7

简而言之,我正在处理一个有问题的 PDF,它:

  • evince由于缺少字体信息,无法在文档查看器中完全呈现;
  • 但是 -ghostscript可以完全呈现​​相同的 PDF。

因此——不管用什么ghostscript来填补空白(可能是备用字形,或访问字体的不同方法)——我希望能够用来ghostscript生成(“蒸馏”)输出 PDF,其中几乎除了添加字体信息外,什么都不会改变,因此evince可以以相同的方式呈现相同的文档ghostscript

因此,我的问题是——这有可能吗?如果是这样,命令行是什么来实现这样的目标?

非常感谢您的任何答案,
干杯!


细节:

我实际上使用的是较旧的 Ubuntu 10.04,我可能遇到了 - 不是错误 - 而是安装问题evince(缺少poppler-data软件包),如错误 #386008 “由于“未知字体标签而无法显示某些字体”中所述。 ..”:错误:“poppler”包:Ubuntu

但是,这正是我想要处理的,所以我将使用该fontspec.pdf帖子的附件(PDF 触发错误。 ”,// v.)来演示问题。

evince

首先,我打开这个 pdf 的第 3 页evince;并evince抱怨:

$ evince --page-label=3 fontspec.pdf

Error: Missing language pack for 'Adobe-Japan1' mapping
Error: Unknown font tag 'F5.1'
Error (7597): No font in show
Error: Unknown font tag 'F5.1'
Error (7630): No font in show
Error: Unknown font tag 'F5.1'
Error (7660): No font in show
Error: Unknown font tag 'F5.1'
...

渲染看起来像这样:

evince-pdf-missfont-render.png

...很明显,缺少一些字体形状。

土坯acroread

只需说明 Adob​​e 的 Acrobat Reader for Linux 的行为方式;以下命令行:

$ ./Adobe/Reader9/bin/acroread /a "page=3" fontspec.pdf

... 不会向终端生成任何输出(有关/a开关的更多信息,请参阅手册页 acroread)——并且程序显示字体绝对没有问题。

另外,虽然我想避免往返于 postscript - 但是,请注意它acroread本身可用于将 PDF 转换为 postscript:

$ ./Adobe/Reader9/bin/acroread -v
9.5.1

$ ./Adobe/Reader9/bin/acroread -toPostScript \ 
-rotateAndCenter -choosePaperByPDFPageSize \
-start 3 -end 3 \
-level3 -transQuality 5 \
-optimizeForSpeed -saveVM \
fontspec.pdf ./ 

同样,上面的命令行不会向终端生成任何输出;-optimizeForSpeed -saveVM在那里,因为显然他们处理字体;最后一个参数./是输出目录(输出文件被自动调用fontspec.ps)。

现在,evince 可以在输出中显示以前丢失的字体fontspec.ps- 但再次抱怨:

$ evince fontspec.ps 
GPL Ghostscript 9.02: Error: Font Renderer Plugin ( FreeType ) return code = -1
GPL Ghostscript 9.02: Error: Font Renderer Plugin ( FreeType ) return code = -1
...

...此外,所有文本似乎都在后记中被展平为曲线 - 所以现在无法再选择 .ps 文件中的文本evince(请注意,.ps 文件无法在 中打开acroread)。但是,可以再次将此 .ps 转换回 .pdf:

$ pstopdf fontspec.ps   # note, `pstopdf` has no output filename option;
                        # it will automatically choose 'fontspec.pdf',
                        # and overwrite previous 'fontspec.pdf' in 
                        # the same directory 

...现在输出中的文本pstopdf可以在 中选择evince,所有字体都在那里,evince不再抱怨。但是,正如我所指出的,我想完全避免往返于 postscript 文件。

display(来自imagemagick

imagemagick我们还可以使用s观察同一文档中的页面display请注意,使用 'display' 从命令行进行图像平移显然仍然不可用,因此我在-crop下面使用来调整视口):

$ display -density 150 -crop 740x450+280+200 fontspec.pdf[2]
   **** Warning: considering '0000000000 00000 n' as a free entry.
...
   **** This file had errors that were repaired or ignored.
   **** The file was produced by: 
   **** >>>> Mac OS X 10.5.4 Quartz PDFContext <<<<
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe's published PDF
   **** specification.

...这会产生一些ghostscripish 错误 - 结果如下:

imagemagick-显示-pdf.png

...很明显,evince无法渲​​染的缺失字体现在正确显示在此处,并带有imagemagicks display

ghostscript

最后,我们可以使用 ghostscript 作为 x11 查看器本身——观察相同的页面、相同的文档:

$ gs -sDevice=x11 -g740x450 -r150x150 -dFirstPage=3 \
-c '<</PageOffset [-120 520]>> setpagedevice' \
-f fontspec.pdf

GPL Ghostscript 9.02 (2011-03-30)
Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
Processing pages 3 through 74.
Page 3
>>showpage, press <return> to continue<<
^C

...以及此输出的结果:

ghostscript-pdf-view.png

 

总之:(ghostscript显然通过扩展,imagemagick)似乎可以找到丢失的字体(或至少对其进行一些替换),并使用该字体呈现页面 - 即使evince对于同一文档失败。

因此,我只想从 中导出 PDF 版本ghostscript,该版本仅嵌入缺少的字体,没有其他处理;所以我试试这个:

$ gs -dBATCH -dNOPAUSE -dSAFER  \
-dEmbedAllFonts -dSubsetFonts=true -dMaxSubsetPct=99 \
-dAutoFilterMonoImages=false \
-dAutoFilterGrayImages=false \
-dAutoFilterColorImages=false \
-dDownsampleColorImages=false \
-dDownsampleGrayImages=false \
-dDownsampleMonoImages=false \
-sDEVICE=pdfwrite \
-dFirstPage=3 -dLastPage=3 \
-sOutputFile=mypg3out.pdf -f fontspec.pdf

GPL Ghostscript 9.02 (2011-03-30)
Copyright (C) 2010 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
   **** Warning: considering '0000000000 00000 n' as a free entry.
Processing pages 3 through 3.
Page 3

   **** This file had errors that were repaired or ignored.
   **** The file was produced by:
   **** >>>> Mac OS X 10.5.4 Quartz PDFContext <<<<
   **** Please notify the author of the software that produced this
   **** file that it does not conform to Adobe's published PDF
   **** specification.

...但它不起作用 - 输出文件遇到与前面提到 mypg3out.pdf的完全相同的问题。evince

注意:虽然我想避免 postscript 往返,但gs这里有一个从 pdf 到 ps 的带有字体嵌入的命令行的好例子:(#277826) pdf - 如何使 GhostScript PS2PDF 停止子集字体;但是 .pdf 到 .pdf 的相同命令行切换似乎对上述问题没有任何影响。

4

2 回答 2

3

是的,我对此有更深入的了解(但不完全) - 所以我会在这里发布部分答案/评论。

本质上,这不是 PDF 中字体嵌入的问题——这是字体映射的问题。

为了证明这一点,让我们分析OPmypg3out.pdf中提取的gs(来自fontspec.pdf文档的第 3 页):

$ pdffonts mypg3out.pdf 
name                                 type              emb sub uni object ID
------------------------------------ ----------------- --- --- --- ---------
Error: Missing language pack for 'Adobe-Japan1' mapping
CAAAAA+Osaka-Mono-Identity-H         CID TrueType      yes yes yes     19  0
GBWBYF+CMMI9                         Type 1C           yes yes yes     28  0
FDFZUN+Skia-Regular_wght13333_wdth11999 TrueType          yes yes yes     16  0
ZRLTKK+Optima-Regular                TrueType          yes yes yes     30  0
ZFQZLD+FPLNeu-Bold                   Type 1C           yes yes yes      8  0
DDRFOG+FPLNeu-Italic                 Type 1C           yes yes no      22  0
HMZJAO+FPLNeu-Regular                Type 1C           yes yes yes     10  0
RDNKXT+FPLNeu-Regular                Type 1C           yes yes yes     32  0
GBWBYF+Skia-Regular_wght13333_wdth11999 TrueType          yes yes no      26  0

如输出所示 - 所有字体确实是嵌入;所以还有别的问题。(要完整地观察这一点会更加困难fontspec.pdf,因为那里有大量的字体和大量的错误消息。

这里的关键点(我认为)是:

  • 只有一个“ Error: Missing language pack for 'Adobe-Japan1' mapping”消息;和
  • 只有一种CID TrueType字体,即CAAAAA+Osaka-Mono-Identity-H

CID TrueType和“Adobe-Japan1”映射错误之间似乎有明显的关系;我终于通过CID 字体澄清了这一点 - 如何使用 Ghostscript

CID 字体是包含大量字形的 PostScript 资源(例如,远东语言的字形、中文、日文和韩文)。有关详细信息,请参阅 PostScript 语言参考,第三版。

CID 字体资源是一种不同于字体的 PostScript 资源。特别是,它们不能用作常规字体。CID 字体资源必须先与定义字形的特定代码的 CMap 资源组合,然后才能用作字体。这允许重复使用具有不同编码的字形集合。

一切都好——除了这里我们处理的是 PDF 字体,而不是 PostScript 字体;让我们稍微演示一下。

例如,5.3。Using Ghostscript To Preview Fonts - Making Fonts Available to Ghostscript - Font HowTo描述了如何使用 Ghostscript 安装的脚本prfont.ps来渲染字体表。

但是,在这里只需列出 Ghostscript 字体 [gs-devel]并使用resourcestatus 运算符查询特定字体会更容易——这不需要特殊的 .ps 脚本:

$ gs -o /dev/null -dNODISPLAY -f mypg3out.pdf \
-c 'currentpagedevice (*) {=} 100 string /Font resourceforall'
...
Processing pages 1 through 1.
Page 1
URWAntiquaT-RegularCondensed
Palatino-Italic
Hershey-Gothic-Italian
...

$ gs -o /dev/null -dNODISPLAY -f mypg3out.pdf \
-c '/TimesNewRoman findfont pop [/TimesNewRoman /Font resourcestatus]'
....
Processing pages 1 through 1.
Page 1
Can't find (or can't open) font file /usr/share/ghostscript/9.02/Resource/Font/TimesNewRomanPSMT.
Can't find (or can't open) font file TimesNewRomanPSMT.
Can't find (or can't open) font file /usr/share/ghostscript/9.02/Resource/Font/TimesNewRomanPSMT.
Can't find (or can't open) font file TimesNewRomanPSMT.
Querying operating system for font files...
Loading TimesNewRomanPSMT font from /usr/share/fonts/truetype/msttcorefonts/times.ttf... 2549340 1142090 3496416 1237949 1 done.

我们得到了一个字体列表;但是,这些是可用的系统字体ghostscript-不是嵌入在 PDF 中的字体!

基本上,

  • gs -o /dev/null -dNODISPLAY -f mypg3out.pdf -c 'currentpagedevice (*) {=} 100 string /Font resourceforall' | grep -i osaka不会返回任何内容,并且
  • -c '/CAAAAA+Osaka-Mono-Identity-H findfont pop [/CAAAAA+Osaka-Mono-Identity-H /Font resourcestatus]'将以“在系统上未找到此字体!将字体 Courier 替换为 CAAAAA+Osaka-Mono-Identity-H。 ”结束。)

要列出 PDF 中的字体,可以使用Ghostscript 中的pdf_info.ps 脚本文件未安装,在源代码中):

$ wget "http://git.ghostscript.com/?p=ghostpdl.git;a=blob_plain;f=gs/toolbin/pdf_info.ps" -O pdf_info.ps

$ gs -dNODISPLAY -q -sFile=mypg3out.pdf -dDumpFontsNeeded pdf_info.ps
...
No system fonts are needed.

$ gs -dNODISPLAY -q -sFile=mypg3out.pdf -dDumpFontsUsed -dShowEmbeddedFonts pdf_info.ps
...
Font or CIDFont resources used:
CAAAAA+Osaka-Mono
DDRFOG+FPLNeu-Italic
FDFZUN+Skia-Regular_wght13333_wdth11999
GBWBYF+CMMI9
GBWBYF+Skia-Regular_wght13333_wdth11999
GTIIKZ+Osaka-Mono
HMZJAO+FPLNeu-Regular
RDNKXT+FPLNeu-Regular
ZFQZLD+FPLNeu-Bold
ZRLTKK+Optima-Regular

所以最后我们可以CAAAAA+Osaka-Mono在 Ghostscript 中观察 - 虽然我不知道如何从内部查询有关它的更具体信息ghostscript

 

最后,我想我的问题归结为:如何ghostscript使用,将字形从 CID 嵌入字体映射到具有不同“编码”(或“字符映射”?)的字体,这不需要额外的语言文件?

附录

我也尝试过这些方法:

  • pdffonts此处的输出不会列出大阪单声道,但仍会抱怨“错误:缺少'Adobe-Japan1'映射的语言包”:
    $ wget http://whalepdfviewer.googlecode.com/svn/trunk/cmaps/japanese/Adobe-Japan1-UCS2 
    $ gs -sDEVICE=pdfwrite -o mypg3o2.pdf -dBATCH -f mypg3out.pdf Adob​​e-Japan1-UCS2
  • 与以前相同 - 这(通过 Ghostscript 的“Use.htm”)也使大阪单声道从pdffonts列表中消失:
    gs -sDEVICE=pdfwrite -o mypg3o2.pdf -dBATCH \
    -c '/CIDSystemInfo << /Registry (Adobe) /Ordering (Unicode) /Supplement 1 >>' \
    -f mypg3out.pdf
  • 这崩溃了Error: /undefinedresource in findresource
    gs -sDEVICE=pdfwrite -o mypg3o2.pdf -dBATCH \
    -c '/Osaka-Mono-Identity-H /H /CMap findresource [/Osaka-Mono-Identity /CIDFont findresource] == ' \
    -f mypg3out.pdf

最后请注意,某些 .ps 脚本ghostscript会安装,它可能会自动使用;例如,您可以找到gs_ttf.ps

$ locate gs_ttf.ps
/usr/share/ghostscript/9.02/Resource/Init/gs_ttf.ps

...然后使用,您可以在代码开头添加语句;然后每当调用上述命令之一时,打印输出将在标准输出中可见。sudo nano locate gs_ttf.ps(Hello from gs_ttf.ps\n) printgs

参考

于 2012-06-19T07:52:48.733 回答
3

确定点1;您不能使用 Ghostscript 和 pdfwrite 来创建 PDF 文件“无需任何额外处理”。

pdfwrite 和 Ghostscript 的工作方式是完全解释传入的数据(PostScript、PDF、XPS、PCL 等),创建一系列图形基元,然后将其传递给 pdfwrite 设备。pdfwrite 设备然后将这些重新组合成一个全新的 PDF 文件。

因此,不可能将 PDF 文件作为输入并对其进行操作,它总是会创建一个新文件。

现在,我建议您先将 9.02 Ghostscript 升级到 9.05。丢失的 CIDFonts 在 9.05 中得到了更好的处理(今年晚些时候将在 9.06 中进一步改进)。(您缺少的“Osaka Mono”字体实际上是 CIDFont,而不是常规字体)

使用当前最前沿的 Ghostscript 代码为我生成了一个 PDF 文件,其中嵌入了缺失的字体。我不知道这是否对您有用,因为我的 evince 副本可以完美地呈现原始文件。

稍后添加

检查原始 PDF 文件,我发现确实嵌入了字体(正如我所料,因为它们是子集)。所以实际上正如您在上面自己的答案中所说,问题不在于字体嵌入,而在于 CIDFonts 的使用。

我在这里的回答对你没有帮助,因为 pdfwrite 仍然会在输出中产生一个 CIDFont 。基本上,这是您的版本或 evince 安装中的缺陷。

“重新映射”字符的问题在于字体限制为 256 个字形,而 CIDFont 实际上没有限制。所以没有办法将 CIDFont 放入 Font 中。这样做的唯一方法是创建多个字体,每个字体都包含原始字体的一部分,然后根据需要在它们之间切换。缓慢而笨拙。

如果您使用 ps2write 设备转换为 PostScript,那么它将为您执行此操作,但您面临很大的风险,即在此过程中它将矢量字形数据转换为位图,这将无法很好地缩放。

从根本上说,您无法使用 Ghostscript 或实际上使用我知道的任何其他工具来真正实现您想要做的事情(将 1 CIDFont 转换为 N 个常规字体)。虽然它在技术上是可行的,但没有真正意义,因为所有 PDF 消费者都应该能够处理 CIDFonts。如果他们不能,那么它是 PDF 消费者中的一个错误。

于 2012-06-19T08:08:10.170 回答