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