src/opengl/gl2paintengineex/qtriangulator.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qtriangulator_p.h"
       
    43 
       
    44 #include <QtGui/qdialog.h>
       
    45 #include <QtGui/qevent.h>
       
    46 #include <QtGui/qpainter.h>
       
    47 #include <QtGui/qpainterpath.h>
       
    48 #include <QtGui/private/qbezier_p.h>
       
    49 #include <QtGui/private/qdatabuffer_p.h>
       
    50 #include <QtCore/qbitarray.h>
       
    51 #include <QtCore/qvarlengtharray.h>
       
    52 #include <QtCore/qqueue.h>
       
    53 #include <QtCore/qglobal.h>
       
    54 #include <QtCore/qpoint.h>
       
    55 #include <QtCore/qalgorithms.h>
       
    56 #include <QtDebug>
       
    57 
       
    58 #include <math.h>
       
    59 
       
    60 QT_BEGIN_NAMESPACE
       
    61 
       
    62 //#define Q_TRIANGULATOR_DEBUG
       
    63 
       
    64 #define Q_FIXED_POINT_SCALE 32
       
    65 
       
    66 // Quick sort.
       
    67 template <class T, class LessThan>
       
    68 static void sort(T *array, int count, LessThan lessThan)
       
    69 {
       
    70     // If the number of elements fall below some threshold, use insertion sort.
       
    71     const int INSERTION_SORT_LIMIT = 7; // About 7 is fastest on my computer...
       
    72     if (count <= INSERTION_SORT_LIMIT) {
       
    73         for (int i = 1; i < count; ++i) {
       
    74             T temp = array[i];
       
    75             int j = i;
       
    76             while (j > 0 && lessThan(temp, array[j - 1])) {
       
    77                 array[j] = array[j - 1];
       
    78                 --j;
       
    79             }
       
    80             array[j] = temp;
       
    81         }
       
    82         return;
       
    83     }
       
    84 
       
    85     int high = count - 1;
       
    86     int low = 0;
       
    87     int mid = high / 2;
       
    88     if (lessThan(array[mid], array[low]))
       
    89         qSwap(array[mid], array[low]);
       
    90     if (lessThan(array[high], array[mid]))
       
    91         qSwap(array[high], array[mid]);
       
    92     if (lessThan(array[mid], array[low]))
       
    93         qSwap(array[mid], array[low]);
       
    94 
       
    95     --high;
       
    96     ++low;
       
    97     qSwap(array[mid], array[high]);
       
    98     int pivot = high;
       
    99     --high;
       
   100 
       
   101     while (low <= high) {
       
   102         while (!lessThan(array[pivot], array[low])) {
       
   103             ++low;
       
   104             if (low > high)
       
   105                 goto sort_loop_end;
       
   106         }
       
   107         while (!lessThan(array[high], array[pivot])) {
       
   108             --high;
       
   109             if (low > high)
       
   110                 goto sort_loop_end;
       
   111         }
       
   112         qSwap(array[low], array[high]);
       
   113         ++low;
       
   114         --high;
       
   115     }
       
   116 sort_loop_end:
       
   117     if (low != pivot)
       
   118         qSwap(array[pivot], array[low]);
       
   119     sort(array, low, lessThan);
       
   120     sort(array + low + 1, count - low - 1, lessThan);
       
   121 }
       
   122 
       
   123 // Quick sort.
       
   124 template <class T>
       
   125 static void sort(T *array, int count)
       
   126 {
       
   127     // If the number of elements fall below some threshold, use insertion sort.
       
   128     const int INSERTION_SORT_LIMIT = 25; // About 25 is fastest on my computer...
       
   129     if (count <= INSERTION_SORT_LIMIT) {
       
   130         for (int i = 1; i < count; ++i) {
       
   131             T temp = array[i];
       
   132             int j = i;
       
   133             while (j > 0 && (temp < array[j - 1])) {
       
   134                 array[j] = array[j - 1];
       
   135                 --j;
       
   136             }
       
   137             array[j] = temp;
       
   138         }
       
   139         return;
       
   140     }
       
   141 
       
   142     int high = count - 1;
       
   143     int low = 0;
       
   144     int mid = high / 2;
       
   145     if ((array[mid] < array[low]))
       
   146         qSwap(array[mid], array[low]);
       
   147     if ((array[high] < array[mid]))
       
   148         qSwap(array[high], array[mid]);
       
   149     if ((array[mid] < array[low]))
       
   150         qSwap(array[mid], array[low]);
       
   151 
       
   152     --high;
       
   153     ++low;
       
   154     qSwap(array[mid], array[high]);
       
   155     int pivot = high;
       
   156     --high;
       
   157 
       
   158     while (low <= high) {
       
   159         while (!(array[pivot] < array[low])) {
       
   160             ++low;
       
   161             if (low > high)
       
   162                 goto sort_loop_end;
       
   163         }
       
   164         while (!(array[high] < array[pivot])) {
       
   165             --high;
       
   166             if (low > high)
       
   167                 goto sort_loop_end;
       
   168         }
       
   169         qSwap(array[low], array[high]);
       
   170         ++low;
       
   171         --high;
       
   172     }
       
   173 sort_loop_end:
       
   174     if (low != pivot)
       
   175         qSwap(array[pivot], array[low]);
       
   176     sort(array, low);
       
   177     sort(array + low + 1, count - low - 1);
       
   178 }
       
   179 
       
   180 //============================================================================//
       
   181 //                                 QFraction                                  //
       
   182 //============================================================================//
       
   183 
       
   184 // Fraction must be in the range [0, 1)
       
   185 struct QFraction
       
   186 {
       
   187     // Comparison operators must not be called on invalid fractions.
       
   188     inline bool operator < (const QFraction &other) const;
       
   189     inline bool operator == (const QFraction &other) const;
       
   190     inline bool operator != (const QFraction &other) const {return !(*this == other);}
       
   191     inline bool operator > (const QFraction &other) const {return other < *this;}
       
   192     inline bool operator >= (const QFraction &other) const {return !(*this < other);}
       
   193     inline bool operator <= (const QFraction &other) const {return !(*this > other);}
       
   194 
       
   195     inline bool isValid() const {return denominator != 0;}
       
   196 
       
   197     // numerator and denominator must not have common denominators.
       
   198     quint64 numerator, denominator;
       
   199 };
       
   200 
       
   201 static inline quint64 gcd(quint64 x, quint64 y)
       
   202 {
       
   203     while (y != 0) {
       
   204         quint64 z = y;
       
   205         y = x % y;
       
   206         x = z;
       
   207     }
       
   208     return x;
       
   209 }
       
   210 
       
   211 static inline int compare(quint64 a, quint64 b)
       
   212 {
       
   213     return (a > b) - (a < b);
       
   214 }
       
   215 
       
   216 // Compare a/b with c/d.
       
   217 // Return negative if less, 0 if equal, positive if greater.
       
   218 // a < b, c < d
       
   219 static int qCompareFractions(quint64 a, quint64 b, quint64 c, quint64 d)
       
   220 {
       
   221     const quint64 LIMIT = Q_UINT64_C(0x100000000);
       
   222     for (;;) {
       
   223         // If the products 'ad' and 'bc' fit into 64 bits, they can be directly compared.
       
   224         if (b < LIMIT && d < LIMIT)
       
   225             return compare(a * d, b * c);
       
   226 
       
   227         if (a == 0 || c == 0)
       
   228             return compare(a, c);
       
   229 
       
   230         // a/b < c/d  <=>  d/c < b/a
       
   231         quint64 b_div_a = b / a;
       
   232         quint64 d_div_c = d / c;
       
   233         if (b_div_a != d_div_c)
       
   234             return compare(d_div_c, b_div_a);
       
   235 
       
   236         // floor(d/c) == floor(b/a)
       
   237         // frac(d/c) < frac(b/a) ?
       
   238         // frac(x/y) = (x%y)/y
       
   239         d -= d_div_c * c; //d %= c;
       
   240         b -= b_div_a * a; //b %= a;
       
   241         qSwap(a, d);
       
   242         qSwap(b, c);
       
   243     }
       
   244 }
       
   245 
       
   246 // Fraction must be in the range [0, 1)
       
   247 // Assume input is valid.
       
   248 static QFraction qFraction(quint64 n, quint64 d) {
       
   249     QFraction result;
       
   250     if (n == 0) {
       
   251         result.numerator = 0;
       
   252         result.denominator = 1;
       
   253     } else {
       
   254         quint64 g = gcd(n, d);
       
   255         result.numerator = n / g;
       
   256         result.denominator = d / g;
       
   257     }
       
   258     return result;
       
   259 }
       
   260 
       
   261 inline bool QFraction::operator < (const QFraction &other) const
       
   262 {
       
   263     return qCompareFractions(numerator, denominator, other.numerator, other.denominator) < 0;
       
   264 }
       
   265 
       
   266 inline bool QFraction::operator == (const QFraction &other) const
       
   267 {
       
   268     return numerator == other.numerator && denominator == other.denominator;
       
   269 }
       
   270 
       
   271 //============================================================================//
       
   272 //                                 QPodPoint                                  //
       
   273 //============================================================================//
       
   274 
       
   275 struct QPodPoint
       
   276 {
       
   277     inline bool operator < (const QPodPoint &other) const
       
   278     {
       
   279         if (y != other.y)
       
   280             return y < other.y;
       
   281         return x < other.x;
       
   282     }
       
   283 
       
   284     inline bool operator > (const QPodPoint &other) const {return other < *this;}
       
   285     inline bool operator <= (const QPodPoint &other) const {return !(*this > other);}
       
   286     inline bool operator >= (const QPodPoint &other) const {return !(*this < other);}
       
   287     inline bool operator == (const QPodPoint &other) const {return x == other.x && y == other.y;}
       
   288     inline bool operator != (const QPodPoint &other) const {return x != other.x || y != other.y;}
       
   289 
       
   290     inline QPodPoint &operator += (const QPodPoint &other) {x += other.x; y += other.y; return *this;}
       
   291     inline QPodPoint &operator -= (const QPodPoint &other) {x -= other.x; y -= other.y; return *this;}
       
   292     inline QPodPoint operator + (const QPodPoint &other) const {QPodPoint result = {x + other.x, y + other.y}; return result;}
       
   293     inline QPodPoint operator - (const QPodPoint &other) const {QPodPoint result = {x - other.x, y - other.y}; return result;}
       
   294 
       
   295     int x;
       
   296     int y;
       
   297 };
       
   298 
       
   299 static inline qint64 qCross(const QPodPoint &u, const QPodPoint &v)
       
   300 {
       
   301     return qint64(u.x) * qint64(v.y) - qint64(u.y) * qint64(v.x);
       
   302 }
       
   303 
       
   304 static inline qint64 qDot(const QPodPoint &u, const QPodPoint &v)
       
   305 {
       
   306     return qint64(u.x) * qint64(v.x) + qint64(u.y) * qint64(v.y);
       
   307 }
       
   308 
       
   309 // Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
       
   310 // line and zero if exactly on the line.
       
   311 // The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
       
   312 // which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
       
   313 static inline qint64 qPointDistanceFromLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
       
   314 {
       
   315     return qCross(v2 - v1, p - v1);
       
   316 }
       
   317 
       
   318 static inline bool qPointIsLeftOfLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
       
   319 {
       
   320     return qPointDistanceFromLine(p, v1, v2) < 0;
       
   321 }
       
   322 
       
   323 // Return:
       
   324 // -1 if u < v
       
   325 //  0 if u == v
       
   326 //  1 if u > v
       
   327 static int comparePoints(const QPodPoint &u, const QPodPoint &v)
       
   328 {
       
   329     if (u.y < v.y)
       
   330         return -1;
       
   331     if (u.y > v.y)
       
   332         return 1;
       
   333     if (u.x < v.x)
       
   334         return -1;
       
   335     if (u.x > v.x)
       
   336         return 1;
       
   337     return 0;
       
   338 }
       
   339 
       
   340 //============================================================================//
       
   341 //                             QIntersectionPoint                             //
       
   342 //============================================================================//
       
   343 
       
   344 struct QIntersectionPoint
       
   345 {
       
   346     inline bool isValid() const {return xOffset.isValid() && yOffset.isValid();}
       
   347     QPodPoint round() const;
       
   348     inline bool isAccurate() const {return xOffset.numerator == 0 && yOffset.numerator == 0;}
       
   349     bool operator < (const QIntersectionPoint &other) const;
       
   350     bool operator == (const QIntersectionPoint &other) const;
       
   351     inline bool operator != (const QIntersectionPoint &other) const {return !(*this == other);}
       
   352     inline bool operator > (const QIntersectionPoint &other) const {return other < *this;}
       
   353     inline bool operator >= (const QIntersectionPoint &other) const {return !(*this < other);}
       
   354     inline bool operator <= (const QIntersectionPoint &other) const {return !(*this > other);}
       
   355     bool isOnLine(const QPodPoint &u, const QPodPoint &v) const;
       
   356 
       
   357     QPodPoint upperLeft;
       
   358     QFraction xOffset;
       
   359     QFraction yOffset;
       
   360 };
       
   361 
       
   362 static inline QIntersectionPoint qIntersectionPoint(const QPodPoint &point)
       
   363 {
       
   364     // upperLeft = point, xOffset = 0/1, yOffset = 0/1.
       
   365     QIntersectionPoint p = {{point.x, point.y}, {0, 1}, {0, 1}};
       
   366     return p;
       
   367 }
       
   368 
       
   369 static inline QIntersectionPoint qIntersectionPoint(int x, int y)
       
   370 {
       
   371     // upperLeft = (x, y), xOffset = 0/1, yOffset = 0/1.
       
   372     QIntersectionPoint p = {{x, y}, {0, 1}, {0, 1}};
       
   373     return p;
       
   374 }
       
   375 
       
   376 static QIntersectionPoint qIntersectionPoint(const QPodPoint &u1, const QPodPoint &u2, const QPodPoint &v1, const QPodPoint &v2)
       
   377 {
       
   378     QIntersectionPoint result = {{0, 0}, {0, 0}, {0, 0}};
       
   379 
       
   380     QPodPoint u = u2 - u1;
       
   381     QPodPoint v = v2 - v1;
       
   382     qint64 d1 = qCross(u, v1 - u1);
       
   383     qint64 d2 = qCross(u, v2 - u1);
       
   384     qint64 det = d2 - d1;
       
   385     qint64 d3 = qCross(v, u1 - v1);
       
   386     qint64 d4 = d3 - det; //qCross(v, u2 - v1);
       
   387 
       
   388     // Check that the math is correct.
       
   389     Q_ASSERT(d4 == qCross(v, u2 - v1));
       
   390 
       
   391     // The intersection point can be expressed as:
       
   392     // v1 - v * d1/det
       
   393     // v2 - v * d2/det
       
   394     // u1 + u * d3/det
       
   395     // u2 + u * d4/det
       
   396 
       
   397     // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap.
       
   398     if (det == 0)
       
   399         return result;
       
   400 
       
   401     if (det < 0) {
       
   402         det = -det;
       
   403         d1 = -d1;
       
   404         d2 = -d2;
       
   405         d3 = -d3;
       
   406         d4 = -d4;
       
   407     }
       
   408 
       
   409     // I'm only interested in lines intersecting at their interior, not at their end points.
       
   410     // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'.
       
   411     if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0)
       
   412         return result;
       
   413 
       
   414     // Calculate the intersection point as follows:
       
   415     // v1 - v * d1/det | v1 <= v2 (component-wise)
       
   416     // v2 - v * d2/det | v2 < v1 (component-wise)
       
   417 
       
   418     // Assuming 21 bits per vector component.
       
   419     // TODO: Make code path for 31 bits per vector component.
       
   420     if (v.x >= 0) {
       
   421         result.upperLeft.x = v1.x + (-v.x * d1) / det;
       
   422         result.xOffset = qFraction(quint64(-v.x * d1) % quint64(det), quint64(det));
       
   423     } else {
       
   424         result.upperLeft.x = v2.x + (-v.x * d2) / det;
       
   425         result.xOffset = qFraction(quint64(-v.x * d2) % quint64(det), quint64(det));
       
   426     }
       
   427 
       
   428     if (v.y >= 0) {
       
   429         result.upperLeft.y = v1.y + (-v.y * d1) / det;
       
   430         result.yOffset = qFraction(quint64(-v.y * d1) % quint64(det), quint64(det));
       
   431     } else {
       
   432         result.upperLeft.y = v2.y + (-v.y * d2) / det;
       
   433         result.yOffset = qFraction(quint64(-v.y * d2) % quint64(det), quint64(det));
       
   434     }
       
   435 
       
   436     Q_ASSERT(result.xOffset.isValid());
       
   437     Q_ASSERT(result.yOffset.isValid());
       
   438     return result;
       
   439 }
       
   440 
       
   441 QPodPoint QIntersectionPoint::round() const
       
   442 {
       
   443     QPodPoint result = upperLeft;
       
   444     if (2 * xOffset.numerator >= xOffset.denominator)
       
   445         ++result.x;
       
   446     if (2 * yOffset.numerator >= yOffset.denominator)
       
   447         ++result.y;
       
   448     return result;
       
   449 }
       
   450 
       
   451 bool QIntersectionPoint::operator < (const QIntersectionPoint &other) const
       
   452 {
       
   453     if (upperLeft.y != other.upperLeft.y)
       
   454         return upperLeft.y < other.upperLeft.y;
       
   455     if (yOffset != other.yOffset)
       
   456         return yOffset < other.yOffset;
       
   457     if (upperLeft.x != other.upperLeft.x)
       
   458         return upperLeft.x < other.upperLeft.x;
       
   459     return xOffset < other.xOffset;
       
   460 }
       
   461 
       
   462 bool QIntersectionPoint::operator == (const QIntersectionPoint &other) const
       
   463 {
       
   464     return upperLeft == other.upperLeft && xOffset == other.xOffset && yOffset == other.yOffset;
       
   465 }
       
   466 
       
   467 // Returns true if this point is on the infinite line passing through 'u' and 'v'.
       
   468 bool QIntersectionPoint::isOnLine(const QPodPoint &u, const QPodPoint &v) const
       
   469 {
       
   470     // TODO: Make code path for coordinates with more than 21 bits.
       
   471     const QPodPoint p = upperLeft - u;
       
   472     const QPodPoint q = v - u;
       
   473     bool isHorizontal = p.y == 0 && yOffset.numerator == 0;
       
   474     bool isVertical = p.x == 0 && xOffset.numerator == 0;
       
   475     if (isHorizontal && isVertical)
       
   476         return true;
       
   477     if (isHorizontal)
       
   478         return q.y == 0;
       
   479     if (q.y == 0)
       
   480         return false;
       
   481     if (isVertical)
       
   482         return q.x == 0;
       
   483     if (q.x == 0)
       
   484         return false;
       
   485 
       
   486     // At this point, 'p+offset' and 'q' cannot lie on the x or y axis.
       
   487 
       
   488     if (((q.x < 0) == (q.y < 0)) != ((p.x < 0) == (p.y < 0)))
       
   489         return false; // 'p + offset' and 'q' pass through different quadrants.
       
   490     
       
   491     // Move all coordinates into the first quadrant.
       
   492     quint64 nx, ny;
       
   493     if (p.x < 0)
       
   494         nx = quint64(-p.x) * xOffset.denominator - xOffset.numerator;
       
   495     else
       
   496         nx = quint64(p.x) * xOffset.denominator + xOffset.numerator;
       
   497     if (p.y < 0)
       
   498         ny = quint64(-p.y) * yOffset.denominator - yOffset.numerator;
       
   499     else
       
   500         ny = quint64(p.y) * yOffset.denominator + yOffset.numerator;
       
   501 
       
   502     return qFraction(quint64(qAbs(q.x)) * xOffset.denominator, quint64(qAbs(q.y)) * yOffset.denominator) == qFraction(nx, ny);
       
   503 }
       
   504 
       
   505 //============================================================================//
       
   506 //                                  QMaxHeap                                  //
       
   507 //============================================================================//
       
   508 
       
   509 template <class T>
       
   510 class QMaxHeap
       
   511 {
       
   512 public:
       
   513     QMaxHeap() : m_data(0) {}
       
   514     inline int size() const {return m_data.size();}
       
   515     inline bool empty() const {return m_data.isEmpty();}
       
   516     inline bool isEmpty() const {return m_data.isEmpty();}
       
   517     void push(const T &x);
       
   518     T pop();
       
   519     inline const T &top() const {return m_data.first();}
       
   520 private:
       
   521     static inline int parent(int i) {return (i - 1) / 2;}
       
   522     static inline int left(int i) {return 2 * i + 1;}
       
   523     static inline int right(int i) {return 2 * i + 2;}
       
   524 
       
   525     QDataBuffer<T> m_data;
       
   526 };
       
   527 
       
   528 template <class T>
       
   529 void QMaxHeap<T>::push(const T &x)
       
   530 {
       
   531     int current = m_data.size();
       
   532     int parent = QMaxHeap::parent(current);
       
   533     m_data.add(x);
       
   534     while (current != 0 && m_data.at(parent) < x) {
       
   535         m_data.at(current) = m_data.at(parent);
       
   536         current = parent;
       
   537         parent = QMaxHeap::parent(current);
       
   538     }
       
   539     m_data.at(current) = x;
       
   540 }
       
   541 
       
   542 template <class T>
       
   543 T QMaxHeap<T>::pop()
       
   544 {
       
   545     T result = m_data.first();
       
   546     T back = m_data.last();
       
   547     m_data.pop_back();
       
   548     if (!m_data.isEmpty()) {
       
   549         int current = 0;
       
   550         for (;;) {
       
   551             int left = QMaxHeap::left(current);
       
   552             int right = QMaxHeap::right(current);
       
   553             if (left >= m_data.size())
       
   554                 break;
       
   555             int greater = left;
       
   556             if (right < m_data.size() && m_data.at(left) < m_data.at(right))
       
   557                 greater = right;
       
   558             if (m_data.at(greater) < back)
       
   559                 break;
       
   560             m_data.at(current) = m_data.at(greater);
       
   561             current = greater;
       
   562         }
       
   563         m_data.at(current) = back;
       
   564     }
       
   565     return result;
       
   566 }
       
   567 
       
   568 //============================================================================//
       
   569 //                                  QRBTree                                   //
       
   570 //============================================================================//
       
   571 
       
   572 template <class T>
       
   573 struct QRBTree
       
   574 {
       
   575     struct Node
       
   576     {
       
   577         inline Node() : parent(0), left(0), right(0), red(true) { }
       
   578         inline ~Node() {if (left) delete left; if (right) delete right;}
       
   579         T data;
       
   580         Node *parent;
       
   581         Node *left;
       
   582         Node *right;
       
   583         bool red;
       
   584     };
       
   585 
       
   586     inline QRBTree() : root(0), freeList(0) { }
       
   587     inline ~QRBTree();
       
   588 
       
   589     inline void clear();
       
   590 
       
   591     void attachBefore(Node *parent, Node *child);
       
   592     void attachAfter(Node *parent, Node *child);
       
   593 
       
   594     inline Node *front(Node *node) const;
       
   595     inline Node *back(Node *node) const;
       
   596     Node *next(Node *node) const;
       
   597     Node *previous(Node *node) const;
       
   598 
       
   599     inline void deleteNode(Node *&node);
       
   600     inline Node *newNode();
       
   601 
       
   602     // Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
       
   603     // 'left' and 'right' cannot be null.
       
   604     int order(Node *left, Node *right);
       
   605     inline bool verify() const;
       
   606 
       
   607 private:
       
   608     void rotateLeft(Node *node);
       
   609     void rotateRight(Node *node);
       
   610     void update(Node *node);
       
   611 
       
   612     inline void attachLeft(Node *parent, Node *child);
       
   613     inline void attachRight(Node *parent, Node *child);
       
   614 
       
   615     int blackDepth(Node *top) const;
       
   616     bool checkRedBlackProperty(Node *top) const;
       
   617 
       
   618     void swapNodes(Node *n1, Node *n2);
       
   619     void detach(Node *node);
       
   620 
       
   621     // 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
       
   622     void rebalance(Node *node);
       
   623 
       
   624 public:
       
   625     Node *root;
       
   626 private:
       
   627     Node *freeList;
       
   628 };
       
   629 
       
   630 template <class T>
       
   631 inline QRBTree<T>::~QRBTree()
       
   632 {
       
   633     clear();
       
   634     while (freeList) {
       
   635         // Avoid recursively calling the destructor, as this list may become large.
       
   636         Node *next = freeList->right;
       
   637         freeList->right = 0;
       
   638         delete freeList;
       
   639         freeList = next;
       
   640     }
       
   641 }
       
   642 
       
   643 template <class T>
       
   644 inline void QRBTree<T>::clear()
       
   645 {
       
   646     if (root)
       
   647         delete root;
       
   648     root = 0;
       
   649 }
       
   650 
       
   651 template <class T>
       
   652 void QRBTree<T>::rotateLeft(Node *node)
       
   653 {
       
   654     //   |            |      //
       
   655     //   N            B      //
       
   656     //  / \          / \     //
       
   657     // A   B  --->  N   D    //
       
   658     //    / \      / \       //
       
   659     //   C   D    A   C      //
       
   660 
       
   661     Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
       
   662     ref = node->right;
       
   663     node->right->parent = node->parent;
       
   664 
       
   665     //   :        //
       
   666     //   N        //
       
   667     //  / :|      //
       
   668     // A   B      //
       
   669     //    / \     //
       
   670     //   C   D    //
       
   671 
       
   672     node->right = ref->left;
       
   673     if (ref->left)
       
   674         ref->left->parent = node;
       
   675 
       
   676     //   :   |     //
       
   677     //   N   B     //
       
   678     //  / \ : \    //
       
   679     // A   C   D   //
       
   680 
       
   681     ref->left = node;
       
   682     node->parent = ref;
       
   683 
       
   684     //     |       //
       
   685     //     B       //
       
   686     //    / \      //
       
   687     //   N   D     //
       
   688     //  / \        //
       
   689     // A   C       //
       
   690 }
       
   691 
       
   692 template <class T>
       
   693 void QRBTree<T>::rotateRight(Node *node)
       
   694 {
       
   695     //     |            |        //
       
   696     //     N            A        //
       
   697     //    / \          / \       //
       
   698     //   A   B  --->  C   N      //
       
   699     //  / \              / \     //
       
   700     // C   D            D   B    //
       
   701 
       
   702     Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
       
   703     ref = node->left;
       
   704     node->left->parent = node->parent;
       
   705 
       
   706     node->left = ref->right;
       
   707     if (ref->right)
       
   708         ref->right->parent = node;
       
   709 
       
   710     ref->right = node;
       
   711     node->parent = ref;
       
   712 }
       
   713 
       
   714 template <class T>
       
   715 void QRBTree<T>::update(Node *node) // call this after inserting a node
       
   716 {
       
   717     for (;;) {
       
   718         Node *parent = node->parent;
       
   719 
       
   720         // if the node is the root, color it black
       
   721         if (!parent) {
       
   722             node->red = false;
       
   723             return;
       
   724         }
       
   725 
       
   726         // if the parent is black, the node can be left red
       
   727         if (!parent->red)
       
   728             return;
       
   729 
       
   730         // at this point, the parent is red and cannot be the root
       
   731         Node *grandpa = parent->parent;
       
   732         Q_ASSERT(grandpa);
       
   733 
       
   734         Node *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left);
       
   735         if (uncle && uncle->red) {
       
   736             // grandpa's black, parent and uncle are red.
       
   737             // let parent and uncle be black, grandpa red and recursively update grandpa.
       
   738             Q_ASSERT(!grandpa->red);
       
   739             parent->red = false;
       
   740             uncle->red = false;
       
   741             grandpa->red = true;
       
   742             node = grandpa;
       
   743             continue;
       
   744         }
       
   745 
       
   746         // at this point, uncle is black
       
   747         if (node == parent->right && parent == grandpa->left)
       
   748             rotateLeft(node = parent);
       
   749         else if (node == parent->left && parent == grandpa->right)
       
   750             rotateRight(node = parent);
       
   751         parent = node->parent;
       
   752 
       
   753         if (parent == grandpa->left) {
       
   754             rotateRight(grandpa);
       
   755             parent->red = false;
       
   756             grandpa->red = true;
       
   757         } else {
       
   758             rotateLeft(grandpa);
       
   759             parent->red = false;
       
   760             grandpa->red = true;
       
   761         }
       
   762         return;
       
   763     }
       
   764 }
       
   765 
       
   766 template <class T>
       
   767 inline void QRBTree<T>::attachLeft(Node *parent, Node *child)
       
   768 {
       
   769     Q_ASSERT(!parent->left);
       
   770     parent->left = child;
       
   771     child->parent = parent;
       
   772     update(child);
       
   773 }
       
   774 
       
   775 template <class T>
       
   776 inline void QRBTree<T>::attachRight(Node *parent, Node *child)
       
   777 {
       
   778     Q_ASSERT(!parent->right);
       
   779     parent->right = child;
       
   780     child->parent = parent;
       
   781     update(child);
       
   782 }
       
   783 
       
   784 template <class T>
       
   785 void QRBTree<T>::attachBefore(Node *parent, Node *child)
       
   786 {
       
   787     if (!root)
       
   788         update(root = child);
       
   789     else if (!parent)
       
   790         attachRight(back(root), child);
       
   791     else if (parent->left)
       
   792         attachRight(back(parent->left), child);
       
   793     else
       
   794         attachLeft(parent, child);
       
   795 }
       
   796 
       
   797 template <class T>
       
   798 void QRBTree<T>::attachAfter(Node *parent, Node *child)
       
   799 {
       
   800     if (!root)
       
   801         update(root = child);
       
   802     else if (!parent)
       
   803         attachLeft(front(root), child);
       
   804     else if (parent->right)
       
   805         attachLeft(front(parent->right), child);
       
   806     else
       
   807         attachRight(parent, child);
       
   808 }
       
   809 
       
   810 template <class T>
       
   811 void QRBTree<T>::swapNodes(Node *n1, Node *n2)
       
   812 {
       
   813     // Since iterators must not be invalidated, it is not sufficient to only swap the data.
       
   814     if (n1->parent == n2) {
       
   815         n1->parent = n2->parent;
       
   816         n2->parent = n1;
       
   817     } else if (n2->parent == n1) {
       
   818         n2->parent = n1->parent;
       
   819         n1->parent = n2;
       
   820     } else {
       
   821         qSwap(n1->parent, n2->parent);
       
   822     }
       
   823 
       
   824     qSwap(n1->left, n2->left);
       
   825     qSwap(n1->right, n2->right);
       
   826     qSwap(n1->red, n2->red);
       
   827 
       
   828     if (n1->parent) {
       
   829         if (n1->parent->left == n2)
       
   830             n1->parent->left = n1;
       
   831         else
       
   832             n1->parent->right = n1;
       
   833     } else {
       
   834         root = n1;
       
   835     }
       
   836 
       
   837     if (n2->parent) {
       
   838         if (n2->parent->left == n1)
       
   839             n2->parent->left = n2;
       
   840         else
       
   841             n2->parent->right = n2;
       
   842     } else {
       
   843         root = n2;
       
   844     }
       
   845 
       
   846     if (n1->left)
       
   847         n1->left->parent = n1;
       
   848     if (n1->right)
       
   849         n1->right->parent = n1;
       
   850 
       
   851     if (n2->left)
       
   852         n2->left->parent = n2;
       
   853     if (n2->right)
       
   854         n2->right->parent = n2;
       
   855 }
       
   856 
       
   857 template <class T>
       
   858 void QRBTree<T>::detach(Node *node) // call this before removing a node.
       
   859 {
       
   860     if (node->right)
       
   861         swapNodes(node, front(node->right));
       
   862 
       
   863     Node *child = (node->left ? node->left : node->right);
       
   864 
       
   865     if (!node->red) {
       
   866         if (child && child->red)
       
   867             child->red = false;
       
   868         else
       
   869             rebalance(node);
       
   870     }
       
   871 
       
   872     Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
       
   873     ref = child;
       
   874     if (child)
       
   875         child->parent = node->parent;
       
   876     node->left = node->right = node->parent = 0;
       
   877 }
       
   878 
       
   879 // 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
       
   880 template <class T>
       
   881 void QRBTree<T>::rebalance(Node *node)
       
   882 {
       
   883     Q_ASSERT(!node->red);
       
   884     for (;;) {
       
   885         if (!node->parent)
       
   886             return;
       
   887 
       
   888         // at this point, node is not a parent, it is black, thus it must have a sibling.
       
   889         Node *sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
       
   890         Q_ASSERT(sibling);
       
   891 
       
   892         if (sibling->red) {
       
   893             sibling->red = false;
       
   894             node->parent->red = true;
       
   895             if (node == node->parent->left)
       
   896                 rotateLeft(node->parent);
       
   897             else
       
   898                 rotateRight(node->parent);
       
   899             sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
       
   900             Q_ASSERT(sibling);
       
   901         }
       
   902 
       
   903         // at this point, the sibling is black.
       
   904         Q_ASSERT(!sibling->red);
       
   905 
       
   906         if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) {
       
   907             bool parentWasRed = node->parent->red;
       
   908             sibling->red = true;
       
   909             node->parent->red = false;
       
   910             if (parentWasRed)
       
   911                 return;
       
   912             node = node->parent;
       
   913             continue;
       
   914         }
       
   915 
       
   916         // at this point, at least one of the sibling's children is red.
       
   917 
       
   918         if (node == node->parent->left) {
       
   919             if (!sibling->right || !sibling->right->red) {
       
   920                 Q_ASSERT(sibling->left);
       
   921                 sibling->red = true;
       
   922                 sibling->left->red = false;
       
   923                 rotateRight(sibling);
       
   924 
       
   925                 sibling = sibling->parent;
       
   926                 Q_ASSERT(sibling);
       
   927             }
       
   928             sibling->red = node->parent->red;
       
   929             node->parent->red = false;
       
   930 
       
   931             Q_ASSERT(sibling->right->red);
       
   932             sibling->right->red = false;
       
   933             rotateLeft(node->parent);
       
   934         } else {
       
   935             if (!sibling->left || !sibling->left->red) {
       
   936                 Q_ASSERT(sibling->right);
       
   937                 sibling->red = true;
       
   938                 sibling->right->red = false;
       
   939                 rotateLeft(sibling);
       
   940 
       
   941                 sibling = sibling->parent;
       
   942                 Q_ASSERT(sibling);
       
   943             }
       
   944             sibling->red = node->parent->red;
       
   945             node->parent->red = false;
       
   946 
       
   947             Q_ASSERT(sibling->left->red);
       
   948             sibling->left->red = false;
       
   949             rotateRight(node->parent);
       
   950         }
       
   951         return;
       
   952     }
       
   953 }
       
   954 
       
   955 template <class T>
       
   956 inline typename QRBTree<T>::Node *QRBTree<T>::front(Node *node) const
       
   957 {
       
   958     while (node->left)
       
   959         node = node->left;
       
   960     return node;
       
   961 }
       
   962 
       
   963 template <class T>
       
   964 inline typename QRBTree<T>::Node *QRBTree<T>::back(Node *node) const
       
   965 {
       
   966     while (node->right)
       
   967         node = node->right;
       
   968     return node;
       
   969 }
       
   970 
       
   971 template <class T>
       
   972 typename QRBTree<T>::Node *QRBTree<T>::next(Node *node) const
       
   973 {
       
   974     if (node->right)
       
   975         return front(node->right);
       
   976     while (node->parent && node == node->parent->right)
       
   977         node = node->parent;
       
   978     return node->parent;
       
   979 }
       
   980 
       
   981 template <class T>
       
   982 typename QRBTree<T>::Node *QRBTree<T>::previous(Node *node) const
       
   983 {
       
   984     if (node->left)
       
   985         return back(node->left);
       
   986     while (node->parent && node == node->parent->left)
       
   987         node = node->parent;
       
   988     return node->parent;
       
   989 }
       
   990 
       
   991 template <class T>
       
   992 int QRBTree<T>::blackDepth(Node *top) const
       
   993 {
       
   994     if (!top)
       
   995         return 0;
       
   996     int leftDepth = blackDepth(top->left);
       
   997     int rightDepth = blackDepth(top->right);
       
   998     if (leftDepth != rightDepth)
       
   999         return -1;
       
  1000     if (!top->red)
       
  1001         ++leftDepth;
       
  1002     return leftDepth;
       
  1003 }
       
  1004 
       
  1005 template <class T>
       
  1006 bool QRBTree<T>::checkRedBlackProperty(Node *top) const
       
  1007 {
       
  1008     if (!top)
       
  1009         return true;
       
  1010     if (top->left && !checkRedBlackProperty(top->left))
       
  1011         return false;
       
  1012     if (top->right && !checkRedBlackProperty(top->right))
       
  1013         return false;
       
  1014     return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red)));
       
  1015 }
       
  1016 
       
  1017 template <class T>
       
  1018 inline bool QRBTree<T>::verify() const
       
  1019 {
       
  1020     return checkRedBlackProperty(root) && blackDepth(root) != -1;
       
  1021 }
       
  1022 
       
  1023 template <class T>
       
  1024 inline void QRBTree<T>::deleteNode(Node *&node)
       
  1025 {
       
  1026     Q_ASSERT(node);
       
  1027     detach(node);
       
  1028     node->right = freeList;
       
  1029     freeList = node;
       
  1030     node = 0;
       
  1031 }
       
  1032 
       
  1033 template <class T>
       
  1034 inline typename QRBTree<T>::Node *QRBTree<T>::newNode()
       
  1035 {
       
  1036     if (freeList) {
       
  1037         Node *node = freeList;
       
  1038         freeList = freeList->right;
       
  1039         node->parent = node->left = node->right = 0;
       
  1040         node->red = true;
       
  1041         return node;
       
  1042     }
       
  1043     return new Node;
       
  1044 }
       
  1045 
       
  1046 // Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
       
  1047 // 'left' and 'right' cannot be null.
       
  1048 template <class T>
       
  1049 int QRBTree<T>::order(Node *left, Node *right)
       
  1050 {
       
  1051     Q_ASSERT(left && right);
       
  1052     if (left == right)
       
  1053         return 0;
       
  1054 
       
  1055     QVector<Node *> leftAncestors;
       
  1056     QVector<Node *> rightAncestors;
       
  1057     while (left) {
       
  1058         leftAncestors.push_back(left);
       
  1059         left = left->parent;
       
  1060     }
       
  1061     while (right) {
       
  1062         rightAncestors.push_back(right);
       
  1063         right = right->parent;
       
  1064     }
       
  1065     Q_ASSERT(leftAncestors.back() == root && rightAncestors.back() == root);
       
  1066 
       
  1067     while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) {
       
  1068         leftAncestors.pop_back();
       
  1069         rightAncestors.pop_back();
       
  1070     }
       
  1071 
       
  1072     if (!leftAncestors.empty())
       
  1073         return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1);
       
  1074 
       
  1075     if (!rightAncestors.empty())
       
  1076         return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1);
       
  1077 
       
  1078     // The code should never reach this point.
       
  1079     Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty());
       
  1080     return 0;
       
  1081 }
       
  1082 
       
  1083 //============================================================================//
       
  1084 //                                 QInt64Hash                                 //
       
  1085 //============================================================================//
       
  1086 
       
  1087 // Copied from qhash.cpp
       
  1088 static const uchar prime_deltas[] = {
       
  1089     0,  0,  1,  3,  1,  5,  3,  3,  1,  9,  7,  5,  3,  9, 25,  3,
       
  1090     1, 21,  3, 21,  7, 15,  9,  5,  3, 29, 15,  0,  0,  0,  0,  0
       
  1091 };
       
  1092 
       
  1093 // Copied from qhash.cpp
       
  1094 static inline int primeForNumBits(int numBits)
       
  1095 {
       
  1096     return (1 << numBits) + prime_deltas[numBits];
       
  1097 }
       
  1098 
       
  1099 static inline int primeForCount(int count)
       
  1100 {
       
  1101     int low = 0;
       
  1102     int high = 32;
       
  1103     for (int i = 0; i < 5; ++i) {
       
  1104         int mid = (high + low) / 2;
       
  1105         if (count >= 1 << mid)
       
  1106             low = mid;
       
  1107         else
       
  1108             high = mid;
       
  1109     }
       
  1110     return primeForNumBits(high);
       
  1111 }
       
  1112 
       
  1113 // Hash set of quint64s. Elements cannot be removed without clearing the
       
  1114 // entire set. A value of -1 is used to mark unused entries.
       
  1115 class QInt64Set
       
  1116 {
       
  1117 public:
       
  1118     inline QInt64Set(int capacity = 64);
       
  1119     inline ~QInt64Set() {if (m_array) delete[] m_array;}
       
  1120     inline bool isValid() const {return m_array;}
       
  1121     void insert(quint64 key);
       
  1122     bool contains(quint64 key) const;
       
  1123     inline void clear();
       
  1124 private:
       
  1125     bool rehash(int capacity);
       
  1126 
       
  1127     static const quint64 UNUSED;
       
  1128 
       
  1129     quint64 *m_array;
       
  1130     int m_capacity;
       
  1131     int m_count;
       
  1132 };
       
  1133 
       
  1134 const quint64 QInt64Set::UNUSED = quint64(-1);
       
  1135 
       
  1136 inline QInt64Set::QInt64Set(int capacity)
       
  1137 {
       
  1138     m_capacity = primeForCount(capacity);
       
  1139     m_array = new quint64[m_capacity];
       
  1140     if (m_array)
       
  1141         clear();
       
  1142     else
       
  1143         m_capacity = 0;
       
  1144 }
       
  1145 
       
  1146 bool QInt64Set::rehash(int capacity)
       
  1147 {
       
  1148     quint64 *oldArray = m_array;
       
  1149     int oldCapacity = m_capacity;
       
  1150 
       
  1151     m_capacity = capacity;
       
  1152     m_array = new quint64[m_capacity];
       
  1153     if (m_array) {
       
  1154         clear();
       
  1155         if (oldArray) {
       
  1156             for (int i = 0; i < oldCapacity; ++i) {
       
  1157                 if (oldArray[i] != UNUSED)
       
  1158                     insert(oldArray[i]);
       
  1159             }
       
  1160             delete[] oldArray;
       
  1161         }
       
  1162         return true;
       
  1163     } else {
       
  1164         m_capacity = oldCapacity;
       
  1165         m_array = oldArray;
       
  1166         return false;
       
  1167     }
       
  1168 }
       
  1169 
       
  1170 void QInt64Set::insert(quint64 key)
       
  1171 {
       
  1172     if (m_count > 3 * m_capacity / 4)
       
  1173         rehash(primeForCount(2 * m_capacity));
       
  1174     Q_ASSERT_X(m_array, "QInt64Hash<T>::insert", "Hash set not allocated.");
       
  1175     int index = int(key % m_capacity);
       
  1176     for (int i = 0; i < m_capacity; ++i) {
       
  1177         index += i;
       
  1178         if (index >= m_capacity)
       
  1179             index -= m_capacity;
       
  1180         if (m_array[index] == key)
       
  1181             return;
       
  1182         if (m_array[index] == UNUSED) {
       
  1183             ++m_count;
       
  1184             m_array[index] = key;
       
  1185             return;
       
  1186         }
       
  1187     }
       
  1188     Q_ASSERT_X(0, "QInt64Hash<T>::insert", "Hash set full.");
       
  1189 }
       
  1190 
       
  1191 bool QInt64Set::contains(quint64 key) const
       
  1192 {
       
  1193     Q_ASSERT_X(m_array, "QInt64Hash<T>::contains", "Hash set not allocated.");
       
  1194     int index = int(key % m_capacity);
       
  1195     for (int i = 0; i < m_capacity; ++i) {
       
  1196         index += i;
       
  1197         if (index >= m_capacity)
       
  1198             index -= m_capacity;
       
  1199         if (m_array[index] == key)
       
  1200             return true;
       
  1201         if (m_array[index] == UNUSED)
       
  1202             return false;
       
  1203     }
       
  1204     return false;
       
  1205 }
       
  1206 
       
  1207 inline void QInt64Set::clear()
       
  1208 {
       
  1209     Q_ASSERT_X(m_array, "QInt64Hash<T>::clear", "Hash set not allocated.");
       
  1210     for (int i = 0; i < m_capacity; ++i)
       
  1211         m_array[i] = UNUSED;
       
  1212     m_count = 0;
       
  1213 }
       
  1214 
       
  1215 //============================================================================//
       
  1216 //                                QRingBuffer                                 //
       
  1217 //============================================================================//
       
  1218 
       
  1219 // T must be POD.
       
  1220 template <class T>
       
  1221 class QRingBuffer
       
  1222 {
       
  1223 public:
       
  1224     inline QRingBuffer() : m_array(0), m_head(0), m_size(0), m_capacity(0) { }
       
  1225     inline ~QRingBuffer() {if (m_array) delete[] m_array;}
       
  1226     bool reallocate(int capacity);
       
  1227     inline const T &head() const {Q_ASSERT(m_size > 0); return m_array[m_head];}
       
  1228     inline const T &dequeue();
       
  1229     inline void enqueue(const T &x);
       
  1230     inline bool isEmpty() const {return m_size == 0;}
       
  1231 private:
       
  1232     T *m_array;
       
  1233     int m_head;
       
  1234     int m_size;
       
  1235     int m_capacity;
       
  1236 };
       
  1237 
       
  1238 template <class T>
       
  1239 bool QRingBuffer<T>::reallocate(int capacity)
       
  1240 {
       
  1241     T *oldArray = m_array;
       
  1242     m_array = new T[capacity];
       
  1243     if (m_array) {
       
  1244         if (oldArray) {
       
  1245             if (m_head + m_size > m_capacity) {
       
  1246                 memcpy(m_array, oldArray + m_head, (m_capacity - m_head) * sizeof(T));
       
  1247                 memcpy(m_array + (m_capacity - m_head), oldArray, (m_head + m_size - m_capacity) * sizeof(T));
       
  1248             } else {
       
  1249                 memcpy(m_array, oldArray + m_head, m_size * sizeof(T));
       
  1250             }
       
  1251             delete[] oldArray;
       
  1252         }
       
  1253         m_capacity = capacity;
       
  1254         m_head = 0;
       
  1255         return true;
       
  1256     } else {
       
  1257         m_array = oldArray;
       
  1258         return false;
       
  1259     }
       
  1260 }
       
  1261 
       
  1262 template <class T>
       
  1263 inline const T &QRingBuffer<T>::dequeue()
       
  1264 {
       
  1265     Q_ASSERT(m_size > 0);
       
  1266     Q_ASSERT(m_array);
       
  1267     Q_ASSERT(m_capacity >= m_size);
       
  1268     int index = m_head;
       
  1269     if (++m_head >= m_capacity)
       
  1270         m_head -= m_capacity;
       
  1271     --m_size;
       
  1272     return m_array[index];
       
  1273 }
       
  1274 
       
  1275 template <class T>
       
  1276 inline void QRingBuffer<T>::enqueue(const T &x)
       
  1277 {
       
  1278     if (m_size == m_capacity)
       
  1279         reallocate(qMax(2 * m_capacity, 64));
       
  1280     int index = m_head + m_size;
       
  1281     if (index >= m_capacity)
       
  1282         index -= m_capacity;
       
  1283     m_array[index] = x;
       
  1284     ++m_size;
       
  1285 }
       
  1286 
       
  1287 //============================================================================//
       
  1288 //                               QTriangulator                                //
       
  1289 //============================================================================//
       
  1290 
       
  1291 class QTriangulator
       
  1292 {
       
  1293 public:
       
  1294     typedef QVarLengthArray<int, 6> ShortArray;
       
  1295 
       
  1296     //================================//
       
  1297     // QTriangulator::ComplexToSimple //
       
  1298     //================================//
       
  1299     friend class ComplexToSimple;
       
  1300     class ComplexToSimple
       
  1301     {
       
  1302     public:
       
  1303         inline ComplexToSimple(QTriangulator *parent) : m_parent(parent),
       
  1304             m_edges(0), m_events(0), m_splits(0) { }
       
  1305         void decompose();
       
  1306     private:
       
  1307         struct Edge
       
  1308         {
       
  1309             inline int &upper() {return pointingUp ? to : from;}
       
  1310             inline int &lower() {return pointingUp ? from : to;}
       
  1311             inline int upper() const {return pointingUp ? to : from;}
       
  1312             inline int lower() const {return pointingUp ? from : to;}
       
  1313 
       
  1314             QRBTree<int>::Node *node;
       
  1315             int from, to; // vertex
       
  1316             int next, previous; // edge
       
  1317             int winding;
       
  1318             bool mayIntersect;
       
  1319             bool pointingUp, originallyPointingUp;
       
  1320         };
       
  1321 
       
  1322         friend class CompareEdges;
       
  1323         class CompareEdges
       
  1324         {
       
  1325         public:
       
  1326             inline CompareEdges(ComplexToSimple *parent) : m_parent(parent) { }
       
  1327             bool operator () (int i, int j) const;
       
  1328         private:
       
  1329             ComplexToSimple *m_parent;
       
  1330         };
       
  1331 
       
  1332         struct Intersection
       
  1333         {
       
  1334             bool operator < (const Intersection &other) const {return other.intersectionPoint < intersectionPoint;}
       
  1335 
       
  1336             QIntersectionPoint intersectionPoint;
       
  1337             int vertex;
       
  1338             int leftEdge;
       
  1339             int rightEdge;
       
  1340         };
       
  1341 
       
  1342         struct Split
       
  1343         {
       
  1344             int vertex;
       
  1345             int edge;
       
  1346             bool accurate;
       
  1347         };
       
  1348 
       
  1349         struct Event
       
  1350         {
       
  1351             enum Type {Upper, Lower};
       
  1352             inline bool operator < (const Event &other) const;
       
  1353 
       
  1354             QPodPoint point;
       
  1355             Type type;
       
  1356             int edge;
       
  1357         };
       
  1358 
       
  1359 #ifdef Q_TRIANGULATOR_DEBUG
       
  1360         friend class DebugDialog;
       
  1361         friend class QTriangulator;
       
  1362         class DebugDialog : public QDialog
       
  1363         {
       
  1364         public:
       
  1365             DebugDialog(ComplexToSimple *parent, int currentVertex);
       
  1366         protected:
       
  1367             void paintEvent(QPaintEvent *);
       
  1368             void wheelEvent(QWheelEvent *);
       
  1369             void mouseMoveEvent(QMouseEvent *);
       
  1370             void mousePressEvent(QMouseEvent *);
       
  1371         private:
       
  1372             ComplexToSimple *m_parent;
       
  1373             QRectF m_window;
       
  1374             QPoint m_lastMousePos;
       
  1375             int m_vertex;
       
  1376         };
       
  1377 #endif
       
  1378 
       
  1379         void initEdges();
       
  1380         bool calculateIntersection(int left, int right);
       
  1381         bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
       
  1382         QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex) const;
       
  1383         QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const;
       
  1384         QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> bounds(const QPodPoint &point) const;
       
  1385         QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> outerBounds(const QPodPoint &point) const;
       
  1386         void splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint);
       
  1387         void reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost);
       
  1388         void sortEdgeList(const QPodPoint eventPoint);
       
  1389         void fillPriorityQueue();
       
  1390         void calculateIntersections();
       
  1391         int splitEdge(int splitIndex);
       
  1392         bool splitEdgesAtIntersections();
       
  1393         void insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i);
       
  1394         void removeUnwantedEdgesAndConnect();
       
  1395         void removeUnusedPoints();
       
  1396 
       
  1397         QTriangulator *m_parent;
       
  1398         QDataBuffer<Edge> m_edges;
       
  1399         QRBTree<int> m_edgeList;
       
  1400         QDataBuffer<Event> m_events;
       
  1401         QDataBuffer<Split> m_splits;
       
  1402         QMaxHeap<Intersection> m_topIntersection;
       
  1403         QInt64Set m_processedEdgePairs;
       
  1404         int m_initialPointCount;
       
  1405     };
       
  1406 #ifdef Q_TRIANGULATOR_DEBUG
       
  1407     friend class ComplexToSimple::DebugDialog;
       
  1408 #endif
       
  1409 
       
  1410     //=================================//
       
  1411     // QTriangulator::SimpleToMonotone //
       
  1412     //=================================//
       
  1413     friend class SimpleToMonotone;
       
  1414     class SimpleToMonotone
       
  1415     {
       
  1416     public:
       
  1417         inline SimpleToMonotone(QTriangulator *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { }
       
  1418         void decompose();
       
  1419     private:
       
  1420         enum VertexType {MergeVertex, EndVertex, RegularVertex, StartVertex, SplitVertex};
       
  1421 
       
  1422         struct Edge
       
  1423         {
       
  1424             QRBTree<int>::Node *node;
       
  1425             int helper, twin, next, previous;
       
  1426             quint32 from, to;
       
  1427             VertexType type;
       
  1428             bool pointingUp;
       
  1429             int upper() const {return (pointingUp ? to : from);}
       
  1430             int lower() const {return (pointingUp ? from : to);}
       
  1431         };
       
  1432 
       
  1433         friend class CompareVertices;
       
  1434         class CompareVertices
       
  1435         {
       
  1436         public:
       
  1437             CompareVertices(SimpleToMonotone *parent) : m_parent(parent) { }
       
  1438             bool operator () (int i, int j) const;
       
  1439         private:
       
  1440             SimpleToMonotone *m_parent;
       
  1441         };
       
  1442 
       
  1443         void setupDataStructures();
       
  1444         void removeZeroLengthEdges();
       
  1445         void fillPriorityQueue();
       
  1446         bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
       
  1447         // Returns the rightmost edge not to the right of the given edge.
       
  1448         QRBTree<int>::Node *searchEdgeLeftOfEdge(int edgeIndex) const;
       
  1449         // Returns the rightmost edge left of the given point.
       
  1450         QRBTree<int>::Node *searchEdgeLeftOfPoint(int pointIndex) const;
       
  1451         void classifyVertex(int i);
       
  1452         void classifyVertices();
       
  1453         bool pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3);
       
  1454         bool pointIsInSector(int vertex, int sector);
       
  1455         int findSector(int edge, int vertex);
       
  1456         void createDiagonal(int lower, int upper);
       
  1457         void monotoneDecomposition();
       
  1458 
       
  1459         QTriangulator *m_parent;
       
  1460         QRBTree<int> m_edgeList;
       
  1461         QDataBuffer<Edge> m_edges;
       
  1462         QDataBuffer<int> m_upperVertex;
       
  1463         bool m_clockwiseOrder;
       
  1464     };
       
  1465 
       
  1466     //====================================//
       
  1467     // QTriangulator::MonotoneToTriangles //
       
  1468     //====================================//
       
  1469     friend class MonotoneToTriangles;
       
  1470     class MonotoneToTriangles
       
  1471     {
       
  1472     public:
       
  1473         inline MonotoneToTriangles(QTriangulator *parent) : m_parent(parent) { }
       
  1474         void decompose();
       
  1475     private:
       
  1476         inline quint32 indices(int index) const {return m_parent->m_indices.at(index + m_first);}
       
  1477         inline int next(int index) const {return (index + 1) % m_length;}
       
  1478         inline int previous(int index) const {return (index + m_length - 1) % m_length;}
       
  1479         inline bool less(int i, int j) const {return m_parent->m_vertices.at(indices(i)) < m_parent->m_vertices.at(indices(j));}
       
  1480         inline bool leftOfEdge(int i, int j, int k) const
       
  1481         {
       
  1482             return qPointIsLeftOfLine(m_parent->m_vertices.at(indices(i)),
       
  1483                 m_parent->m_vertices.at(indices(j)), m_parent->m_vertices.at(indices(k)));
       
  1484         }
       
  1485 
       
  1486         QTriangulator *m_parent;
       
  1487         int m_first;
       
  1488         int m_length;
       
  1489     };
       
  1490 
       
  1491     inline QTriangulator() : m_vertices(0) { }
       
  1492 
       
  1493     // Call this only once.
       
  1494     void initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix);
       
  1495     // Call this only once.
       
  1496     void initialize(const QVectorPath &path, const QTransform &matrix, qreal lod);
       
  1497     // Call this only once.
       
  1498     void initialize(const QPainterPath &path, const QTransform &matrix, qreal lod);
       
  1499     // Call either triangulate() or polyline() only once.
       
  1500     QTriangleSet triangulate();
       
  1501     QPolylineSet polyline();
       
  1502 private:
       
  1503     QDataBuffer<QPodPoint> m_vertices;
       
  1504     QVector<quint32> m_indices;
       
  1505     uint m_hint;
       
  1506 };
       
  1507 
       
  1508 //============================================================================//
       
  1509 //                               QTriangulator                                //
       
  1510 //============================================================================//
       
  1511 
       
  1512 QTriangleSet QTriangulator::triangulate()
       
  1513 {
       
  1514     for (int i = 0; i < m_vertices.size(); ++i) {
       
  1515         Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
       
  1516         Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
       
  1517     }
       
  1518 
       
  1519     if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
       
  1520         m_hint |= QVectorPath::OddEvenFill;
       
  1521 
       
  1522     if (m_hint & QVectorPath::NonConvexShapeMask) {
       
  1523         ComplexToSimple c2s(this);
       
  1524         c2s.decompose();
       
  1525         SimpleToMonotone s2m(this);
       
  1526         s2m.decompose();
       
  1527     }
       
  1528     MonotoneToTriangles m2t(this);
       
  1529     m2t.decompose();
       
  1530 
       
  1531     QTriangleSet result;
       
  1532     result.indices = m_indices;
       
  1533     result.vertices.resize(2 * m_vertices.size());
       
  1534     for (int i = 0; i < m_vertices.size(); ++i) {
       
  1535         result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
       
  1536         result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
       
  1537     }
       
  1538     return result;
       
  1539 }
       
  1540 
       
  1541 QPolylineSet QTriangulator::polyline()
       
  1542 {
       
  1543     QPolylineSet result;
       
  1544     result.indices = m_indices;
       
  1545     result.vertices.resize(2 * m_vertices.size());
       
  1546     for (int i = 0; i < m_vertices.size(); ++i) {
       
  1547         result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
       
  1548         result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
       
  1549     }
       
  1550     return result;
       
  1551 }
       
  1552 
       
  1553 void QTriangulator::initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix)
       
  1554 {
       
  1555     m_hint = hint;
       
  1556     m_vertices.resize(count);
       
  1557     m_indices.resize(count + 1);
       
  1558     for (int i = 0; i < count; ++i) {
       
  1559         qreal x, y;
       
  1560         matrix.map(polygon[2 * i + 0], polygon[2 * i + 1], &x, &y);
       
  1561         m_vertices.at(i).x = qRound(x * Q_FIXED_POINT_SCALE);
       
  1562         m_vertices.at(i).y = qRound(y * Q_FIXED_POINT_SCALE);
       
  1563         m_indices[i] = i;
       
  1564     }
       
  1565     m_indices[count] = Q_TRIANGULATE_END_OF_POLYGON;
       
  1566 }
       
  1567 
       
  1568 void QTriangulator::initialize(const QVectorPath &path, const QTransform &matrix, qreal lod)
       
  1569 {
       
  1570     m_hint = path.hints();
       
  1571     // Curved paths will be converted to complex polygons.
       
  1572     m_hint &= ~QVectorPath::CurvedShapeMask;
       
  1573 
       
  1574     const qreal *p = path.points();
       
  1575     const QPainterPath::ElementType *e = path.elements();
       
  1576     if (e) {
       
  1577         for (int i = 0; i < path.elementCount(); ++i, ++e, p += 2) {
       
  1578             switch (*e) {
       
  1579             case QPainterPath::MoveToElement:
       
  1580                 if (!m_indices.isEmpty())
       
  1581                     m_indices.push_back(Q_TRIANGULATE_END_OF_POLYGON);
       
  1582                 // Fall through.
       
  1583             case QPainterPath::LineToElement:
       
  1584                 m_indices.push_back(quint32(m_vertices.size()));
       
  1585                 m_vertices.resize(m_vertices.size() + 1);
       
  1586                 qreal x, y;
       
  1587                 matrix.map(p[0], p[1], &x, &y);
       
  1588                 m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
       
  1589                 m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
       
  1590                 break;
       
  1591             case QPainterPath::CurveToElement:
       
  1592                 {
       
  1593                     qreal pts[8];
       
  1594                     for (int i = 0; i < 4; ++i)
       
  1595                         matrix.map(p[2 * i - 2], p[2 * i - 1], &pts[2 * i + 0], &pts[2 * i + 1]);
       
  1596                     for (int i = 0; i < 8; ++i)
       
  1597                         pts[i] *= lod;
       
  1598                     QBezier bezier = QBezier::fromPoints(QPointF(pts[0], pts[1]), QPointF(pts[2], pts[3]), QPointF(pts[4], pts[5]), QPointF(pts[6], pts[7]));
       
  1599                     QPolygonF poly = bezier.toPolygon();
       
  1600                     // Skip first point, it already exists in 'm_vertices'.
       
  1601                     for (int j = 1; j < poly.size(); ++j) {
       
  1602                         m_indices.push_back(quint32(m_vertices.size()));
       
  1603                         m_vertices.resize(m_vertices.size() + 1);
       
  1604                         m_vertices.last().x = qRound(poly.at(j).x() * Q_FIXED_POINT_SCALE / lod);
       
  1605                         m_vertices.last().y = qRound(poly.at(j).y() * Q_FIXED_POINT_SCALE / lod);
       
  1606                     }
       
  1607                 }
       
  1608                 i += 2;
       
  1609                 e += 2;
       
  1610                 p += 4;
       
  1611                 break;
       
  1612             default:
       
  1613                 Q_ASSERT_X(0, "QTriangulator::triangulate", "Unexpected element type.");
       
  1614                 break;
       
  1615             }
       
  1616         }
       
  1617     } else {
       
  1618         for (int i = 0; i < path.elementCount(); ++i, p += 2) {
       
  1619             m_indices.push_back(quint32(m_vertices.size()));
       
  1620             m_vertices.resize(m_vertices.size() + 1);
       
  1621             qreal x, y;
       
  1622             matrix.map(p[0], p[1], &x, &y);
       
  1623             m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
       
  1624             m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
       
  1625         }
       
  1626     }
       
  1627     m_indices.push_back(Q_TRIANGULATE_END_OF_POLYGON);
       
  1628 }
       
  1629 
       
  1630 void QTriangulator::initialize(const QPainterPath &path, const QTransform &matrix, qreal lod)
       
  1631 {
       
  1632     initialize(qtVectorPathForPath(path), matrix, lod);
       
  1633 }
       
  1634 
       
  1635 //============================================================================//
       
  1636 //                       QTriangulator::ComplexToSimple                       //
       
  1637 //============================================================================//
       
  1638 
       
  1639 void QTriangulator::ComplexToSimple::decompose()
       
  1640 {
       
  1641     m_initialPointCount = m_parent->m_vertices.size();
       
  1642     initEdges();
       
  1643     do {
       
  1644         calculateIntersections();
       
  1645     } while (splitEdgesAtIntersections());
       
  1646 
       
  1647     removeUnwantedEdgesAndConnect();
       
  1648     removeUnusedPoints();
       
  1649 
       
  1650     m_parent->m_indices.clear();
       
  1651     QBitArray processed(m_edges.size(), false);
       
  1652     for (int first = 0; first < m_edges.size(); ++first) {
       
  1653         // If already processed, or if unused path, skip.
       
  1654         if (processed.at(first) || m_edges.at(first).next == -1)
       
  1655             continue;
       
  1656 
       
  1657         int i = first;
       
  1658         do {
       
  1659             Q_ASSERT(!processed.at(i));
       
  1660             Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
       
  1661             m_parent->m_indices.push_back(m_edges.at(i).from);
       
  1662             processed.setBit(i);
       
  1663             i = m_edges.at(i).next; // CCW order
       
  1664         } while (i != first);
       
  1665         m_parent->m_indices.push_back(Q_TRIANGULATE_END_OF_POLYGON);
       
  1666     }
       
  1667 }
       
  1668 
       
  1669 void QTriangulator::ComplexToSimple::initEdges()
       
  1670 {
       
  1671     // Initialize edge structure.
       
  1672     // 'next' and 'previous' are not being initialized at this point.
       
  1673     int first = 0;
       
  1674     for (int i = 0; i < m_parent->m_indices.size(); ++i) {
       
  1675         if (m_parent->m_indices.at(i) == Q_TRIANGULATE_END_OF_POLYGON) {
       
  1676             if (m_edges.size() != first)
       
  1677                 m_edges.last().to = m_edges.at(first).from;
       
  1678             first = m_edges.size();
       
  1679         } else {
       
  1680             Q_ASSERT(i + 1 < m_parent->m_indices.size());
       
  1681             // {node, from, to, next, previous, winding, mayIntersect, pointingUp, originallyPointingUp}
       
  1682             Edge edge = {0, m_parent->m_indices.at(i), m_parent->m_indices.at(i + 1), -1, -1, 0, true, false, false};
       
  1683             m_edges.add(edge);
       
  1684         }
       
  1685     }
       
  1686     if (first != m_edges.size())
       
  1687         m_edges.last().to = m_edges.at(first).from;
       
  1688     for (int i = 0; i < m_edges.size(); ++i) {
       
  1689         m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp = 
       
  1690             m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
       
  1691     }
       
  1692 }
       
  1693 
       
  1694 // Return true if new intersection was found
       
  1695 bool QTriangulator::ComplexToSimple::calculateIntersection(int left, int right)
       
  1696 {
       
  1697     const Edge &e1 = m_edges.at(left);
       
  1698     const Edge &e2 = m_edges.at(right);
       
  1699 
       
  1700     const QPodPoint &u1 = m_parent->m_vertices.at(e1.from);
       
  1701     const QPodPoint &u2 = m_parent->m_vertices.at(e1.to);
       
  1702     const QPodPoint &v1 = m_parent->m_vertices.at(e2.from);
       
  1703     const QPodPoint &v2 = m_parent->m_vertices.at(e2.to);
       
  1704     if (qMax(u1.x, u2.x) <= qMin(v1.x, v2.x))
       
  1705         return false;
       
  1706 
       
  1707     quint64 key = (left > right ? (quint64(right) << 32) | quint64(left) : (quint64(left) << 32) | quint64(right));
       
  1708     if (m_processedEdgePairs.contains(key))
       
  1709         return false;
       
  1710     m_processedEdgePairs.insert(key);
       
  1711 
       
  1712     Intersection intersection;
       
  1713     intersection.leftEdge = left;
       
  1714     intersection.rightEdge = right;
       
  1715     intersection.intersectionPoint = qIntersectionPoint(u1, u2, v1, v2);
       
  1716 
       
  1717     if (!intersection.intersectionPoint.isValid())
       
  1718         return false;
       
  1719 
       
  1720     Q_ASSERT(intersection.intersectionPoint.isOnLine(u1, u2));
       
  1721     Q_ASSERT(intersection.intersectionPoint.isOnLine(v1, v2));
       
  1722 
       
  1723     intersection.vertex = m_parent->m_vertices.size();
       
  1724     m_topIntersection.push(intersection);
       
  1725     m_parent->m_vertices.add(intersection.intersectionPoint.round());
       
  1726     return true;
       
  1727 }
       
  1728 
       
  1729 bool QTriangulator::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
       
  1730 {
       
  1731     const Edge &leftEdge = m_edges.at(leftEdgeIndex);
       
  1732     const Edge &rightEdge = m_edges.at(rightEdgeIndex);
       
  1733     const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
       
  1734     const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
       
  1735     const QPodPoint &upper = m_parent->m_vertices.at(leftEdge.upper());
       
  1736     if (upper.x < qMin(l.x, u.x))
       
  1737         return true;
       
  1738     if (upper.x > qMax(l.x, u.x))
       
  1739         return false;
       
  1740     qint64 d = qPointDistanceFromLine(upper, l, u);
       
  1741     // d < 0: left, d > 0: right, d == 0: on top
       
  1742     if (d == 0)
       
  1743         d = qPointDistanceFromLine(m_parent->m_vertices.at(leftEdge.lower()), l, u);
       
  1744     return d < 0;
       
  1745 }
       
  1746 
       
  1747 QRBTree<int>::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
       
  1748 {
       
  1749     QRBTree<int>::Node *current = m_edgeList.root;
       
  1750     QRBTree<int>::Node *result = 0;
       
  1751     while (current) {
       
  1752         if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
       
  1753             current = current->left;
       
  1754         } else {
       
  1755             result = current;
       
  1756             current = current->right;
       
  1757         }
       
  1758     }
       
  1759     return result;
       
  1760 }
       
  1761 
       
  1762 QRBTree<int>::Node *QTriangulator::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
       
  1763 {
       
  1764     if (!m_edgeList.root)
       
  1765         return after;
       
  1766     QRBTree<int>::Node *result = after;
       
  1767     QRBTree<int>::Node *current = (after ? m_edgeList.next(after) : m_edgeList.front(m_edgeList.root));
       
  1768     while (current) {
       
  1769         if (edgeIsLeftOfEdge(edgeIndex, current->data))
       
  1770             return result;
       
  1771         result = current;
       
  1772         current = m_edgeList.next(current);
       
  1773     }
       
  1774     return result;
       
  1775 }
       
  1776 
       
  1777 QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator::ComplexToSimple::bounds(const QPodPoint &point) const
       
  1778 {
       
  1779     QRBTree<int>::Node *current = m_edgeList.root;
       
  1780     QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
       
  1781     while (current) {
       
  1782         const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
       
  1783         const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
       
  1784         qint64 d = qPointDistanceFromLine(point, v1, v2);
       
  1785         if (d == 0) {
       
  1786             result.first = result.second = current;
       
  1787             break;
       
  1788         }
       
  1789         current = (d < 0 ? current->left : current->right);
       
  1790     }
       
  1791     if (current == 0)
       
  1792         return result;
       
  1793 
       
  1794     current = result.first->left;
       
  1795     while (current) {
       
  1796         const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
       
  1797         const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
       
  1798         qint64 d = qPointDistanceFromLine(point, v1, v2);
       
  1799         Q_ASSERT(d >= 0);
       
  1800         if (d == 0) {
       
  1801             result.first = current;
       
  1802             current = current->left;
       
  1803         } else {
       
  1804             current = current->right;
       
  1805         }
       
  1806     }
       
  1807 
       
  1808     current = result.second->right;
       
  1809     while (current) {
       
  1810         const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
       
  1811         const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
       
  1812         qint64 d = qPointDistanceFromLine(point, v1, v2);
       
  1813         Q_ASSERT(d <= 0);
       
  1814         if (d == 0) {
       
  1815             result.second = current;
       
  1816             current = current->right;
       
  1817         } else {
       
  1818             current = current->left;
       
  1819         }
       
  1820     }
       
  1821 
       
  1822     return result;
       
  1823 }
       
  1824 
       
  1825 QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator::ComplexToSimple::outerBounds(const QPodPoint &point) const
       
  1826 {
       
  1827     QRBTree<int>::Node *current = m_edgeList.root;
       
  1828     QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
       
  1829 
       
  1830     while (current) {
       
  1831         const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
       
  1832         const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
       
  1833         qint64 d = qPointDistanceFromLine(point, v1, v2);
       
  1834         if (d == 0)
       
  1835             break;
       
  1836         if (d < 0) {
       
  1837             result.second = current;
       
  1838             current = current->left;
       
  1839         } else {
       
  1840             result.first = current;
       
  1841             current = current->right;
       
  1842         }
       
  1843     }
       
  1844 
       
  1845     if (!current)
       
  1846         return result;
       
  1847 
       
  1848     QRBTree<int>::Node *mid = current;
       
  1849 
       
  1850     current = mid->left;
       
  1851     while (current) {
       
  1852         const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
       
  1853         const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
       
  1854         qint64 d = qPointDistanceFromLine(point, v1, v2);
       
  1855         Q_ASSERT(d >= 0);
       
  1856         if (d == 0) {
       
  1857             current = current->left;
       
  1858         } else {
       
  1859             result.first = current;
       
  1860             current = current->right;
       
  1861         }
       
  1862     }
       
  1863 
       
  1864     current = mid->right;
       
  1865     while (current) {
       
  1866         const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
       
  1867         const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
       
  1868         qint64 d = qPointDistanceFromLine(point, v1, v2);
       
  1869         Q_ASSERT(d <= 0);
       
  1870         if (d == 0) {
       
  1871             current = current->right;
       
  1872         } else {
       
  1873             result.second = current;
       
  1874             current = current->left;
       
  1875         }
       
  1876     }
       
  1877 
       
  1878     return result;
       
  1879 }
       
  1880 
       
  1881 void QTriangulator::ComplexToSimple::splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint)
       
  1882 {
       
  1883     Q_ASSERT(leftmost && rightmost);
       
  1884 
       
  1885     // Split.
       
  1886     for (;;) {
       
  1887         const QPodPoint &u = m_parent->m_vertices.at(m_edges.at(leftmost->data).from);
       
  1888         const QPodPoint &v = m_parent->m_vertices.at(m_edges.at(leftmost->data).to);
       
  1889         Q_ASSERT(intersectionPoint.isOnLine(u, v));
       
  1890         const Split split = {vertex, leftmost->data, intersectionPoint.isAccurate()};
       
  1891         if (intersectionPoint.xOffset.numerator != 0 || intersectionPoint.yOffset.numerator != 0 || (intersectionPoint.upperLeft != u && intersectionPoint.upperLeft != v))
       
  1892             m_splits.add(split);
       
  1893         if (leftmost == rightmost)
       
  1894             break;
       
  1895         leftmost = m_edgeList.next(leftmost);
       
  1896     }
       
  1897 }
       
  1898 
       
  1899 
       
  1900 void QTriangulator::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost)
       
  1901 {
       
  1902     Q_ASSERT(leftmost && rightmost);
       
  1903 
       
  1904     QRBTree<int>::Node *storeLeftmost = leftmost;
       
  1905     QRBTree<int>::Node *storeRightmost = rightmost;
       
  1906 
       
  1907     // Reorder.
       
  1908     while (leftmost != rightmost) {
       
  1909         Edge &left = m_edges.at(leftmost->data);
       
  1910         Edge &right = m_edges.at(rightmost->data);
       
  1911         qSwap(left.node, right.node);
       
  1912         qSwap(leftmost->data, rightmost->data);
       
  1913         leftmost = m_edgeList.next(leftmost);
       
  1914         if (leftmost == rightmost)
       
  1915             break;
       
  1916         rightmost = m_edgeList.previous(rightmost);
       
  1917     }
       
  1918 
       
  1919     rightmost = m_edgeList.next(storeRightmost);
       
  1920     leftmost = m_edgeList.previous(storeLeftmost);
       
  1921     if (leftmost)
       
  1922         calculateIntersection(leftmost->data, storeLeftmost->data);
       
  1923     if (rightmost)
       
  1924         calculateIntersection(storeRightmost->data, rightmost->data);
       
  1925 }
       
  1926 
       
  1927 void QTriangulator::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
       
  1928 {
       
  1929     QIntersectionPoint eventPoint2 = qIntersectionPoint(eventPoint);
       
  1930     while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint < eventPoint2) {
       
  1931         Intersection intersection = m_topIntersection.pop();
       
  1932 
       
  1933         QIntersectionPoint currentIntersectionPoint = intersection.intersectionPoint;
       
  1934         int currentVertex = intersection.vertex;
       
  1935 
       
  1936         QRBTree<int>::Node *leftmost = m_edges.at(intersection.leftEdge).node;
       
  1937         QRBTree<int>::Node *rightmost = m_edges.at(intersection.rightEdge).node;
       
  1938 
       
  1939         for (;;) {
       
  1940             QRBTree<int>::Node *previous = m_edgeList.previous(leftmost);
       
  1941             if (!previous)
       
  1942                 break;
       
  1943             const Edge &edge = m_edges.at(previous->data);
       
  1944             const QPodPoint &u = m_parent->m_vertices.at(edge.from);
       
  1945             const QPodPoint &v = m_parent->m_vertices.at(edge.to);
       
  1946             if (!currentIntersectionPoint.isOnLine(u, v)) {
       
  1947                 Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
       
  1948                 break;
       
  1949             }
       
  1950             leftmost = previous;
       
  1951         }
       
  1952 
       
  1953         for (;;) {
       
  1954             QRBTree<int>::Node *next = m_edgeList.next(rightmost);
       
  1955             if (!next)
       
  1956                 break;
       
  1957             const Edge &edge = m_edges.at(next->data);
       
  1958             const QPodPoint &u = m_parent->m_vertices.at(edge.from);
       
  1959             const QPodPoint &v = m_parent->m_vertices.at(edge.to);
       
  1960             if (!currentIntersectionPoint.isOnLine(u, v)) {
       
  1961                 Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
       
  1962                 break;
       
  1963             }
       
  1964             rightmost = next;
       
  1965         }
       
  1966 
       
  1967         Q_ASSERT(leftmost && rightmost);
       
  1968         splitEdgeListRange(leftmost, rightmost, currentVertex, currentIntersectionPoint);
       
  1969         reorderEdgeListRange(leftmost, rightmost);
       
  1970 
       
  1971         while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= currentIntersectionPoint)
       
  1972             m_topIntersection.pop();
       
  1973 
       
  1974 #ifdef Q_TRIANGULATOR_DEBUG
       
  1975         DebugDialog dialog(this, intersection.vertex);
       
  1976         dialog.exec();
       
  1977 #endif
       
  1978 
       
  1979     }
       
  1980 }
       
  1981 
       
  1982 void QTriangulator::ComplexToSimple::fillPriorityQueue()
       
  1983 {
       
  1984     m_events.reset();
       
  1985     m_events.reserve(m_edges.size() * 2);
       
  1986     for (int i = 0; i < m_edges.size(); ++i) {
       
  1987         Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
       
  1988         Q_ASSERT(m_edges.at(i).node == 0);
       
  1989         Q_ASSERT(m_edges.at(i).pointingUp == m_edges.at(i).originallyPointingUp);
       
  1990         Q_ASSERT(m_edges.at(i).pointingUp == (m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from)));
       
  1991         // Ignore zero-length edges.
       
  1992         if (m_parent->m_vertices.at(m_edges.at(i).to) != m_parent->m_vertices.at(m_edges.at(i).from)) {
       
  1993             QPodPoint upper = m_parent->m_vertices.at(m_edges.at(i).upper());
       
  1994             QPodPoint lower = m_parent->m_vertices.at(m_edges.at(i).lower());
       
  1995             Event upperEvent = {{upper.x, upper.y}, Event::Upper, i};
       
  1996             Event lowerEvent = {{lower.x, lower.y}, Event::Lower, i};
       
  1997             m_events.add(upperEvent);
       
  1998             m_events.add(lowerEvent);
       
  1999         }
       
  2000     }
       
  2001     //qSort(m_events.data(), m_events.data() + m_events.size());
       
  2002     sort(m_events.data(), m_events.size());
       
  2003 }
       
  2004 
       
  2005 void QTriangulator::ComplexToSimple::calculateIntersections()
       
  2006 {
       
  2007     fillPriorityQueue();
       
  2008 
       
  2009     Q_ASSERT(m_topIntersection.empty());
       
  2010     Q_ASSERT(m_edgeList.root == 0);
       
  2011 
       
  2012     // Find all intersection points.
       
  2013     while (!m_events.isEmpty()) {
       
  2014         Event event = m_events.last();
       
  2015         sortEdgeList(event.point);
       
  2016 
       
  2017         // Find all edges in the edge list that contain the current vertex and mark them to be split later.
       
  2018         QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> range = bounds(event.point);
       
  2019         QRBTree<int>::Node *leftNode = range.first ? m_edgeList.previous(range.first) : 0;
       
  2020         int vertex = (event.type == Event::Upper ? m_edges.at(event.edge).upper() : m_edges.at(event.edge).lower());
       
  2021         QIntersectionPoint eventPoint = qIntersectionPoint(event.point);
       
  2022 
       
  2023         if (range.first != 0) {
       
  2024             splitEdgeListRange(range.first, range.second, vertex, eventPoint);
       
  2025             reorderEdgeListRange(range.first, range.second);
       
  2026         }
       
  2027 
       
  2028         // Handle the edges with start or end point in the current vertex.
       
  2029         while (!m_events.isEmpty() && m_events.last().point == event.point) {
       
  2030             event = m_events.last();
       
  2031             m_events.pop_back();
       
  2032             int i = event.edge;
       
  2033 
       
  2034             if (m_edges.at(i).node) {
       
  2035                 // Remove edge from edge list.
       
  2036                 Q_ASSERT(event.type == Event::Lower);
       
  2037                 QRBTree<int>::Node *left = m_edgeList.previous(m_edges.at(i).node);
       
  2038                 QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
       
  2039                 m_edgeList.deleteNode(m_edges.at(i).node);
       
  2040                 if (!left || !right)
       
  2041                     continue;
       
  2042                 calculateIntersection(left->data, right->data);
       
  2043             } else {
       
  2044                 // Insert edge into edge list.
       
  2045                 Q_ASSERT(event.type == Event::Upper);
       
  2046                 QRBTree<int>::Node *left = searchEdgeLeftOf(i, leftNode);
       
  2047                 m_edgeList.attachAfter(left, m_edges.at(i).node = m_edgeList.newNode());
       
  2048                 m_edges.at(i).node->data = i;
       
  2049                 QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
       
  2050                 if (left)
       
  2051                     calculateIntersection(left->data, i);
       
  2052                 if (right)
       
  2053                     calculateIntersection(i, right->data);
       
  2054             }
       
  2055         }
       
  2056         while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= eventPoint)
       
  2057             m_topIntersection.pop();
       
  2058 #ifdef Q_TRIANGULATOR_DEBUG
       
  2059         DebugDialog dialog(this, vertex);
       
  2060         dialog.exec();
       
  2061 #endif
       
  2062     }
       
  2063     m_processedEdgePairs.clear();
       
  2064 }
       
  2065 
       
  2066 // Split an edge into two pieces at the given point.
       
  2067 // The upper piece is pushed to the end of the 'm_edges' vector.
       
  2068 // The lower piece replaces the old edge.
       
  2069 // Return the edge whose 'from' is 'pointIndex'.
       
  2070 int QTriangulator::ComplexToSimple::splitEdge(int splitIndex)
       
  2071 {
       
  2072     const Split &split = m_splits.at(splitIndex);
       
  2073     Edge &lowerEdge = m_edges.at(split.edge);
       
  2074     Q_ASSERT(lowerEdge.node == 0);
       
  2075     Q_ASSERT(lowerEdge.previous == -1 && lowerEdge.next == -1);
       
  2076 
       
  2077     if (lowerEdge.from == split.vertex)
       
  2078         return split.edge;
       
  2079     if (lowerEdge.to == split.vertex)
       
  2080         return lowerEdge.next;
       
  2081 
       
  2082     // Check that angle >= 90 degrees.
       
  2083     //Q_ASSERT(qDot(m_points.at(m_edges.at(edgeIndex).from) - m_points.at(pointIndex),
       
  2084     //    m_points.at(m_edges.at(edgeIndex).to) - m_points.at(pointIndex)) <= 0);
       
  2085 
       
  2086     Edge upperEdge = lowerEdge;
       
  2087     upperEdge.mayIntersect |= !split.accurate; // The edge may have been split before at an inaccurate split point.
       
  2088     lowerEdge.mayIntersect = !split.accurate;
       
  2089     if (lowerEdge.pointingUp) {
       
  2090         lowerEdge.to = upperEdge.from = split.vertex;
       
  2091         m_edges.add(upperEdge);
       
  2092         return m_edges.size() - 1;
       
  2093     } else {
       
  2094         lowerEdge.from = upperEdge.to = split.vertex;
       
  2095         m_edges.add(upperEdge);
       
  2096         return split.edge;
       
  2097     }
       
  2098 }
       
  2099 
       
  2100 bool QTriangulator::ComplexToSimple::splitEdgesAtIntersections()
       
  2101 {
       
  2102     for (int i = 0; i < m_edges.size(); ++i)
       
  2103         m_edges.at(i).mayIntersect = false;
       
  2104     bool checkForNewIntersections = false;
       
  2105     for (int i = 0; i < m_splits.size(); ++i) {
       
  2106         splitEdge(i);
       
  2107         checkForNewIntersections |= !m_splits.at(i).accurate;
       
  2108     }
       
  2109     for (int i = 0; i < m_edges.size(); ++i) {
       
  2110         m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
       
  2111             m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
       
  2112     }
       
  2113     m_splits.reset();
       
  2114     return checkForNewIntersections;
       
  2115 }
       
  2116 
       
  2117 void QTriangulator::ComplexToSimple::insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i)
       
  2118 {
       
  2119     // Edges with zero length should not reach this part.
       
  2120     Q_ASSERT(m_parent->m_vertices.at(m_edges.at(i).from) != m_parent->m_vertices.at(m_edges.at(i).to));
       
  2121 
       
  2122     // Skip edges with unwanted winding number.
       
  2123     int windingNumber = m_edges.at(i).winding;
       
  2124     if (m_edges.at(i).originallyPointingUp)
       
  2125         ++windingNumber;
       
  2126 
       
  2127     // Make sure exactly one fill rule is specified.
       
  2128     Q_ASSERT(((m_parent->m_hint & QVectorPath::WindingFill) != 0) != ((m_parent->m_hint & QVectorPath::OddEvenFill) != 0));
       
  2129 
       
  2130     if ((m_parent->m_hint & QVectorPath::WindingFill) && windingNumber != 0 && windingNumber != 1)
       
  2131         return;
       
  2132 
       
  2133     // Skip cancelling edges.
       
  2134     if (!orderedEdges.isEmpty()) {
       
  2135         int j = orderedEdges[orderedEdges.size() - 1];
       
  2136         // If the last edge is already connected in one end, it should not be cancelled.
       
  2137         if (m_edges.at(j).next == -1 && m_edges.at(j).previous == -1
       
  2138             && (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(j).to))
       
  2139             && (m_parent->m_vertices.at(m_edges.at(i).to) == m_parent->m_vertices.at(m_edges.at(j).from))) {
       
  2140             orderedEdges.removeLast();
       
  2141             return;
       
  2142         }
       
  2143     }
       
  2144     orderedEdges.append(i);
       
  2145 }
       
  2146 
       
  2147 void QTriangulator::ComplexToSimple::removeUnwantedEdgesAndConnect()
       
  2148 {
       
  2149     Q_ASSERT(m_edgeList.root == 0);
       
  2150     // Initialize priority queue.
       
  2151     fillPriorityQueue();
       
  2152 
       
  2153     ShortArray orderedEdges;
       
  2154 
       
  2155     while (!m_events.isEmpty()) {
       
  2156         Event event = m_events.last();
       
  2157         int edgeIndex = event.edge;
       
  2158 
       
  2159         // Check that all the edges in the list crosses the current scanline
       
  2160         //if (m_edgeList.root) {
       
  2161         //    for (QRBTree<int>::Node *node = m_edgeList.front(m_edgeList.root); node; node = m_edgeList.next(node)) {
       
  2162         //        Q_ASSERT(event.point <= m_points.at(m_edges.at(node->data).lower()));
       
  2163         //    }
       
  2164         //}
       
  2165 
       
  2166         orderedEdges.clear();
       
  2167         QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> b = outerBounds(event.point);
       
  2168         if (m_edgeList.root) {
       
  2169             QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
       
  2170             // Process edges that are going to be removed from the edge list at the current event point.
       
  2171             while (current != b.second) {
       
  2172                 Q_ASSERT(current);
       
  2173                 Q_ASSERT(m_edges.at(current->data).node == current);
       
  2174                 Q_ASSERT(qIntersectionPoint(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(m_edges.at(current->data).to)));
       
  2175                 Q_ASSERT(m_parent->m_vertices.at(m_edges.at(current->data).from) == event.point || m_parent->m_vertices.at(m_edges.at(current->data).to) == event.point);
       
  2176                 insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
       
  2177                 current = m_edgeList.next(current);
       
  2178             }
       
  2179         }
       
  2180 
       
  2181         // Remove edges above the event point, insert edges below the event point.
       
  2182         do {
       
  2183             event = m_events.last();
       
  2184             m_events.pop_back();
       
  2185             edgeIndex = event.edge;
       
  2186 
       
  2187             // Edges with zero length should not reach this part.
       
  2188             Q_ASSERT(m_parent->m_vertices.at(m_edges.at(edgeIndex).from) != m_parent->m_vertices.at(m_edges.at(edgeIndex).to));
       
  2189 
       
  2190             if (m_edges.at(edgeIndex).node) {
       
  2191                 Q_ASSERT(event.type == Event::Lower);
       
  2192                 Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).lower()));
       
  2193                 m_edgeList.deleteNode(m_edges.at(edgeIndex).node);
       
  2194             } else {
       
  2195                 Q_ASSERT(event.type == Event::Upper);
       
  2196                 Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).upper()));
       
  2197                 QRBTree<int>::Node *left = searchEdgeLeftOf(edgeIndex, b.first);
       
  2198                 m_edgeList.attachAfter(left, m_edges.at(edgeIndex).node = m_edgeList.newNode());
       
  2199                 m_edges.at(edgeIndex).node->data = edgeIndex;
       
  2200             }
       
  2201         } while (!m_events.isEmpty() && m_events.last().point == event.point);
       
  2202 
       
  2203         if (m_edgeList.root) {
       
  2204             QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
       
  2205 
       
  2206             // Calculate winding number and turn counter-clockwise.
       
  2207             int currentWindingNumber = (b.first ? m_edges.at(b.first->data).winding : 0);
       
  2208             while (current != b.second) {
       
  2209                 Q_ASSERT(current);
       
  2210                 //Q_ASSERT(b.second == 0 || m_edgeList.order(current, b.second) < 0);
       
  2211                 int i = current->data;
       
  2212                 Q_ASSERT(m_edges.at(i).node == current);
       
  2213 
       
  2214                 // Winding number.
       
  2215                 int ccwWindingNumber = m_edges.at(i).winding = currentWindingNumber;
       
  2216                 if (m_edges.at(i).originallyPointingUp) {
       
  2217                     --m_edges.at(i).winding;
       
  2218                 } else {
       
  2219                     ++m_edges.at(i).winding;
       
  2220                     ++ccwWindingNumber;
       
  2221                 }
       
  2222                 currentWindingNumber = m_edges.at(i).winding;
       
  2223 
       
  2224                 // Turn counter-clockwise.
       
  2225                 if ((ccwWindingNumber & 1) == 0) {
       
  2226                     Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
       
  2227                     qSwap(m_edges.at(i).from, m_edges.at(i).to);
       
  2228                     m_edges.at(i).pointingUp = !m_edges.at(i).pointingUp;
       
  2229                 }
       
  2230 
       
  2231                 current = m_edgeList.next(current);
       
  2232             }
       
  2233 
       
  2234             // Process edges that were inserted into the edge list at the current event point.
       
  2235             current = (b.second ? m_edgeList.previous(b.second) : m_edgeList.back(m_edgeList.root));
       
  2236             while (current != b.first) {
       
  2237                 Q_ASSERT(current);
       
  2238                 Q_ASSERT(m_edges.at(current->data).node == current);
       
  2239                 insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
       
  2240                 current = m_edgeList.previous(current);
       
  2241             }
       
  2242         }
       
  2243         if (orderedEdges.isEmpty())
       
  2244             continue;
       
  2245 
       
  2246         Q_ASSERT((orderedEdges.size() & 1) == 0);
       
  2247 
       
  2248         // Connect edges.
       
  2249         // First make sure the first edge point towards the current point.
       
  2250         int i;
       
  2251         if (m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).from) == event.point) {
       
  2252             i = 1;
       
  2253             int copy = orderedEdges[0]; // Make copy in case the append() will cause a reallocation.
       
  2254             orderedEdges.append(copy);
       
  2255         } else {
       
  2256             Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).to) == event.point);
       
  2257             i = 0;
       
  2258         }
       
  2259 
       
  2260         // Remove references to duplicate points. First find the point with lowest index.
       
  2261         int pointIndex = INT_MAX;
       
  2262         for (int j = i; j < orderedEdges.size(); j += 2) {
       
  2263             Q_ASSERT(j + 1 < orderedEdges.size());
       
  2264             Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j]).to) == event.point);
       
  2265             Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j + 1]).from) == event.point);
       
  2266             if (m_edges.at(orderedEdges[j]).to < pointIndex)
       
  2267                 pointIndex = m_edges.at(orderedEdges[j]).to;
       
  2268             if (m_edges.at(orderedEdges[j + 1]).from < pointIndex)
       
  2269                 pointIndex = m_edges.at(orderedEdges[j + 1]).from;
       
  2270         }
       
  2271 
       
  2272         for (; i < orderedEdges.size(); i += 2) {
       
  2273             // Remove references to duplicate points by making all edges reference one common point.
       
  2274             m_edges.at(orderedEdges[i]).to = m_edges.at(orderedEdges[i + 1]).from = pointIndex;
       
  2275 
       
  2276             Q_ASSERT(m_edges.at(orderedEdges[i]).pointingUp || m_edges.at(orderedEdges[i]).previous != -1);
       
  2277             Q_ASSERT(!m_edges.at(orderedEdges[i + 1]).pointingUp || m_edges.at(orderedEdges[i + 1]).next != -1);
       
  2278 
       
  2279             m_edges.at(orderedEdges[i]).next = orderedEdges[i + 1];
       
  2280             m_edges.at(orderedEdges[i + 1]).previous = orderedEdges[i];
       
  2281         }
       
  2282     } // end while
       
  2283 }
       
  2284 
       
  2285 void QTriangulator::ComplexToSimple::removeUnusedPoints() {
       
  2286     QBitArray used(m_parent->m_vertices.size(), false);
       
  2287     for (int i = 0; i < m_edges.size(); ++i) {
       
  2288         Q_ASSERT((m_edges.at(i).previous == -1) == (m_edges.at(i).next == -1));
       
  2289         if (m_edges.at(i).next != -1)
       
  2290             used.setBit(m_edges.at(i).from);
       
  2291     }
       
  2292     QDataBuffer<quint32> newMapping(m_parent->m_vertices.size());
       
  2293     newMapping.resize(m_parent->m_vertices.size());
       
  2294     int count = 0;
       
  2295     for (int i = 0; i < m_parent->m_vertices.size(); ++i) {
       
  2296         if (used.at(i)) {
       
  2297             m_parent->m_vertices.at(count) = m_parent->m_vertices.at(i);
       
  2298             newMapping.at(i) = count;
       
  2299             ++count;
       
  2300         }
       
  2301     }
       
  2302     m_parent->m_vertices.resize(count);
       
  2303     for (int i = 0; i < m_edges.size(); ++i) {
       
  2304         m_edges.at(i).from = newMapping.at(m_edges.at(i).from);
       
  2305         m_edges.at(i).to = newMapping.at(m_edges.at(i).to);
       
  2306     }
       
  2307 }
       
  2308 
       
  2309 bool QTriangulator::ComplexToSimple::CompareEdges::operator () (int i, int j) const
       
  2310 {
       
  2311     int cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from),
       
  2312         m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from));
       
  2313     if (cmp == 0) {
       
  2314         cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).to),
       
  2315             m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).to));
       
  2316     }
       
  2317     return cmp > 0;
       
  2318 }
       
  2319 
       
  2320 inline bool QTriangulator::ComplexToSimple::Event::operator < (const Event &other) const
       
  2321 {
       
  2322     if (point == other.point)
       
  2323         return type < other.type; // 'Lower' has higher priority than 'Upper'.
       
  2324     return other.point < point;
       
  2325 }
       
  2326 
       
  2327 //============================================================================//
       
  2328 //                QTriangulator::ComplexToSimple::DebugDialog                 //
       
  2329 //============================================================================//
       
  2330 
       
  2331 #ifdef Q_TRIANGULATOR_DEBUG
       
  2332 
       
  2333 QTriangulator::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent, int currentVertex)
       
  2334     : m_parent(parent), m_vertex(currentVertex)
       
  2335 {
       
  2336     QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
       
  2337     if (vertices.isEmpty())
       
  2338         return;
       
  2339     
       
  2340     int minX, maxX, minY, maxY;
       
  2341     minX = maxX = vertices.at(0).x;
       
  2342     minY = maxY = vertices.at(0).y;
       
  2343     for (int i = 1; i < vertices.size(); ++i) {
       
  2344         minX = qMin(minX, vertices.at(i).x);
       
  2345         maxX = qMax(maxX, vertices.at(i).x);
       
  2346         minY = qMin(minY, vertices.at(i).y);
       
  2347         maxY = qMax(maxY, vertices.at(i).y);
       
  2348     }
       
  2349     int w = maxX - minX;
       
  2350     int h = maxY - minY;
       
  2351     qreal border = qMin(w, h) / 10.0;
       
  2352     m_window = QRectF(minX - border, minY - border, (maxX - minX + 2 * border), (maxY - minY + 2 * border));
       
  2353 }
       
  2354 
       
  2355 void QTriangulator::ComplexToSimple::DebugDialog::paintEvent(QPaintEvent *)
       
  2356 {
       
  2357     QPainter p(this);
       
  2358     p.setRenderHint(QPainter::Antialiasing, true);
       
  2359     p.fillRect(rect(), Qt::black);
       
  2360     QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
       
  2361     if (vertices.isEmpty())
       
  2362         return;
       
  2363     
       
  2364     qreal halfPointSize = qMin(m_window.width(), m_window.height()) / 300.0;
       
  2365     p.setWindow(m_window.toRect());
       
  2366 
       
  2367     p.setPen(Qt::white);
       
  2368 
       
  2369     QDataBuffer<Edge> &edges = m_parent->m_edges;
       
  2370     for (int i = 0; i < edges.size(); ++i) {
       
  2371         QPodPoint u = vertices.at(edges.at(i).from);
       
  2372         QPodPoint v = vertices.at(edges.at(i).to);
       
  2373         p.drawLine(u.x, u.y, v.x, v.y);
       
  2374     }
       
  2375 
       
  2376     for (int i = 0; i < vertices.size(); ++i) {
       
  2377         QPodPoint q = vertices.at(i);
       
  2378         p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::red);
       
  2379     }
       
  2380 
       
  2381     Qt::GlobalColor colors[6] = {Qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow};
       
  2382     p.setOpacity(0.5);
       
  2383     int count = 0;
       
  2384     if (m_parent->m_edgeList.root) {
       
  2385         QRBTree<int>::Node *current = m_parent->m_edgeList.front(m_parent->m_edgeList.root);
       
  2386         while (current) {
       
  2387             p.setPen(colors[count++ % 6]);
       
  2388             QPodPoint u = vertices.at(edges.at(current->data).from);
       
  2389             QPodPoint v = vertices.at(edges.at(current->data).to);
       
  2390             p.drawLine(u.x, u.y, v.x, v.y);
       
  2391             current = m_parent->m_edgeList.next(current);
       
  2392         }
       
  2393     }
       
  2394 
       
  2395     p.setOpacity(1.0);
       
  2396     QPodPoint q = vertices.at(m_vertex);
       
  2397     p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::green);
       
  2398 
       
  2399     p.setPen(Qt::gray);
       
  2400     QDataBuffer<Split> &splits = m_parent->m_splits;
       
  2401     for (int i = 0; i < splits.size(); ++i) {
       
  2402         QPodPoint q = vertices.at(splits.at(i).vertex);
       
  2403         QPodPoint u = vertices.at(edges.at(splits.at(i).edge).from) - q;
       
  2404         QPodPoint v = vertices.at(edges.at(splits.at(i).edge).to) - q;
       
  2405         qreal uLen = sqrt(qreal(qDot(u, u)));
       
  2406         qreal vLen = sqrt(qreal(qDot(v, v)));
       
  2407         if (uLen) {
       
  2408             u.x *= 2 * halfPointSize / uLen;
       
  2409             u.y *= 2 * halfPointSize / uLen;
       
  2410         }
       
  2411         if (vLen) {
       
  2412             v.x *= 2 * halfPointSize / vLen;
       
  2413             v.y *= 2 * halfPointSize / vLen;
       
  2414         }
       
  2415         u += q;
       
  2416         v += q;
       
  2417         p.drawLine(u.x, u.y, v.x, v.y);        
       
  2418     }
       
  2419 }
       
  2420 
       
  2421 void QTriangulator::ComplexToSimple::DebugDialog::wheelEvent(QWheelEvent *event)
       
  2422 {
       
  2423     qreal scale = exp(-0.001 * event->delta());
       
  2424     QPointF center = m_window.center();
       
  2425     QPointF delta = scale * (m_window.bottomRight() - center);
       
  2426     m_window = QRectF(center - delta, center + delta);
       
  2427     event->accept();
       
  2428     update();
       
  2429 }
       
  2430 
       
  2431 void QTriangulator::ComplexToSimple::DebugDialog::mouseMoveEvent(QMouseEvent *event)
       
  2432 {
       
  2433     if (event->buttons() & Qt::LeftButton) {
       
  2434         QPointF delta = event->pos() - m_lastMousePos;
       
  2435         delta.setX(delta.x() * m_window.width() / width());
       
  2436         delta.setY(delta.y() * m_window.height() / height());
       
  2437         m_window.translate(-delta.x(), -delta.y());
       
  2438         m_lastMousePos = event->pos();
       
  2439         event->accept();
       
  2440         update();
       
  2441     }
       
  2442 }
       
  2443 
       
  2444 void QTriangulator::ComplexToSimple::DebugDialog::mousePressEvent(QMouseEvent *event)
       
  2445 {
       
  2446     if (event->button() == Qt::LeftButton)
       
  2447         m_lastMousePos = event->pos();
       
  2448     event->accept();
       
  2449 }
       
  2450 
       
  2451 
       
  2452 #endif
       
  2453 
       
  2454 //============================================================================//
       
  2455 //                      QTriangulator::SimpleToMonotone                       //
       
  2456 //============================================================================//
       
  2457 
       
  2458 void QTriangulator::SimpleToMonotone::decompose()
       
  2459 {
       
  2460     setupDataStructures();
       
  2461     removeZeroLengthEdges();
       
  2462     monotoneDecomposition();
       
  2463 
       
  2464     m_parent->m_indices.clear();
       
  2465     QBitArray processed(m_edges.size(), false);
       
  2466     for (int first = 0; first < m_edges.size(); ++first) {
       
  2467         if (processed.at(first))
       
  2468             continue;
       
  2469         int i = first;
       
  2470         do {
       
  2471             Q_ASSERT(!processed.at(i));
       
  2472             Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
       
  2473             m_parent->m_indices.push_back(m_edges.at(i).from);
       
  2474             processed.setBit(i);
       
  2475             i = m_edges.at(i).next;
       
  2476         } while (i != first);
       
  2477         if (m_parent->m_indices.size() > 0 && m_parent->m_indices.back() != Q_TRIANGULATE_END_OF_POLYGON)
       
  2478             m_parent->m_indices.push_back(Q_TRIANGULATE_END_OF_POLYGON);
       
  2479     }
       
  2480 }
       
  2481 
       
  2482 void QTriangulator::SimpleToMonotone::setupDataStructures()
       
  2483 {
       
  2484     int i = 0;
       
  2485     Edge e;
       
  2486     e.node = 0;
       
  2487     e.twin = -1;
       
  2488 
       
  2489     while (i + 3 <= m_parent->m_indices.size()) {
       
  2490         int start = m_edges.size();
       
  2491 
       
  2492         do {
       
  2493             e.from = m_parent->m_indices.at(i);
       
  2494             e.type = RegularVertex;
       
  2495             e.next = m_edges.size() + 1;
       
  2496             e.previous = m_edges.size() - 1;
       
  2497             m_edges.add(e);
       
  2498             ++i;
       
  2499             Q_ASSERT(i < m_parent->m_indices.size());
       
  2500         } while (m_parent->m_indices.at(i) != Q_TRIANGULATE_END_OF_POLYGON);
       
  2501 
       
  2502         m_edges.last().next = start;
       
  2503         m_edges.at(start).previous = m_edges.size() - 1;
       
  2504         ++i; // Skip Q_TRIANGULATE_END_OF_POLYGON.
       
  2505     }
       
  2506 
       
  2507     for (i = 0; i < m_edges.size(); ++i) {
       
  2508         m_edges.at(i).to = m_edges.at(m_edges.at(i).next).from;
       
  2509         m_edges.at(i).pointingUp = m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
       
  2510         m_edges.at(i).helper = -1; // Not initialized here.
       
  2511     }
       
  2512 }
       
  2513 
       
  2514 void QTriangulator::SimpleToMonotone::removeZeroLengthEdges()
       
  2515 {
       
  2516     for (int i = 0; i < m_edges.size(); ++i) {
       
  2517         if (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(i).to)) {
       
  2518             m_edges.at(m_edges.at(i).previous).next = m_edges.at(i).next;
       
  2519             m_edges.at(m_edges.at(i).next).previous = m_edges.at(i).previous;
       
  2520             m_edges.at(m_edges.at(i).next).from = m_edges.at(i).from;
       
  2521             m_edges.at(i).next = -1; // Mark as removed.
       
  2522         }
       
  2523     }
       
  2524 
       
  2525     QDataBuffer<int> newMapping(m_edges.size());
       
  2526     newMapping.resize(m_edges.size());
       
  2527     int count = 0;
       
  2528     for (int i = 0; i < m_edges.size(); ++i) {
       
  2529         if (m_edges.at(i).next != -1) {
       
  2530             m_edges.at(count) = m_edges.at(i);
       
  2531             newMapping.at(i) = count;
       
  2532             ++count;
       
  2533         }
       
  2534     }
       
  2535     m_edges.resize(count);
       
  2536     for (int i = 0; i < m_edges.size(); ++i) {
       
  2537         m_edges.at(i).next = newMapping.at(m_edges.at(i).next);
       
  2538         m_edges.at(i).previous = newMapping.at(m_edges.at(i).previous);
       
  2539     }
       
  2540 }
       
  2541 
       
  2542 void QTriangulator::SimpleToMonotone::fillPriorityQueue()
       
  2543 {
       
  2544     m_upperVertex.reset();
       
  2545     m_upperVertex.reserve(m_edges.size());
       
  2546     for (int i = 0; i < m_edges.size(); ++i)
       
  2547         m_upperVertex.add(i);
       
  2548     CompareVertices cmp(this);
       
  2549     //qSort(m_upperVertex.data(), m_upperVertex.data() + m_upperVertex.size(), cmp);
       
  2550     sort(m_upperVertex.data(), m_upperVertex.size(), cmp);
       
  2551     //for (int i = 1; i < m_upperVertex.size(); ++i) {
       
  2552     //    Q_ASSERT(!cmp(m_upperVertex.at(i), m_upperVertex.at(i - 1)));
       
  2553     //}
       
  2554 }
       
  2555 
       
  2556 bool QTriangulator::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
       
  2557 {
       
  2558     const Edge &leftEdge = m_edges.at(leftEdgeIndex);
       
  2559     const Edge &rightEdge = m_edges.at(rightEdgeIndex);
       
  2560     const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
       
  2561     const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
       
  2562     qint64 d = qPointDistanceFromLine(m_parent->m_vertices.at(leftEdge.upper()), l, u);
       
  2563     // d < 0: left, d > 0: right, d == 0: on top
       
  2564     if (d == 0)
       
  2565         d = qPointDistanceFromLine(m_parent->m_vertices.at(leftEdge.lower()), l, u);
       
  2566     return d < 0;
       
  2567 }
       
  2568 
       
  2569 // Returns the rightmost edge not to the right of the given edge.
       
  2570 QRBTree<int>::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const
       
  2571 {
       
  2572     QRBTree<int>::Node *current = m_edgeList.root;
       
  2573     QRBTree<int>::Node *result = 0;
       
  2574     while (current) {
       
  2575         if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
       
  2576             current = current->left;
       
  2577         } else {
       
  2578             result = current;
       
  2579             current = current->right;
       
  2580         }
       
  2581     }
       
  2582     return result;
       
  2583 }
       
  2584 
       
  2585 // Returns the rightmost edge left of the given point.
       
  2586 QRBTree<int>::Node *QTriangulator::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const
       
  2587 {
       
  2588     QRBTree<int>::Node *current = m_edgeList.root;
       
  2589     QRBTree<int>::Node *result = 0;
       
  2590     while (current) {
       
  2591         const QPodPoint &p1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
       
  2592         const QPodPoint &p2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
       
  2593         qint64 d = qPointDistanceFromLine(m_parent->m_vertices.at(pointIndex), p1, p2);
       
  2594         if (d <= 0) {
       
  2595             current = current->left;
       
  2596         } else {
       
  2597             result = current;
       
  2598             current = current->right;
       
  2599         }
       
  2600     }
       
  2601     return result;
       
  2602 }
       
  2603 
       
  2604 void QTriangulator::SimpleToMonotone::classifyVertex(int i)
       
  2605 {
       
  2606     Edge &e2 = m_edges.at(i);
       
  2607     const Edge &e1 = m_edges.at(e2.previous);
       
  2608 
       
  2609     bool startOrSplit = (e1.pointingUp && !e2.pointingUp);
       
  2610     bool endOrMerge = (!e1.pointingUp && e2.pointingUp);
       
  2611 
       
  2612     const QPodPoint &p1 = m_parent->m_vertices.at(e1.from);
       
  2613     const QPodPoint &p2 = m_parent->m_vertices.at(e2.from);
       
  2614     const QPodPoint &p3 = m_parent->m_vertices.at(e2.to);
       
  2615     qint64 d = qPointDistanceFromLine(p1, p2, p3);
       
  2616     Q_ASSERT(d != 0 || (!startOrSplit && !endOrMerge));
       
  2617 
       
  2618     e2.type = RegularVertex;
       
  2619 
       
  2620     if (m_clockwiseOrder) {
       
  2621         if (startOrSplit)
       
  2622             e2.type = (d < 0 ? SplitVertex : StartVertex);
       
  2623         else if (endOrMerge)
       
  2624             e2.type = (d < 0 ? MergeVertex : EndVertex);
       
  2625     } else {
       
  2626         if (startOrSplit)
       
  2627             e2.type = (d > 0 ? SplitVertex : StartVertex);
       
  2628         else if (endOrMerge)
       
  2629             e2.type = (d > 0 ? MergeVertex : EndVertex);
       
  2630     }
       
  2631 }
       
  2632 
       
  2633 void QTriangulator::SimpleToMonotone::classifyVertices()
       
  2634 {
       
  2635     for (int i = 0; i < m_edges.size(); ++i)
       
  2636         classifyVertex(i);
       
  2637 }
       
  2638 
       
  2639 bool QTriangulator::SimpleToMonotone::pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3)
       
  2640 {
       
  2641     bool leftOfPreviousEdge = !qPointIsLeftOfLine(p, v2, v1);
       
  2642     bool leftOfNextEdge = !qPointIsLeftOfLine(p, v3, v2);
       
  2643 
       
  2644     if (qPointIsLeftOfLine(v1, v2, v3))
       
  2645         return leftOfPreviousEdge && leftOfNextEdge;
       
  2646     else
       
  2647         return leftOfPreviousEdge || leftOfNextEdge;
       
  2648 }
       
  2649 
       
  2650 bool QTriangulator::SimpleToMonotone::pointIsInSector(int vertex, int sector)
       
  2651 {
       
  2652     const QPodPoint &center = m_parent->m_vertices.at(m_edges.at(sector).from);
       
  2653     // Handle degenerate edges.
       
  2654     while (m_parent->m_vertices.at(m_edges.at(vertex).from) == center)
       
  2655         vertex = m_edges.at(vertex).next;
       
  2656     int next = m_edges.at(sector).next;
       
  2657     while (m_parent->m_vertices.at(m_edges.at(next).from) == center)
       
  2658         next = m_edges.at(next).next;
       
  2659     int previous = m_edges.at(sector).previous;
       
  2660     while (m_parent->m_vertices.at(m_edges.at(previous).from) == center)
       
  2661         previous = m_edges.at(previous).previous;
       
  2662 
       
  2663     const QPodPoint &p = m_parent->m_vertices.at(m_edges.at(vertex).from);
       
  2664     const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(previous).from);
       
  2665     const QPodPoint &v3 = m_parent->m_vertices.at(m_edges.at(next).from);
       
  2666     if (m_clockwiseOrder)
       
  2667         return pointIsInSector(p, v3, center, v1);
       
  2668     else
       
  2669         return pointIsInSector(p, v1, center, v3);
       
  2670 }
       
  2671 
       
  2672 int QTriangulator::SimpleToMonotone::findSector(int edge, int vertex)
       
  2673 {
       
  2674     while (!pointIsInSector(vertex, edge)) {
       
  2675         edge = m_edges.at(m_edges.at(edge).previous).twin;
       
  2676         Q_ASSERT(edge != -1);
       
  2677     }
       
  2678     return edge;
       
  2679 }
       
  2680 
       
  2681 void QTriangulator::SimpleToMonotone::createDiagonal(int lower, int upper)
       
  2682 {
       
  2683     lower = findSector(lower, upper);
       
  2684     upper = findSector(upper, lower);
       
  2685 
       
  2686     int prevLower = m_edges.at(lower).previous;
       
  2687     int prevUpper = m_edges.at(upper).previous;
       
  2688 
       
  2689     Edge e;
       
  2690 
       
  2691     e.twin = m_edges.size() + 1;
       
  2692     e.next = upper;
       
  2693     e.previous = prevLower;
       
  2694     e.from = m_edges.at(lower).from;
       
  2695     e.to = m_edges.at(upper).from;
       
  2696     m_edges.at(upper).previous = m_edges.at(prevLower).next = int(m_edges.size());
       
  2697     m_edges.add(e);
       
  2698 
       
  2699     e.twin = m_edges.size() - 1;
       
  2700     e.next = lower;
       
  2701     e.previous = prevUpper;
       
  2702     e.from = m_edges.at(upper).from;
       
  2703     e.to = m_edges.at(lower).from;
       
  2704     m_edges.at(lower).previous = m_edges.at(prevUpper).next = int(m_edges.size());
       
  2705     m_edges.add(e);
       
  2706 }
       
  2707 
       
  2708 void QTriangulator::SimpleToMonotone::monotoneDecomposition()
       
  2709 {
       
  2710     if (m_edges.isEmpty())
       
  2711         return;
       
  2712 
       
  2713     Q_ASSERT(!m_edgeList.root);
       
  2714     QDataBuffer<QPair<int, int> > diagonals(m_upperVertex.size());
       
  2715 
       
  2716     int i = 0;
       
  2717     for (int index = 1; index < m_edges.size(); ++index) {
       
  2718         if (m_parent->m_vertices.at(m_edges.at(index).from) < m_parent->m_vertices.at(m_edges.at(i).from))
       
  2719             i = index;
       
  2720     }
       
  2721     Q_ASSERT(i < m_edges.size());
       
  2722     int j = m_edges.at(i).previous;
       
  2723     Q_ASSERT(j < m_edges.size());
       
  2724     m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at(m_edges.at(i).from),
       
  2725         m_parent->m_vertices.at(m_edges.at(j).from), m_parent->m_vertices.at(m_edges.at(i).to));
       
  2726 
       
  2727     classifyVertices();
       
  2728     fillPriorityQueue();
       
  2729 
       
  2730     // debug: set helpers explicitly (shouldn't be necessary)
       
  2731     //for (int i = 0; i < m_edges.size(); ++i)
       
  2732     //    m_edges.at(i).helper = m_edges.at(i).upper();
       
  2733 
       
  2734     while (!m_upperVertex.isEmpty()) {
       
  2735         i = m_upperVertex.last();
       
  2736         Q_ASSERT(i < m_edges.size());
       
  2737         m_upperVertex.pop_back();
       
  2738         j = m_edges.at(i).previous;
       
  2739         Q_ASSERT(j < m_edges.size());
       
  2740 
       
  2741         QRBTree<int>::Node *leftEdgeNode = 0;
       
  2742 
       
  2743         switch (m_edges.at(i).type) {
       
  2744         case RegularVertex:
       
  2745             // If polygon interior is to the right of the vertex...
       
  2746             if (m_edges.at(i).pointingUp == m_clockwiseOrder) {
       
  2747                 if (m_edges.at(i).node) {
       
  2748                     Q_ASSERT(!m_edges.at(j).node);
       
  2749                     if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
       
  2750                         diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
       
  2751                     m_edges.at(j).node = m_edges.at(i).node;
       
  2752                     m_edges.at(i).node = 0;
       
  2753                     m_edges.at(j).node->data = j;
       
  2754                     m_edges.at(j).helper = i;
       
  2755                 } else if (m_edges.at(j).node) {
       
  2756                     Q_ASSERT(!m_edges.at(i).node);
       
  2757                     if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
       
  2758                         diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
       
  2759                     m_edges.at(i).node = m_edges.at(j).node;
       
  2760                     m_edges.at(j).node = 0;
       
  2761                     m_edges.at(i).node->data = i;
       
  2762                     m_edges.at(i).helper = i;
       
  2763                 } else {
       
  2764                     qWarning("Inconsistent polygon. (#1)");
       
  2765                 }
       
  2766             } else {
       
  2767                 leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
       
  2768                 if (leftEdgeNode) {
       
  2769                     if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
       
  2770                         diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
       
  2771                     m_edges.at(leftEdgeNode->data).helper = i;
       
  2772                 } else {
       
  2773                     qWarning("Inconsistent polygon. (#2)");
       
  2774                 }
       
  2775             }
       
  2776             break;
       
  2777         case SplitVertex:
       
  2778             leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
       
  2779             if (leftEdgeNode) {
       
  2780                 diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
       
  2781                 m_edges.at(leftEdgeNode->data).helper = i;
       
  2782             } else {
       
  2783                 qWarning("Inconsistent polygon. (#3)");
       
  2784             }
       
  2785             // Fall through.
       
  2786         case StartVertex:
       
  2787             if (m_clockwiseOrder) {
       
  2788                 leftEdgeNode = searchEdgeLeftOfEdge(j);
       
  2789                 QRBTree<int>::Node *node = m_edgeList.newNode();
       
  2790                 node->data = j;
       
  2791                 m_edges.at(j).node = node;
       
  2792                 m_edges.at(j).helper = i;
       
  2793                 m_edgeList.attachAfter(leftEdgeNode, node);
       
  2794                 Q_ASSERT(m_edgeList.verify());
       
  2795             } else  {
       
  2796                 leftEdgeNode = searchEdgeLeftOfEdge(i);
       
  2797                 QRBTree<int>::Node *node = m_edgeList.newNode();
       
  2798                 node->data = i;
       
  2799                 m_edges.at(i).node = node;
       
  2800                 m_edges.at(i).helper = i;
       
  2801                 m_edgeList.attachAfter(leftEdgeNode, node);
       
  2802                 Q_ASSERT(m_edgeList.verify());
       
  2803             }
       
  2804             break;
       
  2805         case MergeVertex:
       
  2806             leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
       
  2807             if (leftEdgeNode) {
       
  2808                 if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
       
  2809                     diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
       
  2810                 m_edges.at(leftEdgeNode->data).helper = i;
       
  2811             } else {
       
  2812                 qWarning("Inconsistent polygon. (#4)");
       
  2813             }
       
  2814             // Fall through.
       
  2815         case EndVertex:
       
  2816             if (m_clockwiseOrder) {
       
  2817                 if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
       
  2818                     diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
       
  2819                 if (m_edges.at(i).node) {
       
  2820                     m_edgeList.deleteNode(m_edges.at(i).node);
       
  2821                     Q_ASSERT(m_edgeList.verify());
       
  2822                 } else {
       
  2823                     qWarning("Inconsistent polygon. (#5)");
       
  2824                 }
       
  2825             } else {
       
  2826                 if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
       
  2827                     diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
       
  2828                 if (m_edges.at(j).node) {
       
  2829                     m_edgeList.deleteNode(m_edges.at(j).node);
       
  2830                     Q_ASSERT(m_edgeList.verify());
       
  2831                 } else {
       
  2832                     qWarning("Inconsistent polygon. (#6)");
       
  2833                 }
       
  2834             }
       
  2835             break;
       
  2836         }
       
  2837     }
       
  2838 
       
  2839     for (int i = 0; i < diagonals.size(); ++i)
       
  2840         createDiagonal(diagonals.at(i).first, diagonals.at(i).second);
       
  2841 }
       
  2842 
       
  2843 bool QTriangulator::SimpleToMonotone::CompareVertices::operator () (int i, int j) const
       
  2844 {
       
  2845     if (m_parent->m_edges.at(i).from == m_parent->m_edges.at(j).from)
       
  2846         return m_parent->m_edges.at(i).type > m_parent->m_edges.at(j).type;
       
  2847     return m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from) >
       
  2848         m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from);
       
  2849 }
       
  2850 
       
  2851 //============================================================================//
       
  2852 //                     QTriangulator::MonotoneToTriangles                     //
       
  2853 //============================================================================//
       
  2854 
       
  2855 void QTriangulator::MonotoneToTriangles::decompose()
       
  2856 {
       
  2857     QVector<quint32> result;
       
  2858     QDataBuffer<int> stack(m_parent->m_indices.size());
       
  2859     m_first = 0;
       
  2860     // Require at least three more indices.
       
  2861     while (m_first + 3 <= m_parent->m_indices.size()) {
       
  2862         m_length = 0;
       
  2863         while (m_parent->m_indices.at(m_first + m_length) != Q_TRIANGULATE_END_OF_POLYGON) {
       
  2864             ++m_length;
       
  2865             Q_ASSERT(m_first + m_length < m_parent->m_indices.size());
       
  2866         }
       
  2867         if (m_length < 3) {
       
  2868             m_first += m_length + 1;
       
  2869             continue;
       
  2870         }
       
  2871 
       
  2872         int minimum = 0;
       
  2873         while (less(next(minimum), minimum))
       
  2874             minimum = next(minimum);
       
  2875         while (less(previous(minimum), minimum))
       
  2876             minimum = previous(minimum);
       
  2877 
       
  2878         stack.reset();
       
  2879         stack.add(minimum);
       
  2880         int left = previous(minimum);
       
  2881         int right = next(minimum);
       
  2882         bool stackIsOnLeftSide;
       
  2883         bool clockwiseOrder = leftOfEdge(minimum, left, right);
       
  2884 
       
  2885         if (less(left, right)) {
       
  2886             stack.add(left);
       
  2887             left = previous(left);
       
  2888             stackIsOnLeftSide = true;
       
  2889         } else {
       
  2890             stack.add(right);
       
  2891             right = next(right);
       
  2892             stackIsOnLeftSide = false;
       
  2893         }
       
  2894 
       
  2895         for (int count = 0; count + 2 < m_length; ++count)
       
  2896         {
       
  2897             Q_ASSERT(stack.size() >= 2);
       
  2898             if (less(left, right)) {
       
  2899                 if (stackIsOnLeftSide == false) {
       
  2900                     for (int i = 0; i + 1 < stack.size(); ++i) {
       
  2901                         result.push_back(indices(stack.at(i + 1)));
       
  2902                         result.push_back(indices(left));
       
  2903                         result.push_back(indices(stack.at(i)));
       
  2904                     }
       
  2905                     stack.first() = stack.last();
       
  2906                     stack.resize(1);
       
  2907                 } else {
       
  2908                     while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(left, stack.at(stack.size() - 2), stack.last()))) {
       
  2909                         result.push_back(indices(stack.at(stack.size() - 2)));
       
  2910                         result.push_back(indices(left));
       
  2911                         result.push_back(indices(stack.last()));
       
  2912                         stack.pop_back();
       
  2913                     }
       
  2914                 }
       
  2915                 stack.add(left);
       
  2916                 left = previous(left);
       
  2917                 stackIsOnLeftSide = true;
       
  2918             } else {
       
  2919                 if (stackIsOnLeftSide == true) {
       
  2920                     for (int i = 0; i + 1 < stack.size(); ++i) {
       
  2921                         result.push_back(indices(stack.at(i)));
       
  2922                         result.push_back(indices(right));
       
  2923                         result.push_back(indices(stack.at(i + 1)));
       
  2924                     }
       
  2925                     stack.first() = stack.last();
       
  2926                     stack.resize(1);
       
  2927                 } else {
       
  2928                     while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(right, stack.last(), stack.at(stack.size() - 2)))) {
       
  2929                         result.push_back(indices(stack.last()));
       
  2930                         result.push_back(indices(right));
       
  2931                         result.push_back(indices(stack.at(stack.size() - 2)));
       
  2932                         stack.pop_back();
       
  2933                     }
       
  2934                 }
       
  2935                 stack.add(right);
       
  2936                 right = next(right);
       
  2937                 stackIsOnLeftSide = false;
       
  2938             }
       
  2939         }
       
  2940 
       
  2941         m_first += m_length + 1;
       
  2942     }
       
  2943     m_parent->m_indices = result;
       
  2944 }
       
  2945 
       
  2946 //============================================================================//
       
  2947 //                                qTriangulate                                //
       
  2948 //============================================================================//
       
  2949 
       
  2950 QTriangleSet qTriangulate(const qreal *polygon, int count, uint hint, const QTransform &matrix)
       
  2951 {
       
  2952     QTriangulator triangulator;
       
  2953     triangulator.initialize(polygon, count, hint, matrix);
       
  2954     return triangulator.triangulate();
       
  2955 }
       
  2956 
       
  2957 QTriangleSet qTriangulate(const QVectorPath &path, const QTransform &matrix, qreal lod)
       
  2958 {
       
  2959     QTriangulator triangulator;
       
  2960     triangulator.initialize(path, matrix, lod);
       
  2961     return triangulator.triangulate();
       
  2962 }
       
  2963 
       
  2964 QTriangleSet qTriangulate(const QPainterPath &path, const QTransform &matrix, qreal lod)
       
  2965 {
       
  2966     QTriangulator triangulator;
       
  2967     triangulator.initialize(path, matrix, lod);
       
  2968     return triangulator.triangulate();
       
  2969 }
       
  2970 
       
  2971 QPolylineSet qPolyline(const QVectorPath &path, const QTransform &matrix, qreal lod)
       
  2972 {
       
  2973     QTriangulator triangulator;
       
  2974     triangulator.initialize(path, matrix, lod);
       
  2975     return triangulator.polyline();
       
  2976 }
       
  2977 
       
  2978 QPolylineSet qPolyline(const QPainterPath &path, const QTransform &matrix, qreal lod)
       
  2979 {
       
  2980     QTriangulator triangulator;
       
  2981     triangulator.initialize(path, matrix, lod);
       
  2982     return triangulator.polyline();
       
  2983 }
       
  2984 
       
  2985 QT_END_NAMESPACE