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