Example #1
0
static void SVG_Draw_bitmap(GF_TraverseState *tr_state)
{
	DrawableContext *ctx = tr_state->ctx;
	if (!tr_state->visual->DrawBitmap(tr_state->visual, tr_state, ctx, NULL)) {
		visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state);
	}
}
Example #2
0
static void layer3d_draw_2d(GF_Node *node, GF_TraverseState *tr_state)
{
	DrawableContext *ctx = tr_state->ctx;
	if (tr_state->visual->DrawBitmap(tr_state->visual, tr_state, ctx, NULL)) 
		return;

	visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state);
}
Example #3
0
void group_cache_draw(GroupCache *cache, GF_TraverseState *tr_state)
{
	GF_TextureHandler *old_txh = tr_state->ctx->aspect.fill_texture;
	/*switch the texture to our offscreen cache*/
	tr_state->ctx->aspect.fill_texture = &cache->txh;

	if (! tr_state->visual->DrawBitmap(tr_state->visual, tr_state, tr_state->ctx, NULL)) {
		visual_2d_texture_path(tr_state->visual, cache->drawable->path, tr_state->ctx, tr_state);
	}
	tr_state->ctx->aspect.fill_texture = old_txh;
}
Example #4
0
static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state)
{
	Background2DStack *stack;
	if (!ctx || !ctx->drawable || !ctx->drawable->node) return;
	stack = (Background2DStack *) gf_node_get_private(ctx->drawable->node);

	if (!ctx->bi->clip.width || !ctx->bi->clip.height) return;

	stack->flags &= ~CTX_PATH_FILLED;

	if (back_use_texture((M_Background2D *)ctx->drawable->node)) {

		if (!tr_state->visual->DrawBitmap(tr_state->visual, tr_state, ctx, NULL)) {
			/*set target rect*/
			gf_path_reset(stack->drawable->path);
			gf_path_add_rect_center(stack->drawable->path, 
								ctx->bi->unclip.x + ctx->bi->unclip.width/2,
								ctx->bi->unclip.y - ctx->bi->unclip.height/2,
								ctx->bi->unclip.width, ctx->bi->unclip.height);

			/*draw texture*/
			visual_2d_texture_path(tr_state->visual, stack->drawable->path, ctx, tr_state);
		}
		stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY);
	} else {
		
		/*direct drawing, draw without clippers */
		if (tr_state->immediate_draw) {
			/*directly clear with specified color*/
			tr_state->visual->ClearSurface(tr_state->visual, &ctx->bi->clip, ctx->aspect.fill_color);
		} else {
			u32 i;
			GF_IRect clip;
			for (i=0; i<tr_state->visual->to_redraw.count; i++) {
				/*there's an opaque region above, don't draw*/
#ifdef TRACK_OPAQUE_REGIONS
				if (tr_state->visual->draw_node_index<tr_state->visual->to_redraw.opaque_node_index[i]) continue;
#endif
				clip = ctx->bi->clip;
				gf_irect_intersect(&clip, &tr_state->visual->to_redraw.list[i]);
				if (clip.width && clip.height) {
					tr_state->visual->ClearSurface(tr_state->visual, &clip, ctx->aspect.fill_color);
				}
			}
		}
		stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY);
	}
	tr_state->visual->has_modif = 1;
}
Example #5
0
static void compositor_2d_draw_rectangle(GF_TraverseState *tr_state)
{
	DrawableContext *ctx = tr_state->ctx;

	if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->data
#ifndef GPAC_DISABLE_3D
	        && !tr_state->visual->compositor->hybrid_opengl
#endif
	   ) {
		Bool res;

		/*get image size WITHOUT line size or antialias margin*/
		if ( !(ctx->flags & CTX_NO_ANTIALIAS) ) {
			GF_Rect orig_unclip;
			GF_IRect orig_clip;
			orig_unclip = ctx->bi->unclip;
			orig_clip = ctx->bi->clip;

			gf_path_get_bounds(ctx->drawable->path, &ctx->bi->unclip);
			gf_mx2d_apply_rect(&ctx->transform, &ctx->bi->unclip);
			ctx->bi->clip = gf_rect_pixelize(&ctx->bi->unclip);
			gf_irect_intersect(&ctx->bi->clip, &orig_clip);

			res = tr_state->visual->DrawBitmap(tr_state->visual, tr_state, ctx, NULL);

			/*strike path*/
			ctx->bi->unclip = orig_unclip;
			ctx->bi->clip = orig_clip;
			if (res) {
				ctx->flags |= CTX_PATH_FILLED;
				visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
			}
		} else {
			res = tr_state->visual->DrawBitmap(tr_state->visual, tr_state, ctx, NULL);
		}
		/*if failure retry with raster*/
		if (res) return;
	}

	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);
}
Example #6
0
static void svg_traverse_filter(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	GF_FilterStack *st = gf_node_get_private(node);
	if (is_destroy) {
		drawable_del(st->drawable);
		if (st->data) gf_free(st->data);
		st->txh.data = NULL;
		gf_sc_texture_release(&st->txh);
		gf_sc_texture_destroy(&st->txh);
		gf_free(st);
		return;
	}

	if (tr_state->traversing_mode==TRAVERSE_DRAW_2D) {
		if (! tr_state->visual->DrawBitmap(tr_state->visual, tr_state, tr_state->ctx, NULL)) {
			visual_2d_texture_path(tr_state->visual, st->drawable->path, tr_state->ctx, tr_state);
		}
	}
}
Example #7
0
void group_cache_draw(GroupCache *cache, GF_TraverseState *tr_state)
{
	GF_TextureHandler *old_txh = tr_state->ctx->aspect.fill_texture;
	/*switch the texture to our offscreen cache*/
	tr_state->ctx->aspect.fill_texture = &cache->txh;


#ifndef GPAC_DISABLE_3D
	if (tr_state->traversing_mode == TRAVERSE_DRAW_3D) {
		if (!cache->drawable->mesh) {
			cache->drawable->mesh = new_mesh();
		}
		mesh_from_path(cache->drawable->mesh, cache->drawable->path);

		visual_3d_draw_2d(cache->drawable, tr_state);
		return;
	}
#endif

	if (! tr_state->visual->DrawBitmap(tr_state->visual, tr_state, tr_state->ctx, NULL)) {
		visual_2d_texture_path(tr_state->visual, cache->drawable->path, tr_state->ctx, tr_state);
	}
	tr_state->ctx->aspect.fill_texture = old_txh;
}
Example #8
0
static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state)
{
	Bool clear_all = GF_TRUE;
	u32 color;
	Bool use_texture;
	Bool is_offscreen = GF_FALSE;
	Background2DStack *stack;
	if (!ctx || !ctx->drawable || !ctx->drawable->node) return;
	stack = (Background2DStack *) gf_node_get_private(ctx->drawable->node);

	if (!ctx->bi->clip.width || !ctx->bi->clip.height) return;

	stack->flags &= ~CTX_PATH_FILLED;
	color = ctx->aspect.fill_color;

	use_texture = back_use_texture((M_Background2D *)ctx->drawable->node);
	if (!use_texture && !tr_state->visual->is_attached) {
		use_texture = 1;
		stack->txh.data = stack->col_tx;
		stack->txh.width = 2;
		stack->txh.height = 2;
		stack->txh.stride = 6;
		stack->txh.pixelformat = GF_PIXEL_RGB_24;
	}

	if (use_texture) {

		if (!tr_state->visual->DrawBitmap(tr_state->visual, tr_state, ctx)) {
			/*set target rect*/
			gf_path_reset(stack->drawable->path);
			gf_path_add_rect_center(stack->drawable->path,
			                        ctx->bi->unclip.x + ctx->bi->unclip.width/2,
			                        ctx->bi->unclip.y - ctx->bi->unclip.height/2,
			                        ctx->bi->unclip.width, ctx->bi->unclip.height);

			/*draw texture*/
			visual_2d_texture_path(tr_state->visual, stack->drawable->path, ctx, tr_state);
		}
		//a quick hack, if texture not ready return (we don't have direct notification of this through the above functions
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->compositor->hybrid_opengl && !stack->txh.tx_io) 
			return;
#endif

		stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY);
		tr_state->visual->has_modif = 1;
#ifndef GPAC_DISABLE_3D
		//in opengl auto mode we still have to clear the canvas
		if (!tr_state->immediate_draw && !tr_state->visual->offscreen && tr_state->visual->compositor->hybrid_opengl) {
			clear_all = GF_FALSE;
			is_offscreen = GF_TRUE;
			color &= 0x00FFFFFF;
		} else
#endif
			return;
	}


#ifndef GPAC_DISABLE_3D
	if (ctx->flags & CTX_BACKROUND_NOT_LAYER) {
		if (clear_all && !tr_state->visual->offscreen && tr_state->visual->compositor->hybrid_opengl) {
			compositor_2d_hybgl_clear_surface(tr_state->visual, NULL, color, GF_FALSE);
			is_offscreen = GF_TRUE;
			color &= 0x00FFFFFF;
			//we may need to clear the canvas for immediate mode
		}
	} else {
		is_offscreen = GF_TRUE;
	}
#endif
	/*direct drawing, draw without clippers */
	if (tr_state->immediate_draw
	   ) {
		/*directly clear with specified color*/
		if (clear_all)
			tr_state->visual->ClearSurface(tr_state->visual, &ctx->bi->clip, color, is_offscreen);
	} else {
		u32 i;
		GF_IRect clip;
		for (i=0; i<tr_state->visual->to_redraw.count; i++) {
			/*there's an opaque region above, don't draw*/
#ifdef TRACK_OPAQUE_REGIONS
			if (tr_state->visual->draw_node_index < tr_state->visual->to_redraw.list[i].opaque_node_index) continue;
#endif
			clip = ctx->bi->clip;
			gf_irect_intersect(&clip, &tr_state->visual->to_redraw.list[i].rect);
			if (clip.width && clip.height) {
				tr_state->visual->ClearSurface(tr_state->visual, &clip, color, is_offscreen);
			}
		}
	}
	stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY);
	tr_state->visual->has_modif = 1;
}
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);
}