Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qpolygon.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qpolygon.h"
5#include "qrect.h"
6#include "qdatastream.h"
7#include "qdebug.h"
8#include "qpainterpath.h"
9#include "qtransform.h"
10#include "qvariant.h"
11#include "qpainterpath_p.h"
12#include "qbezier_p.h"
13
14#include <stdarg.h>
15
17
18//same as qt_painterpath_isect_line in qpainterpath.cpp
19static void qt_polygon_isect_line(const QPointF &p1, const QPointF &p2, const QPointF &pos,
20 int *winding)
21{
22 qreal x1 = p1.x();
23 qreal y1 = p1.y();
24 qreal x2 = p2.x();
25 qreal y2 = p2.y();
26 qreal y = pos.y();
27
28 int dir = 1;
29
30 if (qFuzzyCompare(y1, y2)) {
31 // ignore horizontal lines according to scan conversion rule
32 return;
33 } else if (y2 < y1) {
34 qreal x_tmp = x2; x2 = x1; x1 = x_tmp;
35 qreal y_tmp = y2; y2 = y1; y1 = y_tmp;
36 dir = -1;
37 }
38
39 if (y >= y1 && y < y2) {
40 qreal x = x1 + ((x2 - x1) / (y2 - y1)) * (y - y1);
41
42 // count up the winding number if we're
43 if (x<=pos.x()) {
44 (*winding) += dir;
45 }
46 }
47}
48
88/*****************************************************************************
89 QPolygon member functions
90 *****************************************************************************/
91
123QPolygon::QPolygon(const QRect &r, bool closed)
124{
125 reserve(closed ? 5 : 4);
126 *this << QPoint(r.x(), r.y())
127 << QPoint(r.x() + r.width(), r.y())
128 << QPoint(r.x() + r.width(), r.y() + r.height())
129 << QPoint(r.x(), r.y() + r.height());
130 if (closed)
131 *this << QPoint(r.left(), r.top());
132}
133
142QPolygon::QPolygon(int nPoints, const int *points)
143{
144 setPoints(nPoints, points);
145}
146
153void QPolygon::translate(int dx, int dy)
154{
155 if (dx == 0 && dy == 0)
156 return;
157
158 QPoint *p = data();
159 int i = size();
160 QPoint pt(dx, dy);
161 while (i--) {
162 *p += pt;
163 ++p;
164 }
165}
166
182QPolygon QPolygon::translated(int dx, int dy) const
183{
184 QPolygon copy(*this);
185 copy.translate(dx, dy);
186 return copy;
187}
188
206void QPolygon::point(int index, int *x, int *y) const
207{
208 QPoint p = at(index);
209 if (x)
210 *x = (int)p.x();
211 if (y)
212 *y = (int)p.y();
213}
214
235void QPolygon::setPoint(int index, int x, int y)
236{
237 (*this)[index] = QPoint(x, y);
238}
239
240
253void QPolygon::setPoints(int nPoints, const int *points)
254{
255 resize(nPoints);
256 int i = 0;
257 while (nPoints--) {
258 setPoint(i++, *points, *(points+1));
259 points += 2;
260 }
261}
262
277void QPolygon::setPoints(int nPoints, int firstx, int firsty, ...)
278{
279 va_list ap;
280 resize(nPoints);
281 setPoint(0, firstx, firsty);
282 int i = 0, x, y;
283 va_start(ap, firsty);
284 while (--nPoints) {
285 x = va_arg(ap, int);
286 y = va_arg(ap, int);
287 setPoint(++i, x, y);
288 }
289 va_end(ap);
290}
291
303void QPolygon::putPoints(int index, int nPoints, const int *points)
304{
305 if (index + nPoints > size())
306 resize(index + nPoints);
307 int i = index;
308 while (nPoints--) {
309 setPoint(i++, *points, *(points+1));
310 points += 2;
311 }
312}
313
335void QPolygon::putPoints(int index, int nPoints, int firstx, int firsty, ...)
336{
337 va_list ap;
338 if (index + nPoints > size())
339 resize(index + nPoints);
340 if (nPoints <= 0)
341 return;
342 setPoint(index, firstx, firsty);
343 int i = index, x, y;
344 va_start(ap, firsty);
345 while (--nPoints) {
346 x = va_arg(ap, int);
347 y = va_arg(ap, int);
348 setPoint(++i, x, y);
349 }
350 va_end(ap);
351}
352
353
365void QPolygon::putPoints(int index, int nPoints, const QPolygon & from, int fromIndex)
366{
367 if (index + nPoints > size())
368 resize(index + nPoints);
369 if (nPoints <= 0)
370 return;
371 int n = 0;
372 while(n < nPoints) {
373 setPoint(index + n, from[fromIndex+n]);
374 ++n;
375 }
376}
377
378
387{
388 const QPoint *pd = constData();
389 const QPoint *pe = pd + size();
390 if (pd == pe)
391 return QRect(0, 0, 0, 0);
392 int minx, maxx, miny, maxy;
393 minx = maxx = pd->x();
394 miny = maxy = pd->y();
395 ++pd;
396 for (; pd != pe; ++pd) {
397 if (pd->x() < minx)
398 minx = pd->x();
399 else if (pd->x() > maxx)
400 maxx = pd->x();
401 if (pd->y() < miny)
402 miny = pd->y();
403 else if (pd->y() > maxy)
404 maxy = pd->y();
405 }
406 return QRect(QPoint(minx,miny), QPoint(maxx,maxy));
407}
408
419#ifndef QT_NO_DEBUG_STREAM
421{
422 return QtPrivate::printSequentialContainer(dbg, "QPolygon", a);
423}
424#endif
425
426
460/*****************************************************************************
461 QPolygonF member functions
462 *****************************************************************************/
463
490{
491 reserve(5);
492 append(QPointF(r.x(), r.y()));
493 append(QPointF(r.x() + r.width(), r.y()));
494 append(QPointF(r.x() + r.width(), r.y() + r.height()));
495 append(QPointF(r.x(), r.y() + r.height()));
496 append(QPointF(r.x(), r.y()));
497}
498
509{
510 reserve(a.size());
511 for (int i=0; i<a.size(); ++i)
512 append(a.at(i));
513}
514
522{
523 if (offset.isNull())
524 return;
525
526 QPointF *p = data();
527 int i = size();
528 while (i--) {
529 *p += offset;
530 ++p;
531 }
532}
533
550{
551 QPolygonF copy(*this);
552 copy.translate(offset);
553 return copy;
554}
555
584{
585 const QPointF *pd = constData();
586 const QPointF *pe = pd + size();
587 if (pd == pe)
588 return QRectF(0, 0, 0, 0);
589 qreal minx, maxx, miny, maxy;
590 minx = maxx = pd->x();
591 miny = maxy = pd->y();
592 ++pd;
593 while (pd != pe) {
594 if (pd->x() < minx)
595 minx = pd->x();
596 else if (pd->x() > maxx)
597 maxx = pd->x();
598 if (pd->y() < miny)
599 miny = pd->y();
600 else if (pd->y() > maxy)
601 maxy = pd->y();
602 ++pd;
603 }
604 return QRectF(minx,miny, maxx - minx, maxy - miny);
605}
606
615{
616 QPolygon a;
617 a.reserve(size());
618 for (int i=0; i<size(); ++i)
619 a.append(at(i).toPoint());
620 return a;
621}
622
642QPolygon::operator QVariant() const
643{
644 return QVariant::fromValue(*this);
645}
646
647/*****************************************************************************
648 QPolygon stream functions
649 *****************************************************************************/
650#ifndef QT_NO_DATASTREAM
662{
663 const QList<QPoint> &v = a;
664 return s << v;
665}
666
678{
679 QList<QPoint> &v = a;
680 return s >> v;
681}
682#endif // QT_NO_DATASTREAM
683
684/*****************************************************************************
685 QPolygonF stream functions
686 *****************************************************************************/
687#ifndef QT_NO_DATASTREAM
699{
700 return s << static_cast<const QList<QPointF> &>(a);
701}
702
714{
715 return s >> static_cast<QList<QPointF> &>(a);
716}
717#endif //QT_NO_DATASTREAM
718
719#ifndef QT_NO_DEBUG_STREAM
721{
722 return QtPrivate::printSequentialContainer(dbg, "QPolygonF", a);
723}
724#endif
725
726
735bool QPolygonF::containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
736{
737 if (isEmpty())
738 return false;
739
740 int winding_number = 0;
741
742 QPointF last_pt = at(0);
743 QPointF last_start = at(0);
744 for (int i = 1; i < size(); ++i) {
745 const QPointF &e = at(i);
746 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
747 last_pt = e;
748 }
749
750 // implicitly close last subpath
751 if (last_pt != last_start)
752 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
753
754 return (fillRule == Qt::WindingFill
755 ? (winding_number != 0)
756 : ((winding_number % 2) != 0));
757}
758
766bool QPolygon::containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
767{
768 if (isEmpty())
769 return false;
770
771 int winding_number = 0;
772
773 QPoint last_pt = at(0);
774 QPoint last_start = at(0);
775 for (int i = 1; i < size(); ++i) {
776 const QPoint &e = at(i);
777 qt_polygon_isect_line(last_pt, e, pt, &winding_number);
778 last_pt = e;
779 }
780
781 // implicitly close last subpath
782 if (last_pt != last_start)
783 qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
784
785 return (fillRule == Qt::WindingFill
786 ? (winding_number != 0)
787 : ((winding_number % 2) != 0));
788}
789
802{
803 QPainterPath subject; subject.addPolygon(*this);
804 QPainterPath clip; clip.addPolygon(r);
805
806 return subject.united(clip).toFillPolygon().toPolygon();
807}
808
821{
822 QPainterPath subject; subject.addPolygon(*this);
823 QPainterPath clip; clip.addPolygon(r);
824
825 return subject.intersected(clip).toFillPolygon().toPolygon();
826}
827
839{
840 QPainterPath subject; subject.addPolygon(*this);
841 QPainterPath clip; clip.addPolygon(r);
842
843 return subject.subtracted(clip).toFillPolygon().toPolygon();
844}
845
859{
860 QPainterPath subject; subject.addPolygon(*this);
861 QPainterPath clip; clip.addPolygon(p);
862
863 return subject.intersects(clip);
864}
865
878{
879 QPainterPath subject; subject.addPolygon(*this);
880 QPainterPath clip; clip.addPolygon(r);
881
882 return subject.united(clip).toFillPolygon();
883}
884
897{
898 QPainterPath subject; subject.addPolygon(*this);
899 QPainterPath clip; clip.addPolygon(r);
900
901 return subject.intersected(clip).toFillPolygon();
902}
903
915{
916 QPainterPath subject; subject.addPolygon(*this);
917 QPainterPath clip; clip.addPolygon(r);
918 return subject.subtracted(clip).toFillPolygon();
919}
920
934{
935 QPainterPath subject; subject.addPolygon(*this);
936 QPainterPath clip; clip.addPolygon(p);
937
938 return subject.intersects(clip);
939}
940
945QPolygonF::operator QVariant() const
946{
947 return QVariant::fromValue(*this);
948}
949
\inmodule QtCore\reentrant
Definition qdatastream.h:46
\inmodule QtCore
qsizetype size() const noexcept
Definition qlist.h:397
const_pointer constData() const noexcept
Definition qlist.h:433
bool isEmpty() const noexcept
Definition qlist.h:401
void reserve(qsizetype size)
Definition qlist.h:753
pointer data()
Definition qlist.h:431
void resize(qsizetype size)
Definition qlist.h:403
void append(parameter_type t)
Definition qlist.h:458
\inmodule QtGui
QPainterPath subtracted(const QPainterPath &r) const
void addPolygon(const QPolygonF &polygon)
Adds the given polygon to the path as an (unclosed) subpath.
QPolygonF toFillPolygon(const QTransform &matrix=QTransform()) const
Converts the path into a polygon using the QTransform matrix, and returns the polygon.
bool intersects(const QRectF &rect) const
Returns true if any point in the given rectangle intersects the path; otherwise returns false.
QPainterPath united(const QPainterPath &r) const
QPainterPath intersected(const QPainterPath &r) const
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
\inmodule QtCore\reentrant
Definition qpoint.h:25
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:130
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:135
The QPolygonF class provides a list of points using floating point precision.
Definition qpolygon.h:96
QPolygon Q_GUI_EXPORT toPolygon() const
Creates and returns a QPolygon by converting each QPointF to a QPoint.
Definition qpolygon.cpp:614
Q_GUI_EXPORT QPolygonF intersected(const QPolygonF &r) const
Definition qpolygon.cpp:896
Q_GUI_EXPORT bool containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
Definition qpolygon.cpp:735
Q_GUI_EXPORT QPolygonF subtracted(const QPolygonF &r) const
Definition qpolygon.cpp:914
Q_GUI_EXPORT QPolygonF united(const QPolygonF &r) const
Definition qpolygon.cpp:877
Q_GUI_EXPORT bool intersects(const QPolygonF &r) const
Definition qpolygon.cpp:933
void translate(qreal dx, qreal dy)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qpolygon.h:144
QPolygonF()=default
Constructs a polygon with no points.
QRectF Q_GUI_EXPORT boundingRect() const
Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0) if the polygon is empty.
Definition qpolygon.cpp:583
QPolygonF translated(qreal dx, qreal dy) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qpolygon.h:147
The QPolygon class provides a list of points using integer precision.
Definition qpolygon.h:23
Q_GUI_EXPORT bool intersects(const QPolygon &r) const
Definition qpolygon.cpp:858
Q_GUI_EXPORT QPolygon subtracted(const QPolygon &r) const
Definition qpolygon.cpp:838
Q_GUI_EXPORT void translate(int dx, int dy)
Translates all points in the polygon by ({dx}, {dy}).
Definition qpolygon.cpp:153
QPolygon()=default
Constructs a polygon with no points.
Q_GUI_EXPORT QPolygon translated(int dx, int dy) const
Returns a copy of the polygon that is translated by ({dx}, {dy}).
Definition qpolygon.cpp:182
Q_GUI_EXPORT bool containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
Definition qpolygon.cpp:766
Q_GUI_EXPORT void putPoints(int index, int nPoints, const int *points)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qpolygon.cpp:303
Q_GUI_EXPORT QPolygon united(const QPolygon &r) const
Definition qpolygon.cpp:801
Q_GUI_EXPORT void setPoint(int index, int x, int y)
Sets the point at the given index to the point specified by ({x}, {y}).
Definition qpolygon.cpp:235
Q_GUI_EXPORT QRect boundingRect() const
Returns the bounding rectangle of the polygon, or QRect(0, 0, 0, 0) if the polygon is empty.
Definition qpolygon.cpp:386
Q_GUI_EXPORT void point(int i, int *x, int *y) const
Extracts the coordinates of the point at the given index to {x} and *{y} (if they are valid pointers)...
Definition qpolygon.cpp:206
Q_GUI_EXPORT QPolygon intersected(const QPolygon &r) const
Definition qpolygon.cpp:820
Q_GUI_EXPORT void setPoints(int nPoints, const int *points)
Resizes the polygon to nPoints and populates it with the given points.
Definition qpolygon.cpp:253
\inmodule QtCore\reentrant
Definition qrect.h:484
\inmodule QtCore\reentrant
Definition qrect.h:30
\inmodule QtCore
Definition qvariant.h:65
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
QPixmap p2
QPixmap p1
[0]
Combined button and popup list for selecting options.
QDebug printSequentialContainer(QDebug debug, const char *which, const SequentialContainer &c)
Definition qdebug.h:276
@ WindingFill
static jboolean copy(JNIEnv *, jobject)
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLfloat GLfloat GLfloat GLfloat y1
GLuint index
[2]
GLboolean r
[2]
GLuint GLfloat GLfloat GLfloat x1
GLenum GLuint GLintptr offset
GLfloat n
GLint y
GLfixed GLfixed GLint GLint GLfixed points
GLdouble s
[6]
Definition qopenglext.h:235
GLfixed GLfixed GLfixed y2
GLfixed GLfixed x2
GLfloat GLfloat p
[1]
QDataStream & operator>>(QDataStream &s, QPolygon &a)
Definition qpolygon.cpp:677
static QT_BEGIN_NAMESPACE void qt_polygon_isect_line(const QPointF &p1, const QPointF &p2, const QPointF &pos, int *winding)
Definition qpolygon.cpp:19
QDebug operator<<(QDebug dbg, const QPolygon &a)
Definition qpolygon.cpp:420
double qreal
Definition qtypes.h:187
QString dir
[11]
QAction * at