嵌入带CFF轮廓的Noto Sans HK字体到PDF后部分阅读器渲染异常
在自研PDF生成库中嵌入带CFF轮廓的子集化Noto Sans HK字体时,出现如下异常:
- Mac Preview中无任何字形显示(仅为不可选中的空白),无报错
- Adobe Reader中随机显示.notdef符号与空格,无报错
- 未安装任何字体的Docker镜像中通过Poppler渲染、未安装该字体的Mac版Chrome中均可完美显示,且Chrome渲染的PDF与Cairo生成的同字体参考PDF以50%透明度叠加后完全一致
渲染效果对比:
- Chrome渲染:上方为Noto Sans HK,下方为PingFang HK(正常显示)
- Preview渲染:Noto Sans HK不可见,PingFang HK正常显示
PingFang HK等其他香港中文CFF字体在所有测试阅读器中均可正常渲染,FontBook确认Noto Sans HK无嵌入限制。
字体嵌入配置
所有字体以Identity-H编码的CIDFontType0C格式嵌入,暂未提供ToUnicode映射(后续开发计划),但此配置不应影响渲染。
Noto Sans HK字体对象(已移除Widths)
6 0 obj << /Ascent 1160 /CapHeight 733 /Descent -288 /Flags 4 /FontBBox [ -991 -1050 2930 1810 ] /FontFile3 10 0 R /FontName /NZGUSD+NotoSansHK-Thin /ItalicAngle 0 /StemV 58 /Type /FontDescriptor >> endobj 7 0 obj << /BaseFont /NZGUSD+NotoSansHK-Thin /DescendantFonts [ 8 0 R ] /Encoding /Identity-H /Subtype /Type0 /Type /Font >> endobj 8 0 obj << /BaseFont /NZGUSD+NotoSansHK-Thin /CIDSystemInfo << /Ordering (Identity) /Registry (Adobe) /Supplement 0 >> /FontDescriptor 6 0 R /Subtype /CIDFontType0 /Type /Font /W 9 0 R >> endobj
PingFang HK字体对象
11 0 obj << /Ascent 1060 /CapHeight 860 /Descent -340 /Flags 4 /FontBBox [ -72 -212 1126 952 ] /FontFile3 15 0 R /FontName /DYBBAB+PingFangHK-Regular /ItalicAngle 0 /StemV 95 /Type /FontDescriptor >> endobj 12 0 obj << /BaseFont /DYBBAB+PingFangHK-Regular /DescendantFonts [ 13 0 R ] /Encoding /Identity-H /Subtype /Type0 /Type /Font >> endobj 13 0 obj << /BaseFont /DYBBAB+PingFangHK-Regular /CIDSystemInfo << /Ordering (Identity) /Registry (Adobe) /Supplement 0 >> /FontDescriptor 11 0 R /Subtype /CIDFontType0 /Type /Font /W 14 0 R >> endobj
相关页面对象
3 0 obj << /F4v0 12 0 R /F5v0 7 0 R >> endobj 4 0 obj << /Contents 5 0 R /CropBox [ 2.5 4 595 842 ] /MediaBox [ 0 0 600 850 ] /Parent 2 0 R /Resources << /Font 3 0 R >> /Type /Page >> endobj 5 0 obj << /Length 462 >> stream q 1 1 1 rg 0 0 600 850 re F Q BT /F5v0 15.000000 Tf 0 0 0 rg 0 Tr 27.500000 802.000000 Td [<0AFD292728192FFF3162282746BB112F14E410E20E96201D0D820A9111440EC016922CB046A10AFD0EC039AF1D0B272D17D431C92A2B4F4D384719160F2C29C9297634F34F4D1846>] TJ ET BT /F4v0 15.000000 Tf 0 0 0 rg 0 Tr 27.500000 780.280000 Td [<05487DE1129E161216D412A7726A08C175A77465074A7A1706A504E4748207710B1814B5726605480771641D0E4D12580BD481D113A37267628146D107BE7E0D1358AD3772670C18>] TJ ET endstream endobj
子集生成方式
使用HarfBuzz生成子集,设置HB_SUBSET_FLAGS_RETAIN_GIDS标志,FontForge验证子集内所需字形均存在且GID正确。
后续调查(编辑内容)
尝试将Noto Sans HK以CIDFontType2格式嵌入时,Preview可正常显示;Adobe Reader仍显示.notdef符号;Poppler警告字体类型错误但仍正常渲染。推测Preview和Poppler会自动将字体解析为CIDFontType0并忽略错误的/Subtype字段,但无法解释为何正确嵌入时反而无法显示。
嵌入完整Noto Sans HK字体时,Preview不再完全空白,但显示随机字符,且渲染字形与提供的GID完全不匹配(FontForge验证);Chrome显示效果仍正常。PingFang HK等字体在两种嵌入方式下均正常渲染。
怀疑问题与字形索引(GID)有关:Cairo等PDF生成器会将GID重新映射为低数值,因此无问题;而自研库保留了原始2字节GID,可能触发了某些阅读器未公开的实现限制,后续将尝试重新映射GID并验证效果。
内容的提问来源于stack exchange,提问作者DividedByZero

