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 | 8 |
9 #include "SkEdge.h" | 9 #include "SkEdge.h" |
10 #include "SkFDot6.h" | 10 #include "SkFDot6.h" |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 // shift down dist (it is currently in dot6) | 165 // shift down dist (it is currently in dot6) |
166 // down by 5 should give us 1/2 pixel accuracy (assuming our dist is accurat
e...) | 166 // down by 5 should give us 1/2 pixel accuracy (assuming our dist is accurat
e...) |
167 // this is chosen by heuristic: make it as big as possible (to minimize segm
ents) | 167 // this is chosen by heuristic: make it as big as possible (to minimize segm
ents) |
168 // ... but small enough so that our curves still look smooth | 168 // ... but small enough so that our curves still look smooth |
169 dist = (dist + (1 << 4)) >> 5; | 169 dist = (dist + (1 << 4)) >> 5; |
170 | 170 |
171 // each subdivision (shift value) cuts this dist (error) by 1/4 | 171 // each subdivision (shift value) cuts this dist (error) by 1/4 |
172 return (32 - SkCLZ(dist)) >> 1; | 172 return (32 - SkCLZ(dist)) >> 1; |
173 } | 173 } |
174 | 174 |
175 int SkQuadraticEdge::setQuadratic(const SkPoint pts[3], int shift) | 175 bool SkQuadraticEdge::setQuadraticWithoutUpdate(const SkPoint pts[3], int shift)
{ |
176 { | |
177 SkFDot6 x0, y0, x1, y1, x2, y2; | 176 SkFDot6 x0, y0, x1, y1, x2, y2; |
178 | 177 |
179 { | 178 { |
180 #ifdef SK_RASTERIZE_EVEN_ROUNDING | 179 #ifdef SK_RASTERIZE_EVEN_ROUNDING |
181 x0 = SkScalarRoundToFDot6(pts[0].fX, shift); | 180 x0 = SkScalarRoundToFDot6(pts[0].fX, shift); |
182 y0 = SkScalarRoundToFDot6(pts[0].fY, shift); | 181 y0 = SkScalarRoundToFDot6(pts[0].fY, shift); |
183 x1 = SkScalarRoundToFDot6(pts[1].fX, shift); | 182 x1 = SkScalarRoundToFDot6(pts[1].fX, shift); |
184 y1 = SkScalarRoundToFDot6(pts[1].fY, shift); | 183 y1 = SkScalarRoundToFDot6(pts[1].fY, shift); |
185 x2 = SkScalarRoundToFDot6(pts[2].fX, shift); | 184 x2 = SkScalarRoundToFDot6(pts[2].fX, shift); |
186 y2 = SkScalarRoundToFDot6(pts[2].fY, shift); | 185 y2 = SkScalarRoundToFDot6(pts[2].fY, shift); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 A = SkFDot6ToFixedDiv2(y0 - y1 - y1 + y2); // 1/2 the real value | 258 A = SkFDot6ToFixedDiv2(y0 - y1 - y1 + y2); // 1/2 the real value |
260 B = SkFDot6ToFixed(y1 - y0); // 1/2 the real value | 259 B = SkFDot6ToFixed(y1 - y0); // 1/2 the real value |
261 | 260 |
262 fQy = SkFDot6ToFixed(y0); | 261 fQy = SkFDot6ToFixed(y0); |
263 fQDy = B + (A >> shift); // biased by shift | 262 fQDy = B + (A >> shift); // biased by shift |
264 fQDDy = A >> (shift - 1); // biased by shift | 263 fQDDy = A >> (shift - 1); // biased by shift |
265 | 264 |
266 fQLastX = SkFDot6ToFixed(x2); | 265 fQLastX = SkFDot6ToFixed(x2); |
267 fQLastY = SkFDot6ToFixed(y2); | 266 fQLastY = SkFDot6ToFixed(y2); |
268 | 267 |
| 268 return true; |
| 269 } |
| 270 |
| 271 int SkQuadraticEdge::setQuadratic(const SkPoint pts[3], int shift) { |
| 272 if (!setQuadraticWithoutUpdate(pts, shift)) { |
| 273 return 0; |
| 274 } |
269 return this->updateQuadratic(); | 275 return this->updateQuadratic(); |
270 } | 276 } |
271 | 277 |
272 int SkQuadraticEdge::updateQuadratic() | 278 int SkQuadraticEdge::updateQuadratic() |
273 { | 279 { |
274 int success; | 280 int success; |
275 int count = fCurveCount; | 281 int count = fCurveCount; |
276 SkFixed oldx = fQx; | 282 SkFixed oldx = fQx; |
277 SkFixed oldy = fQy; | 283 SkFixed oldy = fQy; |
278 SkFixed dx = fQDx; | 284 SkFixed dx = fQDx; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 */ | 331 */ |
326 static SkFDot6 cubic_delta_from_line(SkFDot6 a, SkFDot6 b, SkFDot6 c, SkFDot6 d) | 332 static SkFDot6 cubic_delta_from_line(SkFDot6 a, SkFDot6 b, SkFDot6 c, SkFDot6 d) |
327 { | 333 { |
328 // since our parameters may be negative, we don't use << to avoid ASAN warni
ngs | 334 // since our parameters may be negative, we don't use << to avoid ASAN warni
ngs |
329 SkFDot6 oneThird = (a*8 - b*15 + 6*c + d) * 19 >> 9; | 335 SkFDot6 oneThird = (a*8 - b*15 + 6*c + d) * 19 >> 9; |
330 SkFDot6 twoThird = (a + 6*b - c*15 + d*8) * 19 >> 9; | 336 SkFDot6 twoThird = (a + 6*b - c*15 + d*8) * 19 >> 9; |
331 | 337 |
332 return SkMax32(SkAbs32(oneThird), SkAbs32(twoThird)); | 338 return SkMax32(SkAbs32(oneThird), SkAbs32(twoThird)); |
333 } | 339 } |
334 | 340 |
335 int SkCubicEdge::setCubic(const SkPoint pts[4], int shift) { | 341 bool SkCubicEdge::setCubicWithoutUpdate(const SkPoint pts[4], int shift) { |
336 SkFDot6 x0, y0, x1, y1, x2, y2, x3, y3; | 342 SkFDot6 x0, y0, x1, y1, x2, y2, x3, y3; |
337 | 343 |
338 { | 344 { |
339 #ifdef SK_RASTERIZE_EVEN_ROUNDING | 345 #ifdef SK_RASTERIZE_EVEN_ROUNDING |
340 x0 = SkScalarRoundToFDot6(pts[0].fX, shift); | 346 x0 = SkScalarRoundToFDot6(pts[0].fX, shift); |
341 y0 = SkScalarRoundToFDot6(pts[0].fY, shift); | 347 y0 = SkScalarRoundToFDot6(pts[0].fY, shift); |
342 x1 = SkScalarRoundToFDot6(pts[1].fX, shift); | 348 x1 = SkScalarRoundToFDot6(pts[1].fX, shift); |
343 y1 = SkScalarRoundToFDot6(pts[1].fY, shift); | 349 y1 = SkScalarRoundToFDot6(pts[1].fY, shift); |
344 x2 = SkScalarRoundToFDot6(pts[2].fX, shift); | 350 x2 = SkScalarRoundToFDot6(pts[2].fX, shift); |
345 y2 = SkScalarRoundToFDot6(pts[2].fY, shift); | 351 y2 = SkScalarRoundToFDot6(pts[2].fY, shift); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 D = SkFDot6UpShift(y3 + 3 * (y1 - y2) - y0, upShift); | 427 D = SkFDot6UpShift(y3 + 3 * (y1 - y2) - y0, upShift); |
422 | 428 |
423 fCy = SkFDot6ToFixed(y0); | 429 fCy = SkFDot6ToFixed(y0); |
424 fCDy = B + (C >> shift) + (D >> 2*shift); // biased by shift | 430 fCDy = B + (C >> shift) + (D >> 2*shift); // biased by shift |
425 fCDDy = 2*C + (3*D >> (shift - 1)); // biased by 2*shift | 431 fCDDy = 2*C + (3*D >> (shift - 1)); // biased by 2*shift |
426 fCDDDy = 3*D >> (shift - 1); // biased by 2*shift | 432 fCDDDy = 3*D >> (shift - 1); // biased by 2*shift |
427 | 433 |
428 fCLastX = SkFDot6ToFixed(x3); | 434 fCLastX = SkFDot6ToFixed(x3); |
429 fCLastY = SkFDot6ToFixed(y3); | 435 fCLastY = SkFDot6ToFixed(y3); |
430 | 436 |
| 437 return true; |
| 438 } |
| 439 |
| 440 int SkCubicEdge::setCubic(const SkPoint pts[4], int shift) { |
| 441 if (!this->setCubicWithoutUpdate(pts, shift)) { |
| 442 return 0; |
| 443 } |
431 return this->updateCubic(); | 444 return this->updateCubic(); |
432 } | 445 } |
433 | 446 |
434 int SkCubicEdge::updateCubic() | 447 int SkCubicEdge::updateCubic() |
435 { | 448 { |
436 int success; | 449 int success; |
437 int count = fCurveCount; | 450 int count = fCurveCount; |
438 SkFixed oldx = fCx; | 451 SkFixed oldx = fCx; |
439 SkFixed oldy = fCy; | 452 SkFixed oldy = fCy; |
440 SkFixed newx, newy; | 453 SkFixed newx, newy; |
(...skipping 29 matching lines...) Expand all Loading... |
470 success = this->updateLine(oldx, oldy, newx, newy); | 483 success = this->updateLine(oldx, oldy, newx, newy); |
471 oldx = newx; | 484 oldx = newx; |
472 oldy = newy; | 485 oldy = newy; |
473 } while (count < 0 && !success); | 486 } while (count < 0 && !success); |
474 | 487 |
475 fCx = newx; | 488 fCx = newx; |
476 fCy = newy; | 489 fCy = newy; |
477 fCurveCount = SkToS8(count); | 490 fCurveCount = SkToS8(count); |
478 return success; | 491 return success; |
479 } | 492 } |
OLD | NEW |