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