qregion.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qregion.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2015 The Qt Company Ltd.-
4** Contact: http://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see http://www.qt.io/terms-conditions. For further-
15** information use the contact form at http://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 2.1 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qregion.h"-
35#include "qpainterpath.h"-
36#include "qpolygon.h"-
37#include "qbuffer.h"-
38#include "qdatastream.h"-
39#include "qvariant.h"-
40#include "qvarlengtharray.h"-
41#include "qimage.h"-
42#include "qbitmap.h"-
43-
44#include <private/qdebug_p.h>-
45-
46QT_BEGIN_NAMESPACE-
47-
48/*!-
49 \class QRegion-
50 \brief The QRegion class specifies a clip region for a painter.-
51-
52 \inmodule QtGui-
53 \ingroup painting-
54 \ingroup shared-
55-
56 QRegion is used with QPainter::setClipRegion() to limit the paint-
57 area to what needs to be painted. There is also a QWidget::repaint()-
58 function that takes a QRegion parameter. QRegion is the best tool for-
59 minimizing the amount of screen area to be updated by a repaint.-
60-
61 This class is not suitable for constructing shapes for rendering, especially-
62 as outlines. Use QPainterPath to create paths and shapes for use with-
63 QPainter.-
64-
65 QRegion is an \l{implicitly shared} class.-
66-
67 \section1 Creating and Using Regions-
68-
69 A region can be created from a rectangle, an ellipse, a polygon or-
70 a bitmap. Complex regions may be created by combining simple-
71 regions using united(), intersected(), subtracted(), or xored() (exclusive-
72 or). You can move a region using translate().-
73-
74 You can test whether a region isEmpty() or if it-
75 contains() a QPoint or QRect. The bounding rectangle can be found-
76 with boundingRect().-
77-
78 The function rects() gives a decomposition of the region into-
79 rectangles.-
80-
81 Example of using complex regions:-
82 \snippet code/src_gui_painting_qregion.cpp 0-
83-
84 \section1 Additional License Information-
85-
86 On Embedded Linux, Windows CE and X11 platforms, parts of this class rely on-
87 code obtained under the following licenses:-
88-
89 \legalese-
90 Copyright (c) 1987 X Consortium-
91-
92 Permission is hereby granted, free of charge, to any person obtaining a copy-
93 of this software and associated documentation files (the "Software"), to deal-
94 in the Software without restriction, including without limitation the rights-
95 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-
96 copies of the Software, and to permit persons to whom the Software is-
97 furnished to do so, subject to the following conditions:-
98-
99 The above copyright notice and this permission notice shall be included in-
100 all copies or substantial portions of the Software.-
101-
102 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-
103 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-
104 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-
105 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN-
106 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN-
107 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.-
108-
109 Except as contained in this notice, the name of the X Consortium shall not be-
110 used in advertising or otherwise to promote the sale, use or other dealings-
111 in this Software without prior written authorization from the X Consortium.-
112 \endlegalese-
113-
114 \br-
115-
116 \legalese-
117 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.-
118-
119 All Rights Reserved-
120-
121 Permission to use, copy, modify, and distribute this software and its-
122 documentation for any purpose and without fee is hereby granted,-
123 provided that the above copyright notice appear in all copies and that-
124 both that copyright notice and this permission notice appear in-
125 supporting documentation, and that the name of Digital not be-
126 used in advertising or publicity pertaining to distribution of the-
127 software without specific, written prior permission.-
128-
129 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING-
130 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL-
131 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR-
132 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,-
133 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,-
134 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS-
135 SOFTWARE.-
136 \endlegalese-
137-
138 \sa QPainter::setClipRegion(), QPainter::setClipRect(), QPainterPath-
139*/-
140-
141-
142/*!-
143 \enum QRegion::RegionType-
144-
145 Specifies the shape of the region to be created.-
146-
147 \value Rectangle the region covers the entire rectangle.-
148 \value Ellipse the region is an ellipse inside the rectangle.-
149*/-
150-
151/*!-
152 \fn void QRegion::translate(const QPoint &point)-
153-
154 \overload-
155-
156 Translates the region \a{point}\e{.x()} along the x axis and-
157 \a{point}\e{.y()} along the y axis, relative to the current-
158 position. Positive values move the region to the right and down.-
159-
160 Translates to the given \a point.-
161*/-
162-
163/*****************************************************************************-
164 QRegion member functions-
165 *****************************************************************************/-
166-
167/*!-
168 \fn QRegion::QRegion()-
169-
170 Constructs an empty region.-
171-
172 \sa isEmpty()-
173*/-
174-
175/*!-
176 \fn QRegion::QRegion(const QRect &r, RegionType t)-
177 \overload-
178-
179 Create a region based on the rectange \a r with region type \a t.-
180-
181 If the rectangle is invalid a null region will be created.-
182-
183 \sa QRegion::RegionType-
184*/-
185-
186/*!-
187 \fn QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule)-
188-
189 Constructs a polygon region from the point array \a a with the fill rule-
190 specified by \a fillRule.-
191-
192 If \a fillRule is \l{Qt::WindingFill}, the polygon region is defined-
193 using the winding algorithm; if it is \l{Qt::OddEvenFill}, the odd-even fill-
194 algorithm is used.-
195-
196 \warning This constructor can be used to create complex regions that will-
197 slow down painting when used.-
198*/-
199-
200/*!-
201 \fn QRegion::QRegion(const QRegion &r)-
202-
203 Constructs a new region which is equal to region \a r.-
204*/-
205-
206/*!-
207 \fn QRegion::QRegion(const QBitmap &bm)-
208-
209 Constructs a region from the bitmap \a bm.-
210-
211 The resulting region consists of the pixels in bitmap \a bm that-
212 are Qt::color1, as if each pixel was a 1 by 1 rectangle.-
213-
214 This constructor may create complex regions that will slow down-
215 painting when used. Note that drawing masked pixmaps can be done-
216 much faster using QPixmap::setMask().-
217*/-
218-
219/*!-
220 Constructs a rectangular or elliptic region.-
221-
222 If \a t is \c Rectangle, the region is the filled rectangle (\a x,-
223 \a y, \a w, \a h). If \a t is \c Ellipse, the region is the filled-
224 ellipse with center at (\a x + \a w / 2, \a y + \a h / 2) and size-
225 (\a w ,\a h).-
226*/-
227QRegion::QRegion(int x, int y, int w, int h, RegionType t)-
228{-
229 QRegion tmp(QRect(x, y, w, h), t);-
230 tmp.d->ref.ref();-
231 d = tmp.d;-
232}
never executed: end of block
0
233-
234/*!-
235 \fn QRegion::~QRegion()-
236 \internal-
237-
238 Destroys the region.-
239*/-
240-
241void QRegion::detach()-
242{-
243 if (d->ref.isShared())
d->ref.isShared()Description
TRUEnever evaluated
FALSEnever evaluated
0
244 *this = copy();
never executed: *this = copy();
0
245}
never executed: end of block
0
246-
247// duplicates in qregion_win.cpp and qregion_wce.cpp-
248#define QRGN_SETRECT 1 // region stream commands-
249#define QRGN_SETELLIPSE 2 // (these are internal)-
250#define QRGN_SETPTARRAY_ALT 3-
251#define QRGN_SETPTARRAY_WIND 4-
252#define QRGN_TRANSLATE 5-
253#define QRGN_OR 6-
254#define QRGN_AND 7-
255#define QRGN_SUB 8-
256#define QRGN_XOR 9-
257#define QRGN_RECTS 10-
258-
259-
260#ifndef QT_NO_DATASTREAM-
261-
262/*-
263 Executes region commands in the internal buffer and rebuilds the-
264 original region.-
265-
266 We do this when we read a region from the data stream.-
267-
268 If \a ver is non-0, uses the format version \a ver on reading the-
269 byte array.-
270*/-
271void QRegion::exec(const QByteArray &buffer, int ver, QDataStream::ByteOrder byteOrder)-
272{-
273 QByteArray copy = buffer;-
274 QDataStream s(&copy, QIODevice::ReadOnly);-
275 if (ver)
verDescription
TRUEnever evaluated
FALSEnever evaluated
0
276 s.setVersion(ver);
never executed: s.setVersion(ver);
0
277 s.setByteOrder(byteOrder);-
278 QRegion rgn;-
279#ifndef QT_NO_DEBUG-
280 int test_cnt = 0;-
281#endif-
282 while (!s.atEnd()) {
!s.atEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
283 qint32 id;-
284 if (s.version() == 1) {
s.version() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
285 int id_int;-
286 s >> id_int;-
287 id = id_int;-
288 } else {
never executed: end of block
0
289 s >> id;-
290 }
never executed: end of block
0
291#ifndef QT_NO_DEBUG-
292 if (test_cnt > 0 && id != QRGN_TRANSLATE)
test_cnt > 0Description
TRUEnever evaluated
FALSEnever evaluated
id != 5Description
TRUEnever evaluated
FALSEnever evaluated
0
293 qWarning("QRegion::exec: Internal error");
never executed: QMessageLogger(__FILE__, 293, __PRETTY_FUNCTION__).warning("QRegion::exec: Internal error");
0
294 test_cnt++;-
295#endif-
296 if (id == QRGN_SETRECT || id == QRGN_SETELLIPSE) {
id == 1Description
TRUEnever evaluated
FALSEnever evaluated
id == 2Description
TRUEnever evaluated
FALSEnever evaluated
0
297 QRect r;-
298 s >> r;-
299 rgn = QRegion(r, id == QRGN_SETRECT ? Rectangle : Ellipse);-
300 } else if (id == QRGN_SETPTARRAY_ALT || id == QRGN_SETPTARRAY_WIND) {
never executed: end of block
id == 3Description
TRUEnever evaluated
FALSEnever evaluated
id == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
301 QPolygon a;-
302 s >> a;-
303 rgn = QRegion(a, id == QRGN_SETPTARRAY_WIND ? Qt::WindingFill : Qt::OddEvenFill);-
304 } else if (id == QRGN_TRANSLATE) {
never executed: end of block
id == 5Description
TRUEnever evaluated
FALSEnever evaluated
0
305 QPoint p;-
306 s >> p;-
307 rgn.translate(p.x(), p.y());-
308 } else if (id >= QRGN_OR && id <= QRGN_XOR) {
never executed: end of block
id >= 6Description
TRUEnever evaluated
FALSEnever evaluated
id <= 9Description
TRUEnever evaluated
FALSEnever evaluated
0
309 QByteArray bop1, bop2;-
310 QRegion r1, r2;-
311 s >> bop1;-
312 r1.exec(bop1);-
313 s >> bop2;-
314 r2.exec(bop2);-
315-
316 switch (id) {-
317 case QRGN_OR:
never executed: case 6:
0
318 rgn = r1.united(r2);-
319 break;
never executed: break;
0
320 case QRGN_AND:
never executed: case 7:
0
321 rgn = r1.intersected(r2);-
322 break;
never executed: break;
0
323 case QRGN_SUB:
never executed: case 8:
0
324 rgn = r1.subtracted(r2);-
325 break;
never executed: break;
0
326 case QRGN_XOR:
never executed: case 9:
0
327 rgn = r1.xored(r2);-
328 break;
never executed: break;
0
329 }-
330 } else if (id == QRGN_RECTS) {
never executed: end of block
id == 10Description
TRUEnever evaluated
FALSEnever evaluated
0
331 // (This is the only form used in Qt 2.0)-
332 quint32 n;-
333 s >> n;-
334 QRect r;-
335 for (int i=0; i<(int)n; i++) {
i<(int)nDescription
TRUEnever evaluated
FALSEnever evaluated
0
336 s >> r;-
337 rgn = rgn.united(QRegion(r));-
338 }
never executed: end of block
0
339 }
never executed: end of block
0
340 }
never executed: end of block
0
341 *this = rgn;-
342}
never executed: end of block
0
343-
344-
345/*****************************************************************************-
346 QRegion stream functions-
347 *****************************************************************************/-
348-
349/*!-
350 \fn QRegion &QRegion::operator=(const QRegion &r)-
351-
352 Assigns \a r to this region and returns a reference to the region.-
353*/-
354-
355/*!-
356 \fn QRegion &QRegion::operator=(QRegion &&other)-
357-
358 Move-assigns \a other to this QRegion instance.-
359-
360 \since 5.2-
361*/-
362-
363/*!-
364 \fn void QRegion::swap(QRegion &other)-
365 \since 4.8-
366-
367 Swaps region \a other with this region. This operation is very-
368 fast and never fails.-
369*/-
370-
371/*!-
372 \relates QRegion-
373-
374 Writes the region \a r to the stream \a s and returns a reference-
375 to the stream.-
376-
377 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}-
378*/-
379-
380QDataStream &operator<<(QDataStream &s, const QRegion &r)-
381{-
382 QVector<QRect> a = r.rects();-
383 if (a.isEmpty()) {
a.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
384 s << (quint32)0;-
385 } else {
never executed: end of block
0
386 if (s.version() == 1) {
s.version() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
387 int i;-
388 for (i = a.size() - 1; i > 0; --i) {
i > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
389 s << (quint32)(12 + i * 24);-
390 s << (int)QRGN_OR;-
391 }
never executed: end of block
0
392 for (i = 0; i < a.size(); ++i) {
i < a.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
393 s << (quint32)(4+8) << (int)QRGN_SETRECT << a[i];-
394 }
never executed: end of block
0
395 } else {
never executed: end of block
0
396 s << (quint32)(4 + 4 + 16 * a.size()); // 16: storage size of QRect-
397 s << (qint32)QRGN_RECTS;-
398 s << a;-
399 }
never executed: end of block
0
400 }-
401 return s;
never executed: return s;
0
402}-
403-
404/*!-
405 \relates QRegion-
406-
407 Reads a region from the stream \a s into \a r and returns a-
408 reference to the stream.-
409-
410 \sa{Serializing Qt Data Types}{Format of the QDataStream operators}-
411*/-
412-
413QDataStream &operator>>(QDataStream &s, QRegion &r)-
414{-
415 QByteArray b;-
416 s >> b;-
417 r.exec(b, s.version(), s.byteOrder());-
418 return s;
never executed: return s;
0
419}-
420#endif //QT_NO_DATASTREAM-
421-
422#ifndef QT_NO_DEBUG_STREAM-
423QDebug operator<<(QDebug s, const QRegion &r)-
424{-
425 QDebugStateSaver saver(s);-
426 s.nospace();-
427 s << "QRegion(";-
428 if (r.isNull()) {
r.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
429 s << "null";-
430 } else if (r.isEmpty()) {
never executed: end of block
r.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
431 s << "empty";-
432 } else {
never executed: end of block
0
433 const QVector<QRect> rects = r.rects();-
434 const int count = rects.size();-
435 if (count > 1)
count > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
436 s << "size=" << count << ", bounds=(";
never executed: s << "size=" << count << ", bounds=(";
0
437 QtDebugUtils::formatQRect(s, r.boundingRect());-
438 if (count > 1) {
count > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
439 s << ") - [";-
440 for (int i = 0; i < count; ++i) {
i < countDescription
TRUEnever evaluated
FALSEnever evaluated
0
441 if (i)
iDescription
TRUEnever evaluated
FALSEnever evaluated
0
442 s << ", ";
never executed: s << ", ";
0
443 s << '(';-
444 QtDebugUtils::formatQRect(s, rects.at(i));-
445 s << ')';-
446 }
never executed: end of block
0
447 s << ']';-
448 }
never executed: end of block
0
449 }
never executed: end of block
0
450 s << ')';-
451 return s;
never executed: return s;
0
452}-
453#endif-
454-
455-
456// These are not inline - they can be implemented better on some platforms-
457// (eg. Windows at least provides 3-variable operations). For now, simple.-
458-
459-
460/*!-
461 Applies the united() function to this region and \a r. \c r1|r2 is-
462 equivalent to \c r1.united(r2).-
463-
464 \sa united(), operator+()-
465*/-
466#ifdef Q_COMPILER_MANGLES_RETURN_TYPE-
467const-
468#endif-
469QRegion QRegion::operator|(const QRegion &r) const-
470 { return united(r); }
never executed: return united(r);
0
471-
472/*!-
473 Applies the united() function to this region and \a r. \c r1+r2 is-
474 equivalent to \c r1.united(r2).-
475-
476 \sa united(), operator|()-
477*/-
478#ifdef Q_COMPILER_MANGLES_RETURN_TYPE-
479const-
480#endif-
481QRegion QRegion::operator+(const QRegion &r) const-
482 { return united(r); }
never executed: return united(r);
0
483-
484/*!-
485 \overload-
486 \since 4.4-
487 */-
488#ifdef Q_COMPILER_MANGLES_RETURN_TYPE-
489const-
490#endif-
491QRegion QRegion::operator+(const QRect &r) const-
492 { return united(r); }
never executed: return united(r);
0
493-
494/*!-
495 Applies the intersected() function to this region and \a r. \c r1&r2-
496 is equivalent to \c r1.intersected(r2).-
497-
498 \sa intersected()-
499*/-
500#ifdef Q_COMPILER_MANGLES_RETURN_TYPE-
501const-
502#endif-
503QRegion QRegion::operator&(const QRegion &r) const-
504 { return intersected(r); }
never executed: return intersected(r);
0
505-
506/*!-
507 \overload-
508 \since 4.4-
509 */-
510#ifdef Q_COMPILER_MANGLES_RETURN_TYPE-
511const-
512#endif-
513QRegion QRegion::operator&(const QRect &r) const-
514{-
515 return intersected(r);
never executed: return intersected(r);
0
516}-
517-
518/*!-
519 Applies the subtracted() function to this region and \a r. \c r1-r2-
520 is equivalent to \c r1.subtracted(r2).-
521-
522 \sa subtracted()-
523*/-
524#ifdef Q_COMPILER_MANGLES_RETURN_TYPE-
525const-
526#endif-
527QRegion QRegion::operator-(const QRegion &r) const-
528 { return subtracted(r); }
never executed: return subtracted(r);
0
529-
530/*!-
531 Applies the xored() function to this region and \a r. \c r1^r2 is-
532 equivalent to \c r1.xored(r2).-
533-
534 \sa xored()-
535*/-
536#ifdef Q_COMPILER_MANGLES_RETURN_TYPE-
537const-
538#endif-
539QRegion QRegion::operator^(const QRegion &r) const-
540 { return xored(r); }
never executed: return xored(r);
0
541-
542/*!-
543 Applies the united() function to this region and \a r and assigns-
544 the result to this region. \c r1|=r2 is equivalent to \c-
545 {r1 = r1.united(r2)}.-
546-
547 \sa united()-
548*/-
549QRegion& QRegion::operator|=(const QRegion &r)-
550 { return *this = *this | r; }
never executed: return *this = *this | r;
0
551-
552/*!-
553 \fn QRegion& QRegion::operator+=(const QRect &rect)-
554-
555 Returns a region that is the union of this region with the specified \a rect.-
556-
557 \sa united()-
558*/-
559/*!-
560 \fn QRegion& QRegion::operator+=(const QRegion &r)-
561-
562 Applies the united() function to this region and \a r and assigns-
563 the result to this region. \c r1+=r2 is equivalent to \c-
564 {r1 = r1.united(r2)}.-
565-
566 \sa intersected()-
567*/-
568#if !defined (Q_OS_UNIX) && !defined (Q_OS_WIN)-
569QRegion& QRegion::operator+=(const QRect &r)-
570{-
571 return operator+=(QRegion(r));-
572}-
573#endif-
574-
575/*!-
576 \fn QRegion& QRegion::operator&=(const QRegion &r)-
577-
578 Applies the intersected() function to this region and \a r and-
579 assigns the result to this region. \c r1&=r2 is equivalent to \c-
580 r1 = r1.intersected(r2).-
581-
582 \sa intersected()-
583*/-
584QRegion& QRegion::operator&=(const QRegion &r)-
585 { return *this = *this & r; }
never executed: return *this = *this & r;
0
586-
587/*!-
588 \overload-
589 \since 4.4-
590 */-
591#if defined (Q_OS_UNIX) || defined (Q_OS_WIN)-
592QRegion& QRegion::operator&=(const QRect &r)-
593{-
594 return *this = *this & r;
never executed: return *this = *this & r;
0
595}-
596#else-
597QRegion& QRegion::operator&=(const QRect &r)-
598{-
599 return *this &= (QRegion(r));-
600}-
601#endif-
602-
603/*!-
604 \fn QRegion& QRegion::operator-=(const QRegion &r)-
605-
606 Applies the subtracted() function to this region and \a r and-
607 assigns the result to this region. \c r1-=r2 is equivalent to \c-
608 {r1 = r1.subtracted(r2)}.-
609-
610 \sa subtracted()-
611*/-
612QRegion& QRegion::operator-=(const QRegion &r)-
613 { return *this = *this - r; }
never executed: return *this = *this - r;
0
614-
615/*!-
616 Applies the xored() function to this region and \a r and-
617 assigns the result to this region. \c r1^=r2 is equivalent to \c-
618 {r1 = r1.xored(r2)}.-
619-
620 \sa xored()-
621*/-
622QRegion& QRegion::operator^=(const QRegion &r)-
623 { return *this = *this ^ r; }
never executed: return *this = *this ^ r;
0
624-
625/*!-
626 \fn bool QRegion::operator!=(const QRegion &other) const-
627-
628 Returns \c true if this region is different from the \a other region;-
629 otherwise returns \c false.-
630*/-
631-
632/*!-
633 Returns the region as a QVariant-
634*/-
635QRegion::operator QVariant() const-
636{-
637 return QVariant(QVariant::Region, this);
never executed: return QVariant(QVariant::Region, this);
0
638}-
639-
640/*!-
641 \fn bool QRegion::operator==(const QRegion &r) const-
642-
643 Returns \c true if the region is equal to \a r; otherwise returns-
644 false.-
645*/-
646-
647/*!-
648 \fn void QRegion::translate(int dx, int dy)-
649-
650 Translates (moves) the region \a dx along the X axis and \a dy-
651 along the Y axis.-
652*/-
653-
654/*!-
655 \fn QRegion QRegion::translated(const QPoint &p) const-
656 \overload-
657 \since 4.1-
658-
659 Returns a copy of the regtion that is translated \a{p}\e{.x()}-
660 along the x axis and \a{p}\e{.y()} along the y axis, relative to-
661 the current position. Positive values move the rectangle to the-
662 right and down.-
663-
664 \sa translate()-
665*/-
666-
667/*!-
668 \since 4.1-
669-
670 Returns a copy of the region that is translated \a dx along the-
671 x axis and \a dy along the y axis, relative to the current-
672 position. Positive values move the region to the right and-
673 down.-
674-
675 \sa translate()-
676*/-
677-
678QRegion-
679QRegion::translated(int dx, int dy) const-
680{-
681 QRegion ret(*this);-
682 ret.translate(dx, dy);-
683 return ret;
never executed: return ret;
0
684}-
685-
686-
687inline bool rect_intersects(const QRect &r1, const QRect &r2)-
688{-
689 return (r1.right() >= r2.left() && r1.left() <= r2.right() &&
never executed: return (r1.right() >= r2.left() && r1.left() <= r2.right() && r1.bottom() >= r2.top() && r1.top() <= r2.bottom());
r1.right() >= r2.left()Description
TRUEnever evaluated
FALSEnever evaluated
r1.left() <= r2.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
690 r1.bottom() >= r2.top() && r1.top() <= r2.bottom());
never executed: return (r1.right() >= r2.left() && r1.left() <= r2.right() && r1.bottom() >= r2.top() && r1.top() <= r2.bottom());
r1.bottom() >= r2.top()Description
TRUEnever evaluated
FALSEnever evaluated
r1.top() <= r2.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
691}-
692-
693/*!-
694 \since 4.2-
695-
696 Returns \c true if this region intersects with \a region, otherwise-
697 returns \c false.-
698*/-
699bool QRegion::intersects(const QRegion &region) const-
700{-
701 if (isEmpty() || region.isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
region.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
702 return false;
never executed: return false;
0
703-
704 if (!rect_intersects(boundingRect(), region.boundingRect()))
!rect_intersec...oundingRect())Description
TRUEnever evaluated
FALSEnever evaluated
0
705 return false;
never executed: return false;
0
706 if (rectCount() == 1 && region.rectCount() == 1)
rectCount() == 1Description
TRUEnever evaluated
FALSEnever evaluated
region.rectCount() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
707 return true;
never executed: return true;
0
708-
709 const QVector<QRect> myRects = rects();-
710 const QVector<QRect> otherRects = region.rects();-
711-
712 for (QVector<QRect>::const_iterator i1 = myRects.constBegin(); i1 < myRects.constEnd(); ++i1)
i1 < myRects.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
713 for (QVector<QRect>::const_iterator i2 = otherRects.constBegin(); i2 < otherRects.constEnd(); ++i2)
i2 < otherRects.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
714 if (rect_intersects(*i1, *i2))
rect_intersects(*i1, *i2)Description
TRUEnever evaluated
FALSEnever evaluated
0
715 return true;
never executed: return true;
0
716 return false;
never executed: return false;
0
717}-
718-
719/*!-
720 \fn bool QRegion::intersects(const QRect &rect) const-
721 \since 4.2-
722-
723 Returns \c true if this region intersects with \a rect, otherwise-
724 returns \c false.-
725*/-
726-
727-
728#if !defined (Q_OS_UNIX) && !defined (Q_OS_WIN)-
729/*!-
730 \overload-
731 \since 4.4-
732*/-
733QRegion QRegion::intersect(const QRect &r) const-
734{-
735 return intersect(QRegion(r));-
736}-
737#endif-
738-
739/*!-
740 \fn int QRegion::rectCount() const-
741 \since 4.6-
742-
743 Returns the number of rectangles that will be returned in rects().-
744*/-
745-
746/*!-
747 \fn bool QRegion::isEmpty() const-
748-
749 Returns \c true if the region is empty; otherwise returns \c false. An-
750 empty region is a region that contains no points.-
751-
752 Example:-
753 \snippet code/src_gui_painting_qregion_unix.cpp 0-
754*/-
755-
756/*!-
757 \fn bool QRegion::isNull() const-
758 \since 5.0-
759-
760 Returns \c true if the region is empty; otherwise returns \c false. An-
761 empty region is a region that contains no points. This function is-
762 the same as isEmpty-
763-
764 \sa isEmpty()-
765*/-
766-
767/*!-
768 \fn bool QRegion::contains(const QPoint &p) const-
769-
770 Returns \c true if the region contains the point \a p; otherwise-
771 returns \c false.-
772*/-
773-
774/*!-
775 \fn bool QRegion::contains(const QRect &r) const-
776 \overload-
777-
778 Returns \c true if the region overlaps the rectangle \a r; otherwise-
779 returns \c false.-
780*/-
781-
782/*!-
783 \fn QRegion QRegion::unite(const QRegion &r) const-
784 \obsolete-
785-
786 Use united(\a r) instead.-
787*/-
788-
789/*!-
790 \fn QRegion QRegion::unite(const QRect &rect) const-
791 \since 4.4-
792 \obsolete-
793-
794 Use united(\a rect) instead.-
795*/-
796-
797/*!-
798 \fn QRegion QRegion::united(const QRect &rect) const-
799 \since 4.4-
800-
801 Returns a region which is the union of this region and the given \a rect.-
802-
803 \sa intersected(), subtracted(), xored()-
804*/-
805-
806/*!-
807 \fn QRegion QRegion::united(const QRegion &r) const-
808 \since 4.2-
809-
810 Returns a region which is the union of this region and \a r.-
811-
812 \image runion.png Region Union-
813-
814 The figure shows the union of two elliptical regions.-
815-
816 \sa intersected(), subtracted(), xored()-
817*/-
818-
819/*!-
820 \fn QRegion QRegion::intersect(const QRegion &r) const-
821 \obsolete-
822-
823 Use intersected(\a r) instead.-
824*/-
825-
826/*!-
827 \fn QRegion QRegion::intersect(const QRect &rect) const-
828 \since 4.4-
829 \obsolete-
830-
831 Use intersected(\a rect) instead.-
832*/-
833-
834/*!-
835 \fn QRegion QRegion::intersected(const QRect &rect) const-
836 \since 4.4-
837-
838 Returns a region which is the intersection of this region and the given \a rect.-
839-
840 \sa subtracted(), united(), xored()-
841*/-
842-
843/*!-
844 \fn QRegion QRegion::intersected(const QRegion &r) const-
845 \since 4.2-
846-
847 Returns a region which is the intersection of this region and \a r.-
848-
849 \image rintersect.png Region Intersection-
850-
851 The figure shows the intersection of two elliptical regions.-
852-
853 \sa subtracted(), united(), xored()-
854*/-
855-
856/*!-
857 \fn QRegion QRegion::subtract(const QRegion &r) const-
858 \obsolete-
859-
860 Use subtracted(\a r) instead.-
861*/-
862-
863/*!-
864 \fn QRegion QRegion::subtracted(const QRegion &r) const-
865 \since 4.2-
866-
867 Returns a region which is \a r subtracted from this region.-
868-
869 \image rsubtract.png Region Subtraction-
870-
871 The figure shows the result when the ellipse on the right is-
872 subtracted from the ellipse on the left (\c {left - right}).-
873-
874 \sa intersected(), united(), xored()-
875*/-
876-
877/*!-
878 \fn QRegion QRegion::eor(const QRegion &r) const-
879 \obsolete-
880-
881 Use xored(\a r) instead.-
882*/-
883-
884/*!-
885 \fn QRegion QRegion::xored(const QRegion &r) const-
886 \since 4.2-
887-
888 Returns a region which is the exclusive or (XOR) of this region-
889 and \a r.-
890-
891 \image rxor.png Region XORed-
892-
893 The figure shows the exclusive or of two elliptical regions.-
894-
895 \sa intersected(), united(), subtracted()-
896*/-
897-
898/*!-
899 \fn QRect QRegion::boundingRect() const-
900-
901 Returns the bounding rectangle of this region. An empty region-
902 gives a rectangle that is QRect::isNull().-
903*/-
904-
905/*!-
906 \fn QVector<QRect> QRegion::rects() const-
907-
908 Returns an array of non-overlapping rectangles that make up the-
909 region.-
910-
911 The union of all the rectangles is equal to the original region.-
912*/-
913-
914/*!-
915 \fn void QRegion::setRects(const QRect *rects, int number)-
916-
917 Sets the region using the array of rectangles specified by \a rects and-
918 \a number.-
919 The rectangles \e must be optimally Y-X sorted and follow these restrictions:-
920-
921 \list-
922 \li The rectangles must not intersect.-
923 \li All rectangles with a given top coordinate must have the same height.-
924 \li No two rectangles may abut horizontally (they should be combined-
925 into a single wider rectangle in that case).-
926 \li The rectangles must be sorted in ascending order, with Y as the major-
927 sort key and X as the minor sort key.-
928 \endlist-
929 \omit-
930 Only some platforms have these restrictions (Qt for Embedded Linux, X11 and \macos).-
931 \endomit-
932*/-
933-
934namespace {-
935-
936struct Segment-
937{-
938 Segment() {}-
939 Segment(const QPoint &p)-
940 : added(false)-
941 , point(p)-
942 {-
943 }
never executed: end of block
0
944-
945 int left() const-
946 {-
947 return qMin(point.x(), next->point.x());
never executed: return qMin(point.x(), next->point.x());
0
948 }-
949-
950 int right() const-
951 {-
952 return qMax(point.x(), next->point.x());
never executed: return qMax(point.x(), next->point.x());
0
953 }-
954-
955 bool overlaps(const Segment &other) const-
956 {-
957 return left() < other.right() && other.left() < right();
never executed: return left() < other.right() && other.left() < right();
left() < other.right()Description
TRUEnever evaluated
FALSEnever evaluated
other.left() < right()Description
TRUEnever evaluated
FALSEnever evaluated
0
958 }-
959-
960 void connect(Segment &other)-
961 {-
962 next = &other;-
963 other.prev = this;-
964-
965 horizontal = (point.y() == other.point.y());-
966 }
never executed: end of block
0
967-
968 void merge(Segment &other)-
969 {-
970 if (right() <= other.right()) {
right() <= other.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
971 QPoint p = other.point;-
972 Segment *oprev = other.prev;-
973-
974 other.point = point;-
975 other.prev = prev;-
976 prev->next = &other;-
977-
978 point = p;-
979 prev = oprev;-
980 oprev->next = this;-
981 } else {
never executed: end of block
0
982 Segment *onext = other.next;-
983 other.next = next;-
984 next->prev = &other;-
985-
986 next = onext;-
987 next->prev = this;-
988 }
never executed: end of block
0
989 }-
990-
991 int horizontal : 1;-
992 int added : 1;-
993-
994 QPoint point;-
995 Segment *prev;-
996 Segment *next;-
997};-
998-
999void mergeSegments(Segment *a, int na, Segment *b, int nb)-
1000{-
1001 int i = 0;-
1002 int j = 0;-
1003-
1004 while (i != na && j != nb) {
i != naDescription
TRUEnever evaluated
FALSEnever evaluated
j != nbDescription
TRUEnever evaluated
FALSEnever evaluated
0
1005 Segment &sa = a[i];-
1006 Segment &sb = b[j];-
1007 const int ra = sa.right();-
1008 const int rb = sb.right();-
1009 if (sa.overlaps(sb))
sa.overlaps(sb)Description
TRUEnever evaluated
FALSEnever evaluated
0
1010 sa.merge(sb);
never executed: sa.merge(sb);
0
1011 i += (rb >= ra);-
1012 j += (ra >= rb);-
1013 }
never executed: end of block
0
1014}
never executed: end of block
0
1015-
1016void addSegmentsToPath(Segment *segment, QPainterPath &path)-
1017{-
1018 Segment *current = segment;-
1019 path.moveTo(current->point);-
1020-
1021 current->added = true;-
1022-
1023 Segment *last = current;-
1024 current = current->next;-
1025 while (current != segment) {
current != segmentDescription
TRUEnever evaluated
FALSEnever evaluated
0
1026 if (current->horizontal != last->horizontal)
current->horiz...st->horizontalDescription
TRUEnever evaluated
FALSEnever evaluated
0
1027 path.lineTo(current->point);
never executed: path.lineTo(current->point);
0
1028 current->added = true;-
1029 last = current;-
1030 current = current->next;-
1031 }
never executed: end of block
0
1032}
never executed: end of block
0
1033-
1034}-
1035-
1036Q_GUI_EXPORT QPainterPath qt_regionToPath(const QRegion &region)-
1037{-
1038 QPainterPath result;-
1039 if (region.rectCount() == 1) {
region.rectCount() == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1040 result.addRect(region.boundingRect());-
1041 return result;
never executed: return result;
0
1042 }-
1043-
1044 const QVector<QRect> rects = region.rects();-
1045-
1046 QVarLengthArray<Segment> segments;-
1047 segments.resize(4 * rects.size());-
1048-
1049 const QRect *rect = rects.constData();-
1050 const QRect *end = rect + rects.size();-
1051-
1052 int lastRowSegmentCount = 0;-
1053 Segment *lastRowSegments = 0;-
1054-
1055 int lastSegment = 0;-
1056 int lastY = 0;-
1057 while (rect != end) {
rect != endDescription
TRUEnever evaluated
FALSEnever evaluated
0
1058 const int y = rect[0].y();-
1059 int count = 0;-
1060 while (&rect[count] != end && rect[count].y() == y)
&rect[count] != endDescription
TRUEnever evaluated
FALSEnever evaluated
rect[count].y() == yDescription
TRUEnever evaluated
FALSEnever evaluated
0
1061 ++count;
never executed: ++count;
0
1062-
1063 for (int i = 0; i < count; ++i) {
i < countDescription
TRUEnever evaluated
FALSEnever evaluated
0
1064 int offset = lastSegment + i;-
1065 segments[offset] = Segment(rect[i].topLeft());-
1066 segments[offset += count] = Segment(rect[i].topRight() + QPoint(1, 0));-
1067 segments[offset += count] = Segment(rect[i].bottomRight() + QPoint(1, 1));-
1068 segments[offset += count] = Segment(rect[i].bottomLeft() + QPoint(0, 1));-
1069-
1070 offset = lastSegment + i;-
1071 for (int j = 0; j < 4; ++j)
j < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
1072 segments[offset + j * count].connect(segments[offset + ((j + 1) % 4) * count]);
never executed: segments[offset + j * count].connect(segments[offset + ((j + 1) % 4) * count]);
0
1073 }
never executed: end of block
0
1074-
1075 if (lastRowSegments && lastY == y)
lastRowSegmentsDescription
TRUEnever evaluated
FALSEnever evaluated
lastY == yDescription
TRUEnever evaluated
FALSEnever evaluated
0
1076 mergeSegments(lastRowSegments, lastRowSegmentCount, &segments[lastSegment], count);
never executed: mergeSegments(lastRowSegments, lastRowSegmentCount, &segments[lastSegment], count);
0
1077-
1078 lastRowSegments = &segments[lastSegment + 2 * count];-
1079 lastRowSegmentCount = count;-
1080 lastSegment += 4 * count;-
1081 lastY = y + rect[0].height();-
1082 rect += count;-
1083 }
never executed: end of block
0
1084-
1085 for (int i = 0; i < lastSegment; ++i) {
i < lastSegmentDescription
TRUEnever evaluated
FALSEnever evaluated
0
1086 Segment *segment = &segments[i];-
1087 if (!segment->added)
!segment->addedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1088 addSegmentsToPath(segment, result);
never executed: addSegmentsToPath(segment, result);
0
1089 }
never executed: end of block
0
1090-
1091 return result;
never executed: return result;
0
1092}-
1093-
1094#if defined(Q_OS_UNIX) || defined(Q_OS_WIN)-
1095-
1096//#define QT_REGION_DEBUG-
1097/*-
1098 * clip region-
1099 */-
1100-
1101struct QRegionPrivate {-
1102 int numRects;-
1103 int innerArea;-
1104 QVector<QRect> rects;-
1105 QRect extents;-
1106 QRect innerRect;-
1107-
1108 inline QRegionPrivate() : numRects(0), innerArea(-1) {}
never executed: end of block
0
1109 inline QRegionPrivate(const QRect &r)-
1110 : numRects(1),-
1111 innerArea(r.width() * r.height()),-
1112 extents(r),-
1113 innerRect(r)-
1114 {-
1115 }
never executed: end of block
0
1116-
1117 void intersect(const QRect &r);-
1118-
1119 /*-
1120 * Returns \c true if r is guaranteed to be fully contained in this region.-
1121 * A false return value does not guarantee the opposite.-
1122 */-
1123 inline bool contains(const QRegionPrivate &r) const {-
1124 return contains(r.extents);
never executed: return contains(r.extents);
0
1125 }-
1126-
1127 inline bool contains(const QRect &r2) const {-
1128 const QRect &r1 = innerRect;-
1129 return r2.left() >= r1.left() && r2.right() <= r1.right()
never executed: return r2.left() >= r1.left() && r2.right() <= r1.right() && r2.top() >= r1.top() && r2.bottom() <= r1.bottom();
r2.left() >= r1.left()Description
TRUEnever evaluated
FALSEnever evaluated
r2.right() <= r1.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1130 && r2.top() >= r1.top() && r2.bottom() <= r1.bottom();
never executed: return r2.left() >= r1.left() && r2.right() <= r1.right() && r2.top() >= r1.top() && r2.bottom() <= r1.bottom();
r2.top() >= r1.top()Description
TRUEnever evaluated
FALSEnever evaluated
r2.bottom() <= r1.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
1131 }-
1132-
1133 /*-
1134 * Returns \c true if this region is guaranteed to be fully contained in r.-
1135 */-
1136 inline bool within(const QRect &r1) const {-
1137 const QRect &r2 = extents;-
1138 return r2.left() >= r1.left() && r2.right() <= r1.right()
never executed: return r2.left() >= r1.left() && r2.right() <= r1.right() && r2.top() >= r1.top() && r2.bottom() <= r1.bottom();
r2.left() >= r1.left()Description
TRUEnever evaluated
FALSEnever evaluated
r2.right() <= r1.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1139 && r2.top() >= r1.top() && r2.bottom() <= r1.bottom();
never executed: return r2.left() >= r1.left() && r2.right() <= r1.right() && r2.top() >= r1.top() && r2.bottom() <= r1.bottom();
r2.top() >= r1.top()Description
TRUEnever evaluated
FALSEnever evaluated
r2.bottom() <= r1.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
1140 }-
1141-
1142 inline void updateInnerRect(const QRect &rect) {-
1143 const int area = rect.width() * rect.height();-
1144 if (area > innerArea) {
area > innerAreaDescription
TRUEnever evaluated
FALSEnever evaluated
0
1145 innerArea = area;-
1146 innerRect = rect;-
1147 }
never executed: end of block
0
1148 }
never executed: end of block
0
1149-
1150 inline void vectorize() {-
1151 if (numRects == 1) {
numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1152 if (!rects.size())
!rects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1153 rects.resize(1);
never executed: rects.resize(1);
0
1154 rects[0] = extents;-
1155 }
never executed: end of block
0
1156 }
never executed: end of block
0
1157-
1158 inline void append(const QRect *r);-
1159 void append(const QRegionPrivate *r);-
1160 void prepend(const QRect *r);-
1161 void prepend(const QRegionPrivate *r);-
1162 inline bool canAppend(const QRect *r) const;-
1163 inline bool canAppend(const QRegionPrivate *r) const;-
1164 inline bool canPrepend(const QRect *r) const;-
1165 inline bool canPrepend(const QRegionPrivate *r) const;-
1166-
1167 inline bool mergeFromRight(QRect *left, const QRect *right);-
1168 inline bool mergeFromLeft(QRect *left, const QRect *right);-
1169 inline bool mergeFromBelow(QRect *top, const QRect *bottom,-
1170 const QRect *nextToTop,-
1171 const QRect *nextToBottom);-
1172 inline bool mergeFromAbove(QRect *bottom, const QRect *top,-
1173 const QRect *nextToBottom,-
1174 const QRect *nextToTop);-
1175-
1176#ifdef QT_REGION_DEBUG-
1177 void selfTest() const;-
1178#endif-
1179};-
1180-
1181static inline bool isEmptyHelper(const QRegionPrivate *preg)-
1182{-
1183 return !preg || preg->numRects == 0;
never executed: return !preg || preg->numRects == 0;
!pregDescription
TRUEnever evaluated
FALSEnever evaluated
preg->numRects == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1184}-
1185-
1186static inline bool canMergeFromRight(const QRect *left, const QRect *right)-
1187{-
1188 return (right->top() == left->top()
never executed: return (right->top() == left->top() && right->bottom() == left->bottom() && right->left() <= (left->right() + 1));
right->top() == left->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
1189 && right->bottom() == left->bottom()
never executed: return (right->top() == left->top() && right->bottom() == left->bottom() && right->left() <= (left->right() + 1));
right->bottom(...left->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
1190 && right->left() <= (left->right() + 1));
never executed: return (right->top() == left->top() && right->bottom() == left->bottom() && right->left() <= (left->right() + 1));
right->left() ...->right() + 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1191}-
1192-
1193static inline bool canMergeFromLeft(const QRect *right, const QRect *left)-
1194{-
1195 return canMergeFromRight(left, right);
never executed: return canMergeFromRight(left, right);
0
1196}-
1197-
1198bool QRegionPrivate::mergeFromRight(QRect *left, const QRect *right)-
1199{-
1200 if (canMergeFromRight(left, right)) {
canMergeFromRight(left, right)Description
TRUEnever evaluated
FALSEnever evaluated
0
1201 left->setRight(right->right());-
1202 updateInnerRect(*left);-
1203 return true;
never executed: return true;
0
1204 }-
1205 return false;
never executed: return false;
0
1206}-
1207-
1208bool QRegionPrivate::mergeFromLeft(QRect *right, const QRect *left)-
1209{-
1210 if (canMergeFromLeft(right, left)) {
canMergeFromLeft(right, left)Description
TRUEnever evaluated
FALSEnever evaluated
0
1211 right->setLeft(left->left());-
1212 updateInnerRect(*right);-
1213 return true;
never executed: return true;
0
1214 }-
1215 return false;
never executed: return false;
0
1216}-
1217-
1218static inline bool canMergeFromBelow(const QRect *top, const QRect *bottom,-
1219 const QRect *nextToTop,-
1220 const QRect *nextToBottom)-
1221{-
1222 if (nextToTop && nextToTop->y() == top->y())
nextToTopDescription
TRUEnever evaluated
FALSEnever evaluated
nextToTop->y() == top->y()Description
TRUEnever evaluated
FALSEnever evaluated
0
1223 return false;
never executed: return false;
0
1224 if (nextToBottom && nextToBottom->y() == bottom->y())
nextToBottomDescription
TRUEnever evaluated
FALSEnever evaluated
nextToBottom->...== bottom->y()Description
TRUEnever evaluated
FALSEnever evaluated
0
1225 return false;
never executed: return false;
0
1226-
1227 return ((top->bottom() >= (bottom->top() - 1))
never executed: return ((top->bottom() >= (bottom->top() - 1)) && top->left() == bottom->left() && top->right() == bottom->right());
(top->bottom()...m->top() - 1))Description
TRUEnever evaluated
FALSEnever evaluated
0
1228 && top->left() == bottom->left()
never executed: return ((top->bottom() >= (bottom->top() - 1)) && top->left() == bottom->left() && top->right() == bottom->right());
top->left() == bottom->left()Description
TRUEnever evaluated
FALSEnever evaluated
0
1229 && top->right() == bottom->right());
never executed: return ((top->bottom() >= (bottom->top() - 1)) && top->left() == bottom->left() && top->right() == bottom->right());
top->right() =...ottom->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1230}-
1231-
1232bool QRegionPrivate::mergeFromBelow(QRect *top, const QRect *bottom,-
1233 const QRect *nextToTop,-
1234 const QRect *nextToBottom)-
1235{-
1236 if (canMergeFromBelow(top, bottom, nextToTop, nextToBottom)) {
canMergeFromBe... nextToBottom)Description
TRUEnever evaluated
FALSEnever evaluated
0
1237 top->setBottom(bottom->bottom());-
1238 updateInnerRect(*top);-
1239 return true;
never executed: return true;
0
1240 }-
1241 return false;
never executed: return false;
0
1242}-
1243-
1244bool QRegionPrivate::mergeFromAbove(QRect *bottom, const QRect *top,-
1245 const QRect *nextToBottom,-
1246 const QRect *nextToTop)-
1247{-
1248 if (canMergeFromBelow(top, bottom, nextToTop, nextToBottom)) {
canMergeFromBe... nextToBottom)Description
TRUEnever evaluated
FALSEnever evaluated
0
1249 bottom->setTop(top->top());-
1250 updateInnerRect(*bottom);-
1251 return true;
never executed: return true;
0
1252 }-
1253 return false;
never executed: return false;
0
1254}-
1255-
1256static inline QRect qt_rect_intersect_normalized(const QRect &r1,-
1257 const QRect &r2)-
1258{-
1259 QRect r;-
1260 r.setLeft(qMax(r1.left(), r2.left()));-
1261 r.setRight(qMin(r1.right(), r2.right()));-
1262 r.setTop(qMax(r1.top(), r2.top()));-
1263 r.setBottom(qMin(r1.bottom(), r2.bottom()));-
1264 return r;
never executed: return r;
0
1265}-
1266-
1267void QRegionPrivate::intersect(const QRect &rect)-
1268{-
1269 Q_ASSERT(extents.intersects(rect));-
1270 Q_ASSERT(numRects > 1);-
1271-
1272#ifdef QT_REGION_DEBUG-
1273 selfTest();-
1274#endif-
1275-
1276 const QRect r = rect.normalized();-
1277 extents = QRect();-
1278 innerRect = QRect();-
1279 innerArea = -1;-
1280-
1281 QRect *dest = rects.data();-
1282 const QRect *src = dest;-
1283 int n = numRects;-
1284 numRects = 0;-
1285 while (n--) {
n--Description
TRUEnever evaluated
FALSEnever evaluated
0
1286 *dest = qt_rect_intersect_normalized(*src++, r);-
1287 if (dest->isEmpty())
dest->isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1288 continue;
never executed: continue;
0
1289-
1290 if (numRects == 0) {
numRects == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1291 extents = *dest;-
1292 } else {
never executed: end of block
0
1293 extents.setLeft(qMin(extents.left(), dest->left()));-
1294 // hw: extents.top() will never change after initialization-
1295 //extents.setTop(qMin(extents.top(), dest->top()));-
1296 extents.setRight(qMax(extents.right(), dest->right()));-
1297 extents.setBottom(qMax(extents.bottom(), dest->bottom()));-
1298-
1299 const QRect *nextToLast = (numRects > 1 ? dest - 2 : 0);
numRects > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1300-
1301 // mergeFromBelow inlined and optimized-
1302 if (canMergeFromBelow(dest - 1, dest, nextToLast, 0)) {
canMergeFromBe...nextToLast, 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1303 if (!n || src->y() != dest->y() || src->left() > r.right()) {
!nDescription
TRUEnever evaluated
FALSEnever evaluated
src->y() != dest->y()Description
TRUEnever evaluated
FALSEnever evaluated
src->left() > r.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1304 QRect *prev = dest - 1;-
1305 prev->setBottom(dest->bottom());-
1306 updateInnerRect(*prev);-
1307 continue;
never executed: continue;
0
1308 }-
1309 }
never executed: end of block
0
1310 }
never executed: end of block
0
1311 updateInnerRect(*dest);-
1312 ++dest;-
1313 ++numRects;-
1314 }
never executed: end of block
0
1315#ifdef QT_REGION_DEBUG-
1316 selfTest();-
1317#endif-
1318}
never executed: end of block
0
1319-
1320void QRegionPrivate::append(const QRect *r)-
1321{-
1322 Q_ASSERT(!r->isEmpty());-
1323-
1324 QRect *myLast = (numRects == 1 ? &extents : rects.data() + (numRects - 1));
numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1325 if (mergeFromRight(myLast, r)) {
mergeFromRight(myLast, r)Description
TRUEnever evaluated
FALSEnever evaluated
0
1326 if (numRects > 1) {
numRects > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1327 const QRect *nextToTop = (numRects > 2 ? myLast - 2 : 0);
numRects > 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1328 if (mergeFromBelow(myLast - 1, myLast, nextToTop, 0))
mergeFromBelow... nextToTop, 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1329 --numRects;
never executed: --numRects;
0
1330 }
never executed: end of block
0
1331 } else if (mergeFromBelow(myLast, r, (numRects > 1 ? myLast - 1 : 0), 0)) {
never executed: end of block
mergeFromBelow...t - 1 : 0), 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1332 // nothing-
1333 } else {
never executed: end of block
0
1334 vectorize();-
1335 ++numRects;-
1336 updateInnerRect(*r);-
1337 if (rects.size() < numRects)
rects.size() < numRectsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1338 rects.resize(numRects);
never executed: rects.resize(numRects);
0
1339 rects[numRects - 1] = *r;-
1340 }
never executed: end of block
0
1341 extents.setCoords(qMin(extents.left(), r->left()),-
1342 qMin(extents.top(), r->top()),-
1343 qMax(extents.right(), r->right()),-
1344 qMax(extents.bottom(), r->bottom()));-
1345-
1346#ifdef QT_REGION_DEBUG-
1347 selfTest();-
1348#endif-
1349}
never executed: end of block
0
1350-
1351void QRegionPrivate::append(const QRegionPrivate *r)-
1352{-
1353 Q_ASSERT(!isEmptyHelper(r));-
1354-
1355 if (r->numRects == 1) {
r->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1356 append(&r->extents);-
1357 return;
never executed: return;
0
1358 }-
1359-
1360 vectorize();-
1361-
1362 QRect *destRect = rects.data() + numRects;-
1363 const QRect *srcRect = r->rects.constData();-
1364 int numAppend = r->numRects;-
1365-
1366 // try merging-
1367 {-
1368 const QRect *rFirst = srcRect;-
1369 QRect *myLast = destRect - 1;-
1370 const QRect *nextToLast = (numRects > 1 ? myLast - 1 : 0);
numRects > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1371 if (mergeFromRight(myLast, rFirst)) {
mergeFromRight(myLast, rFirst)Description
TRUEnever evaluated
FALSEnever evaluated
0
1372 ++srcRect;-
1373 --numAppend;-
1374 const QRect *rNextToFirst = (numAppend > 1 ? rFirst + 2 : 0);
numAppend > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1375 if (mergeFromBelow(myLast, rFirst + 1, nextToLast, rNextToFirst)) {
mergeFromBelow... rNextToFirst)Description
TRUEnever evaluated
FALSEnever evaluated
0
1376 ++srcRect;-
1377 --numAppend;-
1378 }
never executed: end of block
0
1379 if (numRects > 1) {
numRects > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1380 nextToLast = (numRects > 2 ? myLast - 2 : 0);
numRects > 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1381 rNextToFirst = (numAppend > 0 ? srcRect : 0);
numAppend > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1382 if (mergeFromBelow(myLast - 1, myLast, nextToLast, rNextToFirst)) {
mergeFromBelow... rNextToFirst)Description
TRUEnever evaluated
FALSEnever evaluated
0
1383 --destRect;-
1384 --numRects;-
1385 }
never executed: end of block
0
1386 }
never executed: end of block
0
1387 } else if (mergeFromBelow(myLast, rFirst, nextToLast, rFirst + 1)) {
never executed: end of block
mergeFromBelow...t, rFirst + 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1388 ++srcRect;-
1389 --numAppend;-
1390 }
never executed: end of block
0
1391 }-
1392-
1393 // append rectangles-
1394 if (numAppend > 0) {
numAppend > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1395 const int newNumRects = numRects + numAppend;-
1396 if (newNumRects > rects.size()) {
newNumRects > rects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1397 rects.resize(newNumRects);-
1398 destRect = rects.data() + numRects;-
1399 }
never executed: end of block
0
1400 memcpy(destRect, srcRect, numAppend * sizeof(QRect));-
1401-
1402 numRects = newNumRects;-
1403 }
never executed: end of block
0
1404-
1405 // update inner rectangle-
1406 if (innerArea < r->innerArea) {
innerArea < r->innerAreaDescription
TRUEnever evaluated
FALSEnever evaluated
0
1407 innerArea = r->innerArea;-
1408 innerRect = r->innerRect;-
1409 }
never executed: end of block
0
1410-
1411 // update extents-
1412 destRect = &extents;-
1413 srcRect = &r->extents;-
1414 extents.setCoords(qMin(destRect->left(), srcRect->left()),-
1415 qMin(destRect->top(), srcRect->top()),-
1416 qMax(destRect->right(), srcRect->right()),-
1417 qMax(destRect->bottom(), srcRect->bottom()));-
1418-
1419#ifdef QT_REGION_DEBUG-
1420 selfTest();-
1421#endif-
1422}
never executed: end of block
0
1423-
1424void QRegionPrivate::prepend(const QRegionPrivate *r)-
1425{-
1426 Q_ASSERT(!isEmptyHelper(r));-
1427-
1428 if (r->numRects == 1) {
r->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1429 prepend(&r->extents);-
1430 return;
never executed: return;
0
1431 }-
1432-
1433 vectorize();-
1434-
1435 int numPrepend = r->numRects;-
1436 int numSkip = 0;-
1437-
1438 // try merging-
1439 {-
1440 QRect *myFirst = rects.data();-
1441 const QRect *nextToFirst = (numRects > 1 ? myFirst + 1 : 0);
numRects > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1442 const QRect *rLast = r->rects.constData() + r->numRects - 1;-
1443 const QRect *rNextToLast = (r->numRects > 1 ? rLast - 1 : 0);
r->numRects > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1444 if (mergeFromLeft(myFirst, rLast)) {
mergeFromLeft(myFirst, rLast)Description
TRUEnever evaluated
FALSEnever evaluated
0
1445 --numPrepend;-
1446 --rLast;-
1447 rNextToLast = (numPrepend > 1 ? rLast - 1 : 0);
numPrepend > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1448 if (mergeFromAbove(myFirst, rLast, nextToFirst, rNextToLast)) {
mergeFromAbove..., rNextToLast)Description
TRUEnever evaluated
FALSEnever evaluated
0
1449 --numPrepend;-
1450 --rLast;-
1451 }
never executed: end of block
0
1452 if (numRects > 1) {
numRects > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1453 nextToFirst = (numRects > 2? myFirst + 2 : 0);
numRects > 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1454 rNextToLast = (numPrepend > 0 ? rLast : 0);
numPrepend > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1455 if (mergeFromAbove(myFirst + 1, myFirst, nextToFirst, rNextToLast)) {
mergeFromAbove..., rNextToLast)Description
TRUEnever evaluated
FALSEnever evaluated
0
1456 --numRects;-
1457 ++numSkip;-
1458 }
never executed: end of block
0
1459 }
never executed: end of block
0
1460 } else if (mergeFromAbove(myFirst, rLast, nextToFirst, rNextToLast)) {
never executed: end of block
mergeFromAbove..., rNextToLast)Description
TRUEnever evaluated
FALSEnever evaluated
0
1461 --numPrepend;-
1462 }
never executed: end of block
0
1463 }-
1464-
1465 if (numPrepend > 0) {
numPrepend > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1466 const int newNumRects = numRects + numPrepend;-
1467 if (newNumRects > rects.size())
newNumRects > rects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1468 rects.resize(newNumRects);
never executed: rects.resize(newNumRects);
0
1469-
1470 // move existing rectangles-
1471 memmove(rects.data() + numPrepend, rects.constData() + numSkip,-
1472 numRects * sizeof(QRect));-
1473-
1474 // prepend new rectangles-
1475 memcpy(rects.data(), r->rects.constData(), numPrepend * sizeof(QRect));-
1476-
1477 numRects = newNumRects;-
1478 }
never executed: end of block
0
1479-
1480 // update inner rectangle-
1481 if (innerArea < r->innerArea) {
innerArea < r->innerAreaDescription
TRUEnever evaluated
FALSEnever evaluated
0
1482 innerArea = r->innerArea;-
1483 innerRect = r->innerRect;-
1484 }
never executed: end of block
0
1485-
1486 // update extents-
1487 extents.setCoords(qMin(extents.left(), r->extents.left()),-
1488 qMin(extents.top(), r->extents.top()),-
1489 qMax(extents.right(), r->extents.right()),-
1490 qMax(extents.bottom(), r->extents.bottom()));-
1491-
1492#ifdef QT_REGION_DEBUG-
1493 selfTest();-
1494#endif-
1495}
never executed: end of block
0
1496-
1497void QRegionPrivate::prepend(const QRect *r)-
1498{-
1499 Q_ASSERT(!r->isEmpty());-
1500-
1501 QRect *myFirst = (numRects == 1 ? &extents : rects.data());
numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1502 if (mergeFromLeft(myFirst, r)) {
mergeFromLeft(myFirst, r)Description
TRUEnever evaluated
FALSEnever evaluated
0
1503 if (numRects > 1) {
numRects > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1504 const QRect *nextToFirst = (numRects > 2 ? myFirst + 2 : 0);
numRects > 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1505 if (mergeFromAbove(myFirst + 1, myFirst, nextToFirst, 0)) {
mergeFromAbove...extToFirst, 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1506 --numRects;-
1507 memmove(rects.data(), rects.constData() + 1,-
1508 numRects * sizeof(QRect));-
1509 }
never executed: end of block
0
1510 }
never executed: end of block
0
1511 } else if (mergeFromAbove(myFirst, r, (numRects > 1 ? myFirst + 1 : 0), 0)) {
never executed: end of block
mergeFromAbove...t + 1 : 0), 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1512 // nothing-
1513 } else {
never executed: end of block
0
1514 vectorize();-
1515 ++numRects;-
1516 updateInnerRect(*r);-
1517 rects.prepend(*r);-
1518 }
never executed: end of block
0
1519 extents.setCoords(qMin(extents.left(), r->left()),-
1520 qMin(extents.top(), r->top()),-
1521 qMax(extents.right(), r->right()),-
1522 qMax(extents.bottom(), r->bottom()));-
1523-
1524#ifdef QT_REGION_DEBUG-
1525 selfTest();-
1526#endif-
1527}
never executed: end of block
0
1528-
1529bool QRegionPrivate::canAppend(const QRect *r) const-
1530{-
1531 Q_ASSERT(!r->isEmpty());-
1532-
1533 const QRect *myLast = (numRects == 1) ? &extents : (rects.constData() + (numRects - 1));
(numRects == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1534 if (r->top() > myLast->bottom())
r->top() > myLast->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
1535 return true;
never executed: return true;
0
1536 if (r->top() == myLast->top()
r->top() == myLast->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
1537 && r->height() == myLast->height()
r->height() ==...Last->height()Description
TRUEnever evaluated
FALSEnever evaluated
0
1538 && r->left() > myLast->right())
r->left() > myLast->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1539 {-
1540 return true;
never executed: return true;
0
1541 }-
1542-
1543 return false;
never executed: return false;
0
1544}-
1545-
1546bool QRegionPrivate::canAppend(const QRegionPrivate *r) const-
1547{-
1548 return canAppend(r->numRects == 1 ? &r->extents : r->rects.constData());
never executed: return canAppend(r->numRects == 1 ? &r->extents : r->rects.constData());
0
1549}-
1550-
1551bool QRegionPrivate::canPrepend(const QRect *r) const-
1552{-
1553 Q_ASSERT(!r->isEmpty());-
1554-
1555 const QRect *myFirst = (numRects == 1) ? &extents : rects.constData();
(numRects == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1556 if (r->bottom() < myFirst->top()) // not overlapping
r->bottom() < myFirst->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
1557 return true;
never executed: return true;
0
1558 if (r->top() == myFirst->top()
r->top() == myFirst->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
1559 && r->height() == myFirst->height()
r->height() ==...irst->height()Description
TRUEnever evaluated
FALSEnever evaluated
0
1560 && r->right() < myFirst->left())
r->right() < myFirst->left()Description
TRUEnever evaluated
FALSEnever evaluated
0
1561 {-
1562 return true;
never executed: return true;
0
1563 }-
1564-
1565 return false;
never executed: return false;
0
1566}-
1567-
1568bool QRegionPrivate::canPrepend(const QRegionPrivate *r) const-
1569{-
1570 return canPrepend(r->numRects == 1 ? &r->extents : r->rects.constData() + r->numRects - 1);
never executed: return canPrepend(r->numRects == 1 ? &r->extents : r->rects.constData() + r->numRects - 1);
0
1571}-
1572-
1573#ifdef QT_REGION_DEBUG-
1574void QRegionPrivate::selfTest() const-
1575{-
1576 if (numRects == 0) {-
1577 Q_ASSERT(extents.isEmpty());-
1578 Q_ASSERT(innerRect.isEmpty());-
1579 return;-
1580 }-
1581-
1582 Q_ASSERT(innerArea == (innerRect.width() * innerRect.height()));-
1583-
1584 if (numRects == 1) {-
1585 Q_ASSERT(innerRect == extents);-
1586 Q_ASSERT(!innerRect.isEmpty());-
1587 return;-
1588 }-
1589-
1590 for (int i = 0; i < numRects; ++i) {-
1591 const QRect r = rects.at(i);-
1592 if ((r.width() * r.height()) > innerArea)-
1593 qDebug() << "selfTest(): innerRect" << innerRect << '<' << r;-
1594 }-
1595-
1596 QRect r = rects.first();-
1597 for (int i = 1; i < numRects; ++i) {-
1598 const QRect r2 = rects.at(i);-
1599 Q_ASSERT(!r2.isEmpty());-
1600 if (r2.y() == r.y()) {-
1601 Q_ASSERT(r.bottom() == r2.bottom());-
1602 Q_ASSERT(r.right() < (r2.left() + 1));-
1603 } else {-
1604 Q_ASSERT(r2.y() >= r.bottom());-
1605 }-
1606 r = r2;-
1607 }-
1608}-
1609#endif // QT_REGION_DEBUG-
1610-
1611static QRegionPrivate qrp;-
1612const QRegion::QRegionData QRegion::shared_empty = {Q_REFCOUNT_INITIALIZE_STATIC, &qrp};-
1613-
1614typedef void (*OverlapFunc)(QRegionPrivate &dest, const QRect *r1, const QRect *r1End,-
1615 const QRect *r2, const QRect *r2End, int y1, int y2);-
1616typedef void (*NonOverlapFunc)(QRegionPrivate &dest, const QRect *r, const QRect *rEnd,-
1617 int y1, int y2);-
1618-
1619static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2);-
1620static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest);-
1621static void miRegionOp(QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2,-
1622 OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func,-
1623 NonOverlapFunc nonOverlap2Func);-
1624-
1625#define RectangleOut 0-
1626#define RectangleIn 1-
1627#define RectanglePart 2-
1628#define EvenOddRule 0-
1629#define WindingRule 1-
1630-
1631// START OF region.h extract-
1632/* $XConsortium: region.h,v 11.14 94/04/17 20:22:20 rws Exp $ */-
1633/************************************************************************-
1634-
1635Copyright (c) 1987 X Consortium-
1636-
1637Permission is hereby granted, free of charge, to any person obtaining a copy-
1638of this software and associated documentation files (the "Software"), to deal-
1639in the Software without restriction, including without limitation the rights-
1640to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-
1641copies of the Software, and to permit persons to whom the Software is-
1642furnished to do so, subject to the following conditions:-
1643-
1644The above copyright notice and this permission notice shall be included in-
1645all copies or substantial portions of the Software.-
1646-
1647THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-
1648IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-
1649FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-
1650X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN-
1651AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN-
1652CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.-
1653-
1654Except as contained in this notice, the name of the X Consortium shall not be-
1655used in advertising or otherwise to promote the sale, use or other dealings-
1656in this Software without prior written authorization from the X Consortium.-
1657-
1658-
1659Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.-
1660-
1661 All Rights Reserved-
1662-
1663Permission to use, copy, modify, and distribute this software and its-
1664documentation for any purpose and without fee is hereby granted,-
1665provided that the above copyright notice appear in all copies and that-
1666both that copyright notice and this permission notice appear in-
1667supporting documentation, and that the name of Digital not be-
1668used in advertising or publicity pertaining to distribution of the-
1669software without specific, written prior permission.-
1670-
1671DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING-
1672ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL-
1673DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR-
1674ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,-
1675WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,-
1676ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS-
1677SOFTWARE.-
1678-
1679************************************************************************/-
1680-
1681#ifndef _XREGION_H-
1682#define _XREGION_H-
1683-
1684QT_BEGIN_INCLUDE_NAMESPACE-
1685#include <limits.h>-
1686QT_END_INCLUDE_NAMESPACE-
1687-
1688/* 1 if two BOXes overlap.-
1689 * 0 if two BOXes do not overlap.-
1690 * Remember, x2 and y2 are not in the region-
1691 */-
1692#define EXTENTCHECK(r1, r2) \-
1693 ((r1)->right() >= (r2)->left() && \-
1694 (r1)->left() <= (r2)->right() && \-
1695 (r1)->bottom() >= (r2)->top() && \-
1696 (r1)->top() <= (r2)->bottom())-
1697-
1698/*-
1699 * update region extents-
1700 */-
1701#define EXTENTS(r,idRect){\-
1702 if((r)->left() < (idRect)->extents.left())\-
1703 (idRect)->extents.setLeft((r)->left());\-
1704 if((r)->top() < (idRect)->extents.top())\-
1705 (idRect)->extents.setTop((r)->top());\-
1706 if((r)->right() > (idRect)->extents.right())\-
1707 (idRect)->extents.setRight((r)->right());\-
1708 if((r)->bottom() > (idRect)->extents.bottom())\-
1709 (idRect)->extents.setBottom((r)->bottom());\-
1710 }-
1711-
1712/*-
1713 * Check to see if there is enough memory in the present region.-
1714 */-
1715#define MEMCHECK(dest, rect, firstrect){\-
1716 if ((dest).numRects >= ((dest).rects.size()-1)){\-
1717 firstrect.resize(firstrect.size() * 2); \-
1718 (rect) = (firstrect).data() + (dest).numRects;\-
1719 }\-
1720 }-
1721-
1722-
1723/*-
1724 * number of points to buffer before sending them off-
1725 * to scanlines(): Must be an even number-
1726 */-
1727#define NUMPTSTOBUFFER 200-
1728-
1729/*-
1730 * used to allocate buffers for points and link-
1731 * the buffers together-
1732 */-
1733typedef struct _POINTBLOCK {-
1734 char data[NUMPTSTOBUFFER * sizeof(QPoint)];-
1735 QPoint *pts;-
1736 struct _POINTBLOCK *next;-
1737} POINTBLOCK;-
1738-
1739#endif-
1740// END OF region.h extract-
1741-
1742// START OF Region.c extract-
1743/* $XConsortium: Region.c /main/30 1996/10/22 14:21:24 kaleb $ */-
1744/************************************************************************-
1745-
1746Copyright (c) 1987, 1988 X Consortium-
1747-
1748Permission is hereby granted, free of charge, to any person obtaining a copy-
1749of this software and associated documentation files (the "Software"), to deal-
1750in the Software without restriction, including without limitation the rights-
1751to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-
1752copies of the Software, and to permit persons to whom the Software is-
1753furnished to do so, subject to the following conditions:-
1754-
1755The above copyright notice and this permission notice shall be included in-
1756all copies or substantial portions of the Software.-
1757-
1758THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-
1759IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-
1760FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-
1761X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN-
1762AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN-
1763CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.-
1764-
1765Except as contained in this notice, the name of the X Consortium shall not be-
1766used in advertising or otherwise to promote the sale, use or other dealings-
1767in this Software without prior written authorization from the X Consortium.-
1768-
1769-
1770Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.-
1771-
1772 All Rights Reserved-
1773-
1774Permission to use, copy, modify, and distribute this software and its-
1775documentation for any purpose and without fee is hereby granted,-
1776provided that the above copyright notice appear in all copies and that-
1777both that copyright notice and this permission notice appear in-
1778supporting documentation, and that the name of Digital not be-
1779used in advertising or publicity pertaining to distribution of the-
1780software without specific, written prior permission.-
1781-
1782DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING-
1783ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL-
1784DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR-
1785ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,-
1786WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,-
1787ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS-
1788SOFTWARE.-
1789-
1790************************************************************************/-
1791/*-
1792 * The functions in this file implement the Region abstraction, similar to one-
1793 * used in the X11 sample server. A Region is simply an area, as the name-
1794 * implies, and is implemented as a "y-x-banded" array of rectangles. To-
1795 * explain: Each Region is made up of a certain number of rectangles sorted-
1796 * by y coordinate first, and then by x coordinate.-
1797 *-
1798 * Furthermore, the rectangles are banded such that every rectangle with a-
1799 * given upper-left y coordinate (y1) will have the same lower-right y-
1800 * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it-
1801 * will span the entire vertical distance of the band. This means that some-
1802 * areas that could be merged into a taller rectangle will be represented as-
1803 * several shorter rectangles to account for shorter rectangles to its left-
1804 * or right but within its "vertical scope".-
1805 *-
1806 * An added constraint on the rectangles is that they must cover as much-
1807 * horizontal area as possible. E.g. no two rectangles in a band are allowed-
1808 * to touch.-
1809 *-
1810 * Whenever possible, bands will be merged together to cover a greater vertical-
1811 * distance (and thus reduce the number of rectangles). Two bands can be merged-
1812 * only if the bottom of one touches the top of the other and they have-
1813 * rectangles in the same places (of the same width, of course). This maintains-
1814 * the y-x-banding that's so nice to have...-
1815 */-
1816/* $XFree86: xc/lib/X11/Region.c,v 1.1.1.2.2.2 1998/10/04 15:22:50 hohndel Exp $ */-
1817-
1818static void UnionRectWithRegion(const QRect *rect, const QRegionPrivate *source,-
1819 QRegionPrivate &dest)-
1820{-
1821 if (rect->isEmpty())
rect->isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1822 return;
never executed: return;
0
1823-
1824 Q_ASSERT(EqualRegion(source, &dest));-
1825-
1826 if (dest.numRects == 0) {
dest.numRects == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1827 dest = QRegionPrivate(*rect);-
1828 } else if (dest.canAppend(rect)) {
never executed: end of block
dest.canAppend(rect)Description
TRUEnever evaluated
FALSEnever evaluated
0
1829 dest.append(rect);-
1830 } else {
never executed: end of block
0
1831 QRegionPrivate p(*rect);-
1832 UnionRegion(&p, source, dest);-
1833 }
never executed: end of block
0
1834}-
1835-
1836/*--
1837 *------------------------------------------------------------------------
1838 * miSetExtents ---
1839 * Reset the extents and innerRect of a region to what they should be.-
1840 * Called by miSubtract and miIntersect b/c they can't figure it out-
1841 * along the way or do so easily, as miUnion can.-
1842 *-
1843 * Results:-
1844 * None.-
1845 *-
1846 * Side Effects:-
1847 * The region's 'extents' and 'innerRect' structure is overwritten.-
1848 *-
1849 *------------------------------------------------------------------------
1850 */-
1851static void miSetExtents(QRegionPrivate &dest)-
1852{-
1853 const QRect *pBox,-
1854 *pBoxEnd;-
1855 QRect *pExtents;-
1856-
1857 dest.innerRect.setCoords(0, 0, -1, -1);-
1858 dest.innerArea = -1;-
1859 if (dest.numRects == 0) {
dest.numRects == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1860 dest.extents.setCoords(0, 0, -1, -1);-
1861 return;
never executed: return;
0
1862 }-
1863-
1864 pExtents = &dest.extents;-
1865 if (dest.rects.isEmpty())
dest.rects.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
1866 pBox = &dest.extents;
never executed: pBox = &dest.extents;
0
1867 else-
1868 pBox = dest.rects.constData();
never executed: pBox = dest.rects.constData();
0
1869 pBoxEnd = pBox + dest.numRects - 1;-
1870-
1871 /*-
1872 * Since pBox is the first rectangle in the region, it must have the-
1873 * smallest y1 and since pBoxEnd is the last rectangle in the region,-
1874 * it must have the largest y2, because of banding. Initialize x1 and-
1875 * x2 from pBox and pBoxEnd, resp., as good things to initialize them-
1876 * to...-
1877 */-
1878 pExtents->setLeft(pBox->left());-
1879 pExtents->setTop(pBox->top());-
1880 pExtents->setRight(pBoxEnd->right());-
1881 pExtents->setBottom(pBoxEnd->bottom());-
1882-
1883 Q_ASSERT(pExtents->top() <= pExtents->bottom());-
1884 while (pBox <= pBoxEnd) {
pBox <= pBoxEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
1885 if (pBox->left() < pExtents->left())
pBox->left() <...xtents->left()Description
TRUEnever evaluated
FALSEnever evaluated
0
1886 pExtents->setLeft(pBox->left());
never executed: pExtents->setLeft(pBox->left());
0
1887 if (pBox->right() > pExtents->right())
pBox->right() ...tents->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1888 pExtents->setRight(pBox->right());
never executed: pExtents->setRight(pBox->right());
0
1889 dest.updateInnerRect(*pBox);-
1890 ++pBox;-
1891 }
never executed: end of block
0
1892 Q_ASSERT(pExtents->left() <= pExtents->right());-
1893}
never executed: end of block
0
1894-
1895/* TranslateRegion(pRegion, x, y)-
1896 translates in place-
1897 added by raymond-
1898*/-
1899-
1900static void OffsetRegion(QRegionPrivate &region, int x, int y)-
1901{-
1902 if (region.rects.size()) {
region.rects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
1903 QRect *pbox = region.rects.data();-
1904 int nbox = region.numRects;-
1905-
1906 while (nbox--) {
nbox--Description
TRUEnever evaluated
FALSEnever evaluated
0
1907 pbox->translate(x, y);-
1908 ++pbox;-
1909 }
never executed: end of block
0
1910 }
never executed: end of block
0
1911 region.extents.translate(x, y);-
1912 region.innerRect.translate(x, y);-
1913}
never executed: end of block
0
1914-
1915/*======================================================================-
1916 * Region Intersection-
1917 *====================================================================*/-
1918/*--
1919 *------------------------------------------------------------------------
1920 * miIntersectO ---
1921 * Handle an overlapping band for miIntersect.-
1922 *-
1923 * Results:-
1924 * None.-
1925 *-
1926 * Side Effects:-
1927 * Rectangles may be added to the region.-
1928 *-
1929 *------------------------------------------------------------------------
1930 */-
1931static void miIntersectO(QRegionPrivate &dest, const QRect *r1, const QRect *r1End,-
1932 const QRect *r2, const QRect *r2End, int y1, int y2)-
1933{-
1934 int x1;-
1935 int x2;-
1936 QRect *pNextRect;-
1937-
1938 pNextRect = dest.rects.data() + dest.numRects;-
1939-
1940 while (r1 != r1End && r2 != r2End) {
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
r2 != r2EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
1941 x1 = qMax(r1->left(), r2->left());-
1942 x2 = qMin(r1->right(), r2->right());-
1943-
1944 /*-
1945 * If there's any overlap between the two rectangles, add that-
1946 * overlap to the new region.-
1947 * There's no need to check for subsumption because the only way-
1948 * such a need could arise is if some region has two rectangles-
1949 * right next to each other. Since that should never happen...-
1950 */-
1951 if (x1 <= x2) {
x1 <= x2Description
TRUEnever evaluated
FALSEnever evaluated
0
1952 Q_ASSERT(y1 <= y2);-
1953 MEMCHECK(dest, pNextRect, dest.rects)
never executed: end of block
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1954 pNextRect->setCoords(x1, y1, x2, y2);-
1955 ++dest.numRects;-
1956 ++pNextRect;-
1957 }
never executed: end of block
0
1958-
1959 /*-
1960 * Need to advance the pointers. Shift the one that extends-
1961 * to the right the least, since the other still has a chance to-
1962 * overlap with that region's next rectangle, if you see what I mean.-
1963 */-
1964 if (r1->right() < r2->right()) {
r1->right() < r2->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1965 ++r1;-
1966 } else if (r2->right() < r1->right()) {
never executed: end of block
r2->right() < r1->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
1967 ++r2;-
1968 } else {
never executed: end of block
0
1969 ++r1;-
1970 ++r2;-
1971 }
never executed: end of block
0
1972 }-
1973}
never executed: end of block
0
1974-
1975/*======================================================================-
1976 * Generic Region Operator-
1977 *====================================================================*/-
1978-
1979/*--
1980 *------------------------------------------------------------------------
1981 * miCoalesce ---
1982 * Attempt to merge the boxes in the current band with those in the-
1983 * previous one. Used only by miRegionOp.-
1984 *-
1985 * Results:-
1986 * The new index for the previous band.-
1987 *-
1988 * Side Effects:-
1989 * If coalescing takes place:-
1990 * - rectangles in the previous band will have their y2 fields-
1991 * altered.-
1992 * - dest.numRects will be decreased.-
1993 *-
1994 *------------------------------------------------------------------------
1995 */-
1996static int miCoalesce(QRegionPrivate &dest, int prevStart, int curStart)-
1997{-
1998 QRect *pPrevBox; /* Current box in previous band */-
1999 QRect *pCurBox; /* Current box in current band */-
2000 QRect *pRegEnd; /* End of region */-
2001 int curNumRects; /* Number of rectangles in current band */-
2002 int prevNumRects; /* Number of rectangles in previous band */-
2003 int bandY1; /* Y1 coordinate for current band */-
2004 QRect *rData = dest.rects.data();-
2005-
2006 pRegEnd = rData + dest.numRects;-
2007-
2008 pPrevBox = rData + prevStart;-
2009 prevNumRects = curStart - prevStart;-
2010-
2011 /*-
2012 * Figure out how many rectangles are in the current band. Have to do-
2013 * this because multiple bands could have been added in miRegionOp-
2014 * at the end when one region has been exhausted.-
2015 */-
2016 pCurBox = rData + curStart;-
2017 bandY1 = pCurBox->top();-
2018 for (curNumRects = 0; pCurBox != pRegEnd && pCurBox->top() == bandY1; ++curNumRects) {
pCurBox != pRegEndDescription
TRUEnever evaluated
FALSEnever evaluated
pCurBox->top() == bandY1Description
TRUEnever evaluated
FALSEnever evaluated
0
2019 ++pCurBox;-
2020 }
never executed: end of block
0
2021-
2022 if (pCurBox != pRegEnd) {
pCurBox != pRegEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2023 /*-
2024 * If more than one band was added, we have to find the start-
2025 * of the last band added so the next coalescing job can start-
2026 * at the right place... (given when multiple bands are added,-
2027 * this may be pointless -- see above).-
2028 */-
2029 --pRegEnd;-
2030 while ((pRegEnd - 1)->top() == pRegEnd->top())
(pRegEnd - 1)-...pRegEnd->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
2031 --pRegEnd;
never executed: --pRegEnd;
0
2032 curStart = pRegEnd - rData;-
2033 pRegEnd = rData + dest.numRects;-
2034 }
never executed: end of block
0
2035-
2036 if (curNumRects == prevNumRects && curNumRects != 0) {
curNumRects == prevNumRectsDescription
TRUEnever evaluated
FALSEnever evaluated
curNumRects != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2037 pCurBox -= curNumRects;-
2038 /*-
2039 * The bands may only be coalesced if the bottom of the previous-
2040 * matches the top scanline of the current.-
2041 */-
2042 if (pPrevBox->bottom() == pCurBox->top() - 1) {
pPrevBox->bott...Box->top() - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2043 /*-
2044 * Make sure the bands have boxes in the same places. This-
2045 * assumes that boxes have been added in such a way that they-
2046 * cover the most area possible. I.e. two boxes in a band must-
2047 * have some horizontal space between them.-
2048 */-
2049 do {-
2050 if (pPrevBox->left() != pCurBox->left() || pPrevBox->right() != pCurBox->right()) {
pPrevBox->left...CurBox->left()Description
TRUEnever evaluated
FALSEnever evaluated
pPrevBox->righ...urBox->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
2051 // The bands don't line up so they can't be coalesced.-
2052 return curStart;
never executed: return curStart;
0
2053 }-
2054 ++pPrevBox;-
2055 ++pCurBox;-
2056 --prevNumRects;-
2057 } while (prevNumRects != 0);
never executed: end of block
prevNumRects != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2058-
2059 dest.numRects -= curNumRects;-
2060 pCurBox -= curNumRects;-
2061 pPrevBox -= curNumRects;-
2062-
2063 /*-
2064 * The bands may be merged, so set the bottom y of each box-
2065 * in the previous band to that of the corresponding box in-
2066 * the current band.-
2067 */-
2068 do {-
2069 pPrevBox->setBottom(pCurBox->bottom());-
2070 dest.updateInnerRect(*pPrevBox);-
2071 ++pPrevBox;-
2072 ++pCurBox;-
2073 curNumRects -= 1;-
2074 } while (curNumRects != 0);
never executed: end of block
curNumRects != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2075-
2076 /*-
2077 * If only one band was added to the region, we have to backup-
2078 * curStart to the start of the previous band.-
2079 *-
2080 * If more than one band was added to the region, copy the-
2081 * other bands down. The assumption here is that the other bands-
2082 * came from the same region as the current one and no further-
2083 * coalescing can be done on them since it's all been done-
2084 * already... curStart is already in the right place.-
2085 */-
2086 if (pCurBox == pRegEnd) {
pCurBox == pRegEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2087 curStart = prevStart;-
2088 } else {
never executed: end of block
0
2089 do {-
2090 *pPrevBox++ = *pCurBox++;-
2091 dest.updateInnerRect(*pPrevBox);-
2092 } while (pCurBox != pRegEnd);
never executed: end of block
pCurBox != pRegEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2093 }
never executed: end of block
0
2094 }-
2095 }
never executed: end of block
0
2096 return curStart;
never executed: return curStart;
0
2097}-
2098-
2099/*--
2100 *------------------------------------------------------------------------
2101 * miRegionOp ---
2102 * Apply an operation to two regions. Called by miUnion, miInverse,-
2103 * miSubtract, miIntersect...-
2104 *-
2105 * Results:-
2106 * None.-
2107 *-
2108 * Side Effects:-
2109 * The new region is overwritten.-
2110 *-
2111 * Notes:-
2112 * The idea behind this function is to view the two regions as sets.-
2113 * Together they cover a rectangle of area that this function divides-
2114 * into horizontal bands where points are covered only by one region-
2115 * or by both. For the first case, the nonOverlapFunc is called with-
2116 * each the band and the band's upper and lower extents. For the-
2117 * second, the overlapFunc is called to process the entire band. It-
2118 * is responsible for clipping the rectangles in the band, though-
2119 * this function provides the boundaries.-
2120 * At the end of each band, the new region is coalesced, if possible,-
2121 * to reduce the number of rectangles in the region.-
2122 *-
2123 *------------------------------------------------------------------------
2124 */-
2125static void miRegionOp(QRegionPrivate &dest,-
2126 const QRegionPrivate *reg1, const QRegionPrivate *reg2,-
2127 OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func,-
2128 NonOverlapFunc nonOverlap2Func)-
2129{-
2130 const QRect *r1; // Pointer into first region-
2131 const QRect *r2; // Pointer into 2d region-
2132 const QRect *r1End; // End of 1st region-
2133 const QRect *r2End; // End of 2d region-
2134 int ybot; // Bottom of intersection-
2135 int ytop; // Top of intersection-
2136 int prevBand; // Index of start of previous band in dest-
2137 int curBand; // Index of start of current band in dest-
2138 const QRect *r1BandEnd; // End of current band in r1-
2139 const QRect *r2BandEnd; // End of current band in r2-
2140 int top; // Top of non-overlapping band-
2141 int bot; // Bottom of non-overlapping band-
2142-
2143 /*-
2144 * Initialization:-
2145 * set r1, r2, r1End and r2End appropriately, preserve the important-
2146 * parts of the destination region until the end in case it's one of-
2147 * the two source regions, then mark the "new" region empty, allocating-
2148 * another array of rectangles for it to use.-
2149 */-
2150 if (reg1->numRects == 1)
reg1->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2151 r1 = &reg1->extents;
never executed: r1 = &reg1->extents;
0
2152 else-
2153 r1 = reg1->rects.constData();
never executed: r1 = reg1->rects.constData();
0
2154 if (reg2->numRects == 1)
reg2->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2155 r2 = &reg2->extents;
never executed: r2 = &reg2->extents;
0
2156 else-
2157 r2 = reg2->rects.constData();
never executed: r2 = reg2->rects.constData();
0
2158-
2159 r1End = r1 + reg1->numRects;-
2160 r2End = r2 + reg2->numRects;-
2161-
2162 dest.vectorize();-
2163-
2164 QVector<QRect> oldRects = dest.rects;-
2165-
2166 dest.numRects = 0;-
2167-
2168 /*-
2169 * Allocate a reasonable number of rectangles for the new region. The idea-
2170 * is to allocate enough so the individual functions don't need to-
2171 * reallocate and copy the array, which is time consuming, yet we don't-
2172 * have to worry about using too much memory. I hope to be able to-
2173 * nuke the realloc() at the end of this function eventually.-
2174 */-
2175 dest.rects.resize(qMax(reg1->numRects,reg2->numRects) * 2);-
2176-
2177 /*-
2178 * Initialize ybot and ytop.-
2179 * In the upcoming loop, ybot and ytop serve different functions depending-
2180 * on whether the band being handled is an overlapping or non-overlapping-
2181 * band.-
2182 * In the case of a non-overlapping band (only one of the regions-
2183 * has points in the band), ybot is the bottom of the most recent-
2184 * intersection and thus clips the top of the rectangles in that band.-
2185 * ytop is the top of the next intersection between the two regions and-
2186 * serves to clip the bottom of the rectangles in the current band.-
2187 * For an overlapping band (where the two regions intersect), ytop clips-
2188 * the top of the rectangles of both regions and ybot clips the bottoms.-
2189 */-
2190 if (reg1->extents.top() < reg2->extents.top())
reg1->extents....>extents.top()Description
TRUEnever evaluated
FALSEnever evaluated
0
2191 ybot = reg1->extents.top() - 1;
never executed: ybot = reg1->extents.top() - 1;
0
2192 else-
2193 ybot = reg2->extents.top() - 1;
never executed: ybot = reg2->extents.top() - 1;
0
2194-
2195 /*-
2196 * prevBand serves to mark the start of the previous band so rectangles-
2197 * can be coalesced into larger rectangles. qv. miCoalesce, above.-
2198 * In the beginning, there is no previous band, so prevBand == curBand-
2199 * (curBand is set later on, of course, but the first band will always-
2200 * start at index 0). prevBand and curBand must be indices because of-
2201 * the possible expansion, and resultant moving, of the new region's-
2202 * array of rectangles.-
2203 */-
2204 prevBand = 0;-
2205-
2206 do {-
2207 curBand = dest.numRects;-
2208-
2209 /*-
2210 * This algorithm proceeds one source-band (as opposed to a-
2211 * destination band, which is determined by where the two regions-
2212 * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the-
2213 * rectangle after the last one in the current band for their-
2214 * respective regions.-
2215 */-
2216 r1BandEnd = r1;-
2217 while (r1BandEnd != r1End && r1BandEnd->top() == r1->top())
r1BandEnd != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
r1BandEnd->top() == r1->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
2218 ++r1BandEnd;
never executed: ++r1BandEnd;
0
2219-
2220 r2BandEnd = r2;-
2221 while (r2BandEnd != r2End && r2BandEnd->top() == r2->top())
r2BandEnd != r2EndDescription
TRUEnever evaluated
FALSEnever evaluated
r2BandEnd->top() == r2->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
2222 ++r2BandEnd;
never executed: ++r2BandEnd;
0
2223-
2224 /*-
2225 * First handle the band that doesn't intersect, if any.-
2226 *-
2227 * Note that attention is restricted to one band in the-
2228 * non-intersecting region at once, so if a region has n-
2229 * bands between the current position and the next place it overlaps-
2230 * the other, this entire loop will be passed through n times.-
2231 */-
2232 if (r1->top() < r2->top()) {
r1->top() < r2->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
2233 top = qMax(r1->top(), ybot + 1);-
2234 bot = qMin(r1->bottom(), r2->top() - 1);-
2235-
2236 if (nonOverlap1Func != 0 && bot >= top)
nonOverlap1Func != 0Description
TRUEnever evaluated
FALSEnever evaluated
bot >= topDescription
TRUEnever evaluated
FALSEnever evaluated
0
2237 (*nonOverlap1Func)(dest, r1, r1BandEnd, top, bot);
never executed: (*nonOverlap1Func)(dest, r1, r1BandEnd, top, bot);
0
2238 ytop = r2->top();-
2239 } else if (r2->top() < r1->top()) {
never executed: end of block
r2->top() < r1->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
2240 top = qMax(r2->top(), ybot + 1);-
2241 bot = qMin(r2->bottom(), r1->top() - 1);-
2242-
2243 if (nonOverlap2Func != 0 && bot >= top)
nonOverlap2Func != 0Description
TRUEnever evaluated
FALSEnever evaluated
bot >= topDescription
TRUEnever evaluated
FALSEnever evaluated
0
2244 (*nonOverlap2Func)(dest, r2, r2BandEnd, top, bot);
never executed: (*nonOverlap2Func)(dest, r2, r2BandEnd, top, bot);
0
2245 ytop = r1->top();-
2246 } else {
never executed: end of block
0
2247 ytop = r1->top();-
2248 }
never executed: end of block
0
2249-
2250 /*-
2251 * If any rectangles got added to the region, try and coalesce them-
2252 * with rectangles from the previous band. Note we could just do-
2253 * this test in miCoalesce, but some machines incur a not-
2254 * inconsiderable cost for function calls, so...-
2255 */-
2256 if (dest.numRects != curBand)
dest.numRects != curBandDescription
TRUEnever evaluated
FALSEnever evaluated
0
2257 prevBand = miCoalesce(dest, prevBand, curBand);
never executed: prevBand = miCoalesce(dest, prevBand, curBand);
0
2258-
2259 /*-
2260 * Now see if we've hit an intersecting band. The two bands only-
2261 * intersect if ybot >= ytop-
2262 */-
2263 ybot = qMin(r1->bottom(), r2->bottom());-
2264 curBand = dest.numRects;-
2265 if (ybot >= ytop)
ybot >= ytopDescription
TRUEnever evaluated
FALSEnever evaluated
0
2266 (*overlapFunc)(dest, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
never executed: (*overlapFunc)(dest, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
0
2267-
2268 if (dest.numRects != curBand)
dest.numRects != curBandDescription
TRUEnever evaluated
FALSEnever evaluated
0
2269 prevBand = miCoalesce(dest, prevBand, curBand);
never executed: prevBand = miCoalesce(dest, prevBand, curBand);
0
2270-
2271 /*-
2272 * If we've finished with a band (y2 == ybot) we skip forward-
2273 * in the region to the next band.-
2274 */-
2275 if (r1->bottom() == ybot)
r1->bottom() == ybotDescription
TRUEnever evaluated
FALSEnever evaluated
0
2276 r1 = r1BandEnd;
never executed: r1 = r1BandEnd;
0
2277 if (r2->bottom() == ybot)
r2->bottom() == ybotDescription
TRUEnever evaluated
FALSEnever evaluated
0
2278 r2 = r2BandEnd;
never executed: r2 = r2BandEnd;
0
2279 } while (r1 != r1End && r2 != r2End);
never executed: end of block
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
r2 != r2EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2280-
2281 /*-
2282 * Deal with whichever region still has rectangles left.-
2283 */-
2284 curBand = dest.numRects;-
2285 if (r1 != r1End) {
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2286 if (nonOverlap1Func != 0) {
nonOverlap1Func != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2287 do {-
2288 r1BandEnd = r1;-
2289 while (r1BandEnd < r1End && r1BandEnd->top() == r1->top())
r1BandEnd < r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
r1BandEnd->top() == r1->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
2290 ++r1BandEnd;
never executed: ++r1BandEnd;
0
2291 (*nonOverlap1Func)(dest, r1, r1BandEnd, qMax(r1->top(), ybot + 1), r1->bottom());-
2292 r1 = r1BandEnd;-
2293 } while (r1 != r1End);
never executed: end of block
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2294 }
never executed: end of block
0
2295 } else if ((r2 != r2End) && (nonOverlap2Func != 0)) {
never executed: end of block
(r2 != r2End)Description
TRUEnever evaluated
FALSEnever evaluated
(nonOverlap2Func != 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2296 do {-
2297 r2BandEnd = r2;-
2298 while (r2BandEnd < r2End && r2BandEnd->top() == r2->top())
r2BandEnd < r2EndDescription
TRUEnever evaluated
FALSEnever evaluated
r2BandEnd->top() == r2->top()Description
TRUEnever evaluated
FALSEnever evaluated
0
2299 ++r2BandEnd;
never executed: ++r2BandEnd;
0
2300 (*nonOverlap2Func)(dest, r2, r2BandEnd, qMax(r2->top(), ybot + 1), r2->bottom());-
2301 r2 = r2BandEnd;-
2302 } while (r2 != r2End);
never executed: end of block
r2 != r2EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2303 }
never executed: end of block
0
2304-
2305 if (dest.numRects != curBand)
dest.numRects != curBandDescription
TRUEnever evaluated
FALSEnever evaluated
0
2306 (void)miCoalesce(dest, prevBand, curBand);
never executed: (void)miCoalesce(dest, prevBand, curBand);
0
2307-
2308 /*-
2309 * A bit of cleanup. To keep regions from growing without bound,-
2310 * we shrink the array of rectangles to match the new number of-
2311 * rectangles in the region.-
2312 *-
2313 * Only do this stuff if the number of rectangles allocated is more than-
2314 * twice the number of rectangles in the region (a simple optimization).-
2315 */-
2316 if (qMax(4, dest.numRects) < (dest.rects.size() >> 1))
qMax(4, dest.n...s.size() >> 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2317 dest.rects.resize(dest.numRects);
never executed: dest.rects.resize(dest.numRects);
0
2318}
never executed: end of block
0
2319-
2320/*======================================================================-
2321 * Region Union-
2322 *====================================================================*/-
2323-
2324/*--
2325 *------------------------------------------------------------------------
2326 * miUnionNonO ---
2327 * Handle a non-overlapping band for the union operation. Just-
2328 * Adds the rectangles into the region. Doesn't have to check for-
2329 * subsumption or anything.-
2330 *-
2331 * Results:-
2332 * None.-
2333 *-
2334 * Side Effects:-
2335 * dest.numRects is incremented and the final rectangles overwritten-
2336 * with the rectangles we're passed.-
2337 *-
2338 *------------------------------------------------------------------------
2339 */-
2340-
2341static void miUnionNonO(QRegionPrivate &dest, const QRect *r, const QRect *rEnd,-
2342 int y1, int y2)-
2343{-
2344 QRect *pNextRect;-
2345-
2346 pNextRect = dest.rects.data() + dest.numRects;-
2347-
2348 Q_ASSERT(y1 <= y2);-
2349-
2350 while (r != rEnd) {
r != rEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2351 Q_ASSERT(r->left() <= r->right());-
2352 MEMCHECK(dest, pNextRect, dest.rects)
never executed: end of block
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2353 pNextRect->setCoords(r->left(), y1, r->right(), y2);-
2354 dest.numRects++;-
2355 ++pNextRect;-
2356 ++r;-
2357 }
never executed: end of block
0
2358}
never executed: end of block
0
2359-
2360-
2361/*--
2362 *------------------------------------------------------------------------
2363 * miUnionO ---
2364 * Handle an overlapping band for the union operation. Picks the-
2365 * left-most rectangle each time and merges it into the region.-
2366 *-
2367 * Results:-
2368 * None.-
2369 *-
2370 * Side Effects:-
2371 * Rectangles are overwritten in dest.rects and dest.numRects will-
2372 * be changed.-
2373 *-
2374 *------------------------------------------------------------------------
2375 */-
2376-
2377static void miUnionO(QRegionPrivate &dest, const QRect *r1, const QRect *r1End,-
2378 const QRect *r2, const QRect *r2End, int y1, int y2)-
2379{-
2380 QRect *pNextRect;-
2381-
2382 pNextRect = dest.rects.data() + dest.numRects;-
2383-
2384#define MERGERECT(r) \-
2385 if ((dest.numRects != 0) && \-
2386 (pNextRect[-1].top() == y1) && \-
2387 (pNextRect[-1].bottom() == y2) && \-
2388 (pNextRect[-1].right() >= r->left()-1)) { \-
2389 if (pNextRect[-1].right() < r->right()) { \-
2390 pNextRect[-1].setRight(r->right()); \-
2391 dest.updateInnerRect(pNextRect[-1]); \-
2392 Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \-
2393 } \-
2394 } else { \-
2395 MEMCHECK(dest, pNextRect, dest.rects) \-
2396 pNextRect->setCoords(r->left(), y1, r->right(), y2); \-
2397 dest.updateInnerRect(*pNextRect); \-
2398 dest.numRects++; \-
2399 pNextRect++; \-
2400 } \-
2401 r++;-
2402-
2403 Q_ASSERT(y1 <= y2);-
2404 while (r1 != r1End && r2 != r2End) {
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
r2 != r2EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2405 if (r1->left() < r2->left()) {
r1->left() < r2->left()Description
TRUEnever evaluated
FALSEnever evaluated
0
2406 MERGERECT(r1)
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
pNextRect[-1].... < r1->right()Description
TRUEnever evaluated
FALSEnever evaluated
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
(dest.numRects != 0)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1].top() == y1)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1].bottom() == y2)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1]... r1->left()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2407 } else {
never executed: end of block
0
2408 MERGERECT(r2)
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
pNextRect[-1].... < r2->right()Description
TRUEnever evaluated
FALSEnever evaluated
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
(dest.numRects != 0)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1].top() == y1)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1].bottom() == y2)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1]... r2->left()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2409 }
never executed: end of block
0
2410 }-
2411-
2412 if (r1 != r1End) {
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2413 do {-
2414 MERGERECT(r1)
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
pNextRect[-1].... < r1->right()Description
TRUEnever evaluated
FALSEnever evaluated
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
(dest.numRects != 0)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1].top() == y1)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1].bottom() == y2)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1]... r1->left()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2415 } while (r1 != r1End);
never executed: end of block
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2416 } else {
never executed: end of block
0
2417 while (r2 != r2End) {
r2 != r2EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2418 MERGERECT(r2)
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
pNextRect[-1].... < r2->right()Description
TRUEnever evaluated
FALSEnever evaluated
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
(dest.numRects != 0)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1].top() == y1)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1].bottom() == y2)Description
TRUEnever evaluated
FALSEnever evaluated
(pNextRect[-1]... r2->left()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2419 }
never executed: end of block
0
2420 }
never executed: end of block
0
2421}-
2422-
2423static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest)-
2424{-
2425 Q_ASSERT(!isEmptyHelper(reg1) && !isEmptyHelper(reg2));-
2426 Q_ASSERT(!reg1->contains(*reg2));-
2427 Q_ASSERT(!reg2->contains(*reg1));-
2428 Q_ASSERT(!EqualRegion(reg1, reg2));-
2429 Q_ASSERT(!reg1->canAppend(reg2));-
2430 Q_ASSERT(!reg2->canAppend(reg1));-
2431-
2432 if (reg1->innerArea > reg2->innerArea) {
reg1->innerAre...eg2->innerAreaDescription
TRUEnever evaluated
FALSEnever evaluated
0
2433 dest.innerArea = reg1->innerArea;-
2434 dest.innerRect = reg1->innerRect;-
2435 } else {
never executed: end of block
0
2436 dest.innerArea = reg2->innerArea;-
2437 dest.innerRect = reg2->innerRect;-
2438 }
never executed: end of block
0
2439 miRegionOp(dest, reg1, reg2, miUnionO, miUnionNonO, miUnionNonO);-
2440-
2441 dest.extents.setCoords(qMin(reg1->extents.left(), reg2->extents.left()),-
2442 qMin(reg1->extents.top(), reg2->extents.top()),-
2443 qMax(reg1->extents.right(), reg2->extents.right()),-
2444 qMax(reg1->extents.bottom(), reg2->extents.bottom()));-
2445}
never executed: end of block
0
2446-
2447/*======================================================================-
2448 * Region Subtraction-
2449 *====================================================================*/-
2450-
2451/*--
2452 *------------------------------------------------------------------------
2453 * miSubtractNonO ---
2454 * Deal with non-overlapping band for subtraction. Any parts from-
2455 * region 2 we discard. Anything from region 1 we add to the region.-
2456 *-
2457 * Results:-
2458 * None.-
2459 *-
2460 * Side Effects:-
2461 * dest may be affected.-
2462 *-
2463 *------------------------------------------------------------------------
2464 */-
2465-
2466static void miSubtractNonO1(QRegionPrivate &dest, const QRect *r,-
2467 const QRect *rEnd, int y1, int y2)-
2468{-
2469 QRect *pNextRect;-
2470-
2471 pNextRect = dest.rects.data() + dest.numRects;-
2472-
2473 Q_ASSERT(y1<=y2);-
2474-
2475 while (r != rEnd) {
r != rEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2476 Q_ASSERT(r->left() <= r->right());-
2477 MEMCHECK(dest, pNextRect, dest.rects)
never executed: end of block
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2478 pNextRect->setCoords(r->left(), y1, r->right(), y2);-
2479 ++dest.numRects;-
2480 ++pNextRect;-
2481 ++r;-
2482 }
never executed: end of block
0
2483}
never executed: end of block
0
2484-
2485/*--
2486 *------------------------------------------------------------------------
2487 * miSubtractO ---
2488 * Overlapping band subtraction. x1 is the left-most point not yet-
2489 * checked.-
2490 *-
2491 * Results:-
2492 * None.-
2493 *-
2494 * Side Effects:-
2495 * dest may have rectangles added to it.-
2496 *-
2497 *------------------------------------------------------------------------
2498 */-
2499-
2500static void miSubtractO(QRegionPrivate &dest, const QRect *r1, const QRect *r1End,-
2501 const QRect *r2, const QRect *r2End, int y1, int y2)-
2502{-
2503 QRect *pNextRect;-
2504 int x1;-
2505-
2506 x1 = r1->left();-
2507-
2508 Q_ASSERT(y1 <= y2);-
2509 pNextRect = dest.rects.data() + dest.numRects;-
2510-
2511 while (r1 != r1End && r2 != r2End) {
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
r2 != r2EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2512 if (r2->right() < x1) {
r2->right() < x1Description
TRUEnever evaluated
FALSEnever evaluated
0
2513 /*-
2514 * Subtrahend missed the boat: go to next subtrahend.-
2515 */-
2516 ++r2;-
2517 } else if (r2->left() <= x1) {
never executed: end of block
r2->left() <= x1Description
TRUEnever evaluated
FALSEnever evaluated
0
2518 /*-
2519 * Subtrahend precedes minuend: nuke left edge of minuend.-
2520 */-
2521 x1 = r2->right() + 1;-
2522 if (x1 > r1->right()) {
x1 > r1->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
2523 /*-
2524 * Minuend completely covered: advance to next minuend and-
2525 * reset left fence to edge of new minuend.-
2526 */-
2527 ++r1;-
2528 if (r1 != r1End)
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2529 x1 = r1->left();
never executed: x1 = r1->left();
0
2530 } else {
never executed: end of block
0
2531 // Subtrahend now used up since it doesn't extend beyond minuend-
2532 ++r2;-
2533 }
never executed: end of block
0
2534 } else if (r2->left() <= r1->right()) {
r2->left() <= r1->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
2535 /*-
2536 * Left part of subtrahend covers part of minuend: add uncovered-
2537 * part of minuend to region and skip to next subtrahend.-
2538 */-
2539 Q_ASSERT(x1 < r2->left());-
2540 MEMCHECK(dest, pNextRect, dest.rects)
never executed: end of block
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2541 pNextRect->setCoords(x1, y1, r2->left() - 1, y2);-
2542 ++dest.numRects;-
2543 ++pNextRect;-
2544-
2545 x1 = r2->right() + 1;-
2546 if (x1 > r1->right()) {
x1 > r1->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
2547 /*-
2548 * Minuend used up: advance to new...-
2549 */-
2550 ++r1;-
2551 if (r1 != r1End)
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2552 x1 = r1->left();
never executed: x1 = r1->left();
0
2553 } else {
never executed: end of block
0
2554 // Subtrahend used up-
2555 ++r2;-
2556 }
never executed: end of block
0
2557 } else {-
2558 /*-
2559 * Minuend used up: add any remaining piece before advancing.-
2560 */-
2561 if (r1->right() >= x1) {
r1->right() >= x1Description
TRUEnever evaluated
FALSEnever evaluated
0
2562 MEMCHECK(dest, pNextRect, dest.rects)
never executed: end of block
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2563 pNextRect->setCoords(x1, y1, r1->right(), y2);-
2564 ++dest.numRects;-
2565 ++pNextRect;-
2566 }
never executed: end of block
0
2567 ++r1;-
2568 if (r1 != r1End)
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2569 x1 = r1->left();
never executed: x1 = r1->left();
0
2570 }
never executed: end of block
0
2571 }-
2572-
2573 /*-
2574 * Add remaining minuend rectangles to region.-
2575 */-
2576 while (r1 != r1End) {
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2577 Q_ASSERT(x1 <= r1->right());-
2578 MEMCHECK(dest, pNextRect, dest.rects)
never executed: end of block
(dest).numRect...ects.size()-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2579 pNextRect->setCoords(x1, y1, r1->right(), y2);-
2580 ++dest.numRects;-
2581 ++pNextRect;-
2582-
2583 ++r1;-
2584 if (r1 != r1End)
r1 != r1EndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2585 x1 = r1->left();
never executed: x1 = r1->left();
0
2586 }
never executed: end of block
0
2587}
never executed: end of block
0
2588-
2589/*--
2590 *------------------------------------------------------------------------
2591 * miSubtract ---
2592 * Subtract regS from regM and leave the result in regD.-
2593 * S stands for subtrahend, M for minuend and D for difference.-
2594 *-
2595 * Side Effects:-
2596 * regD is overwritten.-
2597 *-
2598 *------------------------------------------------------------------------
2599 */-
2600-
2601static void SubtractRegion(QRegionPrivate *regM, QRegionPrivate *regS,-
2602 QRegionPrivate &dest)-
2603{-
2604 Q_ASSERT(!isEmptyHelper(regM));-
2605 Q_ASSERT(!isEmptyHelper(regS));-
2606 Q_ASSERT(EXTENTCHECK(&regM->extents, &regS->extents));-
2607 Q_ASSERT(!regS->contains(*regM));-
2608 Q_ASSERT(!EqualRegion(regM, regS));-
2609-
2610 miRegionOp(dest, regM, regS, miSubtractO, miSubtractNonO1, 0);-
2611-
2612 /*-
2613 * Can't alter dest's extents before we call miRegionOp because-
2614 * it might be one of the source regions and miRegionOp depends-
2615 * on the extents of those regions being the unaltered. Besides, this-
2616 * way there's no checking against rectangles that will be nuked-
2617 * due to coalescing, so we have to examine fewer rectangles.-
2618 */-
2619 miSetExtents(dest);-
2620}
never executed: end of block
0
2621-
2622static void XorRegion(QRegionPrivate *sra, QRegionPrivate *srb, QRegionPrivate &dest)-
2623{-
2624 Q_ASSERT(!isEmptyHelper(sra) && !isEmptyHelper(srb));-
2625 Q_ASSERT(EXTENTCHECK(&sra->extents, &srb->extents));-
2626 Q_ASSERT(!EqualRegion(sra, srb));-
2627-
2628 QRegionPrivate tra, trb;-
2629-
2630 if (!srb->contains(*sra))
!srb->contains(*sra)Description
TRUEnever evaluated
FALSEnever evaluated
0
2631 SubtractRegion(sra, srb, tra);
never executed: SubtractRegion(sra, srb, tra);
0
2632 if (!sra->contains(*srb))
!sra->contains(*srb)Description
TRUEnever evaluated
FALSEnever evaluated
0
2633 SubtractRegion(srb, sra, trb);
never executed: SubtractRegion(srb, sra, trb);
0
2634-
2635 Q_ASSERT(isEmptyHelper(&trb) || !tra.contains(trb));-
2636 Q_ASSERT(isEmptyHelper(&tra) || !trb.contains(tra));-
2637-
2638 if (isEmptyHelper(&tra)) {
isEmptyHelper(&tra)Description
TRUEnever evaluated
FALSEnever evaluated
0
2639 dest = trb;-
2640 } else if (isEmptyHelper(&trb)) {
never executed: end of block
isEmptyHelper(&trb)Description
TRUEnever evaluated
FALSEnever evaluated
0
2641 dest = tra;-
2642 } else if (tra.canAppend(&trb)) {
never executed: end of block
tra.canAppend(&trb)Description
TRUEnever evaluated
FALSEnever evaluated
0
2643 dest = tra;-
2644 dest.append(&trb);-
2645 } else if (trb.canAppend(&tra)) {
never executed: end of block
trb.canAppend(&tra)Description
TRUEnever evaluated
FALSEnever evaluated
0
2646 dest = trb;-
2647 dest.append(&tra);-
2648 } else {
never executed: end of block
0
2649 UnionRegion(&tra, &trb, dest);-
2650 }
never executed: end of block
0
2651}-
2652-
2653/*-
2654 * Check to see if two regions are equal-
2655 */-
2656static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)-
2657{-
2658 if (r1->numRects != r2->numRects) {
r1->numRects != r2->numRectsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2659 return false;
never executed: return false;
0
2660 } else if (r1->numRects == 0) {
r1->numRects == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2661 return true;
never executed: return true;
0
2662 } else if (r1->extents != r2->extents) {
r1->extents != r2->extentsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2663 return false;
never executed: return false;
0
2664 } else if (r1->numRects == 1 && r2->numRects == 1) {
r1->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
r2->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2665 return true; // equality tested in previous if-statement
never executed: return true;
0
2666 } else {-
2667 const QRect *rr1 = (r1->numRects == 1) ? &r1->extents : r1->rects.constData();
(r1->numRects == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2668 const QRect *rr2 = (r2->numRects == 1) ? &r2->extents : r2->rects.constData();
(r2->numRects == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2669 for (int i = 0; i < r1->numRects; ++i, ++rr1, ++rr2) {
i < r1->numRectsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2670 if (*rr1 != *rr2)
*rr1 != *rr2Description
TRUEnever evaluated
FALSEnever evaluated
0
2671 return false;
never executed: return false;
0
2672 }
never executed: end of block
0
2673 }
never executed: end of block
0
2674-
2675 return true;
never executed: return true;
0
2676}-
2677-
2678static bool PointInRegion(QRegionPrivate *pRegion, int x, int y)-
2679{-
2680 int i;-
2681-
2682 if (isEmptyHelper(pRegion))
isEmptyHelper(pRegion)Description
TRUEnever evaluated
FALSEnever evaluated
0
2683 return false;
never executed: return false;
0
2684 if (!pRegion->extents.contains(x, y))
!pRegion->exte...contains(x, y)Description
TRUEnever evaluated
FALSEnever evaluated
0
2685 return false;
never executed: return false;
0
2686 if (pRegion->numRects == 1)
pRegion->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2687 return pRegion->extents.contains(x, y);
never executed: return pRegion->extents.contains(x, y);
0
2688 if (pRegion->innerRect.contains(x, y))
pRegion->inner...contains(x, y)Description
TRUEnever evaluated
FALSEnever evaluated
0
2689 return true;
never executed: return true;
0
2690 for (i = 0; i < pRegion->numRects; ++i) {
i < pRegion->numRectsDescription
TRUEnever evaluated
FALSEnever evaluated
0
2691 if (pRegion->rects[i].contains(x, y))
pRegion->rects...contains(x, y)Description
TRUEnever evaluated
FALSEnever evaluated
0
2692 return true;
never executed: return true;
0
2693 }
never executed: end of block
0
2694 return false;
never executed: return false;
0
2695}-
2696-
2697static bool RectInRegion(QRegionPrivate *region, int rx, int ry, uint rwidth, uint rheight)-
2698{-
2699 const QRect *pbox;-
2700 const QRect *pboxEnd;-
2701 QRect rect(rx, ry, rwidth, rheight);-
2702 QRect *prect = &rect;-
2703 int partIn, partOut;-
2704-
2705 if (!region || region->numRects == 0 || !EXTENTCHECK(&region->extents, prect))
!regionDescription
TRUEnever evaluated
FALSEnever evaluated
region->numRects == 0Description
TRUEnever evaluated
FALSEnever evaluated
(&region->exte...prect)->left()Description
TRUEnever evaluated
FALSEnever evaluated
(&region->exte...rect)->right()Description
TRUEnever evaluated
FALSEnever evaluated
(&region->exte...(prect)->top()Description
TRUEnever evaluated
FALSEnever evaluated
(&region->exte...ect)->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
2706 return RectangleOut;
never executed: return 0;
0
2707-
2708 partOut = false;-
2709 partIn = false;-
2710-
2711 /* can stop when both partOut and partIn are true, or we reach prect->y2 */-
2712 pbox = (region->numRects == 1) ? &region->extents : region->rects.constData();
(region->numRects == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2713 pboxEnd = pbox + region->numRects;-
2714 for (; pbox < pboxEnd; ++pbox) {
pbox < pboxEndDescription
TRUEnever evaluated
FALSEnever evaluated
0
2715 if (pbox->bottom() < ry)
pbox->bottom() < ryDescription
TRUEnever evaluated
FALSEnever evaluated
0
2716 continue;
never executed: continue;
0
2717-
2718 if (pbox->top() > ry) {
pbox->top() > ryDescription
TRUEnever evaluated
FALSEnever evaluated
0
2719 partOut = true;-
2720 if (partIn || pbox->top() > prect->bottom())
partInDescription
TRUEnever evaluated
FALSEnever evaluated
pbox->top() > prect->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
2721 break;
never executed: break;
0
2722 ry = pbox->top();-
2723 }
never executed: end of block
0
2724-
2725 if (pbox->right() < rx)
pbox->right() < rxDescription
TRUEnever evaluated
FALSEnever evaluated
0
2726 continue; /* not far enough over yet */
never executed: continue;
0
2727-
2728 if (pbox->left() > rx) {
pbox->left() > rxDescription
TRUEnever evaluated
FALSEnever evaluated
0
2729 partOut = true; /* missed part of rectangle to left */-
2730 if (partIn)
partInDescription
TRUEnever evaluated
FALSEnever evaluated
0
2731 break;
never executed: break;
0
2732 }
never executed: end of block
0
2733-
2734 if (pbox->left() <= prect->right()) {
pbox->left() <= prect->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
2735 partIn = true; /* definitely overlap */-
2736 if (partOut)
partOutDescription
TRUEnever evaluated
FALSEnever evaluated
0
2737 break;
never executed: break;
0
2738 }
never executed: end of block
0
2739-
2740 if (pbox->right() >= prect->right()) {
pbox->right() ...prect->right()Description
TRUEnever evaluated
FALSEnever evaluated
0
2741 ry = pbox->bottom() + 1; /* finished with this band */-
2742 if (ry > prect->bottom())
ry > prect->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
2743 break;
never executed: break;
0
2744 rx = prect->left(); /* reset x out to left again */-
2745 } else {
never executed: end of block
0
2746 /*-
2747 * Because boxes in a band are maximal width, if the first box-
2748 * to overlap the rectangle doesn't completely cover it in that-
2749 * band, the rectangle must be partially out, since some of it-
2750 * will be uncovered in that band. partIn will have been set true-
2751 * by now...-
2752 */-
2753 break;
never executed: break;
0
2754 }-
2755 }-
2756 return partIn ? ((ry <= prect->bottom()) ? RectanglePart : RectangleIn) : RectangleOut;
never executed: return partIn ? ((ry <= prect->bottom()) ? 2 : 1) : 0;
partInDescription
TRUEnever evaluated
FALSEnever evaluated
(ry <= prect->bottom())Description
TRUEnever evaluated
FALSEnever evaluated
0
2757}-
2758// END OF Region.c extract-
2759// START OF poly.h extract-
2760/* $XConsortium: poly.h,v 1.4 94/04/17 20:22:19 rws Exp $ */-
2761/************************************************************************-
2762-
2763Copyright (c) 1987 X Consortium-
2764-
2765Permission is hereby granted, free of charge, to any person obtaining a copy-
2766of this software and associated documentation files (the "Software"), to deal-
2767in the Software without restriction, including without limitation the rights-
2768to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-
2769copies of the Software, and to permit persons to whom the Software is-
2770furnished to do so, subject to the following conditions:-
2771-
2772The above copyright notice and this permission notice shall be included in-
2773all copies or substantial portions of the Software.-
2774-
2775THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-
2776IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-
2777FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-
2778X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN-
2779AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN-
2780CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.-
2781-
2782Except as contained in this notice, the name of the X Consortium shall not be-
2783used in advertising or otherwise to promote the sale, use or other dealings-
2784in this Software without prior written authorization from the X Consortium.-
2785-
2786-
2787Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.-
2788-
2789 All Rights Reserved-
2790-
2791Permission to use, copy, modify, and distribute this software and its-
2792documentation for any purpose and without fee is hereby granted,-
2793provided that the above copyright notice appear in all copies and that-
2794both that copyright notice and this permission notice appear in-
2795supporting documentation, and that the name of Digital not be-
2796used in advertising or publicity pertaining to distribution of the-
2797software without specific, written prior permission.-
2798-
2799DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING-
2800ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL-
2801DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR-
2802ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,-
2803WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,-
2804ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS-
2805SOFTWARE.-
2806-
2807************************************************************************/-
2808-
2809/*-
2810 * This file contains a few macros to help track-
2811 * the edge of a filled object. The object is assumed-
2812 * to be filled in scanline order, and thus the-
2813 * algorithm used is an extension of Bresenham's line-
2814 * drawing algorithm which assumes that y is always the-
2815 * major axis.-
2816 * Since these pieces of code are the same for any filled shape,-
2817 * it is more convenient to gather the library in one-
2818 * place, but since these pieces of code are also in-
2819 * the inner loops of output primitives, procedure call-
2820 * overhead is out of the question.-
2821 * See the author for a derivation if needed.-
2822 */-
2823-
2824-
2825/*-
2826 * In scan converting polygons, we want to choose those pixels-
2827 * which are inside the polygon. Thus, we add .5 to the starting-
2828 * x coordinate for both left and right edges. Now we choose the-
2829 * first pixel which is inside the pgon for the left edge and the-
2830 * first pixel which is outside the pgon for the right edge.-
2831 * Draw the left pixel, but not the right.-
2832 *-
2833 * How to add .5 to the starting x coordinate:-
2834 * If the edge is moving to the right, then subtract dy from the-
2835 * error term from the general form of the algorithm.-
2836 * If the edge is moving to the left, then add dy to the error term.-
2837 *-
2838 * The reason for the difference between edges moving to the left-
2839 * and edges moving to the right is simple: If an edge is moving-
2840 * to the right, then we want the algorithm to flip immediately.-
2841 * If it is moving to the left, then we don't want it to flip until-
2842 * we traverse an entire pixel.-
2843 */-
2844#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \-
2845 int dx; /* local storage */ \-
2846\-
2847 /* \-
2848 * if the edge is horizontal, then it is ignored \-
2849 * and assumed not to be processed. Otherwise, do this stuff. \-
2850 */ \-
2851 if ((dy) != 0) { \-
2852 xStart = (x1); \-
2853 dx = (x2) - xStart; \-
2854 if (dx < 0) { \-
2855 m = dx / (dy); \-
2856 m1 = m - 1; \-
2857 incr1 = -2 * dx + 2 * (dy) * m1; \-
2858 incr2 = -2 * dx + 2 * (dy) * m; \-
2859 d = 2 * m * (dy) - 2 * dx - 2 * (dy); \-
2860 } else { \-
2861 m = dx / (dy); \-
2862 m1 = m + 1; \-
2863 incr1 = 2 * dx - 2 * (dy) * m1; \-
2864 incr2 = 2 * dx - 2 * (dy) * m; \-
2865 d = -2 * m * (dy) + 2 * dx; \-
2866 } \-
2867 } \-
2868}-
2869-
2870#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \-
2871 if (m1 > 0) { \-
2872 if (d > 0) { \-
2873 minval += m1; \-
2874 d += incr1; \-
2875 } \-
2876 else { \-
2877 minval += m; \-
2878 d += incr2; \-
2879 } \-
2880 } else {\-
2881 if (d >= 0) { \-
2882 minval += m1; \-
2883 d += incr1; \-
2884 } \-
2885 else { \-
2886 minval += m; \-
2887 d += incr2; \-
2888 } \-
2889 } \-
2890}-
2891-
2892-
2893/*-
2894 * This structure contains all of the information needed-
2895 * to run the bresenham algorithm.-
2896 * The variables may be hardcoded into the declarations-
2897 * instead of using this structure to make use of-
2898 * register declarations.-
2899 */-
2900typedef struct {-
2901 int minor_axis; /* minor axis */-
2902 int d; /* decision variable */-
2903 int m, m1; /* slope and slope+1 */-
2904 int incr1, incr2; /* error increments */-
2905} BRESINFO;-
2906-
2907-
2908#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \-
2909 BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \-
2910 bres.m, bres.m1, bres.incr1, bres.incr2)-
2911-
2912#define BRESINCRPGONSTRUCT(bres) \-
2913 BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)-
2914-
2915-
2916-
2917/*-
2918 * These are the data structures needed to scan-
2919 * convert regions. Two different scan conversion-
2920 * methods are available -- the even-odd method, and-
2921 * the winding number method.-
2922 * The even-odd rule states that a point is inside-
2923 * the polygon if a ray drawn from that point in any-
2924 * direction will pass through an odd number of-
2925 * path segments.-
2926 * By the winding number rule, a point is decided-
2927 * to be inside the polygon if a ray drawn from that-
2928 * point in any direction passes through a different-
2929 * number of clockwise and counter-clockwise path-
2930 * segments.-
2931 *-
2932 * These data structures are adapted somewhat from-
2933 * the algorithm in (Foley/Van Dam) for scan converting-
2934 * polygons.-
2935 * The basic algorithm is to start at the top (smallest y)-
2936 * of the polygon, stepping down to the bottom of-
2937 * the polygon by incrementing the y coordinate. We-
2938 * keep a list of edges which the current scanline crosses,-
2939 * sorted by x. This list is called the Active Edge Table (AET)-
2940 * As we change the y-coordinate, we update each entry in-
2941 * in the active edge table to reflect the edges new xcoord.-
2942 * This list must be sorted at each scanline in case-
2943 * two edges intersect.-
2944 * We also keep a data structure known as the Edge Table (ET),-
2945 * which keeps track of all the edges which the current-
2946 * scanline has not yet reached. The ET is basically a-
2947 * list of ScanLineList structures containing a list of-
2948 * edges which are entered at a given scanline. There is one-
2949 * ScanLineList per scanline at which an edge is entered.-
2950 * When we enter a new edge, we move it from the ET to the AET.-
2951 *-
2952 * From the AET, we can implement the even-odd rule as in-
2953 * (Foley/Van Dam).-
2954 * The winding number rule is a little trickier. We also-
2955 * keep the EdgeTableEntries in the AET linked by the-
2956 * nextWETE (winding EdgeTableEntry) link. This allows-
2957 * the edges to be linked just as before for updating-
2958 * purposes, but only uses the edges linked by the nextWETE-
2959 * link as edges representing spans of the polygon to-
2960 * drawn (as with the even-odd rule).-
2961 */-
2962-
2963/*-
2964 * for the winding number rule-
2965 */-
2966#define CLOCKWISE 1-
2967#define COUNTERCLOCKWISE -1-
2968-
2969typedef struct _EdgeTableEntry {-
2970 int ymax; /* ycoord at which we exit this edge. */-
2971 int ClockWise; /* flag for winding number rule */-
2972 BRESINFO bres; /* Bresenham info to run the edge */-
2973 struct _EdgeTableEntry *next; /* next in the list */-
2974 struct _EdgeTableEntry *back; /* for insertion sort */-
2975 struct _EdgeTableEntry *nextWETE; /* for winding num rule */-
2976} EdgeTableEntry;-
2977-
2978-
2979typedef struct _ScanLineList{-
2980 int scanline; /* the scanline represented */-
2981 EdgeTableEntry *edgelist; /* header node */-
2982 struct _ScanLineList *next; /* next in the list */-
2983} ScanLineList;-
2984-
2985-
2986typedef struct {-
2987 int ymax; /* ymax for the polygon */-
2988 int ymin; /* ymin for the polygon */-
2989 ScanLineList scanlines; /* header node */-
2990} EdgeTable;-
2991-
2992-
2993/*-
2994 * Here is a struct to help with storage allocation-
2995 * so we can allocate a big chunk at a time, and then take-
2996 * pieces from this heap when we need to.-
2997 */-
2998#define SLLSPERBLOCK 25-
2999-
3000typedef struct _ScanLineListBlock {-
3001 ScanLineList SLLs[SLLSPERBLOCK];-
3002 struct _ScanLineListBlock *next;-
3003} ScanLineListBlock;-
3004-
3005-
3006-
3007/*-
3008 *-
3009 * a few macros for the inner loops of the fill code where-
3010 * performance considerations don't allow a procedure call.-
3011 *-
3012 * Evaluate the given edge at the given scanline.-
3013 * If the edge has expired, then we leave it and fix up-
3014 * the active edge table; otherwise, we increment the-
3015 * x value to be ready for the next scanline.-
3016 * The winding number rule is in effect, so we must notify-
3017 * the caller when the edge has been removed so he-
3018 * can reorder the Winding Active Edge Table.-
3019 */-
3020#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \-
3021 if (pAET->ymax == y) { /* leaving this edge */ \-
3022 pPrevAET->next = pAET->next; \-
3023 pAET = pPrevAET->next; \-
3024 fixWAET = 1; \-
3025 if (pAET) \-
3026 pAET->back = pPrevAET; \-
3027 } \-
3028 else { \-
3029 BRESINCRPGONSTRUCT(pAET->bres) \-
3030 pPrevAET = pAET; \-
3031 pAET = pAET->next; \-
3032 } \-
3033}-
3034-
3035-
3036/*-
3037 * Evaluate the given edge at the given scanline.-
3038 * If the edge has expired, then we leave it and fix up-
3039 * the active edge table; otherwise, we increment the-
3040 * x value to be ready for the next scanline.-
3041 * The even-odd rule is in effect.-
3042 */-
3043#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \-
3044 if (pAET->ymax == y) { /* leaving this edge */ \-
3045 pPrevAET->next = pAET->next; \-
3046 pAET = pPrevAET->next; \-
3047 if (pAET) \-
3048 pAET->back = pPrevAET; \-
3049 } \-
3050 else { \-
3051 BRESINCRPGONSTRUCT(pAET->bres) \-
3052 pPrevAET = pAET; \-
3053 pAET = pAET->next; \-
3054 } \-
3055}-
3056// END OF poly.h extract-
3057// START OF PolyReg.c extract-
3058/* $XConsortium: PolyReg.c,v 11.23 94/11/17 21:59:37 converse Exp $ */-
3059/************************************************************************-
3060-
3061Copyright (c) 1987 X Consortium-
3062-
3063Permission is hereby granted, free of charge, to any person obtaining a copy-
3064of this software and associated documentation files (the "Software"), to deal-
3065in the Software without restriction, including without limitation the rights-
3066to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-
3067copies of the Software, and to permit persons to whom the Software is-
3068furnished to do so, subject to the following conditions:-
3069-
3070The above copyright notice and this permission notice shall be included in-
3071all copies or substantial portions of the Software.-
3072-
3073THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-
3074IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-
3075FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-
3076X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN-
3077AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN-
3078CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.-
3079-
3080Except as contained in this notice, the name of the X Consortium shall not be-
3081used in advertising or otherwise to promote the sale, use or other dealings-
3082in this Software without prior written authorization from the X Consortium.-
3083-
3084-
3085Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.-
3086-
3087 All Rights Reserved-
3088-
3089Permission to use, copy, modify, and distribute this software and its-
3090documentation for any purpose and without fee is hereby granted,-
3091provided that the above copyright notice appear in all copies and that-
3092both that copyright notice and this permission notice appear in-
3093supporting documentation, and that the name of Digital not be-
3094used in advertising or publicity pertaining to distribution of the-
3095software without specific, written prior permission.-
3096-
3097DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING-
3098ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL-
3099DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR-
3100ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,-
3101WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,-
3102ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS-
3103SOFTWARE.-
3104-
3105************************************************************************/-
3106/* $XFree86: xc/lib/X11/PolyReg.c,v 1.1.1.2.8.2 1998/10/04 15:22:49 hohndel Exp $ */-
3107-
3108#define LARGE_COORDINATE INT_MAX-
3109#define SMALL_COORDINATE INT_MIN-
3110-
3111/*-
3112 * InsertEdgeInET-
3113 *-
3114 * Insert the given edge into the edge table.-
3115 * First we must find the correct bucket in the-
3116 * Edge table, then find the right slot in the-
3117 * bucket. Finally, we can insert it.-
3118 *-
3119 */-
3120static void InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline,-
3121 ScanLineListBlock **SLLBlock, int *iSLLBlock)-
3122{-
3123 EdgeTableEntry *start, *prev;-
3124 ScanLineList *pSLL, *pPrevSLL;-
3125 ScanLineListBlock *tmpSLLBlock;-
3126-
3127 /*-
3128 * find the right bucket to put the edge into-
3129 */-
3130 pPrevSLL = &ET->scanlines;-
3131 pSLL = pPrevSLL->next;-
3132 while (pSLL && (pSLL->scanline < scanline)) {
pSLLDescription
TRUEnever evaluated
FALSEnever evaluated
(pSLL->scanline < scanline)Description
TRUEnever evaluated
FALSEnever evaluated
0
3133 pPrevSLL = pSLL;-
3134 pSLL = pSLL->next;-
3135 }
never executed: end of block
0
3136-
3137 /*-
3138 * reassign pSLL (pointer to ScanLineList) if necessary-
3139 */-
3140 if ((!pSLL) || (pSLL->scanline > scanline)) {
(!pSLL)Description
TRUEnever evaluated
FALSEnever evaluated
(pSLL->scanline > scanline)Description
TRUEnever evaluated
FALSEnever evaluated
0
3141 if (*iSLLBlock > SLLSPERBLOCK-1)
*iSLLBlock > 25 -1Description
TRUEnever evaluated
FALSEnever evaluated
0
3142 {-
3143 tmpSLLBlock =-
3144 (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));-
3145 Q_CHECK_PTR(tmpSLLBlock);
never executed: qt_check_pointer(__FILE__,3145);
!(tmpSLLBlock)Description
TRUEnever evaluated
FALSEnever evaluated
0
3146 (*SLLBlock)->next = tmpSLLBlock;-
3147 tmpSLLBlock->next = (ScanLineListBlock *)NULL;-
3148 *SLLBlock = tmpSLLBlock;-
3149 *iSLLBlock = 0;-
3150 }
never executed: end of block
0
3151 pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);-
3152-
3153 pSLL->next = pPrevSLL->next;-
3154 pSLL->edgelist = (EdgeTableEntry *)NULL;-
3155 pPrevSLL->next = pSLL;-
3156 }
never executed: end of block
0
3157 pSLL->scanline = scanline;-
3158-
3159 /*-
3160 * now insert the edge in the right bucket-
3161 */-
3162 prev = 0;-
3163 start = pSLL->edgelist;-
3164 while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) {
startDescription
TRUEnever evaluated
FALSEnever evaluated
(start->bres.m...es.minor_axis)Description
TRUEnever evaluated
FALSEnever evaluated
0
3165 prev = start;-
3166 start = start->next;-
3167 }
never executed: end of block
0
3168 ETE->next = start;-
3169-
3170 if (prev)
prevDescription
TRUEnever evaluated
FALSEnever evaluated
0
3171 prev->next = ETE;
never executed: prev->next = ETE;
0
3172 else-
3173 pSLL->edgelist = ETE;
never executed: pSLL->edgelist = ETE;
0
3174}-
3175-
3176/*-
3177 * CreateEdgeTable-
3178 *-
3179 * This routine creates the edge table for-
3180 * scan converting polygons.-
3181 * The Edge Table (ET) looks like:-
3182 *-
3183 * EdgeTable-
3184 * ---------
3185 * | ymax | ScanLineLists-
3186 * |scanline|-->------------>-------------->...-
3187 * -------- |scanline| |scanline|-
3188 * |edgelist| |edgelist|-
3189 * --------- ----------
3190 * | |-
3191 * | |-
3192 * V V-
3193 * list of ETEs list of ETEs-
3194 *-
3195 * where ETE is an EdgeTableEntry data structure,-
3196 * and there is one ScanLineList per scanline at-
3197 * which an edge is initially entered.-
3198 *-
3199 */-
3200-
3201static void CreateETandAET(int count, const QPoint *pts,-
3202 EdgeTable *ET, EdgeTableEntry *AET, EdgeTableEntry *pETEs,-
3203 ScanLineListBlock *pSLLBlock)-
3204{-
3205 const QPoint *top,-
3206 *bottom,-
3207 *PrevPt,-
3208 *CurrPt;-
3209 int iSLLBlock = 0;-
3210 int dy;-
3211-
3212 if (count < 2)
count < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
3213 return;
never executed: return;
0
3214-
3215 /*-
3216 * initialize the Active Edge Table-
3217 */-
3218 AET->next = 0;-
3219 AET->back = 0;-
3220 AET->nextWETE = 0;-
3221 AET->bres.minor_axis = SMALL_COORDINATE;-
3222-
3223 /*-
3224 * initialize the Edge Table.-
3225 */-
3226 ET->scanlines.next = 0;-
3227 ET->ymax = SMALL_COORDINATE;-
3228 ET->ymin = LARGE_COORDINATE;-
3229 pSLLBlock->next = 0;-
3230-
3231 PrevPt = &pts[count - 1];-
3232-
3233 /*-
3234 * for each vertex in the array of points.-
3235 * In this loop we are dealing with two vertices at-
3236 * a time -- these make up one edge of the polygon.-
3237 */-
3238 while (count--) {
count--Description
TRUEnever evaluated
FALSEnever evaluated
0
3239 CurrPt = pts++;-
3240-
3241 /*-
3242 * find out which point is above and which is below.-
3243 */-
3244 if (PrevPt->y() > CurrPt->y()) {
PrevPt->y() > CurrPt->y()Description
TRUEnever evaluated
FALSEnever evaluated
0
3245 bottom = PrevPt;-
3246 top = CurrPt;-
3247 pETEs->ClockWise = 0;-
3248 } else {
never executed: end of block
0
3249 bottom = CurrPt;-
3250 top = PrevPt;-
3251 pETEs->ClockWise = 1;-
3252 }
never executed: end of block
0
3253-
3254 /*-
3255 * don't add horizontal edges to the Edge table.-
3256 */-
3257 if (bottom->y() != top->y()) {
bottom->y() != top->y()Description
TRUEnever evaluated
FALSEnever evaluated
0
3258 pETEs->ymax = bottom->y() - 1; /* -1 so we don't get last scanline */-
3259-
3260 /*-
3261 * initialize integer edge algorithm-
3262 */-
3263 dy = bottom->y() - top->y();-
3264 BRESINITPGONSTRUCT(dy, top->x(), bottom->x(), pETEs->bres)
never executed: end of block
never executed: end of block
(dy) != 0Description
TRUEnever evaluated
FALSEnever evaluated
dx < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3265-
3266 InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock);-
3267-
3268 if (PrevPt->y() > ET->ymax)
PrevPt->y() > ET->ymaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3269 ET->ymax = PrevPt->y();
never executed: ET->ymax = PrevPt->y();
0
3270 if (PrevPt->y() < ET->ymin)
PrevPt->y() < ET->yminDescription
TRUEnever evaluated
FALSEnever evaluated
0
3271 ET->ymin = PrevPt->y();
never executed: ET->ymin = PrevPt->y();
0
3272 ++pETEs;-
3273 }
never executed: end of block
0
3274-
3275 PrevPt = CurrPt;-
3276 }
never executed: end of block
0
3277}
never executed: end of block
0
3278-
3279/*-
3280 * loadAET-
3281 *-
3282 * This routine moves EdgeTableEntries from the-
3283 * EdgeTable into the Active Edge Table,-
3284 * leaving them sorted by smaller x coordinate.-
3285 *-
3286 */-
3287-
3288static void loadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs)-
3289{-
3290 EdgeTableEntry *pPrevAET;-
3291 EdgeTableEntry *tmp;-
3292-
3293 pPrevAET = AET;-
3294 AET = AET->next;-
3295 while (ETEs) {
ETEsDescription
TRUEnever evaluated
FALSEnever evaluated
0
3296 while (AET && AET->bres.minor_axis < ETEs->bres.minor_axis) {
AETDescription
TRUEnever evaluated
FALSEnever evaluated
AET->bres.mino...res.minor_axisDescription
TRUEnever evaluated
FALSEnever evaluated
0
3297 pPrevAET = AET;-
3298 AET = AET->next;-
3299 }
never executed: end of block
0
3300 tmp = ETEs->next;-
3301 ETEs->next = AET;-
3302 if (AET)
AETDescription
TRUEnever evaluated
FALSEnever evaluated
0
3303 AET->back = ETEs;
never executed: AET->back = ETEs;
0
3304 ETEs->back = pPrevAET;-
3305 pPrevAET->next = ETEs;-
3306 pPrevAET = ETEs;-
3307-
3308 ETEs = tmp;-
3309 }
never executed: end of block
0
3310}
never executed: end of block
0
3311-
3312/*-
3313 * computeWAET-
3314 *-
3315 * This routine links the AET by the-
3316 * nextWETE (winding EdgeTableEntry) link for-
3317 * use by the winding number rule. The final-
3318 * Active Edge Table (AET) might look something-
3319 * like:-
3320 *-
3321 * AET-
3322 * ---------- --------- ----------
3323 * |ymax | |ymax | |ymax |-
3324 * | ... | |... | |... |-
3325 * |next |->|next |->|next |->...-
3326 * |nextWETE| |nextWETE| |nextWETE|-
3327 * --------- --------- ^---------
3328 * | | |-
3329 * V-------------------> V---> ...-
3330 *-
3331 */-
3332static void computeWAET(EdgeTableEntry *AET)-
3333{-
3334 EdgeTableEntry *pWETE;-
3335 int inside = 1;-
3336 int isInside = 0;-
3337-
3338 AET->nextWETE = 0;-
3339 pWETE = AET;-
3340 AET = AET->next;-
3341 while (AET) {
AETDescription
TRUEnever evaluated
FALSEnever evaluated
0
3342 if (AET->ClockWise)
AET->ClockWiseDescription
TRUEnever evaluated
FALSEnever evaluated
0
3343 ++isInside;
never executed: ++isInside;
0
3344 else-
3345 --isInside;
never executed: --isInside;
0
3346-
3347 if ((!inside && !isInside) || (inside && isInside)) {
!insideDescription
TRUEnever evaluated
FALSEnever evaluated
!isInsideDescription
TRUEnever evaluated
FALSEnever evaluated
insideDescription
TRUEnever evaluated
FALSEnever evaluated
isInsideDescription
TRUEnever evaluated
FALSEnever evaluated
0
3348 pWETE->nextWETE = AET;-
3349 pWETE = AET;-
3350 inside = !inside;-
3351 }
never executed: end of block
0
3352 AET = AET->next;-
3353 }
never executed: end of block
0
3354 pWETE->nextWETE = 0;-
3355}
never executed: end of block
0
3356-
3357/*-
3358 * InsertionSort-
3359 *-
3360 * Just a simple insertion sort using-
3361 * pointers and back pointers to sort the Active-
3362 * Edge Table.-
3363 *-
3364 */-
3365-
3366static int InsertionSort(EdgeTableEntry *AET)-
3367{-
3368 EdgeTableEntry *pETEchase;-
3369 EdgeTableEntry *pETEinsert;-
3370 EdgeTableEntry *pETEchaseBackTMP;-
3371 int changed = 0;-
3372-
3373 AET = AET->next;-
3374 while (AET) {
AETDescription
TRUEnever evaluated
FALSEnever evaluated
0
3375 pETEinsert = AET;-
3376 pETEchase = AET;-
3377 while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
pETEchase->bac...res.minor_axisDescription
TRUEnever evaluated
FALSEnever evaluated
0
3378 pETEchase = pETEchase->back;
never executed: pETEchase = pETEchase->back;
0
3379-
3380 AET = AET->next;-
3381 if (pETEchase != pETEinsert) {
pETEchase != pETEinsertDescription
TRUEnever evaluated
FALSEnever evaluated
0
3382 pETEchaseBackTMP = pETEchase->back;-
3383 pETEinsert->back->next = AET;-
3384 if (AET)
AETDescription
TRUEnever evaluated
FALSEnever evaluated
0
3385 AET->back = pETEinsert->back;
never executed: AET->back = pETEinsert->back;
0
3386 pETEinsert->next = pETEchase;-
3387 pETEchase->back->next = pETEinsert;-
3388 pETEchase->back = pETEinsert;-
3389 pETEinsert->back = pETEchaseBackTMP;-
3390 changed = 1;-
3391 }
never executed: end of block
0
3392 }
never executed: end of block
0
3393 return changed;
never executed: return changed;
0
3394}-
3395-
3396/*-
3397 * Clean up our act.-
3398 */-
3399static void FreeStorage(ScanLineListBlock *pSLLBlock)-
3400{-
3401 ScanLineListBlock *tmpSLLBlock;-
3402-
3403 while (pSLLBlock) {
pSLLBlockDescription
TRUEnever evaluated
FALSEnever evaluated
0
3404 tmpSLLBlock = pSLLBlock->next;-
3405 free(pSLLBlock);-
3406 pSLLBlock = tmpSLLBlock;-
3407 }
never executed: end of block
0
3408}
never executed: end of block
0
3409-
3410struct QRegionSpan {-
3411 QRegionSpan() {}-
3412 QRegionSpan(int x1_, int x2_) : x1(x1_), x2(x2_) {}
never executed: end of block
0
3413-
3414 int x1;-
3415 int x2;-
3416 int width() const { return x2 - x1; }
never executed: return x2 - x1;
0
3417};-
3418-
3419Q_DECLARE_TYPEINFO(QRegionSpan, Q_PRIMITIVE_TYPE);-
3420-
3421static inline void flushRow(const QRegionSpan *spans, int y, int numSpans, QRegionPrivate *reg, int *lastRow, int *extendTo, bool *needsExtend)-
3422{-
3423 QRect *regRects = reg->rects.data() + *lastRow;-
3424 bool canExtend = reg->rects.size() - *lastRow == numSpans
reg->rects.siz...ow == numSpansDescription
TRUEnever evaluated
FALSEnever evaluated
0
3425 && !(*needsExtend && *extendTo + 1 != y)
*needsExtendDescription
TRUEnever evaluated
FALSEnever evaluated
*extendTo + 1 != yDescription
TRUEnever evaluated
FALSEnever evaluated
0
3426 && (*needsExtend || regRects[0].y() + regRects[0].height() == y);
*needsExtendDescription
TRUEnever evaluated
FALSEnever evaluated
regRects[0].y(....height() == yDescription
TRUEnever evaluated
FALSEnever evaluated
0
3427-
3428 for (int i = 0; i < numSpans && canExtend; ++i) {
i < numSpansDescription
TRUEnever evaluated
FALSEnever evaluated
canExtendDescription
TRUEnever evaluated
FALSEnever evaluated
0
3429 if (regRects[i].x() != spans[i].x1 || regRects[i].right() != spans[i].x2 - 1)
regRects[i].x() != spans[i].x1Description
TRUEnever evaluated
FALSEnever evaluated
regRects[i].ri...pans[i].x2 - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
3430 canExtend = false;
never executed: canExtend = false;
0
3431 }
never executed: end of block
0
3432-
3433 if (canExtend) {
canExtendDescription
TRUEnever evaluated
FALSEnever evaluated
0
3434 *extendTo = y;-
3435 *needsExtend = true;-
3436 } else {
never executed: end of block
0
3437 if (*needsExtend) {
*needsExtendDescription
TRUEnever evaluated
FALSEnever evaluated
0
3438 for (int i = 0; i < reg->rects.size() - *lastRow; ++i)
i < reg->rects...e() - *lastRowDescription
TRUEnever evaluated
FALSEnever evaluated
0
3439 regRects[i].setBottom(*extendTo);
never executed: regRects[i].setBottom(*extendTo);
0
3440 }
never executed: end of block
0
3441-
3442 *lastRow = reg->rects.size();-
3443 reg->rects.reserve(*lastRow + numSpans);-
3444 for (int i = 0; i < numSpans; ++i)
i < numSpansDescription
TRUEnever evaluated
FALSEnever evaluated
0
3445 reg->rects << QRect(spans[i].x1, y, spans[i].width(), 1);
never executed: reg->rects << QRect(spans[i].x1, y, spans[i].width(), 1);
0
3446-
3447 if (spans[0].x1 < reg->extents.left())
spans[0].x1 < ...extents.left()Description
TRUEnever evaluated
FALSEnever evaluated
0
3448 reg->extents.setLeft(spans[0].x1);
never executed: reg->extents.setLeft(spans[0].x1);
0
3449-
3450 if (spans[numSpans-1].x2 - 1 > reg->extents.right())
spans[numSpans...xtents.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
3451 reg->extents.setRight(spans[numSpans-1].x2 - 1);
never executed: reg->extents.setRight(spans[numSpans-1].x2 - 1);
0
3452-
3453 *needsExtend = false;-
3454 }
never executed: end of block
0
3455}-
3456-
3457/*-
3458 * Create an array of rectangles from a list of points.-
3459 * If indeed these things (POINTS, RECTS) are the same,-
3460 * then this proc is still needed, because it allocates-
3461 * storage for the array, which was allocated on the-
3462 * stack by the calling procedure.-
3463 *-
3464 */-
3465static void PtsToRegion(int numFullPtBlocks, int iCurPtBlock,-
3466 POINTBLOCK *FirstPtBlock, QRegionPrivate *reg)-
3467{-
3468 int lastRow = 0;-
3469 int extendTo = 0;-
3470 bool needsExtend = false;-
3471 QVarLengthArray<QRegionSpan> row;-
3472 int rowSize = 0;-
3473-
3474 reg->extents.setLeft(INT_MAX);-
3475 reg->extents.setRight(INT_MIN);-
3476 reg->innerArea = -1;-
3477-
3478 POINTBLOCK *CurPtBlock = FirstPtBlock;-
3479 for (; numFullPtBlocks >= 0; --numFullPtBlocks) {
numFullPtBlocks >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3480 /* the loop uses 2 points per iteration */-
3481 int i = NUMPTSTOBUFFER >> 1;-
3482 if (!numFullPtBlocks)
!numFullPtBlocksDescription
TRUEnever evaluated
FALSEnever evaluated
0
3483 i = iCurPtBlock >> 1;
never executed: i = iCurPtBlock >> 1;
0
3484 if(i) {
iDescription
TRUEnever evaluated
FALSEnever evaluated
0
3485 row.resize(qMax(row.size(), rowSize + i));-
3486 for (QPoint *pts = CurPtBlock->pts; i--; pts += 2) {
i--Description
TRUEnever evaluated
FALSEnever evaluated
0
3487 const int width = pts[1].x() - pts[0].x();-
3488 if (width) {
widthDescription
TRUEnever evaluated
FALSEnever evaluated
0
3489 if (rowSize && row[rowSize-1].x2 == pts[0].x())
rowSizeDescription
TRUEnever evaluated
FALSEnever evaluated
row[rowSize-1]... == pts[0].x()Description
TRUEnever evaluated
FALSEnever evaluated
0
3490 row[rowSize-1].x2 = pts[1].x();
never executed: row[rowSize-1].x2 = pts[1].x();
0
3491 else-
3492 row[rowSize++] = QRegionSpan(pts[0].x(), pts[1].x());
never executed: row[rowSize++] = QRegionSpan(pts[0].x(), pts[1].x());
0
3493 }-
3494-
3495 if (rowSize) {
rowSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
3496 QPoint *next = i ? &pts[2] : (numFullPtBlocks && iCurPtBlock ? CurPtBlock->next->pts : Q_NULLPTR);
iDescription
TRUEnever evaluated
FALSEnever evaluated
numFullPtBlocksDescription
TRUEnever evaluated
FALSEnever evaluated
iCurPtBlockDescription
TRUEnever evaluated
FALSEnever evaluated
0
3497-
3498 if (!next || next->y() != pts[0].y()) {
!nextDescription
TRUEnever evaluated
FALSEnever evaluated
next->y() != pts[0].y()Description
TRUEnever evaluated
FALSEnever evaluated
0
3499 flushRow(row.data(), pts[0].y(), rowSize, reg, &lastRow, &extendTo, &needsExtend);-
3500 rowSize = 0;-
3501 }
never executed: end of block
0
3502 }
never executed: end of block
0
3503 }
never executed: end of block
0
3504 }
never executed: end of block
0
3505 CurPtBlock = CurPtBlock->next;-
3506 }
never executed: end of block
0
3507-
3508 if (needsExtend) {
needsExtendDescription
TRUEnever evaluated
FALSEnever evaluated
0
3509 for (int i = lastRow; i < reg->rects.size(); ++i)
i < reg->rects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
3510 reg->rects[i].setBottom(extendTo);
never executed: reg->rects[i].setBottom(extendTo);
0
3511 }
never executed: end of block
0
3512-
3513 reg->numRects = reg->rects.size();-
3514-
3515 if (reg->numRects) {
reg->numRectsDescription
TRUEnever evaluated
FALSEnever evaluated
0
3516 reg->extents.setTop(reg->rects[0].top());-
3517 reg->extents.setBottom(reg->rects[lastRow].bottom());-
3518-
3519 for (int i = 0; i < reg->rects.size(); ++i)
i < reg->rects.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
3520 reg->updateInnerRect(reg->rects[i]);
never executed: reg->updateInnerRect(reg->rects[i]);
0
3521 } else {
never executed: end of block
0
3522 reg->extents.setCoords(0, 0, 0, 0);-
3523 }
never executed: end of block
0
3524}-
3525-
3526/*-
3527 * polytoregion-
3528 *-
3529 * Scan converts a polygon by returning a run-length-
3530 * encoding of the resultant bitmap -- the run-length-
3531 * encoding is in the form of an array of rectangles.-
3532 *-
3533 * Can return 0 in case of errors.-
3534 */-
3535static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)-
3536 //Point *Pts; /* the pts */-
3537 //int Count; /* number of pts */-
3538 //int rule; /* winding rule */-
3539{-
3540 QRegionPrivate *region;-
3541 EdgeTableEntry *pAET; /* Active Edge Table */-
3542 int y; /* current scanline */-
3543 int iPts = 0; /* number of pts in buffer */-
3544 EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/-
3545 ScanLineList *pSLL; /* current scanLineList */-
3546 QPoint *pts; /* output buffer */-
3547 EdgeTableEntry *pPrevAET; /* ptr to previous AET */-
3548 EdgeTable ET; /* header node for ET */-
3549 EdgeTableEntry *AET; /* header node for AET */-
3550 EdgeTableEntry *pETEs; /* EdgeTableEntries pool */-
3551 ScanLineListBlock SLLBlock; /* header for scanlinelist */-
3552 int fixWAET = false;-
3553 POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */-
3554 FirstPtBlock.pts = reinterpret_cast<QPoint *>(FirstPtBlock.data);-
3555 POINTBLOCK *tmpPtBlock;-
3556 int numFullPtBlocks = 0;-
3557-
3558 region = new QRegionPrivate;-
3559-
3560 /* special case a rectangle */-
3561 if (((Count == 4) ||
(Count == 4)Description
TRUEnever evaluated
FALSEnever evaluated
0
3562 ((Count == 5) && (Pts[4].x() == Pts[0].x()) && (Pts[4].y() == Pts[0].y())))
(Count == 5)Description
TRUEnever evaluated
FALSEnever evaluated
(Pts[4].x() == Pts[0].x())Description
TRUEnever evaluated
FALSEnever evaluated
(Pts[4].y() == Pts[0].y())Description
TRUEnever evaluated
FALSEnever evaluated
0
3563 && (((Pts[0].y() == Pts[1].y()) && (Pts[1].x() == Pts[2].x()) && (Pts[2].y() == Pts[3].y())
(Pts[0].y() == Pts[1].y())Description
TRUEnever evaluated
FALSEnever evaluated
(Pts[1].x() == Pts[2].x())Description
TRUEnever evaluated
FALSEnever evaluated
(Pts[2].y() == Pts[3].y())Description
TRUEnever evaluated
FALSEnever evaluated
0
3564 && (Pts[3].x() == Pts[0].x())) || ((Pts[0].x() == Pts[1].x())
(Pts[3].x() == Pts[0].x())Description
TRUEnever evaluated
FALSEnever evaluated
(Pts[0].x() == Pts[1].x())Description
TRUEnever evaluated
FALSEnever evaluated
0
3565 && (Pts[1].y() == Pts[2].y()) && (Pts[2].x() == Pts[3].x())
(Pts[1].y() == Pts[2].y())Description
TRUEnever evaluated
FALSEnever evaluated
(Pts[2].x() == Pts[3].x())Description
TRUEnever evaluated
FALSEnever evaluated
0
3566 && (Pts[3].y() == Pts[0].y())))) {
(Pts[3].y() == Pts[0].y())Description
TRUEnever evaluated
FALSEnever evaluated
0
3567 int x = qMin(Pts[0].x(), Pts[2].x());-
3568 region->extents.setLeft(x);-
3569 int y = qMin(Pts[0].y(), Pts[2].y());-
3570 region->extents.setTop(y);-
3571 region->extents.setWidth(qMax(Pts[0].x(), Pts[2].x()) - x);-
3572 region->extents.setHeight(qMax(Pts[0].y(), Pts[2].y()) - y);-
3573 if ((region->extents.left() <= region->extents.right()) &&
(region->exten...tents.right())Description
TRUEnever evaluated
FALSEnever evaluated
0
3574 (region->extents.top() <= region->extents.bottom())) {
(region->exten...ents.bottom())Description
TRUEnever evaluated
FALSEnever evaluated
0
3575 region->numRects = 1;-
3576 region->innerRect = region->extents;-
3577 region->innerArea = region->innerRect.width() * region->innerRect.height();-
3578 }
never executed: end of block
0
3579 return region;
never executed: return region;
0
3580 }-
3581-
3582 if (!(pETEs = static_cast<EdgeTableEntry *>(malloc(sizeof(EdgeTableEntry) * Count)))) {
!(pETEs = stat...ry) * Count)))Description
TRUEnever evaluated
FALSEnever evaluated
0
3583 delete region;-
3584 return 0;
never executed: return 0;
0
3585 }-
3586-
3587 region->vectorize();-
3588-
3589 AET = new EdgeTableEntry;-
3590 pts = FirstPtBlock.pts;-
3591 CreateETandAET(Count, Pts, &ET, AET, pETEs, &SLLBlock);-
3592-
3593 pSLL = ET.scanlines.next;-
3594 curPtBlock = &FirstPtBlock;-
3595-
3596 // sanity check that the region won't become too big...-
3597 if (ET.ymax - ET.ymin > 100000) {
ET.ymax - ET.ymin > 100000Description
TRUEnever evaluated
FALSEnever evaluated
0
3598 // clean up region ptr-
3599#ifndef QT_NO_DEBUG-
3600 qWarning("QRegion: creating region from big polygon failed...!");-
3601#endif-
3602 delete AET;-
3603 delete region;-
3604 return 0;
never executed: return 0;
0
3605 }-
3606-
3607-
3608 QT_TRY {-
3609 if (rule == EvenOddRule) {
rule == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3610 /*-
3611 * for each scanline-
3612 */-
3613 for (y = ET.ymin; y < ET.ymax; ++y) {
y < ET.ymaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3614-
3615 /*-
3616 * Add a new edge to the active edge table when we-
3617 * get to the next edge.-
3618 */-
3619 if (pSLL && y == pSLL->scanline) {
pSLLDescription
TRUEnever evaluated
FALSEnever evaluated
y == pSLL->scanlineDescription
TRUEnever evaluated
FALSEnever evaluated
0
3620 loadAET(AET, pSLL->edgelist);-
3621 pSLL = pSLL->next;-
3622 }
never executed: end of block
0
3623 pPrevAET = AET;-
3624 pAET = AET->next;-
3625-
3626 /*-
3627 * for each active edge-
3628 */-
3629 while (pAET) {
pAETDescription
TRUEnever evaluated
FALSEnever evaluated
0
3630 pts->setX(pAET->bres.minor_axis);-
3631 pts->setY(y);-
3632 ++pts;-
3633 ++iPts;-
3634-
3635 /*-
3636 * send out the buffer-
3637 */-
3638 if (iPts == NUMPTSTOBUFFER) {
iPts == 200Description
TRUEnever evaluated
FALSEnever evaluated
0
3639 tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK));-
3640 Q_CHECK_PTR(tmpPtBlock);
never executed: qt_check_pointer(__FILE__,3640);
!(tmpPtBlock)Description
TRUEnever evaluated
FALSEnever evaluated
0
3641 tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data);-
3642 curPtBlock->next = tmpPtBlock;-
3643 curPtBlock = tmpPtBlock;-
3644 pts = curPtBlock->pts;-
3645 ++numFullPtBlocks;-
3646 iPts = 0;-
3647 }
never executed: end of block
0
3648 EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
never executed: pAET->back = pPrevAET;
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
pAETDescription
TRUEnever evaluated
FALSEnever evaluated
pAET->ymax == yDescription
TRUEnever evaluated
FALSEnever evaluated
pAET->bres.m1 > 0Description
TRUEnever evaluated
FALSEnever evaluated
pAET->bres.d > 0Description
TRUEnever evaluated
FALSEnever evaluated
pAET->bres.d >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3649 }-
3650 InsertionSort(AET);-
3651 }
never executed: end of block
0
3652 } else {
never executed: end of block
0
3653 /*-
3654 * for each scanline-
3655 */-
3656 for (y = ET.ymin; y < ET.ymax; ++y) {
y < ET.ymaxDescription
TRUEnever evaluated
FALSEnever evaluated
0
3657 /*-
3658 * Add a new edge to the active edge table when we-
3659 * get to the next edge.-
3660 */-
3661 if (pSLL && y == pSLL->scanline) {
pSLLDescription
TRUEnever evaluated
FALSEnever evaluated
y == pSLL->scanlineDescription
TRUEnever evaluated
FALSEnever evaluated
0
3662 loadAET(AET, pSLL->edgelist);-
3663 computeWAET(AET);-
3664 pSLL = pSLL->next;-
3665 }
never executed: end of block
0
3666 pPrevAET = AET;-
3667 pAET = AET->next;-
3668 pWETE = pAET;-
3669-
3670 /*-
3671 * for each active edge-
3672 */-
3673 while (pAET) {
pAETDescription
TRUEnever evaluated
FALSEnever evaluated
0
3674 /*-
3675 * add to the buffer only those edges that-
3676 * are in the Winding active edge table.-
3677 */-
3678 if (pWETE == pAET) {
pWETE == pAETDescription
TRUEnever evaluated
FALSEnever evaluated
0
3679 pts->setX(pAET->bres.minor_axis);-
3680 pts->setY(y);-
3681 ++pts;-
3682 ++iPts;-
3683-
3684 /*-
3685 * send out the buffer-
3686 */-
3687 if (iPts == NUMPTSTOBUFFER) {
iPts == 200Description
TRUEnever evaluated
FALSEnever evaluated
0
3688 tmpPtBlock = static_cast<POINTBLOCK *>(malloc(sizeof(POINTBLOCK)));-
3689 tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data);-
3690 curPtBlock->next = tmpPtBlock;-
3691 curPtBlock = tmpPtBlock;-
3692 pts = curPtBlock->pts;-
3693 ++numFullPtBlocks;-
3694 iPts = 0;-
3695 }
never executed: end of block
0
3696 pWETE = pWETE->nextWETE;-
3697 }
never executed: end of block
0
3698 EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
never executed: pAET->back = pPrevAET;
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
never executed: end of block
pAETDescription
TRUEnever evaluated
FALSEnever evaluated
pAET->ymax == yDescription
TRUEnever evaluated
FALSEnever evaluated
pAET->bres.m1 > 0Description
TRUEnever evaluated
FALSEnever evaluated
pAET->bres.d > 0Description
TRUEnever evaluated
FALSEnever evaluated
pAET->bres.d >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3699 }-
3700-
3701 /*-
3702 * recompute the winding active edge table if-
3703 * we just resorted or have exited an edge.-
3704 */-
3705 if (InsertionSort(AET) || fixWAET) {
InsertionSort(AET)Description
TRUEnever evaluated
FALSEnever evaluated
fixWAETDescription
TRUEnever evaluated
FALSEnever evaluated
0
3706 computeWAET(AET);-
3707 fixWAET = false;-
3708 }
never executed: end of block
0
3709 }
never executed: end of block
0
3710 }
never executed: end of block
0
3711 } QT_CATCH(...) {
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3712 FreeStorage(SLLBlock.next);
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3713 PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3714 for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3715 tmpPtBlock = curPtBlock->next;
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3716 free(curPtBlock);
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3717 curPtBlock = tmpPtBlock;
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3718 }
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3719 free(pETEs);
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3720 return 0; // this function returns 0 in case of an error
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3721 }
dead code: { FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { tmpPtBlock = curPtBlock->next; free(curPtBlock); curPtBlock = tmpPtBlock; } free(pETEs); return 0; }
-
3722-
3723 FreeStorage(SLLBlock.next);-
3724 PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);-
3725 for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
--numFullPtBlocks >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3726 tmpPtBlock = curPtBlock->next;-
3727 free(curPtBlock);-
3728 curPtBlock = tmpPtBlock;-
3729 }
never executed: end of block
0
3730 delete AET;-
3731 free(pETEs);-
3732 return region;
never executed: return region;
0
3733}-
3734// END OF PolyReg.c extract-
3735-
3736QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap)-
3737{-
3738 const QImage image = bitmap.toImage();-
3739-
3740 QRegionPrivate *region = new QRegionPrivate;-
3741-
3742 QRect xr;-
3743-
3744#define AddSpan \-
3745 { \-
3746 xr.setCoords(prev1, y, x-1, y); \-
3747 UnionRectWithRegion(&xr, region, *region); \-
3748 }-
3749-
3750 const uchar zero = 0;-
3751 bool little = image.format() == QImage::Format_MonoLSB;-
3752-
3753 int x,-
3754 y;-
3755 for (y = 0; y < image.height(); ++y) {
y < image.height()Description
TRUEnever evaluated
FALSEnever evaluated
0
3756 const uchar *line = image.constScanLine(y);-
3757 int w = image.width();-
3758 uchar all = zero;-
3759 int prev1 = -1;-
3760 for (x = 0; x < w;) {
x < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
3761 uchar byte = line[x / 8];-
3762 if (x > w - 8 || byte!=all) {
x > w - 8Description
TRUEnever evaluated
FALSEnever evaluated
byte!=allDescription
TRUEnever evaluated
FALSEnever evaluated
0
3763 if (little) {
littleDescription
TRUEnever evaluated
FALSEnever evaluated
0
3764 for (int b = 8; b > 0 && x < w; --b) {
b > 0Description
TRUEnever evaluated
FALSEnever evaluated
x < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
3765 if (!(byte & 0x01) == !all) {
!(byte & 0x01) == !allDescription
TRUEnever evaluated
FALSEnever evaluated
0
3766 // More of the same-
3767 } else {
never executed: end of block
0
3768 // A change.-
3769 if (all!=zero) {
all!=zeroDescription
TRUEnever evaluated
FALSEnever evaluated
0
3770 AddSpan-
3771 all = zero;-
3772 } else {
never executed: end of block
0
3773 prev1 = x;-
3774 all = ~zero;-
3775 }
never executed: end of block
0
3776 }-
3777 byte >>= 1;-
3778 ++x;-
3779 }
never executed: end of block
0
3780 } else {
never executed: end of block
0
3781 for (int b = 8; b > 0 && x < w; --b) {
b > 0Description
TRUEnever evaluated
FALSEnever evaluated
x < wDescription
TRUEnever evaluated
FALSEnever evaluated
0
3782 if (!(byte & 0x80) == !all) {
!(byte & 0x80) == !allDescription
TRUEnever evaluated
FALSEnever evaluated
0
3783 // More of the same-
3784 } else {
never executed: end of block
0
3785 // A change.-
3786 if (all != zero) {
all != zeroDescription
TRUEnever evaluated
FALSEnever evaluated
0
3787 AddSpan-
3788 all = zero;-
3789 } else {
never executed: end of block
0
3790 prev1 = x;-
3791 all = ~zero;-
3792 }
never executed: end of block
0
3793 }-
3794 byte <<= 1;-
3795 ++x;-
3796 }
never executed: end of block
0
3797 }
never executed: end of block
0
3798 } else {-
3799 x += 8;-
3800 }
never executed: end of block
0
3801 }-
3802 if (all != zero) {
all != zeroDescription
TRUEnever evaluated
FALSEnever evaluated
0
3803 AddSpan-
3804 }
never executed: end of block
0
3805 }
never executed: end of block
0
3806#undef AddSpan-
3807-
3808 return region;
never executed: return region;
0
3809}-
3810-
3811QRegion::QRegion()-
3812 : d(const_cast<QRegionData*>(&shared_empty))-
3813{-
3814}
never executed: end of block
0
3815-
3816QRegion::QRegion(const QRect &r, RegionType t)-
3817{-
3818 if (r.isEmpty()) {
r.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
3819 d = const_cast<QRegionData*>(&shared_empty);-
3820 } else {
never executed: end of block
0
3821 d = new QRegionData;-
3822 d->ref.initializeOwned();-
3823 if (t == Rectangle) {
t == RectangleDescription
TRUEnever evaluated
FALSEnever evaluated
0
3824 d->qt_rgn = new QRegionPrivate(r);-
3825 } else if (t == Ellipse) {
never executed: end of block
t == EllipseDescription
TRUEnever evaluated
FALSEnever evaluated
0
3826 QPainterPath path;-
3827 path.addEllipse(r.x(), r.y(), r.width(), r.height());-
3828 QPolygon a = path.toSubpathPolygons().at(0).toPolygon();-
3829 d->qt_rgn = PolygonRegion(a.constData(), a.size(), EvenOddRule);-
3830 }
never executed: end of block
0
3831 }
never executed: end of block
0
3832}-
3833-
3834QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule)-
3835{-
3836 if (a.count() > 2) {
a.count() > 2Description
TRUEnever evaluated
FALSEnever evaluated
0
3837 QRegionPrivate *qt_rgn = PolygonRegion(a.constData(), a.size(),-
3838 fillRule == Qt::WindingFill ? WindingRule : EvenOddRule);-
3839 if (qt_rgn) {
qt_rgnDescription
TRUEnever evaluated
FALSEnever evaluated
0
3840 d = new QRegionData;-
3841 d->ref.initializeOwned();-
3842 d->qt_rgn = qt_rgn;-
3843 } else {
never executed: end of block
0
3844 d = const_cast<QRegionData*>(&shared_empty);-
3845 }
never executed: end of block
0
3846 } else {-
3847 d = const_cast<QRegionData*>(&shared_empty);-
3848 }
never executed: end of block
0
3849}-
3850-
3851QRegion::QRegion(const QRegion &r)-
3852{-
3853 d = r.d;-
3854 d->ref.ref();-
3855}
never executed: end of block
0
3856-
3857-
3858QRegion::QRegion(const QBitmap &bm)-
3859{-
3860 if (bm.isNull()) {
bm.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
3861 d = const_cast<QRegionData*>(&shared_empty);-
3862 } else {
never executed: end of block
0
3863 d = new QRegionData;-
3864 d->ref.initializeOwned();-
3865 d->qt_rgn = qt_bitmapToRegion(bm);-
3866 }
never executed: end of block
0
3867}-
3868-
3869void QRegion::cleanUp(QRegion::QRegionData *x)-
3870{-
3871 delete x->qt_rgn;-
3872 delete x;-
3873}
never executed: end of block
0
3874-
3875QRegion::~QRegion()-
3876{-
3877 if (!d->ref.deref())
!d->ref.deref()Description
TRUEnever evaluated
FALSEnever evaluated
0
3878 cleanUp(d);
never executed: cleanUp(d);
0
3879}
never executed: end of block
0
3880-
3881-
3882QRegion &QRegion::operator=(const QRegion &r)-
3883{-
3884 r.d->ref.ref();-
3885 if (!d->ref.deref())
!d->ref.deref()Description
TRUEnever evaluated
FALSEnever evaluated
0
3886 cleanUp(d);
never executed: cleanUp(d);
0
3887 d = r.d;-
3888 return *this;
never executed: return *this;
0
3889}-
3890-
3891-
3892/*!-
3893 \internal-
3894*/-
3895QRegion QRegion::copy() const-
3896{-
3897 QRegion r;-
3898 QScopedPointer<QRegionData> x(new QRegionData);-
3899 x->ref.initializeOwned();-
3900 if (d->qt_rgn)
d->qt_rgnDescription
TRUEnever evaluated
FALSEnever evaluated
0
3901 x->qt_rgn = new QRegionPrivate(*d->qt_rgn);
never executed: x->qt_rgn = new QRegionPrivate(*d->qt_rgn);
0
3902 else-
3903 x->qt_rgn = new QRegionPrivate;
never executed: x->qt_rgn = new QRegionPrivate;
0
3904 if (!r.d->ref.deref())
!r.d->ref.deref()Description
TRUEnever evaluated
FALSEnever evaluated
0
3905 cleanUp(r.d);
never executed: cleanUp(r.d);
0
3906 r.d = x.take();-
3907 return r;
never executed: return r;
0
3908}-
3909-
3910bool QRegion::isEmpty() const-
3911{-
3912 return d == &shared_empty || d->qt_rgn->numRects == 0;
never executed: return d == &shared_empty || d->qt_rgn->numRects == 0;
d == &shared_emptyDescription
TRUEnever evaluated
FALSEnever evaluated
d->qt_rgn->numRects == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3913}-
3914-
3915bool QRegion::isNull() const-
3916{-
3917 return d == &shared_empty || d->qt_rgn->numRects == 0;
never executed: return d == &shared_empty || d->qt_rgn->numRects == 0;
d == &shared_emptyDescription
TRUEnever evaluated
FALSEnever evaluated
d->qt_rgn->numRects == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
3918}-
3919-
3920bool QRegion::contains(const QPoint &p) const-
3921{-
3922 return PointInRegion(d->qt_rgn, p.x(), p.y());
never executed: return PointInRegion(d->qt_rgn, p.x(), p.y());
0
3923}-
3924-
3925bool QRegion::contains(const QRect &r) const-
3926{-
3927 return RectInRegion(d->qt_rgn, r.left(), r.top(), r.width(), r.height()) != RectangleOut;
never executed: return RectInRegion(d->qt_rgn, r.left(), r.top(), r.width(), r.height()) != 0;
0
3928}-
3929-
3930-
3931-
3932void QRegion::translate(int dx, int dy)-
3933{-
3934 if ((dx == 0 && dy == 0) || isEmptyHelper(d->qt_rgn))
dx == 0Description
TRUEnever evaluated
FALSEnever evaluated
dy == 0Description
TRUEnever evaluated
FALSEnever evaluated
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3935 return;
never executed: return;
0
3936-
3937 detach();-
3938 OffsetRegion(*d->qt_rgn, dx, dy);-
3939}
never executed: end of block
0
3940-
3941QRegion QRegion::united(const QRegion &r) const-
3942{-
3943 if (isEmptyHelper(d->qt_rgn))
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3944 return r;
never executed: return r;
0
3945 if (isEmptyHelper(r.d->qt_rgn))
isEmptyHelper(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3946 return *this;
never executed: return *this;
0
3947 if (d == r.d)
d == r.dDescription
TRUEnever evaluated
FALSEnever evaluated
0
3948 return *this;
never executed: return *this;
0
3949-
3950 if (d->qt_rgn->contains(*r.d->qt_rgn)) {
d->qt_rgn->con...(*r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3951 return *this;
never executed: return *this;
0
3952 } else if (r.d->qt_rgn->contains(*d->qt_rgn)) {
r.d->qt_rgn->c...ns(*d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3953 return r;
never executed: return r;
0
3954 } else if (d->qt_rgn->canAppend(r.d->qt_rgn)) {
d->qt_rgn->can...d(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3955 QRegion result(*this);-
3956 result.detach();-
3957 result.d->qt_rgn->append(r.d->qt_rgn);-
3958 return result;
never executed: return result;
0
3959 } else if (d->qt_rgn->canPrepend(r.d->qt_rgn)) {
d->qt_rgn->can...d(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3960 QRegion result(*this);-
3961 result.detach();-
3962 result.d->qt_rgn->prepend(r.d->qt_rgn);-
3963 return result;
never executed: return result;
0
3964 } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) {
EqualRegion(d-..., r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3965 return *this;
never executed: return *this;
0
3966 } else {-
3967 QRegion result;-
3968 result.detach();-
3969 UnionRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);-
3970 return result;
never executed: return result;
0
3971 }-
3972}-
3973-
3974QRegion& QRegion::operator+=(const QRegion &r)-
3975{-
3976 if (isEmptyHelper(d->qt_rgn))
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3977 return *this = r;
never executed: return *this = r;
0
3978 if (isEmptyHelper(r.d->qt_rgn))
isEmptyHelper(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3979 return *this;
never executed: return *this;
0
3980 if (d == r.d)
d == r.dDescription
TRUEnever evaluated
FALSEnever evaluated
0
3981 return *this;
never executed: return *this;
0
3982-
3983 if (d->qt_rgn->contains(*r.d->qt_rgn)) {
d->qt_rgn->con...(*r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3984 return *this;
never executed: return *this;
0
3985 } else if (r.d->qt_rgn->contains(*d->qt_rgn)) {
r.d->qt_rgn->c...ns(*d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3986 return *this = r;
never executed: return *this = r;
0
3987 } else if (d->qt_rgn->canAppend(r.d->qt_rgn)) {
d->qt_rgn->can...d(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3988 detach();-
3989 d->qt_rgn->append(r.d->qt_rgn);-
3990 return *this;
never executed: return *this;
0
3991 } else if (d->qt_rgn->canPrepend(r.d->qt_rgn)) {
d->qt_rgn->can...d(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3992 detach();-
3993 d->qt_rgn->prepend(r.d->qt_rgn);-
3994 return *this;
never executed: return *this;
0
3995 } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) {
EqualRegion(d-..., r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
3996 return *this;
never executed: return *this;
0
3997 } else {-
3998 detach();-
3999 UnionRegion(d->qt_rgn, r.d->qt_rgn, *d->qt_rgn);-
4000 return *this;
never executed: return *this;
0
4001 }-
4002}-
4003-
4004QRegion QRegion::united(const QRect &r) const-
4005{-
4006 if (isEmptyHelper(d->qt_rgn))
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4007 return r;
never executed: return r;
0
4008 if (r.isEmpty())
r.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
4009 return *this;
never executed: return *this;
0
4010-
4011 if (d->qt_rgn->contains(r)) {
d->qt_rgn->contains(r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4012 return *this;
never executed: return *this;
0
4013 } else if (d->qt_rgn->within(r)) {
d->qt_rgn->within(r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4014 return r;
never executed: return r;
0
4015 } else if (d->qt_rgn->numRects == 1 && d->qt_rgn->extents == r) {
d->qt_rgn->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
d->qt_rgn->extents == rDescription
TRUEnever evaluated
FALSEnever evaluated
0
4016 return *this;
never executed: return *this;
0
4017 } else if (d->qt_rgn->canAppend(&r)) {
d->qt_rgn->canAppend(&r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4018 QRegion result(*this);-
4019 result.detach();-
4020 result.d->qt_rgn->append(&r);-
4021 return result;
never executed: return result;
0
4022 } else if (d->qt_rgn->canPrepend(&r)) {
d->qt_rgn->canPrepend(&r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4023 QRegion result(*this);-
4024 result.detach();-
4025 result.d->qt_rgn->prepend(&r);-
4026 return result;
never executed: return result;
0
4027 } else {-
4028 QRegion result;-
4029 result.detach();-
4030 QRegionPrivate rp(r);-
4031 UnionRegion(d->qt_rgn, &rp, *result.d->qt_rgn);-
4032 return result;
never executed: return result;
0
4033 }-
4034}-
4035-
4036QRegion& QRegion::operator+=(const QRect &r)-
4037{-
4038 if (isEmptyHelper(d->qt_rgn))
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4039 return *this = r;
never executed: return *this = r;
0
4040 if (r.isEmpty())
r.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
4041 return *this;
never executed: return *this;
0
4042-
4043 if (d->qt_rgn->contains(r)) {
d->qt_rgn->contains(r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4044 return *this;
never executed: return *this;
0
4045 } else if (d->qt_rgn->within(r)) {
d->qt_rgn->within(r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4046 return *this = r;
never executed: return *this = r;
0
4047 } else if (d->qt_rgn->canAppend(&r)) {
d->qt_rgn->canAppend(&r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4048 detach();-
4049 d->qt_rgn->append(&r);-
4050 return *this;
never executed: return *this;
0
4051 } else if (d->qt_rgn->canPrepend(&r)) {
d->qt_rgn->canPrepend(&r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4052 detach();-
4053 d->qt_rgn->prepend(&r);-
4054 return *this;
never executed: return *this;
0
4055 } else if (d->qt_rgn->numRects == 1 && d->qt_rgn->extents == r) {
d->qt_rgn->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
d->qt_rgn->extents == rDescription
TRUEnever evaluated
FALSEnever evaluated
0
4056 return *this;
never executed: return *this;
0
4057 } else {-
4058 detach();-
4059 QRegionPrivate p(r);-
4060 UnionRegion(d->qt_rgn, &p, *d->qt_rgn);-
4061 return *this;
never executed: return *this;
0
4062 }-
4063}-
4064-
4065QRegion QRegion::intersected(const QRegion &r) const-
4066{-
4067 if (isEmptyHelper(d->qt_rgn) || isEmptyHelper(r.d->qt_rgn)
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
isEmptyHelper(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4068 || !EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents))
(&d->qt_rgn->e...tents)->left()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...ents)->right()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...xtents)->top()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...nts)->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
4069 return QRegion();
never executed: return QRegion();
0
4070-
4071 /* this is fully contained in r */-
4072 if (r.d->qt_rgn->contains(*d->qt_rgn))
r.d->qt_rgn->c...ns(*d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4073 return *this;
never executed: return *this;
0
4074-
4075 /* r is fully contained in this */-
4076 if (d->qt_rgn->contains(*r.d->qt_rgn))
d->qt_rgn->con...(*r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4077 return r;
never executed: return r;
0
4078-
4079 if (r.d->qt_rgn->numRects == 1 && d->qt_rgn->numRects == 1) {
r.d->qt_rgn->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
d->qt_rgn->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4080 const QRect rect = qt_rect_intersect_normalized(r.d->qt_rgn->extents,-
4081 d->qt_rgn->extents);-
4082 return QRegion(rect);
never executed: return QRegion(rect);
0
4083 } else if (r.d->qt_rgn->numRects == 1) {
r.d->qt_rgn->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4084 QRegion result(*this);-
4085 result.detach();-
4086 result.d->qt_rgn->intersect(r.d->qt_rgn->extents);-
4087 return result;
never executed: return result;
0
4088 } else if (d->qt_rgn->numRects == 1) {
d->qt_rgn->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4089 QRegion result(r);-
4090 result.detach();-
4091 result.d->qt_rgn->intersect(d->qt_rgn->extents);-
4092 return result;
never executed: return result;
0
4093 }-
4094-
4095 QRegion result;-
4096 result.detach();-
4097 miRegionOp(*result.d->qt_rgn, d->qt_rgn, r.d->qt_rgn, miIntersectO, 0, 0);-
4098-
4099 /*-
4100 * Can't alter dest's extents before we call miRegionOp because-
4101 * it might be one of the source regions and miRegionOp depends-
4102 * on the extents of those regions being the same. Besides, this-
4103 * way there's no checking against rectangles that will be nuked-
4104 * due to coalescing, so we have to examine fewer rectangles.-
4105 */-
4106 miSetExtents(*result.d->qt_rgn);-
4107 return result;
never executed: return result;
0
4108}-
4109-
4110QRegion QRegion::intersected(const QRect &r) const-
4111{-
4112 if (isEmptyHelper(d->qt_rgn) || r.isEmpty()
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
r.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
4113 || !EXTENTCHECK(&d->qt_rgn->extents, &r))
(&d->qt_rgn->e...= (&r)->left()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e... (&r)->right()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...>= (&r)->top()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...(&r)->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
4114 return QRegion();
never executed: return QRegion();
0
4115-
4116 /* this is fully contained in r */-
4117 if (d->qt_rgn->within(r))
d->qt_rgn->within(r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4118 return *this;
never executed: return *this;
0
4119-
4120 /* r is fully contained in this */-
4121 if (d->qt_rgn->contains(r))
d->qt_rgn->contains(r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4122 return r;
never executed: return r;
0
4123-
4124 if (d->qt_rgn->numRects == 1) {
d->qt_rgn->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4125 const QRect rect = qt_rect_intersect_normalized(d->qt_rgn->extents,-
4126 r.normalized());-
4127 return QRegion(rect);
never executed: return QRegion(rect);
0
4128 }-
4129-
4130 QRegion result(*this);-
4131 result.detach();-
4132 result.d->qt_rgn->intersect(r);-
4133 return result;
never executed: return result;
0
4134}-
4135-
4136QRegion QRegion::subtracted(const QRegion &r) const-
4137{-
4138 if (isEmptyHelper(d->qt_rgn) || isEmptyHelper(r.d->qt_rgn))
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
isEmptyHelper(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4139 return *this;
never executed: return *this;
0
4140 if (r.d->qt_rgn->contains(*d->qt_rgn))
r.d->qt_rgn->c...ns(*d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4141 return QRegion();
never executed: return QRegion();
0
4142 if (!EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents))
(&d->qt_rgn->e...tents)->left()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...ents)->right()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...xtents)->top()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...nts)->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
4143 return *this;
never executed: return *this;
0
4144 if (d == r.d || EqualRegion(d->qt_rgn, r.d->qt_rgn))
d == r.dDescription
TRUEnever evaluated
FALSEnever evaluated
EqualRegion(d-..., r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4145 return QRegion();
never executed: return QRegion();
0
4146-
4147#ifdef QT_REGION_DEBUG-
4148 d->qt_rgn->selfTest();-
4149 r.d->qt_rgn->selfTest();-
4150#endif-
4151-
4152 QRegion result;-
4153 result.detach();-
4154 SubtractRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);-
4155#ifdef QT_REGION_DEBUG-
4156 result.d->qt_rgn->selfTest();-
4157#endif-
4158 return result;
never executed: return result;
0
4159}-
4160-
4161QRegion QRegion::xored(const QRegion &r) const-
4162{-
4163 if (isEmptyHelper(d->qt_rgn)) {
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4164 return r;
never executed: return r;
0
4165 } else if (isEmptyHelper(r.d->qt_rgn)) {
isEmptyHelper(r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4166 return *this;
never executed: return *this;
0
4167 } else if (!EXTENTCHECK(&d->qt_rgn->extents, &r.d->qt_rgn->extents)) {
(&d->qt_rgn->e...tents)->left()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...ents)->right()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...xtents)->top()Description
TRUEnever evaluated
FALSEnever evaluated
(&d->qt_rgn->e...nts)->bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
4168 return (*this + r);
never executed: return (*this + r);
0
4169 } else if (d == r.d || EqualRegion(d->qt_rgn, r.d->qt_rgn)) {
d == r.dDescription
TRUEnever evaluated
FALSEnever evaluated
EqualRegion(d-..., r.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
0
4170 return QRegion();
never executed: return QRegion();
0
4171 } else {-
4172 QRegion result;-
4173 result.detach();-
4174 XorRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);-
4175 return result;
never executed: return result;
0
4176 }-
4177}-
4178-
4179QRect QRegion::boundingRect() const-
4180{-
4181 if (isEmpty())
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
4182 return QRect();
never executed: return QRect();
0
4183 return d->qt_rgn->extents;
never executed: return d->qt_rgn->extents;
0
4184}-
4185-
4186/*! \internal-
4187 Returns \c true if \a rect is guaranteed to be fully contained in \a region.-
4188 A false return value does not guarantee the opposite.-
4189*/-
4190Q_GUI_EXPORT-
4191bool qt_region_strictContains(const QRegion &region, const QRect &rect)-
4192{-
4193 if (isEmptyHelper(region.d->qt_rgn) || !rect.isValid())
isEmptyHelper(...ion.d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
!rect.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
4194 return false;
never executed: return false;
0
4195-
4196#if 0 // TEST_INNERRECT-
4197 static bool guard = false;-
4198 if (guard)-
4199 return false;-
4200 guard = true;-
4201 QRegion inner = region.d->qt_rgn->innerRect;-
4202 Q_ASSERT((inner - region).isEmpty());-
4203 guard = false;-
4204-
4205 int maxArea = 0;-
4206 for (int i = 0; i < region.d->qt_rgn->numRects; ++i) {-
4207 const QRect r = region.d->qt_rgn->rects.at(i);-
4208 if (r.width() * r.height() > maxArea)-
4209 maxArea = r.width() * r.height();-
4210 }-
4211-
4212 if (maxArea > region.d->qt_rgn->innerArea) {-
4213 qDebug() << "not largest rectangle" << region << region.d->qt_rgn->innerRect;-
4214 }-
4215 Q_ASSERT(maxArea <= region.d->qt_rgn->innerArea);-
4216#endif-
4217-
4218 const QRect r1 = region.d->qt_rgn->innerRect;-
4219 return (rect.left() >= r1.left() && rect.right() <= r1.right()
never executed: return (rect.left() >= r1.left() && rect.right() <= r1.right() && rect.top() >= r1.top() && rect.bottom() <= r1.bottom());
rect.left() >= r1.left()Description
TRUEnever evaluated
FALSEnever evaluated
rect.right() <= r1.right()Description
TRUEnever evaluated
FALSEnever evaluated
0
4220 && rect.top() >= r1.top() && rect.bottom() <= r1.bottom());
never executed: return (rect.left() >= r1.left() && rect.right() <= r1.right() && rect.top() >= r1.top() && rect.bottom() <= r1.bottom());
rect.top() >= r1.top()Description
TRUEnever evaluated
FALSEnever evaluated
rect.bottom() <= r1.bottom()Description
TRUEnever evaluated
FALSEnever evaluated
0
4221}-
4222-
4223QVector<QRect> QRegion::rects() const-
4224{-
4225 if (d->qt_rgn) {
d->qt_rgnDescription
TRUEnever evaluated
FALSEnever evaluated
0
4226 d->qt_rgn->vectorize();-
4227 d->qt_rgn->rects.reserve(d->qt_rgn->numRects);-
4228 d->qt_rgn->rects.resize(d->qt_rgn->numRects);-
4229 return d->qt_rgn->rects;
never executed: return d->qt_rgn->rects;
0
4230 } else {-
4231 return QVector<QRect>();
never executed: return QVector<QRect>();
0
4232 }-
4233}-
4234-
4235void QRegion::setRects(const QRect *rects, int num)-
4236{-
4237 *this = QRegion();-
4238 if (!rects || num == 0 || (num == 1 && rects->isEmpty()))
!rectsDescription
TRUEnever evaluated
FALSEnever evaluated
num == 0Description
TRUEnever evaluated
FALSEnever evaluated
num == 1Description
TRUEnever evaluated
FALSEnever evaluated
rects->isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
4239 return;
never executed: return;
0
4240-
4241 detach();-
4242-
4243 d->qt_rgn->numRects = num;-
4244 if (num == 1) {
num == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4245 d->qt_rgn->extents = *rects;-
4246 d->qt_rgn->innerRect = *rects;-
4247 } else {
never executed: end of block
0
4248 d->qt_rgn->rects.resize(num);-
4249-
4250 int left = INT_MAX,-
4251 right = INT_MIN,-
4252 top = INT_MAX,-
4253 bottom = INT_MIN;-
4254 for (int i = 0; i < num; ++i) {
i < numDescription
TRUEnever evaluated
FALSEnever evaluated
0
4255 const QRect &rect = rects[i];-
4256 d->qt_rgn->rects[i] = rect;-
4257 left = qMin(rect.left(), left);-
4258 right = qMax(rect.right(), right);-
4259 top = qMin(rect.top(), top);-
4260 bottom = qMax(rect.bottom(), bottom);-
4261 d->qt_rgn->updateInnerRect(rect);-
4262 }
never executed: end of block
0
4263 d->qt_rgn->extents = QRect(QPoint(left, top), QPoint(right, bottom));-
4264 }
never executed: end of block
0
4265}-
4266-
4267int QRegion::rectCount() const-
4268{-
4269 return (d->qt_rgn ? d->qt_rgn->numRects : 0);
never executed: return (d->qt_rgn ? d->qt_rgn->numRects : 0);
d->qt_rgnDescription
TRUEnever evaluated
FALSEnever evaluated
0
4270}-
4271-
4272-
4273bool QRegion::operator==(const QRegion &r) const-
4274{-
4275 if (!d->qt_rgn)
!d->qt_rgnDescription
TRUEnever evaluated
FALSEnever evaluated
0
4276 return r.isEmpty();
never executed: return r.isEmpty();
0
4277 if (!r.d->qt_rgn)
!r.d->qt_rgnDescription
TRUEnever evaluated
FALSEnever evaluated
0
4278 return isEmpty();
never executed: return isEmpty();
0
4279-
4280 if (d == r.d)
d == r.dDescription
TRUEnever evaluated
FALSEnever evaluated
0
4281 return true;
never executed: return true;
0
4282 else-
4283 return EqualRegion(d->qt_rgn, r.d->qt_rgn);
never executed: return EqualRegion(d->qt_rgn, r.d->qt_rgn);
0
4284}-
4285-
4286bool QRegion::intersects(const QRect &rect) const-
4287{-
4288 if (isEmptyHelper(d->qt_rgn) || rect.isNull())
isEmptyHelper(d->qt_rgn)Description
TRUEnever evaluated
FALSEnever evaluated
rect.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
4289 return false;
never executed: return false;
0
4290-
4291 const QRect r = rect.normalized();-
4292 if (!rect_intersects(d->qt_rgn->extents, r))
!rect_intersec...n->extents, r)Description
TRUEnever evaluated
FALSEnever evaluated
0
4293 return false;
never executed: return false;
0
4294 if (d->qt_rgn->numRects == 1)
d->qt_rgn->numRects == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
4295 return true;
never executed: return true;
0
4296-
4297 const QVector<QRect> myRects = rects();-
4298 for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it)
it < myRects.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
4299 if (rect_intersects(r, *it))
rect_intersects(r, *it)Description
TRUEnever evaluated
FALSEnever evaluated
0
4300 return true;
never executed: return true;
0
4301 return false;
never executed: return false;
0
4302}-
4303-
4304-
4305#endif-
4306QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9