如果嵌入字体子集的名称相同,但这些子集的真正内容不同(包含不同的字形集),我已经看到会发生这种情况。
检查所有输入文件中使用的字体。为此使用 Poppler 的 pdffonts 实用程序:
for i in input*.pdf; do
pdffonts ${i} | tee ${i}.pdffonts.txt
done
查找每个 PDF 中使用的字体名称。
我的理论/赌注是你看到不同的输入文件使用相同的字体名称(类似于BAAAAA+ArialMT 的名称)。
用于子集字体的BAAAAA+ 字体名称前缀应该是随机(尽管官方规范对此不是很清楚)。但是,某些应用程序使用 predictable 前缀,以 BAAAAA+、CAAAAAA+ DAAAAA+ 等开头(OpenOffice.org 和 LibreOffice 因这方面而臭名昭著)。 这意味着前缀BAAAAA+ 会在每个使用了至少一种子集字体的文件中使用...
您的输入文件不使用完全相同的字符子集很容易发生。然而,使用相同的名称可能会使 Ghostscript 认为字体确实是相同的。它(错误地)“优化”合并的 PDF 并仅嵌入 2 个字体实例之一(两者具有相同的名称,例如 BAAAAA+Arial)。但是,此实例可能不包含某些字形,这些字形是其他实例的一部分。
这会导致合并输出中缺少一些字符。
我知道,较新版本的 Ghostscript 对其字体处理代码进行了大修。尝试 Ghostscript v9.06(迄今为止的最新版本)可能会让您更加幸运。
我非常有兴趣对此进行更详细的调查。如果您可以提供输入文件的示例(以及 GS v8.70 给出的合并输出),我可以测试它是否与 v9.06 一起使用更好。
你可以做些什么来避免这个问题
-
尝试始终将字体作为完整集而不是子集嵌入:
- 我不知道在使用 wkhtmltopdf 时是否以及如何控制嵌入完整字体。
- 如果您从 Libre/OpenOffice 生成输入 PDF,那么您就很不走运并且无法控制它。
- 如果您使用 Acrobat 生成输入 PDF,您可以在 Distiller 设置中调整字体嵌入细节。
- 如果 Ghostscript 生成您的输入 PDF,则强制全字体嵌入的命令行参数为:
gs -o output.pdf -sDEVICE=pdfwrite -dSubsetFonts=false input.file
某些类型的字体不能完全嵌入,只能嵌入子集(TrueType、Type3、CIDFontType0、CIDFontType1、CIDFontType2)。请参阅this answer 来提问“为什么 Acrobat Distiller 不完全嵌入所有字体?”了解更多详细信息。
-
仅当您确定没有其他人可以看到、打印或使用您的个人输入文件时才执行以下操作:根本不要嵌入字体——仅在与 Ghostscript 合并时嵌入您输入的最终结果 PDF。
- 我不知道在使用 wkhtmltopdf 时是否以及如何控制不嵌入字体。
- 如果您从 Libre/OpenOffice 生成输入 PDF,那么您就很不走运并且无法控制它。
- 如果您使用 Acrobat 生成输入 PDF,您可以在 Distiller 设置中调整字体嵌入细节。
- 如果 Ghostscript 生成您的输入 PDF,用于防止字体嵌入的命令行参数是:
gs -o output.pdf -sDEVICE=pdfwrite -dEmbedAllFonts=false -c "<</AlwaysEmbed [ ]>>setpagedevice" input.file
某些类型的字体不能完全嵌入,只能嵌入子集(Type3、CIDFontType1)。请参阅this answer 来提问“为什么 Acrobat Distiller 不完全嵌入所有字体?”了解更多详情。
-
不要使用 Ghostscript,而是使用 pdftk 来合并 PDF。 pdftk 是一个比 Ghostscript(至少旧版本的 pdftk)更“愚蠢”的实用程序。合并 PDF,这种愚蠢可能是一个优势......
更新
再次回答,但这次更明确(遵循下面 cmets 中@sacohe 的额外问题。在许多(不是所有)情况下,以下过程将工作:
然后,即使输入 PDF 对不同字体(子集)使用相同的名称前缀,生成的输出 PDF 也应该对字体名称使用不同的(唯一的)前缀。
当我处理原始问题的作者“R 先生”提供给我的原始输入文件样本时,此过程对我有用。修复后,“跳过字符问题”在最终结果中消失了(从固定的输入文件创建的合并 PDF)。