static void PrintVertexPtrs(size_t numPts, VertexPtr *vp, Vertex *vtBase) { DebugPrintf("\nSorted Vertices:\n"); for (size_t i = 0; i < numPts; i++) { Vertex *e0, *e1; Vertex *vt = vp[i].vt; Vertex::VertexType type = vt->classify(&e0, &e1); DebugPrintf("%2d: %2d: (%.7g, %.7g), prev(%d), next(%d), " "type(%s), left(%d), right(%d)", i, vt - vtBase, vt->point().fX, vt->point().fY, vt->prev() - vtBase, vt->next() - vtBase, GetVertexTypeString(type), e0 - vtBase, e1 - vtBase); Trapezoid *trap[2]; vt->trapezoids(trap, trap+1); for (int j = 0; j < 2; ++j) { if (trap[j] != NULL) { DebugPrintf(", trap(L=%d, R=%d, B=%d)", trap[j]->left() - vtBase, trap[j]->right() - vtBase, trap[j]->bottom() - vtBase); } } DebugPrintf("\n"); } }
// Enhance the polygon with trapezoids. bool ConvertPointsToVertices(size_t numPts, const SkPoint *pts, Vertex *vta) { DebugPrintf("ConvertPointsToVertices()\n"); // Clear everything. DebugPrintf("Zeroing vertices\n"); sk_bzero(vta, numPts * sizeof(*vta)); // Initialize vertices. DebugPrintf("Initializing vertices\n"); SetVertexPoints(numPts, pts, vta); InitializeVertexTopology(numPts, vta); PrintVertices(numPts, vta); SkTDArray<VertexPtr> vtptr; vtptr.setCount(numPts); for (int i = numPts; i-- != 0;) vtptr[i].vt = vta + i; PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta); DebugPrintf("Sorting vertrap ptr array [%d] %p %p\n", vtptr.count(), &vtptr[0], &vtptr[vtptr.count() - 1] ); // SkTHeapSort(vtptr.begin(), vtptr.count()); BubbleSort(vtptr.begin(), vtptr.count()); DebugPrintf("Done sorting\n"); PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta); DebugPrintf("Traversing sorted vertrap ptrs\n"); ActiveTrapezoids incompleteTrapezoids; for (VertexPtr *vtpp = vtptr.begin(); vtpp < vtptr.end(); ++vtpp) { DebugPrintf("%d: sorted vertrap %d\n", vtpp - vtptr.begin(), vtpp->vt - vta); Vertex *vt = vtpp->vt; Vertex *e0, *e1; Trapezoid *t; switch (vt->classify(&e0, &e1)) { case Vertex::MONOTONE: monotone: DebugPrintf("MONOTONE %d %d\n", e0 - vta, e1 - vta); // We should find one edge. t = incompleteTrapezoids.getTrapezoidWithEdge(e0); if (t == NULL) { // One of the edges is flat. DebugPrintf("Monotone: cannot find a trapezoid with e0: " "trying convex\n"); goto convex; } t->setBottom(vt); // This trapezoid is now complete. incompleteTrapezoids.remove(t); if (e0 == t->left()) // Replace the left edge. incompleteTrapezoids.insertNewTrapezoid(vt, e1, t->right()); else // Replace the right edge. incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), e1); break; case Vertex::CONVEX: // Start of a new trapezoid. convex: // We don't expect to find any edges. DebugPrintf("CONVEX %d %d\n", e0 - vta, e1 - vta); if (incompleteTrapezoids.withinActiveTrapezoid( vt->point(), &t)) { // Complete trapezoid. SkASSERT(t != NULL); t->setBottom(vt); incompleteTrapezoids.remove(t); // Introduce two new trapezoids. incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), e0); incompleteTrapezoids.insertNewTrapezoid(vt, e1, t->right()); } else { // Insert a new trapezoid. incompleteTrapezoids.insertNewTrapezoid(vt, e0, e1); } break; case Vertex::CONCAVE: // End of a trapezoid. DebugPrintf("CONCAVE %d %d\n", e0 - vta, e1 - vta); // We should find two edges. t = incompleteTrapezoids.getTrapezoidWithEdge(e0); if (t == NULL) { DebugPrintf("Concave: cannot find a trapezoid with e0: " " trying monotone\n"); goto monotone; } SkASSERT(t != NULL); if (e0 == t->left() && e1 == t->right()) { DebugPrintf( "Concave edges belong to the same trapezoid.\n"); // Edges belong to the same trapezoid. // Complete trapezoid & transfer it from the active list. t->setBottom(vt); incompleteTrapezoids.remove(t); } else { // Edges belong to different trapezoids DebugPrintf( "Concave edges belong to different trapezoids.\n"); // Complete left and right trapezoids. Trapezoid *s = incompleteTrapezoids.getTrapezoidWithEdge( e1); if (s == NULL) { DebugPrintf( "Concave: cannot find a trapezoid with e1: " " trying monotone\n"); goto monotone; } t->setBottom(vt); s->setBottom(vt); incompleteTrapezoids.remove(t); incompleteTrapezoids.remove(s); // Merge the two trapezoids into one below this vertex. incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), s->right()); } break; } } RemoveDegenerateTrapezoids(numPts, vta); DebugPrintf("Done making trapezoids\n"); PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta); size_t k = incompleteTrapezoids.count(); if (k > 0) { FailureMessage("%d incomplete trapezoids\n", k); return false; } return true; }