Java 如何使用pdfbox获取曲线的当前位置和位置

Java 如何使用pdfbox获取曲线的当前位置和位置,java,pdf,pdf-generation,pdfbox,Java,Pdf,Pdf Generation,Pdfbox,我正在尝试使用pdfbox获得一个立方贝塞尔的位置。 我试图截取“c”运算,并试图从列表中提取曲线的参数。首先,当前位置总是(0,0) float x = getGraphicsState().getCurrentTransformationMatrix().getXPosition(); float y = getGraphicsState().getCurrentTransformationMatrix().getYPosition(); 当前变换矩阵始终是单位矩阵。我是否应该执行仿射变换

我正在尝试使用pdfbox获得一个立方贝塞尔的位置。 我试图截取“c”运算,并试图从列表中提取曲线的参数。首先,当前位置总是(0,0)

float x = getGraphicsState().getCurrentTransformationMatrix().getXPosition();
float y = getGraphicsState().getCurrentTransformationMatrix().getYPosition();
当前变换矩阵始终是单位矩阵。我是否应该执行
仿射变换
?但是去哪里呢? 第二个是“c”操作的参数大于页面维度。我应该用x和y尺度来划分它们吗

背景

通过考虑当前的转换矩阵,你做了一件必要的事情,但是还有另一个要考虑的数据,即当前路径的当前点。请参看:

当前正在构建的路径称为当前路径。在PDF中(与PostScript不同),当前路径不是图形状态的一部分,不会与其他图形状态参数一起保存和恢复。PDF路径应严格为内部对象,无显式表示。绘制当前路径后,将不再定义当前路径;在使用mre操作符开始新路径之前,没有当前路径

最近添加到当前路径的线段的尾随端点称为当前点。如果当前路径为空,则当前点应未定义。大多数向当前路径添加段的操作符从当前点开始;如果当前点未定义,则应产生错误

[……]

x1 y1 x2 y2 x3 y3c在当前路径上附加一条三次贝塞尔曲线。曲线 应使用(x1,y1)和(x2,y2)作为贝塞尔控制点(见8.5.2.2,“三次贝塞尔曲线”),从当前点延伸到点(x3,y3)。新的电流点应为(x3,y3)

(第8.5.2节道路施工操作员,第132页)

看看这个

3 0 0 3 300 300 cm
10 0 m
10 5.52 5.52 10 0 10 c
-5.52 10 -10 5.52 -10 0 c
-10 -5.52 -5.52 -10 0 -10 c
5.52 -10 10 -5.52 10 0 c
S 
mcS操作围绕原点绘制一个直径为10的圆:

  • 10 0 m将当前点移动到(10,0)
  • 10 5.52 5.52 10 0 10 c将当前点的四分之一圆路径元素添加到(0,10);现在,当前点是(0,10)
  • -5.52 10-10 5.52-10 0 c将当前点的四分之一圆路径元素添加到(-10,0);现在,当前点为(-10,0)
  • -10-5.52-5.52-10 0-10 c将当前点的四分之一圆路径元素添加到(0,-10);现在,当前点是(0,-10)
  • 5.52-10 10-5.52 10 0 c添加从当前点到(10,0)完成圆的四分之一圆路径元素;现在的点是(10,0)
  • S沿给定路径元素定义的路径绘制,即圆线
但是由于之前由3 0 0 3 300 300 cm设置的变换矩阵按因子3缩放,并将缩放内容移动到(300,300),因此圆实际上是围绕(300,300)绘制的,半径为30

通过乘法获得最终坐标,例如第一个圆段(10,0)的起点:

实际上是(330300)

你的任务 因此,要找到曲线的坐标,您必须关注的不仅仅是c操作。相反,您必须使用mre操作符找到路径构建过程开始的位置,并跟踪当前点。当到达感兴趣的曲线时,它从变换后的当前点开始,并在明确给定的变换曲线终点结束

根据您的代码,转换矩阵可以由框架提供,也可以由您跟踪

如果使用从
PDFStreamEngine
派生的某个类来拦截“c”操作,则可以通过注册相应的
运算符处理器
使该引擎跟踪当前转换矩阵

另一方面,如果处理由
PDFStreamParser.getTokens()
返回的列表,则必须手动跟踪它

无论哪种情况,重要的操作都是:

-q将当前图形状态保存在图形状态堆栈上(请参见 8.4.2,“图形状态堆栈”)

-Q通过从堆栈中删除最近保存的状态并使其成为当前状态来恢复图形状态(参见8.4.2,“图形状态堆栈”)

a b c d e fcm通过连接指定矩阵修改当前变换矩阵(CTM)(见8.3.2,“坐标空间”)。尽管操作数指定了一个矩阵,但它们应被写入六个独立的数字,而不是数组

(第8.4.4节图形状态运算符,第127页)


曲线从上一次“移动到”、“线到”或“曲线绘制”操作停止的位置开始。因此,您必须跟踪所有这些操作。此外,正如您所做的,您必须关注当前的变换矩阵。曲线命令“c”例如,定义了绘制曲线的参数。唯一没有定义的是起点。我想我可以从当前变换矩阵中得到它。绘制曲线的参数在“pt”r8中给出?我的方法错了吗?如果我使用扩展PDFStreamEngine的类截取命令“c”,当前变换矩阵在绘制曲线之前包含x和y位置?所以我不需要截取其他改变当前转换矩阵的操作符,一个调用超类方法的回退逻辑不会吗?我的意思是我需要拦截“cm”命令e
             ┌   3   0   0 ┐
[ 10 0 1 ] x │   0   3   0 │ = [ 330 300 1]
             └ 300 300   1 ┘