OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 | 7 |
8 #include "SkGeometry.h" | 8 #include "SkGeometry.h" |
9 #include "SkMatrix.h" | 9 #include "SkMatrix.h" |
| 10 #include "Sk2x.h" |
10 | 11 |
11 /** If defined, this makes eval_quad and eval_cubic do more setup (sometimes | 12 /** If defined, this makes eval_quad and eval_cubic do more setup (sometimes |
12 involving integer multiplies by 2 or 3, but fewer calls to SkScalarMul. | 13 involving integer multiplies by 2 or 3, but fewer calls to SkScalarMul. |
13 May also introduce overflow of fixed when we compute our setup. | 14 May also introduce overflow of fixed when we compute our setup. |
14 */ | 15 */ |
15 // #define DIRECT_EVAL_OF_POLYNOMIALS | 16 // #define DIRECT_EVAL_OF_POLYNOMIALS |
16 | 17 |
17 //////////////////////////////////////////////////////////////////////// | 18 //////////////////////////////////////////////////////////////////////// |
18 | 19 |
19 static int is_not_monotonic(SkScalar a, SkScalar b, SkScalar c) { | 20 static int is_not_monotonic(SkScalar a, SkScalar b, SkScalar c) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 | 121 |
121 if (pt) { | 122 if (pt) { |
122 pt->set(eval_quad(&src[0].fX, t), eval_quad(&src[0].fY, t)); | 123 pt->set(eval_quad(&src[0].fX, t), eval_quad(&src[0].fY, t)); |
123 } | 124 } |
124 if (tangent) { | 125 if (tangent) { |
125 tangent->set(eval_quad_derivative(&src[0].fX, t), | 126 tangent->set(eval_quad_derivative(&src[0].fX, t), |
126 eval_quad_derivative(&src[0].fY, t)); | 127 eval_quad_derivative(&src[0].fY, t)); |
127 } | 128 } |
128 } | 129 } |
129 | 130 |
130 #include "Sk2x.h" | |
131 | |
132 SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { | 131 SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { |
133 SkASSERT(src); | 132 SkASSERT(src); |
134 SkASSERT(t >= 0 && t <= SK_Scalar1); | 133 SkASSERT(t >= 0 && t <= SK_Scalar1); |
135 | 134 |
136 const Sk2f t2(t); | 135 const Sk2f t2(t); |
137 | 136 |
138 Sk2f P0 = Sk2f::Load(&src[0].fX); | 137 Sk2f P0 = Sk2f::Load(&src[0].fX); |
139 Sk2f P1 = Sk2f::Load(&src[1].fX); | 138 Sk2f P1 = Sk2f::Load(&src[1].fX); |
140 Sk2f P2 = Sk2f::Load(&src[2].fX); | 139 Sk2f P2 = Sk2f::Load(&src[2].fX); |
141 | 140 |
142 Sk2f B = P1 - P0; | 141 Sk2f B = P1 - P0; |
143 Sk2f A = P2 - P1 - B; | 142 Sk2f A = P2 - P1 - B; |
144 | 143 |
145 SkPoint result; | 144 SkPoint result; |
146 ((A * t2 + B+B) * t2 + P0).store(&result.fX); | 145 ((A * t2 + B+B) * t2 + P0).store(&result.fX); |
147 return result; | 146 return result; |
148 } | 147 } |
149 | 148 |
| 149 SkVector SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t) { |
| 150 SkASSERT(src); |
| 151 SkASSERT(t >= 0 && t <= SK_Scalar1); |
| 152 |
| 153 Sk2f P0 = Sk2f::Load(&src[0].fX); |
| 154 Sk2f P1 = Sk2f::Load(&src[1].fX); |
| 155 Sk2f P2 = Sk2f::Load(&src[2].fX); |
| 156 |
| 157 Sk2f B = P1 - P0; |
| 158 Sk2f A = P2 - P1 - B; |
| 159 Sk2f T = A * Sk2f(t) + B; |
| 160 |
| 161 SkVector result; |
| 162 (T + T).store(&result.fX); |
| 163 return result; |
| 164 } |
| 165 |
150 static void interp_quad_coords(const SkScalar* src, SkScalar* dst, SkScalar t) { | 166 static void interp_quad_coords(const SkScalar* src, SkScalar* dst, SkScalar t) { |
151 SkScalar ab = SkScalarInterp(src[0], src[2], t); | 167 SkScalar ab = SkScalarInterp(src[0], src[2], t); |
152 SkScalar bc = SkScalarInterp(src[2], src[4], t); | 168 SkScalar bc = SkScalarInterp(src[2], src[4], t); |
153 | 169 |
154 dst[0] = src[0]; | 170 dst[0] = src[0]; |
155 dst[2] = ab; | 171 dst[2] = ab; |
156 dst[4] = SkScalarInterp(ab, bc, t); | 172 dst[4] = SkScalarInterp(ab, bc, t); |
157 dst[6] = bc; | 173 dst[6] = bc; |
158 dst[8] = src[4]; | 174 dst[8] = src[4]; |
159 } | 175 } |
160 | 176 |
161 void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t) { | 177 void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t) { |
162 SkASSERT(t > 0 && t < SK_Scalar1); | 178 SkASSERT(t > 0 && t < SK_Scalar1); |
163 | 179 |
164 interp_quad_coords(&src[0].fX, &dst[0].fX, t); | 180 interp_quad_coords(&src[0].fX, &dst[0].fX, t); |
165 interp_quad_coords(&src[0].fY, &dst[0].fY, t); | 181 interp_quad_coords(&src[0].fY, &dst[0].fY, t); |
166 } | 182 } |
167 | 183 |
| 184 static inline Sk2s interp(const Sk2s& v0, const Sk2s& v1, const Sk2s& t) { |
| 185 return v0 + (v1 - v0) * t; |
| 186 } |
| 187 |
| 188 void SkChopQuadAt2(const SkPoint src[3], SkPoint dst[5], SkScalar t) { |
| 189 SkASSERT(t > 0 && t < SK_Scalar1); |
| 190 |
| 191 Sk2s p0 = Sk2f::Load(&src[0].fX); |
| 192 Sk2s p1 = Sk2f::Load(&src[1].fX); |
| 193 Sk2s p2 = Sk2f::Load(&src[2].fX); |
| 194 Sk2s tt = Sk2s(t); |
| 195 |
| 196 Sk2s p01 = interp(p0, p1, tt); |
| 197 Sk2s p12 = interp(p1, p2, tt); |
| 198 |
| 199 p0.store(&dst[0].fX); |
| 200 p01.store(&dst[1].fX); |
| 201 interp(p01, p12, tt).store(&dst[2].fX); |
| 202 p12.store(&dst[3].fX); |
| 203 p2.store(&dst[4].fX); |
| 204 } |
| 205 |
168 void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) { | 206 void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) { |
169 SkScalar x01 = SkScalarAve(src[0].fX, src[1].fX); | 207 SkScalar x01 = SkScalarAve(src[0].fX, src[1].fX); |
170 SkScalar y01 = SkScalarAve(src[0].fY, src[1].fY); | 208 SkScalar y01 = SkScalarAve(src[0].fY, src[1].fY); |
171 SkScalar x12 = SkScalarAve(src[1].fX, src[2].fX); | 209 SkScalar x12 = SkScalarAve(src[1].fX, src[2].fX); |
172 SkScalar y12 = SkScalarAve(src[1].fY, src[2].fY); | 210 SkScalar y12 = SkScalarAve(src[1].fY, src[2].fY); |
173 | 211 |
174 dst[0] = src[0]; | 212 dst[0] = src[0]; |
175 dst[1].set(x01, y01); | 213 dst[1].set(x01, y01); |
176 dst[2].set(SkScalarAve(x01, x12), SkScalarAve(y01, y12)); | 214 dst[2].set(SkScalarAve(x01, x12), SkScalarAve(y01, y12)); |
177 dst[3].set(x12, y12); | 215 dst[3].set(x12, y12); |
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1479 matrix.preScale(SK_Scalar1, -SK_Scalar1); | 1517 matrix.preScale(SK_Scalar1, -SK_Scalar1); |
1480 } | 1518 } |
1481 if (userMatrix) { | 1519 if (userMatrix) { |
1482 matrix.postConcat(*userMatrix); | 1520 matrix.postConcat(*userMatrix); |
1483 } | 1521 } |
1484 for (int i = 0; i < conicCount; ++i) { | 1522 for (int i = 0; i < conicCount; ++i) { |
1485 matrix.mapPoints(dst[i].fPts, 3); | 1523 matrix.mapPoints(dst[i].fPts, 3); |
1486 } | 1524 } |
1487 return conicCount; | 1525 return conicCount; |
1488 } | 1526 } |
OLD | NEW |