Ejemplo n.º 1
0
TLIBAPI TBOOL region_orrectlist(struct RectPool *pool, struct RectList *list, 
	TINT s[4], TBOOL opportunistic)
{
	if (list->rl_NumNodes > 0)
	{
		TINT x0 = s[0];
		TINT y0 = s[1];
		TINT x1 = s[2];
		TINT y1 = s[3];
		TUINT64 area = 0;
		
		struct TNode *next, *node = list->rl_List.tlh_Head;
		for (; (next = node->tln_Succ); node = next)
		{
			struct RectNode *rn = (struct RectNode *) node;
			TINT *r = rn->rn_Rect;
			if (s[0] >= r[0] && s[1] >= r[1] &&
				s[2] <= r[2] && s[3] <= r[3])
				return TTRUE;
			if (!opportunistic)
				continue;
			area += (r[2] - r[0] + 1) * (r[3] - r[1] + 1);
			x0 = TMIN(x0, r[0]);
			y0 = TMIN(y0, r[1]);
			x1 = TMAX(x1, r[2]);
			y1 = TMAX(y1, r[3]);
		}
		if (opportunistic)
		{
			TUINT64 area2 = (x1 - x0 + 1) * (y1 - y0 + 1);
			if (area2 < OPPORTUNISTIC_MERGE_THRESHOLD ||
				(area * 256 / area2) > OPPORTUNISTIC_MERGE_RATIO)
			{
				/* merge list into a single rectangle */
				TDBPRINTF(TDB_TRACE,("merge %d rects\n",
					list->rl_NumNodes + 1));
				region_freerects(pool, list);
				assert(list->rl_NumNodes == 0);
				return region_insertrect(pool, list, x0, y0, x1, y1);
			}
		}
	}

	struct RectList temp;
	region_initrectlist(&temp);
	if (region_cutrectlist(pool, list, &temp, s))
	{
		if (region_insertrect(pool, &temp, s[0], s[1], s[2], s[3]))
		{
			region_freerects(pool, list);
			region_relinkrects(list, &temp);
			return TTRUE;
		}
	}
	region_freerects(pool, &temp);
	return TFALSE;
}
Ejemplo n.º 2
0
TLIBAPI TBOOL region_xorrect(struct RectPool *pool, struct Region *region,
	RECTINT s[])
{
	struct TNode *next, *node;
	TBOOL success;
	struct RectList r1, r2;
	
	region_initrectlist(&r1);
	region_initrectlist(&r2);

	success = region_insertrect(pool, &r2, s[0], s[1], s[2], s[3]);

	node = region->rg_Rects.rl_List.tlh_Head;
	for (; success && (next = node->tln_Succ); node = next)
	{
		struct TNode *next2, *node2;
		struct RectNode *rn = (struct RectNode *) node;
		struct RectList temp;

		region_initrectlist(&temp);
		success = region_cutrect(pool, &temp, rn->rn_Rect, s);

		node2 = temp.rl_List.tlh_Head;
		for (; success && (next2 = node2->tln_Succ); node2 = next2)
		{
			struct RectNode *rn2 = (struct RectNode *) node2;
			success = region_insertrect(pool, &r1, rn2->rn_Rect[0],
				rn2->rn_Rect[1], rn2->rn_Rect[2], rn2->rn_Rect[3]);
		}
		
		region_freerects(pool, &temp);

		if (success)
		{
			success = region_cutrectlist(pool, &r2, &temp, rn->rn_Rect);
			region_freerects(pool, &r2);
			region_relinkrects(&r2, &temp);
		}
	}

	if (success)
	{
		region_freerects(pool, &region->rg_Rects);
		region_relinkrects(&region->rg_Rects, &r1);
		region_orregion(region, &r2, TFALSE);
		region_freerects(pool, &r2);
	}
	else
	{
		region_freerects(pool, &r1);
		region_freerects(pool, &r2);
	}
	return success;
}
Ejemplo n.º 3
0
static TBOOL region_andrect_internal(struct RectList *temp,
	struct Region *region, TINT s[], TINT dx, TINT dy)
{
	struct RectPool *pool = region->rg_Pool;
	struct TNode *next, *node = region->rg_Rects.rl_List.tlh_Head;
	TBOOL success = TTRUE;
	TINT s0 = s[0] + dx;
	TINT s1 = s[1] + dy;
	TINT s2 = s[2] + dx;
	TINT s3 = s[3] + dy;
	for (; success && (next = node->tln_Succ); node = next)
	{
		struct RectNode *dr = (struct RectNode *) node;
		TINT x0 = dr->rn_Rect[0];
		TINT y0 = dr->rn_Rect[1];
		TINT x1 = dr->rn_Rect[2];
		TINT y1 = dr->rn_Rect[3];
		if (OVERLAP(x0, y0, x1, y1, s0, s1, s2, s3))
		{
			success = region_insertrect(pool, temp,
				TMAX(x0, s0), TMAX(y0, s1), TMIN(x1, s2), TMIN(y1, s3));
		}
	}
	if (!success)
		region_freerects(pool, temp);
	return success;
}
Ejemplo n.º 4
0
static TBOOL region_cutrectlist(struct RectPool *pool, struct RectList *inlist,
	struct RectList *outlist, const RECTINT s[4])
{
	TBOOL success = TTRUE;
	struct TNode *next, *node = inlist->rl_List.tlh_Head;
	for (; success && (next = node->tln_Succ); node = next)
	{
		struct RectNode *rn = (struct RectNode *) node;
		struct RectList temp;
		region_initrectlist(&temp);
		success = region_cutrect(pool, &temp, rn->rn_Rect, s);
		if (success)
		{
			struct TNode *next2, *node2 = temp.rl_List.tlh_Head;
			for (; success && (next2 = node2->tln_Succ); node2 = next2)
			{
				struct RectNode *rn2 = (struct RectNode *) node2;
				success = region_insertrect(pool, outlist, rn2->rn_Rect[0],
					rn2->rn_Rect[1], rn2->rn_Rect[2], rn2->rn_Rect[3]);
				/* note that if unsuccessful, outlist is unusable as well */
			}
		}
		region_freerects(pool, &temp);
	}
	return success;
}
Ejemplo n.º 5
0
static TBOOL region_cutrect(struct RectPool *pool, struct RectList *list,
	const RECTINT d[4], const RECTINT s[4])
{
	TINT d0 = d[0];
	TINT d1 = d[1];
	TINT d2 = d[2];
	TINT d3 = d[3];

	if (!OVERLAPRECT(d, s))
		return region_insertrect(pool, list, d[0], d[1], d[2], d[3]);

	for (;;)
	{
		if (d0 < s[0])
		{
			if (!region_insertrect(pool, list, d0, d1, s[0] - 1, d3))
				break;
			d0 = s[0];
		}

		if (d1 < s[1])
		{
			if (!region_insertrect(pool, list, d0, d1, d2, s[1] - 1))
				break;
			d1 = s[1];
		}

		if (d2 > s[2])
		{
			if (!region_insertrect(pool, list, s[2] + 1, d1, d2, d3))
				break;
			d2 = s[2];
		}

		if (d3 > s[3])
		{
			if (!region_insertrect(pool, list, d0, s[3] + 1, d2, d3))
				break;
		}

		return TTRUE;

	}
	return TFALSE;
}
Ejemplo n.º 6
0
TLIBAPI TBOOL region_init(struct RectPool *pool, struct Region *region, 
	TINT *s)
{
	region->rg_Pool = pool;
	region_initrectlist(&region->rg_Rects);
	if (s && !region_insertrect(pool, &region->rg_Rects,
		s[0], s[1], s[2], s[3]))
		return TFALSE;
	return TTRUE;
}
Ejemplo n.º 7
0
TLIBAPI struct Region *region_new(struct RectPool *pool, TINT *s)
{
	struct TExecBase *TExecBase = pool->p_ExecBase;
	struct Region *region = TAlloc(TNULL, sizeof(struct Region));
	if (region)
	{
		region->rg_Pool = pool;
		region_initrectlist(&region->rg_Rects);
		if (s && !region_insertrect(pool, &region->rg_Rects,
			s[0], s[1], s[2], s[3]))
		{
			TFree(region);
			region = TNULL;
		}
	}
	return region;
}