我将一个TrueType字体嵌入到pdf中,因此需要为它创建描述符字典。
在 StemV 中需要的字段中,我还没有找到ttf中存储此信息的位置。
我想我在某个地方看到它是CVT
程序的一部分,但没有具体说明。
所以,我的问题是如何找出给定TrueType字体的StemV值。我想直接从ttf文件中读取这个值(而不是使用ie windows API),因为我想编写跨平台的解决方案。
更新:
Grep-ed LibreOffice 5.1.0.3源代码似乎在导出为pdf时,FontDescriptor
生成vcl/source/gdi/pdfwriter_impl.cxx
方法PDFWriterImpl::emitFontDescriptor()
。在那里,第3888行附近是代码:
// According to PDF reference 1.4 StemV is required
// seems a tad strange to me, but well ...
aLine.append( "\n"
"/StemV 80\n" );
现在的问题是80
,而不是42
?但严重的是,如果像LibreOffice这样的项目使用硬编码常量,它似乎表明该值未存储到字体文件中或读取它非常昂贵(即需要实现TrueType字体引擎来解释字体程序)。
答案 0 :(得分:8)
根据ISO 32000-1:2008,StemH
是可选的,StemV
是必需的(参见表122)。唉,似乎没有就从何处获取这些数据达成明确的共识。
该变量可能源自Adobe的原始Type 1(CFF)字体格式:
条目
StdVW
是一个只有一个实数条目的数组 表示垂直茎的主要宽度(水平测量) 在角色空间单位)。通常,这将是宽度 小写字母的直茎。 (对于斜体字体程序, 给出以垂直角度测量的垂直杆的宽度 到了方向。)例如:
/StdVW [85] def
(Adobe Type 1 Font Format,1993年2月,1.1版,第42页)
这是CFF字体的/Private
字典中的可选条目。
然而,Werner Lemberg表示(http://blog.gmane.org/gmane.comp.fonts.freetype.devel/month=20130601)
如果嵌入字体,则PDF引擎使用的不
如果PDF中没有StemV值,则使用以下算法 适用...
这增加了混乱,因为它被标记为"必需"在PDF规范中。
Apache FOP 注意到其目标'在字体
下..如果[important],解析.pfb文件以在构建FOP xml度量标准文件时将其解压缩..
(http://www.cs.helsinki.fi/group/xmltools/formatters/fop/fop-0.20.5/build/site/dev/fonts.html)
PDFLib 使用 FreeType ,头文件ft_font.h
包含一个列表:
+---------------------------------------------------------------------------+
Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. |
+---------------------------------------------------------------------------+
(.. omitted..)
/*
* these defaults are used when the stem value
* must be derived from the name (unused)
*/
#define FNT_STEMV_MIN 50 /* minimum StemV value */
#define FNT_STEMV_LIGHT 71 /* light StemV value */
#define FNT_STEMV_NORMAL 109 /* normal StemV value */
#define FNT_STEMV_MEDIUM 125 /* mediumbold StemV value */
#define FNT_STEMV_SEMIBOLD 135 /* semibold StemV value */
#define FNT_STEMV_BOLD 165 /* bold StemV value */
#define FNT_STEMV_EXTRABOLD 201 /* extrabold StemV value */
#define FNT_STEMV_BLACK 241 /* black StemV value */
注意"未使用"。此列表也只出现在旧版本的FreeType中。
PrawnPDF 只是说(http://prawnpdf.org/docs/0.11.1/Prawn/Font/TTF.html)
stemV()
不确定如何为真实字体计算...
Apache FontBox 中的TrueType嵌入器做出了有根据的猜测:
// StemV - there's no true TTF equivalent of this, so we estimate it fd.setStemV(fd.getFontBoundingBox().getWidth() * .13f);
(https://pdfbox.apache.org/download.cgi) - 我觉得我必须补充一点,它比没有好,但只是非常狭窄。对于大多数字体,词干宽度和边界框之间的关系并不是这么简单。还有一些着名的字体变胖"内向"所以他们的边界框实际上具有完全相同的值。
进一步搜索引领我回到1998年的UseNet帖子:
.ttf表格和PDF的StemV值
来自:John Bley
日期:1998年6月16日星期二17:09:19格林尼治标准时间 在PDF中嵌入TrueType字体时,我需要一个垂直的茎宽值 - 我可以从各种.ttf表中获得所需的所有其他值(上升,下降,斜体等),但我不能似乎在任何地方定位或计算平均或正常的垂直(或水平)茎宽度。通过观看嵌入的PDF字体,我知道"提示"在' OS / 2'表是不够的 - 它是一个非常精确的值,而不是1-10种规模。有线索吗?谢谢你的时间!该值不是TrueType字体。你必须通过分析,例如,上限字形来计算它。不要过分担心输入一个精确的值:只有当PDF文件中没有字体时,才会使用该值,而使用的是相似的字体。 - 劳伦斯
(http://www.truetype-typography.com/ttqa_1998.htm)
"' OS / 2'表"据推测,提示是usWeightClass
。虽然其值定义在100到900的范围内,但这不是连续范围。仅使用整个100个,因此它是1-9的比例(不是上面问题中提到的1-10)。该比例源自Microsoft的字体定义,它只有这9个不同的值。 (请注意,ft_font.h
文件仅列出 8 预定义的词干值。另一个问题是,在那里。)
使用Adobe InDesign CS4,我使用Light,Regular和Bold中的Aller字体以及常规,粗体和黑色Arial(这些都是TTF字体)创建了一个小型测试PDF,并且发现InDesign写出了StemV& #39; s as
Aller-Light 68
Aller-Regular 100
Aller-Bold 144
Arial 88
Arial-Bold 136
Arial-Black 200
这表明InDesign使用某种启发式方法来计算每种字体的茎宽,而不依赖于固定的基于权重的表。它不像"大写' I'"的宽度,它们是69,102,147(Aller)和94.7,144.5,221.68(Arial)设计单位,分别。我故意用无衬线字体测试,因为衬线字体上的衬线需要估计字形中间某处的宽度。
我使用InDesign CC 2014导出了相同的文档,并获得了完全相同的值。关于如何找出InDesign从哪里获取这些值,我没有进一步的想法。
(稍后添加:) Minion Pro是一种CFF风格的OpenType字体,因此它可能包含有效的StdVW
值。经过测试,我发现它确实:79 StdVW
。值得注意的是:InDesign 不使用此值,而是将其导出为/StemV 80
。 Minion Pro Bold,128,的值是正确的,但在这一点上,我很肯定这可能是纯粹的巧合。由于这两者已经不同,我没有进一步的动机来检查Minion Pro Semibold或Minion Black。
最差的解决方案似乎是从OS / 2标头中读取usWeightClass
并将其直接映射到合理的值。