Mercurial > mplayer.hg
comparison libvo/sub.c @ 5638:86663f1b9b00
new osd code, use osd objs to follow changes and do minimal updates
author | arpi |
---|---|
date | Mon, 15 Apr 2002 19:17:12 +0000 |
parents | a531a579f005 |
children | a0cee3bb7f78 |
comparison
equal
deleted
inserted
replaced
5637:6890819bc0dc | 5638:86663f1b9b00 |
---|---|
1 | 1 |
2 #include <stdio.h> | 2 #include <stdio.h> |
3 #include <stdlib.h> | 3 #include <stdlib.h> |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "mp_msg.h" | |
6 #include "video_out.h" | 7 #include "video_out.h" |
7 #include "font_load.h" | 8 #include "font_load.h" |
8 #include "sub.h" | 9 #include "sub.h" |
9 | 10 |
10 char * __sub_osd_names[]={ | 11 char * __sub_osd_names[]={ |
61 // | | | | | | 62 // | | | | | |
62 // [ === === === ... === ] | 63 // [ === === === ... === ] |
63 // | 64 // |
64 // the above schema is rescalled to n=elems bars | 65 // the above schema is rescalled to n=elems bars |
65 | 66 |
66 inline static void vo_draw_text_progbar(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ | 67 inline static void vo_update_text_progbar(mp_osd_obj_t* obj,int dxs,int dys){ |
67 unsigned char *s; | 68 |
68 unsigned char *sa; | 69 obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; |
69 int i,w,h,st,mark; | 70 |
71 if(vo_osd_progbar_type<0 || !vo_font){ | |
72 obj->flags&=~OSDFLAG_VISIBLE; | |
73 return; | |
74 } | |
75 | |
76 { | |
70 int y=(dys-vo_font->height)/2; | 77 int y=(dys-vo_font->height)/2; |
71 int c,font; | |
72 int delimw=vo_font->width[OSD_PB_START] | 78 int delimw=vo_font->width[OSD_PB_START] |
73 +vo_font->width[OSD_PB_END] | 79 +vo_font->width[OSD_PB_END] |
74 +vo_font->charspace; | 80 +vo_font->charspace; |
75 int width=(2*dxs-3*delimw)/3; | 81 int width=(2*dxs-3*delimw)/3; |
76 int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; | 82 int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; |
77 int elems=width/charw; | 83 int elems=width/charw; |
78 int x=(dxs-elems*charw-delimw)/2; | 84 int x=(dxs-elems*charw-delimw)/2; |
85 obj->bbox.x1=obj->x=x; | |
86 obj->bbox.y1=obj->y=y; | |
87 obj->bbox.x2=x+width+delimw; | |
88 obj->bbox.y2=y+vo_font->height; | |
89 obj->params.progbar.elems=elems; | |
90 } | |
91 | |
92 } | |
93 | |
94 inline static void vo_draw_text_progbar(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ | |
95 unsigned char *s; | |
96 unsigned char *sa; | |
97 int i,w,h,st,mark; | |
98 int x=obj->x; | |
99 int y=obj->y; | |
100 int c,font; | |
101 int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; | |
102 int elems=obj->params.progbar.elems; | |
79 | 103 |
80 if (vo_osd_progbar_value<=0) | 104 if (vo_osd_progbar_value<=0) |
81 mark=0; | 105 mark=0; |
82 else { | 106 else { |
83 int ev=vo_osd_progbar_value*elems; | 107 int ev=vo_osd_progbar_value*elems; |
151 | 175 |
152 } | 176 } |
153 | 177 |
154 subtitle* vo_sub=NULL; | 178 subtitle* vo_sub=NULL; |
155 | 179 |
156 #define MAX_UCS 1600 | 180 // vo_draw_text_sub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) |
157 #define MAX_UCSLINES 16 | 181 |
158 | 182 inline static void vo_update_text_sub(mp_osd_obj_t* obj,int dxs,int dys){ |
159 | |
160 inline static void vo_draw_text_sub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ | |
161 static int utbl[MAX_UCS+1]; | |
162 static int xtbl[MAX_UCSLINES]; | |
163 static int lines; | |
164 static subtitle *memsub=NULL; | |
165 static int memy; | |
166 static int memdxs; | |
167 static int memdys; | |
168 | |
169 unsigned char *t; | 183 unsigned char *t; |
170 int c,i,j,l,x,y,font; | 184 int c,i,j,l,x,y,font; |
171 int len; | 185 int len; |
172 int k,lastk; | 186 int k,lastk; |
173 int lastStripPosition; | 187 int lastStripPosition; |
174 int xsize,lastxsize; | 188 int xsize,lastxsize; |
175 int h,lasth; | 189 int h,lasth; |
176 | 190 |
177 if ((memsub!=vo_sub)||(memdxs!=dxs)||(memdys!=dys)){ | 191 obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; |
178 | 192 |
179 memsub=vo_sub; | 193 if(!vo_sub || !vo_font){ |
180 memdxs=dxs; | 194 obj->flags&=~OSDFLAG_VISIBLE; |
181 memdys=memy=dys; | 195 return; |
182 | 196 } |
197 | |
198 obj->y=dys; | |
199 obj->params.subtitle.lines=0; | |
200 | |
183 // too long lines divide into a smaller ones | 201 // too long lines divide into a smaller ones |
184 i=k=lines=lasth=0; | 202 i=k=lasth=0; |
185 h=vo_font->height; | 203 h=vo_font->height; |
186 xsize=-vo_font->charspace; | 204 xsize=-vo_font->charspace; |
187 lastStripPosition=-1; | 205 lastStripPosition=-1; |
188 l=vo_sub->lines; | 206 l=vo_sub->lines; |
189 | 207 |
206 } else if (sub_unicode) | 224 } else if (sub_unicode) |
207 c = (c<<8) + t[++j]; | 225 c = (c<<8) + t[++j]; |
208 } | 226 } |
209 if (k==MAX_UCS){ | 227 if (k==MAX_UCS){ |
210 len=j; // end here | 228 len=j; // end here |
211 printf ("\nMAX_UCS exceeded!\n"); | 229 mp_msg(MSGT_OSD,MSGL_WARN,"\nMAX_UCS exceeded!\n"); |
212 } | 230 } |
213 if (!c) c++; // avoid UCS 0 | 231 if (!c) c++; // avoid UCS 0 |
214 if (c==' '){ | 232 if (c==' '){ |
215 lastk=k; | 233 lastk=k; |
216 lastStripPosition=j; | 234 lastStripPosition=j; |
218 } else if ((font=vo_font->font[c])>=0){ | 236 } else if ((font=vo_font->font[c])>=0){ |
219 if (vo_font->pic_a[font]->h > h){ | 237 if (vo_font->pic_a[font]->h > h){ |
220 h=vo_font->pic_a[font]->h; | 238 h=vo_font->pic_a[font]->h; |
221 } | 239 } |
222 } | 240 } |
223 utbl[k++]=c; | 241 obj->params.subtitle.utbl[k++]=c; |
224 xsize+=vo_font->width[c]+vo_font->charspace; | 242 xsize+=vo_font->width[c]+vo_font->charspace; |
225 if (dxs<xsize){ | 243 if (dxs<xsize){ |
226 if (lastStripPosition>0){ | 244 if (lastStripPosition>0){ |
227 j=lastStripPosition; | 245 j=lastStripPosition; |
228 xsize=lastxsize; | 246 xsize=lastxsize; |
232 k--; // cut line here | 250 k--; // cut line here |
233 while (t[j] && t[j]!=' ') j++; // jump to the nearest space | 251 while (t[j] && t[j]!=' ') j++; // jump to the nearest space |
234 } | 252 } |
235 } else if (j<len) | 253 } else if (j<len) |
236 continue; | 254 continue; |
237 if (h>memy){ // out of the screen so end parsing | 255 if (h>obj->y){ // out of the screen so end parsing |
238 memy -= lasth - vo_font->height; // correct the y position | 256 obj->y -= lasth - vo_font->height; // correct the y position |
239 l=0; | 257 l=0; |
240 break; | 258 break; |
241 } | 259 } |
242 utbl[k++]=0; | 260 obj->params.subtitle.utbl[k++]=0; |
243 xtbl[lines++]=(dxs-xsize)/2; | 261 obj->params.subtitle.xtbl[obj->params.subtitle.lines++]=(dxs-xsize)/2; |
244 if (lines==MAX_UCSLINES||k>MAX_UCS){ | 262 if (obj->params.subtitle.lines==MAX_UCSLINES||k>MAX_UCS){ |
245 l=0; len=j; // end parsing | 263 l=0; len=j; // end parsing |
246 } else if(l || j<len){ // not the last line or not the last char | 264 } else if(l || j<len){ // not the last line or not the last char |
247 lastStripPosition=-1; | 265 lastStripPosition=-1; |
248 xsize=-vo_font->charspace; | 266 xsize=-vo_font->charspace; |
249 lasth=h; | 267 lasth=h; |
250 h=vo_font->height; | 268 h=vo_font->height; |
251 } | 269 } |
252 // printf("h: %d -> %d \n",vo_font->height,h); | 270 // printf("h: %d -> %d \n",vo_font->height,h); |
253 memy -=h; // according to max of vo_font->pic_a[font]->h | 271 obj->y -=h; // according to max of vo_font->pic_a[font]->h |
254 } | 272 } |
255 } | 273 } |
256 } | 274 |
257 | 275 // TODO: calculate bbox |
258 if (memy < (dys * sub_pos / 100)) { y = memy; } else { y = dys * sub_pos /100;}; | 276 |
277 } | |
278 | |
279 inline static void vo_draw_text_sub(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ | |
280 int y,i,j,c,x,l,font; | |
281 | |
282 // FIXME (bbox): | |
283 if (obj->y < (obj->dys * sub_pos / 100)) { y = obj->y; } else { y = obj->dys * sub_pos /100;}; | |
259 | 284 |
260 // printf("lines=%d y=%d\n",lines,y); | 285 // printf("lines=%d y=%d\n",lines,y); |
261 | 286 |
262 i=j=0; | 287 i=j=0; |
263 if ((l=lines)) for (;;) { | 288 if ((l=obj->params.subtitle.lines)) for (;;) { |
264 x=xtbl[i++]; | 289 x=obj->params.subtitle.xtbl[i++]; |
265 while ((c=utbl[j++])){ | 290 while ((c=obj->params.subtitle.utbl[j++])){ |
266 if ((font=vo_font->font[c])>=0) | 291 if ((font=vo_font->font[c])>=0) |
267 draw_alpha(x,y, | 292 draw_alpha(x,y, |
268 vo_font->width[c], | 293 vo_font->width[c], |
269 vo_font->pic_a[font]->h+y<dys ? vo_font->pic_a[font]->h : dys-y, | 294 vo_font->pic_a[font]->h+y<obj->dys ? vo_font->pic_a[font]->h : obj->dys-y, |
270 vo_font->pic_b[font]->bmp+vo_font->start[c], | 295 vo_font->pic_b[font]->bmp+vo_font->start[c], |
271 vo_font->pic_a[font]->bmp+vo_font->start[c], | 296 vo_font->pic_a[font]->bmp+vo_font->start[c], |
272 vo_font->pic_a[font]->w); | 297 vo_font->pic_a[font]->w); |
273 x+=vo_font->width[c]+vo_font->charspace; | 298 x+=vo_font->width[c]+vo_font->charspace; |
274 } | 299 } |
275 if (!--l) | 300 if (!--l) break; |
276 return; | |
277 y+=vo_font->height; | 301 y+=vo_font->height; |
278 } | 302 } |
279 } | 303 } |
280 | 304 |
281 void *vo_spudec=NULL; | 305 void *vo_spudec=NULL; |
282 void *vo_vobsub=NULL; | 306 void *vo_vobsub=NULL; |
283 inline static void vo_draw_spudec(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ | |
284 spudec_draw_scaled(vo_spudec, dxs, dys, draw_alpha); | |
285 } | |
286 inline static void vo_draw_vobsub(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ | |
287 vobsub_draw(vo_vobsub, dxs, dys, draw_alpha); | |
288 } | |
289 | 307 |
290 static int draw_alpha_init_flag=0; | 308 static int draw_alpha_init_flag=0; |
291 | 309 |
292 extern void vo_draw_alpha_init(); | 310 extern void vo_draw_alpha_init(); |
293 | 311 |
294 void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ | 312 static mp_osd_obj_t* vo_osd_list=NULL; |
295 | 313 |
296 if(vo_spudec){ | 314 mp_osd_obj_t* new_osd_obj(int type){ |
297 vo_draw_spudec(dxs,dys,draw_alpha); | 315 mp_osd_obj_t* osd=malloc(sizeof(mp_osd_obj_t)); |
298 } | 316 memset(osd,0,sizeof(mp_osd_obj_t)); |
299 | 317 osd->next=vo_osd_list; |
300 if(vo_vobsub){ | 318 vo_osd_list=osd; |
301 vo_draw_vobsub(dxs,dys,draw_alpha); | 319 osd->type=type; |
302 } | 320 return osd; |
303 | 321 } |
304 if(!vo_font) return; // no font | 322 |
305 | 323 void free_osd_list(){ |
324 mp_osd_obj_t* obj=vo_osd_list; | |
325 while(obj){ | |
326 mp_osd_obj_t* next=obj->next; | |
327 free(obj); | |
328 obj=next; | |
329 } | |
330 vo_osd_list=NULL; | |
331 } | |
332 | |
333 int vo_update_osd(int dxs,int dys){ | |
334 mp_osd_obj_t* obj=vo_osd_list; | |
335 int chg=0; | |
336 while(obj){ | |
337 if(dxs!=obj->dxs || dys!=obj->dys || obj->flags&OSDFLAG_FORCE_UPDATE){ | |
338 int vis=obj->flags&OSDFLAG_VISIBLE; | |
339 switch(obj->type){ | |
340 case OSDTYPE_SUBTITLE: | |
341 vo_update_text_sub(obj,dxs,dys); | |
342 break; | |
343 case OSDTYPE_PROGBAR: | |
344 vo_update_text_progbar(obj,dxs,dys); | |
345 break; | |
346 case OSDTYPE_SPU: | |
347 if(vo_spudec && spudec_visible(vo_spudec)) | |
348 obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED; | |
349 else | |
350 obj->flags&=~OSDFLAG_VISIBLE; | |
351 break; | |
352 case OSDTYPE_VOBSUB: | |
353 if(vo_vobsub) | |
354 obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED; | |
355 else | |
356 obj->flags&=~OSDFLAG_VISIBLE; | |
357 break; | |
358 case OSDTYPE_OSD: | |
359 if(vo_font && vo_osd_text && vo_osd_text[0]) | |
360 obj->flags|=OSDFLAG_VISIBLE|OSDFLAG_CHANGED; | |
361 else | |
362 obj->flags&=~OSDFLAG_VISIBLE; | |
363 break; | |
364 } | |
365 // check if visibility changed: | |
366 if(vis != (obj->flags&OSDFLAG_VISIBLE) ) obj->flags|=OSDFLAG_CHANGED; | |
367 // remove the cause of updating: | |
368 obj->dxs=dxs; obj->dys=dys; | |
369 obj->flags&=~OSDFLAG_FORCE_UPDATE; | |
370 } | |
371 if(obj->flags&OSDFLAG_CHANGED){ | |
372 chg|=1<<obj->type; | |
373 mp_msg(MSGT_OSD,MSGL_DBG2,"OSD chg: %d V: %s pb:%d \n",obj->type,(obj->flags&OSDFLAG_VISIBLE)?"yes":"no",vo_osd_progbar_type); | |
374 } | |
375 obj=obj->next; | |
376 } | |
377 return chg; | |
378 } | |
379 | |
380 void vo_init_osd(){ | |
306 if(!draw_alpha_init_flag){ | 381 if(!draw_alpha_init_flag){ |
307 draw_alpha_init_flag=1; | 382 draw_alpha_init_flag=1; |
308 vo_draw_alpha_init(); | 383 vo_draw_alpha_init(); |
309 } | 384 } |
310 | 385 if(vo_osd_list) free_osd_list; |
311 if(vo_osd_text){ | 386 // temp hack, should be moved to mplayer/mencoder later |
312 vo_draw_text_osd(dxs,dys,draw_alpha); | 387 new_osd_obj(OSDTYPE_OSD); |
313 } | 388 new_osd_obj(OSDTYPE_SUBTITLE); |
314 | 389 new_osd_obj(OSDTYPE_PROGBAR); |
315 if(vo_sub){ | 390 new_osd_obj(OSDTYPE_SPU); |
316 vo_draw_text_sub(dxs,dys,draw_alpha); | 391 new_osd_obj(OSDTYPE_VOBSUB); |
317 } | 392 } |
318 | 393 |
319 if(vo_osd_progbar_type>=0 && vo_font->font[OSD_PB_0]>=0){ | 394 void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ |
320 vo_draw_text_progbar(dxs,dys,draw_alpha); | 395 mp_osd_obj_t* obj=vo_osd_list; |
321 } | 396 |
322 | 397 vo_update_osd(dxs,dys); |
323 } | 398 |
324 | 399 while(obj){ |
400 if(obj->flags&OSDFLAG_VISIBLE) | |
401 switch(obj->type){ | |
402 case OSDTYPE_SPU: | |
403 spudec_draw_scaled(vo_spudec, dxs, dys, draw_alpha); // FIXME | |
404 break; | |
405 case OSDTYPE_VOBSUB: | |
406 vobsub_draw(vo_vobsub, dxs, dys, draw_alpha); // FIXME | |
407 break; | |
408 case OSDTYPE_OSD: | |
409 vo_draw_text_osd(dxs,dys,draw_alpha); | |
410 break; | |
411 case OSDTYPE_SUBTITLE: | |
412 vo_draw_text_sub(obj,draw_alpha); | |
413 break; | |
414 case OSDTYPE_PROGBAR: | |
415 vo_draw_text_progbar(obj,draw_alpha); | |
416 break; | |
417 } | |
418 obj->old_bbox=obj->bbox; | |
419 obj->flags&=~OSDFLAG_CHANGED; | |
420 | |
421 obj=obj->next; | |
422 } | |
423 } | |
424 | |
325 static int vo_osd_changed_status = 0; | 425 static int vo_osd_changed_status = 0; |
326 | 426 |
327 int vo_osd_changed(int new_value) | 427 int vo_osd_changed(int new_value) |
328 { | 428 { |
429 mp_osd_obj_t* obj=vo_osd_list; | |
329 int ret = vo_osd_changed_status; | 430 int ret = vo_osd_changed_status; |
330 vo_osd_changed_status = new_value; | 431 vo_osd_changed_status = new_value; |
432 | |
433 while(obj){ | |
434 if(obj->type==new_value) obj->flags|=OSDFLAG_FORCE_UPDATE; | |
435 obj=obj->next; | |
436 } | |
437 | |
331 return ret; | 438 return ret; |
332 } | 439 } |
440 |