Coverage Report

Created: 2026-03-31 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/painting/qpolygon.cpp
Line
Count
Source
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
// Qt-Security score:significant reason:default
4
5
#include "qpolygon.h"
6
#include "qrect.h"
7
#include "qdatastream.h"
8
#include "qdebug.h"
9
#include "qpainterpath.h"
10
#include "qtransform.h"
11
#include "qvariant.h"
12
#include "qpainterpath_p.h"
13
#include "qbezier_p.h"
14
15
#include <stdarg.h>
16
17
QT_BEGIN_NAMESPACE
18
19
//same as qt_painterpath_isect_line in qpainterpath.cpp
20
static void qt_polygon_isect_line(const QPointF &p1, const QPointF &p2, const QPointF &pos,
21
                                  int *winding)
22
0
{
23
0
    qreal x1 = p1.x();
24
0
    qreal y1 = p1.y();
25
0
    qreal x2 = p2.x();
26
0
    qreal y2 = p2.y();
27
0
    qreal y = pos.y();
28
29
0
    int dir = 1;
30
31
0
    if (qFuzzyCompare(y1, y2)) {
32
        // ignore horizontal lines according to scan conversion rule
33
0
        return;
34
0
    } else if (y2 < y1) {
35
0
        qreal x_tmp = x2; x2 = x1; x1 = x_tmp;
36
0
        qreal y_tmp = y2; y2 = y1; y1 = y_tmp;
37
0
        dir = -1;
38
0
    }
39
40
0
    if (y >= y1 && y < y2) {
41
0
        qreal x = x1 + ((x2 - x1) / (y2 - y1)) * (y - y1);
42
43
        // count up the winding number if we're
44
0
        if (x<=pos.x()) {
45
0
            (*winding) += dir;
46
0
        }
47
0
    }
48
0
}
49
50
/*!
51
    \class QPolygon
52
    \brief The QPolygon class provides a list of points using
53
    integer precision.
54
    \inmodule QtGui
55
56
    \reentrant
57
58
    \ingroup painting
59
    \ingroup shared
60
61
    A QPolygon object is a QList<QPoint>.  The easiest way to add
62
    points to a QPolygon is to use QList's streaming operator, as
63
    illustrated below:
64
65
    \snippet polygon/polygon.cpp 0
66
67
    In addition to the functions provided by QList, QPolygon
68
    provides some point-specific functions.
69
70
    Each point in a polygon can be retrieved by passing its index to
71
    the point() function. To populate the polygon, QPolygon provides
72
    the setPoint() function to set the point at a given index, the
73
    setPoints() function to set all the points in the polygon
74
    (resizing it to the given number of points), and the putPoints()
75
    function which copies a number of given points into the polygon
76
    from a specified index (resizing the polygon if necessary).
77
78
    QPolygon provides the boundingRect() and translate() functions for
79
    geometry functions. Use the QTransform::map() function for more
80
    general transformations of QPolygons.
81
82
    The QPolygon class is \l {Implicit Data Sharing}{implicitly
83
    shared}.
84
85
    \sa QList, QPolygonF, QLine
86
*/
87
88
89
/*****************************************************************************
90
  QPolygon member functions
91
 *****************************************************************************/
92
93
/*!
94
    \fn QPolygon::QPolygon()
95
96
    Constructs a polygon with no points.
97
98
    \sa QList::isEmpty()
99
*/
100
101
/*!
102
    \fn QPolygon::QPolygon(const QList<QPoint> &points)
103
104
    Constructs a polygon containing the specified \a points.
105
106
    \sa setPoints()
107
*/
108
109
/*!
110
    \fn QPolygon::QPolygon(const QRect &rectangle, bool closed)
111
112
    Constructs a polygon from the given \a rectangle.  If \a closed is
113
    false, the polygon just contains the four points of the rectangle
114
    ordered clockwise, otherwise the polygon's fifth point is set to
115
    \a {rectangle}.topLeft().
116
117
    Note that the bottom-right corner of the rectangle is located at
118
    (rectangle.x() + rectangle.width(), rectangle.y() +
119
    rectangle.height()).
120
121
    \sa setPoints()
122
*/
123
124
QPolygon::QPolygon(const QRect &r, bool closed)
125
0
{
126
0
    reserve(closed ? 5 : 4);
127
0
    *this << QPoint(r.x(), r.y())
128
0
          << QPoint(r.x() + r.width(), r.y())
129
0
          << QPoint(r.x() + r.width(), r.y() + r.height())
130
0
          << QPoint(r.x(), r.y() + r.height());
131
0
    if (closed)
132
0
        *this << QPoint(r.left(), r.top());
133
0
}
134
135
/*!
136
    \internal
137
    Constructs a point array with \a nPoints points, taken from the
138
    \a points array.
139
140
    Equivalent to setPoints(nPoints, points).
141
*/
142
143
QPolygon::QPolygon(int nPoints, const int *points)
144
0
{
145
0
    setPoints(nPoints, points);
146
0
}
147
148
/*!
149
    Translates all points in the polygon by (\a{dx}, \a{dy}).
150
151
    \sa translated()
152
*/
153
154
void QPolygon::translate(int dx, int dy)
155
0
{
156
0
    if (dx == 0 && dy == 0)
157
0
        return;
158
159
0
    QPoint *p = data();
160
0
    int i = size();
161
0
    QPoint pt(dx, dy);
162
0
    while (i--) {
163
0
        *p += pt;
164
0
        ++p;
165
0
    }
166
0
}
167
168
/*!
169
    \fn void QPolygon::translate(const QPoint &offset)
170
    \overload
171
172
    Translates all points in the polygon by the given \a offset.
173
174
    \sa translated()
175
*/
176
177
/*!
178
    Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
179
180
    \since 4.6
181
    \sa translate()
182
*/
183
QPolygon QPolygon::translated(int dx, int dy) const
184
0
{
185
0
    QPolygon copy(*this);
186
0
    copy.translate(dx, dy);
187
0
    return copy;
188
0
}
189
190
/*!
191
    \fn void QPolygon::translated(const QPoint &offset) const
192
    \overload
193
    \since 4.6
194
195
    Returns a copy of the polygon that is translated by the given \a offset.
196
197
    \sa translate()
198
*/
199
200
/*!
201
    Extracts the coordinates of the point at the given \a index to
202
    *\a{x} and *\a{y} (if they are valid pointers).
203
204
    \sa setPoint()
205
*/
206
207
void QPolygon::point(int index, int *x, int *y) const
208
0
{
209
0
    QPoint p = at(index);
210
0
    if (x)
211
0
        *x = (int)p.x();
212
0
    if (y)
213
0
        *y = (int)p.y();
214
0
}
215
216
/*!
217
    \fn QPoint QPolygon::point(int index) const
218
    \overload
219
220
    Returns the point at the given \a index.
221
*/
222
223
/*!
224
    \fn void QPolygon::setPoint(int index, const QPoint &point)
225
    \overload
226
227
    Sets the point at the given \a index to the given \a point.
228
*/
229
230
/*!
231
    Sets the point at the given \a index to the point specified by
232
    (\a{x}, \a{y}).
233
234
    \sa point(), putPoints(), setPoints(),
235
*/
236
void QPolygon::setPoint(int index, int x, int y)
237
0
{
238
0
    (*this)[index] = QPoint(x, y);
239
0
}
240
241
242
/*!
243
    Resizes the polygon to \a nPoints and populates it with the given
244
    \a points.
245
246
    The example code creates a polygon with two points (10, 20) and
247
    (30, 40):
248
249
    \snippet polygon/polygon.cpp 2
250
251
    \sa setPoint(), putPoints()
252
*/
253
254
void QPolygon::setPoints(int nPoints, const int *points)
255
0
{
256
0
    resize(nPoints);
257
0
    int i = 0;
258
0
    while (nPoints--) {
259
0
        setPoint(i++, *points, *(points+1));
260
0
        points += 2;
261
0
    }
262
0
}
263
264
/*!
265
    \overload
266
267
    Resizes the polygon to \a nPoints and populates it with the points
268
    specified by the variable argument list.  The points are given as a
269
    sequence of integers, starting with \a firstx then \a firsty, and
270
    so on.
271
272
    The example code creates a polygon with two points (10, 20) and
273
    (30, 40):
274
275
    \snippet polygon/polygon.cpp 3
276
*/
277
278
void QPolygon::setPoints(int nPoints, int firstx, int firsty, ...)
279
0
{
280
0
    va_list ap;
281
0
    resize(nPoints);
282
0
    setPoint(0, firstx, firsty);
283
0
    int i = 0, x, y;
284
0
    va_start(ap, firsty);
285
0
    while (--nPoints) {
286
0
        x = va_arg(ap, int);
287
0
        y = va_arg(ap, int);
288
0
        setPoint(++i, x, y);
289
0
    }
290
0
    va_end(ap);
291
0
}
292
293
/*!
294
    \overload
295
    \internal
296
297
    Copies \a nPoints points from the \a points coord array into this
298
    point array, and resizes the point array if \c{index+nPoints}
299
    exceeds the size of the array.
300
301
    \sa setPoint()
302
*/
303
304
void QPolygon::putPoints(int index, int nPoints, const int *points)
305
0
{
306
0
    if (index + nPoints > size())
307
0
        resize(index + nPoints);
308
0
    int i = index;
309
0
    while (nPoints--) {
310
0
        setPoint(i++, *points, *(points+1));
311
0
        points += 2;
312
0
    }
313
0
}
314
315
/*!
316
    Copies \a nPoints points from the variable argument list into this
317
    polygon from the given \a index.
318
319
    The points are given as a sequence of integers, starting with \a
320
    firstx then \a firsty, and so on. The polygon is resized if
321
    \c{index+nPoints} exceeds its current size.
322
323
    The example code creates a polygon with three points (4,5), (6,7)
324
    and (8,9), by expanding the polygon from 1 to 3 points:
325
326
    \snippet polygon/polygon.cpp 4
327
328
    The following code has the same result, but here the putPoints()
329
    function overwrites rather than extends:
330
331
    \snippet polygon/polygon.cpp 5
332
333
    \sa setPoints()
334
*/
335
336
void QPolygon::putPoints(int index, int nPoints, int firstx, int firsty, ...)
337
0
{
338
0
    va_list ap;
339
0
    if (index + nPoints > size())
340
0
        resize(index + nPoints);
341
0
    if (nPoints <= 0)
342
0
        return;
343
0
    setPoint(index, firstx, firsty);
344
0
    int i = index, x, y;
345
0
    va_start(ap, firsty);
346
0
    while (--nPoints) {
347
0
        x = va_arg(ap, int);
348
0
        y = va_arg(ap, int);
349
0
        setPoint(++i, x, y);
350
0
    }
351
0
    va_end(ap);
352
0
}
353
354
355
/*!
356
    \fn void QPolygon::putPoints(int index, int nPoints, const QPolygon &fromPolygon, int fromIndex)
357
    \overload
358
359
    Copies \a nPoints points from the given \a fromIndex ( 0 by
360
    default) in \a fromPolygon into this polygon, starting at the
361
    specified \a index. For example:
362
363
    \snippet polygon/polygon.cpp 6
364
*/
365
366
void QPolygon::putPoints(int index, int nPoints, const QPolygon & from, int fromIndex)
367
0
{
368
0
    if (index + nPoints > size())
369
0
        resize(index + nPoints);
370
0
    if (nPoints <= 0)
371
0
        return;
372
0
    int n = 0;
373
0
    while(n < nPoints) {
374
0
        setPoint(index + n, from[fromIndex+n]);
375
0
        ++n;
376
0
    }
377
0
}
378
379
380
/*!
381
    Returns the bounding rectangle of the polygon, or QRect(0, 0, 0,
382
    0) if the polygon is empty.
383
384
    \sa QList::isEmpty()
385
*/
386
387
QRect QPolygon::boundingRect() const
388
0
{
389
0
    const QPoint *pd = constData();
390
0
    const QPoint *pe = pd + size();
391
0
    if (pd == pe)
392
0
        return QRect(0, 0, 0, 0);
393
0
    int minx, maxx, miny, maxy;
394
0
    minx = maxx = pd->x();
395
0
    miny = maxy = pd->y();
396
0
    ++pd;
397
0
    for (; pd != pe; ++pd) {
398
0
        if (pd->x() < minx)
399
0
            minx = pd->x();
400
0
        else if (pd->x() > maxx)
401
0
            maxx = pd->x();
402
0
        if (pd->y() < miny)
403
0
            miny = pd->y();
404
0
        else if (pd->y() > maxy)
405
0
            maxy = pd->y();
406
0
    }
407
0
    return QRect(QPoint(minx,miny), QPoint(maxx,maxy));
408
0
}
409
410
/*!
411
    \fn QPolygon::toPolygonF() const
412
    \since 6.4
413
414
    Returns this polygon as a polygon with floating point accuracy.
415
416
    \sa QPolygonF::toPolygon()
417
*/
418
419
420
#ifndef QT_NO_DEBUG_STREAM
421
QDebug operator<<(QDebug dbg, const QPolygon &a)
422
0
{
423
0
    return QtPrivate::printSequentialContainer(dbg, "QPolygon", a);
424
0
}
425
#endif
426
427
428
/*!
429
    \class QPolygonF
430
    \brief The QPolygonF class provides a list of points using
431
    floating point precision.
432
    \inmodule QtGui
433
434
    \reentrant
435
    \ingroup painting
436
    \ingroup shared
437
438
    A QPolygonF is a QList<QPointF>. The easiest way to add points
439
    to a QPolygonF is to use its streaming operator, as illustrated
440
    below:
441
442
    \snippet polygon/polygon.cpp 1
443
444
    In addition to the functions provided by QList, QPolygonF
445
    provides the boundingRect() and translate() functions for geometry
446
    operations. Use the QTransform::map() function for more general
447
    transformations of QPolygonFs.
448
449
    QPolygonF also provides the isClosed() function to determine
450
    whether a polygon's start and end points are the same, and the
451
    toPolygon() function returning an integer precision copy of this
452
    polygon.
453
454
    The QPolygonF class is \l {Implicit Data Sharing}{implicitly
455
    shared}.
456
457
    \sa QList, QPolygon, QLineF
458
*/
459
460
461
/*****************************************************************************
462
  QPolygonF member functions
463
 *****************************************************************************/
464
465
/*!
466
    \fn QPolygonF::QPolygonF()
467
468
    Constructs a polygon with no points.
469
470
    \sa QList::isEmpty()
471
*/
472
473
/*!
474
    \fn QPolygonF::QPolygonF(const QList<QPointF> &points)
475
476
    Constructs a polygon containing the specified \a points.
477
*/
478
479
/*!
480
    \fn QPolygonF::QPolygonF(const QRectF &rectangle)
481
482
    Constructs a closed polygon from the specified \a rectangle.
483
484
    The polygon contains the four vertices of the rectangle in
485
    clockwise order starting and ending with the top-left vertex.
486
487
    \sa isClosed()
488
*/
489
490
QPolygonF::QPolygonF(const QRectF &r)
491
0
{
492
0
    reserve(5);
493
0
    append(QPointF(r.x(), r.y()));
494
0
    append(QPointF(r.x() + r.width(), r.y()));
495
0
    append(QPointF(r.x() + r.width(), r.y() + r.height()));
496
0
    append(QPointF(r.x(), r.y() + r.height()));
497
0
    append(QPointF(r.x(), r.y()));
498
0
}
499
500
/*!
501
    \fn QPolygonF::QPolygonF(const QPolygon &polygon)
502
503
    Constructs a float based polygon from the specified integer based
504
    \a polygon.
505
506
    \sa toPolygon()
507
*/
508
509
QPolygonF::QPolygonF(const QPolygon &a)
510
0
{
511
0
    reserve(a.size());
512
0
    for (int i=0; i<a.size(); ++i)
513
0
        append(a.at(i));
514
0
}
515
516
/*!
517
    Translate all points in the polygon by the given \a offset.
518
519
    \sa translated()
520
*/
521
522
void QPolygonF::translate(const QPointF &offset)
523
0
{
524
0
    if (offset.isNull())
525
0
        return;
526
527
0
    QPointF *p = data();
528
0
    int i = size();
529
0
    while (i--) {
530
0
        *p += offset;
531
0
        ++p;
532
0
    }
533
0
}
534
535
/*!
536
    \fn void QPolygonF::translate(qreal dx, qreal dy)
537
    \overload
538
539
    Translates all points in the polygon by (\a{dx}, \a{dy}).
540
541
    \sa translated()
542
*/
543
544
/*!
545
    Returns a copy of the polygon that is translated by the given \a offset.
546
547
    \since 4.6
548
    \sa translate()
549
*/
550
QPolygonF QPolygonF::translated(const QPointF &offset) const
551
0
{
552
0
    QPolygonF copy(*this);
553
0
    copy.translate(offset);
554
0
    return copy;
555
0
}
556
557
/*!
558
    \fn void QPolygonF::translated(qreal dx, qreal dy) const
559
    \overload
560
    \since 4.6
561
562
    Returns a copy of the polygon that is translated by (\a{dx}, \a{dy}).
563
564
    \sa translate()
565
*/
566
567
/*!
568
    \fn bool QPolygonF::isClosed() const
569
570
    Returns \c true if the polygon is closed; otherwise returns \c false.
571
572
    A polygon is said to be closed if its start point and end point are equal.
573
574
    \sa QList::first(), QList::last()
575
*/
576
577
/*!
578
    Returns the bounding rectangle of the polygon, or QRectF(0,0,0,0)
579
    if the polygon is empty.
580
581
    \sa QList::isEmpty()
582
*/
583
584
QRectF QPolygonF::boundingRect() const
585
0
{
586
0
    const QPointF *pd = constData();
587
0
    const QPointF *pe = pd + size();
588
0
    if (pd == pe)
589
0
        return QRectF(0, 0, 0, 0);
590
0
    qreal minx, maxx, miny, maxy;
591
0
    minx = maxx = pd->x();
592
0
    miny = maxy = pd->y();
593
0
    ++pd;
594
0
    while (pd != pe) {
595
0
        if (pd->x() < minx)
596
0
            minx = pd->x();
597
0
        else if (pd->x() > maxx)
598
0
            maxx = pd->x();
599
0
        if (pd->y() < miny)
600
0
            miny = pd->y();
601
0
        else if (pd->y() > maxy)
602
0
            maxy = pd->y();
603
0
        ++pd;
604
0
    }
605
0
    return QRectF(minx,miny, maxx - minx, maxy - miny);
606
0
}
607
608
/*!
609
    Creates and returns a QPolygon by converting each QPointF to a
610
    QPoint.
611
612
    \sa QPointF::toPoint()
613
*/
614
615
QPolygon QPolygonF::toPolygon() const
616
0
{
617
0
    QPolygon a;
618
0
    a.reserve(size());
619
0
    for (int i=0; i<size(); ++i)
620
0
        a.append(at(i).toPoint());
621
0
    return a;
622
0
}
623
624
/*!
625
    \fn void QPolygon::swap(QPolygon &other)
626
    \since 4.8
627
    \memberswap{polygon}
628
*/
629
630
/*!
631
    \fn void QPolygonF::swap(QPolygonF &other)
632
    \since 4.8
633
    \memberswap{polygon}
634
*/
635
636
/*!
637
   Returns the polygon as a QVariant
638
*/
639
QPolygon::operator QVariant() const
640
0
{
641
0
    return QVariant::fromValue(*this);
642
0
}
643
644
/*****************************************************************************
645
  QPolygon stream functions
646
 *****************************************************************************/
647
#ifndef QT_NO_DATASTREAM
648
/*!
649
    \fn QDataStream &operator<<(QDataStream &stream, const QPolygon &polygon)
650
    \since 4.4
651
    \relates QPolygon
652
653
    Writes the given \a polygon to the given \a stream, and returns a
654
    reference to the stream.
655
656
    \sa {Serializing Qt Data Types}
657
*/
658
QDataStream &operator<<(QDataStream &s, const QPolygon &a)
659
0
{
660
0
    const QList<QPoint> &v = a;
661
0
    return s << v;
662
0
}
663
664
/*!
665
    \fn QDataStream &operator>>(QDataStream &stream, QPolygon &polygon)
666
    \since 4.4
667
    \relates QPolygon
668
669
    Reads a polygon from the given \a stream into the given \a
670
    polygon, and returns a reference to the stream.
671
672
    \sa {Serializing Qt Data Types}
673
*/
674
QDataStream &operator>>(QDataStream &s, QPolygon &a)
675
0
{
676
0
    QList<QPoint> &v = a;
677
0
    return s >> v;
678
0
}
679
#endif // QT_NO_DATASTREAM
680
681
/*****************************************************************************
682
  QPolygonF stream functions
683
 *****************************************************************************/
684
#ifndef QT_NO_DATASTREAM
685
/*!
686
    \fn QDataStream &operator<<(QDataStream &stream, const QPolygonF &polygon)
687
    \relates QPolygonF
688
689
    Writes the given \a polygon to the given \a stream, and returns a
690
    reference to the stream.
691
692
    \sa {Serializing Qt Data Types}
693
*/
694
695
QDataStream &operator<<(QDataStream &s, const QPolygonF &a)
696
0
{
697
0
    return s << static_cast<const QList<QPointF> &>(a);
698
0
}
699
700
/*!
701
    \fn QDataStream &operator>>(QDataStream &stream, QPolygonF &polygon)
702
    \relates QPolygonF
703
704
    Reads a polygon from the given \a stream into the given \a
705
    polygon, and returns a reference to the stream.
706
707
    \sa {Serializing Qt Data Types}
708
*/
709
710
QDataStream &operator>>(QDataStream &s, QPolygonF &a)
711
0
{
712
0
    return s >> static_cast<QList<QPointF> &>(a);
713
0
}
714
#endif //QT_NO_DATASTREAM
715
716
#ifndef QT_NO_DEBUG_STREAM
717
QDebug operator<<(QDebug dbg, const QPolygonF &a)
718
0
{
719
0
    return QtPrivate::printSequentialContainer(dbg, "QPolygonF", a);
720
0
}
721
#endif
722
723
724
/*!
725
    \since 4.3
726
727
    \fn bool QPolygonF::containsPoint(const QPointF &point, Qt::FillRule fillRule) const
728
729
    Returns \c true if the given \a point is inside the polygon according to
730
    the specified \a fillRule; otherwise returns \c false.
731
*/
732
bool QPolygonF::containsPoint(const QPointF &pt, Qt::FillRule fillRule) const
733
0
{
734
0
    if (isEmpty())
735
0
        return false;
736
737
0
    int winding_number = 0;
738
739
0
    QPointF last_pt = at(0);
740
0
    QPointF last_start = at(0);
741
0
    for (int i = 1; i < size(); ++i) {
742
0
        const QPointF &e = at(i);
743
0
        qt_polygon_isect_line(last_pt, e, pt, &winding_number);
744
0
        last_pt = e;
745
0
    }
746
747
    // implicitly close last subpath
748
0
    if (last_pt != last_start)
749
0
        qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
750
751
0
    return (fillRule == Qt::WindingFill
752
0
            ? (winding_number != 0)
753
0
            : ((winding_number % 2) != 0));
754
0
}
755
756
/*!
757
    \since 4.3
758
759
    \fn bool QPolygon::containsPoint(const QPoint &point, Qt::FillRule fillRule) const
760
    Returns \c true if the given \a point is inside the polygon according to
761
    the specified \a fillRule; otherwise returns \c false.
762
*/
763
bool QPolygon::containsPoint(const QPoint &pt, Qt::FillRule fillRule) const
764
0
{
765
0
    if (isEmpty())
766
0
        return false;
767
768
0
    int winding_number = 0;
769
770
0
    QPoint last_pt = at(0);
771
0
    QPoint last_start = at(0);
772
0
    for (int i = 1; i < size(); ++i) {
773
0
        const QPoint &e = at(i);
774
0
        qt_polygon_isect_line(last_pt, e, pt, &winding_number);
775
0
        last_pt = e;
776
0
    }
777
778
    // implicitly close last subpath
779
0
    if (last_pt != last_start)
780
0
        qt_polygon_isect_line(last_pt, last_start, pt, &winding_number);
781
782
0
    return (fillRule == Qt::WindingFill
783
0
            ? (winding_number != 0)
784
0
            : ((winding_number % 2) != 0));
785
0
}
786
787
/*!
788
    \since 4.3
789
790
    Returns a polygon which is the union of this polygon and \a r.
791
792
    Set operations on polygons, will treat the polygons as areas, and
793
    implicitly close the polygon.
794
795
    \sa intersected(), subtracted()
796
*/
797
798
QPolygon QPolygon::united(const QPolygon &r) const
799
0
{
800
0
    QPainterPath subject; subject.addPolygon(*this);
801
0
    QPainterPath clip; clip.addPolygon(r);
802
803
0
    return subject.united(clip).toFillPolygon().toPolygon();
804
0
}
805
806
/*!
807
    \since 4.3
808
809
    Returns a polygon which is the intersection of this polygon and \a r.
810
811
    Set operations on polygons will treat the polygons as
812
    areas. Non-closed polygons will be treated as implicitly closed.
813
814
    \sa intersects()
815
*/
816
817
QPolygon QPolygon::intersected(const QPolygon &r) const
818
0
{
819
0
    QPainterPath subject; subject.addPolygon(*this);
820
0
    QPainterPath clip; clip.addPolygon(r);
821
822
0
    return subject.intersected(clip).toFillPolygon().toPolygon();
823
0
}
824
825
/*!
826
    \since 4.3
827
828
    Returns a polygon which is \a r subtracted from this polygon.
829
830
    Set operations on polygons will treat the polygons as
831
    areas. Non-closed polygons will be treated as implicitly closed.
832
833
*/
834
835
QPolygon QPolygon::subtracted(const QPolygon &r) const
836
0
{
837
0
    QPainterPath subject; subject.addPolygon(*this);
838
0
    QPainterPath clip; clip.addPolygon(r);
839
840
0
    return subject.subtracted(clip).toFillPolygon().toPolygon();
841
0
}
842
843
/*!
844
    \since 5.10
845
846
    Returns \c true if the current polygon intersects at any point the given polygon \a p.
847
    Also returns \c true if the current polygon contains or is contained by any part of \a p.
848
849
    Set operations on polygons will treat the polygons as
850
    areas. Non-closed polygons will be treated as implicitly closed.
851
852
    \sa intersected()
853
*/
854
855
bool QPolygon::intersects(const QPolygon &p) const
856
0
{
857
0
    QPainterPath subject; subject.addPolygon(*this);
858
0
    QPainterPath clip; clip.addPolygon(p);
859
860
0
    return subject.intersects(clip);
861
0
}
862
863
/*!
864
    \since 4.3
865
866
    Returns a polygon which is the union of this polygon and \a r.
867
868
    Set operations on polygons will treat the polygons as
869
    areas. Non-closed polygons will be treated as implicitly closed.
870
871
    \sa intersected(), subtracted()
872
*/
873
874
QPolygonF QPolygonF::united(const QPolygonF &r) const
875
0
{
876
0
    QPainterPath subject; subject.addPolygon(*this);
877
0
    QPainterPath clip; clip.addPolygon(r);
878
879
0
    return subject.united(clip).toFillPolygon();
880
0
}
881
882
/*!
883
    \since 4.3
884
885
    Returns a polygon which is the intersection of this polygon and \a r.
886
887
    Set operations on polygons will treat the polygons as
888
    areas. Non-closed polygons will be treated as implicitly closed.
889
890
    \sa intersects()
891
*/
892
893
QPolygonF QPolygonF::intersected(const QPolygonF &r) const
894
0
{
895
0
    QPainterPath subject; subject.addPolygon(*this);
896
0
    QPainterPath clip; clip.addPolygon(r);
897
898
0
    return subject.intersected(clip).toFillPolygon();
899
0
}
900
901
/*!
902
    \since 4.3
903
904
    Returns a polygon which is \a r subtracted from this polygon.
905
906
    Set operations on polygons will treat the polygons as
907
    areas. Non-closed polygons will be treated as implicitly closed.
908
909
*/
910
911
QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
912
0
{
913
0
    QPainterPath subject; subject.addPolygon(*this);
914
0
    QPainterPath clip; clip.addPolygon(r);
915
0
    return subject.subtracted(clip).toFillPolygon();
916
0
}
917
918
/*!
919
    \since 5.10
920
921
    Returns \c true if the current polygon intersects at any point the given polygon \a p.
922
    Also returns \c true if the current polygon contains or is contained by any part of \a p.
923
924
    Set operations on polygons will treat the polygons as
925
    areas. Non-closed polygons will be treated as implicitly closed.
926
927
    \sa intersected()
928
*/
929
930
bool QPolygonF::intersects(const QPolygonF &p) const
931
0
{
932
0
    QPainterPath subject; subject.addPolygon(*this);
933
0
    QPainterPath clip; clip.addPolygon(p);
934
935
0
    return subject.intersects(clip);
936
0
}
937
938
/*!
939
   Returns the polygon as a QVariant.
940
*/
941
942
QPolygonF::operator QVariant() const
943
0
{
944
0
    return QVariant::fromValue(*this);
945
0
}
946
947
QT_END_NAMESPACE