?? region.c
字號:
{ if (REGION_NOT_EMPTY(newReg)) { CLIPRECT *prev_rects = newReg->rects; newReg->size = newReg->numRects; newReg->rects = realloc( newReg->rects, sizeof(CLIPRECT) * newReg->size ); if (! newReg->rects) newReg->rects = prev_rects; } else { /* * No point in doing the extra work involved in an Xrealloc if * the region is empty */ newReg->size = 1; free( newReg->rects ); newReg->rects = malloc( sizeof(CLIPRECT) ); } } free( oldRects );#else if (pdst != newReg) { EmptyClipRgn (newReg); *newReg = my_dst; }#endif}/*********************************************************************** * Region Intersection ***********************************************************************//*********************************************************************** * REGION_IntersectO * * Handle an overlapping band for REGION_Intersect. * * Results: * None. * * Side Effects: * Rectangles may be added to the region. * */static voidREGION_IntersectO (CLIPRGN *region, const CLIPRECT *r1, const CLIPRECT *r1End, const CLIPRECT *r2, const CLIPRECT *r2End, int top, int bottom){ int left, right; CLIPRECT *newcliprect; while ((r1 != r1End) && (r2 != r2End)) { left = MAX (r1->rc.left, r2->rc.left); right = MIN (r1->rc.right, r2->rc.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 (left < right) { NEWCLIPRECT (region, newcliprect); newcliprect->rc.left = left; newcliprect->rc.top = top; newcliprect->rc.right = right; newcliprect->rc.bottom = bottom; } /* * 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->rc.right < r2->rc.right) { r1 = r1->next; } else if (r2->rc.right < r1->rc.right) { r2 = r2->next; } else { r1 = r1->next; r2 = r2->next; } }}/*********************************************************************** * Region Union ***********************************************************************//*********************************************************************** * REGION_UnionNonO * * Handle a non-overlapping band for the union operation. Just * Adds the rectangles into the region. Doesn't have to check for * subsumption or anything. * * Results: * None. * * Side Effects: * region->numRects is incremented and the final rectangles overwritten * with the rectangles we're passed. * */static voidREGION_UnionNonO (CLIPRGN *region, const CLIPRECT *r, const CLIPRECT *rEnd, int top, int bottom){ CLIPRECT *newcliprect; while (r != rEnd) { NEWCLIPRECT (region, newcliprect); newcliprect->rc.left = r->rc.left; newcliprect->rc.top = top; newcliprect->rc.right = r->rc.right; newcliprect->rc.bottom = bottom; r = r->next; }}/*********************************************************************** * REGION_UnionO * * Handle an overlapping band for the union operation. Picks the * left-most rectangle each time and merges it into the region. * * Results: * None. * * Side Effects: * Rectangles are overwritten in region->rects and region->numRects will * be changed. * */static voidREGION_UnionO(CLIPRGN *region, const CLIPRECT *r1, const CLIPRECT *r1End, const CLIPRECT *r2, const CLIPRECT *r2End, int top, int bottom){ CLIPRECT *newcliprect; #define MERGERECT(r) \ if ((region->head) && \ (region->tail->rc.top == top) && \ (region->tail->rc.bottom == bottom) && \ (region->tail->rc.right >= r->rc.left)) \ { \ if (region->tail->rc.right < r->rc.right) \ { \ region->tail->rc.right = r->rc.right; \ } \ } \ else \ { \ NEWCLIPRECT(region, newcliprect); \ newcliprect->rc.top = top; \ newcliprect->rc.bottom = bottom; \ newcliprect->rc.left = r->rc.left; \ newcliprect->rc.right = r->rc.right; \ } \ r = r->next; while ((r1 != r1End) && (r2 != r2End)) { if (r1->rc.left < r2->rc.left) { MERGERECT(r1); } else { MERGERECT(r2); } } if (r1 != r1End) { do { MERGERECT(r1); } while (r1 != r1End); } else while (r2 != r2End) { MERGERECT(r2); }}/*********************************************************************** * Region Subtraction ***********************************************************************//*********************************************************************** * REGION_SubtractNonO1 * * Deal with non-overlapping band for subtraction. Any parts from * region 2 we discard. Anything from region 1 we add to the region. * * Results: * None. * * Side Effects: * region may be affected. * */static voidREGION_SubtractNonO1 (CLIPRGN *region, const CLIPRECT *r, const CLIPRECT *rEnd, int top, int bottom){ CLIPRECT *newcliprect; while (r != rEnd) { NEWCLIPRECT(region, newcliprect); newcliprect->rc.left = r->rc.left; newcliprect->rc.top = top; newcliprect->rc.right = r->rc.right; newcliprect->rc.bottom = bottom; r = r->next; }}/*********************************************************************** * REGION_SubtractO * * Overlapping band subtraction. x1 is the left-most point not yet * checked. * * Results: * None. * * Side Effects: * region may have rectangles added to it. * */static voidREGION_SubtractO (CLIPRGN *region, const CLIPRECT *r1, const CLIPRECT *r1End, const CLIPRECT *r2, const CLIPRECT *r2End, int top, int bottom){ CLIPRECT *newcliprect; int left; left = r1->rc.left; while ((r1 != r1End) && (r2 != r2End)) { if (r2->rc.right <= left) { /* * Subtrahend missed the boat: go to next subtrahend. */ r2 = r2->next; } else if (r2->rc.left <= left) { /* * Subtrahend preceeds minuend: nuke left edge of minuend. */ left = r2->rc.right; if (left >= r1->rc.right) { /* * Minuend completely covered: advance to next minuend and * reset left fence to edge of new minuend. */ r1 = r1->next; if (r1 != r1End) left = r1->rc.left; } else { /* * Subtrahend now used up since it doesn't extend beyond * minuend */ r2 = r2->next; } } else if (r2->rc.left < r1->rc.right) { /* * Left part of subtrahend covers part of minuend: add uncovered * part of minuend to region and skip to next subtrahend. */ NEWCLIPRECT(region, newcliprect); newcliprect->rc.left = left; newcliprect->rc.top = top; newcliprect->rc.right = r2->rc.left; newcliprect->rc.bottom = bottom; left = r2->rc.right; if (left >= r1->rc.right) { /* * Minuend used up: advance to new... */ r1 = r1->next; if (r1 != r1End) left = r1->rc.left; } else { /* * Subtrahend used up */ r2 = r2->next; } } else { /* * Minuend used up: add any remaining piece before advancing. */ if (r1->rc.right > left) { NEWCLIPRECT(region, newcliprect); newcliprect->rc.left = left; newcliprect->rc.top = top; newcliprect->rc.right = r1->rc.right; newcliprect->rc.bottom = bottom; } r1 = r1->next; if (r1 != r1End) left = r1->rc.left; } } /* * Add remaining minuend rectangles to region. */ while (r1 != r1End) { NEWCLIPRECT(region, newcliprect); newcliprect->rc.left = left; newcliprect->rc.top = top; newcliprect->rc.right = r1->rc.right; newcliprect->rc.bottom = bottom; r1 = r1->next; if (r1 != r1End) left = r1->rc.left; }}/*********************************************************************** * IntersectRegion */BOOL GUIAPI ClipRgnIntersect (CLIPRGN *dst, const CLIPRGN *src1, const CLIPRGN *src2){ /* check for trivial reject */ if ( (!(src1->head)) || (!(src2->head)) || (!EXTENTCHECK(&src1->rcBound, &src2->rcBound))) { EmptyClipRgn (dst); return TRUE; } else REGION_RegionOp (dst, src1, src2, REGION_IntersectO, NULL, NULL); /* * Can't alter dst's rcBound before we call miRegionOp because * it might be one of the source regions and miRegionOp depends * on the rcBound 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. */ REGION_SetExtents(dst); dst->type = (dst->head) ? COMPLEXREGION : NULLREGION ; return TRUE;}/*********************************************************************** * SubtractRegion * * Subtract rgnS from rgnM and leave the result in rgnD. * S stands for subtrahend, M for minuend and D for difference. * * Results: * TRUE. * * Side Effects: * regD is overwritten. * */BOOL GUIAPI SubtractRegion (CLIPRGN *rgnD, const CLIPRGN *rgnM, const CLIPRGN *rgnS){ /* check for trivial reject */ if ( (!(rgnM->head)) || (!(rgnS->head)) || (!EXTENTCHECK (&rgnM->rcBound, &rgnS->rcBound)) ) { CopyRegion (rgnD, rgnM); return TRUE; } REGION_RegionOp (rgnD, rgnM, rgnS, REGION_SubtractO, REGION_SubtractNonO1, NULL); /* * Can't alter newReg's rcBound before we call miRegionOp because * it might be one of the source regions and miRegionOp depends * on the rcBound of those regions being the unaltered. Besides, this * way there's no checking against rectangles that will be nuked * due to coalescing, so we have to examine fewer rectangles. */ REGION_SetExtents (rgnD); rgnD->type = (rgnD->head) ? COMPLEXREGION : NULLREGION; return TRUE;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -