OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #ifndef SkPathOpsCurve_DEFINE | 7 #ifndef SkPathOpsCurve_DEFINE |
8 #define SkPathOpsCurve_DEFINE | 8 #define SkPathOpsCurve_DEFINE |
9 | 9 |
10 #include "SkIntersections.h" | 10 #include "SkIntersections.h" |
11 #include "SkPathOpsCubic.h" | 11 #include "SkPathOpsCubic.h" |
12 #include "SkPathOpsLine.h" | 12 #include "SkPathOpsLine.h" |
13 #include "SkPathOpsQuad.h" | 13 #include "SkPathOpsQuad.h" |
14 | 14 |
15 static SkDPoint dline_xy_at_t(const SkPoint a[2], double t) { | 15 #ifndef SK_RELEASE |
| 16 #include "SkPath.h" |
| 17 #endif |
| 18 |
| 19 struct SkOpCurve { |
| 20 SkPoint fPts[4]; |
| 21 SkScalar fWeight; |
| 22 SkDEBUGCODE(SkPath::Verb fVerb); |
| 23 |
| 24 const SkPoint& operator[](int n) const { |
| 25 SkASSERT(n >= 0 && n <= SkPathOpsVerbToPoints(fVerb)); |
| 26 return fPts[n]; |
| 27 } |
| 28 |
| 29 void set(const SkDCubic& cubic) { |
| 30 for (int index = 0; index < SkDCubic::kPointCount; ++index) { |
| 31 fPts[index] = cubic[index].asSkPoint(); |
| 32 } |
| 33 SkDEBUGCODE(fWeight = 1); |
| 34 SkDEBUGCODE(fVerb = SkPath::kCubic_Verb); |
| 35 } |
| 36 }; |
| 37 |
| 38 struct SkDCurve { |
| 39 union { |
| 40 SkDLine fLine; |
| 41 SkDQuad fQuad; |
| 42 SkDConic fConic; |
| 43 SkDCubic fCubic; |
| 44 }; |
| 45 SkDEBUGCODE(SkPath::Verb fVerb); |
| 46 |
| 47 const SkDPoint& operator[](int n) const { |
| 48 SkASSERT(n >= 0 && n <= SkPathOpsVerbToPoints(fVerb)); |
| 49 return fCubic[n]; |
| 50 } |
| 51 |
| 52 SkDPoint& operator[](int n) { |
| 53 SkASSERT(n >= 0 && n <= SkPathOpsVerbToPoints(fVerb)); |
| 54 return fCubic[n]; |
| 55 } |
| 56 |
| 57 void dumpID(int ) const; |
| 58 }; |
| 59 |
| 60 static SkDPoint dline_xy_at_t(const SkPoint a[2], SkScalar , double t) { |
16 SkDLine line; | 61 SkDLine line; |
17 line.set(a); | 62 line.set(a); |
18 return line.ptAtT(t); | 63 return line.ptAtT(t); |
19 } | 64 } |
20 | 65 |
21 static SkDPoint dquad_xy_at_t(const SkPoint a[3], double t) { | 66 static SkDPoint dquad_xy_at_t(const SkPoint a[3], SkScalar , double t) { |
22 SkDQuad quad; | 67 SkDQuad quad; |
23 quad.set(a); | 68 quad.set(a); |
24 return quad.ptAtT(t); | 69 return quad.ptAtT(t); |
25 } | 70 } |
26 | 71 |
27 static SkDPoint dcubic_xy_at_t(const SkPoint a[4], double t) { | 72 static SkDPoint dconic_xy_at_t(const SkPoint a[3], SkScalar weight, double t) { |
| 73 SkDConic conic; |
| 74 conic.set(a, weight); |
| 75 return conic.ptAtT(t); |
| 76 } |
| 77 |
| 78 static SkDPoint dcubic_xy_at_t(const SkPoint a[4], SkScalar , double t) { |
28 SkDCubic cubic; | 79 SkDCubic cubic; |
29 cubic.set(a); | 80 cubic.set(a); |
30 return cubic.ptAtT(t); | 81 return cubic.ptAtT(t); |
31 } | 82 } |
32 | 83 |
33 static SkDPoint (* const CurveDPointAtT[])(const SkPoint[], double ) = { | 84 static SkDPoint (* const CurveDPointAtT[])(const SkPoint[], SkScalar , double )
= { |
34 NULL, | 85 NULL, |
35 dline_xy_at_t, | 86 dline_xy_at_t, |
36 dquad_xy_at_t, | 87 dquad_xy_at_t, |
| 88 dconic_xy_at_t, |
37 dcubic_xy_at_t | 89 dcubic_xy_at_t |
38 }; | 90 }; |
39 | 91 |
40 static SkPoint fline_xy_at_t(const SkPoint a[2], double t) { | 92 static SkPoint fline_xy_at_t(const SkPoint a[2], SkScalar weight, double t) { |
41 return dline_xy_at_t(a, t).asSkPoint(); | 93 return dline_xy_at_t(a, weight, t).asSkPoint(); |
42 } | 94 } |
43 | 95 |
44 static SkPoint fquad_xy_at_t(const SkPoint a[3], double t) { | 96 static SkPoint fquad_xy_at_t(const SkPoint a[3], SkScalar weight, double t) { |
45 return dquad_xy_at_t(a, t).asSkPoint(); | 97 return dquad_xy_at_t(a, weight, t).asSkPoint(); |
46 } | 98 } |
47 | 99 |
48 static SkPoint fcubic_xy_at_t(const SkPoint a[4], double t) { | 100 static SkPoint fconic_xy_at_t(const SkPoint a[3], SkScalar weight, double t) { |
49 return dcubic_xy_at_t(a, t).asSkPoint(); | 101 return dconic_xy_at_t(a, weight, t).asSkPoint(); |
50 } | 102 } |
51 | 103 |
52 static SkPoint (* const CurvePointAtT[])(const SkPoint[], double ) = { | 104 static SkPoint fcubic_xy_at_t(const SkPoint a[4], SkScalar weight, double t) { |
| 105 return dcubic_xy_at_t(a, weight, t).asSkPoint(); |
| 106 } |
| 107 |
| 108 static SkPoint (* const CurvePointAtT[])(const SkPoint[], SkScalar , double ) =
{ |
53 NULL, | 109 NULL, |
54 fline_xy_at_t, | 110 fline_xy_at_t, |
55 fquad_xy_at_t, | 111 fquad_xy_at_t, |
| 112 fconic_xy_at_t, |
56 fcubic_xy_at_t | 113 fcubic_xy_at_t |
57 }; | 114 }; |
58 | 115 |
59 static SkDVector dline_dxdy_at_t(const SkPoint a[2], double ) { | 116 static SkDVector dline_dxdy_at_t(const SkPoint a[2], SkScalar , double ) { |
60 SkDLine line; | 117 SkDLine line; |
61 line.set(a); | 118 line.set(a); |
62 return line[1] - line[0]; | 119 return line[1] - line[0]; |
63 } | 120 } |
64 | 121 |
65 static SkDVector dquad_dxdy_at_t(const SkPoint a[3], double t) { | 122 static SkDVector dquad_dxdy_at_t(const SkPoint a[3], SkScalar , double t) { |
66 SkDQuad quad; | 123 SkDQuad quad; |
67 quad.set(a); | 124 quad.set(a); |
68 return quad.dxdyAtT(t); | 125 return quad.dxdyAtT(t); |
69 } | 126 } |
70 | 127 |
71 static SkDVector dcubic_dxdy_at_t(const SkPoint a[4], double t) { | 128 static SkDVector dconic_dxdy_at_t(const SkPoint a[3], SkScalar weight, double t)
{ |
| 129 SkDConic conic; |
| 130 conic.set(a, weight); |
| 131 return conic.dxdyAtT(t); |
| 132 } |
| 133 |
| 134 static SkDVector dcubic_dxdy_at_t(const SkPoint a[4], SkScalar , double t) { |
72 SkDCubic cubic; | 135 SkDCubic cubic; |
73 cubic.set(a); | 136 cubic.set(a); |
74 return cubic.dxdyAtT(t); | 137 return cubic.dxdyAtT(t); |
75 } | 138 } |
76 | 139 |
77 static SkDVector (* const CurveDSlopeAtT[])(const SkPoint[], double ) = { | 140 static SkDVector (* const CurveDSlopeAtT[])(const SkPoint[], SkScalar , double )
= { |
78 NULL, | 141 NULL, |
79 dline_dxdy_at_t, | 142 dline_dxdy_at_t, |
80 dquad_dxdy_at_t, | 143 dquad_dxdy_at_t, |
| 144 dconic_dxdy_at_t, |
81 dcubic_dxdy_at_t | 145 dcubic_dxdy_at_t |
82 }; | 146 }; |
83 | 147 |
84 static SkVector fline_dxdy_at_t(const SkPoint a[2], double ) { | 148 static SkVector fline_dxdy_at_t(const SkPoint a[2], SkScalar , double ) { |
85 return a[1] - a[0]; | 149 return a[1] - a[0]; |
86 } | 150 } |
87 | 151 |
88 static SkVector fquad_dxdy_at_t(const SkPoint a[3], double t) { | 152 static SkVector fquad_dxdy_at_t(const SkPoint a[3], SkScalar weight, double t) { |
89 return dquad_dxdy_at_t(a, t).asSkVector(); | 153 return dquad_dxdy_at_t(a, weight, t).asSkVector(); |
90 } | 154 } |
91 | 155 |
92 static SkVector fcubic_dxdy_at_t(const SkPoint a[4], double t) { | 156 static SkVector fconic_dxdy_at_t(const SkPoint a[3], SkScalar weight, double t)
{ |
93 return dcubic_dxdy_at_t(a, t).asSkVector(); | 157 return dconic_dxdy_at_t(a, weight, t).asSkVector(); |
94 } | 158 } |
95 | 159 |
96 static SkVector (* const CurveSlopeAtT[])(const SkPoint[], double ) = { | 160 static SkVector fcubic_dxdy_at_t(const SkPoint a[4], SkScalar weight, double t)
{ |
| 161 return dcubic_dxdy_at_t(a, weight, t).asSkVector(); |
| 162 } |
| 163 |
| 164 static SkVector (* const CurveSlopeAtT[])(const SkPoint[], SkScalar , double ) =
{ |
97 NULL, | 165 NULL, |
98 fline_dxdy_at_t, | 166 fline_dxdy_at_t, |
99 fquad_dxdy_at_t, | 167 fquad_dxdy_at_t, |
| 168 fconic_dxdy_at_t, |
100 fcubic_dxdy_at_t | 169 fcubic_dxdy_at_t |
101 }; | 170 }; |
102 | 171 |
103 static SkPoint quad_top(const SkPoint a[3], double startT, double endT) { | 172 static SkPoint quad_top(const SkPoint a[3], SkScalar , double startT, double end
T) { |
104 SkDQuad quad; | 173 SkDQuad quad; |
105 quad.set(a); | 174 quad.set(a); |
106 SkDPoint topPt = quad.top(startT, endT); | 175 SkDPoint topPt = quad.top(startT, endT); |
107 return topPt.asSkPoint(); | 176 return topPt.asSkPoint(); |
108 } | 177 } |
109 | 178 |
110 static SkPoint cubic_top(const SkPoint a[4], double startT, double endT) { | 179 static SkPoint conic_top(const SkPoint a[3], SkScalar weight, double startT, dou
ble endT) { |
| 180 SkDConic conic; |
| 181 conic.set(a, weight); |
| 182 SkDPoint topPt = conic.top(startT, endT); |
| 183 return topPt.asSkPoint(); |
| 184 } |
| 185 |
| 186 static SkPoint cubic_top(const SkPoint a[4], SkScalar , double startT, double en
dT) { |
111 SkDCubic cubic; | 187 SkDCubic cubic; |
112 cubic.set(a); | 188 cubic.set(a); |
113 SkDPoint topPt = cubic.top(startT, endT); | 189 SkDPoint topPt = cubic.top(startT, endT); |
114 return topPt.asSkPoint(); | 190 return topPt.asSkPoint(); |
115 } | 191 } |
116 | 192 |
117 static SkPoint (* const CurveTop[])(const SkPoint[], double , double ) = { | 193 static SkPoint (* const CurveTop[])(const SkPoint[], SkScalar , double , double
) = { |
118 NULL, | 194 NULL, |
119 NULL, | 195 NULL, |
120 quad_top, | 196 quad_top, |
| 197 conic_top, |
121 cubic_top | 198 cubic_top |
122 }; | 199 }; |
123 | 200 |
124 static bool line_is_vertical(const SkPoint a[2], double startT, double endT) { | 201 static bool line_is_vertical(const SkPoint a[2], SkScalar , double startT, doubl
e endT) { |
125 SkDLine line; | 202 SkDLine line; |
126 line.set(a); | 203 line.set(a); |
127 SkDPoint dst[2] = { line.ptAtT(startT), line.ptAtT(endT) }; | 204 SkDPoint dst[2] = { line.ptAtT(startT), line.ptAtT(endT) }; |
128 return AlmostEqualUlps(dst[0].fX, dst[1].fX); | 205 return AlmostEqualUlps(dst[0].fX, dst[1].fX); |
129 } | 206 } |
130 | 207 |
131 static bool quad_is_vertical(const SkPoint a[3], double startT, double endT) { | 208 static bool quad_is_vertical(const SkPoint a[3], SkScalar , double startT, doubl
e endT) { |
132 SkDQuad quad; | 209 SkDQuad quad; |
133 quad.set(a); | 210 quad.set(a); |
134 SkDQuad dst = quad.subDivide(startT, endT); | 211 SkDQuad dst = quad.subDivide(startT, endT); |
135 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, d
st[2].fX); | 212 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, d
st[2].fX); |
136 } | 213 } |
137 | 214 |
138 static bool cubic_is_vertical(const SkPoint a[4], double startT, double endT) { | 215 static bool conic_is_vertical(const SkPoint a[3], SkScalar weight, double startT
, double endT) { |
| 216 SkDConic conic; |
| 217 conic.set(a, weight); |
| 218 SkDConic dst = conic.subDivide(startT, endT); |
| 219 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, d
st[2].fX); |
| 220 } |
| 221 |
| 222 static bool cubic_is_vertical(const SkPoint a[4], SkScalar , double startT, doub
le endT) { |
139 SkDCubic cubic; | 223 SkDCubic cubic; |
140 cubic.set(a); | 224 cubic.set(a); |
141 SkDCubic dst = cubic.subDivide(startT, endT); | 225 SkDCubic dst = cubic.subDivide(startT, endT); |
142 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, d
st[2].fX) | 226 return AlmostEqualUlps(dst[0].fX, dst[1].fX) && AlmostEqualUlps(dst[1].fX, d
st[2].fX) |
143 && AlmostEqualUlps(dst[2].fX, dst[3].fX); | 227 && AlmostEqualUlps(dst[2].fX, dst[3].fX); |
144 } | 228 } |
145 | 229 |
146 static bool (* const CurveIsVertical[])(const SkPoint[], double , double) = { | 230 static bool (* const CurveIsVertical[])(const SkPoint[], SkScalar , double , dou
ble) = { |
147 NULL, | 231 NULL, |
148 line_is_vertical, | 232 line_is_vertical, |
149 quad_is_vertical, | 233 quad_is_vertical, |
| 234 conic_is_vertical, |
150 cubic_is_vertical | 235 cubic_is_vertical |
151 }; | 236 }; |
152 | 237 |
153 static void line_intersect_ray(const SkPoint a[2], const SkDLine& ray, SkInterse
ctions* i) { | 238 static void line_intersect_ray(const SkPoint a[2], SkScalar , const SkDLine& ray
, |
| 239 SkIntersections* i) { |
154 SkDLine line; | 240 SkDLine line; |
155 line.set(a); | 241 line.set(a); |
156 i->intersectRay(line, ray); | 242 i->intersectRay(line, ray); |
157 } | 243 } |
158 | 244 |
159 static void quad_intersect_ray(const SkPoint a[3], const SkDLine& ray, SkInterse
ctions* i) { | 245 static void quad_intersect_ray(const SkPoint a[3], SkScalar , const SkDLine& ray
, |
| 246 SkIntersections* i) { |
160 SkDQuad quad; | 247 SkDQuad quad; |
161 quad.set(a); | 248 quad.set(a); |
162 i->intersectRay(quad, ray); | 249 i->intersectRay(quad, ray); |
163 } | 250 } |
164 | 251 |
165 static void cubic_intersect_ray(const SkPoint a[4], const SkDLine& ray, SkInters
ections* i) { | 252 static void conic_intersect_ray(const SkPoint a[3], SkScalar weight, const SkDLi
ne& ray, |
| 253 SkIntersections* i) { |
| 254 SkDConic conic; |
| 255 conic.set(a, weight); |
| 256 i->intersectRay(conic, ray); |
| 257 } |
| 258 |
| 259 static void cubic_intersect_ray(const SkPoint a[4], SkScalar , const SkDLine& ra
y, |
| 260 SkIntersections* i) { |
166 SkDCubic cubic; | 261 SkDCubic cubic; |
167 cubic.set(a); | 262 cubic.set(a); |
168 i->intersectRay(cubic, ray); | 263 i->intersectRay(cubic, ray); |
169 } | 264 } |
170 | 265 |
171 static void (* const CurveIntersectRay[])(const SkPoint[] , const SkDLine& , SkI
ntersections* ) = { | 266 static void (* const CurveIntersectRay[])(const SkPoint[] , SkScalar , const SkD
Line& , |
| 267 SkIntersections* ) = { |
172 NULL, | 268 NULL, |
173 line_intersect_ray, | 269 line_intersect_ray, |
174 quad_intersect_ray, | 270 quad_intersect_ray, |
| 271 conic_intersect_ray, |
175 cubic_intersect_ray | 272 cubic_intersect_ray |
176 }; | 273 }; |
177 | 274 |
178 #endif | 275 #endif |
OLD | NEW |