1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include "qdatastream.h"
47 #include "qpainterpath.h"
49 #include "qpainterpath_p.h"
50 #include "qbezier_p.h"
56 //same as qt_painterpath_isect_line in qpainterpath.cpp
57 static void qt_polygon_isect_line(const QPointF &p1, const QPointF &p2, const QPointF &pos,
68 if (qFuzzyCompare(y1, y2)) {
69 // ignore horizontal lines according to scan conversion rule
72 qreal x_tmp = x2; x2 = x1; x1 = x_tmp;
73 qreal y_tmp = y2; y2 = y1; y1 = y_tmp;
77 if (y >= y1 && y < y2) {
78 qreal x = x1 + ((x2 - x1) / (y2 - y1)) * (y - y1);
80 // count up the winding number if we're
89 \brief The QPolygon class provides a vector of points using
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
101 \snippet polygon/polygon.cpp 0
103 In addition to the functions provided by QVector, QPolygon
104 provides some point-specific functions.
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).
114 QPolygon provides the boundingRect() and translate() functions for
115 geometry functions. Use the QMatrix::map() function for more
116 general transformations of QPolygons.
118 The QPolygon class is \l {Implicit Data Sharing}{implicitly
121 \sa QVector, QPolygonF, QLine
125 /*****************************************************************************
126 QPolygon member functions
127 *****************************************************************************/
130 \fn QPolygon::QPolygon()
132 Constructs a polygon with no points.
134 \sa QVector::isEmpty()
138 \fn QPolygon::QPolygon(int size)
140 Constructs a polygon of the given \a size. Creates an empty
141 polygon if \a size == 0.
143 \sa QVector::isEmpty()
147 \fn QPolygon::QPolygon(const QPolygon &polygon)
149 Constructs a copy of the given \a polygon.
155 \fn QPolygon::QPolygon(const QVector<QPoint> &points)
157 Constructs a polygon containing the specified \a points.
163 \fn QPolygon::QPolygon(const QRect &rectangle, bool closed)
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().
170 Note that the bottom-right corner of the rectangle is located at
171 (rectangle.x() + rectangle.width(), rectangle.y() +
177 QPolygon::QPolygon(const QRect &r, bool closed)
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());
185 *this << QPoint(r.left(), r.top());
190 Constructs a point array with \a nPoints points, taken from the
193 Equivalent to setPoints(nPoints, points).
196 QPolygon::QPolygon(int nPoints, const int *points)
198 setPoints(nPoints, points);
203 \fn QPolygon::~QPolygon()
205 Destroys the polygon.
210 Translates all points in the polygon by (\a{dx}, \a{dy}).
215 void QPolygon::translate(int dx, int dy)
217 if (dx == 0 && dy == 0)
220 register QPoint *p = data();
221 register int i = size();
230 \fn void QPolygon::translate(const QPoint &offset)
233 Translates all points in the polygon by the given \a offset.
239 Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
244 QPolygon QPolygon::translated(int dx, int dy) const
246 QPolygon copy(*this);
247 copy.translate(dx, dy);
252 \fn void QPolygon::translated(const QPoint &offset) const
256 Returns a copy of the polygon that is translated by the given \a offset.
262 Extracts the coordinates of the point at the given \a index to
263 *\a{x} and *\a{y} (if they are valid pointers).
268 void QPolygon::point(int index, int *x, int *y) const
270 QPoint p = at(index);
278 \fn QPoint QPolygon::point(int index) const
281 Returns the point at the given \a index.
285 \fn void QPolygon::setPoint(int index, const QPoint &point)
288 Sets the point at the given \a index to the given \a point.
292 \fn void QPolygon::setPoint(int index, int x, int y)
294 Sets the point at the given \a index to the point specified by
297 \sa point(), putPoints(), setPoints(),
301 Resizes the polygon to \a nPoints and populates it with the given
304 The example code creates a polygon with two points (10, 20) and
307 \snippet polygon/polygon.cpp 2
309 \sa setPoint(), putPoints()
312 void QPolygon::setPoints(int nPoints, const int *points)
317 setPoint(i++, *points, *(points+1));
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
330 The example code creates a polygon with two points (10, 20) and
333 \snippet polygon/polygon.cpp 3
336 void QPolygon::setPoints(int nPoints, int firstx, int firsty, ...)
340 setPoint(0, firstx, firsty);
342 va_start(ap, firsty);
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.
362 void QPolygon::putPoints(int index, int nPoints, const int *points)
364 if (index + nPoints > size())
365 resize(index + nPoints);
368 setPoint(i++, *points, *(points+1));
374 Copies \a nPoints points from the variable argument list into this
375 polygon from the given \a index.
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.
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:
384 \snippet polygon/polygon.cpp 4
386 The following code has the same result, but here the putPoints()
387 function overwrites rather than extends:
389 \snippet polygon/polygon.cpp 5
394 void QPolygon::putPoints(int index, int nPoints, int firstx, int firsty, ...)
397 if (index + nPoints > size())
398 resize(index + nPoints);
401 setPoint(index, firstx, firsty);
403 va_start(ap, firsty);
414 \fn void QPolygon::putPoints(int index, int nPoints, const QPolygon &fromPolygon, int fromIndex)
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:
421 \snippet polygon/polygon.cpp 6
424 void QPolygon::putPoints(int index, int nPoints, const QPolygon & from, int fromIndex)
426 if (index + nPoints > size())
427 resize(index + nPoints);
432 setPoint(index + n, from[fromIndex+n]);
439 Returns the bounding rectangle of the polygon, or QRect(0, 0, 0,
440 0) if the polygon is empty.
442 \sa QVector::isEmpty()
445 QRect QPolygon::boundingRect() const
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();
454 for (int i = 1; i < size(); ++i) {
457 else if (pd->x() > maxx)
461 else if (pd->y() > maxy)
465 return QRect(QPoint(minx,miny), QPoint(maxx,maxy));
468 #ifndef QT_NO_DEBUG_STREAM
469 QDebug operator<<(QDebug dbg, const QPolygon &a)
471 dbg.nospace() << "QPolygon(";
472 for (int i = 0; i < a.count(); ++i)
473 dbg.nospace() << a.at(i);
474 dbg.nospace() << ')';
482 \brief The QPolygonF class provides a vector of points using
483 floating point precision.
489 A QPolygonF is a QVector<QPointF>. The easiest way to add points
490 to a QPolygonF is to use its streaming operator, as illustrated
493 \snippet polygon/polygon.cpp 1
495 In addition to the functions provided by QVector, QPolygonF
496 provides the boundingRect() and translate() functions for geometry
497 operations. Use the QMatrix::map() function for more general
498 transformations of QPolygonFs.
500 QPolygonF also provides the isClosed() function to determine
501 whether a polygon's start and end points are the same, and the
502 toPolygon() function returning an integer precision copy of this
505 The QPolygonF class is \l {Implicit Data Sharing}{implicitly
508 \sa QVector, QPolygon, QLineF
512 /*****************************************************************************
513 QPolygonF member functions
514 *****************************************************************************/
517 \fn QPolygonF::QPolygonF()
519 Constructs a polygon with no points.
521 \sa QVector::isEmpty()
525 \fn QPolygonF::QPolygonF(int size)
527 Constructs a polygon of the given \a size. Creates an empty
528 polygon if \a size == 0.
530 \sa QVector::isEmpty()
534 \fn QPolygonF::QPolygonF(const QPolygonF &polygon)
536 Constructs a copy of the given \a polygon.
540 \fn QPolygonF::QPolygonF(const QVector<QPointF> &points)
542 Constructs a polygon containing the specified \a points.
546 \fn QPolygonF::QPolygonF(const QRectF &rectangle)
548 Constructs a closed polygon from the specified \a rectangle.
550 The polygon contains the four vertices of the rectangle in
551 clockwise order starting and ending with the top-left vertex.
556 QPolygonF::QPolygonF(const QRectF &r)
559 append(QPointF(r.x(), r.y()));
560 append(QPointF(r.x() + r.width(), r.y()));
561 append(QPointF(r.x() + r.width(), r.y() + r.height()));
562 append(QPointF(r.x(), r.y() + r.height()));
563 append(QPointF(r.x(), r.y()));
567 \fn QPolygonF::QPolygonF(const QPolygon &polygon)
569 Constructs a float based polygon from the specified integer based
575 QPolygonF::QPolygonF(const QPolygon &a)
578 for (int i=0; i<a.size(); ++i)
583 \fn QPolygonF::~QPolygonF()
585 Destroys the polygon.
590 Translate all points in the polygon by the given \a offset.
595 void QPolygonF::translate(const QPointF &offset)
600 register QPointF *p = data();
601 register int i = size();
609 \fn void QPolygonF::translate(qreal dx, qreal dy)
612 Translates all points in the polygon by (\a{dx}, \a{dy}).
618 Returns a copy of the polygon that is translated by the given \a offset.
623 QPolygonF QPolygonF::translated(const QPointF &offset) const
625 QPolygonF copy(*this);
626 copy.translate(offset);
631 \fn void QPolygonF::translated(qreal dx, qreal dy) const
635 Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
641 \fn bool QPolygonF::isClosed() const
643 Returns true if the polygon is closed; otherwise returns false.
645 A polygon is said to be closed if its start point and end point are equal.
647 \sa QVector::first(), QVector::last()
651 Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0)
652 if the polygon is empty.
654 \sa QVector::isEmpty()
657 QRectF QPolygonF::boundingRect() const
660 return QRectF(0, 0, 0, 0);
661 register const QPointF *pd = constData();
662 qreal minx, maxx, miny, maxy;
663 minx = maxx = pd->x();
664 miny = maxy = pd->y();
666 for (int i = 1; i < size(); ++i) {
669 else if (pd->x() > maxx)
673 else if (pd->y() > maxy)
677 return QRectF(minx,miny, maxx - minx, maxy - miny);
681 Creates and returns a QPolygon by converting each QPointF to a
684 \sa QPointF::toPoint()
687 QPolygon QPolygonF::toPolygon() const
691 for (int i=0; i<size(); ++i)
692 a.append(at(i).toPoint());
697 \fn void QPolygon::swap(QPolygon &other)
700 Swaps polygon \a other with this polygon. This operation is very
701 fast and never fails.
705 \fn void QPolygonF::swap(QPolygonF &other)
708 Swaps polygon \a other with this polygon. This operation is very
709 fast and never fails.
713 Returns the polygon as a QVariant
715 QPolygon::operator QVariant() const
717 return QVariant(QVariant::Polygon, this);
720 /*****************************************************************************
721 QPolygon stream functions
722 *****************************************************************************/
723 #ifndef QT_NO_DATASTREAM
725 \fn QDataStream &operator<<(QDataStream &stream, const QPolygon &polygon)
729 Writes the given \a polygon to the given \a stream, and returns a
730 reference to the stream.
732 \sa {Serializing Qt Data Types}
734 QDataStream &operator<<(QDataStream &s, const QPolygon &a)
736 const QVector<QPoint> &v = a;
741 \fn QDataStream &operator>>(QDataStream &stream, QPolygon &polygon)
745 Reads a polygon from the given \a stream into the given \a
746 polygon, and returns a reference to the stream.
748 \sa {Serializing Qt Data Types}
750 QDataStream &operator>>(QDataStream &s, QPolygon &a)
752 QVector<QPoint> &v = a;
755 #endif // QT_NO_DATASTREAM
757 /*****************************************************************************
758 QPolygonF stream functions
759 *****************************************************************************/
760 #ifndef QT_NO_DATASTREAM
762 \fn QDataStream &operator<<(QDataStream &stream, const QPolygonF &polygon)
765 Writes the given \a polygon to the given \a stream, and returns a
766 reference to the stream.
768 \sa {Serializing Qt Data Types}
771 QDataStream &operator<<(QDataStream &s, const QPolygonF &a)
773 quint32 len = a.size();
777 for (i = 0; i < len; ++i)
783 \fn QDataStream &operator>>(QDataStream &stream, QPolygonF &polygon)
786 Reads a polygon from the given \a stream into the given \a
787 polygon, and returns a reference to the stream.
789 \sa {Serializing Qt Data Types}
792 QDataStream &operator>>(QDataStream &s, QPolygonF &a)
798 a.reserve(a.size() + (int)len);
800 for (i = 0; i < len; ++i) {
806 #endif //QT_NO_DATASTREAM
808 #ifndef QT_NO_DEBUG_STREAM
809 QDebug operator<<(QDebug dbg, const QPolygonF &a)
811 dbg.nospace() << "QPolygonF(";
812 for (int i = 0; i < a.count(); ++i)
813 dbg.nospace() << a.at(i);
814 dbg.nospace() << ')';
823 \fn bool QPolygonF::containsPoint(const QPointF &point, Qt::FillRule fillRule) const
825 Returns true if the given \a point is inside the polygon according to
826 the specified \a fillRule; otherwise returns false.
828 bool QPolygonF::containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
833 int winding_number = 0;
835 QPointF last_pt = at(0);
836 QPointF last_start = at(0);
837 for (int i = 1; i < size(); ++i) {
838 const QPointF &e = at(i);
839 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
843 // implicitly close last subpath
844 if (last_pt != last_start)
845 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
847 return (fillRule == Qt::WindingFill
848 ? (winding_number != 0)
849 : ((winding_number % 2) != 0));
855 \fn bool QPolygon::containsPoint(const QPoint &point, Qt::FillRule fillRule) const
856 Returns true if the given \a point is inside the polygon according to
857 the specified \a fillRule; otherwise returns false.
859 bool QPolygon::containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
864 int winding_number = 0;
866 QPoint last_pt = at(0);
867 QPoint last_start = at(0);
868 for (int i = 1; i < size(); ++i) {
869 const QPoint &e = at(i);
870 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
874 // implicitly close last subpath
875 if (last_pt != last_start)
876 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
878 return (fillRule == Qt::WindingFill
879 ? (winding_number != 0)
880 : ((winding_number % 2) != 0));
886 Returns a polygon which is the union of this polygon and \a r.
888 Set operations on polygons, will treat the polygons as areas, and
889 implicitly close the polygon.
891 \sa intersected(), subtracted()
894 QPolygon QPolygon::united(const QPolygon &r) const
896 QPainterPath subject; subject.addPolygon(*this);
897 QPainterPath clip; clip.addPolygon(r);
899 return subject.united(clip).toFillPolygon().toPolygon();
905 Returns a polygon which is the intersection of this polygon and \a r.
907 Set operations on polygons will treat the polygons as
908 areas. Non-closed polygons will be treated as implicitly closed.
911 QPolygon QPolygon::intersected(const QPolygon &r) const
913 QPainterPath subject; subject.addPolygon(*this);
914 QPainterPath clip; clip.addPolygon(r);
916 return subject.intersected(clip).toFillPolygon().toPolygon();
922 Returns a polygon which is \a r subtracted from this polygon.
924 Set operations on polygons will treat the polygons as
925 areas. Non-closed polygons will be treated as implicitly closed.
929 QPolygon QPolygon::subtracted(const QPolygon &r) const
931 QPainterPath subject; subject.addPolygon(*this);
932 QPainterPath clip; clip.addPolygon(r);
934 return subject.subtracted(clip).toFillPolygon().toPolygon();
940 Returns a polygon which is the union of this polygon and \a r.
942 Set operations on polygons will treat the polygons as
943 areas. Non-closed polygons will be treated as implicitly closed.
945 \sa intersected(), subtracted()
948 QPolygonF QPolygonF::united(const QPolygonF &r) const
950 QPainterPath subject; subject.addPolygon(*this);
951 QPainterPath clip; clip.addPolygon(r);
953 return subject.united(clip).toFillPolygon();
959 Returns a polygon which is the intersection of this polygon and \a r.
961 Set operations on polygons will treat the polygons as
962 areas. Non-closed polygons will be treated as implicitly closed.
966 QPolygonF QPolygonF::intersected(const QPolygonF &r) const
968 QPainterPath subject; subject.addPolygon(*this);
969 QPainterPath clip; clip.addPolygon(r);
971 return subject.intersected(clip).toFillPolygon();
977 Returns a polygon which is \a r subtracted from this polygon.
979 Set operations on polygons will treat the polygons as
980 areas. Non-closed polygons will be treated as implicitly closed.
984 QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
986 QPainterPath subject; subject.addPolygon(*this);
987 QPainterPath clip; clip.addPolygon(r);
988 return subject.subtracted(clip).toFillPolygon();