ReportLab:使用中文/ Unicode字符
TL; DR: 是否有某种方法告诉ReportLab使用特定字体,如果缺少某些字符的字形,则回退到另一字体吗? 另外,
您是否知道一种精简的TrueType字体,其中包含所有欧洲语言(希伯来语,俄语,中文,日语和阿拉伯语)的字形?
我一直在使用ReportLab创建报告,并且在渲染包含汉字的字符串时遇到了问题。我一直在使用的字体是DejaVu Sans
Condensed,它不包含中文的字形(但是,它确实包含西里尔字母,希伯来语,阿拉伯语和各种支持欧洲语言的Umlauts,这使它非常通用,我需要他们不时地)
但是,该字体不支持中文,并且我无法找到支持所有语言并符合我们图形设计要求的TrueType字体。作为一种临时的解决方法,我做到了这一点,以便针对中国客户的报表使用完全不同的字体,仅包含英文和中文字形,希望字符串中不会出现其他语言的字符。但是,由于明显的原因,这很笨拙并破坏了图形设计,因为它不是DejaVu
Sans,而是围绕其设计了整体外观。
因此,问题是
,您将如何处理在一个文档中支持多种语言并保持每种语言使用指定字体的需求。由于有时字符串包含多种语言,因此使情况变得更加复杂,因此,确定每个字符串应使用哪种字体都不是一个选择。
是否有某种方法告诉ReportLab使用特定字体,如果缺少某些字符的字形,则回退到另一字体?我在文档中发现模糊的提示,提示应该可以,尽管我可能会误解。
另外,您是否知道一种精简的TrueType字体,其中包含所有欧洲语言(希伯来语,俄语,中文,日语和阿拉伯语)的字形?
谢谢。
-
这个问题使我整个星期都着迷,所以由于是周末,所以我潜入其中,并精确地找到了一个我称之为
MultiFontParagraph
正常的解决方案,但Paragraph
有很大的不同,您可以准确地设置字体后备顺序。例如,我从互联网上提取的此随机日语文本使用以下字体回退
"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)