次のコードは、指定した使用可能な高さに収まるまで、reportlab Platypus のフロー可能なテキストのフォント サイズを変更しようとします。しかし、Paragraph flowable が再帰の各ループで style.fontSize 属性を保存しておらず、Python が無限再帰でボークしていることがわかります。
def fits_space(w,h,aW,aH,p):
"""
Determines if inputted text fits in the space given for a paragraph
and if it doesn't, reduces the font-size until it does.
"""
if w<=aW and h<=aH:
# return font size to apply it to the para again
print "final font_size: %d" % p.style.fontSize
return p # now render the paragraph in the doctemplate
else:
p.style.fontSize -= 1
w,h = p.wrap(aW, aH)
fits_space(w,h,aW,aH,p)
def renderPage(name, text):
doc = SimpleDocTemplate("%s.pdf" % name)
parts = []
style = ParagraphStyle(name='fancy')
style.fontSize = 150
p = Paragraph(text, style)
aW = PAGE_WIDTH-4*inch # available width and height
aH = PAGE_HEIGHT-4*inch
w,h = p.wrap(aW, aH) # find required space
p = fits_space(w,h,aW,aH,p) # recursively fit the font size to the text
parts.append(p)
doc.build(parts)
誰かが私に理由を教えてもらえますか-fits_space()関数のelse句で、p.wrap(aW、aH)を呼び出すと、出力された値は段落のfontSizeを1減らす前と同じですか? フォントサイズを小さくすると、ラップされた高さが小さくなるはずです。
私が間違っているアイデアはありますか?
UPDATE Nitzie の以下のコードは、私の場合も style.leading にリサイザーを追加するために必要なだけでほとんど機能しました。
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
style.leading -= 1 # do this if you're leading is based on the fontSize
lines = break_lines(text, aW)
width, height = line_wrap(lines, style)
ティア