Qt 4.8
Classes | Macros | Typedefs | Functions | Variables
qregion_qws.cpp File Reference
#include "qregion.h"
#include "qpainterpath.h"
#include "qpolygon.h"
#include "qbuffer.h"
#include "qimage.h"
#include <qdebug.h>
#include "qbitmap.h"
#include <stdlib.h>
#include <qatomic.h>
#include <qsemaphore.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
 
class  QFastMutex
 
struct  QRegionPrivate
 

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 CONTAINSCHECK(r1, r2)
 
#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   1000000
 
#define MEMCHECK(dest, rect, firstrect)
 
#define MERGERECT(r)
 
#define NUMPTSTOBUFFER   200
 
#define private   public
 
#define RectangleIn   1
 
#define RectangleOut   0
 
#define RectanglePart   2
 
#define SLLSPERBLOCK   25
 
#define SMALL_COORDINATE   -LARGE_COORDINATE
 
#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 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 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)
 
static bool PointInRegion (QRegionPrivate *pRegion, int x, int y)
 
static QRegionPrivatePolygonRegion (const QPoint *Pts, int Count, int rule, QRegionPrivate *region)
 
static void PtsToRegion (register int numFullPtBlocks, register int iCurPtBlock, POINTBLOCK *FirstPtBlock, QRegionPrivate *reg)
 
static QRegionPrivateqt_allocRegion ()
 
static QRegionPrivateqt_allocRegion (const QRect &r)
 
static QRegionPrivateqt_allocRegion (const QRegionPrivate &r)
 
static QRegionPrivateqt_allocRegionMemory ()
 
QRegionPrivateqt_bitmapToRegion (const QBitmap &bitmap, QRegionPrivate *region)
 
void qt_freeRegion (QRegionPrivate *rp)
 
static void qt_freeRegionMemory (QRegionPrivate *rp)
 
bool qt_region_strictContains (const QRegion &region, const QRect &rect)
 
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)
 

Variables

static QFastMutex qt_nextRegionLock
 
static QRegionPrivateqt_nextRegionPtr = 0
 

Macro Definition Documentation

◆ _XREGION_H

#define _XREGION_H

Definition at line 433 of file qregion_qws.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 1613 of file qregion_qws.cpp.

◆ BRESINCRPGONSTRUCT

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

Definition at line 1655 of file qregion_qws.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 1587 of file qregion_qws.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 at line 1651 of file qregion_qws.cpp.

Referenced by CreateETandAET().

◆ CLOCKWISE

#define CLOCKWISE   1

Definition at line 1709 of file qregion_qws.cpp.

◆ CONTAINSCHECK

#define CONTAINSCHECK (   r1,
  r2 
)
Value:
((r2).left() >= (r1).left() && (r2).right() <= (r1).right() && \
(r2).top() >= (r1).top() && (r2).bottom() <= (r1).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 89 of file qregion_qws.cpp.

Referenced by QRegionPrivate::contains(), and qt_bitmapToRegion().

◆ COUNTERCLOCKWISE

#define COUNTERCLOCKWISE   -1

Definition at line 1710 of file qregion_qws.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 1786 of file qregion_qws.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 1763 of file qregion_qws.cpp.

Referenced by PolygonRegion().

◆ EvenOddRule

#define EvenOddRule   0

Definition at line 379 of file qregion_qws.cpp.

Referenced by PolygonRegion(), and qt_bitmapToRegion().

◆ 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 443 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion(), RectInRegion(), 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 452 of file qregion_qws.cpp.

◆ LARGE_COORDINATE

#define LARGE_COORDINATE   1000000

Definition at line 1851 of file qregion_qws.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 466 of file qregion_qws.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 478 of file qregion_qws.cpp.

Referenced by PolygonRegion(), and PtsToRegion().

◆ private

#define private   public

Definition at line 43 of file qregion_qws.cpp.

◆ RectangleIn

#define RectangleIn   1

Definition at line 377 of file qregion_qws.cpp.

Referenced by RectInRegion().

◆ RectangleOut

#define RectangleOut   0

Definition at line 376 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion(), and RectInRegion().

◆ RectanglePart

#define RectanglePart   2

Definition at line 378 of file qregion_qws.cpp.

Referenced by RectInRegion().

◆ SLLSPERBLOCK

#define SLLSPERBLOCK   25

Definition at line 1741 of file qregion_qws.cpp.

Referenced by InsertEdgeInET().

◆ SMALL_COORDINATE

#define SMALL_COORDINATE   -LARGE_COORDINATE

Definition at line 1852 of file qregion_qws.cpp.

Referenced by CreateETandAET().

◆ WindingRule

#define WindingRule   1

Definition at line 380 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

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 367 of file qregion_qws.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 365 of file qregion_qws.cpp.

◆ POINTBLOCK

typedef struct _POINTBLOCK POINTBLOCK

◆ ScanLineList

typedef struct _ScanLineList ScanLineList

◆ ScanLineListBlock

Function Documentation

◆ computeWAET()

static void computeWAET ( register EdgeTableEntry AET)
static

Definition at line 2074 of file qregion_qws.cpp.

Referenced by PolygonRegion().

2075 {
2076  register EdgeTableEntry *pWETE;
2077  register int inside = 1;
2078  register int isInside = 0;
2079 
2080  AET->nextWETE = 0;
2081  pWETE = AET;
2082  AET = AET->next;
2083  while (AET) {
2084  if (AET->ClockWise)
2085  ++isInside;
2086  else
2087  --isInside;
2088 
2089  if (!inside && !isInside || inside && isInside) {
2090  pWETE->nextWETE = AET;
2091  pWETE = AET;
2092  inside = !inside;
2093  }
2094  AET = AET->next;
2095  }
2096  pWETE->nextWETE = 0;
2097 }
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 1943 of file qregion_qws.cpp.

Referenced by PolygonRegion().

1946 {
1947  register const QPoint *top,
1948  *bottom,
1949  *PrevPt,
1950  *CurrPt;
1951  int iSLLBlock = 0;
1952  int dy;
1953 
1954  if (count < 2)
1955  return;
1956 
1957  /*
1958  * initialize the Active Edge Table
1959  */
1960  AET->next = 0;
1961  AET->back = 0;
1962  AET->nextWETE = 0;
1964 
1965  /*
1966  * initialize the Edge Table.
1967  */
1968  ET->scanlines.next = 0;
1969  ET->ymax = SMALL_COORDINATE;
1970  ET->ymin = LARGE_COORDINATE;
1971  pSLLBlock->next = 0;
1972 
1973  PrevPt = &pts[count - 1];
1974 
1975  /*
1976  * for each vertex in the array of points.
1977  * In this loop we are dealing with two vertices at
1978  * a time -- these make up one edge of the polygon.
1979  */
1980  while (count--) {
1981  CurrPt = pts++;
1982 
1983  /*
1984  * find out which point is above and which is below.
1985  */
1986  if (PrevPt->y() > CurrPt->y()) {
1987  bottom = PrevPt;
1988  top = CurrPt;
1989  pETEs->ClockWise = 0;
1990  } else {
1991  bottom = CurrPt;
1992  top = PrevPt;
1993  pETEs->ClockWise = 1;
1994  }
1995 
1996  /*
1997  * don't add horizontal edges to the Edge table.
1998  */
1999  if (bottom->y() != top->y()) {
2000  pETEs->ymax = bottom->y() - 1; /* -1 so we don't get last scanline */
2001 
2002  /*
2003  * initialize integer edge algorithm
2004  */
2005  dy = bottom->y() - top->y();
2006  BRESINITPGONSTRUCT(dy, top->x(), bottom->x(), pETEs->bres)
2007 
2008  InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock);
2009 
2010  if (PrevPt->y() > ET->ymax)
2011  ET->ymax = PrevPt->y();
2012  if (PrevPt->y() < ET->ymin)
2013  ET->ymin = PrevPt->y();
2014  ++pETEs;
2015  }
2016 
2017  PrevPt = CurrPt;
2018  }
2019 }
struct _ScanLineList * next
Definition: qregion.cpp:3136
int minor_axis
Definition: qregion.cpp:3055
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 SMALL_COORDINATE
static void InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline, ScanLineListBlock **SLLBlock, int *iSLLBlock)
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
struct _EdgeTableEntry * next
Definition: qregion.cpp:3126
#define LARGE_COORDINATE
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 BRESINITPGONSTRUCT(dmaj, min1, min2, bres)

