📄 smil_anim.c
字号:
} else #endif { GF_FieldInfo info; if (gf_svg_get_attribute_by_tag(e, TAG_SVG_ATT_rotate, 0, 0, &info) == GF_OK) { rai->rotate = ((SVG_Rotate *)info.far_ptr)->type; } else { rai->rotate = SVG_NUMBER_VALUE; } if (gf_svg_get_attribute_by_tag(e, TAG_SVG_ATT_path, 0, 0, &info) == GF_OK) { the_path = ((SVG_PathData *)info.far_ptr); } child = ((SVG_Element *)e)->children; } if ((!animp->to || animp->to->type == 0) && (!animp->by || animp->by->type == 0) && (!animp->values || animp->values->type == 0)) {#if USE_GF_PATH if (!gf_path_is_empty(the_path)) { rai->path = the_path; rai->path_iterator = gf_path_iterator_new(rai->path); rai->length = gf_path_iterator_get_length(rai->path_iterator); } #else rai->path = gf_path_new(); if (gf_list_count(the_path->points)) { gf_svg_path_build(rai->path, the_path->commands, the_path->points); rai->path_iterator = gf_path_iterator_new(rai->path); rai->length = gf_path_iterator_get_length(rai->path_iterator); } #endif else { while (child) { GF_Node *used_path = NULL; u32 child_tag = gf_node_get_tag(child->node);#ifdef GPAC_ENABLE_SVG_SA if (child_tag == TAG_SVG_SA_mpath) { SVG_SA_mpathElement *mpath = (SVG_SA_mpathElement *)child->node; if (mpath->xlink->href.target) used_path = (GF_Node *)mpath->xlink->href.target; else if (mpath->xlink->href.iri) used_path = (GF_Node *)gf_sg_find_node_by_name(gf_node_get_graph((GF_Node *)mpath), mpath->xlink->href.iri); if (used_path && gf_node_get_tag(used_path) == TAG_SVG_SA_path) { SVG_SA_pathElement *used_path_elt = (SVG_SA_pathElement *)used_path;#if USE_GF_PATH rai->path = &used_path_elt->d;#else gf_svg_path_build(rai->path, used_path_elt->d.commands, used_path_elt->d.points);#endif rai->path_iterator = gf_path_iterator_new(rai->path); rai->length = gf_path_iterator_get_length(rai->path_iterator); } break; } else #endif if (child_tag == TAG_SVG_mpath) { GF_FieldInfo info; if (gf_svg_get_attribute_by_tag(child->node, TAG_SVG_ATT_xlink_href, 0, 0, &info) == GF_OK) { XMLRI *iri = (XMLRI *)info.far_ptr; if (iri->target) used_path = iri->target; else if (iri->string) used_path = (GF_Node *)gf_sg_find_node_by_name(gf_node_get_graph(child->node), iri->string); if (used_path && gf_node_get_tag(used_path) == TAG_SVG_path) { gf_svg_get_attribute_by_tag(used_path, TAG_SVG_ATT_d, 1, 0, &info);#if USE_GF_PATH rai->path = (SVG_PathData *)info.far_ptr;#else gf_svg_path_build(rai->path, ((SVG_PathData *)info.far_ptr)->commands, ((SVG_PathData *)info.far_ptr)->points);#endif rai->path_iterator = gf_path_iterator_new(rai->path); rai->length = gf_path_iterator_get_length(rai->path_iterator); } } break; } child = child->next; } } } } /* for all animations, check if there is already one animation on this attribute, if yes, get the list and append the new animation runtime info if no, create a list and add the new animation runtime info. */ for (i = 0; i < gf_node_animation_count(target); i++) { aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); if (aa->presentation_value.fieldIndex == target_attribute.fieldIndex) { gf_list_add(aa->anims, rai); break; } aa = NULL; } if (!aa) { GF_SAFEALLOC(aa, SMIL_AttributeAnimations) /* We copy (one copy for all animations on the same attribute) the DOM specified value before any animation starts (because the animation will override it), we also save the initial memory address of the specified value (orig_dom_ptr) for inheritance hack */ aa->specified_value = target_attribute; aa->is_property = gf_svg_is_property(target, &target_attribute); aa->orig_dom_ptr = aa->specified_value.far_ptr; aa->specified_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); gf_svg_attributes_copy(&aa->specified_value, &target_attribute, 0); /* Now, the initial memory address for the specified value hold the presentation value, and the presentation value is initialized */ aa->presentation_value = target_attribute; aa->anims = gf_list_new(); gf_list_add(aa->anims, rai); gf_node_animation_add(target, aa); /* determine what the rendering will need to do when the animation runs */ if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) { aa->dirty_flags = gf_svg_get_rendering_flag_if_modified((SVG_Element *)target, &target_attribute); }#ifdef GPAC_ENABLE_SVG_SA else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) { aa->dirty_flags = gf_svg_sa_get_rendering_flag_if_modified((SVG_SA_Element *)target, &target_attribute); } #endif#ifdef GPAC_ENABLE_SVG_SANI else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) { aa->dirty_flags = gf_svg_sani_get_rendering_flag_if_modified((SVG_SANI_Element *)target, &target_attribute); }#endif } rai->owner = aa; gf_smil_anim_get_last_specified_value(rai); /* for animation (unlike other timed elements like video), the interpolation cannot be done during timing evaluation, because due to inheritance, interpolation can only be computed during scene tree traversal, therefore we need to postpone evaluation of the timed element */ timingp->runtime->postpone = 1; timingp->runtime->evaluate = gf_smil_anim_evaluate;}void gf_smil_anim_delete_runtime_info(SMIL_Anim_RTI *rai){ gf_svg_delete_attribute_value(rai->interpolated_value.fieldType, rai->interpolated_value.far_ptr, rai->anim_elt->sgprivate->scenegraph);#if USE_GF_PATH #else if (rai->path) gf_path_del(rai->path);#endif if (rai->path_iterator) gf_path_iterator_del(rai->path_iterator); free(rai);}void gf_smil_anim_remove_from_target(GF_Node *anim, GF_Node *target){ u32 i, j; if (!target) return; for (i = 0; i < gf_node_animation_count((GF_Node *)target); i ++) { SMIL_Anim_RTI *rai; SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get((GF_Node *)target, i); j=0; while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { if ((GF_Node *)rai->anim_elt == anim) { gf_list_rem(aa->anims, j-1); gf_smil_anim_delete_runtime_info(rai); break; } } if (gf_list_count(aa->anims) == 0) { gf_list_del(aa->anims); gf_svg_delete_attribute_value(aa->specified_value.fieldType, aa->specified_value.far_ptr, target->sgprivate->scenegraph); aa->presentation_value.far_ptr = aa->orig_dom_ptr; gf_node_animation_rem((GF_Node *)target, i); free(aa); } }}void gf_smil_anim_delete_animations(GF_Node *e){ u32 i, j; for (i = 0; i < gf_node_animation_count(e); i ++) { SMIL_Anim_RTI *rai; SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(e, i); gf_svg_delete_attribute_value(aa->specified_value.fieldType, aa->specified_value.far_ptr, e->sgprivate->scenegraph); j=0; while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { rai->xlinkp->href->target = NULL; gf_smil_anim_delete_runtime_info(rai); } gf_list_del(aa->anims); free(aa); } gf_node_animation_del(e);}void gf_smil_anim_init_discard(GF_Node *node){ XLinkAttributesPointers *xlinkp = NULL; u32 tag = gf_node_get_tag(node); gf_smil_timing_init_runtime_info(node); if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) { SVGAllAttributes all_atts; SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); e->xlinkp = malloc(sizeof(XLinkAttributesPointers)); xlinkp = e->xlinkp; xlinkp->href = all_atts.xlink_href; xlinkp->type = all_atts.xlink_type; e->timingp->runtime->evaluate_status = SMIL_TIMING_EVAL_DISCARD; }#ifdef GPAC_ENABLE_SVG_SA else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) { ((SVG_SA_Element *)node)->timingp->runtime->evaluate_status = SMIL_TIMING_EVAL_DISCARD; }#endif#ifdef GPAC_ENABLE_SVG_SANI else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) { ((SVG_SANI_Element *)node)->timingp->runtime->evaluate_status = SMIL_TIMING_EVAL_DISCARD; }#endif}void gf_smil_anim_init_node(GF_Node *node){ XLinkAttributesPointers *xlinkp = NULL; SMILAnimationAttributesPointers *animp = NULL; u32 tag = gf_node_get_tag(node); if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) { SVGAllAttributes all_atts; SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); e->xlinkp = malloc(sizeof(XLinkAttributesPointers)); xlinkp = e->xlinkp; xlinkp->href = all_atts.xlink_href; xlinkp->type = all_atts.xlink_type; e->animp = malloc(sizeof(SMILAnimationAttributesPointers)); animp = e->animp; animp->accumulate = all_atts.accumulate; animp->additive = all_atts.additive; animp->attributeName = all_atts.attributeName; animp->attributeType = all_atts.attributeType; animp->by = all_atts.by; animp->calcMode = all_atts.calcMode; animp->from = all_atts.from; animp->keySplines = all_atts.keySplines; animp->keyTimes = all_atts.keyTimes; animp->lsr_enabled = all_atts.lsr_enabled; animp->to = all_atts.to; animp->type = all_atts.transform_type; animp->values = all_atts.values; if (tag == TAG_SVG_animateMotion) { e->animp->keyPoints = all_atts.keyPoints; e->animp->origin = all_atts.origin; e->animp->path = all_atts.path; e->animp->rotate = all_atts.rotate; } } #ifdef GPAC_ENABLE_SVG_SA else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) { SVG_SA_Element *e = (SVG_SA_Element *)node; e->xlinkp = malloc(sizeof(XLinkAttributesPointers)); e->xlinkp->href = &e->xlink->href; e->xlinkp->type = &e->xlink->type; xlinkp = e->xlinkp; e->animp = malloc(sizeof(SMILAnimationAttributesPointers)); e->animp->accumulate = &e->anim->accumulate; e->animp->additive = &e->anim->additive; e->animp->attributeName = &e->anim->attributeName; e->animp->attributeType = &e->anim->attributeType; e->animp->by = &e->anim->by; e->animp->calcMode = &e->anim->calcMode; e->animp->from = &e->anim->from; e->animp->keySplines = &e->anim->keySplines; e->animp->keyTimes = &e->anim->keyTimes; e->animp->lsr_enabled = &e->anim->lsr_enabled; e->animp->to = &e->anim->to; e->animp->type = &e->anim->type; e->animp->values = &e->anim->values; if (tag == TAG_SVG_SA_animateMotion) { e->animp->keyPoints = &((SVG_SA_animateMotionElement *)e)->keyPoints; e->animp->origin = &((SVG_SA_animateMotionElement *)e)->origin; e->animp->path = &((SVG_SA_animateMotionElement *)e)->path; e->animp->rotate = &((SVG_SA_animateMotionElement *)e)->rotate; } animp = e->animp; }#endif#ifdef GPAC_ENABLE_SVG_SANI else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) { SVG_SANI_Element *e = (SVG_SANI_Element *)node; e->xlinkp = malloc(sizeof(XLinkAttributesPointers)); e->xlinkp->href = &e->xlink->href; e->xlinkp->type = &e->xlink->type; xlinkp = e->xlinkp; e->animp = malloc(sizeof(SMILAnimationAttributesPointers)); e->animp->accumulate = &e->anim->accumulate; e->animp->additive = &e->anim->additive; e->animp->attributeName = &e->anim->attributeName; e->animp->attributeType = &e->anim->attributeType; e->animp->by = &e->anim->by; e->animp->calcMode = &e->anim->calcMode; e->animp->from = &e->anim->from; e->animp->keySplines = &e->anim->keySplines; e->animp->keyTimes = &e->anim->keyTimes; e->animp->lsr_enabled = &e->anim->lsr_enabled; e->animp->to = &e->anim->to; e->animp->type = &e->anim->type; e->animp->values = &e->anim->values; if (tag == TAG_SVG_SANI_animateMotion) { e->animp->keyPoints = &((SVG_SANI_animateMotionElement *)e)->keyPoints; e->animp->origin = &((SVG_SANI_animateMotionElement *)e)->origin; e->animp->path = &((SVG_SANI_animateMotionElement *)e)->path; e->animp->rotate = &((SVG_SANI_animateMotionElement *)e)->rotate; } animp = e->animp; }#endif else { return; } if (xlinkp->href->type == XMLRI_STRING) { if (!xlinkp->href->string) { fprintf(stderr, "Error: IRI not initialized\n"); return; } else { GF_Node *n; n = (GF_Node*)gf_sg_find_node_by_name(gf_node_get_graph(node), xlinkp->href->string); if (n) { xlinkp->href->type = XMLRI_ELEMENTID; xlinkp->href->target = n; gf_svg_register_iri(node->sgprivate->scenegraph, xlinkp->href); } else { return; } } } if (!xlinkp->href->target) return; gf_smil_timing_init_runtime_info(node); gf_smil_anim_init_runtime_info(node);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -