Chromium Code Reviews| 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 "GrPathUtils.h" | 10 #include "GrPathUtils.h" |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 #endif | 197 #endif |
| 198 return data; | 198 return data; |
| 199 } | 199 } |
| 200 | 200 |
| 201 struct EdgeList { | 201 struct EdgeList { |
| 202 EdgeList() : fHead(nullptr), fTail(nullptr) {} | 202 EdgeList() : fHead(nullptr), fTail(nullptr) {} |
| 203 Edge* fHead; | 203 Edge* fHead; |
| 204 Edge* fTail; | 204 Edge* fTail; |
| 205 }; | 205 }; |
| 206 | 206 |
| 207 struct VertexList { | 207 template<class T> struct List { |
| 208 VertexList() : fHead(nullptr), fTail(nullptr) {} | 208 List() : fHead(nullptr), fTail(nullptr) {} |
| 209 Vertex* fHead; | 209 T* fHead; |
| 210 Vertex* fTail; | 210 T* fTail; |
| 211 void insert(Vertex* v, Vertex* prev, Vertex* next) { | 211 void insert(T* t, T* prev, T* next) { |
| 212 list_insert<Vertex, &Vertex::fPrev, &Vertex::fNext>(v, prev, next, &fHea d, &fTail); | 212 list_insert<T, &T::fPrev, &T::fNext>(t, prev, next, &fHead, &fTail); |
| 213 } | 213 } |
| 214 void append(Vertex* v) { | 214 void append(T* t) { |
| 215 insert(v, fTail, nullptr); | 215 insert(t, fTail, nullptr); |
| 216 } | 216 } |
| 217 void prepend(Vertex* v) { | 217 void prepend(T* t) { |
| 218 insert(v, nullptr, fHead); | 218 insert(t, nullptr, fHead); |
| 219 } | |
| 220 void remove(T* t) { | |
| 221 list_remove<T, &T::fPrev, &T::fNext>(t, &fHead, &fTail); | |
| 219 } | 222 } |
| 220 }; | 223 }; |
| 221 | 224 |
| 225 typedef List<Vertex> VertexList; | |
| 226 | |
| 222 /** | 227 /** |
| 223 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of "edges above" and | 228 * An Edge joins a top Vertex to a bottom Vertex. Edge ordering for the list of "edges above" and |
| 224 * "edge below" a vertex as well as for the active edge list is handled by isLef tOf()/isRightOf(). | 229 * "edge below" a vertex as well as for the active edge list is handled by isLef tOf()/isRightOf(). |
| 225 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b ecause floating | 230 * Note that an Edge will give occasionally dist() != 0 for its own endpoints (b ecause floating |
| 226 * point). For speed, that case is only tested by the callers which require it ( e.g., | 231 * point). For speed, that case is only tested by the callers which require it ( e.g., |
| 227 * cleanup_active_edges()). Edges also handle checking for intersection with oth er edges. | 232 * cleanup_active_edges()). Edges also handle checking for intersection with oth er edges. |
| 228 * Currently, this converts the edges to the parametric form, in order to avoid doing a division | 233 * Currently, this converts the edges to the parametric form, in order to avoid doing a division |
| 229 * until an intersection has been confirmed. This is slightly slower in the "fou nd" case, but | 234 * until an intersection has been confirmed. This is slightly slower in the "fou nd" case, but |
| 230 * a lot faster in the "not found" case. | 235 * a lot faster in the "not found" case. |
| 231 * | 236 * |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 242 : fWinding(winding) | 247 : fWinding(winding) |
| 243 , fTop(top) | 248 , fTop(top) |
| 244 , fBottom(bottom) | 249 , fBottom(bottom) |
| 245 , fLeft(nullptr) | 250 , fLeft(nullptr) |
| 246 , fRight(nullptr) | 251 , fRight(nullptr) |
| 247 , fPrevEdgeAbove(nullptr) | 252 , fPrevEdgeAbove(nullptr) |
| 248 , fNextEdgeAbove(nullptr) | 253 , fNextEdgeAbove(nullptr) |
| 249 , fPrevEdgeBelow(nullptr) | 254 , fPrevEdgeBelow(nullptr) |
| 250 , fNextEdgeBelow(nullptr) | 255 , fNextEdgeBelow(nullptr) |
| 251 , fLeftPoly(nullptr) | 256 , fLeftPoly(nullptr) |
| 252 , fRightPoly(nullptr) { | 257 , fRightPoly(nullptr) |
| 258 , fLeftPolyPrev(nullptr) | |
| 259 , fLeftPolyNext(nullptr) | |
| 260 , fRightPolyPrev(nullptr) | |
| 261 , fRightPolyNext(nullptr) { | |
| 253 recompute(); | 262 recompute(); |
| 254 } | 263 } |
| 255 int fWinding; // 1 == edge goes downward; -1 = edge goes upwar d. | 264 int fWinding; // 1 == edge goes downward; -1 = edge goes upwar d. |
| 256 Vertex* fTop; // The top vertex in vertex-sort-order (sweep_lt ). | 265 Vertex* fTop; // The top vertex in vertex-sort-order (sweep_lt ). |
| 257 Vertex* fBottom; // The bottom vertex in vertex-sort-order. | 266 Vertex* fBottom; // The bottom vertex in vertex-sort-order. |
| 258 Edge* fLeft; // The linked list of edges in the active edge l ist. | 267 Edge* fLeft; // The linked list of edges in the active edge l ist. |
| 259 Edge* fRight; // " | 268 Edge* fRight; // " |
| 260 Edge* fPrevEdgeAbove; // The linked list of edges in the bottom Vertex 's "edges above". | 269 Edge* fPrevEdgeAbove; // The linked list of edges in the bottom Vertex 's "edges above". |
| 261 Edge* fNextEdgeAbove; // " | 270 Edge* fNextEdgeAbove; // " |
| 262 Edge* fPrevEdgeBelow; // The linked list of edges in the top Vertex's "edges below". | 271 Edge* fPrevEdgeBelow; // The linked list of edges in the top Vertex's "edges below". |
| 263 Edge* fNextEdgeBelow; // " | 272 Edge* fNextEdgeBelow; // " |
| 264 Poly* fLeftPoly; // The Poly to the left of this edge, if any. | 273 Poly* fLeftPoly; // The Poly to the left of this edge, if any. |
| 265 Poly* fRightPoly; // The Poly to the right of this edge, if any. | 274 Poly* fRightPoly; // The Poly to the right of this edge, if any. |
| 275 Edge* fLeftPolyPrev; | |
| 276 Edge* fLeftPolyNext; | |
| 277 Edge* fRightPolyPrev; | |
| 278 Edge* fRightPolyNext; | |
| 266 double fDX; // The line equation for this edge, in implicit form. | 279 double fDX; // The line equation for this edge, in implicit form. |
| 267 double fDY; // fDY * x + fDX * y + fC = 0, for point (x, y) on the line. | 280 double fDY; // fDY * x + fDX * y + fC = 0, for point (x, y) on the line. |
| 268 double fC; | 281 double fC; |
| 269 double dist(const SkPoint& p) const { | 282 double dist(const SkPoint& p) const { |
| 270 return fDY * p.fX - fDX * p.fY + fC; | 283 return fDY * p.fX - fDX * p.fY + fC; |
| 271 } | 284 } |
| 272 bool isRightOf(Vertex* v) const { | 285 bool isRightOf(Vertex* v) const { |
| 273 return dist(v->fPoint) < 0.0; | 286 return dist(v->fPoint) < 0.0; |
| 274 } | 287 } |
| 275 bool isLeftOf(Vertex* v) const { | 288 bool isLeftOf(Vertex* v) const { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 309 return true; | 322 return true; |
| 310 } | 323 } |
| 311 bool isActive(EdgeList* activeEdges) const { | 324 bool isActive(EdgeList* activeEdges) const { |
| 312 return activeEdges && (fLeft || fRight || activeEdges->fHead == this); | 325 return activeEdges && (fLeft || fRight || activeEdges->fHead == this); |
| 313 } | 326 } |
| 314 }; | 327 }; |
| 315 | 328 |
| 316 /******************************************************************************* ********/ | 329 /******************************************************************************* ********/ |
| 317 | 330 |
| 318 struct Poly { | 331 struct Poly { |
| 319 Poly(int winding) | 332 Poly(Vertex* v, int winding) |
| 320 : fWinding(winding) | 333 : fFirstVertex(v) |
| 321 , fHead(nullptr) | 334 , fWinding(winding) |
| 322 , fTail(nullptr) | |
| 323 , fActive(nullptr) | |
| 324 , fNext(nullptr) | 335 , fNext(nullptr) |
| 325 , fPartner(nullptr) | 336 , fPartner(nullptr) |
| 326 , fCount(0) | 337 , fCount(0) |
| 327 { | 338 { |
| 328 #if LOGGING_ENABLED | 339 #if LOGGING_ENABLED |
| 329 static int gID = 0; | 340 static int gID = 0; |
| 330 fID = gID++; | 341 fID = gID++; |
| 331 LOG("*** created Poly %d\n", fID); | 342 LOG("*** created Poly %d\n", fID); |
| 332 #endif | 343 #endif |
| 333 } | 344 } |
| 334 typedef enum { kNeither_Side, kLeft_Side, kRight_Side } Side; | 345 typedef enum { kLeft_Side, kRight_Side } Side; |
| 335 struct MonotonePoly { | 346 struct MonotonePoly { |
| 336 MonotonePoly() | 347 MonotonePoly(Edge* edge, Side side) |
| 337 : fSide(kNeither_Side) | 348 : fSide(side) |
| 349 , fFirstEdge(nullptr) | |
| 350 , fLastEdge(nullptr) | |
| 338 , fPrev(nullptr) | 351 , fPrev(nullptr) |
| 339 , fNext(nullptr) {} | 352 , fNext(nullptr) { |
| 353 addEdge(edge); | |
| 354 } | |
| 340 Side fSide; | 355 Side fSide; |
| 341 VertexList fVertices; | 356 Edge* fFirstEdge; |
| 357 Edge* fLastEdge; | |
| 342 MonotonePoly* fPrev; | 358 MonotonePoly* fPrev; |
| 343 MonotonePoly* fNext; | 359 MonotonePoly* fNext; |
| 344 bool addVertex(Vertex* v, Side side, SkChunkAlloc& alloc) { | 360 void addEdge(Edge* edge) { |
| 345 Vertex* newV = ALLOC_NEW(Vertex, (v->fPoint), alloc); | 361 if (fSide == kRight_Side) { |
| 346 bool done = false; | 362 list_insert<Edge, &Edge::fRightPolyPrev, &Edge::fRightPolyNext>( |
| 347 if (fSide == kNeither_Side) { | 363 edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge); |
| 348 fSide = side; | |
| 349 } else { | 364 } else { |
| 350 done = side != fSide; | 365 list_insert<Edge, &Edge::fLeftPolyPrev, &Edge::fLeftPolyNext>( |
| 366 edge, fLastEdge, nullptr, &fFirstEdge, &fLastEdge); | |
| 351 } | 367 } |
| 352 if (fSide == kRight_Side) { | |
| 353 fVertices.append(newV); | |
| 354 } else { | |
| 355 fVertices.prepend(newV); | |
| 356 } | |
| 357 return done; | |
| 358 } | 368 } |
| 359 | 369 |
| 360 SkPoint* emit(SkPoint* data) { | 370 SkPoint* emit(SkPoint* data) { |
| 361 Vertex* first = fVertices.fHead; | 371 Edge* e = fFirstEdge; |
| 372 e->fTop->fPrev = e->fTop->fNext = nullptr; | |
| 373 VertexList vertices; | |
| 374 vertices.append(e->fTop); | |
| 375 while (e != nullptr) { | |
| 376 e->fBottom->fPrev = e->fBottom->fNext = nullptr; | |
| 377 if (kRight_Side == fSide) { | |
| 378 vertices.append(e->fBottom); | |
| 379 e = e->fRightPolyNext; | |
| 380 } else { | |
| 381 vertices.prepend(e->fBottom); | |
| 382 e = e->fLeftPolyNext; | |
| 383 } | |
| 384 } | |
| 385 Vertex* first = vertices.fHead; | |
| 362 Vertex* v = first->fNext; | 386 Vertex* v = first->fNext; |
| 363 while (v != fVertices.fTail) { | 387 while (v != vertices.fTail) { |
| 364 SkASSERT(v && v->fPrev && v->fNext); | 388 SkASSERT(v && v->fPrev && v->fNext); |
| 365 Vertex* prev = v->fPrev; | 389 Vertex* prev = v->fPrev; |
| 366 Vertex* curr = v; | 390 Vertex* curr = v; |
| 367 Vertex* next = v->fNext; | 391 Vertex* next = v->fNext; |
| 368 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint. fX; | 392 double ax = static_cast<double>(curr->fPoint.fX) - prev->fPoint. fX; |
| 369 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint. fY; | 393 double ay = static_cast<double>(curr->fPoint.fY) - prev->fPoint. fY; |
| 370 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint. fX; | 394 double bx = static_cast<double>(next->fPoint.fX) - curr->fPoint. fX; |
| 371 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint. fY; | 395 double by = static_cast<double>(next->fPoint.fY) - curr->fPoint. fY; |
| 372 if (ax * by - ay * bx >= 0.0) { | 396 if (ax * by - ay * bx >= 0.0) { |
| 373 data = emit_triangle(prev, curr, next, data); | 397 data = emit_triangle(prev, curr, next, data); |
| 374 v->fPrev->fNext = v->fNext; | 398 v->fPrev->fNext = v->fNext; |
| 375 v->fNext->fPrev = v->fPrev; | 399 v->fNext->fPrev = v->fPrev; |
| 376 if (v->fPrev == first) { | 400 if (v->fPrev == first) { |
| 377 v = v->fNext; | 401 v = v->fNext; |
| 378 } else { | 402 } else { |
| 379 v = v->fPrev; | 403 v = v->fPrev; |
| 380 } | 404 } |
| 381 } else { | 405 } else { |
| 382 v = v->fNext; | 406 v = v->fNext; |
| 383 } | 407 } |
| 384 } | 408 } |
| 385 return data; | 409 return data; |
| 386 } | 410 } |
| 387 }; | 411 }; |
| 388 Poly* addVertex(Vertex* v, Side side, SkChunkAlloc& alloc) { | 412 void addEdge(Edge* e, Side side, SkChunkAlloc& alloc) { |
| 389 LOG("addVertex() to %d at %g (%g, %g), %s side\n", fID, v->fID, v->fPoin t.fX, v->fPoint.fY, | 413 LOG("addEdge (%g,%g)-(%g,%g) to poly %d, %s side\n", |
| 390 side == kLeft_Side ? "left" : side == kRight_Side ? "right" : "ne ither"); | 414 e->fTop->fPoint.fX, e->fTop->fPoint.fY, |
| 415 e->fBottom->fPoint.fX, e->fBottom->fPoint.fY, | |
|
robertphillips
2016/06/02 12:19:48
Does the "neither" case still make sense ?
Stephen White
2016/06/02 18:01:21
Good point. Removed.
| |
| 416 fID, side == kLeft_Side ? "left" : side == kRight_Side ? "right" : "neither"); | |
| 391 Poly* partner = fPartner; | 417 Poly* partner = fPartner; |
| 392 Poly* poly = this; | |
| 393 if (partner) { | 418 if (partner) { |
| 394 fPartner = partner->fPartner = nullptr; | 419 fPartner = partner->fPartner = nullptr; |
| 395 } | 420 } |
| 396 if (!fActive) { | 421 if (!fMonotones.fTail) { |
| 397 fActive = ALLOC_NEW(MonotonePoly, (), alloc); | 422 fMonotones.append(ALLOC_NEW(MonotonePoly, (e, side), alloc)); |
| 423 fCount += 2; | |
| 424 } else if (side == fMonotones.fTail->fSide) { | |
| 425 fMonotones.fTail->addEdge(e); | |
| 426 fCount++; | |
| 427 } else { | |
| 428 if (e->fBottom == fMonotones.fTail->fLastEdge->fBottom) { | |
| 429 return; | |
| 430 } | |
| 431 e = ALLOC_NEW(Edge, (fMonotones.fTail->fLastEdge->fBottom, e->fBotto m, 1), alloc); | |
| 432 fMonotones.fTail->addEdge(e); | |
| 433 fCount++; | |
| 434 MonotonePoly* m; | |
| 435 if (partner) { | |
| 436 m = partner->fMonotones.fTail; | |
| 437 m->addEdge(e); | |
| 438 partner->fMonotones.remove(m); | |
| 439 } else { | |
| 440 m = ALLOC_NEW(MonotonePoly, (e, side), alloc); | |
| 441 } | |
| 442 fCount += 2; | |
| 443 fMonotones.append(m); | |
| 398 } | 444 } |
| 399 if (fActive->addVertex(v, side, alloc)) { | |
| 400 if (fTail) { | |
| 401 fActive->fPrev = fTail; | |
| 402 fTail->fNext = fActive; | |
| 403 fTail = fActive; | |
| 404 } else { | |
| 405 fHead = fTail = fActive; | |
| 406 } | |
| 407 if (partner) { | |
| 408 partner->addVertex(v, side, alloc); | |
| 409 poly = partner; | |
| 410 } else { | |
| 411 Vertex* prev = fActive->fSide == Poly::kLeft_Side ? | |
| 412 fActive->fVertices.fHead->fNext : fActive->fVerti ces.fTail->fPrev; | |
| 413 fActive = ALLOC_NEW(MonotonePoly, , alloc); | |
| 414 fActive->addVertex(prev, Poly::kNeither_Side, alloc); | |
| 415 fActive->addVertex(v, side, alloc); | |
| 416 } | |
| 417 } | |
| 418 fCount++; | |
| 419 return poly; | |
| 420 } | |
| 421 void end(Vertex* v, SkChunkAlloc& alloc) { | |
| 422 LOG("end() %d at %g, %g\n", fID, v->fPoint.fX, v->fPoint.fY); | |
| 423 if (fPartner) { | |
| 424 fPartner = fPartner->fPartner = nullptr; | |
| 425 } | |
| 426 addVertex(v, fActive->fSide == kLeft_Side ? kRight_Side : kLeft_Side, al loc); | |
| 427 } | 445 } |
| 428 SkPoint* emit(SkPoint *data) { | 446 SkPoint* emit(SkPoint *data) { |
| 429 if (fCount < 3) { | 447 if (fCount < 3) { |
| 430 return data; | 448 return data; |
| 431 } | 449 } |
| 432 LOG("emit() %d, size %d\n", fID, fCount); | 450 LOG("emit() %d, size %d\n", fID, fCount); |
| 433 for (MonotonePoly* m = fHead; m != nullptr; m = m->fNext) { | 451 for (MonotonePoly* m = fMonotones.fHead; m != nullptr; m = m->fNext) { |
| 434 data = m->emit(data); | 452 data = m->emit(data); |
| 435 } | 453 } |
| 436 return data; | 454 return data; |
| 437 } | 455 } |
| 456 Vertex* lastVertex() const { | |
| 457 return fMonotones.fTail ? fMonotones.fTail->fLastEdge->fBottom : fFirst Vertex; | |
| 458 } | |
| 459 Vertex* fFirstVertex; | |
| 438 int fWinding; | 460 int fWinding; |
| 439 MonotonePoly* fHead; | 461 List<MonotonePoly> fMonotones; |
| 440 MonotonePoly* fTail; | |
| 441 MonotonePoly* fActive; | |
| 442 Poly* fNext; | 462 Poly* fNext; |
| 443 Poly* fPartner; | 463 Poly* fPartner; |
| 444 int fCount; | 464 int fCount; |
| 445 #if LOGGING_ENABLED | 465 #if LOGGING_ENABLED |
| 446 int fID; | 466 int fID; |
| 447 #endif | 467 #endif |
| 448 }; | 468 }; |
| 449 | 469 |
| 450 /******************************************************************************* ********/ | 470 /******************************************************************************* ********/ |
| 451 | 471 |
| 452 bool coincident(const SkPoint& a, const SkPoint& b) { | 472 bool coincident(const SkPoint& a, const SkPoint& b) { |
| 453 return a == b; | 473 return a == b; |
| 454 } | 474 } |
| 455 | 475 |
| 456 Poly* new_poly(Poly** head, Vertex* v, int winding, SkChunkAlloc& alloc) { | 476 Poly* new_poly(Poly** head, Vertex* v, int winding, SkChunkAlloc& alloc) { |
| 457 Poly* poly = ALLOC_NEW(Poly, (winding), alloc); | 477 Poly* poly = ALLOC_NEW(Poly, (v, winding), alloc); |
| 458 poly->addVertex(v, Poly::kNeither_Side, alloc); | |
| 459 poly->fNext = *head; | 478 poly->fNext = *head; |
| 460 *head = poly; | 479 *head = poly; |
| 461 return poly; | 480 return poly; |
| 462 } | 481 } |
| 463 | 482 |
| 464 Vertex* append_point_to_contour(const SkPoint& p, Vertex* prev, Vertex** head, | 483 Vertex* append_point_to_contour(const SkPoint& p, Vertex* prev, Vertex** head, |
| 465 SkChunkAlloc& alloc) { | 484 SkChunkAlloc& alloc) { |
| 466 Vertex* v = ALLOC_NEW(Vertex, (p), alloc); | 485 Vertex* v = ALLOC_NEW(Vertex, (p), alloc); |
| 467 #if LOGGING_ENABLED | 486 #if LOGGING_ENABLED |
| 468 static float gID = 0.0f; | 487 static float gID = 0.0f; |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1187 for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) { | 1206 for (Edge* e = v->fFirstEdgeAbove; e; e = e->fNextEdgeAbove) { |
| 1188 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, | 1207 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, |
| 1189 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRight Poly->fID : -1); | 1208 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRight Poly->fID : -1); |
| 1190 } | 1209 } |
| 1191 LOG("edges below:\n"); | 1210 LOG("edges below:\n"); |
| 1192 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { | 1211 for (Edge* e = v->fFirstEdgeBelow; e; e = e->fNextEdgeBelow) { |
| 1193 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, | 1212 LOG("%g -> %g, lpoly %d, rpoly %d\n", e->fTop->fID, e->fBottom->fID, |
| 1194 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRight Poly->fID : -1); | 1213 e->fLeftPoly ? e->fLeftPoly->fID : -1, e->fRightPoly ? e->fRight Poly->fID : -1); |
| 1195 } | 1214 } |
| 1196 #endif | 1215 #endif |
| 1197 if (v->fFirstEdgeAbove) { | 1216 if (v->fFirstEdgeAbove) { |
|
robertphillips
2016/06/02 12:19:48
Either "nullptr != e" or "e" ?
| |
| 1198 if (leftPoly) { | 1217 for (Edge* e = v->fFirstEdgeAbove; e != nullptr; e = e->fNextEdgeAbo ve) { |
| 1199 leftPoly = leftPoly->addVertex(v, Poly::kRight_Side, alloc); | 1218 remove_edge(e, &activeEdges); |
| 1200 } | 1219 if (e->fLeftPoly) { |
| 1201 if (rightPoly) { | 1220 e->fLeftPoly->addEdge(e, Poly::kRight_Side, alloc); |
| 1202 rightPoly = rightPoly->addVertex(v, Poly::kLeft_Side, alloc); | |
| 1203 } | |
| 1204 for (Edge* e = v->fFirstEdgeAbove; e != v->fLastEdgeAbove; e = e->fN extEdgeAbove) { | |
| 1205 Edge* leftEdge = e; | |
| 1206 Edge* rightEdge = e->fNextEdgeAbove; | |
| 1207 SkASSERT(rightEdge->isRightOf(leftEdge->fTop)); | |
| 1208 remove_edge(leftEdge, &activeEdges); | |
| 1209 if (leftEdge->fRightPoly) { | |
| 1210 leftEdge->fRightPoly->end(v, alloc); | |
| 1211 } | 1221 } |
| 1212 if (rightEdge->fLeftPoly && rightEdge->fLeftPoly != leftEdge->fR ightPoly) { | 1222 if (e->fRightPoly) { |
| 1213 rightEdge->fLeftPoly->end(v, alloc); | 1223 e->fRightPoly->addEdge(e, Poly::kLeft_Side, alloc); |
| 1214 } | 1224 } |
| 1215 } | 1225 } |
| 1216 remove_edge(v->fLastEdgeAbove, &activeEdges); | |
| 1217 if (!v->fFirstEdgeBelow) { | 1226 if (!v->fFirstEdgeBelow) { |
| 1218 if (leftPoly && rightPoly && leftPoly != rightPoly) { | 1227 if (leftPoly && rightPoly && leftPoly != rightPoly) { |
| 1219 SkASSERT(leftPoly->fPartner == nullptr && rightPoly->fPartne r == nullptr); | 1228 SkASSERT(leftPoly->fPartner == nullptr && rightPoly->fPartne r == nullptr); |
| 1220 rightPoly->fPartner = leftPoly; | 1229 rightPoly->fPartner = leftPoly; |
| 1221 leftPoly->fPartner = rightPoly; | 1230 leftPoly->fPartner = rightPoly; |
| 1222 } | 1231 } |
| 1223 } | 1232 } |
| 1224 } | 1233 } |
| 1225 if (v->fFirstEdgeBelow) { | 1234 if (v->fFirstEdgeBelow) { |
| 1226 if (!v->fFirstEdgeAbove) { | 1235 if (!v->fFirstEdgeAbove) { |
| 1227 if (leftPoly && leftPoly == rightPoly) { | 1236 if (leftPoly) { |
| 1228 // Split the poly. | 1237 if (leftPoly == rightPoly) { |
| 1229 if (leftPoly->fActive->fSide == Poly::kLeft_Side) { | 1238 if (leftPoly->fMonotones.fTail && |
| 1230 leftPoly = new_poly(&polys, leftEnclosingEdge->fTop, lef tPoly->fWinding, | 1239 leftPoly->fMonotones.fTail->fSide == Poly::kLeft_Sid e) { |
| 1231 alloc); | 1240 leftPoly = new_poly(&polys, leftPoly->lastVertex(), |
| 1232 leftPoly->addVertex(v, Poly::kRight_Side, alloc); | 1241 leftPoly->fWinding, alloc); |
| 1233 rightPoly->addVertex(v, Poly::kLeft_Side, alloc); | 1242 leftEnclosingEdge->fRightPoly = leftPoly; |
| 1234 leftEnclosingEdge->fRightPoly = leftPoly; | 1243 } else { |
| 1235 } else { | 1244 rightPoly = new_poly(&polys, rightPoly->lastVertex() , |
| 1236 rightPoly = new_poly(&polys, rightEnclosingEdge->fTop, r ightPoly->fWinding, | 1245 rightPoly->fWinding, alloc); |
| 1237 alloc); | 1246 rightEnclosingEdge->fLeftPoly = rightPoly; |
| 1238 rightPoly->addVertex(v, Poly::kLeft_Side, alloc); | 1247 } |
| 1239 leftPoly->addVertex(v, Poly::kRight_Side, alloc); | |
| 1240 rightEnclosingEdge->fLeftPoly = rightPoly; | |
| 1241 } | 1248 } |
| 1242 } else { | 1249 Edge* join = ALLOC_NEW(Edge, (leftPoly->lastVertex(), v, 1), alloc); |
| 1243 if (leftPoly) { | 1250 leftPoly->addEdge(join, Poly::kRight_Side, alloc); |
| 1244 leftPoly = leftPoly->addVertex(v, Poly::kRight_Side, all oc); | 1251 rightPoly->addEdge(join, Poly::kLeft_Side, alloc); |
| 1245 } | |
| 1246 if (rightPoly) { | |
| 1247 rightPoly = rightPoly->addVertex(v, Poly::kLeft_Side, al loc); | |
| 1248 } | |
| 1249 } | 1252 } |
| 1250 } | 1253 } |
| 1251 Edge* leftEdge = v->fFirstEdgeBelow; | 1254 Edge* leftEdge = v->fFirstEdgeBelow; |
| 1252 leftEdge->fLeftPoly = leftPoly; | 1255 leftEdge->fLeftPoly = leftPoly; |
| 1253 insert_edge(leftEdge, leftEnclosingEdge, &activeEdges); | 1256 insert_edge(leftEdge, leftEnclosingEdge, &activeEdges); |
| 1254 for (Edge* rightEdge = leftEdge->fNextEdgeBelow; rightEdge; | 1257 for (Edge* rightEdge = leftEdge->fNextEdgeBelow; rightEdge; |
| 1255 rightEdge = rightEdge->fNextEdgeBelow) { | 1258 rightEdge = rightEdge->fNextEdgeBelow) { |
| 1256 insert_edge(rightEdge, leftEdge, &activeEdges); | 1259 insert_edge(rightEdge, leftEdge, &activeEdges); |
| 1257 int winding = leftEdge->fLeftPoly ? leftEdge->fLeftPoly->fWindin g : 0; | 1260 int winding = leftEdge->fLeftPoly ? leftEdge->fLeftPoly->fWindin g : 0; |
| 1258 winding += leftEdge->fWinding; | 1261 winding += leftEdge->fWinding; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1433 } | 1436 } |
| 1434 } | 1437 } |
| 1435 int actualCount = static_cast<int>(vertsEnd - *verts); | 1438 int actualCount = static_cast<int>(vertsEnd - *verts); |
| 1436 SkASSERT(actualCount <= count); | 1439 SkASSERT(actualCount <= count); |
| 1437 SkASSERT(pointsEnd - points == actualCount); | 1440 SkASSERT(pointsEnd - points == actualCount); |
| 1438 delete[] points; | 1441 delete[] points; |
| 1439 return actualCount; | 1442 return actualCount; |
| 1440 } | 1443 } |
| 1441 | 1444 |
| 1442 } // namespace | 1445 } // namespace |
| OLD | NEW |