◆ EqualRegion()

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

Definition at line 1400 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion(), qt_region_strictContains(), SubtractRegion(), UnionRectWithRegion(), UnionRegion(), and XorRegion().

1401 {
1402  if (r1->numRects != r2->numRects) {
1403  return false;
1404  } else if (r1->numRects == 0) {
1405  return true;
1406  } else if (r1->extents != r2->extents) {
1407  return false;
1408  } else if (r1->mode == QRegionPrivate::Single && r2->mode == QRegionPrivate::Single) {
1409  return r1->single == r2->single;
1410  } else {
1411  const QRect *rr1 = (r1->mode==QRegionPrivate::Vector)?r1->rects.constData():&r1->single;
1412  const QRect *rr2 = (r2->mode==QRegionPrivate::Vector)?r2->rects.constData():&r2->single;
1413  for (int i = 0; i < r1->numRects; ++i, ++rr1, ++rr2) {
1414  if (*rr1 != *rr2)
1415  return false;
1416  }
1417  }
1418 
1419  return true;
1420 }
enum QRegionPrivate::@253 mode
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

◆ FreeStorage()

static void FreeStorage ( register ScanLineListBlock pSLLBlock)
static

Definition at line 2141 of file qregion_qws.cpp.

Referenced by PolygonRegion().

2142 {
2143  register ScanLineListBlock *tmpSLLBlock;
2144 
2145  while (pSLLBlock) {
2146  tmpSLLBlock = pSLLBlock->next;
2147  free(pSLLBlock);
2148  pSLLBlock = tmpSLLBlock;
2149  }
2150 }
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 1863 of file qregion_qws.cpp.

Referenced by CreateETandAET().

1865 {
1866  register EdgeTableEntry *start, *prev;
1867  register ScanLineList *pSLL, *pPrevSLL;
1868  ScanLineListBlock *tmpSLLBlock;
1869 
1870  /*
1871  * find the right bucket to put the edge into
1872  */
1873  pPrevSLL = &ET->scanlines;
1874  pSLL = pPrevSLL->next;
1875  while (pSLL && (pSLL->scanline < scanline)) {
1876  pPrevSLL = pSLL;
1877  pSLL = pSLL->next;
1878  }
1879 
1880  /*
1881  * reassign pSLL (pointer to ScanLineList) if necessary
1882  */
1883  if ((!pSLL) || (pSLL->scanline > scanline)) {
1884  if (*iSLLBlock > SLLSPERBLOCK-1)
1885  {
1886  tmpSLLBlock =
1887  (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));
1888  (*SLLBlock)->next = tmpSLLBlock;
1889  tmpSLLBlock->next = (ScanLineListBlock *)NULL;
1890  *SLLBlock = tmpSLLBlock;
1891  *iSLLBlock = 0;
1892  }
1893  pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
1894 
1895  pSLL->next = pPrevSLL->next;
1896  pSLL->edgelist = (EdgeTableEntry *)NULL;
1897  pPrevSLL->next = pSLL;
1898  }
1899  pSLL->scanline = scanline;
1900 
1901  /*
1902  * now insert the edge in the right bucket
1903  */
1904  prev = 0;
1905  start = pSLL->edgelist;
1906  while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) {
1907  prev = start;
1908  start = start->next;
1909  }
1910  ETE->next = start;
1911 
1912  if (prev)
1913  prev->next = ETE;
1914  else
1915  pSLL->edgelist = ETE;
1916 }
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
EdgeTableEntry * edgelist
Definition: qregion.cpp:3135
#define SLLSPERBLOCK
struct _EdgeTableEntry * next
Definition: qregion.cpp:3126

◆ InsertionSort()

static int InsertionSort ( register EdgeTableEntry AET)
static

Definition at line 2108 of file qregion_qws.cpp.

Referenced by PolygonRegion().

2109 {
2110  register EdgeTableEntry *pETEchase;
2111  register EdgeTableEntry *pETEinsert;
2112  register EdgeTableEntry *pETEchaseBackTMP;
2113  register int changed = 0;
2114 
2115  AET = AET->next;
2116  while (AET) {
2117  pETEinsert = AET;
2118  pETEchase = AET;
2119  while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
2120  pETEchase = pETEchase->back;
2121 
2122  AET = AET->next;
2123  if (pETEchase != pETEinsert) {
2124  pETEchaseBackTMP = pETEchase->back;
2125  pETEinsert->back->next = AET;
2126  if (AET)
2127  AET->back = pETEinsert->back;
2128  pETEinsert->next = pETEchase;
2129  pETEchase->back->next = pETEinsert;
2130  pETEchase->back = pETEinsert;
2131  pETEinsert->back = pETEchaseBackTMP;
2132  changed = 1;
2133  }
2134  }
2135  return changed;
2136 }
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

Definition at line 235 of file qregion_qws.cpp.

Referenced by PointInRegion(), qt_bitmapToRegion(), qt_region_strictContains(), SubtractRegion(), UnionRectWithRegion(), UnionRegion(), and XorRegion().

236 {
237  return !preg || preg->numRects == 0;
238 }

◆ loadAET()

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

Definition at line 2030 of file qregion_qws.cpp.

Referenced by PolygonRegion().

2031 {
2032  register EdgeTableEntry *pPrevAET;
2033  register EdgeTableEntry *tmp;
2034 
2035  pPrevAET = AET;
2036  AET = AET->next;
2037  while (ETEs) {
2038  while (AET && AET->bres.minor_axis < ETEs->bres.minor_axis) {
2039  pPrevAET = AET;
2040  AET = AET->next;
2041  }
2042  tmp = ETEs->next;
2043  ETEs->next = AET;
2044  if (AET)
2045  AET->back = ETEs;
2046  ETEs->back = pPrevAET;
2047  pPrevAET->next = ETEs;
2048  pPrevAET = ETEs;
2049 
2050  ETEs = tmp;
2051  }
2052 }
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 749 of file qregion_qws.cpp.

Referenced by miRegionOp().

750 {
751  register QRect *pPrevBox; /* Current box in previous band */
752  register QRect *pCurBox; /* Current box in current band */
753  register QRect *pRegEnd; /* End of region */
754  int curNumRects; /* Number of rectangles in current band */
755  int prevNumRects; /* Number of rectangles in previous band */
756  int bandY1; /* Y1 coordinate for current band */
757  QRect *rData = dest.rects.data();
758 
759  pRegEnd = rData + dest.numRects;
760 
761  pPrevBox = rData + prevStart;
762  prevNumRects = curStart - prevStart;
763 
764  /*
765  * Figure out how many rectangles are in the current band. Have to do
766  * this because multiple bands could have been added in miRegionOp
767  * at the end when one region has been exhausted.
768  */
769  pCurBox = rData + curStart;
770  bandY1 = pCurBox->top();
771  for (curNumRects = 0; pCurBox != pRegEnd && pCurBox->top() == bandY1; ++curNumRects) {
772  ++pCurBox;
773  }
774 
775  if (pCurBox != pRegEnd) {
776  /*
777  * If more than one band was added, we have to find the start
778  * of the last band added so the next coalescing job can start
779  * at the right place... (given when multiple bands are added,
780  * this may be pointless -- see above).
781  */
782  --pRegEnd;
783  while ((pRegEnd - 1)->top() == pRegEnd->top())
784  --pRegEnd;
785  curStart = pRegEnd - rData;
786  pRegEnd = rData + dest.numRects;
787  }
788 
789  if (curNumRects == prevNumRects && curNumRects != 0) {
790  pCurBox -= curNumRects;
791  /*
792  * The bands may only be coalesced if the bottom of the previous
793  * matches the top scanline of the current.
794  */
795  if (pPrevBox->bottom() == pCurBox->top() - 1) {
796  /*
797  * Make sure the bands have boxes in the same places. This
798  * assumes that boxes have been added in such a way that they
799  * cover the most area possible. I.e. two boxes in a band must
800  * have some horizontal space between them.
801  */
802  do {
803  if (pPrevBox->left() != pCurBox->left() || pPrevBox->right() != pCurBox->right()) {
804  // The bands don't line up so they can't be coalesced.
805  return curStart;
806  }
807  ++pPrevBox;
808  ++pCurBox;
809  --prevNumRects;
810  } while (prevNumRects != 0);
811 
812  dest.numRects -= curNumRects;
813  pCurBox -= curNumRects;
814  pPrevBox -= curNumRects;
815 
816  /*
817  * The bands may be merged, so set the bottom y of each box
818  * in the previous band to that of the corresponding box in
819  * the current band.
820  */
821  do {
822  pPrevBox->setBottom(pCurBox->bottom());
823  dest.updateInnerRect(*pPrevBox);
824  ++pPrevBox;
825  ++pCurBox;
826  curNumRects -= 1;
827  } while (curNumRects != 0);
828 
829  /*
830  * If only one band was added to the region, we have to backup
831  * curStart to the start of the previous band.
832  *
833  * If more than one band was added to the region, copy the
834  * other bands down. The assumption here is that the other bands
835  * came from the same region as the current one and no further
836  * coalescing can be done on them since it's all been done
837  * already... curStart is already in the right place.
838  */
839  if (pCurBox == pRegEnd) {
840  curStart = prevStart;
841  } else {
842  do {
843  *pPrevBox++ = *pCurBox++;
844  dest.updateInnerRect(*pPrevBox);
845  } while (pCurBox != pRegEnd);
846  }
847  }
848  }
849  return curStart;
850 }
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 684 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

686 {
687  register int x1;
688  register int x2;
689  register QRect *pNextRect;
690 
691  pNextRect = dest.rects.data() + dest.numRects;
692 
693  while (r1 != r1End && r2 != r2End) {
694  x1 = qMax(r1->left(), r2->left());
695  x2 = qMin(r1->right(), r2->right());
696 
697  /*
698  * If there's any overlap between the two rectangles, add that
699  * overlap to the new region.
700  * There's no need to check for subsumption because the only way
701  * such a need could arise is if some region has two rectangles
702  * right next to each other. Since that should never happen...
703  */
704  if (x1 <= x2) {
705  Q_ASSERT(y1 <= y2);
706  MEMCHECK(dest, pNextRect, dest.rects)
707  pNextRect->setCoords(x1, y1, x2, y2);
708  ++dest.numRects;
709  ++pNextRect;
710  }
711 
712  /*
713  * Need to advance the pointers. Shift the one that extends
714  * to the right the least, since the other still has a chance to
715  * overlap with that region's next rectangle, if you see what I mean.
716  */
717  if (r1->right() < r2->right()) {
718  ++r1;
719  } else if (r2->right() < r1->right()) {
720  ++r2;
721  } else {
722  ++r1;
723  ++r2;
724  }
725  }
726 }
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
#define MEMCHECK(dest, rect, firstrect)
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

◆ miRegionOp()

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

Definition at line 878 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion(), SubtractRegion(), and UnionRegion().

