| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkEdge.h" | 10 #include "SkEdge.h" |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 use 16/512 to approximate 1/27 | 325 use 16/512 to approximate 1/27 |
| 326 */ | 326 */ |
| 327 static SkFDot6 cubic_delta_from_line(SkFDot6 a, SkFDot6 b, SkFDot6 c, SkFDot6 d) | 327 static SkFDot6 cubic_delta_from_line(SkFDot6 a, SkFDot6 b, SkFDot6 c, SkFDot6 d) |
| 328 { | 328 { |
| 329 SkFDot6 oneThird = ((a << 3) - ((b << 4) - b) + 6*c + d) * 19 >> 9; | 329 SkFDot6 oneThird = ((a << 3) - ((b << 4) - b) + 6*c + d) * 19 >> 9; |
| 330 SkFDot6 twoThird = (a + 6*b - ((c << 4) - c) + (d << 3)) * 19 >> 9; | 330 SkFDot6 twoThird = (a + 6*b - ((c << 4) - c) + (d << 3)) * 19 >> 9; |
| 331 | 331 |
| 332 return SkMax32(SkAbs32(oneThird), SkAbs32(twoThird)); | 332 return SkMax32(SkAbs32(oneThird), SkAbs32(twoThird)); |
| 333 } | 333 } |
| 334 | 334 |
| 335 int SkCubicEdge::setCubic(const SkPoint pts[4], const SkIRect* clip, int shift) | 335 int SkCubicEdge::setCubic(const SkPoint pts[4], int shift) { |
| 336 { | |
| 337 SkFDot6 x0, y0, x1, y1, x2, y2, x3, y3; | 336 SkFDot6 x0, y0, x1, y1, x2, y2, x3, y3; |
| 338 | 337 |
| 339 { | 338 { |
| 340 #ifdef SK_RASTERIZE_EVEN_ROUNDING | 339 #ifdef SK_RASTERIZE_EVEN_ROUNDING |
| 341 x0 = SkScalarRoundToFDot6(pts[0].fX, shift); | 340 x0 = SkScalarRoundToFDot6(pts[0].fX, shift); |
| 342 y0 = SkScalarRoundToFDot6(pts[0].fY, shift); | 341 y0 = SkScalarRoundToFDot6(pts[0].fY, shift); |
| 343 x1 = SkScalarRoundToFDot6(pts[1].fX, shift); | 342 x1 = SkScalarRoundToFDot6(pts[1].fX, shift); |
| 344 y1 = SkScalarRoundToFDot6(pts[1].fY, shift); | 343 y1 = SkScalarRoundToFDot6(pts[1].fY, shift); |
| 345 x2 = SkScalarRoundToFDot6(pts[2].fX, shift); | 344 x2 = SkScalarRoundToFDot6(pts[2].fX, shift); |
| 346 y2 = SkScalarRoundToFDot6(pts[2].fY, shift); | 345 y2 = SkScalarRoundToFDot6(pts[2].fY, shift); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 369 winding = -1; | 368 winding = -1; |
| 370 } | 369 } |
| 371 | 370 |
| 372 int top = SkFDot6Round(y0); | 371 int top = SkFDot6Round(y0); |
| 373 int bot = SkFDot6Round(y3); | 372 int bot = SkFDot6Round(y3); |
| 374 | 373 |
| 375 // are we a zero-height cubic (line)? | 374 // are we a zero-height cubic (line)? |
| 376 if (top == bot) | 375 if (top == bot) |
| 377 return 0; | 376 return 0; |
| 378 | 377 |
| 379 // are we completely above or below the clip? | |
| 380 if (clip && (top >= clip->fBottom || bot <= clip->fTop)) | |
| 381 return 0; | |
| 382 | |
| 383 // compute number of steps needed (1 << shift) | 378 // compute number of steps needed (1 << shift) |
| 384 { | 379 { |
| 385 // Can't use (center of curve - center of baseline), since center-of-cur
ve | 380 // Can't use (center of curve - center of baseline), since center-of-cur
ve |
| 386 // need not be the max delta from the baseline (it could even be coincid
ent) | 381 // need not be the max delta from the baseline (it could even be coincid
ent) |
| 387 // so we try just looking at the two off-curve points | 382 // so we try just looking at the two off-curve points |
| 388 SkFDot6 dx = cubic_delta_from_line(x0, x1, x2, x3); | 383 SkFDot6 dx = cubic_delta_from_line(x0, x1, x2, x3); |
| 389 SkFDot6 dy = cubic_delta_from_line(y0, y1, y2, y3); | 384 SkFDot6 dy = cubic_delta_from_line(y0, y1, y2, y3); |
| 390 // add 1 (by observation) | 385 // add 1 (by observation) |
| 391 shift = diff_to_shift(dx, dy) + 1; | 386 shift = diff_to_shift(dx, dy) + 1; |
| 392 } | 387 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 D = SkFDot6UpShift(y3 + 3 * (y1 - y2) - y0, upShift); | 421 D = SkFDot6UpShift(y3 + 3 * (y1 - y2) - y0, upShift); |
| 427 | 422 |
| 428 fCy = SkFDot6ToFixed(y0); | 423 fCy = SkFDot6ToFixed(y0); |
| 429 fCDy = B + (C >> shift) + (D >> 2*shift); // biased by shift | 424 fCDy = B + (C >> shift) + (D >> 2*shift); // biased by shift |
| 430 fCDDy = 2*C + (3*D >> (shift - 1)); // biased by 2*shift | 425 fCDDy = 2*C + (3*D >> (shift - 1)); // biased by 2*shift |
| 431 fCDDDy = 3*D >> (shift - 1); // biased by 2*shift | 426 fCDDDy = 3*D >> (shift - 1); // biased by 2*shift |
| 432 | 427 |
| 433 fCLastX = SkFDot6ToFixed(x3); | 428 fCLastX = SkFDot6ToFixed(x3); |
| 434 fCLastY = SkFDot6ToFixed(y3); | 429 fCLastY = SkFDot6ToFixed(y3); |
| 435 | 430 |
| 436 if (clip) | |
| 437 { | |
| 438 do { | |
| 439 if (!this->updateCubic()) { | |
| 440 return 0; | |
| 441 } | |
| 442 } while (!this->intersectsClip(*clip)); | |
| 443 this->chopLineWithClip(*clip); | |
| 444 return 1; | |
| 445 } | |
| 446 return this->updateCubic(); | 431 return this->updateCubic(); |
| 447 } | 432 } |
| 448 | 433 |
| 449 int SkCubicEdge::updateCubic() | 434 int SkCubicEdge::updateCubic() |
| 450 { | 435 { |
| 451 int success; | 436 int success; |
| 452 int count = fCurveCount; | 437 int count = fCurveCount; |
| 453 SkFixed oldx = fCx; | 438 SkFixed oldx = fCx; |
| 454 SkFixed oldy = fCy; | 439 SkFixed oldy = fCy; |
| 455 SkFixed newx, newy; | 440 SkFixed newx, newy; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 485 success = this->updateLine(oldx, oldy, newx, newy); | 470 success = this->updateLine(oldx, oldy, newx, newy); |
| 486 oldx = newx; | 471 oldx = newx; |
| 487 oldy = newy; | 472 oldy = newy; |
| 488 } while (count < 0 && !success); | 473 } while (count < 0 && !success); |
| 489 | 474 |
| 490 fCx = newx; | 475 fCx = newx; |
| 491 fCy = newy; | 476 fCy = newy; |
| 492 fCurveCount = SkToS8(count); | 477 fCurveCount = SkToS8(count); |
| 493 return success; | 478 return success; |
| 494 } | 479 } |
| OLD | NEW |