GF_Node *gf_xml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *cloned_parent, char *inst_id, Bool deep) { GF_DOMAttribute *att; GF_Node *clone = gf_node_new(inScene, orig->sgprivate->tag); if (!clone) return NULL; if (orig->sgprivate->tag == TAG_DOMText) { GF_DOMText *n_src,*n_dst; n_src = (GF_DOMText *)orig; n_dst = (GF_DOMText *)clone; n_dst->type = n_src->type; n_dst->textContent = gf_strdup(n_src->textContent); } else { if (orig->sgprivate->tag == TAG_DOMFullNode) { GF_DOMFullNode *n_src,*n_dst; n_src = (GF_DOMFullNode *)orig; n_dst = (GF_DOMFullNode *)clone; n_dst->ns = n_src->ns; n_dst->name = gf_strdup(n_dst->name); } att = ((GF_DOMNode *)orig)->attributes; while (att) { GF_FieldInfo dst, src; /*create by name*/ if (att->tag==TAG_DOM_ATT_any) { gf_node_get_attribute_by_name(clone, ((GF_DOMFullAttribute*)att)->name, 0, 1, 0, &dst); } else { gf_node_get_attribute_by_tag(clone, att->tag, 1, 0, &dst); } src.far_ptr = att->data; src.fieldType = att->data_type; src.fieldIndex = att->tag; gf_svg_attributes_copy(&dst, &src, 0); if (att->tag==TAG_XLINK_ATT_href) { XMLRI *iri = (XMLRI *)att->data; if (iri->target == gf_node_get_parent(orig, 0)) { ((XMLRI *)dst.far_ptr)->target = cloned_parent; } else { ((XMLRI *)dst.far_ptr)->target = NULL; } } att = att->next; } } if (cloned_parent) { gf_node_list_add_child( & ((GF_ParentNode*)cloned_parent)->children, clone); gf_node_register(clone, cloned_parent); /*TO CLARIFY: can we init the node right now or should we wait for insertion in the scene tree ?*/ gf_node_init(clone); } if (deep) { GF_ChildNodeItem *child = ((GF_ParentNode *)orig)->children; while (child) { gf_node_clone(inScene, child->node, clone, inst_id, 1); child = child->next; } } return clone; }
void VTT_load_script(VTTDec *vttdec, GF_SceneGraph *graph) { GF_Node *n, *root; GF_FieldInfo info; const char *path; FILE *jsfile; if (!graph) return; gf_sg_add_namespace(graph, "http://www.w3.org/2000/svg", NULL); gf_sg_add_namespace(graph, "http://www.w3.org/1999/xlink", "xlink"); gf_sg_add_namespace(graph, "http://www.w3.org/2001/xml-events", "ev"); gf_sg_set_scene_size_info(graph, 800, 600, GF_TRUE); /* modify the scene with an Inline/Animation pointing to the VTT Renderer */ n = root = gf_node_new(graph, TAG_SVG_svg); gf_node_register(root, NULL); gf_sg_set_root_node(graph, root); gf_node_get_attribute_by_name(n, "xmlns", 0, GF_TRUE, GF_FALSE, &info); gf_svg_parse_attribute(n, &info, "http://www.w3.org/2000/svg", 0); VTT_UpdateSizeInfo(vttdec); gf_node_init(n); n = gf_node_new(graph, TAG_SVG_script); gf_node_register(n, root); gf_node_list_add_child(&((GF_ParentNode *)root)->children, n); path = gf_modules_get_option((GF_BaseInterface *)vttdec->module, "WebVTT", "RenderingScript"); if (!path) { /* try to find the JS renderer in the default GPAC installation folder */ const char *startuppath = gf_modules_get_option((GF_BaseInterface *)vttdec->module, "General", "StartupFile"); path = gf_url_concatenate(startuppath, "webvtt-renderer.js"); jsfile = gf_fopen(path, "rt"); if (jsfile) { gf_modules_set_option((GF_BaseInterface *)vttdec->module, "WebVTT", "RenderingScript", path); gf_fclose(jsfile); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[WebVTT] Cannot find Rendering Script [WebVTT:RenderingScript] - check config file\n")); return; } } jsfile = gf_fopen(path, "rt"); if (jsfile) { gf_fclose(jsfile); gf_node_get_attribute_by_tag(n, TAG_XLINK_ATT_href, GF_TRUE, GF_FALSE, &info); if (strstr(path, ":\\")) { gf_svg_parse_attribute(n, &info, (char *) path, 0); } else { char szPath[GF_MAX_PATH]; strcpy(szPath, "file://"); strcat(szPath, path); gf_svg_parse_attribute(n, &info, (char *) szPath, 0); } vttdec->has_rendering_script = GF_TRUE; } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[WebVTT] Cannot open Rendering Script - %s\n", path)); return; } gf_node_init(n); }
static void svg_parse_animation(GF_SceneGraph *sg, SVG_DeferedAnimation *anim) { GF_FieldInfo info; u32 tag; u8 anim_value_type = 0; if (anim->resolve_stage==0) { /* Stage 0: parsing the animation attribute values for that we need to resolve the target first */ if (!anim->target) anim->target = (SVG_Element *) gf_sg_find_node_by_name(sg, anim->target_id + 1); if (!anim->target) { /* the target is still not known stay in stage 0 */ return; } else { XMLRI *iri; gf_node_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_XLINK_ATT_href, 1, 0, &info); iri = (XMLRI *)info.far_ptr; iri->type = XMLRI_ELEMENTID; iri->target = anim->target; gf_node_register_iri(sg, iri); } tag = gf_node_get_tag((GF_Node *)anim->animation_elt); /* get the attribute name attribute if specified */ if (anim->type && (tag== TAG_SVG_animateTransform) ) { gf_node_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_transform_type, 1, 0, &info); gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->type, 0); switch(*(SVG_TransformType *) info.far_ptr) { case SVG_TRANSFORM_TRANSLATE: anim_value_type = SVG_Transform_Translate_datatype; break; case SVG_TRANSFORM_SCALE: anim_value_type = SVG_Transform_Scale_datatype; break; case SVG_TRANSFORM_ROTATE: anim_value_type = SVG_Transform_Rotate_datatype; break; case SVG_TRANSFORM_SKEWX: anim_value_type = SVG_Transform_SkewX_datatype; break; case SVG_TRANSFORM_SKEWY: anim_value_type = SVG_Transform_SkewY_datatype; break; case SVG_TRANSFORM_MATRIX: anim_value_type = SVG_Transform_datatype; break; default: fprintf(stdout, "unknown datatype for animate transform"); return; } } else if (gf_node_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_attributeName, 0, 0, &info) == GF_OK) { gf_node_get_attribute_by_name((GF_Node *)anim->target, ((SMIL_AttributeName *)info.far_ptr)->name, 0, 1, 1, &info); anim_value_type = info.fieldType; } else { if (tag == TAG_SVG_animateMotion) { anim_value_type = SVG_Motion_datatype; } else if (tag == TAG_SVG_discard) { /* there is no value to parse in discard, we can jump to the next stage */ anim->resolve_stage = 1; svg_parse_animation(sg, anim); return; } else { fprintf(stdout, "Missing attributeName attribute on %s", gf_node_get_name((GF_Node *)anim->animation_elt)); return; } } if (anim->to) { gf_node_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_to, 1, 0, &info); gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->to, anim_value_type); } if (anim->from) { gf_node_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_from, 1, 0, &info); gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->from, anim_value_type); } if (anim->by) { gf_node_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_by, 1, 0, &info); gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->by, anim_value_type); } if (anim->values) { gf_node_get_attribute_by_tag((GF_Node *)anim->animation_elt, TAG_SVG_ATT_values, 1, 0, &info); gf_svg_parse_attribute((GF_Node *)anim->animation_elt, &info, anim->values, anim_value_type); } anim->resolve_stage = 1; } }