我正在尝试使用pdfbox获取立方贝塞尔的位置。 我试图拦截“c”操作并尝试通过从列表中提取它们来获取曲线的参数。这里有两个问题。首先,当前位置始终是(0,0)。以获得我使用的当前位置
float x = getGraphicsState().getCurrentTransformationMatrix().getXPosition();
float y = getGraphicsState().getCurrentTransformationMatrix().getYPosition();
当前的变换矩阵总是一个单位矩阵。我应该做AffineTransform
吗?但到了哪里?
第二个是“c”操作的参数大于页面尺寸。我应该用x和y比例划分它们吗?
答案 0 :(得分:3)
通过尝试考虑当前的转换矩阵,您做了一件必要的事情,但还有另一个需要考虑的数据,当前路径的当前点 。参看specification:
当前正在构建的路径称为当前路径。在PDF中(与PostScript不同),当前路径不是图形状态的一部分,不会与其他图形状态参数一起保存和恢复。 PDF路径应该是严格的内部对象,没有明确的表示。在绘制当前路径后,它将不再被定义;在使用 m 或 re 运算符开始新的路径之前,没有当前路径。
最近添加到当前路径的段的尾随端点称为当前点。如果当前路径为空,则当前点应该是未定义的。大多数将段添加到当前路径的运算符从当前点开始;如果当前点未定义,则应生成错误。
[...]
x1 y1 x2 y2 x3 y3 c 将三次贝塞尔曲线附加到当前路径。曲线 应使用(x1,y1)和(x2,y2)作为Bézier控制点,从当前点延伸到点(x3,y3)(见8.5.2.2,“CubicBézier曲线”)。新的当前点应为(x3,y3)。
(第8.5.2节路径构建运算符,第132页)
E.g。看看这个
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
m , c 和 S 操作在原点周围绘制一个直径为10的圆圈:
但是由于之前设置的变换矩阵 3 0 0 3 300 300 cm ,它按比例缩放3并将缩放的内容移动到(300,300),实际上圆圈被绘制(300,300),半径为30。
通过乘法获得最终坐标,例如对于第一个圆弧段(10,0)的起点:
┌ 3 0 0 ┐
[ 10 0 1 ] x │ 0 3 0 │ = [ 330 300 1]
└ 300 300 1 ┘
所以它实际上是(330,300)。
因此,要找到曲线的坐标,您必须不仅仅关注 c 操作。相反,您必须使用 m 或重新运算符找到路径构建过程的位置,并跟踪当前点< / em>的。当你到达你感兴趣的曲线时,它从转换的当前点开始,并在明确给定的曲线终点转换结束。
根据您的代码,转换矩阵可能由框架提供,或者您可能还必须跟踪它。
如果通过使用从PDFStreamEngine
派生的某个类来拦截“c”操作,您可以让该引擎通过注册相应的{{1}来跟踪当前的转换矩阵}第
另一方面,如果您处理OperatorProcessor
返回的列表,则必须手动跟踪它。
在任何一种情况下,重要的操作都是:
- q 将当前图形状态保存在图形状态堆栈中(请参阅 8.4.2,“图形状态堆栈”)。
- Q 通过从堆栈中删除最近保存的状态并使其成为当前状态来恢复图形状态(请参见8.4.2,“图形状态堆栈”) )。
a b c d e f cm 通过连接指定的矩阵来修改当前的变换矩阵(CTM)(参见8.3.2,“坐标空间”)。尽管操作数指定了矩阵,但它们应写为六个单独的数字,而不是数组。
(第8.4.4节图形状态运算符,第127页)