Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2009 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 ////////////////////////////////////////////////////////////////////////////////
     12 // This is an implementation of the triangulation algorithm described by Alain
     13 // Fournier and Delfin Montuno, in "Triangulating Simple Polygons and Equivalent
     14 // Problems", in the ACM Transactions on Graphics, vol. 3, no. 2, April 1984,
     15 // pp. 153-174.
     16 //
     17 // No new vertices are created in the triangulation: triangles are constructed
     18 // only from the points in the original polygon, so there is no possibility for
     19 // cracks to develop from finite precision arithmetic.
     20 ////////////////////////////////////////////////////////////////////////////////
     21 
     22 // TODO:
     23 // - RemoveDegenerateTrapezoids() was added to make the code robust, but it
     24 //   unfortunately introduces T-vertices. Make it robust without T-vertices.
     25 // - It should be easy enough to detect whether the outer contour is right- or
     26 //   left-handed by looking at the top vertex, which is available in the
     27 //   pre-sort during trapezoidization. Use this information in angleIsConvex()
     28 //   to allowed either handedness outer contour. In either case, though, holes
     29 //   need to have the opposite orientation.
     30 // - SkTHeapSort was broken, so I wrote a bubble sort so that I could make other
     31 //   things work. Use SkQSort() instead.
     32 // - The ActiveTrapezoid array does a linear search which is O(n) inefficient.
     33 //   Use SkSearch to implement O(log n) binary search and insertion sort.
     34 // - There is no need to use SkTDArray for everything. Use SkAutoTMalloc for
     35 //   everything else.
     36 
     37 #include "SkTDArray.h"
     38 #include "SkGeometry.h"
     39 #include "SkTSort.h"
     40 
     41 // This is used to prevent runaway code bugs, and can probably be removed after
     42 // the code has been proven robust.
     43 #define kMaxCount 1000
     44 
     45 #define DEBUG
     46 #ifdef DEBUG
     47 //------------------------------------------------------------------------------
     48 // Debugging support
     49 //------------------------------------------------------------------------------
     50 
     51 #include <cstdio>
     52 #include <stdarg.h>
     53 
     54 static int gDebugLevel = 0;   // This enables debug reporting.
     55 
     56 static void DebugPrintf(const char *format, ...) {
     57     if (gDebugLevel > 0) {
     58         va_list ap;
     59         va_start(ap, format);
     60         vprintf(format, ap);
     61         va_end(ap);
     62     }
     63 }
     64 
     65 static void FailureMessage(const char *format, ...) {
     66     if (1) {
     67         printf("FAILURE: ");
     68         va_list ap;
     69         va_start(ap, format);
     70         vprintf(format, ap);
     71         va_end(ap);
     72     }
     73 }
     74 #else  // !DEBUG
     75 inline void DebugPrintf(const char *format, ...) {}
     76 inline void FailureMessage(const char *format, ...) {}
     77 #endif  // DEBUG
     78 
     79 
     80 // Forward declaration.
     81 class Vertex;
     82 
     83 
     84 //------------------------------------------------------------------------------
     85 // The Trapezoid (actually, up to two of them) is embedded into a Vertex, whose
     86 // point() provides the top of the Trapezoid, whereas the bottom, and the left
     87 // and right edges, are stored in the Trapezoid. The edges are represented by
     88 // their tail point; the head is the successive point modulo the number of
     89 // points in the polygon. Only the Y coordinate of the top and bottom are
     90 // relevant.
     91 //------------------------------------------------------------------------------
     92 class Trapezoid {
     93 public:
     94     const Vertex* left()   const    { return fLeft;   }
     95     const Vertex* right()  const    { return fRight;  }
     96     const Vertex* bottom() const    { return fBottom; }
     97     Vertex* left()                  { return fLeft;   }
     98     Vertex* right()                 { return fRight;  }
     99     Vertex* bottom()                { return fBottom; }
    100     void   setLeft(Vertex *left)    { fLeft   = left;   }
    101     void  setRight(Vertex *right)   { fRight  = right;  }
    102     void setBottom(Vertex *bottom)  { fBottom = bottom; }
    103     void nullify()                  { setBottom(NULL); }
    104 
    105     bool operator<(Trapezoid &t1)   { return compare(t1) < 0; }
    106     bool operator>(Trapezoid &t1)   { return compare(t1) > 0; }
    107 
    108 private:
    109     Vertex *fLeft, *fRight, *fBottom;
    110 
    111     // These return a number that is less than, equal to, or greater than zero
    112     // depending on whether the trapezoid or point is to the left, on, or to the
    113     // right.
    114     SkScalar compare(const Trapezoid &t1) const;
    115     SkScalar compare(const SkPoint &p) const;
    116 };
    117 
    118 
    119 //------------------------------------------------------------------------------
    120 // The ActiveTrapezoids are a sorted list containing the currently active
    121 // trapezoids, i.e. those that have the top, left, and right, but still need the
    122 // bottom. This could use some optimization, to reduce search time from O(n) to
    123 // O(log n).
    124 //------------------------------------------------------------------------------
    125 class ActiveTrapezoids {
    126 public:
    127     ActiveTrapezoids() { fTrapezoids.setCount(0); }
    128 
    129     size_t count() const { return fTrapezoids.count(); }
    130 
    131     // Select an unused trapezoid from the Vertex vt, initialize it with the
    132     // left and right edges, and insert it into the sorted list.
    133     bool insertNewTrapezoid(Vertex *vt, Vertex *left, Vertex *right);
    134 
    135     // Remove the specified Trapezoids from the active list.
    136     void remove(Trapezoid *t);
    137 
    138     // Determine whether the given point lies within any active trapezoid, and
    139     // return a pointer to that Trapezoid.
    140     bool withinActiveTrapezoid(const SkPoint &pt, Trapezoid **tp);
    141 
    142     // Find an active trapezoid that contains the given edge.
    143     Trapezoid* getTrapezoidWithEdge(const Vertex *edge);
    144 
    145 private:
    146     // Insert the specified Trapezoid into the sorted list.
    147     void insert(Trapezoid *t);
    148 
    149     // The sorted list of active trapezoids. This is O(n), and would benefit
    150     // a 2-3 tree o achieve O(log n).
    151     SkTDArray<Trapezoid*> fTrapezoids;  // Fournier suggests a 2-3 tree instead.
    152 };
    153 
    154 
    155 //------------------------------------------------------------------------------
    156 // The Vertex is used to communicate information between the various phases of
    157 // triangulation.
    158 //------------------------------------------------------------------------------
    159 class Vertex {
    160 public:
    161     enum VertexType { MONOTONE, CONVEX, CONCAVE };
    162 
    163     Trapezoid fTrap0;
    164     Trapezoid fTrap1;
    165 
    166     const SkPoint &point() const        { return fPoint; }
    167     void setPoint(const SkPoint &point) { fPoint = point; }
    168 
    169     // The next and previous vertices around the polygon.
    170     Vertex *next()                      { return fNext; }
    171     Vertex *prev()                      { return fPrev; }
    172     const Vertex *next() const          { return fNext; }
    173     const Vertex *prev() const          { return fPrev; }
    174     void setNext(Vertex *next)          { fNext = next; }
    175     void setPrev(Vertex *prev)          { fPrev = prev; }
    176 
    177     void setDone(bool done)             { fDone = done; }
    178     bool done() const                   { return fDone; }
    179 
    180     // Trapezoid accessors return non-null for any complete trapezoids.
    181     void trapezoids(Trapezoid **trap0, Trapezoid **trap1) {
    182         *trap0 = (fTrap0.bottom() != NULL) ? &fTrap0 : NULL;
    183         *trap1 = (fTrap1.bottom() != NULL) ? &fTrap1 : NULL;
    184     }
    185 
    186     // Eliminate a trapezoid.
    187     void nullifyTrapezoid() {
    188         if (fTrap1.bottom() != NULL) {
    189             DebugPrintf("Unexpected non-null second trapezoid.\n");
    190             fTrap1.nullify();
    191             return;
    192         }
    193         fTrap0.nullify();
    194     }
    195 
    196     // Determine whether the edge specified by this Vertex shares the given top
    197     // and bottom.
    198     bool shareEdge(Vertex *top, Vertex *bottom);
    199 
    200     // Determines whether the angle specified by { prev, this, next } is convex.
    201     // Note that collinear is considered to be convex.
    202     bool angleIsConvex();
    203 
    204     // Remove this Vertex from the { prev, next } linked list.
    205     void delink() {
    206         Vertex *p = prev(),
    207                *n = next();
    208         p->setNext(n);
    209         n->setPrev(p);
    210     }
    211 
    212     // Return a number that is less than, equal to, or greater than zero
    213     // depending on whether the point is to the left, on, or to the right of the
    214     // edge that has this Vertex as a base.
    215     SkScalar compare(const SkPoint &pt) const;
    216 
    217     // Classify the vertex, and return its sorted edges.
    218     VertexType classify(Vertex **e0, Vertex **e1);
    219 
    220     // This helps determine unimonotonicity.
    221     Vertex *diagonal();
    222 
    223 private:
    224     SkPoint fPoint;
    225     Vertex *fNext;
    226     Vertex *fPrev;
    227     bool fDone;
    228 };
    229 
    230 
    231 bool Vertex::angleIsConvex() {
    232     SkPoint vPrev = prev()->point() - point(),
    233             vNext = next()->point() - point();
    234     // TODO(turk): There might be overflow in fixed-point.
    235     return SkPoint::CrossProduct(vNext, vPrev) >= 0;
    236 }
    237 
    238 
    239 bool Vertex::shareEdge(Vertex *top, Vertex *bottom) {
    240     return (((this == top)    && (this->next() == bottom)) ||
    241             ((this == bottom) && (this->next() == top)));
    242 }
    243 
    244 
    245 SkScalar Vertex::compare(const SkPoint &pt) const  {
    246     SkPoint ve = next()->point() - point(),
    247             vp = pt              - point();
    248     SkScalar d;
    249     if (ve.fY == 0) {
    250         // Return twice the distance to the center of the horizontal edge.
    251         d = ve.fX + pt.fX - next()->point().fX;
    252     } else {
    253         // Return the distance to the edge, scaled by the edge length.
    254         d = SkPoint::CrossProduct(ve, vp);
    255         if (ve.fY > 0) d = -d;
    256     }
    257     return d;
    258 }
    259 
    260 
    261 SkScalar Trapezoid::compare(const SkPoint &pt) const {
    262     SkScalar d = left()->compare(pt);
    263     if (d <= 0)
    264         return d;   // Left of the left edge.
    265     d = right()->compare(pt);
    266     if (d >= 0)
    267         return d;   // Right of the right edge.
    268     return 0;       // Somewhere between the left and the right edges.
    269 }
    270 
    271 
    272 
    273 SkScalar Trapezoid::compare(const Trapezoid &t1) const {
    274 #if 1
    275     SkScalar d = left()->compare(t1.left()->point());
    276     if (d == 0)
    277         d = right()->compare(t1.right()->point());
    278     return d;
    279 #else
    280     SkScalar dl =  left()->compare( t1.left()->point()),
    281              dr = right()->compare(t1.right()->point());
    282     if (dl < 0 && dr < 0)
    283         return dr;
    284     if (dl > 0 && dr > 0)
    285         return dl;
    286     return 0;
    287 #endif
    288 }
    289 
    290 
    291 Trapezoid* ActiveTrapezoids::getTrapezoidWithEdge(const Vertex *edge) {
    292     DebugPrintf("Entering getTrapezoidWithEdge(): looking through %d\n",
    293            fTrapezoids.count());
    294     DebugPrintf("trying to find %p: ", edge);
    295     Trapezoid **tp;
    296     for (tp = fTrapezoids.begin(); tp < fTrapezoids.end(); ++tp) {
    297         SkASSERT(tp != NULL);
    298         SkASSERT(*tp != NULL);
    299         DebugPrintf("%p and %p, ", (**tp).left(), (**tp).right());
    300         if ((**tp).left() == edge || (**tp).right() == edge) {
    301             DebugPrintf("\ngetTrapezoidWithEdge found the trapezoid\n");
    302             return *tp;
    303         }
    304     }
    305     DebugPrintf("getTrapezoidWithEdge found no trapezoid\n");
    306     return NULL;
    307 }
    308 
    309 
    310 bool ActiveTrapezoids::insertNewTrapezoid(Vertex *vt,
    311                                           Vertex *left,
    312                                           Vertex *right) {
    313     DebugPrintf("Inserting a trapezoid...");
    314     if (vt->fTrap0.left() == NULL && vt->fTrap0.right() == NULL) {
    315         vt->fTrap0.setLeft(left);
    316         vt->fTrap0.setRight(right);
    317         insert(&vt->fTrap0);
    318     } else if (vt->fTrap1.left() == NULL && vt->fTrap1.right() == NULL) {
    319         DebugPrintf("a second one...");
    320         vt->fTrap1.setLeft(left);
    321         vt->fTrap1.setRight(right);
    322         if (vt->fTrap1 < vt->fTrap0) {  // Keep trapezoids sorted.
    323             remove(&vt->fTrap0);
    324             Trapezoid t = vt->fTrap0;
    325             vt->fTrap0 = vt->fTrap1;
    326             vt->fTrap1 = t;
    327             insert(&vt->fTrap0);
    328         }
    329         insert(&vt->fTrap1);
    330     } else {
    331         FailureMessage("More than 2 trapezoids requested for a vertex\n");
    332         return false;
    333     }
    334     DebugPrintf(" done. %d incomplete trapezoids\n", fTrapezoids.count());
    335     return true;
    336 }
    337 
    338 
    339 void ActiveTrapezoids::insert(Trapezoid *t) {
    340     Trapezoid **tp;
    341     for (tp = fTrapezoids.begin(); tp < fTrapezoids.end(); ++tp)
    342         if (**tp > *t)
    343             break;
    344     fTrapezoids.insert(tp - fTrapezoids.begin(), 1, &t);
    345     // SHOULD VERIFY THAT ALL TRAPEZOIDS ARE PROPERLY SORTED
    346 }
    347 
    348 
    349 void ActiveTrapezoids::remove(Trapezoid *t) {
    350     DebugPrintf("Removing a trapezoid...");
    351     for (Trapezoid **tp = fTrapezoids.begin(); tp < fTrapezoids.end(); ++tp) {
    352         if (*tp == t) {
    353             fTrapezoids.remove(tp - fTrapezoids.begin());
    354             DebugPrintf(" done.\n");
    355             return;
    356         }
    357     }
    358     DebugPrintf(" Arghh! Panic!\n");
    359     SkASSERT(t == 0);   // Cannot find t in active trapezoid list.
    360 }
    361 
    362 
    363 bool ActiveTrapezoids::withinActiveTrapezoid(const SkPoint &pt,
    364                                              Trapezoid **trap) {
    365     DebugPrintf("Entering withinActiveTrapezoid()\n");
    366     // This is where a good search data structure would be helpful.
    367     Trapezoid **t;
    368     for (t = fTrapezoids.begin(); t < fTrapezoids.end(); ++t) {
    369         if ((**t).left()->compare(pt) <= 0) {
    370             // The point is to the left of the left edge of this trapezoid.
    371             DebugPrintf("withinActiveTrapezoid: Before a trapezoid\n");
    372             *trap = *t;     // Return the place where a new trapezoid would go.
    373 // We have a bug with the sorting -- look through everything.
    374             continue;
    375 //             return false;   // Outside all trapezoids, since they are sorted.
    376         }
    377         // The point is to the right of the left edge of this trapezoid.
    378 
    379         if ((**t).right()->compare(pt) < 0) {
    380             // The point is to the left of the right edge.
    381             DebugPrintf("withinActiveTrapezoid: Within an Active Trapezoid\n");
    382             *trap = *t;
    383             return true;
    384         }
    385     }
    386 
    387     // The point is to the right of all trapezoids.
    388     DebugPrintf("withinActiveTrapezoid: After all trapezoids\n");
    389     *trap = NULL;
    390     return false;
    391 }
    392 
    393 
    394 Vertex* Vertex::diagonal() {
    395     Vertex *diag = NULL;
    396     if (fTrap0.bottom() != NULL) {
    397         if (!fTrap0.left() ->shareEdge(this, fTrap0.bottom()) &&
    398             !fTrap0.right()->shareEdge(this, fTrap0.bottom())
    399         ) {
    400             diag = fTrap0.bottom();
    401             fTrap0 = fTrap1;
    402             fTrap1.nullify();
    403         } else if (fTrap1.bottom() != NULL &&
    404                   !fTrap1.left() ->shareEdge(this, fTrap1.bottom()) &&
    405                   !fTrap1.right()->shareEdge(this, fTrap1.bottom())
    406         ) {
    407             diag = fTrap1.bottom();
    408             fTrap1.nullify();
    409         }
    410     }
    411     return diag;
    412 }
    413 
    414 
    415 // We use this to sort the edges vertically for a scan-conversion type of
    416 // operation.
    417 class VertexPtr {
    418 public:
    419     Vertex *vt;
    420 };
    421 
    422 
    423 bool operator<(VertexPtr &v0, VertexPtr &v1) {
    424     // DebugPrintf("< %p %p\n", &v0, &v1);
    425     if (v0.vt->point().fY < v1.vt->point().fY)  return true;
    426     if (v0.vt->point().fY > v1.vt->point().fY)  return false;
    427     if (v0.vt->point().fX < v1.vt->point().fX)  return true;
    428     else                                        return false;
    429 }
    430 
    431 
    432 bool operator>(VertexPtr &v0, VertexPtr &v1) {
    433     // DebugPrintf("> %p %p\n", &v0, &v1);
    434     if (v0.vt->point().fY > v1.vt->point().fY)  return true;
    435     if (v0.vt->point().fY < v1.vt->point().fY)  return false;
    436     if (v0.vt->point().fX > v1.vt->point().fX)  return true;
    437     else                                        return false;
    438 }
    439 
    440 
    441 static void SetVertexPoints(size_t numPts, const SkPoint *pt, Vertex *vt) {
    442     for (; numPts-- != 0; ++pt, ++vt)
    443         vt->setPoint(*pt);
    444 }
    445 
    446 
    447 static void InitializeVertexTopology(size_t numPts, Vertex *v1) {
    448     Vertex *v0 = v1 + numPts - 1, *v_1 = v0 - 1;
    449     for (; numPts-- != 0; v_1 = v0, v0 = v1++) {
    450         v0->setPrev(v_1);
    451         v0->setNext(v1);
    452     }
    453 }
    454 
    455 Vertex::VertexType Vertex::classify(Vertex **e0, Vertex **e1) {
    456     VertexType type;
    457     SkPoint vPrev, vNext;
    458     vPrev.fX = prev()->point().fX - point().fX;
    459     vPrev.fY = prev()->point().fY - point().fY;
    460     vNext.fX = next()->point().fX - point().fX;
    461     vNext.fY = next()->point().fY - point().fY;
    462 
    463     // This can probably be simplified, but there are enough potential bugs,
    464     // we will leave it expanded until all cases are tested appropriately.
    465     if (vPrev.fY < 0) {
    466         if (vNext.fY > 0) {
    467             // Prev comes from above, Next goes below.
    468             type = MONOTONE;
    469             *e0 = prev();
    470             *e1 = this;
    471         } else if (vNext.fY < 0) {
    472             // The are both above: sort so that e0 is on the left.
    473             type = CONCAVE;
    474             if (SkPoint::CrossProduct(vPrev, vNext) <= 0) {
    475                 *e0 = this;
    476                 *e1 = prev();
    477             } else {
    478                 *e0 = prev();
    479                 *e1 = this;
    480             }
    481         } else {
    482             DebugPrintf("### py < 0, ny = 0\n");
    483             if (vNext.fX < 0) {
    484                 type = CONCAVE;
    485                 *e0 = this;     // flat to the left
    486                 *e1 = prev();   // concave on the right
    487             } else {
    488                 type = CONCAVE;
    489                 *e0 = prev();   // concave to the left
    490                 *e1 = this;     // flat to the right
    491             }
    492         }
    493     } else if (vPrev.fY > 0) {
    494         if (vNext.fY < 0) {
    495             // Next comes from above, Prev goes below.
    496             type = MONOTONE;
    497             *e0 = this;
    498             *e1 = prev();
    499         } else if (vNext.fY > 0) {
    500             // They are both below: sort so that e0 is on the left.
    501             type = CONVEX;
    502             if (SkPoint::CrossProduct(vPrev, vNext) <= 0) {
    503                 *e0 = prev();
    504                 *e1 = this;
    505             } else {
    506                 *e0 = this;
    507                 *e1 = prev();
    508             }
    509         } else {
    510             DebugPrintf("### py > 0, ny = 0\n");
    511             if (vNext.fX < 0) {
    512                 type = MONOTONE;
    513                 *e0 = this;     // flat to the left
    514                 *e1 = prev();   // convex on the right - try monotone first
    515             } else {
    516                 type = MONOTONE;
    517                 *e0 = prev();   // convex to the left - try monotone first
    518                 *e1 = this;     // flat to the right
    519             }
    520         }
    521     } else {  // vPrev.fY == 0
    522         if (vNext.fY < 0) {
    523             DebugPrintf("### py = 0, ny < 0\n");
    524             if (vPrev.fX < 0) {
    525                 type = CONCAVE;
    526                 *e0 = prev();   // flat to the left
    527                 *e1 = this;     // concave on the right
    528             } else {
    529                 type = CONCAVE;
    530                 *e0 = this;     // concave on the left - defer
    531                 *e1 = prev();   // flat to the right
    532             }
    533         } else if (vNext.fY > 0) {
    534             DebugPrintf("### py = 0, ny > 0\n");
    535             if (vPrev.fX < 0) {
    536                 type = MONOTONE;
    537                 *e0 = prev();   // flat to the left
    538                 *e1 = this;     // convex on the right - try monotone first
    539             } else {
    540                 type = MONOTONE;
    541                 *e0 = this;     // convex to the left - try monotone first
    542                 *e1 = prev();   // flat to the right
    543             }
    544         } else {
    545             DebugPrintf("### py = 0, ny = 0\n");
    546             // First we try concave, then monotone, then convex.
    547             if (vPrev.fX <= vNext.fX) {
    548                 type = CONCAVE;
    549                 *e0 = prev();   // flat to the left
    550                 *e1 = this;     // flat to the right
    551             } else {
    552                 type = CONCAVE;
    553                 *e0 = this;     // flat to the left
    554                 *e1 = prev();   // flat to the right
    555             }
    556         }
    557     }
    558     return type;
    559 }
    560 
    561 
    562 #ifdef DEBUG
    563 static const char* GetVertexTypeString(Vertex::VertexType type) {
    564     const char *typeStr = NULL;
    565     switch (type) {
    566         case Vertex::MONOTONE:
    567             typeStr = "MONOTONE";
    568             break;
    569         case Vertex::CONCAVE:
    570             typeStr = "CONCAVE";
    571             break;
    572         case Vertex::CONVEX:
    573             typeStr = "CONVEX";
    574             break;
    575     }
    576     return typeStr;
    577 }
    578 
    579 
    580 static void PrintVertices(size_t numPts, Vertex *vt) {
    581     DebugPrintf("\nVertices:\n");
    582     for (size_t i = 0; i < numPts; i++) {
    583         Vertex *e0, *e1;
    584         Vertex::VertexType type = vt[i].classify(&e0, &e1);
    585         DebugPrintf("%2d: (%.7g, %.7g), prev(%d), next(%d), "
    586                     "type(%s), left(%d), right(%d)",
    587                     i, vt[i].point().fX, vt[i].point().fY,
    588                     vt[i].prev() - vt, vt[i].next() - vt,
    589                     GetVertexTypeString(type), e0 - vt, e1 - vt);
    590         Trapezoid *trap[2];
    591         vt[i].trapezoids(trap, trap+1);
    592         for (int j = 0; j < 2; ++j) {
    593             if (trap[j] != NULL) {
    594                 DebugPrintf(", trap(L=%d, R=%d, B=%d)",
    595                             trap[j]->left()   - vt,
    596                             trap[j]->right()  - vt,
    597                             trap[j]->bottom() - vt);
    598             }
    599         }
    600         DebugPrintf("\n");
    601     }
    602 }
    603 
    604 
    605 static void PrintVertexPtrs(size_t numPts, VertexPtr *vp, Vertex *vtBase) {
    606     DebugPrintf("\nSorted Vertices:\n");
    607     for (size_t i = 0; i < numPts; i++) {
    608         Vertex *e0, *e1;
    609         Vertex *vt = vp[i].vt;
    610         Vertex::VertexType type = vt->classify(&e0, &e1);
    611         DebugPrintf("%2d: %2d: (%.7g, %.7g), prev(%d), next(%d), "
    612                     "type(%s), left(%d), right(%d)",
    613                     i, vt - vtBase, vt->point().fX, vt->point().fY,
    614                     vt->prev() - vtBase, vt->next() - vtBase,
    615                     GetVertexTypeString(type), e0 - vtBase, e1 - vtBase);
    616         Trapezoid *trap[2];
    617         vt->trapezoids(trap, trap+1);
    618         for (int j = 0; j < 2; ++j) {
    619             if (trap[j] != NULL) {
    620                 DebugPrintf(", trap(L=%d, R=%d, B=%d)",
    621                             trap[j]->left()   - vtBase,
    622                             trap[j]->right()  - vtBase,
    623                             trap[j]->bottom() - vtBase);
    624             }
    625         }
    626         DebugPrintf("\n");
    627     }
    628 }
    629 #else  // !DEBUG
    630 inline void PrintVertices(size_t numPts, Vertex *vt) {}
    631 inline void PrintVertexPtrs(size_t numPts, VertexPtr *vp, Vertex *vtBase) {}
    632 #endif  // !DEBUG
    633 
    634 
    635 // SkTHeapSort is broken, so we use a bubble sort in the meantime.
    636 template <typename T>
    637 void BubbleSort(T *array, size_t count) {
    638     bool sorted;
    639     size_t count_1 = count - 1;
    640     do {
    641         sorted = true;
    642         for (size_t i = 0; i < count_1; ++i) {
    643             if (array[i + 1] < array[i]) {
    644                 T t = array[i];
    645                 array[i] = array[i + 1];
    646                 array[i + 1] = t;
    647                 sorted = false;
    648             }
    649         }
    650     } while (!sorted);
    651 }
    652 
    653 
    654 // Remove zero-height trapezoids.
    655 static void RemoveDegenerateTrapezoids(size_t numVt, Vertex *vt) {
    656     for (; numVt-- != 0; vt++) {
    657         Trapezoid *traps[2];
    658         vt->trapezoids(traps, traps+1);
    659         if (traps[1] != NULL &&
    660                 vt->point().fY >= traps[1]->bottom()->point().fY) {
    661             traps[1]->nullify();
    662             traps[1] = NULL;
    663         }
    664         if (traps[0] != NULL &&
    665                 vt->point().fY >= traps[0]->bottom()->point().fY) {
    666             if (traps[1] != NULL) {
    667                 *traps[0] = *traps[1];
    668                 traps[1]->nullify();
    669             } else {
    670                 traps[0]->nullify();
    671             }
    672         }
    673     }
    674 }
    675 
    676 
    677 // Enhance the polygon with trapezoids.
    678 bool ConvertPointsToVertices(size_t numPts, const SkPoint *pts, Vertex *vta) {
    679     DebugPrintf("ConvertPointsToVertices()\n");
    680 
    681     // Clear everything.
    682     DebugPrintf("Zeroing vertices\n");
    683     sk_bzero(vta, numPts * sizeof(*vta));
    684 
    685     // Initialize vertices.
    686     DebugPrintf("Initializing vertices\n");
    687     SetVertexPoints(numPts, pts, vta);
    688     InitializeVertexTopology(numPts, vta);
    689 
    690     PrintVertices(numPts, vta);
    691 
    692     SkTDArray<VertexPtr> vtptr;
    693     vtptr.setCount(numPts);
    694     for (int i = numPts; i-- != 0;)
    695         vtptr[i].vt = vta + i;
    696     PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);
    697     DebugPrintf("Sorting vertrap ptr array [%d] %p %p\n", vtptr.count(),
    698         &vtptr[0], &vtptr[vtptr.count() - 1]
    699     );
    700 //  SkTHeapSort(vtptr.begin(), vtptr.count());
    701     BubbleSort(vtptr.begin(), vtptr.count());
    702     DebugPrintf("Done sorting\n");
    703     PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);
    704 
    705     DebugPrintf("Traversing sorted vertrap ptrs\n");
    706     ActiveTrapezoids incompleteTrapezoids;
    707     for (VertexPtr *vtpp = vtptr.begin(); vtpp < vtptr.end(); ++vtpp) {
    708         DebugPrintf("%d: sorted vertrap %d\n",
    709                     vtpp - vtptr.begin(), vtpp->vt - vta);
    710         Vertex *vt = vtpp->vt;
    711         Vertex *e0, *e1;
    712         Trapezoid *t;
    713         switch (vt->classify(&e0, &e1)) {
    714             case Vertex::MONOTONE:
    715             monotone:
    716                 DebugPrintf("MONOTONE %d %d\n", e0 - vta, e1 - vta);
    717                 // We should find one edge.
    718                 t = incompleteTrapezoids.getTrapezoidWithEdge(e0);
    719                 if (t == NULL) {      // One of the edges is flat.
    720                     DebugPrintf("Monotone: cannot find a trapezoid with e0: "
    721                                 "trying convex\n");
    722                     goto convex;
    723                 }
    724                 t->setBottom(vt);     // This trapezoid is now complete.
    725                 incompleteTrapezoids.remove(t);
    726 
    727                 if (e0 == t->left())  // Replace the left edge.
    728                     incompleteTrapezoids.insertNewTrapezoid(vt, e1, t->right());
    729                 else                  // Replace the right edge.
    730                     incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), e1);
    731                 break;
    732 
    733             case Vertex::CONVEX:      // Start of a new trapezoid.
    734             convex:
    735                 // We don't expect to find any edges.
    736                 DebugPrintf("CONVEX %d %d\n", e0 - vta, e1 - vta);
    737                 if (incompleteTrapezoids.withinActiveTrapezoid(
    738                         vt->point(), &t)) {
    739                     // Complete trapezoid.
    740                     SkASSERT(t != NULL);
    741                     t->setBottom(vt);
    742                     incompleteTrapezoids.remove(t);
    743                     // Introduce two new trapezoids.
    744                     incompleteTrapezoids.insertNewTrapezoid(vt, t->left(), e0);
    745                     incompleteTrapezoids.insertNewTrapezoid(vt, e1, t->right());
    746                 } else {
    747                     // Insert a new trapezoid.
    748                     incompleteTrapezoids.insertNewTrapezoid(vt, e0, e1);
    749                 }
    750                 break;
    751 
    752             case Vertex::CONCAVE:   // End of a trapezoid.
    753                 DebugPrintf("CONCAVE %d %d\n", e0 - vta, e1 - vta);
    754                 // We should find two edges.
    755                 t = incompleteTrapezoids.getTrapezoidWithEdge(e0);
    756                 if (t == NULL) {
    757                     DebugPrintf("Concave: cannot find a trapezoid with e0: "
    758                                 " trying monotone\n");
    759                     goto monotone;
    760                 }
    761                 SkASSERT(t != NULL);
    762                 if (e0 == t->left() && e1 == t->right()) {
    763                     DebugPrintf(
    764                             "Concave edges belong to the same trapezoid.\n");
    765                     // Edges belong to the same trapezoid.
    766                     // Complete trapezoid & transfer it from the active list.
    767                     t->setBottom(vt);
    768                     incompleteTrapezoids.remove(t);
    769                 } else {  // Edges belong to different trapezoids
    770                     DebugPrintf(
    771                             "Concave edges belong to different trapezoids.\n");
    772                     // Complete left and right trapezoids.
    773                     Trapezoid *s = incompleteTrapezoids.getTrapezoidWithEdge(
    774                                                                             e1);
    775                     if (s == NULL) {
    776                         DebugPrintf(
    777                                 "Concave: cannot find a trapezoid with e1: "
    778                                 " trying monotone\n");
    779                         goto monotone;
    780                     }
    781                     t->setBottom(vt);
    782                     s->setBottom(vt);
    783                     incompleteTrapezoids.remove(t);
    784                     incompleteTrapezoids.remove(s);
    785 
    786                     // Merge the two trapezoids into one below this vertex.
    787                     incompleteTrapezoids.insertNewTrapezoid(vt, t->left(),
    788                                                                 s->right());
    789                 }
    790                 break;
    791         }
    792     }
    793 
    794     RemoveDegenerateTrapezoids(numPts, vta);
    795 
    796     DebugPrintf("Done making trapezoids\n");
    797     PrintVertexPtrs(vtptr.count(), vtptr.begin(), vta);
    798 
    799     size_t k = incompleteTrapezoids.count();
    800     if (k > 0) {
    801         FailureMessage("%d incomplete trapezoids\n", k);
    802         return false;
    803     }
    804     return true;
    805 }
    806 
    807 
    808 inline void appendTriangleAtVertex(const Vertex *v,
    809                                    SkTDArray<SkPoint> *triangles) {
    810     SkPoint *p = triangles->append(3);
    811     p[0] = v->prev()->point();
    812     p[1] = v->point();
    813     p[2] = v->next()->point();
    814     DebugPrintf(
    815           "Appending triangle: { (%.7g, %.7g), (%.7g, %.7g), (%.7g, %.7g) }\n",
    816           p[0].fX, p[0].fY,
    817           p[1].fX, p[1].fY,
    818           p[2].fX, p[2].fY
    819     );
    820 }
    821 
    822 
    823 static size_t CountVertices(const Vertex *first, const Vertex *last) {
    824     DebugPrintf("Counting vertices: ");
    825     size_t count = 1;
    826     for (; first != last; first = first->next()) {
    827         ++count;
    828         SkASSERT(count <= kMaxCount);
    829         if (count >= kMaxCount) {
    830             FailureMessage("Vertices do not seem to be in a linked chain\n");
    831             break;
    832         }
    833     }
    834     return count;
    835 }
    836 
    837 
    838 bool operator<(const SkPoint &p0, const SkPoint &p1) {
    839     if (p0.fY < p1.fY)  return true;
    840     if (p0.fY > p1.fY)  return false;
    841     if (p0.fX < p1.fX)  return true;
    842     else                return false;
    843 }
    844 
    845 
    846 static void PrintLinkedVertices(size_t n, Vertex *vertices) {
    847     DebugPrintf("%d vertices:\n", n);
    848     Vertex *v;
    849     for (v = vertices; n-- != 0; v = v->next())
    850         DebugPrintf("   (%.7g, %.7g)\n", v->point().fX, v->point().fY);
    851     if (v != vertices)
    852         FailureMessage("Vertices are not in a linked chain\n");
    853 }
    854 
    855 
    856 // Triangulate an unimonotone chain.
    857 bool TriangulateMonotone(Vertex *first, Vertex *last,
    858                          SkTDArray<SkPoint> *triangles) {
    859     DebugPrintf("TriangulateMonotone()\n");
    860 
    861     size_t numVertices = CountVertices(first, last);
    862     if (numVertices == kMaxCount) {
    863         FailureMessage("Way too many vertices: %d:\n", numVertices);
    864         PrintLinkedVertices(numVertices, first);
    865         return false;
    866     }
    867 
    868     Vertex *start = first;
    869     // First find the point with the smallest Y.
    870     DebugPrintf("TriangulateMonotone: finding bottom\n");
    871     int count = kMaxCount;    // Maximum number of vertices.
    872     for (Vertex *v = first->next(); v != first && count-- > 0; v = v->next())
    873         if (v->point() < start->point())
    874             start = v;
    875     if (count <= 0) {
    876         FailureMessage("TriangulateMonotone() was given disjoint chain\n");
    877         return false;   // Something went wrong.
    878     }
    879 
    880     // Start at the far end of the long edge.
    881     if (start->prev()->point() < start->next()->point())
    882         start = start->next();
    883 
    884     Vertex *current = start->next();
    885     while (numVertices >= 3) {
    886         if (current->angleIsConvex()) {
    887             DebugPrintf("Angle %p is convex\n", current);
    888             // Print the vertices
    889             PrintLinkedVertices(numVertices, start);
    890 
    891             appendTriangleAtVertex(current, triangles);
    892             if (triangles->count() > kMaxCount * 3) {
    893                 FailureMessage("An extraordinarily large number of triangles "
    894                                "were generated\n");
    895                 return false;
    896             }
    897             Vertex *save = current->prev();
    898             current->delink();
    899             current = (save == start || save == start->prev()) ? start->next()
    900                                                                : save;
    901             --numVertices;
    902         } else {
    903             if (numVertices == 3) {
    904                 FailureMessage("Convexity error in TriangulateMonotone()\n");
    905                 appendTriangleAtVertex(current, triangles);
    906                 return false;
    907             }
    908             DebugPrintf("Angle %p is concave\n", current);
    909             current = current->next();
    910         }
    911     }
    912     return true;
    913 }
    914 
    915 
    916 // Split the polygon into sets of unimonotone chains, and eventually call
    917 // TriangulateMonotone() to convert them into triangles.
    918 bool Triangulate(Vertex *first, Vertex *last, SkTDArray<SkPoint> *triangles) {
    919     DebugPrintf("Triangulate()\n");
    920     Vertex *currentVertex = first;
    921     while (!currentVertex->done()) {
    922         currentVertex->setDone(true);
    923         Vertex *bottomVertex = currentVertex->diagonal();
    924         if (bottomVertex != NULL) {
    925             Vertex *saveNext = currentVertex->next();
    926             Vertex *savePrev = bottomVertex->prev();
    927             currentVertex->setNext(bottomVertex);
    928             bottomVertex->setPrev(currentVertex);
    929             currentVertex->nullifyTrapezoid();
    930             bool success = Triangulate(bottomVertex, currentVertex, triangles);
    931             currentVertex->setDone(false);
    932             bottomVertex->setDone(false);
    933             currentVertex->setNext(saveNext);
    934             bottomVertex->setPrev(savePrev);
    935             bottomVertex->setNext(currentVertex);
    936             currentVertex->setPrev(bottomVertex);
    937             return Triangulate(currentVertex, bottomVertex, triangles)
    938                    && success;
    939         } else {
    940             currentVertex = currentVertex->next();
    941         }
    942     }
    943     return TriangulateMonotone(first, last, triangles);
    944 }
    945 
    946 
    947 bool SkConcaveToTriangles(size_t numPts,
    948                           const SkPoint pts[],
    949                           SkTDArray<SkPoint> *triangles) {
    950     DebugPrintf("SkConcaveToTriangles()\n");
    951 
    952     SkTDArray<Vertex> vertices;
    953     vertices.setCount(numPts);
    954     if (!ConvertPointsToVertices(numPts, pts, vertices.begin()))
    955         return false;
    956 
    957     triangles->setReserve(numPts);
    958     triangles->setCount(0);
    959     return Triangulate(vertices.begin(), vertices.end() - 1, triangles);
    960 }
    961