我想在使用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
让我们来看看...... [切换成PDF调试模式。
首先,我解开你的full_template.pdf的帮助下qpdf
,一个命令行实用程序“做结构,内容保留在PDF文件转换”(自我介绍):
qpdf --qdf full_template.pdf qdf---test.pdf
结果,QDF ---检验.pdf现在更容易在一个普通的文本编辑器来分析,因为所有的数据流进行解压缩。
搜索字符串“EST”找到我们这一行:
[(T) 120 (est)] TJ
周围多一点戳(看着qpdf
!的洒入其输出非常有益的意见),我们发现这一点:在您的镜像字符串‘Test’出现在原始PDF 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
< - >六角table命令,打印我们一个很好的ASCII。 该表证实:
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
操作( 这是什么?!?)在起作用。 我们还要仰望Tm
在PDF规格:
Tm : set text matrix and text line matrix
什么是奇怪然而,就是这个矩阵使用1 0 0 -1
(而不是更常见的1 0 0 1
)。 这导致上下倒置镜像文本。
等一下!?!
原文内容抚摸与镜像文本矩阵,但仍显示正常? 但你添加的文本不使用任何自己的文本矩阵,但似乎反映? 到底是怎么回事?!
我不打算现在追查下来更多。 我的假设然而,在原始PDF的胆量某处,创作软件定义“扩展的图形状态”,这会导致所有抚摸操作被默认镜像。
看来你没有做错任何事,塞巴斯蒂安-你只是不走运与您所选择的测试对象,并用相当怪异的一个祝福得到。 试试吧继续你的“虾”实验与一些其他的PDF文件第一...
人们可以通过替换QDF ---这个检验.pdf行“修理”你full_template.pdf:
286.55 797.384 Td
本之一:
1 0 0 -1 286.55 797.384 Tm
然后运行最后qdf
命令修复(现在我们的编辑损坏)PDF交叉引用表和流lenghts:
qpdf QDF ---检验.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将显示文本非镜像。
我拉入请求已经被合并 ,所以现在的问题是固定在prawn-templates
宝石。 整个解决方案添加任何内容到PDF之前重置图形状态。
这是发生,因为谷歌Chrome和谷歌文档导出PDF文件使用一个转换矩阵,垂直翻转的所有内容。 默认情况下,PDF文件是从左下角呈现。 谷歌的自定义转换意味着他们可以从PDF的左上角,这确实让我更有意义计算坐标。
PS非常感谢@KurtPfeifle了非常有用的答案! 我也不会走到这一步没有这些信息。