static void svg_traverse_text_block(GF_Node *node, SVGAllAttributes *atts, GF_TraverseState *tr_state, GF_List *spans) { GF_ChildNodeItem *child; Bool is_switch = GF_FALSE; switch (gf_node_get_tag(node)) { case TAG_DOMText: svg_traverse_domtext(node, atts, tr_state, spans, NULL); break; case TAG_SVG_tspan: /*mark tspan as dirty to force rebuild*/ gf_node_dirty_set(node, 0, GF_FALSE); gf_node_traverse(node, tr_state); break; case TAG_SVG_switch: is_switch = GF_TRUE; case TAG_SVG_a: child = ((GF_ParentNode *)node)->children; while (child) { if (is_switch) { SVGAllAttributes a_atts; gf_svg_flatten_attributes((SVG_Element*)child->node, &a_atts); if (compositor_svg_evaluate_conditional(tr_state->visual->compositor, &a_atts)) { svg_traverse_text_block(child->node, atts, tr_state, spans); break; } } else if (gf_node_get_tag(child->node)==TAG_DOMText) { svg_traverse_domtext(child->node, atts, tr_state, spans, node); } child = child->next; } break; default: break; } }
Bool compositor_svg_traverse_base(GF_Node *node, SVGAllAttributes *atts, GF_TraverseState *tr_state, SVGPropertiesPointers *backup_props, u32 *backup_flags) { u32 inherited_flags_mask, flags; if (atts->requiredFeatures || atts->requiredExtensions || atts->systemLanguage || atts->requiredFonts || atts->requiredFormats) { if (!compositor_svg_evaluate_conditional(tr_state->visual->compositor, atts)) return 0; } memcpy(backup_props, tr_state->svg_props, sizeof(SVGPropertiesPointers)); *backup_flags = tr_state->svg_flags; #if 0 // applying inheritance and determining which group of properties are being inherited inherited_flags_mask = gf_svg_apply_inheritance(atts, tr_state->svg_props); gf_svg_apply_animations(node, tr_state->svg_props); // including again inheritance if values are 'inherit' #else /* animation (including possibly inheritance) then full inheritance */ gf_svg_apply_animations(node, tr_state->svg_props); inherited_flags_mask = gf_svg_apply_inheritance(atts, tr_state->svg_props); // gf_svg_apply_inheritance_no_inheritance(atts, tr_state->svg_props); // inherited_flags_mask = 0xFFFFFFFF; #endif tr_state->svg_flags &= inherited_flags_mask; flags = gf_node_dirty_get(node); tr_state->svg_flags |= flags; return 1; }
static void svg_compute_text_width(GF_Node *node, SVGAllAttributes *atts, GF_TraverseState *tr_state ) { GF_ChildNodeItem *child; Bool is_switch = GF_FALSE; /*compute length of all text blocks*/ switch (gf_node_get_tag(node)) { case TAG_DOMText: get_domtext_width(node, atts, tr_state); break; case TAG_SVG_tspan: get_tspan_width(node, tr_state); break; case TAG_SVG_switch: is_switch = GF_TRUE; case TAG_SVG_a: child = ((GF_ParentNode *)node)->children; while (child) { if (is_switch) { SVGAllAttributes a_atts; gf_svg_flatten_attributes((SVG_Element*)child->node, &a_atts); if (compositor_svg_evaluate_conditional(tr_state->visual->compositor, &a_atts)) { svg_compute_text_width(child->node, atts, tr_state); break; } } else { svg_compute_text_width(child->node, atts, tr_state); } child = child->next; } break; default: break; } }
static void svg_traverse_switch(GF_Node *node, void *rs, Bool is_destroy) { GF_Matrix2D backup_matrix; GF_Matrix mx_3d; SVGPropertiesPointers backup_props; u32 backup_flags; s32 *selected_idx = gf_node_get_private(node); u32 styling_size = sizeof(SVGPropertiesPointers); SVGAllAttributes all_atts; GF_TraverseState *tr_state = (GF_TraverseState *) rs; if (is_destroy) { gf_free(selected_idx); gf_sc_check_focus_upon_destroy(node); return; } gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (gf_node_dirty_get(node)) { u32 pos = 0; GF_ChildNodeItem *child = ((SVG_Element*)node)->children; *selected_idx = -1; while (child) { SVGAllAttributes atts; gf_svg_flatten_attributes((SVG_Element *)child->node, &atts); if (compositor_svg_evaluate_conditional(tr_state->visual->compositor, &atts)) { *selected_idx = pos; break; } pos++; child = child->next; } drawable_reset_group_highlight(tr_state, node); gf_node_dirty_clear(node, 0); } if (!compositor_svg_traverse_base(node, &all_atts, tr_state, &backup_props, &backup_flags)) return; if (compositor_svg_is_display_off(tr_state->svg_props)) { memcpy(tr_state->svg_props, &backup_props, styling_size); tr_state->svg_flags = backup_flags; return; } if (*selected_idx >= 0) { compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d); if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) { gf_sc_get_nodes_bounds(node, ((SVG_Element *)node)->children, tr_state, selected_idx); } else if (*selected_idx >= 0) { GF_Node *child = gf_node_list_get_child(((SVG_Element *)node)->children, *selected_idx); gf_node_traverse(child, tr_state); drawable_check_focus_highlight(node, tr_state, NULL); } compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d); } memcpy(tr_state->svg_props, &backup_props, styling_size); tr_state->svg_flags = backup_flags; }