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