OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2009 The Android Open Source Project | 3 * Copyright 2009 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 "SkEdgeClipper.h" | 10 #include "SkEdgeClipper.h" |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 } | 218 } |
219 | 219 |
220 *fCurrVerb = SkPath::kDone_Verb; | 220 *fCurrVerb = SkPath::kDone_Verb; |
221 fCurrPoint = fPoints; | 221 fCurrPoint = fPoints; |
222 fCurrVerb = fVerbs; | 222 fCurrVerb = fVerbs; |
223 return SkPath::kDone_Verb != fVerbs[0]; | 223 return SkPath::kDone_Verb != fVerbs[0]; |
224 } | 224 } |
225 | 225 |
226 /////////////////////////////////////////////////////////////////////////////// | 226 /////////////////////////////////////////////////////////////////////////////// |
227 | 227 |
| 228 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER |
228 static SkScalar eval_cubic_coeff(SkScalar A, SkScalar B, SkScalar C, | 229 static SkScalar eval_cubic_coeff(SkScalar A, SkScalar B, SkScalar C, |
229 SkScalar D, SkScalar t) { | 230 SkScalar D, SkScalar t) { |
230 return SkScalarMulAdd(SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C), t, D); | 231 return SkScalarMulAdd(SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C), t, D); |
231 } | 232 } |
232 | 233 |
233 /* Given 4 cubic points (either Xs or Ys), and a target X or Y, compute the | 234 /* Given 4 cubic points (either Xs or Ys), and a target X or Y, compute the |
234 t value such that cubic(t) = target | 235 t value such that cubic(t) = target |
235 */ | 236 */ |
236 static bool chopMonoCubicAt(SkScalar c0, SkScalar c1, SkScalar c2, SkScalar c3, | 237 static bool chopMonoCubicAt(SkScalar c0, SkScalar c1, SkScalar c2, SkScalar c3, |
237 SkScalar target, SkScalar* t) { | 238 SkScalar target, SkScalar* t) { |
(...skipping 29 matching lines...) Expand all Loading... |
267 return true; | 268 return true; |
268 } | 269 } |
269 | 270 |
270 static bool chopMonoCubicAtY(SkPoint pts[4], SkScalar y, SkScalar* t) { | 271 static bool chopMonoCubicAtY(SkPoint pts[4], SkScalar y, SkScalar* t) { |
271 return chopMonoCubicAt(pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY, y, t); | 272 return chopMonoCubicAt(pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY, y, t); |
272 } | 273 } |
273 | 274 |
274 static bool chopMonoCubicAtX(SkPoint pts[4], SkScalar x, SkScalar* t) { | 275 static bool chopMonoCubicAtX(SkPoint pts[4], SkScalar x, SkScalar* t) { |
275 return chopMonoCubicAt(pts[0].fX, pts[1].fX, pts[2].fX, pts[3].fX, x, t); | 276 return chopMonoCubicAt(pts[0].fX, pts[1].fX, pts[2].fX, pts[3].fX, x, t); |
276 } | 277 } |
| 278 #endif |
277 | 279 |
278 // Modify pts[] in place so that it is clipped in Y to the clip rect | 280 // Modify pts[] in place so that it is clipped in Y to the clip rect |
279 static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) { | 281 static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) { |
280 | 282 |
281 // are we partially above | 283 // are we partially above |
282 if (pts[0].fY < clip.fTop) { | 284 if (pts[0].fY < clip.fTop) { |
| 285 SkPoint tmp[7]; |
| 286 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER |
283 SkScalar t; | 287 SkScalar t; |
284 if (chopMonoCubicAtY(pts, clip.fTop, &t)) { | 288 if (chopMonoCubicAtY(pts, clip.fTop, &t)) { |
285 SkPoint tmp[7]; | |
286 SkChopCubicAt(pts, tmp, t); | 289 SkChopCubicAt(pts, tmp, t); |
287 | 290 #else |
288 // tmp[3, 4, 5].fY should all be to the below clip.fTop. | 291 if (SkChopMonoCubicAtY(pts, clip.fTop, tmp)) { |
| 292 #endif |
| 293 // tmp[3, 4].fY should all be to the below clip.fTop. |
289 // Since we can't trust the numerics of | 294 // Since we can't trust the numerics of |
290 // the chopper, we force those conditions now | 295 // the chopper, we force those conditions now |
291 tmp[3].fY = clip.fTop; | 296 tmp[3].fY = clip.fTop; |
292 clamp_ge(tmp[4].fY, clip.fTop); | 297 clamp_ge(tmp[4].fY, clip.fTop); |
| 298 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER |
293 clamp_ge(tmp[5].fY, clip.fTop); | 299 clamp_ge(tmp[5].fY, clip.fTop); |
| 300 #endif |
294 | 301 |
295 pts[0] = tmp[3]; | 302 pts[0] = tmp[3]; |
296 pts[1] = tmp[4]; | 303 pts[1] = tmp[4]; |
297 pts[2] = tmp[5]; | 304 pts[2] = tmp[5]; |
298 } else { | 305 } else { |
299 // if chopMonoCubicAtY failed, then we may have hit inexact numerics | 306 // if chopMonoCubicAtY failed, then we may have hit inexact numerics |
300 // so we just clamp against the top | 307 // so we just clamp against the top |
301 for (int i = 0; i < 4; i++) { | 308 for (int i = 0; i < 4; i++) { |
302 clamp_ge(pts[i].fY, clip.fTop); | 309 clamp_ge(pts[i].fY, clip.fTop); |
303 } | 310 } |
304 } | 311 } |
305 } | 312 } |
306 | 313 |
307 // are we partially below | 314 // are we partially below |
308 if (pts[3].fY > clip.fBottom) { | 315 if (pts[3].fY > clip.fBottom) { |
| 316 SkPoint tmp[7]; |
| 317 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER |
309 SkScalar t; | 318 SkScalar t; |
310 if (chopMonoCubicAtY(pts, clip.fBottom, &t)) { | 319 if (chopMonoCubicAtY(pts, clip.fBottom, &t)) { |
311 SkPoint tmp[7]; | |
312 SkChopCubicAt(pts, tmp, t); | 320 SkChopCubicAt(pts, tmp, t); |
| 321 #else |
| 322 if (SkChopMonoCubicAtY(pts, clip.fBottom, tmp)) { |
| 323 #endif |
313 tmp[3].fY = clip.fBottom; | 324 tmp[3].fY = clip.fBottom; |
314 clamp_le(tmp[2].fY, clip.fBottom); | 325 clamp_le(tmp[2].fY, clip.fBottom); |
315 | 326 |
316 pts[1] = tmp[1]; | 327 pts[1] = tmp[1]; |
317 pts[2] = tmp[2]; | 328 pts[2] = tmp[2]; |
318 pts[3] = tmp[3]; | 329 pts[3] = tmp[3]; |
319 } else { | 330 } else { |
320 // if chopMonoCubicAtY failed, then we may have hit inexact numerics | 331 // if chopMonoCubicAtY failed, then we may have hit inexact numerics |
321 // so we just clamp against the bottom | 332 // so we just clamp against the bottom |
322 for (int i = 0; i < 4; i++) { | 333 for (int i = 0; i < 4; i++) { |
(...skipping 30 matching lines...) Expand all Loading... |
353 } | 364 } |
354 if (pts[0].fX >= clip.fRight) { // wholly to the right | 365 if (pts[0].fX >= clip.fRight) { // wholly to the right |
355 if (!this->canCullToTheRight()) { | 366 if (!this->canCullToTheRight()) { |
356 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse); | 367 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse); |
357 } | 368 } |
358 return; | 369 return; |
359 } | 370 } |
360 | 371 |
361 // are we partially to the left | 372 // are we partially to the left |
362 if (pts[0].fX < clip.fLeft) { | 373 if (pts[0].fX < clip.fLeft) { |
| 374 SkPoint tmp[7]; |
| 375 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER |
363 SkScalar t; | 376 SkScalar t; |
364 if (chopMonoCubicAtX(pts, clip.fLeft, &t)) { | 377 if (chopMonoCubicAtX(pts, clip.fLeft, &t)) { |
365 SkPoint tmp[7]; | |
366 SkChopCubicAt(pts, tmp, t); | 378 SkChopCubicAt(pts, tmp, t); |
| 379 #else |
| 380 if (SkChopMonoCubicAtX(pts, clip.fLeft, tmp)) { |
| 381 #endif |
367 this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse); | 382 this->appendVLine(clip.fLeft, tmp[0].fY, tmp[3].fY, reverse); |
368 | 383 |
369 // tmp[3, 4, 5].fX should all be to the right of clip.fLeft. | 384 // tmp[3, 4].fX should all be to the right of clip.fLeft. |
370 // Since we can't trust the numerics of | 385 // Since we can't trust the numerics of |
371 // the chopper, we force those conditions now | 386 // the chopper, we force those conditions now |
372 tmp[3].fX = clip.fLeft; | 387 tmp[3].fX = clip.fLeft; |
373 clamp_ge(tmp[4].fX, clip.fLeft); | 388 clamp_ge(tmp[4].fX, clip.fLeft); |
| 389 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER |
374 clamp_ge(tmp[5].fX, clip.fLeft); | 390 clamp_ge(tmp[5].fX, clip.fLeft); |
| 391 #endif |
375 | 392 |
376 pts[0] = tmp[3]; | 393 pts[0] = tmp[3]; |
377 pts[1] = tmp[4]; | 394 pts[1] = tmp[4]; |
378 pts[2] = tmp[5]; | 395 pts[2] = tmp[5]; |
379 } else { | 396 } else { |
380 // if chopMonocubicAtY failed, then we may have hit inexact numerics | 397 // if chopMonocubicAtY failed, then we may have hit inexact numerics |
381 // so we just clamp against the left | 398 // so we just clamp against the left |
382 this->appendVLine(clip.fLeft, pts[0].fY, pts[3].fY, reverse); | 399 this->appendVLine(clip.fLeft, pts[0].fY, pts[3].fY, reverse); |
383 return; | 400 return; |
384 } | 401 } |
385 } | 402 } |
386 | 403 |
387 // are we partially to the right | 404 // are we partially to the right |
388 if (pts[3].fX > clip.fRight) { | 405 if (pts[3].fX > clip.fRight) { |
| 406 SkPoint tmp[7]; |
| 407 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER |
389 SkScalar t; | 408 SkScalar t; |
390 if (chopMonoCubicAtX(pts, clip.fRight, &t)) { | 409 if (chopMonoCubicAtX(pts, clip.fRight, &t)) { |
391 SkPoint tmp[7]; | |
392 SkChopCubicAt(pts, tmp, t); | 410 SkChopCubicAt(pts, tmp, t); |
| 411 #else |
| 412 if (SkChopMonoCubicAtX(pts, clip.fRight, tmp)) { |
| 413 #endif |
393 tmp[3].fX = clip.fRight; | 414 tmp[3].fX = clip.fRight; |
394 clamp_le(tmp[2].fX, clip.fRight); | 415 clamp_le(tmp[2].fX, clip.fRight); |
| 416 #ifdef SK_SUPPORT_LEGACY_CUBIC_CHOPPER |
395 clamp_le(tmp[1].fX, clip.fRight); | 417 clamp_le(tmp[1].fX, clip.fRight); |
| 418 #endif |
396 | 419 |
397 this->appendCubic(tmp, reverse); | 420 this->appendCubic(tmp, reverse); |
398 this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse); | 421 this->appendVLine(clip.fRight, tmp[3].fY, tmp[6].fY, reverse); |
399 } else { | 422 } else { |
400 // if chopMonoCubicAtX failed, then we may have hit inexact numerics | 423 // if chopMonoCubicAtX failed, then we may have hit inexact numerics |
401 // so we just clamp against the right | 424 // so we just clamp against the right |
402 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse); | 425 this->appendVLine(clip.fRight, pts[0].fY, pts[3].fY, reverse); |
403 } | 426 } |
404 } else { // wholly inside the clip | 427 } else { // wholly inside the clip |
405 this->appendCubic(pts, reverse); | 428 this->appendCubic(pts, reverse); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 assert_monotonic(&pts[0].fY, count); | 549 assert_monotonic(&pts[0].fY, count); |
527 } | 550 } |
528 } | 551 } |
529 | 552 |
530 void sk_assert_monotonic_x(const SkPoint pts[], int count) { | 553 void sk_assert_monotonic_x(const SkPoint pts[], int count) { |
531 if (count > 1) { | 554 if (count > 1) { |
532 assert_monotonic(&pts[0].fX, count); | 555 assert_monotonic(&pts[0].fX, count); |
533 } | 556 } |
534 } | 557 } |
535 #endif | 558 #endif |
OLD | NEW |