用脚本取消设置PDF字体

我使用xhtml2pdf库自动创buildPDF。 几个月前,我有这个问题 (图书馆embedded字体,我没有使用,所以印刷公司不能打印的PDF),我没有find一个解决scheme。 所以我下载PDF到我的电脑和Adobe Acrobat Pro删除未使用的字体。 但有什么办法用脚本来做到这一点? 不pipe用什么语言。

唯一的想法,我发现在互联网上是这样的: http : //www.commandlinefu.com/commands/view/1666/remove-embedded-fonts-from-a-pdf 。 但我不知道如何使用它。 (我认为这将删除所有的字体,而不是未使用的字体)

非常感谢

Java的

可以使用iText库等工具完成。 看到这里的例子 。 但是这是在Java中。

(实际上,我已经尝试过构建了一个非常简单的JAR,就是打开一个Stamper,并调用未使用的对象,TFM说这将删除未使用的字体 ,所以如果你的麻烦的字体真的没有用到,应该如果你有一个测试它的PDF,我可以给它一个 – 或者我可以发送.java和.jar文件,它们是针对iText 5.4.2构建的,你可以在5.5.3 ):

 java -jar pdftrim.jar input.pdf output.pdf 

其他语言( 理论上甚至是bash脚本)

在Python,C或shell中,没有我知道的工具能够完成这个任务。 但是自己写一个不是不可能的。

作为第一步,您需要使用pdftk解压缩PDF文件(不是无意的,它是由iText制成的)。 由此产生的PDF是一个文本文件(除了第一行和多字节的考虑…),并可以在闲暇时进行检查。 例如, grep将起作用。

要检测字体使用情况,您需要检查格式中的所有行

 /Font NNNNNN 0 R 

这会告诉你,字体引用对象NNNNNN正在被一些文本使用。 字体引用列表( 不是字体),然后给出

 grep "^\/Font " $PDFFILE | sort -n -k2.1 | uniq 

我们现在在文件中查找这样的项目

  NNNNNN 0 obj << /F0 XXXXXX 0 R /F1 YYYYYY 0 R >> 

这将为我们提供更多的相同字体的不同字体的对象编号。 XXXXXX可能是粗体字体的标题,YYYYYY是粗体斜体字体的标题。 XXXXXX和YYYYYY(也可能是ZZZZZZ …)是我们的“真实”字体编号。 而在这些对象偏移中,会发现类似的东西

 XXXXXX 0 obj << /Encoding /WinAnsiEncoding /ToUnicode AAAAAA 0 R /FontDescriptor BBBBBB 0 R /Widths [...] /Subtype /TrueType /Type /Font /FirstChar 32 /LastChar 121 /BaseFont /Whatever+Font+Name >> 

这会告诉我们这个头文件在偏移量BBBBBB处引用一个描述符,在地址AAAAAA处引用一个字体数据块。 字体数据块又可以由子流组成。

因此,通过一些字典查找存储来处理事实,即我们有这些间接级别,而一个指令(如/ Font指的是一个数字,而相应的/ BaseFont指向另一个指针),我们现在可以:

  • 找到安装的字体(通过/ BaseFont指令,如果需要的话)
  • 找到使用的字体(通过/ Font指令)

通过删除未使用的字体对象子树(从BaseFont和FontDescriptor提供的地址开始),重新编号具有较高ID号的对象ID,然后重新计算所有文件偏移量 (它们位于PDF文件的底部); 在实践中,最后一步是通过将对象从旧PDF复制到新文件并通过ftell()读取新文件中的文件偏移量来实现的。 然后可以重写底部的PDF XREF

 xref -- start of XREF (NOT NECESSARILY AT A NEWLINE) 0 3315 -- there are 3315 objects 0000000000 65535 f -- not an object; flags 0000000015 00000 n -- first object is 15 bytes past the beginning of the file 0000033003 00000 n ... 0010169101 00000 n trailer << /Info 3314 0 R -- the info table, usually just before the XREF (needs renumbering) /Root 3259 0 R -- the root object ID (needs renumbering) /Size 3315 -- number of objects, again >> startxref 10169367 -- file offset of XREF table above. %%EOF 

然后可以使用pdftk重新压缩生成的PDF文件。

我也尝试使用PDFEdit等工具,但成效不大。

通常情况下,字体包含在文件中,如果它的一些字符已被使用。 一个更安全的方法是将所有字体嵌入到您的PDF文件中。 假设output.pdf的印前质量要求,可以使用

  gswin64c -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress -dCompressFonts=true -dSubsetFonts=true -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=output.pdf -f input.pdf 

你需要安装ghostscript( http://www.ghostscript.com/ ),这里给出的选项说明是http://www.ghostscript.com/doc/9.14/Ps2pdf.htm#Options