gpt4 book ai didi

python - ReportLab:使用中文/Unicode 字符

转载 作者:IT老高 更新时间:2023-10-28 20:55:46 32 4
gpt4 key购买 nike

TL;DR:是否有某种方法可以告诉 ReportLab 使用特定字体,如果某些字符的字形缺失,则回退到另一种字体? 或者,您知道包含以下字形的压缩 TrueType 字体吗?所有欧洲语言,希伯来语、俄语、汉语、日语和阿拉伯语?

我一直在使用 ReportLab 创建报告,在呈现包含中文字符的字符串时遇到了问题。我一直在使用的字体是 DejaVu Sans Condensed,它不包含中文的字形(但是,它确实包含西里尔文、希伯来文、阿拉伯文和各种用于欧洲语言支持的变音符号 - 这使它非常通用,我需要他们都是不时的)

但是,该字体不支持中文,而且我无法找到支持所有语言且符合我们图形设计要求的 TrueType 字体。作为临时解决方法,我让中国客户的报告使用完全不同的字体,只包含英文和中文字形,希望其他语言的字符不会出现在字符串中。然而,由于明显的原因,这很笨拙并且破坏了图形设计,因为它不是 DejaVu Sans,整个外观和感觉都是围绕它设计的。

所以问题是,您将如何处理在一个文档中支持多种语言的需求,并为每种语言保持指定字体的使用。由于有时字符串包含多种语言,因此这变得更加复杂,因此无法确定每个字符串应使用哪种 ONE 字体。

是否有某种方法可以告诉 ReportLab 使用特定字体,并在某些字符的字形缺失时回退到另一种字体?我在文档中发现了一些模糊的提示,虽然我可能理解不正确。

或者,您知道包含所有欧洲语言(希伯来语、俄语、中文、日语和阿拉伯语)字形的精简 TrueType 字体吗?

谢谢。

最佳答案

这个问题让我着迷了整整一周,所以因为是周末,我直接潜入其中并准确找到了一个我称之为 MultiFontParagraph 的解决方案,它是一个普通的 Paragraph一个很大的区别是您可以准确地设置字体后备顺序。

Example of the font fallback working

例如,我从互联网上提取的这个随机日文文本使用了以下字体后备“Bauhaus”、“Arial”、“HanaMinA”。它检查第一个字体是否有字符的字形,如果有,则使用它,如果没有,则回退到下一个字体。目前代码效率不高,因为它会在每个字符周围放置标签,这很容易解决,但为了清楚起见,我没有在这里做。

我使用以下代码创建了上面的示例:

foreign_string = u'6905\u897f\u963f\u79d1\u8857\uff0c\u5927\u53a6\uff03\u5927'
P = MultiFontParagraph(foreign_string, styles["Normal"],
[ ("Bauhaus", "C:\Windows\Fonts\\BAUHS93.TTF"),
("Arial", "C:\Windows\Fonts\\arial.ttf"),
("HanaMinA", 'C:\Windows\Fonts\HanaMinA.ttf')])

MultiFontParagraph的来源(git)如下:

from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import Paragraph


class MultiFontParagraph(Paragraph):
# Created by B8Vrede for http://stackoverflow.com/questions/35172207/
def __init__(self, text, style, fonts_locations):

font_list = []
for font_name, font_location in fonts_locations:
# Load the font
font = TTFont(font_name, font_location)

# Get the char width of all known symbols
font_widths = font.face.charWidths

# Register the font to able it use
pdfmetrics.registerFont(font)

# Store the font and info in a list for lookup
font_list.append((font_name, font_widths))

# Set up the string to hold the new text
new_text = u''

# Loop through the string
for char in text:

# Loop through the fonts
for font_name, font_widths in font_list:

# Check whether this font know the width of the character
# If so it has a Glyph for it so use it
if ord(char) in font_widths:

# Set the working font for the current character
new_text += u'<font name="{}">{}</font>'.format(font_name, char)
break

Paragraph.__init__(self, new_text, style)

关于python - ReportLab:使用中文/Unicode 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35172207/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com