Mercurial > mplayer.hg
annotate libmenu/menu.c @ 20874:b6d87b58754f
Partial fix for semitransparent glyph outlines.
This fix removes semitransparent area (less then pixel width) between glyph and
it's outline. Instead, it makes them overlap a little. It usually looks much
better this way.
Complete fix seems impossible with the current output format (single color
alpha bitmaps). The right way is to blend both glyph and outline into one
bitmap so that 2 pixels with 50% transparency produce a fully solid one.
This requires RGBA bitmap output from libass.
author | eugeni |
---|---|
date | Mon, 13 Nov 2006 16:35:15 +0000 |
parents | d03b71ab8b65 |
children | 14061bc22cb3 |
rev | line source |
---|---|
8197 | 1 |
16862 | 2 #include "config.h" |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
3 #include "mp_msg.h" |
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
4 #include "help_mp.h" |
8197 | 5 |
6 #include <stdlib.h> | |
7 #include <stdio.h> | |
8 #include <string.h> | |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
9 #include <fcntl.h> |
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
10 #include <unistd.h> |
8197 | 11 |
16862 | 12 #include "libvo/osd.h" |
13 #include "libvo/font_load.h" | |
14 #include "osdep/keycodes.h" | |
15 #include "asxparser.h" | |
19271
64d82a45a05d
introduce new 'stream' directory for all stream layer related components and split them from libmpdemux
ben
parents:
18194
diff
changeset
|
16 #include "stream/stream.h" |
8197 | 17 |
19431
ac69ba536915
Explicitly include libmpcodecs/img_format.h and libvo/fastmemcpy.h.
diego
parents:
19271
diff
changeset
|
18 #include "libmpcodecs/img_format.h" |
ac69ba536915
Explicitly include libmpcodecs/img_format.h and libvo/fastmemcpy.h.
diego
parents:
19271
diff
changeset
|
19 #include "libmpcodecs/mp_image.h" |
16862 | 20 #include "m_option.h" |
21 #include "m_struct.h" | |
8197 | 22 #include "menu.h" |
23 | |
24 extern menu_info_t menu_info_cmdlist; | |
25 extern menu_info_t menu_info_pt; | |
26 extern menu_info_t menu_info_filesel; | |
27 extern menu_info_t menu_info_txt; | |
28 extern menu_info_t menu_info_console; | |
29 extern menu_info_t menu_info_pref; | |
10626
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
30 #ifdef HAS_DVBIN_SUPPORT |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
31 extern menu_info_t menu_info_dvbsel; |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
32 #endif |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
33 |
8197 | 34 |
35 menu_info_t* menu_info_list[] = { | |
36 &menu_info_pt, | |
37 &menu_info_cmdlist, | |
38 &menu_info_filesel, | |
39 &menu_info_txt, | |
40 &menu_info_console, | |
10626
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
41 #ifdef HAS_DVBIN_SUPPORT |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
42 &menu_info_dvbsel, |
fd97f3727f15
Finnaly commit Nico's dvb menu. Sorry for committing this
albeu
parents:
10397
diff
changeset
|
43 #endif |
8197 | 44 &menu_info_pref, |
45 NULL | |
46 }; | |
47 | |
48 typedef struct menu_def_st { | |
49 char* name; | |
50 menu_info_t* type; | |
51 void* cfg; | |
52 char* args; | |
53 } menu_def_t; | |
54 | |
55 static menu_def_t* menu_list = NULL; | |
56 static int mcount = 0; | |
57 | |
58 | |
59 static int menu_parse_config(char* buffer) { | |
60 char *element,*body, **attribs, *name; | |
61 menu_info_t* minfo = NULL; | |
62 int r,i; | |
63 ASX_Parser_t* parser = asx_parser_new(); | |
64 | |
65 while(1) { | |
66 r = asx_get_element(parser,&buffer,&element,&body,&attribs); | |
67 if(r < 0) { | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
68 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_SyntaxErrorAtLine,parser->line); |
8197 | 69 asx_parser_free(parser); |
70 return 0; | |
71 } else if(r == 0) { | |
72 asx_parser_free(parser); | |
73 return 1; | |
74 } | |
75 // Has it a name ? | |
76 name = asx_get_attrib("name",attribs); | |
77 if(!name) { | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
78 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuDefinitionsNeedANameAttrib,parser->line); |
8197 | 79 free(element); |
80 if(body) free(body); | |
81 asx_free_attribs(attribs); | |
82 continue; | |
83 } | |
84 | |
85 // Try to find this menu type in our list | |
86 for(i = 0, minfo = NULL ; menu_info_list[i] ; i++) { | |
87 if(strcasecmp(element,menu_info_list[i]->name) == 0) { | |
88 minfo = menu_info_list[i]; | |
89 break; | |
90 } | |
91 } | |
92 // Got it : add this to our list | |
93 if(minfo) { | |
94 menu_list = realloc(menu_list,(mcount+2)*sizeof(menu_def_t)); | |
95 menu_list[mcount].name = name; | |
96 menu_list[mcount].type = minfo; | |
97 menu_list[mcount].cfg = m_struct_alloc(&minfo->priv_st); | |
98 menu_list[mcount].args = body; | |
99 // Setup the attribs | |
100 for(i = 0 ; attribs[2*i] ; i++) { | |
101 if(strcasecmp(attribs[2*i],"name") == 0) continue; | |
102 if(!m_struct_set(&minfo->priv_st,menu_list[mcount].cfg,attribs[2*i], attribs[2*i+1])) | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
103 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_BadAttrib,attribs[2*i],attribs[2*i+1], |
8197 | 104 name,parser->line); |
105 } | |
106 mcount++; | |
107 memset(&menu_list[mcount],0,sizeof(menu_def_t)); | |
108 } else { | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
109 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_UnknownMenuType,element,parser->line); |
8197 | 110 free(name); |
111 if(body) free(body); | |
112 } | |
113 | |
114 free(element); | |
115 asx_free_attribs(attribs); | |
116 } | |
117 | |
118 } | |
119 | |
120 | |
121 /// This will build the menu_defs list from the cfg file | |
122 #define BUF_STEP 1024 | |
123 #define BUF_MIN 128 | |
124 #define BUF_MAX BUF_STEP*1024 | |
125 int menu_init(char* cfg_file) { | |
126 char* buffer = NULL; | |
127 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
|
128 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
|
129 #ifndef HAVE_FREETYPE |
9103
6c2c74adaebe
mplayer crashes if one tries to use osd menu without having a font
arpi
parents:
8604
diff
changeset
|
130 if(vo_font == NULL) |
6c2c74adaebe
mplayer crashes if one tries to use osd menu without having a font
arpi
parents:
8604
diff
changeset
|
131 return 0; |
9212
24b102dbd0fe
Fixes a problem where the menu won't work, if you just use freetype fonts
arpi
parents:
9103
diff
changeset
|
132 #endif |
9103
6c2c74adaebe
mplayer crashes if one tries to use osd menu without having a font
arpi
parents:
8604
diff
changeset
|
133 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
|
134 if(fd < 0) { |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
135 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_CantOpenConfigFile,cfg_file); |
8197 | 136 return 0; |
137 } | |
138 buffer = malloc(bl); | |
139 while(1) { | |
140 int r; | |
141 if(bl - br < BUF_MIN) { | |
142 if(bl >= BUF_MAX) { | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
143 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_ConfigFileIsTooBig,BUF_MAX/1024); |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
144 close(fd); |
8197 | 145 free(buffer); |
146 return 0; | |
147 } | |
148 bl += BUF_STEP; | |
149 buffer = realloc(buffer,bl); | |
150 } | |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
151 r = read(fd,buffer+br,bl-br); |
8197 | 152 if(r == 0) break; |
153 br += r; | |
154 } | |
155 if(!br) { | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
156 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_ConfigFileIsEmpty); |
8197 | 157 return 0; |
158 } | |
159 buffer[br-1] = '\0'; | |
160 | |
8604
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
161 close(fd); |
41a1e5dbb552
This patch fixes the reading of the menu.conf, because stream_open()
arpi
parents:
8251
diff
changeset
|
162 |
8197 | 163 f = menu_parse_config(buffer); |
164 free(buffer); | |
165 return f; | |
166 } | |
167 | |
168 // Destroy all this stuff | |
169 void menu_unint(void) { | |
170 int i; | |
171 for(i = 0 ; menu_list && menu_list[i].name ; i++) { | |
172 free(menu_list[i].name); | |
173 m_struct_free(&menu_list[i].type->priv_st,menu_list[i].cfg); | |
174 if(menu_list[i].args) free(menu_list[i].args); | |
175 } | |
176 free(menu_list); | |
177 mcount = 0; | |
178 } | |
179 | |
180 /// Default read_key function | |
181 void menu_dflt_read_key(menu_t* menu,int cmd) { | |
182 switch(cmd) { | |
183 case KEY_UP: | |
184 menu->read_cmd(menu,MENU_CMD_UP); | |
185 break; | |
186 case KEY_DOWN: | |
187 menu->read_cmd(menu,MENU_CMD_DOWN); | |
188 break; | |
189 case KEY_LEFT: | |
17945
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
190 menu->read_cmd(menu,MENU_CMD_LEFT); |
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
191 break; |
8197 | 192 case KEY_ESC: |
193 menu->read_cmd(menu,MENU_CMD_CANCEL); | |
194 break; | |
195 case KEY_RIGHT: | |
17945
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
196 menu->read_cmd(menu,MENU_CMD_RIGHT); |
98f4e3704a76
Allow 6 ways (up/down/left/right/ok/cancel) navigation.
albeu
parents:
16862
diff
changeset
|
197 break; |
8197 | 198 case KEY_ENTER: |
199 menu->read_cmd(menu,MENU_CMD_OK); | |
200 break; | |
201 } | |
202 } | |
203 | |
204 menu_t* menu_open(char *name) { | |
205 menu_t* m; | |
206 int i; | |
207 | |
208 for(i = 0 ; menu_list[i].name != NULL ; i++) { | |
209 if(strcmp(name,menu_list[i].name) == 0) | |
210 break; | |
211 } | |
212 if(menu_list[i].name == NULL) { | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
213 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuNotFound,name); |
8197 | 214 return NULL; |
215 } | |
216 m = calloc(1,sizeof(menu_t)); | |
217 m->priv_st = &(menu_list[i].type->priv_st); | |
218 m->priv = m_struct_copy(m->priv_st,menu_list[i].cfg); | |
219 if(menu_list[i].type->open(m,menu_list[i].args)) | |
220 return m; | |
221 if(m->priv) | |
222 m_struct_free(m->priv_st,m->priv); | |
223 free(m); | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
224 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuInitFailed,name); |
8197 | 225 return NULL; |
226 } | |
227 | |
228 void menu_draw(menu_t* menu,mp_image_t* mpi) { | |
229 if(menu->show && menu->draw) | |
230 menu->draw(menu,mpi); | |
231 } | |
232 | |
233 void menu_read_cmd(menu_t* menu,int cmd) { | |
234 if(menu->read_cmd) | |
235 menu->read_cmd(menu,cmd); | |
236 } | |
237 | |
238 void menu_close(menu_t* menu) { | |
239 if(menu->close) | |
240 menu->close(menu); | |
241 if(menu->priv) | |
242 m_struct_free(menu->priv_st,menu->priv); | |
243 free(menu); | |
244 } | |
245 | |
246 void menu_read_key(menu_t* menu,int cmd) { | |
247 if(menu->read_key) | |
248 menu->read_key(menu,cmd); | |
249 else | |
250 menu_dflt_read_key(menu,cmd); | |
251 } | |
252 | |
253 ///////////////////////////// Helpers //////////////////////////////////// | |
254 | |
255 typedef void (*draw_alpha_f)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride); | |
256 | |
257 inline static draw_alpha_f get_draw_alpha(uint32_t fmt) { | |
258 switch(fmt) { | |
259 case IMGFMT_BGR15: | |
260 case IMGFMT_RGB15: | |
261 return vo_draw_alpha_rgb15; | |
262 case IMGFMT_BGR16: | |
263 case IMGFMT_RGB16: | |
264 return vo_draw_alpha_rgb16; | |
265 case IMGFMT_BGR24: | |
266 case IMGFMT_RGB24: | |
267 return vo_draw_alpha_rgb24; | |
268 case IMGFMT_BGR32: | |
269 case IMGFMT_RGB32: | |
270 return vo_draw_alpha_rgb32; | |
271 case IMGFMT_YV12: | |
272 case IMGFMT_I420: | |
273 case IMGFMT_IYUV: | |
274 case IMGFMT_YVU9: | |
275 case IMGFMT_IF09: | |
276 case IMGFMT_Y800: | |
277 case IMGFMT_Y8: | |
278 return vo_draw_alpha_yv12; | |
279 case IMGFMT_YUY2: | |
280 return vo_draw_alpha_yuy2; | |
18194 | 281 case IMGFMT_UYVY: |
282 return vo_draw_alpha_uyvy; | |
8197 | 283 } |
284 | |
285 return NULL; | |
286 } | |
287 | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
288 // return the real height of a char: |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
289 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
|
290 int font; |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
291 if ((font=vo_font->font[c])>=0) |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
292 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
|
293 return h; |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
294 } |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
295 |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
296 #ifdef HAVE_FREETYPE |
20507
d03b71ab8b65
Fix possible crash: negative values may no be passed to render_one_glyph
reimar
parents:
19431
diff
changeset
|
297 #define render_txt(t) { unsigned char* p = t; while(*p) render_one_glyph(vo_font,*p++); } |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
298 #else |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
299 #define render_txt(t) |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
300 #endif |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
301 |
8197 | 302 |
303 void menu_draw_text(mp_image_t* mpi,char* txt, int x, int y) { | |
304 draw_alpha_f draw_alpha = get_draw_alpha(mpi->imgfmt); | |
305 int font; | |
306 | |
307 if(!draw_alpha) { | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
308 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_UnsupportedOutformat); |
8197 | 309 return; |
310 } | |
311 | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
312 render_txt(txt); |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
313 |
8197 | 314 while (*txt) { |
315 unsigned char c=*txt++; | |
316 if ((font=vo_font->font[c])>=0 && (x + vo_font->width[c] <= mpi->w) && (y + vo_font->pic_a[font]->h <= mpi->h)) | |
317 draw_alpha(vo_font->width[c], vo_font->pic_a[font]->h, | |
318 vo_font->pic_b[font]->bmp+vo_font->start[c], | |
319 vo_font->pic_a[font]->bmp+vo_font->start[c], | |
320 vo_font->pic_a[font]->w, | |
321 mpi->planes[0] + y * mpi->stride[0] + x * (mpi->bpp>>3), | |
322 mpi->stride[0]); | |
323 x+=vo_font->width[c]+vo_font->charspace; | |
324 } | |
325 | |
326 } | |
327 | |
328 void menu_draw_text_full(mp_image_t* mpi,char* txt, | |
329 int x, int y,int w, int h, | |
330 int vspace, int warp, int align, int anchor) { | |
331 int need_w,need_h; | |
332 int sy, ymin, ymax; | |
333 int sx, xmin, xmax, xmid, xrmin; | |
334 int ll = 0; | |
335 int font; | |
336 draw_alpha_f draw_alpha = get_draw_alpha(mpi->imgfmt); | |
337 | |
338 if(!draw_alpha) { | |
17994
6927fabaef92
Part1 of several printf2mp_msg changes in patch from Otvos Attila oattila AT chello DOT hu
reynaldo
parents:
17993
diff
changeset
|
339 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_UnsupportedOutformat); |
8197 | 340 return; |
341 } | |
342 | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
343 render_txt(txt); |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
344 |
8197 | 345 if(x > mpi->w || y > mpi->h) |
346 return; | |
347 | |
348 if(anchor & MENU_TEXT_VCENTER) { | |
349 if(h <= 0) h = mpi->h; | |
350 ymin = y - h/2; | |
351 ymax = y + h/2; | |
352 } else if(anchor & MENU_TEXT_BOT) { | |
353 if(h <= 0) h = mpi->h - y; | |
354 ymin = y - h; | |
355 ymax = y; | |
356 } else { | |
357 if(h <= 0) h = mpi->h - y; | |
358 ymin = y; | |
359 ymax = y + h; | |
360 } | |
361 | |
362 if(anchor & MENU_TEXT_HCENTER) { | |
363 if(w <= 0) w = mpi->w; | |
364 xmin = x - w/2; | |
365 xmax = x + w/2; | |
366 } else if(anchor & MENU_TEXT_RIGHT) { | |
367 if(w <= 0) w = mpi->w -x; | |
368 xmin = x - w; | |
369 xmax = x; | |
370 } else { | |
371 if(w <= 0) w = mpi->w -x; | |
372 xmin = x; | |
373 xmax = x + w; | |
374 } | |
375 | |
376 // How many space do we need to draw this ? | |
377 menu_text_size(txt,w,vspace,warp,&need_w,&need_h); | |
378 | |
379 // Find the first line | |
380 if(align & MENU_TEXT_VCENTER) | |
381 sy = ymin + ((h - need_h)/2); | |
382 else if(align & MENU_TEXT_BOT) | |
8232 | 383 sy = ymax - need_h - 1; |
8197 | 384 else |
385 sy = y; | |
386 | |
387 #if 0 | |
388 // Find the first col | |
389 if(align & MENU_TEXT_HCENTER) | |
390 sx = xmin + ((w - need_w)/2); | |
391 else if(align & MENU_TEXT_RIGHT) | |
392 sx = xmax - need_w; | |
393 #endif | |
394 | |
395 xmid = xmin + (xmax - xmin) / 2; | |
396 xrmin = xmin; | |
397 // Clamp the bb to the mpi size | |
398 if(ymin < 0) ymin = 0; | |
399 if(xmin < 0) xmin = 0; | |
400 if(ymax > mpi->h) ymax = mpi->h; | |
401 if(xmax > mpi->w) xmax = mpi->w; | |
402 | |
403 // Jump some the beginnig text if needed | |
404 while(sy < ymin && *txt) { | |
405 unsigned char c=*txt++; | |
406 if(c == '\n' || (warp && ll + vo_font->width[c] > w)) { | |
407 ll = 0; | |
408 sy += vo_font->height + vspace; | |
409 if(c == '\n') continue; | |
410 } | |
411 ll += vo_font->width[c]+vo_font->charspace; | |
412 } | |
413 if(*txt == '\0') // Nothing left to draw | |
414 return; | |
415 | |
416 while(sy < ymax && *txt) { | |
417 char* line_end = NULL; | |
418 int n; | |
419 | |
420 if(txt[0] == '\n') { // New line | |
421 sy += vo_font->height + vspace; | |
422 txt++; | |
423 continue; | |
424 } | |
425 | |
426 // Get the length and end of this line | |
427 for(n = 0, ll = 0 ; txt[n] != '\0' && txt[n] != '\n' ; n++) { | |
428 unsigned char c = txt[n]; | |
429 if(warp && ll + vo_font->width[c] > w) break; | |
430 ll += vo_font->width[c]+vo_font->charspace; | |
431 } | |
432 line_end = &txt[n]; | |
433 ll -= vo_font->charspace; | |
434 | |
435 | |
436 if(align & (MENU_TEXT_HCENTER|MENU_TEXT_RIGHT)) { | |
437 // Too long line | |
438 if(ll > xmax-xmin) { | |
439 if(align & MENU_TEXT_HCENTER) { | |
440 int mid = ll/2; | |
441 // Find the middle point | |
442 for(n--, ll = 0 ; n <= 0 ; n--) { | |
443 ll += vo_font->width[(int)txt[n]]+vo_font->charspace; | |
444 if(ll - vo_font->charspace > mid) break; | |
445 } | |
446 ll -= vo_font->charspace; | |
447 sx = xmid + mid - ll; | |
448 } else// MENU_TEXT_RIGHT) | |
449 sx = xmax + vo_font->charspace; | |
450 | |
451 // We are after the start point -> go back | |
452 if(sx > xmin) { | |
453 for(n-- ; n <= 0 ; n--) { | |
454 unsigned char c = txt[n]; | |
455 if(sx - vo_font->width[c] - vo_font->charspace < xmin) break; | |
456 sx -= vo_font->width[c]+vo_font->charspace; | |
457 } | |
458 } else { // We are before the start point -> go forward | |
459 for( ; sx < xmin && (&txt[n]) != line_end ; n++) { | |
460 unsigned char c = txt[n]; | |
461 sx += vo_font->width[c]+vo_font->charspace; | |
462 } | |
463 } | |
464 txt = &txt[n]; // Jump to the new start char | |
465 } else { | |
466 if(align & MENU_TEXT_HCENTER) | |
467 sx = xmid - ll/2; | |
468 else | |
8232 | 469 sx = xmax - 1 - ll; |
8197 | 470 } |
471 } else { | |
472 for(sx = xrmin ; sx < xmin && txt != line_end ; txt++) { | |
473 unsigned char c = txt[n]; | |
474 sx += vo_font->width[c]+vo_font->charspace; | |
475 } | |
476 } | |
477 | |
478 while(sx < xmax && txt != line_end) { | |
479 unsigned char c = *txt++; | |
480 font = vo_font->font[c]; | |
8232 | 481 if(font >= 0) { |
482 int cs = (vo_font->pic_a[font]->h - vo_font->height) / 2; | |
483 if ((sx + vo_font->width[c] < xmax) && (sy + vo_font->height < ymax) ) | |
484 draw_alpha(vo_font->width[c], vo_font->height, | |
485 vo_font->pic_b[font]->bmp+vo_font->start[c] + | |
486 cs * vo_font->pic_a[font]->w, | |
487 vo_font->pic_a[font]->bmp+vo_font->start[c] + | |
488 cs * vo_font->pic_a[font]->w, | |
489 vo_font->pic_a[font]->w, | |
490 mpi->planes[0] + sy * mpi->stride[0] + sx * (mpi->bpp>>3), | |
491 mpi->stride[0]); | |
492 // else | |
493 //printf("Can't draw '%c'\n",c); | |
494 } | |
8197 | 495 sx+=vo_font->width[c]+vo_font->charspace; |
496 } | |
497 txt = line_end; | |
498 if(txt[0] == '\0') break; | |
499 sy += vo_font->height + vspace; | |
500 } | |
501 } | |
502 | |
503 int menu_text_length(char* txt) { | |
504 int l = 0; | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
505 render_txt(txt); |
8197 | 506 while (*txt) { |
507 unsigned char c=*txt++; | |
508 l += vo_font->width[c]+vo_font->charspace; | |
509 } | |
510 return l - vo_font->charspace; | |
511 } | |
512 | |
513 void menu_text_size(char* txt,int max_width, int vspace, int warp, int* _w, int* _h) { | |
514 int l = 1, i = 0; | |
515 int w = 0; | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
516 |
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
517 render_txt(txt); |
8197 | 518 while (*txt) { |
519 unsigned char c=*txt++; | |
520 if(c == '\n' || (warp && i + vo_font->width[c] >= max_width)) { | |
521 if(*txt) | |
522 l++; | |
523 i = 0; | |
524 if(c == '\n') continue; | |
525 } | |
526 i += vo_font->width[c]+vo_font->charspace; | |
527 if(i > w) w = i; | |
528 } | |
529 | |
530 *_w = w; | |
531 *_h = (l-1) * (vo_font->height + vspace) + vo_font->height; | |
532 } | |
533 | |
534 | |
535 int menu_text_num_lines(char* txt, int max_width) { | |
536 int l = 1, i = 0; | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
537 render_txt(txt); |
8197 | 538 while (*txt) { |
539 unsigned char c=*txt++; | |
540 if(c == '\n' || i + vo_font->width[c] > max_width) { | |
541 l++; | |
542 i = 0; | |
543 if(c == '\n') continue; | |
544 } | |
545 i += vo_font->width[c]+vo_font->charspace; | |
546 } | |
547 return l; | |
548 } | |
549 | |
550 char* menu_text_get_next_line(char* txt, int max_width) { | |
551 int i = 0; | |
8224
fefc56153615
Fix freetype. Freetype is highly recommended for a nice output ;)
albeu
parents:
8197
diff
changeset
|
552 render_txt(txt); |
8197 | 553 while (*txt) { |
554 unsigned char c=*txt; | |
555 if(c == '\n') { | |
556 txt++; | |
557 break; | |
558 } | |
559 i += vo_font->width[c]; | |
560 if(i >= max_width) | |
561 break; | |
562 i += vo_font->charspace; | |
563 } | |
564 return txt; | |
565 } | |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
566 |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
567 |
18193 | 568 void menu_draw_box(mp_image_t* mpi,unsigned char grey,unsigned char alpha, int x, int y, int w, int h) { |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
569 draw_alpha_f draw_alpha = get_draw_alpha(mpi->imgfmt); |
18193 | 570 int g; |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
571 |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
572 if(!draw_alpha) { |
18193 | 573 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_UnsupportedOutformat); |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
574 return; |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
575 } |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
576 |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
577 if(x > mpi->w || y > mpi->h) return; |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
578 |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
579 if(x < 0) w += x, x = 0; |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
580 if(x+w > mpi->w) w = mpi->w-x; |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
581 if(y < 0) h += y, y = 0; |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
582 if(y+h > mpi->h) h = mpi->h-y; |
18193 | 583 |
584 g = ((256-alpha)*grey)>>8; | |
585 if(g < 1) g = 1; | |
586 | |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
587 { |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
588 int stride = (w+7)&(~7); // round to 8 |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
589 char pic[stride*h],pic_alpha[stride*h]; |
18193 | 590 memset(pic,g,stride*h); |
17993
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
591 memset(pic_alpha,alpha,stride*h); |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
592 draw_alpha(w,h,pic,pic_alpha,stride, |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
593 mpi->planes[0] + y * mpi->stride[0] + x * (mpi->bpp>>3), |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
594 mpi->stride[0]); |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
595 } |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
596 |
98eb966a4024
Add a function to draw flat boxes and use it to make the list
albeu
parents:
17945
diff
changeset
|
597 } |