Qt 4.8
Classes | Macros | Typedefs | Functions
qregion.cpp File Reference
#include "qregion.h"
#include "qpainterpath.h"
#include "qpolygon.h"
#include "qbuffer.h"
#include "qdatastream.h"
#include "qvariant.h"
#include "qvarlengtharray.h"
#include <qdebug.h>
#include "qimage.h"
#include "qbitmap.h"
#include <stdlib.h>
#include "qregion_x11.cpp"
#include <limits.h>

Go to the source code of this file.

Classes

struct  _EdgeTableEntry
 
struct  _POINTBLOCK
 
struct  _ScanLineList
 
struct  _ScanLineListBlock
 
struct  BRESINFO
 
struct  EdgeTable
 
struct  QRegionPrivate
 
struct  QRegionSpan
 

Macros

#define _XREGION_H
 
#define AddSpan
 
#define BRESINCRPGON(d, minval, m, m1, incr1, incr2)
 
#define BRESINCRPGONSTRUCT(bres)   BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)
 
#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2)
 
#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres)
 
#define CLOCKWISE   1
 
#define COUNTERCLOCKWISE   -1
 
#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
 
#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
 
#define EvenOddRule   0
 
#define EXTENTCHECK(r1, r2)
 
#define EXTENTS(r, idRect)
 
#define LARGE_COORDINATE   INT_MAX
 
#define MEMCHECK(dest, rect, firstrect)
 
#define MERGERECT(r)
 
#define NUMPTSTOBUFFER   200
 
#define QRGN_AND   7
 
#define QRGN_OR   6
 
#define QRGN_RECTS   10
 
#define QRGN_SETELLIPSE   2
 
#define QRGN_SETPTARRAY_ALT   3
 
#define QRGN_SETPTARRAY_WIND   4
 
#define QRGN_SETRECT   1
 
#define QRGN_SUB   8
 
#define QRGN_TRANSLATE   5
 
#define QRGN_XOR   9
 
#define RectangleIn   1
 
#define RectangleOut   0
 
#define RectanglePart   2
 
#define SLLSPERBLOCK   25
 
#define SMALL_COORDINATE   INT_MIN
 
#define WindingRule   1
 

Typedefs

typedef struct _EdgeTableEntry EdgeTableEntry
 
typedef void(* NonOverlapFunc) (register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, register int y1, register int y2)
 
typedef void(* OverlapFunc) (register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, register const QRect *r2, const QRect *r2End, register int y1, register int y2)
 
typedef struct _POINTBLOCK POINTBLOCK
 
typedef struct _ScanLineList ScanLineList
 
typedef struct _ScanLineListBlock ScanLineListBlock
 

Functions

static bool canMergeFromBelow (const QRect *top, const QRect *bottom, const QRect *nextToTop, const QRect *nextToBottom)
 
static bool canMergeFromLeft (const QRect *right, const QRect *left)
 
static bool canMergeFromRight (const QRect *left, const QRect *right)
 
static void computeWAET (register EdgeTableEntry *AET)
 
static void CreateETandAET (register int count, register const QPoint *pts, EdgeTable *ET, EdgeTableEntry *AET, register EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
 
static bool EqualRegion (const QRegionPrivate *r1, const QRegionPrivate *r2)
 
static void flushRow (const QRegionSpan *spans, int y, int numSpans, QRegionPrivate *reg, int *lastRow, int *extendTo, bool *needsExtend)
 
static void FreeStorage (register ScanLineListBlock *pSLLBlock)
 
static void InsertEdgeInET (EdgeTable *ET, EdgeTableEntry *ETE, int scanline, ScanLineListBlock **SLLBlock, int *iSLLBlock)
 
static int InsertionSort (register EdgeTableEntry *AET)
 
static bool isEmptyHelper (const QRegionPrivate *preg)
 
static void loadAET (register EdgeTableEntry *AET, register EdgeTableEntry *ETEs)
 
static int miCoalesce (register QRegionPrivate &dest, int prevStart, int curStart)
 
static void miIntersectO (register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, register const QRect *r2, const QRect *r2End, int y1, int y2)
 
static void miRegionOp (register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2, OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func, NonOverlapFunc nonOverlap2Func)
 
static void miSetExtents (QRegionPrivate &dest)
 
static void miSubtractNonO1 (register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, register int y1, register int y2)
 
static void miSubtractO (register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, register const QRect *r2, const QRect *r2End, register int y1, register int y2)
 
static void miUnionNonO (register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, register int y1, register int y2)
 
static void miUnionO (register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, register const QRect *r2, const QRect *r2End, register int y1, register int y2)
 
static void OffsetRegion (register QRegionPrivate &region, register int x, register int y)
 
QDebug operator<< (QDebug s, const QRegion &r)
 
static bool PointInRegion (QRegionPrivate *pRegion, int x, int y)
 
static QRegionPrivatePolygonRegion (const QPoint *Pts, int Count, int rule)
 
static void PtsToRegion (register int numFullPtBlocks, register int iCurPtBlock, POINTBLOCK *FirstPtBlock, QRegionPrivate *reg)
 
 Q_DECLARE_TYPEINFO (QRegionSpan, Q_PRIMITIVE_TYPE)
 
QRegionPrivateqt_bitmapToRegion (const QBitmap &bitmap)
 
static QRect qt_rect_intersect_normalized (const QRect &r1, const QRect &r2)
 
Q_GUI_EXPORT bool qt_region_strictContains (const QRegion &region, const QRect &rect)
 Returns true if rect is guaranteed to be fully contained in region. More...
 
Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath (const QRegion &region)
 
bool rect_intersects (const QRect &r1, const QRect &r2)
 
static bool RectInRegion (register QRegionPrivate *region, int rx, int ry, uint rwidth, uint rheight)
 
static void SubtractRegion (QRegionPrivate *regM, QRegionPrivate *regS, register QRegionPrivate &dest)
 
static void UnionRectWithRegion (register const QRect *rect, const QRegionPrivate *source, QRegionPrivate &dest)
 
static void UnionRegion (const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest)
 
static void XorRegion (QRegionPrivate *sra, QRegionPrivate *srb, QRegionPrivate &dest)
 

Macro Definition Documentation

◆ _XREGION_H

#define _XREGION_H

Definition at line 1836 of file qregion.cpp.

◆ AddSpan

#define AddSpan
Value:
{ \
xr.setCoords(prev1, y, x-1, y); \
UnionRectWithRegion(&xr, region, *region); \
}

Referenced by qt_bitmapToRegion().

◆ BRESINCRPGON

#define BRESINCRPGON (   d,
  minval,
  m,
  m1,
  incr1,
  incr2 
)
Value:
{ \
if (m1 > 0) { \
if (d > 0) { \
minval += m1; \
d += incr1; \
} \
else { \
minval += m; \
d += incr2; \
} \
} else {\
if (d >= 0) { \
minval += m1; \
d += incr1; \
} \
else { \
minval += m; \
d += incr2; \
} \
} \
}
double d
Definition: qnumeric_p.h:62

Definition at line 3024 of file qregion.cpp.

◆ BRESINCRPGONSTRUCT

#define BRESINCRPGONSTRUCT (   bres)    BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)

Definition at line 3066 of file qregion.cpp.

◆ BRESINITPGON

#define BRESINITPGON (   dy,
  x1,
  x2,
  xStart,
  d,
  m,
  m1,
  incr1,
  incr2 
)
Value:
{ \
int dx; /* local storage */ \
\
/* \
* if the edge is horizontal, then it is ignored \
* and assumed not to be processed. Otherwise, do this stuff. \
*/ \
if ((dy) != 0) { \
xStart = (x1); \
dx = (x2) - xStart; \
if (dx < 0) { \
m = dx / (dy); \
m1 = m - 1; \
incr1 = -2 * dx + 2 * (dy) * m1; \
incr2 = -2 * dx + 2 * (dy) * m; \
d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
} else { \
m = dx / (dy); \
m1 = m + 1; \
incr1 = 2 * dx - 2 * (dy) * m1; \
incr2 = 2 * dx - 2 * (dy) * m; \
d = -2 * m * (dy) + 2 * dx; \
} \
} \
}

Definition at line 2998 of file qregion.cpp.

◆ BRESINITPGONSTRUCT

#define BRESINITPGONSTRUCT (   dmaj,
  min1,
  min2,
  bres 
)
Value:
BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \
bres.m, bres.m1, bres.incr1, bres.incr2)
#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2)
Definition: qregion.cpp:2998

Definition at line 3062 of file qregion.cpp.

Referenced by CreateETandAET().

◆ CLOCKWISE

#define CLOCKWISE   1

Definition at line 3120 of file qregion.cpp.

◆ COUNTERCLOCKWISE

#define COUNTERCLOCKWISE   -1

Definition at line 3121 of file qregion.cpp.

◆ EVALUATEEDGEEVENODD

#define EVALUATEEDGEEVENODD (   pAET,
  pPrevAET,
 
)
Value:
{ \
if (pAET->ymax == y) { /* leaving this edge */ \
pPrevAET->next = pAET->next; \
pAET = pPrevAET->next; \
if (pAET) \
pAET->back = pPrevAET; \
} \
else { \
BRESINCRPGONSTRUCT(pAET->bres) \
pPrevAET = pAET; \
pAET = pAET->next; \
} \
}

Definition at line 3197 of file qregion.cpp.

Referenced by PolygonRegion().

◆ EVALUATEEDGEWINDING

#define EVALUATEEDGEWINDING (   pAET,
  pPrevAET,
  y,
  fixWAET 
)
Value:
{ \
if (pAET->ymax == y) { /* leaving this edge */ \
pPrevAET->next = pAET->next; \
pAET = pPrevAET->next; \
fixWAET = 1; \
if (pAET) \
pAET->back = pPrevAET; \
} \
else { \
BRESINCRPGONSTRUCT(pAET->bres) \
pPrevAET = pAET; \
pAET = pAET->next; \
} \
}

Definition at line 3174 of file qregion.cpp.

Referenced by PolygonRegion().

◆ EvenOddRule

#define EvenOddRule   0

◆ EXTENTCHECK

#define EXTENTCHECK (   r1,
  r2 
)
Value:
((r1)->right() >= (r2)->left() && \
(r1)->left() <= (r2)->right() && \
(r1)->bottom() >= (r2)->top() && \
(r1)->top() <= (r2)->bottom())
QTextStream & right(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignRight) on stream and returns stream...
QTextStream & left(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignLeft) on stream and returns stream...

Definition at line 1846 of file qregion.cpp.

Referenced by QRegion::eor(), QRegion::intersect(), RectInRegion(), QRegion::subtract(), SubtractRegion(), and XorRegion().

◆ EXTENTS

#define EXTENTS (   r,
  idRect 
)
Value:
{\
if((r)->left() < (idRect)->extents.left())\
(idRect)->extents.setLeft((r)->left());\
if((r)->top() < (idRect)->extents.top())\
(idRect)->extents.setTop((r)->top());\
if((r)->right() > (idRect)->extents.right())\
(idRect)->extents.setRight((r)->right());\
if((r)->bottom() > (idRect)->extents.bottom())\
(idRect)->extents.setBottom((r)->bottom());\
}
QTextStream & right(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignRight) on stream and returns stream...
QTextStream & left(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignLeft) on stream and returns stream...

Definition at line 1855 of file qregion.cpp.

◆ LARGE_COORDINATE

#define LARGE_COORDINATE   INT_MAX

Definition at line 3262 of file qregion.cpp.

Referenced by CreateETandAET().

◆ MEMCHECK

#define MEMCHECK (   dest,
  rect,
  firstrect 
)
Value:
{\
if ((dest).numRects >= ((dest).rects.size()-1)){\
firstrect.resize(firstrect.size() * 2); \
(rect) = (firstrect).data() + (dest).numRects;\
}\
}

Definition at line 1869 of file qregion.cpp.

Referenced by miIntersectO(), miSubtractNonO1(), miSubtractO(), and miUnionNonO().

◆ MERGERECT

#define MERGERECT (   r)
Value:
if ((dest.numRects != 0) && \
(pNextRect[-1].top() == y1) && \
(pNextRect[-1].bottom() == y2) && \
(pNextRect[-1].right() >= r->left()-1)) { \
if (pNextRect[-1].right() < r->right()) { \
pNextRect[-1].setRight(r->right()); \
dest.updateInnerRect(pNextRect[-1]); \
Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \
} \
} else { \
MEMCHECK(dest, pNextRect, dest.rects) \
pNextRect->setCoords(r->left(), y1, r->right(), y2); \
dest.updateInnerRect(*pNextRect); \
dest.numRects++; \
pNextRect++; \
} \
r++;
QTextStream & right(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignRight) on stream and returns stream...
QTextStream & left(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignLeft) on stream and returns stream...

Referenced by miUnionO().

◆ NUMPTSTOBUFFER

#define NUMPTSTOBUFFER   200

Definition at line 1881 of file qregion.cpp.

Referenced by PolygonRegion(), and PtsToRegion().

◆ QRGN_AND

#define QRGN_AND   7

Definition at line 319 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_OR

#define QRGN_OR   6

Definition at line 318 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_RECTS

#define QRGN_RECTS   10

Definition at line 322 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_SETELLIPSE

#define QRGN_SETELLIPSE   2

Definition at line 314 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_SETPTARRAY_ALT

#define QRGN_SETPTARRAY_ALT   3

Definition at line 315 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_SETPTARRAY_WIND

#define QRGN_SETPTARRAY_WIND   4

Definition at line 316 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_SETRECT

#define QRGN_SETRECT   1

Definition at line 313 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_SUB

#define QRGN_SUB   8

Definition at line 320 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_TRANSLATE

#define QRGN_TRANSLATE   5

Definition at line 317 of file qregion.cpp.

Referenced by QRegion::exec().

◆ QRGN_XOR

#define QRGN_XOR   9

Definition at line 321 of file qregion.cpp.

Referenced by QRegion::exec().

◆ RectangleIn

#define RectangleIn   1

Definition at line 1780 of file qregion.cpp.

Referenced by RectInRegion().

◆ RectangleOut

#define RectangleOut   0

Definition at line 1779 of file qregion.cpp.

Referenced by QRegion::contains(), and RectInRegion().

◆ RectanglePart

#define RectanglePart   2

Definition at line 1781 of file qregion.cpp.

Referenced by RectInRegion().

◆ SLLSPERBLOCK

#define SLLSPERBLOCK   25

Definition at line 3152 of file qregion.cpp.

Referenced by InsertEdgeInET().

◆ SMALL_COORDINATE

#define SMALL_COORDINATE   INT_MIN

Definition at line 3263 of file qregion.cpp.

Referenced by CreateETandAET().

◆ WindingRule

#define WindingRule   1

Definition at line 1783 of file qregion.cpp.

Referenced by QX11PaintEnginePrivate::fillPolygon_dev(), and QRegion::QRegion().

Typedef Documentation

◆ EdgeTableEntry

◆ NonOverlapFunc

typedef void(* NonOverlapFunc) (register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, register int y1, register int y2)

Definition at line 1770 of file qregion.cpp.

◆ OverlapFunc

typedef void(* OverlapFunc) (register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, register const QRect *r2, const QRect *r2End, register int y1, register int y2)

Definition at line 1768 of file qregion.cpp.

◆ POINTBLOCK

typedef struct _POINTBLOCK POINTBLOCK

◆ ScanLineList

typedef struct _ScanLineList ScanLineList

◆ ScanLineListBlock

Function Documentation

◆ canMergeFromBelow()

static bool canMergeFromBelow ( const QRect top,
const QRect bottom,
const QRect nextToTop,
const QRect nextToBottom 
)
inlinestatic

Definition at line 1358 of file qregion.cpp.

Referenced by QRegionPrivate::intersect(), QRegionPrivate::mergeFromAbove(), and QRegionPrivate::mergeFromBelow().

1361 {
1362  if (nextToTop && nextToTop->y() == top->y())
1363  return false;
1364  if (nextToBottom && nextToBottom->y() == bottom->y())
1365  return false;
1366 
1367  return ((top->bottom() >= (bottom->top() - 1))
1368  && top->left() == bottom->left()
1369  && top->right() == bottom->right());
1370 }
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255

◆ canMergeFromLeft()

static bool canMergeFromLeft ( const QRect right,
const QRect left 
)
inlinestatic

Definition at line 1333 of file qregion.cpp.

Referenced by QRegionPrivate::mergeFromLeft().

1334 {
1335  return canMergeFromRight(left, right);
1336 }
static bool canMergeFromRight(const QRect *left, const QRect *right)
Definition: qregion.cpp:1326

◆ canMergeFromRight()

static bool canMergeFromRight ( const QRect left,
const QRect right 
)
inlinestatic

Definition at line 1326 of file qregion.cpp.

Referenced by canMergeFromLeft(), and QRegionPrivate::mergeFromRight().

1327 {
1328  return (right->top() == left->top()
1329  && right->bottom() == left->bottom()
1330  && right->left() <= (left->right() + 1));
1331 }
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246

◆ computeWAET()

static void computeWAET ( register EdgeTableEntry AET)
static

Definition at line 3486 of file qregion.cpp.

Referenced by PolygonRegion().

3487 {
3488  register EdgeTableEntry *pWETE;
3489  register int inside = 1;
3490  register int isInside = 0;
3491 
3492  AET->nextWETE = 0;
3493  pWETE = AET;
3494  AET = AET->next;
3495  while (AET) {
3496  if (AET->ClockWise)
3497  ++isInside;
3498  else
3499  --isInside;
3500 
3501  if ((!inside && !isInside) || (inside && isInside)) {
3502  pWETE->nextWETE = AET;
3503  pWETE = AET;
3504  inside = !inside;
3505  }
3506  AET = AET->next;
3507  }
3508  pWETE->nextWETE = 0;
3509 }
struct _EdgeTableEntry * nextWETE
Definition: qregion.cpp:3128
struct _EdgeTableEntry * next
Definition: qregion.cpp:3126

◆ CreateETandAET()

static void CreateETandAET ( register int  count,
register const QPoint pts,
EdgeTable ET,
EdgeTableEntry AET,
register EdgeTableEntry pETEs,
ScanLineListBlock pSLLBlock 
)
static

Definition at line 3355 of file qregion.cpp.

Referenced by PolygonRegion().

3358 {
3359  register const QPoint *top,
3360  *bottom,
3361  *PrevPt,
3362  *CurrPt;
3363  int iSLLBlock = 0;
3364  int dy;
3365 
3366  if (count < 2)
3367  return;
3368 
3369  /*
3370  * initialize the Active Edge Table
3371  */
3372  AET->next = 0;
3373  AET->back = 0;
3374  AET->nextWETE = 0;
3376 
3377  /*
3378  * initialize the Edge Table.
3379  */
3380  ET->scanlines.next = 0;
3381  ET->ymax = SMALL_COORDINATE;
3382  ET->ymin = LARGE_COORDINATE;
3383  pSLLBlock->next = 0;
3384 
3385  PrevPt = &pts[count - 1];
3386 
3387  /*
3388  * for each vertex in the array of points.
3389  * In this loop we are dealing with two vertices at
3390  * a time -- these make up one edge of the polygon.
3391  */
3392  while (count--) {
3393  CurrPt = pts++;
3394 
3395  /*
3396  * find out which point is above and which is below.
3397  */
3398  if (PrevPt->y() > CurrPt->y()) {
3399  bottom = PrevPt;
3400  top = CurrPt;
3401  pETEs->ClockWise = 0;
3402  } else {
3403  bottom = CurrPt;
3404  top = PrevPt;
3405  pETEs->ClockWise = 1;
3406  }
3407 
3408  /*
3409  * don't add horizontal edges to the Edge table.
3410  */
3411  if (bottom->y() != top->y()) {
3412  pETEs->ymax = bottom->y() - 1; /* -1 so we don't get last scanline */
3413 
3414  /*
3415  * initialize integer edge algorithm
3416  */
3417  dy = bottom->y() - top->y();
3418  BRESINITPGONSTRUCT(dy, top->x(), bottom->x(), pETEs->bres)
3419 
3420  InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock);
3421 
3422  if (PrevPt->y() > ET->ymax)
3423  ET->ymax = PrevPt->y();
3424  if (PrevPt->y() < ET->ymin)
3425  ET->ymin = PrevPt->y();
3426  ++pETEs;
3427  }
3428 
3429  PrevPt = CurrPt;
3430  }
3431 }
struct _ScanLineList * next
Definition: qregion.cpp:3136
int minor_axis
Definition: qregion.cpp:3055
#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres)
Definition: qregion.cpp:3062
struct _EdgeTableEntry * back
Definition: qregion.cpp:3127
ScanLineList scanlines
Definition: qregion.cpp:3143
struct _EdgeTableEntry * nextWETE
Definition: qregion.cpp:3128
BRESINFO bres
Definition: qregion.cpp:3125
struct _ScanLineListBlock * next
Definition: qregion.cpp:3156
#define LARGE_COORDINATE
Definition: qregion.cpp:3262
static void InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline, ScanLineListBlock **SLLBlock, int *iSLLBlock)
Definition: qregion.cpp:3274
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
struct _EdgeTableEntry * next
Definition: qregion.cpp:3126
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
#define SMALL_COORDINATE
Definition: qregion.cpp:3263

◆ EqualRegion()

static bool EqualRegion ( const QRegionPrivate r1,
const QRegionPrivate r2 
)
static

Definition at line 2810 of file qregion.cpp.

Referenced by QRegion::eor(), QRegion::operator+=(), QRegion::operator==(), QRegion::subtract(), SubtractRegion(), UnionRectWithRegion(), UnionRegion(), QRegion::unite(), and XorRegion().

2811 {
2812  if (r1->numRects != r2->numRects) {
2813  return false;
2814  } else if (r1->numRects == 0) {
2815  return true;
2816  } else if (r1->extents != r2->extents) {
2817  return false;
2818  } else if (r1->numRects == 1 && r2->numRects == 1) {
2819  return true; // equality tested in previous if-statement
2820  } else {
2821  const QRect *rr1 = (r1->numRects == 1) ? &r1->extents : r1->rects.constData();
2822  const QRect *rr2 = (r2->numRects == 1) ? &r2->extents : r2->rects.constData();
2823  for (int i = 0; i < r1->numRects; ++i, ++rr1, ++rr2) {
2824  if (*rr1 != *rr2)
2825  return false;
2826  }
2827  }
2828 
2829  return true;
2830 }
QVector< QRect > rects
Definition: qregion.cpp:1227
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154

◆ flushRow()

static void flushRow ( const QRegionSpan spans,
int  y,
int  numSpans,
QRegionPrivate reg,
int *  lastRow,
int *  extendTo,
bool *  needsExtend 
)
inlinestatic

Definition at line 3575 of file qregion.cpp.

Referenced by PtsToRegion().

3576 {
3577  QRect *regRects = reg->rects.data() + *lastRow;
3578  bool canExtend = reg->rects.size() - *lastRow == numSpans
3579  && !(*needsExtend && *extendTo + 1 != y)
3580  && (*needsExtend || regRects[0].y() + regRects[0].height() == y);
3581 
3582  for (int i = 0; i < numSpans && canExtend; ++i) {
3583  if (regRects[i].x() != spans[i].x1 || regRects[i].right() != spans[i].x2 - 1)
3584  canExtend = false;
3585  }
3586 
3587  if (canExtend) {
3588  *extendTo = y;
3589  *needsExtend = true;
3590  } else {
3591  if (*needsExtend) {
3592  for (int i = 0; i < reg->rects.size() - *lastRow; ++i)
3593  regRects[i].setBottom(*extendTo);
3594  }
3595 
3596  *lastRow = reg->rects.size();
3597  reg->rects.reserve(*lastRow + numSpans);
3598  for (int i = 0; i < numSpans; ++i)
3599  reg->rects << QRect(spans[i].x1, y, spans[i].width(), 1);
3600 
3601  if (spans[0].x1 < reg->extents.left())
3602  reg->extents.setLeft(spans[0].x1);
3603 
3604  if (spans[numSpans-1].x2 - 1 > reg->extents.right())
3605  reg->extents.setRight(spans[numSpans-1].x2 - 1);
3606 
3607  *needsExtend = false;
3608  }
3609 }
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
void setRight(int pos)
Sets the right edge of the rectangle to the given x coordinate.
Definition: qrect.h:264
QVector< QRect > rects
Definition: qregion.cpp:1227
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
void setLeft(int pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:258
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
void reserve(int size)
Attempts to allocate memory for at least size elements.
Definition: qvector.h:339
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ FreeStorage()

static void FreeStorage ( register ScanLineListBlock pSLLBlock)
static

Definition at line 3553 of file qregion.cpp.

Referenced by PolygonRegion().

3554 {
3555  register ScanLineListBlock *tmpSLLBlock;
3556 
3557  while (pSLLBlock) {
3558  tmpSLLBlock = pSLLBlock->next;
3559  free(pSLLBlock);
3560  pSLLBlock = tmpSLLBlock;
3561  }
3562 }
struct _ScanLineListBlock * next
Definition: qregion.cpp:3156

◆ InsertEdgeInET()

static void InsertEdgeInET ( EdgeTable ET,
EdgeTableEntry ETE,
int  scanline,
ScanLineListBlock **  SLLBlock,
int *  iSLLBlock 
)
static

Definition at line 3274 of file qregion.cpp.

Referenced by CreateETandAET().

3276 {
3277  register EdgeTableEntry *start, *prev;
3278  register ScanLineList *pSLL, *pPrevSLL;
3279  ScanLineListBlock *tmpSLLBlock;
3280 
3281  /*
3282  * find the right bucket to put the edge into
3283  */
3284  pPrevSLL = &ET->scanlines;
3285  pSLL = pPrevSLL->next;
3286  while (pSLL && (pSLL->scanline < scanline)) {
3287  pPrevSLL = pSLL;
3288  pSLL = pSLL->next;
3289  }
3290 
3291  /*
3292  * reassign pSLL (pointer to ScanLineList) if necessary
3293  */
3294  if ((!pSLL) || (pSLL->scanline > scanline)) {
3295  if (*iSLLBlock > SLLSPERBLOCK-1)
3296  {
3297  tmpSLLBlock =
3298  (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));
3299  Q_CHECK_PTR(tmpSLLBlock);
3300  (*SLLBlock)->next = tmpSLLBlock;
3301  tmpSLLBlock->next = (ScanLineListBlock *)NULL;
3302  *SLLBlock = tmpSLLBlock;
3303  *iSLLBlock = 0;
3304  }
3305  pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
3306 
3307  pSLL->next = pPrevSLL->next;
3308  pSLL->edgelist = (EdgeTableEntry *)NULL;
3309  pPrevSLL->next = pSLL;
3310  }
3311  pSLL->scanline = scanline;
3312 
3313  /*
3314  * now insert the edge in the right bucket
3315  */
3316  prev = 0;
3317  start = pSLL->edgelist;
3318  while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) {
3319  prev = start;
3320  start = start->next;
3321  }
3322  ETE->next = start;
3323 
3324  if (prev)
3325  prev->next = ETE;
3326  else
3327  pSLL->edgelist = ETE;
3328 }
struct _ScanLineList * next
Definition: qregion.cpp:3136
int minor_axis
Definition: qregion.cpp:3055
ScanLineList scanlines
Definition: qregion.cpp:3143
BRESINFO bres
Definition: qregion.cpp:3125
struct _ScanLineListBlock * next
Definition: qregion.cpp:3156
#define SLLSPERBLOCK
Definition: qregion.cpp:3152
EdgeTableEntry * edgelist
Definition: qregion.cpp:3135
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
struct _EdgeTableEntry * next
Definition: qregion.cpp:3126

◆ InsertionSort()

static int InsertionSort ( register EdgeTableEntry AET)
static

Definition at line 3520 of file qregion.cpp.

Referenced by PolygonRegion().

3521 {
3522  register EdgeTableEntry *pETEchase;
3523  register EdgeTableEntry *pETEinsert;
3524  register EdgeTableEntry *pETEchaseBackTMP;
3525  register int changed = 0;
3526 
3527  AET = AET->next;
3528  while (AET) {
3529  pETEinsert = AET;
3530  pETEchase = AET;
3531  while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
3532  pETEchase = pETEchase->back;
3533 
3534  AET = AET->next;
3535  if (pETEchase != pETEinsert) {
3536  pETEchaseBackTMP = pETEchase->back;
3537  pETEinsert->back->next = AET;
3538  if (AET)
3539  AET->back = pETEinsert->back;
3540  pETEinsert->next = pETEchase;
3541  pETEchase->back->next = pETEinsert;
3542  pETEchase->back = pETEinsert;
3543  pETEinsert->back = pETEchaseBackTMP;
3544  changed = 1;
3545  }
3546  }
3547  return changed;
3548 }
int minor_axis
Definition: qregion.cpp:3055
struct _EdgeTableEntry * back
Definition: qregion.cpp:3127
BRESINFO bres
Definition: qregion.cpp:3125
struct _EdgeTableEntry * next
Definition: qregion.cpp:3126

◆ isEmptyHelper()

static bool isEmptyHelper ( const QRegionPrivate preg)
inlinestatic

◆ loadAET()

static void loadAET ( register EdgeTableEntry AET,
register EdgeTableEntry ETEs 
)
static

Definition at line 3442 of file qregion.cpp.

Referenced by PolygonRegion().

3443 {
3444  register EdgeTableEntry *pPrevAET;
3445  register EdgeTableEntry *tmp;
3446 
3447  pPrevAET = AET;
3448  AET = AET->next;
3449  while (ETEs) {
3450  while (AET && AET->bres.minor_axis < ETEs->bres.minor_axis) {
3451  pPrevAET = AET;
3452  AET = AET->next;
3453  }
3454  tmp = ETEs->next;
3455  ETEs->next = AET;
3456  if (AET)
3457  AET->back = ETEs;
3458  ETEs->back = pPrevAET;
3459  pPrevAET->next = ETEs;
3460  pPrevAET = ETEs;
3461 
3462  ETEs = tmp;
3463  }
3464 }
struct _EdgeTableEntry * back
Definition: qregion.cpp:3127
struct _EdgeTableEntry * next
Definition: qregion.cpp:3126

◆ miCoalesce()

static int miCoalesce ( register QRegionPrivate dest,
int  prevStart,
int  curStart 
)
static

Definition at line 2150 of file qregion.cpp.

Referenced by miRegionOp().

