5

我想使用 Rails 在现有 PDF 上添加文本,所以我这样做了:

filename = "#{Rails.root}/app/assets/images/sample.pdf"
Prawn::Document.generate("#{Rails.root}/app/assets/images/full_template.pdf", :template => filename) do
  text "Test", :align => :center
end

当我打开 full_template.pdf 时,我有我的模板 PDF + 我的文本“测试”,但是这个文本写的方向不好,就好像我的文本是用镜子写的一样。

您可以在此处找到两个 PDF 文档:

原文: http ://www.sebfie.com/wp-content/uploads/sample.pdf

生成: http ://www.sebfie.com/wp-content/uploads/full_template.pdf

4

2 回答 2

9

让我们看看... [切换到 PDF 调试模式]

首先,我在 的帮助下解压缩您的full_template.pdfqpdf ,这是一个命令行实用程序“对 PDF 文件进行结构性、内容保留的转换”(自我描述):

qpdf --qdf full_template.pdf qdf---test.pdf

结果,qdf---test.pdf现在更容易在普通文本编辑器中分析,因为所有流都已解包。

搜索字符串“est”会找到这一行:

[(T) 120 (est)] TJ

再多打探一下(看看qpdf's 非常有用的评论散布在它的输出中!)我们发现:在原始 PDF 中出现镜像字符串“Test”的 PDF 对象是数字 22。它是一个完全独立的对象文件的其余部分,它也是唯一一个使用非嵌入式 Helvetica 字体的文件。

因此,让我们将其与原始文件分开提取:

qpdf --show-object=22 --filtered-stream-data full_template.pdf 

 q
 /DeviceRGB cs
 0.000 0.000 0.000 scn
 /DeviceRGB CS
 0.000 0.000 0.000 SCN
 1 w
 0 J
 0 j
 [ ] 0 d

 BT
 286.55 797.384 Td
 /F3.0 12 Tf
 [<54> 120 <657374>] TJ
 ET

 Q

好的,这里这件作品[(T) 120 (est)] TJ显示为[<54> 120 <657374>] TJ。我们在命令的帮助下验证了这一点,它为ascii我们打印了一个漂亮的 ASCII <-> Hex 表。该表证实:

T  54
e  65
s  73
t  74

其他运营商是什么意思?我们在官方ISO 32000 PDF-1.7 规范附件 A“操作员摘要”中查找它们。在这里,我们找到以下信息:

 q   : gsave
 Q   : grestore
 cs  : setcolorspace for nonstroking ops
 CS  : setcolorspace for stroking ops
 scn : setcolor for nonstroking ops
 SCN : setcolor for stroking ops
 w   : setlinewidth
 j   : setlinejoin
 J   : setlinecap
 d   : setdash
 BT  : begin text object
 Td  : move text position
 Tf  : set text font and size
 TJ  : show text allowing individual glyph positioning
 Tj  : show text
 ET  : end text object

目前没有什么可疑的...

但是,查看原始页面内容出现的另一个对象(对象编号 5),我们发现了一个不同之处。例如:

1 0 0 -1 -17.2308 -13.485 Tm
<0013001c001200130018001200140015> Tj

Tj在这里,在(显示文本)的每个单个操作之前,Tm操作符(这是什么?!?)在起作用。让我们也查看一下TmPDF 规范:

 Tm  : set text matrix and text line matrix

然而奇怪的是,这个矩阵使用1 0 0 -1(而不是更常见的1 0 0 1)。这导致文本的上下镜像。

等一下!?!

原文本内容用镜像文本矩阵描边,但还是显示正常??但是您添加的文本不使用自己的任何文本矩阵,而是出现镜像?到底是怎么回事?!

我现在不打算追查它了。然而,我的假设是,在原始 PDF 的内脏中,创作软件定义了一个“扩展图形状态”,默认情况下会镜像所有描边操作。

看来你没有做错任何事,塞巴斯蒂安——你只是不走运地选择了一个测试对象,并且幸运地得到了一个相当奇怪的对象。试试吧,先用其他一些 PDF 继续你的“Prawn”实验......

可以通过替换qdf---test.pdf中的这一行来“修复”您的full_template.pdf

286.55 797.384 Td

通过这个:

1 0 0 -1 286.55 797.384 Tm

然后运行最后一个qdf命令来修复(现在被我们的编辑损坏)PDF交叉引用表和流长度:

qpdf qdf---test.pdf full_template---fixed.pdf

控制台输出将显示你想要它:

  WARNING: qdf---test.pdf: file is damaged
  WARNING: qdf---test.pdf (file position 151169): xref not found
  WARNING: qdf---test.pdf: Attempting to reconstruct cross-reference table
  WARNING: qdf---test.pdf (object 8 0, file position 9072): attempting to recover stream length
  qpdf: operation succeeded with warnings; resulting file may have some problems

“固定”PDF 将显示未镜像的文本。

于 2012-08-23T10:06:10.757 回答
1

我的拉取请求已合并,因此问题现在已在prawn-templatesgem 中修复。修复是在向 PDF 添加任何内容之前重置图形状态。

发生这种情况是因为 Google Chrome 和 Google Docs 导出 PDF 时带有一个垂直翻转所有内容的转换矩阵。默认情况下,PDF 从左下角呈现。Google 的自定义转换意味着他们可以从 PDF 的左上角计算坐标,这对我来说确实更有意义。

PS 非常感谢@KurtPfeifle 非常有帮助的答案!如果没有这些信息,我不会走到这一步。

于 2017-10-03T10:57:35.997 回答