qregion.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qregion.cpp
Switch to Source codePreprocessed file
LineSourceCount
1-
2-
3-
4QRegion::QRegion(int x, int y, int w, int h, RegionType t)-
5{-
6 QRegion tmp(QRect(x, y, w, h), t);-
7 tmp.d->ref.ref();-
8 d = tmp.d;-
9}-
10void QRegion::detach()-
11{-
12 if (d->ref.isShared())-
13 *this = copy();-
14}-
15void QRegion::exec(const QByteArray &buffer, int ver, QDataStream::ByteOrder byteOrder)-
16{-
17 QByteArray copy = buffer;-
18 QDataStream s(&copy, QIODevice::ReadOnly);-
19 if (ver)-
20 s.setVersion(ver);-
21 s.setByteOrder(byteOrder);-
22 QRegion rgn;-
23-
24 int test_cnt = 0;-
25-
26 while (!s.atEnd()) {-
27 qint32 id;-
28 if (s.version() == 1) {-
29 int id_int;-
30 s >> id_int;-
31 id = id_int;-
32 } else {-
33 s >> id;-
34 }-
35-
36 if (test_cnt > 0 && id != 5)-
37 QMessageLogger(__FILE__, 293309, __PRETTY_FUNCTION__).warning("QRegion::exec: Internal error");-
38 test_cnt++;-
39-
40 if (id == 1 || id == 2) {-
41 QRect r;-
42 s >> r;-
43 rgn = QRegion(r, id == 1 ? Rectangle : Ellipse);-
44 } else if (id == 3 || id == 4) {-
45 QPolygon a;-
46 s >> a;-
47 rgn = QRegion(a, id == 4 ? Qt::WindingFill : Qt::OddEvenFill);-
48 } else if (id == 5) {-
49 QPoint p;-
50 s >> p;-
51 rgn.translate(p.x(), p.y());-
52 } else if (id >= 6 && id <= 9) {-
53 QByteArray bop1, bop2;-
54 QRegion r1, r2;-
55 s >> bop1;-
56 r1.exec(bop1);-
57 s >> bop2;-
58 r2.exec(bop2);-
59-
60 switch (id) {-
61 case 6:-
62 rgn = r1.united(r2);-
63 break;-
64 case 7:-
65 rgn = r1.intersected(r2);-
66 break;-
67 case 8:-
68 rgn = r1.subtracted(r2);-
69 break;-
70 case 9:-
71 rgn = r1.xored(r2);-
72 break;-
73 }-
74 } else if (id == 10) {-
75-
76 quint32 n;-
77 s >> n;-
78 QRect r;-
79 for (int i=0; i<(int)n; i++) {-
80 s >> r;-
81 rgn = rgn.united(QRegion(r));-
82 }-
83 }-
84 }-
85 *this = rgn;-
86}-
87QDataStream &operator<<(QDataStream &s, const QRegion &r)-
88{-
89 QVector<QRect> a = r.rects();-
90 if (a.isEmpty()) {-
91 s << (quint32)0;-
92 } else {-
93 if (s.version() == 1) {-
94 int i;-
95 for (i = a.size() - 1; i > 0; --i) {-
96 s << (quint32)(12 + i * 24);-
97 s << (int)6;-
98 }-
99 for (i = 0; i < a.size(); ++i) {-
100 s << (quint32)(4+8) << (int)1 << a[i];-
101 }-
102 } else {-
103 s << (quint32)(4 + 4 + 16 * a.size());-
104 s << (qint32)10;-
105 s << a;-
106 }-
107 }-
108 return s;-
109}-
110QDataStream &operator>>(QDataStream &s, QRegion &r)-
111{-
112 QByteArray b;-
113 s >> b;-
114 r.exec(b, s.version(), s.byteOrder());-
115 return s;-
116}-
117-
118-
119-
120QDebug operator<<(QDebug s, const QRegion &r)-
121{-
122 QDebugStateSaver saver(s);-
123 s.nospace();-
124 s << "QRegion(";-
125 if (r.isNull()) {-
126 s << "null";-
127 } else if (r.isEmpty()) {-
128 s << "empty";-
129 } else {-
130 const QVector<QRect> rects = r.rects();-
131 const int count = rects.size();-
132 if (count > 1)-
133 s << "size=" << count << ", bounds=(";-
134 QtDebugUtils::formatQRect(s, r.boundingRect());-
135 if (count > 1) {-
136 s << ") - [";-
137 for (int i = 0; i < count; ++i) {-
138 if (i)-
139 s << ", ";-
140 s << '(';-
141 QtDebugUtils::formatQRect(s, rects.at(i));-
142 s << ')';-
143 }-
144 s << ']';-
145 }-
146 }-
147 s << ')';-
148 return s;-
149}-
150QRegion QRegion::operator|(const QRegion &r) const-
151 { return united(r); }-
152QRegion QRegion::operator+(const QRegion &r) const-
153 { return united(r); }-
154QRegion QRegion::operator+(const QRect &r) const-
155 { return united(r); }-
156QRegion QRegion::operator&(const QRegion &r) const-
157 { return intersected(r); }-
158QRegion QRegion::operator&(const QRect &r) const-
159{-
160 return intersected(r);-
161}-
162QRegion QRegion::operator-(const QRegion &r) const-
163 { return subtracted(r); }-
164QRegion QRegion::operator^(const QRegion &r) const-
165 { return xored(r); }-
166QRegion& QRegion::operator|=(const QRegion &r)-
167 { return *this = *this | r; }-
168QRegion& QRegion::operator&=(const QRegion &r)-
169 { return *this = *this & r; }-
170-
171-
172-
173-
174-
175-
176QRegion& QRegion::operator&=(const QRect &r)-
177{-
178 return *this = *this & r;-
179}-
180QRegion& QRegion::operator-=(const QRegion &r)-
181 { return *this = *this - r; }-
182QRegion& QRegion::operator^=(const QRegion &r)-
183 { return *this = *this ^ r; }-
184QRegion::operator QVariant() const-
185{-
186 return QVariant(QVariant::Region, this);-
187}-
188QRegion-
189QRegion::translated(int dx, int dy) const-
190{-
191 QRegion ret(*this);-
192 ret.translate(dx, dy);-
193 return ret;-
194}-
195-
196-
197inline bool rect_intersects(const QRect &r1, const QRect &r2)-
198{-
199 return (r1.right() >= r2.left() && r1.left() <= r2.right() &&-
200 r1.bottom() >= r2.top() && r1.top() <= r2.bottom());-
201}-
202-
203-
204-
205-
206-
207-
208-
209bool QRegion::intersects(const QRegion &region) const-
210{-
211 if (isEmpty() || region.isEmpty())-
212 return false;-
213-
214 if (!rect_intersects(boundingRect(), region.boundingRect()))-
215 return false;-
216 if (rectCount() == 1 && region.rectCount() == 1)-
217 return true;-
218-
219 const QVector<QRect> myRects = rects();-
220 const QVector<QRect> otherRects = region.rects();-
221-
222 for (QVector<QRect>::const_iterator i1 = myRects.constBegin(); i1 < myRects.constEnd(); ++i1)-
223 for (QVector<QRect>::const_iterator i2 = otherRects.constBegin(); i2 < otherRects.constEnd(); ++i2)-
224 if (rect_intersects(*i1, *i2))-
225 return true;-
226 return false;-
227}-
228namespace {-
229-
230struct Segment-
231{-
232 Segment() {}-
233 Segment(const QPoint &p)-
234 : added(false)-
235 , point(p)-
236 {-
237 }-
238-
239 int left() const-
240 {-
241 return qMin(point.x(), next->point.x());-
242 }-
243-
244 int right() const-
245 {-
246 return qMax(point.x(), next->point.x());-
247 }-
248-
249 bool overlaps(const Segment &other) const-
250 {-
251 return left() < other.right() && other.left() < right();-
252 }-
253-
254 void connect(Segment &other)-
255 {-
256 next = &other;-
257 other.prev = this;-
258-
259 horizontal = (point.y() == other.point.y());-
260 }-
261-
262 void merge(Segment &other)-
263 {-
264 if (right() <= other.right()) {-
265 QPoint p = other.point;-
266 Segment *oprev = other.prev;-
267-
268 other.point = point;-
269 other.prev = prev;-
270 prev->next = &other;-
271-
272 point = p;-
273 prev = oprev;-
274 oprev->next = this;-
275 } else {-
276 Segment *onext = other.next;-
277 other.next = next;-
278 next->prev = &other;-
279-
280 next = onext;-
281 next->prev = this;-
282 }-
283 }-
284-
285 int horizontal : 1;-
286 int added : 1;-
287-
288 QPoint point;-
289 Segment *prev;-
290 Segment *next;-
291};-
292-
293void mergeSegments(Segment *a, int na, Segment *b, int nb)-
294{-
295 int i = 0;-
296 int j = 0;-
297-
298 while (i != na && j != nb) {-
299 Segment &sa = a[i];-
300 Segment &sb = b[j];-
301 const int ra = sa.right();-
302 const int rb = sb.right();-
303 if (sa.overlaps(sb))-
304 sa.merge(sb);-
305 i += (rb >= ra);-
306 j += (ra >= rb);-
307 }-
308}-
309-
310void addSegmentsToPath(Segment *segment, QPainterPath &path)-
311{-
312 Segment *current = segment;-
313 path.moveTo(current->point);-
314-
315 current->added = true;-
316-
317 Segment *last = current;-
318 current = current->next;-
319 while (current != segment) {-
320 if (current->horizontal != last->horizontal)-
321 path.lineTo(current->point);-
322 current->added = true;-
323 last = current;-
324 current = current->next;-
325 }-
326}-
327-
328}-
329-
330-
331-
332-
333-
334-
335-
336template<> class QTypeInfo<Segment > { public: enum { isComplex = (((Q_PRIMITIVE_TYPE) & Q_PRIMITIVE_TYPE) == 0), isStatic = (((Q_PRIMITIVE_TYPE) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), isRelocatable = !isStatic || ((Q_PRIMITIVE_TYPE) & Q_RELOCATABLE_TYPE), isLarge = (sizeof(Segment)>sizeof(void*)), isPointer = false, isIntegral = QtPrivate::is_integral< Segment >::value, isDummy = (((Q_PRIMITIVE_TYPE) & Q_DUMMY_TYPE) != 0), sizeOf = sizeof(Segment) }; static inline const char *name() { return "Segment"; } };-
337-
338__attribute__((visibility("default"))) QPainterPath qt_regionToPath(const QRegion &region)-
339{-
340 QPainterPath result;-
341 if (region.rectCount() == 1) {-
342 result.addRect(region.boundingRect());-
343 return result;-
344 }-
345-
346 const QVector<QRect> rects = region.rects();-
347-
348 QVarLengthArray<Segment> segments;-
349 segments.resize(4 * rects.size());-
350-
351 const QRect *rect = rects.constData();-
352 const QRect *end = rect + rects.size();-
353-
354 int lastRowSegmentCount = 0;-
355 Segment *lastRowSegments = 0;-
356-
357 int lastSegment = 0;-
358 int lastY = 0;-
359 while (rect != end) {-
360 const int y = rect[0].y();-
361 int count = 0;-
362 while (&rect[count] != end && rect[count].y() == y)-
363 ++count;-
364-
365 for (int i = 0; i < count; ++i) {-
366 int offset = lastSegment + i;-
367 segments[offset] = Segment(rect[i].topLeft());-
368 segments[offset += count] = Segment(rect[i].topRight() + QPoint(1, 0));-
369 segments[offset += count] = Segment(rect[i].bottomRight() + QPoint(1, 1));-
370 segments[offset += count] = Segment(rect[i].bottomLeft() + QPoint(0, 1));-
371-
372 offset = lastSegment + i;-
373 for (int j = 0; j < 4; ++j)-
374 segments[offset + j * count].connect(segments[offset + ((j + 1) % 4) * count]);-
375 }-
376-
377 if (lastRowSegments && lastY == y)-
378 mergeSegments(lastRowSegments, lastRowSegmentCount, &segments[lastSegment], count);-
379-
380 lastRowSegments = &segments[lastSegment + 2 * count];-
381 lastRowSegmentCount = count;-
382 lastSegment += 4 * count;-
383 lastY = y + rect[0].height();-
384 rect += count;-
385 }-
386-
387 for (int i = 0; i < lastSegment; ++i) {-
388 Segment *segment = &segments[i];-
389 if (!segment->added)-
390 addSegmentsToPath(segment, result);-
391 }-
392-
393 return result;-
394}-
395struct QRegionPrivate {-
396 int numRects;-
397 int innerArea;-
398 QVector<QRect> rects;-
399 QRect extents;-
400 QRect innerRect;-
401-
402 inline QRegionPrivate() : numRects(0), innerArea(-1) {}-
403 inline QRegionPrivate(const QRect &r)-
404 : numRects(1),-
405 innerArea(r.width() * r.height()),-
406 extents(r),-
407 innerRect(r)-
408 {-
409 }-
410-
411 void intersect(const QRect &r);-
412-
413-
414-
415-
416-
417 inline bool contains(const QRegionPrivate &r) const {-
418 return contains(r.extents);-
419 }-
420-
421 inline bool contains(const QRect &r2) const {-
422 const QRect &r1 = innerRect;-
423 return r2.left() >= r1.left() && r2.right() <= r1.right()-
424 && r2.top() >= r1.top() && r2.bottom() <= r1.bottom();-
425 }-
426-
427-
428-
429-
430 inline bool within(const QRect &r1) const {-
431 const QRect &r2 = extents;-
432 return r2.left() >= r1.left() && r2.right() <= r1.right()-
433 && r2.top() >= r1.top() && r2.bottom() <= r1.bottom();-
434 }-
435-
436 inline void updateInnerRect(const QRect &rect) {-
437 const int area = rect.width() * rect.height();-
438 if (area > innerArea) {-
439 innerArea = area;-
440 innerRect = rect;-
441 }-
442 }-
443-
444 inline void vectorize() {-
445 if (numRects == 1) {-
446 if (!rects.size())-
447 rects.resize(1);-
448 rects[0] = extents;-
449 }-
450 }-
451-
452 inline void append(const QRect *r);-
453 void append(const QRegionPrivate *r);-
454 void prepend(const QRect *r);-
455 void prepend(const QRegionPrivate *r);-
456 inline bool canAppend(const QRect *r) const;-
457 inline bool canAppend(const QRegionPrivate *r) const;-
458 inline bool canPrepend(const QRect *r) const;-
459 inline bool canPrepend(const QRegionPrivate *r) const;-
460-
461 inline bool mergeFromRight(QRect *left, const QRect *right);-
462 inline bool mergeFromLeft(QRect *left, const QRect *right);-
463 inline bool mergeFromBelow(QRect *top, const QRect *bottom,-
464 const QRect *nextToTop,-
465 const QRect *nextToBottom);-
466 inline bool mergeFromAbove(QRect *bottom, const QRect *top,-
467 const QRect *nextToBottom,-
468 const QRect *nextToTop);-
469-
470-
471-
472-
473};-
474-
475static inline bool isEmptyHelper(const QRegionPrivate *preg)-
476{-
477 return !preg || preg->numRects == 0;-
478}-
479-
480static inline bool canMergeFromRight(const QRect *left, const QRect *right)-
481{-
482 return (right->top() == left->top()-
483 && right->bottom() == left->bottom()-
484 && right->left() <= (left->right() + 1));-
485}-
486-
487static inline bool canMergeFromLeft(const QRect *right, const QRect *left)-
488{-
489 return canMergeFromRight(left, right);-
490}-
491-
492bool QRegionPrivate::mergeFromRight(QRect *left, const QRect *right)-
493{-
494 if (canMergeFromRight(left, right)) {-
495 left->setRight(right->right());-
496 updateInnerRect(*left);-
497 return true;-
498 }-
499 return false;-
500}-
501-
502bool QRegionPrivate::mergeFromLeft(QRect *right, const QRect *left)-
503{-
504 if (canMergeFromLeft(right, left)) {-
505 right->setLeft(left->left());-
506 updateInnerRect(*right);-
507 return true;-
508 }-
509 return false;-
510}-
511-
512static inline bool canMergeFromBelow(const QRect *top, const QRect *bottom,-
513 const QRect *nextToTop,-
514 const QRect *nextToBottom)-
515{-
516 if (nextToTop && nextToTop->y() == top->y())-
517 return false;-
518 if (nextToBottom && nextToBottom->y() == bottom->y())-
519 return false;-
520-
521 return ((top->bottom() >= (bottom->top() - 1))-
522 && top->left() == bottom->left()-
523 && top->right() == bottom->right());-
524}-
525-
526bool QRegionPrivate::mergeFromBelow(QRect *top, const QRect *bottom,-
527 const QRect *nextToTop,-
528 const QRect *nextToBottom)-
529{-
530 if (canMergeFromBelow(top, bottom, nextToTop, nextToBottom)) {-
531 top->setBottom(bottom->bottom());-
532 updateInnerRect(*top);-
533 return true;-
534 }-
535 return false;-
536}-
537-
538bool QRegionPrivate::mergeFromAbove(QRect *bottom, const QRect *top,-
539 const QRect *nextToBottom,-
540 const QRect *nextToTop)-
541{-
542 if (canMergeFromBelow(top, bottom, nextToTop, nextToBottom)) {-
543 bottom->setTop(top->top());-
544 updateInnerRect(*bottom);-
545 return true;-
546 }-
547 return false;-
548}-
549-
550static inline QRect qt_rect_intersect_normalized(const QRect &r1,-
551 const QRect &r2)-
552{-
553 QRect r;-
554 r.setLeft(qMax(r1.left(), r2.left()));-
555 r.setRight(qMin(r1.right(), r2.right()));-
556 r.setTop(qMax(r1.top(), r2.top()));-
557 r.setBottom(qMin(r1.bottom(), r2.bottom()));-
558 return r;-
559}-
560-
561void QRegionPrivate::intersect(const QRect &rect)-
562{-
563 ((!(extents.intersects(rect))) ? qt_assert("extents.intersects(rect)",__FILE__,12691293) : qt_noop());-
564 ((!(numRects > 1)) ? qt_assert("numRects > 1",__FILE__,12701294) : qt_noop());-
565-
566-
567-
568-
569-
570 const QRect r = rect.normalized();-
571 extents = QRect();-
572 innerRect = QRect();-
573 innerArea = -1;-
574-
575 QRect *dest = rects.data();-
576 const QRect *src = dest;-
577 int n = numRects;-
578 numRects = 0;-
579 while (n--) {-
580 *dest = qt_rect_intersect_normalized(*src++, r);-
581 if (dest->isEmpty())-
582 continue;-
583-
584 if (numRects == 0) {-
585 extents = *dest;-
586 } else {-
587 extents.setLeft(qMin(extents.left(), dest->left()));-
588-
589-
590 extents.setRight(qMax(extents.right(), dest->right()));-
591 extents.setBottom(qMax(extents.bottom(), dest->bottom()));-
592-
593 const QRect *nextToLast = (numRects > 1 ? dest - 2 : 0);-
594-
595-
596 if (canMergeFromBelow(dest - 1, dest, nextToLast, 0)) {-
597 if (!n || src->y() != dest->y() || src->left() > r.right()) {-
598 QRect *prev = dest - 1;-
599 prev->setBottom(dest->bottom());-
600 updateInnerRect(*prev);-
601 continue;-
602 }-
603 }-
604 }-
605 updateInnerRect(*dest);-
606 ++dest;-
607 ++numRects;-
608 }-
609-
610-
611-
612}-
613-
614void QRegionPrivate::append(const QRect *r)-
615{-
616 ((!(!r->isEmpty())) ? qt_assert("!r->isEmpty()",__FILE__,13221346) : qt_noop());-
617-
618 QRect *myLast = (numRects == 1 ? &extents : rects.data() + (numRects - 1));-
619 if (mergeFromRight(myLast, r)) {-
620 if (numRects > 1) {-
621 const QRect *nextToTop = (numRects > 2 ? myLast - 2 : 0);-
622 if (mergeFromBelow(myLast - 1, myLast, nextToTop, 0))-
623 --numRects;-
624 }-
625 } else if (mergeFromBelow(myLast, r, (numRects > 1 ? myLast - 1 : 0), 0)) {-
626-
627 } else {-
628 vectorize();-
629 ++numRects;-
630 updateInnerRect(*r);-
631 if (rects.size() < numRects)-
632 rects.resize(numRects);-
633 rects[numRects - 1] = *r;-
634 }-
635 extents.setCoords(qMin(extents.left(), r->left()),-
636 qMin(extents.top(), r->top()),-
637 qMax(extents.right(), r->right()),-
638 qMax(extents.bottom(), r->bottom()));-
639-
640-
641-
642-
643}-
644-
645void QRegionPrivate::append(const QRegionPrivate *r)-
646{-
647 ((!(!isEmptyHelper(r))) ? qt_assert("!isEmptyHelper(r)",__FILE__,13531377) : qt_noop());-
648-
649 if (r->numRects == 1) {-
650 append(&r->extents);-
651 return;-
652 }-
653-
654 vectorize();-
655-
656 QRect *destRect = rects.data() + numRects;-
657 const QRect *srcRect = r->rects.constData();-
658 int numAppend = r->numRects;-
659-
660-
661 {-
662 const QRect *rFirst = srcRect;-
663 QRect *myLast = destRect - 1;-
664 const QRect *nextToLast = (numRects > 1 ? myLast - 1 : 0);-
665 if (mergeFromRight(myLast, rFirst)) {-
666 ++srcRect;-
667 --numAppend;-
668 const QRect *rNextToFirst = (numAppend > 1 ? rFirst + 2 : 0);-
669 if (mergeFromBelow(myLast, rFirst + 1, nextToLast, rNextToFirst)) {-
670 ++srcRect;-
671 --numAppend;-
672 }-
673 if (numRects > 1) {-
674 nextToLast = (numRects > 2 ? myLast - 2 : 0);-
675 rNextToFirst = (numAppend > 0 ? srcRect : 0);-
676 if (mergeFromBelow(myLast - 1, myLast, nextToLast, rNextToFirst)) {-
677 --destRect;-
678 --numRects;-
679 }-
680 }-
681 } else if (mergeFromBelow(myLast, rFirst, nextToLast, rFirst + 1)) {-
682 ++srcRect;-
683 --numAppend;-
684 }-
685 }-
686-
687-
688 if (numAppend > 0) {-
689 const int newNumRects = numRects + numAppend;-
690 if (newNumRects > rects.size()) {-
691 rects.resize(newNumRects);-
692 destRect = rects.data() + numRects;-
693 }-
694 memcpy(destRect, srcRect, numAppend * sizeof(QRect));-
695-
696 numRects = newNumRects;-
697 }-
698-
699-
700 if (innerArea < r->innerArea) {-
701 innerArea = r->innerArea;-
702 innerRect = r->innerRect;-
703 }-
704-
705-
706 destRect = &extents;-
707 srcRect = &r->extents;-
708 extents.setCoords(qMin(destRect->left(), srcRect->left()),-
709 qMin(destRect->top(), srcRect->top()),-
710 qMax(destRect->right(), srcRect->right()),-
711 qMax(destRect->bottom(), srcRect->bottom()));-
712-
713-
714-
715-
716}-
717-
718void QRegionPrivate::prepend(const QRegionPrivate *r)-
719{-
720 ((!(!isEmptyHelper(r))) ? qt_assert("!isEmptyHelper(r)",__FILE__,14261450) : qt_noop());-
721-
722 if (r->numRects == 1) {-
723 prepend(&r->extents);-
724 return;-
725 }-
726-
727 vectorize();-
728-
729 int numPrepend = r->numRects;-
730 int numSkip = 0;-
731-
732-
733 {-
734 QRect *myFirst = rects.data();-
735 const QRect *nextToFirst = (numRects > 1 ? myFirst + 1 : 0);-
736 const QRect *rLast = r->rects.constData() + r->numRects - 1;-
737 const QRect *rNextToLast = (r->numRects > 1 ? rLast - 1 : 0);-
738 if (mergeFromLeft(myFirst, rLast)) {-
739 --numPrepend;-
740 --rLast;-
741 rNextToLast = (numPrepend > 1 ? rLast - 1 : 0);-
742 if (mergeFromAbove(myFirst, rLast, nextToFirst, rNextToLast)) {-
743 --numPrepend;-
744 --rLast;-
745 }-
746 if (numRects > 1) {-
747 nextToFirst = (numRects > 2? myFirst + 2 : 0);-
748 rNextToLast = (numPrepend > 0 ? rLast : 0);-
749 if (mergeFromAbove(myFirst + 1, myFirst, nextToFirst, rNextToLast)) {-
750 --numRects;-
751 ++numSkip;-
752 }-
753 }-
754 } else if (mergeFromAbove(myFirst, rLast, nextToFirst, rNextToLast)) {-
755 --numPrepend;-
756 }-
757 }-
758-
759 if (numPrepend > 0) {-
760 const int newNumRects = numRects + numPrepend;-
761 if (newNumRects > rects.size())-
762 rects.resize(newNumRects);-
763-
764-
765 memmove(rects.data() + numPrepend, rects.constData() + numSkip,-
766 numRects * sizeof(QRect));-
767-
768-
769 memcpy(rects.data(), r->rects.constData(), numPrepend * sizeof(QRect));-
770-
771 numRects = newNumRects;-
772 }-
773-
774-
775 if (innerArea < r->innerArea) {-
776 innerArea = r->innerArea;-
777 innerRect = r->innerRect;-
778 }-
779-
780-
781 extents.setCoords(qMin(extents.left(), r->extents.left()),-
782 qMin(extents.top(), r->extents.top()),-
783 qMax(extents.right(), r->extents.right()),-
784 qMax(extents.bottom(), r->extents.bottom()));-
785-
786-
787-
788-
789}-
790-
791void QRegionPrivate::prepend(const QRect *r)-
792{-
793 ((!(!r->isEmpty())) ? qt_assert("!r->isEmpty()",__FILE__,14991523) : qt_noop());-
794-
795 QRect *myFirst = (numRects == 1 ? &extents : rects.data());-
796 if (mergeFromLeft(myFirst, r)) {-
797 if (numRects > 1) {-
798 const QRect *nextToFirst = (numRects > 2 ? myFirst + 2 : 0);-
799 if (mergeFromAbove(myFirst + 1, myFirst, nextToFirst, 0)) {-
800 --numRects;-
801 memmove(rects.data(), rects.constData() + 1,-
802 numRects * sizeof(QRect));-
803 }-
804 }-
805 } else if (mergeFromAbove(myFirst, r, (numRects > 1 ? myFirst + 1 : 0), 0)) {-
806-
807 } else {-
808 vectorize();-
809 ++numRects;-
810 updateInnerRect(*r);-
811 rects.prepend(*r);-
812 }-
813 extents.setCoords(qMin(extents.left(), r->left()),-
814 qMin(extents.top(), r->top()),-
815 qMax(extents.right(), r->right()),-
816 qMax(extents.bottom(), r->bottom()));-
817-
818-
819-
820-
821}-
822-
823bool QRegionPrivate::canAppend(const QRect *r) const-
824{-
825 ((!(!r->isEmpty())) ? qt_assert("!r->isEmpty()",__FILE__,15311555) : qt_noop());-
826-
827 const QRect *myLast = (numRects == 1) ? &extents : (rects.constData() + (numRects - 1));-
828 if (r->top() > myLast->bottom())-
829 return true;-
830 if (r->top() == myLast->top()-
831 && r->height() == myLast->height()-
832 && r->left() > myLast->right())-
833 {-
834 return true;-
835 }-
836-
837 return false;-
838}-
839-
840bool QRegionPrivate::canAppend(const QRegionPrivate *r) const-
841{-
842 return canAppend(r->numRects == 1 ? &r->extents : r->rects.constData());-
843}-
844-
845bool QRegionPrivate::canPrepend(const QRect *r) const-
846{-
847 ((!(!r->isEmpty())) ? qt_assert("!r->isEmpty()",__FILE__,15531577) : qt_noop());-
848-
849 const QRect *myFirst = (numRects == 1) ? &extents : rects.constData();-
850 if (r->bottom() < myFirst->top())-
851 return true;-
852 if (r->top() == myFirst->top()-
853 && r->height() == myFirst->height()-
854 && r->right() < myFirst->left())-
855 {-
856 return true;-
857 }-
858-
859 return false;-
860}-
861-
862bool QRegionPrivate::canPrepend(const QRegionPrivate *r) const-
863{-
864 return canPrepend(r->numRects == 1 ? &r->extents : r->rects.constData() + r->numRects - 1);-
865}-
866static QRegionPrivate qrp;-
867const QRegion::QRegionData QRegion::shared_empty = {{ { -1 } }, &qrp};-
868-
869typedef void (*OverlapFunc)(QRegionPrivate &dest, const QRect *r1, const QRect *r1End,-
870 const QRect *r2, const QRect *r2End, int y1, int y2);-
871typedef void (*NonOverlapFunc)(QRegionPrivate &dest, const QRect *r, const QRect *rEnd,-
872 int y1, int y2);-
873-
874static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2);-
875static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest);-
876static void miRegionOp(QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2,-
877 OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func,-
878 NonOverlapFunc nonOverlap2Func);-
879-
880-
881typedef struct _POINTBLOCK {-
882 char data[200 * sizeof(QPoint)];-
883 QPoint *pts;-
884 struct _POINTBLOCK *next;-
885} POINTBLOCK;-
886static void UnionRectWithRegion(const QRect *rect, const QRegionPrivate *source,-
887 QRegionPrivate &dest)-
888{-
889 if (rect->isEmpty())-
890 return;-
891-
892 ((!(EqualRegion(source, &dest))) ? qt_assert("EqualRegion(source, &dest)",__FILE__,18241848) : qt_noop());-
893-
894 if (dest.numRects == 0) {-
895 dest = QRegionPrivate(*rect);-
896 } else if (dest.canAppend(rect)) {-
897 dest.append(rect);-
898 } else {-
899 QRegionPrivate p(*rect);-
900 UnionRegion(&p, source, dest);-
901 }-
902}-
903static void miSetExtents(QRegionPrivate &dest)-
904{-
905 const QRect *pBox,-
906 *pBoxEnd;-
907 QRect *pExtents;-
908-
909 dest.innerRect.setCoords(0, 0, -1, -1);-
910 dest.innerArea = -1;-
911 if (dest.numRects == 0) {-
912 dest.extents.setCoords(0, 0, -1, -1);-
913 return;-
914 }-
915-
916 pExtents = &dest.extents;-
917 if (dest.rects.isEmpty())-
918 pBox = &dest.extents;-
919 else-
920 pBox = dest.rects.constData();-
921 pBoxEnd = pBox + dest.numRects - 1;-
922 pExtents->setLeft(pBox->left());-
923 pExtents->setTop(pBox->top());-
924 pExtents->setRight(pBoxEnd->right());-
925 pExtents->setBottom(pBoxEnd->bottom());-
926-
927 ((!(pExtents->top() <= pExtents->bottom())) ? qt_assert("pExtents->top() <= pExtents->bottom()",__FILE__,18831907) : qt_noop());-
928 while (pBox <= pBoxEnd) {-
929 if (pBox->left() < pExtents->left())-
930 pExtents->setLeft(pBox->left());-
931 if (pBox->right() > pExtents->right())-
932 pExtents->setRight(pBox->right());-
933 dest.updateInnerRect(*pBox);-
934 ++pBox;-
935 }-
936 ((!(pExtents->left() <= pExtents->right())) ? qt_assert("pExtents->left() <= pExtents->right()",__FILE__,18921916) : qt_noop());-
937}-
938-
939-
940-
941-
942-
943-
944static void OffsetRegion(QRegionPrivate &region, int x, int y)-
945{-
946 if (region.rects.size()) {-
947 QRect *pbox = region.rects.data();-
948 int nbox = region.numRects;-
949-
950 while (nbox--) {-
951 pbox->translate(x, y);-
952 ++pbox;-
953 }-
954 }-
955 region.extents.translate(x, y);-
956 region.innerRect.translate(x, y);-
957}-
958static void miIntersectO(QRegionPrivate &dest, const QRect *r1, const QRect *r1End,-
959 const QRect *r2, const QRect *r2End, int y1, int y2)-
960{-
961 int x1;-
962 int x2;-
963 QRect *pNextRect;-
964-
965 pNextRect = dest.rects.data() + dest.numRects;-
966-
967 while (r1 != r1End && r2 != r2End) {-
968 x1 = qMax(r1->left(), r2->left());-
969 x2 = qMin(r1->right(), r2->right());-
970 if (x1 <= x2) {-
971 ((!(y1 <= y2)) ? qt_assert("y1 <= y2",__FILE__,19521976) : qt_noop());-
972 { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } }-
973 pNextRect->setCoords(x1, y1, x2, y2);-
974 ++dest.numRects;-
975 ++pNextRect;-
976 }-
977-
978-
979-
980-
981-
982-
983 if (r1->right() < r2->right()) {-
984 ++r1;-
985 } else if (r2->right() < r1->right()) {-
986 ++r2;-
987 } else {-
988 ++r1;-
989 ++r2;-
990 }-
991 }-
992}-
993static int miCoalesce(QRegionPrivate &dest, int prevStart, int curStart)-
994{-
995 QRect *pPrevBox;-
996 QRect *pCurBox;-
997 QRect *pRegEnd;-
998 int curNumRects;-
999 int prevNumRects;-
1000 int bandY1;-
1001 QRect *rData = dest.rects.data();-
1002-
1003 pRegEnd = rData + dest.numRects;-
1004-
1005 pPrevBox = rData + prevStart;-
1006 prevNumRects = curStart - prevStart;-
1007-
1008-
1009-
1010-
1011-
1012-
1013 pCurBox = rData + curStart;-
1014 bandY1 = pCurBox->top();-
1015 for (curNumRects = 0; pCurBox != pRegEnd && pCurBox->top() == bandY1; ++curNumRects) {-
1016 ++pCurBox;-
1017 }-
1018-
1019 if (pCurBox != pRegEnd) {-
1020-
1021-
1022-
1023-
1024-
1025-
1026 --pRegEnd;-
1027 while ((pRegEnd - 1)->top() == pRegEnd->top())-
1028 --pRegEnd;-
1029 curStart = pRegEnd - rData;-
1030 pRegEnd = rData + dest.numRects;-
1031 }-
1032-
1033 if (curNumRects == prevNumRects && curNumRects != 0) {-
1034 pCurBox -= curNumRects;-
1035-
1036-
1037-
1038-
1039 if (pPrevBox->bottom() == pCurBox->top() - 1) {-
1040-
1041-
1042-
1043-
1044-
1045-
1046 do {-
1047 if (pPrevBox->left() != pCurBox->left() || pPrevBox->right() != pCurBox->right()) {-
1048-
1049 return curStart;-
1050 }-
1051 ++pPrevBox;-
1052 ++pCurBox;-
1053 --prevNumRects;-
1054 } while (prevNumRects != 0);-
1055-
1056 dest.numRects -= curNumRects;-
1057 pCurBox -= curNumRects;-
1058 pPrevBox -= curNumRects;-
1059-
1060-
1061-
1062-
1063-
1064-
1065 do {-
1066 pPrevBox->setBottom(pCurBox->bottom());-
1067 dest.updateInnerRect(*pPrevBox);-
1068 ++pPrevBox;-
1069 ++pCurBox;-
1070 curNumRects -= 1;-
1071 } while (curNumRects != 0);-
1072 if (pCurBox == pRegEnd) {-
1073 curStart = prevStart;-
1074 } else {-
1075 do {-
1076 *pPrevBox++ = *pCurBox++;-
1077 dest.updateInnerRect(*pPrevBox);-
1078 } while (pCurBox != pRegEnd);-
1079 }-
1080 }-
1081 }-
1082 return curStart;-
1083}-
1084static void miRegionOp(QRegionPrivate &dest,-
1085 const QRegionPrivate *reg1, const QRegionPrivate *reg2,-
1086 OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func,-
1087 NonOverlapFunc nonOverlap2Func)-
1088{-
1089 const QRect *r1;-
1090 const QRect *r2;-
1091 const QRect *r1End;-
1092 const QRect *r2End;-
1093 int ybot;-
1094 int ytop;-
1095 int prevBand;-
1096 int curBand;-
1097 const QRect *r1BandEnd;-
1098 const QRect *r2BandEnd;-
1099 int top;-
1100 int bot;-
1101 if (reg1->numRects == 1)-
1102 r1 = &reg1->extents;-
1103 else-
1104 r1 = reg1->rects.constData();-
1105 if (reg2->numRects == 1)-
1106 r2 = &reg2->extents;-
1107 else-
1108 r2 = reg2->rects.constData();-
1109-
1110 r1End = r1 + reg1->numRects;-
1111 r2End = r2 + reg2->numRects;-
1112-
1113 dest.vectorize();-
1114-
1115 QVector<QRect> oldRects = dest.rects;-
1116-
1117 dest.numRects = 0;-
1118 dest.rects.resize(qMax(reg1->numRects,reg2->numRects) * 2);-
1119 if (reg1->extents.top() < reg2->extents.top())-
1120 ybot = reg1->extents.top() - 1;-
1121 else-
1122 ybot = reg2->extents.top() - 1;-
1123 prevBand = 0;-
1124-
1125 do {-
1126 curBand = dest.numRects;-
1127 r1BandEnd = r1;-
1128 while (r1BandEnd != r1End && r1BandEnd->top() == r1->top())-
1129 ++r1BandEnd;-
1130-
1131 r2BandEnd = r2;-
1132 while (r2BandEnd != r2End && r2BandEnd->top() == r2->top())-
1133 ++r2BandEnd;-
1134 if (r1->top() < r2->top()) {-
1135 top = qMax(r1->top(), ybot + 1);-
1136 bot = qMin(r1->bottom(), r2->top() - 1);-
1137-
1138 if (nonOverlap1Func != 0 && bot >= top)-
1139 (*nonOverlap1Func)(dest, r1, r1BandEnd, top, bot);-
1140 ytop = r2->top();-
1141 } else if (r2->top() < r1->top()) {-
1142 top = qMax(r2->top(), ybot + 1);-
1143 bot = qMin(r2->bottom(), r1->top() - 1);-
1144-
1145 if (nonOverlap2Func != 0 && bot >= top)-
1146 (*nonOverlap2Func)(dest, r2, r2BandEnd, top, bot);-
1147 ytop = r1->top();-
1148 } else {-
1149 ytop = r1->top();-
1150 }-
1151-
1152-
1153-
1154-
1155-
1156-
1157-
1158 if (dest.numRects != curBand)-
1159 prevBand = miCoalesce(dest, prevBand, curBand);-
1160-
1161-
1162-
1163-
1164-
1165 ybot = qMin(r1->bottom(), r2->bottom());-
1166 curBand = dest.numRects;-
1167 if (ybot >= ytop)-
1168 (*overlapFunc)(dest, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);-
1169-
1170 if (dest.numRects != curBand)-
1171 prevBand = miCoalesce(dest, prevBand, curBand);-
1172-
1173-
1174-
1175-
1176-
1177 if (r1->bottom() == ybot)-
1178 r1 = r1BandEnd;-
1179 if (r2->bottom() == ybot)-
1180 r2 = r2BandEnd;-
1181 } while (r1 != r1End && r2 != r2End);-
1182-
1183-
1184-
1185-
1186 curBand = dest.numRects;-
1187 if (r1 != r1End) {-
1188 if (nonOverlap1Func != 0) {-
1189 do {-
1190 r1BandEnd = r1;-
1191 while (r1BandEnd < r1End && r1BandEnd->top() == r1->top())-
1192 ++r1BandEnd;-
1193 (*nonOverlap1Func)(dest, r1, r1BandEnd, qMax(r1->top(), ybot + 1), r1->bottom());-
1194 r1 = r1BandEnd;-
1195 } while (r1 != r1End);-
1196 }-
1197 } else if ((r2 != r2End) && (nonOverlap2Func != 0)) {-
1198 do {-
1199 r2BandEnd = r2;-
1200 while (r2BandEnd < r2End && r2BandEnd->top() == r2->top())-
1201 ++r2BandEnd;-
1202 (*nonOverlap2Func)(dest, r2, r2BandEnd, qMax(r2->top(), ybot + 1), r2->bottom());-
1203 r2 = r2BandEnd;-
1204 } while (r2 != r2End);-
1205 }-
1206-
1207 if (dest.numRects != curBand)-
1208 (void)miCoalesce(dest, prevBand, curBand);-
1209 if (qMax(4, dest.numRects) < (dest.rects.size() >> 1))-
1210 dest.rects.resize(dest.numRects);-
1211}-
1212static void miUnionNonO(QRegionPrivate &dest, const QRect *r, const QRect *rEnd,-
1213 int y1, int y2)-
1214{-
1215 QRect *pNextRect;-
1216-
1217 pNextRect = dest.rects.data() + dest.numRects;-
1218-
1219 ((!(y1 <= y2)) ? qt_assert("y1 <= y2",__FILE__,23482372) : qt_noop());-
1220-
1221 while (r != rEnd) {-
1222 ((!(r->left() <= r->right())) ? qt_assert("r->left() <= r->right()",__FILE__,23512375) : qt_noop());-
1223 { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } }-
1224 pNextRect->setCoords(r->left(), y1, r->right(), y2);-
1225 dest.numRects++;-
1226 ++pNextRect;-
1227 ++r;-
1228 }-
1229}-
1230static void miUnionO(QRegionPrivate &dest, const QRect *r1, const QRect *r1End,-
1231 const QRect *r2, const QRect *r2End, int y1, int y2)-
1232{-
1233 QRect *pNextRect;-
1234-
1235 pNextRect = dest.rects.data() + dest.numRects;-
1236 ((!(y1 <= y2)) ? qt_assert("y1 <= y2",__FILE__,24032427) : qt_noop());-
1237 while (r1 != r1End && r2 != r2End) {-
1238 if (r1->left() < r2->left()) {-
1239 if ((dest.numRects != 0) && (pNextRect[-1].top() == y1) && (pNextRect[-1].bottom() == y2) && (pNextRect[-1].right() >= r1->left()-1)) { if (pNextRect[-1].right() < r1->right()) { pNextRect[-1].setRight(r1->right()); dest.updateInnerRect(pNextRect[-1]); ((!(pNextRect[-1].left() <= pNextRect[-1].right())) ? qt_assert("pNextRect[-1].left() <= pNextRect[-1].right()",__FILE__,24062430) : qt_noop()); } } else { { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } } pNextRect->setCoords(r1->left(), y1, r1->right(), y2); dest.updateInnerRect(*pNextRect); dest.numRects++; pNextRect++; } r1++;-
1240 } else {-
1241 if ((dest.numRects != 0) && (pNextRect[-1].top() == y1) && (pNextRect[-1].bottom() == y2) && (pNextRect[-1].right() >= r2->left()-1)) { if (pNextRect[-1].right() < r2->right()) { pNextRect[-1].setRight(r2->right()); dest.updateInnerRect(pNextRect[-1]); ((!(pNextRect[-1].left() <= pNextRect[-1].right())) ? qt_assert("pNextRect[-1].left() <= pNextRect[-1].right()",__FILE__,24082432) : qt_noop()); } } else { { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } } pNextRect->setCoords(r2->left(), y1, r2->right(), y2); dest.updateInnerRect(*pNextRect); dest.numRects++; pNextRect++; } r2++;-
1242 }-
1243 }-
1244-
1245 if (r1 != r1End) {-
1246 do {-
1247 if ((dest.numRects != 0) && (pNextRect[-1].top() == y1) && (pNextRect[-1].bottom() == y2) && (pNextRect[-1].right() >= r1->left()-1)) { if (pNextRect[-1].right() < r1->right()) { pNextRect[-1].setRight(r1->right()); dest.updateInnerRect(pNextRect[-1]); ((!(pNextRect[-1].left() <= pNextRect[-1].right())) ? qt_assert("pNextRect[-1].left() <= pNextRect[-1].right()",__FILE__,24142438) : qt_noop()); } } else { { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } } pNextRect->setCoords(r1->left(), y1, r1->right(), y2); dest.updateInnerRect(*pNextRect); dest.numRects++; pNextRect++; } r1++;-
1248 } while (r1 != r1End);-
1249 } else {-
1250 while (r2 != r2End) {-
1251 if ((dest.numRects != 0) && (pNextRect[-1].top() == y1) && (pNextRect[-1].bottom() == y2) && (pNextRect[-1].right() >= r2->left()-1)) { if (pNextRect[-1].right() < r2->right()) { pNextRect[-1].setRight(r2->right()); dest.updateInnerRect(pNextRect[-1]); ((!(pNextRect[-1].left() <= pNextRect[-1].right())) ? qt_assert("pNextRect[-1].left() <= pNextRect[-1].right()",__FILE__,24182442) : qt_noop()); } } else { { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } } pNextRect->setCoords(r2->left(), y1, r2->right(), y2); dest.updateInnerRect(*pNextRect); dest.numRects++; pNextRect++; } r2++;-
1252 }-
1253 }-
1254}-
1255-
1256static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest)-
1257{-
1258 ((!(!isEmptyHelper(reg1) && !isEmptyHelper(reg2))) ? qt_assert("!isEmptyHelper(reg1) && !isEmptyHelper(reg2)",__FILE__,24252449) : qt_noop());-
1259 ((!(!reg1->contains(*reg2))) ? qt_assert("!reg1->contains(*reg2)",__FILE__,24262450) : qt_noop());-
1260 ((!(!reg2->contains(*reg1))) ? qt_assert("!reg2->contains(*reg1)",__FILE__,24272451) : qt_noop());-
1261 ((!(!EqualRegion(reg1, reg2))) ? qt_assert("!EqualRegion(reg1, reg2)",__FILE__,24282452) : qt_noop());-
1262 ((!(!reg1->canAppend(reg2))) ? qt_assert("!reg1->canAppend(reg2)",__FILE__,24292453) : qt_noop());-
1263 ((!(!reg2->canAppend(reg1))) ? qt_assert("!reg2->canAppend(reg1)",__FILE__,24302454) : qt_noop());-
1264-
1265 if (reg1->innerArea > reg2->innerArea) {-
1266 dest.innerArea = reg1->innerArea;-
1267 dest.innerRect = reg1->innerRect;-
1268 } else {-
1269 dest.innerArea = reg2->innerArea;-
1270 dest.innerRect = reg2->innerRect;-
1271 }-
1272 miRegionOp(dest, reg1, reg2, miUnionO, miUnionNonO, miUnionNonO);-
1273-
1274 dest.extents.setCoords(qMin(reg1->extents.left(), reg2->extents.left()),-
1275 qMin(reg1->extents.top(), reg2->extents.top()),-
1276 qMax(reg1->extents.right(), reg2->extents.right()),-
1277 qMax(reg1->extents.bottom(), reg2->extents.bottom()));-
1278}-
1279static void miSubtractNonO1(QRegionPrivate &dest, const QRect *r,-
1280 const QRect *rEnd, int y1, int y2)-
1281{-
1282 QRect *pNextRect;-
1283-
1284 pNextRect = dest.rects.data() + dest.numRects;-
1285-
1286 ((!(y1<=y2)) ? qt_assert("y1<=y2",__FILE__,24732497) : qt_noop());-
1287-
1288 while (r != rEnd) {-
1289 ((!(r->left() <= r->right())) ? qt_assert("r->left() <= r->right()",__FILE__,24762500) : qt_noop());-
1290 { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } }-
1291 pNextRect->setCoords(r->left(), y1, r->right(), y2);-
1292 ++dest.numRects;-
1293 ++pNextRect;-
1294 ++r;-
1295 }-
1296}-
1297static void miSubtractO(QRegionPrivate &dest, const QRect *r1, const QRect *r1End,-
1298 const QRect *r2, const QRect *r2End, int y1, int y2)-
1299{-
1300 QRect *pNextRect;-
1301 int x1;-
1302-
1303 x1 = r1->left();-
1304-
1305 ((!(y1 <= y2)) ? qt_assert("y1 <= y2",__FILE__,25082532) : qt_noop());-
1306 pNextRect = dest.rects.data() + dest.numRects;-
1307-
1308 while (r1 != r1End && r2 != r2End) {-
1309 if (r2->right() < x1) {-
1310-
1311-
1312-
1313 ++r2;-
1314 } else if (r2->left() <= x1) {-
1315-
1316-
1317-
1318 x1 = r2->right() + 1;-
1319 if (x1 > r1->right()) {-
1320-
1321-
1322-
1323-
1324 ++r1;-
1325 if (r1 != r1End)-
1326 x1 = r1->left();-
1327 } else {-
1328-
1329 ++r2;-
1330 }-
1331 } else if (r2->left() <= r1->right()) {-
1332-
1333-
1334-
1335-
1336 ((!(x1 < r2->left())) ? qt_assert("x1 < r2->left()",__FILE__,25392563) : qt_noop());-
1337 { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } }-
1338 pNextRect->setCoords(x1, y1, r2->left() - 1, y2);-
1339 ++dest.numRects;-
1340 ++pNextRect;-
1341-
1342 x1 = r2->right() + 1;-
1343 if (x1 > r1->right()) {-
1344-
1345-
1346-
1347 ++r1;-
1348 if (r1 != r1End)-
1349 x1 = r1->left();-
1350 } else {-
1351-
1352 ++r2;-
1353 }-
1354 } else {-
1355-
1356-
1357-
1358 if (r1->right() >= x1) {-
1359 { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } }-
1360 pNextRect->setCoords(x1, y1, r1->right(), y2);-
1361 ++dest.numRects;-
1362 ++pNextRect;-
1363 }-
1364 ++r1;-
1365 if (r1 != r1End)-
1366 x1 = r1->left();-
1367 }-
1368 }-
1369-
1370-
1371-
1372-
1373 while (r1 != r1End) {-
1374 ((!(x1 <= r1->right())) ? qt_assert("x1 <= r1->right()",__FILE__,25772601) : qt_noop());-
1375 { if ((dest).numRects >= ((dest).rects.size()-1)){ dest.rects.resize(dest.rects.size() * 2); (pNextRect) = (dest.rects).data() + (dest).numRects; } }-
1376 pNextRect->setCoords(x1, y1, r1->right(), y2);-
1377 ++dest.numRects;-
1378 ++pNextRect;-
1379-
1380 ++r1;-
1381 if (r1 != r1End)-
1382 x1 = r1->left();-
1383 }-
1384}-
1385static void SubtractRegion(QRegionPrivate *regM, QRegionPrivate *regS,-
1386 QRegionPrivate &dest)-
1387{-
1388 ((!(!isEmptyHelper(regM))) ? qt_assert("!isEmptyHelper(regM)",__FILE__,26042628) : qt_noop());-
1389 ((!(!isEmptyHelper(regS))) ? qt_assert("!isEmptyHelper(regS)",__FILE__,26052629) : qt_noop());-
1390 ((!(((&regM->extents)->right() >= (&regS->extents)->left() && (&regM->extents)->left() <= (&regS->extents)->right() && (&regM->extents)->bottom() >= (&regS->extents)->top() && (&regM->extents)->top() <= (&regS->extents)->bottom()))) ? qt_assert("EXTENTCHECK(&regM->extents, &regS->extents)",__FILE__,26062630) : qt_noop());-
1391 ((!(!regS->contains(*regM))) ? qt_assert("!regS->contains(*regM)",__FILE__,26072631) : qt_noop());-
1392 ((!(!EqualRegion(regM, regS))) ? qt_assert("!EqualRegion(regM, regS)",__FILE__,26082632) : qt_noop());-
1393-
1394 miRegionOp(dest, regM, regS, miSubtractO, miSubtractNonO1, 0);-
1395 miSetExtents(dest);-
1396}-
1397-
1398static void XorRegion(QRegionPrivate *sra, QRegionPrivate *srb, QRegionPrivate &dest)-
1399{-
1400 ((!(!isEmptyHelper(sra) && !isEmptyHelper(srb))) ? qt_assert("!isEmptyHelper(sra) && !isEmptyHelper(srb)",__FILE__,26242648) : qt_noop());-
1401 ((!(((&sra->extents)->right() >= (&srb->extents)->left() && (&sra->extents)->left() <= (&srb->extents)->right() && (&sra->extents)->bottom() >= (&srb->extents)->top() && (&sra->extents)->top() <= (&srb->extents)->bottom()))) ? qt_assert("EXTENTCHECK(&sra->extents, &srb->extents)",__FILE__,26252649) : qt_noop());-
1402 ((!(!EqualRegion(sra, srb))) ? qt_assert("!EqualRegion(sra, srb)",__FILE__,26262650) : qt_noop());-
1403-
1404 QRegionPrivate tra, trb;-
1405-
1406 if (!srb->contains(*sra))-
1407 SubtractRegion(sra, srb, tra);-
1408 if (!sra->contains(*srb))-
1409 SubtractRegion(srb, sra, trb);-
1410-
1411 ((!(isEmptyHelper(&trb) || !tra.contains(trb))) ? qt_assert("isEmptyHelper(&trb) || !tra.contains(trb)",__FILE__,26352659) : qt_noop());-
1412 ((!(isEmptyHelper(&tra) || !trb.contains(tra))) ? qt_assert("isEmptyHelper(&tra) || !trb.contains(tra)",__FILE__,26362660) : qt_noop());-
1413-
1414 if (isEmptyHelper(&tra)) {-
1415 dest = trb;-
1416 } else if (isEmptyHelper(&trb)) {-
1417 dest = tra;-
1418 } else if (tra.canAppend(&trb)) {-
1419 dest = tra;-
1420 dest.append(&trb);-
1421 } else if (trb.canAppend(&tra)) {-
1422 dest = trb;-
1423 dest.append(&tra);-
1424 } else {-
1425 UnionRegion(&tra, &trb, dest);-
1426 }-
1427}-
1428-
1429-
1430-
1431-
1432static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)-
1433{-
1434 if (r1->numRects != r2->numRects) {-
1435 return false;-
1436 } else if (r1->numRects == 0) {-
1437 return true;-
1438 } else if (r1->extents != r2->extents) {-
1439 return false;-
1440 } else if (r1->numRects == 1 && r2->numRects == 1) {-
1441 return true;-
1442 } else {-
1443 const QRect *rr1 = (r1->numRects == 1) ? &r1->extents : r1->rects.constData();-
1444 const QRect *rr2 = (r2->numRects == 1) ? &r2->extents : r2->rects.constData();-
1445 for (int i = 0; i < r1->numRects; ++i, ++rr1, ++rr2) {-
1446 if (*rr1 != *rr2)-
1447 return false;-
1448 }-
1449 }-
1450-
1451 return true;-
1452}-
1453-
1454static bool PointInRegion(QRegionPrivate *pRegion, int x, int y)-
1455{-
1456 int i;-
1457-
1458 if (isEmptyHelper(pRegion))-
1459 return false;-
1460 if (!pRegion->extents.contains(x, y))-
1461 return false;-
1462 if (pRegion->numRects == 1)-
1463 return pRegion->extents.contains(x, y);-
1464 if (pRegion->innerRect.contains(x, y))-
1465 return true;-
1466 for (i = 0; i < pRegion->numRects; ++i) {-
1467 if (pRegion->rects[i].contains(x, y))-
1468 return true;-
1469 }-
1470 return false;-
1471}-
1472-
1473static bool RectInRegion(QRegionPrivate *region, int rx, int ry, uint rwidth, uint rheight)-
1474{-
1475 const QRect *pbox;-
1476 const QRect *pboxEnd;-
1477 QRect rect(rx, ry, rwidth, rheight);-
1478 QRect *prect = &rect;-
1479 int partIn, partOut;-
1480-
1481 if (!region || region->numRects == 0 || !((&region->extents)->right() >= (prect)->left() && (&region->extents)->left() <= (prect)->right() && (&region->extents)->bottom() >= (prect)->top() && (&region->extents)->top() <= (prect)->bottom()))-
1482 return 0;-
1483-
1484 partOut = false;-
1485 partIn = false;-
1486-
1487-
1488 pbox = (region->numRects == 1) ? &region->extents : region->rects.constData();-
1489 pboxEnd = pbox + region->numRects;-
1490 for (; pbox < pboxEnd; ++pbox) {-
1491 if (pbox->bottom() < ry)-
1492 continue;-
1493-
1494 if (pbox->top() > ry) {-
1495 partOut = true;-
1496 if (partIn || pbox->top() > prect->bottom())-
1497 break;-
1498 ry = pbox->top();-
1499 }-
1500-
1501 if (pbox->right() < rx)-
1502 continue;-
1503-
1504 if (pbox->left() > rx) {-
1505 partOut = true;-
1506 if (partIn)-
1507 break;-
1508 }-
1509-
1510 if (pbox->left() <= prect->right()) {-
1511 partIn = true;-
1512 if (partOut)-
1513 break;-
1514 }-
1515-
1516 if (pbox->right() >= prect->right()) {-
1517 ry = pbox->bottom() + 1;-
1518 if (ry > prect->bottom())-
1519 break;-
1520 rx = prect->left();-
1521 } else {-
1522-
1523-
1524-
1525-
1526-
1527-
1528-
1529 break;-
1530 }-
1531 }-
1532 return partIn ? ((ry <= prect->bottom()) ? 2 : 1) : 0;-
1533}-
1534typedef struct {-
1535 int minor_axis;-
1536 int d;-
1537 int m, m1;-
1538 int incr1, incr2;-
1539} BRESINFO;-
1540typedef struct _EdgeTableEntry {-
1541 int ymax;-
1542 int ClockWise;-
1543 BRESINFO bres;-
1544 struct _EdgeTableEntry *next;-
1545 struct _EdgeTableEntry *back;-
1546 struct _EdgeTableEntry *nextWETE;-
1547} EdgeTableEntry;-
1548-
1549-
1550typedef struct _ScanLineList{-
1551 int scanline;-
1552 EdgeTableEntry *edgelist;-
1553 struct _ScanLineList *next;-
1554} ScanLineList;-
1555-
1556-
1557typedef struct {-
1558 int ymax;-
1559 int ymin;-
1560 ScanLineList scanlines;-
1561} EdgeTable;-
1562typedef struct _ScanLineListBlock {-
1563 ScanLineList SLLs[25];-
1564 struct _ScanLineListBlock *next;-
1565} ScanLineListBlock;-
1566static void InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline,-
1567 ScanLineListBlock **SLLBlock, int *iSLLBlock)-
1568{-
1569 EdgeTableEntry *start, *prev;-
1570 ScanLineList *pSLL, *pPrevSLL;-
1571 ScanLineListBlock *tmpSLLBlock;-
1572-
1573-
1574-
1575-
1576 pPrevSLL = &ET->scanlines;-
1577 pSLL = pPrevSLL->next;-
1578 while (pSLL && (pSLL->scanline < scanline)) {-
1579 pPrevSLL = pSLL;-
1580 pSLL = pSLL->next;-
1581 }-
1582-
1583-
1584-
1585-
1586 if ((!pSLL) || (pSLL->scanline > scanline)) {-
1587 if (*iSLLBlock > 25 -1)-
1588 {-
1589 tmpSLLBlock =-
1590 (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));-
1591 do {if(!(tmpSLLBlock))qt_check_pointer(__FILE__,31453169);} while (0);-
1592 (*SLLBlock)->next = tmpSLLBlock;-
1593 tmpSLLBlock->next = (ScanLineListBlock *)__null;-
1594 *SLLBlock = tmpSLLBlock;-
1595 *iSLLBlock = 0;-
1596 }-
1597 pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);-
1598-
1599 pSLL->next = pPrevSLL->next;-
1600 pSLL->edgelist = (EdgeTableEntry *)__null;-
1601 pPrevSLL->next = pSLL;-
1602 }-
1603 pSLL->scanline = scanline;-
1604-
1605-
1606-
1607-
1608 prev = 0;-
1609 start = pSLL->edgelist;-
1610 while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) {-
1611 prev = start;-
1612 start = start->next;-
1613 }-
1614 ETE->next = start;-
1615-
1616 if (prev)-
1617 prev->next = ETE;-
1618 else-
1619 pSLL->edgelist = ETE;-
1620}-
1621static void CreateETandAET(int count, const QPoint *pts,-
1622 EdgeTable *ET, EdgeTableEntry *AET, EdgeTableEntry *pETEs,-
1623 ScanLineListBlock *pSLLBlock)-
1624{-
1625 const QPoint *top,-
1626 *bottom,-
1627 *PrevPt,-
1628 *CurrPt;-
1629 int iSLLBlock = 0;-
1630 int dy;-
1631-
1632 if (count < 2)-
1633 return;-
1634-
1635-
1636-
1637-
1638 AET->next = 0;-
1639 AET->back = 0;-
1640 AET->nextWETE = 0;-
1641 AET->bres.minor_axis = (-2147483647 - 1);-
1642-
1643-
1644-
1645-
1646 ET->scanlines.next = 0;-
1647 ET->ymax = (-2147483647 - 1);-
1648 ET->ymin = 2147483647;-
1649 pSLLBlock->next = 0;-
1650-
1651 PrevPt = &pts[count - 1];-
1652-
1653-
1654-
1655-
1656-
1657-
1658 while (count--) {-
1659 CurrPt = pts++;-
1660-
1661-
1662-
1663-
1664 if (PrevPt->y() > CurrPt->y()) {-
1665 bottom = PrevPt;-
1666 top = CurrPt;-
1667 pETEs->ClockWise = 0;-
1668 } else {-
1669 bottom = CurrPt;-
1670 top = PrevPt;-
1671 pETEs->ClockWise = 1;-
1672 }-
1673-
1674-
1675-
1676-
1677 if (bottom->y() != top->y()) {-
1678 pETEs->ymax = bottom->y() - 1;-
1679-
1680-
1681-
1682-
1683 dy = bottom->y() - top->y();-
1684 { int dx; if ((dy) != 0) { pETEs->bres.minor_axis = (top->x()); dx = (bottom->x()) - pETEs->bres.minor_axis; if (dx < 0) { pETEs->bres.m = dx / (dy); pETEs->bres.m1 = pETEs->bres.m - 1; pETEs->bres.incr1 = -2 * dx + 2 * (dy) * pETEs->bres.m1; pETEs->bres.incr2 = -2 * dx + 2 * (dy) * pETEs->bres.m; pETEs->bres.d = 2 * pETEs->bres.m * (dy) - 2 * dx - 2 * (dy); } else { pETEs->bres.m = dx / (dy); pETEs->bres.m1 = pETEs->bres.m + 1; pETEs->bres.incr1 = 2 * dx - 2 * (dy) * pETEs->bres.m1; pETEs->bres.incr2 = 2 * dx - 2 * (dy) * pETEs->bres.m; pETEs->bres.d = -2 * pETEs->bres.m * (dy) + 2 * dx; } } }-
1685-
1686 InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock);-
1687-
1688 if (PrevPt->y() > ET->ymax)-
1689 ET->ymax = PrevPt->y();-
1690 if (PrevPt->y() < ET->ymin)-
1691 ET->ymin = PrevPt->y();-
1692 ++pETEs;-
1693 }-
1694-
1695 PrevPt = CurrPt;-
1696 }-
1697}-
1698static void loadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs)-
1699{-
1700 EdgeTableEntry *pPrevAET;-
1701 EdgeTableEntry *tmp;-
1702-
1703 pPrevAET = AET;-
1704 AET = AET->next;-
1705 while (ETEs) {-
1706 while (AET && AET->bres.minor_axis < ETEs->bres.minor_axis) {-
1707 pPrevAET = AET;-
1708 AET = AET->next;-
1709 }-
1710 tmp = ETEs->next;-
1711 ETEs->next = AET;-
1712 if (AET)-
1713 AET->back = ETEs;-
1714 ETEs->back = pPrevAET;-
1715 pPrevAET->next = ETEs;-
1716 pPrevAET = ETEs;-
1717-
1718 ETEs = tmp;-
1719 }-
1720}-
1721static void computeWAET(EdgeTableEntry *AET)-
1722{-
1723 EdgeTableEntry *pWETE;-
1724 int inside = 1;-
1725 int isInside = 0;-
1726-
1727 AET->nextWETE = 0;-
1728 pWETE = AET;-
1729 AET = AET->next;-
1730 while (AET) {-
1731 if (AET->ClockWise)-
1732 ++isInside;-
1733 else-
1734 --isInside;-
1735-
1736 if ((!inside && !isInside) || (inside && isInside)) {-
1737 pWETE->nextWETE = AET;-
1738 pWETE = AET;-
1739 inside = !inside;-
1740 }-
1741 AET = AET->next;-
1742 }-
1743 pWETE->nextWETE = 0;-
1744}-
1745static int InsertionSort(EdgeTableEntry *AET)-
1746{-
1747 EdgeTableEntry *pETEchase;-
1748 EdgeTableEntry *pETEinsert;-
1749 EdgeTableEntry *pETEchaseBackTMP;-
1750 int changed = 0;-
1751-
1752 AET = AET->next;-
1753 while (AET) {-
1754 pETEinsert = AET;-
1755 pETEchase = AET;-
1756 while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)-
1757 pETEchase = pETEchase->back;-
1758-
1759 AET = AET->next;-
1760 if (pETEchase != pETEinsert) {-
1761 pETEchaseBackTMP = pETEchase->back;-
1762 pETEinsert->back->next = AET;-
1763 if (AET)-
1764 AET->back = pETEinsert->back;-
1765 pETEinsert->next = pETEchase;-
1766 pETEchase->back->next = pETEinsert;-
1767 pETEchase->back = pETEinsert;-
1768 pETEinsert->back = pETEchaseBackTMP;-
1769 changed = 1;-
1770 }-
1771 }-
1772 return changed;-
1773}-
1774-
1775-
1776-
1777-
1778static void FreeStorage(ScanLineListBlock *pSLLBlock)-
1779{-
1780 ScanLineListBlock *tmpSLLBlock;-
1781-
1782 while (pSLLBlock) {-
1783 tmpSLLBlock = pSLLBlock->next;-
1784 free(pSLLBlock);-
1785 pSLLBlock = tmpSLLBlock;-
1786 }-
1787}-
1788-
1789struct QRegionSpan {-
1790 QRegionSpan() {}-
1791 QRegionSpan(int x1_, int x2_) : x1(x1_), x2(x2_) {}-
1792-
1793 int x1;-
1794 int x2;-
1795 int width() const { return x2 - x1; }-
1796};-
1797-
1798template<> class QTypeInfo<QRegionSpan > { public: enum { isComplex = (((Q_PRIMITIVE_TYPE) & Q_PRIMITIVE_TYPE) == 0), isStatic = (((Q_PRIMITIVE_TYPE) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), isRelocatable = !isStatic || ((Q_PRIMITIVE_TYPE) & Q_RELOCATABLE_TYPE), isLarge = (sizeof(QRegionSpan)>sizeof(void*)), isPointer = false, isIntegral = QtPrivate::is_integral< QRegionSpan >::value, isDummy = (((Q_PRIMITIVE_TYPE) & Q_DUMMY_TYPE) != 0), sizeOf = sizeof(QRegionSpan) }; static inline const char *name() { return "QRegionSpan"; } };-
1799-
1800static inline void flushRow(const QRegionSpan *spans, int y, int numSpans, QRegionPrivate *reg, int *lastRow, int *extendTo, bool *needsExtend)-
1801{-
1802 QRect *regRects = reg->rects.data() + *lastRow;-
1803 bool canExtend = reg->rects.size() - *lastRow == numSpans-
1804 && !(*needsExtend && *extendTo + 1 != y)-
1805 && (*needsExtend || regRects[0].y() + regRects[0].height() == y);-
1806-
1807 for (int i = 0; i < numSpans && canExtend; ++i) {-
1808 if (regRects[i].x() != spans[i].x1 || regRects[i].right() != spans[i].x2 - 1)-
1809 canExtend = false;-
1810 }-
1811-
1812 if (canExtend) {-
1813 *extendTo = y;-
1814 *needsExtend = true;-
1815 } else {-
1816 if (*needsExtend) {-
1817 for (int i = 0; i < reg->rects.size() - *lastRow; ++i)-
1818 regRects[i].setBottom(*extendTo);-
1819 }-
1820-
1821 *lastRow = reg->rects.size();-
1822 reg->rects.reserve(*lastRow + numSpans);-
1823 for (int i = 0; i < numSpans; ++i)-
1824 reg->rects << QRect(spans[i].x1, y, spans[i].width(), 1);-
1825-
1826 if (spans[0].x1 < reg->extents.left())-
1827 reg->extents.setLeft(spans[0].x1);-
1828-
1829 if (spans[numSpans-1].x2 - 1 > reg->extents.right())-
1830 reg->extents.setRight(spans[numSpans-1].x2 - 1);-
1831-
1832 *needsExtend = false;-
1833 }-
1834}-
1835static void PtsToRegion(int numFullPtBlocks, int iCurPtBlock,-
1836 POINTBLOCK *FirstPtBlock, QRegionPrivate *reg)-
1837{-
1838 int lastRow = 0;-
1839 int extendTo = 0;-
1840 bool needsExtend = false;-
1841 QVarLengthArray<QRegionSpan> row;-
1842 int rowSize = 0;-
1843-
1844 reg->extents.setLeft(2147483647);-
1845 reg->extents.setRight((-2147483647 - 1));-
1846 reg->innerArea = -1;-
1847-
1848 POINTBLOCK *CurPtBlock = FirstPtBlock;-
1849 for (; numFullPtBlocks >= 0; --numFullPtBlocks) {-
1850-
1851 int i = 200 >> 1;-
1852 if (!numFullPtBlocks)-
1853 i = iCurPtBlock >> 1;-
1854 if(i) {-
1855 row.resize(qMax(row.size(), rowSize + i));-
1856 for (QPoint *pts = CurPtBlock->pts; i--; pts += 2) {-
1857 const int width = pts[1].x() - pts[0].x();-
1858 if (width) {-
1859 if (rowSize && row[rowSize-1].x2 == pts[0].x())-
1860 row[rowSize-1].x2 = pts[1].x();-
1861 else-
1862 row[rowSize++] = QRegionSpan(pts[0].x(), pts[1].x());-
1863 }-
1864-
1865 if (rowSize) {-
1866 QPoint *next = i ? &pts[2] : (numFullPtBlocks && iCurPtBlock ? CurPtBlock->next->pts : nullptr);-
1867-
1868 if (!next || next->y() != pts[0].y()) {-
1869 flushRow(row.data(), pts[0].y(), rowSize, reg, &lastRow, &extendTo, &needsExtend);-
1870 rowSize = 0;-
1871 }-
1872 }-
1873 }-
1874 }-
1875 CurPtBlock = CurPtBlock->next;-
1876 }-
1877-
1878 if (needsExtend) {-
1879 for (int i = lastRow; i < reg->rects.size(); ++i)-
1880 reg->rects[i].setBottom(extendTo);-
1881 }-
1882-
1883 reg->numRects = reg->rects.size();-
1884-
1885 if (reg->numRects) {-
1886 reg->extents.setTop(reg->rects[0].top());-
1887 reg->extents.setBottom(reg->rects[lastRow].bottom());-
1888-
1889 for (int i = 0; i < reg->rects.size(); ++i)-
1890 reg->updateInnerRect(reg->rects[i]);-
1891 } else {-
1892 reg->extents.setCoords(0, 0, 0, 0);-
1893 }-
1894}-
1895static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule)-
1896-
1897-
1898-
1899{-
1900 QRegionPrivate *region;-
1901 EdgeTableEntry *pAET;-
1902 int y;-
1903 int iPts = 0;-
1904 EdgeTableEntry *pWETE;-
1905 ScanLineList *pSLL;-
1906 QPoint *pts;-
1907 EdgeTableEntry *pPrevAET;-
1908 EdgeTable ET;-
1909 EdgeTableEntry *AET;-
1910 EdgeTableEntry *pETEs;-
1911 ScanLineListBlock SLLBlock;-
1912 int fixWAET = false;-
1913 POINTBLOCK FirstPtBlock, *curPtBlock;-
1914 FirstPtBlock.pts = reinterpret_cast<QPoint *>(FirstPtBlock.data);-
1915 POINTBLOCK *tmpPtBlock;-
1916 int numFullPtBlocks = 0;-
1917-
1918 region = new QRegionPrivate;-
1919-
1920-
1921 if (((Count == 4) ||-
1922 ((Count == 5) && (Pts[4].x() == Pts[0].x()) && (Pts[4].y() == Pts[0].y())))-
1923 && (((Pts[0].y() == Pts[1].y()) && (Pts[1].x() == Pts[2].x()) && (Pts[2].y() == Pts[3].y())-
1924 && (Pts[3].x() == Pts[0].x())) || ((Pts[0].x() == Pts[1].x())-
1925 && (Pts[1].y() == Pts[2].y()) && (Pts[2].x() == Pts[3].x())-
1926 && (Pts[3].y() == Pts[0].y())))) {-
1927 int x = qMin(Pts[0].x(), Pts[2].x());-
1928 region->extents.setLeft(x);-
1929 int y = qMin(Pts[0].y(), Pts[2].y());-
1930 region->extents.setTop(y);-
1931 region->extents.setWidth(qMax(Pts[0].x(), Pts[2].x()) - x);-
1932 region->extents.setHeight(qMax(Pts[0].y(), Pts[2].y()) - y);-
1933 if ((region->extents.left() <= region->extents.right()) &&-
1934 (region->extents.top() <= region->extents.bottom())) {-
1935 region->numRects = 1;-
1936 region->innerRect = region->extents;-
1937 region->innerArea = region->innerRect.width() * region->innerRect.height();-
1938 }-
1939 return region;-
1940 }-
1941-
1942 if (!(pETEs = static_cast<EdgeTableEntry *>(malloc(sizeof(EdgeTableEntry) * Count)))) {-
1943 delete region;-
1944 return 0;-
1945 }-
1946-
1947 region->vectorize();-
1948-
1949 AET = new EdgeTableEntry;-
1950 pts = FirstPtBlock.pts;-
1951 CreateETandAET(Count, Pts, &ET, AET, pETEs, &SLLBlock);-
1952-
1953 pSLL = ET.scanlines.next;-
1954 curPtBlock = &FirstPtBlock;-
1955-
1956-
1957 if (ET.ymax - ET.ymin > 100000) {-
1958-
1959-
1960 QMessageLogger(__FILE__, 36003624, __PRETTY_FUNCTION__).warning("QRegion: creating region from big polygon failed...!");-
1961-
1962 delete AET;-
1963 delete region;-
1964 return 0;-
1965 }-
1966-
1967-
1968 if (true) {-
1969 if (rule == 0) {-
1970-
1971-
1972-
1973 for (y = ET.ymin; y < ET.ymax; ++y) {-
1974-
1975-
1976-
1977-
1978-
1979 if (pSLL && y == pSLL->scanline) {-
1980 loadAET(AET, pSLL->edgelist);-
1981 pSLL = pSLL->next;-
1982 }-
1983 pPrevAET = AET;-
1984 pAET = AET->next;-
1985-
1986-
1987-
1988-
1989 while (pAET) {-
1990 pts->setX(pAET->bres.minor_axis);-
1991 pts->setY(y);-
1992 ++pts;-
1993 ++iPts;-
1994-
1995-
1996-
1997-
1998 if (iPts == 200) {-
1999 tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK));-
2000 do {if(!(tmpPtBlock))qt_check_pointer(__FILE__,36403664);} while (0);-
2001 tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data);-
2002 curPtBlock->next = tmpPtBlock;-
2003 curPtBlock = tmpPtBlock;-
2004 pts = curPtBlock->pts;-
2005 ++numFullPtBlocks;-
2006 iPts = 0;-
2007 }-
2008 { if (pAET->ymax == y) { pPrevAET->next = pAET->next; pAET = pPrevAET->next; if (pAET) pAET->back = pPrevAET; } else { { if (pAET->bres.m1 > 0) { if (pAET->bres.d > 0) { pAET->bres.minor_axis += pAET->bres.m1; pAET->bres.d += pAET->bres.incr1; } else { pAET->bres.minor_axis += pAET->bres.m; pAET->bres.d += pAET->bres.incr2; } } else { if (pAET->bres.d >= 0) { pAET->bres.minor_axis += pAET->bres.m1; pAET->bres.d += pAET->bres.incr1; } else { pAET->bres.minor_axis += pAET->bres.m; pAET->bres.d += pAET->bres.incr2; } } } pPrevAET = pAET; pAET = pAET->next; } }-
2009 }-
2010 InsertionSort(AET);-
2011 }-
2012 } else {-
2013-
2014-
2015-
2016 for (y = ET.ymin; y < ET.ymax; ++y) {-
2017-
2018-
2019-
2020-
2021 if (pSLL && y == pSLL->scanline) {-
2022 loadAET(AET, pSLL->edgelist);-
2023 computeWAET(AET);-
2024 pSLL = pSLL->next;-
2025 }-
2026 pPrevAET = AET;-
2027 pAET = AET->next;-
2028 pWETE = pAET;-
2029-
2030-
2031-
2032-
2033 while (pAET) {-
2034-
2035-
2036-
2037-
2038 if (pWETE == pAET) {-
2039 pts->setX(pAET->bres.minor_axis);-
2040 pts->setY(y);-
2041 ++pts;-
2042 ++iPts;-
2043-
2044-
2045-
2046-
2047 if (iPts == 200) {-
2048 tmpPtBlock = static_cast<POINTBLOCK *>(malloc(sizeof(POINTBLOCK)));-
2049 tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data);-
2050 curPtBlock->next = tmpPtBlock;-
2051 curPtBlock = tmpPtBlock;-
2052 pts = curPtBlock->pts;-
2053 ++numFullPtBlocks;-
2054 iPts = 0;-
2055 }-
2056 pWETE = pWETE->nextWETE;-
2057 }-
2058 { if (pAET->ymax == y) { pPrevAET->next = pAET->next; pAET = pPrevAET->next; fixWAET = 1; if (pAET) pAET->back = pPrevAET; } else { { if (pAET->bres.m1 > 0) { if (pAET->bres.d > 0) { pAET->bres.minor_axis += pAET->bres.m1; pAET->bres.d += pAET->bres.incr1; } else { pAET->bres.minor_axis += pAET->bres.m; pAET->bres.d += pAET->bres.incr2; } } else { if (pAET->bres.d >= 0) { pAET->bres.minor_axis += pAET->bres.m1; pAET->bres.d += pAET->bres.incr1; } else { pAET->bres.minor_axis += pAET->bres.m; pAET->bres.d += pAET->bres.incr2; } } } pPrevAET = pAET; pAET = pAET->next; } }-
2059 }-
2060-
2061-
2062-
2063-
2064-
2065 if (InsertionSort(AET) || fixWAET) {-
2066 computeWAET(AET);-
2067 fixWAET = false;-
2068 }-
2069 }-
2070 }-
2071 } else {
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; }
-
2072 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; }
-
2073 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; }
-
2074 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; }
-
2075 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; }
-
2076 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; }
-
2077 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; }
-
2078 }
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; }
-
2079 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; }
-
2080 return 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; }
-
2081 }
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; }
-
2082-
2083 FreeStorage(SLLBlock.next);-
2084 PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);-
2085 for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {-
2086 tmpPtBlock = curPtBlock->next;-
2087 free(curPtBlock);-
2088 curPtBlock = tmpPtBlock;-
2089 }-
2090 delete AET;-
2091 free(pETEs);-
2092 return region;-
2093}-
2094-
2095-
2096QRegionPrivate *qt_bitmapToRegion(const QBitmap& bitmap)-
2097{-
2098 const QImage image = bitmap.toImage();-
2099-
2100 QRegionPrivate *region = new QRegionPrivate;-
2101-
2102 QRect xr;-
2103-
2104-
2105-
2106-
2107-
2108-
2109-
2110 const uchar zero = 0;-
2111 bool little = image.format() == QImage::Format_MonoLSB;-
2112-
2113 int x,-
2114 y;-
2115 for (y = 0; y < image.height(); ++y) {-
2116 const uchar *line = image.constScanLine(y);-
2117 int w = image.width();-
2118 uchar all = zero;-
2119 int prev1 = -1;-
2120 for (x = 0; x < w;) {-
2121 uchar byte = line[x / 8];-
2122 if (x > w - 8 || byte!=all) {-
2123 if (little) {-
2124 for (int b = 8; b > 0 && x < w; --b) {-
2125 if (!(byte & 0x01) == !all) {-
2126-
2127 } else {-
2128-
2129 if (all!=zero) {-
2130 { xr.setCoords(prev1, y, x-1, y); UnionRectWithRegion(&xr, region, *region); }-
2131 all = zero;-
2132 } else {-
2133 prev1 = x;-
2134 all = ~zero;-
2135 }-
2136 }-
2137 byte >>= 1;-
2138 ++x;-
2139 }-
2140 } else {-
2141 for (int b = 8; b > 0 && x < w; --b) {-
2142 if (!(byte & 0x80) == !all) {-
2143-
2144 } else {-
2145-
2146 if (all != zero) {-
2147 { xr.setCoords(prev1, y, x-1, y); UnionRectWithRegion(&xr, region, *region); }-
2148 all = zero;-
2149 } else {-
2150 prev1 = x;-
2151 all = ~zero;-
2152 }-
2153 }-
2154 byte <<= 1;-
2155 ++x;-
2156 }-
2157 }-
2158 } else {-
2159 x += 8;-
2160 }-
2161 }-
2162 if (all != zero) {-
2163 { xr.setCoords(prev1, y, x-1, y); UnionRectWithRegion(&xr, region, *region); }-
2164 }-
2165 }-
2166-
2167-
2168 return region;-
2169}-
2170-
2171QRegion::QRegion()-
2172 : d(const_cast<QRegionData*>(&shared_empty))-
2173{-
2174}-
2175-
2176QRegion::QRegion(const QRect &r, RegionType t)-
2177{-
2178 if (r.isEmpty()) {-
2179 d = const_cast<QRegionData*>(&shared_empty);-
2180 } else {-
2181 d = new QRegionData;-
2182 d->ref.initializeOwned();-
2183 if (t == Rectangle) {-
2184 d->qt_rgn = new QRegionPrivate(r);-
2185 } else if (t == Ellipse) {-
2186 QPainterPath path;-
2187 path.addEllipse(r.x(), r.y(), r.width(), r.height());-
2188 QPolygon a = path.toSubpathPolygons().at(0).toPolygon();-
2189 d->qt_rgn = PolygonRegion(a.constData(), a.size(), 0);-
2190 }-
2191 }-
2192}-
2193-
2194QRegion::QRegion(const QPolygon &a, Qt::FillRule fillRule)-
2195{-
2196 if (a.count() > 2) {-
2197 QRegionPrivate *qt_rgn = PolygonRegion(a.constData(), a.size(),-
2198 fillRule == Qt::WindingFill ? 1 : 0);-
2199 if (qt_rgn) {-
2200 d = new QRegionData;-
2201 d->ref.initializeOwned();-
2202 d->qt_rgn = qt_rgn;-
2203 } else {-
2204 d = const_cast<QRegionData*>(&shared_empty);-
2205 }-
2206 } else {-
2207 d = const_cast<QRegionData*>(&shared_empty);-
2208 }-
2209}-
2210-
2211QRegion::QRegion(const QRegion &r)-
2212{-
2213 d = r.d;-
2214 d->ref.ref();-
2215}-
2216-
2217-
2218QRegion::QRegion(const QBitmap &bm)-
2219{-
2220 if (bm.isNull()) {-
2221 d = const_cast<QRegionData*>(&shared_empty);-
2222 } else {-
2223 d = new QRegionData;-
2224 d->ref.initializeOwned();-
2225 d->qt_rgn = qt_bitmapToRegion(bm);-
2226 }-
2227}-
2228-
2229void QRegion::cleanUp(QRegion::QRegionData *x)-
2230{-
2231 delete x->qt_rgn;-
2232 delete x;-
2233}-
2234-
2235QRegion::~QRegion()-
2236{-
2237 if (!d->ref.deref())-
2238 cleanUp(d);-
2239}-
2240-
2241-
2242QRegion &QRegion::operator=(const QRegion &r)-
2243{-
2244 r.d->ref.ref();-
2245 if (!d->ref.deref())-
2246 cleanUp(d);-
2247 d = r.d;-
2248 return *this;-
2249}-
2250-
2251-
2252-
2253-
2254-
2255QRegion QRegion::copy() const-
2256{-
2257 QRegion r;-
2258 QScopedPointer<QRegionData> x(new QRegionData);-
2259 x->ref.initializeOwned();-
2260 if (d->qt_rgn)-
2261 x->qt_rgn = new QRegionPrivate(*d->qt_rgn);-
2262 else-
2263 x->qt_rgn = new QRegionPrivate;-
2264 if (!r.d->ref.deref())-
2265 cleanUp(r.d);-
2266 r.d = x.take();-
2267 return r;-
2268}-
2269-
2270bool QRegion::isEmpty() const-
2271{-
2272 return d == &shared_empty || d->qt_rgn->numRects == 0;-
2273}-
2274-
2275bool QRegion::isNull() const-
2276{-
2277 return d == &shared_empty || d->qt_rgn->numRects == 0;-
2278}-
2279-
2280bool QRegion::contains(const QPoint &p) const-
2281{-
2282 return PointInRegion(d->qt_rgn, p.x(), p.y());-
2283}-
2284-
2285bool QRegion::contains(const QRect &r) const-
2286{-
2287 return RectInRegion(d->qt_rgn, r.left(), r.top(), r.width(), r.height()) != 0;-
2288}-
2289-
2290-
2291-
2292void QRegion::translate(int dx, int dy)-
2293{-
2294 if ((dx == 0 && dy == 0) || isEmptyHelper(d->qt_rgn))-
2295 return;-
2296-
2297 detach();-
2298 OffsetRegion(*d->qt_rgn, dx, dy);-
2299}-
2300-
2301QRegion QRegion::united(const QRegion &r) const-
2302{-
2303 if (isEmptyHelper(d->qt_rgn))-
2304 return r;-
2305 if (isEmptyHelper(r.d->qt_rgn))-
2306 return *this;-
2307 if (d == r.d)-
2308 return *this;-
2309-
2310 if (d->qt_rgn->contains(*r.d->qt_rgn)) {-
2311 return *this;-
2312 } else if (r.d->qt_rgn->contains(*d->qt_rgn)) {-
2313 return r;-
2314 } else if (d->qt_rgn->canAppend(r.d->qt_rgn)) {-
2315 QRegion result(*this);-
2316 result.detach();-
2317 result.d->qt_rgn->append(r.d->qt_rgn);-
2318 return result;-
2319 } else if (d->qt_rgn->canPrepend(r.d->qt_rgn)) {-
2320 QRegion result(*this);-
2321 result.detach();-
2322 result.d->qt_rgn->prepend(r.d->qt_rgn);-
2323 return result;-
2324 } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) {-
2325 return *this;-
2326 } else {-
2327 QRegion result;-
2328 result.detach();-
2329 UnionRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);-
2330 return result;-
2331 }-
2332}-
2333-
2334QRegion& QRegion::operator+=(const QRegion &r)-
2335{-
2336 if (isEmptyHelper(d->qt_rgn))-
2337 return *this = r;-
2338 if (isEmptyHelper(r.d->qt_rgn))-
2339 return *this;-
2340 if (d == r.d)-
2341 return *this;-
2342-
2343 if (d->qt_rgn->contains(*r.d->qt_rgn)) {-
2344 return *this;-
2345 } else if (r.d->qt_rgn->contains(*d->qt_rgn)) {-
2346 return *this = r;-
2347 } else if (d->qt_rgn->canAppend(r.d->qt_rgn)) {-
2348 detach();-
2349 d->qt_rgn->append(r.d->qt_rgn);-
2350 return *this;-
2351 } else if (d->qt_rgn->canPrepend(r.d->qt_rgn)) {-
2352 detach();-
2353 d->qt_rgn->prepend(r.d->qt_rgn);-
2354 return *this;-
2355 } else if (EqualRegion(d->qt_rgn, r.d->qt_rgn)) {-
2356 return *this;-
2357 } else {-
2358 detach();-
2359 UnionRegion(d->qt_rgn, r.d->qt_rgn, *d->qt_rgn);-
2360 return *this;-
2361 }-
2362}-
2363-
2364QRegion QRegion::united(const QRect &r) const-
2365{-
2366 if (isEmptyHelper(d->qt_rgn))-
2367 return r;-
2368 if (r.isEmpty())-
2369 return *this;-
2370-
2371 if (d->qt_rgn->contains(r)) {-
2372 return *this;-
2373 } else if (d->qt_rgn->within(r)) {-
2374 return r;-
2375 } else if (d->qt_rgn->numRects == 1 && d->qt_rgn->extents == r) {-
2376 return *this;-
2377 } else if (d->qt_rgn->canAppend(&r)) {-
2378 QRegion result(*this);-
2379 result.detach();-
2380 result.d->qt_rgn->append(&r);-
2381 return result;-
2382 } else if (d->qt_rgn->canPrepend(&r)) {-
2383 QRegion result(*this);-
2384 result.detach();-
2385 result.d->qt_rgn->prepend(&r);-
2386 return result;-
2387 } else {-
2388 QRegion result;-
2389 result.detach();-
2390 QRegionPrivate rp(r);-
2391 UnionRegion(d->qt_rgn, &rp, *result.d->qt_rgn);-
2392 return result;-
2393 }-
2394}-
2395-
2396QRegion& QRegion::operator+=(const QRect &r)-
2397{-
2398 if (isEmptyHelper(d->qt_rgn))-
2399 return *this = r;-
2400 if (r.isEmpty())-
2401 return *this;-
2402-
2403 if (d->qt_rgn->contains(r)) {-
2404 return *this;-
2405 } else if (d->qt_rgn->within(r)) {-
2406 return *this = r;-
2407 } else if (d->qt_rgn->canAppend(&r)) {-
2408 detach();-
2409 d->qt_rgn->append(&r);-
2410 return *this;-
2411 } else if (d->qt_rgn->canPrepend(&r)) {-
2412 detach();-
2413 d->qt_rgn->prepend(&r);-
2414 return *this;-
2415 } else if (d->qt_rgn->numRects == 1 && d->qt_rgn->extents == r) {-
2416 return *this;-
2417 } else {-
2418 detach();-
2419 QRegionPrivate p(r);-
2420 UnionRegion(d->qt_rgn, &p, *d->qt_rgn);-
2421 return *this;-
2422 }-
2423}-
2424-
2425QRegion QRegion::intersected(const QRegion &r) const-
2426{-
2427 if (isEmptyHelper(d->qt_rgn) || isEmptyHelper(r.d->qt_rgn)-
2428 || !((&d->qt_rgn->extents)->right() >= (&r.d->qt_rgn->extents)->left() && (&d->qt_rgn->extents)->left() <= (&r.d->qt_rgn->extents)->right() && (&d->qt_rgn->extents)->bottom() >= (&r.d->qt_rgn->extents)->top() && (&d->qt_rgn->extents)->top() <= (&r.d->qt_rgn->extents)->bottom()))-
2429 return QRegion();-
2430-
2431-
2432 if (r.d->qt_rgn->contains(*d->qt_rgn))-
2433 return *this;-
2434-
2435-
2436 if (d->qt_rgn->contains(*r.d->qt_rgn))-
2437 return r;-
2438-
2439 if (r.d->qt_rgn->numRects == 1 && d->qt_rgn->numRects == 1) {-
2440 const QRect rect = qt_rect_intersect_normalized(r.d->qt_rgn->extents,-
2441 d->qt_rgn->extents);-
2442 return QRegion(rect);-
2443 } else if (r.d->qt_rgn->numRects == 1) {-
2444 QRegion result(*this);-
2445 result.detach();-
2446 result.d->qt_rgn->intersect(r.d->qt_rgn->extents);-
2447 return result;-
2448 } else if (d->qt_rgn->numRects == 1) {-
2449 QRegion result(r);-
2450 result.detach();-
2451 result.d->qt_rgn->intersect(d->qt_rgn->extents);-
2452 return result;-
2453 }-
2454-
2455 QRegion result;-
2456 result.detach();-
2457 miRegionOp(*result.d->qt_rgn, d->qt_rgn, r.d->qt_rgn, miIntersectO, 0, 0);-
2458 miSetExtents(*result.d->qt_rgn);-
2459 return result;-
2460}-
2461-
2462QRegion QRegion::intersected(const QRect &r) const-
2463{-
2464 if (isEmptyHelper(d->qt_rgn) || r.isEmpty()-
2465 || !((&d->qt_rgn->extents)->right() >= (&r)->left() && (&d->qt_rgn->extents)->left() <= (&r)->right() && (&d->qt_rgn->extents)->bottom() >= (&r)->top() && (&d->qt_rgn->extents)->top() <= (&r)->bottom()))-
2466 return QRegion();-
2467-
2468-
2469 if (d->qt_rgn->within(r))-
2470 return *this;-
2471-
2472-
2473 if (d->qt_rgn->contains(r))-
2474 return r;-
2475-
2476 if (d->qt_rgn->numRects == 1) {-
2477 const QRect rect = qt_rect_intersect_normalized(d->qt_rgn->extents,-
2478 r.normalized());-
2479 return QRegion(rect);-
2480 }-
2481-
2482 QRegion result(*this);-
2483 result.detach();-
2484 result.d->qt_rgn->intersect(r);-
2485 return result;-
2486}-
2487-
2488QRegion QRegion::subtracted(const QRegion &r) const-
2489{-
2490 if (isEmptyHelper(d->qt_rgn) || isEmptyHelper(r.d->qt_rgn))-
2491 return *this;-
2492 if (r.d->qt_rgn->contains(*d->qt_rgn))-
2493 return QRegion();-
2494 if (!((&d->qt_rgn->extents)->right() >= (&r.d->qt_rgn->extents)->left() && (&d->qt_rgn->extents)->left() <= (&r.d->qt_rgn->extents)->right() && (&d->qt_rgn->extents)->bottom() >= (&r.d->qt_rgn->extents)->top() && (&d->qt_rgn->extents)->top() <= (&r.d->qt_rgn->extents)->bottom()))-
2495 return *this;-
2496 if (d == r.d || EqualRegion(d->qt_rgn, r.d->qt_rgn))-
2497 return QRegion();-
2498-
2499-
2500-
2501-
2502-
2503-
2504 QRegion result;-
2505 result.detach();-
2506 SubtractRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);-
2507-
2508-
2509-
2510 return result;-
2511}-
2512-
2513QRegion QRegion::xored(const QRegion &r) const-
2514{-
2515 if (isEmptyHelper(d->qt_rgn)) {-
2516 return r;-
2517 } else if (isEmptyHelper(r.d->qt_rgn)) {-
2518 return *this;-
2519 } else if (!((&d->qt_rgn->extents)->right() >= (&r.d->qt_rgn->extents)->left() && (&d->qt_rgn->extents)->left() <= (&r.d->qt_rgn->extents)->right() && (&d->qt_rgn->extents)->bottom() >= (&r.d->qt_rgn->extents)->top() && (&d->qt_rgn->extents)->top() <= (&r.d->qt_rgn->extents)->bottom())) {-
2520 return (*this + r);-
2521 } else if (d == r.d || EqualRegion(d->qt_rgn, r.d->qt_rgn)) {-
2522 return QRegion();-
2523 } else {-
2524 QRegion result;-
2525 result.detach();-
2526 XorRegion(d->qt_rgn, r.d->qt_rgn, *result.d->qt_rgn);-
2527 return result;-
2528 }-
2529}-
2530-
2531QRect QRegion::boundingRect() const-
2532{-
2533 if (isEmpty())-
2534 return QRect();-
2535 return d->qt_rgn->extents;-
2536}-
2537-
2538-
2539-
2540-
2541-
2542__attribute__((visibility("default")))-
2543bool qt_region_strictContains(const QRegion &region, const QRect &rect)-
2544{-
2545 if (isEmptyHelper(region.d->qt_rgn) || !rect.isValid())-
2546 return false;-
2547 const QRect r1 = region.d->qt_rgn->innerRect;-
2548 return (rect.left() >= r1.left() && rect.right() <= r1.right()-
2549 && rect.top() >= r1.top() && rect.bottom() <= r1.bottom());-
2550}-
2551-
2552QVector<QRect> QRegion::rects() const-
2553{-
2554 if (d->qt_rgn) {-
2555 d->qt_rgn->vectorize();-
2556 d->qt_rgn->rects.reserve(d->qt_rgn->numRects);-
2557 d->qt_rgn->rects.resize(d->qt_rgn->numRects);-
2558 return d->qt_rgn->rects;-
2559 } else {-
2560 return QVector<QRect>();-
2561 }-
2562}-
2563-
2564void QRegion::setRects(const QRect *rects, int num)-
2565{-
2566 *this = QRegion();-
2567 if (!rects || num == 0 || (num == 1 && rects->isEmpty()))-
2568 return;-
2569-
2570 detach();-
2571-
2572 d->qt_rgn->numRects = num;-
2573 if (num == 1) {-
2574 d->qt_rgn->extents = *rects;-
2575 d->qt_rgn->innerRect = *rects;-
2576 } else {-
2577 d->qt_rgn->rects.resize(num);-
2578-
2579 int left = 2147483647,-
2580 right = (-2147483647 - 1),-
2581 top = 2147483647,-
2582 bottom = (-2147483647 - 1);-
2583 for (int i = 0; i < num; ++i) {-
2584 const QRect &rect = rects[i];-
2585 d->qt_rgn->rects[i] = rect;-
2586 left = qMin(rect.left(), left);-
2587 right = qMax(rect.right(), right);-
2588 top = qMin(rect.top(), top);-
2589 bottom = qMax(rect.bottom(), bottom);-
2590 d->qt_rgn->updateInnerRect(rect);-
2591 }-
2592 d->qt_rgn->extents = QRect(QPoint(left, top), QPoint(right, bottom));-
2593 }-
2594}-
2595-
2596int QRegion::rectCount() const-
2597{-
2598 return (d->qt_rgn ? d->qt_rgn->numRects : 0);-
2599}-
2600-
2601-
2602bool QRegion::operator==(const QRegion &r) const-
2603{-
2604 if (!d->qt_rgn)-
2605 return r.isEmpty();-
2606 if (!r.d->qt_rgn)-
2607 return isEmpty();-
2608-
2609 if (d == r.d)-
2610 return true;-
2611 else-
2612 return EqualRegion(d->qt_rgn, r.d->qt_rgn);-
2613}-
2614-
2615bool QRegion::intersects(const QRect &rect) const-
2616{-
2617 if (isEmptyHelper(d->qt_rgn) || rect.isNull())-
2618 return false;-
2619-
2620 const QRect r = rect.normalized();-
2621 if (!rect_intersects(d->qt_rgn->extents, r))-
2622 return false;-
2623 if (d->qt_rgn->numRects == 1)-
2624 return true;-
2625-
2626 const QVector<QRect> myRects = rects();-
2627 for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it)-
2628 if (rect_intersects(r, *it))-
2629 return true;-
2630 return false;-
2631}-
2632-
2633-
2634-
2635-
Switch to Source codePreprocessed file

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