Mercurial > mplayer.hg
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){ |