Ejemplo n.º 1
0
GF_Command *gf_sg_command_clone(GF_Command *com, GF_SceneGraph *inGraph)
{
	u32 i, count;
	GF_Command *dest;
	
	if (com->tag==GF_SG_SCENE_REPLACE) return NULL;
	/*FIXME - to do*/
	if (gf_list_count(com->new_proto_list)) return NULL;
	dest = gf_sg_command_new(inGraph, com->tag);

	/*node the command applies to - may be NULL*/
	dest->node = gf_node_clone(inGraph, com->node, NULL);
	/*route insert, replace and delete*/
	dest->RouteID = com->RouteID;
	if (com->def_name) dest->def_name = strdup(com->def_name);
	dest->fromNodeID = com->fromNodeID;
	dest->fromFieldIndex = com->fromFieldIndex;
	dest->toNodeID = com->toNodeID;
	dest->toFieldIndex = com->toFieldIndex;
	dest->del_proto_list_size = com->del_proto_list_size;
	if (com->del_proto_list_size) {
		dest->del_proto_list = (u32*)malloc(sizeof(u32) * com->del_proto_list_size);
		memcpy(dest->del_proto_list, com->del_proto_list, sizeof(u32) * com->del_proto_list_size);
	}
	count = gf_list_count(com->command_fields);
	for (i=0; i<count; i++) {
		GF_CommandField *fo = (GF_CommandField *)gf_list_get(com->command_fields, i);
		GF_CommandField *fd = (GF_CommandField *)gf_sg_command_field_new(dest);

		fd->fieldIndex = fo->fieldIndex;
		fd->fieldType = fo->fieldType;
		fd->pos = fo->pos;
		if (fo->field_ptr) {
			fd->field_ptr = gf_sg_vrml_field_pointer_new(fd->fieldType);
			gf_sg_vrml_field_copy(fd->field_ptr, fo->field_ptr, fo->fieldType);
		}

		if (fo->new_node) {
			fd->new_node = gf_node_clone(inGraph, fo->new_node, dest->node);
			fd->field_ptr = &fd->new_node;
		}
		if (fo->node_list) {
			GF_ChildNodeItem *child, *cur, *prev;
			prev = NULL;
			child = fo->node_list;
			while (child) {
				cur = (GF_ChildNodeItem*) malloc(sizeof(GF_ChildNodeItem));
				cur->node = gf_node_clone(inGraph, child->node, dest->node);
				cur->next = NULL;
				if (prev) prev->next = cur;
				else fd->node_list = cur;
				prev = cur;
				child = child->next;
			}
			fd->field_ptr = &fd->node_list;
		}
	}
	return dest;
}
Ejemplo n.º 2
0
GF_Node *gf_xml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *cloned_parent, char *inst_id, Bool deep)
{
	GF_DOMAttribute *att;
	GF_Node *clone = gf_node_new(inScene, orig->sgprivate->tag);
	if (!clone) return NULL;

	if (orig->sgprivate->tag == TAG_DOMText) {
		GF_DOMText *n_src,*n_dst;
		n_src = (GF_DOMText *)orig;
		n_dst = (GF_DOMText *)clone;
		n_dst->type = n_src->type;
		n_dst->textContent = gf_strdup(n_src->textContent);
	} else {
		if (orig->sgprivate->tag == TAG_DOMFullNode) {
			GF_DOMFullNode *n_src,*n_dst;
			n_src = (GF_DOMFullNode *)orig;
			n_dst = (GF_DOMFullNode *)clone;
			n_dst->ns = n_src->ns;
			n_dst->name = gf_strdup(n_dst->name);
		} 
		
		att = ((GF_DOMNode *)orig)->attributes;
		while (att) {
			GF_FieldInfo dst, src;
			/*create by name*/
			if (att->tag==TAG_DOM_ATT_any) {
				gf_node_get_attribute_by_name(clone, ((GF_DOMFullAttribute*)att)->name, 0, 1, 0, &dst);
			} else {
				gf_node_get_attribute_by_tag(clone, att->tag, 1, 0, &dst);
			}
			src.far_ptr = att->data;
			src.fieldType = att->data_type;
			src.fieldIndex = att->tag;
			gf_svg_attributes_copy(&dst, &src, 0);
			if (att->tag==TAG_XLINK_ATT_href) {
				XMLRI *iri = (XMLRI *)att->data;
				if (iri->target == gf_node_get_parent(orig, 0)) {
					((XMLRI *)dst.far_ptr)->target = cloned_parent;
				} else {
					((XMLRI *)dst.far_ptr)->target = NULL;
				}
			}
			att = att->next;
		}	
	}
	if (cloned_parent) {
		gf_node_list_add_child( & ((GF_ParentNode*)cloned_parent)->children, clone);
		gf_node_register(clone, cloned_parent);
		/*TO CLARIFY: can we init the node right now or should we wait for insertion in the scene tree ?*/
		gf_node_init(clone);
	}
	if (deep) {
		GF_ChildNodeItem *child = ((GF_ParentNode *)orig)->children;
		while (child) {
			gf_node_clone(inScene, child->node, clone, inst_id, 1);
			child = child->next;
		}
	}
	return clone;
}
Ejemplo n.º 3
0
GF_Command *gf_sg_vrml_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool force_clone)
{
	u32 i, count;
	GF_Command *dest;
	
	/*FIXME - to do*/
	if (gf_list_count(com->new_proto_list)) return NULL;
	dest = gf_sg_command_new(inGraph, com->tag);

	if (com->in_scene!=inGraph) force_clone = 1;

	/*node the command applies to - may be NULL*/
	if (force_clone) {
		dest->node = gf_node_clone(inGraph, com->node, NULL, "", 0);
	} else {
		dest->node = com->node;
		gf_node_register(dest->node, NULL);
	}
	/*route insert, replace and delete*/
	dest->RouteID = com->RouteID;
	if (com->def_name) dest->def_name = gf_strdup(com->def_name);
	dest->fromNodeID = com->fromNodeID;
	dest->fromFieldIndex = com->fromFieldIndex;
	dest->toNodeID = com->toNodeID;
	dest->toFieldIndex = com->toFieldIndex;
	dest->send_event_integer = com->send_event_integer;
	dest->send_event_x = com->send_event_x;
	dest->send_event_y = com->send_event_y;
	if (com->send_event_string)
		dest->send_event_string = gf_strdup(com->send_event_string);

	dest->del_proto_list_size = com->del_proto_list_size;
	if (com->del_proto_list_size) {
		dest->del_proto_list = (u32*)gf_malloc(sizeof(u32) * com->del_proto_list_size);
		memcpy(dest->del_proto_list, com->del_proto_list, sizeof(u32) * com->del_proto_list_size);
	}
	count = gf_list_count(com->command_fields);
	for (i=0; i<count; i++) {
		GF_CommandField *fo = (GF_CommandField *)gf_list_get(com->command_fields, i);
		GF_CommandField *fd = (GF_CommandField *)gf_sg_command_field_new(dest);

		fd->fieldIndex = fo->fieldIndex;
		fd->fieldType = fo->fieldType;
		fd->pos = fo->pos;

		/*FIXME - this can also be LASeR commands, not supported for now*/
		if (fo->field_ptr) {
			fd->field_ptr = gf_sg_vrml_field_pointer_new(fd->fieldType);
			gf_sg_vrml_field_clone(fd->field_ptr, fo->field_ptr, fo->fieldType, dest->in_scene);
		}

		if (fo->new_node) {
			if (force_clone) {
				fd->new_node = gf_node_clone(inGraph, fo->new_node, dest->node, "", 0);
			} else {
				fd->new_node = fo->new_node;
				gf_node_register(fd->new_node, NULL);
			}
			fd->field_ptr = &fd->new_node;
		}
		if (fo->node_list) {
			GF_ChildNodeItem *child, *cur, *prev;
			prev = NULL;
			child = fo->node_list;
			while (child) {
				cur = (GF_ChildNodeItem*) gf_malloc(sizeof(GF_ChildNodeItem));
				if (force_clone) {
					cur->node = gf_node_clone(inGraph, child->node, dest->node, "", 0);
				} else {
					cur->node = child->node;
					gf_node_register(cur->node, NULL);
				}
				cur->next = NULL;
				if (prev) prev->next = cur;
				else fd->node_list = cur;
				prev = cur;
				child = child->next;
			}
			fd->field_ptr = &fd->node_list;
		}
	}
	return dest;
}
Ejemplo n.º 4
0
static void TTD_NewTextChunk(TTDPriv *priv, GF_TextSampleDescriptor *tsd, M_Form *form, u16 *utf16_txt, TTDTextChunk *tc)
{
	GF_Node *txt_model, *n2, *txt_material;
	M_Text *text;
	M_FontStyle *fs;
	char *fontName;
	char szStyle[1024];
	u32 fontSize, styleFlags, color, i, start_char;

	if (!tc->srec) {
		fontName = TTD_FindFont(tsd, tsd->default_style.fontID);
		fontSize = tsd->default_style.font_size;
		styleFlags = tsd->default_style.style_flags;
		color = tsd->default_style.text_color;
	} else {
		fontName = TTD_FindFont(tsd, tc->srec->fontID);
		fontSize = tc->srec->font_size;
		styleFlags = tc->srec->style_flags;
		color = tc->srec->text_color;
	}

	/*create base model for text node. It will then be cloned for each text item*/
	txt_model = ttd_create_node(priv, TAG_MPEG4_Shape, NULL);
	gf_node_register(txt_model, NULL);
	n2 = ttd_create_node(priv, TAG_MPEG4_Appearance, NULL);
	((M_Shape *)txt_model)->appearance = n2;
	gf_node_register(n2, txt_model);
	txt_material = ttd_create_node(priv, TAG_MPEG4_Material2D, NULL);
	((M_Appearance *)n2)->material = txt_material;
	gf_node_register(txt_material, n2);

	((M_Material2D *)txt_material)->filled = 1;
	((M_Material2D *)txt_material)->transparency = FIX_ONE - INT2FIX((color>>24) & 0xFF) / 255;
	((M_Material2D *)txt_material)->emissiveColor.red = INT2FIX((color>>16) & 0xFF) / 255;
	((M_Material2D *)txt_material)->emissiveColor.green = INT2FIX((color>>8) & 0xFF) / 255;
	((M_Material2D *)txt_material)->emissiveColor.blue = INT2FIX((color) & 0xFF) / 255;
	/*force 0 lineWidth if blinking (the stupid MPEG-4 default values once again..)*/
	if (tc->has_blink) {
		((M_Material2D *)txt_material)->lineProps = ttd_create_node(priv, TAG_MPEG4_LineProperties, NULL);
		((M_LineProperties *)((M_Material2D *)txt_material)->lineProps)->width = 0;
		gf_node_register(((M_Material2D *)txt_material)->lineProps, txt_material);
	}

	n2 = ttd_create_node(priv, TAG_MPEG4_Text, NULL);
	((M_Shape *)txt_model)->geometry = n2;
	gf_node_register(n2, txt_model);
	text = (M_Text *) n2;
	fs = (M_FontStyle *) ttd_create_node(priv, TAG_MPEG4_FontStyle, NULL);
	gf_free(fs->family.vals[0]);

	/*translate default fonts to MPEG-4/VRML names*/
	if (!stricmp(fontName, "Serif")) fs->family.vals[0] = gf_strdup("SERIF");
	else if (!stricmp(fontName, "Sans-Serif")) fs->family.vals[0] = gf_strdup("SANS");
	else if (!stricmp(fontName, "Monospace")) fs->family.vals[0] = gf_strdup("TYPEWRITER");
	else fs->family.vals[0] = gf_strdup(fontName);

	fs->size = INT2FIX(fontSize);
	gf_free(fs->style.buffer);
	strcpy(szStyle, "");
	if (styleFlags & GF_TXT_STYLE_BOLD) {
		if (styleFlags & GF_TXT_STYLE_ITALIC) strcpy(szStyle, "BOLDITALIC");
		else strcpy(szStyle, "BOLD");
	} else if (styleFlags & GF_TXT_STYLE_ITALIC) strcat(szStyle, "ITALIC");
	if (!strlen(szStyle)) strcpy(szStyle, "PLAIN");
	/*also underline for URLs*/
	if ((styleFlags & GF_TXT_STYLE_UNDERLINED) || (tc->hlink && tc->hlink->URL)) strcat(szStyle, " UNDERLINED");

	if (tc->is_hilight) {
		if (tc->hilight_col) {
			char szTxt[50];
			sprintf(szTxt, " HIGHLIGHT#%x", tc->hilight_col);
			strcat(szStyle, szTxt);
		} else {
			strcat(szStyle, " HIGHLIGHT#RV");
		}
	}
	/*a better way would be to draw the entire text box in a composite texture & bitmap but we can't really rely
	on text box size (in MP4Box, it actually defaults to the entire video area) and drawing a too large texture
	& bitmap could slow down rendering*/
	if (priv->use_texture) strcat(szStyle, " TEXTURED");
	if (priv->outline) strcat(szStyle, " OUTLINED");

	fs->style.buffer = gf_strdup(szStyle);
	fs->horizontal = (tsd->displayFlags & GF_TXT_VERTICAL) ? 0 : 1;
	text->fontStyle = (GF_Node *) fs;
	gf_node_register((GF_Node *)fs, (GF_Node *)text);
	gf_sg_vrml_mf_reset(&text->string, GF_SG_VRML_MFSTRING);

	if (tc->hlink && tc->hlink->URL) {
		SFURL *s;
		M_Anchor *anc = (M_Anchor *) ttd_create_node(priv, TAG_MPEG4_Anchor, NULL);
		gf_sg_vrml_mf_append(&anc->url, GF_SG_VRML_MFURL, (void **) &s);
		s->OD_ID = 0;
		s->url = gf_strdup(tc->hlink->URL);
		if (tc->hlink->URL_hint) anc->description.buffer = gf_strdup(tc->hlink->URL_hint);
		gf_node_list_add_child(& anc->children, txt_model);
		gf_node_register(txt_model, (GF_Node *)anc);
		txt_model = (GF_Node *)anc;
		gf_node_register((GF_Node *)anc, NULL);
	}

	start_char = tc->start_char;
	for (i=tc->start_char; i<tc->end_char; i++) {
		Bool new_line = 0;
		if ((utf16_txt[i] == '\n') || (utf16_txt[i] == '\r') || (utf16_txt[i] == 0x85) || (utf16_txt[i] == 0x2028) || (utf16_txt[i] == 0x2029)) new_line = 1;

		if (new_line || (i+1==tc->end_char) ) {
			SFString *st;

			if (i+1==tc->end_char) i++;

			if (i!=start_char) {
				char szLine[5000];
				u32 len;
				s16 wsChunk[5000], *sp;

				/*spliting lines, duplicate node*/

				n2 = gf_node_clone(priv->sg, txt_model, NULL, "", 1);
				if (tc->hlink && tc->hlink->URL) {
					GF_Node *t = ((M_Anchor *)n2)->children->node;
					text = (M_Text *) ((M_Shape *)t)->geometry;
					txt_material = ((M_Appearance *) ((M_Shape *)t)->appearance)->material;
				} else {
					text = (M_Text *) ((M_Shape *)n2)->geometry;
					txt_material = ((M_Appearance *) ((M_Shape *)n2)->appearance)->material;
				}
				gf_sg_vrml_mf_reset(&text->string, GF_SG_VRML_MFSTRING);
				gf_node_list_add_child( &form->children, n2);
				gf_node_register(n2, (GF_Node *) form);
				ttd_add_item(form);
				/*clone node always register by default*/
				gf_node_unregister(n2, NULL);

				if (tc->has_blink && txt_material) gf_list_add(priv->blink_nodes, txt_material);


				memcpy(wsChunk, &utf16_txt[start_char], sizeof(s16)*(i-start_char));
				wsChunk[i-start_char] = 0;
				sp = &wsChunk[0];
				len = gf_utf8_wcstombs(szLine, 5000, (const unsigned short **) &sp);
				szLine[len] = 0;

				gf_sg_vrml_mf_append(&text->string, GF_SG_VRML_MFSTRING, (void **) &st);
				st->buffer = gf_strdup(szLine);
			}
			start_char = i+1;
			if (new_line) {
				ttd_add_line(form);
				if ((utf16_txt[i]=='\r') && (utf16_txt[i+1]=='\n')) i++;
			}
		}
	}
	gf_node_unregister(txt_model, NULL);
	return;
}