fix(转换能力): 修复PDF转换回归
build.yaml / build (push) Successful in 4m39s

This commit is contained in:
xiaoqidun committed 2026-10-21 10:35:24 +08:00
1 parent 580592bbf8
commit b4d566019d
11 files changed
+793 -171

No files matched your search

+57 -2
View File
@@ -196,10 +196,18 @@ func (CanvasBackend) Stroke(path GeometryPath, options StrokeOptions) (result Ge
if slices.Contains(options.Dashes, 0) {
return path.Stroke(options)
}
if options.Cap == "Round" {
if pointPath, found := canvasPointPath(path); found {
return pointPath.Stroke(options)
}
}
p, err := geometryToCanvasPath(&path)
if err != nil {
return nil, err
}
if p.Empty() && options.Cap == "Round" {
return path.Stroke(options)
}
tolerance := options.Tolerance
if tolerance == 0 {
tolerance = canvas.Tolerance
@@ -222,6 +230,45 @@ func (CanvasBackend) Stroke(path GeometryPath, options StrokeOptions) (result Ge
return *geometryFromCanvasPath(p), nil
}
// canvasPointPath 保留普通闭合轮廓,将闭合单点改为同位置绘制段
// 入参: path 原始几何路径
// 返回: GeometryPath 只在需要时复制的路径, bool 是否含实际绘制的单点子路径
func canvasPointPath(path GeometryPath) (GeometryPath, bool) {
result := path
var start Point
point, drawn, active, found, copied := false, false, false, false, false
for i, segment := range path {
switch segment.Verb {
case GeometryMove:
found = found || point && drawn
start = segment.End
point, drawn, active = true, false, true
case GeometryClose:
if point && active {
if !copied {
result = slices.Clone(path)
copied = true
}
result[i] = GeometrySegment{Verb: GeometryLine, End: start}
found = true
}
point, drawn, active = true, false, false
case GeometryLine:
point = point && segment.End == start
drawn, active = true, true
case GeometryQuad:
point = point && segment.End == start && segment.Control1 == start
drawn, active = true, true
case GeometryCubic:
point = point && segment.End == start && segment.Control1 == start && segment.Control2 == start
drawn, active = true, true
default:
point, drawn, active = false, true, true
}
}
return result, found || point && drawn
}
// Clip 解析对象裁剪并与父裁剪相交,保留未裁剪与完全裁去的区别
// 入参: r 渲染器, clips OFD裁剪, matrix 裁剪坐标到页面的变换, parent 父裁剪
// 返回: *GeometryPath 页面裁剪, error 无效父路径错误
@@ -389,7 +436,11 @@ func geometryToCanvasPath(path *GeometryPath) (*canvas.Path, error) {
case GeometryArc:
p.ArcTo(s.RadiusX, s.RadiusY, -s.Rotation, s.Large, !s.Sweep, s.End.X, -s.End.Y)
case GeometryClose:
p.Close()
if data := p.Data(); len(data) != 0 && data[len(data)-1] == canvas.MoveToCmd {
p = canvas.NewPathFromData(append(data, canvas.CloseCmd, data[len(data)-3], data[len(data)-2], canvas.CloseCmd))
} else {
p.Close()
}
default:
return nil, fmt.Errorf("unsupported geometry command %d", s.Verb)
}
@@ -419,7 +470,11 @@ func canvasObjectPath(path GeometryPath) (*canvas.Path, error) {
data = p.Data()
case GeometryClose:
p := canvas.NewPathFromData(data)
p.Close()
if len(data) != 0 && data[len(data)-1] == canvas.MoveToCmd {
p = canvas.NewPathFromData(append(data, canvas.CloseCmd, data[len(data)-3], data[len(data)-2], canvas.CloseCmd))
} else {
p.Close()
}
data = p.Data()
default:
return nil, fmt.Errorf("unsupported geometry command %d", s.Verb)