OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 | 7 |
8 #include "GrAAHairLinePathRenderer.h" | 8 #include "GrAAHairLinePathRenderer.h" |
9 | 9 |
10 #include "GrContext.h" | 10 #include "GrContext.h" |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 // This point may not be within 1 pixel of a control point. We update the bo
unding box to | 593 // This point may not be within 1 pixel of a control point. We update the bo
unding box to |
594 // include it. | 594 // include it. |
595 intersect_lines(a0.fPos, abN, c0.fPos, cbN, &b0.fPos); | 595 intersect_lines(a0.fPos, abN, c0.fPos, cbN, &b0.fPos); |
596 devBounds->growToInclude(b0.fPos.fX, b0.fPos.fY); | 596 devBounds->growToInclude(b0.fPos.fX, b0.fPos.fY); |
597 | 597 |
598 if (toSrc) { | 598 if (toSrc) { |
599 toSrc->mapPointsWithStride(&verts[0].fPos, sizeof(BezierVertex), kVertsP
erQuad); | 599 toSrc->mapPointsWithStride(&verts[0].fPos, sizeof(BezierVertex), kVertsP
erQuad); |
600 } | 600 } |
601 } | 601 } |
602 | 602 |
603 // Input: | |
604 // Three control points: p[0], p[1], p[2] and weight: w | |
605 // Output: | |
606 // Let: | |
607 // l = (2*w * (y1 - y0), 2*w * (x0 - x1), 2*w * (x1*y0 - x0*y1)) | |
608 // m = (2*w * (y2 - y1), 2*w * (x1 - x2), 2*w * (x2*y1 - x1*y2)) | |
609 // k = (y2 - y0, x0 - x2, (x2 - x0)*y0 - (y2 - y0)*x0 ) | |
610 void calc_conic_klm(const SkPoint p[3], const SkScalar weight, | |
611 SkScalar k[3], SkScalar l[3], SkScalar m[3]) { | |
612 const SkScalar w2 = 2 * weight; | |
613 l[0] = w2 * (p[1].fY - p[0].fY); | |
614 l[1] = w2 * (p[0].fX - p[1].fX); | |
615 l[2] = w2 * (p[1].fX * p[0].fY - p[0].fX * p[1].fY); | |
616 | |
617 m[0] = w2 * (p[2].fY - p[1].fY); | |
618 m[1] = w2 * (p[1].fX - p[2].fX); | |
619 m[2] = w2 * (p[2].fX * p[1].fY - p[1].fX * p[2].fY); | |
620 | |
621 k[0] = p[2].fY - p[0].fY; | |
622 k[1] = p[0].fX - p[2].fX; | |
623 k[2] = (p[2].fX - p[0].fX) * p[0].fY - (p[2].fY - p[0].fY) * p[0].fX; | |
624 | |
625 // scale the max absolute value of coeffs to 10 | |
626 SkScalar scale = 0.0f; | |
627 for (int i = 0; i < 3; ++i) { | |
628 scale = SkMaxScalar(scale, SkScalarAbs(k[i])); | |
629 scale = SkMaxScalar(scale, SkScalarAbs(l[i])); | |
630 scale = SkMaxScalar(scale, SkScalarAbs(m[i])); | |
631 } | |
632 SkASSERT(scale > 0); | |
633 scale /= 10.0f; | |
634 k[0] /= scale; | |
635 k[1] /= scale; | |
636 k[2] /= scale; | |
637 l[0] /= scale; | |
638 l[1] /= scale; | |
639 l[2] /= scale; | |
640 m[0] /= scale; | |
641 m[1] /= scale; | |
642 m[2] /= scale; | |
643 } | |
644 | |
645 // Equations based off of Loop-Blinn Quadratic GPU Rendering | 603 // Equations based off of Loop-Blinn Quadratic GPU Rendering |
646 // Input Parametric: | 604 // Input Parametric: |
647 // P(t) = (P0*(1-t)^2 + 2*w*P1*t*(1-t) + P2*t^2) / (1-t)^2 + 2*w*t*(1-t) + t^2) | 605 // P(t) = (P0*(1-t)^2 + 2*w*P1*t*(1-t) + P2*t^2) / (1-t)^2 + 2*w*t*(1-t) + t^2) |
648 // Output Implicit: | 606 // Output Implicit: |
649 // f(x, y, w) = f(P) = K^2 - LM | 607 // f(x, y, w) = f(P) = K^2 - LM |
650 // K = dot(k, P), L = dot(l, P), M = dot(m, P) | 608 // K = dot(k, P), L = dot(l, P), M = dot(m, P) |
651 // k, l, m are calculated in function calc_conic_klm | 609 // k, l, m are calculated in function GrPathUtils::getConicKLM |
652 void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kVertsPerQuad], con
st float weight) { | 610 void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kVertsPerQuad], |
653 SkScalar k[3]; | 611 const SkScalar weight) { |
654 SkScalar l[3]; | 612 SkScalar klm[9]; |
655 SkScalar m[3]; | |
656 | 613 |
657 calc_conic_klm(p, weight, k, l, m); | 614 GrPathUtils::getConicKLM(p, weight, klm); |
658 | 615 |
659 for (int i = 0; i < kVertsPerQuad; ++i) { | 616 for (int i = 0; i < kVertsPerQuad; ++i) { |
660 const SkPoint pnt = verts[i].fPos; | 617 const SkPoint pnt = verts[i].fPos; |
661 verts[i].fConic.fK = pnt.fX * k[0] + pnt.fY * k[1] + k[2]; | 618 verts[i].fConic.fK = pnt.fX * klm[0] + pnt.fY * klm[1] + klm[2]; |
662 verts[i].fConic.fL = pnt.fX * l[0] + pnt.fY * l[1] + l[2]; | 619 verts[i].fConic.fL = pnt.fX * klm[3] + pnt.fY * klm[4] + klm[5]; |
663 verts[i].fConic.fM = pnt.fX * m[0] + pnt.fY * m[1] + m[2]; | 620 verts[i].fConic.fM = pnt.fX * klm[6] + pnt.fY * klm[7] + klm[8]; |
664 } | 621 } |
665 } | 622 } |
666 | 623 |
667 void add_conics(const SkPoint p[3], | 624 void add_conics(const SkPoint p[3], |
668 float weight, | 625 const SkScalar weight, |
669 const SkMatrix* toDevice, | 626 const SkMatrix* toDevice, |
670 const SkMatrix* toSrc, | 627 const SkMatrix* toSrc, |
671 BezierVertex** vert, | 628 BezierVertex** vert, |
672 SkRect* devBounds) { | 629 SkRect* devBounds) { |
673 bloat_quad(p, toDevice, toSrc, *vert, devBounds); | 630 bloat_quad(p, toDevice, toSrc, *vert, devBounds); |
674 set_conic_coeffs(p, *vert, weight); | 631 set_conic_coeffs(p, *vert, weight); |
675 *vert += kVertsPerQuad; | 632 *vert += kVertsPerQuad; |
676 } | 633 } |
677 | 634 |
678 void add_quads(const SkPoint p[3], | 635 void add_quads(const SkPoint p[3], |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 &devBounds); | 1335 &devBounds); |
1379 conics += n; | 1336 conics += n; |
1380 } | 1337 } |
1381 } | 1338 } |
1382 } | 1339 } |
1383 | 1340 |
1384 target->resetIndexSource(); | 1341 target->resetIndexSource(); |
1385 | 1342 |
1386 return true; | 1343 return true; |
1387 } | 1344 } |
OLD | NEW |