1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qpolygon.h"
43 #include "qrect.h"
44 #include "qdatastream.h"
45 #include "qmatrix.h"
46 #include "qdebug.h"
47 #include "qpainterpath.h"
48 #include "qvariant.h"
49 #include "qpainterpath_p.h"
50 #include "qbezier_p.h"
51 
52 #include <stdarg.h>
53 
54 QT_BEGIN_NAMESPACE
55 
56 //same as qt_painterpath_isect_line in qpainterpath.cpp
qt_polygon_isect_line(const QPointF & p1,const QPointF & p2,const QPointF & pos,int * winding)57 static void qt_polygon_isect_line(const QPointF &p1, const QPointF &p2, const QPointF &pos,
58                                   int *winding)
59 {
60     qreal x1 = p1.x();
61     qreal y1 = p1.y();
62     qreal x2 = p2.x();
63     qreal y2 = p2.y();
64     qreal y = pos.y();
65 
66     int dir = 1;
67 
68     if (qFuzzyCompare(y1, y2)) {
69         // ignore horizontal lines according to scan conversion rule
70         return;
71     } else if (y2 < y1) {
72         qreal x_tmp = x2; x2 = x1; x1 = x_tmp;
73         qreal y_tmp = y2; y2 = y1; y1 = y_tmp;
74         dir = -1;
75     }
76 
77     if (y >= y1 && y < y2) {
78         qreal x = x1 + ((x2 - x1) / (y2 - y1)) * (y - y1);
79 
80         // count up the winding number if we're
81         if (x<=pos.x()) {
82             (*winding) += dir;
83         }
84     }
85 }
86 
87 /*!
88     \class QPolygon
89     \brief The QPolygon class provides a vector of points using
90     integer precision.
91 
92     \reentrant
93 
94     \ingroup painting
95     \ingroup shared
96 
97     A QPolygon object is a QVector<QPoint>.  The easiest way to add
98     points to a QPolygon is to use QVector's streaming operator, as
99     illustrated below:
100 
101     \snippet doc/src/snippets/polygon/polygon.cpp 0
102 
103     In addition to the functions provided by QVector, QPolygon
104     provides some point-specific functions.
105 
106     Each point in a polygon can be retrieved by passing its index to
107     the point() function. To populate the polygon, QPolygon provides
108     the setPoint() function to set the point at a given index, the
109     setPoints() function to set all the points in the polygon
110     (resizing it to the given number of points), and the putPoints()
111     function which copies a number of given points into the polygon
112     from a specified index (resizing the polygon if necessary).
113 
114     QPolygon provides the boundingRect() and translate() functions for
115     geometry functions. Use the QMatrix::map() function for more
116     general transformations of QPolygons.
117 
118     The QPolygon class is \l {Implicit Data Sharing}{implicitly
119     shared}.
120 
121     \sa QVector, QPolygonF, QLine
122 */
123 
124 
125 /*****************************************************************************
126   QPolygon member functions
127  *****************************************************************************/
128 
129 /*!
130     \fn QPolygon::QPolygon()
131 
132     Constructs a polygon with no points.
133 
134     \sa QVector::isEmpty()
135 */
136 
137 /*!
138     \fn QPolygon::QPolygon(int size)
139 
140     Constructs a polygon of the given \a size. Creates an empty
141     polygon if \a size == 0.
142 
143     \sa QVector::isEmpty()
144 */
145 
146 /*!
147     \fn QPolygon::QPolygon(const QPolygon &polygon)
148 
149     Constructs a copy of the given \a polygon.
150 
151     \sa setPoints()
152 */
153 
154 /*!
155     \fn QPolygon::QPolygon(const QVector<QPoint> &points)
156 
157     Constructs a polygon containing the specified \a points.
158 
159     \sa setPoints()
160 */
161 
162 /*!
163     \fn QPolygon::QPolygon(const QRect &rectangle, bool closed)
164 
165     Constructs a polygon from the given \a rectangle.  If \a closed is
166     false, the polygon just contains the four points of the rectangle
167     ordered clockwise, otherwise the polygon's fifth point is set to
168     \a {rectangle}.topLeft().
169 
170     Note that the bottom-right corner of the rectangle is located at
171     (rectangle.x() + rectangle.width(), rectangle.y() +
172     rectangle.height()).
173 
174     \sa setPoints()
175 */
176 
QPolygon(const QRect & r,bool closed)177 QPolygon::QPolygon(const QRect &r, bool closed)
178 {
179     reserve(closed ? 5 : 4);
180     *this << QPoint(r.x(), r.y())
181           << QPoint(r.x() + r.width(), r.y())
182           << QPoint(r.x() + r.width(), r.y() + r.height())
183           << QPoint(r.x(), r.y() + r.height());
184     if (closed)
185         *this << QPoint(r.left(), r.top());
186 }
187 
188 /*!
189     \internal
190     Constructs a point array with \a nPoints points, taken from the
191     \a points array.
192 
193     Equivalent to setPoints(nPoints, points).
194 */
195 
QPolygon(int nPoints,const int * points)196 QPolygon::QPolygon(int nPoints, const int *points)
197 {
198     setPoints(nPoints, points);
199 }
200 
201 
202 /*!
203     \fn QPolygon::~QPolygon()
204 
205     Destroys the polygon.
206 */
207 
208 
209 /*!
210     Translates all points in the polygon by (\a{dx}, \a{dy}).
211 
212     \sa translated()
213 */
214 
translate(int dx,int dy)215 void QPolygon::translate(int dx, int dy)
216 {
217     if (dx == 0 && dy == 0)
218         return;
219 
220     QPoint *p = data();
221     int i = size();
222     QPoint pt(dx, dy);
223     while (i--) {
224         *p += pt;
225         ++p;
226     }
227 }
228 
229 /*!
230     \fn void QPolygon::translate(const QPoint &offset)
231     \overload
232 
233     Translates all points in the polygon by the given \a offset.
234 
235     \sa translated()
236 */
237 
238 /*!
239     Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
240 
241     \since 4.6
242     \sa translate()
243 */
translated(int dx,int dy) const244 QPolygon QPolygon::translated(int dx, int dy) const
245 {
246     QPolygon copy(*this);
247     copy.translate(dx, dy);
248     return copy;
249 }
250 
251 /*!
252     \fn void QPolygon::translated(const QPoint &offset) const
253     \overload
254     \since 4.6
255 
256     Returns a copy of the polygon that is translated by the given \a offset.
257 
258     \sa translate()
259 */
260 
261 /*!
262     Extracts the coordinates of the point at the given \a index to
263     *\a{x} and *\a{y} (if they are valid pointers).
264 
265     \sa setPoint()
266 */
267 
point(int index,int * x,int * y) const268 void QPolygon::point(int index, int *x, int *y) const
269 {
270     QPoint p = at(index);
271     if (x)
272         *x = (int)p.x();
273     if (y)
274         *y = (int)p.y();
275 }
276 
277 /*!
278     \fn QPoint QPolygon::point(int index) const
279     \overload
280 
281     Returns the point at the given \a index.
282 */
283 
284 /*!
285     \fn void QPolygon::setPoint(int index, const QPoint &point)
286     \overload
287 
288     Sets the point at the given \a index to the given \a point.
289 */
290 
291 /*!
292     \fn void QPolygon::setPoint(int index, int x, int y)
293 
294     Sets the point at the given \a index to the point specified by
295     (\a{x}, \a{y}).
296 
297     \sa point(), putPoints(), setPoints(),
298 */
299 
300 /*!
301     Resizes the polygon to \a nPoints and populates it with the given
302     \a points.
303 
304     The example code creates a polygon with two points (10, 20) and
305     (30, 40):
306 
307     \snippet doc/src/snippets/polygon/polygon.cpp 2
308 
309     \sa setPoint() putPoints()
310 */
311 
setPoints(int nPoints,const int * points)312 void QPolygon::setPoints(int nPoints, const int *points)
313 {
314     resize(nPoints);
315     int i = 0;
316     while (nPoints--) {
317         setPoint(i++, *points, *(points+1));
318         points += 2;
319     }
320 }
321 
322 /*!
323     \overload
324 
325     Resizes the polygon to \a nPoints and populates it with the points
326     specified by the variable argument list.  The points are given as a
327     sequence of integers, starting with \a firstx then \a firsty, and
328     so on.
329 
330     The example code creates a polygon with two points (10, 20) and
331     (30, 40):
332 
333     \snippet doc/src/snippets/polygon/polygon.cpp 3
334 */
335 
setPoints(int nPoints,int firstx,int firsty,...)336 void QPolygon::setPoints(int nPoints, int firstx, int firsty, ...)
337 {
338     va_list ap;
339     resize(nPoints);
340     setPoint(0, firstx, firsty);
341     int i = 0, x, y;
342     va_start(ap, firsty);
343     while (--nPoints) {
344         x = va_arg(ap, int);
345         y = va_arg(ap, int);
346         setPoint(++i, x, y);
347     }
348     va_end(ap);
349 }
350 
351 /*!
352     \overload
353     \internal
354 
355     Copies \a nPoints points from the \a points coord array into this
356     point array, and resizes the point array if \c{index+nPoints}
357     exceeds the size of the array.
358 
359     \sa setPoint()
360 */
361 
putPoints(int index,int nPoints,const int * points)362 void QPolygon::putPoints(int index, int nPoints, const int *points)
363 {
364     if (index + nPoints > size())
365         resize(index + nPoints);
366     int i = index;
367     while (nPoints--) {
368         setPoint(i++, *points, *(points+1));
369         points += 2;
370     }
371 }
372 
373 /*!
374     Copies \a nPoints points from the variable argument list into this
375     polygon from the given \a index.
376 
377     The points are given as a sequence of integers, starting with \a
378     firstx then \a firsty, and so on. The polygon is resized if
379     \c{index+nPoints} exceeds its current size.
380 
381     The example code creates a polygon with three points (4,5), (6,7)
382     and (8,9), by expanding the polygon from 1 to 3 points:
383 
384     \snippet doc/src/snippets/polygon/polygon.cpp 4
385 
386     The following code has the same result, but here the putPoints()
387     function overwrites rather than extends:
388 
389     \snippet doc/src/snippets/polygon/polygon.cpp 5
390 
391     \sa setPoints()
392 */
393 
putPoints(int index,int nPoints,int firstx,int firsty,...)394 void QPolygon::putPoints(int index, int nPoints, int firstx, int firsty, ...)
395 {
396     va_list ap;
397     if (index + nPoints > size())
398         resize(index + nPoints);
399     if (nPoints <= 0)
400         return;
401     setPoint(index, firstx, firsty);
402     int i = index, x, y;
403     va_start(ap, firsty);
404     while (--nPoints) {
405         x = va_arg(ap, int);
406         y = va_arg(ap, int);
407         setPoint(++i, x, y);
408     }
409     va_end(ap);
410 }
411 
412 
413 /*!
414     \fn void QPolygon::putPoints(int index, int nPoints, const QPolygon &fromPolygon, int fromIndex)
415     \overload
416 
417     Copies \a nPoints points from the given \a fromIndex ( 0 by
418     default) in \a fromPolygon into this polygon, starting at the
419     specified \a index. For example:
420 
421     \snippet doc/src/snippets/polygon/polygon.cpp 6
422 */
423 
putPoints(int index,int nPoints,const QPolygon & from,int fromIndex)424 void QPolygon::putPoints(int index, int nPoints, const QPolygon & from, int fromIndex)
425 {
426     if (index + nPoints > size())
427         resize(index + nPoints);
428     if (nPoints <= 0)
429         return;
430     int n = 0;
431     while(n < nPoints) {
432         setPoint(index + n, from[fromIndex+n]);
433         ++n;
434     }
435 }
436 
437 
438 /*!
439     Returns the bounding rectangle of the polygon, or QRect(0, 0, 0,
440     0) if the polygon is empty.
441 
442     \sa QVector::isEmpty()
443 */
444 
boundingRect() const445 QRect QPolygon::boundingRect() const
446 {
447     if (isEmpty())
448         return QRect(0, 0, 0, 0);
449     const QPoint *pd = constData();
450     int minx, maxx, miny, maxy;
451     minx = maxx = pd->x();
452     miny = maxy = pd->y();
453     ++pd;
454     for (int i = 1; i < size(); ++i) {
455         if (pd->x() < minx)
456             minx = pd->x();
457         else if (pd->x() > maxx)
458             maxx = pd->x();
459         if (pd->y() < miny)
460             miny = pd->y();
461         else if (pd->y() > maxy)
462             maxy = pd->y();
463         ++pd;
464     }
465     return QRect(QPoint(minx,miny), QPoint(maxx,maxy));
466 }
467 
468 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QPolygon & a)469 QDebug operator<<(QDebug dbg, const QPolygon &a)
470 {
471 #ifndef Q_BROKEN_DEBUG_STREAM
472     dbg.nospace() << "QPolygon(";
473     for (int i = 0; i < a.count(); ++i)
474         dbg.nospace() << a.at(i);
475     dbg.nospace() << ')';
476     return dbg.space();
477 #else
478     qWarning("This compiler doesn't support streaming QPolygon to QDebug");
479     return dbg;
480     Q_UNUSED(a);
481 #endif
482 }
483 #endif
484 
485 
486 /*!
487     \class QPolygonF
488     \brief The QPolygonF class provides a vector of points using
489     floating point precision.
490 
491     \reentrant
492     \ingroup painting
493     \ingroup shared
494 
495     A QPolygonF is a QVector<QPointF>. The easiest way to add points
496     to a QPolygonF is to use its streaming operator, as illustrated
497     below:
498 
499     \snippet doc/src/snippets/polygon/polygon.cpp 1
500 
501     In addition to the functions provided by QVector, QPolygonF
502     provides the boundingRect() and translate() functions for geometry
503     operations. Use the QMatrix::map() function for more general
504     transformations of QPolygonFs.
505 
506     QPolygonF also provides the isClosed() function to determine
507     whether a polygon's start and end points are the same, and the
508     toPolygon() function returning an integer precision copy of this
509     polygon.
510 
511     The QPolygonF class is \l {Implicit Data Sharing}{implicitly
512     shared}.
513 
514     \sa QVector, QPolygon, QLineF
515 */
516 
517 
518 /*****************************************************************************
519   QPolygonF member functions
520  *****************************************************************************/
521 
522 /*!
523     \fn QPolygonF::QPolygonF()
524 
525     Constructs a polygon with no points.
526 
527     \sa QVector::isEmpty()
528 */
529 
530 /*!
531     \fn QPolygonF::QPolygonF(int size)
532 
533     Constructs a polygon of the given \a size. Creates an empty
534     polygon if \a size == 0.
535 
536     \sa QVector::isEmpty()
537 */
538 
539 /*!
540     \fn QPolygonF::QPolygonF(const QPolygonF &polygon)
541 
542     Constructs a copy of the given \a polygon.
543 */
544 
545 /*!
546     \fn QPolygonF::QPolygonF(const QVector<QPointF> &points)
547 
548     Constructs a polygon containing the specified \a points.
549 */
550 
551 /*!
552     \fn QPolygonF::QPolygonF(const QRectF &rectangle)
553 
554     Constructs a closed polygon from the specified \a rectangle.
555 
556     The polygon contains the four vertices of the rectangle in
557     clockwise order starting and ending with the top-left vertex.
558 
559     \sa isClosed()
560 */
561 
QPolygonF(const QRectF & r)562 QPolygonF::QPolygonF(const QRectF &r)
563 {
564     reserve(5);
565     append(QPointF(r.x(), r.y()));
566     append(QPointF(r.x() + r.width(), r.y()));
567     append(QPointF(r.x() + r.width(), r.y() + r.height()));
568     append(QPointF(r.x(), r.y() + r.height()));
569     append(QPointF(r.x(), r.y()));
570 }
571 
572 /*!
573     \fn QPolygonF::QPolygonF(const QPolygon &polygon)
574 
575     Constructs a float based polygon from the specified integer based
576     \a polygon.
577 
578     \sa toPolygon()
579 */
580 
QPolygonF(const QPolygon & a)581 QPolygonF::QPolygonF(const QPolygon &a)
582 {
583     reserve(a.size());
584     for (int i=0; i<a.size(); ++i)
585         append(a.at(i));
586 }
587 
588 /*!
589     \fn QPolygonF::~QPolygonF()
590 
591     Destroys the polygon.
592 */
593 
594 
595 /*!
596     Translate all points in the polygon by the given \a offset.
597 
598     \sa translated()
599 */
600 
translate(const QPointF & offset)601 void QPolygonF::translate(const QPointF &offset)
602 {
603     if (offset.isNull())
604         return;
605 
606     QPointF *p = data();
607     int i = size();
608     while (i--) {
609         *p += offset;
610         ++p;
611     }
612 }
613 
614 /*!
615     \fn void QPolygonF::translate(qreal dx, qreal dy)
616     \overload
617 
618     Translates all points in the polygon by (\a{dx}, \a{dy}).
619 
620     \sa translated()
621 */
622 
623 /*!
624     Returns a copy of the polygon that is translated by the given \a offset.
625 
626     \since 4.6
627     \sa translate()
628 */
translated(const QPointF & offset) const629 QPolygonF QPolygonF::translated(const QPointF &offset) const
630 {
631     QPolygonF copy(*this);
632     copy.translate(offset);
633     return copy;
634 }
635 
636 /*!
637     \fn void QPolygonF::translated(qreal dx, qreal dy) const
638     \overload
639     \since 4.6
640 
641     Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
642 
643     \sa translate()
644 */
645 
646 /*!
647     \fn bool QPolygonF::isClosed() const
648 
649     Returns true if the polygon is closed; otherwise returns false.
650 
651     A polygon is said to be closed if its start point and end point are equal.
652 
653     \sa QVector::first(), QVector::last()
654 */
655 
656 /*!
657     Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0)
658     if the polygon is empty.
659 
660     \sa QVector::isEmpty()
661 */
662 
boundingRect() const663 QRectF QPolygonF::boundingRect() const
664 {
665     if (isEmpty())
666         return QRectF(0, 0, 0, 0);
667     const QPointF *pd = constData();
668     qreal minx, maxx, miny, maxy;
669     minx = maxx = pd->x();
670     miny = maxy = pd->y();
671     ++pd;
672     for (int i = 1; i < size(); ++i) {
673         if (pd->x() < minx)
674             minx = pd->x();
675         else if (pd->x() > maxx)
676             maxx = pd->x();
677         if (pd->y() < miny)
678             miny = pd->y();
679         else if (pd->y() > maxy)
680             maxy = pd->y();
681         ++pd;
682     }
683     return QRectF(minx,miny, maxx - minx, maxy - miny);
684 }
685 
686 /*!
687     Creates and returns a QPolygon by converting each QPointF to a
688     QPoint.
689 
690     \sa QPointF::toPoint()
691 */
692 
toPolygon() const693 QPolygon QPolygonF::toPolygon() const
694 {
695     QPolygon a;
696     a.reserve(size());
697     for (int i=0; i<size(); ++i)
698         a.append(at(i).toPoint());
699     return a;
700 }
701 
702 /*!
703     \fn void QPolygon::swap(QPolygon &other)
704     \since 4.8
705 
706     Swaps polygon \a other with this polygon. This operation is very
707     fast and never fails.
708 */
709 
710 /*!
711     \fn void QPolygonF::swap(QPolygonF &other)
712     \since 4.8
713 
714     Swaps polygon \a other with this polygon. This operation is very
715     fast and never fails.
716 */
717 
718 /*!
719    Returns the polygon as a QVariant
720 */
operator QVariant() const721 QPolygon::operator QVariant() const
722 {
723     return QVariant(QVariant::Polygon, this);
724 }
725 
726 /*****************************************************************************
727   QPolygon stream functions
728  *****************************************************************************/
729 #ifndef QT_NO_DATASTREAM
730 /*!
731     \fn QDataStream &operator<<(QDataStream &stream, const QPolygon &polygon)
732     \since 4.4
733     \relates QPolygon
734 
735     Writes the given \a polygon to the given \a stream, and returns a
736     reference to the stream.
737 
738     \sa {Serializing Qt Data Types}
739 */
operator <<(QDataStream & s,const QPolygon & a)740 QDataStream &operator<<(QDataStream &s, const QPolygon &a)
741 {
742     const QVector<QPoint> &v = a;
743     return s << v;
744 }
745 
746 /*!
747     \fn QDataStream &operator>>(QDataStream &stream, QPolygon &polygon)
748     \since 4.4
749     \relates QPolygon
750 
751     Reads a polygon from the given \a stream into the given \a
752     polygon, and returns a reference to the stream.
753 
754     \sa {Serializing Qt Data Types}
755 */
operator >>(QDataStream & s,QPolygon & a)756 QDataStream &operator>>(QDataStream &s, QPolygon &a)
757 {
758     QVector<QPoint> &v = a;
759     return s >> v;
760 }
761 #endif // QT_NO_DATASTREAM
762 
763 /*****************************************************************************
764   QPolygonF stream functions
765  *****************************************************************************/
766 #ifndef QT_NO_DATASTREAM
767 /*!
768     \fn QDataStream &operator<<(QDataStream &stream, const QPolygonF &polygon)
769     \relates QPolygonF
770 
771     Writes the given \a polygon to the given \a stream, and returns a
772     reference to the stream.
773 
774     \sa {Serializing Qt Data Types}
775 */
776 
operator <<(QDataStream & s,const QPolygonF & a)777 QDataStream &operator<<(QDataStream &s, const QPolygonF &a)
778 {
779     quint32 len = a.size();
780     uint i;
781 
782     s << len;
783     for (i = 0; i < len; ++i)
784         s << a.at(i);
785     return s;
786 }
787 
788 /*!
789     \fn QDataStream &operator>>(QDataStream &stream, QPolygonF &polygon)
790     \relates QPolygonF
791 
792     Reads a polygon from the given \a stream into the given \a
793     polygon, and returns a reference to the stream.
794 
795     \sa {Serializing Qt Data Types}
796 */
797 
operator >>(QDataStream & s,QPolygonF & a)798 QDataStream &operator>>(QDataStream &s, QPolygonF &a)
799 {
800     quint32 len;
801     uint i;
802 
803     s >> len;
804     a.reserve(a.size() + (int)len);
805     QPointF p;
806     for (i = 0; i < len; ++i) {
807         s >> p;
808         a.insert(i, p);
809     }
810     return s;
811 }
812 #endif //QT_NO_DATASTREAM
813 
814 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QPolygonF & a)815 QDebug operator<<(QDebug dbg, const QPolygonF &a)
816 {
817 #ifndef Q_BROKEN_DEBUG_STREAM
818     dbg.nospace() << "QPolygonF(";
819     for (int i = 0; i < a.count(); ++i)
820         dbg.nospace() << a.at(i);
821     dbg.nospace() << ')';
822     return dbg.space();
823 #else
824     qWarning("This compiler doesn't support streaming QPolygonF to QDebug");
825     return dbg;
826     Q_UNUSED(a);
827 #endif
828 }
829 #endif
830 
831 
832 /*!
833     \since 4.3
834 
835     \fn bool QPolygonF::containsPoint(const QPointF &point, Qt::FillRule fillRule) const
836 
837     Returns true if the given \a point is inside the polygon according to
838     the specified \a fillRule; otherwise returns false.
839 */
containsPoint(const QPointF & pt,Qt::FillRule fillRule) const840 bool QPolygonF::containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
841 {
842     if (isEmpty())
843         return false;
844 
845     int winding_number = 0;
846 
847     QPointF last_pt = at(0);
848     QPointF last_start = at(0);
849     for (int i = 1; i < size(); ++i) {
850         const QPointF &e = at(i);
851         qt_polygon_isect_line(last_pt, e, pt, &winding_number);
852         last_pt = e;
853     }
854 
855     // implicitly close last subpath
856     if (last_pt != last_start)
857         qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
858 
859     return (fillRule == Qt::WindingFill
860             ? (winding_number != 0)
861             : ((winding_number % 2) != 0));
862 }
863 
864 /*!
865     \since 4.3
866 
867     \fn bool QPolygon::containsPoint(const QPoint &point, Qt::FillRule fillRule) const
868     Returns true if the given \a point is inside the polygon according to
869     the specified \a fillRule; otherwise returns false.
870 */
containsPoint(const QPoint & pt,Qt::FillRule fillRule) const871 bool QPolygon::containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
872 {
873     if (isEmpty())
874         return false;
875 
876     int winding_number = 0;
877 
878     QPoint last_pt = at(0);
879     QPoint last_start = at(0);
880     for (int i = 1; i < size(); ++i) {
881         const QPoint &e = at(i);
882         qt_polygon_isect_line(last_pt, e, pt, &winding_number);
883         last_pt = e;
884     }
885 
886     // implicitly close last subpath
887     if (last_pt != last_start)
888         qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
889 
890     return (fillRule == Qt::WindingFill
891             ? (winding_number != 0)
892             : ((winding_number % 2) != 0));
893 }
894 
895 /*!
896     \since 4.3
897 
898     Returns a polygon which is the union of this polygon and \a r.
899 
900     Set operations on polygons, will treat the polygons as areas, and
901     implicitly close the polygon.
902 
903     \sa intersected(), subtracted()
904 */
905 
united(const QPolygon & r) const906 QPolygon QPolygon::united(const QPolygon &r) const
907 {
908     QPainterPath subject; subject.addPolygon(*this);
909     QPainterPath clip; clip.addPolygon(r);
910 
911     return subject.united(clip).toFillPolygon().toPolygon();
912 }
913 
914 /*!
915     \since 4.3
916 
917     Returns a polygon which is the intersection of this polygon and \a r.
918 
919     Set operations on polygons will treat the polygons as
920     areas. Non-closed polygons will be treated as implicitly closed.
921 */
922 
intersected(const QPolygon & r) const923 QPolygon QPolygon::intersected(const QPolygon &r) const
924 {
925     QPainterPath subject; subject.addPolygon(*this);
926     QPainterPath clip; clip.addPolygon(r);
927 
928     return subject.intersected(clip).toFillPolygon().toPolygon();
929 }
930 
931 /*!
932     \since 4.3
933 
934     Returns a polygon which is \a r subtracted from this polygon.
935 
936     Set operations on polygons will treat the polygons as
937     areas. Non-closed polygons will be treated as implicitly closed.
938 
939 */
940 
subtracted(const QPolygon & r) const941 QPolygon QPolygon::subtracted(const QPolygon &r) const
942 {
943     QPainterPath subject; subject.addPolygon(*this);
944     QPainterPath clip; clip.addPolygon(r);
945 
946     return subject.subtracted(clip).toFillPolygon().toPolygon();
947 }
948 
949 /*!
950     \since 4.3
951 
952     Returns a polygon which is the union of this polygon and \a r.
953 
954     Set operations on polygons will treat the polygons as
955     areas. Non-closed polygons will be treated as implicitly closed.
956 
957     \sa intersected(), subtracted()
958 */
959 
united(const QPolygonF & r) const960 QPolygonF QPolygonF::united(const QPolygonF &r) const
961 {
962     QPainterPath subject; subject.addPolygon(*this);
963     QPainterPath clip; clip.addPolygon(r);
964 
965     return subject.united(clip).toFillPolygon();
966 }
967 
968 /*!
969     \since 4.3
970 
971     Returns a polygon which is the intersection of this polygon and \a r.
972 
973     Set operations on polygons will treat the polygons as
974     areas. Non-closed polygons will be treated as implicitly closed.
975 
976 */
977 
intersected(const QPolygonF & r) const978 QPolygonF QPolygonF::intersected(const QPolygonF &r) const
979 {
980     QPainterPath subject; subject.addPolygon(*this);
981     QPainterPath clip; clip.addPolygon(r);
982 
983     return subject.intersected(clip).toFillPolygon();
984 }
985 
986 /*!
987     \since 4.3
988 
989     Returns a polygon which is \a r subtracted from this polygon.
990 
991     Set operations on polygons will treat the polygons as
992     areas. Non-closed polygons will be treated as implicitly closed.
993 
994 */
995 
subtracted(const QPolygonF & r) const996 QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
997 {
998     QPainterPath subject; subject.addPolygon(*this);
999     QPainterPath clip; clip.addPolygon(r);
1000     return subject.subtracted(clip).toFillPolygon();
1001 }
1002 
1003 QT_END_NAMESPACE
1004