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 |