Mercurial > mplayer.hg
annotate libmenu/menu.c @ 16718:044260623695
makes demux_lavf (-demuxer 35) use the framerate specified in the container
if it's set and only fall back to the codec framerate if the former is not
set.
This solves the issue of some avi's playing at 30000/1 fps instead of the
correct framerate.
Patch by Ivo < ivop AH euronet POIS nl >
Original thread:
Date: Sep 25, 2005 12:34 AM
Subject: [MPlayer-dev-eng] [PATCH] make demux_lavf use container framerate
author | gpoirier |
---|---|
date | Mon, 10 Oct 2005 05:45:38 +0000 |
parents | fd97f3727f15 |
children | 931bdbc37ee0 |
rev | line source |
---|---|
8197 | 1 |
2 #include "../config.h" | |
3 | |
4 #include <stdlib.h> | |
5 #include <stdio.h> | |
6 #include <string.h> | |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
7 #include <fcntl.h> |
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
8 #include <unistd.h> |
8197 | 9 |
10 #include "../libvo/osd.h" | |
11 #include "../libvo/font_load.h" | |
9380 | 12 #include "../osdep/keycodes.h" |
8197 | 13 #include "../asxparser.h" |
14 #include "../libmpdemux/stream.h" | |
15 | |
16 #include "img_format.h" | |
17 #include "mp_image.h" | |
18 #include "../m_option.h" | |
19 #include "../m_struct.h" | |
20 #include "menu.h" | |
21 | |
22 extern menu_info_t menu_info_cmdlist; | |
23 extern menu_info_t menu_info_pt; | |
24 extern menu_info_t menu_info_filesel; | |
25 extern menu_info_t menu_info_txt; | |
26 extern menu_info_t menu_info_console; | |
27 extern menu_info_t menu_info_pref; | |
10626
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
28 #ifdef HAS_DVBIN_SUPPORT |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
29 extern menu_info_t menu_info_dvbsel; |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
30 #endif |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
31 |
8197 | 32 |
33 menu_info_t* menu_info_list[] = { | |
34 &menu_info_pt, | |
35 &menu_info_cmdlist, | |
36 &menu_info_filesel, | |
37 &menu_info_txt, | |
38 &menu_info_console, | |
10626
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
39 #ifdef HAS_DVBIN_SUPPORT |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
40 &menu_info_dvbsel, |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
41 #endif |
8197 | 42 &menu_info_pref, |
43 NULL | |
44 }; | |
45 | |
46 typedef struct menu_def_st { | |
47 char* name; | |
48 menu_info_t* type; | |
49 void* cfg; | |
50 char* args; | |
51 } menu_def_t; | |
52 | |
53 static menu_def_t* menu_list = NULL; | |
54 static int mcount = 0; | |
55 | |
56 | |
57 static int menu_parse_config(char* buffer) { | |
58 char *element,*body, **attribs, *name; | |
59 menu_info_t* minfo = NULL; | |
60 int r,i; | |
61 ASX_Parser_t* parser = asx_parser_new(); | |
62 | |
63 while(1) { | |
64 r = asx_get_element(parser,&buffer,&element,&body,&attribs); | |
65 if(r < 0) { | |
66 printf("Syntax error at line %d\n",parser->line); | |
67 asx_parser_free(parser); | |
68 return 0; | |
69 } else if(r == 0) { | |
70 asx_parser_free(parser); | |
71 return 1; | |
72 } | |
73 // Has it a name ? | |
74 name = asx_get_attrib("name",attribs); | |
75 if(!name) { | |
76 printf("Menu definitions need a name attrib (line %d)\n",parser->line); | |
77 free(element); | |
78 if(body) free(body); | |
79 asx_free_attribs(attribs); | |
80 continue; | |
81 } | |
82 | |
83 // Try to find this menu type in our list | |
84 for(i = 0, minfo = NULL ; menu_info_list[i] ; i++) { | |
85 if(strcasecmp(element,menu_info_list[i]->name) == 0) { | |
86 minfo = menu_info_list[i]; | |
87 break; | |
88 } | |
89 } | |
90 // Got it : add this to our list | |
91 if(minfo) { | |
92 menu_list = realloc(menu_list,(mcount+2)*sizeof(menu_def_t)); | |
93 menu_list[mcount].name = name; | |
94 menu_list[mcount].type = minfo; | |
95 menu_list[mcount].cfg = m_struct_alloc(&minfo->priv_st); | |
96 menu_list[mcount].args = body; | |
97 // Setup the attribs | |
98 for(i = 0 ; attribs[2*i] ; i++) { | |
99 if(strcasecmp(attribs[2*i],"name") == 0) continue; | |
100 if(!m_struct_set(&minfo->priv_st,menu_list[mcount].cfg,attribs[2*i], attribs[2*i+1])) | |
101 printf("Bad attrib %s=%s in menu %s at line %d\n",attribs[2*i],attribs[2*i+1], | |
102 name,parser->line); | |
103 } | |
104 mcount++; | |
105 memset(&menu_list[mcount],0,sizeof(menu_def_t)); | |
106 } else { | |
10397 | 107 printf("Unknown menu type %s at line %d\n",element,parser->line); |
8197 | 108 free(name); |
109 if(body) free(body); | |
110 } | |
111 | |
112 free(element); | |
113 asx_free_attribs(attribs); | |
114 } | |
115 | |
116 } | |
117 | |
118 | |
119 /// This will build the menu_defs list from the cfg file | |
120 #define BUF_STEP 1024 | |
121 #define BUF_MIN 128 | |
122 #define BUF_MAX BUF_STEP*1024 | |
123 int menu_init(char* cfg_file) { | |
124 char* buffer = NULL; | |
125 int bl = BUF_STEP, br = 0; | |
9103
6c2c74adaebe
mplayer crashes if one tries to use osd menu without having a font
arpi
parents:
8604
diff
changeset
|
126 int f, fd; |
9212
24b102dbd0fe
Fixes a problem where the menu won't work, if you just use freetype fonts
arpi
parents:
9103
diff
changeset
|
127 #ifndef HAVE_FREETYPE |
9103
6c2c74adaebe
mplayer crashes if one tries to use osd menu without having a font
arpi
parents:
8604
diff
changeset
|
128 if(vo_font == NULL) |
6c2c74adaebe
mplayer crashes if one tries to use osd menu without having a font
arpi
parents:
8604
diff
changeset
|
129 return 0; |
9212
24b102dbd0fe
Fixes a problem where the menu won't work, if you just use freetype fonts
arpi
parents:
9103
diff
changeset
|
130 #endif |
9103
6c2c74adaebe
mplayer crashes if one tries to use osd menu without having a font
arpi
parents:
8604
diff
changeset
|
131 fd = open(cfg_file, O_RDONLY); |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
132 if(fd < 0) { |
8197 | 133 printf("Can't open menu config file: %s\n",cfg_file); |
134 return 0; | |
135 } | |
136 buffer = malloc(bl); | |
137 while(1) { | |
138 int r; | |
139 if(bl - br < BUF_MIN) { | |
140 if(bl >= BUF_MAX) { | |
141 printf("Menu config file is too big (> %d KB)\n",BUF_MAX/1024); | |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
142 close(fd); |
8197 | 143 free(buffer); |
144 return 0; | |
145 } | |
146 bl += BUF_STEP; | |
147 buffer = realloc(buffer,bl); | |
148 } | |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
149 r = read(fd,buffer+br,bl-br); |
8197 | 150 if(r == 0) break; |
151 br += r; | |
152 } | |
153 if(!br) { | |
154 printf("Menu config file is empty\n"); | |
155 return 0; | |
156 } | |
157 buffer[br-1] = '\0'; | |
158 | |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
159 close(fd); |
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
160 |
8197 | 161 f = menu_parse_config(buffer); |
162 free(buffer); | |
163 return f; | |
164 } | |
165 | |
166 // Destroy all this stuff | |
167 void menu_unint(void) { | |
168 int i; | |
169 for(i = 0 ; menu_list && menu_list[i].name ; i++) { | |
170 free(menu_list[i].name); | |
171 m_struct_free(&menu_list[i].type->priv_st,menu_list[i].cfg); | |
172 if(menu_list[i].args) free(menu_list[i].args); | |
173 } | |
174 free(menu_list); | |
175 mcount = 0; | |
176 } | |
177 | |
178 /// Default read_key function | |
179 void menu_dflt_read_key(menu_t* menu,int cmd) { | |
180 switch(cmd) { | |
181 case KEY_UP: | |
182 menu->read_cmd(menu,MENU_CMD_UP); | |
183 break; | |
184 case KEY_DOWN: | |
185 menu->read_cmd(menu,MENU_CMD_DOWN); | |
186 break; | |
187 case KEY_LEFT: | |
188 case KEY_ESC: | |
189 menu->read_cmd(menu,MENU_CMD_CANCEL); | |
190 break; | |
191 case KEY_RIGHT: | |
192 case KEY_ENTER: | |
193 menu->read_cmd(menu,MENU_CMD_OK); | |
194 break; | |
195 } | |
196 } | |
197 | |
198 menu_t* menu_open(char *name) { | |
199 menu_t* m; | |
200 int i; | |
201 | |
202 for(i = 0 ; menu_list[i].name != NULL ; i++) { | |
203 if(strcmp(name,menu_list[i].name) == 0) | |
204 break; | |
205 } | |
206 if(menu_list[i].name == NULL) { | |
207 printf("Menu %s not found\n",name); | |
208 return NULL; | |
209 } | |
210 m = calloc(1,sizeof(menu_t)); | |
211 m->priv_st = &(menu_list[i].type->priv_st); | |
212 m->priv = m_struct_copy(m->priv_st,menu_list[i].cfg); | |
213 if(menu_list[i].type->open(m,menu_list[i].args)) | |
214 return m; | |
215 if(m->priv) | |
216 m_struct_free(m->priv_st,m->priv); | |
217 free(m); | |
218 printf("Menu %s: init failed\n",name); | |
219 return NULL; | |
220 } | |
221 | |
222 void menu_draw(menu_t* menu,mp_image_t* mpi) { | |
223 if(menu->show && menu->draw) | |
224 menu->draw(menu,mpi); | |
225 } | |
226 | |
227 void menu_read_cmd(menu_t* menu,int cmd) { | |
228 if(menu->read_cmd) | |
229 menu->read_cmd(menu,cmd); | |
230 } | |
231 | |
232 void menu_close(menu_t* menu) { | |
233 if(menu->close) | |
234 menu->close(menu); | |
235 if(menu->priv) | |
236 m_struct_free(menu->priv_st,menu->priv); | |
237 free(menu); | |
238 } | |
239 | |
240 void menu_read_key(menu_t* menu,int cmd) { | |
241 if(menu->read_key) | |
242 menu->read_key(menu,cmd); | |
243 else | |
244 menu_dflt_read_key(menu,cmd); | |
245 } | |
246 | |
247 ///////////////////////////// Helpers //////////////////////////////////// | |
248 | |
249 typedef void (*draw_alpha_f)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride); | |
250 | |
251 inline static draw_alpha_f get_draw_alpha(uint32_t fmt) { | |
252 switch(fmt) { | |
253 case IMGFMT_BGR15: | |
254 case IMGFMT_RGB15: | |
255 return vo_draw_alpha_rgb15; | |
256 case IMGFMT_BGR16: | |
257 case IMGFMT_RGB16: | |
258 return vo_draw_alpha_rgb16; | |
259 case IMGFMT_BGR24: | |
260 case IMGFMT_RGB24: | |
261 return vo_draw_alpha_rgb24; | |
262 case IMGFMT_BGR32: | |
263 case IMGFMT_RGB32: | |
264 return vo_draw_alpha_rgb32; | |
265 case IMGFMT_YV12: | |
266 case IMGFMT_I420: | |
267 case IMGFMT_IYUV: | |
268 case IMGFMT_YVU9: | |
269 case IMGFMT_IF09: | |
270 case IMGFMT_Y800: | |
271 case IMGFMT_Y8: | |
272 return vo_draw_alpha_yv12; | |
273 case IMGFMT_YUY2: | |
274 return vo_draw_alpha_yuy2; | |
275 } | |
276 | |
277 return NULL; | |
278 } | |
279 | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
280 // return the real height of a char: |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
281 static inline int get_height(int c,int h){ |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
282 int font; |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
283 if ((font=vo_font->font[c])>=0) |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
284 if(h<vo_font->pic_a[font]->h) h=vo_font->pic_a[font]->h; |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
285 return h; |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
286 } |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
287 |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
288 #ifdef HAVE_FREETYPE |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
289 #define render_txt(t) { char* p = t; while(*p) render_one_glyph(vo_font,*p++); } |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
290 #else |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
291 #define render_txt(t) |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
292 #endif |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
293 |
8197 | 294 |
295 void menu_draw_text(mp_image_t* mpi,char* txt, int x, int y) { | |
296 draw_alpha_f draw_alpha = get_draw_alpha(mpi->imgfmt); | |
297 int font; | |
298 | |
299 if(!draw_alpha) { | |
300 printf("Unsupported outformat !!!!\n"); | |
301 return; | |
302 } | |
303 | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
304 render_txt(txt); |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
305 |
8197 | 306 while (*txt) { |
307 unsigned char c=*txt++; | |
308 if ((font=vo_font->font[c])>=0 && (x + vo_font->width[c] <= mpi->w) && (y + vo_font->pic_a[font]->h <= mpi->h)) | |
309 draw_alpha(vo_font->width[c], vo_font->pic_a[font]->h, | |
310 vo_font->pic_b[font]->bmp+vo_font->start[c], | |
311 vo_font->pic_a[font]->bmp+vo_font->start[c], | |
312 vo_font->pic_a[font]->w, | |
313 mpi->planes[0] + y * mpi->stride[0] + x * (mpi->bpp>>3), | |
314 mpi->stride[0]); | |
315 x+=vo_font->width[c]+vo_font->charspace; | |
316 } | |
317 | |
318 } | |
319 | |
320 void menu_draw_text_full(mp_image_t* mpi,char* txt, | |
321 int x, int y,int w, int h, | |
322 int vspace, int warp, int align, int anchor) { | |
323 int need_w,need_h; | |
324 int sy, ymin, ymax; | |
325 int sx, xmin, xmax, xmid, xrmin; | |
326 int ll = 0; | |
327 int font; | |
328 draw_alpha_f draw_alpha = get_draw_alpha(mpi->imgfmt); | |
329 | |
330 if(!draw_alpha) { | |
331 printf("Unsupported outformat !!!!\n"); | |
332 return; | |
333 } | |
334 | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
335 render_txt(txt); |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
336 |
8197 | 337 if(x > mpi->w || y > mpi->h) |
338 return; | |
339 | |
340 if(anchor & MENU_TEXT_VCENTER) { | |
341 if(h <= 0) h = mpi->h; | |
342 ymin = y - h/2; | |
343 ymax = y + h/2; | |
344 } else if(anchor & MENU_TEXT_BOT) { | |
345 if(h <= 0) h = mpi->h - y; | |
346 ymin = y - h; | |
347 ymax = y; | |
348 } else { | |
349 if(h <= 0) h = mpi->h - y; | |
350 ymin = y; | |
351 ymax = y + h; | |
352 } | |
353 | |
354 if(anchor & MENU_TEXT_HCENTER) { | |
355 if(w <= 0) w = mpi->w; | |
356 xmin = x - w/2; | |
357 xmax = x + w/2; | |
358 } else if(anchor & MENU_TEXT_RIGHT) { | |
359 if(w <= 0) w = mpi->w -x; | |
360 xmin = x - w; | |
361 xmax = x; | |
362 } else { | |
363 if(w <= 0) w = mpi->w -x; | |
364 xmin = x; | |
365 xmax = x + w; | |
366 } | |
367 | |
368 // How many space do we need to draw this ? | |
369 menu_text_size(txt,w,vspace,warp,&need_w,&need_h); | |
370 | |
371 // Find the first line | |
372 if(align & MENU_TEXT_VCENTER) | |
373 sy = ymin + ((h - need_h)/2); | |
374 else if(align & MENU_TEXT_BOT) | |
8232 | 375 sy = ymax - need_h - 1; |
8197 | 376 else |
377 sy = y; | |
378 | |
379 #if 0 | |
380 // Find the first col | |
381 if(align & MENU_TEXT_HCENTER) | |
382 sx = xmin + ((w - need_w)/2); | |
383 else if(align & MENU_TEXT_RIGHT) | |
384 sx = xmax - need_w; | |
385 #endif | |
386 | |
387 xmid = xmin + (xmax - xmin) / 2; | |
388 xrmin = xmin; | |
389 // Clamp the bb to the mpi size | |
390 if(ymin < 0) ymin = 0; | |
391 if(xmin < 0) xmin = 0; | |
392 if(ymax > mpi->h) ymax = mpi->h; | |
393 if(xmax > mpi->w) xmax = mpi->w; | |
394 | |
395 // Jump some the beginnig text if needed | |
396 while(sy < ymin && *txt) { | |
397 unsigned char c=*txt++; | |
398 if(c == '\n' || (warp && ll + vo_font->width[c] > w)) { | |
399 ll = 0; | |
400 sy += vo_font->height + vspace; | |
401 if(c == '\n') continue; | |
402 } | |
403 ll += vo_font->width[c]+vo_font->charspace; | |
404 } | |
405 if(*txt == '\0') // Nothing left to draw | |
406 return; | |
407 | |
408 while(sy < ymax && *txt) { | |
409 char* line_end = NULL; | |
410 int n; | |
411 | |
412 if(txt[0] == '\n') { // New line | |
413 sy += vo_font->height + vspace; | |
414 txt++; | |
415 continue; | |
416 } | |
417 | |
418 // Get the length and end of this line | |
419 for(n = 0, ll = 0 ; txt[n] != '\0' && txt[n] != '\n' ; n++) { | |
420 unsigned char c = txt[n]; | |
421 if(warp && ll + vo_font->width[c] > w) break; | |
422 ll += vo_font->width[c]+vo_font->charspace; | |
423 } | |
424 line_end = &txt[n]; | |
425 ll -= vo_font->charspace; | |
426 | |
427 | |
428 if(align & (MENU_TEXT_HCENTER|MENU_TEXT_RIGHT)) { | |
429 // Too long line | |
430 if(ll > xmax-xmin) { | |
431 if(align & MENU_TEXT_HCENTER) { | |
432 int mid = ll/2; | |
433 // Find the middle point | |
434 for(n--, ll = 0 ; n <= 0 ; n--) { | |
435 ll += vo_font->width[(int)txt[n]]+vo_font->charspace; | |
436 if(ll - vo_font->charspace > mid) break; | |
437 } | |
438 ll -= vo_font->charspace; | |
439 sx = xmid + mid - ll; | |
440 } else// MENU_TEXT_RIGHT) | |
441 sx = xmax + vo_font->charspace; | |
442 | |
443 // We are after the start point -> go back | |
444 if(sx > xmin) { | |
445 for(n-- ; n <= 0 ; n--) { | |
446 unsigned char c = txt[n]; | |
447 if(sx - vo_font->width[c] - vo_font->charspace < xmin) break; | |
448 sx -= vo_font->width[c]+vo_font->charspace; | |
449 } | |
450 } else { // We are before the start point -> go forward | |
451 for( ; sx < xmin && (&txt[n]) != line_end ; n++) { | |
452 unsigned char c = txt[n]; | |
453 sx += vo_font->width[c]+vo_font->charspace; | |
454 } | |
455 } | |
456 txt = &txt[n]; // Jump to the new start char | |
457 } else { | |
458 if(align & MENU_TEXT_HCENTER) | |
459 sx = xmid - ll/2; | |
460 else | |
8232 | 461 sx = xmax - 1 - ll; |
8197 | 462 } |
463 } else { | |
464 for(sx = xrmin ; sx < xmin && txt != line_end ; txt++) { | |
465 unsigned char c = txt[n]; | |
466 sx += vo_font->width[c]+vo_font->charspace; | |
467 } | |
468 } | |
469 | |
470 while(sx < xmax && txt != line_end) { | |
471 unsigned char c = *txt++; | |
472 font = vo_font->font[c]; | |
8232 | 473 if(font >= 0) { |
474 int cs = (vo_font->pic_a[font]->h - vo_font->height) / 2; | |
475 if ((sx + vo_font->width[c] < xmax) && (sy + vo_font->height < ymax) ) | |
476 draw_alpha(vo_font->width[c], vo_font->height, | |
477 vo_font->pic_b[font]->bmp+vo_font->start[c] + | |
478 cs * vo_font->pic_a[font]->w, | |
479 vo_font->pic_a[font]->bmp+vo_font->start[c] + | |
480 cs * vo_font->pic_a[font]->w, | |
481 vo_font->pic_a[font]->w, | |
482 mpi->planes[0] + sy * mpi->stride[0] + sx * (mpi->bpp>>3), | |
483 mpi->stride[0]); | |
484 // else | |
485 //printf("Can't draw '%c'\n",c); | |
486 } | |
8197 | 487 sx+=vo_font->width[c]+vo_font->charspace; |
488 } | |
489 txt = line_end; | |
490 if(txt[0] == '\0') break; | |
491 sy += vo_font->height + vspace; | |
492 } | |
493 } | |
494 | |
495 int menu_text_length(char* txt) { | |
496 int l = 0; | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
497 render_txt(txt); |
8197 | 498 while (*txt) { |
499 unsigned char c=*txt++; | |
500 l += vo_font->width[c]+vo_font->charspace; | |
501 } | |
502 return l - vo_font->charspace; | |
503 } | |
504 | |
505 void menu_text_size(char* txt,int max_width, int vspace, int warp, int* _w, int* _h) { | |
506 int l = 1, i = 0; | |
507 int w = 0; | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
508 |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
509 render_txt(txt); |
8197 | 510 while (*txt) { |
511 unsigned char c=*txt++; | |
512 if(c == '\n' || (warp && i + vo_font->width[c] >= max_width)) { | |
513 if(*txt) | |
514 l++; | |
515 i = 0; | |
516 if(c == '\n') continue; | |
517 } | |
518 i += vo_font->width[c]+vo_font->charspace; | |
519 if(i > w) w = i; | |
520 } | |
521 | |
522 *_w = w; | |
523 *_h = (l-1) * (vo_font->height + vspace) + vo_font->height; | |
524 } | |
525 | |
526 | |
527 int menu_text_num_lines(char* txt, int max_width) { | |
528 int l = 1, i = 0; | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
529 render_txt(txt); |
8197 | 530 while (*txt) { |
531 unsigned char c=*txt++; | |
532 if(c == '\n' || i + vo_font->width[c] > max_width) { | |
533 l++; | |
534 i = 0; | |
535 if(c == '\n') continue; | |
536 } | |
537 i += vo_font->width[c]+vo_font->charspace; | |
538 } | |
539 return l; | |
540 } | |
541 | |
542 char* menu_text_get_next_line(char* txt, int max_width) { | |
543 int i = 0; | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
544 render_txt(txt); |
8197 | 545 while (*txt) { |
546 unsigned char c=*txt; | |
547 if(c == '\n') { | |
548 txt++; | |
549 break; | |
550 } | |
551 i += vo_font->width[c]; | |
552 if(i >= max_width) | |
553 break; | |
554 i += vo_font->charspace; | |
555 } | |
556 return txt; | |
557 } |