| 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 |