首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调整可流动的reportlab.platypus.Paragraph大小?

调整可流动的reportlab.platypus.Paragraph大小?
EN

Stack Overflow用户
提问于 2013-02-05 23:56:37
回答 1查看 6.8K关注 0票数 3

下面的代码试图调整reportlab Platypus可流动文本的字体大小,直到它符合我给它的可用高度。但是我发现,可流动的段落并没有在递归的每个循环中保存它的style.fontSize属性,而且python具有无限递归。

代码语言:javascript
复制
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添加一个大小调整器:

代码语言:javascript
复制
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)

提亚

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-06 03:11:48

由于某些原因,一旦您在调用了fontsize一次之后更改了fontsize,p.wrap似乎不会真正重新计算它的高度/宽度。

通过计算基于ReportLab的stringWidthsplitLines方法的字体大小,我获得了一个工作版本。尽管这意味着它不再是递归的:

代码语言:javascript
复制
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)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14719194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档