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 doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/polygon/polygon.cpp 4
386 The following code has the same result, but here the putPoints()
387 function overwrites rather than extends:
389 \snippet doc/src/snippets/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 doc/src/snippets/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 #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() << ')';
478 qWarning("This compiler doesn't support streaming QPolygon to QDebug");
488 \brief The QPolygonF class provides a vector of points using
489 floating point precision.
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
499 \snippet doc/src/snippets/polygon/polygon.cpp 1
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.
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
511 The QPolygonF class is \l {Implicit Data Sharing}{implicitly
514 \sa QVector, QPolygon, QLineF
518 /*****************************************************************************
519 QPolygonF member functions
520 *****************************************************************************/
523 \fn QPolygonF::QPolygonF()
525 Constructs a polygon with no points.
527 \sa QVector::isEmpty()
531 \fn QPolygonF::QPolygonF(int size)
533 Constructs a polygon of the given \a size. Creates an empty
534 polygon if \a size == 0.
536 \sa QVector::isEmpty()
540 \fn QPolygonF::QPolygonF(const QPolygonF &polygon)
542 Constructs a copy of the given \a polygon.
546 \fn QPolygonF::QPolygonF(const QVector<QPointF> &points)
548 Constructs a polygon containing the specified \a points.
552 \fn QPolygonF::QPolygonF(const QRectF &rectangle)
554 Constructs a closed polygon from the specified \a rectangle.
556 The polygon contains the four vertices of the rectangle in
557 clockwise order starting and ending with the top-left vertex.
562 QPolygonF::QPolygonF(const QRectF &r)
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()));
573 \fn QPolygonF::QPolygonF(const QPolygon &polygon)
575 Constructs a float based polygon from the specified integer based
581 QPolygonF::QPolygonF(const QPolygon &a)
584 for (int i=0; i<a.size(); ++i)
589 \fn QPolygonF::~QPolygonF()
591 Destroys the polygon.
596 Translate all points in the polygon by the given \a offset.
601 void QPolygonF::translate(const QPointF &offset)
606 register QPointF *p = data();
607 register int i = size();
615 \fn void QPolygonF::translate(qreal dx, qreal dy)
618 Translates all points in the polygon by (\a{dx}, \a{dy}).
624 Returns a copy of the polygon that is translated by the given \a offset.
629 QPolygonF QPolygonF::translated(const QPointF &offset) const
631 QPolygonF copy(*this);
632 copy.translate(offset);
637 \fn void QPolygonF::translated(qreal dx, qreal dy) const
641 Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
647 \fn bool QPolygonF::isClosed() const
649 Returns true if the polygon is closed; otherwise returns false.
651 A polygon is said to be closed if its start point and end point are equal.
653 \sa QVector::first(), QVector::last()
657 Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0)
658 if the polygon is empty.
660 \sa QVector::isEmpty()
663 QRectF QPolygonF::boundingRect() const
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();
672 for (int i = 1; i < size(); ++i) {
675 else if (pd->x() > maxx)
679 else if (pd->y() > maxy)
683 return QRectF(minx,miny, maxx - minx, maxy - miny);
687 Creates and returns a QPolygon by converting each QPointF to a
690 \sa QPointF::toPoint()
693 QPolygon QPolygonF::toPolygon() const
697 for (int i=0; i<size(); ++i)
698 a.append(at(i).toPoint());
703 \fn void QPolygon::swap(QPolygon &other)
706 Swaps polygon \a other with this polygon. This operation is very
707 fast and never fails.
711 \fn void QPolygonF::swap(QPolygonF &other)
714 Swaps polygon \a other with this polygon. This operation is very
715 fast and never fails.
719 Returns the polygon as a QVariant
721 QPolygon::operator QVariant() const
723 return QVariant(QVariant::Polygon, this);
726 /*****************************************************************************
727 QPolygon stream functions
728 *****************************************************************************/
729 #ifndef QT_NO_DATASTREAM
731 \fn QDataStream &operator<<(QDataStream &stream, const QPolygon &polygon)
735 Writes the given \a polygon to the given \a stream, and returns a
736 reference to the stream.
738 \sa {Serializing Qt Data Types}
740 QDataStream &operator<<(QDataStream &s, const QPolygon &a)
742 const QVector<QPoint> &v = a;
747 \fn QDataStream &operator>>(QDataStream &stream, QPolygon &polygon)
751 Reads a polygon from the given \a stream into the given \a
752 polygon, and returns a reference to the stream.
754 \sa {Serializing Qt Data Types}
756 QDataStream &operator>>(QDataStream &s, QPolygon &a)
758 QVector<QPoint> &v = a;
761 #endif // QT_NO_DATASTREAM
763 /*****************************************************************************
764 QPolygonF stream functions
765 *****************************************************************************/
766 #ifndef QT_NO_DATASTREAM
768 \fn QDataStream &operator<<(QDataStream &stream, const QPolygonF &polygon)
771 Writes the given \a polygon to the given \a stream, and returns a
772 reference to the stream.
774 \sa {Serializing Qt Data Types}
777 QDataStream &operator<<(QDataStream &s, const QPolygonF &a)
779 quint32 len = a.size();
783 for (i = 0; i < len; ++i)
789 \fn QDataStream &operator>>(QDataStream &stream, QPolygonF &polygon)
792 Reads a polygon from the given \a stream into the given \a
793 polygon, and returns a reference to the stream.
795 \sa {Serializing Qt Data Types}
798 QDataStream &operator>>(QDataStream &s, QPolygonF &a)
804 a.reserve(a.size() + (int)len);
806 for (i = 0; i < len; ++i) {
812 #endif //QT_NO_DATASTREAM
814 #ifndef QT_NO_DEBUG_STREAM
815 QDebug operator<<(QDebug dbg, const QPolygonF &a)
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() << ')';
824 qWarning("This compiler doesn't support streaming QPolygonF to QDebug");
835 \fn bool QPolygonF::containsPoint(const QPointF &point, Qt::FillRule fillRule) const
837 Returns true if the given \a point is inside the polygon according to
838 the specified \a fillRule; otherwise returns false.
840 bool QPolygonF::containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
845 int winding_number = 0;
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);
855 // implicitly close last subpath
856 if (last_pt != last_start)
857 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
859 return (fillRule == Qt::WindingFill
860 ? (winding_number != 0)
861 : ((winding_number % 2) != 0));
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.
871 bool QPolygon::containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
876 int winding_number = 0;
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);
886 // implicitly close last subpath
887 if (last_pt != last_start)
888 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
890 return (fillRule == Qt::WindingFill
891 ? (winding_number != 0)
892 : ((winding_number % 2) != 0));
898 Returns a polygon which is the union of this polygon and \a r.
900 Set operations on polygons, will treat the polygons as areas, and
901 implicitly close the polygon.
903 \sa intersected(), subtracted()
906 QPolygon QPolygon::united(const QPolygon &r) const
908 QPainterPath subject; subject.addPolygon(*this);
909 QPainterPath clip; clip.addPolygon(r);
911 return subject.united(clip).toFillPolygon().toPolygon();
917 Returns a polygon which is the intersection of this polygon and \a r.
919 Set operations on polygons will treat the polygons as
920 areas. Non-closed polygons will be treated as implicitly closed.
923 QPolygon QPolygon::intersected(const QPolygon &r) const
925 QPainterPath subject; subject.addPolygon(*this);
926 QPainterPath clip; clip.addPolygon(r);
928 return subject.intersected(clip).toFillPolygon().toPolygon();
934 Returns a polygon which is \a r subtracted from this polygon.
936 Set operations on polygons will treat the polygons as
937 areas. Non-closed polygons will be treated as implicitly closed.
941 QPolygon QPolygon::subtracted(const QPolygon &r) const
943 QPainterPath subject; subject.addPolygon(*this);
944 QPainterPath clip; clip.addPolygon(r);
946 return subject.subtracted(clip).toFillPolygon().toPolygon();
952 Returns a polygon which is the union of this polygon and \a r.
954 Set operations on polygons will treat the polygons as
955 areas. Non-closed polygons will be treated as implicitly closed.
957 \sa intersected(), subtracted()
960 QPolygonF QPolygonF::united(const QPolygonF &r) const
962 QPainterPath subject; subject.addPolygon(*this);
963 QPainterPath clip; clip.addPolygon(r);
965 return subject.united(clip).toFillPolygon();
971 Returns a polygon which is the intersection of this polygon and \a r.
973 Set operations on polygons will treat the polygons as
974 areas. Non-closed polygons will be treated as implicitly closed.
978 QPolygonF QPolygonF::intersected(const QPolygonF &r) const
980 QPainterPath subject; subject.addPolygon(*this);
981 QPainterPath clip; clip.addPolygon(r);
983 return subject.intersected(clip).toFillPolygon();
989 Returns a polygon which is \a r subtracted from this polygon.
991 Set operations on polygons will treat the polygons as
992 areas. Non-closed polygons will be treated as implicitly closed.
996 QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
998 QPainterPath subject; subject.addPolygon(*this);
999 QPainterPath clip; clip.addPolygon(r);
1000 return subject.subtracted(clip).toFillPolygon();