我曾经见过这种情况发生,如果嵌入字体子集的名称相同,但这些子集的真正内容是不同的(包含不同的字形集)。
检查您使用的所有输入文件中的字体。使用Poppler的
pdffonts
实用程序进行此操作:
for i in input*.pdf
pdffonts ${i} | tee ${i}.pdffonts.txt
done
寻找每个PDF中使用的字体名称。
我的理论/赌注是你会看到不同输入文件使用相同的字体名称(类似于
BAAAAA+ArialMT
的名称)。
用于子集字体的
BAAAAA+
字体名称前缀应该是
随机的(尽管官方规范并不是很清楚)。然而,一些应用程序使用
可预测的前缀,例如
BAAAAA+
、
CAAAAAA+
、
DAAAAA+
等(OpenOffice.org和LibreOffice以此著称)。
这意味着前缀BAAAAA+
在每个至少使用一个子集字体的文件中都会被使用...
你的输入文件可能没有使用完全相同的字符子集。但是,相同的名称可能会让Ghostscript认为字体确实是相同的。它(错误地)“优化”合并的PDF,并仅嵌入其中一个字体实例(两个实例都具有相同的名称,例如
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)。有关更多详细信息,请参见问题“为什么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)。有关更多详细信息,请参见问题“为什么Acrobat Distiller不完全嵌入所有字体?”的
此答案。
不要使用Ghostscript,而是使用
pdftk
合并PDF。
pdftk
在合并PDF时比Ghostscript(至少旧版本的pdftk)更加“愚蠢”,这种愚蠢可能是一个优势...
更新
为了更明确地回答问题(根据下面@sacohe在评论中的额外问题)。在许多情况下(不是所有情况),以下步骤将起作用:
然后生成的输出PDF应该使用不同(唯一)的字体名称前缀,即使输入PDF对于不同的字体(子集)使用相同的名称前缀。
当我处理原始问题作者'Mr R'提供给我的原始输入文件样本时,这个过程对我起作用。在修复输入文件后,最终结果(从修复后的输入文件创建的合并PDF)中的“跳过字符问题”已经消失。
sudo port -p install ghostscript
。 - Kurt PfeifleQRAAAA+NimbusSanL-Regu
和QWAAAA+NimbusSanL-Bold
),那么你不仅有一个,而是两个不同的字体使用了非唯一命名前缀! - Kurt Pfeifle