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 #ifndef SkGeometry_DEFINED | 8 #ifndef SkGeometry_DEFINED |
9 #define SkGeometry_DEFINED | 9 #define SkGeometry_DEFINED |
10 | 10 |
11 #include "SkMatrix.h" | 11 #include "SkMatrix.h" |
12 #include "SkNx.h" | 12 #include "SkNx.h" |
13 | 13 |
14 static inline Sk2s from_point(const SkPoint& point) { | 14 static inline Sk2s from_point(const SkPoint& point) { |
15 return Sk2s::Load(&point.fX); | 15 return Sk2s::Load(&point.fX); |
16 } | 16 } |
17 | 17 |
18 static inline SkPoint to_point(const Sk2s& x) { | 18 static inline SkPoint to_point(const Sk2s& x) { |
19 SkPoint point; | 19 SkPoint point; |
20 x.store(&point.fX); | 20 x.store(&point.fX); |
21 return point; | 21 return point; |
22 } | 22 } |
23 | 23 |
24 static inline Sk2s sk2s_cubic_eval(const Sk2s& A, const Sk2s& B, const Sk2s& C,
const Sk2s& D, | 24 static inline Sk2s sk2s_cubic_eval(const Sk2s& A, const Sk2s& B, const Sk2s& C,
const Sk2s& D, |
25 const Sk2s& t) { | 25 const Sk2s& t) { |
26 return ((A * t + B) * t + C) * t + D; | 26 return ((A * t + B) * t + C) * t + D;» |
| 27 } |
| 28 |
| 29 static Sk2s times_2(const Sk2s& value) { |
| 30 return value + value; |
27 } | 31 } |
28 | 32 |
29 /** Given a quadratic equation Ax^2 + Bx + C = 0, return 0, 1, 2 roots for the | 33 /** Given a quadratic equation Ax^2 + Bx + C = 0, return 0, 1, 2 roots for the |
30 equation. | 34 equation. |
31 */ | 35 */ |
32 int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]); | 36 int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]); |
33 | 37 |
34 /////////////////////////////////////////////////////////////////////////////// | 38 /////////////////////////////////////////////////////////////////////////////// |
35 | 39 |
36 SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t); | 40 SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t); |
37 SkPoint SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t); | 41 SkPoint SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t); |
38 | 42 |
39 /** Set pt to the point on the src quadratic specified by t. t must be | 43 /** Set pt to the point on the src quadratic specified by t. t must be |
40 0 <= t <= 1.0 | 44 0 <= t <= 1.0 |
41 */ | 45 */ |
42 void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tange
nt = nullptr); | 46 void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tange
nt = nullptr); |
43 | 47 |
44 /** | 48 /** |
45 * output is : eval(t) == coeff[0] * t^2 + coeff[1] * t + coeff[2] | 49 * output is : eval(t) == coeff[0] * t^2 + coeff[1] * t + coeff[2]» |
46 */ | 50 */» |
47 void SkQuadToCoeff(const SkPoint pts[3], SkPoint coeff[3]); | 51 void SkQuadToCoeff(const SkPoint pts[3], SkPoint coeff[3]); |
48 | 52 |
49 /** | 53 /** |
50 * output is : eval(t) == coeff[0] * t^3 + coeff[1] * t^2 + coeff[2] * t + coef
f[3] | 54 * output is : eval(t) == coeff[0] * t^3 + coeff[1] * t^2 + coeff[2] * t + coef
f[3] |
51 */ | 55 */ |
52 void SkCubicToCoeff(const SkPoint pts[4], SkPoint coeff[4]); | 56 void SkCubicToCoeff(const SkPoint pts[4], SkPoint coeff[4]); |
53 | 57 |
54 /** Given a src quadratic bezier, chop it at the specified t value, | 58 /** Given a src quadratic bezier, chop it at the specified t value, |
55 where 0 < t < 1, and return the two new quadratics in dst: | 59 where 0 < t < 1, and return the two new quadratics in dst: |
56 dst[0..2] and dst[2..4] | 60 dst[0..2] and dst[2..4] |
57 */ | 61 */ |
58 void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t); | 62 void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 | 238 |
235 /** | 239 /** |
236 * Given a t-value [0...1] return its position and/or tangent. | 240 * Given a t-value [0...1] return its position and/or tangent. |
237 * If pos is not null, return its position at the t-value. | 241 * If pos is not null, return its position at the t-value. |
238 * If tangent is not null, return its tangent at the t-value. NOTE the | 242 * If tangent is not null, return its tangent at the t-value. NOTE the |
239 * tangent value's length is arbitrary, and only its direction should | 243 * tangent value's length is arbitrary, and only its direction should |
240 * be used. | 244 * be used. |
241 */ | 245 */ |
242 void evalAt(SkScalar t, SkPoint* pos, SkVector* tangent = nullptr) const; | 246 void evalAt(SkScalar t, SkPoint* pos, SkVector* tangent = nullptr) const; |
243 void chopAt(SkScalar t, SkConic dst[2]) const; | 247 void chopAt(SkScalar t, SkConic dst[2]) const; |
| 248 void chopAt(SkScalar t1, SkScalar t2, SkConic* dst) const; |
244 void chop(SkConic dst[2]) const; | 249 void chop(SkConic dst[2]) const; |
245 | 250 |
246 SkPoint evalAt(SkScalar t) const; | 251 SkPoint evalAt(SkScalar t) const; |
247 SkVector evalTangentAt(SkScalar t) const; | 252 SkVector evalTangentAt(SkScalar t) const; |
248 | 253 |
249 void computeAsQuadError(SkVector* err) const; | 254 void computeAsQuadError(SkVector* err) const; |
250 bool asQuadTol(SkScalar tol) const; | 255 bool asQuadTol(SkScalar tol) const; |
251 | 256 |
252 /** | 257 /** |
253 * return the power-of-2 number of quads needed to approximate this conic | 258 * return the power-of-2 number of quads needed to approximate this conic |
(...skipping 26 matching lines...) Expand all Loading... |
280 | 285 |
281 static SkScalar TransformW(const SkPoint[3], SkScalar w, const SkMatrix&); | 286 static SkScalar TransformW(const SkPoint[3], SkScalar w, const SkMatrix&); |
282 | 287 |
283 enum { | 288 enum { |
284 kMaxConicsForArc = 5 | 289 kMaxConicsForArc = 5 |
285 }; | 290 }; |
286 static int BuildUnitArc(const SkVector& start, const SkVector& stop, SkRotat
ionDirection, | 291 static int BuildUnitArc(const SkVector& start, const SkVector& stop, SkRotat
ionDirection, |
287 const SkMatrix*, SkConic conics[kMaxConicsForArc]); | 292 const SkMatrix*, SkConic conics[kMaxConicsForArc]); |
288 }; | 293 }; |
289 | 294 |
| 295 // inline helpers are contained in a namespace to avoid external leakage to frag
ile SkNx members |
| 296 namespace { |
| 297 |
| 298 /** |
| 299 * use for : eval(t) == A * t^2 + B * t + C |
| 300 */ |
| 301 struct SkQuadCoeff { |
| 302 SkQuadCoeff() {} |
| 303 |
| 304 SkQuadCoeff(const Sk2s& A, const Sk2s& B, const Sk2s& C) |
| 305 : fA(A) |
| 306 , fB(B) |
| 307 , fC(C) |
| 308 { |
| 309 } |
| 310 |
| 311 SkQuadCoeff(const SkPoint src[3]) { |
| 312 fC = from_point(src[0]); |
| 313 Sk2s P1 = from_point(src[1]); |
| 314 Sk2s P2 = from_point(src[2]); |
| 315 fB = times_2(P1 - fC); |
| 316 fA = P2 - times_2(P1) + fC; |
| 317 } |
| 318 |
| 319 Sk2s eval(SkScalar t) { |
| 320 Sk2s tt(t); |
| 321 return eval(tt); |
| 322 } |
| 323 |
| 324 Sk2s eval(const Sk2s& tt) { |
| 325 return (fA * tt + fB) * tt + fC; |
| 326 } |
| 327 |
| 328 Sk2s fA; |
| 329 Sk2s fB; |
| 330 Sk2s fC; |
| 331 }; |
| 332 |
| 333 struct SkConicCoeff { |
| 334 SkConicCoeff(const SkConic& conic) { |
| 335 Sk2s p0 = from_point(conic.fPts[0]); |
| 336 Sk2s p1 = from_point(conic.fPts[1]); |
| 337 Sk2s p2 = from_point(conic.fPts[2]); |
| 338 Sk2s ww(conic.fW); |
| 339 |
| 340 Sk2s p1w = p1 * ww; |
| 341 fNumer.fC = p0; |
| 342 fNumer.fA = p2 - times_2(p1w) + p0; |
| 343 fNumer.fB = times_2(p1w - p0); |
| 344 |
| 345 fDenom.fC = Sk2s(1); |
| 346 fDenom.fB = times_2(ww - fDenom.fC); |
| 347 fDenom.fA = Sk2s(0) - fDenom.fB; |
| 348 } |
| 349 |
| 350 Sk2s eval(SkScalar t) { |
| 351 Sk2s tt(t); |
| 352 Sk2s numer = fNumer.eval(tt); |
| 353 Sk2s denom = fDenom.eval(tt); |
| 354 return numer / denom; |
| 355 } |
| 356 |
| 357 SkQuadCoeff fNumer; |
| 358 SkQuadCoeff fDenom; |
| 359 }; |
| 360 |
| 361 struct SkCubicCoeff { |
| 362 SkCubicCoeff(const SkPoint src[4]) { |
| 363 Sk2s P0 = from_point(src[0]); |
| 364 Sk2s P1 = from_point(src[1]); |
| 365 Sk2s P2 = from_point(src[2]); |
| 366 Sk2s P3 = from_point(src[3]); |
| 367 Sk2s three(3); |
| 368 fA = P3 + three * (P1 - P2) - P0; |
| 369 fB = three * (P2 - times_2(P1) + P0); |
| 370 fC = three * (P1 - P0); |
| 371 fD = P0; |
| 372 } |
| 373 |
| 374 Sk2s eval(SkScalar t) { |
| 375 Sk2s tt(t); |
| 376 return eval(tt); |
| 377 } |
| 378 |
| 379 Sk2s eval(const Sk2s& t) { |
| 380 return ((fA * t + fB) * t + fC) * t + fD; |
| 381 } |
| 382 |
| 383 Sk2s fA; |
| 384 Sk2s fB; |
| 385 Sk2s fC; |
| 386 Sk2s fD; |
| 387 }; |
| 388 |
| 389 } |
| 390 |
290 #include "SkTemplates.h" | 391 #include "SkTemplates.h" |
291 | 392 |
292 /** | 393 /** |
293 * Help class to allocate storage for approximating a conic with N quads. | 394 * Help class to allocate storage for approximating a conic with N quads. |
294 */ | 395 */ |
295 class SkAutoConicToQuads { | 396 class SkAutoConicToQuads { |
296 public: | 397 public: |
297 SkAutoConicToQuads() : fQuadCount(0) {} | 398 SkAutoConicToQuads() : fQuadCount(0) {} |
298 | 399 |
299 /** | 400 /** |
(...skipping 28 matching lines...) Expand all Loading... |
328 private: | 429 private: |
329 enum { | 430 enum { |
330 kQuadCount = 8, // should handle most conics | 431 kQuadCount = 8, // should handle most conics |
331 kPointCount = 1 + 2 * kQuadCount, | 432 kPointCount = 1 + 2 * kQuadCount, |
332 }; | 433 }; |
333 SkAutoSTMalloc<kPointCount, SkPoint> fStorage; | 434 SkAutoSTMalloc<kPointCount, SkPoint> fStorage; |
334 int fQuadCount; // #quads for current usage | 435 int fQuadCount; // #quads for current usage |
335 }; | 436 }; |
336 | 437 |
337 #endif | 438 #endif |
OLD | NEW |