void QTessellatorPrivate::addEdges() { while (currentVertex < vertices.nPoints) { const Vertex *v = vertices.sorted[currentVertex]; if (v->y > y) break; if (v->flags & LineBeforeStarts) { // add new edge int start = vertices.prevPos(v); Edge e(vertices, start); int pos = scanline.findEdgePosition(e); QDEBUG() << " adding edge" << start << "at position" << pos; scanline.insert(pos, e); if (!mark_clever || !(v->flags & LineAfterEnds)) { if (pos > 0) scanline.edges[pos - 1]->mark = true; if (pos < scanline.size - 1) scanline.edges[pos + 1]->mark = true; } } if (v->flags & LineAfterStarts) { Edge e(vertices, vertices.position(v)); int pos = scanline.findEdgePosition(e); QDEBUG() << " adding edge" << vertices.position(v) << "at position" << pos; scanline.insert(pos, e); if (!mark_clever || !(v->flags & LineBeforeEnds)) { if (pos > 0) scanline.edges[pos - 1]->mark = true; if (pos < scanline.size - 1) scanline.edges[pos + 1]->mark = true; } } if (v->flags & LineAfterHorizontal) { int pos1 = scanline.findEdgePosition(v->x, v->y); const Vertex *next = vertices.next(v); Q_ASSERT(v->y == next->y); int pos2 = scanline.findEdgePosition(next->x, next->y); if (pos2 < pos1) qSwap(pos1, pos2); if (pos1 > 0) --pos1; if (pos2 == scanline.size) --pos2; //QDEBUG() << "marking horizontal edge from " << pos1 << "to" << pos2; scanline.markEdges(pos1, pos2); } ++currentVertex; } }
void QTessellatorPrivate::cancelCoincidingEdges() { Vertex **vv = vertices.sorted; QCoincidingEdge *tl = 0; int tlSize = 0; for (int i = 0; i < vertices.nPoints - 1; ++i) { Vertex *v = vv[i]; int testListSize = 0; while (i < vertices.nPoints - 1) { Vertex *n = vv[i]; if (v->x != n->x || v->y != n->y) break; if (testListSize > tlSize - 2) { tlSize = qMax(tlSize*2, 16); tl = q_check_ptr((QCoincidingEdge *)realloc(tl, tlSize*sizeof(QCoincidingEdge))); } if (n->flags & (LineBeforeStarts|LineBeforeHorizontal)) { tl[testListSize].start = n; tl[testListSize].end = vertices.prev(n); tl[testListSize].used = false; tl[testListSize].before = true; ++testListSize; } if (n->flags & (LineAfterStarts|LineAfterHorizontal)) { tl[testListSize].start = n; tl[testListSize].end = vertices.next(n); tl[testListSize].used = false; tl[testListSize].before = false; ++testListSize; } ++i; } if (!testListSize) continue; qSort(tl, tl + testListSize); for (int j = 0; j < testListSize; ++j) { if (tl[j].used) continue; for (int k = j + 1; k < testListSize; ++k) { if (tl[j].end->x != tl[k].end->x || tl[j].end->y != tl[k].end->y || tl[k].used) break; if (!winding || tl[j].before != tl[k].before) { cancelEdges(tl[j], tl[k]); break; } ++k; } ++j; } } free(tl); }