Bool gf_svg_is_timing_tag(u32 tag) { if (gf_svg_is_animation_tag(tag)) return 1; else return (tag == TAG_SVG_animation || tag == TAG_SVG_audio || tag == TAG_LSR_conditional || tag == TAG_LSR_updates || tag == TAG_SVG_video)?1:0; }
/* Notifies the scene time to a timed element, potentially changing its status and triggering its evaluation Returns: 0 if no rendering traversal is required, 1 if a rendering traversal is required, -1 if the time node is a discard which has been deleted during this notification, -2 means that the timed element is waiting to begin, -3 means that the timed element is active but does not need further notifications (set without dur) but still requires a rendering traversal */ s32 gf_smil_timing_notify_time(SMIL_Timing_RTI *rti, Double in_scene_time) { s32 ret = 0; GF_DOM_Event evt; SMILTimingAttributesPointers *timingp = rti->timingp; Bool force_end = 0; if (!timingp) return 0; /* if the scene time is the same as it was during the previous notification, it means that the animations are paused and we don't need to evaluate it again unless the force_reevaluation flag is set */ if ((rti->scene_time == in_scene_time) && (rti->force_reevaluation == 0)) return 0; if (!rti->paused) rti->scene_time = in_scene_time; rti->force_reevaluation = 0; /* for fraction events, in all cases we indicate that the scene needs redraw */ if (rti->evaluate_status == SMIL_TIMING_EVAL_FRACTION) return 1; if (rti->evaluate_status == SMIL_TIMING_EVAL_DISCARD) { /* TODO: FIX ME discarding should send a begin event ? */ /* Since the discard can only be evaluated once, it unregisters itself from the list of timed elements to be notified, so for this special case we return -1 when the discard has actually been executed */ if (gf_smil_discard(rti, FLT2FIX(rti->scene_time))) return -1; else return 0; } gf_node_register(rti->timed_elt, NULL); waiting_to_begin: if (rti->status == SMIL_STATUS_WAITING_TO_BEGIN) { if (rti->current_interval->begin != -1 && rti->scene_time >= rti->current_interval->begin) { /* if there is a computed interval with a definite begin value and if that value is lesser than the scene time, then the animation becomes active */ GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Activating\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); rti->status = SMIL_STATUS_ACTIVE; if (rti->timed_elt->sgprivate->tag==TAG_LSR_conditional) { SVG_Element *e = (SVG_Element *)rti->timed_elt; /*activate conditional*/ if (e->children) gf_node_traverse(e->children->node, NULL); rti->status = SMIL_STATUS_DONE; } else { gf_smil_reorder_anim(rti); } memset(&evt, 0, sizeof(evt)); evt.type = GF_EVENT_BEGIN_EVENT; evt.smil_event_time = rti->current_interval->begin; gf_dom_event_fire((GF_Node *)rti->timed_elt, &evt); } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Evaluating (Not starting)\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); ret = -2; goto exit; } } if (rti->status == SMIL_STATUS_ACTIVE) { u32 cur_id; if (rti->current_interval->active_duration >= 0 && rti->scene_time >= (rti->current_interval->begin + rti->current_interval->active_duration)) { force_end: GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Stopping \n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); rti->normalized_simple_time = gf_smil_timing_get_normalized_simple_time(rti, rti->scene_time, NULL); ret = rti->postpone; if (timingp->fill && *timingp->fill == SMIL_FILL_FREEZE) { rti->status = SMIL_STATUS_FROZEN; rti->evaluate_status = SMIL_TIMING_EVAL_FREEZE; GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Preparing to freeze\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); if (!rti->postpone) { rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); } } else { rti->status = SMIL_STATUS_DONE; rti->evaluate_status = SMIL_TIMING_EVAL_REMOVE; GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Preparing to remove\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); if (!rti->postpone) { rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); } } memset(&evt, 0, sizeof(evt)); evt.type = GF_EVENT_END_EVENT; /* WARNING: begin + active_duration may be greater than 'now' because of force_end cases */ evt.smil_event_time = rti->current_interval->begin + rti->current_interval->active_duration; gf_dom_event_fire((GF_Node *)rti->timed_elt, &evt); } else { /* the animation is still active */ if (!timingp->restart || *timingp->restart == SMIL_RESTART_ALWAYS) { GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Checking for restart (always)\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); if (rti->next_interval->begin != -1 && rti->next_interval->begin < rti->scene_time) { *rti->current_interval = *rti->next_interval; gf_smil_timing_get_next_interval(rti, 0, rti->next_interval, rti->scene_time); /* mark that this element has been modified and need to be reinserted at its proper place in the list of timed elements in the scenegraph */ gf_smil_mark_modified(rti, 0); /* if this is animation, reinserting the animation in the list of animations that targets this attribute, so that it is the last one */ gf_smil_reorder_anim(rti); memset(&evt, 0, sizeof(evt)); evt.type = GF_EVENT_BEGIN_EVENT; evt.smil_event_time = rti->current_interval->begin; gf_dom_event_fire((GF_Node *)rti->timed_elt, &evt); } } ret = rti->postpone; cur_id = rti->current_interval->nb_iterations; rti->normalized_simple_time = gf_smil_timing_get_normalized_simple_time(rti, rti->scene_time, &force_end); if (force_end) { GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Forcing end (fill or remove)\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); goto force_end; } if (cur_id < rti->current_interval->nb_iterations) { GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[SMIL Timing ] Time %f - Timed element %s - Preparing to repeat\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); memset(&evt, 0, sizeof(evt)); evt.type = GF_EVENT_REPEAT_EVENT; evt.smil_event_time = rti->current_interval->begin + rti->current_interval->nb_iterations*rti->current_interval->simple_duration; evt.detail = rti->current_interval->nb_iterations; gf_dom_event_fire((GF_Node *)rti->timed_elt, &evt); rti->evaluate_status = SMIL_TIMING_EVAL_REPEAT; } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Preparing to update\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); rti->evaluate_status = SMIL_TIMING_EVAL_UPDATE; } if (!rti->postpone) { rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); } /* special case for animations with unspecified simpleDur (not with media timed elements) we need to indicate that this anim does not need to be notified anymore and that it does not require tree traversal */ if (gf_svg_is_animation_tag(rti->timed_elt->sgprivate->tag) && (rti->current_interval->simple_duration==-1) && (rti->current_interval->active_duration==-1) ) { /*GF_SceneGraph * sg = rti->timed_elt->sgprivate->scenegraph; while (sg->parent_scene) sg = sg->parent_scene; gf_list_del_item(sg->smil_timed_elements, rti); ret = -3;*/ ret = 1; } } } if ((rti->status == SMIL_STATUS_DONE) || (rti->status == SMIL_STATUS_FROZEN)) { if (!timingp->restart || *timingp->restart != SMIL_RESTART_NEVER) { /* Check changes in begin or end attributes */ GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Checking for restart when not active\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); if (rti->next_interval->begin != -1) { Bool restart_timing = 0; /*next interval is right now*/ if (rti->next_interval->begin == rti->current_interval->begin+rti->current_interval->active_duration) restart_timing = 1; /*switch intervals*/ if (rti->next_interval->begin >= rti->current_interval->begin+rti->current_interval->active_duration) { *rti->current_interval = *rti->next_interval; gf_smil_timing_print_interval(rti, 1, rti->current_interval); gf_smil_timing_get_next_interval(rti, 0, rti->next_interval, rti->scene_time); /* mark that this element has been modified and need to be reinserted at its proper place in the list of timed elements in the scenegraph */ gf_smil_mark_modified(rti, 0); } else { rti->next_interval->begin = -1; } /*if chaining to new interval, go to wait_for begin right now*/ if (restart_timing) { rti->status = SMIL_STATUS_WAITING_TO_BEGIN; rti->evaluate_status = SMIL_TIMING_EVAL_NONE; GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Returning to eval none status\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); ret = 0; goto waiting_to_begin; } /*otherwise move state to waiting for begin for next smil_timing evaluation, but don't change evaluate status for next anim evaluation*/ else { rti->status = SMIL_STATUS_WAITING_TO_BEGIN; } } else { /*??? what is this ???*/ //ret = 0; } } else if ((rti->status == SMIL_STATUS_DONE) && timingp->restart && (*timingp->restart == SMIL_RESTART_NEVER)) { /* the timed element is done and cannot restart, we don't need to evaluate it anymore */ GF_SceneGraph * sg = rti->timed_elt->sgprivate->scenegraph; while (sg->parent_scene) sg = sg->parent_scene; gf_list_del_item(sg->smil_timed_elements, rti); ret = -1; } } exit: gf_node_unregister(rti->timed_elt, NULL); return ret; }
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes) { u32 i; SVG2BIFS_Converter *converter = (SVG2BIFS_Converter *)sax_cbck; SVGPropertiesPointers *backup_props; char *id_string = NULL; u32 tag; SVG_Element *elt; SVG_DeferedAnimation *anim = NULL; tag = gf_xml_get_element_tag(name, 0); elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag); if (!gf_sg_get_root_node(converter->svg_sg)) { gf_node_register((GF_Node *)elt, NULL); gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt); } else { gf_node_register((GF_Node *)elt, converter->svg_parent); //gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt); } // fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt)); // if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent)); if (gf_svg_is_animation_tag(tag)) { GF_SAFEALLOC(anim, SVG_DeferedAnimation); /*default anim target is parent node*/ anim->animation_elt = elt; if (converter->svg_parent) { anim->target = anim->anim_parent = (SVG_Element*) converter->svg_parent; } } 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")) { 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, 0); id_string = att->value; } else if (anim && !stricmp(att->name, "to")) { anim->to = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "from")) { anim->from = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "by")) { anim->by = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "values")) { anim->values = gf_strdup(att->value); } else if (anim && (tag == TAG_SVG_animateTransform) && !stricmp(att->name, "type")) { anim->type = gf_strdup(att->value); } else { GF_FieldInfo info; 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); } else { fprintf(stdout, "Skipping attribute %s\n", att->name); } } } if (anim) { svg_parse_animation(converter->svg_sg, anim); } memset(&converter->all_atts, 0, sizeof(SVGAllAttributes)); gf_svg_flatten_attributes(elt, &converter->all_atts); backup_props = gf_malloc(sizeof(SVGPropertiesPointers)); memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers)); gf_node_set_private((GF_Node *)elt, backup_props); gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props); fprintf(stdout, "START\t%s\t%s\t%s", converter->svg_parent ? gf_node_get_class_name(converter->svg_parent) : "none", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none", name); converter->svg_parent = (GF_Node *)elt; if (!gf_sg_get_root_node(converter->bifs_sg)) { if (tag == TAG_SVG_svg) { GF_Node *node, *child; converter->bifs_sg->usePixelMetrics = 1; if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) { converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value); } else { converter->bifs_sg->width = 320; } if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) { converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value); } else { converter->bifs_sg->height = 200; } node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup); gf_node_register(node, NULL); gf_sg_set_root_node(converter->bifs_sg, node); child = gf_node_new(converter->bifs_sg, TAG_MPEG4_QuantizationParameter); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_QuantizationParameter *qp = (M_QuantizationParameter *)child; qp->useEfficientCoding = 1; } /* SVG to BIFS coordinate transformation */ child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Viewport *vp = (M_Viewport*)child; if (converter->all_atts.viewBox) { vp->size.x = converter->all_atts.viewBox->width; vp->size.y = converter->all_atts.viewBox->height; vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2; vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2); } else { vp->size.x = INT2FIX(converter->bifs_sg->width); vp->size.y = INT2FIX(converter->bifs_sg->height); vp->position.x = INT2FIX(converter->bifs_sg->width)/2; vp->position.y = -INT2FIX(converter->bifs_sg->height)/2; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Background2D *b = (M_Background2D *)child; b->backColor.red = FIX_ONE; b->backColor.green = FIX_ONE; b->backColor.blue = FIX_ONE; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; { M_Transform2D *tr = (M_Transform2D *)node; tr->scale.y = -FIX_ONE; } converter->bifs_parent = node; } } else { GF_Node *node, *child; node = converter->bifs_parent; switch(tag) { case TAG_SVG_g: { if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; } else { M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group); gf_node_register((GF_Node *)g, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g); node = (GF_Node *)g; converter->bifs_parent = node; } } break; case TAG_SVG_rect: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } if (converter->all_atts.x || converter->all_atts.y) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } { M_Transform2D *tr = (M_Transform2D *)node; if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0); if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0); } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle); gf_node_register(shape->geometry, (GF_Node *)shape); { M_Rectangle *rect = (M_Rectangle *)shape->geometry; if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value; if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value; } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_path: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } if (converter->all_atts.x || converter->all_atts.y) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } { M_Transform2D *tr = (M_Transform2D *)node; if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value; if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D); gf_node_register(shape->geometry, (GF_Node *)shape); if (converter->all_atts.d) { M_Coordinate2D *c2d; M_XCurve2D *xc = (M_XCurve2D *)shape->geometry; u32 i, j, c, k; xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D); c2d = (M_Coordinate2D *)xc->point; gf_node_register(xc->point, (GF_Node *)xc); gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points); gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points); c = 0; k = 0; j = 0; c2d->point.vals[k] = converter->all_atts.d->points[0]; k++; xc->type.vals[0] = 0; for (i = 1; i < converter->all_atts.d->n_points; ) { switch(converter->all_atts.d->tags[i]) { case GF_PATH_CURVE_ON: c2d->point.vals[k] = converter->all_atts.d->points[i]; k++; if (i-1 == converter->all_atts.d->contours[c]) { xc->type.vals[j] = 0; c++; } else { xc->type.vals[j] = 1; } i++; break; case GF_PATH_CURVE_CUBIC: c2d->point.vals[k] = converter->all_atts.d->points[i]; c2d->point.vals[k+1] = converter->all_atts.d->points[i+1]; c2d->point.vals[k+2] = converter->all_atts.d->points[i+2]; k+=3; xc->type.vals[j] = 2; if (converter->all_atts.d->tags[i+2]==GF_PATH_CLOSE) { j++; xc->type.vals[j] = 6; } i+=3; break; case GF_PATH_CLOSE: xc->type.vals[j] = 6; i++; break; case GF_PATH_CURVE_CONIC: c2d->point.vals[k] = converter->all_atts.d->points[i]; c2d->point.vals[k+1] = converter->all_atts.d->points[i+1]; k+=2; xc->type.vals[j] = 7; if (converter->all_atts.d->tags[i+1]==GF_PATH_CLOSE) { j++; xc->type.vals[j] = 6; } i+=2; break; } j++; } xc->type.count = j; c2d->point.count = k; } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_polyline: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D); gf_node_register(shape->geometry, (GF_Node *)shape); if (converter->all_atts.points) { M_Coordinate2D *c2d; M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry; u32 i; ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D); c2d = (M_Coordinate2D *)ifs->coord; gf_node_register(ifs->coord, (GF_Node *)ifs); gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points)); for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) { SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i); c2d->point.vals[i].x = p->x; c2d->point.vals[i].y = p->y; } } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_text: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Transform2D *tr = (M_Transform2D *)child; if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value; if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value; tr->scale.y = -FIX_ONE; } node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_FontStyle *fs; M_Text *text; M_Shape *shape = (M_Shape *)node; text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text); shape->geometry = (GF_Node *)text; converter->bifs_text_node = shape->geometry; gf_node_register(shape->geometry, (GF_Node *)shape); fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle); gf_node_register((GF_Node *)fs, (GF_Node*)text); text->fontStyle = (GF_Node *)fs; gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1); fs->family.vals[0] = gf_strdup(converter->svg_props.font_family->value); fs->size = converter->svg_props.font_size->value; shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_ellipse: case TAG_SVG_circle: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } if (converter->all_atts.cx || converter->all_atts.cy) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Transform2D *tr = (M_Transform2D *)child; if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value; if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value; } node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; if (tag == TAG_SVG_ellipse) { M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse); shape->geometry = (GF_Node *)e; e->radius.x = converter->all_atts.rx->value; e->radius.y = converter->all_atts.ry->value; } else { M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle); shape->geometry = (GF_Node *)c; c->radius = converter->all_atts.r->value; } gf_node_register(shape->geometry, (GF_Node *)shape); shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_defs: { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; { M_Switch *sw = (M_Switch *)node; sw->whichChoice = -1; } converter->bifs_parent = node; } break; case TAG_SVG_solidColor: { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; converter->bifs_parent = node; } break; case TAG_SVG_animateTransform: { GF_Node *child_ts; if (!gf_node_get_id(node)) { gf_node_set_id(node, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } child_ts = gf_node_new(converter->bifs_sg, TAG_MPEG4_TimeSensor); if (!gf_node_get_id(child_ts)) { gf_node_set_id(child_ts, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } gf_node_register(child_ts, node); gf_node_list_add_child(&((GF_ParentNode *)node)->children, child_ts); { M_TimeSensor *ts = (M_TimeSensor *)child_ts; if (converter->all_atts.dur) { ts->cycleInterval = converter->all_atts.dur->clock_value; } if (converter->all_atts.repeatCount && converter->all_atts.repeatCount->type == SMIL_REPEATCOUNT_INDEFINITE) { ts->loop = 1; } } if (converter->all_atts.transform_type) { GF_FieldInfo fromField, toField; switch (*converter->all_atts.transform_type) { case SVG_TRANSFORM_ROTATE: child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D); if (!gf_node_get_id(child)) { gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode *)node)->children, child); gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField); gf_node_get_field_by_name(child, "set_fraction", &toField); gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex); gf_node_get_field_by_name(child, "value_changed", &fromField); gf_node_get_field_by_name(node, "rotationAngle", &toField); gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex); { M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child; if (converter->all_atts.keyTimes) { SFFloat *g; u32 count, i; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g); *g = *f; } } if (converter->all_atts.values) { SFVec2f *g; u32 count, i; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point_Angle *p; p = gf_list_get(converter->all_atts.values->values, i); gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g); g->x = p->x; g->y = p->y; } } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_ScalarInterpolator); if (!gf_node_get_id(child)) { gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode *)node)->children, child); gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField); gf_node_get_field_by_name(child, "set_fraction", &toField); gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex); gf_node_get_field_by_name(child, "value_changed", &fromField); gf_node_get_field_by_name(node, "center", &toField); gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex); { M_ScalarInterpolator *si = (M_ScalarInterpolator *)child; if (converter->all_atts.keyTimes) { SFFloat *g; u32 count, i; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); gf_sg_vrml_mf_append(&si->key, GF_SG_VRML_MFFLOAT, &g); *g = *f; } } if (converter->all_atts.values) { SFFloat *g; u32 count, i; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point_Angle *p; p = gf_list_get(converter->all_atts.values->values, i); gf_sg_vrml_mf_append(&si->keyValue, GF_SG_VRML_MFFLOAT, &g); *g = p->angle; } } } break; case SVG_TRANSFORM_SCALE: case SVG_TRANSFORM_TRANSLATE: child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D); if (!gf_node_get_id(child)) { gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode *)node)->children, child); gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField); gf_node_get_field_by_name(child, "set_fraction", &toField); gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex); gf_node_get_field_by_name(child, "value_changed", &fromField); if (*converter->all_atts.transform_type == SVG_TRANSFORM_SCALE) gf_node_get_field_by_name(node, "scale", &toField); else gf_node_get_field_by_name(node, "translation", &toField); gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex); { M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child; if (converter->all_atts.keyTimes) { SFFloat *g; u32 count, i; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g); *g = *f; } } if (converter->all_atts.values) { SFVec2f *g; u32 count, i; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point *p; p = gf_list_get(converter->all_atts.values->values, i); gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g); g->x = p->x; g->y = p->y; } } } break; default: fprintf(stdout, "Warning: transformation type not supported \n"); } } //converter->bifs_parent = node; } break; default: { fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt)); child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); //gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; converter->bifs_parent = node; } break; } if (id_string) gf_node_set_id(converter->bifs_parent, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);//gf_node_get_name((GF_Node *)elt)); } fprintf(stdout, "\t%s\n", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none"); }