From d9452145ac90caa4a1b843c248b5f9f77237e9cd Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Mon, 7 Sep 2026 16:53:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AA=E5=9B=9E=E5=BD=92=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ofdgo_renderer_image.go | 7 ++----- ofdgo_renderer_path.go | 23 +++++++++++++++++++++-- ofdgo_renderer_text.go | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ofdgo_renderer_image.go b/ofdgo_renderer_image.go index e993d70..5ccd08d 100644 --- a/ofdgo_renderer_image.go +++ b/ofdgo_renderer_image.go @@ -56,10 +56,7 @@ func (r *Renderer) renderImage(ctx *canvas.Context, obj ImageObject, pageH float if obj.CTM == "" { ctm = Matrix{a: box.W, d: box.H} } - objectCTM := ctm - if parentCTM != nil { - objectCTM = parentCTM.Multiply(ctm) - } + localCTM := ctm var m canvas.Matrix if boundaryInCTM && parentCTM != nil { x0 := box.X + ctm.c + ctm.e @@ -77,7 +74,7 @@ func (r *Renderer) renderImage(ctx *canvas.Context, obj ImageObject, pageH float {-ctm.b / imgW, ctm.d / imgH, pageH - box.Y - ctm.d - ctm.f}, } } - clipPath := intersectClipPath(parentClip, r.buildClipPath(obj.Clips, pageH, box.X, box.Y, objectCTM)) + clipPath := intersectClipPath(parentClip, r.buildObjectClipPath(obj.Clips, pageH, box.X, box.Y, localCTM, parentCTM, boundaryInCTM)) img = imageWithClip(img, clipPath, m) img, pad := imageWithTransparentEdge(img) if pad > 0 { diff --git a/ofdgo_renderer_path.go b/ofdgo_renderer_path.go index 5e94691..6bc1aa2 100644 --- a/ofdgo_renderer_path.go +++ b/ofdgo_renderer_path.go @@ -175,7 +175,8 @@ func (r *Renderer) renderPath(ctx *canvas.Context, obj PathObject, pageH float64 bx, by = box.X, box.Y } } - ctm := NewMatrix(obj.CTM) + localCTM := NewMatrix(obj.CTM) + ctm := localCTM if parentCTM != nil { ctm = parentCTM.Multiply(ctm) } @@ -191,7 +192,7 @@ func (r *Renderer) renderPath(ctx *canvas.Context, obj PathObject, pageH float64 if rectPath := r.buildTinyFillRectPath(obj, pageH, ctm, bx, by); rectPath != nil { p = rectPath } - clipPath := intersectClipPath(parentClip, r.buildClipPath(obj.Clips, pageH, bx, by, ctm)) + clipPath := intersectClipPath(parentClip, r.buildObjectClipPath(obj.Clips, pageH, bx, by, localCTM, parentCTM, boundaryInCTM)) shouldFill := false if obj.Fill != nil { shouldFill = *obj.Fill @@ -399,6 +400,24 @@ func (r *Renderer) buildPath(obj PathObject, pageH float64, ctm Matrix, boundary return p } +// buildObjectClipPath 构建对象裁剪路径并应用父级变换 +// 入参: clips 裁剪对象, pageH 页面高度, bx 边界X坐标, by 边界Y坐标, objectCTM 对象CTM, parentCTM 父级CTM, boundaryInCTM 边界是否参与父级CTM +// 返回: *canvas.Path 路径对象 +func (r *Renderer) buildObjectClipPath(clips *Clips, pageH float64, bx, by float64, objectCTM Matrix, parentCTM *Matrix, boundaryInCTM bool) *canvas.Path { + if !boundaryInCTM && parentCTM != nil { + objectCTM = parentCTM.Multiply(objectCTM) + } + p := r.buildClipPath(clips, pageH, bx, by, objectCTM) + if p != nil && boundaryInCTM && parentCTM != nil { + // TransFlag只控制对象CTM,父级变换仍作用于裁剪区域及边界 + p = p.Transform(canvas.Matrix{ + {parentCTM.a, -parentCTM.c, parentCTM.c*pageH + parentCTM.e}, + {-parentCTM.b, parentCTM.d, pageH*(1-parentCTM.d) - parentCTM.f}, + }) + } + return p +} + // buildClipPath 构建裁剪路径 // 入参: clips 裁剪对象, pageH 页面高度, bx 边界X坐标, by 边界Y坐标, objectCTM 对象CTM // 返回: *canvas.Path 路径对象 diff --git a/ofdgo_renderer_text.go b/ofdgo_renderer_text.go index 99bd9fd..388c59b 100644 --- a/ofdgo_renderer_text.go +++ b/ofdgo_renderer_text.go @@ -46,7 +46,7 @@ func (r *Renderer) renderText(ctx *canvas.Context, obj TextObject, pageH float64 if parentCTM != nil { ctm = parentCTM.Multiply(ctm) } - clipPath := intersectClipPath(parentClip, r.buildClipPath(obj.Clips, pageH, bx, by, ctm)) + clipPath := intersectClipPath(parentClip, r.buildObjectClipPath(obj.Clips, pageH, bx, by, localCTM, parentCTM, boundaryInCTM)) var dp *DrawParam if obj.DrawParam != "" { dp = r.getDrawParam(obj.DrawParam, nil)