关于PDF

时间:2016-06-24 03:54:17

标签: pdf pdfbox

我对PDF中的当前转换矩阵(CTM)有一些疑惑。对于this PDF中的第5页,我检查了令牌流(http://pastebin.com/k6g4BGih),并显示了cm命令将转换矩阵设置为{{1}之前的最后一次curve (c)操作}}。完整输出位于http://pastebin.com/9XaPQQm9

接下来,我使用以下一组代码从related SO question

中提供的代码@mkl后的同一页面中提取line和curve命令
  1. 主要课程:http://pastebin.com/htiULanR
  2. 助手班:

    一个。扩展COSInt{10},COSInt{0},COSInt{0},COSInt{10},COSInt{0},COSInt{0}的类:http://pastebin.com/zL2p75ha

    PDFGraphicsStreamEnginehttp://pastebin.com/d3vXCgnC

    ℃。 Pathhttp://pastebin.com/CxunHPiZ

    d。 Subpathhttp://pastebin.com/XP1Dby6U

    Segmenthttp://pastebin.com/fNtHNtws

    F。 Rectanglehttp://pastebin.com/042cgZBp

    克。 Linehttp://pastebin.com/wXbXZdqE

  3. 在该代码中,我使用从Curve类重写的getGraphicsState().getCurrentTransformationMatrix()方法中的curveTo()打印了CTM。这表明CTM为PDFGraphicsStreamEngine。所以我的问题是:

    1. 这两个CTM不一样吗?

    2. 这两个CTM都有缩放操作:第一个以10倍的比例缩放,第二个以0.1的比例缩放。如果我忽略缩放,我可以创建an SVG,它看起来非常接近原始PDF。但我很困惑为什么会这样。我需要考虑[0.1,0.0,0.0,0.1,0.0,0.0]而不是最后一个吗?

1 个答案:

答案 0 :(得分:4)

首先:你说

  

cm命令将转换矩阵设置为curve (c)之前的最后一次COSInt{10},COSInt{0},COSInt{0},COSInt{10},COSInt{0},COSInt{0}操作。

这是不正确的, cm 不会将变换矩阵设置到参数值,但矩阵参数与前者当前相乘转换矩阵并将结果设置为新的当前转换矩阵,该过程也称为连接。因此:

  
      
  1. 这两个CTM不应该相同吗?
  2.   

不,因为 cm 未设置,它会连接!

此外,当前转换矩阵(以及所有其他图形状态值!)不仅由显式setter或连接符指令更改,还由当前忽略的还原状态指令更改。因此:

  
      
  1. 我是否需要在路径之前考虑所有转换矩阵而不是最后一个转换矩阵?
  2.   

您可能需要考虑的不仅仅是最后一个,而只考虑那些未被图形状态恢复所取消的那些。

让我们看看你的示例文档......

当您想要跟踪当前的转换矩阵时,您必须同时检查 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是正确的:

  

我在getGraphicsState().getCurrentTransformationMatrix()类中覆盖的curveTo()方法中使用PDFGraphicsStreamEngine打印了CTM。这表明CTM为[0.1,0.0,0.0,0.1,0.0,0.0]