📄 qregion_qws.cpp
字号:
pExtents->setBottom( pBoxEnd->bottom() ); ASSERT(pExtents->top() <= pExtents->bottom()); while (pBox <= pBoxEnd) { if (pBox->left() < pExtents->left()) { pExtents->setLeft( pBox->left() ); } if (pBox->right() > pExtents->right()) { pExtents->setRight( pBox->right() ); } pBox++; } ASSERT(pExtents->left() <= pExtents->right());}staticintXDestroyRegion( Region r ){ delete r; return 1;}/* TranslateRegion(pRegion, x, y) translates in place added by raymond*/staticintXOffsetRegion(register Region pRegion, register int x, register int y){ register int nbox; register QRect *pbox; pbox = pRegion->rects.data(); nbox = pRegion->numRects; while(nbox--) { pbox->moveBy(x, y); pbox++; } pRegion->extents.moveBy(x, y); return 1;}#if 0/* Utility procedure Compress: Replace r by the region r', where p in r' iff (Quantifer m <= dx) (p + m in r), and Quantifier is Exists if grow is TRUE, For all if grow is FALSE, and (x,y) + m = (x+m,y) if xdir is TRUE; (x,y+m) if xdir is FALSE. Thus, if xdir is TRUE and grow is FALSE, r is replaced by the region of all points p such that p and the next dx points on the same horizontal scan line are all in r. We do this using by noting that p is the head of a run of length 2^i + k iff p is the head of a run of length 2^i and p+2^i is the head of a run of length k. Thus, the loop invariant: s contains the region corresponding to the runs of length shift. r contains the region corresponding to the runs of length 1 + dxo & (shift-1), where dxo is the original value of dx. dx = dxo & ~(shift-1). As parameters, s and t are scratch regions, so that we don't have to allocate them on every call.*/#define ZOpRegion(a,b,c) if (grow) XUnionRegion(a,b,c); \ else XIntersectRegion(a,b,c)#define ZShiftRegion(a,b) if (xdir) XOffsetRegion(a,b,0); \ else XOffsetRegion(a,0,b)#define ZCopyRegion(a,b) XUnionRegion(a,a,b)static voidCompress(Region r, Region s, Region t, register unsigned dx, register int xdir, register int grow){ register unsigned shift = 1; ZCopyRegion(r, s); while (dx) { if (dx & shift) { ZShiftRegion(r, -(int)shift); ZOpRegion(r, s, r); dx -= shift; if (!dx) break; } ZCopyRegion(s, t); ZShiftRegion(s, -(int)shift); ZOpRegion(s, t, s); shift <<= 1; }}#undef ZOpRegion#undef ZShiftRegion#undef ZCopyRegionstaticintXShrinkRegion(Region r, int dx, int dy){ Region s, t; int grow; if (!dx && !dy) return 0; if ((! (s = XCreateRegion())) || (! (t = XCreateRegion()))) return 0; if ((grow = (dx < 0))) dx = -dx; if (dx) Compress(r, s, t, (unsigned) 2*dx, TRUE, grow); if ((grow = (dy < 0))) dy = -dy; if (dy) Compress(r, s, t, (unsigned) 2*dy, FALSE, grow); XOffsetRegion(r, dx, dy); XDestroyRegion(s); XDestroyRegion(t); return 0;}#endif#ifdef notdef/*********************************************************** * Bop down the array of rects until we have passed * scanline y. numRects is the size of the array. ***********************************************************/static BOX*IndexRects(rects, numRects, y) register BOX *rects; register int numRects; register int y;{ while ((numRects--) && (rects->y2 <= y)) rects++; return(rects);}#endif/*====================================================================== * Region Intersection *====================================================================*//*- *----------------------------------------------------------------------- * miIntersectO -- * Handle an overlapping band for miIntersect. * * Results: * None. * * Side Effects: * Rectangles may be added to the region. * *----------------------------------------------------------------------- *//* static void*/staticintmiIntersectO (register Region pReg, register QRect *r1, QRect *r1End, register QRect *r2, QRect *r2End, int y1, int y2){ register int x1; register int x2; register QRect *pNextRect; pNextRect = pReg->rects.data() + pReg->numRects; while ((r1 != r1End) && (r2 != r2End)) { x1 = QMAX(r1->left(),r2->left()); x2 = QMIN(r1->right(),r2->right()); /* * If there's any overlap between the two rectangles, add that * overlap to the new region. * There's no need to check for subsumption because the only way * such a need could arise is if some region has two rectangles * right next to each other. Since that should never happen... */ if (x1 <= x2) { ASSERT(y1<=y2); MEMCHECK(pReg, pNextRect, pReg->rects) pNextRect->setCoords( x1, y1, x2, y2 ); pReg->numRects++; pNextRect++; } /* * Need to advance the pointers. Shift the one that extends * to the right the least, since the other still has a chance to * overlap with that region's next rectangle, if you see what I mean. */ if (r1->right() < r2->right()) { r1++; } else if (r2->right() < r1->right()) { r2++; } else { r1++; r2++; } } return 0; /* lint */}staticintXIntersectRegion(Region reg1, Region reg2, register Region newReg){ /* check for trivial reject */ if ( (!(reg1->numRects)) || (!(reg2->numRects)) || (!EXTENTCHECK(®1->extents, ®2->extents))) newReg->numRects = 0; else miRegionOp (newReg, reg1, reg2, (voidProcp) miIntersectO, (voidProcp) NULL, (voidProcp) NULL); /* * Can't alter newReg's extents before we call miRegionOp because * it might be one of the source regions and miRegionOp depends * on the extents of those regions being the same. Besides, this * way there's no checking against rectangles that will be nuked * due to coalescing, so we have to examine fewer rectangles. */ miSetExtents(newReg); return 1;}static voidmiRegionCopy(register Region dstrgn, register Region rgn){ if (dstrgn != rgn) /* don't want to copy to itself */ { dstrgn->numRects = rgn->numRects; dstrgn->extents = rgn->extents; dstrgn->rects = rgn->rects.copy(); }}#ifdef notdef/* * combinRegs(newReg, reg1, reg2) * if one region is above or below the other.*/static voidcombineRegs(register Region newReg, Region reg1, Region reg2){ register QRect *rects; register QRect *rects1; register QRect *rects2; register int total; rects1 = reg1->rects.data(); rects2 = reg2->rects.data(); total = reg1->numRects + reg2->numRects; newReg->rects.resize(total); rects = &newReg->rects.data(); /* region 1 is below region 2 */ if (reg1->extents.top() > reg2->extents.top()) { int r2count = reg2->numRects; while ( r2count-- ) *rects++ = *rects2++; total -= newReg->numRects; while (total--) *rects++ = *rects1++; } else { int r1count = reg1->numRects; while ( r1count-- ) *rects++ = *rects1++; total -= newReg->numRects; while (total--) *rects++ = *rects2++; } newReg->extents = reg1->extents; newReg->numRects = reg1->numRects + reg2->numRects; EXTENTS(®2->extents, newReg);}/* * QuickCheck checks to see if it does not have to go through all the * the ugly code for the region call. It returns 1 if it did all * the work for Union, otherwise 0 - still work to be done.*/static intQuickCheck(Region newReg, Region reg1, Region reg2){ /* if unioning with itself or no rects to union with */ if ( (reg1 == reg2) || (!(reg1->numRects)) ) { miRegionCopy(newReg, reg2); return TRUE; } /* if nothing to union */ if (!(reg2->numRects)) { miRegionCopy(newReg, reg1); return TRUE; } /* could put an extent check to see if add above or below */ if ((reg1->extents.top() >= reg2->extents.bottom()) || (reg2->extents.top() >= reg1->extents.bottom()) ) { combineRegs(newReg, reg1, reg2); return TRUE; } return FALSE;}/* TopRects(rects, reg1, reg2) * N.B. We now assume that reg1 and reg2 intersect. Therefore we are * NOT checking in the two while loops for stepping off the end of the * region. */static intTopRects(register Region newReg, register QRect *rects, register Region reg1, register Region reg2, QRect *FirstRect){ register QRect *tempRects; /* need to add some rects from region 1 */ if (reg1->extents.top() < reg2->extents.top()) { tempRects = reg1->rects.data(); while(tempRects->top() < reg2->extents.top()) { MEMCHECK(newReg, tempRects, newReg->rects) ADDRECTNOX(newReg,rects, tempRects->left(), tempRects->top(), tempRects->right(), MIN(tempRects->bottom(), reg2->extents.top())); tempRects++; } } /* need to add some rects from region 2 */ if (reg2->extents.top() < reg1->extents.top()) { tempRects = reg2->rects; while (tempRects->top() < reg1->extents.top()) { MEMCHECK(newReg, rects, FirstRect) ADDRECTNOX(newReg, rects, tempRects->left(),tempRects->top(), tempRects->right(), MIN(tempRects->bottom(), reg1->extents.top())); tempRects++; } } return 1;}#endif/*====================================================================== * Generic Region Operator *====================================================================*//*- *----------------------------------------------------------------------- * miCoalesce -- * Attempt to merge the boxes in the current band with those in the * previous one. Used only by miRegionOp. * * Results: * The new index for the previous band. * * Side Effects: * If coalescing takes place: * - rectangles in the previous band will have their y2 fields * altered. * - pReg->numRects will be decreased. * *----------------------------------------------------------------------- *//* static int*/staticintmiCoalesce (register Region pReg, int prevStart, int curStart) //Region pReg; /* Region to coalesce */ //prevStart; /* Index of start of previous band */ //curStart; /* Index of start of current band */{ register QRect *pPrevBox; /* Current box in previous band */ register QRect *pCurBox; /* Current box in current band */ register QRect *pRegEnd; /* End of region */ int curNumRects; /* Number of rectangles in current * band */ int prevNumRects; /* Number of rectangles in previous * band */ int bandY1; /* Y1 coordinate for current band */ pRegEnd = pReg->rects.data() + pReg->numRects; pPrevBox = pReg->rects.data() + prevStart; prevNumRects = curStart - prevStart; /* * Figure out how many rectangles are in the current band. Have to do * this because multiple bands could have been added in miRegionOp * at the end when one region has been exhausted. */ pCurBox = pReg->rects.data() + curStart; bandY1 = pCurBox->top(); for (curNumRects = 0; (pCurBox != pRegEnd) && (pCurBox->top() == bandY1); curNumRects++) { pCurBox++; } if (pCurBox != pRegEnd) { /* * If more than one band was added, we have to find the start * of the last band added so the next coalescing job can start * at the right place... (given when multiple bands are added, * this may be pointless -- see above). */ pRegEnd--; while ((pRegEnd-1)->top() == pRegEnd->top()) { pRegEnd--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -