📄 loader_svg_sa.c
字号:
} else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) { gf_svg_parse_element_id((GF_Node *)elt, att->value, 0); node_name = att->value; } else if (anim && !stricmp(att->name, "attributeName")) { anim->attributeName = strdup(att->value); } else if (anim && !stricmp(att->name, "to")) { anim->to = strdup(att->value); } else if (anim && !stricmp(att->name, "from")) { anim->from = strdup(att->value); } else if (anim && !stricmp(att->name, "by")) { anim->by = strdup(att->value); } else if (anim && !stricmp(att->name, "values")) { anim->values = strdup(att->value); } else if (anim && (tag == TAG_SVG_SA_animateTransform) && !stricmp(att->name, "type")) { anim->type = strdup(att->value); } else if (!stricmp(att->name, "xlink:href") ) { if (!elt->xlink) { svg_sa_report(parser, GF_OK, "xlink:href on element %s ignored\n", name); } else if (gf_svg_sa_is_animation_tag(tag)) { assert(anim); anim->target_id = strdup(att->value); /*may be NULL*/ anim->target = (SVG_SA_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_post_process_href(parser, iri); } } else if (!strnicmp(att->name, "xmlns", 5)) { } else if (!stricmp(att->name, "ev:event") && tag == TAG_SVG_SA_handler) { /* When the handler element specifies the event attribute, an implicit listener is defined */ GF_Node *node = (GF_Node *)elt; SVG_SA_listenerElement *listener; listener = (SVG_SA_listenerElement *) gf_node_new(node->sgprivate->scenegraph, TAG_SVG_SA_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_SA_handlerElement *)node)->ev_event.type = listener->event.type = gf_dom_event_type_by_name(att->value); listener->handler.target = (SVG_SA_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_SA_handlerElement *handler; handler = gf_dom_listener_build((GF_Node *) elt, evtType, 0, NULL); handler->textContent = strdup(att->value); 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_sa_report(parser, GF_OK, "Unknown attribute %s on element %s - skipping\n", (char *)att->name, name); } } } if (anim) { if (svg_sa_parse_animation(parser, parser->load->scene_graph, anim, NULL)) { svg_sa_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_sa_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_SA_listener)) { Bool post_pone = 0; SVG_SA_Element *par = NULL; SVG_SA_listenerElement *listener = (SVG_SA_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 void svg_sa_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes){ SVG_SA_NodeStack *stack, *parent; SVG_SA_Element *elt; GF_SVG_SA_Parser *parser = (GF_SVG_SA_Parser *)sax_cbck; parent = (SVG_SA_NodeStack *)gf_list_last(parser->node_stack); if (parser->has_root) { assert(parent); } elt = svg_sa_parse_element(parser, name, name_space, attributes, nb_attributes, parent); if (!elt) { if (parent) parent->unknown_depth++; return; } GF_SAFEALLOC(stack, SVG_SA_NodeStack); stack->node = elt; gf_list_add(parser->node_stack, stack); if (gf_node_get_tag((GF_Node *)elt) == TAG_SVG_SA_svg && !parser->has_root) svg_sa_init_root_element(parser, (SVG_SA_svgElement *)elt);}static void svg_sa_node_end(void *sax_cbck, const char *name, const char *name_space){ u32 end_tag; GF_SVG_SA_Parser *parser = (GF_SVG_SA_Parser *)sax_cbck; SVG_SA_NodeStack *top = (SVG_SA_NodeStack *)gf_list_last(parser->node_stack); /*only remove created nodes ... */ end_tag = gf_svg_sa_node_type_by_class_name(name); if (end_tag != TAG_UndefinedNode) { GF_Node *node = (GF_Node *) top->node; if (node->sgprivate->tag != end_tag) { if (top->unknown_depth) { top->unknown_depth--; return; } else { svg_sa_report(parser, GF_BAD_PARAM, "SVG depth mismatch"); return; } } free(top); gf_list_rem_last(parser->node_stack); if (parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK) { GF_DOM_Event evt; memset(&evt, 0, sizeof(GF_DOM_Event)); evt.type = GF_EVENT_LOAD; gf_dom_event_fire(node, NULL, &evt); /*init animateMotion once all children have been parsed tomake sure we get the mpath child if any*/ if (node->sgprivate->tag == TAG_SVG_SA_animateMotion) { gf_node_init(node); } } } else if (top) { if (top->unknown_depth) { top->unknown_depth--; } else { svg_sa_report(parser, GF_BAD_PARAM, "SVG depth mismatch"); } }}static void svg_sa_text_content(void *sax_cbck, const char *text_content, Bool is_cdata){ char *result; u32 len; Bool space_preserve = 0; GF_SVG_SA_Parser *parser = (GF_SVG_SA_Parser *)sax_cbck; SVG_SA_Element *node_core, *node; SVG_SA_NodeStack *top = (SVG_SA_NodeStack *)gf_list_last(parser->node_stack); node = top ? (SVG_SA_Element *) top->node : NULL; if (!node) return; if (top && top->unknown_depth) return; node_core = node; if (!node_core) return; if (!node_core->core) return; result = strdup(text_content); len = strlen(text_content); if (is_cdata) goto skip_xml_space; if (node_core->core->space != XML_SPACE_PRESERVE) { u32 j, i, state; i = j = 0; state = 0; for (i=0; i<len; i++) { switch (text_content[i]) { case '\n': case '\r': break; case '\t': case ' ': if (j && !state) { state = 1; result[j] = ' '; j++; } break; default: result[j] = text_content[i]; j++; state = 0; break; } } result[j] = 0; len = j; } else { u32 j, i; i = j = 0; space_preserve = 1; for (i=0; i<len; i++) { switch (text_content[i]) { case '\r': break; case '\n': case '\t': result[j] = ' '; j++; break; default: result[j] = text_content[i]; j++; break; } } result[j] = 0; len = j; }skip_xml_space: if (!len) { free(result); return; } switch (gf_node_get_tag((GF_Node *)node)) { case TAG_SVG_SA_text: { SVG_SA_textElement *text = (SVG_SA_textElement *)node; u32 baselen = 0; if (text->textContent) baselen = strlen(text->textContent); if (baselen && space_preserve) { text->textContent = (char *)realloc(text->textContent,baselen+len+2); strcat(text->textContent, " "); strncpy(text->textContent + baselen + 1, result, len); text->textContent[baselen+len+1] = 0; } else { text->textContent = (char *)realloc(text->textContent,baselen+len+1); strncpy(text->textContent + baselen, result, len); text->textContent[baselen+len] = 0; } gf_node_changed((GF_Node *)node, NULL); free(result); return; } default: if (node->textContent) free(node->textContent); node->textContent = result; break; }}static GF_SVG_SA_Parser *svg_sa_new_parser(GF_SceneLoader *load){ GF_SVG_SA_Parser *parser; GF_SAFEALLOC(parser, GF_SVG_SA_Parser); parser->node_stack = gf_list_new(); parser->defered_hrefs = gf_list_new(); parser->defered_animations = gf_list_new(); parser->defered_listeners = gf_list_new(); parser->sax_parser = gf_xml_sax_new(svg_sa_node_start, svg_sa_node_end, svg_sa_text_content, parser); parser->load = load; load->loader_priv = parser; if (load->ctx) load->ctx->is_pixel_metrics = 1; return parser;}extern size_t gpac_allocated_memory;GF_Err gf_sm_load_init_svg_sa(GF_SceneLoader *load){ GF_Err e; GF_SVG_SA_Parser *parser; if (!load->fileName) return GF_BAD_PARAM; parser = svg_sa_new_parser(load); e = gf_xml_sax_parse_file(parser->sax_parser, (const char *)load->fileName, svg_progress); if (e<0) return svg_sa_report(parser, e, "Unable to parse file %s: %s", load->fileName, gf_xml_sax_get_error(parser->sax_parser) );#if 0 { GF_SystemRTInfo rti; gf_sys_get_rti(0, &rti, GF_RTI_SYSTEM_MEMORY_ONLY); fprintf(stdout, "Memory usage : %d\n", rti.gpac_memory); }#endif return parser->last_error;}GF_Err gf_sm_load_init_svg_sa_string(GF_SceneLoader *load, char *str_data){ GF_Err e; GF_SVG_SA_Parser *parser = (GF_SVG_SA_Parser *)load->loader_priv; if (!parser) { char BOM[6]; BOM[0] = str_data[0]; BOM[1] = str_data[1]; BOM[2] = str_data[2]; BOM[3] = str_data[3]; BOM[4] = BOM[5] = 0; parser = svg_sa_new_parser(load); e = gf_xml_sax_init(parser->sax_parser, (unsigned char*)BOM); if (e) { svg_sa_report(parser, e, "Error initializing SAX parser: %s", gf_xml_sax_get_error(parser->sax_parser) ); return e; } str_data += 4; } return gf_xml_sax_parse(parser->sax_parser, str_data);}GF_Err gf_sm_load_run_svg_sa(GF_SceneLoader *load){ return GF_OK;}GF_Err gf_sm_load_done_svg_sa(GF_SceneLoader *load){ GF_SVG_SA_Parser *parser = (GF_SVG_SA_Parser *)load->loader_priv; if (!parser) return GF_OK; while (gf_list_count(parser->node_stack)) { SVG_SA_NodeStack *st = (SVG_SA_NodeStack *)gf_list_last(parser->node_stack); gf_list_rem_last(parser->node_stack); free(st); } gf_list_del(parser->node_stack); gf_list_del(parser->defered_hrefs); gf_list_del(parser->defered_listeners); svg_sa_reset_defered_animations(parser->defered_animations); gf_list_del(parser->defered_animations); gf_xml_sax_del(parser->sax_parser); free(parser); load->loader_priv = NULL; return GF_OK;}#endif /*GPAC_ENABLE_SVG_SA*/#endif /*GPAC_DISABLE_SVG*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -