For some reason, p.wrap
does not seem to truly recalculate height/width once you've changed the fontsize after calling it once already.
I was able to get a working version by calculating font size based on ReportLab's stringWidth
and splitLines
methods. Although this means it is no longer recursive:
from reportlab.platypus import SimpleDocTemplate
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.units import inch
from reportlab.lib.pagesizes import A4
from reportlab.platypus import Paragraph
from reportlab.lib.utils import simpleSplit
from reportlab.pdfbase.pdfmetrics import stringWidth
def shrink_font_size(aW, aH, text, style):
"""Shrinks font size by using pdfmetrics to calculate the height
of a paragraph, given the font name, size, and available width."""
def break_lines(text, aW):
# simpleSplit calculates how reportlab will break up the lines for
# display in a paragraph, by using width/fontsize.
return simpleSplit(text, style.fontName, style.fontSize, aW)
def line_wrap(lines, style):
# Get overall width of text by getting stringWidth of longest line
width = stringWidth(max(lines), style.fontName, style.fontSize)
# Paragraph height can be calculated via line spacing and number of lines.
height = style.leading * len(lines)
return width, height
lines = break_lines(text, aW)
width, height = line_wrap(lines, style)
while height > aH or width > aW:
style.fontSize -= 1
lines = break_lines(text, aW)
width, height = line_wrap(lines, style)
def renderPage(name, text):
doc = SimpleDocTemplate("%s.pdf" % name)
parts = []
# Wasn't sure where PAGE_WIDTH and PAGE_HEIGHT came from for OP,
# so I just used a standard A4 page measurement.
PAGE_WIDTH, PAGE_HEIGHT = A4
aW = PAGE_WIDTH - 4*inch # available width and height
aH = PAGE_HEIGHT - 4*inch
style = ParagraphStyle(name='fancy')
style.fontSize = 200
style.leading = 20
shrink_font_size(aW, aH, text, style)
p = Paragraph(text, style)
parts.append(p)
doc.build(parts)
if __name__ == "__main__":
renderPage('test', '12345689019283382848248284 842828428529392381472754 842828428529392381472754 842828428529392381472754\n' * 10)