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

Last change on this file since 180 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 22.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
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 multimedia
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
213void QPolygon::translate(int dx, int dy)
214{
215 register QPoint *p = data();
216 register int i = size();
217 QPoint pt(dx, dy);
218 while (i--) {
219 *p += pt;
220 ++p;
221 }
222}
223
224/*!
225 \fn void QPolygon::translate(const QPoint &offset)
226 \overload
227
228 Translates all points in the polygon by the given \a offset.
229*/
230
231
232/*!
233 Extracts the coordinates of the point at the given \a index to
234 *\a{x} and *\a{y} (if they are valid pointers).
235
236 \sa setPoint()
237*/
238
239void QPolygon::point(int index, int *x, int *y) const
240{
241 QPoint p = at(index);
242 if (x)
243 *x = (int)p.x();
244 if (y)
245 *y = (int)p.y();
246}
247
248/*!
249 \fn QPoint QPolygon::point(int index) const
250 \overload
251
252 Returns the point at the given \a index.
253*/
254
255/*!
256 \fn void QPolygon::setPoint(int index, const QPoint &point)
257 \overload
258
259 Sets the point at the given \a index to the given \a point.
260*/
261
262/*!
263 \fn void QPolygon::setPoint(int index, int x, int y)
264
265 Sets the point at the given \a index to the point specified by
266 (\a{x}, \a{y}).
267
268 \sa point(), putPoints(), setPoints(),
269*/
270
271/*!
272 Resizes the polygon to \a nPoints and populates it with the given
273 \a points.
274
275 The example code creates a polygon with two points (10, 20) and
276 (30, 40):
277
278 \snippet doc/src/snippets/polygon/polygon.cpp 2
279
280 \sa setPoint() putPoints()
281*/
282
283void QPolygon::setPoints(int nPoints, const int *points)
284{
285 resize(nPoints);
286 int i = 0;
287 while (nPoints--) {
288 setPoint(i++, *points, *(points+1));
289 points += 2;
290 }
291}
292
293/*!
294 \overload
295
296 Resizes the polygon to \a nPoints and populates it with the points
297 specified by the variable argument list. The points are given as a
298 sequence of integers, starting with \a firstx then \a firsty, and
299 so on.
300
301 The example code creates a polygon with two points (10, 20) and
302 (30, 40):
303
304 \snippet doc/src/snippets/polygon/polygon.cpp 3
305*/
306
307void QPolygon::setPoints(int nPoints, int firstx, int firsty, ...)
308{
309 va_list ap;
310 resize(nPoints);
311 setPoint(0, firstx, firsty);
312 int i = 0, x, y;
313 va_start(ap, firsty);
314 while (--nPoints) {
315 x = va_arg(ap, int);
316 y = va_arg(ap, int);
317 setPoint(++i, x, y);
318 }
319 va_end(ap);
320}
321
322/*!
323 \overload
324 \internal
325
326 Copies \a nPoints points from the \a points coord array into this
327 point array, and resizes the point array if \c{index+nPoints}
328 exceeds the size of the array.
329
330 \sa setPoint()
331*/
332
333void QPolygon::putPoints(int index, int nPoints, const int *points)
334{
335 if (index + nPoints > size())
336 resize(index + nPoints);
337 int i = index;
338 while (nPoints--) {
339 setPoint(i++, *points, *(points+1));
340 points += 2;
341 }
342}
343
344/*!
345 Copies \a nPoints points from the variable argument list into this
346 polygon from the given \a index.
347
348 The points are given as a sequence of integers, starting with \a
349 firstx then \a firsty, and so on. The polygon is resized if
350 \c{index+nPoints} exceeds its current size.
351
352 The example code creates a polygon with three points (4,5), (6,7)
353 and (8,9), by expanding the polygon from 1 to 3 points:
354
355 \snippet doc/src/snippets/polygon/polygon.cpp 4
356
357 The following code has the same result, but here the putPoints()
358 function overwrites rather than extends:
359
360 \snippet doc/src/snippets/polygon/polygon.cpp 5
361
362 \sa setPoints()
363*/
364
365void QPolygon::putPoints(int index, int nPoints, int firstx, int firsty, ...)
366{
367 va_list ap;
368 if (index + nPoints > size())
369 resize(index + nPoints);
370 if (nPoints <= 0)
371 return;
372 setPoint(index, firstx, firsty);
373 int i = index, x, y;
374 va_start(ap, firsty);
375 while (--nPoints) {
376 x = va_arg(ap, int);
377 y = va_arg(ap, int);
378 setPoint(++i, x, y);
379 }
380 va_end(ap);
381}
382
383
384/*!
385 \fn void QPolygon::putPoints(int index, int nPoints, const QPolygon &fromPolygon, int fromIndex)
386 \overload
387
388 Copies \a nPoints points from the given \a fromIndex ( 0 by
389 default) in \a fromPolygon into this polygon, starting at the
390 specified \a index. For example:
391
392 \snippet doc/src/snippets/polygon/polygon.cpp 6
393*/
394
395void QPolygon::putPoints(int index, int nPoints, const QPolygon & from, int fromIndex)
396{
397 if (index + nPoints > size())
398 resize(index + nPoints);
399 if (nPoints <= 0)
400 return;
401 int n = 0;
402 while(n < nPoints) {
403 setPoint(index + n, from[fromIndex+n]);
404 ++n;
405 }
406}
407
408
409/*!
410 Returns the bounding rectangle of the polygon, or QRect(0, 0, 0,
411 0) if the polygon is empty.
412
413 \sa QVector::isEmpty()
414*/
415
416QRect QPolygon::boundingRect() const
417{
418 if (isEmpty())
419 return QRect(0, 0, 0, 0);
420 register const QPoint *pd = constData();
421 int minx, maxx, miny, maxy;
422 minx = maxx = pd->x();
423 miny = maxy = pd->y();
424 ++pd;
425 for (int i = 1; i < size(); ++i) {
426 if (pd->x() < minx)
427 minx = pd->x();
428 else if (pd->x() > maxx)
429 maxx = pd->x();
430 if (pd->y() < miny)
431 miny = pd->y();
432 else if (pd->y() > maxy)
433 maxy = pd->y();
434 ++pd;
435 }
436 return QRect(QPoint(minx,miny), QPoint(maxx,maxy));
437}
438
439#ifndef QT_NO_DEBUG_STREAM
440QDebug operator<<(QDebug dbg, const QPolygon &a)
441{
442#ifndef Q_BROKEN_DEBUG_STREAM
443 dbg.nospace() << "QPolygon(";
444 for (int i = 0; i < a.count(); ++i)
445 dbg.nospace() << a.at(i);
446 dbg.nospace() << ')';
447 return dbg.space();
448#else
449 qWarning("This compiler doesn't support streaming QPolygon to QDebug");
450 return dbg;
451 Q_UNUSED(a);
452#endif
453}
454#endif
455
456
457/*!
458 \class QPolygonF
459 \brief The QPolygonF class provides a vector of points using
460 floating point precision.
461
462 \reentrant
463 \ingroup multimedia
464 \ingroup shared
465
466 A QPolygonF is a QVector<QPointF>. The easiest way to add points
467 to a QPolygonF is to use its streaming operator, as illustrated
468 below:
469
470 \snippet doc/src/snippets/polygon/polygon.cpp 1
471
472 In addition to the functions provided by QVector, QPolygonF
473 provides the boundingRect() and translate() functions for geometry
474 operations. Use the QMatrix::map() function for more general
475 transformations of QPolygonFs.
476
477 QPolygonF also provides the isClosed() function to determine
478 whether a polygon's start and end points are the same, and the
479 toPolygon() function returning an integer precision copy of this
480 polygon.
481
482 The QPolygonF class is \l {Implicit Data Sharing}{implicitly
483 shared}.
484
485 \sa QVector, QPolygon, QLineF
486*/
487
488
489/*****************************************************************************
490 QPolygonF member functions
491 *****************************************************************************/
492
493/*!
494 \fn QPolygonF::QPolygonF()
495
496 Constructs a polygon with no points.
497
498 \sa QVector::isEmpty()
499*/
500
501/*!
502 \fn QPolygonF::QPolygonF(int size)
503
504 Constructs a polygon of the given \a size. Creates an empty
505 polygon if \a size == 0.
506
507 \sa QVector::isEmpty()
508*/
509
510/*!
511 \fn QPolygonF::QPolygonF(const QPolygonF &polygon)
512
513 Constructs a copy of the given \a polygon.
514*/
515
516/*!
517 \fn QPolygonF::QPolygonF(const QVector<QPointF> &points)
518
519 Constructs a polygon containing the specified \a points.
520*/
521
522/*!
523 \fn QPolygonF::QPolygonF(const QRectF &rectangle)
524
525 Constructs a closed polygon from the specified \a rectangle.
526
527 The polygon contains the four vertices of the rectangle in
528 clockwise order starting and ending with the top-left vertex.
529
530 \sa isClosed()
531*/
532
533QPolygonF::QPolygonF(const QRectF &r)
534{
535 reserve(5);
536 append(QPointF(r.x(), r.y()));
537 append(QPointF(r.x() + r.width(), r.y()));
538 append(QPointF(r.x() + r.width(), r.y() + r.height()));
539 append(QPointF(r.x(), r.y() + r.height()));
540 append(QPointF(r.x(), r.y()));
541}
542
543/*!
544 \fn QPolygonF::QPolygonF(const QPolygon &polygon)
545
546 Constructs a float based polygon from the specified integer based
547 \a polygon.
548
549 \sa toPolygon()
550*/
551
552QPolygonF::QPolygonF(const QPolygon &a)
553{
554 reserve(a.size());
555 for (int i=0; i<a.size(); ++i)
556 append(a.at(i));
557}
558
559/*!
560 \fn QPolygonF::~QPolygonF()
561
562 Destroys the polygon.
563*/
564
565
566/*!
567 Translate all points in the polygon by the given \a offset.
568*/
569
570void QPolygonF::translate(const QPointF &offset)
571{
572 register QPointF *p = data();
573 register int i = size();
574 while (i--) {
575 *p += offset;
576 ++p;
577 }
578}
579
580/*!
581 \fn void QPolygonF::translate(qreal dx, qreal dy)
582 \overload
583
584 Translates all points in the polygon by (\a{dx}, \a{dy}).
585*/
586
587/*!
588 \fn bool QPolygonF::isClosed() const
589
590 Returns true if the polygon is closed; otherwise returns false.
591
592 A polygon is said to be closed if its start point and end point are equal.
593
594 \sa QVector::first(), QVector::last()
595*/
596
597/*!
598 Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0)
599 if the polygon is empty.
600
601 \sa QVector::isEmpty()
602*/
603
604QRectF QPolygonF::boundingRect() const
605{
606 if (isEmpty())
607 return QRectF(0, 0, 0, 0);
608 register const QPointF *pd = constData();
609 qreal minx, maxx, miny, maxy;
610 minx = maxx = pd->x();
611 miny = maxy = pd->y();
612 ++pd;
613 for (int i = 1; i < size(); ++i) {
614 if (pd->x() < minx)
615 minx = pd->x();
616 else if (pd->x() > maxx)
617 maxx = pd->x();
618 if (pd->y() < miny)
619 miny = pd->y();
620 else if (pd->y() > maxy)
621 maxy = pd->y();
622 ++pd;
623 }
624 return QRectF(minx,miny, maxx - minx, maxy - miny);
625}
626
627/*!
628 Creates and returns a QPolygon by converting each QPointF to a
629 QPoint.
630
631 \sa QPointF::toPoint()
632*/
633
634QPolygon QPolygonF::toPolygon() const
635{
636 QPolygon a;
637 a.reserve(size());
638 for (int i=0; i<size(); ++i)
639 a.append(at(i).toPoint());
640 return a;
641}
642
643/*!
644 Returns the polygon as a QVariant
645*/
646QPolygon::operator QVariant() const
647{
648 return QVariant(QVariant::Polygon, this);
649}
650
651/*****************************************************************************
652 QPolygon stream functions
653 *****************************************************************************/
654#ifndef QT_NO_DATASTREAM
655/*!
656 \fn QDataStream &operator<<(QDataStream &stream, const QPolygon &polygon)
657 \since 4.4
658 \relates QPolygon
659
660 Writes the given \a polygon to the given \a stream, and returns a
661 reference to the stream.
662
663 \sa {Format of the QDataStream Operators}
664*/
665QDataStream &operator<<(QDataStream &s, const QPolygon &a)
666{
667 const QVector<QPoint> &v = a;
668 return s << v;
669}
670
671/*!
672 \fn QDataStream &operator>>(QDataStream &stream, QPolygon &polygon)
673 \since 4.4
674 \relates QPolygon
675
676 Reads a polygon from the given \a stream into the given \a
677 polygon, and returns a reference to the stream.
678
679 \sa {Format of the QDataStream Operators}
680*/
681QDataStream &operator>>(QDataStream &s, QPolygon &a)
682{
683 QVector<QPoint> &v = a;
684 return s >> v;
685}
686#endif
687
688/*****************************************************************************
689 QPolygonF stream functions
690 *****************************************************************************/
691#ifndef QT_NO_DATASTREAM
692/*!
693 \fn QDataStream &operator<<(QDataStream &stream, const QPolygonF &polygon)
694 \relates QPolygonF
695
696 Writes the given \a polygon to the given \a stream, and returns a
697 reference to the stream.
698
699 \sa {Format of the QDataStream Operators}
700*/
701
702QDataStream &operator<<(QDataStream &s, const QPolygonF &a)
703{
704 quint32 len = a.size();
705 uint i;
706
707 s << len;
708 for (i = 0; i < len; ++i)
709 s << a.at(i);
710 return s;
711}
712
713/*!
714 \fn QDataStream &operator>>(QDataStream &stream, QPolygonF &polygon)
715 \relates QPolygonF
716
717 Reads a polygon from the given \a stream into the given \a
718 polygon, and returns a reference to the stream.
719
720 \sa {Format of the QDataStream Operators}
721*/
722
723QDataStream &operator>>(QDataStream &s, QPolygonF &a)
724{
725 quint32 len;
726 uint i;
727
728 s >> len;
729 a.reserve(a.size() + (int)len);
730 QPointF p;
731 for (i = 0; i < len; ++i) {
732 s >> p;
733 a.insert(i, p);
734 }
735 return s;
736}
737#endif //QT_NO_DATASTREAM
738
739#ifndef QT_NO_DEBUG_STREAM
740QDebug operator<<(QDebug dbg, const QPolygonF &a)
741{
742#ifndef Q_BROKEN_DEBUG_STREAM
743 dbg.nospace() << "QPolygonF(";
744 for (int i = 0; i < a.count(); ++i)
745 dbg.nospace() << a.at(i);
746 dbg.nospace() << ')';
747 return dbg.space();
748#else
749 qWarning("This compiler doesn't support streaming QPolygonF to QDebug");
750 return dbg;
751 Q_UNUSED(a);
752#endif
753}
754#endif
755
756
757/*!
758 \since 4.3
759
760 \fn bool QPolygonF::containsPoint(const QPointF &point, Qt::FillRule fillRule) const
761
762 Returns true if the given \a point is inside the polygon according to
763 the specified \a fillRule; otherwise returns false.
764*/
765bool QPolygonF::containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
766{
767 if (isEmpty())
768 return false;
769
770 int winding_number = 0;
771
772 QPointF last_pt = at(0);
773 QPointF last_start = at(0);
774 for (int i = 1; i < size(); ++i) {
775 const QPointF &e = at(i);
776 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
777 last_pt = e;
778 }
779
780 // implicitly close last subpath
781 if (last_pt != last_start)
782 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
783
784 return (fillRule == Qt::WindingFill
785 ? (winding_number != 0)
786 : ((winding_number % 2) != 0));
787}
788
789/*!
790 \since 4.3
791
792 \fn bool QPolygon::containsPoint(const QPoint &point, Qt::FillRule fillRule) const
793 Returns true if the given \a point is inside the polygon according to
794 the specified \a fillRule; otherwise returns false.
795*/
796bool QPolygon::containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
797{
798 if (isEmpty())
799 return false;
800
801 int winding_number = 0;
802
803 QPoint last_pt = at(0);
804 QPoint last_start = at(0);
805 for (int i = 1; i < size(); ++i) {
806 const QPoint &e = at(i);
807 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
808 last_pt = e;
809 }
810
811 // implicitly close last subpath
812 if (last_pt != last_start)
813 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
814
815 return (fillRule == Qt::WindingFill
816 ? (winding_number != 0)
817 : ((winding_number % 2) != 0));
818}
819
820/*!
821 \since 4.3
822
823 Returns a polygon which is the union of this polygon and \a r.
824
825 Set operations on polygons, will treat the polygons as areas, and
826 implicitly close the polygon.
827
828 \sa intersected(), subtracted()
829*/
830
831QPolygon QPolygon::united(const QPolygon &r) const
832{
833 QPainterPath subject; subject.addPolygon(*this);
834 QPainterPath clip; clip.addPolygon(r);
835
836 return subject.united(clip).toFillPolygon().toPolygon();
837}
838
839/*!
840 \since 4.3
841
842 Returns a polygon which is the intersection of this polygon and \a r.
843
844 Set operations on polygons will treat the polygons as
845 areas. Non-closed polygons will be treated as implicitly closed.
846*/
847
848QPolygon QPolygon::intersected(const QPolygon &r) const
849{
850 QPainterPath subject; subject.addPolygon(*this);
851 QPainterPath clip; clip.addPolygon(r);
852
853 return subject.intersected(clip).toFillPolygon().toPolygon();
854}
855
856/*!
857 \since 4.3
858
859 Returns a polygon which is \a r subtracted from this polygon.
860
861 Set operations on polygons will treat the polygons as
862 areas. Non-closed polygons will be treated as implicitly closed.
863
864*/
865
866QPolygon QPolygon::subtracted(const QPolygon &r) const
867{
868 QPainterPath subject; subject.addPolygon(*this);
869 QPainterPath clip; clip.addPolygon(r);
870
871 return subject.subtracted(clip).toFillPolygon().toPolygon();
872}
873
874/*!
875 \since 4.3
876
877 Returns a polygon which is the union of this polygon and \a r.
878
879 Set operations on polygons will treat the polygons as
880 areas. Non-closed polygons will be treated as implicitly closed.
881
882 \sa intersected(), subtracted()
883*/
884
885QPolygonF QPolygonF::united(const QPolygonF &r) const
886{
887 QPainterPath subject; subject.addPolygon(*this);
888 QPainterPath clip; clip.addPolygon(r);
889
890 return subject.united(clip).toFillPolygon();
891}
892
893/*!
894 \since 4.3
895
896 Returns a polygon which is the intersection of this polygon and \a r.
897
898 Set operations on polygons will treat the polygons as
899 areas. Non-closed polygons will be treated as implicitly closed.
900
901*/
902
903QPolygonF QPolygonF::intersected(const QPolygonF &r) const
904{
905 QPainterPath subject; subject.addPolygon(*this);
906 QPainterPath clip; clip.addPolygon(r);
907
908 return subject.intersected(clip).toFillPolygon();
909}
910
911/*!
912 \since 4.3
913
914 Returns a polygon which is \a r subtracted from this polygon.
915
916 Set operations on polygons will treat the polygons as
917 areas. Non-closed polygons will be treated as implicitly closed.
918
919*/
920
921QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
922{
923 QPainterPath subject; subject.addPolygon(*this);
924 QPainterPath clip; clip.addPolygon(r);
925 return subject.subtracted(clip).toFillPolygon();
926}
927
928QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.