📄 region.h
字号:
do { pPrevRect->BR.y = pCurRect->BR.y; pPrevRect++; pCurRect++; curNumRects -= 1; } while (curNumRects != 0); /* If only one band was added to the region, we have to backup * curStart to the start of the previous band. * * If more than one band was added to the region, copy the * other bands down. The assumption here is that the other bands * came from the same region as the current one and no further * coalescing can be done on them since it's all been done * already... curStart is already in the right place. */ if (pCurRect == pRegEnd) { curStart = prevStart; } else { do { *pPrevRect++ = *pCurRect++; } while (pCurRect != pRegEnd); } } } return (curStart);}/***************************************************************************** * 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 void REGION_UnionO ( wmfAPI* API, wmfRegion* pReg, wmfD_Rect* r1, wmfD_Rect* r1End, wmfD_Rect* r2, wmfD_Rect* r2End, float top, float bottom){ while ((r1 != r1End) && (r2 != r2End)) { if (r1->TL.x < r2->TL.x) { rect_merge (API,pReg,r1,top,bottom); if (ERR (API)) return; r1++; } else { rect_merge (API,pReg,r2,top,bottom); if (ERR (API)) return; r2++; } } if (r1 != r1End) { do { rect_merge (API,pReg,r1,top,bottom); if (ERR (API)) return; r1++; } while (r1 != r1End); } else { while (r2 != r2End) { rect_merge (API,pReg,r2,top,bottom); if (ERR (API)) return; r2++; } }}static void rect_merge ( wmfAPI* API, wmfRegion* rgn, wmfD_Rect* r, float top, float bottom){ wmfD_Rect* pNextRect = 0; wmfD_Rect* pPrior = 0; if ((pNextRect = rgn_memchk (API,rgn)) == 0) return; if (rgn->numRects == 0) { rgn->numRects++; pNextRect->TL.x = r->TL.x; pNextRect->TL.y = top; pNextRect->BR.x = r->BR.x; pNextRect->BR.y = bottom; pNextRect++; } else { pPrior = pNextRect - 1; if ((pPrior->TL.y == top) && (pPrior->BR.y == bottom) && (pPrior->BR.x >= r->TL.x)) { if (pPrior->BR.x < r->BR.x) pPrior->BR.x = r->BR.x; } else { rgn->numRects++; pNextRect->TL.x = r->TL.x; pNextRect->TL.y = top; pNextRect->BR.x = r->BR.x; pNextRect->BR.y = bottom; pNextRect++; } }}/***************************************************************************** * 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 void REGION_UnionNonO ( wmfAPI* API, wmfRegion* pReg, wmfD_Rect* r, wmfD_Rect* rEnd, float top, float bottom){ wmfD_Rect* pNextRect = 0; while (r != rEnd) { if ((pNextRect = rgn_memchk (API,pReg)) == 0) return; pReg->numRects++; pNextRect->TL.x = r->TL.x; pNextRect->TL.y = top; pNextRect->BR.x = r->BR.x; pNextRect->BR.y = bottom; pNextRect++; r++; }}/***************************************************************************** * 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 void REGION_SubtractNonO1 ( wmfAPI* API, wmfRegion* pReg, wmfD_Rect* r, wmfD_Rect* rEnd, float top, float bottom){ wmfD_Rect* pNextRect = 0; while (r != rEnd) { if ((pNextRect = rgn_memchk (API,pReg)) == 0) return; pReg->numRects++; pNextRect->TL.x = r->TL.x; pNextRect->TL.y = top; pNextRect->BR.x = r->BR.x; pNextRect->BR.y = bottom; pNextRect++; r++; }}/***************************************************************************** * REGION_SubtractRegion * * 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. * */static void REGION_SubtractRegion ( wmfAPI* API, wmfRegion* regD, wmfRegion* regM, wmfRegion* regS){ /* check for trivial reject */ if ( (regM->numRects == 0) || (regS->numRects == 0) || (!EXTENTCHECK (®M->extents,®S->extents)) ) { REGION_CopyRegion (API,regD,regM); return; } REGION_RegionOp (API,regD,regM,regS,REGION_SubtractO,REGION_SubtractNonO1,0); if (ERR (API)) { WMF_DEBUG (API,"bailing..."); return; }/* 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 (API,regD); regD->type = ((regD->numRects) ? COMPLEXREGION : NULLREGION);}/***************************************************************************** * 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 void REGION_SubtractO ( wmfAPI* API, wmfRegion* pReg, wmfD_Rect* r1, wmfD_Rect* r1End, wmfD_Rect* r2, wmfD_Rect* r2End, float top, float bottom){ wmfD_Rect* pNextRect = 0; float left = r1->TL.x; if ((pNextRect = rgn_memchk (API,pReg)) == 0) return; while ((r1 != r1End) && (r2 != r2End)) { if (r2->BR.x <= left) { /* Subtrahend missed the boat: go to next subtrahend. */ r2++; } else if (r2->TL.x <= left) { /* Subtrahend preceeds minuend: nuke left edge of minuend. */ left = r2->BR.x; if (left >= r1->BR.x) { /* Minuend completely covered: advance to next minuend and * reset left fence to edge of new minuend. */ r1++; if (r1 != r1End) left = r1->TL.x; } else { /* Subtrahend now used up since it doesn't extend beyond * minuend */ r2++; } } else if (r2->TL.x < r1->BR.x) { /* Left part of subtrahend covers part of minuend: add uncovered * part of minuend to region and skip to next subtrahend. */ if ((pNextRect = rgn_memchk (API,pReg)) == 0) return; pReg->numRects++; pNextRect->TL.x = left; pNextRect->TL.y = top; pNextRect->BR.x = r2->TL.x; pNextRect->BR.y = bottom; pNextRect++; left = r2->BR.x; if (left >= r1->BR.x) { /* Minuend used up: advance to new... */ r1++; if (r1 != r1End) left = r1->TL.x; } else { /* Subtrahend used up */ r2++; } } else { /* Minuend used up: add any remaining piece before advancing. */ if (r1->BR.x > left) { if ((pNextRect = rgn_memchk (API,pReg)) == 0) return; pReg->numRects++; pNextRect->TL.x = left; pNextRect->TL.y = top; pNextRect->BR.x = r1->BR.x; pNextRect->BR.y = bottom; pNextRect++; } r1++; left = r1->TL.x; } }/* Add remaining minuend rectangles to region. */ while (r1 != r1End) { if ((pNextRect = rgn_memchk (API,pReg)) == 0) return; pReg->numRects++; pNextRect->TL.x = left; pNextRect->TL.y = top; pNextRect->BR.x = r1->BR.x; pNextRect->BR.y = bottom; pNextRect++; r1++; if (r1 != r1End) left = r1->TL.x; }}/***************************************************************************** * REGION_SetExtents * Re-calculate the extents of a region */static void REGION_SetExtents ( wmfAPI* API, wmfRegion* pReg){ wmfD_Rect* pRect; wmfD_Rect* pRectEnd; wmfD_Rect* pExtents; if (pReg->numRects == 0) { pReg->extents.TL.x = 0; pReg->extents.TL.y = 0; pReg->extents.BR.x = 0; pReg->extents.BR.y = 0; return; } pExtents = &pReg->extents; pRect = pReg->rects; pRectEnd = pRect + pReg->numRects - 1;/* Since pRect is the first rectangle in the region, it must have the * smallest top and since pRectEnd is the last rectangle in the region, * it must have the largest bottom, because of banding. Initialize left and * right from pRect and pRectEnd, resp., as good things to initialize them * to... */ pExtents->TL.x = pRect->TL.x; pExtents->TL.y = pRect->TL.y; pExtents->BR.x = pRectEnd->BR.x; pExtents->BR.y = pRectEnd->BR.y; while (pRect <= pRectEnd) { if (pRect->TL.x < pExtents->TL.x) pExtents->TL.x = pRect->TL.x; if (pRect->BR.x > pExtents->BR.x) pExtents->BR.x = pRect->BR.x; pRect++; }}/***************************************************************************** * REGION_IntersectRegion */static void REGION_IntersectRegion ( wmfAPI* API, wmfRegion* newReg, wmfRegion* reg1, wmfRegion* reg2){ /* check for trivial reject */ if ( (!(reg1->numRects)) || (!(reg2->numRects)) || (!EXTENTCHECK (®1->extents,®2->extents))) { newReg->numRects = 0; } else { REGION_RegionOp (API,newReg,reg1,reg2,REGION_IntersectO,0,0); }/* 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 (API,newReg); newReg->type = ((newReg->numRects) ? COMPLEXREGION : NULLREGION);}/***************************************************************************** * REGION_IntersectO * * Handle an overlapping band for REGION_Intersect. * * Results: * None. * * Side Effects: * Rectangles may be added to the region. * */static void REGION_IntersectO ( wmfAPI* API, wmfRegion* pReg, wmfD_Rect* r1, wmfD_Rect* r1End, wmfD_Rect* r2, wmfD_Rect* r2End, float top, float bottom){ float left; float right; wmfD_Rect* pNextRect; while ((r1 != r1End) && (r2 != r2End)) { left = MAX (r1->TL.x,r2->TL.x); right = MIN (r1->BR.x,r2->BR.x);/* 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) { if ((pNextRect = rgn_memchk (API,pReg)) == 0) return; pReg->numRects++; pNextRect->TL.x = left; pNextRect->TL.y = top; pNextRect->BR.x = right; pNextRect->BR.y = bottom; 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->BR.x < r2->BR.x) { r1++; } else if (r2->BR.x < r1->BR.x) { r2++; } else { r1++; r2++; } }}#endif /* ! WMFPLAYER_REGION_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -