comparison gui/skin/font.c @ 32734:cc58a1e919d9

Allow character in the font description file to be in UTF-8. A character defined in the font description file can be either an ASCII character, any character in the range of 0x80 to 0xFF or - to avoid character set problems, and that is recommended - a character in UTF-8 encoding now. Non-ASCII characters will be stored in the nonASCIIidx array. The indices 0..127 of this array correspond to the indices 128..255 of the Fnt array. (This also settles the "Translate messages shown in the GUI window(s) from UTF-8" issue.)
author ib
date Thu, 27 Jan 2011 18:04:19 +0000
parents 6ff3cc81d602
children 63844ef43932
comparison
equal deleted inserted replaced
32733:e922613845cc 32734:cc58a1e919d9
44 if ( id == 25 ) return -2; 44 if ( id == 25 ) return -2;
45 45
46 if ( ( Fonts[id]=calloc( 1,sizeof( bmpFont ) ) ) == NULL ) return -1; 46 if ( ( Fonts[id]=calloc( 1,sizeof( bmpFont ) ) ) == NULL ) return -1;
47 47
48 av_strlcpy( Fonts[id]->name,name,128 ); // FIXME: as defined in font.h 48 av_strlcpy( Fonts[id]->name,name,128 ); // FIXME: as defined in font.h
49 for ( i=0;i<256;i++ ) 49 for ( i=0;i<ASCII_CHRS+EXTRA_CHRS;i++ )
50 Fonts[id]->Fnt[i].x=Fonts[id]->Fnt[i].y=Fonts[id]->Fnt[i].sx=Fonts[id]->Fnt[i].sy=-1; 50 Fonts[id]->Fnt[i].x=Fonts[id]->Fnt[i].y=Fonts[id]->Fnt[i].sx=Fonts[id]->Fnt[i].sy=-1;
51 51
52 return id; 52 return id;
53 } 53 }
54 54
100 if ( command[0] == '"' ) 100 if ( command[0] == '"' )
101 { 101 {
102 int i; 102 int i;
103 cutItem( command,command,'"',1 ); 103 cutItem( command,command,'"',1 );
104 if ( !command[0] ) i=(int)'"'; 104 if ( !command[0] ) i=(int)'"';
105 else if ( command[0] & 0x80 )
106 {
107 for ( i = 0; i < EXTRA_CHRS; i++ )
108 {
109 if ( !Fonts[id]->nonASCIIidx[i][0] )
110 {
111 strncpy( Fonts[id]->nonASCIIidx[i], command, 4 );
112 break;
113 }
114 }
115 if ( i == EXTRA_CHRS ) continue;
116 i += ASCII_CHRS;
117 }
105 else i=(int)command[0]; 118 else i=(int)command[0];
106 cutItem( param,tmp,',',0 ); Fonts[id]->Fnt[i].x=atoi( tmp ); 119 cutItem( param,tmp,',',0 ); Fonts[id]->Fnt[i].x=atoi( tmp );
107 cutItem( param,tmp,',',1 ); Fonts[id]->Fnt[i].y=atoi( tmp ); 120 cutItem( param,tmp,',',1 ); Fonts[id]->Fnt[i].y=atoi( tmp );
108 cutItem( param,tmp,',',2 ); Fonts[id]->Fnt[i].sx=atoi( tmp ); 121 cutItem( param,tmp,',',2 ); Fonts[id]->Fnt[i].sx=atoi( tmp );
109 cutItem( param,tmp,',',3 ); Fonts[id]->Fnt[i].sy=atoi( tmp ); 122 cutItem( param,tmp,',',3 ); Fonts[id]->Fnt[i].sy=atoi( tmp );
135 if ( Fonts[i] ) 148 if ( Fonts[i] )
136 if ( !strcmp( name,Fonts[i]->name ) ) return i; 149 if ( !strcmp( name,Fonts[i]->name ) ) return i;
137 return -1; 150 return -1;
138 } 151 }
139 152
153 // get Fnt index of character (utf8 or normal one) *str points to,
154 // then move pointer to next/previous character
155 int fntGetCharIndex( int id, unsigned char **str, gboolean utf8, int direction )
156 {
157 unsigned char *p, uchar[4] = { 0, 0, 0, 0 };
158 int i, c = -1;
159
160 if ( **str & 0x80 )
161 {
162 if ( utf8 )
163 {
164 p = *str;
165 *str = g_utf8_next_char( *str );
166 strncpy( uchar, p, *str - p );
167
168 if ( direction < 0 ) *str = g_utf8_prev_char( p );
169 }
170 else
171 {
172 uchar[0] = **str;
173 *str += direction;
174 }
175
176 for ( i = 0; ( i < EXTRA_CHRS ) && Fonts[id]->nonASCIIidx[i][0]; i++ )
177 {
178 if ( strncmp( Fonts[id]->nonASCIIidx[i], uchar, 4 ) == 0 ) return i + ASCII_CHRS;
179 if ( !utf8 && ( Fonts[id]->nonASCIIidx[i][0] == (*uchar >> 6 | 0xc0) && Fonts[id]->nonASCIIidx[i][1] == (*uchar & 0x3f | 0x80) && Fonts[id]->nonASCIIidx[i][2] == 0 ) ) c = i + ASCII_CHRS;
180 }
181 }
182 else
183 {
184 c = **str;
185
186 if ( utf8 && ( direction < 0 ) ) *str = g_utf8_prev_char( *str );
187 else *str += direction;
188 }
189
190 return c;
191 }
192
140 int fntTextWidth( int id,char * str ) 193 int fntTextWidth( int id,char * str )
141 { 194 {
142 int size = 0; 195 int size = 0;
143 int i; 196 gboolean utf8;
197 unsigned char *p;
144 198
145 if ( ( !Fonts[id] )||( !str[0] ) ) return 0; 199 if ( ( !Fonts[id] )||( !str[0] ) ) return 0;
146 200
147 for ( i=0;i < (int)strlen( str );i++ ) 201 utf8 = g_utf8_validate( str, -1, NULL);
148 { 202 p = (unsigned char *) str;
149 unsigned char c = (unsigned char)str[i]; 203
150 if ( Fonts[id]->Fnt[c].sx == -1 ) c = ' '; 204 while ( *p )
205 {
206 int c = fntGetCharIndex( id, &p, utf8, 1 );
207 if ( c == -1 || Fonts[id]->Fnt[c].sx == -1 ) c = ' ';
151 size+= Fonts[id]->Fnt[ c ].sx; 208 size+= Fonts[id]->Fnt[ c ].sx;
152 } 209 }
153 return size; 210 return size;
154 } 211 }
155 212
156 int fntTextHeight( int id,char * str ) 213 int fntTextHeight( int id,char * str )
157 { 214 {
158 int max = 0,i; 215 int max = 0;
216 gboolean utf8;
217 unsigned char *p;
159 218
160 if ( ( !Fonts[id] )||( !str[0] ) ) return 0; 219 if ( ( !Fonts[id] )||( !str[0] ) ) return 0;
161 220
162 for ( i=0;i < (int)strlen( str );i++ ) 221 utf8 = g_utf8_validate( str, -1, NULL);
222 p = (unsigned char *) str;
223
224 while ( *p )
163 { 225 {
164 int h; 226 int h;
165 unsigned char c = (unsigned char)str[i]; 227 int c = fntGetCharIndex( id, &p, utf8, 1 );
166 if ( Fonts[id]->Fnt[c].sx == -1 ) c = ' '; 228 if ( c == -1 || Fonts[id]->Fnt[c].sx == -1 ) c = ' ';
167 h = Fonts[id]->Fnt[c].sy; 229 h = Fonts[id]->Fnt[c].sy;
168 if ( h > max ) max=h; 230 if ( h > max ) max=h;
169 } 231 }
170 return max; 232 return max;
171 } 233 }
172 234
173 txSample * fntRender( wItem * item,int px,const char * fmt,... ) 235 txSample * fntRender( wItem * item,int px,const char * fmt,... )
174 { 236 {
175 va_list ap; 237 va_list ap;
176 unsigned char p[512]; 238 unsigned char * u, p[512];
177 unsigned int c; 239 int c, i, dx = 0, tw, fbw, iw, id, ofs;
178 int i, dx = 0, tw, fbw, iw, id, ofs;
179 int x,y,fh,fw,fyc,yc; 240 int x,y,fh,fw,fyc,yc;
180 uint32_t * ibuf; 241 uint32_t * ibuf;
181 uint32_t * obuf; 242 uint32_t * obuf;
243 gboolean utf8;
182 244
183 va_start( ap,fmt ); 245 va_start( ap,fmt );
184 vsnprintf( p,512,fmt,ap ); 246 vsnprintf( p,512,fmt,ap );
185 va_end( ap ); 247 va_end( ap );
186 248
222 284
223 } else dx+=px; 285 } else dx+=px;
224 286
225 ofs=dx; 287 ofs=dx;
226 288
227 for ( i=0;i < (int)strlen( p );i++ ) 289 utf8 = g_utf8_validate( p, -1, NULL);
228 { 290 u = p;
229 c=(unsigned int)p[i]; 291
230 fw=Fonts[id]->Fnt[c].sx; 292 while ( *u )
231 293 {
232 if ( fw == -1 ) { c=32; fw=Fonts[id]->Fnt[c].sx; } 294 c = fntGetCharIndex( id, &u, utf8, 1 );
295
296 if ( c != -1 ) fw=Fonts[id]->Fnt[c].sx;
297
298 if ( c == -1 || fw == -1 ) { c=32; fw=Fonts[id]->Fnt[c].sx; }
233 299
234 fh=Fonts[id]->Fnt[c].sy; 300 fh=Fonts[id]->Fnt[c].sy;
235 fyc=Fonts[id]->Fnt[c].y * fbw + Fonts[id]->Fnt[c].x; 301 fyc=Fonts[id]->Fnt[c].y * fbw + Fonts[id]->Fnt[c].x;
236 yc=dx; 302 yc=dx;
237 303
247 } 313 }
248 314
249 if ( ofs > 0 && tw > item->width ) 315 if ( ofs > 0 && tw > item->width )
250 { 316 {
251 dx=ofs; 317 dx=ofs;
252 for ( i=(int)strlen( p );i > 0;i-- ) 318 u = p + strlen( p );
253 { 319
254 c=(unsigned int)p[i]; 320 while ( u > p )
255 fw=Fonts[id]->Fnt[c].sx; 321 {
256 322 c = fntGetCharIndex( id, &u, utf8, -1 );
257 if ( fw == -1 ) { c=32; fw=Fonts[id]->Fnt[c].sx; } 323
324 if ( c != -1) fw=Fonts[id]->Fnt[c].sx;
325
326 if ( c == -1 || fw == -1 ) { c=32; fw=Fonts[id]->Fnt[c].sx; }
258 327
259 fh=Fonts[id]->Fnt[c].sy; 328 fh=Fonts[id]->Fnt[c].sy;
260 fyc=Fonts[id]->Fnt[c].y * fbw + Fonts[id]->Fnt[c].x; 329 fyc=Fonts[id]->Fnt[c].y * fbw + Fonts[id]->Fnt[c].x;
261 330
262 dx-=fw; yc=dx; 331 dx-=fw; yc=dx;