From 28bb8ccf2791599f24ec705c6075a747d7f10030 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Wed, 26 Mar 2003 11:06:39 +0000 Subject: - font encoding cleanup patch by Frantisek Dvorak - xinefonts use unicode now - fix endianess in xine-fontconv.c - public render text api uses locale CVS patchset: 4486 CVS date: 2003/03/26 11:06:39 --- src/input/input_dvb.c | 1 + src/libspucc/cc_decoder.c | 8 ++- src/libsputext/demux_sputext.c | 55 +----------------- src/libsputext/xine_decoder.c | 34 +++++++---- src/xine-engine/osd.c | 119 ++++++++++++++++++++++++++++++++++----- src/xine-engine/osd.h | 4 +- src/xine-engine/xine_interface.c | 4 +- 7 files changed, 140 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c index 12eac8114..a6e428782 100644 --- a/src/input/input_dvb.c +++ b/src/input/input_dvb.c @@ -369,6 +369,7 @@ static void osd_show_channel (dvb_input_plugin_t *this) { if ( (channel >= 0) && (channel < this->num_channels) ) this->stream->osd_renderer->render_text (this->osd, 10, 10+i*35, this->channels[channel].name, + "iso-8859-1", OSD_TEXT3); channel ++; } diff --git a/src/libspucc/cc_decoder.c b/src/libspucc/cc_decoder.c index fd3238e55..ca52f869e 100644 --- a/src/libspucc/cc_decoder.c +++ b/src/libspucc/cc_decoder.c @@ -20,7 +20,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: cc_decoder.c,v 1.19 2003/03/08 14:11:52 mroi Exp $ + * $Id: cc_decoder.c,v 1.20 2003/03/26 11:06:55 miguelfreitas Exp $ * * stuff needed to provide closed captioning decoding and display * @@ -641,9 +641,11 @@ static void ccrow_render(cc_renderer_t *renderer, cc_row_t *this, int rownum) buf[i - seg_pos[seg]] = this->cells[i].c; buf[seg_pos[seg + 1] - seg_pos[seg]] = '\0'; ccrow_set_attributes(renderer, this, seg_attr[seg]); + + /* text is already mapped from EIA-608 into iso-8859-1 */ osd_renderer->render_text(renderer->cap_display, - x + cumulative_seg_width[seg], y, buf, - textcol); + x + cumulative_seg_width[seg], y, buf, + "iso-8859-1", textcol); } pos = ccrow_find_next_text_part(this, endpos); diff --git a/src/libsputext/demux_sputext.c b/src/libsputext/demux_sputext.c index 53cb182a2..db0c96b59 100644 --- a/src/libsputext/demux_sputext.c +++ b/src/libsputext/demux_sputext.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_sputext.c,v 1.12 2003/02/14 16:58:36 f1rmb Exp $ + * $Id: demux_sputext.c,v 1.13 2003/03/26 11:06:56 miguelfreitas Exp $ * * code based on old libsputext/xine_decoder.c * @@ -42,7 +42,6 @@ #include #include #include -#include #include "xine_internal.h" #include "xineutils.h" @@ -707,7 +706,6 @@ static subtitle_t *sub_read_file (demux_sputext_t *this) { sub_read_line_aqt }; - iconv_t iconv_descr; this->format=sub_autodetect (this); if (this->format==-1) { @@ -725,10 +723,9 @@ static subtitle_t *sub_read_file (demux_sputext_t *this) { first = (subtitle_t *) xine_xmalloc(n_max*sizeof(subtitle_t)); if(!first) return NULL; - iconv_descr=iconv_open(class->dst_encoding,class->src_encoding); - while(1){ subtitle_t *sub; + if(this->num>=n_max){ n_max+=16; first=realloc(first,n_max*sizeof(subtitle_t)); @@ -746,28 +743,9 @@ static subtitle_t *sub_read_file (demux_sputext_t *this) { if (this->num > 0 && first[this->num-1].end == -1) { first[this->num-1].end = sub->start; } - for(i=0; inum].lines; i++) - { char *tmp; - char *in_buff, *out_buff; - int in_len, out_len; - - in_len=strlen(first[this->num].text[i])+1; - tmp=malloc(in_len); - in_buff=first[this->num].text[i]; - out_buff=tmp; - out_len=in_len; - if ((size_t)(-1)!=iconv(iconv_descr,&in_buff,&in_len,&out_buff,&out_len)) - { free(first[this->num].text[i]); - first[this->num].text[i]=tmp; - } - else { - printf("demux_sputext: Can't convert subtitle text\n"); - } - } ++this->num; /* Error vs. Valid */ } } - iconv_close(iconv_descr); printf ("demux_sputext: Read %i subtitles", this->num); if (this->errs) @@ -778,24 +756,6 @@ static subtitle_t *sub_read_file (demux_sputext_t *this) { return first; } -static void update_osd_src_encoding(void *this_gen, xine_cfg_entry_t *entry) -{ - demux_sputext_class_t *class = (demux_sputext_class_t *)this_gen; - - class->src_encoding = entry->str_value; - - printf("demux_sputext: spu_src_encoding = %s\n", class->src_encoding ); -} - -static void update_osd_dst_encoding(void *this_gen, xine_cfg_entry_t *entry) -{ - demux_sputext_class_t *class = (demux_sputext_class_t *)this_gen; - - class->dst_encoding = entry->str_value; - - printf("demux_sputext: spu_dst_encoding = %s\n", class->dst_encoding ); -} - static int demux_sputext_next (demux_sputext_t *this_gen) { demux_sputext_t *this = (demux_sputext_t *) this_gen; buf_element_t *buf; @@ -1022,17 +982,6 @@ static void *init_sputext_demux_class (xine_t *xine, void *data) { this->demux_class.get_extensions = get_demux_extensions; this->demux_class.dispose = demux_class_dispose; - this->src_encoding = xine->config->register_string(xine->config, - "misc.spu_src_encoding", - "windows-1250", - _("source encoding of subtitles"), - NULL, 10, update_osd_src_encoding, this); - this->dst_encoding = xine->config->register_string(xine->config, - "misc.spu_dst_encoding", - "iso-8859-2", - _("target encoding for subtitles (have to match font encoding)"), - NULL, 10, update_osd_dst_encoding, this); - return this; } diff --git a/src/libsputext/xine_decoder.c b/src/libsputext/xine_decoder.c index 3b7a7e1ad..4654b0c36 100644 --- a/src/libsputext/xine_decoder.c +++ b/src/libsputext/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.55 2003/03/20 20:44:18 f1rmb Exp $ + * $Id: xine_decoder.c,v 1.56 2003/03/26 11:06:56 miguelfreitas Exp $ * */ @@ -29,7 +29,6 @@ #include #include #include -#include #include "buffer.h" #include "xine_internal.h" @@ -57,6 +56,8 @@ typedef enum { typedef struct sputext_class_s { spu_decoder_class_t class; + char *src_encoding; /* encoding of subtitle file */ + xine_t *xine; } sputext_class_t; @@ -79,11 +80,10 @@ typedef struct sputext_decoder_s { int master_started; int slave_started; - char *font; - subtitle_size subtitle_size; + char *font; /* subtitle font */ + subtitle_size subtitle_size; /* size of subtitles */ int vertical_offset; - osd_renderer_t *renderer; osd_object_t *osd; @@ -159,7 +159,8 @@ static void draw_subtitle(sputext_decoder_t *this, int64_t sub_start, int64_t su } this->renderer->render_text (this->osd, x, y + line*this->line_height, - this->text[line], OSD_TEXT1); + this->text[line], this->class->src_encoding, + OSD_TEXT1); } if( font_size != this->font_size ) @@ -407,19 +408,19 @@ static spu_decoder_t *sputext_class_open_plugin (spu_decoder_class_t *class_gen, this->stream = stream; this->font = class->xine->config->register_string(class->xine->config, - "codec.spu_font", + "misc.spu_font", "sans", - _("font for avi subtitles"), + _("font for external subtitles"), NULL, 0, update_osd_font, this); this->subtitle_size = class->xine->config->register_enum(class->xine->config, - "codec.spu_subtitle_size", + "misc.spu_subtitle_size", 1, subtitle_size_strings, _("subtitle size (relative window size)"), NULL, 0, update_subtitle_size, this); this->vertical_offset = class->xine->config->register_num(class->xine->config, - "codec.spu_vertical_offset", + "misc.spu_vertical_offset", 0, _("subtitle vertical offset (relative window size)"), NULL, 0, update_vertical_offset, this); @@ -439,6 +440,13 @@ static char *sputext_class_get_description (spu_decoder_class_t *this) { return "external subtitle decoder plugin"; } +static void update_src_encoding(void *this_gen, xine_cfg_entry_t *entry) +{ + sputext_class_t *this = (sputext_class_t *)this_gen; + + this->src_encoding = entry->str_value; + printf("libsputext: spu_src_encoding = %s\n", this->src_encoding ); +} static void *init_spu_decoder_plugin (xine_t *xine, void *data) { @@ -457,6 +465,12 @@ static void *init_spu_decoder_plugin (xine_t *xine, void *data) { this->xine = xine; + this->src_encoding = xine->config->register_string(xine->config, + "misc.spu_src_encoding", + "iso-8859-1", + _("encoding of subtitles"), + NULL, 10, update_src_encoding, this); + return &this->class; } diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index 85837ef84..8e896b9e8 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #include "xine_internal.h" #include "video_out/alphablend.h" @@ -44,6 +47,11 @@ #define LOG_DEBUG 1 */ +#define BINARY_SEARCH 1 + +/* unicode value of alias character (it used if conversion fails) */ +#define ALIAS_CHARACTER ' ' + #ifdef MAX #undef MAX #endif @@ -478,7 +486,7 @@ static uint16_t gzread_i16(gzFile *fp) { load bitmap font into osd engine */ -static void osd_renderer_load_font(osd_renderer_t *this, char *filename) { +static int osd_renderer_load_font(osd_renderer_t *this, char *filename) { gzFile *fp; osd_font_t *font = NULL; @@ -504,14 +512,14 @@ static void osd_renderer_load_font(osd_renderer_t *this, char *filename) { font->fontchar = malloc( sizeof(osd_fontchar_t) * font->num_fontchars ); #ifdef LOG_DEBUG - printf("osd: font %s %d\n",font->name, font->num_fontchars); + printf("osd: font %s %d\n", font->name, font->num_fontchars); #endif for( i = 0; i < font->num_fontchars; i++ ) { font->fontchar[i].code = gzread_i16(fp); font->fontchar[i].width = gzread_i16(fp); font->fontchar[i].height = gzread_i16(fp); font->fontchar[i].bmp = malloc(font->fontchar[i].width*font->fontchar[i].height); - if( gzread(fp,font->fontchar[i].bmp, + if( gzread(fp, font->fontchar[i].bmp, font->fontchar[i].width*font->fontchar[i].height) <= 0 ) break; } @@ -543,6 +551,7 @@ static void osd_renderer_load_font(osd_renderer_t *this, char *filename) { } pthread_mutex_unlock (&this->osd_mutex); + return ret; } /* @@ -582,6 +591,7 @@ static int osd_renderer_unload_font(osd_renderer_t *this, char *fontname ) { else this->fonts = font->next; free( font ); + ret = 1; break; } last = font; @@ -633,18 +643,46 @@ static int osd_set_font( osd_object_t *osd, const char *fontname, int size) { } +#ifdef BINARY_SEARCH +/* + * search the character in the sorted array + */ +static int binsearch(osd_fontchar_t *array, size_t n, uint16_t code) { + size_t i, left, right; + + if (!n) return 0; + + left = 0; + right = n - 1; + while (right > left) { + i = (left + right) >> 1; + if (code <= array[i].code) right = i; + else left = i + 1; + } + + return array[right].code == code ? right : n; +} +#endif + + /* - * render text on x,y position (8 bits version) + * render text on x,y position * no \n yet + * if encoding == NULL current locale encoding is used */ static int osd_render_text (osd_object_t *osd, int x1, int y1, - const char *text, int color_base) { + const char *text, const char *encoding, + int color_base) { osd_renderer_t *this = osd->renderer; osd_font_t *font; int i, y; uint8_t *dst, *src; - int c; + iconv_t cd; + char *inbuf; + uint16_t unicode; + size_t inbytesleft; + int def_charset_flag = 0; #ifdef LOG_DEBUG printf("osd_render_text %p (%d,%d) \"%s\"\n", osd, x1, y1, text); @@ -658,23 +696,74 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, pthread_mutex_lock (&this->osd_mutex); - font = osd->font; + if ((font = osd->font) == NULL) { + printf(_("osd: font isn't defined\n")); + pthread_mutex_unlock(&this->osd_mutex); + return 0; + } if( x1 < osd->x1 ) osd->x1 = x1; if( y1 < osd->y1 ) osd->y1 = y1; - while( font && *text ) { - c = *text & 0xff; - + inbuf = (char *)text; + inbytesleft = strlen(text); + + if (!encoding) { +#ifdef ENABLE_NLS + if ((encoding = nl_langinfo(CODESET)) == NULL) { + printf(_("osd: can't find out current locale character set\n")); + encoding = "iso-8859-1"; + def_charset_flag = 1; + } +#else + encoding = "iso-8859-1"; + def_charset_flag = 1; +#endif + } + + /* prepare conversion to UCS-2 */ + if ((cd = iconv_open("UCS-2", encoding)) == (iconv_t)-1) { + printf(_("osd: unsupported conversion %s -> UCS-2\n"), encoding); + if (!def_charset_flag) { + printf("osd: trying iso-8859-1 -> UCS-2\n"); + if ((cd = iconv_open("UCS-2", "iso-8859-1")) == (iconv_t)-1) { + printf(_("osd: iconv_open() failed\n")); + pthread_mutex_unlock(&this->osd_mutex); + return 0; + } + } + } + + while( inbytesleft ) { + char *outbuf = (char*)&unicode; + size_t outbytesleft = 2; + size_t count; + + /* get unicode value */ + count = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + if (count == (size_t)-1 && errno != E2BIG) { + /* unknown character or character wider than 16 bits, try skip one byte */ + printf(_("osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", skipping\n"), + inbuf[0] & 0xFF, encoding); + if (!inbytesleft) break; + inbytesleft--; + inbuf++; + unicode = ALIAS_CHARACTER; + } + +#ifdef BINARY_SEARCH + i = binsearch(font->fontchar, font->num_fontchars, unicode); +#else for( i = 0; i < font->num_fontchars; i++ ) { - if( font->fontchar[i].code == c ) + if( font->fontchar[i].code == unicode ) break; } +#endif #ifdef LOG_DEBUG - printf("font %s [%c:%d] %dx%d -> %d,%d\n",font->name, c, font->fontchar[i].code, - font->fontchar[i].width, font->fontchar[i].height, - x1,y1); + printf("font %s [%d, U+%04X] %dx%d -> %d,%d\n", font->name, i, + unicode, font->fontchar[i].code, font->fontchar[i].width, + font->fontchar[i].height, x1, y1); #endif if ( i != font->num_fontchars ) { @@ -701,8 +790,8 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, if( y1 + font->fontchar[i].height > osd->y2 ) osd->y2 = y1 + font->fontchar[i].height; } - text++; } + iconv_close(cd); pthread_mutex_unlock (&this->osd_mutex); diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h index aa4b36baf..9c2959f77 100644 --- a/src/xine-engine/osd.h +++ b/src/xine-engine/osd.h @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * OSD stuff (text and graphic primitives) - * $Id: osd.h,v 1.13 2003/03/08 17:22:16 f1rmb Exp $ + * $Id: osd.h,v 1.14 2003/03/26 11:06:58 miguelfreitas Exp $ */ #ifndef HAVE_OSD_H @@ -152,7 +152,7 @@ struct osd_renderer_s { * Use OSD_TEXT1, OSD_TEXT2, ... for some preasssigned color indices. */ int (*render_text) (osd_object_t *osd, int x1, int y1, - const char *text, int color_base); + const char *text, const char *encoding, int color_base); /* * get width and height of how text will be renderized diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c index 430776782..72167bd12 100644 --- a/src/xine-engine/xine_interface.c +++ b/src/xine-engine/xine_interface.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_interface.c,v 1.45 2003/03/08 20:25:52 guenter Exp $ + * $Id: xine_interface.c,v 1.46 2003/03/26 11:06:59 miguelfreitas Exp $ * * convenience/abstraction layer, functions to implement * libxine's public interface @@ -565,7 +565,7 @@ void xine_osd_draw_rect(xine_osd_t *this, int x1, int y1, int x2, int y2, int co } void xine_osd_draw_text(xine_osd_t *this, int x1, int y1, const char *text, int color_base) { - this->osd.renderer->render_text(&this->osd, x1, y1, text, color_base); + this->osd.renderer->render_text(&this->osd, x1, y1, text, NULL, color_base); } void xine_osd_get_text_size(xine_osd_t *this, const char *text, int *width, int *height) { -- cgit v1.2.3