MCPcopy
hub / github.com/tdewolff/canvas / Bounds

Method Bounds

path.go:1108–1230  ·  view source on GitHub ↗

Bounds returns the exact bounding box rectangle of the path.

()

Source from the content-addressed store, hash-verified

1106
1107// Bounds returns the exact bounding box rectangle of the path.
1108func (p *Path) Bounds() Rect {
1109 if len(p.d) < 4 {
1110 return Rect{}
1111 }
1112
1113 // first command is MoveTo
1114 start, end := Point{p.d[1], p.d[2]}, Point{}
1115 xmin, xmax := start.X, start.X
1116 ymin, ymax := start.Y, start.Y
1117 for i := 4; i < len(p.d); {
1118 cmd := p.d[i]
1119 switch cmd {
1120 case MoveToCmd, LineToCmd, CloseCmd:
1121 end = Point{p.d[i+1], p.d[i+2]}
1122 xmin = math.Min(xmin, end.X)
1123 xmax = math.Max(xmax, end.X)
1124 ymin = math.Min(ymin, end.Y)
1125 ymax = math.Max(ymax, end.Y)
1126 case QuadToCmd:
1127 cp := Point{p.d[i+1], p.d[i+2]}
1128 end = Point{p.d[i+3], p.d[i+4]}
1129
1130 xmin = math.Min(xmin, end.X)
1131 xmax = math.Max(xmax, end.X)
1132 if tdenom := (start.X - 2*cp.X + end.X); !Equal(tdenom, 0.0) {
1133 if t := (start.X - cp.X) / tdenom; IntervalExclusive(t, 0.0, 1.0) {
1134 x := quadraticBezierPos(start, cp, end, t)
1135 xmin = math.Min(xmin, x.X)
1136 xmax = math.Max(xmax, x.X)
1137 }
1138 }
1139
1140 ymin = math.Min(ymin, end.Y)
1141 ymax = math.Max(ymax, end.Y)
1142 if tdenom := (start.Y - 2*cp.Y + end.Y); !Equal(tdenom, 0.0) {
1143 if t := (start.Y - cp.Y) / tdenom; IntervalExclusive(t, 0.0, 1.0) {
1144 y := quadraticBezierPos(start, cp, end, t)
1145 ymin = math.Min(ymin, y.Y)
1146 ymax = math.Max(ymax, y.Y)
1147 }
1148 }
1149 case CubeToCmd:
1150 cp1 := Point{p.d[i+1], p.d[i+2]}
1151 cp2 := Point{p.d[i+3], p.d[i+4]}
1152 end = Point{p.d[i+5], p.d[i+6]}
1153
1154 a := -start.X + 3*cp1.X - 3*cp2.X + end.X
1155 b := 2*start.X - 4*cp1.X + 2*cp2.X
1156 c := -start.X + cp1.X
1157 t1, t2 := solveQuadraticFormula(a, b, c)
1158
1159 xmin = math.Min(xmin, end.X)
1160 xmax = math.Max(xmax, end.X)
1161 if !math.IsNaN(t1) && IntervalExclusive(t1, 0.0, 1.0) {
1162 x1 := cubicBezierPos(start, cp1, cp2, end, t1)
1163 xmin = math.Min(xmin, x1.X)
1164 xmax = math.Max(xmax, x1.X)
1165 }

Callers 8

DrawPreviewWithAssetsFunction · 0.45
ToVectorRasterizerMethod · 0.45
TestCubicBezierStrokeFunction · 0.45
TestTextBoundsFunction · 0.45
TestPathBoundsFunction · 0.45
drawTextAndMoveDownFunction · 0.45
drawDocumentFunction · 0.45
mainFunction · 0.45

Calls 9

EqualFunction · 0.85
IntervalExclusiveFunction · 0.85
quadraticBezierPosFunction · 0.85
solveQuadraticFormulaFunction · 0.85
cubicBezierPosFunction · 0.85
toArcFlagsFunction · 0.85
ellipseToCenterFunction · 0.85
angleBetweenFunction · 0.85
cmdLenFunction · 0.85

Tested by 3

TestCubicBezierStrokeFunction · 0.36
TestTextBoundsFunction · 0.36
TestPathBoundsFunction · 0.36