| 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 |