📄 loader_svg_sani.c
字号:
for (i=0; i<count; i++) { GF_Node *par; SVG_SANI_listenerElement *listener = (SVG_SANI_listenerElement *)gf_list_get(parser->defered_listeners, i); par = NULL; if (listener->observer.type == XMLRI_ELEMENTID) { if (!listener->observer.target) continue; else par = (GF_Node*)listener->observer.target; } if (listener->target.type == XMLRI_ELEMENTID) { if (!listener->target.target) continue; else { if (!par) par = (GF_Node*)listener->target.target; } } assert(par); gf_dom_listener_add((GF_Node *)par, (GF_Node *) listener); gf_list_rem(parser->defered_listeners, i); i--; count--; } /*check unresolved anims*/ count = gf_list_count(parser->defered_animations); for (i=0; i<count; i++) { DeferedSVG_SANI_Animation *anim = (DeferedSVG_SANI_Animation *)gf_list_get(parser->defered_animations, i); /*resolve it - we don't check the name since it may be used in SMIL times, which we don't track at anim level*/ if (svg_sani_parse_animation(parser, sg, anim, nodeID)) { svg_sani_delete_defered_anim(anim, parser->defered_animations); i--; count--; } }}static SVG_SANI_Element *svg_sani_parse_element(GF_SVG_SANI_Parser *parser, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes, SVG_SANI_NodeStack *parent){ u32 tag, i; SVG_SANI_Element *elt; GF_FieldInfo info; const char *node_name = NULL; DeferedSVG_SANI_Animation *anim = NULL; /* Translates the node type (called name) from a String into a unique numeric identifier in GPAC */ tag = gf_svg_sani_type_by_class_name(name); if (tag == TAG_UndefinedNode) { svg_sani_report(parser, GF_OK, "Unknown element %s - skipping", name); return NULL; } /* Creates a node in the current scene graph */ elt = (SVG_SANI_Element*)gf_node_new(parser->load->scene_graph, tag); if (!elt) { parser->last_error = GF_SG_UNKNOWN_NODE; return NULL; } gf_node_register((GF_Node *)elt, (parent ? (GF_Node *)parent->node : NULL)); if (parent && elt) gf_node_list_add_child_last( & parent->node->children, (GF_Node*)elt, & parent->last_child); if (is_svg_sani_animation_tag(tag)) { GF_SAFEALLOC(anim, DeferedSVG_SANI_Animation); /*default anim target is parent node*/ anim->animation_elt = elt; anim->target = parent->node; anim->anim_parent = parent->node; } else if (tag == TAG_SVG_SANI_video || tag == TAG_SVG_SANI_audio || tag == TAG_SVG_SANI_animation || tag == TAG_SVG_SANI_conditional) { /* warning: we use the DeferedSVG_SANI_Animation structure for some timing nodes which are not animations, but we put the parse stage at 1 (timing) see svg_sani_parse_animation. */ GF_SAFEALLOC(anim, DeferedSVG_SANI_Animation); /*default anim target is parent node*/ anim->animation_elt = elt; anim->anim_parent = parent->node; anim->resolve_stage = 1; } /*parse all att*/ for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!stricmp(att->name, "style")) { /* Special case: style if present will always be first in the list */ gf_svg_parse_style((GF_Node *)elt, att->value); } else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) { gf_svg_parse_element_id((GF_Node *)elt, att->value, parser->command_depth ? 1 : 0); node_name = att->value; } else if (anim && !stricmp(att->name, "attributeName")) { anim->attributeName = att->value; att->value = NULL; } else if (anim && !stricmp(att->name, "to")) { anim->to = att->value; att->value = NULL; } else if (anim && !stricmp(att->name, "from")) { anim->from = att->value; att->value = NULL; } else if (anim && !stricmp(att->name, "by")) { anim->by = att->value; att->value = NULL; } else if (anim && !stricmp(att->name, "values")) { anim->values = att->value; att->value = NULL; } else if (&anim && (tag == TAG_SVG_SANI_animateTransform) && !stricmp(att->name, "type")) { anim->type = att->value; att->value = NULL; } else if (!stricmp(att->name, "xlink:href") ) { if (!elt->xlink) { svg_sani_report(parser, GF_OK, "Warning: xlink:href on element %s ignored\n", name); } else if (is_svg_sani_animation_tag(tag)) { assert(anim); anim->target_id = att->value; att->value = NULL; /*may be NULL*/ anim->target = (SVG_SANI_Element *) gf_sg_find_node_by_name(parser->load->scene_graph, anim->target_id + 1); } else { XMLRI *iri = & elt->xlink->href; memset(&info, 0, sizeof(GF_FieldInfo)); info.far_ptr = & elt->xlink->href; info.fieldType = XMLRI_datatype; info.name = "xlink:href"; gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0); svg_sani_post_process_href(parser, iri); } } else if (!strnicmp(att->name, "xmlns", 5)) { } else if (!stricmp(att->name, "ev:event") && tag == TAG_SVG_SANI_handler) { /* When the handler element specifies the event attribute, an implicit listener is defined */ GF_Node *node = (GF_Node *)elt; SVG_SANI_listenerElement *listener; listener = (SVG_SANI_listenerElement *) gf_node_new(node->sgprivate->scenegraph, TAG_SVG_SANI_listener); gf_node_register((GF_Node *)listener, node); gf_node_list_add_child( & ((GF_ParentNode *)node)->children, (GF_Node*) listener); /* this listener listens to the given type of event */ ((SVG_SANI_handlerElement *)node)->ev_event.type = listener->event.type = gf_dom_event_type_by_name(att->value); listener->handler.target = (SVG_SANI_Element *)node; /* this listener listens with the parent of the handler as the event target */ listener->target.target = parent->node; gf_dom_listener_add((GF_Node *) parent->node, (GF_Node *) listener); } else { u32 evtType = GF_EVENT_UNKNOWN; if (!strncmp(att->name, "on", 2)) evtType = gf_dom_event_type_by_name(att->name + 2); /*SVG 1.1 events: create a listener and a handler on the fly, register them with current node and add listener struct*/ if (evtType != GF_EVENT_UNKNOWN) { XMLEV_Event evt; SVG_SANI_handlerElement *handler; handler = gf_dom_listener_build((GF_Node *) elt, evtType, 0, NULL); handler->textContent = att->value; att->value = NULL; gf_node_init((GF_Node *)handler); } else if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) { gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0); if (info.fieldType== XMLRI_datatype) { XMLRI *iri = (XMLRI *)info.far_ptr; if ((iri->type==XMLRI_ELEMENTID) && !iri->target && iri->string) gf_list_add(parser->defered_hrefs, iri); } } /*LASeR HACKS*/ else if (!strcmp(att->name, "lsr:translation")) { if (gf_node_get_field_by_name((GF_Node *)elt, "transform", &info)==GF_OK) { Float tx, ty; sscanf(att->value, "%f %f", &tx, &ty); gf_mx2d_add_translation((GF_Matrix2D*)info.far_ptr, FLT2FIX(tx), FLT2FIX(ty)); } } else { svg_sani_report(parser, GF_OK, "Unknown attribute %s on element %s - skipping\n", (char *)att->name, gf_node_get_class_name((GF_Node *)elt)); } } } if (anim) { if (svg_sani_parse_animation(parser, parser->load->scene_graph, anim, NULL)) { svg_sani_delete_defered_anim(anim, NULL); } else { gf_list_add(parser->defered_animations, anim); } } /* if the new element has an id, we try to resolve defered references */ if (node_name) { svg_sani_resolved_refs(parser, parser->load->scene_graph, node_name); } /* We need to init the node at the end of the parsing, after parsing all attributes */ /* text nodes must be initialized at the end of the <text> element */ if (!anim && elt) gf_node_init((GF_Node *)elt); /*register listener element*/ if (elt && (tag==TAG_SVG_SANI_listener)) { Bool post_pone = 0; SVG_SANI_Element *par = NULL; SVG_SANI_listenerElement *listener = (SVG_SANI_listenerElement *)elt; if (listener->observer.type == XMLRI_ELEMENTID) { if (!listener->observer.target) post_pone = 1; else par = listener->observer.target; } if (!par && (listener->target.type == XMLRI_ELEMENTID)) { if (!listener->target.target) post_pone = 1; else par = listener->target.target; } if (!listener->handler.target) listener->handler.target = parent->node; if (post_pone) { gf_list_add(parser->defered_listeners, listener); } else { if (!par) par = parent->node; gf_dom_listener_add((GF_Node *)par, (GF_Node *) listener); } } return elt;}static GF_ESD *lsr2_parse_header(GF_SVG_SANI_Parser *parser, const char *name, const char *name_space, GF_List *attrs){ GF_ESD *esd; u32 i, count; if (!strcmp(name, "LASeRHeader")) { GF_LASERConfig *lsrc = (GF_LASERConfig *) gf_odf_desc_new(GF_ODF_LASER_CFG_TAG); count = gf_list_count(attrs); for (i=0; i<count;i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)gf_list_get(attrs, i); if (!strcmp(att->name, "profile")) lsrc->profile = !strcmp(att->value, "full") ? 1 : 0; else if (!strcmp(att->name, "level")) lsrc->level = atoi(att->value); else if (!strcmp(att->name, "resolution")) lsrc->resolution = atoi(att->value); else if (!strcmp(att->name, "timeResolution")) lsrc->time_resolution = atoi(att->value); else if (!strcmp(att->name, "coordBits")) lsrc->coord_bits = atoi(att->value); else if (!strcmp(att->name, "scaleBits_minus_coordBits")) lsrc->scale_bits_minus_coord_bits = atoi(att->value); else if (!strcmp(att->name, "colorComponentBits")) lsrc->colorComponentBits = atoi(att->value); else if (!strcmp(att->name, "append")) lsrc->append = !strcmp(att->value, "yes") ? 1 : 0; else if (!strcmp(att->name, "useFullRequestHost")) lsrc->fullRequestHost = !strcmp(att->value, "yes") ? 1 : 0; else if (!strcmp(att->name, "pathComponents")) lsrc->fullRequestHost = atoi(att->value); else if (!strcmp(att->name, "hasStringsIDs")) lsrc->has_string_ids = !strcmp(att->value, "yes") ? 1 : 0; /*others are ignored in GPAC atm*/ } esd = gf_odf_desc_esd_new(2); gf_odf_desc_del((GF_Descriptor *)esd->decoderConfig->decoderSpecificInfo); esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) lsrc; esd->decoderConfig->streamType = GF_STREAM_SCENE; esd->decoderConfig->objectTypeIndication = 0x09; esd->slConfig->timestampResolution = lsrc->time_resolution ? lsrc->time_resolution : 1000; return esd; } return NULL;}static GF_Err lsr2_parse_command(GF_SVG_SANI_Parser *parser, GF_List *attr){ GF_FieldInfo info; GF_Node *opNode; GF_Err e; Bool is_replace = 0; char *atNode = NULL; char *atAtt = NULL; char *atOperandNode = NULL; char *atOperandAtt = NULL; char *atValue = NULL; GF_CommandField *field; s32 index = -1; u32 i, count = gf_list_count(attr); switch (parser->command->tag) { case GF_SG_LSR_NEW_SCENE: return GF_OK; case GF_SG_LSR_DELETE: for (i=0; i<count; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)gf_list_get(attr, i); if (!strcmp(att->name, "ref")) atNode = att->value; else if (!strcmp(att->name, "attributeName")) atAtt = att->value; else if (!strcmp(att->name, "index")) index = atoi(att->value); } if (!atNode) return svg_sani_report(parser, GF_BAD_PARAM, "Missing node ref for command"); parser->command->node = gf_sg_find_node_by_name(parser->load->scene_graph, atNode); if (!parser->command->node) return svg_sani_report(parser, GF_BAD_PARAM, "Cannot find node node ref %s for command", atNode); if (atAtt || (index>=0) ) { if (!strcmp(atAtt, "children")) atAtt = NULL; if (atAtt && gf_node_get_field_by_name(parser->command->node, atAtt, &info) != GF_OK) return svg_sani_report(parser, GF_BAD_PARAM, "Attribute %s does not belong to node %s", atAtt, atNode); field = gf_sg_command_field_new(parser->command); field->pos = index; field->fieldIndex = atAtt ? info.fieldIndex : 0; field->fieldType = atAtt ? info.fieldType : 0; } gf_node_register(parser->command->node, NULL); return GF_OK; case GF_SG_LSR_REPLACE: is_replace = 1; case GF_SG_LSR_ADD: case GF_SG_LSR_INSERT: for (i=0; i<count; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)gf_list_get(attr, i); if (!strcmp(att->name, "ref")) atNode = att->value; else if (!strcmp(att->name, "operandElementId")) atOperandNode = att->value; else if (!strcmp(att->name, "operandAttributeName")) atOperandAtt = att->value; else if (!strcmp(att->name, "value")) atValue = att->value; else if (!strcmp(att->name, "attributeName")) atAtt = att->value; /*replace only*/ else if (!strcmp(att->name, "index")) index = atoi(att->value); } if (!atNode) return svg_sani_report(parser, GF_BAD_PARAM, "Missing node ref for command"); parser->command->node = gf_sg_find_node_by_name(parser->load->scene_graph, atNode); if (!parser->command->node) return svg_sani_report(parser, GF_BAD_PARAM, "Cannot find node node ref %s for command", atNode); /*child or node replacement*/ if ( (is_replace || (parser->command->tag==GF_SG_LSR_INSERT)) && (!atAtt || !strcmp(atAtt, "children")) ) { field = gf_sg_command_field_new(parser->command); field->pos = index; gf_node_register(parser->command->node, NULL); return GF_OK; } if (!atAtt) return svg_sani_report(parser, GF_BAD_PARAM, "Missing attribute name for command"); if (!strcmp(atAtt, "textContent")) { field = gf_sg_command_field_new(parser->command); field->pos = -1; field->fieldIndex = (u32) -1; field->fieldType = SVG_String_datatype; gf_node_register(parser->command->node, NULL); if (atValue) { field->field_ptr = gf_svg_create_attribute_value(field->fieldType); *(SVG_String *)field->field_ptr = strdup(atValue); } return GF_OK; } e = gf_node_get_field_by_name(parser->command->node, atAtt, &info); if (e != GF_OK) { if (!strcmp(atAtt, "scale") || !strcmp(atAtt, "translation") || !strcmp(atAtt, "rotation")) { e = gf_node_get_field_by_name(parser->command->node, "transform", &info); if (!e) { if (!strcmp(atAtt, "scale")) info.eventType = SVG_TRANSFORM_SCALE; else if (!strcmp(atAtt, "translation")) info.eventType = SVG_TRANSFORM_TRANSLATE; else if (!strcmp(atAtt, "rotation")) info.eventType = SVG_TRANSFORM_ROTATE; } } if (e) return svg_sani_report(parser, GF_BAD_PARAM, "Attribute %s does not belong to node %s", atAtt, atNode); } opNode = NULL; if (atOperandNode) { opNode = gf_sg_find_node_by_name(parser->load->scene_graph, atOperandNode); if (!opNode) return svg_sani_report(parser, GF_BAD_PARAM, "Cannot find operand element %s for command", atOperandNode); } if (!atValue && (!atOperandNode || !atOperandAtt) ) return svg_sani_report(parser, GF_BAD_PARAM, "Missing attribute value for command"); field = gf_sg_command_field_new(parser->command); field->pos = index; field->fieldIndex = info.fieldIndex; field->fieldType = info.fieldType; if (atValue) { GF_FieldInfo nf; nf.fieldType = info.fieldType;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -