📄 region.c
字号:
(reg2->extents.x2 >= reg1->extents.x2) &&
(reg2->extents.y2 >= reg1->extents.y2))
{
if (newReg != reg2)
miRegionCopy(newReg, reg2);
return 1;
}
miRegionOp( newReg,
reg1,
reg2,
miUnionO,
miUnionNonO,
miUnionNonO);
newReg->extents.x1 = min(reg1->extents.x1, reg2->extents.x1);
newReg->extents.y1 = min(reg1->extents.y1, reg2->extents.y1);
newReg->extents.x2 = max(reg1->extents.x2, reg2->extents.x2);
newReg->extents.y2 = max(reg1->extents.y2, reg2->extents.y2);
return 1;
}
/*======================================================================
* _HXRegion Subtraction
*====================================================================*/
/*-
*-----------------------------------------------------------------------
* miSubtractNonO --
* 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*/
static int miSubtractNonO1( register _HXRegion pReg,
register HXBoxPtr r,
HXBoxPtr rEnd,
register short y1,
register short y2
)
{
register HXBoxPtr pNextRect;
pNextRect = &pReg->rects[pReg->numRects];
/* assert(y1<y2); */
while (r != rEnd)
{
/* assert(r->x1<r->x2); */
MEMCHECK(pReg, pNextRect, pReg->rects);
pNextRect->x1 = r->x1;
pNextRect->y1 = y1;
pNextRect->x2 = r->x2;
pNextRect->y2 = y2;
pReg->numRects += 1;
pNextRect++;
/* assert(pReg->numRects <= pReg->size); */
r++;
}
return 0; /* lint */
}
/*-
*-----------------------------------------------------------------------
* miSubtractO --
* 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*/
static int miSubtractO( register _HXRegion pReg,
register HXBoxPtr r1,
HXBoxPtr r1End,
register HXBoxPtr r2,
HXBoxPtr r2End,
register short y1,
register short y2
)
{
register HXBoxPtr pNextRect;
register int x1;
x1 = r1->x1;
/* assert(y1<y2); */
pNextRect = &pReg->rects[pReg->numRects];
while ((r1 != r1End) && (r2 != r2End))
{
if (r2->x2 <= x1)
{
/*
* Subtrahend missed the boat: go to next subtrahend.
*/
r2++;
}
else if (r2->x1 <= x1)
{
/*
* Subtrahend preceeds minuend: nuke left edge of minuend.
*/
x1 = r2->x2;
if (x1 >= r1->x2)
{
/*
* Minuend completely covered: advance to next minuend and
* reset left fence to edge of new minuend.
*/
r1++;
if (r1 != r1End)
x1 = r1->x1;
}
else
{
/*
* Subtrahend now used up since it doesn't extend beyond
* minuend
*/
r2++;
}
}
else if (r2->x1 < r1->x2)
{
/*
* Left part of subtrahend covers part of minuend: add uncovered
* part of minuend to region and skip to next subtrahend.
*/
/* assert(x1<r2->x1); */
MEMCHECK(pReg, pNextRect, pReg->rects);
pNextRect->x1 = x1;
pNextRect->y1 = y1;
pNextRect->x2 = r2->x1;
pNextRect->y2 = y2;
pReg->numRects += 1;
pNextRect++;
/* assert(pReg->numRects<=pReg->size); */
x1 = r2->x2;
if (x1 >= r1->x2)
{
/*
* Minuend used up: advance to new...
*/
r1++;
if (r1 != r1End)
x1 = r1->x1;
}
else
{
/*
* Subtrahend used up
*/
r2++;
}
}
else
{
/*
* Minuend used up: add any remaining piece before advancing.
*/
if (r1->x2 > x1)
{
MEMCHECK(pReg, pNextRect, pReg->rects);
pNextRect->x1 = x1;
pNextRect->y1 = y1;
pNextRect->x2 = r1->x2;
pNextRect->y2 = y2;
pReg->numRects += 1;
pNextRect++;
/* assert(pReg->numRects<=pReg->size); */
}
r1++;
if (!(((r1 != r1End) && (r2 != r2End))))
{
break;
}
x1 = r1->x1;
}
}
/*
* Add remaining minuend rectangles to region.
*/
while (r1 != r1End)
{
/* assert(x1<r1->x2); */
MEMCHECK(pReg, pNextRect, pReg->rects);
pNextRect->x1 = x1;
pNextRect->y1 = y1;
pNextRect->x2 = r1->x2;
pNextRect->y2 = y2;
pReg->numRects += 1;
pNextRect++;
/* assert(pReg->numRects<=pReg->size); */
r1++;
if (r1 != r1End)
{
x1 = r1->x1;
}
}
return 0; /* lint */
}
/*-
*-----------------------------------------------------------------------
* miSubtract --
* 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.
*
*-----------------------------------------------------------------------
*/
int HXSubtractRegion(_HXRegion regM, _HXRegion regS, _HXRegion regD)
{
/* check for trivial reject */
if ( (!(regM->numRects)) || (!(regS->numRects)) ||
(!EXTENTCHECK(®M->extents, ®S->extents)) )
{
miRegionCopy(regD, regM);
return 1;
}
miRegionOp (regD, regM, regS, miSubtractO, miSubtractNonO1, 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.
*/
miSetExtents (regD);
return 1;
}
int HXXorRegion( _HXRegion sra, _HXRegion srb, _HXRegion dr )
{
_HXRegion tra, trb;
if ((! (tra = HXCreateRegion())) || (! (trb = HXCreateRegion())))
return 0;
(void) HXSubtractRegion(sra,srb,tra);
(void) HXSubtractRegion(srb,sra,trb);
(void) HXUnionRegion(tra,trb,dr);
HXDestroyRegion(tra);
HXDestroyRegion(trb);
return 0;
}
/*
* Check to see if the region is empty. Assumes a region is passed
* as a parameter
*/
int HXEmptyRegion( _HXRegion r)
{
if( !r || r->numRects == 0 ) return TRUE;
else return FALSE;
}
/*
* Check to see if two regions are equal
*/
int
HXEqualRegion( _HXRegion r1, _HXRegion r2)
{
int i;
if( r1->numRects != r2->numRects ) return FALSE;
else if( r1->numRects == 0 ) return TRUE;
else if ( r1->extents.x1 != r2->extents.x1 ) return FALSE;
else if ( r1->extents.x2 != r2->extents.x2 ) return FALSE;
else if ( r1->extents.y1 != r2->extents.y1 ) return FALSE;
else if ( r1->extents.y2 != r2->extents.y2 ) return FALSE;
else for( i=0; i < r1->numRects; i++ ) {
if ( r1->rects[i].x1 != r2->rects[i].x1 ) return FALSE;
else if ( r1->rects[i].x2 != r2->rects[i].x2 ) return FALSE;
else if ( r1->rects[i].y1 != r2->rects[i].y1 ) return FALSE;
else if ( r1->rects[i].y2 != r2->rects[i].y2 ) return FALSE;
}
return TRUE;
}
int HXPointInRegion( _HXRegion pRegion, int x, int y )
{
int i;
if (pRegion->numRects == 0)
return FALSE;
if (!INHXBOX(pRegion->extents, x, y))
return FALSE;
for (i=0; i<pRegion->numRects; i++)
{
if (INHXBOX (pRegion->rects[i], x, y))
return TRUE;
}
return FALSE;
}
int HXDetermineBestRect( _HXRegion srcReg, _HXRegion newReg )
{
return 0;
}
int HXRectInRegion(_HXRegion region, int rx, int ry, unsigned int rwidth, unsigned int rheight)
{
register HXBoxPtr pHXBox;
register HXBoxPtr pHXBoxEnd;
HXBOX rect;
register HXBoxPtr prect = ▭
int partIn, partOut;
prect->x1 = rx;
prect->y1 = ry;
prect->x2 = rwidth + rx;
prect->y2 = rheight + ry;
/* this is (just) a useful optimization */
if ((region->numRects == 0) || !EXTENTCHECK(®ion->extents, prect))
return(HXRectangleOut);
partOut = FALSE;
partIn = FALSE;
/* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */
for (pHXBox = region->rects, pHXBoxEnd = pHXBox + region->numRects;
pHXBox < pHXBoxEnd;
pHXBox++)
{
if (pHXBox->y2 <= ry)
continue; /* getting up to speed or skipping remainder of band */
if (pHXBox->y1 > ry)
{
partOut = TRUE; /* missed part of rectangle above */
if (partIn || (pHXBox->y1 >= prect->y2))
break;
ry = pHXBox->y1; /* x guaranteed to be == prect->x1 */
}
if (pHXBox->x2 <= rx)
continue; /* not far enough over yet */
if (pHXBox->x1 > rx)
{
partOut = TRUE; /* missed part of rectangle to left */
if (partIn)
break;
}
if (pHXBox->x1 < prect->x2)
{
partIn = TRUE; /* definitely overlap */
if (partOut)
break;
}
if (pHXBox->x2 >= prect->x2)
{
ry = pHXBox->y2; /* finished with this band */
if (ry >= prect->y2)
break;
rx = prect->x1; /* reset x out to left again */
} else
{
/*
* Because HXBoxes in a band are maximal width, if the first HXBox
* to overlap the rectangle doesn't completely cover it in that
* band, the rectangle must be partially out, since some of it
* will be uncovered in that band. partIn will have been set true
* by now...
*/
break;
}
}
return(partIn ? ((ry < prect->y2) ? HXRectanglePart : HXRectangleIn) :
HXRectangleOut);
}
#ifdef _DEBUG
void _DumpRegion(_HXRegion pRegion )
{
int i=0;
char szBuff[256]; /* Flawfinder: ignore */
sprintf( szBuff, "Region(%p): %d rects\n", pRegion, pRegion->numRects ); /* Flawfinder: ignore */
_DumpString(szBuff);
for(i=0 ; i<pRegion->numRects ; i++)
{
sprintf( szBuff, "Rect# %d (%d,%d)-(%d,%d)\n", /* Flawfinder: ignore */
i,
pRegion->rects[i].x1, pRegion->rects[i].y1,
pRegion->rects[i].x2, pRegion->rects[i].y2
);
_DumpString(szBuff);
}
}
void _DumpString(const char* pszString )
{
#if defined(_WIN32)
OutputDebugString(pszString);
#elif defined(_UNIX)
FILE* pFP=fopen("/tmp/pnvideo.txt", "a+"); /* Flawfinder: ignore */
if( pFP )
{
fprintf( pFP, "%s", pszString);
fclose( pFP );
}
#else
fprintf( stderr, "%s", pszString );
#endif
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -