📄 devrgn.c
字号:
*/ if (left < right) { MEMCHECK(pReg, pNextRect, pReg->rects); pNextRect->left = left; pNextRect->top = top; pNextRect->right = right; pNextRect->bottom = bottom; pReg->numRects += 1; 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++; } }}/*********************************************************************** * GdIntersectRegion */voidGdIntersectRegion(MWCLIPREGION *newReg, MWCLIPREGION *reg1, MWCLIPREGION *reg2){ /* check for trivial reject */ if ( (!(reg1->numRects)) || (!(reg2->numRects)) || (!EXTENTCHECK(®1->extents, ®2->extents))) newReg->numRects = 0; else REGION_RegionOp (newReg, reg1, reg2, (voidProcp) REGION_IntersectO, (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. */ REGION_SetExtents(newReg); newReg->type = (newReg->numRects) ? MWREGION_COMPLEX : MWREGION_NULL ;}/*********************************************************************** * 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: * pReg->numRects is incremented and the final rectangles overwritten * with the rectangles we're passed. * */static voidREGION_UnionNonO(MWCLIPREGION *pReg,MWRECT *r,MWRECT *rEnd,MWCOORD top, MWCOORD bottom){ MWRECT *pNextRect; pNextRect = &pReg->rects[pReg->numRects]; while (r != rEnd) { MEMCHECK(pReg, pNextRect, pReg->rects); pNextRect->left = r->left; pNextRect->top = top; pNextRect->right = r->right; pNextRect->bottom = bottom; pReg->numRects += 1; pNextRect++; r++; }}/*********************************************************************** * 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 pReg->rects and pReg->numRects will * be changed. * */static voidREGION_UnionO(MWCLIPREGION *pReg, MWRECT *r1, MWRECT *r1End, MWRECT *r2, MWRECT *r2End, MWCOORD top, MWCOORD bottom){ MWRECT *pNextRect; pNextRect = &pReg->rects[pReg->numRects];#define MERGERECT(r) \ if ((pReg->numRects != 0) && \ (pNextRect[-1].top == top) && \ (pNextRect[-1].bottom == bottom) && \ (pNextRect[-1].right >= r->left)) \ { \ if (pNextRect[-1].right < r->right) \ { \ pNextRect[-1].right = r->right; \ } \ } \ else \ { \ MEMCHECK(pReg, pNextRect, pReg->rects); \ pNextRect->top = top; \ pNextRect->bottom = bottom; \ pNextRect->left = r->left; \ pNextRect->right = r->right; \ pReg->numRects += 1; \ pNextRect += 1; \ } \ r++; while ((r1 != r1End) && (r2 != r2End)) { if (r1->left < r2->left) { MERGERECT(r1); } else { MERGERECT(r2); } } if (r1 != r1End) { do { MERGERECT(r1); } while (r1 != r1End); } else while (r2 != r2End) { MERGERECT(r2); }}/*********************************************************************** * GdUnionRegion */voidGdUnionRegion(MWCLIPREGION *newReg, MWCLIPREGION *reg1, MWCLIPREGION *reg2){ /* checks all the simple cases */ /* * Region 1 and 2 are the same or region 1 is empty */ if ( (reg1 == reg2) || (!(reg1->numRects)) ) { if (newReg != reg2) GdCopyRegion(newReg, reg2); return; } /* * if nothing to union (region 2 empty) */ if (!(reg2->numRects)) { if (newReg != reg1) GdCopyRegion(newReg, reg1); return; } /* * Region 1 completely subsumes region 2 */ if ((reg1->numRects == 1) && (reg1->extents.left <= reg2->extents.left) && (reg1->extents.top <= reg2->extents.top) && (reg1->extents.right >= reg2->extents.right) && (reg1->extents.bottom >= reg2->extents.bottom)) { if (newReg != reg1) GdCopyRegion(newReg, reg1); return; } /* * Region 2 completely subsumes region 1 */ if ((reg2->numRects == 1) && (reg2->extents.left <= reg1->extents.left) && (reg2->extents.top <= reg1->extents.top) && (reg2->extents.right >= reg1->extents.right) && (reg2->extents.bottom >= reg1->extents.bottom)) { if (newReg != reg2) GdCopyRegion(newReg, reg2); return; } REGION_RegionOp (newReg, reg1, reg2, (voidProcp) REGION_UnionO, (voidProcp) REGION_UnionNonO, (voidProcp) REGION_UnionNonO); newReg->extents.left = MWMIN(reg1->extents.left, reg2->extents.left); newReg->extents.top = MWMIN(reg1->extents.top, reg2->extents.top); newReg->extents.right = MWMAX(reg1->extents.right, reg2->extents.right); newReg->extents.bottom = MWMAX(reg1->extents.bottom, reg2->extents.bottom); newReg->type = (newReg->numRects) ? MWREGION_COMPLEX : MWREGION_NULL ;}/*********************************************************************** * 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: * pReg may be affected. * */static voidREGION_SubtractNonO1(MWCLIPREGION *pReg, MWRECT *r, MWRECT *rEnd, MWCOORD top, MWCOORD bottom){ MWRECT *pNextRect; pNextRect = &pReg->rects[pReg->numRects]; while (r != rEnd) { MEMCHECK(pReg, pNextRect, pReg->rects); pNextRect->left = r->left; pNextRect->top = top; pNextRect->right = r->right; pNextRect->bottom = bottom; pReg->numRects += 1; pNextRect++; r++; }}/*********************************************************************** * REGION_SubtractO * * Overlapping band subtraction. x1 is the left-most point not yet * checked. * * Results: * None. * * Side Effects: * pReg may have rectangles added to it. * */static voidREGION_SubtractO(MWCLIPREGION *pReg, MWRECT *r1, MWRECT *r1End, MWRECT *r2, MWRECT *r2End, MWCOORD top, MWCOORD bottom){ MWRECT *pNextRect; MWCOORD left; left = r1->left; pNextRect = &pReg->rects[pReg->numRects]; while ((r1 != r1End) && (r2 != r2End)) { if (r2->right <= left) { /* * Subtrahend missed the boat: go to next subtrahend. */ r2++; } else if (r2->left <= left) { /* * Subtrahend preceeds minuend: nuke left edge of minuend. */ left = r2->right; if (left >= r1->right) { /* * Minuend completely covered: advance to next minuend and * reset left fence to edge of new minuend. */ r1++; if (r1 != r1End) left = r1->left; } else { /* * Subtrahend now used up since it doesn't extend beyond * minuend */ r2++; } } else if (r2->left < r1->right) { /* * Left part of subtrahend covers part of minuend: add uncovered * part of minuend to region and skip to next subtrahend. */ MEMCHECK(pReg, pNextRect, pReg->rects); pNextRect->left = left; pNextRect->top = top; pNextRect->right = r2->left; pNextRect->bottom = bottom; pReg->numRects += 1; pNextRect++; left = r2->right; if (left >= r1->right) { /* * Minuend used up: advance to new... */ r1++; if (r1 != r1End) left = r1->left; } else { /* * Subtrahend used up */ r2++; } } else { /* * Minuend used up: add any remaining piece before advancing. */ if (r1->right > left) { MEMCHECK(pReg, pNextRect, pReg->rects); pNextRect->left = left; pNextRect->top = top; pNextRect->right = r1->right; pNextRect->bottom = bottom; pReg->numRects += 1; pNextRect++; } r1++; left = r1->left; } } /* * Add remaining minuend rectangles to region. */ while (r1 != r1End) { MEMCHECK(pReg, pNextRect, pReg->rects); pNextRect->left = left; pNextRect->top = top; pNextRect->right = r1->right; pNextRect->bottom = bottom; pReg->numRects += 1; pNextRect++; r1++; if (r1 != r1End) { left = r1->left; } }} /*********************************************************************** * GdSubtractRegion * * Subtract regS from regM and leave the result in regD. * S stands for subtrahend, M for minuend and D for difference. * * Results: * TRUE. * * Side Effects: * regD is overwritten. * */voidGdSubtractRegion(MWCLIPREGION *regD, MWCLIPREGION *regM, MWCLIPREGION *regS ){ /* check for trivial reject */ if ( (!(regM->numRects)) || (!(regS->numRects)) || (!EXTENTCHECK(®M->extents, ®S->extents)) ) { GdCopyRegion(regD, regM); return; } REGION_RegionOp (regD, regM, regS, (voidProcp) REGION_SubtractO, (voidProcp) REGION_SubtractNonO1, (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 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 (regD); regD->type = (regD->numRects) ? MWREGION_COMPLEX : MWREGION_NULL ;}/*********************************************************************** * GdXorRegion */voidGdXorRegion(MWCLIPREGION *dr, MWCLIPREGION *sra, MWCLIPREGION *srb){ MWCLIPREGION *tra, *trb; if ((! (tra = GdAllocRegion())) || (! (trb = GdAllocRegion()))) return; GdSubtractRegion(tra,sra,srb); GdSubtractRegion(trb,srb,sra); GdUnionRegion(dr,tra,trb); GdDestroyRegion(tra); GdDestroyRegion(trb);}#if 0/*********************************************************************** * DumpRegion * Outputs the contents of a MWCLIPREGION */voidDumpRegion(MWCLIPREGION *pReg){ MWRECT *pRect, *pRectEnd = pReg->rects + pReg->numRects; DPRINTF("Region %p: %d,%d - %d,%d %d rects\n", pReg, pReg->extents.left, pReg->extents.top, pReg->extents.right, pReg->extents.bottom, pReg->numRects); for(pRect = pReg->rects; pRect < pRectEnd; pRect++) DPRINTF("\t%d,%d - %d,%d\n", pRect->left, pRect->top, pRect->right, pRect->bottom);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -