MCPcopy Index your code
hub / github.com/tdewolff/canvas / replace

Method replace

path.go:1481–1545  ·  view source on GitHub ↗

replace replaces path segments by their respective functions, each returning the path that will replace the segment or nil if no replacement is to be performed. The line function will take the start and end points. The bezier function will take the start point, control point 1 and 2, and the end poi

(
	line func(Point, Point) *Path,
	quad func(Point, Point, Point) *Path,
	cube func(Point, Point, Point, Point) *Path,
	arc func(Point, float64, float64, float64, bool, bool, Point) *Path,
)

Source from the content-addressed store, hash-verified

1479
1480// replace replaces path segments by their respective functions, each returning the path that will replace the segment or nil if no replacement is to be performed. The line function will take the start and end points. The bezier function will take the start point, control point 1 and 2, and the end point (i.e. a cubic Bézier, quadratic Béziers will be implicitly converted to cubic ones). The arc function will take a start point, the major and minor radii, the radial rotation counter clockwise, the large and sweep booleans, and the end point. The replacing path will replace the path segment without any checks, you need to make sure the be moved so that its start point connects with the last end point of the base path before the replacement. If the end point of the replacing path is different that the end point of what is replaced, the path that follows will be displaced.
1481func (p *Path) replace(
1482 line func(Point, Point) *Path,
1483 quad func(Point, Point, Point) *Path,
1484 cube func(Point, Point, Point, Point) *Path,
1485 arc func(Point, float64, float64, float64, bool, bool, Point) *Path,
1486) *Path {
1487 copied := false
1488 var start, end Point
1489 for i := 0; i < len(p.d); {
1490 var q *Path
1491 cmd := p.d[i]
1492 switch cmd {
1493 case LineToCmd, CloseCmd:
1494 if line != nil {
1495 end = Point{p.d[i+1], p.d[i+2]}
1496 q = line(start, end)
1497 if cmd == CloseCmd {
1498 q.Close()
1499 }
1500 }
1501 case QuadToCmd:
1502 if quad != nil {
1503 cp := Point{p.d[i+1], p.d[i+2]}
1504 end = Point{p.d[i+3], p.d[i+4]}
1505 q = quad(start, cp, end)
1506 }
1507 case CubeToCmd:
1508 if cube != nil {
1509 cp1 := Point{p.d[i+1], p.d[i+2]}
1510 cp2 := Point{p.d[i+3], p.d[i+4]}
1511 end = Point{p.d[i+5], p.d[i+6]}
1512 q = cube(start, cp1, cp2, end)
1513 }
1514 case ArcToCmd:
1515 if arc != nil {
1516 rx, ry, phi := p.d[i+1], p.d[i+2], p.d[i+3]
1517 large, sweep := toArcFlags(p.d[i+4])
1518 end = Point{p.d[i+5], p.d[i+6]}
1519 q = arc(start, rx, ry, phi, large, sweep, end)
1520 }
1521 }
1522
1523 if q != nil {
1524 if !copied {
1525 p = p.Copy()
1526 copied = true
1527 }
1528
1529 r := &Path{append([]float64{MoveToCmd, end.X, end.Y, MoveToCmd}, p.d[i+cmdLen(cmd):]...)}
1530
1531 p.d = p.d[: i : i+cmdLen(cmd)] // make sure not to overwrite the rest of the path
1532 p = p.Join(q)
1533 if cmd != CloseCmd {
1534 p.LineTo(end.X, end.Y)
1535 }
1536
1537 i = len(p.d)
1538 p = p.Join(r) // join the rest of the base path

Callers 4

FlattenMethod · 0.95
ReplaceArcsMethod · 0.95
XMonotoneMethod · 0.95
TestPathReplaceFunction · 0.95

Calls 7

CloseMethod · 0.95
CopyMethod · 0.95
JoinMethod · 0.95
LineToMethod · 0.95
lineStruct · 0.85
toArcFlagsFunction · 0.85
cmdLenFunction · 0.85

Tested by 1

TestPathReplaceFunction · 0.76