📄 sub.c
字号:
(0:wm/2) (wm/2:wm-wm/2)********** *********** (0:hm/3)*** **** **** ******* 1 **** **** 2 **** *** **** **** ************** ********************* ********************* *********** (hm/3:hm-2*hm/3)********** ************** **** **** ******* 3 **** **** 4 ******* **** **** ************** ********************* ********************* ********************* *********** (hm-hm/3:hm/3)*** **** **** ******* 5 **** **** 6 ******* **** **** **** ********** *********** ********** ************/ if(tc.gfx>1){ //separated gfx for(b=0;b<6;b++){ color=(tc.unicode>>b)&1?tc.fg:tc.bg; draw_alpha_buf(obj,x+ax[b]+1,y+ay[b]+1,aw[b]-2,ah[b]-2,buf[color],buf[8],wm); } //separated gfx (background borders) //vertical draw_alpha_buf(obj,x ,y,1,hm,buf[tc.bg],buf[8],wm); draw_alpha_buf(obj,x+ax[1]-1,y,2,hm,buf[tc.bg],buf[8],wm); draw_alpha_buf(obj,x+ax[1]+aw[1]-1,y,wm-ax[1]-aw[1]+1,hm,buf[tc.bg],buf[8],wm); //horizontal draw_alpha_buf(obj,x,y ,wm,1,buf[tc.bg],buf[8],wm); draw_alpha_buf(obj,x,y+ay[0]+ah[0]-1,wm,2,buf[tc.bg],buf[8],wm); draw_alpha_buf(obj,x,y+ay[2]+ah[2]-1,wm,2,buf[tc.bg],buf[8],wm); draw_alpha_buf(obj,x,y+ay[4]+ah[4]-1,wm,hm-ay[4]-ah[4]+1,buf[tc.bg],buf[8],wm); }else{ for(b=0;b<6;b++){ color=(tc.unicode>>b)&1?tc.fg:tc.bg; draw_alpha_buf(obj,x+ax[b],y+ay[b],aw[b],ah[b],buf[color],buf[8],wm); } } } x+=wm; } y+=hm; } for(i=0;i<9;i++) free(buf[i]);}#endifint vo_osd_progbar_type=-1;int vo_osd_progbar_value=100; // 0..256// if we have n=256 bars then OSD progbar looks like below// // 0 1 2 3 ... 256 <= vo_osd_progbar_value// | | | | |// [ === === === ... === ]// // the above schema is rescalled to n=elems barsinline 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; } render_one_glyph(vo_font, OSD_PB_START); render_one_glyph(vo_font, OSD_PB_END); render_one_glyph(vo_font, OSD_PB_0); render_one_glyph(vo_font, OSD_PB_1); render_one_glyph(vo_font, vo_osd_progbar_type); // calculate bbox corners: { 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 delta = 0; 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); if (vo_osd_progbar_type>0 && 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(vo_osd_progbar_type,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); { int minw = vo_font->width[OSD_PB_START]+vo_font->width[OSD_PB_END]+vo_font->width[OSD_PB_0]; if (vo_osd_progbar_type>0 && vo_font->font[vo_osd_progbar_type]>=0){ minw += vo_font->width[vo_osd_progbar_type]+vo_font->charspace+vo_font->spacewidth; } if (obj->bbox.x2 - obj->bbox.x1 < minw) return; // space too small, don't render anything } // render it: { unsigned char *s; unsigned char *sa; int i,w,h,st,mark; int x=obj->x; int y=obj->y; int c,font; int charw=vo_font->width[OSD_PB_0]+vo_font->charspace; int elems=obj->params.progbar.elems; if (vo_osd_progbar_value<=0) mark=0; else { int ev=vo_osd_progbar_value*elems; mark=ev>>8; if (ev & 0xFF) mark++; if (mark>elems) mark=elems; } // printf("osd.progbar width=%d xpos=%d\n",width,x); 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_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], vo_font->pic_a[font]->bmp+vo_font->start[c], vo_font->pic_a[font]->w); } c=OSD_PB_START; if ((font=vo_font->font[c])>=0) 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], vo_font->pic_a[font]->bmp+vo_font->start[c], vo_font->pic_a[font]->w); x+=vo_font->width[c]+vo_font->charspace; c=OSD_PB_0; if ((font=vo_font->font[c])>=0){ w=vo_font->width[c]; h=vo_font->pic_a[font]->h; s=vo_font->pic_b[font]->bmp+vo_font->start[c]; sa=vo_font->pic_a[font]->bmp+vo_font->start[c]; st=vo_font->pic_a[font]->w; if ((i=mark)) do { draw_alpha_buf(obj,x,y,w,h,s,sa,st); x+=charw; } while(--i); } c=OSD_PB_1; if ((font=vo_font->font[c])>=0){ w=vo_font->width[c]; h=vo_font->pic_a[font]->h; s =vo_font->pic_b[font]->bmp+vo_font->start[c]; 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_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_buf(obj,x,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; }// vo_osd_progbar_value=(vo_osd_progbar_value+1)&0xFF;}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))inline static void vo_update_text_sub(mp_osd_obj_t* obj,int dxs,int dys){ unsigned char *t; int c,i,j,l,x,y,font,prevc,counter; int k; int lastStripPosition; int xsize; int xmin=dxs,xmax=0; int h,lasth; int xtblc, utblc; obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; if(!vo_sub || !sub_font || !sub_visibility || (sub_font->font[40]<0)){ obj->flags&=~OSDFLAG_VISIBLE; return; } obj->bbox.y2=obj->y=dys; obj->params.subtitle.lines=0; // too long lines divide into a smaller ones i=k=lasth=0; h=sub_font->height; lastStripPosition=-1; l=vo_sub->lines; { struct osd_text_t *osl, *cp_ott, *tmp_ott, *tmp; struct osd_text_p *otp_sub = NULL, *otp_sub_tmp, // these are used to store the whole sub text osd *otp, *tmp_otp, *pmt; // these are used to manage sub text osd coming from a single sub line int *char_seq, char_position, xlimit = dxs * sub_width_p / 100, counter; while (l) { xsize = -sub_font->charspace; l--; t=vo_sub->text[i++]; char_position = 0; char_seq = calloc(strlen(t), sizeof(int)); prevc = -1; otp = NULL; osl = NULL; x = 1; // reading the subtitle words from vo_sub->text[] while (*t) { if (sub_utf8) c = utf8_get_char(&t); else if ((c = *t++) >= 0x80 && sub_unicode) c = (c<<8) + *t++; if (k==MAX_UCS){ t += strlen(t); // end here mp_msg(MSGT_OSD,MSGL_WARN,"\nMAX_UCS exceeded!\n"); } if (!c) c++; // avoid UCS 0 render_one_glyph(sub_font, c); if (c == ' ') { struct osd_text_t *tmp_ott = (struct osd_text_t *) calloc(1, sizeof(struct osd_text_t)); if (osl == NULL) { osl = cp_ott = tmp_ott; } else { tmp_ott->prev = cp_ott; cp_ott->next = tmp_ott; tmp_ott->osd_kerning = sub_font->charspace + sub_font->width[' ']; cp_ott = tmp_ott; } tmp_ott->osd_length = xsize; tmp_ott->text_length = char_position; tmp_ott->text = (int *) malloc(char_position * sizeof(int)); for (counter = 0; counter < char_position; ++counter) tmp_ott->text[counter] = char_seq[counter]; char_position = 0; xsize = 0; prevc = c; } else { int delta_xsize = sub_font->width[c] + sub_font->charspace + kerning(sub_font, prevc, c); if (xsize + delta_xsize <= dxs) { if (!x) x = 1; prevc = c; char_seq[char_position++] = c; xsize += delta_xsize; if ((!suboverlap_enabled) && ((font = sub_font->font[c]) >= 0)) { if (sub_font->pic_a[font]->h > h) { h = sub_font->pic_a[font]->h; } } } else { if (x) { mp_msg(MSGT_OSD, MSGL_WARN, "\nSubtitle word '%s' too long!\n", t); x = 0; } } } }// for len (all words from subtitle line read) // osl holds an ordered (as they appear in the lines) chain of the subtitle words { struct osd_text_t *tmp_ott = (struct osd_text_t *) calloc(1, sizeof(struct osd_text_t)); if (osl == NULL) { osl = cp_ott = tmp_ott; } else { tmp_ott->prev = cp_ott; cp_ott->next = tmp_ott; tmp_ott->osd_kerning = sub_font->charspace + sub_font->width[' ']; cp_ott = tmp_ott; } tmp_ott->osd_length = xsize; tmp_ott->text_length = char_position; tmp_ott->text = (int *) malloc(char_position * sizeof(int)); for (counter = 0; counter < char_position; ++counter) tmp_ott->text[counter] = char_seq[counter]; char_position = 0; xsize = -sub_font->charspace; } free(char_seq); if (osl != NULL) { int value = 0, exit = 0, minimum = 0; // otp will contain the chain of the osd subtitle lines coming from the single vo_sub line. otp = tmp_otp = (struct osd_text_p *) calloc(1, sizeof(struct osd_text_p)); tmp_otp->ott = osl; for (tmp_ott = tmp_otp->ott; exit == 0; ) { do { value += tmp_ott->osd_kerning + tmp_ott->osd_length; tmp_ott = tmp_ott->next; } while ((tmp_ott != NULL) && (value + tmp_ott->osd_kerning + tmp_ott->osd_length <= xlimit)); if (tmp_ott != NULL) { struct osd_text_p *tmp = (struct osd_text_p *) calloc(1, sizeof(struct osd_text_p)); tmp_otp->value = value; tmp_otp->next = tmp; tmp->prev = tmp_otp; tmp_otp = tmp; tmp_otp->ott = tmp_ott; value = -2 * sub_font->charspace - sub_font->width[' ']; } else { tmp_otp->value = value; exit = 1; } }#ifdef NEW_SPLITTING // minimum holds the 'sum of the differences in length among the lines', // a measure of the evenness of the lengths of the lines for (tmp_otp = otp; tmp_otp->next != NULL; tmp_otp = tmp_otp->next) { pmt = tmp_otp->next; while (pmt != NULL) { minimum += abs(tmp_otp->value - pmt->value); pmt = pmt->next; } } if (otp->next != NULL) { int mem1, mem2; struct osd_text_p *mem, *hold; exit = 0; // until the last word of a line can be moved to the beginning of following line // reducing the 'sum of the differences in length among the lines', it is done while (exit == 0) { hold = NULL; exit = 1; for (tmp_otp = otp; tmp_otp->next != NULL; tmp_otp = tmp_otp->next) { pmt = tmp_otp->next; for (tmp = tmp_otp->ott; tmp->next != pmt->ott; tmp = tmp->next); if (pmt->value + tmp->osd_length + pmt->ott->osd_kerning <= xlimit) { mem1 = tmp_otp->value; mem2 = pmt->value; tmp_otp->value = mem1 - tmp->osd_length - tmp->osd_kerning; pmt->value = mem2 + tmp->osd_length + pmt->ott->osd_kerning; value = 0; for (mem = otp; mem->next != NULL; mem = mem->next) { pmt = mem->next; while (pmt != NULL) { value += abs(mem->value - pmt->value); pmt = pmt->next; } } if (value < minimum) { minimum = value; hold = tmp_otp; exit = 0; } tmp_otp->value = mem1; tmp_otp->next->value = mem2; } } // merging if (exit == 0) { tmp_otp = hold; pmt = tmp_otp->next; for (tmp = tmp_otp->ott; tmp->next != pmt->ott; tmp = tmp->next); mem1 = tmp_otp->value; mem2 = pmt->value; tmp_otp->value = mem1 - tmp->osd_length - tmp->osd_kerning; pmt->value = mem2 + tmp->osd_length + pmt->ott->osd_kerning; pmt->ott = tmp; }//~merging }//~while(exit == 0) }//~if(otp->next!=NULL)#endif // adding otp (containing splitted lines) to otp chain if (otp_sub == NULL) { otp_sub = otp; for (otp_sub_tmp = otp_sub; otp_sub_tmp->next != NULL; otp_sub_tmp = otp_sub_tmp->next); } else { //updating ott chain tmp = otp_sub->ott;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -