关于 PDF 中当前变换矩阵的困惑
Confusion about current transformation matrix in a PDF
我对 PDF 中的当前转换矩阵 (CTM) 感到有些困惑。对于 this PDF, I have examined the Token Stream (http://pastebin.com/k6g4BGih) and that shows the last cm
operation before the curve (c)
commands sets the transfomration matrix to COSInt{10},COSInt{0},COSInt{0},COSInt{10},COSInt{0},COSInt{0}
. The full output is at http://pastebin.com/9XaPQQm9 中的第 5 页。
接下来我使用下面的一组代码从同一页面中提取直线和曲线命令,遵循
中提供的代码@mkl
- 主要 class: http://pastebin.com/htiULanR
助手 classes:
一个。 Class 扩展了 PDFGraphicsStreamEngine
:http://pastebin.com/zL2p75ha
b。 Path
: http://pastebin.com/d3vXCgnC
c。 Subpath
: http://pastebin.com/CxunHPiZ
d。 Segment
: http://pastebin.com/XP1Dby6U
e。 Rectangle
: http://pastebin.com/fNtHNtws
f。 Line
: http://pastebin.com/042cgZBp
克。 Curve
: http://pastebin.com/wXbXZdqE
在该代码中,我在 curveTo()
方法中使用 getGraphicsState().getCurrentTransformationMatrix()
打印了 CTM,该方法被 PDFGraphicsStreamEngine
class 覆盖。这将 CTM 显示为 [0.1,0.0,0.0,0.1,0.0,0.0]
。所以我的问题是:
这两个CTM不应该一样吗?
这两个 CTM 都有缩放操作:第一个缩放系数为 10,第二个缩放系数为 0.1。如果我忽略缩放比例,我可以创建看起来非常接近原始 PDF 的 an SVG。但我很困惑为什么会发生这种情况。我需要考虑 all transformation matrices before the path
而不是最后一个吗?
首先:你说
the last cm
operation before the curve (c)
commands sets the transfomration matrix to COSInt{10},COSInt{0},COSInt{0},COSInt{10},COSInt{0},COSInt{0}
.
这是不正确的,cm 没有设置 转换矩阵到参数值但是它乘矩阵参数和前一个当前变换矩阵,并将结果设置为新的当前变换矩阵,这个过程也称为级联。因此:
- Shouldn't these two CTMs be the same?
不是,因为cm没有设置,是拼接的!
此外,当前变换矩阵(以及所有其他图形状态值!)不仅会被显式 setter 或连接符指令更改,还会被您当前忽略的恢复状态指令更改。因此:
- Do I need to consider all transformation matrices before the path instead of the last one?
你可能需要考虑比上一个更多的东西,但只考虑那些没有被图形状态恢复撤销的东西。
让我们看看您的示例文档...
当你想跟踪当前的变换矩阵时,你必须同时检查 cm 和 q/Q指令。在第 5 页的情况下,重点关注这些指令的内容流直到第一个 c 曲线指令如下所示:
q 0.1 0 0 0.1 0 0 cm
q
q 10 0 0 10 0 0 cm BT
[...large text object...]
ET Q
Q
q
[...clip path definition...]
q 10 0 0 10 0 0 cm BT
[...small text object...]
ET Q
Q
q
[...new clip path definition...]
0.737761 w
1 i
2086.54 2327.82 m
2088.17 2327.59 2089.82 2327.47 2091.46 2327.47 c
假设起始恒等变换矩阵,这意味着当前当前变换矩阵和图形堆栈中的当前变换矩阵的以下流程:
CTM: 1 0 0 1 0 0
堆栈:空
q
CTM: 1 0 0 1 0 0
堆栈:1 0 0 1 0 0
0.1 0 0 0.1 0 0 cm
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0 / 0.1 0 0 0.1 0 0
10 0 0 10 0 0 cm
CTM: 1 0 0 1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0 / 0.1 0 0 0.1 0 0
BT
[...large text object...]
ET Q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
Q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
[...clip path definition...]
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0 / 0.1 0 0 0.1 0 0
10 0 0 10 0 0 cm
CTM: 1 0 0 1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0 / 0.1 0 0 0.1 0 0
BT
[...small text object...]
ET Q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
Q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
[...new clip path definition...]
0.737761 w
1 i
2086.54 2327.82 m
2088.17 2327.59 2089.82 2327.47 2091.46 2327.47 c
因此,当您观察到 PDFBox 是正确的:
I printed the CTM using getGraphicsState().getCurrentTransformationMatrix()
inside the curveTo()
method that is overridden from PDFGraphicsStreamEngine
class. That shows the CTM as [0.1,0.0,0.0,0.1,0.0,0.0]
我对 PDF 中的当前转换矩阵 (CTM) 感到有些困惑。对于 this PDF, I have examined the Token Stream (http://pastebin.com/k6g4BGih) and that shows the last cm
operation before the curve (c)
commands sets the transfomration matrix to COSInt{10},COSInt{0},COSInt{0},COSInt{10},COSInt{0},COSInt{0}
. The full output is at http://pastebin.com/9XaPQQm9 中的第 5 页。
接下来我使用下面的一组代码从同一页面中提取直线和曲线命令,遵循
- 主要 class: http://pastebin.com/htiULanR
助手 classes:
一个。 Class 扩展了
PDFGraphicsStreamEngine
:http://pastebin.com/zL2p75hab。
Path
: http://pastebin.com/d3vXCgnCc。
Subpath
: http://pastebin.com/CxunHPiZd。
Segment
: http://pastebin.com/XP1Dby6Ue。
Rectangle
: http://pastebin.com/fNtHNtwsf。
Line
: http://pastebin.com/042cgZBp克。
Curve
: http://pastebin.com/wXbXZdqE
在该代码中,我在 curveTo()
方法中使用 getGraphicsState().getCurrentTransformationMatrix()
打印了 CTM,该方法被 PDFGraphicsStreamEngine
class 覆盖。这将 CTM 显示为 [0.1,0.0,0.0,0.1,0.0,0.0]
。所以我的问题是:
这两个CTM不应该一样吗?
这两个 CTM 都有缩放操作:第一个缩放系数为 10,第二个缩放系数为 0.1。如果我忽略缩放比例,我可以创建看起来非常接近原始 PDF 的 an SVG。但我很困惑为什么会发生这种情况。我需要考虑
all transformation matrices before the path
而不是最后一个吗?
首先:你说
the last
cm
operation before thecurve (c)
commands sets the transfomration matrix toCOSInt{10},COSInt{0},COSInt{0},COSInt{10},COSInt{0},COSInt{0}
.
这是不正确的,cm 没有设置 转换矩阵到参数值但是它乘矩阵参数和前一个当前变换矩阵,并将结果设置为新的当前变换矩阵,这个过程也称为级联。因此:
- Shouldn't these two CTMs be the same?
不是,因为cm没有设置,是拼接的!
此外,当前变换矩阵(以及所有其他图形状态值!)不仅会被显式 setter 或连接符指令更改,还会被您当前忽略的恢复状态指令更改。因此:
- Do I need to consider all transformation matrices before the path instead of the last one?
你可能需要考虑比上一个更多的东西,但只考虑那些没有被图形状态恢复撤销的东西。
让我们看看您的示例文档...
当你想跟踪当前的变换矩阵时,你必须同时检查 cm 和 q/Q指令。在第 5 页的情况下,重点关注这些指令的内容流直到第一个 c 曲线指令如下所示:
q 0.1 0 0 0.1 0 0 cm
q
q 10 0 0 10 0 0 cm BT
[...large text object...]
ET Q
Q
q
[...clip path definition...]
q 10 0 0 10 0 0 cm BT
[...small text object...]
ET Q
Q
q
[...new clip path definition...]
0.737761 w
1 i
2086.54 2327.82 m
2088.17 2327.59 2089.82 2327.47 2091.46 2327.47 c
假设起始恒等变换矩阵,这意味着当前当前变换矩阵和图形堆栈中的当前变换矩阵的以下流程:
CTM: 1 0 0 1 0 0
堆栈:空
q
CTM: 1 0 0 1 0 0
堆栈:1 0 0 1 0 0
0.1 0 0 0.1 0 0 cm
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0 / 0.1 0 0 0.1 0 0
10 0 0 10 0 0 cm
CTM: 1 0 0 1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0 / 0.1 0 0 0.1 0 0
BT
[...large text object...]
ET Q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
Q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
[...clip path definition...]
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0 / 0.1 0 0 0.1 0 0
10 0 0 10 0 0 cm
CTM: 1 0 0 1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0 / 0.1 0 0 0.1 0 0
BT
[...small text object...]
ET Q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
Q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0
q
CTM: 0.1 0 0 0.1 0 0
堆栈:1 0 0 1 0 0 / 0.1 0 0 0.1 0 0
[...new clip path definition...]
0.737761 w
1 i
2086.54 2327.82 m
2088.17 2327.59 2089.82 2327.47 2091.46 2327.47 c
因此,当您观察到 PDFBox 是正确的:
I printed the CTM using
getGraphicsState().getCurrentTransformationMatrix()
inside thecurveTo()
method that is overridden fromPDFGraphicsStreamEngine
class. That shows the CTM as[0.1,0.0,0.0,0.1,0.0,0.0]