OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrTessellatingPathRenderer.h" | 8 #include "GrTessellatingPathRenderer.h" |
9 | 9 |
10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 data = emit_vertex(v2, data); | 198 data = emit_vertex(v2, data); |
199 data = emit_vertex(v0, data); | 199 data = emit_vertex(v0, data); |
200 #else | 200 #else |
201 data = emit_vertex(v0, data); | 201 data = emit_vertex(v0, data); |
202 data = emit_vertex(v1, data); | 202 data = emit_vertex(v1, data); |
203 data = emit_vertex(v2, data); | 203 data = emit_vertex(v2, data); |
204 #endif | 204 #endif |
205 return data; | 205 return data; |
206 } | 206 } |
207 | 207 |
| 208 struct EdgeList { |
| 209 EdgeList() : fHead(NULL), fTail(NULL) {} |
| 210 Edge* fHead; |
| 211 Edge* fTail; |
| 212 }; |
| 213 |
208 /** | 214 /** |
209 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of
"edges above" and | 215 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of
"edges above" and |
210 * "edge below" a vertex as well as for the active edge list is handled by isLef
tOf()/isRightOf(). | 216 * "edge below" a vertex as well as for the active edge list is handled by isLef
tOf()/isRightOf(). |
211 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b
ecause floating | 217 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b
ecause floating |
212 * point). For speed, that case is only tested by the callers which require it (
e.g., | 218 * point). For speed, that case is only tested by the callers which require it (
e.g., |
213 * cleanup_active_edges()). Edges also handle checking for intersection with oth
er edges. | 219 * cleanup_active_edges()). Edges also handle checking for intersection with oth
er edges. |
214 * Currently, this converts the edges to the parametric form, in order to avoid
doing a division | 220 * Currently, this converts the edges to the parametric form, in order to avoid
doing a division |
215 * until an intersection has been confirmed. This is slightly slower in the "fou
nd" case, but | 221 * until an intersection has been confirmed. This is slightly slower in the "fou
nd" case, but |
216 * a lot faster in the "not found" case. | 222 * a lot faster in the "not found" case. |
217 * | 223 * |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 if (denom > 0.0 ? (sNumer < 0.0 || sNumer > denom || tNumer < 0.0 || tNu
mer > denom) | 293 if (denom > 0.0 ? (sNumer < 0.0 || sNumer > denom || tNumer < 0.0 || tNu
mer > denom) |
288 : (sNumer > 0.0 || sNumer < denom || tNumer > 0.0 || tNu
mer < denom)) { | 294 : (sNumer > 0.0 || sNumer < denom || tNumer > 0.0 || tNu
mer < denom)) { |
289 return false; | 295 return false; |
290 } | 296 } |
291 double s = sNumer / denom; | 297 double s = sNumer / denom; |
292 SkASSERT(s >= 0.0 && s <= 1.0); | 298 SkASSERT(s >= 0.0 && s <= 1.0); |
293 p->fX = SkDoubleToScalar(fTop->fPoint.fX + s * fDX); | 299 p->fX = SkDoubleToScalar(fTop->fPoint.fX + s * fDX); |
294 p->fY = SkDoubleToScalar(fTop->fPoint.fY + s * fDY); | 300 p->fY = SkDoubleToScalar(fTop->fPoint.fY + s * fDY); |
295 return true; | 301 return true; |
296 } | 302 } |
297 bool isActive(Edge** activeEdges) const { | 303 bool isActive(EdgeList* activeEdges) const { |
298 return activeEdges && (fLeft || fRight || *activeEdges == this); | 304 return activeEdges && (fLeft || fRight || activeEdges->fHead == this); |
299 } | 305 } |
300 }; | 306 }; |
301 | 307 |
302 /*******************************************************************************
********/ | 308 /*******************************************************************************
********/ |
303 | 309 |
304 struct Poly { | 310 struct Poly { |
305 Poly(int winding) | 311 Poly(int winding) |
306 : fWinding(winding) | 312 : fWinding(winding) |
307 , fHead(NULL) | 313 , fHead(NULL) |
308 , fTail(NULL) | 314 , fTail(NULL) |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 } | 633 } |
628 } | 634 } |
629 | 635 |
630 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c) { | 636 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c) { |
631 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; | 637 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; |
632 Vertex* top = winding < 0 ? next : prev; | 638 Vertex* top = winding < 0 ? next : prev; |
633 Vertex* bottom = winding < 0 ? prev : next; | 639 Vertex* bottom = winding < 0 ? prev : next; |
634 return ALLOC_NEW(Edge, (top, bottom, winding), alloc); | 640 return ALLOC_NEW(Edge, (top, bottom, winding), alloc); |
635 } | 641 } |
636 | 642 |
637 void remove_edge(Edge* edge, Edge** head) { | 643 void remove_edge(Edge* edge, EdgeList* edges) { |
638 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); | 644 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); |
639 SkASSERT(edge->isActive(head)); | 645 SkASSERT(edge->isActive(edges)); |
640 remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, head, NULL); | 646 remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &edges->fHead, &edges->fTail
); |
641 } | 647 } |
642 | 648 |
643 void insert_edge(Edge* edge, Edge* prev, Edge** head) { | 649 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) { |
644 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); | 650 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); |
645 SkASSERT(!edge->isActive(head)); | 651 SkASSERT(!edge->isActive(edges)); |
646 Edge* next = prev ? prev->fRight : *head; | 652 Edge* next = prev ? prev->fRight : edges->fHead; |
647 insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, head, NULL); | 653 insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &edges->fHead, &
edges->fTail); |
648 } | 654 } |
649 | 655 |
650 void find_enclosing_edges(Vertex* v, Edge* head, Edge** left, Edge** right) { | 656 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right)
{ |
651 if (v->fFirstEdgeAbove) { | 657 if (v->fFirstEdgeAbove) { |
652 *left = v->fFirstEdgeAbove->fLeft; | 658 *left = v->fFirstEdgeAbove->fLeft; |
653 *right = v->fLastEdgeAbove->fRight; | 659 *right = v->fLastEdgeAbove->fRight; |
654 return; | 660 return; |
655 } | 661 } |
656 Edge* prev = NULL; | 662 Edge* next = NULL; |
657 Edge* next; | 663 Edge* prev; |
658 for (next = head; next != NULL; next = next->fRight) { | 664 for (prev = edges->fTail; prev != NULL; prev = prev->fLeft) { |
659 if (next->isRightOf(v)) { | 665 if (prev->isLeftOf(v)) { |
660 break; | 666 break; |
661 } | 667 } |
662 prev = next; | 668 next = prev; |
663 } | 669 } |
664 *left = prev; | 670 *left = prev; |
665 *right = next; | 671 *right = next; |
666 return; | 672 return; |
667 } | 673 } |
668 | 674 |
669 void find_enclosing_edges(Edge* edge, Edge* head, Comparator& c, Edge** left, Ed
ge** right) { | 675 void find_enclosing_edges(Edge* edge, EdgeList* edges, Comparator& c, Edge** lef
t, Edge** right) { |
670 Edge* prev = NULL; | 676 Edge* prev = NULL; |
671 Edge* next; | 677 Edge* next; |
672 for (next = head; next != NULL; next = next->fRight) { | 678 for (next = edges->fHead; next != NULL; next = next->fRight) { |
673 if ((c.sweep_gt(edge->fTop->fPoint, next->fTop->fPoint) && next->isRight
Of(edge->fTop)) || | 679 if ((c.sweep_gt(edge->fTop->fPoint, next->fTop->fPoint) && next->isRight
Of(edge->fTop)) || |
674 (c.sweep_gt(next->fTop->fPoint, edge->fTop->fPoint) && edge->isLeftO
f(next->fTop)) || | 680 (c.sweep_gt(next->fTop->fPoint, edge->fTop->fPoint) && edge->isLeftO
f(next->fTop)) || |
675 (c.sweep_lt(edge->fBottom->fPoint, next->fBottom->fPoint) && | 681 (c.sweep_lt(edge->fBottom->fPoint, next->fBottom->fPoint) && |
676 next->isRightOf(edge->fBottom)) || | 682 next->isRightOf(edge->fBottom)) || |
677 (c.sweep_lt(next->fBottom->fPoint, edge->fBottom->fPoint) && | 683 (c.sweep_lt(next->fBottom->fPoint, edge->fBottom->fPoint) && |
678 edge->isLeftOf(next->fBottom))) { | 684 edge->isLeftOf(next->fBottom))) { |
679 break; | 685 break; |
680 } | 686 } |
681 prev = next; | 687 prev = next; |
682 } | 688 } |
683 *left = prev; | 689 *left = prev; |
684 *right = next; | 690 *right = next; |
685 return; | 691 return; |
686 } | 692 } |
687 | 693 |
688 void fix_active_state(Edge* edge, Edge** activeEdges, Comparator& c) { | 694 void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) { |
689 if (edge->isActive(activeEdges)) { | 695 if (edge->isActive(activeEdges)) { |
690 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) { | 696 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) { |
691 remove_edge(edge, activeEdges); | 697 remove_edge(edge, activeEdges); |
692 } | 698 } |
693 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) { | 699 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) { |
694 Edge* left; | 700 Edge* left; |
695 Edge* right; | 701 Edge* right; |
696 find_enclosing_edges(edge, *activeEdges, c, &left, &right); | 702 find_enclosing_edges(edge, activeEdges, c, &left, &right); |
697 insert_edge(edge, left, activeEdges); | 703 insert_edge(edge, left, activeEdges); |
698 } | 704 } |
699 } | 705 } |
700 | 706 |
701 void insert_edge_above(Edge* edge, Vertex* v, Comparator& c) { | 707 void insert_edge_above(Edge* edge, Vertex* v, Comparator& c) { |
702 if (edge->fTop->fPoint == edge->fBottom->fPoint || | 708 if (edge->fTop->fPoint == edge->fBottom->fPoint || |
703 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { | 709 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { |
704 return; | 710 return; |
705 } | 711 } |
706 LOG("insert edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); | 712 LOG("insert edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove); | 747 edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove); |
742 } | 748 } |
743 | 749 |
744 void remove_edge_below(Edge* edge) { | 750 void remove_edge_below(Edge* edge) { |
745 LOG("removing edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, | 751 LOG("removing edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, |
746 edge->fTop->fID); | 752 edge->fTop->fID); |
747 remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( | 753 remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( |
748 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow); | 754 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow); |
749 } | 755 } |
750 | 756 |
751 void erase_edge_if_zero_winding(Edge* edge, Edge** head) { | 757 void erase_edge_if_zero_winding(Edge* edge, EdgeList* edges) { |
752 if (edge->fWinding != 0) { | 758 if (edge->fWinding != 0) { |
753 return; | 759 return; |
754 } | 760 } |
755 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID); | 761 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID); |
756 remove_edge_above(edge); | 762 remove_edge_above(edge); |
757 remove_edge_below(edge); | 763 remove_edge_below(edge); |
758 if (edge->isActive(head)) { | 764 if (edge->isActive(edges)) { |
759 remove_edge(edge, head); | 765 remove_edge(edge, edges); |
760 } | 766 } |
761 } | 767 } |
762 | 768 |
763 void merge_collinear_edges(Edge* edge, Edge** activeEdges, Comparator& c); | 769 void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Comparator& c); |
764 | 770 |
765 void set_top(Edge* edge, Vertex* v, Edge** activeEdges, Comparator& c) { | 771 void set_top(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c) { |
766 remove_edge_below(edge); | 772 remove_edge_below(edge); |
767 edge->fTop = v; | 773 edge->fTop = v; |
768 edge->recompute(); | 774 edge->recompute(); |
769 insert_edge_below(edge, v, c); | 775 insert_edge_below(edge, v, c); |
770 fix_active_state(edge, activeEdges, c); | 776 fix_active_state(edge, activeEdges, c); |
771 merge_collinear_edges(edge, activeEdges, c); | 777 merge_collinear_edges(edge, activeEdges, c); |
772 } | 778 } |
773 | 779 |
774 void set_bottom(Edge* edge, Vertex* v, Edge** activeEdges, Comparator& c) { | 780 void set_bottom(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c) { |
775 remove_edge_above(edge); | 781 remove_edge_above(edge); |
776 edge->fBottom = v; | 782 edge->fBottom = v; |
777 edge->recompute(); | 783 edge->recompute(); |
778 insert_edge_above(edge, v, c); | 784 insert_edge_above(edge, v, c); |
779 fix_active_state(edge, activeEdges, c); | 785 fix_active_state(edge, activeEdges, c); |
780 merge_collinear_edges(edge, activeEdges, c); | 786 merge_collinear_edges(edge, activeEdges, c); |
781 } | 787 } |
782 | 788 |
783 void merge_edges_above(Edge* edge, Edge* other, Edge** activeEdges, Comparator&
c) { | 789 void merge_edges_above(Edge* edge, Edge* other, EdgeList* activeEdges, Comparato
r& c) { |
784 if (coincident(edge->fTop->fPoint, other->fTop->fPoint)) { | 790 if (coincident(edge->fTop->fPoint, other->fTop->fPoint)) { |
785 LOG("merging coincident above edges (%g, %g) -> (%g, %g)\n", | 791 LOG("merging coincident above edges (%g, %g) -> (%g, %g)\n", |
786 edge->fTop->fPoint.fX, edge->fTop->fPoint.fY, | 792 edge->fTop->fPoint.fX, edge->fTop->fPoint.fY, |
787 edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY); | 793 edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY); |
788 other->fWinding += edge->fWinding; | 794 other->fWinding += edge->fWinding; |
789 erase_edge_if_zero_winding(other, activeEdges); | 795 erase_edge_if_zero_winding(other, activeEdges); |
790 edge->fWinding = 0; | 796 edge->fWinding = 0; |
791 erase_edge_if_zero_winding(edge, activeEdges); | 797 erase_edge_if_zero_winding(edge, activeEdges); |
792 } else if (c.sweep_lt(edge->fTop->fPoint, other->fTop->fPoint)) { | 798 } else if (c.sweep_lt(edge->fTop->fPoint, other->fTop->fPoint)) { |
793 other->fWinding += edge->fWinding; | 799 other->fWinding += edge->fWinding; |
794 erase_edge_if_zero_winding(other, activeEdges); | 800 erase_edge_if_zero_winding(other, activeEdges); |
795 set_bottom(edge, other->fTop, activeEdges, c); | 801 set_bottom(edge, other->fTop, activeEdges, c); |
796 } else { | 802 } else { |
797 edge->fWinding += other->fWinding; | 803 edge->fWinding += other->fWinding; |
798 erase_edge_if_zero_winding(edge, activeEdges); | 804 erase_edge_if_zero_winding(edge, activeEdges); |
799 set_bottom(other, edge->fTop, activeEdges, c); | 805 set_bottom(other, edge->fTop, activeEdges, c); |
800 } | 806 } |
801 } | 807 } |
802 | 808 |
803 void merge_edges_below(Edge* edge, Edge* other, Edge** activeEdges, Comparator&
c) { | 809 void merge_edges_below(Edge* edge, Edge* other, EdgeList* activeEdges, Comparato
r& c) { |
804 if (coincident(edge->fBottom->fPoint, other->fBottom->fPoint)) { | 810 if (coincident(edge->fBottom->fPoint, other->fBottom->fPoint)) { |
805 LOG("merging coincident below edges (%g, %g) -> (%g, %g)\n", | 811 LOG("merging coincident below edges (%g, %g) -> (%g, %g)\n", |
806 edge->fTop->fPoint.fX, edge->fTop->fPoint.fY, | 812 edge->fTop->fPoint.fX, edge->fTop->fPoint.fY, |
807 edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY); | 813 edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY); |
808 other->fWinding += edge->fWinding; | 814 other->fWinding += edge->fWinding; |
809 erase_edge_if_zero_winding(other, activeEdges); | 815 erase_edge_if_zero_winding(other, activeEdges); |
810 edge->fWinding = 0; | 816 edge->fWinding = 0; |
811 erase_edge_if_zero_winding(edge, activeEdges); | 817 erase_edge_if_zero_winding(edge, activeEdges); |
812 } else if (c.sweep_lt(edge->fBottom->fPoint, other->fBottom->fPoint)) { | 818 } else if (c.sweep_lt(edge->fBottom->fPoint, other->fBottom->fPoint)) { |
813 edge->fWinding += other->fWinding; | 819 edge->fWinding += other->fWinding; |
814 erase_edge_if_zero_winding(edge, activeEdges); | 820 erase_edge_if_zero_winding(edge, activeEdges); |
815 set_top(other, edge->fBottom, activeEdges, c); | 821 set_top(other, edge->fBottom, activeEdges, c); |
816 } else { | 822 } else { |
817 other->fWinding += edge->fWinding; | 823 other->fWinding += edge->fWinding; |
818 erase_edge_if_zero_winding(other, activeEdges); | 824 erase_edge_if_zero_winding(other, activeEdges); |
819 set_top(edge, other->fBottom, activeEdges, c); | 825 set_top(edge, other->fBottom, activeEdges, c); |
820 } | 826 } |
821 } | 827 } |
822 | 828 |
823 void merge_collinear_edges(Edge* edge, Edge** activeEdges, Comparator& c) { | 829 void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Comparator& c) { |
824 if (edge->fPrevEdgeAbove && (edge->fTop == edge->fPrevEdgeAbove->fTop || | 830 if (edge->fPrevEdgeAbove && (edge->fTop == edge->fPrevEdgeAbove->fTop || |
825 !edge->fPrevEdgeAbove->isLeftOf(edge->fTop))) { | 831 !edge->fPrevEdgeAbove->isLeftOf(edge->fTop))) { |
826 merge_edges_above(edge, edge->fPrevEdgeAbove, activeEdges, c); | 832 merge_edges_above(edge, edge->fPrevEdgeAbove, activeEdges, c); |
827 } else if (edge->fNextEdgeAbove && (edge->fTop == edge->fNextEdgeAbove->fTop
|| | 833 } else if (edge->fNextEdgeAbove && (edge->fTop == edge->fNextEdgeAbove->fTop
|| |
828 !edge->isLeftOf(edge->fNextEdgeAbove->fT
op))) { | 834 !edge->isLeftOf(edge->fNextEdgeAbove->fT
op))) { |
829 merge_edges_above(edge, edge->fNextEdgeAbove, activeEdges, c); | 835 merge_edges_above(edge, edge->fNextEdgeAbove, activeEdges, c); |
830 } | 836 } |
831 if (edge->fPrevEdgeBelow && (edge->fBottom == edge->fPrevEdgeBelow->fBottom
|| | 837 if (edge->fPrevEdgeBelow && (edge->fBottom == edge->fPrevEdgeBelow->fBottom
|| |
832 !edge->fPrevEdgeBelow->isLeftOf(edge->fBottom))
) { | 838 !edge->fPrevEdgeBelow->isLeftOf(edge->fBottom))
) { |
833 merge_edges_below(edge, edge->fPrevEdgeBelow, activeEdges, c); | 839 merge_edges_below(edge, edge->fPrevEdgeBelow, activeEdges, c); |
834 } else if (edge->fNextEdgeBelow && (edge->fBottom == edge->fNextEdgeBelow->f
Bottom || | 840 } else if (edge->fNextEdgeBelow && (edge->fBottom == edge->fNextEdgeBelow->f
Bottom || |
835 !edge->isLeftOf(edge->fNextEdgeBelow->fB
ottom))) { | 841 !edge->isLeftOf(edge->fNextEdgeBelow->fB
ottom))) { |
836 merge_edges_below(edge, edge->fNextEdgeBelow, activeEdges, c); | 842 merge_edges_below(edge, edge->fNextEdgeBelow, activeEdges, c); |
837 } | 843 } |
838 } | 844 } |
839 | 845 |
840 void split_edge(Edge* edge, Vertex* v, Edge** activeEdges, Comparator& c, SkChun
kAlloc& alloc); | 846 void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c, SkC
hunkAlloc& alloc); |
841 | 847 |
842 void cleanup_active_edges(Edge* edge, Edge** activeEdges, Comparator& c, SkChunk
Alloc& alloc) { | 848 void cleanup_active_edges(Edge* edge, EdgeList* activeEdges, Comparator& c, SkCh
unkAlloc& alloc) { |
843 Vertex* top = edge->fTop; | 849 Vertex* top = edge->fTop; |
844 Vertex* bottom = edge->fBottom; | 850 Vertex* bottom = edge->fBottom; |
845 if (edge->fLeft) { | 851 if (edge->fLeft) { |
846 Vertex* leftTop = edge->fLeft->fTop; | 852 Vertex* leftTop = edge->fLeft->fTop; |
847 Vertex* leftBottom = edge->fLeft->fBottom; | 853 Vertex* leftBottom = edge->fLeft->fBottom; |
848 if (c.sweep_gt(top->fPoint, leftTop->fPoint) && !edge->fLeft->isLeftOf(t
op)) { | 854 if (c.sweep_gt(top->fPoint, leftTop->fPoint) && !edge->fLeft->isLeftOf(t
op)) { |
849 split_edge(edge->fLeft, edge->fTop, activeEdges, c, alloc); | 855 split_edge(edge->fLeft, edge->fTop, activeEdges, c, alloc); |
850 } else if (c.sweep_gt(leftTop->fPoint, top->fPoint) && !edge->isRightOf(
leftTop)) { | 856 } else if (c.sweep_gt(leftTop->fPoint, top->fPoint) && !edge->isRightOf(
leftTop)) { |
851 split_edge(edge, leftTop, activeEdges, c, alloc); | 857 split_edge(edge, leftTop, activeEdges, c, alloc); |
852 } else if (c.sweep_lt(bottom->fPoint, leftBottom->fPoint) && | 858 } else if (c.sweep_lt(bottom->fPoint, leftBottom->fPoint) && |
(...skipping 13 matching lines...) Expand all Loading... |
866 } else if (c.sweep_lt(bottom->fPoint, rightBottom->fPoint) && | 872 } else if (c.sweep_lt(bottom->fPoint, rightBottom->fPoint) && |
867 !edge->fRight->isRightOf(bottom)) { | 873 !edge->fRight->isRightOf(bottom)) { |
868 split_edge(edge->fRight, bottom, activeEdges, c, alloc); | 874 split_edge(edge->fRight, bottom, activeEdges, c, alloc); |
869 } else if (c.sweep_lt(rightBottom->fPoint, bottom->fPoint) && | 875 } else if (c.sweep_lt(rightBottom->fPoint, bottom->fPoint) && |
870 !edge->isLeftOf(rightBottom)) { | 876 !edge->isLeftOf(rightBottom)) { |
871 split_edge(edge, rightBottom, activeEdges, c, alloc); | 877 split_edge(edge, rightBottom, activeEdges, c, alloc); |
872 } | 878 } |
873 } | 879 } |
874 } | 880 } |
875 | 881 |
876 void split_edge(Edge* edge, Vertex* v, Edge** activeEdges, Comparator& c, SkChun
kAlloc& alloc) { | 882 void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c, SkC
hunkAlloc& alloc) { |
877 LOG("splitting edge (%g -> %g) at vertex %g (%g, %g)\n", | 883 LOG("splitting edge (%g -> %g) at vertex %g (%g, %g)\n", |
878 edge->fTop->fID, edge->fBottom->fID, | 884 edge->fTop->fID, edge->fBottom->fID, |
879 v->fID, v->fPoint.fX, v->fPoint.fY); | 885 v->fID, v->fPoint.fX, v->fPoint.fY); |
880 if (c.sweep_lt(v->fPoint, edge->fTop->fPoint)) { | 886 if (c.sweep_lt(v->fPoint, edge->fTop->fPoint)) { |
881 set_top(edge, v, activeEdges, c); | 887 set_top(edge, v, activeEdges, c); |
882 } else if (c.sweep_gt(v->fPoint, edge->fBottom->fPoint)) { | 888 } else if (c.sweep_gt(v->fPoint, edge->fBottom->fPoint)) { |
883 set_bottom(edge, v, activeEdges, c); | 889 set_bottom(edge, v, activeEdges, c); |
884 } else { | 890 } else { |
885 Edge* newEdge = ALLOC_NEW(Edge, (v, edge->fBottom, edge->fWinding), allo
c); | 891 Edge* newEdge = ALLOC_NEW(Edge, (v, edge->fBottom, edge->fWinding), allo
c); |
886 insert_edge_below(newEdge, v, c); | 892 insert_edge_below(newEdge, v, c); |
(...skipping 14 matching lines...) Expand all Loading... |
901 edge = next; | 907 edge = next; |
902 } | 908 } |
903 for (Edge* edge = src->fFirstEdgeBelow; edge;) { | 909 for (Edge* edge = src->fFirstEdgeBelow; edge;) { |
904 Edge* next = edge->fNextEdgeBelow; | 910 Edge* next = edge->fNextEdgeBelow; |
905 set_top(edge, dst, NULL, c); | 911 set_top(edge, dst, NULL, c); |
906 edge = next; | 912 edge = next; |
907 } | 913 } |
908 remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(src, head, NULL); | 914 remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(src, head, NULL); |
909 } | 915 } |
910 | 916 |
911 Vertex* check_for_intersection(Edge* edge, Edge* other, Edge** activeEdges, Comp
arator& c, | 917 Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C
omparator& c, |
912 SkChunkAlloc& alloc) { | 918 SkChunkAlloc& alloc) { |
913 SkPoint p; | 919 SkPoint p; |
914 if (!edge || !other) { | 920 if (!edge || !other) { |
915 return NULL; | 921 return NULL; |
916 } | 922 } |
917 if (edge->intersect(*other, &p)) { | 923 if (edge->intersect(*other, &p)) { |
918 Vertex* v; | 924 Vertex* v; |
919 LOG("found intersection, pt is %g, %g\n", p.fX, p.fY); | 925 LOG("found intersection, pt is %g, %g\n", p.fX, p.fY); |
920 if (p == edge->fTop->fPoint || c.sweep_lt(p, edge->fTop->fPoint)) { | 926 if (p == edge->fTop->fPoint || c.sweep_lt(p, edge->fTop->fPoint)) { |
921 split_edge(other, edge->fTop, activeEdges, c, alloc); | 927 split_edge(other, edge->fTop, activeEdges, c, alloc); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 if (b) { | 1111 if (b) { |
1106 append_vertex_list(b, &head, &tail); | 1112 append_vertex_list(b, &head, &tail); |
1107 } | 1113 } |
1108 return head; | 1114 return head; |
1109 } | 1115 } |
1110 | 1116 |
1111 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges. | 1117 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges. |
1112 | 1118 |
1113 void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) { | 1119 void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) { |
1114 LOG("simplifying complex polygons\n"); | 1120 LOG("simplifying complex polygons\n"); |
1115 Edge* activeEdges = NULL; | 1121 EdgeList activeEdges; |
1116 for (Vertex* v = vertices; v != NULL; v = v->fNext) { | 1122 for (Vertex* v = vertices; v != NULL; v = v->fNext) { |
1117 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { | 1123 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { |
1118 continue; | 1124 continue; |
1119 } | 1125 } |
1120 #if LOGGING_ENABLED | 1126 #if LOGGING_ENABLED |
1121 LOG("\nvertex %g: (%g,%g)\n", v->fID, v->fPoint.fX, v->fPoint.fY); | 1127 LOG("\nvertex %g: (%g,%g)\n", v->fID, v->fPoint.fX, v->fPoint.fY); |
1122 #endif | 1128 #endif |
1123 Edge* leftEnclosingEdge = NULL; | 1129 Edge* leftEnclosingEdge = NULL; |
1124 Edge* rightEnclosingEdge = NULL; | 1130 Edge* rightEnclosingEdge = NULL; |
1125 bool restartChecks; | 1131 bool restartChecks; |
1126 do { | 1132 do { |
1127 restartChecks = false; | 1133 restartChecks = false; |
1128 find_enclosing_edges(v, activeEdges, &leftEnclosingEdge, &rightEnclo
singEdge); | 1134 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEncl
osingEdge); |
1129 if (v->fFirstEdgeBelow) { | 1135 if (v->fFirstEdgeBelow) { |
1130 for (Edge* edge = v->fFirstEdgeBelow; edge != NULL; edge = edge-
>fNextEdgeBelow) { | 1136 for (Edge* edge = v->fFirstEdgeBelow; edge != NULL; edge = edge-
>fNextEdgeBelow) { |
1131 if (check_for_intersection(edge, leftEnclosingEdge, &activeE
dges, c, alloc)) { | 1137 if (check_for_intersection(edge, leftEnclosingEdge, &activeE
dges, c, alloc)) { |
1132 restartChecks = true; | 1138 restartChecks = true; |
1133 break; | 1139 break; |
1134 } | 1140 } |
1135 if (check_for_intersection(edge, rightEnclosingEdge, &active
Edges, c, alloc)) { | 1141 if (check_for_intersection(edge, rightEnclosingEdge, &active
Edges, c, alloc)) { |
1136 restartChecks = true; | 1142 restartChecks = true; |
1137 break; | 1143 break; |
1138 } | 1144 } |
(...skipping 18 matching lines...) Expand all Loading... |
1157 leftEdge = e; | 1163 leftEdge = e; |
1158 } | 1164 } |
1159 v->fProcessed = true; | 1165 v->fProcessed = true; |
1160 } | 1166 } |
1161 } | 1167 } |
1162 | 1168 |
1163 // Stage 5: Tessellate the simplified mesh into monotone polygons. | 1169 // Stage 5: Tessellate the simplified mesh into monotone polygons. |
1164 | 1170 |
1165 Poly* tessellate(Vertex* vertices, SkChunkAlloc& alloc) { | 1171 Poly* tessellate(Vertex* vertices, SkChunkAlloc& alloc) { |
1166 LOG("tessellating simple polygons\n"); | 1172 LOG("tessellating simple polygons\n"); |
1167 Edge* activeEdges = NULL; | 1173 EdgeList activeEdges; |
1168 Poly* polys = NULL; | 1174 Poly* polys = NULL; |
1169 for (Vertex* v = vertices; v != NULL; v = v->fNext) { | 1175 for (Vertex* v = vertices; v != NULL; v = v->fNext) { |
1170 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { | 1176 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { |
1171 continue; | 1177 continue; |
1172 } | 1178 } |
1173 #if LOGGING_ENABLED | 1179 #if LOGGING_ENABLED |
1174 LOG("\nvertex %g: (%g,%g)\n", v->fID, v->fPoint.fX, v->fPoint.fY); | 1180 LOG("\nvertex %g: (%g,%g)\n", v->fID, v->fPoint.fX, v->fPoint.fY); |
1175 #endif | 1181 #endif |
1176 Edge* leftEnclosingEdge = NULL; | 1182 Edge* leftEnclosingEdge = NULL; |
1177 Edge* rightEnclosingEdge = NULL; | 1183 Edge* rightEnclosingEdge = NULL; |
1178 find_enclosing_edges(v, activeEdges, &leftEnclosingEdge, &rightEnclosing
Edge); | 1184 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosin
gEdge); |
1179 Poly* leftPoly = NULL; | 1185 Poly* leftPoly = NULL; |
1180 Poly* rightPoly = NULL; | 1186 Poly* rightPoly = NULL; |
1181 if (v->fFirstEdgeAbove) { | 1187 if (v->fFirstEdgeAbove) { |
1182 leftPoly = v->fFirstEdgeAbove->fLeftPoly; | 1188 leftPoly = v->fFirstEdgeAbove->fLeftPoly; |
1183 rightPoly = v->fLastEdgeAbove->fRightPoly; | 1189 rightPoly = v->fLastEdgeAbove->fRightPoly; |
1184 } else { | 1190 } else { |
1185 leftPoly = leftEnclosingEdge ? leftEnclosingEdge->fRightPoly : NULL; | 1191 leftPoly = leftEnclosingEdge ? leftEnclosingEdge->fRightPoly : NULL; |
1186 rightPoly = rightEnclosingEdge ? rightEnclosingEdge->fLeftPoly : NUL
L; | 1192 rightPoly = rightEnclosingEdge ? rightEnclosingEdge->fLeftPoly : NUL
L; |
1187 } | 1193 } |
1188 #if LOGGING_ENABLED | 1194 #if LOGGING_ENABLED |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 if (winding != 0) { | 1268 if (winding != 0) { |
1263 Poly* poly = new_poly(&polys, v, winding, alloc); | 1269 Poly* poly = new_poly(&polys, v, winding, alloc); |
1264 leftEdge->fRightPoly = rightEdge->fLeftPoly = poly; | 1270 leftEdge->fRightPoly = rightEdge->fLeftPoly = poly; |
1265 } | 1271 } |
1266 leftEdge = rightEdge; | 1272 leftEdge = rightEdge; |
1267 } | 1273 } |
1268 v->fLastEdgeBelow->fRightPoly = rightPoly; | 1274 v->fLastEdgeBelow->fRightPoly = rightPoly; |
1269 } | 1275 } |
1270 #if LOGGING_ENABLED | 1276 #if LOGGING_ENABLED |
1271 LOG("\nactive edges:\n"); | 1277 LOG("\nactive edges:\n"); |
1272 for (Edge* e = activeEdges; e != NULL; e = e->fRight) { | 1278 for (Edge* e = activeEdges->fHead; e != NULL; e = e->fRight) { |
1273 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, | 1279 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, |
1274 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRight
Poly->fID : -1); | 1280 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRight
Poly->fID : -1); |
1275 } | 1281 } |
1276 #endif | 1282 #endif |
1277 } | 1283 } |
1278 return polys; | 1284 return polys; |
1279 } | 1285 } |
1280 | 1286 |
1281 // This is a driver function which calls stages 2-5 in turn. | 1287 // This is a driver function which calls stages 2-5 in turn. |
1282 | 1288 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 SkMatrix vmi; | 1511 SkMatrix vmi; |
1506 if (!viewM.invert(&vmi)) { | 1512 if (!viewM.invert(&vmi)) { |
1507 return false; | 1513 return false; |
1508 } | 1514 } |
1509 vmi.mapRect(&clipBounds); | 1515 vmi.mapRect(&clipBounds); |
1510 SkAutoTUnref<GrBatch> batch(TessellatingPathBatch::Create(color, path, viewM
, clipBounds)); | 1516 SkAutoTUnref<GrBatch> batch(TessellatingPathBatch::Create(color, path, viewM
, clipBounds)); |
1511 target->drawBatch(pipelineBuilder, batch); | 1517 target->drawBatch(pipelineBuilder, batch); |
1512 | 1518 |
1513 return true; | 1519 return true; |
1514 } | 1520 } |
OLD | NEW |