⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 region.c

📁 realvnc是一个非常流行的远程控制程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    return 0;	/* lint */}/*- *----------------------------------------------------------------------- * miUnionO -- *	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*/static intmiUnionO (pReg, r1, r1End, r2, r2End, y1, y2)    register XRegion	pReg;    register BoxPtr	r1;    BoxPtr  	  	r1End;    register BoxPtr	r2;    BoxPtr  	  	r2End;    register short	y1;    register short	y2;{    register BoxPtr	pNextRect;        pNextRect = &pReg->rects[pReg->numRects];#define MERGERECT(r) \    if ((pReg->numRects != 0) &&  \	(pNextRect[-1].y1 == y1) &&  \	(pNextRect[-1].y2 == y2) &&  \	(pNextRect[-1].x2 >= r->x1))  \    {  \	if (pNextRect[-1].x2 < r->x2)  \	{  \	    pNextRect[-1].x2 = r->x2;  \	    assert(pNextRect[-1].x1<pNextRect[-1].x2); \	}  \    }  \    else  \    {  \	MEMCHECK(pReg, pNextRect, pReg->rects);  \	pNextRect->y1 = y1;  \	pNextRect->y2 = y2;  \	pNextRect->x1 = r->x1;  \	pNextRect->x2 = r->x2;  \	pReg->numRects += 1;  \        pNextRect += 1;  \    }  \    assert(pReg->numRects<=pReg->size);\    r++;        assert (y1<y2);    while ((r1 != r1End) && (r2 != r2End))    {	if (r1->x1 < r2->x1)	{	    MERGERECT(r1);	}	else	{	    MERGERECT(r2);	}    }        if (r1 != r1End)    {	do	{	    MERGERECT(r1);	} while (r1 != r1End);    }    else while (r2 != r2End)    {	MERGERECT(r2);    }    return 0;	/* lint */}intXUnionRegion(reg1, reg2, newReg)    XRegion 	  reg1;    XRegion	  reg2;             /* source XRegions     */    XRegion 	  newReg;                  /* destination Region */{    /*  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)            miRegionCopy(newReg, reg2);        return 1;    }    /*     * if nothing to union (region 2 empty)     */    if (!(reg2->numRects))    {        if (newReg != reg1)            miRegionCopy(newReg, reg1);        return 1;    }    /*     * Region 1 completely subsumes region 2     */    if ((reg1->numRects == 1) && 	(reg1->extents.x1 <= reg2->extents.x1) &&	(reg1->extents.y1 <= reg2->extents.y1) &&	(reg1->extents.x2 >= reg2->extents.x2) &&	(reg1->extents.y2 >= reg2->extents.y2))    {        if (newReg != reg1)            miRegionCopy(newReg, reg1);        return 1;    }    /*     * Region 2 completely subsumes region 1     */    if ((reg2->numRects == 1) && 	(reg2->extents.x1 <= reg1->extents.x1) &&	(reg2->extents.y1 <= reg1->extents.y1) &&	(reg2->extents.x2 >= reg1->extents.x2) &&	(reg2->extents.y2 >= reg1->extents.y2))    {        if (newReg != reg2)            miRegionCopy(newReg, reg2);        return 1;    }    miRegionOp (newReg, reg1, reg2, (voidProcp) miUnionO,     		(voidProcp) miUnionNonO, (voidProcp) 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;}/*====================================================================== * 	    	  Region 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 intmiSubtractNonO1 (pReg, r, rEnd, y1, y2)    register XRegion	pReg;    register BoxPtr	r;    BoxPtr  	  	rEnd;    register short  	y1;    register short   	y2;{    register BoxPtr	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 intmiSubtractO (pReg, r1, r1End, r2, r2End, y1, y2)    register XRegion	pReg;    register BoxPtr	r1;    BoxPtr  	  	r1End;    register BoxPtr	r2;    BoxPtr  	  	r2End;    register short  	y1;    register short  	y2;{    register BoxPtr	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++;	    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. * *----------------------------------------------------------------------- */intXSubtractRegion(regM, regS, regD)    XRegion 	  	regM;    XRegion	  	regS;              register XRegion	regD;{   /* check for trivial reject */    if ( (!(regM->numRects)) || (!(regS->numRects))  ||	(!EXTENTCHECK(&regM->extents, &regS->extents)) )    {	miRegionCopy(regD, regM);        return 1;    }     miRegionOp (regD, regM, regS, (voidProcp) miSubtractO,     		(voidProcp) miSubtractNonO1, (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.     */    miSetExtents (regD);    return 1;}intXXorRegion( sra, srb, dr )    XRegion sra, srb, dr;{    XRegion tra, trb;    if ((! (tra = XCreateRegion())) || (! (trb = XCreateRegion())))	return 0;    (void) XSubtractRegion(sra,srb,tra);    (void) XSubtractRegion(srb,sra,trb);    (void) XUnionRegion(tra,trb,dr);    XDestroyRegion(tra);    XDestroyRegion(trb);    return 0;}/* * Check to see if the region is empty.  Assumes a region is passed  * as a parameter */int XEmptyRegion( r )    XRegion r;{    if( r->numRects == 0 ) return TRUE;    else  return FALSE;}/* *	Check to see if two regions are equal	 */int XEqualRegion( r1, r2 )    XRegion r1, 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 XPointInRegion( pRegion, x, y )    XRegion pRegion;    int x, y;{    int i;    if (pRegion->numRects == 0)        return FALSE;    if (!INBOX(pRegion->extents, x, y))        return FALSE;    for (i=0; i<pRegion->numRects; i++)    {        if (INBOX (pRegion->rects[i], x, y))	    return TRUE;    }    return FALSE;}int XRectInRegion(region, rx, ry, rwidth, rheight)    register XRegion	region;    int rx, ry;    unsigned int rwidth, rheight;{    register BoxPtr pbox;    register BoxPtr pboxEnd;    Box rect;    register BoxPtr prect = &rect;    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(&region->extents, prect))        return(RectangleOut);    partOut = FALSE;    partIn = FALSE;    /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */    for (pbox = region->rects, pboxEnd = pbox + region->numRects;	 pbox < pboxEnd;	 pbox++)    {	if (pbox->y2 <= ry)	   continue;	/* getting up to speed or skipping remainder of band */	if (pbox->y1 > ry)	{	   partOut = TRUE;	/* missed part of rectangle above */	   if (partIn || (pbox->y1 >= prect->y2))	      break;	   ry = pbox->y1;	/* x guaranteed to be == prect->x1 */	}	if (pbox->x2 <= rx)	   continue;		/* not far enough over yet */	if (pbox->x1 > rx)	{	   partOut = TRUE;	/* missed part of rectangle to left */	   if (partIn)	      break;	}	if (pbox->x1 < prect->x2)	{	    partIn = TRUE;	/* definitely overlap */	    if (partOut)	       break;	}	if (pbox->x2 >= prect->x2)	{	   ry = pbox->y2;	/* finished with this band */	   if (ry >= prect->y2)	      break;	   rx = prect->x1;	/* reset x out to left again */	} else	{	    /*	     * Because boxes in a band are maximal width, if the first box	     * 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) ? RectanglePart : RectangleIn) : 		RectangleOut);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -