feat(渲染能力): 修复虚线偏移继承与圆弧变换渲染
build.yaml / build (push) Successful in 38s

This commit is contained in:
xiaoqidun committed 2026-09-10 09:18:31 +08:00
1 parent 02493121f0
commit 93bdc0ce1d
5 files changed
+23 -29

No files matched your search

+1 -1
View File
@@ -166,7 +166,7 @@ type PathObject struct {
LineWidth float64 `xml:"LineWidth,attr"` LineWidth float64 `xml:"LineWidth,attr"`
Join string `xml:"Join,attr"` Join string `xml:"Join,attr"`
Cap string `xml:"Cap,attr"` Cap string `xml:"Cap,attr"`
DashOffset float64 `xml:"DashOffset,attr"` DashOffset *float64 `xml:"DashOffset,attr"`
DashPattern string `xml:"DashPattern,attr"` DashPattern string `xml:"DashPattern,attr"`
MiterLimit float64 `xml:"MiterLimit,attr"` MiterLimit float64 `xml:"MiterLimit,attr"`
CTM string `xml:"CTM,attr"` CTM string `xml:"CTM,attr"`
+1 -1
View File
@@ -110,7 +110,7 @@ func (r *Renderer) renderImageBorder(ctx *canvas.Context, obj ImageObject, box B
r.renderPath(ctx, PathObject{ r.renderPath(ctx, PathObject{
Boundary: obj.Boundary, Boundary: obj.Boundary,
LineWidth: width, LineWidth: width,
DashOffset: border.DashOffset, DashOffset: &border.DashOffset,
DashPattern: border.DashPattern, DashPattern: border.DashPattern,
Alpha: obj.Alpha, Alpha: obj.Alpha,
StrokeColor: border.BorderColor, StrokeColor: border.BorderColor,
+2
View File
@@ -228,6 +228,8 @@ func mergeDrawParam(base DrawParam, dp *DrawParam) *DrawParam {
} }
if dp.DashPattern != "" { if dp.DashPattern != "" {
base.DashPattern = dp.DashPattern base.DashPattern = dp.DashPattern
}
if dp.DashOffset != nil {
base.DashOffset = dp.DashOffset base.DashOffset = dp.DashOffset
} }
if dp.MiterLimit > 0 { if dp.MiterLimit > 0 {
+18 -26
View File
@@ -127,7 +127,9 @@ func (s *pathStyle) applyDrawParam(r *Renderer, dp *DrawParam, bx, by, pageH flo
s.applyLineJoin(dp.Join, dp.MiterLimit) s.applyLineJoin(dp.Join, dp.MiterLimit)
if dp.DashPattern != "" { if dp.DashPattern != "" {
s.dashPattern = parseFloats(dp.DashPattern) s.dashPattern = parseFloats(dp.DashPattern)
s.dashOffset = dp.DashOffset }
if dp.DashOffset != nil {
s.dashOffset = *dp.DashOffset
} }
} }
@@ -149,7 +151,9 @@ func (s *pathStyle) applyPathObject(r *Renderer, obj PathObject, bx, by, pageH f
s.applyLineJoin(obj.Join, obj.MiterLimit) s.applyLineJoin(obj.Join, obj.MiterLimit)
if obj.DashPattern != "" { if obj.DashPattern != "" {
s.dashPattern = parseFloats(obj.DashPattern) s.dashPattern = parseFloats(obj.DashPattern)
s.dashOffset = obj.DashOffset }
if obj.DashOffset != nil {
s.dashOffset = *obj.DashOffset
} }
} }
@@ -370,13 +374,10 @@ func (r *Renderer) buildPath(obj PathObject, pageH float64, ctm Matrix, boundary
bx, by = box.X, box.Y bx, by = box.X, box.Y
} }
} }
point := func(x, y float64) (float64, float64) {
if boundaryInCTM { if boundaryInCTM {
tx, ty := ctm.Transform(x+bx, y+by) ctm = ctm.Multiply(TranslationMatrix(bx, by))
return tx, pageH - ty } else {
} ctm = TranslationMatrix(bx, by).Multiply(ctm)
tx, ty := ctm.Transform(x, y)
return tx + bx, pageH - (ty + by)
} }
p := &canvas.Path{} p := &canvas.Path{}
tokens := strings.Fields(obj.AbbreviatedData) tokens := strings.Fields(obj.AbbreviatedData)
@@ -388,16 +389,14 @@ func (r *Renderer) buildPath(obj PathObject, pageH float64, ctm Matrix, boundary
if i+1 < len(tokens) { if i+1 < len(tokens) {
x, _ := strconv.ParseFloat(tokens[i], 64) x, _ := strconv.ParseFloat(tokens[i], 64)
y, _ := strconv.ParseFloat(tokens[i+1], 64) y, _ := strconv.ParseFloat(tokens[i+1], 64)
tx, ty := point(x, y) p.MoveTo(x, y)
p.MoveTo(tx, ty)
i += 2 i += 2
} }
case "L": case "L":
if i+1 < len(tokens) { if i+1 < len(tokens) {
x, _ := strconv.ParseFloat(tokens[i], 64) x, _ := strconv.ParseFloat(tokens[i], 64)
y, _ := strconv.ParseFloat(tokens[i+1], 64) y, _ := strconv.ParseFloat(tokens[i+1], 64)
tx, ty := point(x, y) p.LineTo(x, y)
p.LineTo(tx, ty)
i += 2 i += 2
} }
case "B": case "B":
@@ -408,10 +407,7 @@ func (r *Renderer) buildPath(obj PathObject, pageH float64, ctm Matrix, boundary
y2, _ := strconv.ParseFloat(tokens[i+3], 64) y2, _ := strconv.ParseFloat(tokens[i+3], 64)
x3, _ := strconv.ParseFloat(tokens[i+4], 64) x3, _ := strconv.ParseFloat(tokens[i+4], 64)
y3, _ := strconv.ParseFloat(tokens[i+5], 64) y3, _ := strconv.ParseFloat(tokens[i+5], 64)
tx1, ty1 := point(x1, y1) p.CubeTo(x1, y1, x2, y2, x3, y3)
tx2, ty2 := point(x2, y2)
tx3, ty3 := point(x3, y3)
p.CubeTo(tx1, ty1, tx2, ty2, tx3, ty3)
i += 6 i += 6
} }
case "Q": case "Q":
@@ -420,9 +416,7 @@ func (r *Renderer) buildPath(obj PathObject, pageH float64, ctm Matrix, boundary
y1, _ := strconv.ParseFloat(tokens[i+1], 64) y1, _ := strconv.ParseFloat(tokens[i+1], 64)
x2, _ := strconv.ParseFloat(tokens[i+2], 64) x2, _ := strconv.ParseFloat(tokens[i+2], 64)
y2, _ := strconv.ParseFloat(tokens[i+3], 64) y2, _ := strconv.ParseFloat(tokens[i+3], 64)
tx1, ty1 := point(x1, y1) p.QuadTo(x1, y1, x2, y2)
tx2, ty2 := point(x2, y2)
p.QuadTo(tx1, ty1, tx2, ty2)
i += 4 i += 4
} }
case "A": case "A":
@@ -434,19 +428,17 @@ func (r *Renderer) buildPath(obj PathObject, pageH float64, ctm Matrix, boundary
sweep, _ := strconv.ParseBool(tokens[i+4]) sweep, _ := strconv.ParseBool(tokens[i+4])
x, _ := strconv.ParseFloat(tokens[i+5], 64) x, _ := strconv.ParseFloat(tokens[i+5], 64)
y, _ := strconv.ParseFloat(tokens[i+6], 64) y, _ := strconv.ParseFloat(tokens[i+6], 64)
sx := math.Hypot(ctm.a, ctm.c) p.ArcTo(rx, ry, rot, large, sweep, x, y)
sy := math.Hypot(ctm.b, ctm.d)
ctmRot := math.Atan2(ctm.b, ctm.a) * 180 / math.Pi
tx, ty := point(x, y)
sweep = !sweep
p.ArcTo(rx*sx, ry*sy, -(rot + ctmRot), large, sweep, tx, ty)
i += 7 i += 7
} }
case "C": case "C":
p.Close() p.Close()
} }
} }
return p if canvas.Equal(ctm.a*ctm.d-ctm.b*ctm.c, 0) {
p = p.ReplaceArcs()
}
return p.Transform(canvas.Matrix{{ctm.a, ctm.c, ctm.e}, {-ctm.b, -ctm.d, pageH - ctm.f}})
} }
// buildObjectClipPath 构建对象裁剪路径并应用父级变换 // buildObjectClipPath 构建对象裁剪路径并应用父级变换
+1 -1
View File
@@ -86,7 +86,7 @@ type DrawParam struct {
LineWidth float64 `xml:"LineWidth,attr"` LineWidth float64 `xml:"LineWidth,attr"`
Join string `xml:"Join,attr"` Join string `xml:"Join,attr"`
Cap string `xml:"Cap,attr"` Cap string `xml:"Cap,attr"`
DashOffset float64 `xml:"DashOffset,attr"` DashOffset *float64 `xml:"DashOffset,attr"`
DashPattern string `xml:"DashPattern,attr"` DashPattern string `xml:"DashPattern,attr"`
MiterLimit float64 `xml:"MiterLimit,attr"` MiterLimit float64 `xml:"MiterLimit,attr"`
Font string `xml:"Font,attr"` Font string `xml:"Font,attr"`