【问题标题】:Why does ghostscript replace fontnames to "CairoFont"?为什么 ghostscript 将字体名称替换为“CairoFont”?
【发布时间】:2016-03-16 22:41:57
【问题描述】:

我使用 ghostscript 来优化 pdf 文件(主要是在大小方面),它做得很好。我使用的命令是:

gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
   -dCompatibilityLevel=1.4 -sOutputFile=out.pdf in.pdf

但是,这似乎替换了字体(或子集)并且不保留它们的名称。它用 CairoFont 代替它。我怎样才能得到 ghostscript 来保留字体名称?

示例: 一个简单的 pdf 文件(使用 Inkscape 创建),其中包含一个文本元素(Nimbus Roman)作为输入(in.pdf):

pdffonts 报告的内容:

name                                 type              emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
PMLNBT+NimbusRomanNo9L               Type 1            yes yes yes      5  0

但是,在文件pdffonts 上运行ghostscript 报告后:

name                                 type              emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
OEPSCM+CairoFont-0-0                 Type 1C           yes yes no       8  0

那么,有没有办法让 ghostscript(或 libcairo?)保留字体名称?

输入文件上传here

【问题讨论】:

    标签: pdf ghostscript cairo


    【解决方案1】:

    Ghostscript 不会更改字体名称,但实际上在 PDF 文件中有几个不同的字体“名称”。

    对于您的文件,PDF FontDescriptor 对象有一个名称

    <<
      /Type /FontDescriptor
      /FontName /PMLNBT+NimbusRomanNo9L
      /Flags 4
      /FontBBox [ -168 -281 1031 924 ]
      /ItalicAngle 0
      /Ascent 924
      /Descent -281
      /CapHeight 924
      /StemV 80
      /StemH 80
      /FontFile 7 0 R
    >>
    

    指的是 FontFile 流

      /FontFile 7 0 R
    

    该流包含以下内容:

    %!PS-AdobeFont-1.0: NimbusRomNo9L-Regu 1.06
    %%Title: NimbusRomNo9L-Regu
    %Version: 1.06
    %%CreationDate: Thu Aug  2 13:14:49 2007
    %%Creator: frob
    %Copyright: Copyright (URW)++,Copyright 1999 by (URW)++ Design &
    %Copyright:  Development; Cyrillic glyphs added by Valek Filippov (C)
    %Copyright:  2001-2005
    % Generated by FontForge 20070723 (http://fontforge.sf.net/)
    %%EndComments
    
    FontDirectory/NimbusRomNo9L-Regu known{/NimbusRomNo9L-Regu findfont dup/UniqueID known pop false {dup
    /UniqueID get 5020931 eq exch/FontType get 1 eq and}{pop false}ifelse
    {save true}{false}ifelse}{false}ifelse
    11 dict begin
    /FontType 1 def
    /FontMatrix [0.001 0 0 0.001 0 0 ]readonly def
    /FontName /CairoFont-0-0 def
    

    您看到 actual 字体的 FontName 了吗?它叫CairoFont-0-0

    这让我回到了我在这里和其他地方经常重申的一点;当您使用 Ghostscript 处理 PDF 文件并使用 pdfwrite 设备发出新的 PDF 文件时,您不是在“优化”、“转换”、“子集”或在一般意义上操纵原始 PDF 文件的内容。

    Ghostscript 所做的是解释 PDF 文件,它会生成一组 opf 标记操作(例如“stroke”、“fill”、“image”等),并将其发送到选定的 Ghostscript 设备。然后,大多数 Ghostscript 设备将使用图形库将操作渲染到位图,当页面完成时,会将位图写入文件。 “高级”或“向量”设备将操作重新打包成另一种页面描述语言。在 pdfwrite 的情况下,这是一个 PDF 文件。

    这实际上意味着发出的 PDF 文件与原始 PDF 文件没有任何共同点(除了外观)。特别是对象的描述可能会有所不同。

    因此,在您的情况下,pdfwrite 设备不知道原始 PDF 对象中调用的字体。它确实知道被定义的字体被称为 Cairo-0-0,所以它在发出它时就是这样调用的字体。

    坦率地说,这是来自开罗的另一个糟糕的例子,为了将每个页面定义为是否包含透明度,Font 对象中的 FontNamesupposed 与字体流中的名称。

    很明显,FontName 已被更改,考虑到那里的其余样板。

    【讨论】:

    • 很棒的解释。感谢那!我有一种感觉 libcairo 参与了这个问题,但只是无法弄清楚,inkscape 在首先生成 pdf 时实际上使用了它。您会看到在 FontFile 流中修复字体名称的简单方法吗?您使用什么工具从 pdf 文件中读取蒸汽?
    • 我使用 MuPDF(另一个 Artifex 产品)解压缩原始 PDF 文件,并让 Ghostscript 使用 -dCompressPages=false 和 -dCompressFonts=false 写出自己的 PDF 文件。之后,它只是一个阅读内容的编辑器。您“修复”问题的唯一希望是将字体流中的 /FontName 放回 Nimbus .... 但这不是一项简单的任务。首先,您需要解压缩文件,然后编辑字体流,然后(因为 PDF 是带有外部参照的二进制格式)使用 MuPDF 修复编辑的文件(mutool clean)。 GS 无法处理现有的 PDF 文件。
    • 好的,我明白了。谢谢你的解释。他们非常有帮助!
    猜你喜欢
    • 1970-01-01
    • 2013-12-26
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多