881 {
882  register const QRect *r1; // Pointer into first region
883  register const QRect *r2; // Pointer into 2d region
884  const QRect *r1End; // End of 1st region
885  const QRect *r2End; // End of 2d region
886  register int ybot; // Bottom of intersection
887  register int ytop; // Top of intersection
888  int prevBand; // Index of start of previous band in dest
889  int curBand; // Index of start of current band in dest
890  register const QRect *r1BandEnd; // End of current band in r1
891  register const QRect *r2BandEnd; // End of current band in r2
892  int top; // Top of non-overlapping band
893  int bot; // Bottom of non-overlapping band
894 
895  /*
896  * Initialization:
897  * set r1, r2, r1End and r2End appropriately, preserve the important
898  * parts of the destination region until the end in case it's one of
899  * the two source regions, then mark the "new" region empty, allocating
900  * another array of rectangles for it to use.
901  */
902  r1 = (reg1->mode==QRegionPrivate::Vector)?reg1->rects.data():&reg1->single;
903  r2 = (reg2->mode==QRegionPrivate::Vector)?reg2->rects.data():&reg2->single;
904  r1End = r1 + reg1->numRects;
905  r2End = r2 + reg2->numRects;
906 
907  dest.vector();
908  QVector<QRect> oldRects = dest.rects;
909 
910  dest.numRects = 0;
911 
912  /*
913  * Allocate a reasonable number of rectangles for the new region. The idea
914  * is to allocate enough so the individual functions don't need to
915  * reallocate and copy the array, which is time consuming, yet we don't
916  * have to worry about using too much memory. I hope to be able to
917  * nuke the realloc() at the end of this function eventually.
918  */
919  dest.rects.resize(qMax(reg1->numRects,reg2->numRects) * 2);
920 
921  /*
922  * Initialize ybot and ytop.
923  * In the upcoming loop, ybot and ytop serve different functions depending
924  * on whether the band being handled is an overlapping or non-overlapping
925  * band.
926  * In the case of a non-overlapping band (only one of the regions
927  * has points in the band), ybot is the bottom of the most recent
928  * intersection and thus clips the top of the rectangles in that band.
929  * ytop is the top of the next intersection between the two regions and
930  * serves to clip the bottom of the rectangles in the current band.
931  * For an overlapping band (where the two regions intersect), ytop clips
932  * the top of the rectangles of both regions and ybot clips the bottoms.
933  */
934  if (reg1->extents.top() < reg2->extents.top())
935  ybot = reg1->extents.top() - 1;
936  else
937  ybot = reg2->extents.top() - 1;
938 
939  /*
940  * prevBand serves to mark the start of the previous band so rectangles
941  * can be coalesced into larger rectangles. qv. miCoalesce, above.
942  * In the beginning, there is no previous band, so prevBand == curBand
943  * (curBand is set later on, of course, but the first band will always
944  * start at index 0). prevBand and curBand must be indices because of
945  * the possible expansion, and resultant moving, of the new region's
946  * array of rectangles.
947  */
948  prevBand = 0;
949 
950  do {
951  curBand = dest.numRects;
952 
953  /*
954  * This algorithm proceeds one source-band (as opposed to a
955  * destination band, which is determined by where the two regions
956  * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
957  * rectangle after the last one in the current band for their
958  * respective regions.
959  */
960  r1BandEnd = r1;
961  while (r1BandEnd != r1End && r1BandEnd->top() == r1->top())
962  ++r1BandEnd;
963 
964  r2BandEnd = r2;
965  while (r2BandEnd != r2End && r2BandEnd->top() == r2->top())
966  ++r2BandEnd;
967 
968  /*
969  * First handle the band that doesn't intersect, if any.
970  *
971  * Note that attention is restricted to one band in the
972  * non-intersecting region at once, so if a region has n
973  * bands between the current position and the next place it overlaps
974  * the other, this entire loop will be passed through n times.
975  */
976  if (r1->top() < r2->top()) {
977  top = qMax(r1->top(), ybot + 1);
978  bot = qMin(r1->bottom(), r2->top() - 1);
979 
980  if (nonOverlap1Func != 0 && bot >= top)
981  (*nonOverlap1Func)(dest, r1, r1BandEnd, top, bot);
982  ytop = r2->top();
983  } else if (r2->top() < r1->top()) {
984  top = qMax(r2->top(), ybot + 1);
985  bot = qMin(r2->bottom(), r1->top() - 1);
986 
987  if (nonOverlap2Func != 0 && bot >= top)
988  (*nonOverlap2Func)(dest, r2, r2BandEnd, top, bot);
989  ytop = r1->top();
990  } else {
991  ytop = r1->top();
992  }
993 
994  /*
995  * If any rectangles got added to the region, try and coalesce them
996  * with rectangles from the previous band. Note we could just do
997  * this test in miCoalesce, but some machines incur a not
998  * inconsiderable cost for function calls, so...
999  */
1000  if (dest.numRects != curBand)
1001  prevBand = miCoalesce(dest, prevBand, curBand);
1002 
1003  /*
1004  * Now see if we've hit an intersecting band. The two bands only
1005  * intersect if ybot >= ytop
1006  */
1007  ybot = qMin(r1->bottom(), r2->bottom());
1008  curBand = dest.numRects;
1009  if (ybot >= ytop)
1010  (*overlapFunc)(dest, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
1011 
1012  if (dest.numRects != curBand)
1013  prevBand = miCoalesce(dest, prevBand, curBand);
1014 
1015  /*
1016  * If we've finished with a band (y2 == ybot) we skip forward
1017  * in the region to the next band.
1018  */
1019  if (r1->bottom() == ybot)
1020  r1 = r1BandEnd;
1021  if (r2->bottom() == ybot)
1022  r2 = r2BandEnd;
1023  } while (r1 != r1End && r2 != r2End);
1024 
1025  /*
1026  * Deal with whichever region still has rectangles left.
1027  */
1028  curBand = dest.numRects;
1029  if (r1 != r1End) {
1030  if (nonOverlap1Func != 0) {
1031  do {
1032  r1BandEnd = r1;
1033  while (r1BandEnd < r1End && r1BandEnd->top() == r1->top())
1034  ++r1BandEnd;
1035  (*nonOverlap1Func)(dest, r1, r1BandEnd, qMax(r1->top(), ybot + 1), r1->bottom());
1036  r1 = r1BandEnd;
1037  } while (r1 != r1End);
1038  }
1039  } else if ((r2 != r2End) && (nonOverlap2Func != 0)) {
1040  do {
1041  r2BandEnd = r2;
1042  while (r2BandEnd < r2End && r2BandEnd->top() == r2->top())
1043  ++r2BandEnd;
1044  (*nonOverlap2Func)(dest, r2, r2BandEnd, qMax(r2->top(), ybot + 1), r2->bottom());
1045  r2 = r2BandEnd;
1046  } while (r2 != r2End);
1047  }
1048 
1049  if (dest.numRects != curBand)
1050  (void)miCoalesce(dest, prevBand, curBand);
1051 
1052  /*
1053  * A bit of cleanup. To keep regions from growing without bound,
1054  * we shrink the array of rectangles to match the new number of
1055  * rectangles in the region.
1056  *
1057  * Only do this stuff if the number of rectangles allocated is more than
1058  * twice the number of rectangles in the region (a simple optimization).
1059  */
1060  if (qMax(4, dest.numRects) < (dest.rects.size() >> 1))
1061  dest.rects.resize(dest.numRects);
1062 }
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
static int miCoalesce(register QRegionPrivate &dest, int prevStart, int curStart)
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
enum QRegionPrivate::@253 mode
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
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152

◆ miSetExtents()

static void miSetExtents ( QRegionPrivate dest)
static

Definition at line 602 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion(), and SubtractRegion().

603 {
604  register const QRect *pBox,
605  *pBoxEnd;
606  register QRect *pExtents;
607 
608  dest.innerRect.setCoords(0, 0, -1, -1);
609  dest.innerArea = -1;
610  if (dest.numRects == 0) {
611  dest.extents.setCoords(0, 0, 0, 0);
612  return;
613  }
614 
615  pExtents = &dest.extents;
616  pBox = (dest.mode==QRegionPrivate::Vector)?(dest.rects.constData()):(&dest.single);
617  pBoxEnd = (dest.mode==QRegionPrivate::Vector)?(&pBox[dest.numRects - 1]):(&dest.single);
618 
619  /*
620  * Since pBox is the first rectangle in the region, it must have the
621  * smallest y1 and since pBoxEnd is the last rectangle in the region,
622  * it must have the largest y2, because of banding. Initialize x1 and
623  * x2 from pBox and pBoxEnd, resp., as good things to initialize them
624  * to...
625  */
626  pExtents->setLeft(pBox->left());
627  pExtents->setTop(pBox->top());
628  pExtents->setRight(pBoxEnd->right());
629  pExtents->setBottom(pBoxEnd->bottom());
630 
631  Q_ASSERT(pExtents->top() <= pExtents->bottom());
632  while (pBox <= pBoxEnd) {
633  if (pBox->left() < pExtents->left())
634  pExtents->setLeft(pBox->left());
635  if (pBox->right() > pExtents->right())
636  pExtents->setRight(pBox->right());
637  dest.updateInnerRect(*pBox);
638  ++pBox;
639  }
640  Q_ASSERT(pExtents->left() <= pExtents->right());
641 }
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
enum QRegionPrivate::@253 mode
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
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 1210 of file qregion_qws.cpp.

Referenced by SubtractRegion().

1212 {
1213  register QRect *pNextRect;
1214 
1215  pNextRect = dest.rects.data() + dest.numRects;
1216 
1217  Q_ASSERT(y1<=y2);
1218 
1219  while (r != rEnd) {
1220  Q_ASSERT(r->left() <= r->right());
1221  MEMCHECK(dest, pNextRect, dest.rects)
1222  pNextRect->setCoords(r->left(), y1, r->right(), y2);
1223  ++dest.numRects;
1224  ++pNextRect;
1225  ++r;
1226  }
1227 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define MEMCHECK(dest, rect, firstrect)
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
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 1244 of file qregion_qws.cpp.

Referenced by SubtractRegion().

1246 {
1247  register QRect *pNextRect;
1248  register int x1;
1249 
1250  x1 = r1->left();
1251 
1252  Q_ASSERT(y1 <= y2);
1253  pNextRect = dest.rects.data() + dest.numRects;
1254 
1255  while (r1 != r1End && r2 != r2End) {
1256  if (r2->right() < x1) {
1257  /*
1258  * Subtrahend missed the boat: go to next subtrahend.
1259  */
1260  ++r2;
1261  } else if (r2->left() <= x1) {
1262  /*
1263  * Subtrahend precedes minuend: nuke left edge of minuend.
1264  */
1265  x1 = r2->right() + 1;
1266  if (x1 > r1->right()) {
1267  /*
1268  * Minuend completely covered: advance to next minuend and
1269  * reset left fence to edge of new minuend.
1270  */
1271  ++r1;
1272  if (r1 != r1End)
1273  x1 = r1->left();
1274  } else {
1275  // Subtrahend now used up since it doesn't extend beyond minuend
1276  ++r2;
1277  }
1278  } else if (r2->left() <= r1->right()) {
1279  /*
1280  * Left part of subtrahend covers part of minuend: add uncovered
1281  * part of minuend to region and skip to next subtrahend.
1282  */
1283  Q_ASSERT(x1 < r2->left());
1284  MEMCHECK(dest, pNextRect, dest.rects)
1285  pNextRect->setCoords(x1, y1, r2->left() - 1, y2);
1286  ++dest.numRects;
1287  ++pNextRect;
1288 
1289  x1 = r2->right() + 1;
1290  if (x1 > r1->right()) {
1291  /*
1292  * Minuend used up: advance to new...
1293  */
1294  ++r1;
1295  if (r1 != r1End)
1296  x1 = r1->left();
1297  } else {
1298  // Subtrahend used up
1299  ++r2;
1300  }
1301  } else {
1302  /*
1303  * Minuend used up: add any remaining piece before advancing.
1304  */
1305  if (r1->right() >= x1) {
1306  MEMCHECK(dest, pNextRect, dest.rects)
1307  pNextRect->setCoords(x1, y1, r1->right(), y2);
1308  ++dest.numRects;
1309  ++pNextRect;
1310  }
1311  ++r1;
1312  if (r1 != r1End)
1313  x1 = r1->left();
1314  }
1315  }
1316 
1317  /*
1318  * Add remaining minuend rectangles to region.
1319  */
1320  while (r1 != r1End) {
1321  Q_ASSERT(x1 <= r1->right());
1322  MEMCHECK(dest, pNextRect, dest.rects)
1323  pNextRect->setCoords(x1, y1, r1->right(), y2);
1324  ++dest.numRects;
1325  ++pNextRect;
1326 
1327  ++r1;
1328  if (r1 != r1End)
1329  x1 = r1->left();
1330  }
1331 }
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
#define MEMCHECK(dest, rect, firstrect)
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
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 1085 of file qregion_qws.cpp.

Referenced by UnionRegion().

1087 {
1088  register QRect *pNextRect;
1089 
1090  pNextRect = dest.rects.data() + dest.numRects;
1091 
1092  Q_ASSERT(y1 <= y2);
1093 
1094  while (r != rEnd) {
1095  Q_ASSERT(r->left() <= r->right());
1096  MEMCHECK(dest, pNextRect, dest.rects)
1097  pNextRect->setCoords(r->left(), y1, r->right(), y2);
1098  dest.numRects++;
1099  ++pNextRect;
1100  ++r;
1101  }
1102 }
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define MEMCHECK(dest, rect, firstrect)
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
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 1121 of file qregion_qws.cpp.

Referenced by UnionRegion().

1123 {
1124  register QRect *pNextRect;
1125 
1126  pNextRect = dest.rects.data() + dest.numRects;
1127 
1128 #define MERGERECT(r) \
1129  if ((dest.numRects != 0) && \
1130  (pNextRect[-1].top() == y1) && \
1131  (pNextRect[-1].bottom() == y2) && \
1132  (pNextRect[-1].right() >= r->left()-1)) { \
1133  if (pNextRect[-1].right() < r->right()) { \
1134  pNextRect[-1].setRight(r->right()); \
1135  dest.updateInnerRect(pNextRect[-1]); \
1136  Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \
1137  } \
1138  } else { \
1139  MEMCHECK(dest, pNextRect, dest.rects) \
1140  pNextRect->setCoords(r->left(), y1, r->right(), y2); \
1141  dest.updateInnerRect(*pNextRect); \
1142  dest.numRects++; \
1143  pNextRect++; \
1144  } \
1145  r++;
1146 
1147  Q_ASSERT(y1 <= y2);
1148  while (r1 != r1End && r2 != r2End) {
1149  if (r1->left() < r2->left()) {
1150  MERGERECT(r1)
1151  } else {
1152  MERGERECT(r2)
1153  }
1154  }
1155 
1156  if (r1 != r1End) {
1157  do {
1158  MERGERECT(r1)
1159  } while (r1 != r1End);
1160  } else {
1161  while (r2 != r2End) {
1162  MERGERECT(r2)
1163  }
1164  }
1165 }
#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 648 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

649 {
650  register int nbox;
651  register QRect *pbox;
652 
653  if(region.mode == QRegionPrivate::Single) {
654  region.single.translate(x, y);
655  } else {
656  pbox = region.rects.data();
657  nbox = region.numRects;
658 
659  while (nbox--) {
660  pbox->translate(x, y);
661  ++pbox;
662  }
663  }
664  region.extents.translate(x, y);
665  region.innerRect.translate(x, y);
666 }
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

◆ PointInRegion()

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

Definition at line 1422 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

1423 {
1424  int i;
1425 
1426  if (pRegion->mode == QRegionPrivate::Single)
1427  return pRegion->single.contains(x, y);
1428  if (isEmptyHelper(pRegion))
1429  return false;
1430  if (!pRegion->extents.contains(x, y))
1431  return false;
1432  if (pRegion->innerRect.contains(x, y))
1433  return true;
1434  for (i = 0; i < pRegion->numRects; ++i) {
1435  if (pRegion->rects[i].contains(x, y))
1436  return true;
1437  }
1438  return false;
1439 }
static bool isEmptyHelper(const QRegionPrivate *preg)
enum QRegionPrivate::@253 mode
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

◆ PolygonRegion()

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

Definition at line 2227 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

2232 {
2233  register EdgeTableEntry *pAET; /* Active Edge Table */
2234  register int y; /* current scanline */
2235  register int iPts = 0; /* number of pts in buffer */
2236  register EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/
2237  register ScanLineList *pSLL; /* current scanLineList */
2238  register QPoint *pts; /* output buffer */
2239  EdgeTableEntry *pPrevAET; /* ptr to previous AET */
2240  EdgeTable ET; /* header node for ET */
2241  EdgeTableEntry AET; /* header node for AET */
2242  EdgeTableEntry *pETEs; /* EdgeTableEntries pool */
2243  ScanLineListBlock SLLBlock; /* header for scanlinelist */
2244  int fixWAET = false;
2245  POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */
2246  POINTBLOCK *tmpPtBlock;
2247  int numFullPtBlocks = 0;
2248 
2249  region->vector();
2250 
2251  /* special case a rectangle */
2252  if (((Count == 4) ||
2253  ((Count == 5) && (Pts[4].x() == Pts[0].x()) && (Pts[4].y() == Pts[0].y())))
2254  && (((Pts[0].y() == Pts[1].y()) && (Pts[1].x() == Pts[2].x()) && (Pts[2].y() == Pts[3].y())
2255  && (Pts[3].x() == Pts[0].x())) || ((Pts[0].x() == Pts[1].x())
2256  && (Pts[1].y() == Pts[2].y()) && (Pts[2].x() == Pts[3].x())
2257  && (Pts[3].y() == Pts[0].y())))) {
2258  int x = qMin(Pts[0].x(), Pts[2].x());
2259  region->extents.setLeft(x);
2260  int y = qMin(Pts[0].y(), Pts[2].y());
2261  region->extents.setTop(y);
2262  region->extents.setWidth(qMax(Pts[0].x(), Pts[2].x()) - x);
2263  region->extents.setHeight(qMax(Pts[0].y(), Pts[2].y()) - y);
2264  if ((region->extents.left() <= region->extents.right()) &&
2265  (region->extents.top() <= region->extents.bottom())) {
2266  region->numRects = 1;
2267  region->rects.resize(1);
2268  region->rects[0] = region->extents;
2269  region->innerRect = region->extents;
2270  region->innerArea = region->innerRect.width() * region->innerRect.height();
2271  }
2272  return region;
2273  }
2274 
2275  if (!(pETEs = static_cast<EdgeTableEntry *>(malloc(sizeof(EdgeTableEntry) * Count))))
2276  return 0;
2277 
2278  pts = FirstPtBlock.pts;
2279  CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock);
2280  pSLL = ET.scanlines.next;
2281  curPtBlock = &FirstPtBlock;
2282 
2283  if (rule == EvenOddRule) {
2284  /*
2285  * for each scanline
2286  */
2287  for (y = ET.ymin; y < ET.ymax; ++y) {
2288  /*
2289  * Add a new edge to the active edge table when we
2290  * get to the next edge.
2291  */
2292  if (pSLL && y == pSLL->scanline) {
2293  loadAET(&AET, pSLL->edgelist);
2294  pSLL = pSLL->next;
2295  }
2296  pPrevAET = &AET;
2297  pAET = AET.next;
2298 
2299  /*
2300  * for each active edge
2301  */
2302  while (pAET) {
2303  pts->setX(pAET->bres.minor_axis);
2304  pts->setY(y);
2305  ++pts;
2306  ++iPts;
2307 
2308  /*
2309  * send out the buffer
2310  */
2311  if (iPts == NUMPTSTOBUFFER) {
2312  tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK));
2313  curPtBlock->next = tmpPtBlock;
2314  curPtBlock = tmpPtBlock;
2315  pts = curPtBlock->pts;
2316  ++numFullPtBlocks;
2317  iPts = 0;
2318  }
2319  EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
2320  }
2321  InsertionSort(&AET);
2322  }
2323  } else {
2324  /*
2325  * for each scanline
2326  */
2327  for (y = ET.ymin; y < ET.ymax; ++y) {
2328  /*
2329  * Add a new edge to the active edge table when we
2330  * get to the next edge.
2331  */
2332  if (pSLL && y == pSLL->scanline) {
2333  loadAET(&AET, pSLL->edgelist);
2334  computeWAET(&AET);
2335  pSLL = pSLL->next;
2336  }
2337  pPrevAET = &AET;
2338  pAET = AET.next;
2339  pWETE = pAET;
2340 
2341  /*
2342  * for each active edge
2343  */
2344  while (pAET) {
2345  /*
2346  * add to the buffer only those edges that
2347  * are in the Winding active edge table.
2348  */
2349  if (pWETE == pAET) {
2350  pts->setX(pAET->bres.minor_axis);
2351  pts->setY(y);
2352  ++pts;
2353  ++iPts;
2354 
2355  /*
2356  * send out the buffer
2357  */
2358  if (iPts == NUMPTSTOBUFFER) {
2359  tmpPtBlock = static_cast<POINTBLOCK *>(malloc(sizeof(POINTBLOCK)));
2360  curPtBlock->next = tmpPtBlock;
2361  curPtBlock = tmpPtBlock;
2362  pts = curPtBlock->pts;
2363  ++numFullPtBlocks;
2364  iPts = 0;
2365  }
2366  pWETE = pWETE->nextWETE;
2367  }
2368  EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
2369  }
2370 
2371  /*
2372  * recompute the winding active edge table if
2373  * we just resorted or have exited an edge.
2374  */
2375  if (InsertionSort(&AET) || fixWAET) {
2376  computeWAET(&AET);
2377  fixWAET = false;
2378  }
2379  }
2380  }
2381  FreeStorage(SLLBlock.next);
2382  PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
2383  for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
2384  tmpPtBlock = curPtBlock->next;
2385  free(curPtBlock);
2386  curPtBlock = tmpPtBlock;
2387  }
2388  free(pETEs);
2389  return region;
2390 }
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
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
static void PtsToRegion(register int numFullPtBlocks, register int iCurPtBlock, POINTBLOCK *FirstPtBlock, QRegionPrivate *reg)
QPoint * pts
Definition: qregion.cpp:1889
ScanLineList scanlines
Definition: qregion.cpp:3143
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 CreateETandAET(register int count, register const QPoint *pts, EdgeTable *ET, EdgeTableEntry *AET, register EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
struct _EdgeTableEntry * nextWETE
Definition: qregion.cpp:3128
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
#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
BRESINFO bres
Definition: qregion.cpp:3125
struct _ScanLineListBlock * next
Definition: qregion.cpp:3156
static void loadAET(register EdgeTableEntry *AET, register EdgeTableEntry *ETEs)
void setTop(int pos)
Sets the top edge of the rectangle to the given y coordinate.
Definition: qrect.h:261
static void computeWAET(register EdgeTableEntry *AET)
#define NUMPTSTOBUFFER
EdgeTableEntry * edgelist
Definition: qregion.cpp:3135
static int InsertionSort(register EdgeTableEntry *AET)
QVector< QRect > rects
Definition: qregion.cpp:1227
#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
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
void setX(int x)
Sets the x coordinate of this point to the given x coordinate.
Definition: qpoint.h:134
#define EvenOddRule
static void FreeStorage(register ScanLineListBlock *pSLLBlock)

◆ PtsToRegion()

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

Definition at line 2160 of file qregion_qws.cpp.

Referenced by PolygonRegion().

2162 {
2163  register QRect *rects;
2164  register QPoint *pts;
2165  register POINTBLOCK *CurPtBlock;
2166  register int i;
2167  register QRect *extents;
2168  register int numRects;
2169 
2170  extents = &reg->extents;
2171  numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
2172 
2173  reg->rects.resize(numRects);
2174 
2175  CurPtBlock = FirstPtBlock;
2176  rects = reg->rects.data() - 1;
2177  numRects = 0;
2178  extents->setLeft(INT_MAX);
2179  extents->setRight(INT_MIN);
2180  reg->innerArea = -1;
2181 
2182  for (; numFullPtBlocks >= 0; --numFullPtBlocks) {
2183  /* the loop uses 2 points per iteration */
2184  i = NUMPTSTOBUFFER >> 1;
2185  if (!numFullPtBlocks)
2186  i = iCurPtBlock >> 1;
2187  if(i) {
2188  for (pts = CurPtBlock->pts; i--; pts += 2) {
2189  if (pts->x() == pts[1].x())
2190  continue;
2191  if (numRects && pts->x() == rects->left() && pts->y() == rects->bottom() + 1
2192  && pts[1].x() == rects->right()+1 && (numRects == 1 || rects[-1].top() != rects->top())
2193  && (i && pts[2].y() > pts[1].y())) {
2194  rects->setBottom(pts[1].y());
2195  reg->updateInnerRect(*rects);
2196  continue;
2197  }
2198  ++numRects;
2199  ++rects;
2200  rects->setCoords(pts->x(), pts->y(), pts[1].x() - 1, pts[1].y());
2201  if (rects->left() < extents->left())
2202  extents->setLeft(rects->left());
2203  if (rects->right() > extents->right())
2204  extents->setRight(rects->right());
2205  reg->updateInnerRect(*rects);
2206  }
2207  }
2208  CurPtBlock = CurPtBlock->next;
2209  }
2210 
2211  if (numRects) {
2212  extents->setTop(reg->rects[0].top());
2213  extents->setBottom(rects->bottom());
2214  } else {
2215  extents->setCoords(0, 0, 0, 0);
2216  }
2217  reg->numRects = numRects;
2218 }
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
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
QPoint * pts
Definition: qregion.cpp:1889
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
void resize(int size)
Sets the size of the vector to size.
Definition: qvector.h:342
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
#define NUMPTSTOBUFFER
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 QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
T * data()
Returns a pointer to the data stored in the vector.
Definition: qvector.h:152
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
#define INT_MAX

◆ qt_allocRegion() [1/3]

static QRegionPrivate* qt_allocRegion ( )
static

Definition at line 210 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

211 {
213  return new (mem) QRegionPrivate;
214 }
static QRegionPrivate * qt_allocRegionMemory()

◆ qt_allocRegion() [2/3]

static QRegionPrivate* qt_allocRegion ( const QRect r)
static

Definition at line 216 of file qregion_qws.cpp.

217 {
219  return new (mem) QRegionPrivate(r);
220 }
static QRegionPrivate * qt_allocRegionMemory()

◆ qt_allocRegion() [3/3]

static QRegionPrivate* qt_allocRegion ( const QRegionPrivate r)
static

Definition at line 222 of file qregion_qws.cpp.

223 {
225  return new (mem) QRegionPrivate(r);
226 }
static QRegionPrivate * qt_allocRegionMemory()

◆ qt_allocRegionMemory()

static QRegionPrivate* qt_allocRegionMemory ( )
static

Definition at line 175 of file qregion_qws.cpp.

Referenced by qt_allocRegion().

176 {
177  QRegionPrivate *rv = 0;
179 
180  if(qt_nextRegionPtr) {
181  rv = qt_nextRegionPtr;
182  qt_nextRegionPtr = rv->next;
183  } else {
185  (QRegionPrivate *)malloc(256 * sizeof(QRegionPrivate));
186  for(int ii = 0; ii < 256; ++ii) {
187  if(ii == 255) {
188  qt_nextRegionPtr[ii].next = 0;
189  } else {
190  qt_nextRegionPtr[ii].next = &qt_nextRegionPtr[ii + 1];
191  }
192  }
193 
194  rv = qt_nextRegionPtr;
195  qt_nextRegionPtr = rv->next;
196  }
197 
199  return rv;
200 }
static QFastMutex qt_nextRegionLock
QRegionPrivate * next
void lock()
Definition: qregion_qws.cpp:66
void unlock()
Definition: qregion_qws.cpp:77
static QRegionPrivate * qt_nextRegionPtr

◆ qt_bitmapToRegion()

QRegionPrivate* qt_bitmapToRegion ( const QBitmap bitmap,
QRegionPrivate region 
)

Definition at line 2393 of file qregion_qws.cpp.

2394 {
2395  region->vector();
2396 
2397  QImage image = bitmap.toImage();
2398 
2399  QRect xr;
2400 
2401 #define AddSpan \
2402  { \
2403  xr.setCoords(prev1, y, x-1, y); \
2404  UnionRectWithRegion(&xr, region, *region); \
2405  }
2406 
2407  const uchar zero = 0;
2408  bool little = image.format() == QImage::Format_MonoLSB;
2409 
2410  int x,
2411  y;
2412  for (y = 0; y < image.height(); ++y) {
2413  uchar *line = image.scanLine(y);
2414  int w = image.width();
2415  uchar all = zero;
2416  int prev1 = -1;
2417  for (x = 0; x < w;) {
2418  uchar byte = line[x / 8];
2419  if (x > w - 8 || byte!=all) {
2420  if (little) {
2421  for (int b = 8; b > 0 && x < w; --b) {
2422  if (!(byte & 0x01) == !all) {
2423  // More of the same
2424  } else {
2425  // A change.
2426  if (all!=zero) {
2427  AddSpan
2428  all = zero;
2429  } else {
2430  prev1 = x;
2431  all = ~zero;
2432  }
2433  }
2434  byte >>= 1;
2435  ++x;
2436  }
2437  } else {
2438  for (int b = 8; b > 0 && x < w; --b) {
2439  if (!(byte & 0x80) == !all) {
2440  // More of the same
2441  } else {
2442  // A change.
2443  if (all != zero) {
2444  AddSpan
2445  all = zero;
2446  } else {
2447  prev1 = x;
2448  all = ~zero;
2449  }
2450  }
2451  byte <<= 1;
2452  ++x;
2453  }
2454  }
2455  } else {
2456  x += 8;
2457  }
2458  }
2459  if (all != zero) {
2460  AddSpan
2461  }
2462  }
2463 #undef AddSpan
2464 
2465  return region;
2466 }
QImage toImage() const
Converts the pixmap to a QImage.
Definition: qpixmap.cpp:542
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
#define AddSpan
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
Definition: qimage.cpp:1886

◆ qt_freeRegion()

void qt_freeRegion ( QRegionPrivate rp)

Definition at line 228 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

229 {
230  rp->~QRegionPrivate();
232 // delete rp;
233 }
static void qt_freeRegionMemory(QRegionPrivate *rp)

◆ qt_freeRegionMemory()

static void qt_freeRegionMemory ( QRegionPrivate rp)
static

Definition at line 202 of file qregion_qws.cpp.

Referenced by qt_freeRegion().

203 {
205  rp->next = qt_nextRegionPtr;
206  qt_nextRegionPtr = rp;
208 }
static QFastMutex qt_nextRegionLock
QRegionPrivate * next
void lock()
Definition: qregion_qws.cpp:66
void unlock()
Definition: qregion_qws.cpp:77
static QRegionPrivate * qt_nextRegionPtr

◆ qt_region_strictContains()

bool qt_region_strictContains ( const QRegion region,
const QRect rect 
)
Warning
This function is not part of the public interface.

A false return value does not guarantee the opposite.

Definition at line 3057 of file qregion_qws.cpp.

3058 {
3059  if (isEmptyHelper(region.d->qt_rgn) || !rect.isValid())
3060  return false;
3061 
3062 #if 0 // TEST_INNERRECT
3063  static bool guard = false;
3064  if (guard)
3065  return QRect();
3066  guard = true;
3067  QRegion inner = region.d->qt_rgn->innerRect;
3068  Q_ASSERT((inner - region).isEmpty());
3069  guard = false;
3070 
3071  int maxArea = 0;
3072  for (int i = 0; i < region.d->qt_rgn->numRects; ++i) {
3073  const QRect r = region.d->qt_rgn->rects.at(i);
3074  if (r.width() * r.height() > maxArea)
3075  maxArea = r.width() * r.height();
3076  }
3077 
3078  if (maxArea > region.d->qt_rgn->innerArea) {
3079  qDebug() << "not largest rectangle" << region << region.d->qt_rgn->innerRect;
3080  }
3081  Q_ASSERT(maxArea <= region.d->qt_rgn->innerArea);
3082 #endif
3083 
3084  const QRect r1 = region.d->qt_rgn->innerRect;
3085  return (rect.left() >= r1.left() && rect.right() <= r1.right()
3086  && rect.top() >= r1.top() && rect.bottom() <= r1.bottom());
3087 }
static bool isEmptyHelper(const QRegionPrivate *preg)
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

◆ RectInRegion()

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

Definition at line 1441 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

1442 {
1443  register const QRect *pbox;
1444  register const QRect *pboxEnd;
1445  QRect rect(rx, ry, rwidth, rheight);
1446  register QRect *prect = &rect;
1447  int partIn, partOut;
1448 
1449  if (!region || region->numRects == 0 || !EXTENTCHECK(&region->extents, prect))
1450  return RectangleOut;
1451 
1452  partOut = false;
1453  partIn = false;
1454 
1455  /* can stop when both partOut and partIn are true, or we reach prect->y2 */
1456  for (pbox = (region->mode==QRegionPrivate::Vector)?region->rects.constData():&region->single, pboxEnd = pbox + region->numRects;
1457  pbox < pboxEnd; ++pbox) {
1458  if (pbox->bottom() < ry)
1459  continue;
1460 
1461  if (pbox->top() > ry) {
1462  partOut = true;
1463  if (partIn || pbox->top() > prect->bottom())
1464  break;
1465  ry = pbox->top();
1466  }
1467 
1468  if (pbox->right() < rx)
1469  continue; /* not far enough over yet */
1470 
1471  if (pbox->left() > rx) {
1472  partOut = true; /* missed part of rectangle to left */
1473  if (partIn)
1474  break;
1475  }
1476 
1477  if (pbox->left() <= prect->right()) {
1478  partIn = true; /* definitely overlap */
1479  if (partOut)
1480  break;
1481  }
1482 
1483  if (pbox->right() >= prect->right()) {
1484  ry = pbox->bottom() + 1; /* finished with this band */
1485  if (ry > prect->bottom())
1486  break;
1487  rx = prect->left(); /* reset x out to left again */
1488  } else {
1489  /*
1490  * Because boxes in a band are maximal width, if the first box
1491  * to overlap the rectangle doesn't completely cover it in that
1492  * band, the rectangle must be partially out, since some of it
1493  * will be uncovered in that band. partIn will have been set true
1494  * by now...
1495  */
1496  break;
1497  }
1498  }
1499  return partIn ? ((ry <= prect->bottom()) ? RectanglePart : RectangleIn) : RectangleOut;
1500 }
int left() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:240
#define RectangleIn
#define EXTENTCHECK(r1, r2)
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
#define RectangleOut
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
#define RectanglePart

◆ SubtractRegion()

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

Definition at line 1345 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion(), and XorRegion().

1347 {
1348  Q_ASSERT(!isEmptyHelper(regM));
1349  Q_ASSERT(!isEmptyHelper(regS));
1350  Q_ASSERT(EXTENTCHECK(&regM->extents, &regS->extents));
1351  Q_ASSERT(!regS->contains(*regM));
1352  Q_ASSERT(!EqualRegion(regM, regS));
1353 
1354  miRegionOp(dest, regM, regS, miSubtractO, miSubtractNonO1, 0);
1355 
1356  /*
1357  * Can't alter dest's extents before we call miRegionOp because
1358  * it might be one of the source regions and miRegionOp depends
1359  * on the extents of those regions being the unaltered. Besides, this
1360  * way there's no checking against rectangles that will be nuked
1361  * due to coalescing, so we have to examine fewer rectangles.
1362  */
1363  miSetExtents(dest);
1364 }
static bool isEmptyHelper(const QRegionPrivate *preg)
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 miSubtractNonO1(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, register int y1, register int y2)
#define EXTENTCHECK(r1, r2)
static void miSetExtents(QRegionPrivate &dest)
static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static void miRegionOp(register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2, OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func, NonOverlapFunc nonOverlap2Func)
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 568 of file qregion_qws.cpp.

570 {
571  if (!rect->width() || !rect->height())
572  return;
573 
574  QRegionPrivate region(*rect);
575 
576  Q_ASSERT(EqualRegion(source, &dest));
577  Q_ASSERT(!isEmptyHelper(&region));
578 
579  if (dest.numRects == 0)
580  dest = region;
581  else if (dest.canAppend(&region))
582  dest.append(&region);
583  else
584  UnionRegion(&region, source, dest);
585 }
static bool isEmptyHelper(const QRegionPrivate *preg)
void append(const QRect *r)
Definition: qregion.cpp:1460
static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest)
static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
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 1167 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion(), UnionRectWithRegion(), and XorRegion().

1168 {
1169  Q_ASSERT(!isEmptyHelper(reg1) && !isEmptyHelper(reg2));
1170  Q_ASSERT(!reg1->contains(*reg2));
1171  Q_ASSERT(!reg2->contains(*reg1));
1172  Q_ASSERT(!EqualRegion(reg1, reg2));
1173  Q_ASSERT(!reg1->canAppend(reg2));
1174  Q_ASSERT(!reg2->canAppend(reg1));
1175 
1176  if (reg1->innerArea > reg2->innerArea) {
1177  dest.innerArea = reg1->innerArea;
1178  dest.innerRect = reg1->innerRect;
1179  } else {
1180  dest.innerArea = reg2->innerArea;
1181  dest.innerRect = reg2->innerRect;
1182  }
1183  miRegionOp(dest, reg1, reg2, miUnionO, miUnionNonO, miUnionNonO);
1184 
1185  dest.extents.setCoords(qMin(reg1->extents.left(), reg2->extents.left()),
1186  qMin(reg1->extents.top(), reg2->extents.top()),
1187  qMax(reg1->extents.right(), reg2->extents.right()),
1188  qMax(reg1->extents.bottom(), reg2->extents.bottom()));
1189 }
static bool isEmptyHelper(const QRegionPrivate *preg)
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 bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
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
static void miRegionOp(register QRegionPrivate &dest, const QRegionPrivate *reg1, const QRegionPrivate *reg2, OverlapFunc overlapFunc, NonOverlapFunc nonOverlap1Func, NonOverlapFunc nonOverlap2Func)
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 miUnionO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End, register const QRect *r2, const QRect *r2End, register int y1, register int y2)
bool contains(const QRegionPrivate &r) const
Definition: qregion.cpp:1263
static void miUnionNonO(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd, register int y1, register int y2)

◆ XorRegion()

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

Definition at line 1366 of file qregion_qws.cpp.

Referenced by qt_bitmapToRegion().

1367 {
1368  Q_ASSERT(!isEmptyHelper(sra) && !isEmptyHelper(srb));
1369  Q_ASSERT(EXTENTCHECK(&sra->extents, &srb->extents));
1370  Q_ASSERT(!EqualRegion(sra, srb));
1371 
1372  QRegionPrivate tra, trb;
1373 
1374  if (!srb->contains(*sra))
1375  SubtractRegion(sra, srb, tra);
1376  if (!sra->contains(*srb))
1377  SubtractRegion(srb, sra, trb);
1378 
1379  Q_ASSERT(isEmptyHelper(&trb) || !tra.contains(trb));
1380  Q_ASSERT(isEmptyHelper(&tra) || !trb.contains(tra));
1381 
1382  if (isEmptyHelper(&tra)) {
1383  dest = trb;
1384  } else if (isEmptyHelper(&trb)) {
1385  dest = tra;
1386  } else if (tra.canAppend(&trb)) {
1387  dest = tra;
1388  dest.append(&trb);
1389  } else if (trb.canAppend(&tra)) {
1390  dest = trb;
1391  dest.append(&tra);
1392  } else {
1393  UnionRegion(&tra, &trb, dest);
1394  }
1395 }
static bool isEmptyHelper(const QRegionPrivate *preg)
void append(const QRect *r)
Definition: qregion.cpp:1460
#define EXTENTCHECK(r1, r2)
static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest)
static bool EqualRegion(const QRegionPrivate *r1, const QRegionPrivate *r2)
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static void SubtractRegion(QRegionPrivate *regM, QRegionPrivate *regS, register QRegionPrivate &dest)
bool canAppend(const QRect *r) const
Definition: qregion.cpp:1669
bool contains(const QRegionPrivate &r) const
Definition: qregion.cpp:1263

Variable Documentation

◆ qt_nextRegionLock

QFastMutex qt_nextRegionLock
static

Definition at line 173 of file qregion_qws.cpp.

◆ qt_nextRegionPtr

QRegionPrivate* qt_nextRegionPtr = 0
static

Definition at line 172 of file qregion_qws.cpp.

Referenced by qt_allocRegionMemory(), and qt_freeRegionMemory().