2151 {
2152  register QRect *pPrevBox; /* Current box in previous band */
2153  register QRect *pCurBox; /* Current box in current band */
2154  register QRect *pRegEnd; /* End of region */
2155  int curNumRects; /* Number of rectangles in current band */
2156  int prevNumRects; /* Number of rectangles in previous band */
2157  int bandY1; /* Y1 coordinate for current band */
2158  QRect *rData = dest.rects.data();
2159 
2160  pRegEnd = rData + dest.numRects;
2161 
2162  pPrevBox = rData + prevStart;
2163  prevNumRects = curStart - prevStart;
2164 
2165  /*
2166  * Figure out how many rectangles are in the current band. Have to do
2167  * this because multiple bands could have been added in miRegionOp
2168  * at the end when one region has been exhausted.
2169  */
2170  pCurBox = rData + curStart;
2171  bandY1 = pCurBox->top();
2172  for (curNumRects = 0; pCurBox != pRegEnd && pCurBox->top() == bandY1; ++curNumRects) {
2173  ++pCurBox;
2174  }
2175 
2176  if (pCurBox != pRegEnd) {
2177  /*
2178  * If more than one band was added, we have to find the start
2179  * of the last band added so the next coalescing job can start
2180  * at the right place... (given when multiple bands are added,
2181  * this may be pointless -- see above).
2182  */
2183  --pRegEnd;
2184  while ((pRegEnd - 1)->top() == pRegEnd->top())
2185  --pRegEnd;
2186  curStart = pRegEnd - rData;
2187  pRegEnd = rData + dest.numRects;
2188  }
2189 
2190  if (curNumRects == prevNumRects && curNumRects != 0) {
2191  pCurBox -= curNumRects;
2192  /*
2193  * The bands may only be coalesced if the bottom of the previous
2194  * matches the top scanline of the current.
2195  */
2196  if (pPrevBox->bottom() == pCurBox->top() - 1) {
2197  /*
2198  * Make sure the bands have boxes in the same places. This
2199  * assumes that boxes have been added in such a way that they
2200  * cover the most area possible. I.e. two boxes in a band must
2201  * have some horizontal space between them.
2202  */
2203  do {
2204  if (pPrevBox->left() != pCurBox->left() || pPrevBox->right() != pCurBox->right()) {
2205  // The bands don't line up so they can't be coalesced.
2206  return curStart;
2207  }
2208  ++pPrevBox;
2209  ++pCurBox;
2210  --prevNumRects;
2211  } while (prevNumRects != 0);
2212 
2213  dest.numRects -= curNumRects;
2214  pCurBox -= curNumRects;
2215  pPrevBox -= curNumRects;
2216 
2217  /*
2218  * The bands may be merged, so set the bottom y of each box
2219  * in the previous band to that of the corresponding box in
2220  * the current band.
2221  */
2222  do {
2223  pPrevBox->setBottom(pCurBox->bottom());
2224  dest.updateInnerRect(*pPrevBox);
2225  ++pPrevBox;
2226  ++pCurBox;
2227  curNumRects -= 1;
2228  } while (curNumRects != 0);
2229 
2230  /*
2231  * If only one band was added to the region, we have to backup
2232  * curStart to the start of the previous band.
2233  *
2234  * If more than one band was added to the region, copy the
2235  * other bands down. The assumption here is that the other bands
2236  * came from the same region as the current one and no further
2237  * coalescing can be done on them since it's all been done
2238  * already... curStart is already in the right place.
2239  */
2240  if (pCurBox == pRegEnd) {
2241  curStart = prevStart;
2242  } else {
2243  do {
2244  *pPrevBox++ = *pCurBox++;
2245  dest.updateInnerRect(*pPrevBox);
2246  } while (pCurBox != pRegEnd);
2247  }
2248  }
2249  }
2250  return curStart;
2251 }
void setBottom(int pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:267
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58

◆ miIntersectO()

static void miIntersectO ( register QRegionPrivate dest,
register const QRect r1,
const QRect r1End,
register const QRect r2,
const QRect r2End,
int  y1,
int  y2 
)
static

Definition at line 2085 of file qregion.cpp.

Referenced by QRegion::intersect().

2087 {
2088  register int x1;
2089  register int x2;
2090  register QRect *pNextRect;
2091 
2092  pNextRect = dest.rects.data() + dest.numRects;
2093 
2094  while (r1 != r1End && r2 != r2End) {
2095  x1 = qMax(r1->left(), r2->left());
2096  x2 = qMin(r1->right(), r2->right());
2097 
2098  /*
2099  * If there's any overlap between the two rectangles, add that
2100  * overlap to the new region.
2101  * There's no need to check for subsumption because the only way
2102  * such a need could arise is if some region has two rectangles
2103  * right next to each other. Since that should never happen...
2104  */
2105  if (x1 <= x2) {
2106  Q_ASSERT(y1 <= y2);
2107  MEMCHECK(dest, pNextRect, dest.rects)
2108  pNextRect->setCoords(x1, y1, x2, y2);
2109  ++dest.numRects;
2110  ++pNextRect;
2111  }
2112 
2113  /*
2114  * Need to advance the pointers. Shift the one that extends
2115  * to the right the least, since the other still has a chance to
2116  * overlap with that region's next rectangle, if you see what I mean.
2117  */
2118  if (r1->right() < r2->right()) {
2119  ++r1;
2120  } else if (r2->right() < r1->right()) {
2121  ++r2;
2122  } else {
2123  ++r1;
2124  ++r2;
2125  }
2126  }
2127 }
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QTextStream & right(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignRight) on stream and returns stream...
static void setCoords(GLfloat *coords, const QGLRect &rect)
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
#define MEMCHECK(dest, rect, firstrect)
Definition: qregion.cpp:1869

◆ miRegionOp()

static void miRegionOp ( register QRegionPrivate dest,
const QRegionPrivate reg1,
const QRegionPrivate reg2,
OverlapFunc  overlapFunc,
NonOverlapFunc  nonOverlap1Func,
NonOverlapFunc  nonOverlap2Func 
)
static

Definition at line 2279 of file qregion.cpp.

Referenced by QRegion::intersect(), SubtractRegion(), and UnionRegion().

2283 {
2284  register const QRect *r1; // Pointer into first region
2285  register const QRect *r2; // Pointer into 2d region
2286  const QRect *r1End; // End of 1st region
2287  const QRect *r2End; // End of 2d region
2288  register int ybot; // Bottom of intersection
2289  register int ytop; // Top of intersection
2290  int prevBand; // Index of start of previous band in dest
2291  int curBand; // Index of start of current band in dest
2292  register const QRect *r1BandEnd; // End of current band in r1
2293  register const QRect *r2BandEnd; // End of current band in r2
2294  int top; // Top of non-overlapping band
2295  int bot; // Bottom of non-overlapping band
2296 
2297  /*
2298  * Initialization:
2299  * set r1, r2, r1End and r2End appropriately, preserve the important
2300  * parts of the destination region until the end in case it's one of
2301  * the two source regions, then mark the "new" region empty, allocating
2302  * another array of rectangles for it to use.
2303  */
2304  if (reg1->numRects == 1)
2305  r1 = &reg1->extents;
2306  else
2307  r1 = reg1->rects.constData();
2308  if (reg2->numRects == 1)
2309  r2 = &reg2->extents;
2310  else
2311  r2 = reg2->rects.constData();
2312 
2313  r1End = r1 + reg1->numRects;
2314  r2End = r2 + reg2->numRects;
2315 
2316  dest.vectorize();
2317 
2318  QVector<QRect> oldRects = dest.rects;
2319 
2320  dest.numRects = 0;
2321 
2322  /*
2323  * Allocate a reasonable number of rectangles for the new region. The idea
2324  * is to allocate enough so the individual functions don't need to
2325  * reallocate and copy the array, which is time consuming, yet we don't
2326  * have to worry about using too much memory. I hope to be able to
2327  * nuke the realloc() at the end of this function eventually.
2328  */
2329  dest.rects.resize(qMax(reg1->numRects,reg2->numRects) * 2);
2330 
2331  /*
2332  * Initialize ybot and ytop.
2333  * In the upcoming loop, ybot and ytop serve different functions depending
2334  * on whether the band being handled is an overlapping or non-overlapping
2335  * band.
2336  * In the case of a non-overlapping band (only one of the regions
2337  * has points in the band), ybot is the bottom of the most recent
2338  * intersection and thus clips the top of the rectangles in that band.
2339  * ytop is the top of the next intersection between the two regions and
2340  * serves to clip the bottom of the rectangles in the current band.
2341  * For an overlapping band (where the two regions intersect), ytop clips
2342  * the top of the rectangles of both regions and ybot clips the bottoms.
2343  */
2344  if (reg1->extents.top() < reg2->extents.top())
2345  ybot = reg1->extents.top() - 1;
2346  else
2347  ybot = reg2->extents.top() - 1;
2348 
2349  /*
2350  * prevBand serves to mark the start of the previous band so rectangles
2351  * can be coalesced into larger rectangles. qv. miCoalesce, above.
2352  * In the beginning, there is no previous band, so prevBand == curBand
2353  * (curBand is set later on, of course, but the first band will always
2354  * start at index 0). prevBand and curBand must be indices because of
2355  * the possible expansion, and resultant moving, of the new region's
2356  * array of rectangles.
2357  */
2358  prevBand = 0;
2359 
2360  do {
2361  curBand = dest.numRects;
2362 
2363  /*
2364  * This algorithm proceeds one source-band (as opposed to a
2365  * destination band, which is determined by where the two regions
2366  * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
2367  * rectangle after the last one in the current band for their
2368  * respective regions.
2369  */
2370  r1BandEnd = r1;
2371  while (r1BandEnd != r1End && r1BandEnd->top() == r1->top())
2372  ++r1BandEnd;
2373 
2374  r2BandEnd = r2;
2375  while (r2BandEnd != r2End && r2BandEnd->top() == r2->top())
2376  ++r2BandEnd;
2377 
2378  /*
2379  * First handle the band that doesn't intersect, if any.
2380  *
2381  * Note that attention is restricted to one band in the
2382  * non-intersecting region at once, so if a region has n
2383  * bands between the current position and the next place it overlaps
2384  * the other, this entire loop will be passed through n times.
2385  */
2386  if (r1->top() < r2->top()) {
2387  top = qMax(r1->top(), ybot + 1);
2388  bot = qMin(r1->bottom(), r2->top() - 1);
2389 
2390  if (nonOverlap1Func != 0 && bot >= top)
2391  (*nonOverlap1Func)(dest, r1, r1BandEnd, top, bot);
2392  ytop = r2->top();
2393  } else if (r2->top() < r1->top()) {
2394  top = qMax(r2->top(), ybot + 1);
2395  bot = qMin(r2->bottom(), r1->top() - 1);
2396 
2397  if (nonOverlap2Func != 0 && bot >= top)
2398  (*nonOverlap2Func)(dest, r2, r2BandEnd, top, bot);
2399  ytop = r1->top();
2400  } else {
2401  ytop = r1->top();
2402  }
2403 
2404  /*
2405  * If any rectangles got added to the region, try and coalesce them
2406  * with rectangles from the previous band. Note we could just do
2407  * this test in miCoalesce, but some machines incur a not
2408  * inconsiderable cost for function calls, so...
2409  */
2410  if (dest.numRects != curBand)
2411  prevBand = miCoalesce(dest, prevBand, curBand);
2412 
2413  /*
2414  * Now see if we've hit an intersecting band. The two bands only
2415  * intersect if ybot >= ytop
2416  */
2417  ybot = qMin(r1->bottom(), r2->bottom());
2418  curBand = dest.numRects;
2419  if (ybot >= ytop)
2420  (*overlapFunc)(dest, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
2421 
2422  if (dest.numRects != curBand)
2423  prevBand = miCoalesce(dest, prevBand, curBand);
2424 
2425  /*
2426  * If we've finished with a band (y2 == ybot) we skip forward
2427  * in the region to the next band.
2428  */
2429  if (r1->bottom() == ybot)
2430  r1 = r1BandEnd;
2431  if (r2->bottom() == ybot)
2432  r2 = r2BandEnd;
2433  } while (r1 != r1End && r2 != r2End);
2434 
2435  /*
2436  * Deal with whichever region still has rectangles left.
2437  */
2438  curBand = dest.numRects;
2439  if (r1 != r1End) {
2440  if (nonOverlap1Func != 0) {
2441  do {
2442  r1BandEnd = r1;
2443  while (r1BandEnd < r1End && r1BandEnd->top() == r1->top())
2444  ++r1BandEnd;
2445  (*nonOverlap1Func)(dest, r1, r1BandEnd, qMax(r1->top(), ybot + 1), r1->bottom());
2446  r1 = r1BandEnd;
2447  } while (r1 != r1End);
2448  }
2449  } else if ((r2 != r2End) && (nonOverlap2Func != 0)) {
2450  do {
2451  r2BandEnd = r2;
2452  while (r2BandEnd < r2End && r2BandEnd->top() == r2->top())
2453  ++r2BandEnd;
2454  (*nonOverlap2Func)(dest, r2, r2BandEnd, qMax(r2->top(), ybot + 1), r2->bottom());
2455  r2 = r2BandEnd;
2456  } while (r2 != r2End);
2457  }
2458 
2459  if (dest.numRects != curBand)
2460  (void)miCoalesce(dest, prevBand, curBand);
2461 
2462  /*
2463  * A bit of cleanup. To keep regions from growing without bound,
2464  * we shrink the array of rectangles to match the new number of
2465  * rectangles in the region.
2466  *
2467  * Only do this stuff if the number of rectangles allocated is more than
2468  * twice the number of rectangles in the region (a simple optimization).
2469  */
2470  if (qMax(4, dest.numRects) < (dest.rects.size() >> 1))
2471  dest.rects.resize(dest.numRects);
2472 }
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
QVector< QRect > rects
Definition: qregion.cpp:1227
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
static int miCoalesce(register QRegionPrivate &dest, int prevStart, int curStart)
Definition: qregion.cpp:2150

◆ miSetExtents()

static void miSetExtents ( QRegionPrivate dest)
static

Definition at line 2005 of file qregion.cpp.

Referenced by QRegion::intersect(), and SubtractRegion().

2006 {
2007  register const QRect *pBox,
2008  *pBoxEnd;
2009  register QRect *pExtents;
2010 
2011  dest.innerRect.setCoords(0, 0, -1, -1);
2012  dest.innerArea = -1;
2013  if (dest.numRects == 0) {
2014  dest.extents.setCoords(0, 0, -1, -1);
2015  return;
2016  }
2017 
2018  pExtents = &dest.extents;
2019  if (dest.rects.isEmpty())
2020  pBox = &dest.extents;
2021  else
2022  pBox = dest.rects.constData();
2023  pBoxEnd = pBox + dest.numRects - 1;
2024 
2025  /*
2026  * Since pBox is the first rectangle in the region, it must have the
2027  * smallest y1 and since pBoxEnd is the last rectangle in the region,
2028  * it must have the largest y2, because of banding. Initialize x1 and
2029  * x2 from pBox and pBoxEnd, resp., as good things to initialize them
2030  * to...
2031  */
2032  pExtents->setLeft(pBox->left());
2033  pExtents->setTop(pBox->top());
2034  pExtents->setRight(pBoxEnd->right());
2035  pExtents->setBottom(pBoxEnd->bottom());
2036 
2037  Q_ASSERT(pExtents->top() <= pExtents->bottom());
2038  while (pBox <= pBoxEnd) {
2039  if (pBox->left() < pExtents->left())
2040  pExtents->setLeft(pBox->left());
2041  if (pBox->right() > pExtents->right())
2042  pExtents->setRight(pBox->right());
2043  dest.updateInnerRect(*pBox);
2044  ++pBox;
2045  }
2046  Q_ASSERT(pExtents->left() <= pExtents->right());
2047 }
void setBottom(int pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:267
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
void updateInnerRect(const QRect &rect)
Definition: qregion.cpp:1282
void setRight(int pos)
Sets the right edge of the rectangle to the given x coordinate.
Definition: qrect.h:264
void setCoords(int x1, int y1, int x2, int y2)
Sets the coordinates of the rectangle&#39;s top-left corner to (x1, y1), and the coordinates of its botto...
Definition: qrect.h:416
QVector< QRect > rects
Definition: qregion.cpp:1227
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
void setLeft(int pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:258
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154

◆ miSubtractNonO1()

static void miSubtractNonO1 ( register QRegionPrivate dest,
register const QRect r,
const QRect rEnd,
register int  y1,
register int  y2 
)
static

Definition at line 2620 of file qregion.cpp.

Referenced by SubtractRegion().

2622 {
2623  register QRect *pNextRect;
2624 
2625  pNextRect = dest.rects.data() + dest.numRects;
2626 
2627  Q_ASSERT(y1<=y2);
2628 
2629  while (r != rEnd) {
2630  Q_ASSERT(r->left() <= r->right());
2631  MEMCHECK(dest, pNextRect, dest.rects)
2632  pNextRect->setCoords(r->left(), y1, r->right(), y2);
2633  ++dest.numRects;
2634  ++pNextRect;
2635  ++r;
2636  }
2637 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QTextStream & right(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignRight) on stream and returns stream...
static void setCoords(GLfloat *coords, const QGLRect &rect)
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
#define MEMCHECK(dest, rect, firstrect)
Definition: qregion.cpp:1869
QTextStream & left(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignLeft) on stream and returns stream...

◆ miSubtractO()

static void miSubtractO ( register QRegionPrivate dest,
register const QRect r1,
const QRect r1End,
register const QRect r2,
const QRect r2End,
register int  y1,
register int  y2 
)
static

Definition at line 2654 of file qregion.cpp.

Referenced by SubtractRegion().

2656 {
2657  register QRect *pNextRect;
2658  register int x1;
2659 
2660  x1 = r1->left();
2661 
2662  Q_ASSERT(y1 <= y2);
2663  pNextRect = dest.rects.data() + dest.numRects;
2664 
2665  while (r1 != r1End && r2 != r2End) {
2666  if (r2->right() < x1) {
2667  /*
2668  * Subtrahend missed the boat: go to next subtrahend.
2669  */
2670  ++r2;
2671  } else if (r2->left() <= x1) {
2672  /*
2673  * Subtrahend precedes minuend: nuke left edge of minuend.
2674  */
2675  x1 = r2->right() + 1;
2676  if (x1 > r1->right()) {
2677  /*
2678  * Minuend completely covered: advance to next minuend and
2679  * reset left fence to edge of new minuend.
2680  */
2681  ++r1;
2682  if (r1 != r1End)
2683  x1 = r1->left();
2684  } else {
2685  // Subtrahend now used up since it doesn't extend beyond minuend
2686  ++r2;
2687  }
2688  } else if (r2->left() <= r1->right()) {
2689  /*
2690  * Left part of subtrahend covers part of minuend: add uncovered
2691  * part of minuend to region and skip to next subtrahend.
2692  */
2693  Q_ASSERT(x1 < r2->left());
2694  MEMCHECK(dest, pNextRect, dest.rects)
2695  pNextRect->setCoords(x1, y1, r2->left() - 1, y2);
2696  ++dest.numRects;
2697  ++pNextRect;
2698 
2699  x1 = r2->right() + 1;
2700  if (x1 > r1->right()) {
2701  /*
2702  * Minuend used up: advance to new...
2703  */
2704  ++r1;
2705  if (r1 != r1End)
2706  x1 = r1->left();
2707  } else {
2708  // Subtrahend used up
2709  ++r2;
2710  }
2711  } else {
2712  /*
2713  * Minuend used up: add any remaining piece before advancing.
2714  */
2715  if (r1->right() >= x1) {
2716  MEMCHECK(dest, pNextRect, dest.rects)
2717  pNextRect->setCoords(x1, y1, r1->right(), y2);
2718  ++dest.numRects;
2719  ++pNextRect;
2720  }
2721  ++r1;
2722  if (r1 != r1End)
2723  x1 = r1->left();
2724  }
2725  }
2726 
2727  /*
2728  * Add remaining minuend rectangles to region.
2729  */
2730  while (r1 != r1End) {
2731  Q_ASSERT(x1 <= r1->right());
2732  MEMCHECK(dest, pNextRect, dest.rects)
2733  pNextRect->setCoords(x1, y1, r1->right(), y2);
2734  ++dest.numRects;
2735  ++pNextRect;
2736 
2737  ++r1;
2738  if (r1 != r1End)
2739  x1 = r1->left();
2740  }
2741 }
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QTextStream & right(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignRight) on stream and returns stream...
static void setCoords(GLfloat *coords, const QGLRect &rect)
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
if(void) toggleToolbarShown
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
#define MEMCHECK(dest, rect, firstrect)
Definition: qregion.cpp:1869
QTextStream & left(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignLeft) on stream and returns stream...

◆ miUnionNonO()

static void miUnionNonO ( register QRegionPrivate dest,
register const QRect r,
const QRect rEnd,
register int  y1,
register int  y2 
)
static

Definition at line 2495 of file qregion.cpp.

Referenced by UnionRegion().

2497 {
2498  register QRect *pNextRect;
2499 
2500  pNextRect = dest.rects.data() + dest.numRects;
2501 
2502  Q_ASSERT(y1 <= y2);
2503 
2504  while (r != rEnd) {
2505  Q_ASSERT(r->left() <= r->right());
2506  MEMCHECK(dest, pNextRect, dest.rects)
2507  pNextRect->setCoords(r->left(), y1, r->right(), y2);
2508  dest.numRects++;
2509  ++pNextRect;
2510  ++r;
2511  }
2512 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QTextStream & right(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignRight) on stream and returns stream...
static void setCoords(GLfloat *coords, const QGLRect &rect)
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
#define MEMCHECK(dest, rect, firstrect)
Definition: qregion.cpp:1869
QTextStream & left(QTextStream &stream)
Calls QTextStream::setFieldAlignment(QTextStream::AlignLeft) on stream and returns stream...

◆ miUnionO()

static void miUnionO ( register QRegionPrivate dest,
register const QRect r1,
const QRect r1End,
register const QRect r2,
const QRect r2End,
register int  y1,
register int  y2 
)
static

Definition at line 2531 of file qregion.cpp.

Referenced by UnionRegion().

2533 {
2534  register QRect *pNextRect;
2535 
2536  pNextRect = dest.rects.data() + dest.numRects;
2537 
2538 #define MERGERECT(r) \
2539  if ((dest.numRects != 0) && \
2540  (pNextRect[-1].top() == y1) && \
2541  (pNextRect[-1].bottom() == y2) && \
2542  (pNextRect[-1].right() >= r->left()-1)) { \
2543  if (pNextRect[-1].right() < r->right()) { \
2544  pNextRect[-1].setRight(r->right()); \
2545  dest.updateInnerRect(pNextRect[-1]); \
2546  Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \
2547  } \
2548  } else { \
2549  MEMCHECK(dest, pNextRect, dest.rects) \
2550  pNextRect->setCoords(r->left(), y1, r->right(), y2); \
2551  dest.updateInnerRect(*pNextRect); \
2552  dest.numRects++; \
2553  pNextRect++; \
2554  } \
2555  r++;
2556 
2557  Q_ASSERT(y1 <= y2);
2558  while (r1 != r1End && r2 != r2End) {
2559  if (r1->left() < r2->left()) {
2560  MERGERECT(r1)
2561  } else {
2562  MERGERECT(r2)
2563  }
2564  }
2565 
2566  if (r1 != r1End) {
2567  do {
2568  MERGERECT(r1)
2569  } while (r1 != r1End);
2570  } else {
2571  while (r2 != r2End) {
2572  MERGERECT(r2)
2573  }
2574  }
2575 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define MERGERECT(r)
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58

◆ OffsetRegion()

static void OffsetRegion ( register QRegionPrivate region,
register int  x,
register int  y 
)
static

Definition at line 2054 of file qregion.cpp.

Referenced by QRegion::translate().

2055 {
2056  if (region.rects.size()) {
2057  register QRect *pbox = region.rects.data();
2058  register int nbox = region.numRects;
2059 
2060  while (nbox--) {
2061  pbox->translate(x, y);
2062  ++pbox;
2063  }
2064  }
2065  region.extents.translate(x, y);
2066  region.innerRect.translate(x, y);
2067 }
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
void translate(int dx, int dy)
Moves the rectangle dx along the x axis and dy along the y axis, relative to the current position...
Definition: qrect.h:312

◆ operator<<()

QDebug operator<< ( QDebug  s,
const QRegion r 
)

Definition at line 492 of file qregion.cpp.

493 {
494  QVector<QRect> rects = r.rects();
495  s.nospace() << "QRegion(size=" << rects.size() << "), "
496  << "bounds = " << r.boundingRect() << '\n';
497  for (int i=0; i<rects.size(); ++i)
498  s << "- " << i << rects.at(i) << '\n';
499  return s;
500 }
QDebug & nospace()
Clears the stream&#39;s internal flag that records whether the last character was a space and returns a r...
Definition: qdebug.h:92
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ PointInRegion()

static bool PointInRegion ( QRegionPrivate pRegion,
int  x,
int  y 
)
static

Definition at line 2832 of file qregion.cpp.

Referenced by QRegion::contains().

2833 {
2834  int i;
2835 
2836  if (isEmptyHelper(pRegion))
2837  return false;
2838  if (!pRegion->extents.contains(x, y))
2839  return false;
2840  if (pRegion->numRects == 1)
2841  return pRegion->extents.contains(x, y);
2842  if (pRegion->innerRect.contains(x, y))
2843  return true;
2844  for (i = 0; i < pRegion->numRects; ++i) {
2845  if (pRegion->rects[i].contains(x, y))
2846  return true;
2847  }
2848  return false;
2849 }
bool contains(const QPoint &p, bool proper=false) const
Returns true if the given point is inside or on the edge of the rectangle, otherwise returns false...
Definition: qrect.cpp:1101
QVector< QRect > rects
Definition: qregion.cpp:1227
bool contains(const T &t) const
Returns true if the vector contains an occurrence of value; otherwise returns false.
Definition: qvector.h:731
static bool isEmptyHelper(const QRegionPrivate *preg)
Definition: qregion.cpp:1321

◆ PolygonRegion()

static QRegionPrivate* PolygonRegion ( const QPoint Pts,
int  Count,
int  rule 
)
static

Definition at line 3689 of file qregion.cpp.

Referenced by QRegion::QRegion().

3693 {
3694  QRegionPrivate *region;
3695  register EdgeTableEntry *pAET; /* Active Edge Table */
3696  register int y; /* current scanline */
3697  register int iPts = 0; /* number of pts in buffer */
3698  register EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/
3699  register ScanLineList *pSLL; /* current scanLineList */
3700  register QPoint *pts; /* output buffer */
3701  EdgeTableEntry *pPrevAET; /* ptr to previous AET */
3702  EdgeTable ET; /* header node for ET */
3703  EdgeTableEntry AET; /* header node for AET */
3704  EdgeTableEntry *pETEs; /* EdgeTableEntries pool */
3705  ScanLineListBlock SLLBlock; /* header for scanlinelist */
3706  int fixWAET = false;
3707  POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */
3708  FirstPtBlock.pts = reinterpret_cast<QPoint *>(FirstPtBlock.data);
3709  POINTBLOCK *tmpPtBlock;
3710  int numFullPtBlocks = 0;
3711 
3712  if (!(region = new QRegionPrivate))
3713  return 0;
3714 
3715  /* special case a rectangle */
3716  if (((Count == 4) ||
3717  ((Count == 5) && (Pts[4].x() == Pts[0].x()) && (Pts[4].y() == Pts[0].y())))
3718  && (((Pts[0].y() == Pts[1].y()) && (Pts[1].x() == Pts[2].x()) && (Pts[2].y() == Pts[3].y())
3719  && (Pts[3].x() == Pts[0].x())) || ((Pts[0].x() == Pts[1].x())
3720  && (Pts[1].y() == Pts[2].y()) && (Pts[2].x() == Pts[3].x())
3721  && (Pts[3].y() == Pts[0].y())))) {
3722  int x = qMin(Pts[0].x(), Pts[2].x());
3723  region->extents.setLeft(x);
3724  int y = qMin(Pts[0].y(), Pts[2].y());
3725  region->extents.setTop(y);
3726  region->extents.setWidth(qMax(Pts[0].x(), Pts[2].x()) - x);
3727  region->extents.setHeight(qMax(Pts[0].y(), Pts[2].y()) - y);
3728  if ((region->extents.left() <= region->extents.right()) &&
3729  (region->extents.top() <= region->extents.bottom())) {
3730  region->numRects = 1;
3731  region->innerRect = region->extents;
3732  region->innerArea = region->innerRect.width() * region->innerRect.height();
3733  }
3734  return region;
3735  }
3736 
3737  if (!(pETEs = static_cast<EdgeTableEntry *>(malloc(sizeof(EdgeTableEntry) * Count))))
3738  return 0;
3739 
3740  region->vectorize();
3741 
3742  pts = FirstPtBlock.pts;
3743  CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock);
3744 
3745  pSLL = ET.scanlines.next;
3746  curPtBlock = &FirstPtBlock;
3747 
3748  // sanity check that the region won't become too big...
3749  if (ET.ymax - ET.ymin > 100000) {
3750  // clean up region ptr
3751 #ifndef QT_NO_DEBUG
3752  qWarning("QRegion: creating region from big polygon failed...!");
3753 #endif
3754  delete region;
3755  return 0;
3756  }
3757 
3758 
3759  QT_TRY {
3760  if (rule == EvenOddRule) {
3761  /*
3762  * for each scanline
3763  */
3764  for (y = ET.ymin; y < ET.ymax; ++y) {
3765 
3766  /*
3767  * Add a new edge to the active edge table when we
3768  * get to the next edge.
3769  */
3770  if (pSLL && y == pSLL->scanline) {
3771  loadAET(&AET, pSLL->edgelist);
3772  pSLL = pSLL->next;
3773  }
3774  pPrevAET = &AET;
3775  pAET = AET.next;
3776 
3777  /*
3778  * for each active edge
3779  */
3780  while (pAET) {
3781  pts->setX(pAET->bres.minor_axis);
3782  pts->setY(y);
3783  ++pts;
3784  ++iPts;
3785 
3786  /*
3787  * send out the buffer
3788  */
3789  if (iPts == NUMPTSTOBUFFER) {
3790  tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK));
3791  Q_CHECK_PTR(tmpPtBlock);
3792  tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data);
3793  curPtBlock->next = tmpPtBlock;
3794  curPtBlock = tmpPtBlock;
3795  pts = curPtBlock->pts;
3796  ++numFullPtBlocks;
3797  iPts = 0;
3798  }
3799  EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
3800  }
3801  InsertionSort(&AET);
3802  }
3803  } else {
3804  /*
3805  * for each scanline
3806  */
3807  for (y = ET.ymin; y < ET.ymax; ++y) {
3808  /*
3809  * Add a new edge to the active edge table when we
3810  * get to the next edge.
3811  */
3812  if (pSLL && y == pSLL->scanline) {
3813  loadAET(&AET, pSLL->edgelist);
3814  computeWAET(&AET);
3815  pSLL = pSLL->next;
3816  }
3817  pPrevAET = &AET;
3818  pAET = AET.next;
3819  pWETE = pAET;
3820 
3821  /*
3822  * for each active edge
3823  */
3824  while (pAET) {
3825  /*
3826  * add to the buffer only those edges that
3827  * are in the Winding active edge table.
3828  */
3829  if (pWETE == pAET) {
3830  pts->setX(pAET->bres.minor_axis);
3831  pts->setY(y);
3832  ++pts;
3833  ++iPts;
3834 
3835  /*
3836  * send out the buffer
3837  */
3838  if (iPts == NUMPTSTOBUFFER) {
3839  tmpPtBlock = static_cast<POINTBLOCK *>(malloc(sizeof(POINTBLOCK)));
3840  tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data);
3841  curPtBlock->next = tmpPtBlock;
3842  curPtBlock = tmpPtBlock;
3843  pts = curPtBlock->pts;
3844  ++numFullPtBlocks;
3845  iPts = 0;
3846  }
3847  pWETE = pWETE->nextWETE;
3848  }
3849  EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
3850  }
3851 
3852  /*
3853  * recompute the winding active edge table if
3854  * we just resorted or have exited an edge.
3855  */
3856  if (InsertionSort(&AET) || fixWAET) {
3857  computeWAET(&AET);
3858  fixWAET = false;
3859  }
3860  }
3861  }
3862  } QT_CATCH(...) {
3863  FreeStorage(SLLBlock.next);
3864  PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
3865  for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
3866  tmpPtBlock = curPtBlock->next;
3867  free(curPtBlock);
3868  curPtBlock = tmpPtBlock;
3869  }
3870  free(pETEs);
3871  return 0; // this function returns 0 in case of an error
3872  }
3873 
3874  FreeStorage(SLLBlock.next);
3875  PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
3876  for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
3877  tmpPtBlock = curPtBlock->next;
3878  free(curPtBlock);
3879  curPtBlock = tmpPtBlock;
3880  }
3881  free(pETEs);
3882  return region;
3883 }
struct _ScanLineList * next
Definition: qregion.cpp:3136
void setHeight(int h)
Sets the height of the rectangle to the given height.
Definition: qrect.h:445
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define EvenOddRule
Definition: qregion.cpp:1782
int minor_axis
Definition: qregion.cpp:3055
struct _POINTBLOCK * next
Definition: qregion.cpp:1890
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
QPoint * pts
Definition: qregion.cpp:1889
ScanLineList scanlines
Definition: qregion.cpp:3143
static void loadAET(register EdgeTableEntry *AET, register EdgeTableEntry *ETEs)
Definition: qregion.cpp:3442
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
static void FreeStorage(register ScanLineListBlock *pSLLBlock)
Definition: qregion.cpp:3553
struct _EdgeTableEntry * nextWETE
Definition: qregion.cpp:3128
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
Definition: qregion.cpp:3197
BRESINFO bres
Definition: qregion.cpp:3125
struct _ScanLineListBlock * next
Definition: qregion.cpp:3156
static void computeWAET(register EdgeTableEntry *AET)
Definition: qregion.cpp:3486
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
Q_CORE_EXPORT void qWarning(const char *,...)
EdgeTableEntry * edgelist
Definition: qregion.cpp:3135
#define QT_CATCH(A)
Definition: qglobal.h:1537
int data[NUMPTSTOBUFFER *sizeof(QPoint)]
Definition: qregion.cpp:1888
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
#define NUMPTSTOBUFFER
Definition: qregion.cpp:1881
void setY(int y)
Sets the y coordinate of this point to the given y coordinate.
Definition: qpoint.h:137
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
void setLeft(int pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:258
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
void setWidth(int w)
Sets the width of the rectangle to the given width.
Definition: qrect.h:442
struct _EdgeTableEntry * next
Definition: qregion.cpp:3126
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
Definition: qregion.cpp:3174
static int InsertionSort(register EdgeTableEntry *AET)
Definition: qregion.cpp:3520
static void CreateETandAET(register int count, register const QPoint *pts, EdgeTable *ET, EdgeTableEntry *AET, register EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
Definition: qregion.cpp:3355
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
void setX(int x)
Sets the x coordinate of this point to the given x coordinate.
Definition: qpoint.h:134
#define QT_TRY
Definition: qglobal.h:1536
void vectorize()
Definition: qregion.cpp:1290
static void PtsToRegion(register int numFullPtBlocks, register int iCurPtBlock, POINTBLOCK *FirstPtBlock, QRegionPrivate *reg)
Definition: qregion.cpp:3619

◆ PtsToRegion()

static void PtsToRegion ( register int  numFullPtBlocks,
register int  iCurPtBlock,
POINTBLOCK FirstPtBlock,
QRegionPrivate reg 
)
static

Definition at line 3619 of file qregion.cpp.

Referenced by PolygonRegion().

3621 {
3622  int lastRow = 0;
3623  int extendTo = 0;
3624  bool needsExtend = false;
3626  int rowSize = 0;
3627 
3628  reg->extents.setLeft(INT_MAX);
3629  reg->extents.setRight(INT_MIN);
3630  reg->innerArea = -1;
3631 
3632  POINTBLOCK *CurPtBlock = FirstPtBlock;
3633  for (; numFullPtBlocks >= 0; --numFullPtBlocks) {
3634  /* the loop uses 2 points per iteration */
3635  int i = NUMPTSTOBUFFER >> 1;
3636  if (!numFullPtBlocks)
3637  i = iCurPtBlock >> 1;
3638  if(i) {
3639  row.resize(qMax(row.size(), rowSize + i));
3640  for (QPoint *pts = CurPtBlock->pts; i--; pts += 2) {
3641  const int width = pts[1].x() - pts[0].x();
3642  if (width) {
3643  if (rowSize && row[rowSize-1].x2 == pts[0].x())
3644  row[rowSize-1].x2 = pts[1].x();
3645  else
3646  row[rowSize++] = QRegionSpan(pts[0].x(), pts[1].x());
3647  }
3648 
3649  if (rowSize) {
3650  QPoint *next = i ? &pts[2] : (numFullPtBlocks ? CurPtBlock->next->pts : 0);
3651 
3652  if (!next || next->y() != pts[0].y()) {
3653  flushRow(row.data(), pts[0].y(), rowSize, reg, &lastRow, &extendTo, &needsExtend);
3654  rowSize = 0;
3655  }
3656  }
3657  }
3658  }
3659  CurPtBlock = CurPtBlock->next;
3660  }
3661 
3662  if (needsExtend) {
3663  for (int i = lastRow; i < reg->rects.size(); ++i)
3664  reg->rects[i].setBottom(extendTo);
3665  }
3666 
3667  reg->numRects = reg->rects.size();
3668 
3669  if (reg->numRects) {
3670  reg->extents.setTop(reg->rects[0].top());
3671  reg->extents.setBottom(reg->rects[lastRow].bottom());
3672 
3673  for (int i = 0; i < reg->rects.size(); ++i)
3674  reg->updateInnerRect(reg->rects[i]);
3675  } else {
3676  reg->extents.setCoords(0, 0, 0, 0);
3677  }
3678 }
void resize(int size)
void setBottom(int pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:267
struct _POINTBLOCK * next
Definition: qregion.cpp:1890
QPoint * pts
Definition: qregion.cpp:1889
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
void updateInnerRect(const QRect &rect)
Definition: qregion.cpp:1282
static void flushRow(const QRegionSpan *spans, int y, int numSpans, QRegionPrivate *reg, int *lastRow, int *extendTo, bool *needsExtend)
Definition: qregion.cpp:3575
void setRight(int pos)
Sets the right edge of the rectangle to the given x coordinate.
Definition: qrect.h:264
void setCoords(int x1, int y1, int x2, int y2)
Sets the coordinates of the rectangle&#39;s top-left corner to (x1, y1), and the coordinates of its botto...
Definition: qrect.h:416
QVector< QRect > rects
Definition: qregion.cpp:1227
#define NUMPTSTOBUFFER
Definition: qregion.cpp:1881
void setLeft(int pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:258
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
#define INT_MAX
int size() const

◆ Q_DECLARE_TYPEINFO()

Q_DECLARE_TYPEINFO ( QRegionSpan  ,
Q_PRIMITIVE_TYPE   
)

Referenced by QRegionSpan::width().

◆ qt_bitmapToRegion()

QRegionPrivate* qt_bitmapToRegion ( const QBitmap bitmap)

Definition at line 3886 of file qregion.cpp.

Referenced by QRegion::QRegion().

3887 {
3888  QImage image = bitmap.toImage();
3889 
3890  QRegionPrivate *region = new QRegionPrivate;
3891 
3892  QRect xr;
3893 
3894 #define AddSpan \
3895  { \
3896  xr.setCoords(prev1, y, x-1, y); \
3897  UnionRectWithRegion(&xr, region, *region); \
3898  }
3899 
3900  const uchar zero = 0;
3901  bool little = image.format() == QImage::Format_MonoLSB;
3902 
3903  int x,
3904  y;
3905  for (y = 0; y < image.height(); ++y) {
3906  uchar *line = image.scanLine(y);
3907  int w = image.width();
3908  uchar all = zero;
3909  int prev1 = -1;
3910  for (x = 0; x < w;) {
3911  uchar byte = line[x / 8];
3912  if (x > w - 8 || byte!=all) {
3913  if (little) {
3914  for (int b = 8; b > 0 && x < w; --b) {
3915  if (!(byte & 0x01) == !all) {
3916  // More of the same
3917  } else {
3918  // A change.
3919  if (all!=zero) {
3920  AddSpan
3921  all = zero;
3922  } else {
3923  prev1 = x;
3924  all = ~zero;
3925  }
3926  }
3927  byte >>= 1;
3928  ++x;
3929  }
3930  } else {
3931  for (int b = 8; b > 0 && x < w; --b) {
3932  if (!(byte & 0x80) == !all) {
3933  // More of the same
3934  } else {
3935  // A change.
3936  if (all != zero) {
3937  AddSpan
3938  all = zero;
3939  } else {
3940  prev1 = x;
3941  all = ~zero;
3942  }
3943  }
3944  byte <<= 1;
3945  ++x;
3946  }
3947  }
3948  } else {
3949  x += 8;
3950  }
3951  }
3952  if (all != zero) {
3953  AddSpan
3954  }
3955  }
3956 #undef AddSpan
3957 
3958  return region;
3959 }
QImage toImage() const
Converts the pixmap to a QImage.
Definition: qpixmap.cpp:542
#define AddSpan
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
unsigned char uchar
Definition: qglobal.h:994
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
static const int zero
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886

◆ qt_rect_intersect_normalized()

static QRect qt_rect_intersect_normalized ( const QRect r1,
const QRect r2 
)
inlinestatic

Definition at line 1396 of file qregion.cpp.

Referenced by QRegion::intersect(), and QRegionPrivate::intersect().

1398 {
1399  QRect r;
1400  r.setLeft(qMax(r1.left(), r2.left()));
1401  r.setRight(qMin(r1.right(), r2.right()));
1402  r.setTop(qMax(r1.top(), r2.top()));
1403  r.setBottom(qMin(r1.bottom(), r2.bottom()));
1404  return r;
1405 }
void setBottom(int pos)
Sets the bottom edge of the rectangle to the given y coordinate.
Definition: qrect.h:267
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
void setRight(int pos)
Sets the right edge of the rectangle to the given x coordinate.
Definition: qrect.h:264
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
void setLeft(int pos)
Sets the left edge of the rectangle to the given x coordinate.
Definition: qrect.h:258
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58

◆ qt_region_strictContains()

Q_GUI_EXPORT bool qt_region_strictContains ( const QRegion region,
const QRect rect 
)

Returns true if rect is guaranteed to be fully contained in region.

Warning
This function is not part of the public interface.

A false return value does not guarantee the opposite.

Definition at line 4380 of file qregion.cpp.

Referenced by QRasterPaintEnginePrivate::isUnclipped(), QRasterPaintEnginePrivate::isUnclipped_normalized(), QWidgetBackingStore::markDirty(), and QRegion::operator!=().

4381 {
4382  if (isEmptyHelper(region.d->qt_rgn) || !rect.isValid())
4383  return false;
4384 
4385 #if 0 // TEST_INNERRECT
4386  static bool guard = false;
4387  if (guard)
4388  return false;
4389  guard = true;
4390  QRegion inner = region.d->qt_rgn->innerRect;
4391  Q_ASSERT((inner - region).isEmpty());
4392  guard = false;
4393 
4394  int maxArea = 0;
4395  for (int i = 0; i < region.d->qt_rgn->numRects; ++i) {
4396  const QRect r = region.d->qt_rgn->rects.at(i);
4397  if (r.width() * r.height() > maxArea)
4398  maxArea = r.width() * r.height();
4399  }
4400 
4401  if (maxArea > region.d->qt_rgn->innerArea) {
4402  qDebug() << "not largest rectangle" << region << region.d->qt_rgn->innerRect;
4403  }
4404  Q_ASSERT(maxArea <= region.d->qt_rgn->innerArea);
4405 #endif
4406 
4407  const QRect r1 = region.d->qt_rgn->innerRect;
4408  return (rect.left() >= r1.left() && rect.right() <= r1.right()
4409  && rect.top() >= r1.top() && rect.bottom() <= r1.bottom());
4410 }
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
QRegionPrivate * qt_rgn
Definition: qregion.h:211
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Q_CORE_EXPORT void qDebug(const char *,...)
static bool isEmpty(const char *str)
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QVector< QRect > rects
Definition: qregion.cpp:1227
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool isValid() const
Returns true if the rectangle is valid, otherwise returns false.
Definition: qrect.h:237
struct QRegionData * d
Definition: qregion.h:217
static bool isEmptyHelper(const QRegionPrivate *preg)
Definition: qregion.cpp:1321

◆ qt_regionToPath()

Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath ( const QRegion region)

Definition at line 1160 of file qregion.cpp.

Referenced by QPainter::clipPath(), QPainter::clipRegion(), QGraphicsLineItem::extension(), QGraphicsViewPrivate::findItems(), QGraphicsViewPrivate::freeStyleOptionsArray(), QMatrix::map(), QTransform::map(), QPdfBaseEngine::setupGraphicsState(), QWin32PrintEngine::updateClipPath(), QPdfBaseEngine::updateClipPath(), QGraphicsPixmapItemPrivate::updateShape(), QWin32PrintEngine::updateState(), and QX11PaintEngine::updateState().

1161 {
1162  QPainterPath result;
1163  if (region.rectCount() == 1) {
1164  result.addRect(region.boundingRect());
1165  return result;
1166  }
1167 
1168  const QVector<QRect> rects = region.rects();
1169 
1170  QVarLengthArray<Segment> segments;
1171  segments.resize(4 * rects.size());
1172 
1173  const QRect *rect = rects.constData();
1174  const QRect *end = rect + rects.size();
1175 
1176  int lastRowSegmentCount = 0;
1177  Segment *lastRowSegments = 0;
1178 
1179  int lastSegment = 0;
1180  int lastY = 0;
1181  while (rect != end) {
1182  const int y = rect[0].y();
1183  int count = 0;
1184  while (&rect[count] != end && rect[count].y() == y)
1185  ++count;
1186 
1187  for (int i = 0; i < count; ++i) {
1188  int offset = lastSegment + i;
1189  segments[offset] = Segment(rect[i].topLeft());
1190  segments[offset += count] = Segment(rect[i].topRight() + QPoint(1, 0));
1191  segments[offset += count] = Segment(rect[i].bottomRight() + QPoint(1, 1));
1192  segments[offset += count] = Segment(rect[i].bottomLeft() + QPoint(0, 1));
1193 
1194  offset = lastSegment + i;
1195  for (int j = 0; j < 4; ++j)
1196  segments[offset + j * count].connect(segments[offset + ((j + 1) % 4) * count]);
1197  }
1198 
1199  if (lastRowSegments && lastY == y)
1200  mergeSegments(lastRowSegments, lastRowSegmentCount, &segments[lastSegment], count);
1201 
1202  lastRowSegments = &segments[lastSegment + 2 * count];
1203  lastRowSegmentCount = count;
1204  lastSegment += 4 * count;
1205  lastY = y + rect[0].height();
1206  rect += count;
1207  }
1208 
1209  for (int i = 0; i < lastSegment; ++i) {
1210  Segment *segment = &segments[i];
1211  if (!segment->added)
1212  addSegmentsToPath(segment, result);
1213  }
1214 
1215  return result;
1216 }
void resize(int size)
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:67
QRect boundingRect() const
Returns the bounding rectangle of this region.
Definition: qregion.cpp:4363
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
int rectCount() const
Returns the number of rectangles that will be returned in rects().
Definition: qregion.cpp:4461
void addRect(const QRectF &rect)
Adds the given rectangle to this path as a closed subpath.
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
const T * constData() const
Returns a const pointer to the data stored in the vector.
Definition: qvector.h:154
static const KeyPair *const end
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137

◆ rect_intersects()

bool rect_intersects ( const QRect r1,
const QRect r2 
)
inline

Definition at line 751 of file qregion.cpp.

Referenced by QRegion::intersects().

752 {
753  return (r1.right() >= r2.left() && r1.left() <= r2.right() &&
754  r1.bottom() >= r2.top() && r1.top() <= r2.bottom());
755 }
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246

◆ RectInRegion()

static bool RectInRegion ( register QRegionPrivate region,
int  rx,
int  ry,
uint  rwidth,
uint  rheight 
)
static

Definition at line 2851 of file qregion.cpp.

Referenced by QRegion::contains().

2852 {
2853  register const QRect *pbox;
2854  register const QRect *pboxEnd;
2855  QRect rect(rx, ry, rwidth, rheight);
2856  register QRect *prect = &rect;
2857  int partIn, partOut;
2858 
2859  if (!region || region->numRects == 0 || !EXTENTCHECK(&region->extents, prect))
2860  return RectangleOut;
2861 
2862  partOut = false;
2863  partIn = false;
2864 
2865  /* can stop when both partOut and partIn are true, or we reach prect->y2 */
2866  pbox = (region->numRects == 1) ? &region->extents : region->rects.constData();
2867  pboxEnd = pbox + region->numRects;
2868  for (; pbox < pboxEnd; ++pbox) {
2869  if (pbox->bottom() < ry)
2870  continue;
2871 
2872  if (pbox->top() > ry) {
2873  partOut = true;
2874  if (partIn || pbox->top() > prect->bottom())
2875  break;
2876  ry = pbox->top();
2877  }
2878 
2879  if (pbox->right() < rx)
2880  continue; /* not far enough over yet */
2881 
2882  if (pbox->left() > rx) {
2883  partOut = true; /* missed part of rectangle to left */
2884  if (partIn)
2885  break;
2886  }
2887 
2888  if (pbox->left() <= prect->right()) {
2889  partIn = true; /* definitely overlap */
2890  if (partOut)
2891  break;
2892  }
2893 
2894  if (pbox->right() >= prect->right()) {
2895  ry = pbox->bottom() + 1; /* finished with this band */
2896  if (ry > prect->bottom())
2897  break;
2898  rx = prect->left(); /* reset x out to left again */
2899  } else {
2900  /*
2901  * Because boxes in a band are maximal width, if the first box
2902  * to overlap the rectangle doesn't completely cover it in that
2903  * band, the rectangle must be partially out, since some of it
2904  * will be uncovered in that band. partIn will have been set true
2905  * by now...
2906  */
2907  break;
2908  }
2909  }
2910  return partIn ? ((ry <= prect->bottom()) ? RectanglePart : RectangleIn) : RectangleOut;
2911 }
#define RectanglePart
Definition: qregion.cpp:1781
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
#define EXTENTCHECK(r1, r2)
Definition: qregion.cpp:1846
#define RectangleOut
Definition: qregion.cpp:1779
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
#define RectangleIn
Definition: qregion.cpp:1780

◆ SubtractRegion()

static void SubtractRegion ( QRegionPrivate regM,
QRegionPrivate regS,
register QRegionPrivate dest 
)
static

Definition at line 2755 of file qregion.cpp.

Referenced by QRegion::subtract(), and XorRegion().

2757 {
2758  Q_ASSERT(!isEmptyHelper(regM));
2759  Q_ASSERT(!isEmptyHelper(regS));
2760  Q_ASSERT(EXTENTCHECK(&regM->extents, &regS->extents));
2761  Q_ASSERT(!regS->contains(*regM));
2762  Q_ASSERT(!EqualRegion(regM, regS));
2763 
2764  miRegionOp(dest, regM, regS, miSubtractO, miSubtractNonO1, 0);
2765 
2766  /*
2767  * Can't alter dest's extents before we call miRegionOp because
2768  * it might be one of the source regions and miRegionOp depends
2769  * on the extents of those regions being the unaltered. Besides, this
2770  * way there's no checking against rectangles that will be nuked
2771  * due to coalescing, so we have to examine fewer rectangles.
2772  */
2773  miSetExtents(dest);
2774 }
static void miSubtractO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, register const QRect *r2, const QRect *r2End, register int y1, register int y2)
Definition: qregion.cpp:2654
#define EXTENTCHECK(r1, r2)
Definition: qregion.cpp:1846
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static void miSubtractNonO1(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, register int y1, register int y2)
Definition: qregion.cpp:2620
static void miSetExtents(QRegionPrivate &dest)
Definition: qregion.cpp:2005
static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
Definition: qregion.cpp:2810
static void miRegionOp(register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2, OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func, NonOverlapFunc nonOverlap2Func)
Definition: qregion.cpp:2279
static bool isEmptyHelper(const QRegionPrivate *preg)
Definition: qregion.cpp:1321
bool contains(const QRegionPrivate &r) const
Definition: qregion.cpp:1263

◆ UnionRectWithRegion()

static void UnionRectWithRegion ( register const QRect rect,
const QRegionPrivate source,
QRegionPrivate dest 
)
static

Definition at line 1972 of file qregion.cpp.

1974 {
1975  if (rect->isEmpty())
1976  return;
1977 
1978  Q_ASSERT(EqualRegion(source, &dest));
1979 
1980  if (dest.numRects == 0) {
1981  dest = QRegionPrivate(*rect);
1982  } else if (dest.canAppend(rect)) {
1983  dest.append(rect);
1984  } else {
1985  QRegionPrivate p(*rect);
1986  UnionRegion(&p, source, dest);
1987  }
1988 }
void append(const QRect *r)
Definition: qregion.cpp:1460
static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest)
Definition: qregion.cpp:2577
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
Definition: qregion.cpp:2810
bool canAppend(const QRect *r) const
Definition: qregion.cpp:1669

◆ UnionRegion()

static void UnionRegion ( const QRegionPrivate reg1,
const QRegionPrivate reg2,
QRegionPrivate dest 
)
static

Definition at line 2577 of file qregion.cpp.

Referenced by QRegion::operator+=(), UnionRectWithRegion(), QRegion::unite(), and XorRegion().

2578 {
2579  Q_ASSERT(!isEmptyHelper(reg1) && !isEmptyHelper(reg2));
2580  Q_ASSERT(!reg1->contains(*reg2));
2581  Q_ASSERT(!reg2->contains(*reg1));
2582  Q_ASSERT(!EqualRegion(reg1, reg2));
2583  Q_ASSERT(!reg1->canAppend(reg2));
2584  Q_ASSERT(!reg2->canAppend(reg1));
2585 
2586  if (reg1->innerArea > reg2->innerArea) {
2587  dest.innerArea = reg1->innerArea;
2588  dest.innerRect = reg1->innerRect;
2589  } else {
2590  dest.innerArea = reg2->innerArea;
2591  dest.innerRect = reg2->innerRect;
2592  }
2593  miRegionOp(dest, reg1, reg2, miUnionO, miUnionNonO, miUnionNonO);
2594 
2595  dest.extents.setCoords(qMin(reg1->extents.left(), reg2->extents.left()),
2596  qMin(reg1->extents.top(), reg2->extents.top()),
2597  qMax(reg1->extents.right(), reg2->extents.right()),
2598  qMax(reg1->extents.bottom(), reg2->extents.bottom()));
2599 }
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
static void miUnionO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, register const QRect *r2, const QRect *r2End, register int y1, register int y2)
Definition: qregion.cpp:2531
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static void miUnionNonO(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, register int y1, register int y2)
Definition: qregion.cpp:2495
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
Definition: qregion.cpp:2810
void setCoords(int x1, int y1, int x2, int y2)
Sets the coordinates of the rectangle&#39;s top-left corner to (x1, y1), and the coordinates of its botto...
Definition: qrect.h:416
bool canAppend(const QRect *r) const
Definition: qregion.cpp:1669
int top() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:243
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
static void miRegionOp(register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2, OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func, NonOverlapFunc nonOverlap2Func)
Definition: qregion.cpp:2279
static bool isEmptyHelper(const QRegionPrivate *preg)
Definition: qregion.cpp:1321
bool contains(const QRegionPrivate &r) const
Definition: qregion.cpp:1263

◆ XorRegion()

static void XorRegion ( QRegionPrivate sra,
QRegionPrivate srb,
QRegionPrivate dest 
)
static

Definition at line 2776 of file qregion.cpp.

Referenced by QRegion::eor().

2777 {
2778  Q_ASSERT(!isEmptyHelper(sra) && !isEmptyHelper(srb));
2779  Q_ASSERT(EXTENTCHECK(&sra->extents, &srb->extents));
2780  Q_ASSERT(!EqualRegion(sra, srb));
2781 
2782  QRegionPrivate tra, trb;
2783 
2784  if (!srb->contains(*sra))
2785  SubtractRegion(sra, srb, tra);
2786  if (!sra->contains(*srb))
2787  SubtractRegion(srb, sra, trb);
2788 
2789  Q_ASSERT(isEmptyHelper(&trb) || !tra.contains(trb));
2790  Q_ASSERT(isEmptyHelper(&tra) || !trb.contains(tra));
2791 
2792  if (isEmptyHelper(&tra)) {
2793  dest = trb;
2794  } else if (isEmptyHelper(&trb)) {
2795  dest = tra;
2796  } else if (tra.canAppend(&trb)) {
2797  dest = tra;
2798  dest.append(&trb);
2799  } else if (trb.canAppend(&tra)) {
2800  dest = trb;
2801  dest.append(&tra);
2802  } else {
2803  UnionRegion(&tra, &trb, dest);
2804  }
2805 }
void append(const QRect *r)
Definition: qregion.cpp:1460
static void SubtractRegion(QRegionPrivate *regM, QRegionPrivate *regS, register QRegionPrivate &dest)
Definition: qregion.cpp:2755
static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest)
Definition: qregion.cpp:2577
#define EXTENTCHECK(r1, r2)
Definition: qregion.cpp:1846
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
Definition: qregion.cpp:2810
bool canAppend(const QRect *r) const
Definition: qregion.cpp:1669
static bool isEmptyHelper(const QRegionPrivate *preg)
Definition: qregion.cpp:1321
bool contains(const QRegionPrivate &r) const
Definition: qregion.cpp:1263