From 8b123698e544b1331eb867d007a61092ebed4f82 Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Tue, 8 Sep 2026 21:41:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=B8=B2=E6=9F=93=E5=BC=BA=E5=8C=96):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B7=AF=E5=BE=84=E5=A5=87=E5=81=B6=E5=A1=AB?= =?UTF-8?q?=E5=85=85=E8=A7=84=E5=88=99=EF=BC=8C=E6=AD=A3=E7=A1=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E9=95=82=E7=A9=BA=E5=8C=BA=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ofdgo_page.go | 1 + ofdgo_renderer_path.go | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/ofdgo_page.go b/ofdgo_page.go index dc37b6b..3537757 100644 --- a/ofdgo_page.go +++ b/ofdgo_page.go @@ -163,6 +163,7 @@ type PathObject struct { Visible *bool `xml:"Visible,attr"` Stroke *bool `xml:"Stroke,attr"` Fill *bool `xml:"Fill,attr"` + Rule string `xml:"Rule,attr"` StrokeColor *StrokeColor `xml:"StrokeColor"` FillColor *FillColor `xml:"FillColor"` AbbreviatedData string `xml:"AbbreviatedData"` diff --git a/ofdgo_renderer_path.go b/ofdgo_renderer_path.go index 6bc1aa2..f5b6d69 100644 --- a/ofdgo_renderer_path.go +++ b/ofdgo_renderer_path.go @@ -200,30 +200,35 @@ func (r *Renderer) renderPath(ctx *canvas.Context, obj PathObject, pageH float64 if style.fillPaint == nil { style.fillPaint = style.fillColor } - if shouldFill && style.fillPattern != nil { + if shouldFill { fp := p + fillRule := canvas.NonZero + if obj.Rule == "Even-Odd" { + fillRule = canvas.EvenOdd + if clipPath != nil || style.fillPattern != nil { + fp = fp.Settle(fillRule) + } + } if clipPath != nil { - fp = p.Copy() + fp = fp.Copy() fp.Close() fp = applyClipPath(fp, clipPath) } - r.renderPattern(ctx, style.fillPattern, style.fillPatternColor, pageH, fp, ctm, bx, by) - } else if shouldFill && style.fillPaint != nil { - ctx.SetFill(style.fillPaint) - ctx.SetStrokeColor(canvas.Transparent) - fp := p - if clipPath != nil { - fp = p.Copy() - fp.Close() - fp = applyClipPath(fp, clipPath) + if style.fillPattern != nil { + r.renderPattern(ctx, style.fillPattern, style.fillPatternColor, pageH, fp, ctm, bx, by) + } else if style.fillPaint != nil { + ctx.SetFillRule(fillRule) + ctx.SetFill(style.fillPaint) + ctx.SetStrokeColor(canvas.Transparent) + ctx.DrawPath(0, 0, fp) } - ctx.DrawPath(0, 0, fp) } shouldStroke := true if obj.Stroke != nil { shouldStroke = *obj.Stroke } if shouldStroke { + ctx.SetFillRule(canvas.NonZero) if style.strokePaint == nil { style.strokePaint = style.strokeColor } @@ -409,7 +414,6 @@ func (r *Renderer) buildObjectClipPath(clips *Clips, pageH float64, bx, by float } 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}, @@ -438,6 +442,9 @@ func (r *Renderer) buildClipPath(clips *Clips, pageH float64, bx, by float64, ob cp := r.buildPath(pathObj, pageH, ctm, true) cp.Translate(bx, -by) cp.Close() + if pathObj.Rule == "Even-Odd" { + cp = cp.Settle(canvas.EvenOdd) + } if clipPath == nil { clipPath = cp } else {