Mercurial > mplayer.hg
annotate gui/skin/font.c @ 24515:c5c0cb0e90d2
getch2: Fix incorrect test
Keycode length wasn't checked in one case because of missing
parentheses. This was accidentally broken in my previous commit to the
file. Most likely the error had no practical effect; the length checks
are unreliable in any case as they can be satisfied by unrelated
data corresponding to other keypresses.
author | uau |
---|---|
date | Sat, 15 Sep 2007 18:13:56 +0000 |
parents | 9fb716ab06a3 |
children | 10dfbc523184 |
rev | line source |
---|---|
23077 | 1 |
2 #include <stdlib.h> | |
3 #include <stdio.h> | |
4 #include <stdarg.h> | |
5 #include <string.h> | |
6 #include <inttypes.h> | |
7 | |
8 #include "app.h" | |
9 #include "skin.h" | |
10 #include "font.h" | |
11 #include "cut.h" | |
12 #include "../mp_msg.h" | |
23703
9fb716ab06a3
Avoid code duplication and ugly config.h hack by using av_strlcat/av_strlcpy
reimar
parents:
23077
diff
changeset
|
13 #include "../libavutil/avstring.h" |
23077 | 14 |
15 int items; | |
16 | |
17 bmpFont * Fonts[26] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; | |
18 | |
19 int fntAddNewFont( char * name ) | |
20 { | |
21 int id; | |
22 int i; | |
23 | |
24 for( id=0;id<26;id++ ) | |
25 if ( !Fonts[id] ) break; | |
26 | |
27 if ( id == 25 ) return -2; | |
28 | |
29 if ( ( Fonts[id]=calloc( 1,sizeof( bmpFont ) ) ) == NULL ) return -1; | |
30 | |
23703
9fb716ab06a3
Avoid code duplication and ugly config.h hack by using av_strlcat/av_strlcpy
reimar
parents:
23077
diff
changeset
|
31 av_strlcpy( Fonts[id]->name,name,128 ); // FIXME: as defined in font.h |
23077 | 32 for ( i=0;i<256;i++ ) |
33 Fonts[id]->Fnt[i].x=Fonts[id]->Fnt[i].y=Fonts[id]->Fnt[i].sx=Fonts[id]->Fnt[i].sy=-1; | |
34 | |
35 return id; | |
36 } | |
37 | |
38 void fntFreeFont( void ) | |
39 { | |
40 int i; | |
41 for( i=0;i < 25;i++ ) | |
42 { | |
43 if ( Fonts[i] ) | |
44 { | |
45 if ( Fonts[i]->Bitmap.Image ) free( Fonts[i]->Bitmap.Image ); | |
46 free( Fonts[i] ); | |
47 Fonts[i]=NULL; | |
48 } | |
49 } | |
50 } | |
51 | |
52 int fntRead( char * path,char * fname ) | |
53 { | |
54 FILE * f; | |
55 unsigned char tmp[512]; | |
56 unsigned char * ptmp; | |
57 unsigned char command[32]; | |
58 unsigned char param[256]; | |
59 int c,linenumber = 0; | |
60 int id = fntAddNewFont( fname ); | |
61 | |
62 if ( id < 0 ) return id; | |
63 | |
23703
9fb716ab06a3
Avoid code duplication and ugly config.h hack by using av_strlcat/av_strlcpy
reimar
parents:
23077
diff
changeset
|
64 av_strlcpy( tmp,path,sizeof( tmp ) ); |
9fb716ab06a3
Avoid code duplication and ugly config.h hack by using av_strlcat/av_strlcpy
reimar
parents:
23077
diff
changeset
|
65 av_strlcat( tmp,fname,sizeof( tmp ) ); av_strlcat( tmp,".fnt",sizeof( tmp ) ); |
23077 | 66 if ( ( f=fopen( tmp,"rt" ) ) == NULL ) |
67 { free( Fonts[id] ); return -3; } | |
68 | |
69 while ( !feof( f ) ) | |
70 { | |
71 fgets( tmp,255,f ); linenumber++; | |
72 | |
73 c=tmp[ strlen( tmp ) - 1 ]; if ( ( c == '\n' )||( c == '\r' ) ) tmp[ strlen( tmp ) - 1 ]=0; | |
74 c=tmp[ strlen( tmp ) - 1 ]; if ( ( c == '\n' )||( c == '\r' ) ) tmp[ strlen( tmp ) - 1 ]=0; | |
75 for ( c=0;c < (int)strlen( tmp );c++ ) | |
76 if ( tmp[c] == ';' ) { tmp[c]=0; break; } | |
77 if ( !tmp[0] ) continue; | |
78 ptmp=trimleft( tmp ); | |
79 if ( !tmp[0] ) continue; | |
80 ptmp=strswap( ptmp,'\t',' ' ); | |
81 ptmp=trim( ptmp ); | |
82 cutItem( ptmp,command,'=',0 ); cutItem( ptmp,param,'=',1 ); | |
83 if ( command[0] == '"' ) | |
84 { | |
85 int i; | |
86 cutItem( command,command,'"',1 ); | |
87 i=(int)command[0]; | |
88 cutItem( param,tmp,',',0 ); Fonts[id]->Fnt[i].x=atoi( tmp ); | |
89 cutItem( param,tmp,',',1 ); Fonts[id]->Fnt[i].y=atoi( tmp ); | |
90 cutItem( param,tmp,',',2 ); Fonts[id]->Fnt[i].sx=atoi( tmp ); | |
91 cutItem( param,tmp,',',3 ); Fonts[id]->Fnt[i].sy=atoi( tmp ); | |
92 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[font] char: '%s' params: %d,%d %dx%d\n",command,Fonts[id]->Fnt[i].x,Fonts[id]->Fnt[i].y,Fonts[id]->Fnt[i].sx,Fonts[id]->Fnt[i].sy ); | |
93 } | |
94 else | |
95 { | |
96 if ( !strcmp( command,"image" ) ) | |
97 { | |
23703
9fb716ab06a3
Avoid code duplication and ugly config.h hack by using av_strlcat/av_strlcpy
reimar
parents:
23077
diff
changeset
|
98 av_strlcpy( tmp,path,sizeof( tmp ) ); av_strlcat( tmp,param,sizeof( tmp ) ); |
23077 | 99 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[font] font imagefile: %s\n",tmp ); |
100 if ( skinBPRead( tmp,&Fonts[id]->Bitmap ) ) return -4; | |
101 } | |
102 } | |
103 } | |
104 | |
105 return 0; | |
106 } | |
107 | |
108 int fntFindID( char * name ) | |
109 { | |
110 int i; | |
111 for ( i=0;i < 25;i++ ) | |
112 if ( Fonts[i] ) | |
113 if ( !strcmp( name,Fonts[i]->name ) ) return i; | |
114 return -1; | |
115 } | |
116 | |
117 int fntTextWidth( int id,char * str ) | |
118 { | |
119 int size = 0; | |
120 int i; | |
121 | |
122 if ( ( !Fonts[id] )||( !str[0] ) ) return 0; | |
123 | |
124 for ( i=0;i < (int)strlen( str );i++ ) | |
125 { | |
126 unsigned char c = (unsigned char)str[i]; | |
127 if ( Fonts[id]->Fnt[c].sx == -1 ) c = ' '; | |
128 size+= Fonts[id]->Fnt[ c ].sx; | |
129 } | |
130 return size; | |
131 } | |
132 | |
133 int fntTextHeight( int id,char * str ) | |
134 { | |
135 int max = 0,i; | |
136 | |
137 if ( ( !Fonts[id] )||( !str[0] ) ) return 0; | |
138 | |
139 for ( i=0;i < (int)strlen( str );i++ ) | |
140 { | |
141 int h; | |
142 unsigned char c = (unsigned char)str[i]; | |
143 if ( Fonts[id]->Fnt[c].sx == -1 ) c = ' '; | |
144 h = Fonts[id]->Fnt[c].sy; | |
145 if ( h > max ) max=h; | |
146 } | |
147 return max; | |
148 } | |
149 | |
150 txSample * fntRender( wItem * item,int px,const char * fmt,... ) | |
151 { | |
152 va_list ap; | |
153 unsigned char p[512]; | |
154 unsigned int c; | |
155 int i, dx = 0, tw, fbw, iw, id, ofs; | |
156 int x,y,fh,fw,fyc,yc; | |
157 uint32_t * ibuf; | |
158 uint32_t * obuf; | |
159 | |
160 va_start( ap,fmt ); | |
161 vsnprintf( p,512,fmt,ap ); | |
162 va_end( ap ); | |
163 | |
164 iw=item->width; | |
165 id=item->fontid; | |
166 | |
167 if ( ( !item )|| | |
168 ( !Fonts[id] )|| | |
169 ( !p[0] )|| | |
170 ( !fntTextWidth( id,p ) ) ) return NULL; | |
171 | |
172 tw=fntTextWidth( id,p ); | |
173 fbw=Fonts[id]->Bitmap.Width; | |
174 | |
175 if ( item->Bitmap.Image == NULL ) | |
176 { | |
177 item->Bitmap.Height=item->height=fntTextHeight( id,p ); | |
178 item->Bitmap.Width=item->width=iw; | |
179 item->Bitmap.ImageSize=item->height * iw * 4; | |
180 if ( !item->Bitmap.ImageSize ) return NULL; | |
181 item->Bitmap.BPP=32; | |
182 item->Bitmap.Image=malloc( item->Bitmap.ImageSize ); | |
183 } | |
184 | |
185 obuf=(uint32_t *)item->Bitmap.Image; | |
186 ibuf=(uint32_t *)Fonts[id]->Bitmap.Image; | |
187 | |
188 for ( i=0;i < item->Bitmap.ImageSize / 4;i++ ) obuf[i]=0xff00ff; | |
189 | |
190 if ( tw <= iw ) | |
191 { | |
192 switch ( item->align ) | |
193 { | |
194 default: | |
195 case fntAlignLeft: dx=0; break; | |
196 case fntAlignCenter: dx=( iw - fntTextWidth( id,p ) ) / 2; break; | |
197 case fntAlignRight: dx=iw - fntTextWidth( id,p ); break; | |
198 } | |
199 | |
200 } else dx+=px; | |
201 | |
202 ofs=dx; | |
203 | |
204 for ( i=0;i < (int)strlen( p );i++ ) | |
205 { | |
206 c=(unsigned int)p[i]; | |
207 fw=Fonts[id]->Fnt[c].sx; | |
208 | |
209 if ( fw == -1 ) { c=32; fw=Fonts[id]->Fnt[c].sx; } | |
210 | |
211 fh=Fonts[id]->Fnt[c].sy; | |
212 fyc=Fonts[id]->Fnt[c].y * fbw + Fonts[id]->Fnt[c].x; | |
213 yc=dx; | |
214 | |
215 if ( dx >= 0 ) | |
216 for ( y=0;y < fh;y++ ) | |
217 { | |
218 for ( x=0; x < fw;x++ ) | |
219 if ( dx + x >= 0 && dx + x < iw ) obuf[yc + x]=ibuf[ fyc + x ]; | |
220 fyc+=fbw; | |
221 yc+=iw; | |
222 } | |
223 dx+=fw; | |
224 } | |
225 | |
226 if ( ofs > 0 && tw > item->width ) | |
227 { | |
228 dx=ofs; | |
229 for ( i=(int)strlen( p );i > 0;i-- ) | |
230 { | |
231 c=(unsigned int)p[i]; | |
232 fw=Fonts[id]->Fnt[c].sx; | |
233 | |
234 if ( fw == -1 ) { c=32; fw=Fonts[id]->Fnt[c].sx; } | |
235 | |
236 fh=Fonts[id]->Fnt[c].sy; | |
237 fyc=Fonts[id]->Fnt[c].y * fbw + Fonts[id]->Fnt[c].x; | |
238 | |
239 dx-=fw; yc=dx; | |
240 if ( dx >= 0 ) | |
241 for ( y=0;y < fh;y++ ) | |
242 { | |
243 for ( x=fw - 1;x >= 0;x-- ) | |
244 if ( dx + x >= 0 && dx + x < iw ) obuf[yc + x]=ibuf[fyc + x]; | |
245 fyc+=fbw; | |
246 yc+=iw; | |
247 } | |
248 } | |
249 } | |
250 | |
251 return &item->Bitmap; | |
252 } |