⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smil_anim.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* we still need to apply additive/replace behavior even when frozen 	   because we don't know how many other animations have run during this cycle,	   on this attribute, before the current one, which might have changed the underlying value. */	if (animp->additive && *animp->additive == SMIL_ADDITIVE_SUM) {		if (rai->owner->presentation_value_changed || rai->interpolated_value_changed) {					GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Animation] Time %f - Animation     %s - applying additive freeze behavior\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_name((GF_Node *)rai->anim_elt)));			if (rai->is_first_anim) gf_svg_attributes_add(&rai->owner->specified_value, &rai->interpolated_value, &rai->owner->presentation_value, 1);			else gf_svg_attributes_add(&rai->owner->presentation_value, &rai->interpolated_value, &rai->owner->presentation_value, 1);			rai->owner->presentation_value_changed = 1;		} else {			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Animation] Time %f - Animation     %s - applying additive freeze behavior (nothing done)\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_name((GF_Node *)rai->anim_elt)));		}	} else {		if (rai->interpolated_value_changed) {			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Animation] Time %f - Animation     %s - applying freeze behavior\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_name((GF_Node *)rai->anim_elt)));			gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->interpolated_value, 1);			rai->owner->presentation_value_changed = 1;		} else {			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Animation] Time %f - Animation     %s - applying freeze behavior (nothing done)\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_name((GF_Node *)rai->anim_elt)));						rai->owner->presentation_value_changed = 0;		}	}	if (rti->cycle_number == rti->first_frozen)			gf_smil_anim_reset_variables(rai);}static void gf_smil_anim_remove(SMIL_Timing_RTI *rti, Fixed normalized_simple_time){	SMIL_Anim_RTI *rai = gf_smil_anim_get_anim_runtime_from_timing(rti);	if (!rai) return;	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Animation] Time %f - Animation     %s - applying remove behavior\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_name((GF_Node *)rai->anim_elt)));	gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->owner->specified_value, 0);	rai->owner->presentation_value_changed = 1;	gf_smil_anim_reset_variables(rai);}static void gf_smil_anim_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time, u32 state){	switch (state) {	case SMIL_TIMING_EVAL_UPDATE: 	case SMIL_TIMING_EVAL_REPEAT:		gf_smil_anim_animate(rti, normalized_simple_time);		break;	case SMIL_TIMING_EVAL_FREEZE: 		gf_smil_anim_freeze(rti, normalized_simple_time);		break;	case SMIL_TIMING_EVAL_REMOVE: 		gf_smil_anim_remove(rti, normalized_simple_time);		break;	case SMIL_TIMING_EVAL_FRACTION: 		gf_smil_anim_animate_with_fraction(rti, normalized_simple_time);		break;/*	discard should be done before in smil_notify_time	case SMIL_TIMING_EVAL_DISCARD:		break;*/	}}/************************************************************************************** **************************************************************************************/GF_EXPORTvoid gf_svg_apply_animations(GF_Node *node, SVGPropertiesPointers *render_svg_props){	u32 count_all, i;	/* Perform all the animations on this node */	count_all = gf_node_animation_count(node);	for (i = 0; i < count_all; i++) {		u32 j, count;		u32 nb_active_animations;		SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(node, i);				count = gf_list_count(aa->anims);		if (!count) continue;			aa->presentation_value_changed = 0;		nb_active_animations = 0;		if (aa->is_property) {			/* Storing the pointer to the parent presentation value, 			   i.e. the presentation value issued at the parent level in the tree */			aa->parent_presentation_value = aa->presentation_value;			if ((node->sgprivate->tag>=GF_NODE_RANGE_FIRST_SVG) && (node->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG)) {				aa->parent_presentation_value.far_ptr = gf_svg_get_property_pointer((SVG_Element *)node, aa->orig_dom_ptr, render_svg_props); 			} #ifdef GPAC_ENABLE_SVG_SA			else if ((node->sgprivate->tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (node->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG_SA)) {				aa->parent_presentation_value.far_ptr = gf_svg_sa_get_property_pointer(render_svg_props, 																					((SVG_SA_Element*)node)->properties,																					aa->orig_dom_ptr);			}#endif			/* Storing also the pointer to the presentation value of the color property 			   (special handling of the keyword 'currentColor' if used in animation values) */			aa->current_color_value.fieldType = SVG_Paint_datatype;			if ((node->sgprivate->tag>=GF_NODE_RANGE_FIRST_SVG) && (node->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG)) {				GF_FieldInfo info;				gf_svg_get_attribute_by_tag(node, TAG_SVG_ATT_color, 1, 1, &info);				aa->current_color_value.far_ptr = info.far_ptr;			} #ifdef GPAC_ENABLE_SVG_SA			else if ((node->sgprivate->tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (node->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG_SA)) {				aa->current_color_value.far_ptr = &((SVG_SA_Element*)node)->properties->color;			} #endif		}		/* Performing all the animations targetting the given attribute */		for (j = 0; j < count; j++) {			Double scene_time;			SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j);						SMIL_Timing_RTI *rti = rai->timingp->runtime;			if (j == 0) rai->is_first_anim = 1;			//scene_time = gf_node_get_scene_time(node);			scene_time = rti->scene_time;			if (rti->evaluate_status) {				Fixed simple_time = gf_smil_timing_get_normalized_simple_time(rti, scene_time);				rti->evaluate(rti, simple_time, rti->evaluate_status);				nb_active_animations++;			}		}		if (nb_active_animations) {			if (aa->presentation_value_changed) {				GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SMIL Animation] Time %f - Element %s - Presentation value changed for attribute %s\n", gf_node_get_scene_time(node), gf_node_get_name(node), gf_svg_get_attribute_name(aa->presentation_value.fieldIndex)));				gf_node_dirty_set(node, aa->dirty_flags, 0);			} else {				/* WARNING - This does not work for use elements because apply_animations may be called several times */				gf_node_dirty_clear(node, aa->dirty_flags);			}		}	}}#ifdef GPAC_ENABLE_SVG_SANIGF_EXPORTvoid gf_svg_sani_apply_animations(GF_Node *node){	u32 count_all, i;	/*TODO FIXME - THIS IS WRONG, we're changing orders of animations which may corrupt the visual result*/	/* Perform all the animations on this node */	count_all = gf_node_animation_count(node);	for (i = 0; i < count_all; i++) {		/* Performing the animations for a given animated attribute */		u32 j, count;				SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(node, i);				count = gf_list_count(aa->anims);		if (!count) continue;			aa->presentation_value_changed = 0;		for (j = 0; j < count; j++) {			SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j);						SMIL_Timing_RTI *rti = ((SVG_SANI_Element *)rai->anim_elt)->timingp->runtime;			//Double scene_time = gf_node_get_scene_time(node);			Double scene_time = rti->scene_time;			if (j == 0) rai->is_first_anim = 1;			if (rti->evaluate_status) {				Fixed simple_time = gf_smil_timing_get_normalized_simple_time(rti, scene_time);				rti->evaluate(rti, simple_time, rti->evaluate_status);			}		}		if (aa->presentation_value_changed) {			gf_node_dirty_set(node, aa->dirty_flags, 0);		}	}}#elseGF_EXPORTvoid gf_svg_sani_apply_animations(GF_Node *node){}#endifvoid gf_smil_anim_init_runtime_info(GF_Node *e){	u32 i;	GF_FieldInfo target_attribute;	SMIL_AttributeAnimations *aa = NULL;	SMIL_Anim_RTI *rai;	XLinkAttributesPointers *xlinkp = NULL;	SMILAnimationAttributesPointers *animp = NULL;	SMILTimingAttributesPointers *timingp = NULL;	GF_Node *target = NULL;	u32 tag;	/* Filling animation structures to be independent of the SVG Element structure */	tag = gf_node_get_tag(e);	if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) {		animp = ((SVGTimedAnimBaseElement *)e)->animp;		timingp = ((SVGTimedAnimBaseElement *)e)->timingp;		xlinkp = ((SVGTimedAnimBaseElement *)e)->xlinkp;	} #ifdef GPAC_ENABLE_SVG_SA	else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) {		animp = ((SVG_SA_Element *)e)->animp;		timingp = ((SVG_SA_Element *)e)->timingp;		xlinkp = ((SVG_SA_Element *)e)->xlinkp;	} #endif#ifdef GPAC_ENABLE_SVG_SANI	else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) {		animp = ((SVG_SANI_Element *)e)->animp;		timingp = ((SVG_SANI_Element *)e)->timingp;		xlinkp = ((SVG_SANI_Element *)e)->xlinkp;	} #endif	else {		return;	}	/* from this point, the animation node 'e' should not be used */	target = xlinkp->href->target;	memset(&target_attribute, 0, sizeof(GF_FieldInfo));	if (animp->attributeName && (animp->attributeName->name || animp->attributeName->tag)) {		/* Filling the target_attribute structure with info on the animated attribute (type, pointer to data, ...)		NOTE: in the mode Dynamic Allocation of Attributes, this means that the animated 		attribute is created with a default value, if it was not specified on the target element */		if (animp->attributeName->tag) {			gf_svg_get_attribute_by_tag(target, animp->attributeName->tag, 1, 1, &target_attribute);		} else {			gf_node_get_field_by_name(target, animp->attributeName->name, &target_attribute);		}	} else {		/* All animation elements should have a target attribute except for animateMotion		cf http://www.w3.org/mid/u403c21ajf1sjqtk58g0g38eaep9f9g2ss@hive.bjoern.hoehrmann.de		"For animateMotion, the attributeName is implied and cannot be specified; 		animateTransform requires specification of the attribute name and any attribute that is		a transform-like attribute can be a target, e.g. gradientTransform."*/		switch (tag) {#ifdef GPAC_ENABLE_SVG_SA_BASE#ifdef GPAC_ENABLE_SVG_SA		case TAG_SVG_SA_animateMotion:#endif#ifdef GPAC_ENABLE_SVG_SANI		case TAG_SVG_SANI_animateMotion:#endif		{			SVGTransformableElement *tr_e = (SVGTransformableElement *)target;			if (!tr_e->motionTransform) {				tr_e->motionTransform = (GF_Matrix2D*)malloc(sizeof(GF_Matrix2D));				gf_mx2d_init(*tr_e->motionTransform);			}			gf_node_get_field_by_name((GF_Node *)tr_e, "motionTransform", &target_attribute);		}			break;#endif		case TAG_SVG_animateMotion:			/* Explicit creation of the pseudo 'motionTransform' attribute since it cannot be specified */			gf_svg_get_attribute_by_tag(target, TAG_SVG_ATT_motionTransform, 1, 0, &target_attribute);			gf_mx2d_init(*(GF_Matrix2D *)target_attribute.far_ptr);			break;		default:			GF_LOG(GF_LOG_WARNING, GF_LOG_COMPOSE, ("[SMIL Animation] Missing attributeName attribute on element %s\n", gf_node_get_name((GF_Node*)e) ));			return;		}	}	if ((!animp->values || !gf_list_count(animp->values->values)) && /* 'values' attribute not specified */		(!animp->to || animp->to->type == 0) &&						 /* 'to' attribute not specified */		(!animp->from || animp->from->type == 0) &&					 /* 'from' attribute not specified */		(animp->by && animp->by->type != 0)) {						 /* 'by' attribute specified */				/* if this is a 'by' animation without from the animation is defined to be additive		   see http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#AnimationNS-FromToBy		   we override the additive attribute */		if (!animp->additive) { 			/* this case can only happen with dynamic allocation of attributes */			GF_FieldInfo info;			gf_svg_get_attribute_by_tag(e, TAG_SVG_ATT_additive, 1, 0, &info);			animp->additive = info.far_ptr;		}		*animp->additive = SMIL_ADDITIVE_SUM;	} 	/*TODO 	http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation		To animation defines its own kind of additive semantics, so the additive attribute is ignored.	*/	/*TODO 	http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation		Because to animation is defined in terms of absolute values of the target attribute, 		cumulative animation is not defined:	*/	/* TODO 	http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-setElement	The set element is non-additive. The additive and accumulate attributes are not allowed, 	and will be ignored if specified.	*/		/* Creation and setup of the runtime structure for animation */	GF_SAFEALLOC(rai, SMIL_Anim_RTI)	rai->anim_elt = e;		rai->animp = animp;	rai->timingp = timingp;	rai->xlinkp = xlinkp;	gf_mx2d_init(rai->identity);	rai->default_transform_value.far_ptr = &rai->identity;	rai->default_transform_value.fieldType = SVG_Transform_datatype;	/* the interpolated value has the same type as the target attribute,	   but we need to create a new pointer to hold its value */	rai->interpolated_value = target_attribute;	rai->interpolated_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType);	/* there has not been any interpolation yet, so the previous key index and interpolation coefficient	   shall not be set*/	rai->previous_key_index = -1;	rai->previous_coef = -1;	/* For animateMotion, we need to retrieve the value of the rotate attribute, retrieve the path either	from the 'path' attribute or from the 'mpath' element, and then initialize the path iterator*/	if ((tag == TAG_SVG_animateMotion)#ifdef GPAC_ENABLE_SVG_SA		|| (tag == TAG_SVG_SA_animateMotion)#endif#ifdef GPAC_ENABLE_SVG_SANI		|| (tag == TAG_SVG_SANI_animateMotion)#endif		) {		GF_Path *the_path = NULL;		GF_ChildNodeItem *child = NULL;#ifdef GPAC_ENABLE_SVG_SA		if (tag == TAG_SVG_SA_animateMotion) {			SVG_SA_animateMotionElement *am = (SVG_SA_animateMotionElement *)e;			rai->rotate = am->rotate.type;			the_path = &am->path;			child = am->children;		} else #endif#ifdef GPAC_ENABLE_SVG_SANI		if (tag == TAG_SVG_SANI_animateMotion) {			SVG_SANI_animateMotionElement *am = (SVG_SANI_animateMotionElement *)e;			rai->rotate = am->rotate.type;			the_path = &am->path;			child = am->children;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -