如何使用ttf文件来估计浏览器以固定宽度包装文本的方式

2024-10-02 22:23:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我想估计一个div元素的高度,它只包含浏览器呈现的文本。例如,考虑以下htm文件:

<html>
  <body>
    <div style="position:absolute; top:100pt; left:80pt; width:200pt">
      <p style="line-height:16pt; font-size:9pt; font-family:Monospace; font-style:normal; font-weight:normal;">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
    </div>
  </body>
</html>

这是我在python中的尝试:

from PIL import ImageFont
import re


def getHeightOfTextBox(line_height, font_size, ttfFileName, box_width, text):
    text = text.strip()
    text = re.sub('\s+', ' ', text)
    font = ImageFont.truetype(ttfFileName, font_size)
    numLines = 1
    cursor = 0

    spaceWidth = font.getsize(' ')[0]
    afterLineBreak = False

    for word in text.split(' '):
        wordWidth = font.getsize(word)[0]
        cursor += wordWidth + (spaceWidth if afterLineBreak else 0)
        if cursor > box_width:
            print(word)
            numLines += 1
            afterLineBreak = True
            cursor = wordWidth
        else:
            afterLineBreak = False
            cursor += spaceWidth

    return numLines * line_height


text = '''
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
'''

print(getHeightOfTextBox(16, 9, "LiberationMono-Regular.ttf", 200, text))

以下是脚本的输出:

adipiscing
incididunt
aliqua.
nostrud
nisi
Duis
in
fugiat
occaecat
culpa
id
192

总共有12行。下面是如何在我的Firefox浏览器中呈现div元素:

enter image description here

一共有13行。在本例中,pillow说字符的宽度是5pts,因此是div宽度的0.025。使用Firefox的inspect元素功能,Firefox计算字符的宽度是7px,div的宽度是266.667px,因此是div宽度的0.02625。此时,我最好的猜测是,造成这种差异的原因是Firefox认为,如果一个字符比枕头稍大,那么它的宽度就是。如果我用10pts的字体大小来修改这个例子,那么我的代码和Firefox之间就会达成一致。你知道吗

是否可以使用字体度量文件更正我的代码以准确估计浏览器呈现的div高度?我知道另一个选择是使用无头浏览器,比如PhantomJS和Selenium。但我希望避免这种情况,因为我觉得这可能是过度杀戮。你知道吗


Tags: textindiv元素宽度style浏览器firefox