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

📄 pixman-region.c

📁 嵌入式图形库
💻 C
📖 第 1 页 / 共 5 页
字号:
	freeData(newReg);	newReg->data = (pixman_region16_data_t *)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 = (pixman_region16_data_t *)NULL;    if (!pixman_op(newReg, &invReg, reg1, pixman_region_subtractO, TRUE, FALSE, &overlap))	return FALSE;    /*     * Can't alter newReg's extents before we call pixman_op because     * it might be one of the source regions and pixman_op 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.     */    pixman_set_extents(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) */pixman_region_overlap_tpixman_region_contains_rectangle(pixman_region16_t *  region,				 pixman_box16_t *     prect){    int	x;    int	y;    pixman_box16_t *     pbox;    pixman_box16_t *     pboxEnd;    int			partIn, partOut;    int			numRects;    good(region);    numRects = PIXREGION_NUM_RECTS(region);    /* useful optimization */    if (!numRects || !EXTENTCHECK(&region->extents, prect))        return(PIXMAN_REGION_OUT);    if (numRects == 1)    {	/* We know that it must be PIXMAN_REGION_IN or PIXMAN_REGION_PART */	if (SUBSUMES(&region->extents, prect))	    return(PIXMAN_REGION_IN);	else	    return(PIXMAN_REGION_PART);    }    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 = PIXREGION_BOXPTR(region), pboxEnd = pbox + numRects;         pbox != pboxEnd;         pbox++)    {        if (pbox->y2 <= y)           continue;    /* getting up to speed or skipping remainder of band */        if (pbox->y1 > y)        {           partOut = TRUE;      /* missed part of rectangle above */           if (partIn || (pbox->y1 >= prect->y2))              break;           y = pbox->y1;        /* x guaranteed to be == prect->x1 */        }        if (pbox->x2 <= x)           continue;            /* not far enough over yet */        if (pbox->x1 > x)        {           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)        {           y = pbox->y2;        /* finished with this band */           if (y >= prect->y2)              break;           x = 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...	     */	    partOut = TRUE;	    break;	}    }    if (partIn)    {	if (y < prect->y2)	    return PIXMAN_REGION_PART;	else	    return PIXMAN_REGION_IN;    }    else    {	return PIXMAN_REGION_OUT;    }}/* pixman_region_translate (region, x, y)   translates in place*/voidpixman_region_translate (pixman_region16_t * region, int x, int y){    int x1, x2, y1, y2;    int nbox;    pixman_box16_t * pbox;    good(region);    region->extents.x1 = x1 = region->extents.x1 + x;    region->extents.y1 = y1 = region->extents.y1 + y;    region->extents.x2 = x2 = region->extents.x2 + x;    region->extents.y2 = y2 = region->extents.y2 + y;    if (((x1 - SHRT_MIN)|(y1 - SHRT_MIN)|(SHRT_MAX - x2)|(SHRT_MAX - y2)) >= 0)    {	if (region->data && (nbox = region->data->numRects))	{	    for (pbox = PIXREGION_BOXPTR(region); nbox--; pbox++)	    {		pbox->x1 += x;		pbox->y1 += y;		pbox->x2 += x;		pbox->y2 += y;	    }	}	return;    }    if (((x2 - SHRT_MIN)|(y2 - SHRT_MIN)|(SHRT_MAX - x1)|(SHRT_MAX - y1)) <= 0)    {	region->extents.x2 = region->extents.x1;	region->extents.y2 = region->extents.y1;	freeData(region);	region->data = pixman_region_emptyData;	return;    }    if (x1 < SHRT_MIN)	region->extents.x1 = SHRT_MIN;    else if (x2 > SHRT_MAX)	region->extents.x2 = SHRT_MAX;    if (y1 < SHRT_MIN)	region->extents.y1 = SHRT_MIN;    else if (y2 > SHRT_MAX)	region->extents.y2 = SHRT_MAX;    if (region->data && (nbox = region->data->numRects))    {	pixman_box16_t * pboxout;	for (pboxout = pbox = PIXREGION_BOXPTR(region); nbox--; pbox++)	{	    pboxout->x1 = x1 = pbox->x1 + x;	    pboxout->y1 = y1 = pbox->y1 + y;	    pboxout->x2 = x2 = pbox->x2 + x;	    pboxout->y2 = y2 = pbox->y2 + y;	    if (((x2 - SHRT_MIN)|(y2 - SHRT_MIN)|		 (SHRT_MAX - x1)|(SHRT_MAX - y1)) <= 0)	    {		region->data->numRects--;		continue;	    }	    if (x1 < SHRT_MIN)		pboxout->x1 = SHRT_MIN;	    else if (x2 > SHRT_MAX)		pboxout->x2 = SHRT_MAX;	    if (y1 < SHRT_MIN)		pboxout->y1 = SHRT_MIN;	    else if (y2 > SHRT_MAX)		pboxout->y2 = SHRT_MAX;	    pboxout++;	}	if (pboxout != pbox)	{	    if (region->data->numRects == 1)	    {		region->extents = *PIXREGION_BOXPTR(region);		freeData(region);		region->data = (pixman_region16_data_t *)NULL;	    }	    else		pixman_set_extents(region);	}    }}/* XXX: Do we need this?static pixman_bool_tpixman_region16_data_copy(pixman_region16_t * dst, pixman_region16_t * src){    good(dst);    good(src);    if (dst->data)	return TRUE;    if (dst == src)	return TRUE;    if (!src->data || !src->data->size)    {	freeData(dst);	dst->data = (pixman_region16_data_t *)NULL;	return TRUE;    }    if (!dst->data || (dst->data->size < src->data->numRects))    {	freeData(dst);	dst->data = allocData(src->data->numRects);	if (!dst->data)	    return pixman_break (dst);    }    dst->data->size = src->data->size;    dst->data->numRects = src->data->numRects;    return TRUE;}*/voidpixman_region_reset(pixman_region16_t *region, pixman_box16_t *box){    good(region);    assert(box->x1<=box->x2);    assert(box->y1<=box->y2);    region->extents = *box;    freeData(region);    region->data = (pixman_region16_data_t *)NULL;}/* box is "return" value */intpixman_region_contains_point(pixman_region16_t * region,			     int x, int y,			     pixman_box16_t * box){    pixman_box16_t *pbox, *pboxEnd;    int numRects;    good(region);    numRects = PIXREGION_NUM_RECTS(region);    if (!numRects || !INBOX(&region->extents, x, y))        return(FALSE);    if (numRects == 1)    {	*box = region->extents;	return(TRUE);    }    for (pbox = PIXREGION_BOXPTR(region), pboxEnd = pbox + numRects;	 pbox != pboxEnd;	 pbox++)    {        if (y >= pbox->y2)	   continue;		/* not there yet */	if ((y < pbox->y1) || (x < pbox->x1))	   break;		/* missed it */	if (x >= pbox->x2)	   continue;		/* not there yet */	*box = *pbox;	return(TRUE);    }    return(FALSE);}intpixman_region_not_empty(pixman_region16_t * region){    good(region);    return(!PIXREGION_NIL(region));}/* XXX: Do we need this?static intpixman_region16_broken(pixman_region16_t * region){    good(region);    return (PIXREGION_NAR(region));}*/voidpixman_region_empty(pixman_region16_t * region){    good(region);    freeData(region);    region->extents.x2 = region->extents.x1;    region->extents.y2 = region->extents.y1;    region->data = pixman_region_emptyData;}pixman_box16_t *pixman_region_extents(pixman_region16_t * region){    good(region);    return(&region->extents);}#define ExchangeSpans(a, b)				    \{							    \    pixman_region16_point_t tpt;					    \    int    tw;						    \							    \    tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt;    \    tw = widths[a]; widths[a] = widths[b]; widths[b] = tw;  \}/* ||| I should apply the merge sort code to rectangle sorting above, and see   if mapping time can be improved.  But right now I've been at work 12 hours,   so forget it.*/static void QuickSortSpans(    pixman_region16_point_t spans[],    int	    widths[],    int	    numSpans){    int	    y;    int	    i, j, m;    pixman_region16_point_t *r;    /* Always called with numSpans > 1 */    /* Sorts only by y, doesn't bother to sort by x */    do    {	if (numSpans < 9)	{	    /* Do insertion sort */	    int yprev;	    yprev = spans[0].y;	    i = 1;	    do	    { /* while i != numSpans */		y = spans[i].y;		if (yprev > y)		{		    /* spans[i] is out of order.  Move into proper location. */		    pixman_region16_point_t tpt;		    int	    tw, k;		    for (j = 0; y >= spans[j].y; j++) {}		    tpt = spans[i];		    tw  = widths[i];		    for (k = i; k != j; k--)		    {			spans[k] = spans[k-1];			widths[k] = widths[k-1];		    }		    spans[j] = tpt;		    widths[j] = tw;		    y = spans[i].y;		} /* if out of order */		yprev = y;		i++;	    } while (i != numSpans);	    return;	}	/* Choose partition element, stick in location 0 */	m = numSpans / 2;	if (spans[m].y > spans[0].y)		ExchangeSpans(m, 0);	if (spans[m].y > spans[numSpans-1].y)   ExchangeSpans(m, numSpans-1);	if (spans[m].y > spans[0].y)		ExchangeSpans(m, 0);	y = spans[0].y;        /* Partition array */        i = 0;        j = numSpans;        do	{	    r = &(spans[i]);	    do	    {		r++;		i++;            } while (i != numSpans && r->y < y);	    r = &(spans[j]);	    do	    {		r--;		j--;            } while (y < r->y);            if (i < j)		ExchangeSpans(i, j);        } while (i < j);        /* Move partition element back to middle */        ExchangeSpans(0, j);	/* Recurse */        if (numSpans-j-1 > 1)	    QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);        numSpans = j;    } while (numSpans > 1);}#define NextBand()						    \{								    \    clipy1 = pboxBandStart->y1;					    \    clipy2 = pboxBandStart->y2;					    \    pboxBandEnd = pboxBandStart + 1;				    \    while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) {  \	pboxBandEnd++;						    \    }								    \    for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \}/*    Clip a list of scanlines to a region.  The caller has allocated the    space.  FSorted is non-zero if the scanline origins are in ascending    order.    returns the number of new, clipped scanlines.*/#ifdef XXX_DO_WE_NEED_THISstatic intpixman_region16_clip_spans(    pixman_region16_t 		*prgnDst,    pixman_region16_point_t 	*ppt,    int	    		*pwidth,    int			nspans,    pixman_region16_point_t 	*pptNew,    int			*pwi

⌨️ 快捷键说明

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