ain*_*ain 3 pdf truetype 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" );
Run Code Online (Sandbox Code Playgroud)
现在的问题是为什么80,不是42吗?但严重的是,如果像LibreOffice这样的项目使用硬编码常量,则似乎表明该值未存储到字体文件中或读取它非常昂贵(即需要实现TrueType字体引擎来解释字体程序).
顺便说一句,对于那些想知道这个StemV是什么的人 - 在"PDF参考第六版"中,它被描述为"水平测量的字体中字形的主要垂直茎的厚度".
根据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)
如果嵌入字体是Type 1或CFF字体,则PDF引擎不使用StemV值; 在这种情况下,私人字典的值被使用.对于CID字体,将使用与字形的字体DICT关联的值.
如果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 */
Run Code Online (Sandbox Code Playgroud)
注意"未使用".此列表也仅出现在较旧版本的FreeType中.
PrawnPDF刚才说(http://prawnpdf.org/docs/0.11.1/Prawn/Font/TTF.html)
stemV()
不确定如何为真实字体计算这个...
Apache FontBox中的TrueType嵌入器做出了有根据的猜测:
Run Code Online (Sandbox Code Playgroud)// 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 GMT
当在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写为
Aller-Light      68
Aller-Regular   100
Aller-Bold      144
Arial            88
Arial-Bold      136
Arial-Black     200
Run Code Online (Sandbox Code Playgroud)
这表明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.
最差的解决方案似乎是usWeightClass从OS/2标头读出并将其直接映射到合理的值.