使用iText7时负坐标线条代表什么?程序是否存在问题?
iText7 RENDER_PATH事件中负坐标线段的疑问
我用VB.Net写了一个程序,拦截iText7的RENDER_PATH事件,用来提取并显示线段的X、Y坐标,代码如下:
Dim iNrPaths As Integer = 0 Dim iNrSubPaths As Integer = 0 Dim iNrSegments As Integer = 0 Dim iNrLines As Integer = 0 For Each oPath As PathRenderInfo In listener.getPaths() Dim m As Matrix = oPath.GetCtm() iNrPaths += 1 Dim iLineWidth = oPath.GetLineWidth() sw.WriteLine("Render.LINE-WIDTH: " & CStr(iLineWidth)) For Each sp As Subpath In oPath.GetPath().GetSubpaths() iNrSubPaths += 1 sw.WriteLine(oPath.GetPath().ToString()) For Each segment In sp.GetSegments() iNrSegments += 1 sw.WriteLine(" " & segment.ToString()) Select Case segment.GetType() Case GetType(iText.Kernel.Geom.Line) iNrLines += 1 Dim oLine As iText.Kernel.Geom.Line = segment Dim oList As List(Of Point) = oLine.GetBasePoints() Dim n = 0 For Each p In oList sw.WriteLine(" p" & CStr(n) & ".x: " & oList(n).GetX().ToString("0.####")) sw.WriteLine(" p" & CStr(n) & ".y: " & oList(n).GetY().ToString("0.####")) n += 1 Next sw.WriteLine(" width: " & CStr(oList(0).GetX() - oList(1).GetX())) sw.WriteLine(" height: " & CStr(oList(0).GetY() - oList(1).GetY())) Case GetType(iText.Kernel.Geom.BezierCurve) Case Else Dim i0 = 0 End Select Next Next Next
正常正坐标输出示例
Render.LINE-WIDTH: 9,50001 iText.Kernel.Geom.Path iText.Kernel.Geom.Line p0.x: 1818,9301 p0.y: 1475,79 p1.x: 2365,02 p1.y: 1475,79 width: -546,089965820313 height: 0 iText.Kernel.Geom.Line p0.x: 2365,02 p0.y: 1475,79 p1.x: 2365,02 p1.y: 2298,3989 width: 0 height: -822,60888671875 iText.Kernel.Geom.Line p0.x: 2365,02 p0.y: 2298,3989 p1.x: 1818,9301 p1.y: 2298,3989 width: 546,089965820313 height: 0
出现负坐标的输出示例
Render.LINE-WIDTH: 12,5 iText.Kernel.Geom.Path iText.Kernel.Geom.Line p0.x: -99,2109 p0.y: 8192,1396 p1.x: -249,215 p1.y: 8192,1396 width: 150,004096984863 height: 0 iText.Kernel.Geom.Path iText.Kernel.Geom.Line p0.x: 6051,98 p0.y: 8192,1396 p1.x: 6201,98 p1.y: 8192,1396 width: -150 height: 0 iText.Kernel.Geom.Path iText.Kernel.Geom.Line p0.x: -99,2109 p0.y: -0,0039 p1.x: -249,215 p1.y: -0,0039 width: 150,004096984863 height: 0
疑问
- 这类负坐标的线条代表什么含义?
- 两点均为负坐标的线条是什么?
- 我的VB.Net程序是否存在显示错误?
解答
1. 程序无显示错误,但有关键遗漏
你的代码逻辑能正确提取路径的原始坐标,但忽略了CTM(当前变换矩阵)的转换——你已经获取了oPath.GetCtm(),但没有用它转换坐标点。PDF内容流里的路径坐标是未经变换的原始值,最终页面显示位置需要通过CTM做平移、缩放、旋转等转换。
2. 负坐标线条的含义
- PDF默认以页面左下角为原点(0,0),但很多PDF生成工具会通过CTM调整坐标系(比如把原点移到左上角,或整体平移页面内容)。你看到的负坐标是内容流里的原始值,经过CTM转换后,可能落在页面可见区域内,也可能是超出页面边界的元素。
- 部分PDF会包含页面外的装饰线条、残留路径,或是用于裁剪/遮罩的辅助路径(RENDER_PATH事件触发的是实际要渲染的路径)。
3. 两点均为负坐标的线条
这类线条分为两种情况:
- 原始内容流里的位置,经过CTM转换后会映射到页面可见区域内;
- 完全位于页面边界外的无效路径,可能是PDF生成工具的残留产物,不会在最终页面显示。
修正建议
如果要获取页面上的实际显示坐标,需要用CTM转换每个点:
' 替换原坐标输出代码 Dim transformedPoint As Point = m.TransformPoint(p.GetX(), p.GetY()) sw.WriteLine(" p" & CStr(n) & ".x: " & transformedPoint.GetX().ToString("0.####")) sw.WriteLine(" p" & CStr(n) & ".y: " & transformedPoint.GetY().ToString("0.####"))
内容的提问来源于stack exchange,提问作者schlebe
相关产品推荐
相关产品推荐

