Example #1
0
static void svg_animation_smil_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_scene_time, u32 status)
{
	GF_Node *node = gf_smil_get_element(rti);
	SVGlinkStack *stack = gf_node_get_private(node);
	switch (status) {
	case SMIL_TIMING_EVAL_UPDATE:
		svg_animation_smil_update(node, stack, normalized_scene_time);
		break;
	case SMIL_TIMING_EVAL_FREEZE:
		if (stack->resource) {
			gf_mo_stop(stack->resource);
			stack->needs_play = 1;
		}
		break;
	case SMIL_TIMING_EVAL_REMOVE:
		if (stack->resource) {
			svg_reset_xlink_target(node);
			gf_mo_unload_xlink_resource(node, stack->resource);
			stack->resource = NULL;
			stack->fragment_id = NULL;
			stack->inline_sg = NULL;
			gf_node_dirty_set(node, GF_SG_SVG_XLINK_HREF_DIRTY, 0);
		}
		break;
	case SMIL_TIMING_EVAL_REPEAT:
		if (stack->resource) {
			svg_reset_xlink_target(node);
			stack->fragment_id = NULL;
			stack->inline_sg = NULL;
			gf_mo_restart(stack->resource);
		}
		break;
	}
}
Example #2
0
static void svg_animation_smil_update(GF_Node *node, SVGlinkStack *stack, Fixed normalized_scene_time)
{
	if (stack->init_vis_state == 3) {
		stack->init_vis_state = 4;
		gf_mo_resume(stack->resource);
	} else if (stack->needs_play || (gf_node_dirty_get(node) & GF_SG_SVG_XLINK_HREF_DIRTY )) {
		SVGAllAttributes all_atts;
		Double clipBegin, clipEnd;
		GF_MediaObject *new_res;
		gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);
		clipBegin = all_atts.clipBegin ? *all_atts.clipBegin : 0;
		clipEnd = all_atts.clipEnd ? *all_atts.clipEnd : -1;

		if (stack->needs_play) {
			gf_mo_play(stack->resource, clipBegin, clipEnd, 0);
			stack->needs_play = 0;
		} else {            
            Bool primary = all_atts.gpac_useAsPrimary ? *all_atts.gpac_useAsPrimary : 1;
            new_res = gf_mo_load_xlink_resource(node, primary, clipBegin, clipEnd);
			if (new_res != stack->resource) {
				if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource);
				if (all_atts.xlink_href) all_atts.xlink_href->target = NULL;
				stack->resource = new_res;
				stack->fragment_id = NULL;
				stack->inline_sg = NULL;
			}
			gf_node_dirty_clear(node, 0);
		}
	}
}
Example #3
0
static void svg_traverse_font_face_uri(GF_Node *node, void *rs, Bool is_destroy)
{
	if (is_destroy) {
		FontURIStack *st = gf_node_get_private(node);
		if (st) {
			gf_font_manager_unregister_font(st->font->ft_mgr, st->font);
			if (st->font->name) gf_free(st->font->name);
			gf_free(st->font);
			if (st->mo) gf_mo_unload_xlink_resource(node, st->mo);
			gf_free(st);
		}
	}
}
Example #4
0
static void svg_traverse_resource(GF_Node *node, void *rs, Bool is_destroy, Bool is_foreign_object)
{
	GF_Matrix2D backup_matrix;
	GF_Matrix mx_3d;
  	GF_Matrix2D translate;
	SVGPropertiesPointers backup_props;
	u32 backup_flags, dirty;
	Bool is_fragment;
	GF_Node *used_node;
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	SVGAllAttributes all_atts;
	SVGlinkStack *stack = gf_node_get_private(node);
	SFVec2f prev_vp;
	SVG_Number *prev_opacity;

	if (is_destroy) {
		if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource);
		gf_free(stack);
		return;
	}


	gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);
	if (!all_atts.xlink_href) return;

	if (!compositor_svg_traverse_base(node, &all_atts, tr_state, &backup_props, &backup_flags))
		return;

	dirty = gf_node_dirty_get(node);
	if (dirty & GF_SG_CHILD_DIRTY) drawable_reset_group_highlight(tr_state, node);

	if (dirty & GF_SG_SVG_XLINK_HREF_DIRTY) {
		stack->fragment_id = NULL;
		stack->inline_sg = NULL;
		if (all_atts.xlink_href->string && (all_atts.xlink_href->string[0]=='#')) {
			stack->fragment_id = all_atts.xlink_href->string;
			stack->inline_sg = gf_node_get_graph(node);
		} else {
			GF_MediaObject *new_res = gf_mo_load_xlink_resource(node, is_foreign_object, 0, -1);
			if (new_res != stack->resource) {
				if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource);
				stack->resource = new_res;
			}
		}
	}
	gf_node_dirty_clear(node, 0);

	/*locate the used node - this is done at each step to handle progressive loading*/
	is_fragment = 0;
	used_node = NULL;
	if (!stack->inline_sg && !stack->fragment_id && all_atts.xlink_href) {
		if (all_atts.xlink_href->type == XMLRI_ELEMENTID) {
			used_node = all_atts.xlink_href->target;
			is_fragment = 1;
		} else if (stack->resource) {
			stack->inline_sg = gf_mo_get_scenegraph(stack->resource);
			if (!is_foreign_object) {
				stack->fragment_id = strchr(all_atts.xlink_href->string, '#');
			}
		}
	}
	if (!used_node && stack->inline_sg) {
		if (stack->fragment_id) {
			used_node = gf_sg_find_node_by_name(stack->inline_sg, (char *) stack->fragment_id+1);
			is_fragment = 1;
		} else if (is_foreign_object) {
			used_node = gf_sg_get_root_node(stack->inline_sg);
		}
	}
	if (!used_node) goto end;

	/*stack use nodes for picking*/
	gf_list_add(tr_state->use_stack, used_node);
	gf_list_add(tr_state->use_stack, node);

	gf_mx2d_init(translate);
	translate.m[2] = (all_atts.x ? all_atts.x->value : 0);
	translate.m[5] = (all_atts.y ? all_atts.y->value : 0);

	/*update VP size (SVG 1.1)*/
	prev_vp = tr_state->vp_size;
	if (all_atts.width && all_atts.height) {
		tr_state->vp_size.x = gf_sc_svg_convert_length_to_display(tr_state->visual->compositor, all_atts.width);
		tr_state->vp_size.y = gf_sc_svg_convert_length_to_display(tr_state->visual->compositor, all_atts.height);
	}

	prev_opacity = tr_state->parent_use_opacity;
	tr_state->parent_use_opacity = all_atts.opacity;

	if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) {
		compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d);
		if (!compositor_svg_is_display_off(tr_state->svg_props)) {
			gf_node_traverse(used_node, tr_state);
			gf_mx2d_apply_rect(&translate, &tr_state->bounds);
		} 
		compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d);
	}
	/*SORT mode and visible, traverse*/
	else if (!compositor_svg_is_display_off(tr_state->svg_props) 
		&& (*(tr_state->svg_props->visibility) != SVG_VISIBILITY_HIDDEN)) {

		compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d);

#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) {
			gf_mx_add_matrix_2d(&tr_state->model_matrix, &translate);

			if (tr_state->traversing_mode==TRAVERSE_SORT) {
				GF_Matrix tmp;
				gf_mx_from_mx2d(&tmp, &translate);
				visual_3d_matrix_add(tr_state->visual, tmp.m);
			}
		} else 
#endif
			gf_mx2d_pre_multiply(&tr_state->transform, &translate);


		drawable_check_focus_highlight(node, tr_state, NULL);
		if (is_fragment) {
			gf_node_traverse(used_node, tr_state);
		} else {
			gf_sc_traverse_subscene(tr_state->visual->compositor, node, stack->inline_sg, tr_state);
		}
		compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d);  

	}
	gf_list_rem_last(tr_state->use_stack);
	gf_list_rem_last(tr_state->use_stack);
	tr_state->vp_size = prev_vp;

	tr_state->parent_use_opacity = prev_opacity;

end:
	memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers));
	tr_state->svg_flags = backup_flags;
}
Example #5
0
static void svg_traverse_animation(GF_Node *node, void *rs, Bool is_destroy)
{
	SVGAllAttributes all_atts;
	GF_Matrix2D backup_matrix;
	GF_Matrix backup_matrix3d;
	SVGPropertiesPointers backup_props;
	u32 backup_flags;
	SFVec2f prev_vp;
	GF_Rect rc;
	GF_IRect clip, prev_clip;
	SVGAllAttributes *prev_vp_atts;
	GF_TraverseState *tr_state = (GF_TraverseState*)rs;
  	GF_Matrix2D translate;
	SVGPropertiesPointers *old_props;
	SVGlinkStack *stack = gf_node_get_private(node);

	if (is_destroy) {
		if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource);
		gf_free(stack);
		return;
	}
	gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);


	if (!stack->inline_sg && !stack->resource) {
		if (!stack->init_vis_state) {
			if (all_atts.initialVisibility && (*all_atts.initialVisibility==SVG_INITIALVISIBILTY_ALWAYS)) {
				stack->init_vis_state = 2;
				svg_animation_smil_update(node, stack, 0);
			} else {
				stack->init_vis_state = 1;
			}
		}
		if (!stack->inline_sg && !stack->resource)
			return;
	}

	if (!all_atts.width || !all_atts.height) return;
	if (!all_atts.width->value || !all_atts.height->value) return;

	if (!compositor_svg_traverse_base(node, &all_atts, tr_state, &backup_props, &backup_flags))
		return;
	
	if (compositor_svg_is_display_off(tr_state->svg_props) ||
		*(tr_state->svg_props->visibility) == SVG_VISIBILITY_HIDDEN) {
		goto end;
	}

	compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &backup_matrix3d);

	/*add x/y translation*/
	gf_mx2d_init(translate);
	translate.m[2] = (all_atts.x ? all_atts.x->value : 0);
	translate.m[5] = (all_atts.y ? all_atts.y->value : 0);
#ifndef GPAC_DISABLE_3D
	if (tr_state->visual->type_3d) {
		gf_mx_add_matrix_2d(&tr_state->model_matrix, &translate);

		if (tr_state->traversing_mode==TRAVERSE_SORT) {
			GF_Matrix tmp;
			gf_mx_from_mx2d(&tmp, &translate);
			visual_3d_matrix_add(tr_state->visual, tmp.m);
		}
	} else 
#endif
		gf_mx2d_pre_multiply(&tr_state->transform, &translate);

	/*reset SVG props to reload a new inheritance context*/
	old_props = tr_state->svg_props;
	tr_state->svg_props = NULL;
	
	/*store this node's attribute to compute PAR/ViewBox of the child <svg>*/
	prev_vp_atts = tr_state->parent_anim_atts;
	tr_state->parent_anim_atts = &all_atts;

	/*update VP size*/
	prev_vp = tr_state->vp_size;

	tr_state->vp_size.x = gf_sc_svg_convert_length_to_display(tr_state->visual->compositor, all_atts.width);
	tr_state->vp_size.y = gf_sc_svg_convert_length_to_display(tr_state->visual->compositor, all_atts.height);

	/*setup new clipper*/
	rc.width = tr_state->vp_size.x;
	rc.height = tr_state->vp_size.y;
	rc.x = 0;
	rc.y = tr_state->vp_size.y;
	gf_mx2d_apply_rect(&tr_state->transform, &rc);
	prev_clip = tr_state->visual->top_clipper;
	clip = gf_rect_pixelize(&rc);
//	gf_irect_intersect(&tr_state->visual->top_clipper, &clip);

	if (!stack->inline_sg && stack->resource) {
		stack->inline_sg = gf_mo_get_scenegraph(stack->resource);
	}

	if (stack->inline_sg) {
		gf_sc_traverse_subscene(tr_state->visual->compositor, node, stack->inline_sg, tr_state);
	}

	if (stack->init_vis_state == 2) {
		stack->init_vis_state = 3;
		gf_mo_pause(stack->resource);
	}

	tr_state->svg_props = old_props;
	tr_state->visual->top_clipper = prev_clip;

	tr_state->parent_anim_atts = prev_vp_atts;
	tr_state->vp_size = prev_vp;

	compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &backup_matrix3d);  

end:
	memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers));
	tr_state->svg_flags = backup_flags;
}