예제 #1
0
파일: region.c 프로젝트: technosaurus/tekui
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;
}
예제 #2
0
파일: region.c 프로젝트: technosaurus/tekui
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;
}
예제 #3
0
파일: region.c 프로젝트: technosaurus/tekui
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;
}
예제 #4
0
파일: region.c 프로젝트: callcc/tekui
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;
}
예제 #5
0
파일: region.c 프로젝트: technosaurus/tekui
TLIBAPI TBOOL region_andrect(struct RectPool *pool, struct Region *region,
	TINT s[], TINT dx, TINT dy)
{
	struct RectList temp;
	region_initrectlist(&temp);
	if (region_andrect_internal(&temp, region, s, dx, dy))
	{
		region_freerects(pool, &region->rg_Rects);
		region_relinkrects(&region->rg_Rects, &temp);
		return TTRUE;
	}
	return TFALSE;
}
예제 #6
0
파일: region.c 프로젝트: technosaurus/tekui
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;
}
예제 #7
0
파일: region.c 프로젝트: technosaurus/tekui
TLIBAPI TBOOL region_andregion(struct RectPool *pool, struct Region *dregion,
	struct Region *sregion)
{
	struct TNode *next, *node = sregion->rg_Rects.rl_List.tlh_Head;
	TBOOL success = TTRUE;
	struct RectList temp;
	region_initrectlist(&temp);
	for (; success && (next = node->tln_Succ); node = next)
	{
		struct RectNode *sr = (struct RectNode *) node;
		success = region_andrect_internal(&temp, dregion,
			sr->rn_Rect, 0, 0);
	}
	if (success)
	{
		region_freerects(pool, &dregion->rg_Rects);
		region_relinkrects(&dregion->rg_Rects, &temp);
	}
	/* note: if unsucessful, dregion is of no use anymore */
	return success;
}
예제 #8
0
파일: region.c 프로젝트: technosaurus/tekui
static void region_relinkrects(struct RectList *d, struct RectList *s)
{
	region_relinklist(&d->rl_List, &s->rl_List);
	d->rl_NumNodes += s->rl_NumNodes;
	region_initrectlist(s);	
}
예제 #9
0
파일: region.c 프로젝트: technosaurus/tekui
TLIBAPI void region_initpool(struct RectPool *pool, TAPTR TExecBase)
{
	region_initrectlist(&pool->p_Rects);
	pool->p_ExecBase = TExecBase;
}