comparison libvo/sub.c @ 23338:2a66d95355f0

add new -subfont option, that allows having a different font for OSD (controls and menu) and subtitles
author ben
date Sun, 20 May 2007 16:10:45 +0000
parents 239f2c145b2f
children a6c619ee9d30
comparison
equal deleted inserted replaced
23337:10a7279b8e56 23338:2a66d95355f0
12 #include "stream/stream.h" 12 #include "stream/stream.h"
13 #include "stream/stream_dvdnav.h" 13 #include "stream/stream_dvdnav.h"
14 #define OSD_NAV_BOX_ALPHA 0x7f 14 #define OSD_NAV_BOX_ALPHA 0x7f
15 #endif 15 #endif
16 16
17 #include "mplayer.h"
17 #include "mp_msg.h" 18 #include "mp_msg.h"
18 #include "help_mp.h" 19 #include "help_mp.h"
19 #include "video_out.h" 20 #include "video_out.h"
20 #include "font_load.h" 21 #include "font_load.h"
21 #include "sub.h" 22 #include "sub.h"
61 }; 62 };
62 char * __sub_osd_names_short[] ={ "", "|>", "||", "[]", "<<" , ">>", "", "", "", "", "", ""}; 63 char * __sub_osd_names_short[] ={ "", "|>", "||", "[]", "<<" , ">>", "", "", "", "", "", ""};
63 64
64 //static int vo_font_loaded=-1; 65 //static int vo_font_loaded=-1;
65 font_desc_t* vo_font=NULL; 66 font_desc_t* vo_font=NULL;
67 font_desc_t* sub_font=NULL;
66 68
67 unsigned char* vo_osd_text=NULL; 69 unsigned char* vo_osd_text=NULL;
68 int sub_unicode=0; 70 int sub_unicode=0;
69 int sub_utf8=0; 71 int sub_utf8=0;
70 int sub_pos=100; 72 int sub_pos=100;
390 int h,lasth; 392 int h,lasth;
391 int xtblc, utblc; 393 int xtblc, utblc;
392 394
393 obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE; 395 obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE;
394 396
395 if(!vo_sub || !vo_font || !sub_visibility || (vo_font->font[40]<0)){ 397 if(!vo_sub || !sub_font || !sub_visibility || (sub_font->font[40]<0)){
396 obj->flags&=~OSDFLAG_VISIBLE; 398 obj->flags&=~OSDFLAG_VISIBLE;
397 return; 399 return;
398 } 400 }
399 401
400 obj->bbox.y2=obj->y=dys; 402 obj->bbox.y2=obj->y=dys;
401 obj->params.subtitle.lines=0; 403 obj->params.subtitle.lines=0;
402 404
403 // too long lines divide into a smaller ones 405 // too long lines divide into a smaller ones
404 i=k=lasth=0; 406 i=k=lasth=0;
405 h=vo_font->height; 407 h=sub_font->height;
406 lastStripPosition=-1; 408 lastStripPosition=-1;
407 l=vo_sub->lines; 409 l=vo_sub->lines;
408 410
409 { 411 {
410 struct osd_text_t *osl, *cp_ott, *tmp_ott, *tmp; 412 struct osd_text_t *osl, *cp_ott, *tmp_ott, *tmp;
411 struct osd_text_p *otp_sub = NULL, *otp_sub_tmp, // these are used to store the whole sub text osd 413 struct osd_text_p *otp_sub = NULL, *otp_sub_tmp, // these are used to store the whole sub text osd
412 *otp, *tmp_otp, *pmt; // these are used to manage sub text osd coming from a single sub line 414 *otp, *tmp_otp, *pmt; // these are used to manage sub text osd coming from a single sub line
413 int *char_seq, char_position, xlimit = dxs * sub_width_p / 100, counter; 415 int *char_seq, char_position, xlimit = dxs * sub_width_p / 100, counter;
414 416
415 while (l) { 417 while (l) {
416 xsize = -vo_font->charspace; 418 xsize = -sub_font->charspace;
417 l--; 419 l--;
418 t=vo_sub->text[i++]; 420 t=vo_sub->text[i++];
419 char_position = 0; 421 char_position = 0;
420 char_seq = calloc(strlen(t), sizeof(int)); 422 char_seq = calloc(strlen(t), sizeof(int));
421 423
434 if (k==MAX_UCS){ 436 if (k==MAX_UCS){
435 t += strlen(t); // end here 437 t += strlen(t); // end here
436 mp_msg(MSGT_OSD,MSGL_WARN,"\nMAX_UCS exceeded!\n"); 438 mp_msg(MSGT_OSD,MSGL_WARN,"\nMAX_UCS exceeded!\n");
437 } 439 }
438 if (!c) c++; // avoid UCS 0 440 if (!c) c++; // avoid UCS 0
439 render_one_glyph(vo_font, c); 441 render_one_glyph(sub_font, c);
440 442
441 if (c == ' ') { 443 if (c == ' ') {
442 struct osd_text_t *tmp_ott = (struct osd_text_t *) calloc(1, sizeof(struct osd_text_t)); 444 struct osd_text_t *tmp_ott = (struct osd_text_t *) calloc(1, sizeof(struct osd_text_t));
443 445
444 if (osl == NULL) { 446 if (osl == NULL) {
445 osl = cp_ott = tmp_ott; 447 osl = cp_ott = tmp_ott;
446 } else { 448 } else {
447 tmp_ott->prev = cp_ott; 449 tmp_ott->prev = cp_ott;
448 cp_ott->next = tmp_ott; 450 cp_ott->next = tmp_ott;
449 tmp_ott->osd_kerning = 451 tmp_ott->osd_kerning =
450 vo_font->charspace + vo_font->width[' ']; 452 sub_font->charspace + sub_font->width[' '];
451 cp_ott = tmp_ott; 453 cp_ott = tmp_ott;
452 } 454 }
453 tmp_ott->osd_length = xsize; 455 tmp_ott->osd_length = xsize;
454 tmp_ott->text_length = char_position; 456 tmp_ott->text_length = char_position;
455 tmp_ott->text = (int *) malloc(char_position * sizeof(int)); 457 tmp_ott->text = (int *) malloc(char_position * sizeof(int));
457 tmp_ott->text[counter] = char_seq[counter]; 459 tmp_ott->text[counter] = char_seq[counter];
458 char_position = 0; 460 char_position = 0;
459 xsize = 0; 461 xsize = 0;
460 prevc = c; 462 prevc = c;
461 } else { 463 } else {
462 int delta_xsize = vo_font->width[c] + vo_font->charspace + kerning(vo_font, prevc, c); 464 int delta_xsize = sub_font->width[c] + sub_font->charspace + kerning(sub_font, prevc, c);
463 465
464 if (xsize + delta_xsize <= dxs) { 466 if (xsize + delta_xsize <= dxs) {
465 if (!x) x = 1; 467 if (!x) x = 1;
466 prevc = c; 468 prevc = c;
467 char_seq[char_position++] = c; 469 char_seq[char_position++] = c;
468 xsize += delta_xsize; 470 xsize += delta_xsize;
469 if ((!suboverlap_enabled) && ((font = vo_font->font[c]) >= 0)) { 471 if ((!suboverlap_enabled) && ((font = sub_font->font[c]) >= 0)) {
470 if (vo_font->pic_a[font]->h > h) { 472 if (sub_font->pic_a[font]->h > h) {
471 h = vo_font->pic_a[font]->h; 473 h = sub_font->pic_a[font]->h;
472 } 474 }
473 } 475 }
474 } else { 476 } else {
475 if (x) { 477 if (x) {
476 mp_msg(MSGT_OSD, MSGL_WARN, "\nSubtitle word '%s' too long!\n", t); 478 mp_msg(MSGT_OSD, MSGL_WARN, "\nSubtitle word '%s' too long!\n", t);
488 osl = cp_ott = tmp_ott; 490 osl = cp_ott = tmp_ott;
489 } else { 491 } else {
490 tmp_ott->prev = cp_ott; 492 tmp_ott->prev = cp_ott;
491 cp_ott->next = tmp_ott; 493 cp_ott->next = tmp_ott;
492 tmp_ott->osd_kerning = 494 tmp_ott->osd_kerning =
493 vo_font->charspace + vo_font->width[' ']; 495 sub_font->charspace + sub_font->width[' '];
494 cp_ott = tmp_ott; 496 cp_ott = tmp_ott;
495 } 497 }
496 tmp_ott->osd_length = xsize; 498 tmp_ott->osd_length = xsize;
497 tmp_ott->text_length = char_position; 499 tmp_ott->text_length = char_position;
498 tmp_ott->text = (int *) malloc(char_position * sizeof(int)); 500 tmp_ott->text = (int *) malloc(char_position * sizeof(int));
499 for (counter = 0; counter < char_position; ++counter) 501 for (counter = 0; counter < char_position; ++counter)
500 tmp_ott->text[counter] = char_seq[counter]; 502 tmp_ott->text[counter] = char_seq[counter];
501 char_position = 0; 503 char_position = 0;
502 xsize = -vo_font->charspace; 504 xsize = -sub_font->charspace;
503 } 505 }
504 free(char_seq); 506 free(char_seq);
505 507
506 if (osl != NULL) { 508 if (osl != NULL) {
507 int value = 0, exit = 0, minimum = 0; 509 int value = 0, exit = 0, minimum = 0;
520 tmp_otp->value = value; 522 tmp_otp->value = value;
521 tmp_otp->next = tmp; 523 tmp_otp->next = tmp;
522 tmp->prev = tmp_otp; 524 tmp->prev = tmp_otp;
523 tmp_otp = tmp; 525 tmp_otp = tmp;
524 tmp_otp->ott = tmp_ott; 526 tmp_otp->ott = tmp_ott;
525 value = -2 * vo_font->charspace - vo_font->width[' ']; 527 value = -2 * sub_font->charspace - sub_font->width[' '];
526 } else { 528 } else {
527 tmp_otp->value = value; 529 tmp_otp->value = value;
528 exit = 1; 530 exit = 1;
529 } 531 }
530 } 532 }
621 623
622 if ((obj->params.subtitle.lines++) >= MAX_UCSLINES) 624 if ((obj->params.subtitle.lines++) >= MAX_UCSLINES)
623 break; 625 break;
624 626
625 if (h > obj->y) { // out of the screen so end parsing 627 if (h > obj->y) { // out of the screen so end parsing
626 obj->y -= lasth - vo_font->height; // correct the y position 628 obj->y -= lasth - sub_font->height; // correct the y position
627 break; 629 break;
628 } 630 }
629 xsize = tmp_otp->value; 631 xsize = tmp_otp->value;
630 obj->params.subtitle.xtbl[xtblc++] = (dxs - xsize) / 2; 632 obj->params.subtitle.xtbl[xtblc++] = (dxs - xsize) / 2;
631 if (xmin > (dxs - xsize) / 2) 633 if (xmin > (dxs - xsize) / 2)
638 for (counter = 0; counter < tmp_ott->text_length; ++counter) { 640 for (counter = 0; counter < tmp_ott->text_length; ++counter) {
639 if (utblc > MAX_UCS) { 641 if (utblc > MAX_UCS) {
640 break; 642 break;
641 } 643 }
642 c = tmp_ott->text[counter]; 644 c = tmp_ott->text[counter];
643 render_one_glyph(vo_font, c); 645 render_one_glyph(sub_font, c);
644 obj->params.subtitle.utbl[utblc++] = c; 646 obj->params.subtitle.utbl[utblc++] = c;
645 k++; 647 k++;
646 } 648 }
647 obj->params.subtitle.utbl[utblc++] = ' '; 649 obj->params.subtitle.utbl[utblc++] = ' ';
648 } 650 }
649 obj->params.subtitle.utbl[utblc - 1] = 0; 651 obj->params.subtitle.utbl[utblc - 1] = 0;
650 obj->y -= vo_font->height; 652 obj->y -= sub_font->height;
651 } 653 }
652 if(obj->params.subtitle.lines) 654 if(obj->params.subtitle.lines)
653 obj->y = dys - ((obj->params.subtitle.lines - 1) * vo_font->height + vo_font->pic_a[vo_font->font[40]]->h); 655 obj->y = dys - ((obj->params.subtitle.lines - 1) * sub_font->height + sub_font->pic_a[sub_font->font[40]]->h);
654 656
655 // free memory 657 // free memory
656 if (otp_sub != NULL) { 658 if (otp_sub != NULL) {
657 for (tmp = otp_sub->ott; tmp->next != NULL; free(tmp->prev)) { 659 for (tmp = otp_sub->ott; tmp->next != NULL; free(tmp->prev)) {
658 free(tmp->text); 660 free(tmp->text);
687 // calculate bbox: 689 // calculate bbox:
688 if (sub_justify) xmin = 10; 690 if (sub_justify) xmin = 10;
689 obj->bbox.x1=xmin; 691 obj->bbox.x1=xmin;
690 obj->bbox.x2=xmax; 692 obj->bbox.x2=xmax;
691 obj->bbox.y1=obj->y; 693 obj->bbox.y1=obj->y;
692 // obj->bbox.y2=obj->y+obj->params.subtitle.lines*vo_font->height; 694 // obj->bbox.y2=obj->y+obj->params.subtitle.lines*sub_font->height;
693 obj->flags|=OSDFLAG_BBOX; 695 obj->flags|=OSDFLAG_BBOX;
694 696
695 alloc_buf(obj); 697 alloc_buf(obj);
696 698
697 y = obj->y; 699 y = obj->y;
733 //center 735 //center
734 x = obj->params.subtitle.xtbl[i]; 736 x = obj->params.subtitle.xtbl[i];
735 } 737 }
736 prevc = -1; 738 prevc = -1;
737 while ((c=obj->params.subtitle.utbl[j++])){ 739 while ((c=obj->params.subtitle.utbl[j++])){
738 x += kerning(vo_font,prevc,c); 740 x += kerning(sub_font,prevc,c);
739 if ((font=vo_font->font[c])>=0) 741 if ((font=sub_font->font[c])>=0)
740 draw_alpha_buf(obj,x,y, 742 draw_alpha_buf(obj,x,y,
741 vo_font->width[c], 743 sub_font->width[c],
742 vo_font->pic_a[font]->h+y<obj->dys ? vo_font->pic_a[font]->h : obj->dys-y, 744 sub_font->pic_a[font]->h+y<obj->dys ? sub_font->pic_a[font]->h : obj->dys-y,
743 vo_font->pic_b[font]->bmp+vo_font->start[c], 745 sub_font->pic_b[font]->bmp+sub_font->start[c],
744 vo_font->pic_a[font]->bmp+vo_font->start[c], 746 sub_font->pic_a[font]->bmp+sub_font->start[c],
745 vo_font->pic_a[font]->w); 747 sub_font->pic_a[font]->w);
746 x+=vo_font->width[c]+vo_font->charspace; 748 x+=sub_font->width[c]+sub_font->charspace;
747 prevc = c; 749 prevc = c;
748 } 750 }
749 y+=vo_font->height; 751 y+=sub_font->height;
750 } 752 }
751 } 753 }
752 754
753 } 755 }
754 756
827 defer_counter = 0; 829 defer_counter = 0;
828 } 830 }
829 if (defer_counter >= FONT_LOAD_DEFER) force_load_font = 1; 831 if (defer_counter >= FONT_LOAD_DEFER) force_load_font = 1;
830 } 832 }
831 833
832 if (!vo_font || force_load_font) { 834 if (force_load_font) {
833 force_load_font = 0; 835 force_load_font = 0;
834 load_font_ft(dxs, dys); 836 load_font_ft(dxs, dys, &vo_font, font_name);
837 load_font_ft(dxs, dys, &sub_font, sub_font_name);
835 prev_dxs = dxs; 838 prev_dxs = dxs;
836 prev_dys = dys; 839 prev_dys = dys;
837 defer_counter = 0; 840 defer_counter = 0;
841 } else {
842 if (!vo_font)
843 load_font_ft(dxs, dys, &vo_font, font_name);
844 if (!sub_font)
845 load_font_ft(dxs, dys, &sub_font, sub_font_name);
838 } 846 }
839 #endif 847 #endif
840 848
841 while(obj){ 849 while(obj){
842 if(dxs!=obj->dxs || dys!=obj->dys || obj->flags&OSDFLAG_FORCE_UPDATE){ 850 if(dxs!=obj->dxs || dys!=obj->dys || obj->flags&OSDFLAG_FORCE_UPDATE){