OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 | 7 |
8 #include "GrPathUtils.h" | 8 #include "GrPathUtils.h" |
9 | 9 |
10 #include "GrPoint.h" | 10 #include "GrPoint.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 } | 34 } |
35 | 35 |
36 static const int MAX_POINTS_PER_CURVE = 1 << 10; | 36 static const int MAX_POINTS_PER_CURVE = 1 << 10; |
37 static const SkScalar gMinCurveTol = SkFloatToScalar(0.0001f); | 37 static const SkScalar gMinCurveTol = SkFloatToScalar(0.0001f); |
38 | 38 |
39 uint32_t GrPathUtils::quadraticPointCount(const GrPoint points[], | 39 uint32_t GrPathUtils::quadraticPointCount(const GrPoint points[], |
40 SkScalar tol) { | 40 SkScalar tol) { |
41 if (tol < gMinCurveTol) { | 41 if (tol < gMinCurveTol) { |
42 tol = gMinCurveTol; | 42 tol = gMinCurveTol; |
43 } | 43 } |
44 GrAssert(tol > 0); | 44 SkASSERT(tol > 0); |
45 | 45 |
46 SkScalar d = points[1].distanceToLineSegmentBetween(points[0], points[2]); | 46 SkScalar d = points[1].distanceToLineSegmentBetween(points[0], points[2]); |
47 if (d <= tol) { | 47 if (d <= tol) { |
48 return 1; | 48 return 1; |
49 } else { | 49 } else { |
50 // Each time we subdivide, d should be cut in 4. So we need to | 50 // Each time we subdivide, d should be cut in 4. So we need to |
51 // subdivide x = log4(d/tol) times. x subdivisions creates 2^(x) | 51 // subdivide x = log4(d/tol) times. x subdivisions creates 2^(x) |
52 // points. | 52 // points. |
53 // 2^(log4(x)) = sqrt(x); | 53 // 2^(log4(x)) = sqrt(x); |
54 int temp = SkScalarCeil(SkScalarSqrt(SkScalarDiv(d, tol))); | 54 int temp = SkScalarCeil(SkScalarSqrt(SkScalarDiv(d, tol))); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 uint32_t a = generateQuadraticPoints(p0, q[0], r, tolSqd, points, pointsLeft
); | 86 uint32_t a = generateQuadraticPoints(p0, q[0], r, tolSqd, points, pointsLeft
); |
87 uint32_t b = generateQuadraticPoints(r, q[1], p2, tolSqd, points, pointsLeft
); | 87 uint32_t b = generateQuadraticPoints(r, q[1], p2, tolSqd, points, pointsLeft
); |
88 return a + b; | 88 return a + b; |
89 } | 89 } |
90 | 90 |
91 uint32_t GrPathUtils::cubicPointCount(const GrPoint points[], | 91 uint32_t GrPathUtils::cubicPointCount(const GrPoint points[], |
92 SkScalar tol) { | 92 SkScalar tol) { |
93 if (tol < gMinCurveTol) { | 93 if (tol < gMinCurveTol) { |
94 tol = gMinCurveTol; | 94 tol = gMinCurveTol; |
95 } | 95 } |
96 GrAssert(tol > 0); | 96 SkASSERT(tol > 0); |
97 | 97 |
98 SkScalar d = GrMax( | 98 SkScalar d = GrMax( |
99 points[1].distanceToLineSegmentBetweenSqd(points[0], points[3]), | 99 points[1].distanceToLineSegmentBetweenSqd(points[0], points[3]), |
100 points[2].distanceToLineSegmentBetweenSqd(points[0], points[3])); | 100 points[2].distanceToLineSegmentBetweenSqd(points[0], points[3])); |
101 d = SkScalarSqrt(d); | 101 d = SkScalarSqrt(d); |
102 if (d <= tol) { | 102 if (d <= tol) { |
103 return 1; | 103 return 1; |
104 } else { | 104 } else { |
105 int temp = SkScalarCeil(SkScalarSqrt(SkScalarDiv(d, tol))); | 105 int temp = SkScalarCeil(SkScalarSqrt(SkScalarDiv(d, tol))); |
106 int pow2 = GrNextPow2(temp); | 106 int pow2 = GrNextPow2(temp); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 uint32_t a = generateCubicPoints(p0, q[0], r[0], s, tolSqd, points, pointsLe
ft); | 142 uint32_t a = generateCubicPoints(p0, q[0], r[0], s, tolSqd, points, pointsLe
ft); |
143 uint32_t b = generateCubicPoints(s, r[1], q[2], p3, tolSqd, points, pointsLe
ft); | 143 uint32_t b = generateCubicPoints(s, r[1], q[2], p3, tolSqd, points, pointsLe
ft); |
144 return a + b; | 144 return a + b; |
145 } | 145 } |
146 | 146 |
147 int GrPathUtils::worstCasePointCount(const SkPath& path, int* subpaths, | 147 int GrPathUtils::worstCasePointCount(const SkPath& path, int* subpaths, |
148 SkScalar tol) { | 148 SkScalar tol) { |
149 if (tol < gMinCurveTol) { | 149 if (tol < gMinCurveTol) { |
150 tol = gMinCurveTol; | 150 tol = gMinCurveTol; |
151 } | 151 } |
152 GrAssert(tol > 0); | 152 SkASSERT(tol > 0); |
153 | 153 |
154 int pointCount = 0; | 154 int pointCount = 0; |
155 *subpaths = 1; | 155 *subpaths = 1; |
156 | 156 |
157 bool first = true; | 157 bool first = true; |
158 | 158 |
159 SkPath::Iter iter(path, false); | 159 SkPath::Iter iter(path, false); |
160 SkPath::Verb verb; | 160 SkPath::Verb verb; |
161 | 161 |
162 GrPoint pts[4]; | 162 GrPoint pts[4]; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 // It's a point. It should cover zero area. Just set the matrix such | 244 // It's a point. It should cover zero area. Just set the matrix such |
245 // that (u, v) will always be far away from the quad. | 245 // that (u, v) will always be far away from the quad. |
246 fM[0] = 0; fM[1] = 0; fM[2] = 100.f; | 246 fM[0] = 0; fM[1] = 0; fM[2] = 100.f; |
247 fM[3] = 0; fM[4] = 0; fM[5] = 100.f; | 247 fM[3] = 0; fM[4] = 0; fM[5] = 100.f; |
248 } | 248 } |
249 } else { | 249 } else { |
250 m.postConcat(UVpts); | 250 m.postConcat(UVpts); |
251 | 251 |
252 // The matrix should not have perspective. | 252 // The matrix should not have perspective. |
253 SkDEBUGCODE(static const SkScalar gTOL = SkFloatToScalar(1.f / 100.f)); | 253 SkDEBUGCODE(static const SkScalar gTOL = SkFloatToScalar(1.f / 100.f)); |
254 GrAssert(SkScalarAbs(m.get(SkMatrix::kMPersp0)) < gTOL); | 254 SkASSERT(SkScalarAbs(m.get(SkMatrix::kMPersp0)) < gTOL); |
255 GrAssert(SkScalarAbs(m.get(SkMatrix::kMPersp1)) < gTOL); | 255 SkASSERT(SkScalarAbs(m.get(SkMatrix::kMPersp1)) < gTOL); |
256 | 256 |
257 // It may not be normalized to have 1.0 in the bottom right | 257 // It may not be normalized to have 1.0 in the bottom right |
258 float m33 = m.get(SkMatrix::kMPersp2); | 258 float m33 = m.get(SkMatrix::kMPersp2); |
259 if (1.f != m33) { | 259 if (1.f != m33) { |
260 m33 = 1.f / m33; | 260 m33 = 1.f / m33; |
261 fM[0] = m33 * m.get(SkMatrix::kMScaleX); | 261 fM[0] = m33 * m.get(SkMatrix::kMScaleX); |
262 fM[1] = m33 * m.get(SkMatrix::kMSkewX); | 262 fM[1] = m33 * m.get(SkMatrix::kMSkewX); |
263 fM[2] = m33 * m.get(SkMatrix::kMTransX); | 263 fM[2] = m33 * m.get(SkMatrix::kMTransX); |
264 fM[3] = m33 * m.get(SkMatrix::kMSkewY); | 264 fM[3] = m33 * m.get(SkMatrix::kMSkewY); |
265 fM[4] = m33 * m.get(SkMatrix::kMScaleY); | 265 fM[4] = m33 * m.get(SkMatrix::kMScaleY); |
(...skipping 23 matching lines...) Expand all Loading... |
289 const SkPoint& d, | 289 const SkPoint& d, |
290 SkPath::Direction dir, | 290 SkPath::Direction dir, |
291 const SkPoint p) { | 291 const SkPoint p) { |
292 SkVector ap = p - a; | 292 SkVector ap = p - a; |
293 SkScalar apXab = ap.cross(ab); | 293 SkScalar apXab = ap.cross(ab); |
294 if (SkPath::kCW_Direction == dir) { | 294 if (SkPath::kCW_Direction == dir) { |
295 if (apXab > 0) { | 295 if (apXab > 0) { |
296 return false; | 296 return false; |
297 } | 297 } |
298 } else { | 298 } else { |
299 GrAssert(SkPath::kCCW_Direction == dir); | 299 SkASSERT(SkPath::kCCW_Direction == dir); |
300 if (apXab < 0) { | 300 if (apXab < 0) { |
301 return false; | 301 return false; |
302 } | 302 } |
303 } | 303 } |
304 | 304 |
305 SkVector dp = p - d; | 305 SkVector dp = p - d; |
306 SkScalar dpXdc = dp.cross(dc); | 306 SkScalar dpXdc = dp.cross(dc); |
307 if (SkPath::kCW_Direction == dir) { | 307 if (SkPath::kCW_Direction == dir) { |
308 if (dpXdc < 0) { | 308 if (dpXdc < 0) { |
309 return false; | 309 return false; |
310 } | 310 } |
311 } else { | 311 } else { |
312 GrAssert(SkPath::kCCW_Direction == dir); | 312 SkASSERT(SkPath::kCCW_Direction == dir); |
313 if (dpXdc > 0) { | 313 if (dpXdc > 0) { |
314 return false; | 314 return false; |
315 } | 315 } |
316 } | 316 } |
317 return true; | 317 return true; |
318 } | 318 } |
319 | 319 |
320 void convert_noninflect_cubic_to_quads(const SkPoint p[4], | 320 void convert_noninflect_cubic_to_quads(const SkPoint p[4], |
321 SkScalar toleranceSqd, | 321 SkScalar toleranceSqd, |
322 bool constrainWithinTangents, | 322 bool constrainWithinTangents, |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 // base tolerance is 1 pixel. | 469 // base tolerance is 1 pixel. |
470 static const SkScalar kTolerance = SK_Scalar1; | 470 static const SkScalar kTolerance = SK_Scalar1; |
471 const SkScalar tolSqd = SkScalarSquare(SkScalarMul(tolScale, kTolerance)); | 471 const SkScalar tolSqd = SkScalarSquare(SkScalarMul(tolScale, kTolerance)); |
472 | 472 |
473 for (int i = 0; i < count; ++i) { | 473 for (int i = 0; i < count; ++i) { |
474 SkPoint* cubic = chopped + 3*i; | 474 SkPoint* cubic = chopped + 3*i; |
475 convert_noninflect_cubic_to_quads(cubic, tolSqd, constrainWithinTangents
, dir, quads); | 475 convert_noninflect_cubic_to_quads(cubic, tolSqd, constrainWithinTangents
, dir, quads); |
476 } | 476 } |
477 | 477 |
478 } | 478 } |
OLD | NEW |