📄 loader_svg_da.c
字号:
gf_list_add(up->updates, parser->command); } else { gf_list_add(parser->laser_au->commands, parser->command); } /*this is likely a conditional start - update unknown depth level*/ top = (SVG_NodeStack*)gf_list_last(parser->node_stack); if (top) { top->unknown_depth ++; parser->command_depth++; } e = lsr_parse_command(parser, attributes, nb_attributes); if (e!= GF_OK) parser->command->node = NULL; return; } } if (parser->has_root) { assert(parent || parser->command); } elt = svg_parse_element(parser, name, name_space, attributes, nb_attributes, parent); if (!elt) { if (parent) parent->unknown_depth++; else if (cond) parser->command_depth++; svg_report(parser, GF_OK, "Ignoring unknown element %s", name); return; } GF_SAFEALLOC(stack, SVG_NodeStack); stack->node = elt; gf_list_add(parser->node_stack, stack); if ( (gf_node_get_tag((GF_Node *)elt) == TAG_SVG_svg) && (!parser->has_root || (parser->command && !parser->command->node) ) ) { if (!parser->has_root) svg_init_root_element(parser, elt); if (parser->command) parser->command->node = (GF_Node*)elt; } else if (!parent && parser->has_root && parser->command) { GF_CommandField *field = (GF_CommandField *)gf_list_get(parser->command->command_fields, 0); if (field) { /*either not assigned or textContent*/ if (field->new_node && (field->new_node->sgprivate->tag==TAG_DOMText)) { svg_report(parser, GF_OK, "Warning: LASeR cannot replace children with a mix of text nodes and elements - ignoring text\n"); gf_node_unregister(field->new_node, NULL); field->new_node = NULL; } if (field->new_node) { field->field_ptr = &field->node_list; gf_node_list_add_child(& field->node_list, field->new_node); field->new_node = NULL; gf_node_list_add_child( & field->node_list, (GF_Node*) elt); } else if (field->node_list) { gf_node_list_add_child(& field->node_list, (GF_Node*) elt); } else if (!field->new_node) { field->new_node = (GF_Node*)elt; field->field_ptr = &field->new_node; } } else { assert(parser->command->tag==GF_SG_LSR_NEW_SCENE); assert(gf_node_get_tag((GF_Node *)elt) == TAG_SVG_svg); if(!parser->command->node) parser->command->node = (GF_Node *)elt; } } else if (!parser->has_root) { gf_list_del_item(parser->node_stack, stack); free(stack); gf_node_unregister((GF_Node *)elt, NULL); }}static void svg_node_end(void *sax_cbck, const char *name, const char *name_space){ GF_SVG_Parser *parser = (GF_SVG_Parser *)sax_cbck; SVG_NodeStack *top = (SVG_NodeStack *)gf_list_last(parser->node_stack); if (!top) { if (parser->laser_au && !strcmp(name, "sceneUnit")) { parser->laser_au = NULL; return; } if (parser->command) { u32 com_type = lsr_get_command_by_name(name); if (com_type == parser->command->tag) { parser->command = NULL; return; } } /*error*/ return; } /*only remove created nodes ... */ if (gf_svg_get_element_tag(name) != TAG_UndefinedNode) { const char *the_name; SVG_Element *node = top->node; /*check node name...*/ the_name = gf_node_get_class_name((GF_Node *)node); if (strcmp(the_name, name)) { if (top->unknown_depth) { top->unknown_depth--; return; } else { svg_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((GF_Node*)node, NULL, &evt); switch (node->sgprivate->tag) { /*init animateMotion once all children have been parsed tomake sure we get the mpath child if any*/ case TAG_SVG_animateMotion: /*init script once text script is loaded*/ case TAG_SVG_script: case TAG_SVG_handler: gf_node_init((GF_Node *)node); break; } } } else if (top) { if (top->unknown_depth) { top->unknown_depth--; if (!top->unknown_depth) parser->command_depth --; } else if (parser->command_depth) { parser->command_depth--; } else { svg_report(parser, GF_BAD_PARAM, "SVG depth mismatch"); } }}static void svg_text_content(void *sax_cbck, const char *text_content, Bool is_cdata){ GF_SVG_Parser *parser = (GF_SVG_Parser *)sax_cbck; SVG_NodeStack *top = (SVG_NodeStack *)gf_list_last(parser->node_stack); SVG_Element *elt = (top ? top->node : NULL); GF_FieldInfo info; GF_DOMText *text; u8 xml_space; u32 tag; char *result; u32 len; if (top && top->unknown_depth && !parser->command_depth) return; if (!elt && !parser->command) return; result = strdup(text_content); len = strlen(text_content); if (is_cdata) goto skip_xml_space; if (elt && gf_svg_get_attribute_by_tag((GF_Node *)elt, TAG_SVG_ATT_xml_space, 0, 0, &info) == GF_OK) xml_space = *((XML_Space *)info.far_ptr); else xml_space = XML_SPACE_DEFAULT; if (xml_space != XML_SPACE_PRESERVE) { u32 j, i, state; i = j = 0; state = 0; for (i=0; i<len; i++) { switch (text_content[i]) { /*move all \r* to \n*/ case '\r': if (!j) break; if (text_content[i+1]!='\n') { result[j] = '\n'; j++; state = 0; } break; case '\t': case ' ': if (j && !state) { state = 1; result[j] = ' '; j++; } break; case '\n': if (!j) break; default: result[j] = text_content[i]; j++; state = 0; break; } } result[j] = 0; len = j; } else { u32 j, i; i = j = 0; for (i=0; i<len; i++) { switch (text_content[i]) { /*move all \r* to \n*/ case '\r': if (text_content[i+1]!='\n') { result[j] = '\n'; j++; } break; 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; } /*if top is a conditional, create a new text node*/ if (!elt || (elt->sgprivate->tag==TAG_SVG_conditional) ) { GF_CommandField *field = (GF_CommandField *)gf_list_get(parser->command->command_fields, 0); assert(field); if (field->new_node) { free(result); svg_report(parser, GF_OK, "Warning: LASeR cannot replace children with a mix of text nodes and elements - ignoring text\n"); return; } /*create a text node but don't register it with any node*/ text = gf_dom_new_text_node(parser->load->scene_graph); gf_node_register((GF_Node *)text, NULL); text->textContent = result; if (field->new_node) { field->field_ptr = &field->node_list; gf_node_list_add_child(& field->node_list, field->new_node); field->new_node = NULL; gf_node_list_add_child( & field->node_list, (GF_Node*) text); } else if (field->node_list) { gf_node_list_add_child(& field->node_list, (GF_Node*) text); } else if (!field->new_node) { field->new_node = (GF_Node*)text; field->field_ptr = &field->new_node; } return; } tag = gf_node_get_tag((GF_Node *)elt); text = gf_dom_add_text_node((GF_Node *)elt, result); text->is_cdata = is_cdata; gf_node_changed((GF_Node *)text, NULL);}static GF_SVG_Parser *svg_new_parser(GF_SceneLoader *load){ GF_SVG_Parser *parser; if (load->type==GF_SM_LOAD_XSR) { if (!load->ctx) return NULL; } else if (load->type!=GF_SM_LOAD_SVG_DA) return NULL; GF_SAFEALLOC(parser, GF_SVG_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->peeked_nodes = gf_list_new(); parser->sax_parser = gf_xml_sax_new(svg_node_start, svg_node_end, svg_text_content, parser); parser->load = load; load->loader_priv = parser; if (load->ctx) load->ctx->is_pixel_metrics = 1; return parser;}GF_Err gf_sm_load_init_svg(GF_SceneLoader *load){ GF_Err e; GF_SVG_Parser *parser; if (!load->fileName) return GF_BAD_PARAM; parser = svg_new_parser(load); GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ( (load->type==GF_SM_LOAD_XSR) ? "SVG: MPEG-4 (LASER) Scene Parsing\n" : "SVG: SVG Scene Parsing\n")); e = gf_xml_sax_parse_file(parser->sax_parser, (const char *)load->fileName, svg_progress); if (e<0) return svg_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 before delete gz: %d\n", rti.gpac_memory); if (parser->sax_parser) { gf_xml_sax_del(parser->sax_parser); parser->sax_parser = NULL; } gf_sys_get_rti(0, &rti, GF_RTI_SYSTEM_MEMORY_ONLY); fprintf(stdout, "Memory usage after delete gz: %d\n", rti.gpac_memory); }#endif return parser->last_error;}GF_Err gf_sm_load_init_svg_string(GF_SceneLoader *load, char *str_data){ GF_Err e; GF_SVG_Parser *parser = (GF_SVG_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_new_parser(load); e = gf_xml_sax_init(parser->sax_parser, (unsigned char*)BOM); if (e) { svg_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(GF_SceneLoader *load){ return GF_OK;}GF_Err gf_sm_load_done_svg(GF_SceneLoader *load){ SVG_SAFExternalStream *st; GF_SVG_Parser *parser = (GF_SVG_Parser *)load->loader_priv; if (!parser) return GF_OK; while (gf_list_count(parser->node_stack)) { SVG_NodeStack *st = (SVG_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); /*FIXME - if there still are som defered listeners, we should pass them to the scene graph and wait for the parent to be defined*/ gf_list_del(parser->defered_listeners); gf_list_del(parser->peeked_nodes); /* reset animations */ gf_list_del(parser->defered_animations); if (parser->sax_parser) { gf_xml_sax_del(parser->sax_parser); } st = parser->streams; while (st) { SVG_SAFExternalStream *next = st->next; free(st->stream_name); free(st); st = next; } free(parser); load->loader_priv = NULL; return GF_OK;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -