示例#1
0
文件: path2d.c 项目: erelh/gpac
GF_EXPORT
GF_Path *gf_path_get_flatten(GF_Path *gp)
{
	GF_Path *ngp;
	Fixed fineness;
	u32 i, *countour;
	GF_Point2D *pt;
	if (!gp || !gp->n_points) return NULL;

	if (gp->flags & GF_PATH_FLATTENED) return gf_path_clone(gp);

	/*avoid too high precision */
	fineness = MAX(FIX_ONE - gp->fineness, FIX_ONE / 100);

	ngp = gf_path_new();
	pt = &gp->points[0];
	gf_path_add_move_to_vec(ngp, pt);
	countour = gp->contours;
	for (i=1; i<gp->n_points; ) {
		switch (gp->tags[i]) {
		case GF_PATH_CURVE_ON:
		case GF_PATH_CLOSE:
			pt = &gp->points[i];
			if (*countour == i-1) {
				gf_path_add_move_to_vec(ngp, pt);
				countour++;
			} else {
				gf_path_add_line_to_vec(ngp, pt);
			}
			if (gp->tags[i]==GF_PATH_CLOSE) gf_path_close(ngp);
			i++;
			break;
		case GF_PATH_CURVE_CONIC:
		{
			GF_Point2D *ctl, *end, c1, c2;
			ctl = &gp->points[i];
			end = &gp->points[i+1];
			c1.x = pt->x + 2*(ctl->x - pt->x)/3;
			c1.y = pt->y + 2*(ctl->y - pt->y)/3;
			c2.x = c1.x + (end->x - pt->x) / 3;
			c2.y = c1.y + (end->y - pt->y) / 3;

			gf_subdivide_cubic(ngp, pt->x, pt->y, c1.x, c1.y, c2.x, c2.y, end->x, end->y, fineness);
			pt = end;
			if (gp->tags[i+1]==GF_PATH_CLOSE) gf_path_close(ngp);
			i+=2;
		}
			break;
		case GF_PATH_CURVE_CUBIC:
			gf_subdivide_cubic(ngp, pt->x, pt->y, gp->points[i].x, gp->points[i].y, gp->points[i+1].x, gp->points[i+1].y, gp->points[i+2].x, gp->points[i+2].y, fineness);
			pt = &gp->points[i+2];
			if (gp->tags[i+2]==GF_PATH_CLOSE) gf_path_close(ngp);
			i+=3;
			break;
		}
	}
	if (gp->flags & GF_PATH_FILL_ZERO_NONZERO) ngp->flags |= GF_PATH_FILL_ZERO_NONZERO;
	ngp->flags |= (GF_PATH_BBOX_DIRTY | GF_PATH_FLATTENED);
	return ngp;
}
static void ifs2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	u32 i;
	SFVec2f *pts;
	u32 ci_count, c_count;
	Bool started;
	M_IndexedFaceSet2D *ifs2D;
	M_Coordinate2D *coord;

	if (! gf_node_dirty_get(node)) return;

	ifs2D = (M_IndexedFaceSet2D *)node;
	coord = (M_Coordinate2D *)ifs2D->coord;
	drawable_reset_path(stack);
	gf_node_dirty_clear(node, 0);
	drawable_mark_modified(stack, tr_state);


	c_count = coord->point.count;
	ci_count = ifs2D->coordIndex.count;
	pts = coord->point.vals;

	if (ci_count > 0) {
		started = 0;
		for (i=0; i < ci_count; i++) {
			if (ifs2D->coordIndex.vals[i] == -1) {
				gf_path_close(stack->path);
				started = 0;
			} else if (!started) {
				started = 1;
				gf_path_add_move_to_vec(stack->path, &pts[ifs2D->coordIndex.vals[i]]);
			} else {
				gf_path_add_line_to_vec(stack->path, &pts[ifs2D->coordIndex.vals[i]]);
			}
		}
		if (started) gf_path_close(stack->path);
	} else if (c_count) {
		gf_path_add_move_to_vec(stack->path, &pts[0]);
		for (i=1; i < c_count; i++) {
			gf_path_add_line_to_vec(stack->path, &pts[i]);
		}
		gf_path_close(stack->path);
	}
}