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