zto*_*age 19 python unicode fonts reportlab chinese-locale
TL; DR: 是否有某种方法告诉ReportLab使用特定字体,如果某些字符的字形丢失,则回退到另一个字体?另外,您知道一个精简的TrueType字体,其中包含所有欧洲语言,希伯来语,俄语,中文,日语和阿拉伯语的字形吗?
我一直在使用ReportLab创建报表,并且在渲染包含中文字符的字符串时遇到了问题.我一直使用的字体是DejaVu Sans Condensed,它不包含中文的字形(但是,它确实包含西里尔语,希伯来语,阿拉伯语和各种用于欧洲语言支持的变音符号 - 这使得它非常通用,我需要他们不时)
但是,字体不支持中文,我无法找到支持所有语言的TrueType字体,并且符合我们的图形设计要求.作为一个临时的解决方法,我做了这样的事情,以便中国客户的报告使用完全不同的字体,只包含英文和中文字形,希望其他语言的字符不会出现在字符串中.然而,由于显而易见的原因,这是笨重的并打破了平面设计,因为它不是DejaVu Sans,围绕它设计了整个外观和感觉.
所以问题是,您将如何处理在一个文档中支持多种语言的需要,并维护每种语言的指定字体的使用.由于有时字符串包含多种语言,因此确定每个字符串应使用哪种ONE字体不是一种选择.
是否有某种方法告诉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')])
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2617 次 |
| 最近记录: |