static GFINLINE GF_Node *ttd_create_node(TTDPriv *ttd, u32 tag, const char *def_name) { GF_Node *n = gf_node_new(ttd->sg, tag); if (n) { if (def_name) gf_node_set_id(n, gf_sg_get_next_available_node_id(ttd->sg), def_name); gf_node_init(n); } return n; }
GF_Node *V4SceneGraph::CopyNode(GF_Node *node, GF_Node *parent, bool copy) { if (copy) return CloneNodeForEditing(m_pSg, node); u32 nodeID = gf_node_get_id(node); if (!nodeID) { nodeID = gf_sg_get_next_available_node_id(m_pSg); gf_node_set_id(node, nodeID, NULL); gf_node_register(node, parent); } return node; }
// CreateDictionnary -- Create the root node of the dictionnary and populates it void V4SceneManager::CreateDictionnary() { GF_Node * root = gf_sg_get_root_node(m_pIs->graph); dictionnary = NewNode(TAG_MPEG4_Switch); // Insert the dictionnary in the scene and gives it a name gf_node_insert_child(root, dictionnary, 0); gf_node_register(dictionnary, root); gf_node_set_id(dictionnary, gf_sg_get_next_available_node_id(m_pIs->graph), DICTNAME); // makes the dictionnary invisible // the number 1 field is the "whichChoice", setting it to -1 makes it display nothing GF_FieldInfo field; gf_node_get_field(dictionnary, 1, &field); frame->GetFieldView()->SetFieldValue(field, &wxString("-1"), -1); // TODO : maybe put the method SetFieldValue somewhere more accessible // populates dictionnary with the root node of the scene AddToDictionnary(root); }
void V4SceneManager::CreateIDandAddToPool(GF_Node *node) { // gets a node ID u32 id = gf_sg_get_next_available_node_id(GetSceneGraph()); char d[10]; // supposes no more than 1 000 000 000 objects // queries the pool to know which number to use for the name itoa(pools.GetCount(gf_node_get_tag(node)), d, 10); char c[50]; strcpy(c, gf_node_get_class_name(node)); strncat(c, "_", 1); strncat(c, d, 10); gf_node_set_id(node, id, c); // assigns NodeID and name pools.Add(node); // adds to the node pool }
GF_Node *gf_bifs_dec_node(GF_BifsDecoder * codec, GF_BitStream *bs, u32 NDT_Tag) { u32 nodeID, NDTBits, node_type, node_tag, ProtoID, BVersion; Bool skip_init, reset_qp14; GF_Node *new_node; GF_Err e; GF_Proto *proto; void SetupConditional(GF_BifsDecoder *codec, GF_Node *node); //to store the UseName char name[1000]; #if 0 /*should only happen with inputSensor, in which case this is BAAAAD*/ if (!codec->info) { codec->LastError = GF_BAD_PARAM; return NULL; } #endif BVersion = GF_BIFS_V1; /*this is a USE statement*/ if (gf_bs_read_int(bs, 1)) { nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); /*NULL node is encoded as USE with ID = all bits to 1*/ if (nodeID == (u32) (1<<codec->info->config.NodeIDBits)) return NULL; //find node and return it new_node = gf_sg_find_node(codec->current_graph, nodeID); if (!new_node) { codec->LastError = GF_SG_UNKNOWN_NODE; } else { /*restore QP14 length*/ switch (gf_node_get_tag(new_node)) { case TAG_MPEG4_Coordinate: { u32 nbCoord = ((M_Coordinate *)new_node)->point.count; gf_bifs_dec_qp14_enter(codec, 1); gf_bifs_dec_qp14_set_length(codec, nbCoord); gf_bifs_dec_qp14_enter(codec, 0); } break; case TAG_MPEG4_Coordinate2D: { u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count; gf_bifs_dec_qp14_enter(codec, 1); gf_bifs_dec_qp14_set_length(codec, nbCoord); gf_bifs_dec_qp14_enter(codec, 0); } break; } } return new_node; } //this is a new node nodeID = 0; name[0] = 0; node_tag = 0; proto = NULL; //browse all node groups while (1) { NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion); /*this happens in replacescene where no top-level node is present (externProto)*/ if ((BVersion==1) && (NDTBits > 8 * gf_bs_available(bs)) ) { codec->LastError = GF_OK; return NULL; } node_type = gf_bs_read_int(bs, NDTBits); if (node_type) break; //increment BIFS version BVersion += 1; //not supported if (BVersion > GF_BIFS_NUM_VERSION) { codec->LastError = GF_BIFS_UNKNOWN_VERSION; return NULL; } } if (BVersion==2 && node_type==1) { ProtoID = gf_bs_read_int(bs, codec->info->config.ProtoIDBits); /*look in current graph for the proto - this may be a proto graph*/ proto = gf_sg_find_proto(codec->current_graph, ProtoID, NULL); /*this was in proto so look in main scene*/ if (!proto && codec->current_graph != codec->scenegraph) proto = gf_sg_find_proto(codec->scenegraph, ProtoID, NULL); if (!proto) { codec->LastError = GF_SG_UNKNOWN_NODE; return NULL; } } else { node_tag = gf_bifs_ndt_get_node_type(NDT_Tag, node_type, BVersion); } /*special handling of 3D mesh*/ if ((node_tag == TAG_MPEG4_IndexedFaceSet) && codec->info->config.Use3DMeshCoding) { if (gf_bs_read_int(bs, 1)) { nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); if (codec->UseName) gf_bifs_dec_name(bs, name); } /*parse the 3DMesh node*/ return NULL; } /*unknow node*/ if (!node_tag && !proto) { codec->LastError = GF_SG_UNKNOWN_NODE; return NULL; } /*DEF'd flag*/ if (gf_bs_read_int(bs, 1)) { if (!codec->info->config.NodeIDBits) { codec->LastError = GF_NON_COMPLIANT_BITSTREAM; return NULL; } nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); if (codec->UseName) gf_bifs_dec_name(bs, name); } new_node = NULL; skip_init = 0; /*don't check node IDs duplicate since VRML may use them...*/ #if 0 /*if a node with same DEF is already in the scene, use it we don't do that in memory mode because commands may force replacement of a node with a new node with same ID, and we want to be able to dump it (otherwise we would dump a USE)*/ if (nodeID && !codec->dec_memory_mode) { new_node = gf_sg_find_node(codec->current_graph, nodeID); if (new_node) { if (proto) { if ((gf_node_get_tag(new_node) != TAG_ProtoNode) || (gf_node_get_proto(new_node) != proto)) { codec->LastError = GF_NON_COMPLIANT_BITSTREAM; return NULL; } skip_init = 1; } else { if (gf_node_get_tag(new_node) != node_tag) { codec->LastError = GF_NON_COMPLIANT_BITSTREAM; return NULL; } skip_init = 1; } } } #endif if (!new_node) { if (proto) { skip_init = 1; /*create proto interface*/ new_node = gf_sg_proto_create_instance(codec->current_graph, proto); } else { new_node = gf_node_new(codec->current_graph, node_tag); } } if (!new_node) { codec->LastError = GF_NOT_SUPPORTED; return NULL; } /*VRML: "The transformation hierarchy shall be a directed acyclic graph; results are undefined if a node in the transformation hierarchy is its own ancestor" that's good, because the scene graph can't handle cyclic graphs (destroy will never be called). We therefore only register the node once parsed*/ if (nodeID) { if (strlen(name)) { gf_node_set_id(new_node, nodeID, name); } else { gf_node_set_id(new_node, nodeID, NULL); } } /*update default time fields except in proto parsing*/ if (!codec->pCurrentProto) UpdateTimeNode(codec, new_node); /*nodes are only init outside protos */ else skip_init = 1; /*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/ reset_qp14 = !codec->coord_stored; /*QP 14 is a special quant mode for IndexFace/Line(2D)Set to quantize the coordonate(2D) child, based on the first field parsed we must check the type of the node and notfy the QP*/ switch (node_tag) { case TAG_MPEG4_Coordinate: case TAG_MPEG4_Coordinate2D: gf_bifs_dec_qp14_enter(codec, 1); } if (gf_bs_read_int(bs, 1)) { e = gf_bifs_dec_node_mask(codec, bs, new_node, proto ? 1 : 0); } else { e = gf_bifs_dec_node_list(codec, bs, new_node, proto ? 1 : 0); } if (codec->coord_stored && reset_qp14) gf_bifs_dec_qp14_reset(codec); if (e) { codec->LastError = e; /*register*/ gf_node_register(new_node, NULL); /*unregister (deletes)*/ gf_node_unregister(new_node, NULL); return NULL; } if (!skip_init) gf_node_init(new_node); switch (node_tag) { case TAG_MPEG4_Coordinate: case TAG_MPEG4_Coordinate2D: gf_bifs_dec_qp14_enter(codec, 0); break; case TAG_MPEG4_Script: /*load script if in main graph (useless to load in proto declaration)*/ if (codec->scenegraph == codec->current_graph) { gf_sg_script_load(new_node); } break; /*conditionals must be init*/ case TAG_MPEG4_Conditional: SetupConditional(codec, new_node); break; } /*proto is initialized upon the first traversal to have the same behavior as wth BT/XMT loading*/ #if 0 /*if new node is a proto and we're in the top scene, load proto code*/ if (proto && (codec->scenegraph == codec->current_graph)) { codec->LastError = gf_sg_proto_load_code(new_node); } #endif return new_node; }
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"); }
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes) { u32 i; SVG_SANI_BIFS_Converter *converter = (SVG_SANI_BIFS_Converter *)sax_cbck; SVGPropertiesPointers *backup_props; char *id_string = NULL; u32 tag = gf_svg_get_element_tag(name); SVG_Element *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); } converter->svg_parent = (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)); 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 { 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); } } } 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); 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); /* 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); if (converter->all_atts.viewBox) { M_Viewport *vp = (M_Viewport*)child; 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 { M_Viewport *vp = (M_Viewport*)child; 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(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(converter, node); 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(converter, node); 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; 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); j= 0; for (i = 0; i < converter->all_atts.d->n_points; i++) { if (converter->all_atts.d->tags[i] != GF_PATH_CLOSE || i == converter->all_atts.d->n_points-1) { c2d->point.vals[j] = converter->all_atts.d->points[i]; j++; } } c2d->point.count = j; gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points); c = 0; j = 0; xc->type.vals[0] = 0; for (i = 1; i < converter->all_atts.d->n_points; i++) { switch(converter->all_atts.d->tags[i]) { case GF_PATH_CURVE_ON: if (c < converter->all_atts.d->n_contours && i-1 == converter->all_atts.d->contours[c]) { xc->type.vals[j] = 0; c++; } else { xc->type.vals[j] = 1; } break; case GF_PATH_CURVE_CUBIC: xc->type.vals[j] = 2; i+=2; break; case GF_PATH_CLOSE: xc->type.vals[j] = 6; break; case GF_PATH_CURVE_CONIC: xc->type.vals[j] = 7; i++; break; } j++; } xc->type.count = j; } 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(converter, node); 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(converter, node); 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] = 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(converter, node); 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; 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_node_get_id((GF_Node *)elt), gf_node_get_name((GF_Node *)elt)); } }