以编程方式将 CFF 字体转换为 OpenType 字体

Posted

技术标签:

【中文标题】以编程方式将 CFF 字体转换为 OpenType 字体【英文标题】:Convert CFF fonts into OpenType fonts programmatically 【发布时间】:2012-02-05 10:30:54 【问题描述】:

有没有人有任何指针可以找到关于如何围绕 CFF 字体创建 opentype 包装器的额外信息?

目前我有一个 CFF 文件解析器,因此我可以从中获取各种信息(cmap、字形名称、宽度、名称等)。鉴于此信息,我无法创建 Opentype(类似 truetype 格式)包装器,因此我可以使用 GDI 在 Windows 上使用该字体; GDI 不会加载 Opentype 字体,我唯一知道的是它无法加载字体。

是否有人知道任何其他信息、验证应用程序、示例代码、获取其他信息为什么字体不能从 Windows 等加载?

注意:我正在寻找如何操作的信息,而不是实用程序和/或转换工具。

【问题讨论】:

我想问一下,你在哪里找到了 CFF 字体文件?我从来没有见过,搜索结果是空的。有 OpenType/CFF 但那些已经有了包装器。 @Mark:查看 PDF 文件,通常嵌入了子集。 T您也可以在 OTF 字体中找到它们(自然)。目前我正在尝试将 PDF 文件渲染到 GDI 设备上下文(屏幕/打印机),并且还需要渲染一些 CFF 嵌入字体。因此问题。 Microsoft 的 OpenType 文件格式描述中给出的文档对如何构建这个包装器不是很清楚(它是格式记录结构描述,而不是如何)。 下面的简短问题:OpenType 字体文件里面有 CFF 表。我可以简单地通过字典表中的偏移地址和大小来提取它。在 PDF 文件中,字体资源对象、/FontFile3 流内容压缩了 CFF 字体文件。那是相同的CFF吗?实际上,当我看到二进制文件时,我可以看到一些差异,比如文件中的 FontName 是 Font-Name,但在 PDF 中是 FHDH+Font-Name 等。PDF 摘录更短,这对我来说是字体文件的整个 CFF 的一部分。我可以将字体文件的整个 CFF 部分包含在 PDF 文件的资源流中吗? @user1543083:可以对 CFF 字体文件进行一些更改。第一:它是相同的字体文件,但名称不同(由于 PDF 标准)子集(只保留使用的字形)使文件更小,也是常见的做法。 OK,终于拿到了一个OTF字体的CFF表。你能帮我找到哪个索引/字典/位置/偏移/部分等吗?我必须挖掘一些 GLYPH WIDTH 参数值(不是平均字形宽度,不是最小/最大字形宽度,只是一些字形的字形宽度)?我试图在“ISO/IEC STANDARD 14496-22 Open Font Format”和“The Compact Font Format Specification Version 1.0”中查找有关主题的一些信息,但没有找到。 【参考方案1】:

我引用这个链接:Raster, Vector, TrueType, and OpenType Fonts

...字体的字形存储在字体资源文件中。 ...

因此,Windows 从具有它可以理解的格式的文件中加载字形,而不是 CFF 文件,也不是内存中的结构。如果您想在不使用文件转换工具的情况下绘制 CFF 文件,我认为您需要自己加载 CFF 并绘制字形。

要加载 CFF 并确定字形,您可以使用 FreeType Project。这是一个关于 SO 的链接,解释了如何从 FreeType 源构建 Win32 DLL:Compiling FreeType to DLL (as opposed to static library)

要绘制字形,您可以从gdipp project 中获得一些灵感,它是 Windows 文本渲染器的替代品,包含显示从 FreeType 加载的字形的 Win32 C/C++ 示例代码。

【讨论】:

gdipp 很有趣。会调查的。我真正想要的是拥有一个简单的 CFF -> OTF 例程,这样我就可以获取一个 CFF 文件,解析它(这就是我已经拥有的),构建 OTF 文件所需的其他 sfnt 表;从松散的表中构造它(顺便说一句)并将字体加载为内存资源。我宁愿使用这条路线,所以当字体绘制到 GDI EMF 表面时,我会以文本输出而不是位图绘制结束。如果我不能成功,这条路线自然是第二种选择。【参考方案2】:

似乎 CFF 格式被直接嵌入到 OpenType 文件中。微软对 OpenType 文件有很好的概述:http://www.microsoft.com/typography/otspec/otff.htm

【讨论】:

这正是我所追求的,但还有其他表必须填写:cmap、head、maxp 等(根据相同的文档)。问题是:Windows GDI 需要在这个包装器中填写什么来吞下这个字体;例如,Freetype2 适用于半填充字体,但不适用于 Windows。你得到的唯一错误是......不起作用。 我奖励你是因为你参考了规范;虽然它并没有真正回答我的问题,但它是最接近的。感谢您的宝贵时间。【参考方案3】:

到目前为止,我有 3 个库作为参考:

    FreeType:主要在cff包中,主要入口是cff\cffload.c,现在在github中 FontForge:fontforge\parsettf.c,仍在 sf.net 中 fonttools:fonttools\cffLib.py,在 sf.net 中 ots 工具:http://code.google.com/p/ots/source/browse/trunk/src/cff.cc

在 parsettf.c 中,George Williams 写道: True Type 是一种非常讨厌的格式。 ...现在我对它的理解更好,它似乎设计得更好,但文档仍然存在冲突。有时很糟糕。

IMO,cff 文档同样糟糕。 也许它设计得更好。只是也许,如果我有时间:) 我会确认也许。为什么?看看那些东西的创建时间,太老了。

只有年纪大了有什么好处?父母,数学和哲学:) 其他任何东西都必须更新!

【讨论】:

感谢您的链接。其他人的源代码可能是 CFF 文件格式的最佳信息来源。因为我不希望有其他更多信息来源,所以这是迄今为止最好的答案。 更新新链接。 IMO,如果仅通过所谓的 opentype 规范文档就很难。因为我现在正在做一个渲染工作,而规范文档和设计真的很奇怪,至少不是最好的,f.e. CharString 字节码。 对不起,@Ritsaert。我浏览了以下内容,并且知道我的注意力有误。因为我脑子里的一切都只是 cff (东西:)。 GDIPP 应该会有所帮助。和 AGG 在演示页面中有示例:link 和 LCD 演示:link。 Agg source freetype 和窗口字体包装器可能会有所帮助。但我想知道 Windows 加载 otf 何时失败?我使用 Eclipse,它的文本编辑器似乎调用了 windows#Xoutline 函数。我只使用 otf 文件进行编辑:) 去年(2012/4)我尝试了CFF字体处理,在java中找到了关于CFF的源代码,错误。而且根本没用。并且似乎新版本的 FreeType native wrapper 返回了一些错误数据,这与 AGG 读取的结果不同。 这是一篇较旧的帖子,但我想指出 CFF 到 TTF 是有损转换,并且 windows GDI 支持 opentype-with-cff-block 就好了,所以转换是当你有一个 CFF 块时不需要它,你只需要为它形成一个有效的 OpenType 包装器。 pomax.github.io/CFF-glyphlet-fonts 涉及(但只有源代码真正描述了)这个包装器与 CFF 块的工作原理。【参考方案4】:

CFF(Compact Font Format)主要用于在PDF文件中嵌入PostScript字体。您还可以在基于 PostScript 轮廓的 OpenType 字体文件中找到 CFF。

如果您从 PDF 的嵌入字体文件中获得 CFF,您可以从 CFF 的 NameIndex 中获得 PostScript 名称。您应该通过 PostScript 名称找到相应的 OpenType 文件。

如果您从 OpenType 文件中获得 CFF,您为什么要问这个问题? :-D

【讨论】:

以上是关于以编程方式将 CFF 字体转换为 OpenType 字体的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式确定字体是不是为 CFF?

如何使用 CFF2 表在 OpenType 中定义没有任何变体的字体

如何将日文 OTF 字体转换为与 FOP 一起使用

以编程方式生成 OpenType 字体:请求 HOWTO

可安装 OpenType 字体的 Windows 要求是啥?

Microsoft Windows OpenType Compact字体格式远程代码执行漏洞(MS11-007)