示例#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;
}
示例#2
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;
}
示例#3
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;
}
示例#4
0
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;
}
示例#5
0
TLIBAPI TBOOL region_subrect(struct RectPool *pool, struct Region *region, 
	RECTINT s[])
{
	struct RectList r1;
	struct TNode *next, *node;
	TBOOL success = TTRUE;

	region_initrectlist(&r1);
	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)
	{
		region_freerects(pool, &region->rg_Rects);
		region_relinkrects(&region->rg_Rects, &r1);
	}
	else
		region_freerects(pool, &r1);

	return success;
}
示例#6
0
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;
}
示例#7
0
TLIBAPI void region_destroy(struct RectPool *pool, struct Region *region)
{
	region_freerects(pool, &region->rg_Rects);
	TExecFree(pool->p_ExecBase, region);
}
示例#8
0
文件: region.c 项目: callcc/tekui
TLIBAPI void region_free(struct RectPool *pool, struct Region *region)
{
	region_freerects(pool, &region->rg_Rects);
}