source: trunk/src/gui/painting/qpolygon.cpp@ 1034

Last change on this file since 1034 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 23.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
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
54QT_BEGIN_NAMESPACE
55
56//same as qt_painterpath_isect_line in qpainterpath.cpp
57static 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
177QPolygon::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
196QPolygon::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
215void QPolygon::translate(int dx, int dy)
216{
217 if (dx == 0 && dy == 0)
218 return;
219
220 register QPoint *p = data();
221 register 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*/
244QPolygon 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
268void 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
312void 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
336void 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
362void 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
394void 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
424void 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
445QRect QPolygon::boundingRect() const
446{
447 if (isEmpty())
448 return QRect(0, 0, 0, 0);
449 register 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
469QDebug 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
562QPolygonF::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
581QPolygonF::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
601void QPolygonF::translate(const QPointF &offset)
602{
603 if (offset.isNull())
604 return;
605
606 register QPointF *p = data();
607 register 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*/
629QPolygonF 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
663QRectF QPolygonF::boundingRect() const
664{
665 if (isEmpty())
666 return QRectF(0, 0, 0, 0);
667 register 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
693QPolygon 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 Returns the polygon as a QVariant
704*/
705QPolygon::operator QVariant() const
706{
707 return QVariant(QVariant::Polygon, this);
708}
709
710/*****************************************************************************
711 QPolygon stream functions
712 *****************************************************************************/
713#ifndef QT_NO_DATASTREAM
714/*!
715 \fn QDataStream &operator<<(QDataStream &stream, const QPolygon &polygon)
716 \since 4.4
717 \relates QPolygon
718
719 Writes the given \a polygon to the given \a stream, and returns a
720 reference to the stream.
721
722 \sa {Serializing Qt Data Types}
723*/
724QDataStream &operator<<(QDataStream &s, const QPolygon &a)
725{
726 const QVector<QPoint> &v = a;
727 return s << v;
728}
729
730/*!
731 \fn QDataStream &operator>>(QDataStream &stream, QPolygon &polygon)
732 \since 4.4
733 \relates QPolygon
734
735 Reads a polygon from the given \a stream into the given \a
736 polygon, and returns a reference to the stream.
737
738 \sa {Serializing Qt Data Types}
739*/
740QDataStream &operator>>(QDataStream &s, QPolygon &a)
741{
742 QVector<QPoint> &v = a;
743 return s >> v;
744}
745#endif // QT_NO_DATASTREAM
746
747/*****************************************************************************
748 QPolygonF stream functions
749 *****************************************************************************/
750#ifndef QT_NO_DATASTREAM
751/*!
752 \fn QDataStream &operator<<(QDataStream &stream, const QPolygonF &polygon)
753 \relates QPolygonF
754
755 Writes the given \a polygon to the given \a stream, and returns a
756 reference to the stream.
757
758 \sa {Serializing Qt Data Types}
759*/
760
761QDataStream &operator<<(QDataStream &s, const QPolygonF &a)
762{
763 quint32 len = a.size();
764 uint i;
765
766 s << len;
767 for (i = 0; i < len; ++i)
768 s << a.at(i);
769 return s;
770}
771
772/*!
773 \fn QDataStream &operator>>(QDataStream &stream, QPolygonF &polygon)
774 \relates QPolygonF
775
776 Reads a polygon from the given \a stream into the given \a
777 polygon, and returns a reference to the stream.
778
779 \sa {Serializing Qt Data Types}
780*/
781
782QDataStream &operator>>(QDataStream &s, QPolygonF &a)
783{
784 quint32 len;
785 uint i;
786
787 s >> len;
788 a.reserve(a.size() + (int)len);
789 QPointF p;
790 for (i = 0; i < len; ++i) {
791 s >> p;
792 a.insert(i, p);
793 }
794 return s;
795}
796#endif //QT_NO_DATASTREAM
797
798#ifndef QT_NO_DEBUG_STREAM
799QDebug operator<<(QDebug dbg, const QPolygonF &a)
800{
801#ifndef Q_BROKEN_DEBUG_STREAM
802 dbg.nospace() << "QPolygonF(";
803 for (int i = 0; i < a.count(); ++i)
804 dbg.nospace() << a.at(i);
805 dbg.nospace() << ')';
806 return dbg.space();
807#else
808 qWarning("This compiler doesn't support streaming QPolygonF to QDebug");
809 return dbg;
810 Q_UNUSED(a);
811#endif
812}
813#endif
814
815
816/*!
817 \since 4.3
818
819 \fn bool QPolygonF::containsPoint(const QPointF &point, Qt::FillRule fillRule) const
820
821 Returns true if the given \a point is inside the polygon according to
822 the specified \a fillRule; otherwise returns false.
823*/
824bool QPolygonF::containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
825{
826 if (isEmpty())
827 return false;
828
829 int winding_number = 0;
830
831 QPointF last_pt = at(0);
832 QPointF last_start = at(0);
833 for (int i = 1; i < size(); ++i) {
834 const QPointF &e = at(i);
835 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
836 last_pt = e;
837 }
838
839 // implicitly close last subpath
840 if (last_pt != last_start)
841 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
842
843 return (fillRule == Qt::WindingFill
844 ? (winding_number != 0)
845 : ((winding_number % 2) != 0));
846}
847
848/*!
849 \since 4.3
850
851 \fn bool QPolygon::containsPoint(const QPoint &point, Qt::FillRule fillRule) const
852 Returns true if the given \a point is inside the polygon according to
853 the specified \a fillRule; otherwise returns false.
854*/
855bool QPolygon::containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
856{
857 if (isEmpty())
858 return false;
859
860 int winding_number = 0;
861
862 QPoint last_pt = at(0);
863 QPoint last_start = at(0);
864 for (int i = 1; i < size(); ++i) {
865 const QPoint &e = at(i);
866 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
867 last_pt = e;
868 }
869
870 // implicitly close last subpath
871 if (last_pt != last_start)
872 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
873
874 return (fillRule == Qt::WindingFill
875 ? (winding_number != 0)
876 : ((winding_number % 2) != 0));
877}
878
879/*!
880 \since 4.3
881
882 Returns a polygon which is the union of this polygon and \a r.
883
884 Set operations on polygons, will treat the polygons as areas, and
885 implicitly close the polygon.
886
887 \sa intersected(), subtracted()
888*/
889
890QPolygon QPolygon::united(const QPolygon &r) const
891{
892 QPainterPath subject; subject.addPolygon(*this);
893 QPainterPath clip; clip.addPolygon(r);
894
895 return subject.united(clip).toFillPolygon().toPolygon();
896}
897
898/*!
899 \since 4.3
900
901 Returns a polygon which is the intersection of this polygon and \a r.
902
903 Set operations on polygons will treat the polygons as
904 areas. Non-closed polygons will be treated as implicitly closed.
905*/
906
907QPolygon QPolygon::intersected(const QPolygon &r) const
908{
909 QPainterPath subject; subject.addPolygon(*this);
910 QPainterPath clip; clip.addPolygon(r);
911
912 return subject.intersected(clip).toFillPolygon().toPolygon();
913}
914
915/*!
916 \since 4.3
917
918 Returns a polygon which is \a r subtracted from this polygon.
919
920 Set operations on polygons will treat the polygons as
921 areas. Non-closed polygons will be treated as implicitly closed.
922
923*/
924
925QPolygon QPolygon::subtracted(const QPolygon &r) const
926{
927 QPainterPath subject; subject.addPolygon(*this);
928 QPainterPath clip; clip.addPolygon(r);
929
930 return subject.subtracted(clip).toFillPolygon().toPolygon();
931}
932
933/*!
934 \since 4.3
935
936 Returns a polygon which is the union of this polygon and \a r.
937
938 Set operations on polygons will treat the polygons as
939 areas. Non-closed polygons will be treated as implicitly closed.
940
941 \sa intersected(), subtracted()
942*/
943
944QPolygonF QPolygonF::united(const QPolygonF &r) const
945{
946 QPainterPath subject; subject.addPolygon(*this);
947 QPainterPath clip; clip.addPolygon(r);
948
949 return subject.united(clip).toFillPolygon();
950}
951
952/*!
953 \since 4.3
954
955 Returns a polygon which is the intersection of this polygon and \a r.
956
957 Set operations on polygons will treat the polygons as
958 areas. Non-closed polygons will be treated as implicitly closed.
959
960*/
961
962QPolygonF QPolygonF::intersected(const QPolygonF &r) const
963{
964 QPainterPath subject; subject.addPolygon(*this);
965 QPainterPath clip; clip.addPolygon(r);
966
967 return subject.intersected(clip).toFillPolygon();
968}
969
970/*!
971 \since 4.3
972
973 Returns a polygon which is \a r subtracted from this polygon.
974
975 Set operations on polygons will treat the polygons as
976 areas. Non-closed polygons will be treated as implicitly closed.
977
978*/
979
980QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
981{
982 QPainterPath subject; subject.addPolygon(*this);
983 QPainterPath clip; clip.addPolygon(r);
984 return subject.subtracted(clip).toFillPolygon();
985}
986
987QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.