1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "GrTessellator.h" 9 10 #include "GrDefaultGeoProcFactory.h" 11 #include "GrPathUtils.h" 12 13 #include "SkArenaAlloc.h" 14 #include "SkGeometry.h" 15 #include "SkPath.h" 16 17 #include <stdio.h> 18 19 /* 20 * There are six stages to the basic algorithm: 21 * 22 * 1) Linearize the path contours into piecewise linear segments (path_to_contours()). 23 * 2) Build a mesh of edges connecting the vertices (build_edges()). 24 * 3) Sort the vertices in Y (and secondarily in X) (merge_sort()). 25 * 4) Simplify the mesh by inserting new vertices at intersecting edges (simplify()). 26 * 5) Tessellate the simplified mesh into monotone polygons (tessellate()). 27 * 6) Triangulate the monotone polygons directly into a vertex buffer (polys_to_triangles()). 28 * 29 * For screenspace antialiasing, the algorithm is modified as follows: 30 * 31 * Run steps 1-5 above to produce polygons. 32 * 5b) Apply fill rules to extract boundary contours from the polygons (extract_boundaries()). 33 * 5c) Simplify boundaries to remove "pointy" vertices that cause inversions (simplify_boundary()). 34 * 5d) Displace edges by half a pixel inward and outward along their normals. Intersect to find 35 * new vertices, and set zero alpha on the exterior and one alpha on the interior. Build a new 36 * antialiased mesh from those vertices (stroke_boundary()). 37 * Run steps 3-6 above on the new mesh, and produce antialiased triangles. 38 * 39 * The vertex sorting in step (3) is a merge sort, since it plays well with the linked list 40 * of vertices (and the necessity of inserting new vertices on intersection). 41 * 42 * Stages (4) and (5) use an active edge list -- a list of all edges for which the 43 * sweep line has crossed the top vertex, but not the bottom vertex. It's sorted 44 * left-to-right based on the point where both edges are active (when both top vertices 45 * have been seen, so the "lower" top vertex of the two). If the top vertices are equal 46 * (shared), it's sorted based on the last point where both edges are active, so the 47 * "upper" bottom vertex. 48 * 49 * The most complex step is the simplification (4). It's based on the Bentley-Ottman 50 * line-sweep algorithm, but due to floating point inaccuracy, the intersection points are 51 * not exact and may violate the mesh topology or active edge list ordering. We 52 * accommodate this by adjusting the topology of the mesh and AEL to match the intersection 53 * points. This occurs in three ways: 54 * 55 * A) Intersections may cause a shortened edge to no longer be ordered with respect to its 56 * neighbouring edges at the top or bottom vertex. This is handled by merging the 57 * edges (merge_collinear_edges()). 58 * B) Intersections may cause an edge to violate the left-to-right ordering of the 59 * active edge list. This is handled by splitting the neighbour edge on the 60 * intersected vertex (cleanup_active_edges()). 61 * C) Shortening an edge may cause an active edge to become inactive or an inactive edge 62 * to become active. This is handled by removing or inserting the edge in the active 63 * edge list (fix_active_state()). 64 * 65 * The tessellation steps (5) and (6) are based on "Triangulating Simple Polygons and 66 * Equivalent Problems" (Fournier and Montuno); also a line-sweep algorithm. Note that it 67 * currently uses a linked list for the active edge list, rather than a 2-3 tree as the 68 * paper describes. The 2-3 tree gives O(lg N) lookups, but insertion and removal also 69 * become O(lg N). In all the test cases, it was found that the cost of frequent O(lg N) 70 * insertions and removals was greater than the cost of infrequent O(N) lookups with the 71 * linked list implementation. With the latter, all removals are O(1), and most insertions 72 * are O(1), since we know the adjacent edge in the active edge list based on the topology. 73 * Only type 2 vertices (see paper) require the O(N) lookups, and these are much less 74 * frequent. There may be other data structures worth investigating, however. 75 * 76 * Note that the orientation of the line sweep algorithms is determined by the aspect ratio of the 77 * path bounds. When the path is taller than it is wide, we sort vertices based on increasing Y 78 * coordinate, and secondarily by increasing X coordinate. When the path is wider than it is tall, 79 * we sort by increasing X coordinate, but secondarily by *decreasing* Y coordinate. This is so 80 * that the "left" and "right" orientation in the code remains correct (edges to the left are 81 * increasing in Y; edges to the right are decreasing in Y). That is, the setting rotates 90 82 * degrees counterclockwise, rather that transposing. 83 */ 84 85 #define LOGGING_ENABLED 0 86 87 #if LOGGING_ENABLED 88 #define LOG printf 89 #else 90 #define LOG(...) 91 #endif 92 93 namespace { 94 95 const int kArenaChunkSize = 16 * 1024; 96 97 struct Vertex; 98 struct Edge; 99 struct Poly; 100 101 template <class T, T* T::*Prev, T* T::*Next> 102 void list_insert(T* t, T* prev, T* next, T** head, T** tail) { 103 t->*Prev = prev; 104 t->*Next = next; 105 if (prev) { 106 prev->*Next = t; 107 } else if (head) { 108 *head = t; 109 } 110 if (next) { 111 next->*Prev = t; 112 } else if (tail) { 113 *tail = t; 114 } 115 } 116 117 template <class T, T* T::*Prev, T* T::*Next> 118 void list_remove(T* t, T** head, T** tail) { 119 if (t->*Prev) { 120 t->*Prev->*Next = t->*Next; 121 } else if (head) { 122 *head = t->*Next; 123 } 124 if (t->*Next) { 125 t->*Next->*Prev = t->*Prev; 126 } else if (tail) { 127 *tail = t->*Prev; 128 } 129 t->*Prev = t->*Next = nullptr; 130 } 131 132 /** 133 * Vertices are used in three ways: first, the path contours are converted into a 134 * circularly-linked list of Vertices for each contour. After edge construction, the same Vertices 135 * are re-ordered by the merge sort according to the sweep_lt comparator (usually, increasing 136 * in Y) using the same fPrev/fNext pointers that were used for the contours, to avoid 137 * reallocation. Finally, MonotonePolys are built containing a circularly-linked list of 138 * Vertices. (Currently, those Vertices are newly-allocated for the MonotonePolys, since 139 * an individual Vertex from the path mesh may belong to multiple 140 * MonotonePolys, so the original Vertices cannot be re-used. 141 */ 142 143 struct Vertex { 144 Vertex(const SkPoint& point, uint8_t alpha) 145 : fPoint(point), fPrev(nullptr), fNext(nullptr) 146 , fFirstEdgeAbove(nullptr), fLastEdgeAbove(nullptr) 147 , fFirstEdgeBelow(nullptr), fLastEdgeBelow(nullptr) 148 , fPartner(nullptr) 149 , fProcessed(false) 150 , fAlpha(alpha) 151 #if LOGGING_ENABLED 152 , fID (-1.0f) 153 #endif 154 {} 155 SkPoint fPoint; // Vertex position 156 Vertex* fPrev; // Linked list of contours, then Y-sorted vertices. 157 Vertex* fNext; // " 158 Edge* fFirstEdgeAbove; // Linked list of edges above this vertex. 159 Edge* fLastEdgeAbove; // " 160 Edge* fFirstEdgeBelow; // Linked list of edges below this vertex. 161 Edge* fLastEdgeBelow; // " 162 Vertex* fPartner; // Corresponding inner or outer vertex (for AA). 163 bool fProcessed; // Has this vertex been seen in simplify()? 164 uint8_t fAlpha; 165 #if LOGGING_ENABLED 166 float fID; // Identifier used for logging. 167 #endif 168 }; 169 170 /***************************************************************************************/ 171 172 struct AAParams { 173 bool fTweakAlpha; 174 GrColor fColor; 175 }; 176 177 typedef bool (*CompareFunc)(const SkPoint& a, const SkPoint& b); 178 179 bool sweep_lt_horiz(const SkPoint& a, const SkPoint& b) { 180 return a.fX < b.fX || (a.fX == b.fX && a.fY > b.fY); 181 } 182 183 bool sweep_lt_vert(const SkPoint& a, const SkPoint& b) { 184 return a.fY < b.fY || (a.fY == b.fY && a.fX < b.fX); 185 } 186 187 struct Comparator { 188 enum class Direction { kVertical, kHorizontal }; 189 Comparator(Direction direction) : fDirection(direction) {} 190 bool sweep_lt(const SkPoint& a, const SkPoint& b) const { 191 return fDirection == Direction::kHorizontal ? sweep_lt_horiz(a, b) : sweep_lt_vert(a, b); 192 } 193 Direction fDirection; 194 }; 195 196 inline void* emit_vertex(Vertex* v, const AAParams* aaParams, void* data) { 197 if (!aaParams) { 198 SkPoint* d = static_cast<SkPoint*>(data); 199 *d++ = v->fPoint; 200 return d; 201 } 202 if (aaParams->fTweakAlpha) { 203 auto d = static_cast<GrDefaultGeoProcFactory::PositionColorAttr*>(data); 204 d->fPosition = v->fPoint; 205 d->fColor = SkAlphaMulQ(aaParams->fColor, SkAlpha255To256(v->fAlpha)); 206 d++; 207 return d; 208 } 209 auto d = static_cast<GrDefaultGeoProcFactory::PositionColorCoverageAttr*>(data); 210 d->fPosition = v->fPoint; 211 d->fColor = aaParams->fColor; 212 d->fCoverage = GrNormalizeByteToFloat(v->fAlpha); 213 d++; 214 return d; 215 } 216 217 void* emit_triangle(Vertex* v0, Vertex* v1, Vertex* v2, const AAParams* aaParams, void* data) { 218 LOG("emit_triangle (%g, %g) %d\n", v0->fPoint.fX, v0->fPoint.fY, v0->fAlpha); 219 LOG(" (%g, %g) %d\n", v1->fPoint.fX, v1->fPoint.fY, v1->fAlpha); 220 LOG(" (%g, %g) %d\n", v2->fPoint.fX, v2->fPoint.fY, v2->fAlpha); 221 #if TESSELLATOR_WIREFRAME 222 data = emit_vertex(v0, aaParams, data); 223 data = emit_vertex(v1, aaParams, data); 224 data = emit_vertex(v1, aaParams, data); 225 data = emit_vertex(v2, aaParams, data); 226 data = emit_vertex(v2, aaParams, data); 227 data = emit_vertex(v0, aaParams, data); 228 #else 229 data = emit_vertex(v0, aaParams, data); 230 data = emit_vertex(v1, aaParams, data); 231 data = emit_vertex(v2, aaParams, data); 232 #endif 233 return data; 234 } 235 236 struct VertexList { 237 VertexList() : fHead(nullptr), fTail(nullptr) {} 238 VertexList(Vertex* head, Vertex* tail) : fHead(head), fTail(tail) {} 239 Vertex* fHead; 240 Vertex* fTail; 241 void insert(Vertex* v, Vertex* prev, Vertex* next) { 242 list_insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, prev, next, &fHead, &fTail); 243 } 244 void append(Vertex* v) { 245 insert(v, fTail, nullptr); 246 } 247 void append(const VertexList& list) { 248 if (!list.fHead) { 249 return; 250 } 251 if (fTail) { 252 fTail->fNext = list.fHead; 253 list.fHead->fPrev = fTail; 254 } else { 255 fHead = list.fHead; 256 } 257 fTail = list.fTail; 258 } 259 void prepend(Vertex* v) { 260 insert(v, nullptr, fHead); 261 } 262 void remove(Vertex* v) { 263 list_remove<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, &fHead, &fTail); 264 } 265 void close() { 266 if (fHead && fTail) { 267 fTail->fNext = fHead; 268 fHead->fPrev = fTail; 269 } 270 } 271 }; 272 273 // Round to nearest quarter-pixel. This is used for screenspace tessellation. 274 275 inline void round(SkPoint* p) { 276 p->fX = SkScalarRoundToScalar(p->fX * SkFloatToScalar(4.0f)) * SkFloatToScalar(0.25f); 277 p->fY = SkScalarRoundToScalar(p->fY * SkFloatToScalar(4.0f)) * SkFloatToScalar(0.25f); 278 } 279 280 // A line equation in implicit form. fA * x + fB * y + fC = 0, for all points (x, y) on the line. 281 struct Line { 282 Line(Vertex* p, Vertex* q) : Line(p->fPoint, q->fPoint) {} 283 Line(const SkPoint& p, const SkPoint& q) 284 : fA(static_cast<double>(q.fY) - p.fY) // a = dY 285 , fB(static_cast<double>(p.fX) - q.fX) // b = -dX 286 , fC(static_cast<double>(p.fY) * q.fX - // c = cross(q, p) 287 static_cast<double>(p.fX) * q.fY) {} 288 double dist(const SkPoint& p) const { 289 return fA * p.fX + fB * p.fY + fC; 290 } 291 double magSq() const { 292 return fA * fA + fB * fB; 293 } 294 295 // Compute the intersection of two (infinite) Lines. 296 bool intersect(const Line& other, SkPoint* point) { 297 double denom = fA * other.fB - fB * other.fA; 298 if (denom == 0.0) { 299 return false; 300 } 301 double scale = 1.0f / denom; 302 point->fX = SkDoubleToScalar((fB * other.fC - other.fB * fC) * scale); 303 point->fY = SkDoubleToScalar((other.fA * fC - fA * other.fC) * scale); 304 round(point); 305 return true; 306 } 307 double fA, fB, fC; 308 }; 309 310 /** 311 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of "edges above" and 312 * "edge below" a vertex as well as for the active edge list is handled by isLeftOf()/isRightOf(). 313 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (because floating 314 * point). For speed, that case is only tested by the callers that require it (e.g., 315 * cleanup_active_edges()). Edges also handle checking for intersection with other edges. 316 * Currently, this converts the edges to the parametric form, in order to avoid doing a division 317 * until an intersection has been confirmed. This is slightly slower in the "found" case, but 318 * a lot faster in the "not found" case. 319 * 320 * The coefficients of the line equation stored in double precision to avoid catastrphic 321 * cancellation in the isLeftOf() and isRightOf() checks. Using doubles ensures that the result is 322 * correct in float, since it's a polynomial of degree 2. The intersect() function, being 323 * degree 5, is still subject to catastrophic cancellation. We deal with that by assuming its 324 * output may be incorrect, and adjusting the mesh topology to match (see comment at the top of 325 * this file). 326 */ 327 328 struct Edge { 329 enum class Type { kInner, kOuter, kConnector }; 330 Edge(Vertex* top, Vertex* bottom, int winding, Type type) 331 : fWinding(winding) 332 , fTop(top) 333 , fBottom(bottom) 334 , fType(type) 335 , fLeft(nullptr) 336 , fRight(nullptr) 337 , fPrevEdgeAbove(nullptr) 338 , fNextEdgeAbove(nullptr) 339 , fPrevEdgeBelow(nullptr) 340 , fNextEdgeBelow(nullptr) 341 , fLeftPoly(nullptr) 342 , fRightPoly(nullptr) 343 , fLeftPolyPrev(nullptr) 344 , fLeftPolyNext(nullptr) 345 , fRightPolyPrev(nullptr) 346 , fRightPolyNext(nullptr) 347 , fUsedInLeftPoly(false) 348 , fUsedInRightPoly(false) 349 , fLine(top, bottom) { 350 } 351 int fWinding; // 1 == edge goes downward; -1 = edge goes upward. 352 Vertex* fTop; // The top vertex in vertex-sort-order (sweep_lt). 353 Vertex* fBottom; // The bottom vertex in vertex-sort-order. 354 Type fType; 355 Edge* fLeft; // The linked list of edges in the active edge list. 356 Edge* fRight; // " 357 Edge* fPrevEdgeAbove; // The linked list of edges in the bottom Vertex's "edges above". 358 Edge* fNextEdgeAbove; // " 359 Edge* fPrevEdgeBelow; // The linked list of edges in the top Vertex's "edges below". 360 Edge* fNextEdgeBelow; // " 361 Poly* fLeftPoly; // The Poly to the left of this edge, if any. 362 Poly* fRightPoly; // The Poly to the right of this edge, if any. 363 Edge* fLeftPolyPrev; 364 Edge* fLeftPolyNext; 365 Edge* fRightPolyPrev; 366 Edge* fRightPolyNext; 367 bool fUsedInLeftPoly; 368 bool fUsedInRightPoly; 369 Line fLine; 370 double dist(const SkPoint& p) const { 371 return fLine.dist(p); 372 } 373 bool isRightOf(Vertex* v) const { 374 return fLine.dist(v->fPoint) < 0.0; 375 } 376 bool isLeftOf(Vertex* v) const { 377 return fLine.dist(v->fPoint) > 0.0; 378 } 379 void recompute() { 380 fLine = Line(fTop, fBottom); 381 } 382 bool intersect(const Edge& other, SkPoint* p, uint8_t* alpha = nullptr) { 383 LOG("intersecting %g -> %g with %g -> %g\n", 384 fTop->fID, fBottom->fID, 385 other.fTop->fID, other.fBottom->fID); 386 if (fTop == other.fTop || fBottom == other.fBottom) { 387 return false; 388 } 389 double denom = fLine.fA * other.fLine.fB - fLine.fB * other.fLine.fA; 390 if (denom == 0.0) { 391 return false; 392 } 393 double dx = static_cast<double>(other.fTop->fPoint.fX) - fTop->fPoint.fX; 394 double dy = static_cast<double>(other.fTop->fPoint.fY) - fTop->fPoint.fY; 395 double sNumer = dy * other.fLine.fB + dx * other.fLine.fA; 396 double tNumer = dy * fLine.fB + dx * fLine.fA; 397 // If (sNumer / denom) or (tNumer / denom) is not in [0..1], exit early. 398 // This saves us doing the divide below unless absolutely necessary. 399 if (denom > 0.0 ? (sNumer < 0.0 || sNumer > denom || tNumer < 0.0 || tNumer > denom) 400 : (sNumer > 0.0 || sNumer < denom || tNumer > 0.0 || tNumer < denom)) { 401 return false; 402 } 403 double s = sNumer / denom; 404 SkASSERT(s >= 0.0 && s <= 1.0); 405 p->fX = SkDoubleToScalar(fTop->fPoint.fX - s * fLine.fB); 406 p->fY = SkDoubleToScalar(fTop->fPoint.fY + s * fLine.fA); 407 if (alpha) { 408 if (fType == Type::kConnector) { 409 *alpha = (1.0 - s) * fTop->fAlpha + s * fBottom->fAlpha; 410 } else if (other.fType == Type::kConnector) { 411 double t = tNumer / denom; 412 *alpha = (1.0 - t) * other.fTop->fAlpha + t * other.fBottom->fAlpha; 413 } else if (fType == Type::kOuter && other.fType == Type::kOuter) { 414 *alpha = 0; 415 } else { 416 *alpha = 255; 417 } 418 } 419 return true; 420 } 421 }; 422 423 struct EdgeList { 424 EdgeList() : fHead(nullptr), fTail(nullptr) {} 425 Edge* fHead; 426 Edge* fTail; 427 void insert(Edge* edge, Edge* prev, Edge* next) { 428 list_insert<Edge, &Edge::fLeft, &Edge::fRight>(edge, prev, next, &fHead, &fTail); 429 } 430 void append(Edge* e) { 431 insert(e, fTail, nullptr); 432 } 433 void remove(Edge* edge) { 434 list_remove<Edge, &Edge::fLeft, &Edge::fRight>(edge, &fHead, &fTail); 435 } 436 void removeAll() { 437 while (fHead) { 438 this->remove(fHead); 439 } 440 } 441 void close() { 442 if (fHead && fTail) { 443 fTail->fRight = fHead; 444 fHead->fLeft = fTail; 445 } 446 } 447 bool contains(Edge* edge) const { 448 return edge->fLeft || edge->fRight || fHead == edge; 449 } 450 }; 451 452 /***************************************************************************************/ 453 454 struct Poly { 455 Poly(Vertex* v, int winding) 456 : fFirstVertex(v) 457 , fWinding(winding) 458 , fHead(nullptr) 459 , fTail(nullptr) 460 , fNext(nullptr) 461 , fPartner(nullptr) 462 , fCount(0) 463 { 464 #if LOGGING_ENABLED 465 static int gID = 0; 466 fID = gID++; 467 LOG("*** created Poly %d\n", fID); 468 #endif 469 } 470 typedef enum { kLeft_Side, kRight_Side } Side; 471 struct MonotonePoly { 472 MonotonePoly(Edge* edge, Side side) 473 : fSide(side) 474 , fFirstEdge(nullptr) 475 , fLastEdge(nullptr) 476 , fPrev(nullptr) 477 , fNext(nullptr) { 478 this->addEdge(edge); 479 } 480 Side fSide; 481 Edge* fFirstEdge; 482 Edge* fLastEdge; 483 MonotonePoly* fPrev; 484 MonotonePoly* fNext; 485 void addEdge(Edge* edge) { 486 if (fSide == kRight_Side) { 487 SkASSERT(!edge->fUsedInRightPoly); 488 list_insert<Edge, &Edge::fRightPolyPrev, &Edge::fRightPolyNext>( 489 edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge); 490 edge->fUsedInRightPoly = true; 491 } else { 492 SkASSERT(!edge->fUsedInLeftPoly); 493 list_insert<Edge, &Edge::fLeftPolyPrev, &Edge::fLeftPolyNext>( 494 edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge); 495 edge->fUsedInLeftPoly = true; 496 } 497 } 498 499 void* emit(const AAParams* aaParams, void* data) { 500 Edge* e = fFirstEdge; 501 VertexList vertices; 502 vertices.append(e->fTop); 503 int count = 1; 504 while (e != nullptr) { 505 if (kRight_Side == fSide) { 506 vertices.append(e->fBottom); 507 e = e->fRightPolyNext; 508 } else { 509 vertices.prepend(e->fBottom); 510 e = e->fLeftPolyNext; 511 } 512 count++; 513 } 514 Vertex* first = vertices.fHead; 515 Vertex* v = first->fNext; 516 while (v != vertices.fTail) { 517 SkASSERT(v && v->fPrev && v->fNext); 518 Vertex* prev = v->fPrev; 519 Vertex* curr = v; 520 Vertex* next = v->fNext; 521 if (count == 3) { 522 return emit_triangle(prev, curr, next, aaParams, data); 523 } 524 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint.fX; 525 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint.fY; 526 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint.fX; 527 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint.fY; 528 if (ax * by - ay * bx >= 0.0) { 529 data = emit_triangle(prev, curr, next, aaParams, data); 530 v->fPrev->fNext = v->fNext; 531 v->fNext->fPrev = v->fPrev; 532 count--; 533 if (v->fPrev == first) { 534 v = v->fNext; 535 } else { 536 v = v->fPrev; 537 } 538 } else { 539 v = v->fNext; 540 } 541 } 542 return data; 543 } 544 }; 545 Poly* addEdge(Edge* e, Side side, SkArenaAlloc& alloc) { 546 LOG("addEdge (%g -> %g) to poly %d, %s side\n", 547 e->fTop->fID, e->fBottom->fID, fID, side == kLeft_Side ? "left" : "right"); 548 Poly* partner = fPartner; 549 Poly* poly = this; 550 if (side == kRight_Side) { 551 if (e->fUsedInRightPoly) { 552 return this; 553 } 554 } else { 555 if (e->fUsedInLeftPoly) { 556 return this; 557 } 558 } 559 if (partner) { 560 fPartner = partner->fPartner = nullptr; 561 } 562 if (!fTail) { 563 fHead = fTail = alloc.make<MonotonePoly>(e, side); 564 fCount += 2; 565 } else if (e->fBottom == fTail->fLastEdge->fBottom) { 566 return poly; 567 } else if (side == fTail->fSide) { 568 fTail->addEdge(e); 569 fCount++; 570 } else { 571 e = alloc.make<Edge>(fTail->fLastEdge->fBottom, e->fBottom, 1, Edge::Type::kInner); 572 fTail->addEdge(e); 573 fCount++; 574 if (partner) { 575 partner->addEdge(e, side, alloc); 576 poly = partner; 577 } else { 578 MonotonePoly* m = alloc.make<MonotonePoly>(e, side); 579 m->fPrev = fTail; 580 fTail->fNext = m; 581 fTail = m; 582 } 583 } 584 return poly; 585 } 586 void* emit(const AAParams* aaParams, void *data) { 587 if (fCount < 3) { 588 return data; 589 } 590 LOG("emit() %d, size %d\n", fID, fCount); 591 for (MonotonePoly* m = fHead; m != nullptr; m = m->fNext) { 592 data = m->emit(aaParams, data); 593 } 594 return data; 595 } 596 Vertex* lastVertex() const { return fTail ? fTail->fLastEdge->fBottom : fFirstVertex; } 597 Vertex* fFirstVertex; 598 int fWinding; 599 MonotonePoly* fHead; 600 MonotonePoly* fTail; 601 Poly* fNext; 602 Poly* fPartner; 603 int fCount; 604 #if LOGGING_ENABLED 605 int fID; 606 #endif 607 }; 608 609 /***************************************************************************************/ 610 611 bool coincident(const SkPoint& a, const SkPoint& b) { 612 return a == b; 613 } 614 615 Poly* new_poly(Poly** head, Vertex* v, int winding, SkArenaAlloc& alloc) { 616 Poly* poly = alloc.make<Poly>(v, winding); 617 poly->fNext = *head; 618 *head = poly; 619 return poly; 620 } 621 622 void append_point_to_contour(const SkPoint& p, VertexList* contour, SkArenaAlloc& alloc) { 623 Vertex* v = alloc.make<Vertex>(p, 255); 624 #if LOGGING_ENABLED 625 static float gID = 0.0f; 626 v->fID = gID++; 627 #endif 628 contour->append(v); 629 } 630 631 void generate_quadratic_points(const SkPoint& p0, 632 const SkPoint& p1, 633 const SkPoint& p2, 634 SkScalar tolSqd, 635 VertexList* contour, 636 int pointsLeft, 637 SkArenaAlloc& alloc) { 638 SkScalar d = p1.distanceToLineSegmentBetweenSqd(p0, p2); 639 if (pointsLeft < 2 || d < tolSqd || !SkScalarIsFinite(d)) { 640 append_point_to_contour(p2, contour, alloc); 641 return; 642 } 643 644 const SkPoint q[] = { 645 { SkScalarAve(p0.fX, p1.fX), SkScalarAve(p0.fY, p1.fY) }, 646 { SkScalarAve(p1.fX, p2.fX), SkScalarAve(p1.fY, p2.fY) }, 647 }; 648 const SkPoint r = { SkScalarAve(q[0].fX, q[1].fX), SkScalarAve(q[0].fY, q[1].fY) }; 649 650 pointsLeft >>= 1; 651 generate_quadratic_points(p0, q[0], r, tolSqd, contour, pointsLeft, alloc); 652 generate_quadratic_points(r, q[1], p2, tolSqd, contour, pointsLeft, alloc); 653 } 654 655 void generate_cubic_points(const SkPoint& p0, 656 const SkPoint& p1, 657 const SkPoint& p2, 658 const SkPoint& p3, 659 SkScalar tolSqd, 660 VertexList* contour, 661 int pointsLeft, 662 SkArenaAlloc& alloc) { 663 SkScalar d1 = p1.distanceToLineSegmentBetweenSqd(p0, p3); 664 SkScalar d2 = p2.distanceToLineSegmentBetweenSqd(p0, p3); 665 if (pointsLeft < 2 || (d1 < tolSqd && d2 < tolSqd) || 666 !SkScalarIsFinite(d1) || !SkScalarIsFinite(d2)) { 667 append_point_to_contour(p3, contour, alloc); 668 return; 669 } 670 const SkPoint q[] = { 671 { SkScalarAve(p0.fX, p1.fX), SkScalarAve(p0.fY, p1.fY) }, 672 { SkScalarAve(p1.fX, p2.fX), SkScalarAve(p1.fY, p2.fY) }, 673 { SkScalarAve(p2.fX, p3.fX), SkScalarAve(p2.fY, p3.fY) } 674 }; 675 const SkPoint r[] = { 676 { SkScalarAve(q[0].fX, q[1].fX), SkScalarAve(q[0].fY, q[1].fY) }, 677 { SkScalarAve(q[1].fX, q[2].fX), SkScalarAve(q[1].fY, q[2].fY) } 678 }; 679 const SkPoint s = { SkScalarAve(r[0].fX, r[1].fX), SkScalarAve(r[0].fY, r[1].fY) }; 680 pointsLeft >>= 1; 681 generate_cubic_points(p0, q[0], r[0], s, tolSqd, contour, pointsLeft, alloc); 682 generate_cubic_points(s, r[1], q[2], p3, tolSqd, contour, pointsLeft, alloc); 683 } 684 685 // Stage 1: convert the input path to a set of linear contours (linked list of Vertices). 686 687 void path_to_contours(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds, 688 VertexList* contours, SkArenaAlloc& alloc, bool *isLinear) { 689 SkScalar toleranceSqd = tolerance * tolerance; 690 691 SkPoint pts[4]; 692 *isLinear = true; 693 VertexList* contour = contours; 694 SkPath::Iter iter(path, false); 695 if (path.isInverseFillType()) { 696 SkPoint quad[4]; 697 clipBounds.toQuad(quad); 698 for (int i = 3; i >= 0; i--) { 699 append_point_to_contour(quad[i], contours, alloc); 700 } 701 contour++; 702 } 703 SkAutoConicToQuads converter; 704 SkPath::Verb verb; 705 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 706 switch (verb) { 707 case SkPath::kConic_Verb: { 708 SkScalar weight = iter.conicWeight(); 709 const SkPoint* quadPts = converter.computeQuads(pts, weight, toleranceSqd); 710 for (int i = 0; i < converter.countQuads(); ++i) { 711 int pointsLeft = GrPathUtils::quadraticPointCount(quadPts, tolerance); 712 generate_quadratic_points(quadPts[0], quadPts[1], quadPts[2], toleranceSqd, 713 contour, pointsLeft, alloc); 714 quadPts += 2; 715 } 716 *isLinear = false; 717 break; 718 } 719 case SkPath::kMove_Verb: 720 if (contour->fHead) { 721 contour++; 722 } 723 append_point_to_contour(pts[0], contour, alloc); 724 break; 725 case SkPath::kLine_Verb: { 726 append_point_to_contour(pts[1], contour, alloc); 727 break; 728 } 729 case SkPath::kQuad_Verb: { 730 int pointsLeft = GrPathUtils::quadraticPointCount(pts, tolerance); 731 generate_quadratic_points(pts[0], pts[1], pts[2], toleranceSqd, contour, 732 pointsLeft, alloc); 733 *isLinear = false; 734 break; 735 } 736 case SkPath::kCubic_Verb: { 737 int pointsLeft = GrPathUtils::cubicPointCount(pts, tolerance); 738 generate_cubic_points(pts[0], pts[1], pts[2], pts[3], toleranceSqd, contour, 739 pointsLeft, alloc); 740 *isLinear = false; 741 break; 742 } 743 case SkPath::kClose_Verb: 744 case SkPath::kDone_Verb: 745 break; 746 } 747 } 748 } 749 750 inline bool apply_fill_type(SkPath::FillType fillType, int winding) { 751 switch (fillType) { 752 case SkPath::kWinding_FillType: 753 return winding != 0; 754 case SkPath::kEvenOdd_FillType: 755 return (winding & 1) != 0; 756 case SkPath::kInverseWinding_FillType: 757 return winding == 1; 758 case SkPath::kInverseEvenOdd_FillType: 759 return (winding & 1) == 1; 760 default: 761 SkASSERT(false); 762 return false; 763 } 764 } 765 766 inline bool apply_fill_type(SkPath::FillType fillType, Poly* poly) { 767 return poly && apply_fill_type(fillType, poly->fWinding); 768 } 769 770 Edge* new_edge(Vertex* prev, Vertex* next, Edge::Type type, Comparator& c, SkArenaAlloc& alloc) { 771 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; 772 Vertex* top = winding < 0 ? next : prev; 773 Vertex* bottom = winding < 0 ? prev : next; 774 return alloc.make<Edge>(top, bottom, winding, type); 775 } 776 777 void remove_edge(Edge* edge, EdgeList* edges) { 778 LOG("removing edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); 779 SkASSERT(edges->contains(edge)); 780 edges->remove(edge); 781 } 782 783 void insert_edge(Edge* edge, Edge* prev, EdgeList* edges) { 784 LOG("inserting edge %g -> %g\n", edge->fTop->fID, edge->fBottom->fID); 785 SkASSERT(!edges->contains(edge)); 786 Edge* next = prev ? prev->fRight : edges->fHead; 787 edges->insert(edge, prev, next); 788 } 789 790 void find_enclosing_edges(Vertex* v, EdgeList* edges, Edge** left, Edge** right) { 791 if (v->fFirstEdgeAbove && v->fLastEdgeAbove) { 792 *left = v->fFirstEdgeAbove->fLeft; 793 *right = v->fLastEdgeAbove->fRight; 794 return; 795 } 796 Edge* next = nullptr; 797 Edge* prev; 798 for (prev = edges->fTail; prev != nullptr; prev = prev->fLeft) { 799 if (prev->isLeftOf(v)) { 800 break; 801 } 802 next = prev; 803 } 804 *left = prev; 805 *right = next; 806 } 807 808 void find_enclosing_edges(Edge* edge, EdgeList* edges, Comparator& c, Edge** left, Edge** right) { 809 Edge* prev = nullptr; 810 Edge* next; 811 for (next = edges->fHead; next != nullptr; next = next->fRight) { 812 if ((c.sweep_lt(next->fTop->fPoint, edge->fTop->fPoint) && next->isRightOf(edge->fTop)) || 813 (c.sweep_lt(edge->fTop->fPoint, next->fTop->fPoint) && edge->isLeftOf(next->fTop)) || 814 (c.sweep_lt(edge->fBottom->fPoint, next->fBottom->fPoint) && 815 next->isRightOf(edge->fBottom)) || 816 (c.sweep_lt(next->fBottom->fPoint, edge->fBottom->fPoint) && 817 edge->isLeftOf(next->fBottom))) { 818 break; 819 } 820 prev = next; 821 } 822 *left = prev; 823 *right = next; 824 } 825 826 void fix_active_state(Edge* edge, EdgeList* activeEdges, Comparator& c) { 827 if (!activeEdges) { 828 return; 829 } 830 if (activeEdges->contains(edge)) { 831 if (edge->fBottom->fProcessed || !edge->fTop->fProcessed) { 832 remove_edge(edge, activeEdges); 833 } 834 } else if (edge->fTop->fProcessed && !edge->fBottom->fProcessed) { 835 Edge* left; 836 Edge* right; 837 find_enclosing_edges(edge, activeEdges, c, &left, &right); 838 insert_edge(edge, left, activeEdges); 839 } 840 } 841 842 void insert_edge_above(Edge* edge, Vertex* v, Comparator& c) { 843 if (edge->fTop->fPoint == edge->fBottom->fPoint || 844 c.sweep_lt(edge->fBottom->fPoint, edge->fTop->fPoint)) { 845 return; 846 } 847 LOG("insert edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBottom->fID, v->fID); 848 Edge* prev = nullptr; 849 Edge* next; 850 for (next = v->fFirstEdgeAbove; next; next = next->fNextEdgeAbove) { 851 if (next->isRightOf(edge->fTop)) { 852 break; 853 } 854 prev = next; 855 } 856 list_insert<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( 857 edge, prev, next, &v->fFirstEdgeAbove, &v->fLastEdgeAbove); 858 } 859 860 void insert_edge_below(Edge* edge, Vertex* v, Comparator& c) { 861 if (edge->fTop->fPoint == edge->fBottom->fPoint || 862 c.sweep_lt(edge->fBottom->fPoint, edge->fTop->fPoint)) { 863 return; 864 } 865 LOG("insert edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBottom->fID, v->fID); 866 Edge* prev = nullptr; 867 Edge* next; 868 for (next = v->fFirstEdgeBelow; next; next = next->fNextEdgeBelow) { 869 if (next->isRightOf(edge->fBottom)) { 870 break; 871 } 872 prev = next; 873 } 874 list_insert<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( 875 edge, prev, next, &v->fFirstEdgeBelow, &v->fLastEdgeBelow); 876 } 877 878 void remove_edge_above(Edge* edge) { 879 LOG("removing edge (%g -> %g) above vertex %g\n", edge->fTop->fID, edge->fBottom->fID, 880 edge->fBottom->fID); 881 list_remove<Edge, &Edge::fPrevEdgeAbove, &Edge::fNextEdgeAbove>( 882 edge, &edge->fBottom->fFirstEdgeAbove, &edge->fBottom->fLastEdgeAbove); 883 } 884 885 void remove_edge_below(Edge* edge) { 886 LOG("removing edge (%g -> %g) below vertex %g\n", edge->fTop->fID, edge->fBottom->fID, 887 edge->fTop->fID); 888 list_remove<Edge, &Edge::fPrevEdgeBelow, &Edge::fNextEdgeBelow>( 889 edge, &edge->fTop->fFirstEdgeBelow, &edge->fTop->fLastEdgeBelow); 890 } 891 892 void disconnect(Edge* edge) 893 { 894 remove_edge_above(edge); 895 remove_edge_below(edge); 896 } 897 898 void erase_edge(Edge* edge, EdgeList* edges) { 899 LOG("erasing edge (%g -> %g)\n", edge->fTop->fID, edge->fBottom->fID); 900 disconnect(edge); 901 if (edges && edges->contains(edge)) { 902 remove_edge(edge, edges); 903 } 904 } 905 906 void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Comparator& c); 907 908 void set_top(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c) { 909 remove_edge_below(edge); 910 edge->fTop = v; 911 edge->recompute(); 912 insert_edge_below(edge, v, c); 913 fix_active_state(edge, activeEdges, c); 914 merge_collinear_edges(edge, activeEdges, c); 915 } 916 917 void set_bottom(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c) { 918 remove_edge_above(edge); 919 edge->fBottom = v; 920 edge->recompute(); 921 insert_edge_above(edge, v, c); 922 fix_active_state(edge, activeEdges, c); 923 merge_collinear_edges(edge, activeEdges, c); 924 } 925 926 void merge_edges_above(Edge* edge, Edge* other, EdgeList* activeEdges, Comparator& c) { 927 if (coincident(edge->fTop->fPoint, other->fTop->fPoint)) { 928 LOG("merging coincident above edges (%g, %g) -> (%g, %g)\n", 929 edge->fTop->fPoint.fX, edge->fTop->fPoint.fY, 930 edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY); 931 other->fWinding += edge->fWinding; 932 erase_edge(edge, activeEdges); 933 } else if (c.sweep_lt(edge->fTop->fPoint, other->fTop->fPoint)) { 934 other->fWinding += edge->fWinding; 935 set_bottom(edge, other->fTop, activeEdges, c); 936 } else { 937 edge->fWinding += other->fWinding; 938 set_bottom(other, edge->fTop, activeEdges, c); 939 } 940 } 941 942 void merge_edges_below(Edge* edge, Edge* other, EdgeList* activeEdges, Comparator& c) { 943 if (coincident(edge->fBottom->fPoint, other->fBottom->fPoint)) { 944 LOG("merging coincident below edges (%g, %g) -> (%g, %g)\n", 945 edge->fTop->fPoint.fX, edge->fTop->fPoint.fY, 946 edge->fBottom->fPoint.fX, edge->fBottom->fPoint.fY); 947 other->fWinding += edge->fWinding; 948 erase_edge(edge, activeEdges); 949 } else if (c.sweep_lt(edge->fBottom->fPoint, other->fBottom->fPoint)) { 950 edge->fWinding += other->fWinding; 951 set_top(other, edge->fBottom, activeEdges, c); 952 } else { 953 other->fWinding += edge->fWinding; 954 set_top(edge, other->fBottom, activeEdges, c); 955 } 956 } 957 958 void merge_collinear_edges(Edge* edge, EdgeList* activeEdges, Comparator& c) { 959 if (edge->fPrevEdgeAbove && (edge->fTop == edge->fPrevEdgeAbove->fTop || 960 !edge->fPrevEdgeAbove->isLeftOf(edge->fTop))) { 961 merge_edges_above(edge, edge->fPrevEdgeAbove, activeEdges, c); 962 } else if (edge->fNextEdgeAbove && (edge->fTop == edge->fNextEdgeAbove->fTop || 963 !edge->isLeftOf(edge->fNextEdgeAbove->fTop))) { 964 merge_edges_above(edge, edge->fNextEdgeAbove, activeEdges, c); 965 } 966 if (edge->fPrevEdgeBelow && (edge->fBottom == edge->fPrevEdgeBelow->fBottom || 967 !edge->fPrevEdgeBelow->isLeftOf(edge->fBottom))) { 968 merge_edges_below(edge, edge->fPrevEdgeBelow, activeEdges, c); 969 } else if (edge->fNextEdgeBelow && (edge->fBottom == edge->fNextEdgeBelow->fBottom || 970 !edge->isLeftOf(edge->fNextEdgeBelow->fBottom))) { 971 merge_edges_below(edge, edge->fNextEdgeBelow, activeEdges, c); 972 } 973 } 974 975 void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c, SkArenaAlloc& alloc); 976 977 void cleanup_active_edges(Edge* edge, EdgeList* activeEdges, Comparator& c, SkArenaAlloc& alloc) { 978 Vertex* top = edge->fTop; 979 Vertex* bottom = edge->fBottom; 980 if (edge->fLeft) { 981 Vertex* leftTop = edge->fLeft->fTop; 982 Vertex* leftBottom = edge->fLeft->fBottom; 983 if (c.sweep_lt(leftTop->fPoint, top->fPoint) && !edge->fLeft->isLeftOf(top)) { 984 split_edge(edge->fLeft, edge->fTop, activeEdges, c, alloc); 985 } else if (c.sweep_lt(top->fPoint, leftTop->fPoint) && !edge->isRightOf(leftTop)) { 986 split_edge(edge, leftTop, activeEdges, c, alloc); 987 } else if (c.sweep_lt(bottom->fPoint, leftBottom->fPoint) && 988 !edge->fLeft->isLeftOf(bottom)) { 989 split_edge(edge->fLeft, bottom, activeEdges, c, alloc); 990 } else if (c.sweep_lt(leftBottom->fPoint, bottom->fPoint) && !edge->isRightOf(leftBottom)) { 991 split_edge(edge, leftBottom, activeEdges, c, alloc); 992 } 993 } 994 if (edge->fRight) { 995 Vertex* rightTop = edge->fRight->fTop; 996 Vertex* rightBottom = edge->fRight->fBottom; 997 if (c.sweep_lt(rightTop->fPoint, top->fPoint) && !edge->fRight->isRightOf(top)) { 998 split_edge(edge->fRight, top, activeEdges, c, alloc); 999 } else if (c.sweep_lt(top->fPoint, rightTop->fPoint) && !edge->isLeftOf(rightTop)) { 1000 split_edge(edge, rightTop, activeEdges, c, alloc); 1001 } else if (c.sweep_lt(bottom->fPoint, rightBottom->fPoint) && 1002 !edge->fRight->isRightOf(bottom)) { 1003 split_edge(edge->fRight, bottom, activeEdges, c, alloc); 1004 } else if (c.sweep_lt(rightBottom->fPoint, bottom->fPoint) && 1005 !edge->isLeftOf(rightBottom)) { 1006 split_edge(edge, rightBottom, activeEdges, c, alloc); 1007 } 1008 } 1009 } 1010 1011 void split_edge(Edge* edge, Vertex* v, EdgeList* activeEdges, Comparator& c, SkArenaAlloc& alloc) { 1012 LOG("splitting edge (%g -> %g) at vertex %g (%g, %g)\n", 1013 edge->fTop->fID, edge->fBottom->fID, 1014 v->fID, v->fPoint.fX, v->fPoint.fY); 1015 if (c.sweep_lt(v->fPoint, edge->fTop->fPoint)) { 1016 set_top(edge, v, activeEdges, c); 1017 } else if (c.sweep_lt(edge->fBottom->fPoint, v->fPoint)) { 1018 set_bottom(edge, v, activeEdges, c); 1019 } else { 1020 Edge* newEdge = alloc.make<Edge>(v, edge->fBottom, edge->fWinding, edge->fType); 1021 insert_edge_below(newEdge, v, c); 1022 insert_edge_above(newEdge, edge->fBottom, c); 1023 set_bottom(edge, v, activeEdges, c); 1024 cleanup_active_edges(edge, activeEdges, c, alloc); 1025 fix_active_state(newEdge, activeEdges, c); 1026 merge_collinear_edges(newEdge, activeEdges, c); 1027 } 1028 } 1029 1030 Edge* connect(Vertex* prev, Vertex* next, Edge::Type type, Comparator& c, SkArenaAlloc& alloc, 1031 int winding_scale = 1) { 1032 Edge* edge = new_edge(prev, next, type, c, alloc); 1033 insert_edge_below(edge, edge->fTop, c); 1034 insert_edge_above(edge, edge->fBottom, c); 1035 edge->fWinding *= winding_scale; 1036 merge_collinear_edges(edge, nullptr, c); 1037 return edge; 1038 } 1039 1040 void merge_vertices(Vertex* src, Vertex* dst, VertexList* mesh, Comparator& c, 1041 SkArenaAlloc& alloc) { 1042 LOG("found coincident verts at %g, %g; merging %g into %g\n", src->fPoint.fX, src->fPoint.fY, 1043 src->fID, dst->fID); 1044 dst->fAlpha = SkTMax(src->fAlpha, dst->fAlpha); 1045 if (src->fPartner) { 1046 src->fPartner->fPartner = dst; 1047 } 1048 for (Edge* edge = src->fFirstEdgeAbove; edge;) { 1049 Edge* next = edge->fNextEdgeAbove; 1050 set_bottom(edge, dst, nullptr, c); 1051 edge = next; 1052 } 1053 for (Edge* edge = src->fFirstEdgeBelow; edge;) { 1054 Edge* next = edge->fNextEdgeBelow; 1055 set_top(edge, dst, nullptr, c); 1056 edge = next; 1057 } 1058 mesh->remove(src); 1059 } 1060 1061 uint8_t max_edge_alpha(Edge* a, Edge* b) { 1062 if (a->fType == Edge::Type::kInner || b->fType == Edge::Type::kInner) { 1063 return 255; 1064 } else if (a->fType == Edge::Type::kOuter && b->fType == Edge::Type::kOuter) { 1065 return 0; 1066 } else { 1067 return SkTMax(SkTMax(a->fTop->fAlpha, a->fBottom->fAlpha), 1068 SkTMax(b->fTop->fAlpha, b->fBottom->fAlpha)); 1069 } 1070 } 1071 1072 Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, Comparator& c, 1073 SkArenaAlloc& alloc) { 1074 if (!edge || !other) { 1075 return nullptr; 1076 } 1077 SkPoint p; 1078 uint8_t alpha; 1079 if (edge->intersect(*other, &p, &alpha)) { 1080 Vertex* v; 1081 LOG("found intersection, pt is %g, %g\n", p.fX, p.fY); 1082 if (p == edge->fTop->fPoint || c.sweep_lt(p, edge->fTop->fPoint)) { 1083 split_edge(other, edge->fTop, activeEdges, c, alloc); 1084 v = edge->fTop; 1085 } else if (p == edge->fBottom->fPoint || c.sweep_lt(edge->fBottom->fPoint, p)) { 1086 split_edge(other, edge->fBottom, activeEdges, c, alloc); 1087 v = edge->fBottom; 1088 } else if (p == other->fTop->fPoint || c.sweep_lt(p, other->fTop->fPoint)) { 1089 split_edge(edge, other->fTop, activeEdges, c, alloc); 1090 v = other->fTop; 1091 } else if (p == other->fBottom->fPoint || c.sweep_lt(other->fBottom->fPoint, p)) { 1092 split_edge(edge, other->fBottom, activeEdges, c, alloc); 1093 v = other->fBottom; 1094 } else { 1095 Vertex* nextV = edge->fTop; 1096 while (c.sweep_lt(p, nextV->fPoint)) { 1097 nextV = nextV->fPrev; 1098 } 1099 while (c.sweep_lt(nextV->fPoint, p)) { 1100 nextV = nextV->fNext; 1101 } 1102 Vertex* prevV = nextV->fPrev; 1103 if (coincident(prevV->fPoint, p)) { 1104 v = prevV; 1105 } else if (coincident(nextV->fPoint, p)) { 1106 v = nextV; 1107 } else { 1108 v = alloc.make<Vertex>(p, alpha); 1109 LOG("inserting between %g (%g, %g) and %g (%g, %g)\n", 1110 prevV->fID, prevV->fPoint.fX, prevV->fPoint.fY, 1111 nextV->fID, nextV->fPoint.fX, nextV->fPoint.fY); 1112 #if LOGGING_ENABLED 1113 v->fID = (nextV->fID + prevV->fID) * 0.5f; 1114 #endif 1115 v->fPrev = prevV; 1116 v->fNext = nextV; 1117 prevV->fNext = v; 1118 nextV->fPrev = v; 1119 } 1120 split_edge(edge, v, activeEdges, c, alloc); 1121 split_edge(other, v, activeEdges, c, alloc); 1122 } 1123 v->fAlpha = SkTMax(v->fAlpha, alpha); 1124 return v; 1125 } 1126 return nullptr; 1127 } 1128 1129 void sanitize_contours(VertexList* contours, int contourCnt, bool approximate) { 1130 for (VertexList* contour = contours; contourCnt > 0; --contourCnt, ++contour) { 1131 SkASSERT(contour->fHead); 1132 Vertex* prev = contour->fTail; 1133 if (approximate) { 1134 round(&prev->fPoint); 1135 } 1136 for (Vertex* v = contour->fHead; v;) { 1137 if (approximate) { 1138 round(&v->fPoint); 1139 } 1140 Vertex* next = v->fNext; 1141 if (coincident(prev->fPoint, v->fPoint)) { 1142 LOG("vertex %g,%g coincident; removing\n", v->fPoint.fX, v->fPoint.fY); 1143 contour->remove(v); 1144 } 1145 prev = v; 1146 v = next; 1147 } 1148 } 1149 } 1150 1151 void merge_coincident_vertices(VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) { 1152 if (!mesh->fHead) { 1153 return; 1154 } 1155 for (Vertex* v = mesh->fHead->fNext; v != nullptr; v = v->fNext) { 1156 if (c.sweep_lt(v->fPoint, v->fPrev->fPoint)) { 1157 v->fPoint = v->fPrev->fPoint; 1158 } 1159 if (coincident(v->fPrev->fPoint, v->fPoint)) { 1160 merge_vertices(v->fPrev, v, mesh, c, alloc); 1161 } 1162 } 1163 } 1164 1165 // Stage 2: convert the contours to a mesh of edges connecting the vertices. 1166 1167 void build_edges(VertexList* contours, int contourCnt, VertexList* mesh, Comparator& c, 1168 SkArenaAlloc& alloc) { 1169 for (VertexList* contour = contours; contourCnt > 0; --contourCnt, ++contour) { 1170 Vertex* prev = contour->fTail; 1171 for (Vertex* v = contour->fHead; v;) { 1172 Vertex* next = v->fNext; 1173 connect(prev, v, Edge::Type::kInner, c, alloc); 1174 mesh->append(v); 1175 prev = v; 1176 v = next; 1177 } 1178 } 1179 } 1180 1181 void connect_partners(VertexList* outerVertices, Comparator& c, SkArenaAlloc& alloc) { 1182 for (Vertex* outer = outerVertices->fHead; outer; outer = outer->fNext) { 1183 if (Vertex* inner = outer->fPartner) { 1184 // Connector edges get zero winding, since they're only structural (i.e., to ensure 1185 // no 0-0-0 alpha triangles are produced), and shouldn't affect the poly winding number. 1186 connect(outer, inner, Edge::Type::kConnector, c, alloc, 0); 1187 inner->fPartner = outer->fPartner = nullptr; 1188 } 1189 } 1190 } 1191 1192 template <CompareFunc sweep_lt> 1193 void sorted_merge(VertexList* front, VertexList* back, VertexList* result) { 1194 Vertex* a = front->fHead; 1195 Vertex* b = back->fHead; 1196 while (a && b) { 1197 if (sweep_lt(a->fPoint, b->fPoint)) { 1198 front->remove(a); 1199 result->append(a); 1200 a = front->fHead; 1201 } else { 1202 back->remove(b); 1203 result->append(b); 1204 b = back->fHead; 1205 } 1206 } 1207 result->append(*front); 1208 result->append(*back); 1209 } 1210 1211 void sorted_merge(VertexList* front, VertexList* back, VertexList* result, Comparator& c) { 1212 if (c.fDirection == Comparator::Direction::kHorizontal) { 1213 sorted_merge<sweep_lt_horiz>(front, back, result); 1214 } else { 1215 sorted_merge<sweep_lt_vert>(front, back, result); 1216 } 1217 } 1218 1219 // Stage 3: sort the vertices by increasing sweep direction. 1220 1221 template <CompareFunc sweep_lt> 1222 void merge_sort(VertexList* vertices) { 1223 Vertex* slow = vertices->fHead; 1224 if (!slow) { 1225 return; 1226 } 1227 Vertex* fast = slow->fNext; 1228 if (!fast) { 1229 return; 1230 } 1231 do { 1232 fast = fast->fNext; 1233 if (fast) { 1234 fast = fast->fNext; 1235 slow = slow->fNext; 1236 } 1237 } while (fast); 1238 VertexList front(vertices->fHead, slow); 1239 VertexList back(slow->fNext, vertices->fTail); 1240 front.fTail->fNext = back.fHead->fPrev = nullptr; 1241 1242 merge_sort<sweep_lt>(&front); 1243 merge_sort<sweep_lt>(&back); 1244 1245 vertices->fHead = vertices->fTail = nullptr; 1246 sorted_merge<sweep_lt>(&front, &back, vertices); 1247 } 1248 1249 // Stage 4: Simplify the mesh by inserting new vertices at intersecting edges. 1250 1251 void simplify(const VertexList& vertices, Comparator& c, SkArenaAlloc& alloc) { 1252 LOG("simplifying complex polygons\n"); 1253 EdgeList activeEdges; 1254 for (Vertex* v = vertices.fHead; v != nullptr; v = v->fNext) { 1255 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { 1256 continue; 1257 } 1258 #if LOGGING_ENABLED 1259 LOG("\nvertex %g: (%g,%g), alpha %d\n", v->fID, v->fPoint.fX, v->fPoint.fY, v->fAlpha); 1260 #endif 1261 Edge* leftEnclosingEdge; 1262 Edge* rightEnclosingEdge; 1263 bool restartChecks; 1264 do { 1265 restartChecks = false; 1266 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge); 1267 if (v->fFirstEdgeBelow) { 1268 for (Edge* edge = v->fFirstEdgeBelow; edge; edge = edge->fNextEdgeBelow) { 1269 if (check_for_intersection(edge, leftEnclosingEdge, &activeEdges, c, alloc)) { 1270 restartChecks = true; 1271 break; 1272 } 1273 if (check_for_intersection(edge, rightEnclosingEdge, &activeEdges, c, alloc)) { 1274 restartChecks = true; 1275 break; 1276 } 1277 } 1278 } else { 1279 if (Vertex* pv = check_for_intersection(leftEnclosingEdge, rightEnclosingEdge, 1280 &activeEdges, c, alloc)) { 1281 if (c.sweep_lt(pv->fPoint, v->fPoint)) { 1282 v = pv; 1283 } 1284 restartChecks = true; 1285 } 1286 1287 } 1288 } while (restartChecks); 1289 if (v->fAlpha == 0) { 1290 if ((leftEnclosingEdge && leftEnclosingEdge->fWinding < 0) && 1291 (rightEnclosingEdge && rightEnclosingEdge->fWinding > 0)) { 1292 v->fAlpha = max_edge_alpha(leftEnclosingEdge, rightEnclosingEdge); 1293 } 1294 } 1295 for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) { 1296 remove_edge(e, &activeEdges); 1297 } 1298 Edge* leftEdge = leftEnclosingEdge; 1299 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { 1300 insert_edge(e, leftEdge, &activeEdges); 1301 leftEdge = e; 1302 } 1303 v->fProcessed = true; 1304 } 1305 } 1306 1307 // This is a stripped-down version of simplify() (the Bentley-Ottmann algorithm) that 1308 // early-returns true on the first found intersection, false if none. 1309 bool is_complex(const VertexList& vertices) { 1310 LOG("testing polygon complexity\n"); 1311 EdgeList activeEdges; 1312 for (Vertex* v = vertices.fHead; v != nullptr; v = v->fNext) { 1313 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { 1314 continue; 1315 } 1316 Edge* leftEnclosingEdge; 1317 Edge* rightEnclosingEdge; 1318 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge); 1319 SkPoint dummy; 1320 if (v->fFirstEdgeBelow) { 1321 for (Edge* edge = v->fFirstEdgeBelow; edge; edge = edge->fNextEdgeBelow) { 1322 if (edge && leftEnclosingEdge && edge->intersect(*leftEnclosingEdge, &dummy)) { 1323 activeEdges.removeAll(); 1324 return true; 1325 } 1326 if (edge && rightEnclosingEdge && edge->intersect(*rightEnclosingEdge, &dummy)) { 1327 activeEdges.removeAll(); 1328 return true; 1329 } 1330 } 1331 } else if (leftEnclosingEdge && rightEnclosingEdge && 1332 leftEnclosingEdge->intersect(*rightEnclosingEdge, &dummy)) { 1333 activeEdges.removeAll(); 1334 return true; 1335 } 1336 for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) { 1337 remove_edge(e, &activeEdges); 1338 } 1339 Edge* leftEdge = leftEnclosingEdge; 1340 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { 1341 insert_edge(e, leftEdge, &activeEdges); 1342 leftEdge = e; 1343 } 1344 } 1345 activeEdges.removeAll(); 1346 return false; 1347 } 1348 1349 // Stage 5: Tessellate the simplified mesh into monotone polygons. 1350 1351 Poly* tessellate(const VertexList& vertices, SkArenaAlloc& alloc) { 1352 LOG("tessellating simple polygons\n"); 1353 EdgeList activeEdges; 1354 Poly* polys = nullptr; 1355 for (Vertex* v = vertices.fHead; v != nullptr; v = v->fNext) { 1356 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { 1357 continue; 1358 } 1359 #if LOGGING_ENABLED 1360 LOG("\nvertex %g: (%g,%g), alpha %d\n", v->fID, v->fPoint.fX, v->fPoint.fY, v->fAlpha); 1361 #endif 1362 Edge* leftEnclosingEdge; 1363 Edge* rightEnclosingEdge; 1364 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge); 1365 Poly* leftPoly; 1366 Poly* rightPoly; 1367 if (v->fFirstEdgeAbove) { 1368 leftPoly = v->fFirstEdgeAbove->fLeftPoly; 1369 rightPoly = v->fLastEdgeAbove->fRightPoly; 1370 } else { 1371 leftPoly = leftEnclosingEdge ? leftEnclosingEdge->fRightPoly : nullptr; 1372 rightPoly = rightEnclosingEdge ? rightEnclosingEdge->fLeftPoly : nullptr; 1373 } 1374 #if LOGGING_ENABLED 1375 LOG("edges above:\n"); 1376 for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) { 1377 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, 1378 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRightPoly->fID : -1); 1379 } 1380 LOG("edges below:\n"); 1381 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { 1382 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, 1383 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRightPoly->fID : -1); 1384 } 1385 #endif 1386 if (v->fFirstEdgeAbove) { 1387 if (leftPoly) { 1388 leftPoly = leftPoly->addEdge(v->fFirstEdgeAbove, Poly::kRight_Side, alloc); 1389 } 1390 if (rightPoly) { 1391 rightPoly = rightPoly->addEdge(v->fLastEdgeAbove, Poly::kLeft_Side, alloc); 1392 } 1393 for (Edge* e = v->fFirstEdgeAbove; e != v->fLastEdgeAbove; e = e->fNextEdgeAbove) { 1394 Edge* rightEdge = e->fNextEdgeAbove; 1395 SkASSERT(rightEdge->isRightOf(e->fTop)); 1396 remove_edge(e, &activeEdges); 1397 if (e->fRightPoly) { 1398 e->fRightPoly->addEdge(e, Poly::kLeft_Side, alloc); 1399 } 1400 if (rightEdge->fLeftPoly && rightEdge->fLeftPoly != e->fRightPoly) { 1401 rightEdge->fLeftPoly->addEdge(e, Poly::kRight_Side, alloc); 1402 } 1403 } 1404 remove_edge(v->fLastEdgeAbove, &activeEdges); 1405 if (!v->fFirstEdgeBelow) { 1406 if (leftPoly && rightPoly && leftPoly != rightPoly) { 1407 SkASSERT(leftPoly->fPartner == nullptr && rightPoly->fPartner == nullptr); 1408 rightPoly->fPartner = leftPoly; 1409 leftPoly->fPartner = rightPoly; 1410 } 1411 } 1412 } 1413 if (v->fFirstEdgeBelow) { 1414 if (!v->fFirstEdgeAbove) { 1415 if (leftPoly && rightPoly) { 1416 if (leftPoly == rightPoly) { 1417 if (leftPoly->fTail && leftPoly->fTail->fSide == Poly::kLeft_Side) { 1418 leftPoly = new_poly(&polys, leftPoly->lastVertex(), 1419 leftPoly->fWinding, alloc); 1420 leftEnclosingEdge->fRightPoly = leftPoly; 1421 } else { 1422 rightPoly = new_poly(&polys, rightPoly->lastVertex(), 1423 rightPoly->fWinding, alloc); 1424 rightEnclosingEdge->fLeftPoly = rightPoly; 1425 } 1426 } 1427 Edge* join = alloc.make<Edge>(leftPoly->lastVertex(), v, 1, Edge::Type::kInner); 1428 leftPoly = leftPoly->addEdge(join, Poly::kRight_Side, alloc); 1429 rightPoly = rightPoly->addEdge(join, Poly::kLeft_Side, alloc); 1430 } 1431 } 1432 Edge* leftEdge = v->fFirstEdgeBelow; 1433 leftEdge->fLeftPoly = leftPoly; 1434 insert_edge(leftEdge, leftEnclosingEdge, &activeEdges); 1435 for (Edge* rightEdge = leftEdge->fNextEdgeBelow; rightEdge; 1436 rightEdge = rightEdge->fNextEdgeBelow) { 1437 insert_edge(rightEdge, leftEdge, &activeEdges); 1438 int winding = leftEdge->fLeftPoly ? leftEdge->fLeftPoly->fWinding : 0; 1439 winding += leftEdge->fWinding; 1440 if (winding != 0) { 1441 Poly* poly = new_poly(&polys, v, winding, alloc); 1442 leftEdge->fRightPoly = rightEdge->fLeftPoly = poly; 1443 } 1444 leftEdge = rightEdge; 1445 } 1446 v->fLastEdgeBelow->fRightPoly = rightPoly; 1447 } 1448 #if LOGGING_ENABLED 1449 LOG("\nactive edges:\n"); 1450 for (Edge* e = activeEdges.fHead; e != nullptr; e = e->fRight) { 1451 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, 1452 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRightPoly->fID : -1); 1453 } 1454 #endif 1455 } 1456 return polys; 1457 } 1458 1459 void remove_non_boundary_edges(const VertexList& mesh, SkPath::FillType fillType, 1460 SkArenaAlloc& alloc) { 1461 LOG("removing non-boundary edges\n"); 1462 EdgeList activeEdges; 1463 for (Vertex* v = mesh.fHead; v != nullptr; v = v->fNext) { 1464 if (!v->fFirstEdgeAbove && !v->fFirstEdgeBelow) { 1465 continue; 1466 } 1467 Edge* leftEnclosingEdge; 1468 Edge* rightEnclosingEdge; 1469 find_enclosing_edges(v, &activeEdges, &leftEnclosingEdge, &rightEnclosingEdge); 1470 bool prevFilled = leftEnclosingEdge && 1471 apply_fill_type(fillType, leftEnclosingEdge->fWinding); 1472 for (Edge* e = v->fFirstEdgeAbove; e;) { 1473 Edge* next = e->fNextEdgeAbove; 1474 remove_edge(e, &activeEdges); 1475 bool filled = apply_fill_type(fillType, e->fWinding); 1476 if (filled == prevFilled) { 1477 disconnect(e); 1478 } 1479 prevFilled = filled; 1480 e = next; 1481 } 1482 Edge* prev = leftEnclosingEdge; 1483 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { 1484 if (prev) { 1485 e->fWinding += prev->fWinding; 1486 } 1487 insert_edge(e, prev, &activeEdges); 1488 prev = e; 1489 } 1490 } 1491 } 1492 1493 // Note: this is the normal to the edge, but not necessarily unit length. 1494 void get_edge_normal(const Edge* e, SkVector* normal) { 1495 normal->set(SkDoubleToScalar(e->fLine.fA) * e->fWinding, 1496 SkDoubleToScalar(e->fLine.fB) * e->fWinding); 1497 } 1498 1499 // Stage 5c: detect and remove "pointy" vertices whose edge normals point in opposite directions 1500 // and whose adjacent vertices are less than a quarter pixel from an edge. These are guaranteed to 1501 // invert on stroking. 1502 1503 void simplify_boundary(EdgeList* boundary, Comparator& c, SkArenaAlloc& alloc) { 1504 Edge* prevEdge = boundary->fTail; 1505 SkVector prevNormal; 1506 get_edge_normal(prevEdge, &prevNormal); 1507 for (Edge* e = boundary->fHead; e != nullptr;) { 1508 Vertex* prev = prevEdge->fWinding == 1 ? prevEdge->fTop : prevEdge->fBottom; 1509 Vertex* next = e->fWinding == 1 ? e->fBottom : e->fTop; 1510 double dist = e->dist(prev->fPoint); 1511 SkVector normal; 1512 get_edge_normal(e, &normal); 1513 double denom = 0.0625f * e->fLine.magSq(); 1514 if (prevNormal.dot(normal) < 0.0 && (dist * dist) <= denom) { 1515 Edge* join = new_edge(prev, next, Edge::Type::kInner, c, alloc); 1516 insert_edge(join, e, boundary); 1517 remove_edge(prevEdge, boundary); 1518 remove_edge(e, boundary); 1519 if (join->fLeft && join->fRight) { 1520 prevEdge = join->fLeft; 1521 e = join; 1522 } else { 1523 prevEdge = boundary->fTail; 1524 e = boundary->fHead; // join->fLeft ? join->fLeft : join; 1525 } 1526 get_edge_normal(prevEdge, &prevNormal); 1527 } else { 1528 prevEdge = e; 1529 prevNormal = normal; 1530 e = e->fRight; 1531 } 1532 } 1533 } 1534 1535 void fix_inversions(Vertex* prev, Vertex* next, Edge* prevBisector, Edge* nextBisector, 1536 Edge* prevEdge, Comparator& c) { 1537 if (!prev || !next) { 1538 return; 1539 } 1540 int winding = c.sweep_lt(prev->fPoint, next->fPoint) ? 1 : -1; 1541 SkPoint p; 1542 uint8_t alpha; 1543 if (winding != prevEdge->fWinding && prevBisector->intersect(*nextBisector, &p, &alpha)) { 1544 prev->fPoint = next->fPoint = p; 1545 prev->fAlpha = next->fAlpha = alpha; 1546 } 1547 } 1548 1549 // Stage 5d: Displace edges by half a pixel inward and outward along their normals. Intersect to 1550 // find new vertices, and set zero alpha on the exterior and one alpha on the interior. Build a 1551 // new antialiased mesh from those vertices. 1552 1553 void stroke_boundary(EdgeList* boundary, VertexList* innerMesh, VertexList* outerMesh, 1554 Comparator& c, SkArenaAlloc& alloc) { 1555 // A boundary with fewer than 3 edges is degenerate. 1556 if (!boundary->fHead || !boundary->fHead->fRight || !boundary->fHead->fRight->fRight) { 1557 return; 1558 } 1559 Edge* prevEdge = boundary->fTail; 1560 float radius = 0.5f; 1561 double offset = radius * sqrt(prevEdge->fLine.magSq()) * prevEdge->fWinding; 1562 Line prevInner(prevEdge->fLine); 1563 prevInner.fC -= offset; 1564 Line prevOuter(prevEdge->fLine); 1565 prevOuter.fC += offset; 1566 VertexList innerVertices; 1567 VertexList outerVertices; 1568 Edge* prevBisector = nullptr; 1569 for (Edge* e = boundary->fHead; e != nullptr; e = e->fRight) { 1570 double offset = radius * sqrt(e->fLine.magSq()) * e->fWinding; 1571 Line inner(e->fLine); 1572 inner.fC -= offset; 1573 Line outer(e->fLine); 1574 outer.fC += offset; 1575 SkPoint innerPoint, outerPoint; 1576 if (prevInner.intersect(inner, &innerPoint) && 1577 prevOuter.intersect(outer, &outerPoint)) { 1578 Vertex* innerVertex = alloc.make<Vertex>(innerPoint, 255); 1579 Vertex* outerVertex = alloc.make<Vertex>(outerPoint, 0); 1580 Edge* bisector = new_edge(outerVertex, innerVertex, Edge::Type::kConnector, c, alloc); 1581 fix_inversions(innerVertices.fTail, innerVertex, prevBisector, bisector, prevEdge, c); 1582 fix_inversions(outerVertices.fTail, outerVertex, prevBisector, bisector, prevEdge, c); 1583 innerVertex->fPartner = outerVertex; 1584 outerVertex->fPartner = innerVertex; 1585 innerVertices.append(innerVertex); 1586 outerVertices.append(outerVertex); 1587 prevBisector = bisector; 1588 } 1589 prevInner = inner; 1590 prevOuter = outer; 1591 prevEdge = e; 1592 } 1593 1594 Vertex* innerVertex = innerVertices.fHead; 1595 Vertex* outerVertex = outerVertices.fHead; 1596 if (!innerVertex || !outerVertex) { 1597 return; 1598 } 1599 Edge* bisector = new_edge(outerVertices.fHead, innerVertices.fHead, Edge::Type::kConnector, c, 1600 alloc); 1601 fix_inversions(innerVertices.fTail, innerVertices.fHead, prevBisector, bisector, prevEdge, c); 1602 fix_inversions(outerVertices.fTail, outerVertices.fHead, prevBisector, bisector, prevEdge, c); 1603 Vertex* prevInnerVertex = innerVertices.fTail; 1604 Vertex* prevOuterVertex = outerVertices.fTail; 1605 while (innerVertex && outerVertex) { 1606 // Connect vertices into a quad mesh. Outer edges get default (1) winding. 1607 // Inner edges get -2 winding. This ensures that the interior is always filled 1608 // (-1 winding number for normal cases, 3 for thin features where the interior inverts). 1609 connect(prevOuterVertex, outerVertex, Edge::Type::kOuter, c, alloc); 1610 connect(prevInnerVertex, innerVertex, Edge::Type::kInner, c, alloc, -2); 1611 prevInnerVertex = innerVertex; 1612 prevOuterVertex = outerVertex; 1613 innerVertex = innerVertex->fNext; 1614 outerVertex = outerVertex->fNext; 1615 } 1616 innerMesh->append(innerVertices); 1617 outerMesh->append(outerVertices); 1618 } 1619 1620 void extract_boundary(EdgeList* boundary, Edge* e, SkPath::FillType fillType, SkArenaAlloc& alloc) { 1621 bool down = apply_fill_type(fillType, e->fWinding); 1622 while (e) { 1623 e->fWinding = down ? 1 : -1; 1624 Edge* next; 1625 boundary->append(e); 1626 if (down) { 1627 // Find outgoing edge, in clockwise order. 1628 if ((next = e->fNextEdgeAbove)) { 1629 down = false; 1630 } else if ((next = e->fBottom->fLastEdgeBelow)) { 1631 down = true; 1632 } else if ((next = e->fPrevEdgeAbove)) { 1633 down = false; 1634 } 1635 } else { 1636 // Find outgoing edge, in counter-clockwise order. 1637 if ((next = e->fPrevEdgeBelow)) { 1638 down = true; 1639 } else if ((next = e->fTop->fFirstEdgeAbove)) { 1640 down = false; 1641 } else if ((next = e->fNextEdgeBelow)) { 1642 down = true; 1643 } 1644 } 1645 disconnect(e); 1646 e = next; 1647 } 1648 } 1649 1650 // Stage 5b: Extract boundaries from mesh, simplify and stroke them into a new mesh. 1651 1652 void extract_boundaries(const VertexList& inMesh, VertexList* innerVertices, 1653 VertexList* outerVertices, SkPath::FillType fillType, 1654 Comparator& c, SkArenaAlloc& alloc) { 1655 remove_non_boundary_edges(inMesh, fillType, alloc); 1656 for (Vertex* v = inMesh.fHead; v; v = v->fNext) { 1657 while (v->fFirstEdgeBelow) { 1658 EdgeList boundary; 1659 extract_boundary(&boundary, v->fFirstEdgeBelow, fillType, alloc); 1660 simplify_boundary(&boundary, c, alloc); 1661 stroke_boundary(&boundary, innerVertices, outerVertices, c, alloc); 1662 } 1663 } 1664 } 1665 1666 // This is a driver function that calls stages 2-5 in turn. 1667 1668 void contours_to_mesh(VertexList* contours, int contourCnt, bool antialias, 1669 VertexList* mesh, Comparator& c, SkArenaAlloc& alloc) { 1670 #if LOGGING_ENABLED 1671 for (int i = 0; i < contourCnt; ++i) { 1672 Vertex* v = contours[i].fHead; 1673 SkASSERT(v); 1674 LOG("path.moveTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY); 1675 for (v = v->fNext; v; v = v->fNext) { 1676 LOG("path.lineTo(%20.20g, %20.20g);\n", v->fPoint.fX, v->fPoint.fY); 1677 } 1678 } 1679 #endif 1680 sanitize_contours(contours, contourCnt, antialias); 1681 build_edges(contours, contourCnt, mesh, c, alloc); 1682 } 1683 1684 void sort_mesh(VertexList* vertices, Comparator& c, SkArenaAlloc& alloc) { 1685 if (!vertices || !vertices->fHead) { 1686 return; 1687 } 1688 1689 // Sort vertices in Y (secondarily in X). 1690 if (c.fDirection == Comparator::Direction::kHorizontal) { 1691 merge_sort<sweep_lt_horiz>(vertices); 1692 } else { 1693 merge_sort<sweep_lt_vert>(vertices); 1694 } 1695 #if LOGGING_ENABLED 1696 for (Vertex* v = vertices->fHead; v != nullptr; v = v->fNext) { 1697 static float gID = 0.0f; 1698 v->fID = gID++; 1699 } 1700 #endif 1701 } 1702 1703 Poly* contours_to_polys(VertexList* contours, int contourCnt, SkPath::FillType fillType, 1704 const SkRect& pathBounds, bool antialias, VertexList* outerMesh, 1705 SkArenaAlloc& alloc) { 1706 Comparator c(pathBounds.width() > pathBounds.height() ? Comparator::Direction::kHorizontal 1707 : Comparator::Direction::kVertical); 1708 VertexList mesh; 1709 contours_to_mesh(contours, contourCnt, antialias, &mesh, c, alloc); 1710 sort_mesh(&mesh, c, alloc); 1711 merge_coincident_vertices(&mesh, c, alloc); 1712 simplify(mesh, c, alloc); 1713 if (antialias) { 1714 VertexList innerMesh; 1715 extract_boundaries(mesh, &innerMesh, outerMesh, fillType, c, alloc); 1716 sort_mesh(&innerMesh, c, alloc); 1717 sort_mesh(outerMesh, c, alloc); 1718 if (is_complex(innerMesh) || is_complex(*outerMesh)) { 1719 LOG("found complex mesh; taking slow path\n"); 1720 VertexList aaMesh; 1721 connect_partners(outerMesh, c, alloc); 1722 sorted_merge(&innerMesh, outerMesh, &aaMesh, c); 1723 merge_coincident_vertices(&aaMesh, c, alloc); 1724 simplify(aaMesh, c, alloc); 1725 outerMesh->fHead = outerMesh->fTail = nullptr; 1726 return tessellate(aaMesh, alloc); 1727 } else { 1728 LOG("no complex polygons; taking fast path\n"); 1729 merge_coincident_vertices(&innerMesh, c, alloc); 1730 return tessellate(innerMesh, alloc); 1731 } 1732 } else { 1733 return tessellate(mesh, alloc); 1734 } 1735 } 1736 1737 // Stage 6: Triangulate the monotone polygons into a vertex buffer. 1738 void* polys_to_triangles(Poly* polys, SkPath::FillType fillType, const AAParams* aaParams, 1739 void* data) { 1740 for (Poly* poly = polys; poly; poly = poly->fNext) { 1741 if (apply_fill_type(fillType, poly)) { 1742 data = poly->emit(aaParams, data); 1743 } 1744 } 1745 return data; 1746 } 1747 1748 Poly* path_to_polys(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds, 1749 int contourCnt, SkArenaAlloc& alloc, bool antialias, bool* isLinear, 1750 VertexList* outerMesh) { 1751 SkPath::FillType fillType = path.getFillType(); 1752 if (SkPath::IsInverseFillType(fillType)) { 1753 contourCnt++; 1754 } 1755 std::unique_ptr<VertexList[]> contours(new VertexList[contourCnt]); 1756 1757 path_to_contours(path, tolerance, clipBounds, contours.get(), alloc, isLinear); 1758 return contours_to_polys(contours.get(), contourCnt, path.getFillType(), path.getBounds(), 1759 antialias, outerMesh, alloc); 1760 } 1761 1762 int get_contour_count(const SkPath& path, SkScalar tolerance) { 1763 int contourCnt; 1764 int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, tolerance); 1765 if (maxPts <= 0) { 1766 return 0; 1767 } 1768 if (maxPts > ((int)SK_MaxU16 + 1)) { 1769 SkDebugf("Path not rendered, too many verts (%d)\n", maxPts); 1770 return 0; 1771 } 1772 return contourCnt; 1773 } 1774 1775 int count_points(Poly* polys, SkPath::FillType fillType) { 1776 int count = 0; 1777 for (Poly* poly = polys; poly; poly = poly->fNext) { 1778 if (apply_fill_type(fillType, poly) && poly->fCount >= 3) { 1779 count += (poly->fCount - 2) * (TESSELLATOR_WIREFRAME ? 6 : 3); 1780 } 1781 } 1782 return count; 1783 } 1784 1785 int count_outer_mesh_points(const VertexList& outerMesh) { 1786 int count = 0; 1787 for (Vertex* v = outerMesh.fHead; v; v = v->fNext) { 1788 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { 1789 count += TESSELLATOR_WIREFRAME ? 12 : 6; 1790 } 1791 } 1792 return count; 1793 } 1794 1795 void* outer_mesh_to_triangles(const VertexList& outerMesh, const AAParams* aaParams, void* data) { 1796 for (Vertex* v = outerMesh.fHead; v; v = v->fNext) { 1797 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { 1798 Vertex* v0 = e->fTop; 1799 Vertex* v1 = e->fBottom; 1800 Vertex* v2 = e->fBottom->fPartner; 1801 Vertex* v3 = e->fTop->fPartner; 1802 data = emit_triangle(v0, v1, v2, aaParams, data); 1803 data = emit_triangle(v0, v2, v3, aaParams, data); 1804 } 1805 } 1806 return data; 1807 } 1808 1809 } // namespace 1810 1811 namespace GrTessellator { 1812 1813 // Stage 6: Triangulate the monotone polygons into a vertex buffer. 1814 1815 int PathToTriangles(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds, 1816 VertexAllocator* vertexAllocator, bool antialias, const GrColor& color, 1817 bool canTweakAlphaForCoverage, bool* isLinear) { 1818 int contourCnt = get_contour_count(path, tolerance); 1819 if (contourCnt <= 0) { 1820 *isLinear = true; 1821 return 0; 1822 } 1823 SkArenaAlloc alloc(kArenaChunkSize); 1824 VertexList outerMesh; 1825 Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, antialias, 1826 isLinear, &outerMesh); 1827 SkPath::FillType fillType = antialias ? SkPath::kWinding_FillType : path.getFillType(); 1828 int count = count_points(polys, fillType); 1829 if (0 == count) { 1830 return 0; 1831 } 1832 if (antialias) { 1833 count += count_outer_mesh_points(outerMesh); 1834 } 1835 1836 void* verts = vertexAllocator->lock(count); 1837 if (!verts) { 1838 SkDebugf("Could not allocate vertices\n"); 1839 return 0; 1840 } 1841 1842 LOG("emitting %d verts\n", count); 1843 AAParams aaParams; 1844 aaParams.fTweakAlpha = canTweakAlphaForCoverage; 1845 aaParams.fColor = color; 1846 1847 void* end = polys_to_triangles(polys, fillType, antialias ? &aaParams : nullptr, verts); 1848 end = outer_mesh_to_triangles(outerMesh, &aaParams, end); 1849 int actualCount = static_cast<int>((static_cast<uint8_t*>(end) - static_cast<uint8_t*>(verts)) 1850 / vertexAllocator->stride()); 1851 SkASSERT(actualCount <= count); 1852 vertexAllocator->unlock(actualCount); 1853 return actualCount; 1854 } 1855 1856 int PathToVertices(const SkPath& path, SkScalar tolerance, const SkRect& clipBounds, 1857 GrTessellator::WindingVertex** verts) { 1858 int contourCnt = get_contour_count(path, tolerance); 1859 if (contourCnt <= 0) { 1860 return 0; 1861 } 1862 SkArenaAlloc alloc(kArenaChunkSize); 1863 bool isLinear; 1864 Poly* polys = path_to_polys(path, tolerance, clipBounds, contourCnt, alloc, false, &isLinear, 1865 nullptr); 1866 SkPath::FillType fillType = path.getFillType(); 1867 int count = count_points(polys, fillType); 1868 if (0 == count) { 1869 *verts = nullptr; 1870 return 0; 1871 } 1872 1873 *verts = new GrTessellator::WindingVertex[count]; 1874 GrTessellator::WindingVertex* vertsEnd = *verts; 1875 SkPoint* points = new SkPoint[count]; 1876 SkPoint* pointsEnd = points; 1877 for (Poly* poly = polys; poly; poly = poly->fNext) { 1878 if (apply_fill_type(fillType, poly)) { 1879 SkPoint* start = pointsEnd; 1880 pointsEnd = static_cast<SkPoint*>(poly->emit(nullptr, pointsEnd)); 1881 while (start != pointsEnd) { 1882 vertsEnd->fPos = *start; 1883 vertsEnd->fWinding = poly->fWinding; 1884 ++start; 1885 ++vertsEnd; 1886 } 1887 } 1888 } 1889 int actualCount = static_cast<int>(vertsEnd - *verts); 1890 SkASSERT(actualCount <= count); 1891 SkASSERT(pointsEnd - points == actualCount); 1892 delete[] points; 1893 return actualCount; 1894 } 1895 1896 } // namespace 1897