static void visual_2d_fill_path(GF_VisualManager *visual, DrawableContext *ctx, GF_STENCIL stencil, GF_TraverseState *tr_state, Bool is_erase)
{
	Bool has_modif = GF_FALSE;
	GF_IRect clip;
	GF_Raster2D *raster = visual->compositor->rasterizer;

	/*background & direct drawing : use ctx clip*/
	if ((ctx->flags & CTX_IS_BACKGROUND) || tr_state->immediate_draw) {
		if (ctx->bi->clip.width && ctx->bi->clip.height) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (direct draw)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node) ));

			if (stencil) {
				raster->surface_set_clipper(visual->raster_surface, &ctx->bi->clip);
				raster->surface_fill(visual->raster_surface, stencil);
			} else {
				raster->surface_clear(visual->raster_surface, &ctx->bi->clip, 0);
			}

			has_modif = GF_TRUE;
		}
	}
	/*indirect drawing, draw path in all dirty areas*/
	else {
		u32 i;
		for (i=0; i<visual->to_redraw.count; i++) {
			/*there's an opaque region above, don't draw*/
#ifdef TRACK_OPAQUE_REGIONS
			if (!is_erase && (visual->draw_node_index<visual->to_redraw.list[i].opaque_node_index)) continue;
#endif
			clip = ctx->bi->clip;
			gf_irect_intersect(&clip, &visual->to_redraw.list[i].rect);
			if (clip.width && clip.height) {
				GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (indirect draw @ dirty rect idx %d)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node), i));
				if (stencil) {
					raster->surface_set_clipper(visual->raster_surface, &clip);
					raster->surface_fill(visual->raster_surface, stencil);
				} else {
					raster->surface_clear(visual->raster_surface, &clip, 0);
				}
				has_modif = 1;
			}
		}
	}
#ifndef GPAC_DISABLE_3D
	if (!is_erase)
		visual->nb_objects_on_canvas_since_last_ogl_flush++;
#endif
	if (has_modif) {
		visual->has_modif = 1;
#ifndef GPAC_DISABLE_3D
		if (!visual->offscreen && visual->compositor->hybrid_opengl && !is_erase)
			ra_union_rect(&visual->hybgl_drawn, &ctx->bi->clip);
#endif
	}
}
Example #2
0
static void visual_2d_fill_path(GF_VisualManager *visual, DrawableContext *ctx, GF_STENCIL stencil, GF_TraverseState *tr_state)
{
	GF_IRect clip;
	GF_Raster2D *raster = visual->compositor->rasterizer;

	/*background & direct drawing : use ctx clip*/
	if ((ctx->flags & CTX_IS_BACKGROUND) || tr_state->immediate_draw) {
		if (ctx->bi->clip.width && ctx->bi->clip.height) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (direct draw)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node) ));

			if (stencil) {
				raster->surface_set_clipper(visual->raster_surface, &ctx->bi->clip);
				raster->surface_fill(visual->raster_surface, stencil);
			} else {
				raster->surface_clear(visual->raster_surface, &ctx->bi->clip, 0);
			}

			visual->has_modif = 1;
		}
	}
	/*indirect drawing, draw path in all dirty areas*/
	else {
		u32 i;
		for (i=0; i<visual->to_redraw.count; i++) {
			/*there's an opaque region above, don't draw*/
#ifdef TRACK_OPAQUE_REGIONS
			if (visual->draw_node_index<visual->to_redraw.opaque_node_index[i]) continue;
#endif
			clip = ctx->bi->clip;
			gf_irect_intersect(&clip, &visual->to_redraw.list[i]);
			if (clip.width && clip.height) {
				GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (indirect draw @ dirty rect idx %d)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node), i));
				if (stencil) {
					raster->surface_set_clipper(visual->raster_surface, &clip);
					raster->surface_fill(visual->raster_surface, stencil);
				} else {
					raster->surface_clear(visual->raster_surface, &clip, 0);
				}
				visual->has_modif = 1;
			}
		}
	}
}
void visual_2d_draw_path_extended(GF_VisualManager *visual, GF_Path *path, DrawableContext *ctx, GF_STENCIL brush, GF_STENCIL pen, GF_TraverseState *tr_state, GF_Rect *orig_bounds, GF_Matrix2D *ext_mx, Bool is_erase)
{
	Bool dofill, dostrike;
	GF_Raster2D *raster = visual->compositor->rasterizer;
#ifdef SKIP_DRAW
	return;
#endif
	if (! visual->CheckAttached(visual) ) return;

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

	if (! (ctx->flags & CTX_IS_BACKGROUND) )
		visual_2d_set_options(visual->compositor, visual->raster_surface, ctx->flags & CTX_IS_TEXT, ctx->flags & CTX_NO_ANTIALIAS);

	dofill = dostrike = 0;
	if (!(ctx->flags & CTX_PATH_FILLED) && (is_erase || GF_COL_A(ctx->aspect.fill_color)) ) {
		dofill = 1;
		if (!brush) {
			brush = visual->raster_brush;
			raster->stencil_set_brush_color(brush, ctx->aspect.fill_color);
		}
	}


	/*compute width based on transform and top_level transform*/
	if (!(ctx->flags & CTX_PATH_STROKE) && ctx->aspect.pen_props.width) {
		dostrike = 1;
	} else if (!dofill) {
		return;
	}

	/*set path transform, except for background2D node which is directly build in the final coord system*/
	raster->surface_set_matrix(visual->raster_surface, (ctx->flags & CTX_IS_BACKGROUND) ? NULL : &ctx->transform);

	/*fill path*/
	if (dofill) {
#if ADAPTATION_SIZE
		if ((ctx->bi->clip.width<ADAPTATION_SIZE) && (ctx->bi->clip.height<ADAPTATION_SIZE)) {
			raster->surface_clear(visual->raster_surface, &ctx->bi->clip, ctx->aspect.fill_color);
		} else
#endif
		{
			/*push path*/
			raster->surface_set_path(visual->raster_surface, path);
			visual_2d_fill_path(visual, ctx, brush, tr_state, is_erase);
			raster->surface_set_path(visual->raster_surface, NULL);
		}
	}

	if (dostrike) {
#if ADAPTATION_SIZE
		if ((ctx->bi->clip.width<ADAPTATION_SIZE) && (ctx->bi->clip.height<ADAPTATION_SIZE)) {
		} else
#endif
		{
			StrikeInfo2D *si;

			if (!pen) {
				pen = visual->raster_brush;
				raster->stencil_set_brush_color(pen, ctx->aspect.line_color);
			}

			si = drawable_get_strikeinfo(visual->compositor, ctx->drawable, &ctx->aspect, ctx->appear, path, ctx->flags, NULL);
			if (si && si->outline) {
				if (ctx->aspect.line_texture) {
					visual_2d_texture_path_extended(visual, si->outline, ctx->aspect.line_texture, ctx, orig_bounds, ext_mx, tr_state);
				} else {
					raster->surface_set_path(visual->raster_surface, si->outline);
					visual_2d_fill_path(visual, ctx, pen, tr_state, 0);
				}
				/*that's ugly, but we cannot cache path outline for IFS2D/ILS2D*/
				if (path && !(ctx->flags & CTX_IS_TEXT) && (path!=ctx->drawable->path) ) {
					gf_path_del(si->outline);
					si->outline = NULL;
				}
			}
//			drawable_reset_path_outline(ctx->drawable);
		}
	}

	if (visual->compositor->draw_bvol) draw_clipper(visual, ctx);
}