diff -urN --exclude-from dontdiff vanilla/main/libvo/sub.c main/libvo/sub.c --- vanilla/main/libvo/sub.c Sat May 25 19:40:33 2002 +++ main/libvo/sub.c Thu Aug 15 16:12:21 2002 @@ -40,10 +40,68 @@ return h; } +static void draw_alpha_buf(mp_osd_obj_t* obj, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride) +{ + int dststride = obj->stride; + int dstskip = obj->stride-w; + int srcskip = stride-w; + int i, j; + unsigned char *b = obj->bitmap_buffer + (y0-obj->bbox.y1)*dststride + (x0-obj->bbox.x1); + unsigned char *a = obj->alpha_buffer + (y0-obj->bbox.y1)*dststride + (x0-obj->bbox.x1); + unsigned char *bs = src; + unsigned char *as = srca; + + if (x0 < obj->bbox.x1 || x0+w > obj->bbox.x2 || y0 < obj->bbox.y1 || y0+h > obj->bbox.y2) { + fprintf(stderr, "osd text out of range!\n"); + return; + } + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++, b++, a++, bs++, as++) { + *b |= *bs; + if (*as) { + if (*a == 0 || *a > *as) *a = *as; + } + } + b+= dstskip; + a+= dstskip; + bs+= srcskip; + as+= srcskip; + } +} + +static void alloc_buf(mp_osd_obj_t* obj) +{ + int len; + obj->stride = ((obj->bbox.x2-obj->bbox.x1)+7)&(~7); + len = obj->stride*(obj->bbox.y2-obj->bbox.y1); + if (obj->allocatedallocated = len; + free(obj->bitmap_buffer); + free(obj->alpha_buffer); + obj->bitmap_buffer = (unsigned char *)memalign(16, len); + obj->alpha_buffer = (unsigned char *)memalign(16, len); + } + memset(obj->bitmap_buffer, 0, len); + memset(obj->alpha_buffer, 0, len); +} + +inline static void vo_draw_text_from_buffer(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ + if (obj->allocated > 0) { + draw_alpha(obj->bbox.x1,obj->bbox.y1, + obj->bbox.x2-obj->bbox.x1, + obj->bbox.y2-obj->bbox.y1, + obj->bitmap_buffer, + obj->alpha_buffer, + obj->stride); + } +} + inline static void vo_update_text_osd(mp_osd_obj_t* obj,int dxs,int dys){ unsigned char *cp=vo_osd_text; int x=20; int h=0; + int font; obj->bbox.x1=obj->x=x; obj->bbox.y1=obj->y=10; @@ -58,22 +116,19 @@ obj->bbox.y2=obj->bbox.y1+h; obj->flags|=OSDFLAG_BBOX; -} - -inline static void vo_draw_text_osd(mp_osd_obj_t* obj,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)){ - unsigned char *cp=vo_osd_text; - int font; - int x=obj->x; + alloc_buf(obj); + cp=vo_osd_text; + x = obj->x; while (*cp){ int c=*cp++; if ((font=vo_font->font[c])>=0) - draw_alpha(x,obj->y, - vo_font->width[c], - vo_font->pic_a[font]->h, - vo_font->pic_b[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->w); + draw_alpha_buf(obj,x,obj->y, + vo_font->width[c], + vo_font->pic_a[font]->h, + vo_font->pic_b[font]->bmp+vo_font->start[c], + vo_font->pic_a[font]->bmp+vo_font->start[c], + vo_font->pic_a[font]->w); x+=vo_font->width[c]+vo_font->charspace; } } @@ -89,39 +144,7 @@ // // the above schema is rescalled to n=elems bars -inline static void vo_update_text_progbar(mp_osd_obj_t* obj,int dxs,int dys){ - - obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; - - if(vo_osd_progbar_type<0 || !vo_font){ - obj->flags&=~OSDFLAG_VISIBLE; - return; - } - - { int h=0; - int y=(dys-vo_font->height)/2; - int delimw=vo_font->width[OSD_PB_START] - +vo_font->width[OSD_PB_END] - +vo_font->charspace; - int width=(2*dxs-3*delimw)/3; - int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; - int elems=width/charw; - int x=(dxs-elems*charw-delimw)/2; - h=get_height(OSD_PB_START,h); - h=get_height(OSD_PB_END,h); - h=get_height(OSD_PB_0,h); - h=get_height(OSD_PB_1,h); - obj->bbox.x1=obj->x=x; - obj->bbox.y1=obj->y=y; - obj->bbox.x2=x+width+delimw; - obj->bbox.y2=y+h; //vo_font->height; - obj->flags|=OSDFLAG_BBOX; - obj->params.progbar.elems=elems; - } - -} - -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)){ +inline static void vo_draw_text_progbar_buf(mp_osd_obj_t* obj){ unsigned char *s; unsigned char *sa; int i,w,h,st,mark; @@ -146,7 +169,7 @@ c=vo_osd_progbar_type; if(vo_osd_progbar_type>0 && (font=vo_font->font[c])>=0) { int xp=x-vo_font->width[c]-vo_font->spacewidth; - draw_alpha((xp<0?0:xp),y, + draw_alpha_buf(obj,(xp<0?0:xp),y, vo_font->width[c], vo_font->pic_a[font]->h, vo_font->pic_b[font]->bmp+vo_font->start[c], @@ -156,7 +179,7 @@ c=OSD_PB_START; if ((font=vo_font->font[c])>=0) - draw_alpha(x,y, + draw_alpha_buf(obj,x,y, vo_font->width[c], vo_font->pic_a[font]->h, vo_font->pic_b[font]->bmp+vo_font->start[c], @@ -172,7 +195,7 @@ sa=vo_font->pic_a[font]->bmp+vo_font->start[c]; st=vo_font->pic_a[font]->w; if ((i=mark)) do { - draw_alpha(x,y,w,h,s,sa,st); + draw_alpha_buf(obj,x,y,w,h,s,sa,st); x+=charw; } while(--i); } @@ -185,14 +208,14 @@ sa=vo_font->pic_a[font]->bmp+vo_font->start[c]; st=vo_font->pic_a[font]->w; if ((i=elems-mark)) do { - draw_alpha(x,y,w,h,s,sa,st); + draw_alpha_buf(obj,x,y,w,h,s,sa,st); x+=charw; } while(--i); } c=OSD_PB_END; if ((font=vo_font->font[c])>=0) - draw_alpha(x,y, + draw_alpha_buf(obj,x,y, vo_font->width[c], vo_font->pic_a[font]->h, vo_font->pic_b[font]->bmp+vo_font->start[c], @@ -205,6 +228,47 @@ } +inline static void vo_update_text_progbar(mp_osd_obj_t* obj,int dxs,int dys){ + + obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; + + if(vo_osd_progbar_type<0 || !vo_font){ + obj->flags&=~OSDFLAG_VISIBLE; + return; + } + + { int h=0; + int y=(dys-vo_font->height)/2; + int delimw=vo_font->width[OSD_PB_START] + +vo_font->width[OSD_PB_END] + +vo_font->charspace; + int width=(2*dxs-3*delimw)/3; + int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; + int elems=width/charw; + int x=(dxs-elems*charw-delimw)/2; + int font, delta = 0; + if (vo_osd_progbar_type > 0 && (font=vo_font->font[vo_osd_progbar_type])>=0) { + delta = vo_font->width[vo_osd_progbar_type]+vo_font->spacewidth; + delta = (x-delta > 0) ? delta : x; + } + h=get_height(OSD_PB_START,h); + h=get_height(OSD_PB_END,h); + h=get_height(OSD_PB_0,h); + h=get_height(OSD_PB_1,h); + obj->bbox.x1=obj->x=x; + obj->bbox.y1=obj->y=y; + obj->bbox.x2=x+width+delimw; + obj->bbox.y2=y+h; //vo_font->height; + obj->flags|=OSDFLAG_BBOX; + obj->params.progbar.elems=elems; + obj->bbox.x1-=delta; // space for an icon + } + + alloc_buf(obj); + + vo_draw_text_progbar_buf(obj); +} + subtitle* vo_sub=NULL; // 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)) @@ -317,6 +381,27 @@ obj->bbox.y1=obj->y; // obj->bbox.y2=obj->y+obj->params.subtitle.lines*vo_font->height; obj->flags|=OSDFLAG_BBOX; + + alloc_buf(obj); + + y = obj->y; + + i=j=0; + if ((l=obj->params.subtitle.lines)) for (;;) { + x=obj->params.subtitle.xtbl[i++]; + while ((c=obj->params.subtitle.utbl[j++])){ + if ((font=vo_font->font[c])>=0) + draw_alpha_buf(obj,x,y, + vo_font->width[c], + vo_font->pic_a[font]->h+ydys ? vo_font->pic_a[font]->h : obj->dys-y, + vo_font->pic_b[font]->bmp+vo_font->start[c], + vo_font->pic_a[font]->bmp+vo_font->start[c], + vo_font->pic_a[font]->w); + x+=vo_font->width[c]+vo_font->charspace; + } + if (!--l) break; + y+=vo_font->height; + } } @@ -336,27 +421,6 @@ { spudec_draw_scaled(vo_spudec, obj->dxs, obj->dys, draw_alpha); } -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)){ - int i,j,c,x,l,font; - int y=obj->y; - - i=j=0; - if ((l=obj->params.subtitle.lines)) for (;;) { - x=obj->params.subtitle.xtbl[i++]; - while ((c=obj->params.subtitle.utbl[j++])){ - if ((font=vo_font->font[c])>=0) - draw_alpha(x,y, - vo_font->width[c], - vo_font->pic_a[font]->h+ydys ? vo_font->pic_a[font]->h : obj->dys-y, - vo_font->pic_b[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->bmp+vo_font->start[c], - vo_font->pic_a[font]->w); - x+=vo_font->width[c]+vo_font->charspace; - } - if (!--l) break; - y+=vo_font->height; - } -} void *vo_spudec=NULL; void *vo_vobsub=NULL; @@ -373,6 +437,9 @@ osd->next=vo_osd_list; vo_osd_list=osd; osd->type=type; + osd->alpha_buffer = NULL; + osd->bitmap_buffer = NULL; + osd->allocated = -1; return osd; } @@ -380,6 +447,8 @@ mp_osd_obj_t* obj=vo_osd_list; while(obj){ mp_osd_obj_t* next=obj->next; + if (obj->alpha_buffer) free(obj->alpha_buffer); + if (obj->bitmap_buffer) free(obj->bitmap_buffer); free(obj); obj=next; } @@ -494,13 +563,13 @@ vo_draw_spudec_sub(obj, draw_alpha); // FIXME break; case OSDTYPE_OSD: - vo_draw_text_osd(obj,draw_alpha); + vo_draw_text_from_buffer(obj,draw_alpha); break; case OSDTYPE_SUBTITLE: - vo_draw_text_sub(obj,draw_alpha); + vo_draw_text_from_buffer(obj,draw_alpha); break; case OSDTYPE_PROGBAR: - vo_draw_text_progbar(obj,draw_alpha); + vo_draw_text_from_buffer(obj,draw_alpha); break; } obj->old_bbox=obj->bbox; diff -urN --exclude-from dontdiff vanilla/main/libvo/sub.h main/libvo/sub.h --- vanilla/main/libvo/sub.h Tue Jun 4 22:17:07 2002 +++ main/libvo/sub.h Thu Aug 15 15:27:27 2002 @@ -40,6 +40,11 @@ int elems; } progbar; } params; + int stride; + + int allocated; + unsigned char *alpha_buffer; + unsigned char *bitmap_buffer; } mp_osd_obj_t;