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

📄 miregion.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************************************Copyright (c) 1987, 1988, 1989  X ConsortiumPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THEX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER INAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of the X Consortium shall not beused in advertising or otherwise to promote the sale, use or other dealingsin this Software without prior written authorization from the X Consortium. Copyright 1987, 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.                         All Rights ReservedPermission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and thatboth that copyright notice and this permission notice appear in supporting documentation, and that the name of Digital not beused in advertising or publicity pertaining to distribution of thesoftware without specific, written prior permission.  DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDINGALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALLDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ORANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THISSOFTWARE.******************************************************************//* $XConsortium: miregion.c,v 1.60 94/04/17 20:27:49 dpw Exp $ */#include <stdio.h>#include "miscstruct.h"#include "regionstr.h"#include "Xprotostr.h"#include "gc.h"#if defined (__GNUC__) && !defined (NO_INLINES)#define INLINE	__inline#else#define INLINE#endif/* * hack until callers of these functions can deal with out-of-memory */extern Bool Must_have_memory;#ifdef DEBUG#define assert(expr) {if (!(expr)) \		FatalError("Assertion failed file %s, line %d: expr\n", \			__FILE__, __LINE__); }#else#define assert(expr)#endif#define good(reg) assert(miValidRegion(reg))/* * The functions in this file implement the Region abstraction used extensively * throughout the X11 sample server. A Region is simply a set of disjoint * (non-overlapping) rectangles, plus an "extent" rectangle which is the * smallest single rectangle that contains all the non-overlapping rectangles. * * A Region is implemented as a "y-x-banded" array of rectangles.  This array * imposes two degrees of order.  First, all rectangles are sorted by top side * y coordinate first (y1), and then by left side x coordinate (x1). * * Furthermore, the rectangles are grouped into "bands".  Each rectangle in a * band has the same top y coordinate (y1), and each has the same bottom y * coordinate (y2).  Thus all rectangles in a band differ only in their left * and right side (x1 and x2).  Bands are implicit in the array of rectangles: * there is no separate list of band start pointers. * * The y-x band representation does not minimize rectangles.  In particular, * if a rectangle vertically crosses a band (the rectangle has scanlines in  * the y1 to y2 area spanned by the band), then the rectangle may be broken * down into two or more smaller rectangles stacked one atop the other.  * *  -----------				    ----------- *  |         |				    |         |		    band 0 *  |         |  --------		    -----------  -------- *  |         |  |      |  in y-x banded    |         |  |      |   band 1 *  |         |  |      |  form is	    |         |  |      | *  -----------  |      |		    -----------  -------- *               |      |				 |      |   band 2 *               --------				 -------- * * An added constraint on the rectangles is that they must cover as much * horizontal area as possible: no two rectangles within a band are allowed * to touch. * * Whenever possible, bands will be merged together to cover a greater vertical * distance (and thus reduce the number of rectangles). Two bands can be merged * only if the bottom of one touches the top of the other and they have * rectangles in the same places (of the same width, of course). * * Adam de Boor wrote most of the original region code.  Joel McCormack * substantially modified or rewrote most of the core arithmetic routines, * and added miRegionValidate in order to support several speed improvements * to miValidateTree.  Bob Scheifler changed the representation to be more * compact when empty or a single rectangle, and did a bunch of gratuitous * reformatting. *//*  true iff two Boxes overlap */#define EXTENTCHECK(r1,r2) \      (!( ((r1)->x2 <= (r2)->x1)  || \          ((r1)->x1 >= (r2)->x2)  || \          ((r1)->y2 <= (r2)->y1)  || \          ((r1)->y1 >= (r2)->y2) ) )/* true iff (x,y) is in Box */#define INBOX(r,x,y) \      ( ((r)->x2 >  x) && \        ((r)->x1 <= x) && \        ((r)->y2 >  y) && \        ((r)->y1 <= y) )/* true iff Box r1 contains Box r2 */#define SUBSUMES(r1,r2) \      ( ((r1)->x1 <= (r2)->x1) && \        ((r1)->x2 >= (r2)->x2) && \        ((r1)->y1 <= (r2)->y1) && \        ((r1)->y2 >= (r2)->y2) )#define xallocData(n) (RegDataPtr)xalloc(REGION_SZOF(n))#define xfreeData(reg) if ((reg)->data && (reg)->data->size) xfree((reg)->data)#define RECTALLOC(pReg,n) \if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \    miRectAlloc(pReg, n)#define ADDRECT(pNextRect,nx1,ny1,nx2,ny2)	\{						\    pNextRect->x1 = nx1;			\    pNextRect->y1 = ny1;			\    pNextRect->x2 = nx2;			\    pNextRect->y2 = ny2;			\    pNextRect++;				\}#define NEWRECT(pReg,pNextRect,nx1,ny1,nx2,ny2)			\{									\    if (!(pReg)->data || ((pReg)->data->numRects == (pReg)->data->size))\    {									\	miRectAlloc(pReg, 1);						\	pNextRect = REGION_TOP(pReg);					\    }									\    ADDRECT(pNextRect,nx1,ny1,nx2,ny2);					\    pReg->data->numRects++;						\    assert(pReg->data->numRects<=pReg->data->size);			\}#define DOWNSIZE(reg,numRects)						 \if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \{									 \    RegDataPtr NewData;							 \    NewData = (RegDataPtr)xrealloc((reg)->data, REGION_SZOF(numRects));	 \    if (NewData)							 \    {									 \	NewData->size = (numRects);					 \	(reg)->data = NewData;						 \    }									 \}BoxRec miEmptyBox = {0, 0, 0, 0};RegDataRec miEmptyData = {0, 0};#ifdef DEBUGintmiPrintRegion(rgn)    RegionPtr rgn;{    int num, size;    register int i;    BoxPtr rects;    num = REGION_NUM_RECTS(rgn);    size = REGION_SIZE(rgn);    rects = REGION_RECTS(rgn);    ErrorF("num: %d size: %d\n", num, size);    ErrorF("extents: %d %d %d %d\n",	   rgn->extents.x1, rgn->extents.y1, rgn->extents.x2, rgn->extents.y2);    for (i = 0; i < num; i++)      ErrorF("%d %d %d %d \n",	     rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);    ErrorF("\n");    return(num);}BoolmiRegionsEqual(reg1, reg2)    RegionPtr reg1;    RegionPtr reg2;{    int i;    BoxPtr rects1, rects2;    if (reg1->extents.x1 != reg2->extents.x1) return FALSE;    if (reg1->extents.x2 != reg2->extents.x2) return FALSE;    if (reg1->extents.y1 != reg2->extents.y1) return FALSE;    if (reg1->extents.y2 != reg2->extents.y2) return FALSE;    if (REGION_NUM_RECTS(reg1) != REGION_NUM_RECTS(reg2)) return FALSE;        rects1 = REGION_RECTS(reg1);    rects2 = REGION_RECTS(reg2);    for (i = 0; i != REGION_NUM_RECTS(reg1); i++) {	if (rects1[i].x1 != rects2[i].x1) return FALSE;	if (rects1[i].x2 != rects2[i].x2) return FALSE;	if (rects1[i].y1 != rects2[i].y1) return FALSE;	if (rects1[i].y2 != rects2[i].y2) return FALSE;    }    return TRUE;}BoolmiValidRegion(reg)    RegionPtr reg;{    register int i, numRects;    if ((reg->extents.x1 > reg->extents.x2) ||	(reg->extents.y1 > reg->extents.y2))	return FALSE;    numRects = REGION_NUM_RECTS(reg);    if (!numRects)	return ((reg->extents.x1 == reg->extents.x2) &&		(reg->extents.y1 == reg->extents.y2) &&		(reg->data->size || (reg->data == &miEmptyData)));    else if (numRects == 1)	return (!reg->data);    else    {	register BoxPtr pboxP, pboxN;	BoxRec box;	pboxP = REGION_RECTS(reg);	box = *pboxP;	box.y2 = pboxP[numRects-1].y2;	pboxN = pboxP + 1;	for (i = numRects; --i > 0; pboxP++, pboxN++)	{	    if ((pboxN->x1 >= pboxN->x2) ||		(pboxN->y1 >= pboxN->y2))		return FALSE;	    if (pboxN->x1 < box.x1)	        box.x1 = pboxN->x1;	    if (pboxN->x2 > box.x2)		box.x2 = pboxN->x2;	    if ((pboxN->y1 < pboxP->y1) ||		((pboxN->y1 == pboxP->y1) &&		 ((pboxN->x1 < pboxP->x2) || (pboxN->y2 != pboxP->y2))))		return FALSE;	}	return ((box.x1 == reg->extents.x1) &&		(box.x2 == reg->extents.x2) &&		(box.y1 == reg->extents.y1) &&		(box.y2 == reg->extents.y2));    }}#endif /* DEBUG *//***************************************************************** *   RegionCreate(rect, size) *     This routine does a simple malloc to make a structure of *     REGION of "size" number of rectangles. *****************************************************************/RegionPtrmiRegionCreate(rect, size)    BoxPtr rect;    int size;{    register RegionPtr pReg;       Must_have_memory = TRUE; /* XXX */    pReg = (RegionPtr)xalloc(sizeof(RegionRec));    Must_have_memory = FALSE; /* XXX */    if (rect)    {	pReg->extents = *rect;	pReg->data = (RegDataPtr)NULL;    }    else    {	pReg->extents = miEmptyBox;	if ((size > 1) && (pReg->data = xallocData(size)))	{	    pReg->data->size = size;	    pReg->data->numRects = 0;	}	else	    pReg->data = &miEmptyData;    }    return(pReg);}/***************************************************************** *   RegionInit(pReg, rect, size) *     Outer region rect is statically allocated. *****************************************************************/voidmiRegionInit(pReg, rect, size)    RegionPtr pReg;    BoxPtr rect;    int size;{    if (rect)    {	pReg->extents = *rect;	pReg->data = (RegDataPtr)NULL;    }    else    {	pReg->extents = miEmptyBox;	if ((size > 1) && (pReg->data = xallocData(size)))	{	    pReg->data->size = size;	    pReg->data->numRects = 0;	}	else	    pReg->data = &miEmptyData;    }}voidmiRegionDestroy(pReg)    RegionPtr pReg;{    good(pReg);    xfreeData(pReg);    xfree(pReg);}voidmiRegionUninit(pReg)    RegionPtr pReg;{    good(pReg);    xfreeData(pReg);}BoolmiRectAlloc(pRgn, n)    register RegionPtr pRgn;    int n;{    Must_have_memory = TRUE; /* XXX */    if (!pRgn->data)    {	n++;	pRgn->data = xallocData(n);	pRgn->data->numRects = 1;	*REGION_BOXPTR(pRgn) = pRgn->extents;    }    else if (!pRgn->data->size)    {	pRgn->data = xallocData(n);	pRgn->data->numRects = 0;    }    else    {	if (n == 1)	{	    n = pRgn->data->numRects;	    if (n > 500) /* XXX pick numbers out of a hat */		n = 250;	}	n += pRgn->data->numRects;	pRgn->data = (RegDataPtr)xrealloc(pRgn->data, REGION_SZOF(n));    }    Must_have_memory = FALSE; /* XXX */    pRgn->data->size = n;    return TRUE;}BoolmiRegionCopy(dst, src)    register RegionPtr dst;    register RegionPtr src;{    good(dst);    good(src);    if (dst == src)	return TRUE;    dst->extents = src->extents;    if (!src->data || !src->data->size)    {	xfreeData(dst);	dst->data = src->data;	return TRUE;    }    if (!dst->data || (dst->data->size < src->data->numRects))    {	xfreeData(dst);	Must_have_memory = TRUE; /* XXX */	dst->data = xallocData(src->data->numRects);	Must_have_memory = FALSE; /* XXX */	dst->data->size = src->data->numRects;    }    dst->data->numRects = src->data->numRects;    memmove((char *)REGION_BOXPTR(dst),(char *)REGION_BOXPTR(src), 	  dst->data->numRects * sizeof(BoxRec));    return TRUE;}/*====================================================================== *	    Generic Region Operator *====================================================================*//*- *----------------------------------------------------------------------- * miCoalesce -- *	Attempt to merge the boxes in the current band with those in the *	previous one.  We are guaranteed that the current band extends to *      the end of the rects array.  Used only by miRegionOp. * * Results: *	The new index for the previous band. * * Side Effects: *	If coalescing takes place: *	    - rectangles in the previous band will have their y2 fields *	      altered. *	    - pReg->data->numRects will be decreased. * *----------------------------------------------------------------------- */INLINE static intmiCoalesce (pReg, prevStart, curStart)    register RegionPtr	pReg;	    	/* Region to coalesce		     */    int	    	  	prevStart;  	/* Index of start of previous band   */    int	    	  	curStart;   	/* Index of start of current band    */{    register BoxPtr	pPrevBox;   	/* Current box in previous band	     */    register BoxPtr	pCurBox;    	/* Current box in current band       */    register int  	numRects;	/* Number rectangles in both bands   */    register int	y2;		/* Bottom of current band	     */    /*     * Figure out how many rectangles are in the band.     */    numRects = curStart - prevStart;    assert(numRects == pReg->data->numRects - curStart);    if (!numRects) return curStart;    /*     * The bands may only be coalesced if the bottom of the previous     * matches the top scanline of the current.     */    pPrevBox = REGION_BOX(pReg, prevStart);    pCurBox = REGION_BOX(pReg, curStart);    if (pPrevBox->y2 != pCurBox->y1) return curStart;    /*     * Make sure the bands have boxes in the same places. This     * assumes that boxes have been added in such a way that they

⌨️ 快捷键说明

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