⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timedtext_dec.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
	}}static void ttd_set_scroll_fraction(GF_Node *node){	Fixed frac;	TTDPriv *priv = (TTDPriv *)gf_node_get_private(node);	frac = priv->process_scroll->set_fraction;	if (frac==FIX_ONE) priv->is_active = 0;	if (!priv->tr_scroll) return;		switch (priv->scroll_type - 1) {	case GF_TXT_SCROLL_CREDITS:	case GF_TXT_SCROLL_DOWN:		priv->tr_scroll->translation.x = 0;		if (priv->scroll_mode & GF_TXT_SCROLL_IN) {			if (frac>priv->scroll_time) {				priv->scroll_mode &= ~GF_TXT_SCROLL_IN;				priv->tr_scroll->translation.y = 0;			} else {				priv->tr_scroll->translation.y = gf_muldiv(priv->dlist->size.y, frac, priv->scroll_time) - priv->dlist->size.y;			}		} else if (priv->scroll_mode & GF_TXT_SCROLL_OUT) {			if (frac < FIX_ONE - priv->scroll_time) return;			frac -= FIX_ONE - priv->scroll_time;			if (priv->scroll_type - 1 == GF_TXT_SCROLL_DOWN) {				priv->tr_scroll->translation.y = gf_muldiv(priv->dlist->size.y, frac, priv->scroll_time);			} else {				priv->tr_scroll->translation.y = gf_muldiv(priv->dlist->size.y, frac, priv->scroll_time);			}		}			if (priv->scroll_type - 1 == GF_TXT_SCROLL_DOWN) priv->tr_scroll->translation.y *= -1;		break;	case GF_TXT_SCROLL_MARQUEE:	case GF_TXT_SCROLL_RIGHT:		priv->tr_scroll->translation.y = 0;		if (priv->scroll_mode & GF_TXT_SCROLL_IN) {			if (! (priv->scroll_mode & GF_TXT_SCROLL_OUT)) {				if (frac<priv->scroll_delay) return;				frac-=priv->scroll_delay;			}			if (frac>priv->scroll_time) {				priv->scroll_mode &= ~GF_TXT_SCROLL_IN;				priv->tr_scroll->translation.x = 0;			} else {				priv->tr_scroll->translation.x = gf_muldiv(priv->dlist->size.x, frac, priv->scroll_time) - priv->dlist->size.x;			}		} else if (priv->scroll_mode & GF_TXT_SCROLL_OUT) {			if (frac < FIX_ONE - priv->scroll_time) return;			frac -= FIX_ONE - priv->scroll_time;			priv->tr_scroll->translation.x = gf_muldiv(priv->dlist->size.x, frac, priv->scroll_time);		}		if (priv->scroll_type - 1 == GF_TXT_SCROLL_MARQUEE) priv->tr_scroll->translation.x *= -1;		break;	default:		break;	}	gf_node_changed((GF_Node *)priv->tr_scroll, NULL);}static void TTD_ResetDisplay(TTDPriv *priv){	gf_list_reset(priv->blink_nodes);	gf_node_unregister_children((GF_Node*)priv->dlist, priv->dlist->children);	priv->dlist->children = NULL;	gf_node_changed((GF_Node *) priv->dlist, NULL);	priv->tr_scroll = NULL;}char *TTD_FindFont(GF_TextSampleDescriptor *tsd, u32 ID){	u32 i;	for (i=0; i<tsd->font_count; i++) {		if (tsd->fonts[i].fontID==ID) return tsd->fonts[i].fontName;	}	return "SERIF";}static void ttd_add_item(M_Form *form){	s32 *new_gr;	gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &new_gr);	(*new_gr) = gf_node_list_get_count(form->children);	gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &new_gr);	(*new_gr) = -1;	/*store line info*/	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &new_gr);	(*new_gr) = gf_node_list_get_count(form->children);}static void ttd_add_line(M_Form *form){	s32 *new_gr;	gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &new_gr);	(*new_gr) = -1;}typedef struct{	u32 start_char, end_char;	GF_StyleRecord *srec;	Bool is_hilight;	u32 hilight_col;	/*0 means RV*/	GF_TextHyperTextBox *hlink;	Bool has_blink;	/*karaoke not done yet*/	/*text wrapping is not supported - we will need to move to Layout (rather than form), and modify	layout to handle new lines and proper scrolling*/} TTDTextChunk;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);	free(fs->family.vals[0]);		/*translate default fonts to MPEG-4/VRML names*/	if (!stricmp(fontName, "Serif")) fs->family.vals[0] = strdup("SERIF");	else if (!stricmp(fontName, "Sans-Serif")) fs->family.vals[0] = strdup("SANS");	else if (!stricmp(fontName, "Monospace")) fs->family.vals[0] = strdup("TYPEWRITER");	else fs->family.vals[0] = strdup(fontName);	fs->size = INT2FIX(fontSize);	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");	fs->style.buffer = 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 = strdup(tc->hlink->URL);		if (tc->hlink->URL_hint) anc->description.buffer = 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);				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 = 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;}/*mod can be any of TextHighlight, TextKaraoke, TextHyperText, TextBlink*/void TTD_SplitChunks(GF_TextSample *txt, u32 nb_chars, GF_List *chunks, GF_Box *mod){	TTDTextChunk *tc;	u32 start_char, end_char;	u32 i;	switch (mod->type) {	/*these 3 can be safelly typecasted to the same struct for start/end char*/	case GF_ISOM_BOX_TYPE_HLIT:	case GF_ISOM_BOX_TYPE_HREF:	case GF_ISOM_BOX_TYPE_BLNK:		start_char = ((GF_TextHighlightBox *)mod)->startcharoffset;		end_char = ((GF_TextHighlightBox *)mod)->endcharoffset;		break;	case GF_ISOM_BOX_TYPE_KROK:	default:		return;	}	if (end_char>nb_chars) end_char = nb_chars;	i=0;	while ((tc = (TTDTextChunk *)gf_list_enum(chunks, &i))) {		if (tc->end_char<=start_char) continue;		/*need to split chunk at begin*/		if (tc->start_char<start_char) {			TTDTextChunk *tc2;			tc2 = (TTDTextChunk *) malloc(sizeof(TTDTextChunk));			memcpy(tc2, tc, sizeof(TTDTextChunk));			tc2->start_char = start_char;			tc2->end_char = tc->end_char;			tc->end_char = start_char;			gf_list_insert(chunks, tc2, i+1);			i++;			tc = tc2;		}		/*need to split chunks at end*/		if (tc->end_char>end_char) {			TTDTextChunk *tc2;			tc2 = (TTDTextChunk *) malloc(sizeof(TTDTextChunk));			memcpy(tc2, tc, sizeof(TTDTextChunk));			tc2->start_char = tc->start_char;			tc2->end_char = end_char;			tc->start_char = end_char;			gf_list_insert(chunks, tc2, i);			i++;			tc = tc2;		}		/*assign mod*/		switch (mod->type) {		case GF_ISOM_BOX_TYPE_HLIT:			tc->is_hilight = 1;			if (txt->highlight_color) tc->hilight_col = txt->highlight_color->hil_color;			break;		case GF_ISOM_BOX_TYPE_HREF:			tc->hlink = (GF_TextHyperTextBox *) mod;			break;		case GF_ISOM_BOX_TYPE_BLNK:			tc->has_blink = 1;			break;		}		/*done*/		if (tc->end_char==end_char) return;	}}static void TTD_ApplySample(TTDPriv *priv, GF_TextSample *txt, u32 sdi, Bool is_utf_16, u32 sample_duration){	u32 i, nb_lines, start_idx, count;	s32 *id, thw, thh, tw, th, offset;	Bool vertical;	MFInt32 idx;	SFString *s;	GF_BoxRecord br;	M_Material2D *n;	M_Form *form;	u16 utf16_text[5000];	u32 char_offset, char_count;	GF_List *chunks;	TTDTextChunk *tc;	GF_Box *a;	GF_TextSampleDescriptor *td = NULL;		/*stop timer sensor*/	if (gf_list_count(priv->blink_nodes)) {		priv->ts_blink->stopTime = gf_node_get_scene_time((GF_Node *) priv->ts_blink);		gf_node_changed((GF_Node *) priv->ts_blink, NULL);	}		priv->ts_scroll->stopTime = gf_node_get_scene_time((GF_Node *) priv->ts_scroll);	gf_node_changed((GF_Node *) priv->ts_scroll, NULL);	/*flush routes to avoid getting the set_fraction of the scroll sensor deactivation*/	gf_sg_activate_routes(priv->inlineScene->graph);	TTD_ResetDisplay(priv);	if (!sdi || !txt || !txt->len) return;	i=0;	while ((td = (GF_TextSampleDescriptor *)gf_list_enum(priv->cfg->sample_descriptions, &i))) {		if (td->sample_index==sdi) break;		td = NULL;	}	if (!td) return;		vertical = (td->displayFlags & GF_TXT_VERTICAL) ? 1 : 0;	/*set back color*/	/*do we fill the text box or the entire text track region*/	if (td->displayFlags & GF_TXT_FILL_REGION) {		priv->mat_box->transparency = FIX_ONE;		n = priv->mat_track;	} else {		priv->mat_track->transparency = FIX_ONE;		n = priv->mat_box;	}	n->transparency = FIX_ONE - INT2FIX((td->back_color>>24) & 0xFF) / 255;	n->emissiveColor.red = INT2FIX((td->back_color>>16) & 0xFF) / 255;	n->emissiveColor.green = INT2FIX((td->back_color>>8) & 0xFF) / 255;	n->emissiveColor.blue = INT2FIX((td->back_color) & 0xFF) / 255;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -