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
98 A QPolygon object is a QVector<QPoint>. The easiest way to add
99 points to a QPolygon is to use QVector's streaming operator, as
102 \snippet polygon/polygon.cpp 0
104 In addition to the functions provided by QVector, QPolygon
105 provides some point-specific functions.
107 Each point in a polygon can be retrieved by passing its index to
108 the point() function. To populate the polygon, QPolygon provides
109 the setPoint() function to set the point at a given index, the
110 setPoints() function to set all the points in the polygon
111 (resizing it to the given number of points), and the putPoints()
112 function which copies a number of given points into the polygon
113 from a specified index (resizing the polygon if necessary).
115 QPolygon provides the boundingRect() and translate() functions for
116 geometry functions. Use the QMatrix::map() function for more
117 general transformations of QPolygons.
119 The QPolygon class is \l {Implicit Data Sharing}{implicitly
122 \sa QVector, QPolygonF, QLine
126 /*****************************************************************************
127 QPolygon member functions
128 *****************************************************************************/
131 \fn QPolygon::QPolygon()
133 Constructs a polygon with no points.
135 \sa QVector::isEmpty()
139 \fn QPolygon::QPolygon(int size)
141 Constructs a polygon of the given \a size. Creates an empty
142 polygon if \a size == 0.
144 \sa QVector::isEmpty()
148 \fn QPolygon::QPolygon(const QPolygon &polygon)
150 Constructs a copy of the given \a polygon.
156 \fn QPolygon::QPolygon(const QVector<QPoint> &points)
158 Constructs a polygon containing the specified \a points.
164 \fn QPolygon::QPolygon(const QRect &rectangle, bool closed)
166 Constructs a polygon from the given \a rectangle. If \a closed is
167 false, the polygon just contains the four points of the rectangle
168 ordered clockwise, otherwise the polygon's fifth point is set to
169 \a {rectangle}.topLeft().
171 Note that the bottom-right corner of the rectangle is located at
172 (rectangle.x() + rectangle.width(), rectangle.y() +
178 QPolygon::QPolygon(const QRect &r, bool closed)
180 reserve(closed ? 5 : 4);
181 *this << QPoint(r.x(), r.y())
182 << QPoint(r.x() + r.width(), r.y())
183 << QPoint(r.x() + r.width(), r.y() + r.height())
184 << QPoint(r.x(), r.y() + r.height());
186 *this << QPoint(r.left(), r.top());
191 Constructs a point array with \a nPoints points, taken from the
194 Equivalent to setPoints(nPoints, points).
197 QPolygon::QPolygon(int nPoints, const int *points)
199 setPoints(nPoints, points);
204 \fn QPolygon::~QPolygon()
206 Destroys the polygon.
211 Translates all points in the polygon by (\a{dx}, \a{dy}).
216 void QPolygon::translate(int dx, int dy)
218 if (dx == 0 && dy == 0)
221 register QPoint *p = data();
222 register int i = size();
231 \fn void QPolygon::translate(const QPoint &offset)
234 Translates all points in the polygon by the given \a offset.
240 Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
245 QPolygon QPolygon::translated(int dx, int dy) const
247 QPolygon copy(*this);
248 copy.translate(dx, dy);
253 \fn void QPolygon::translated(const QPoint &offset) const
257 Returns a copy of the polygon that is translated by the given \a offset.
263 Extracts the coordinates of the point at the given \a index to
264 *\a{x} and *\a{y} (if they are valid pointers).
269 void QPolygon::point(int index, int *x, int *y) const
271 QPoint p = at(index);
279 \fn QPoint QPolygon::point(int index) const
282 Returns the point at the given \a index.
286 \fn void QPolygon::setPoint(int index, const QPoint &point)
289 Sets the point at the given \a index to the given \a point.
293 \fn void QPolygon::setPoint(int index, int x, int y)
295 Sets the point at the given \a index to the point specified by
298 \sa point(), putPoints(), setPoints(),
302 Resizes the polygon to \a nPoints and populates it with the given
305 The example code creates a polygon with two points (10, 20) and
308 \snippet polygon/polygon.cpp 2
310 \sa setPoint(), putPoints()
313 void QPolygon::setPoints(int nPoints, const int *points)
318 setPoint(i++, *points, *(points+1));
326 Resizes the polygon to \a nPoints and populates it with the points
327 specified by the variable argument list. The points are given as a
328 sequence of integers, starting with \a firstx then \a firsty, and
331 The example code creates a polygon with two points (10, 20) and
334 \snippet polygon/polygon.cpp 3
337 void QPolygon::setPoints(int nPoints, int firstx, int firsty, ...)
341 setPoint(0, firstx, firsty);
343 va_start(ap, firsty);
356 Copies \a nPoints points from the \a points coord array into this
357 point array, and resizes the point array if \c{index+nPoints}
358 exceeds the size of the array.
363 void QPolygon::putPoints(int index, int nPoints, const int *points)
365 if (index + nPoints > size())
366 resize(index + nPoints);
369 setPoint(i++, *points, *(points+1));
375 Copies \a nPoints points from the variable argument list into this
376 polygon from the given \a index.
378 The points are given as a sequence of integers, starting with \a
379 firstx then \a firsty, and so on. The polygon is resized if
380 \c{index+nPoints} exceeds its current size.
382 The example code creates a polygon with three points (4,5), (6,7)
383 and (8,9), by expanding the polygon from 1 to 3 points:
385 \snippet polygon/polygon.cpp 4
387 The following code has the same result, but here the putPoints()
388 function overwrites rather than extends:
390 \snippet polygon/polygon.cpp 5
395 void QPolygon::putPoints(int index, int nPoints, int firstx, int firsty, ...)
398 if (index + nPoints > size())
399 resize(index + nPoints);
402 setPoint(index, firstx, firsty);
404 va_start(ap, firsty);
415 \fn void QPolygon::putPoints(int index, int nPoints, const QPolygon &fromPolygon, int fromIndex)
418 Copies \a nPoints points from the given \a fromIndex ( 0 by
419 default) in \a fromPolygon into this polygon, starting at the
420 specified \a index. For example:
422 \snippet polygon/polygon.cpp 6
425 void QPolygon::putPoints(int index, int nPoints, const QPolygon & from, int fromIndex)
427 if (index + nPoints > size())
428 resize(index + nPoints);
433 setPoint(index + n, from[fromIndex+n]);
440 Returns the bounding rectangle of the polygon, or QRect(0, 0, 0,
441 0) if the polygon is empty.
443 \sa QVector::isEmpty()
446 QRect QPolygon::boundingRect() const
449 return QRect(0, 0, 0, 0);
450 register const QPoint *pd = constData();
451 int minx, maxx, miny, maxy;
452 minx = maxx = pd->x();
453 miny = maxy = pd->y();
455 for (int i = 1; i < size(); ++i) {
458 else if (pd->x() > maxx)
462 else if (pd->y() > maxy)
466 return QRect(QPoint(minx,miny), QPoint(maxx,maxy));
469 #ifndef QT_NO_DEBUG_STREAM
470 QDebug operator<<(QDebug dbg, const QPolygon &a)
472 dbg.nospace() << "QPolygon(";
473 for (int i = 0; i < a.count(); ++i)
474 dbg.nospace() << a.at(i);
475 dbg.nospace() << ')';
483 \brief The QPolygonF class provides a vector of points using
484 floating point precision.
491 A QPolygonF is a QVector<QPointF>. The easiest way to add points
492 to a QPolygonF is to use its streaming operator, as illustrated
495 \snippet polygon/polygon.cpp 1
497 In addition to the functions provided by QVector, QPolygonF
498 provides the boundingRect() and translate() functions for geometry
499 operations. Use the QMatrix::map() function for more general
500 transformations of QPolygonFs.
502 QPolygonF also provides the isClosed() function to determine
503 whether a polygon's start and end points are the same, and the
504 toPolygon() function returning an integer precision copy of this
507 The QPolygonF class is \l {Implicit Data Sharing}{implicitly
510 \sa QVector, QPolygon, QLineF
514 /*****************************************************************************
515 QPolygonF member functions
516 *****************************************************************************/
519 \fn QPolygonF::QPolygonF()
521 Constructs a polygon with no points.
523 \sa QVector::isEmpty()
527 \fn QPolygonF::QPolygonF(int size)
529 Constructs a polygon of the given \a size. Creates an empty
530 polygon if \a size == 0.
532 \sa QVector::isEmpty()
536 \fn QPolygonF::QPolygonF(const QPolygonF &polygon)
538 Constructs a copy of the given \a polygon.
542 \fn QPolygonF::QPolygonF(const QVector<QPointF> &points)
544 Constructs a polygon containing the specified \a points.
548 \fn QPolygonF::QPolygonF(const QRectF &rectangle)
550 Constructs a closed polygon from the specified \a rectangle.
552 The polygon contains the four vertices of the rectangle in
553 clockwise order starting and ending with the top-left vertex.
558 QPolygonF::QPolygonF(const QRectF &r)
561 append(QPointF(r.x(), r.y()));
562 append(QPointF(r.x() + r.width(), r.y()));
563 append(QPointF(r.x() + r.width(), r.y() + r.height()));
564 append(QPointF(r.x(), r.y() + r.height()));
565 append(QPointF(r.x(), r.y()));
569 \fn QPolygonF::QPolygonF(const QPolygon &polygon)
571 Constructs a float based polygon from the specified integer based
577 QPolygonF::QPolygonF(const QPolygon &a)
580 for (int i=0; i<a.size(); ++i)
585 \fn QPolygonF::~QPolygonF()
587 Destroys the polygon.
592 Translate all points in the polygon by the given \a offset.
597 void QPolygonF::translate(const QPointF &offset)
602 register QPointF *p = data();
603 register int i = size();
611 \fn void QPolygonF::translate(qreal dx, qreal dy)
614 Translates all points in the polygon by (\a{dx}, \a{dy}).
620 Returns a copy of the polygon that is translated by the given \a offset.
625 QPolygonF QPolygonF::translated(const QPointF &offset) const
627 QPolygonF copy(*this);
628 copy.translate(offset);
633 \fn void QPolygonF::translated(qreal dx, qreal dy) const
637 Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
643 \fn bool QPolygonF::isClosed() const
645 Returns true if the polygon is closed; otherwise returns false.
647 A polygon is said to be closed if its start point and end point are equal.
649 \sa QVector::first(), QVector::last()
653 Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0)
654 if the polygon is empty.
656 \sa QVector::isEmpty()
659 QRectF QPolygonF::boundingRect() const
662 return QRectF(0, 0, 0, 0);
663 register const QPointF *pd = constData();
664 qreal minx, maxx, miny, maxy;
665 minx = maxx = pd->x();
666 miny = maxy = pd->y();
668 for (int i = 1; i < size(); ++i) {
671 else if (pd->x() > maxx)
675 else if (pd->y() > maxy)
679 return QRectF(minx,miny, maxx - minx, maxy - miny);
683 Creates and returns a QPolygon by converting each QPointF to a
686 \sa QPointF::toPoint()
689 QPolygon QPolygonF::toPolygon() const
693 for (int i=0; i<size(); ++i)
694 a.append(at(i).toPoint());
699 \fn void QPolygon::swap(QPolygon &other)
702 Swaps polygon \a other with this polygon. This operation is very
703 fast and never fails.
707 \fn void QPolygonF::swap(QPolygonF &other)
710 Swaps polygon \a other with this polygon. This operation is very
711 fast and never fails.
715 Returns the polygon as a QVariant
717 QPolygon::operator QVariant() const
719 return QVariant(QVariant::Polygon, this);
722 /*****************************************************************************
723 QPolygon stream functions
724 *****************************************************************************/
725 #ifndef QT_NO_DATASTREAM
727 \fn QDataStream &operator<<(QDataStream &stream, const QPolygon &polygon)
731 Writes the given \a polygon to the given \a stream, and returns a
732 reference to the stream.
734 \sa {Serializing Qt Data Types}
736 QDataStream &operator<<(QDataStream &s, const QPolygon &a)
738 const QVector<QPoint> &v = a;
743 \fn QDataStream &operator>>(QDataStream &stream, QPolygon &polygon)
747 Reads a polygon from the given \a stream into the given \a
748 polygon, and returns a reference to the stream.
750 \sa {Serializing Qt Data Types}
752 QDataStream &operator>>(QDataStream &s, QPolygon &a)
754 QVector<QPoint> &v = a;
757 #endif // QT_NO_DATASTREAM
759 /*****************************************************************************
760 QPolygonF stream functions
761 *****************************************************************************/
762 #ifndef QT_NO_DATASTREAM
764 \fn QDataStream &operator<<(QDataStream &stream, const QPolygonF &polygon)
767 Writes the given \a polygon to the given \a stream, and returns a
768 reference to the stream.
770 \sa {Serializing Qt Data Types}
773 QDataStream &operator<<(QDataStream &s, const QPolygonF &a)
775 quint32 len = a.size();
779 for (i = 0; i < len; ++i)
785 \fn QDataStream &operator>>(QDataStream &stream, QPolygonF &polygon)
788 Reads a polygon from the given \a stream into the given \a
789 polygon, and returns a reference to the stream.
791 \sa {Serializing Qt Data Types}
794 QDataStream &operator>>(QDataStream &s, QPolygonF &a)
800 a.reserve(a.size() + (int)len);
802 for (i = 0; i < len; ++i) {
808 #endif //QT_NO_DATASTREAM
810 #ifndef QT_NO_DEBUG_STREAM
811 QDebug operator<<(QDebug dbg, const QPolygonF &a)
813 dbg.nospace() << "QPolygonF(";
814 for (int i = 0; i < a.count(); ++i)
815 dbg.nospace() << a.at(i);
816 dbg.nospace() << ')';
825 \fn bool QPolygonF::containsPoint(const QPointF &point, Qt::FillRule fillRule) const
827 Returns true if the given \a point is inside the polygon according to
828 the specified \a fillRule; otherwise returns false.
830 bool QPolygonF::containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
835 int winding_number = 0;
837 QPointF last_pt = at(0);
838 QPointF last_start = at(0);
839 for (int i = 1; i < size(); ++i) {
840 const QPointF &e = at(i);
841 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
845 // implicitly close last subpath
846 if (last_pt != last_start)
847 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
849 return (fillRule == Qt::WindingFill
850 ? (winding_number != 0)
851 : ((winding_number % 2) != 0));
857 \fn bool QPolygon::containsPoint(const QPoint &point, Qt::FillRule fillRule) const
858 Returns true if the given \a point is inside the polygon according to
859 the specified \a fillRule; otherwise returns false.
861 bool QPolygon::containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
866 int winding_number = 0;
868 QPoint last_pt = at(0);
869 QPoint last_start = at(0);
870 for (int i = 1; i < size(); ++i) {
871 const QPoint &e = at(i);
872 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
876 // implicitly close last subpath
877 if (last_pt != last_start)
878 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
880 return (fillRule == Qt::WindingFill
881 ? (winding_number != 0)
882 : ((winding_number % 2) != 0));
888 Returns a polygon which is the union of this polygon and \a r.
890 Set operations on polygons, will treat the polygons as areas, and
891 implicitly close the polygon.
893 \sa intersected(), subtracted()
896 QPolygon QPolygon::united(const QPolygon &r) const
898 QPainterPath subject; subject.addPolygon(*this);
899 QPainterPath clip; clip.addPolygon(r);
901 return subject.united(clip).toFillPolygon().toPolygon();
907 Returns a polygon which is the intersection of this polygon and \a r.
909 Set operations on polygons will treat the polygons as
910 areas. Non-closed polygons will be treated as implicitly closed.
913 QPolygon QPolygon::intersected(const QPolygon &r) const
915 QPainterPath subject; subject.addPolygon(*this);
916 QPainterPath clip; clip.addPolygon(r);
918 return subject.intersected(clip).toFillPolygon().toPolygon();
924 Returns a polygon which is \a r subtracted from this polygon.
926 Set operations on polygons will treat the polygons as
927 areas. Non-closed polygons will be treated as implicitly closed.
931 QPolygon QPolygon::subtracted(const QPolygon &r) const
933 QPainterPath subject; subject.addPolygon(*this);
934 QPainterPath clip; clip.addPolygon(r);
936 return subject.subtracted(clip).toFillPolygon().toPolygon();
942 Returns a polygon which is the union of this polygon and \a r.
944 Set operations on polygons will treat the polygons as
945 areas. Non-closed polygons will be treated as implicitly closed.
947 \sa intersected(), subtracted()
950 QPolygonF QPolygonF::united(const QPolygonF &r) const
952 QPainterPath subject; subject.addPolygon(*this);
953 QPainterPath clip; clip.addPolygon(r);
955 return subject.united(clip).toFillPolygon();
961 Returns a polygon which is the intersection of this polygon and \a r.
963 Set operations on polygons will treat the polygons as
964 areas. Non-closed polygons will be treated as implicitly closed.
968 QPolygonF QPolygonF::intersected(const QPolygonF &r) const
970 QPainterPath subject; subject.addPolygon(*this);
971 QPainterPath clip; clip.addPolygon(r);
973 return subject.intersected(clip).toFillPolygon();
979 Returns a polygon which is \a r subtracted from this polygon.
981 Set operations on polygons will treat the polygons as
982 areas. Non-closed polygons will be treated as implicitly closed.
986 QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
988 QPainterPath subject; subject.addPolygon(*this);
989 QPainterPath clip; clip.addPolygon(r);
990 return subject.subtracted(clip).toFillPolygon();
994 Returns the polygon as a QVariant.
997 QPolygonF::operator QVariant() const
999 return QVariant(QMetaType::QPolygonF, this);