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(p1: y1, p2: 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
176QPolygon::QPolygon(const QRect &r, bool closed)
177{
178 reserve(asize: 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
195QPolygon::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
214void 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*/
243QPolygon 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
267void QPolygon::point(int index, int *x, int *y) const
268{
269 QPoint p = at(i: 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
311void QPolygon::setPoints(int nPoints, const int *points)
312{
313 resize(asize: nPoints);
314 int i = 0;
315 while (nPoints--) {
316 setPoint(index: i++, x: *points, y: *(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
335void QPolygon::setPoints(int nPoints, int firstx, int firsty, ...)
336{
337 va_list ap;
338 resize(asize: nPoints);
339 setPoint(index: 0, x: firstx, y: 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(index: ++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
361void QPolygon::putPoints(int index, int nPoints, const int *points)
362{
363 if (index + nPoints > size())
364 resize(asize: index + nPoints);
365 int i = index;
366 while (nPoints--) {
367 setPoint(index: i++, x: *points, y: *(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
393void QPolygon::putPoints(int index, int nPoints, int firstx, int firsty, ...)
394{
395 va_list ap;
396 if (index + nPoints > size())
397 resize(asize: index + nPoints);
398 if (nPoints <= 0)
399 return;
400 setPoint(index, x: firstx, y: 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(index: ++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
423void QPolygon::putPoints(int index, int nPoints, const QPolygon & from, int fromIndex)
424{
425 if (index + nPoints > size())
426 resize(asize: index + nPoints);
427 if (nPoints <= 0)
428 return;
429 int n = 0;
430 while(n < nPoints) {
431 setPoint(index: index + n, pt: 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
444QRect 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
468QDebug 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
557QPolygonF::QPolygonF(const QRectF &r)
558{
559 reserve(asize: 5);
560 append(t: QPointF(r.x(), r.y()));
561 append(t: QPointF(r.x() + r.width(), r.y()));
562 append(t: QPointF(r.x() + r.width(), r.y() + r.height()));
563 append(t: QPointF(r.x(), r.y() + r.height()));
564 append(t: 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
576QPolygonF::QPolygonF(const QPolygon &a)
577{
578 reserve(asize: a.size());
579 for (int i=0; i<a.size(); ++i)
580 append(t: 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
596void 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*/
624QPolygonF 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
658QRectF 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
689QPolygon QPolygonF::toPolygon() const
690{
691 QPolygon a;
692 a.reserve(asize: size());
693 for (int i=0; i<size(); ++i)
694 a.append(t: 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*/
717QPolygon::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*/
736QDataStream &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*/
752QDataStream &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
773QDataStream &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
794QDataStream &operator>>(QDataStream &s, QPolygonF &a)
795{
796 quint32 len;
797 uint i;
798
799 s >> len;
800 a.reserve(asize: a.size() + (int)len);
801 QPointF p;
802 for (i = 0; i < len; ++i) {
803 s >> p;
804 a.insert(i, t: p);
805 }
806 return s;
807}
808#endif //QT_NO_DATASTREAM
809
810#ifndef QT_NO_DEBUG_STREAM
811QDebug 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*/
831bool 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(i: 0);
839 QPointF last_start = at(i: 0);
840 for (int i = 1; i < size(); ++i) {
841 const QPointF &e = at(i);
842 qt_polygon_isect_line(p1: last_pt, p2: e, pos: pt, winding: &winding_number);
843 last_pt = e;
844 }
845
846 // implicitly close last subpath
847 if (last_pt != last_start)
848 qt_polygon_isect_line(p1: last_pt, p2: last_start, pos: pt, winding: &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*/
862bool 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(i: 0);
870 QPoint last_start = at(i: 0);
871 for (int i = 1; i < size(); ++i) {
872 const QPoint &e = at(i);
873 qt_polygon_isect_line(p1: last_pt, p2: e, pos: pt, winding: &winding_number);
874 last_pt = e;
875 }
876
877 // implicitly close last subpath
878 if (last_pt != last_start)
879 qt_polygon_isect_line(p1: last_pt, p2: last_start, pos: pt, winding: &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
897QPolygon QPolygon::united(const QPolygon &r) const
898{
899 QPainterPath subject; subject.addPolygon(polygon: *this);
900 QPainterPath clip; clip.addPolygon(polygon: r);
901
902 return subject.united(r: clip).toFillPolygon(matrix: 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
916QPolygon QPolygon::intersected(const QPolygon &r) const
917{
918 QPainterPath subject; subject.addPolygon(polygon: *this);
919 QPainterPath clip; clip.addPolygon(polygon: r);
920
921 return subject.intersected(r: clip).toFillPolygon(matrix: 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
934QPolygon QPolygon::subtracted(const QPolygon &r) const
935{
936 QPainterPath subject; subject.addPolygon(polygon: *this);
937 QPainterPath clip; clip.addPolygon(polygon: r);
938
939 return subject.subtracted(r: clip).toFillPolygon(matrix: 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
954bool QPolygon::intersects(const QPolygon &p) const
955{
956 QPainterPath subject; subject.addPolygon(polygon: *this);
957 QPainterPath clip; clip.addPolygon(polygon: p);
958
959 return subject.intersects(p: 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
973QPolygonF QPolygonF::united(const QPolygonF &r) const
974{
975 QPainterPath subject; subject.addPolygon(polygon: *this);
976 QPainterPath clip; clip.addPolygon(polygon: r);
977
978 return subject.united(r: clip).toFillPolygon(matrix: 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
992QPolygonF QPolygonF::intersected(const QPolygonF &r) const
993{
994 QPainterPath subject; subject.addPolygon(polygon: *this);
995 QPainterPath clip; clip.addPolygon(polygon: r);
996
997 return subject.intersected(r: clip).toFillPolygon(matrix: 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
1010QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
1011{
1012 QPainterPath subject; subject.addPolygon(polygon: *this);
1013 QPainterPath clip; clip.addPolygon(polygon: r);
1014 return subject.subtracted(r: clip).toFillPolygon(matrix: 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
1029bool QPolygonF::intersects(const QPolygonF &p) const
1030{
1031 QPainterPath subject; subject.addPolygon(polygon: *this);
1032 QPainterPath clip; clip.addPolygon(polygon: p);
1033
1034 return subject.intersects(p: clip);
1035}
1036
1037/*!
1038 Returns the polygon as a QVariant.
1039*/
1040
1041QPolygonF::operator QVariant() const
1042{
1043 return QVariant(QMetaType::QPolygonF, this);
1044}
1045
1046QT_END_NAMESPACE
1047

source code of qtbase/src/gui/painting/qpolygon.cpp