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

📄 miregion.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
    for (i = numRects; --i > 0;)    {	box++;	/* Look for a region to append box to */	for (j = numRI, rit = ri; --j >= 0; rit++)	{	    reg = &rit->reg;	    riBox = REGION_END(reg);	    if (box->y1 == riBox->y1 && box->y2 == riBox->y2)	    {		/* box is in same band as riBox.  Merge or append it */		if (box->x1 <= riBox->x2)		{		    /* Merge it with riBox */		    if (box->x1 < riBox->x2) *pOverlap = TRUE;		    if (box->x2 > riBox->x2) riBox->x2 = box->x2;		}		else		{		    RECTALLOC(reg, 1);		    *REGION_TOP(reg) = *box;		    reg->data->numRects++;		}		goto NextRect;   /* So sue me */	    }	    else if (box->y1 >= riBox->y2)	    {		/* Put box into new band */		if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;		if (reg->extents.x1 > box->x1)   reg->extents.x1 = box->x1;		Coalesce(reg, rit->prevBand, rit->curBand);		rit->curBand = reg->data->numRects;		RECTALLOC(reg, 1);		*REGION_TOP(reg) = *box;		reg->data->numRects++;		goto NextRect;	    }	    /* Well, this region was inappropriate.  Try the next one. */	} /* for j */	/* Uh-oh.  No regions were appropriate.  Create a new one. */	if (sizeRI == numRI)	{	    /* Oops, allocate space for new region information */	    sizeRI <<= 1;	    Must_have_memory = TRUE; /* XXX */	    ri = (RegionInfo *) xrealloc(ri, sizeRI * sizeof(RegionInfo));	    Must_have_memory = FALSE; /* XXX */	    rit = &ri[numRI];	}	numRI++;	rit->prevBand = 0;	rit->curBand = 0;	rit->reg.extents = *box;	rit->reg.data = (RegDataPtr)NULL;	miRectAlloc(&rit->reg, (i+numRI) / numRI); /* MUST force allocation */NextRect: ;    } /* for i */    /* Make a final pass over each region in order to Coalesce and set       extents.x2 and extents.y2 */    for (j = numRI, rit = ri; --j >= 0; rit++)    {	reg = &rit->reg;	riBox = REGION_END(reg);	reg->extents.y2 = riBox->y2;	if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;	Coalesce(reg, rit->prevBand, rit->curBand);	if (reg->data->numRects == 1) /* keep unions happy below */	{	    xfreeData(reg);	    reg->data = (RegDataPtr)NULL;	}    }    /* Step 3: Union all regions into a single region */    while (numRI > 1)    {	int half = numRI/2;	for (j = numRI & 1; j < (half + (numRI & 1)); j++)	{	    reg = &ri[j].reg;	    hreg = &ri[j+half].reg;	    miRegionOp(reg, reg, hreg, miUnionO, TRUE, TRUE, pOverlap);	    if (hreg->extents.x1 < reg->extents.x1)		reg->extents.x1 = hreg->extents.x1;	    if (hreg->extents.y1 < reg->extents.y1)		reg->extents.y1 = hreg->extents.y1;	    if (hreg->extents.x2 > reg->extents.x2)		reg->extents.x2 = hreg->extents.x2;	    if (hreg->extents.y2 > reg->extents.y2)		reg->extents.y2 = hreg->extents.y2;	    xfreeData(hreg);	}	numRI -= half;    }    *badreg = ri[0].reg;    xfree(ri);    good(badreg);    return TRUE;}RegionPtrmiRectsToRegion(nrects, prect, ctype)    int			nrects;    register xRectangle	*prect;    int			ctype;{    register RegionPtr	pRgn;    register RegDataPtr	pData;    register BoxPtr	pBox;    register int        i;    int			x1, y1, x2, y2;    pRgn = miRegionCreate(NullBox, 0);    if (!nrects)	return pRgn;    if (nrects == 1)    {	x1 = prect->x;	y1 = prect->y;	if ((x2 = x1 + (int) prect->width) > MAXSHORT)	    x2 = MAXSHORT;	if ((y2 = y1 + (int) prect->height) > MAXSHORT)	    y2 = MAXSHORT;	if (x1 != x2 && y1 != y2)	{	    pRgn->extents.x1 = x1;	    pRgn->extents.y1 = y1;	    pRgn->extents.x2 = x2;	    pRgn->extents.y2 = y2;	    pRgn->data = (RegDataPtr)NULL;	}	return pRgn;    }    Must_have_memory = TRUE; /* XXX */    pData = xallocData(nrects);    pBox = (BoxPtr) (pData + 1);    Must_have_memory = FALSE; /* XXX */    for (i = nrects; --i >= 0; prect++)    {	x1 = prect->x;	y1 = prect->y;	if ((x2 = x1 + (int) prect->width) > MAXSHORT)	    x2 = MAXSHORT;	if ((y2 = y1 + (int) prect->height) > MAXSHORT)	    y2 = MAXSHORT;	if (x1 != x2 && y1 != y2)	{	    pBox->x1 = x1;	    pBox->y1 = y1;	    pBox->x2 = x2;	    pBox->y2 = y2;	    pBox++;	}    }    if (pBox != (BoxPtr) (pData + 1))    {	pData->size = nrects;	pData->numRects = pBox - (BoxPtr) (pData + 1);    	pRgn->data = pData;    	if (ctype != CT_YXBANDED)    	{	    Bool overlap; /* result ignored */	    pRgn->extents.x1 = pRgn->extents.x2 = 0;	    miRegionValidate(pRgn, &overlap);    	}    	else	    miSetExtents(pRgn);    	good(pRgn);    }    else    {	xfree (pData);    }    return pRgn;}/*====================================================================== * 	    	  Region Subtraction *====================================================================*//*- *----------------------------------------------------------------------- * miSubtractO -- *	Overlapping band subtraction. x1 is the left-most point not yet *	checked. * * Results: *	TRUE if successful. * * Side Effects: *	pReg may have rectangles added to it. * *----------------------------------------------------------------------- *//*ARGSUSED*/static BoolmiSubtractO (pReg, r1, r1End, r2, r2End, y1, y2, pOverlap)    register RegionPtr	pReg;    register BoxPtr	r1;    BoxPtr  	  	r1End;    register BoxPtr	r2;    BoxPtr  	  	r2End;    register int  	y1;             int  	y2;    Bool		*pOverlap;{    register BoxPtr	pNextRect;    register int  	x1;    x1 = r1->x1;        assert(y1<y2);    assert(r1 != r1End && r2 != r2End);    pNextRect = REGION_TOP(pReg);    do    {	if (r2->x2 <= x1)	{	    /*	     * Subtrahend entirely to left of minuend: 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);	    NEWRECT(pReg, pNextRect, x1, y1, r2->x1, y2);	    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)		NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2);	    r1++;	    if (r1 != r1End)		x1 = r1->x1;	}    } while ((r1 != r1End) && (r2 != r2End));    /*     * Add remaining minuend rectangles to region.     */    while (r1 != r1End)    {	assert(x1<r1->x2);	NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2);	r1++;	if (r1 != r1End)	    x1 = r1->x1;    }    return TRUE;}	/*- *----------------------------------------------------------------------- * miSubtract -- *	Subtract regS from regM and leave the result in regD. *	S stands for subtrahend, M for minuend and D for difference. * * Results: *	TRUE if successful. * * Side Effects: *	regD is overwritten. * *----------------------------------------------------------------------- */BoolmiSubtract(regD, regM, regS)    register RegionPtr	regD;                   register RegionPtr 	regM;    register RegionPtr	regS;          {    Bool overlap; /* result ignored */    good(regM);    good(regS);    good(regD);   /* check for trivial rejects */    if (REGION_NIL(regM) || REGION_NIL(regS) ||	!EXTENTCHECK(&regM->extents, &regS->extents))    {	return miRegionCopy(regD, regM);    }    else if (regM == regS)    {	xfreeData(regD);	regD->extents.x2 = regD->extents.x1;	regD->extents.y2 = regD->extents.y1;	regD->data = &miEmptyData;	return TRUE;    }     /* Add those rectangles in region 1 that aren't in region 2,       do yucky substraction for overlaps, and       just throw away rectangles in region 2 that aren't in region 1 */    if (!miRegionOp(regD, regM, regS, miSubtractO, TRUE, FALSE, &overlap))	return FALSE;    /*     * Can't alter RegD'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 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);    good(regD);    return TRUE;}/*====================================================================== *	    Region Inversion *====================================================================*//*- *----------------------------------------------------------------------- * miInverse -- *	Take a region and a box and return a region that is everything *	in the box but not in the region. The careful reader will note *	that this is the same as subtracting the region from the box... * * Results: *	TRUE. * * Side Effects: *	newReg is overwritten. * *----------------------------------------------------------------------- */BoolmiInverse(newReg, reg1, invRect)    RegionPtr 	  newReg;       /* Destination region */    RegionPtr 	  reg1;         /* Region to invert */    BoxPtr     	  invRect; 	/* Bounding box for inversion */{    RegionRec	  invReg;   	/* Quick and dirty region made from the				 * bounding box */    Bool	  overlap;	/* result ignored */    good(reg1);    good(newReg);   /* check for trivial rejects */    if (REGION_NIL(reg1) || !EXTENTCHECK(invRect, &reg1->extents))    {	newReg->extents = *invRect;	xfreeData(newReg);	newReg->data = (RegDataPtr)NULL;        return TRUE;    }    /* Add those rectangles in region 1 that aren't in region 2,       do yucky substraction for overlaps, and       just throw away rectangles in region 2 that aren't in region 1 */    invReg.extents = *invRect;    invReg.data = (RegDataPtr)NULL;    if (!miRegionOp(newReg, &invReg, reg1, miSubtractO, TRUE, FALSE, &overlap))	return FALSE;    /*     * 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 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(newReg);    good(newReg);    return TRUE;}/* *   RectIn(region, rect) *   This routine takes a pointer to a region and a pointer to a box *   and determines if the box is outside/inside/partly inside the region. * *   The idea is to travel through the list of rectangles trying to cover the *   passed box with them. Anytime a piece of the rectangle isn't covered *   by a band of rectangles, partOut is set TRUE. Any time a rectangle in *   the region covers part of the box, partIn is set TRUE. The process ends *   when either the box has been completely covered (we reached a band that *   doesn't overlap the box, partIn is TRUE and partOut is false), the *   box has been partially covered (partIn == partOut == TRUE -- because of *   the banding, the first time this is true we know the box is only *   partially in the region) or is outside the region (we reached a band *   that doesn't overlap the box at all and partIn is false) */intmiRectIn(region, prect)    register RegionPtr  region;    register BoxPtr     prect;{    register int	x;    register int	y;    register BoxPtr     pbox;    register BoxPtr     pboxEnd;    int			partIn, partOut;    int			numRects;    good(region);    numRects = REGION_NUM_RECTS(region);    /* useful optimization */    if (!numRects || !EXTENTCHECK(&region->extents, prect))        return(rgnOUT);    if (numRects == 1)    {	/* We know that it must be rgnIN or rgnPART */	if (SUBSUMES(&region->extents, prect))	    return(rgnIN);	else	    return(rgnPART);    }    partOut = FALSE;    partIn = FALSE;    /* (x,y) starts at upper left of rect, moving to the right and down */    x = prect->x1;    y = prect->y1;    /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */    for (pbox = REGION_BOXPTR(region), pboxEnd = pbox + numRects;         pbox != pboxEnd;         pbox++)    {

⌨️ 快捷键说明

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