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