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