diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libsputext/xine_sputext_decoder.c | 102 |
1 files changed, 64 insertions, 38 deletions
diff --git a/src/libsputext/xine_sputext_decoder.c b/src/libsputext/xine_sputext_decoder.c index e8ef631ca..312b252ee 100644 --- a/src/libsputext/xine_sputext_decoder.c +++ b/src/libsputext/xine_sputext_decoder.c @@ -44,6 +44,39 @@ #define SUB_MAX_TEXT 5 /* lines */ #define SUB_BUFSIZE 256 /* chars per line */ +#define rgb2yuv(R,G,B) ((((((66*R+129*G+25*B+128)>>8)+16)<<8)|(((112*R-94*G-18*B+128)>>8)+128))<<8|(((-38*R-74*G+112*B+128)>>8)+128)) + +static uint32_t sub_palette[22]={ +/* RED */ + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(50,10,10), + rgb2yuv(120,20,20), + rgb2yuv(185,50,50), + rgb2yuv(255,70,70), +/* BLUE */ + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,0,0), + rgb2yuv(0,30,50), + rgb2yuv(0,90,120), + rgb2yuv(0,140,185), + rgb2yuv(0,170,255) +}; + +static uint8_t sub_trans[22]={ + 0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15, + 0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 +}; typedef enum { SUBTITLE_SIZE_TINY = 0, @@ -103,6 +136,9 @@ typedef struct sputext_decoder_s { osd_renderer_t *renderer; osd_object_t *osd; + int current_osd_text; + uint32_t spu_palette[OVL_PALETTE_SIZE]; + uint8_t spu_trans[OVL_PALETTE_SIZE]; int64_t img_duration; int64_t last_subtitle_end; /* no new subtitle before this vpts */ @@ -304,19 +340,23 @@ static void ogm_render_line(sputext_decoder_t *this, int x, int y, char* text) { switch (text[i]) { case '<': if (!strncmp("<b>", text+i, 3)) { - /*Do somethink to enable BOLD typeface*/ + /* enable Bold color */ + this->current_osd_text = OSD_TEXT2; i=i+3; break; } else if (!strncmp("</b>", text+i, 3)) { - /*Do somethink to disable BOLD typeface*/ + /* disable BOLD */ + this->current_osd_text = OSD_TEXT1; i=i+4; break; } else if (!strncmp("<i>", text+i, 3)) { - /*Do somethink to enable italics typeface*/ + /* enable italics color */ + this->current_osd_text = OSD_TEXT3; i=i+3; break; } else if (!strncmp("</i>", text+i, 3)) { - /*Do somethink to disable italics typeface*/ + /* disable italics */ + this->current_osd_text = OSD_TEXT1; i=i+4; break; } else if (!strncmp("<font>", text+i, 3)) { @@ -338,7 +378,7 @@ static void ogm_render_line(sputext_decoder_t *this, int x, int y, char* text) { memcpy(letter,&text[i],shift); letter[shift]=0; - this->renderer->render_text(this->osd, x, y, letter, OSD_TEXT1); + this->renderer->render_text(this->osd, x, y, letter, this->current_osd_text); this->renderer->get_text_size(this->osd, letter, &w, &dummy); x=x+w; i+=shift; @@ -373,11 +413,8 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su for (line = 0; line < this->lines; line++) /* first, check lenghts and word-wrap if needed */ { - int w, h; - if( this->ogm ) - w = ogm_get_width( this, this->text[line]); - else - this->renderer->get_text_size( this->osd, this->text[line], &w, &h); + int w; + w = ogm_get_width( this, this->text[line]); if( w > this->width ) { /* line is too long */ int chunks=(int)(w/this->width)+(w%this->width?1:0); if( this->lines+chunks <= SUB_MAX_TEXT && chunks>1 ) { /* try adding newlines while keeping existing ones */ @@ -411,7 +448,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su this->lines+=chunks-1; } else { /* regenerate all the lines to find something that better fits */ char buf[SUB_BUFSIZE*SUB_MAX_TEXT]; - int a,w,h,chunks; + int a,w,chunks; buf[0]='\0'; for(a=0;a<this->lines;a++) { if(a) { @@ -421,10 +458,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su } strcat(buf,this->text[a]); } - if( this->ogm ) - w = ogm_get_width( this, buf); - else - this->renderer->get_text_size( this->osd, buf, &w, &h); + w = ogm_get_width( this, buf); chunks=(int)(w/this->width)+(w%this->width?1:0); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Complete subtitle line splitting in %i chunks\n",chunks); if(chunks<=SUB_MAX_TEXT) {/* if the length is over than SUB_MAX_TEXT*this->width nothing can be done */ @@ -461,11 +495,8 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su for (line = 0; line < this->lines; line++) /* first, check lenghts and word-wrap if needed */ { - int w, h; - if( this->ogm ) - w = ogm_get_width( this, this->text[line]); - else - this->renderer->get_text_size( this->osd, this->text[line], &w, &h); + int w; + w = ogm_get_width( this, this->text[line]); if( w > this->width ) { /* line is too long */ int chunks=(int)(w/this->width)+(w%this->width?1:0); if( this->lines+chunks <= SUB_MAX_TEXT && chunks>1 ) { /* try adding newlines while keeping existing ones */ @@ -499,7 +530,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su this->lines+=chunks-1; } else { /* regenerate all the lines to find something that better fits */ char buf[SUB_BUFSIZE*SUB_MAX_TEXT]; - int a,w,h,chunks; + int a,w,chunks; buf[0]='\0'; for(a=0;a<this->lines;a++) { if(a) { @@ -509,10 +540,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su } strcat(buf,this->text[a]); } - if( this->ogm ) - w = ogm_get_width( this, buf); - else - this->renderer->get_text_size( this->osd, buf, &w, &h); + w = ogm_get_width( this, buf); chunks=(int)(w/this->width)+(w%this->width?1:0); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Complete subtitle line splitting in %i chunks\n",chunks); if(chunks<=SUB_MAX_TEXT) {/* if the length is over than SUB_MAX_TEXT*this->width nothing can be done */ @@ -548,14 +576,10 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su y = (SUB_MAX_TEXT - this->lines) * this->line_height; for (line = 0; line < this->lines; line++) { - int w, h, x; + int w, x; while(1) { - if( this->ogm ) - w = ogm_get_width( this, this->text[line]); - else - this->renderer->get_text_size( this->osd, this->text[line], - &w, &h); + w = ogm_get_width( this, this->text[line]); x = (this->width - w) / 2; if( w > this->width && font_size > 16 ) { @@ -566,12 +590,7 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su } } - if( this->ogm ) { - ogm_render_line(this, x, y + line*this->line_height, this->text[line]); - } else { - this->renderer->render_text (this->osd, x, y + line * this->line_height, - this->text[line], OSD_TEXT1); - } + ogm_render_line(this, x, y + line*this->line_height, this->text[line]); } if( font_size != this->font_size ) @@ -583,6 +602,11 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su this->last_subtitle_end = sub_end; this->renderer->set_text_palette (this->osd, -1, OSD_TEXT1); + this->renderer->get_palette(this->osd, this->spu_palette, this->spu_trans); + /* append some colors for colored typeface tag */ + memcpy(this->spu_palette+OSD_TEXT2, sub_palette, sizeof(sub_palette)); + memcpy(this->spu_trans+OSD_TEXT2, sub_trans, sizeof(sub_trans)); + this->renderer->set_palette(this->osd, this->spu_palette, this->spu_trans); if (this->unscaled) this->renderer->show_unscaled (this->osd, sub_start); @@ -626,7 +650,9 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { this->buf_encoding = buf->decoder_info_ptr[2]; else this->buf_encoding = NULL; - + + this->current_osd_text = OSD_TEXT1; + if( (buf->type & 0xFFFF0000) == BUF_SPU_OGM ) { this->ogm = 1; |