OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
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 #include "SkLineParameters.h" | 7 #include "SkLineParameters.h" |
8 #include "SkPathOpsCubic.h" | 8 #include "SkPathOpsCubic.h" |
9 #include "SkPathOpsLine.h" | 9 #include "SkPathOpsLine.h" |
10 #include "SkPathOpsQuad.h" | 10 #include "SkPathOpsQuad.h" |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 double dx = dst[3].fX = interp_cubic_coords(&fPts[0].fX, t2); | 396 double dx = dst[3].fX = interp_cubic_coords(&fPts[0].fX, t2); |
397 double dy = dst[3].fY = interp_cubic_coords(&fPts[0].fY, t2); | 397 double dy = dst[3].fY = interp_cubic_coords(&fPts[0].fY, t2); |
398 double mx = ex * 27 - ax * 8 - dx; | 398 double mx = ex * 27 - ax * 8 - dx; |
399 double my = ey * 27 - ay * 8 - dy; | 399 double my = ey * 27 - ay * 8 - dy; |
400 double nx = fx * 27 - ax - dx * 8; | 400 double nx = fx * 27 - ax - dx * 8; |
401 double ny = fy * 27 - ay - dy * 8; | 401 double ny = fy * 27 - ay - dy * 8; |
402 /* bx = */ dst[1].fX = (mx * 2 - nx) / 18; | 402 /* bx = */ dst[1].fX = (mx * 2 - nx) / 18; |
403 /* by = */ dst[1].fY = (my * 2 - ny) / 18; | 403 /* by = */ dst[1].fY = (my * 2 - ny) / 18; |
404 /* cx = */ dst[2].fX = (nx * 2 - mx) / 18; | 404 /* cx = */ dst[2].fX = (nx * 2 - mx) / 18; |
405 /* cy = */ dst[2].fY = (ny * 2 - my) / 18; | 405 /* cy = */ dst[2].fY = (ny * 2 - my) / 18; |
| 406 // FIXME: call align() ? |
406 return dst; | 407 return dst; |
407 } | 408 } |
408 | 409 |
| 410 void SkDCubic::align(int endIndex, int ctrlIndex, SkDPoint* dstPt) const { |
| 411 if (fPts[endIndex].fX == fPts[ctrlIndex].fX) { |
| 412 dstPt->fX = fPts[endIndex].fX; |
| 413 } |
| 414 if (fPts[endIndex].fY == fPts[ctrlIndex].fY) { |
| 415 dstPt->fY = fPts[endIndex].fY; |
| 416 } |
| 417 } |
| 418 |
409 void SkDCubic::subDivide(const SkDPoint& a, const SkDPoint& d, | 419 void SkDCubic::subDivide(const SkDPoint& a, const SkDPoint& d, |
410 double t1, double t2, SkDPoint dst[2]) const { | 420 double t1, double t2, SkDPoint dst[2]) const { |
| 421 SkASSERT(t1 != t2); |
| 422 #if 0 |
411 double ex = interp_cubic_coords(&fPts[0].fX, (t1 * 2 + t2) / 3); | 423 double ex = interp_cubic_coords(&fPts[0].fX, (t1 * 2 + t2) / 3); |
412 double ey = interp_cubic_coords(&fPts[0].fY, (t1 * 2 + t2) / 3); | 424 double ey = interp_cubic_coords(&fPts[0].fY, (t1 * 2 + t2) / 3); |
413 double fx = interp_cubic_coords(&fPts[0].fX, (t1 + t2 * 2) / 3); | 425 double fx = interp_cubic_coords(&fPts[0].fX, (t1 + t2 * 2) / 3); |
414 double fy = interp_cubic_coords(&fPts[0].fY, (t1 + t2 * 2) / 3); | 426 double fy = interp_cubic_coords(&fPts[0].fY, (t1 + t2 * 2) / 3); |
415 double mx = ex * 27 - a.fX * 8 - d.fX; | 427 double mx = ex * 27 - a.fX * 8 - d.fX; |
416 double my = ey * 27 - a.fY * 8 - d.fY; | 428 double my = ey * 27 - a.fY * 8 - d.fY; |
417 double nx = fx * 27 - a.fX - d.fX * 8; | 429 double nx = fx * 27 - a.fX - d.fX * 8; |
418 double ny = fy * 27 - a.fY - d.fY * 8; | 430 double ny = fy * 27 - a.fY - d.fY * 8; |
419 /* bx = */ dst[0].fX = (mx * 2 - nx) / 18; | 431 /* bx = */ dst[0].fX = (mx * 2 - nx) / 18; |
420 /* by = */ dst[0].fY = (my * 2 - ny) / 18; | 432 /* by = */ dst[0].fY = (my * 2 - ny) / 18; |
421 /* cx = */ dst[1].fX = (nx * 2 - mx) / 18; | 433 /* cx = */ dst[1].fX = (nx * 2 - mx) / 18; |
422 /* cy = */ dst[1].fY = (ny * 2 - my) / 18; | 434 /* cy = */ dst[1].fY = (ny * 2 - my) / 18; |
| 435 #else |
| 436 // this approach assumes that the control points computed directly are accur
ate enough |
| 437 SkDCubic sub = subDivide(t1, t2); |
| 438 dst[0] = sub[1] + (a - sub[0]); |
| 439 dst[1] = sub[2] + (d - sub[3]); |
| 440 #endif |
| 441 if (t1 == 0 || t2 == 0) { |
| 442 align(0, 1, t1 == 0 ? &dst[0] : &dst[1]); |
| 443 } |
| 444 if (t1 == 1 || t2 == 1) { |
| 445 align(3, 2, t1 == 1 ? &dst[0] : &dst[1]); |
| 446 } |
| 447 if (precisely_subdivide_equal(dst[0].fX, a.fX)) { |
| 448 dst[0].fX = a.fX; |
| 449 } |
| 450 if (precisely_subdivide_equal(dst[0].fY, a.fY)) { |
| 451 dst[0].fY = a.fY; |
| 452 } |
| 453 if (precisely_subdivide_equal(dst[1].fX, d.fX)) { |
| 454 dst[1].fX = d.fX; |
| 455 } |
| 456 if (precisely_subdivide_equal(dst[1].fY, d.fY)) { |
| 457 dst[1].fY = d.fY; |
| 458 } |
423 } | 459 } |
424 | 460 |
425 /* classic one t subdivision */ | 461 /* classic one t subdivision */ |
426 static void interp_cubic_coords(const double* src, double* dst, double t) { | 462 static void interp_cubic_coords(const double* src, double* dst, double t) { |
427 double ab = SkDInterp(src[0], src[2], t); | 463 double ab = SkDInterp(src[0], src[2], t); |
428 double bc = SkDInterp(src[2], src[4], t); | 464 double bc = SkDInterp(src[2], src[4], t); |
429 double cd = SkDInterp(src[4], src[6], t); | 465 double cd = SkDInterp(src[4], src[6], t); |
430 double abc = SkDInterp(ab, bc, t); | 466 double abc = SkDInterp(ab, bc, t); |
431 double bcd = SkDInterp(bc, cd, t); | 467 double bcd = SkDInterp(bc, cd, t); |
432 double abcd = SkDInterp(abc, bcd, t); | 468 double abcd = SkDInterp(abc, bcd, t); |
(...skipping 21 matching lines...) Expand all Loading... |
454 dst.pts[4].fY = (fPts[1].fY + 2 * fPts[2].fY + fPts[3].fY) / 4; | 490 dst.pts[4].fY = (fPts[1].fY + 2 * fPts[2].fY + fPts[3].fY) / 4; |
455 dst.pts[5].fX = (fPts[2].fX + fPts[3].fX) / 2; | 491 dst.pts[5].fX = (fPts[2].fX + fPts[3].fX) / 2; |
456 dst.pts[5].fY = (fPts[2].fY + fPts[3].fY) / 2; | 492 dst.pts[5].fY = (fPts[2].fY + fPts[3].fY) / 2; |
457 dst.pts[6] = fPts[3]; | 493 dst.pts[6] = fPts[3]; |
458 return dst; | 494 return dst; |
459 } | 495 } |
460 interp_cubic_coords(&fPts[0].fX, &dst.pts[0].fX, t); | 496 interp_cubic_coords(&fPts[0].fX, &dst.pts[0].fX, t); |
461 interp_cubic_coords(&fPts[0].fY, &dst.pts[0].fY, t); | 497 interp_cubic_coords(&fPts[0].fY, &dst.pts[0].fY, t); |
462 return dst; | 498 return dst; |
463 } | 499 } |
OLD | NEW |