TrueType字体的StemV值

时间:2016-02-18 15:10:20

标签: pdf true-type-fonts embedded-fonts

我将一个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字体引擎来解释字体程序)。

对于那些想知道这个StemV是什么的人 - 请参阅“PDF参考文献” 第六版“它被描述为”水平测量的字体中字形的主要垂直茎的厚度“。

1 个答案:

答案 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 预定义的词干值。另一个问题是,在那里。)

(不确定的)InDesign测试

使用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。

TL,DR摘要:

  • 如果要嵌入Type 1(CFF)字体,可以填写所需的任何内容,并从字体数据中读取实际值
    • ......除非它不在那里。
  • 如果要嵌入TrueType字体,则需要提供良好的值。

最差的解决方案似乎是从OS / 2标头中读取usWeightClass并将其直接映射到合理的值。