Ejemplo n.º 1
0
static void svg_rect_rebuild(GF_Node *node, Drawable *stack, SVGAllAttributes *atts)
{
	Fixed rx = (atts->rx ? atts->rx->value : 0);
	Fixed ry = (atts->ry ? atts->ry->value : 0);
	Fixed x = (atts->x ? atts->x->value : 0);
	Fixed y = (atts->y ? atts->y->value : 0);
	Fixed width = (atts->width ? atts->width->value : 0);
	Fixed height = (atts->height ? atts->height->value : 0);

	drawable_reset_path(stack);
	if (!width || !height) return;

	/*we follow SVG 1.1 and not 1.2 !!*/
	if (rx || ry) {
		Fixed cx, cy;
		if (rx >= width/2) rx = width/2;
		if (ry >= height/2) ry = height/2;
		if (rx == 0) rx = ry;
		if (ry == 0) ry = rx;
		gf_path_add_move_to(stack->path, x+rx, y);

		if (width-rx!=rx)
			gf_path_add_line_to(stack->path, x+width-rx, y);

		cx = x+width-rx; cy = y+ry;
		svg_rect_add_arc(stack->path, x+width, y+ry, cx, cy, rx, ry);
		
		if (height-ry!=ry)
			gf_path_add_line_to(stack->path, x+width, y+height-ry);

		cx = x+width-rx; cy = y+height-ry;
		svg_rect_add_arc(stack->path, x+width-rx, y+height, cx, cy, rx, ry);
		
		if (width-rx!=rx)
			gf_path_add_line_to(stack->path, x+rx, y+height);

		cx = x+rx; cy = y+height-ry;
		svg_rect_add_arc(stack->path, x, y+height-ry, cx, cy, rx, ry);
		
		if (height-ry!=ry)
			gf_path_add_line_to(stack->path, x, y+ry);

		cx = x+rx; cy = y+ry;
		svg_rect_add_arc(stack->path, x+rx, y, cx, cy, rx, ry);

		gf_path_close(stack->path);
	} else {
		gf_path_add_move_to(stack->path, x, y);
		gf_path_add_line_to(stack->path, x+width, y);		
		gf_path_add_line_to(stack->path, x+width, y+height);		
		gf_path_add_line_to(stack->path, x, y+height);		
		gf_path_close(stack->path);		
	}
}
Ejemplo n.º 2
0
static void svg_sani_render_line(GF_Node *node, void *rs, Bool is_destroy)
{
	SVG_SANI_lineElement *line = (SVG_SANI_lineElement *)node;
	Drawable *cs = (Drawable *)gf_node_get_private(node);
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		DestroyDrawableNode(node);
		return;
	}
	if (eff->traversing_mode==TRAVERSE_DRAW) {
		drawable_draw(eff);
		return;
	}
	else if (eff->traversing_mode==TRAVERSE_PICK) {
		drawable_pick(eff);
		return;
	}

	svg_sani_render_base(node, (RenderEffect2D *)rs);

	if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) {
		drawable_reset_path(cs);
		gf_path_add_move_to(cs->path, line->x1.value, line->y1.value);
		gf_path_add_line_to(cs->path, line->x2.value, line->y2.value);
		gf_node_dirty_clear(node, GF_SG_SVG_GEOMETRY_DIRTY);
		cs->flags |= DRAWABLE_HAS_CHANGED;
	}
	svg_sani_DrawablePostRender(cs, (SVG_SANI_TransformableElement *)line, (RenderEffect2D *)rs, 0, 0);
}
Ejemplo n.º 3
0
int ft_move_to(FTCST FT_Vector *to, void *user)
{
	ft_outliner *ftol = (ft_outliner *)user;
	gf_path_add_move_to(ftol->path, INT2FIX(to->x), INT2FIX(to->y) );
	ftol->last_x = (s32) to->x;
	ftol->last_y = (s32) to->y;
	return 0;
}
Ejemplo n.º 4
0
static int ft_move_to(const FT_Vector *to, void *user)
{
	ft_outliner *ftol = (ft_outliner *)user;
	gf_path_add_move_to(ftol->path, INT2FIX(to->x), INT2FIX(to->y) );
	ftol->last_x = to->x;
	ftol->last_y = to->y;
	return 0;
}
Ejemplo n.º 5
0
void visual_2d_fill_irect(GF_VisualManager *visual, GF_IRect *rc, u32 fill, u32 strike)
{
	GF_Path *path;
	GF_Path *outline;
	GF_PenSettings pen;
	GF_Raster2D *raster = visual->compositor->rasterizer;
#ifdef SKIP_DRAW
	return;
#endif

	if (!rc) return;
	if (!visual->is_attached) return;
	if (!fill && !strike ) return;

	/*no aa*/
	visual_2d_set_options(visual->compositor, visual->raster_surface, 0, 1);
	raster->surface_set_matrix(visual->raster_surface, NULL);

	raster->surface_set_raster_level(visual->raster_surface, GF_RASTER_HIGH_SPEED);
	raster->surface_set_matrix(visual->raster_surface, NULL);

	path = gf_path_new();
	gf_path_add_move_to(path, INT2FIX(rc->x-1), INT2FIX(rc->y+2-rc->height));
	gf_path_add_line_to(path, INT2FIX(rc->x+rc->width-2), INT2FIX(rc->y+2-rc->height));
	gf_path_add_line_to(path, INT2FIX(rc->x+rc->width), INT2FIX(rc->y));
	gf_path_add_line_to(path, INT2FIX(rc->x), INT2FIX(rc->y));
	gf_path_close(path);

	if (fill) {
		raster->surface_set_path(visual->raster_surface, path);
		raster->stencil_set_brush_color(visual->raster_brush, fill);

		raster->surface_set_clipper(visual->raster_surface, rc);
		raster->surface_fill(visual->raster_surface, visual->raster_brush);

		raster->surface_set_path(visual->raster_surface, NULL);
	}

	if (strike) {
		memset(&pen, 0, sizeof(GF_PenSettings));
		pen.width = 2;
		pen.align = GF_PATH_LINE_INSIDE;
		pen.join = GF_LINE_JOIN_BEVEL;
		outline = gf_path_get_outline(path, pen);
		outline->flags &= ~GF_PATH_FILL_ZERO_NONZERO;

		raster->surface_set_path(visual->raster_surface, outline);
		raster->stencil_set_brush_color(visual->raster_brush, strike);

		raster->surface_set_clipper(visual->raster_surface, rc);
		raster->surface_fill(visual->raster_surface, visual->raster_brush);

		raster->surface_set_path(visual->raster_surface, NULL);
		gf_path_del(outline);
	}

	gf_path_del(path);
}
Ejemplo n.º 6
0
static void svg_polyline_rebuild(GF_Node *node, Drawable *stack, SVGAllAttributes *atts)
{
	u32 i, nbPoints;
	drawable_reset_path(stack);
	if (atts->points) 
		nbPoints = gf_list_count(*atts->points);
	else 
		nbPoints = 0;

	if (nbPoints) {
		SVG_Point *p = (SVG_Point *)gf_list_get(*atts->points, 0);
		gf_path_add_move_to(stack->path, p->x, p->y);
		for (i = 1; i < nbPoints; i++) {
			p = (SVG_Point *)gf_list_get(*atts->points, i);
			gf_path_add_line_to(stack->path, p->x, p->y);
		}
	} else {
		gf_path_add_move_to(stack->path, 0, 0);
	}
}
Ejemplo n.º 7
0
GF_FontManager *gf_font_manager_new(GF_User *user)
{
	char *def_font = "SERIF";
	u32 i, count;
	GF_FontManager *font_mgr;
	GF_FontReader *ifce;
	const char *opt;

	ifce = NULL;
	opt = gf_cfg_get_key(user->config, "FontEngine", "FontReader");
	if (opt) {
		ifce = (GF_FontReader *) gf_modules_load_interface_by_name(user->modules, opt, GF_FONT_READER_INTERFACE);
		if (ifce && ifce->init_font_engine(ifce) != GF_OK) {
			gf_modules_close_interface((GF_BaseInterface *)ifce);
			ifce = NULL;
		}
	}

	if (!ifce) {
		count = gf_modules_get_count(user->modules);
		for (i=0; i<count; i++) {
			ifce = (GF_FontReader *) gf_modules_load_interface(user->modules, i, GF_FONT_READER_INTERFACE);
			if (!ifce) continue;

			if (ifce->init_font_engine(ifce) != GF_OK) {
				gf_modules_close_interface((GF_BaseInterface *)ifce);
				ifce = NULL;
				continue;
			}

			gf_cfg_set_key(user->config, "FontEngine", "FontReader", ifce->module_name);
			break;
		}
	}
	GF_SAFEALLOC(font_mgr, GF_FontManager);
	font_mgr->reader = ifce;
	font_mgr->id_buffer_size = 20;
	font_mgr->id_buffer = gf_malloc(sizeof(u32)*font_mgr->id_buffer_size);
	gf_font_manager_set_font(font_mgr, &def_font, 1, 0);
	font_mgr->default_font = font_mgr->font;

	font_mgr->line_path= gf_path_new();
	gf_path_add_move_to(font_mgr->line_path, -FIX_ONE/2, FIX_ONE/2);
	gf_path_add_line_to(font_mgr->line_path, FIX_ONE/2, FIX_ONE/2);
	gf_path_add_line_to(font_mgr->line_path, FIX_ONE/2, -FIX_ONE/2);
	gf_path_add_line_to(font_mgr->line_path, -FIX_ONE/2, -FIX_ONE/2);
	gf_path_close(font_mgr->line_path);

	opt = gf_cfg_get_key(user->config, "FontEngine", "WaitForFontLoad");
	if (!opt) gf_cfg_set_key(user->config, "FontEngine", "WaitForFontLoad", "no");
	if (opt && !strcmp(opt, "yes")) font_mgr->wait_font_load = 1;

	return font_mgr;
}
Ejemplo n.º 8
0
static void svg_sani_render_polygon(GF_Node *node, void *rs, Bool is_destroy)
{
	SVG_SANI_polygonElement *polygon = (SVG_SANI_polygonElement *)node;
	Drawable *cs = (Drawable *)gf_node_get_private(node);
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		DestroyDrawableNode(node);
		return;
	}
	if (eff->traversing_mode==TRAVERSE_DRAW) {
		drawable_draw(eff);
		return;
	}
	else if (eff->traversing_mode==TRAVERSE_PICK) {
		drawable_pick(eff);
		return;
	}

	svg_sani_render_base(node, (RenderEffect2D *)rs);

	if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) {
		u32 i;
		u32 nbPoints = gf_list_count(polygon->points);
		drawable_reset_path(cs);
		if (nbPoints) {
			SVG_Point *p = (SVG_Point *)gf_list_get(polygon->points, 0);
			gf_path_add_move_to(cs->path, p->x, p->y);
			for (i = 1; i < nbPoints; i++) {
				p = (SVG_Point *)gf_list_get(polygon->points, i);
				gf_path_add_line_to(cs->path, p->x, p->y);
			}
			gf_path_close(cs->path);
		} else {
			gf_path_add_move_to(cs->path, 0, 0);
		}
		gf_node_dirty_clear(node, GF_SG_SVG_GEOMETRY_DIRTY);
		cs->flags |= DRAWABLE_HAS_CHANGED;
	}
	svg_sani_DrawablePostRender(cs, (SVG_SANI_TransformableElement *)polygon, (RenderEffect2D *)rs, 0, 0);
}
Ejemplo n.º 9
0
Archivo: path2d.c Proyecto: erelh/gpac
/*adds rectangle centered on cx, cy*/
GF_EXPORT
GF_Err gf_path_add_rect_center(GF_Path *gp, Fixed cx, Fixed cy, Fixed w, Fixed h)
{
	GF_Err e = gf_path_add_move_to(gp, cx - w/2, cy - h/2);
	if (e) return e;
	e = gf_path_add_line_to(gp, cx + w/2, cy - h/2);
	if (e) return e;
	e = gf_path_add_line_to(gp, cx + w/2, cy + h/2);
	if (e) return e;
	e = gf_path_add_line_to(gp, cx - w/2, cy + h/2);
	if (e) return e;
	return gf_path_close(gp);
}
Ejemplo n.º 10
0
static void ils2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	u32 i;
	Bool started;
	SFVec2f *pts;
	M_IndexedLineSet2D *ils2D;
	M_Coordinate2D *coord;

	if (! gf_node_dirty_get(node)) return;

	drawable_reset_path(stack);
	gf_node_dirty_clear(node, 0);
	drawable_mark_modified(stack, tr_state);

	ils2D = (M_IndexedLineSet2D *)node;
	coord = (M_Coordinate2D *)ils2D->coord;

	pts = coord->point.vals;
	if (ils2D->coordIndex.count > 0) {
		started = 0;
		for (i=0; i < ils2D->coordIndex.count; i++) {
			/*NO close on ILS2D*/
			if (ils2D->coordIndex.vals[i] == -1) {
				started = 0;
			} else if (!started) {
				started = 1;
				gf_path_add_move_to(stack->path, pts[ils2D->coordIndex.vals[i]].x, pts[ils2D->coordIndex.vals[i]].y);
			} else {
				gf_path_add_line_to(stack->path, pts[ils2D->coordIndex.vals[i]].x, pts[ils2D->coordIndex.vals[i]].y);
			}
		}
	} else if (coord->point.count) {
		gf_path_add_move_to(stack->path, pts[0].x, pts[0].y);
		for (i=1; i < coord->point.count; i++) {
			gf_path_add_line_to(stack->path, pts[i].x, pts[i].y);
		}
	}
	stack->path->flags |= GF_PATH_FILL_ZERO_NONZERO;
}
Ejemplo n.º 11
0
Archivo: path2d.c Proyecto: erelh/gpac
GF_EXPORT
GF_Err gf_path_add_rect(GF_Path *gp, Fixed ox, Fixed oy, Fixed w, Fixed h)
{
	GF_Err e = gf_path_add_move_to(gp, ox, oy);
	if (e) return e;
	e = gf_path_add_line_to(gp, ox + w, oy);
	if (e) return e;
	e = gf_path_add_line_to(gp, ox+w, oy-h);
	if (e) return e;
	e = gf_path_add_line_to(gp, ox, oy-h);
	if (e) return e;
	return gf_path_close(gp);
}
Ejemplo n.º 12
0
Archivo: path2d.c Proyecto: erelh/gpac
GF_EXPORT
GF_Err gf_path_add_arc(GF_Path *gp, Fixed radius, Fixed start_angle, Fixed end_angle, u32 close_type)
{
	GF_Err e;
	Fixed _vx, _vy, step, cur;
	s32 i, do_run;

	step = (end_angle - start_angle) / (GF_2D_DEFAULT_RES);
	radius *= 2;

	/*pie*/
	i=0;
	if (close_type==2) {
		gf_path_add_move_to(gp, 0, 0);
		i=1;
	}
	do_run = 1;
	cur=start_angle;
	while (do_run) {
		if (cur>=end_angle) {
			do_run = 0;
			cur = end_angle;
		}
		_vx = gf_mulfix(radius, gf_cos(cur));
		_vy = gf_mulfix(radius, gf_sin(cur));
		if (!i) {
			e = gf_path_add_move_to(gp, _vx, _vy);
			i = 1;
		} else {
			e = gf_path_add_line_to(gp, _vx, _vy);
		}
		if (e) return e;
		cur+=step;
	}
	if (close_type) e = gf_path_close(gp);
	return e;
}
Ejemplo n.º 13
0
static void polyline2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node)) {
		u32 i;
		X_Polyline2D *a = (X_Polyline2D *) node;
		drawable_reset_path(stack);
		for (i=0; i<a->lineSegments.count; i++) {
			if (i) {
				gf_path_add_line_to(stack->path, a->lineSegments.vals[i].x, a->lineSegments.vals[i].y);
			} else {
				gf_path_add_move_to(stack->path, a->lineSegments.vals[i].x, a->lineSegments.vals[i].y);
			}
		}
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
Ejemplo n.º 14
0
static void triangleset2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node)) {
		u32 i, count;
		X_TriangleSet2D *p = (X_TriangleSet2D *)node;
		drawable_reset_path(stack);
		count = p->vertices.count;
		while (count%3) count--;
		for (i=0; i<count; i+=3) {
			gf_path_add_move_to(stack->path, p->vertices.vals[i].x, p->vertices.vals[i].y);
			gf_path_add_line_to(stack->path, p->vertices.vals[i+1].x, p->vertices.vals[i+1].y);
			gf_path_add_line_to(stack->path, p->vertices.vals[i+2].x, p->vertices.vals[i+2].y);
			gf_path_close(stack->path);
		}
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
Ejemplo n.º 15
0
Archivo: path2d.c Proyecto: erelh/gpac
GF_EXPORT
GF_Err gf_path_add_ellipse(GF_Path *gp, Fixed cx, Fixed cy, Fixed a_axis, Fixed b_axis)
{
	GF_Err e;
	Fixed _vx, _vy, cur;
	u32 i;
	a_axis /= 2;
	b_axis /= 2;
	e = gf_path_add_move_to(gp, cx+a_axis, cy);
	if (e) return e;
	for (i=1; i<GF_2D_DEFAULT_RES; i++) {
		cur = GF_2PI*i/GF_2D_DEFAULT_RES;
		_vx = gf_mulfix(a_axis, gf_cos(cur) );
		_vy = gf_mulfix(b_axis, gf_sin(cur) );
		e = gf_path_add_line_to(gp, _vx + cx, _vy + cy);
		if (e) return e;
	}
	return gf_path_close(gp);
}
Ejemplo n.º 16
0
static void svg_line_rebuild(GF_Node *node, Drawable *stack, SVGAllAttributes *atts)
{
	drawable_reset_path(stack);
	gf_path_add_move_to(stack->path, (atts->x1 ? atts->x1->value : 0), (atts->y1 ? atts->y1->value : 0));
	gf_path_add_line_to(stack->path, (atts->x2 ? atts->x2->value : 0), (atts->y2 ? atts->y2->value : 0));
}
Ejemplo n.º 17
0
void visual_2d_fill_rect(GF_VisualManager *visual, DrawableContext *ctx, GF_Rect *_rc, u32 color, u32 strike_color, GF_TraverseState *tr_state)
{
	GF_Path *path;
	GF_Rect *rc;
	GF_Raster2D *raster = visual->compositor->rasterizer;
#ifdef SKIP_DRAW
	return;
#endif

	if (! visual->CheckAttached(visual) ) return;

	if (!color && !strike_color) return;

	if ((ctx->flags & CTX_PATH_FILLED) && (ctx->flags & CTX_PATH_STROKE) ) {
		if (visual->compositor->draw_bvol) draw_clipper(visual, ctx);
		return;
	}

	/*no aa*/
	visual_2d_set_options(visual->compositor, visual->raster_surface, 0, 1);
	if (_rc) {
		rc = _rc;
		raster->surface_set_matrix(visual->raster_surface, &ctx->transform);
	}
	else {
		rc = &ctx->bi->unclip;
		raster->surface_set_matrix(visual->raster_surface, NULL);
	}

	path = gf_path_new();
	gf_path_add_move_to(path, rc->x, rc->y-rc->height);
	gf_path_add_line_to(path, rc->x+rc->width, rc->y-rc->height);
	gf_path_add_line_to(path, rc->x+rc->width, rc->y);
	gf_path_add_line_to(path, rc->x, rc->y);
	gf_path_close(path);


	if (color) {
		/*push path*/
		raster->surface_set_path(visual->raster_surface, path);
		raster->stencil_set_brush_color(visual->raster_brush, color);
		visual_2d_fill_path(visual, ctx, visual->raster_brush, tr_state, 0);
		raster->surface_set_path(visual->raster_surface, NULL);
	}
	if (strike_color) {
		GF_Path *outline;
		GF_PenSettings pen;
		memset(&pen, 0, sizeof(GF_PenSettings));
		pen.width = 1;
		pen.join = GF_LINE_JOIN_BEVEL;
		pen.dash = GF_DASH_STYLE_DOT;
		raster->stencil_set_brush_color(visual->raster_brush, strike_color);
		outline = gf_path_get_outline(path,  pen);
		outline->flags &= ~GF_PATH_FILL_ZERO_NONZERO;
		raster->surface_set_path(visual->raster_surface, outline);
		visual_2d_fill_path(visual, ctx, visual->raster_brush, tr_state, 0);
		raster->surface_set_path(visual->raster_surface, NULL);
		gf_path_del(outline);
	}

	gf_path_del(path);
}
Ejemplo n.º 18
0
static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state)
{
	GF_Path *path;
	SFVec2f *pts;
	SFColor col;
	Fixed alpha;
	u32 i, count, col_ind, ind, end_at;
	u32 linear[2], *colors;
	SFVec2f start, end;
	u32 j, num_col;
	GF_STENCIL grad;
	GF_Raster2D *raster;
	DrawableContext *ctx = tr_state->ctx;
	M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node;
	M_Coordinate2D *coord = (M_Coordinate2D*) ils2D->coord;
	M_Color *color = (M_Color *) ils2D->color;

	end.x = end.y = 0;
	if (!coord->point.count) return;

	if (! ils2D->color) {
		/*no texturing*/
		visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
		return;
	}

	alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255;
	pts = coord->point.vals;

	if (!ils2D->colorPerVertex || (color->color.count<2) ) {
		count = 0;
		end_at = ils2D->coordIndex.count;
		if (!end_at) end_at = coord->point.count;
		ind = ils2D->coordIndex.count ? ils2D->coordIndex.vals[0] : 0;
		i=1;
		path = gf_path_new();
		gf_path_add_move_to(path, pts[ind].x, pts[ind].y);

		for (; i<=end_at; i++) {
			if ((i==end_at) || (ils2D->coordIndex.count && ils2D->coordIndex.vals[i] == -1)) {

				/*draw current*/
				col_ind = (ils2D->colorIndex.count && (ils2D->colorIndex.vals[count]>=0) ) ? (u32) ils2D->colorIndex.vals[count] : count;
				if (col_ind>=color->color.count) col_ind=color->color.count-1;
				col = color->color.vals[col_ind];
				ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);

				visual_2d_draw_path(tr_state->visual, path, ctx, NULL, NULL, tr_state);

				i++;
				if (i>=end_at) break;
				gf_path_reset(path);

				ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0)) ? (u32) ils2D->coordIndex.vals[i] : i;
				gf_path_add_move_to(path, pts[ind].x, pts[ind].y);

				if (ils2D->coordIndex.count) count++;
				continue;
			} else {
				ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0) ) ? (u32) ils2D->coordIndex.vals[i] : i;
				gf_path_add_line_to(path, pts[ind].x, pts[ind].y);
			}
		}
		gf_path_del(path);
		return;
	}

	raster = NULL;
	end_at = ils2D->coordIndex.count;
	if (!end_at) end_at = coord->point.count;
	count = 0;
	col_ind = 0;
	ind = 0;
	i=0;
	path = gf_path_new();
	while (1) {
		gf_path_reset(path);
		ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0)) ? (u32) ils2D->coordIndex.vals[i] : i;
		start = pts[ind];
		num_col = 1;
		i++;
		gf_path_add_move_to(path, start.x, start.y);

		if (ils2D->coordIndex.count) {
			while (ils2D->coordIndex.vals[i] != -1) {
				end = pts[ils2D->coordIndex.vals[i]];
				gf_path_add_line_to(path, end.x, end.y);
				i++;
				num_col++;
				if (i >= ils2D->coordIndex.count) break;
			}
		} else {
			while (i<end_at) {
				end = pts[i];
				gf_path_add_line_to(path, end.x, end.y);
				i++;
				num_col++;
			}
		}

		raster = tr_state->visual->compositor->rasterizer;
		/*use linear gradient*/
		if (num_col==2) {
			Fixed pos[2];
			grad = raster->stencil_new(raster, GF_STENCIL_LINEAR_GRADIENT);
			if (ils2D->colorIndex.count) {
				col = color->color.vals[ils2D->colorIndex.vals[col_ind]];
				linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
				col = color->color.vals[ils2D->colorIndex.vals[col_ind+1]];
				linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
			} else if (ils2D->coordIndex.count) {
				col = color->color.vals[ils2D->coordIndex.vals[col_ind]];
				linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
				col = color->color.vals[ils2D->coordIndex.vals[col_ind+1]];
				linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
			} else {
				col = color->color.vals[col_ind];
				linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
				col = color->color.vals[col_ind+1];
				linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
			}
			pos[0] = 0;
			pos[1] = FIX_ONE;
			raster->stencil_set_linear_gradient(grad, start.x, start.y, end.x, end.y);
			raster->stencil_set_gradient_interpolation(grad, pos, linear, 2);
		} else {
			grad = raster->stencil_new(raster, GF_STENCIL_VERTEX_GRADIENT);
			if (grad) {
				raster->stencil_set_vertex_path(grad, path);

				colors = (u32*)gf_malloc(sizeof(u32) * num_col);
				for (j=0; j<num_col; j++) {
					if (ils2D->colorIndex.count>0) {
						col = color->color.vals[ils2D->colorIndex.vals[col_ind+j]];
					} else if (ils2D->coordIndex.count) {
						col = color->color.vals[ils2D->coordIndex.vals[col_ind+j]];
					} else {
						col = color->color.vals[col_ind+j];
					}
					colors[j] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
				}
				raster->stencil_set_vertex_colors(grad, colors, num_col);
				gf_free(colors);
			}
		}
		raster->stencil_set_matrix(grad, &ctx->transform);
		visual_2d_draw_path(tr_state->visual, path, ctx, NULL, grad, tr_state);
		if (grad) raster->stencil_delete(grad);

		i ++;
		col_ind += num_col + 1;
		if (i >= ils2D->coordIndex.count) break;
		ctx->flags &= ~CTX_PATH_STROKE;
	}
	gf_path_del(path);
}
Ejemplo n.º 19
0
Archivo: path2d.c Proyecto: erelh/gpac
GF_EXPORT
GF_Err gf_path_add_move_to_vec(GF_Path *gp, GF_Point2D *pt) { return gf_path_add_move_to(gp, pt->x, pt->y); }
Ejemplo n.º 20
0
void curve2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state, MFInt32 *idx)
{
	M_Curve2D *c2D;
	SFVec2f orig, ct_orig, ct_end, end;
	u32 cur_index, i, remain, type_count, pt_count;
	SFVec2f *pts;
	M_Coordinate2D *coord;

	c2D = (M_Curve2D *)node;
	coord = (M_Coordinate2D *)c2D->point;
	drawable_reset_path(stack);
	if (!coord) return;

	stack->path->fineness = c2D->fineness;
	if (tr_state->visual->compositor->high_speed)  stack->path->fineness /= 2;


	pts = coord->point.vals;
	if (!pts)
		return;

	cur_index = c2D->type.count ? 1 : 0;
	/*if the first type is a moveTo skip initial moveTo*/
	i=0;
	if (cur_index) {
		while (c2D->type.vals[i]==0) i++;
	}
	ct_orig = orig = pts[ GET_IDX(i) ];

	gf_path_add_move_to(stack->path, orig.x, orig.y);

	pt_count = coord->point.count;
	type_count = c2D->type.count;
	for (; i<type_count; i++) {

		switch (c2D->type.vals[i]) {
		/*moveTo, 1 point*/
		case 0:
			CHECK_VALID_C2D(0);
			orig = pts[ GET_IDX(cur_index) ];
			if (i) gf_path_add_move_to(stack->path, orig.x, orig.y);
			cur_index += 1;
			break;
		/*lineTo, 1 point*/
		case 1:
			CHECK_VALID_C2D(0);
			end = pts[ GET_IDX(cur_index) ];
			gf_path_add_line_to(stack->path, end.x, end.y);
			orig = end;
			cur_index += 1;
			break;
		/*curveTo, 3 points*/
		case 2:
			CHECK_VALID_C2D(2);
			ct_orig = pts[ GET_IDX(cur_index) ];
			ct_end = pts[ GET_IDX(cur_index+1) ];
			end = pts[ GET_IDX(cur_index+2) ];
			gf_path_add_cubic_to(stack->path, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, end.x, end.y);
			cur_index += 3;
			ct_orig = ct_end;
			orig = end;
			break;
		/*nextCurveTo, 2 points (cf spec)*/
		case 3:
			CHECK_VALID_C2D(1);
			ct_orig.x = 2*orig.x - ct_orig.x;
			ct_orig.y = 2*orig.y - ct_orig.y;
			ct_end = pts[ GET_IDX(cur_index) ];
			end = pts[ GET_IDX(cur_index+1) ];
			gf_path_add_cubic_to(stack->path, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, end.x, end.y);
			cur_index += 2;
			ct_orig = ct_end;
			orig = end;
			break;

		/*all XCurve2D specific*/

		/*CW and CCW ArcTo*/
		case 4:
		case 5:
			CHECK_VALID_C2D(2);
			ct_orig = pts[ GET_IDX(cur_index) ];
			ct_end = pts[ GET_IDX(cur_index+1) ];
			end = pts[ GET_IDX(cur_index+2) ];
			gf_path_add_arc_to(stack->path, end.x, end.y, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, (c2D->type.vals[i]==5) ? 1 : 0);
			cur_index += 3;
			ct_orig = ct_end;
			orig = end;
			break;
		/*ClosePath*/
		case 6:
			gf_path_close(stack->path);
			break;
		/*quadratic CurveTo, 2 points*/
		case 7:
			CHECK_VALID_C2D(1);
			ct_end = pts[ GET_IDX(cur_index) ];
			end = pts[ GET_IDX(cur_index+1) ];
			gf_path_add_quadratic_to(stack->path, ct_end.x, ct_end.y, end.x, end.y);
			cur_index += 2;
			ct_orig = ct_end;
			orig = end;
			break;
		}
	}

	/*what's left is an N-bezier spline*/
	if (!idx && (pt_count > cur_index) ) {
		/*first moveto*/
		if (!cur_index) cur_index++;

		remain = pt_count - cur_index;

		if (remain>1)
			gf_path_add_bezier(stack->path, &pts[cur_index], remain);
	}

	gf_node_dirty_clear(node, 0);
	drawable_mark_modified(stack, tr_state);
}
Ejemplo n.º 21
0
void VS2D_FillRect(VisualSurface2D *surf, DrawableContext *ctx, GF_Rect *_rc, u32 color, u32 strike_color)
{
	GF_Path *path;
	GF_Rect *rc;
	GF_Raster2D *r2d = surf->render->compositor->r2d;
#ifdef SKIP_DRAW
	return;
#endif

	if (!surf->the_surface) return;
	if (!color && !strike_color) return;

	if ((ctx->flags & CTX_PATH_FILLED) && (ctx->flags & CTX_PATH_STROKE) ) {
		if (surf->render->compositor->draw_bvol) draw_clipper(surf, ctx);
		return;
	}

	/*no aa*/
	VS2D_SetOptions(surf->render, surf->the_surface, 0, 1);
	if (_rc) {
		rc = _rc;
		r2d->surface_set_matrix(surf->the_surface, &ctx->transform);
	}
	else {
		rc = &ctx->bi->unclip;
		r2d->surface_set_matrix(surf->the_surface, NULL);
	}

	path = gf_path_new();
	gf_path_add_move_to(path, rc->x, rc->y-rc->height);
	gf_path_add_line_to(path, rc->x+rc->width, rc->y-rc->height);
	gf_path_add_line_to(path, rc->x+rc->width, rc->y);
	gf_path_add_line_to(path, rc->x, rc->y);
	gf_path_close(path);
	

	if (color) {
		/*push path*/
		r2d->surface_set_path(surf->the_surface, path);
		r2d->stencil_set_brush_color(surf->the_brush, color);
		VS2D_DoFill(surf, ctx, surf->the_brush);
		r2d->surface_set_path(surf->the_surface, NULL);
	}
	if (strike_color) {
		GF_Path *outline;
		GF_PenSettings pen;
		memset(&pen, 0, sizeof(GF_PenSettings));
		pen.width = 1;
		pen.join = GF_LINE_JOIN_BEVEL;
		pen.dash = GF_DASH_STYLE_DOT;
		r2d->stencil_set_brush_color(surf->the_brush, strike_color);
		outline = gf_path_get_outline(path,  pen);	
		outline->flags &= ~GF_PATH_FILL_ZERO_NONZERO;
		r2d->surface_set_path(surf->the_surface, outline);
		VS2D_DoFill(surf, ctx, surf->the_brush);
		r2d->surface_set_path(surf->the_surface, NULL);
		gf_path_del(outline);
	}

	gf_path_del(path);
}
Ejemplo n.º 22
0
static void build_shape(FSStack *st, GF_Node *node)
{
	GF_FieldInfo field;
	MFVec2f *coords;
	MFInt32 *com, *widthIndex, *lineIndex, *fillIndex, *coordIndex;
	MFFloat *widths;
	MFColor *colors;
	u32 wi, li, fi, ci, command, i, has_ci;
	FSItem *fill_item, *line_item;
	Fixed w;
	SFVec2f cur, pt, ct1={0,0}, ct2, *pts;
	GF_Rect rc;
	u32 line_col, fill_col;
	Bool need_line, need_fill;

	/*get all fields*/
	gf_node_get_field(node, 0, &field);
	coords = field.far_ptr;
	gf_node_get_field(node, 1, &field);
	com = field.far_ptr;
	gf_node_get_field(node, 2, &field);
	widths = field.far_ptr;
	gf_node_get_field(node, 3, &field);
	colors = field.far_ptr;
	gf_node_get_field(node, 4, &field);
	widthIndex = field.far_ptr;
	gf_node_get_field(node, 5, &field);
	lineIndex = field.far_ptr;
	gf_node_get_field(node, 6, &field);
	fillIndex = field.far_ptr;
	gf_node_get_field(node, 7, &field);
	coordIndex = field.far_ptr;

	wi = li = fi = ci = 0;
	w = 0;

	st->max_width = 0;
	cur.x = cur.y = 0;
	fill_item = line_item = NULL;
	need_line = need_fill = 0;
	cur.x = cur.y = 0;
	has_ci = coordIndex->count ? 1 : 0;
	pts = coords->vals;
	line_col = fill_col = 0;

	/*implicit commands: 0 1 2 3*/

/*
	if (widthIndex->count) {
		w = (widthIndex->vals[wi]==-1) ? 0 : widths->vals[widthIndex->vals[wi]];
		if (!w) {
			need_line = 0;
			line_item = NULL;
		} else {
			need_line = 1;
			if (st->max_width<w) st->max_width = w;
		}
		wi++;
	}
	if (lineIndex->count) {
		if (w) {
			line_col = SFCOL_MAKE_ARGB(colors->vals[lineIndex->vals[li]]);
			need_line = 1;
		}
		li++;
	}
	if (fillIndex->count) {
		if (fillIndex->vals[fi]==-1) {
			fill_col = 0;
			fill_item = NULL;
		} else {
			fill_col = SFCOL_MAKE_ARGB(colors->vals[fillIndex->vals[fi]]);
			need_fill = 1;
		}
		fi++;
	}
	if (!coordIndex->count) return;
	cur = coords->vals[coordIndex->vals[ci]];
	ci++;
*/

	for (command=0; command<com->count; command++) {
		switch (com->vals[command]) {
		/*set line width*/
		case 0:
			if (wi >= widthIndex->count) return;
			w = (widthIndex->vals[wi]==-1) ? 0 : widths->vals[widthIndex->vals[wi]];
			if (!w) 
				line_item = NULL;
			else {
				need_line = 1;
				if (st->max_width<w) st->max_width = w;
			}
			wi++;
			break;
		/*set line color*/
		case 1:
			if (li > lineIndex->count) return;
			if (w) {
				line_col = SFCOL_MAKE_ARGB(colors->vals[lineIndex->vals[li]]);
				need_line = 1;
			}
			li++;
			break;
		/*set fill color*/
		case 2:
			if (fi >= fillIndex->count) return;
			if (fillIndex->vals[fi]==-1) {
				fill_col = 0;
				fill_item = NULL;
			} else {
				fill_col = SFCOL_MAKE_ARGB(colors->vals[fillIndex->vals[fi]]);
				need_fill = 1;
			}
			fi++;
			break;
		/*moveTo*/
		case 3:
			if ((has_ci && ci >= coordIndex->count) || (!has_ci && ci >= coords->count) ) return;
			if (need_fill) {
				fill_item = new_fs_item(st, 0, fill_col, 0);
				need_fill = 0;
			}
			if (need_line) {
				line_item = new_fs_item(st, line_col, 0, w);
				need_line = 0;
			}
			if (has_ci) {
				pt = pts[coordIndex->vals[ci]];
			} else {
				pt = pts[ci];
			}
			if (fill_item) gf_path_add_move_to(fill_item->path, pt.x, pt.y);
			if (line_item) gf_path_add_move_to(line_item->path, pt.x, pt.y);
			ct1 = pt;
			cur = pt;
			ci++;
			break;
		/*lineTo*/
		case 4:
			if ((has_ci && ci >= coordIndex->count) || (!has_ci && ci >= coords->count) ) return;
			if (need_fill) {
				fill_item = new_fs_item(st, 0, fill_col, 0);
				gf_path_add_move_to(fill_item->path, cur.x, cur.y);
				need_fill = 0;
			}
			if (need_line) {
				line_item = new_fs_item(st, line_col, 0, w);
				gf_path_add_move_to(line_item->path, cur.x, cur.y);
				need_line = 0;
			}
			if (has_ci) {
				pt = pts[coordIndex->vals[ci]];
			} else {
				pt = pts[ci];
			}
			if (fill_item) gf_path_add_line_to(fill_item->path, pt.x, pt.y);
			if (line_item) gf_path_add_line_to(line_item->path, pt.x, pt.y);
			cur = pt;
			ci++;
			break;
		/*cubic curveTo*/
		case 5:
			if ((has_ci && ci + 2 >= coordIndex->count) || (!has_ci && ci + 2>= coords->count) ) return;
			if (need_fill) {
				fill_item = new_fs_item(st, 0, fill_col, 0);
				gf_path_add_move_to(fill_item->path, cur.x, cur.y);
				need_fill = 0;
			}
			if (need_line) {
				line_item = new_fs_item(st, line_col, 0, w);
				gf_path_add_move_to(line_item->path, cur.x, cur.y);
				need_line = 0;
			}
			if (has_ci) {
				ct1 = pts[coordIndex->vals[ci]];
				ct2 = pts[coordIndex->vals[ci+1]];
				pt = pts[coordIndex->vals[ci+2]];
			} else {
				ct1 = pts[ci];
				ct2 = pts[ci+1];
				pt = pts[ci+2];
			}
			if (fill_item) gf_path_add_cubic_to(fill_item->path, ct1.x, ct1.y, ct2.x, ct2.y, pt.x, pt.y);
			if (line_item) gf_path_add_cubic_to(line_item->path, ct1.x, ct1.y, ct2.x, ct2.y, pt.x, pt.y);
			ct1 = ct2;
			cur = pt;
			ci += 3;
			break;
		/*cubic nextCurveTo*/
		case 6:
			if ((has_ci && ci + 1 >= coordIndex->count) || (!has_ci && ci + 1>= coords->count) ) return;
			if (need_fill) {
				fill_item = new_fs_item(st, 0, fill_col, 0);
				gf_path_add_move_to(fill_item->path, cur.x, cur.y);
				need_fill = 0;
			}
			if (need_line) {
				line_item = new_fs_item(st, line_col, 0, w);
				gf_path_add_move_to(line_item->path, cur.x, cur.y);
				need_line = 0;
			}
			ct1.x = 2*cur.x - ct1.x;
			ct1.y = 2*cur.y - ct1.y;
			if (has_ci) {
				ct2 = pts[coordIndex->vals[ci]];
				pt = pts[coordIndex->vals[ci+1]];
			} else {
				ct2 = pts[ci];
				pt = pts[ci+1];
			}
			if (fill_item) gf_path_add_cubic_to(fill_item->path, ct1.x, ct1.y, ct2.x, ct2.y, pt.x, pt.y);
			if (line_item) gf_path_add_cubic_to(line_item->path, ct1.x, ct1.y, ct2.x, ct2.y, pt.x, pt.y);
			ct1 = ct2;
			cur = pt;
			ci += 2;
			break;
		/*quadratic CurveTo*/
		case 7:
			if ((has_ci && ci + 1 >= coordIndex->count) || (!has_ci && ci + 1>= coords->count) ) return;
			if (need_fill) {
				fill_item = new_fs_item(st, 0, fill_col, 0);
				gf_path_add_move_to(fill_item->path, cur.x, cur.y);
				need_fill = 0;
			}
			if (need_line) {
				line_item = new_fs_item(st, line_col, 0, w);
				gf_path_add_move_to(line_item->path, cur.x, cur.y);
				need_line = 0;
			}
			if (has_ci) {
				ct1 = pts[coordIndex->vals[ci]];
				pt = pts[coordIndex->vals[ci+1]];
			} else {
				ct1 = pts[ci];
				pt = pts[ci+1];
			}
			if (fill_item) gf_path_add_quadratic_to(fill_item->path, ct1.x, ct1.y, pt.x, pt.y);
			if (line_item) gf_path_add_quadratic_to(line_item->path, ct1.x, ct1.y, pt.x, pt.y);
			cur = pt;
			ci += 2;
			break;
		/*quadratic nextCurveTo*/
		case 8:
			if ((has_ci && ci >= coordIndex->count) || (!has_ci && ci >= coords->count) ) return;
			if (need_fill) {
				fill_item = new_fs_item(st, 0, fill_col, 0);
				gf_path_add_move_to(fill_item->path, cur.x, cur.y);
				need_fill = 0;
			}
			if (need_line) {
				line_item = new_fs_item(st, line_col, 0, w);
				gf_path_add_move_to(line_item->path, cur.x, cur.y);
				need_line = 0;
			}
			ct1.x = 2*cur.x - ct1.x;
			ct1.y = 2*cur.y - ct1.y;
			if (has_ci) {
				pt = pts[coordIndex->vals[ci]];
			} else {
				pt = pts[ci];
			}
			if (fill_item) gf_path_add_quadratic_to(fill_item->path, ct1.x, ct1.y, pt.x, pt.y);
			if (line_item) gf_path_add_quadratic_to(line_item->path, ct1.x, ct1.y, pt.x, pt.y);
			cur = pt;
			ci += 2;
			break;
		/*close*/
		case 9:
			if (fill_item) gf_path_close(fill_item->path);
			if (line_item) gf_path_close(line_item->path);
			break;
		}
	}
	
	/*compute bounds*/
	st->bounds.width = st->bounds.height = 0;
	for (i=0; i<gf_list_count(st->items); i++) {
		line_item = gf_list_get(st->items, i);
		gf_path_get_bounds(line_item->path, &rc);
		gf_rect_union(&st->bounds, &rc);
	}
}
Ejemplo n.º 23
0
static void svg_sani_render_rect(GF_Node *node, void *rs, Bool is_destroy)
{
	Drawable *cs = (Drawable *)gf_node_get_private(node);
	SVG_SANI_rectElement *rect = (SVG_SANI_rectElement *)node;
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		DestroyDrawableNode(node);
		return;
	}
	if (eff->traversing_mode==TRAVERSE_DRAW) {
		drawable_draw(eff);
		return;
	}
	else if (eff->traversing_mode==TRAVERSE_PICK) {
		drawable_pick(eff);
		return;
	}

	svg_sani_render_base(node, (RenderEffect2D *)rs);
	
	/* 3) for a leaf node
	   Recreates the path (i.e the shape) only if the node is dirty 
	   (has changed compared to the previous rendering phase) */
	if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) {
		Fixed rx = rect->rx.value;
		Fixed ry = rect->ry.value;
		Fixed x = rect->x.value;
		Fixed y = rect->y.value;
		Fixed width = rect->width.value;
		Fixed height = rect->height.value;

		//fprintf(stdout, "Rebuilding rect %8x\n",rect);
		drawable_reset_path(cs);
		if (rx || ry) {
			if (rx >= width/2) rx = width/2;
			if (ry >= height/2) ry = height/2;
			if (rx == 0) rx = ry;
			if (ry == 0) ry = rx;
			gf_path_add_move_to(cs->path, x+rx, y);
			gf_path_add_line_to(cs->path, x+width-rx, y);
			gf_path_add_quadratic_to(cs->path, x+width, y, x+width, y+ry);
			gf_path_add_line_to(cs->path, x+width, y+height-ry);
			gf_path_add_quadratic_to(cs->path, x+width, y+height, x+width-rx, y+height);
			gf_path_add_line_to(cs->path, x+rx, y+height);
			gf_path_add_quadratic_to(cs->path, x, y+height, x, y+height-ry);
			gf_path_add_line_to(cs->path, x, y+ry);
			gf_path_add_quadratic_to(cs->path, x, y, x+rx, y);
			gf_path_close(cs->path);
		} else {
			gf_path_add_move_to(cs->path, x, y);
			gf_path_add_line_to(cs->path, x+width, y);		
			gf_path_add_line_to(cs->path, x+width, y+height);		
			gf_path_add_line_to(cs->path, x, y+height);		
			gf_path_close(cs->path);		
		}
		gf_node_dirty_clear(node, GF_SG_SVG_GEOMETRY_DIRTY);
		cs->flags |= DRAWABLE_HAS_CHANGED;
	}
	svg_sani_DrawablePostRender(cs, (SVG_SANI_TransformableElement *)rect, (RenderEffect2D *)rs, 1, 0);
}
Ejemplo n.º 24
0
static GF_Glyph *gdip_load_glyph(GF_FontReader *dr, u32 glyph_name)
{
	GF_Rect bounds;
	GF_Glyph *glyph;
	GpPath *path_tmp;
	GpStringFormat *fmt;
	GpMatrix *mat;
	Float est_advance_h;
	unsigned short str[4];
	int i;
	FontPriv *ctx = (FontPriv *)dr->udta;

	if (!ctx->font) return NULL;

	RectF rc;
	rc.X = rc.Y = 0;
	rc.Width = rc.Height = 0;

	GdipCreateStringFormat(StringFormatFlagsNoWrap | StringFormatFlagsNoFitBlackBox | StringFormatFlagsMeasureTrailingSpaces, LANG_NEUTRAL, &fmt);
	GdipSetStringFormatAlign(fmt, StringAlignmentNear);
	GdipCreatePath(FillModeAlternate, &path_tmp);

	if (glyph_name==0x20) {
		est_advance_h = ctx->whitespace_width;
	} else {
		/*to compute first glyph alignment (say 'x', we figure out its bounding full box by using the '_' char as wrapper (eg, "_x_")
		then the bounding box starting from xMin of the glyph ('x_'). The difference between both will give us a good approx 
		of the glyph alignment*/
		str[0] = glyph_name;
		str[1] = (unsigned short) '_';
		str[2] = (unsigned short) 0;
		GdipAddPathString(path_tmp, (const WCHAR *)str, -1, ctx->font, ctx->font_style, ctx->em_size, &rc, fmt);
		GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL);
		est_advance_h = rc.Width - ctx->underscore_width;
	}
	
	GdipResetPath(path_tmp);

	str[0] = glyph_name;
	str[1] = (unsigned short) 0;
	rc.X = rc.Y = 0;
	rc.Width = rc.Height = 0;
	GdipAddPathString(path_tmp, (const WCHAR *)str, -1, ctx->font, ctx->font_style, ctx->em_size, &rc, fmt);

	GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL);

	/*flip so that we are in a font coordinate system - also move back the glyph to x=0 and y=baseline, GdiPlus doesn't do so*/
	GdipCreateMatrix(&mat);
	GdipTranslateMatrix(mat, - rc.X, -ctx->ascent, MatrixOrderAppend);
	GdipScaleMatrix(mat, 1, -1, MatrixOrderAppend);
	GdipTransformPath(path_tmp, mat);
	GdipDeleteMatrix(mat);


	/*start enum*/
	s32 count;
	GdipGetPointCount(path_tmp, &count);
	GpPointF *pts = new GpPointF[count];
	BYTE *types = new BYTE[count];
	GdipGetPathTypes(path_tmp, types, count);
	GdipGetPathPoints(path_tmp, pts, count);

	GF_SAFEALLOC(glyph, GF_Glyph);
	GF_SAFEALLOC(glyph->path, GF_Path);

	for (i=0; i<count; ) {
		BOOL closed = 0;
		s32 sub_type;
		
		sub_type = types[i] & PathPointTypePathTypeMask;

		if (sub_type == PathPointTypeStart) {
			gf_path_add_move_to(glyph->path, FLT2FIX(pts[i].X), FLT2FIX(pts[i].Y));
			i++;
		}
		else if (sub_type == PathPointTypeLine) {
			gf_path_add_line_to(glyph->path, FLT2FIX(pts[i].X), FLT2FIX(pts[i].Y));
		
			if (types[i] & PathPointTypeCloseSubpath) gf_path_close(glyph->path);

			i++;
		}
		else if (sub_type == PathPointTypeBezier) {
			assert(i+2<=count);
			gf_path_add_cubic_to(glyph->path, FLT2FIX(pts[i].X), FLT2FIX(pts[i].Y), FLT2FIX(pts[i+1].X), FLT2FIX(pts[i+1].Y), FLT2FIX(pts[i+2].X), FLT2FIX(pts[i+2].Y));

			if (types[i+2] & PathPointTypeCloseSubpath) gf_path_close(glyph->path);

			i += 3;
		} else {
			assert(0);
			break;
		}
	}
	
	delete [] pts;
	delete [] types;
	GdipDeleteStringFormat(fmt);
	GdipDeletePath(path_tmp);

	glyph->ID = glyph_name;
	glyph->utf_name = glyph_name;
	glyph->vert_advance = (s32) (ctx->ascent-ctx->descent);
	glyph->horiz_advance = (s32) est_advance_h;
	gf_path_get_bounds(glyph->path, &bounds);
	glyph->width = FIX2INT(bounds.width);
	glyph->height = FIX2INT(bounds.height);
	return glyph;
}
Ejemplo n.º 25
0
/* TODO: update for elliptical arcs */		
GF_EXPORT
void gf_svg_path_build(GF_Path *path, GF_List *commands, GF_List *points)
{
	u32 i, j, command_count;
	SVG_Point orig, ct_orig, ct_end, end, *tmp;
	command_count = gf_list_count(commands);
	orig.x = orig.y = ct_orig.x = ct_orig.y = 0;

	for (i=0, j=0; i<command_count; i++) {
		u8 *command = (u8 *)gf_list_get(commands, i);
		switch (*command) {
		case SVG_PATHCOMMAND_M: /* Move To */
			tmp = (SVG_Point*)gf_list_get(points, j);
			orig = *tmp;
			gf_path_add_move_to(path, orig.x, orig.y);
			j++;
			/*provision for nextCurveTo when no curve is specified:
				"If there is no previous command or if the previous command was not an C, c, S or s, 
				assume the first control point is coincident with the current point.
			*/
			ct_orig = orig;
			break;
		case SVG_PATHCOMMAND_L: /* Line To */
			tmp = (SVG_Point*)gf_list_get(points, j);
			end = *tmp;

			gf_path_add_line_to(path, end.x, end.y);
			j++;
			orig = end;
			/*cf above*/
			ct_orig = orig;
			break;
		case SVG_PATHCOMMAND_C: /* Curve To */
			tmp = (SVG_Point*)gf_list_get(points, j);
			ct_orig = *tmp;
			tmp = (SVG_Point*)gf_list_get(points, j+1);
			ct_end = *tmp;
			tmp = (SVG_Point*)gf_list_get(points, j+2);
			end = *tmp;
			gf_path_add_cubic_to(path, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, end.x, end.y);
			ct_orig = ct_end;
			orig = end;
			j+=3;
			break;
		case SVG_PATHCOMMAND_S: /* Next Curve To */
			ct_orig.x = 2*orig.x - ct_orig.x;
			ct_orig.y = 2*orig.y - ct_orig.y;
			tmp = (SVG_Point*)gf_list_get(points, j);
			ct_end = *tmp;
			tmp = (SVG_Point*)gf_list_get(points, j+1);
			end = *tmp;
			gf_path_add_cubic_to(path, ct_orig.x, ct_orig.y, ct_end.x, ct_end.y, end.x, end.y);
			ct_orig = ct_end;
			orig = end;
			j+=2;
			break;
		case SVG_PATHCOMMAND_Q: /* Quadratic Curve To */
			tmp = (SVG_Point*)gf_list_get(points, j);
			ct_orig = *tmp;
			tmp = (SVG_Point*)gf_list_get(points, j+1);
			end = *tmp;
			gf_path_add_quadratic_to(path, ct_orig.x, ct_orig.y, end.x, end.y);			
			orig = end;
			j+=2;
			break;
		case SVG_PATHCOMMAND_T: /* Next Quadratic Curve To */
			ct_orig.x = 2*orig.x - ct_orig.x;
			ct_orig.y = 2*orig.y - ct_orig.y;
			tmp = (SVG_Point*)gf_list_get(points, j);
			end = *tmp;
			gf_path_add_quadratic_to(path, ct_orig.x, ct_orig.y, end.x, end.y);
				orig = end;
				j++;
			break;
		case SVG_PATHCOMMAND_Z: /* Close */
			gf_path_close(path);
			break;
		}
	}	
}
Ejemplo n.º 26
0
static void IFS2D_Draw(GF_Node *node, GF_TraverseState *tr_state)
{
	u32 i, count, ci_count;
	u32 j, ind_col, num_col;
	SFVec2f center, end;
	SFColor col_cen;
	GF_STENCIL grad;
	u32 *colors;
	GF_Path *path;
	SFVec2f start;
	SFVec2f *pts;
	SFColor col;
	Fixed alpha;
	GF_Raster2D *raster;
	DrawableContext *ctx = tr_state->ctx;
	M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node;
	M_Coordinate2D *coord = (M_Coordinate2D*) ifs2D->coord;
	M_Color *color = (M_Color *) ifs2D->color;
		
	col.red = col.green = col.blue = 0;
	/*simple case, no color specified*/
	if (!ifs2D->color) {
		visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state);
		visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
		return;
	}

	/*if default face use first color*/
	ci_count = ifs2D->coordIndex.count;
	pts = coord->point.vals;

	if (ci_count == 0) {
		col = (ifs2D->colorIndex.count > 0) ? color->color.vals[ifs2D->colorIndex.vals[0]] : color->color.vals[0];

		alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color)) / 255;
		if (!alpha || !ctx->aspect.pen_props.width) {
			alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255;
			ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
		} else {
			ctx->aspect.fill_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
		}
		visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state);
		visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
		return;
	}

	/*we have color per faces so we need N path :(*/
	if (! ifs2D->colorPerVertex) {
		path = gf_path_new();

		count = 0;
		i = 0;
		while (1) {
			gf_path_reset(path);
			start = pts[ifs2D->coordIndex.vals[i]];
			gf_path_add_move_to(path, start.x, start.y);
			i++;

			while (ifs2D->coordIndex.vals[i] != -1) {	
				start = pts[ifs2D->coordIndex.vals[i]];
				gf_path_add_line_to(path, start.x, start.y);
				i++;
				if (i >= ci_count) break;
			}
			/*close in ALL cases because even if the start/end points are the same the line join needs to be present*/
			gf_path_close(path);

			col = (ifs2D->colorIndex.count > 0) ? color->color.vals[ifs2D->colorIndex.vals[count]] : color->color.vals[count];

			alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color)) / 255;
			if (!alpha) {
				alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255;
				ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
			} else {
				ctx->aspect.fill_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
			}

			visual_2d_texture_path(tr_state->visual, path, ctx, tr_state);
			visual_2d_draw_path(tr_state->visual, path, ctx, NULL, NULL, tr_state);
			count++;
			i++;
			if (i >= ci_count) break;
			ctx->flags &= ~CTX_PATH_FILLED;
			ctx->flags &= ~CTX_PATH_STROKE;
		}
		gf_path_del(path);
		return;
	}

	/*final case, color per vertex means gradient fill/strike*/
	raster = tr_state->visual->compositor->rasterizer;
	grad = raster->stencil_new(raster, GF_STENCIL_VERTEX_GRADIENT);
	/*not supported, fill default*/
	if (!grad) {
		visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state);
		visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
		return;
	}


	path = gf_path_new();

	ind_col = 0;
	i = 0;
	while (1) {
		gf_path_reset(path);
		start = pts[ifs2D->coordIndex.vals[i]];
		center = start;
		gf_path_add_move_to(path, start.x, start.y);
		num_col = 1;
		i+=1;
		while (ifs2D->coordIndex.vals[i] != -1) {	
			end = pts[ifs2D->coordIndex.vals[i]];
			gf_path_add_line_to(path, end.x, end.y);
			i++;
			center.x += end.x;
			center.y += end.y;
			num_col ++;
			if (i >= ci_count) break;
		}
		gf_path_close(path);
		num_col++;

		alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color) ) / 255;

		colors = (u32*)gf_malloc(sizeof(u32) * num_col);
		col_cen.blue = col_cen.red = col_cen.green = 0;
		for (j=0; j<num_col-1; j++) {
			if (ifs2D->colorIndex.count > ind_col + j) {
				col = color->color.vals[ifs2D->colorIndex.vals[ind_col + j]];
			} else if (ci_count > ind_col + j) {
				col = color->color.vals[ifs2D->coordIndex.vals[ind_col + j]];
			}
			colors[j] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
			col_cen.blue += col.blue;
			col_cen.green += col.green;
			col_cen.red += col.red;
		}
		colors[num_col-1] = colors[0];

		if (ifs2D->colorIndex.count > ind_col) {
			col = color->color.vals[ifs2D->colorIndex.vals[ind_col]];
		} else if (ci_count > ind_col) {
			col = color->color.vals[ifs2D->coordIndex.vals[ind_col]];
		}
		col_cen.blue += col.blue;
		col_cen.green += col.green;
		col_cen.red += col.red;

		raster->stencil_set_vertex_path(grad, path);
		raster->stencil_set_vertex_colors(grad, colors, num_col);

		gf_free(colors);
		
		col_cen.blue /= num_col;
		col_cen.green /= num_col;
		col_cen.red /= num_col;
		center.x /= num_col;
		center.y /= num_col;
		raster->stencil_set_vertex_center(grad, center.x, center.y, GF_COL_ARGB_FIXED(alpha, col_cen.red, col_cen.green, col_cen.blue) );

		raster->stencil_set_matrix(grad, &ctx->transform);

		/*draw*/
		visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, grad, grad, tr_state);

		raster->stencil_delete(grad);

		//goto next point
		i++;
		ind_col += num_col + 1;	
		if (i >= ci_count) break;
		grad = raster->stencil_new(raster, GF_STENCIL_VERTEX_GRADIENT);
		ctx->flags &= ~CTX_PATH_FILLED;
		ctx->flags &= ~CTX_PATH_STROKE;
	}
	gf_path_del(path);
}