如何在不将字体转换为轮廓的情况下将 cairo-pdf 转换为 eps
Posted
技术标签:
【中文标题】如何在不将字体转换为轮廓的情况下将 cairo-pdf 转换为 eps【英文标题】:How to convert a cairo-pdf to eps without converting fonts to outlines 【发布时间】:2017-05-25 11:33:57 【问题描述】:我们使用 cairo 编写 pdf 文件。结果很棒,文件是可编辑的,因此我们可以通过复制和粘贴来提取文本,甚至可以在 Adobe Illustrator 和 Inkscape 中打开和编辑文件以更改字体属性。
但是,一旦我们将 PDF 转换为 EPS,所有字体都会转换为轮廓。
我最喜欢的工具是 pdftops 和 gs,这是我尝试过的方式:
gs -sDEVICE=eps2write -dLanguageLevel=3 -dEmbedAllFonts=true -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.eps input.pdf
和
pdftops -eps -level3 input.pdf output.eps
此外,我通过命令行尝试了 ps2eps、ps2epsi、epspdf 和 Inkscape,但结果始终相同,所有字体都转换为轮廓。
我们正在使用 Dejavu 字体,字体嵌入似乎没问题:
$ pdffonts input.pdf
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
JTFVDF+DejaVuSans-Bold TrueType WinAnsi yes yes yes 5 0
BTWYHK+DejaVuSansCondensed-Bold TrueType WinAnsi yes yes yes 6 0
VIBPBS+DejaVuSans-Oblique TrueType WinAnsi yes yes yes 7 0
TKGUZX+DejaVuSansCondensed TrueType WinAnsi yes yes yes 8 0
知道如何生成带有可编辑字体的 EPS 文件吗?
这是我的文件:https://www.dropbox.com/s/11afckra7i8trdq/input.pdf?dl=0
【问题讨论】:
【参考方案1】:Ghostscript 的 eps2write 设备不会将字体转换为轮廓。顺便说一句,您怎么知道字体正在转换为轮廓?
我将获取您提供的示例文件(赞!很多人不这样做)并很快回来报告,我可以想到两种可能性:
文件包含透明度。 Cairo 有一种创建 PDF 文件的习惯,其中包含实际上不执行任何操作的透明度操作(例如将 alpha 设置为 100%)。您无法在 PostScript 中表示 PDF 的透明度,因此整个页面都会呈现为图像。 该文件是在文本呈现模式 3(既不是描边也不是填充)中顶部带有文本的图像(或类似文件)。尽管实际文本是不可见的,但 Acrobat 和其他应用程序通常允许您剪切/粘贴它。但是,PostScript 没有执行此操作的模式,并且由于文本不做任何标记,因此通常会被丢弃。[稍后]
嗯,复杂的文件。解压后大于 11 MB....
无论如何,页面在透明组中:
9 0 obj
<<
/Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 720 720 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/I true
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
但是看起来 Ghostscript 决定透明度可以被丢弃,因为页面不是一个完整的位图。
我弄出来的eps文件没有把字体转成轮廓,它嵌入了完整的字体,它使用它们,例如:
8 0 obj
<</BaseFont/ENTCOM+DejaVuSansCondensed-Bold/FontDescriptor 9 0 R/Type/Font
/FirstChar 32/LastChar 220/Widths[
313 0 0 0 0 0 0 0 0 0 0 0 0 374 0 0
0 0 0 0 0 626 626 626 0 0 0 0 0 0 0 0
0 696 686 660 747 615 615 738 753 334 0 697 573 896 753 765
659 765 693 648 614 730 696 993 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 730]
/Encoding 20 0 R/Subtype/TrueType>>
endobj
%%EndResource
9 0 obj
<</Type/FontDescriptor/FontName/ENTCOM+DejaVuSansCondensed-Bold/FontBBox[-362 -176 964 927]/Flags 4
/Ascent 745
/CapHeight 745
/Descent -176
/ItalicAngle 0
/StemV 144
/MissingWidth 540
/FontFile2 17 0 R>>
endobj
%%EndResource
%%BeginResource: file (PDF FontFile obj_17)
17 0 obj
<</Filter/ASCII85Decode
/Length1 6088/Length 7019>>stream
!!*'"!"ApY!!<3t:K&o%z!!!e-!!!""@r5Xnz!!!\J!!!)-@s2r:5.NBR!!!#S!!!("AoMC">68U0
!!!*T!!!##B5Dj*z!!!DJ!!!86BOtU_%6ag,!!!gs!!!!WBP:sc%JC""!!!,V!!!!EBPhj9z!!!f0
.....
Lots of data omitted
.....
!!)s8!!<3$zzzzzzz!!*'"!!6K:Z*:FC?Oo9l!$;IHze&!X4ze&!X4peC[h%QOi,!!*'*zz~>
endstream
endobj
原来是TrueType字体,后面会用到:
10 0 0 10 0 0 cm BT
/R8 12.96 Tf
1 0 0 1 262.795 318.916 Tm
[(N)1(E)1(US)0.998415(T)79.0063(ADT)1.00218]TJ
126.609 339.675 Td
[(F)1(IN)1.00218(DO)0.998415(R)1.00218(F)0.998415(F)1.00218]TJ
-338.998 -203.387 Td
[(W)1(O)1(L)166.005(T)1(M)1(E)1(R)1(S)1(H)1(A)29.9863(US)1(E)1(N)1]TJ
373.499 -12.6809 Td
[(M)0.998415(IT)-21.9915(T)0.998415(E)1.00218]TJ
ET
可能您使用的是旧版本,我使用的是当前版本 9.21。如果没有一个明显的问题是'你为什么认为字体是轮廓?'
【讨论】:
感谢您的检查!我认为字体已转换的原因很简单,因为我无法再在 Inkscape 或 Illustrator 中编辑它们。我只能看到轮廓,无法编辑文本。 :( 也许这是 Inkscape 和 Illustrator 解释代码的问题?! KenS,您是否有 Inkscape 或 Illustrator 来检查您是否可以编辑未对齐到弯曲路径的文本元素? 刚刚检查了我的版本,它是 9.21。 我没有 Illustrator 或 Inkscape,不,抱歉。 PDF 不是一种可编辑的格式,PostScript 更不用说,EPS 专门不要被编辑。我猜它缺少 ToUnicode CMap,或者可能是输出字体是子集并重新排列的事实。不过,您必须询问这些应用程序的开发人员。您明显的解决方案是在创建 EPS 文件之前进行任何编辑。我确信 EPS 文件没有将字体转换为轮廓,它们仍然是字体。 好的,我会检查一下并提供反馈。非常感谢您的支持!以上是关于如何在不将字体转换为轮廓的情况下将 cairo-pdf 转换为 eps的主要内容,如果未能解决你的问题,请参考以下文章
有啥方法可以在不将 CIImage 转换为 UIImage 或 CGImage 的情况下将 CIImage 转换为 NSData?
有没有办法在不将完整文件加载到内存的情况下将 tiff 图像转换为 Base64
如何在不将图像保存在本地的情况下将捕获的图像(Surface View)传递给另一个片段?
如何在不将您的应用设为默认消息应用的情况下将短信发送到 android 中的特定应用?
我们如何在不将 ViewController 对象推入其中的情况下将对象分配给 `UINavigationController`。