更改嵌入的 TrueType 字体,使其可供 Windows GDI 使用
我正在尝试将 PDF 内容渲染到 GDI 设备上下文(确切地说是 24 位位图)。将 PDF 流解析为 PDF 对象并渲染内容字典中的 PDF 命令效果很好,包括字体渲染。
嵌入字体从其 FontFile 流中解压缩,并使用 AddFontMemResourceEx 进行“加载”。现在,一些嵌入字体删除了 GDI 所需的一些 TrueType 表,例如“名称”表。因此,我尝试通过将 TrueType 子集字体解析到其表中来修改字体,并修改那些数据丢失的表/丢失的表使用尽可能正确的信息重新生成。
我使用 Microsoft Font Validator 工具来查看如何“正确”生成的字体是。我仍然遇到一些错误,例如 maxp 表的最大值通常太大(它是子集)或 xAvgCharWidth 字段不等于“OS/2”表的计算值不正确,但这不会阻止其他嵌入字体的使用。使用 PDFCreator 嵌入的字体是有问题的。
问题:
- 我如何确定我需要什么 更改字体文件以便 GDI能用吗?
- 还有其他字体验证吗 可能给我洞察力的工具 仍然存在什么问题 字体文件?
如果需要:我可以制作原始字体文件和更改后的字体文件以供下载。
到目前为止进行了哪些修改:
- 确保有“head”、“hhea”、“maxp”和“OS/2”部分。
- 如果我们有符号字体,请清除“OS/2”部分中的 Panose 和 Unicode 字段。
- 如果 WInAscent/Desc 和 TypoAsc/Desc 为零,请填写正确的值。
- 填写上标/下标/下划线位置和大小可接受的值。
- 扫描剩下的所有字形并在 head 中填写 X/Y 最小/最大值。
- 使用来自 PDF 文件的信息重建名称部分。
I am trying to render PDF content to a GDI device context (a 24bit bitmap to be exact). Parsing the PDF stream into PDF objects and rendering the PDF commands from the content dictionary works well, including font rendering.
Embedded fonts are decompressed from their FontFile streams and "loaded" using AddFontMemResourceEx
. Now some embedded fonts remove some TrueType tables that are needed by GDI, like the 'name' table. Because of this, I tried to modify the font by parsing the TrueType subset font into it's tables and modify those tables that have data missing / missing tables are regenerated with as correct information as possible.
I use the Microsoft Font Validator tool to see how "correct" the generated font is. I still get a few errors, like for the maxp table the max values are usually too large (it is a subset) or the xAvgCharWidth
field does not equal the calculated value of the 'OS/2' table is not correct but this does not stop other embedded fonts to be useable. The fonts embedded using PDFCreator are the ones that are problematic.
Questions:
- How can I determine what I need to
change to the font file in order for
GDI to be able to use it? - Are there any other font validation
tools that might give me insight
into what is still wrong with the
fontfile?
If needed: I can make an original fontfile and an altered fontfile available for download somewhere.
What modifications are made so far:
- Make sure there is a 'head', 'hhea', 'maxp' and 'OS/2' section.
- If we have a symbol font, clear out Panose and Unicode fields in the 'OS/2' section
- Fill in correct values for WInAscent/Desc and TypoAsc/Desc if they we're zero.
- Fill in acceptable values for super/subscript/underline positions and sizes.
- Scan all glyphs that are left en fill in X/Y min/max values in head.
- Rebuild the name section with information from the PDF file it came from.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
几乎晚了一年,但我找到了答案:
“cmap”表和“name”表的字体类型(符号或非符号)应该相同。因此,如果 cmap 具有 3,0,4 cmap(MS、符号、段增量编码)并且名称表包含 3,1,$0409(MS、Unicode、enUS)条目,则该字体将不会加载。
看起来“symbol cmap”的存在决定了 Windows 是否将字体视为符号字体; “OS/2”中的标志似乎并不重要。
因此,如果使用“Microsoft Font Validator”看起来字体正确,请检查“cmap”和“name”表中的符号/unicode 字段是否对齐。
Almost a year late, but I found the answer:
The font kind (symbol or not) should be the same for the 'cmap' table and the 'name' table. So if the cmap has a 3,0,4 cmap (MS, symbol, segment delta coding) and the name table contains 3,1,$0409 (MS, Unicode, enUS) entries, the font will not load.
It looks like the presence of a 'symbol cmap' determines if the font is considered a symbol font by Windows; flags in 'OS/2' don't seem to matter.
So if a font seems correct using 'Microsoft Font Validator', check if the symbol/unicode fields line up in the 'cmap' and 'name' tables.
使用 GDI+ 中的 AddMemoryFont 您可以检查它的 < a href="http://msdn.microsoft.com/en-us/library/ms534175(v=VS.85).aspx" rel="nofollow noreferrer">内存字体中任何错误的状态 ,例如
NotTrueTypeFont
。GDI 的一种选择可能是尝试使用 TTLoadEmbeddedFont,然后检查从 错误消息。唯一提供比此更多信息的函数是 CreateFontPackage/MergeFontPackage ,以及他们的错误代码,但我知道无法了解如何在您的情况下使用它们。
除此之外,您是否有机会查看 PDFCreator 的源代码(假设您是使用开源软件而不是商业软件)?
With AddMemoryFont in GDI+ you can check it's Status for any errors in the memory font, like
NotTrueTypeFont
for example.One option for GDI may be to try to load the embedded font into a document/form yourself with TTLoadEmbeddedFont and then check any errors returned from the error messages. The only functions that supply more information than this one are CreateFontPackage/MergeFontPackage, and their error codes, but I do fail to see how they can be used in your situation.
Barring all this, have you had a chance to review PDFCreator's source code (assuming you're using the open source one as opposed to the commercial one)?