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 "GrTessellator.h" | 8 #include "GrTessellator.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 | 87 |
88 #define ALLOC_NEW(Type, args, alloc) new (alloc.allocThrow(sizeof(Type))) Type a
rgs | 88 #define ALLOC_NEW(Type, args, alloc) new (alloc.allocThrow(sizeof(Type))) Type a
rgs |
89 | 89 |
90 namespace { | 90 namespace { |
91 | 91 |
92 struct Vertex; | 92 struct Vertex; |
93 struct Edge; | 93 struct Edge; |
94 struct Poly; | 94 struct Poly; |
95 | 95 |
96 template <class T, T* T::*Prev, T* T::*Next> | 96 template <class T, T* T::*Prev, T* T::*Next> |
97 void insert(T* t, T* prev, T* next, T** head, T** tail) { | 97 void list_insert(T* t, T* prev, T* next, T** head, T** tail) { |
98 t->*Prev = prev; | 98 t->*Prev = prev; |
99 t->*Next = next; | 99 t->*Next = next; |
100 if (prev) { | 100 if (prev) { |
101 prev->*Next = t; | 101 prev->*Next = t; |
102 } else if (head) { | 102 } else if (head) { |
103 *head = t; | 103 *head = t; |
104 } | 104 } |
105 if (next) { | 105 if (next) { |
106 next->*Prev = t; | 106 next->*Prev = t; |
107 } else if (tail) { | 107 } else if (tail) { |
108 *tail = t; | 108 *tail = t; |
109 } | 109 } |
110 } | 110 } |
111 | 111 |
112 template <class T, T* T::*Prev, T* T::*Next> | 112 template <class T, T* T::*Prev, T* T::*Next> |
113 void remove(T* t, T** head, T** tail) { | 113 void list_remove(T* t, T** head, T** tail) { |
114 if (t->*Prev) { | 114 if (t->*Prev) { |
115 t->*Prev->*Next = t->*Next; | 115 t->*Prev->*Next = t->*Next; |
116 } else if (head) { | 116 } else if (head) { |
117 *head = t->*Next; | 117 *head = t->*Next; |
118 } | 118 } |
119 if (t->*Next) { | 119 if (t->*Next) { |
120 t->*Next->*Prev = t->*Prev; | 120 t->*Next->*Prev = t->*Prev; |
121 } else if (tail) { | 121 } else if (tail) { |
122 *tail = t->*Prev; | 122 *tail = t->*Prev; |
123 } | 123 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 #endif | 203 #endif |
204 return data; | 204 return data; |
205 } | 205 } |
206 | 206 |
207 struct EdgeList { | 207 struct EdgeList { |
208 EdgeList() : fHead(nullptr), fTail(nullptr) {} | 208 EdgeList() : fHead(nullptr), fTail(nullptr) {} |
209 Edge* fHead; | 209 Edge* fHead; |
210 Edge* fTail; | 210 Edge* fTail; |
211 }; | 211 }; |
212 | 212 |
| 213 struct VertexList { |
| 214 VertexList() : fHead(nullptr), fTail(nullptr) {} |
| 215 Vertex* fHead; |
| 216 Vertex* fTail; |
| 217 void insert(Vertex* v, Vertex* prev, Vertex* next) { |
| 218 list_insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, prev, next, &fHea
d, &fTail); |
| 219 } |
| 220 void append(Vertex* v) { |
| 221 insert(v, fTail, nullptr); |
| 222 } |
| 223 void prepend(Vertex* v) { |
| 224 insert(v, nullptr, fHead); |
| 225 } |
| 226 }; |
| 227 |
213 /** | 228 /** |
214 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of
"edges above" and | 229 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of
"edges above" and |
215 * "edge below" a vertex as well as for the active edge list is handled by isLef
tOf()/isRightOf(). | 230 * "edge below" a vertex as well as for the active edge list is handled by isLef
tOf()/isRightOf(). |
216 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b
ecause floating | 231 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b
ecause floating |
217 * point). For speed, that case is only tested by the callers which require it (
e.g., | 232 * point). For speed, that case is only tested by the callers which require it (
e.g., |
218 * cleanup_active_edges()). Edges also handle checking for intersection with oth
er edges. | 233 * cleanup_active_edges()). Edges also handle checking for intersection with oth
er edges. |
219 * Currently, this converts the edges to the parametric form, in order to avoid
doing a division | 234 * Currently, this converts the edges to the parametric form, in order to avoid
doing a division |
220 * until an intersection has been confirmed. This is slightly slower in the "fou
nd" case, but | 235 * until an intersection has been confirmed. This is slightly slower in the "fou
nd" case, but |
221 * a lot faster in the "not found" case. | 236 * a lot faster in the "not found" case. |
222 * | 237 * |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 #if LOGGING_ENABLED | 334 #if LOGGING_ENABLED |
320 static int gID = 0; | 335 static int gID = 0; |
321 fID = gID++; | 336 fID = gID++; |
322 LOG("*** created Poly %d\n", fID); | 337 LOG("*** created Poly %d\n", fID); |
323 #endif | 338 #endif |
324 } | 339 } |
325 typedef enum { kNeither_Side, kLeft_Side, kRight_Side } Side; | 340 typedef enum { kNeither_Side, kLeft_Side, kRight_Side } Side; |
326 struct MonotonePoly { | 341 struct MonotonePoly { |
327 MonotonePoly() | 342 MonotonePoly() |
328 : fSide(kNeither_Side) | 343 : fSide(kNeither_Side) |
329 , fHead(nullptr) | |
330 , fTail(nullptr) | |
331 , fPrev(nullptr) | 344 , fPrev(nullptr) |
332 , fNext(nullptr) {} | 345 , fNext(nullptr) {} |
333 Side fSide; | 346 Side fSide; |
334 Vertex* fHead; | 347 VertexList fVertices; |
335 Vertex* fTail; | |
336 MonotonePoly* fPrev; | 348 MonotonePoly* fPrev; |
337 MonotonePoly* fNext; | 349 MonotonePoly* fNext; |
338 bool addVertex(Vertex* v, Side side, SkChunkAlloc& alloc) { | 350 bool addVertex(Vertex* v, Side side, SkChunkAlloc& alloc) { |
339 Vertex* newV = ALLOC_NEW(Vertex, (v->fPoint), alloc); | 351 Vertex* newV = ALLOC_NEW(Vertex, (v->fPoint), alloc); |
340 bool done = false; | 352 bool done = false; |
341 if (fSide == kNeither_Side) { | 353 if (fSide == kNeither_Side) { |
342 fSide = side; | 354 fSide = side; |
343 } else { | 355 } else { |
344 done = side != fSide; | 356 done = side != fSide; |
345 } | 357 } |
346 if (fHead == nullptr) { | 358 if (fSide == kRight_Side) { |
347 fHead = fTail = newV; | 359 fVertices.append(newV); |
348 } else if (fSide == kRight_Side) { | |
349 newV->fPrev = fTail; | |
350 fTail->fNext = newV; | |
351 fTail = newV; | |
352 } else { | 360 } else { |
353 newV->fNext = fHead; | 361 fVertices.prepend(newV); |
354 fHead->fPrev = newV; | |
355 fHead = newV; | |
356 } | 362 } |
357 return done; | 363 return done; |
358 } | 364 } |
359 | 365 |
360 SkPoint* emit(SkPoint* data) { | 366 SkPoint* emit(SkPoint* data) { |
361 Vertex* first = fHead; | 367 Vertex* first = fVertices.fHead; |
362 Vertex* v = first->fNext; | 368 Vertex* v = first->fNext; |
363 while (v != fTail) { | 369 while (v != fVertices.fTail) { |
364 SkASSERT(v && v->fPrev && v->fNext); | 370 SkASSERT(v && v->fPrev && v->fNext); |
365 Vertex* prev = v->fPrev; | 371 Vertex* prev = v->fPrev; |
366 Vertex* curr = v; | 372 Vertex* curr = v; |
367 Vertex* next = v->fNext; | 373 Vertex* next = v->fNext; |
368 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint.
fX; | 374 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint.
fX; |
369 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint.
fY; | 375 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint.
fY; |
370 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint.
fX; | 376 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint.
fX; |
371 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint.
fY; | 377 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint.
fY; |
372 if (ax * by - ay * bx >= 0.0) { | 378 if (ax * by - ay * bx >= 0.0) { |
373 data = emit_triangle(prev, curr, next, data); | 379 data = emit_triangle(prev, curr, next, data); |
(...skipping 28 matching lines...) Expand all Loading... |
402 fTail->fNext = fActive; | 408 fTail->fNext = fActive; |
403 fTail = fActive; | 409 fTail = fActive; |
404 } else { | 410 } else { |
405 fHead = fTail = fActive; | 411 fHead = fTail = fActive; |
406 } | 412 } |
407 if (partner) { | 413 if (partner) { |
408 partner->addVertex(v, side, alloc); | 414 partner->addVertex(v, side, alloc); |
409 poly = partner; | 415 poly = partner; |
410 } else { | 416 } else { |
411 Vertex* prev = fActive->fSide == Poly::kLeft_Side ? | 417 Vertex* prev = fActive->fSide == Poly::kLeft_Side ? |
412 fActive->fHead->fNext : fActive->fTail->fPrev; | 418 fActive->fVertices.fHead->fNext : fActive->fVerti
ces.fTail->fPrev; |
413 fActive = ALLOC_NEW(MonotonePoly, , alloc); | 419 fActive = ALLOC_NEW(MonotonePoly, , alloc); |
414 fActive->addVertex(prev, Poly::kNeither_Side, alloc); | 420 fActive->addVertex(prev, Poly::kNeither_Side, alloc); |
415 fActive->addVertex(v, side, alloc); | 421 fActive->addVertex(v, side, alloc); |
416 } | 422 } |
417 } | 423 } |
418 fCount++; | 424 fCount++; |
419 return poly; | 425 return poly; |
420 } | 426 } |
421 void end(Vertex* v, SkChunkAlloc& alloc) { | 427 void end(Vertex* v, SkChunkAlloc& alloc) { |
422 LOG("end() %d at %g, %g\n", fID, v->fPoint.fX, v->fPoint.fY); | 428 LOG("end() %d at %g, %g\n", fID, v->fPoint.fX, v->fPoint.fY); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c) { | 644 Edge* new_edge(Vertex* prev, Vertex* next, SkChunkAlloc& alloc, Comparator& c) { |
639 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; | 645 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; |
640 Vertex* top = winding < 0 ? next : prev; | 646 Vertex* top = winding < 0 ? next : prev; |
641 Vertex* bottom = winding < 0 ? prev : next; | 647 Vertex* bottom = winding < 0 ? prev : next; |
642 return ALLOC_NEW(Edge, (top, bottom, winding), alloc); | 648 return ALLOC_NEW(Edge, (top, bottom, winding), alloc); |
643 } | 649 } |
644 | 650 |
645 void remove_edge(Edge* edge, EdgeList* edges) { | 651 void remove_edge(Edge* edge, EdgeList* edges) { |
646 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); | 652 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); |
647 SkASSERT(edge->isActive(edges)); | 653 SkASSERT(edge->isActive(edges)); |
648 remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &edges->fHead, &edges->fTail
); | 654 list_remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &edges->fHead, &edges->
fTail); |
649 } | 655 } |
650 | 656 |
651 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) { | 657 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) { |
652 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); | 658 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); |
653 SkASSERT(!edge->isActive(edges)); | 659 SkASSERT(!edge->isActive(edges)); |
654 Edge* next = prev ? prev->fRight : edges->fHead; | 660 Edge* next = prev ? prev->fRight : edges->fHead; |
655 insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &edges->fHead, &
edges->fTail); | 661 list_insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &edges->fHe
ad, &edges->fTail); |
656 } | 662 } |
657 | 663 |
658 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right)
{ | 664 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right)
{ |
659 if (v->fFirstEdgeAbove) { | 665 if (v->fFirstEdgeAbove) { |
660 *left = v->fFirstEdgeAbove->fLeft; | 666 *left = v->fFirstEdgeAbove->fLeft; |
661 *right = v->fLastEdgeAbove->fRight; | 667 *right = v->fLastEdgeAbove->fRight; |
662 return; | 668 return; |
663 } | 669 } |
664 Edge* next = nullptr; | 670 Edge* next = nullptr; |
665 Edge* prev; | 671 Edge* prev; |
666 for (prev = edges->fTail; prev != nullptr; prev = prev->fLeft) { | 672 for (prev = edges->fTail; prev != nullptr; prev = prev->fLeft) { |
667 if (prev->isLeftOf(v)) { | 673 if (prev->isLeftOf(v)) { |
668 break; | 674 break; |
669 } | 675 } |
670 next = prev; | 676 next = prev; |
671 } | 677 } |
672 *left = prev; | 678 *left = prev; |
673 *right = next; | 679 *right = next; |
674 return; | |
675 } | 680 } |
676 | 681 |
677 void find_enclosing_edges(Edge* edge, EdgeList* edges, Comparator& c, Edge** lef
t, Edge** right) { | 682 void find_enclosing_edges(Edge* edge, EdgeList* edges, Comparator& c, Edge** lef
t, Edge** right) { |
678 Edge* prev = nullptr; | 683 Edge* prev = nullptr; |
679 Edge* next; | 684 Edge* next; |
680 for (next = edges->fHead; next != nullptr; next = next->fRight) { | 685 for (next = edges->fHead; next != nullptr; next = next->fRight) { |
681 if ((c.sweep_gt(edge->fTop->fPoint, next->fTop->fPoint) && next->isRight
Of(edge->fTop)) || | 686 if ((c.sweep_gt(edge->fTop->fPoint, next->fTop->fPoint) && next->isRight
Of(edge->fTop)) || |
682 (c.sweep_gt(next->fTop->fPoint, edge->fTop->fPoint) && edge->isLeftO
f(next->fTop)) || | 687 (c.sweep_gt(next->fTop->fPoint, edge->fTop->fPoint) && edge->isLeftO
f(next->fTop)) || |
683 (c.sweep_lt(edge->fBottom->fPoint, next->fBottom->fPoint) && | 688 (c.sweep_lt(edge->fBottom->fPoint, next->fBottom->fPoint) && |
684 next->isRightOf(edge->fBottom)) || | 689 next->isRightOf(edge->fBottom)) || |
685 (c.sweep_lt(next->fBottom->fPoint, edge->fBottom->fPoint) && | 690 (c.sweep_lt(next->fBottom->fPoint, edge->fBottom->fPoint) && |
686 edge->isLeftOf(next->fBottom))) { | 691 edge->isLeftOf(next->fBottom))) { |
687 break; | 692 break; |
688 } | 693 } |
689 prev = next; | 694 prev = next; |
690 } | 695 } |
691 *left = prev; | 696 *left = prev; |
692 *right = next; | 697 *right = next; |
693 return; | |
694 } | 698 } |
695 | 699 |
696 void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) { | 700 void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) { |
697 if (edge->isActive(activeEdges)) { | 701 if (edge->isActive(activeEdges)) { |
698 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) { | 702 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) { |
699 remove_edge(edge, activeEdges); | 703 remove_edge(edge, activeEdges); |
700 } | 704 } |
701 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) { | 705 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) { |
702 Edge* left; | 706 Edge* left; |
703 Edge* right; | 707 Edge* right; |
704 find_enclosing_edges(edge, activeEdges, c, &left, &right); | 708 find_enclosing_edges(edge, activeEdges, c, &left, &right); |
705 insert_edge(edge, left, activeEdges); | 709 insert_edge(edge, left, activeEdges); |
706 } | 710 } |
707 } | 711 } |
708 | 712 |
709 void insert_edge_above(Edge* edge, Vertex* v, Comparator& c) { | 713 void insert_edge_above(Edge* edge, Vertex* v, Comparator& c) { |
710 if (edge->fTop->fPoint == edge->fBottom->fPoint || | 714 if (edge->fTop->fPoint == edge->fBottom->fPoint || |
711 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { | 715 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { |
712 return; | 716 return; |
713 } | 717 } |
714 LOG("insert edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); | 718 LOG("insert edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); |
715 Edge* prev = nullptr; | 719 Edge* prev = nullptr; |
716 Edge* next; | 720 Edge* next; |
717 for (next = v->fFirstEdgeAbove; next; next = next->fNextEdgeAbove) { | 721 for (next = v->fFirstEdgeAbove; next; next = next->fNextEdgeAbove) { |
718 if (next->isRightOf(edge->fTop)) { | 722 if (next->isRightOf(edge->fTop)) { |
719 break; | 723 break; |
720 } | 724 } |
721 prev = next; | 725 prev = next; |
722 } | 726 } |
723 insert<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( | 727 list_insert<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( |
724 edge, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove); | 728 edge, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove); |
725 } | 729 } |
726 | 730 |
727 void insert_edge_below(Edge* edge, Vertex* v, Comparator& c) { | 731 void insert_edge_below(Edge* edge, Vertex* v, Comparator& c) { |
728 if (edge->fTop->fPoint == edge->fBottom->fPoint || | 732 if (edge->fTop->fPoint == edge->fBottom->fPoint || |
729 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { | 733 c.sweep_gt(edge->fTop->fPoint, edge->fBottom->fPoint)) { |
730 return; | 734 return; |
731 } | 735 } |
732 LOG("insert edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); | 736 LOG("insert edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBott
om->fID, v->fID); |
733 Edge* prev = nullptr; | 737 Edge* prev = nullptr; |
734 Edge* next; | 738 Edge* next; |
735 for (next = v->fFirstEdgeBelow; next; next = next->fNextEdgeBelow) { | 739 for (next = v->fFirstEdgeBelow; next; next = next->fNextEdgeBelow) { |
736 if (next->isRightOf(edge->fBottom)) { | 740 if (next->isRightOf(edge->fBottom)) { |
737 break; | 741 break; |
738 } | 742 } |
739 prev = next; | 743 prev = next; |
740 } | 744 } |
741 insert<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( | 745 list_insert<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( |
742 edge, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow); | 746 edge, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow); |
743 } | 747 } |
744 | 748 |
745 void remove_edge_above(Edge* edge) { | 749 void remove_edge_above(Edge* edge) { |
746 LOG("removing edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, | 750 LOG("removing edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, |
747 edge->fBottom->fID); | 751 edge->fBottom->fID); |
748 remove<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( | 752 list_remove<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( |
749 edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove); | 753 edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove); |
750 } | 754 } |
751 | 755 |
752 void remove_edge_below(Edge* edge) { | 756 void remove_edge_below(Edge* edge) { |
753 LOG("removing edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, | 757 LOG("removing edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBo
ttom->fID, |
754 edge->fTop->fID); | 758 edge->fTop->fID); |
755 remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( | 759 list_remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( |
756 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow); | 760 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow); |
757 } | 761 } |
758 | 762 |
759 void erase_edge_if_zero_winding(Edge* edge, EdgeList* edges) { | 763 void erase_edge_if_zero_winding(Edge* edge, EdgeList* edges) { |
760 if (edge->fWinding != 0) { | 764 if (edge->fWinding != 0) { |
761 return; | 765 return; |
762 } | 766 } |
763 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID); | 767 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID); |
764 remove_edge_above(edge); | 768 remove_edge_above(edge); |
765 remove_edge_below(edge); | 769 remove_edge_below(edge); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 for (Edge* edge = src->fFirstEdgeAbove; edge;) { | 910 for (Edge* edge = src->fFirstEdgeAbove; edge;) { |
907 Edge* next = edge->fNextEdgeAbove; | 911 Edge* next = edge->fNextEdgeAbove; |
908 set_bottom(edge, dst, nullptr, c); | 912 set_bottom(edge, dst, nullptr, c); |
909 edge = next; | 913 edge = next; |
910 } | 914 } |
911 for (Edge* edge = src->fFirstEdgeBelow; edge;) { | 915 for (Edge* edge = src->fFirstEdgeBelow; edge;) { |
912 Edge* next = edge->fNextEdgeBelow; | 916 Edge* next = edge->fNextEdgeBelow; |
913 set_top(edge, dst, nullptr, c); | 917 set_top(edge, dst, nullptr, c); |
914 edge = next; | 918 edge = next; |
915 } | 919 } |
916 remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(src, head, nullptr); | 920 list_remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(src, head, nullptr); |
917 } | 921 } |
918 | 922 |
919 Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C
omparator& c, | 923 Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C
omparator& c, |
920 SkChunkAlloc& alloc) { | 924 SkChunkAlloc& alloc) { |
921 SkPoint p; | 925 SkPoint p; |
922 if (!edge || !other) { | 926 if (!edge || !other) { |
923 return nullptr; | 927 return nullptr; |
924 } | 928 } |
925 if (edge->intersect(*other, &p)) { | 929 if (edge->intersect(*other, &p)) { |
926 Vertex* v; | 930 Vertex* v; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 Vertex* a; | 1081 Vertex* a; |
1078 Vertex* b; | 1082 Vertex* b; |
1079 front_back_split(*head, &a, &b); | 1083 front_back_split(*head, &a, &b); |
1080 | 1084 |
1081 merge_sort(&a, c); | 1085 merge_sort(&a, c); |
1082 merge_sort(&b, c); | 1086 merge_sort(&b, c); |
1083 | 1087 |
1084 *head = sorted_merge(a, b, c); | 1088 *head = sorted_merge(a, b, c); |
1085 } | 1089 } |
1086 | 1090 |
1087 inline void append_vertex(Vertex* v, Vertex** head, Vertex** tail) { | |
1088 insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, *tail, nullptr, head, tail
); | |
1089 } | |
1090 | |
1091 inline void append_vertex_list(Vertex* v, Vertex** head, Vertex** tail) { | |
1092 insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, *tail, v->fNext, head, tai
l); | |
1093 } | |
1094 | |
1095 Vertex* sorted_merge(Vertex* a, Vertex* b, Comparator& c) { | 1091 Vertex* sorted_merge(Vertex* a, Vertex* b, Comparator& c) { |
1096 Vertex* head = nullptr; | 1092 VertexList vertices; |
1097 Vertex* tail = nullptr; | |
1098 | 1093 |
1099 while (a && b) { | 1094 while (a && b) { |
1100 if (c.sweep_lt(a->fPoint, b->fPoint)) { | 1095 if (c.sweep_lt(a->fPoint, b->fPoint)) { |
1101 Vertex* next = a->fNext; | 1096 Vertex* next = a->fNext; |
1102 append_vertex(a, &head, &tail); | 1097 vertices.append(a); |
1103 a = next; | 1098 a = next; |
1104 } else { | 1099 } else { |
1105 Vertex* next = b->fNext; | 1100 Vertex* next = b->fNext; |
1106 append_vertex(b, &head, &tail); | 1101 vertices.append(b); |
1107 b = next; | 1102 b = next; |
1108 } | 1103 } |
1109 } | 1104 } |
1110 if (a) { | 1105 if (a) { |
1111 append_vertex_list(a, &head, &tail); | 1106 vertices.insert(a, vertices.fTail, a->fNext); |
1112 } | 1107 } |
1113 if (b) { | 1108 if (b) { |
1114 append_vertex_list(b, &head, &tail); | 1109 vertices.insert(b, vertices.fTail, b->fNext); |
1115 } | 1110 } |
1116 return head; | 1111 return vertices.fHead; |
1117 } | 1112 } |
1118 | 1113 |
1119 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges. | 1114 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges. |
1120 | 1115 |
1121 void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) { | 1116 void simplify(Vertex* vertices, Comparator& c, SkChunkAlloc& alloc) { |
1122 LOG("simplifying complex polygons\n"); | 1117 LOG("simplifying complex polygons\n"); |
1123 EdgeList activeEdges; | 1118 EdgeList activeEdges; |
1124 for (Vertex* v = vertices; v != nullptr; v = v->fNext) { | 1119 for (Vertex* v = vertices; v != nullptr; v = v->fNext) { |
1125 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { | 1120 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { |
1126 continue; | 1121 continue; |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1461 } | 1456 } |
1462 } | 1457 } |
1463 int actualCount = static_cast<int>(vertsEnd - *verts); | 1458 int actualCount = static_cast<int>(vertsEnd - *verts); |
1464 SkASSERT(actualCount <= count); | 1459 SkASSERT(actualCount <= count); |
1465 SkASSERT(pointsEnd - points == actualCount); | 1460 SkASSERT(pointsEnd - points == actualCount); |
1466 delete[] points; | 1461 delete[] points; |
1467 return actualCount; | 1462 return actualCount; |
1468 } | 1463 } |
1469 | 1464 |
1470 } // namespace | 1465 } // namespace |
OLD | NEW |