osd: remove freetype font rendering code

The previous commit made libass the default OSD renderer. This commit
removes the disabled freetype renderer completely. The commits were
done separately to make rolling back easier, because using libass for
OSD rendering is a risky choice.

Also remove freetype/fontconfig/fribidi code. This is all done by
libass now.

If mplayer is compiled without libass, no OSD is displayed.
This commit is contained in:
wm4 2012-07-28 22:00:31 +02:00
parent 74e7a1e937
commit 85a3a0d5bc
14 changed files with 58 additions and 2827 deletions

View File

@ -26,7 +26,6 @@ include config.mak
SRCS_AUDIO_INPUT-$(ALSA) += stream/ai_alsa1x.c
SRCS_AUDIO_INPUT-$(OSS) += stream/ai_oss.c
SRCS_COMMON-$(AUDIO_INPUT) += $(SRCS_AUDIO_INPUT-yes)
SRCS_COMMON-$(BITMAP_FONT) += sub/font_load.c
SRCS_COMMON-$(CDDA) += stream/stream_cdda.c \
stream/cdinfo.c
SRCS_COMMON-$(CDDB) += stream/stream_cddb.c
@ -63,7 +62,6 @@ SRCS_COMMON-$(FASTMEMCPY) += libvo/aclib.c
SRCS_COMMON-$(FFMPEG_INTERNALS) += libmpcodecs/vf_mcdeint.c \
libmpcodecs/vf_spp.c \
SRCS_COMMON-$(FREETYPE) += sub/font_load_ft.c
SRCS_COMMON-$(FTP) += stream/stream_ftp.c
SRCS_COMMON-$(GIF) += libmpdemux/demux_gif.c
SRCS_COMMON-$(HAVE_POSIX_SELECT) += libmpcodecs/vf_bmovl.c
@ -214,7 +212,7 @@ SRCS_COMMON-$(XANIM_CODECS) += libmpcodecs/vd_xanim.c
SRCS_COMMON-$(XMMS_PLUGINS) += libmpdemux/demux_xmms.c
SRCS_COMMON-$(XVID4) += libmpcodecs/vd_xvid4.c
SRCS_COMMON-$(OLD_OSD) += sub/osd_ft.c
SRCS_COMMON-$(DUMMY_OSD) += sub/osd_dummy.c
SRCS_COMMON-$(LIBASS_OSD) += sub/osd_libass.c
SRCS_COMMON = asxparser.c \

4
README
View File

@ -15,8 +15,8 @@ Libraries specific to particular video output methods
general:
- libasound (ALSA audio output)
- various general X development libraries
- libfreetype
- libfontconfig
- libfreetype (for libass)
- libfontconfig (for libass)
- libass
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libpostproc)

View File

@ -636,19 +636,6 @@ const m_option_t common_opts[] = {
OPT_STRINGLIST("sub", sub_name, 0),
OPT_PATHLIST("sub-paths", sub_paths, 0),
#ifdef CONFIG_FRIBIDI
{"fribidi-charset", &fribidi_charset, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"flip-hebrew", &flip_hebrew, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"noflip-hebrew", &flip_hebrew, CONF_TYPE_FLAG, 0, 1, 0, NULL},
{"flip-hebrew-commas", &fribidi_flip_commas, CONF_TYPE_FLAG, 0, 1, 0, NULL},
{"noflip-hebrew-commas", &fribidi_flip_commas, CONF_TYPE_FLAG, 0, 0, 1, NULL},
#else
{"fribidi-charset", "MPlayer was compiled without FriBiDi support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
{"flip-hebrew", "MPlayer was compiled without FriBiDi support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
{"noflip-hebrew", "MPlayer was compiled without FriBiDi support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
{"flip-hebrew-commas", "MPlayer was compiled without FriBiDi support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
{"noflip-hebrew-commas", "MPlayer was compiled without FriBiDi support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
#endif /* CONFIG_FRIBIDI */
#ifdef CONFIG_ICONV
{"subcp", &sub_cp, CONF_TYPE_STRING, 0, 0, 0, NULL},
#endif
@ -701,13 +688,6 @@ const m_option_t common_opts[] = {
OPT_STRING("ass-styles", ass_styles_file, 0),
OPT_INTRANGE("ass-hinting", ass_hinting, 0, 0, 7),
OPT_START_CONDITIONAL(1, ""),
#ifdef CONFIG_FONTCONFIG
{"fontconfig", &font_fontconfig, CONF_TYPE_FLAG, 0, -1, 1, NULL},
{"nofontconfig", &font_fontconfig, CONF_TYPE_FLAG, 0, 1, -1, NULL},
#else
{"fontconfig", "MPlayer was compiled without fontconfig support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
{"nofontconfig", "MPlayer was compiled without fontconfig support.\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
#endif /* CONFIG_FONTCONFIG */
{NULL, NULL, 0, 0, 0, 0, NULL}
};

102
configure vendored
View File

@ -344,12 +344,8 @@ Optional features:
--disable-dvdread-internal disable internal libdvdread [autodetect]
--disable-libdvdcss-internal disable internal libdvdcss [autodetect]
--disable-cddb disable cddb [autodetect]
--disable-bitmap-font disable bitmap font support [enable]
--disable-freetype disable FreeType 2 font rendering [autodetect]
--disable-fontconfig disable fontconfig font lookup [autodetect]
--disable-unrarexec disable using of UnRAR executable [enabled]
--disable-sortsub disable subtitle sorting [enabled]
--enable-fribidi enable the FriBiDi libs [autodetect]
--disable-enca disable ENCA charset oracle library [autodetect]
--enable-macosx-finder enable Mac OS X Finder invocation parameter
parsing [disabled]
@ -636,9 +632,6 @@ _libdv=auto
_cdda=auto
_cddb=auto
_big_endian=auto
_bitmap_font=yes
_freetype=auto
_fontconfig=auto
_qtx=auto
_coreaudio=auto
_corevideo=auto
@ -648,7 +641,6 @@ quicktime=auto
_macosx_finder=no
_macosx_bundle=auto
_sortsub=yes
_fribidi=auto
_enca=auto
_inet6=auto
_gethostbyname2=auto
@ -975,12 +967,6 @@ for ac_option do
--disable-cddb) _cddb=no ;;
--enable-big-endian) _big_endian=yes ;;
--disable-big-endian) _big_endian=no ;;
--enable-bitmap-font) _bitmap_font=yes ;;
--disable-bitmap-font) _bitmap_font=no ;;
--enable-freetype) _freetype=yes ;;
--disable-freetype) _freetype=no ;;
--enable-fontconfig) _fontconfig=yes ;;
--disable-fontconfig) _fontconfig=no ;;
--enable-unrarexec) _unrar_exec=yes ;;
--disable-unrarexec) _unrar_exec=no ;;
--enable-ftp) _ftp=yes ;;
@ -1000,9 +986,6 @@ for ac_option do
--enable-libpostproc) libpostproc=yes ;;
--disable-libpostproc) libpostproc=no ;;
--enable-fribidi) _fribidi=yes ;;
--disable-fribidi) _fribidi=no ;;
--enable-enca) _enca=yes ;;
--disable-enca) _enca=no ;;
@ -4562,89 +4545,17 @@ echores "$_ass"
echocheck "libass OSD support"
_old_osd=yes
_dummy_osd=yes
if test "$_libass_osd" = auto ; then
_libass_osd=no
if test "$_ass" = yes ; then
_libass_osd=yes
_old_osd=no
_bitmap_font=no
# disable unneeded dependencies
_freetype=no
_fontconfig=no
# this should always be forced, because libass does bidi itself
_fribidi=no
_dummy_osd=no
fi
fi
echores "$_libass_osd"
echocheck "bitmap font support"
if test "$_bitmap_font" = yes ; then
def_bitmap_font="#define CONFIG_BITMAP_FONT 1"
else
def_bitmap_font="#undef CONFIG_BITMAP_FONT"
fi
echores "$_bitmap_font"
echocheck "freetype >= 2.0.9"
# freetype depends on iconv
if test "$_iconv" = no ; then
_freetype=no
res_comment="iconv support needed"
fi
if test "$_freetype" = auto ; then
if pkg_config_add freetype2 ; then
_freetype=yes
else
die "Unable to find development files for libfreetype. Aborting. If you really mean to compile without FreeType support use --disable-freetype."
fi
fi
if test "$_freetype" = yes ; then
def_freetype='#define CONFIG_FREETYPE 1'
else
def_freetype='#undef CONFIG_FREETYPE'
fi
echores "$_freetype"
if test "$_freetype" = no ; then
_fontconfig=no
res_comment="FreeType support needed"
fi
echocheck "fontconfig"
if test "$_fontconfig" = auto ; then
if pkg_config_add 'fontconfig >= 2.4.2' ; then
_fontconfig=yes
else
die "Unable to find development files for libfontconfig. Aborting. If you really mean to compile without fontconfig support use --disable-fontconfig."
fi
fi
if test "$_fontconfig" = yes ; then
def_fontconfig='#define CONFIG_FONTCONFIG 1'
else
def_fontconfig='#undef CONFIG_FONTCONFIG'
fi
echores "$_fontconfig"
echocheck "fribidi with charsets"
if test "$_fribidi" = auto ; then
_fribidi=no
if pkg_config_add fribidi ; then
_fribidi=yes
fi
fi
if test "$_fribidi" = yes ; then
def_fribidi='#define CONFIG_FRIBIDI 1'
else
def_fribidi='#undef CONFIG_FRIBIDI'
fi
echores "$_fribidi"
echocheck "ENCA"
if test "$_enca" = auto ; then
_enca=no
@ -5713,7 +5624,6 @@ ALSA = $_alsa
APPLE_IR = $_apple_ir
APPLE_REMOTE = $_apple_remote
AUDIO_INPUT = $_audio_input
BITMAP_FONT = $_bitmap_font
CACA = $_caca
CDDA = $_cdda
CDDB = $_cddb
@ -5732,7 +5642,6 @@ DVDREAD_INTERNAL = $_dvdread_internal
DXR3 = $_dxr3
FAAD = $_faad
FASTMEMCPY = $_fastmemcpy
FREETYPE = $_freetype
FTP = $_ftp
GIF = $_gif
GL = $_gl
@ -5748,7 +5657,7 @@ LADSPA = $_ladspa
LIBA52 = $_liba52
LIBASS = $_ass
LIBASS_OSD = $_libass_osd
OLD_OSD = $_old_osd
DUMMY_OSD = $_dummy_osd
LIBBLURAY = $_bluray
LIBBS2B = $_libbs2b
LIBDCA = $_libdca
@ -6072,12 +5981,7 @@ $def_tv_v4l2
/* font stuff */
$def_ass
$def_bitmap_font
$def_enca
$def_fontconfig
$def_freetype
$def_fribidi
/* networking */
$def_closesocket

View File

@ -60,10 +60,8 @@ ASS_Track *mp_ass_default_track(ASS_Library *library, struct MPOpts *opts)
track->default_style = sid;
ASS_Style *style = track->styles + sid;
style->Name = strdup("Default");
style->FontName = (font_fontconfig >= 0
&& sub_font_name) ? strdup(sub_font_name)
: (font_fontconfig >= 0
&& font_name) ? strdup(font_name) : strdup("Sans");
style->FontName = sub_font_name ? strdup(sub_font_name)
: font_name ? strdup(font_name) : strdup("Sans");
style->treat_fontname_as_pattern = 1;
double fs = track->PlayResY * text_font_scale_factor / 100.;
@ -250,25 +248,19 @@ void mp_ass_configure_fonts(ASS_Renderer *priv)
{
char *dir, *path, *family;
dir = get_path("fonts");
if (font_fontconfig < 0 && sub_font_name)
path = strdup(sub_font_name);
else if (font_fontconfig < 0 && font_name)
path = strdup(font_name);
else {
path = get_path("subfont.ttf");
if (!mp_path_exists(path)) {
free(path);
path = NULL;
}
path = get_path("subfont.ttf");
if (!mp_path_exists(path)) {
free(path);
path = NULL;
}
if (font_fontconfig >= 0 && sub_font_name)
if (sub_font_name)
family = strdup(sub_font_name);
else if (font_fontconfig >= 0 && font_name)
else if (font_name)
family = strdup(font_name);
else
family = 0;
ass_set_fonts(priv, path, family, font_fontconfig + 1, NULL, 1);
ass_set_fonts(priv, path, family, 1, NULL, 1);
free(dir);
free(path);

View File

@ -1,351 +0,0 @@
/*
* This file is part of MPlayer.
*
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "osdep/io.h"
#include "font_load.h"
#include "mp_msg.h"
#include "libavutil/attributes.h"
raw_file* load_raw(char *name,int verbose){
int bpp;
raw_file* raw=malloc(sizeof(raw_file));
unsigned char head[32];
FILE *f=fopen(name,"rb");
if(!f) goto err_out; // can't open
if(fread(head,32,1,f)<1) goto err_out; // too small
if(memcmp(head,"mhwanh",6)) goto err_out; // not raw file
raw->w=head[8]*256+head[9];
raw->h=head[10]*256+head[11];
raw->c=head[12]*256+head[13];
if(raw->w == 0) // 2 bytes were not enough for the width... read 4 bytes from the end of the header
raw->w = ((head[28]*0x100 + head[29])*0x100 + head[30])*0x100 + head[31];
if(raw->c>256) goto err_out; // too many colors!?
mp_msg(MSGT_OSD, MSGL_DBG2, "RAW: %s %d x %d, %d colors\n",name,raw->w,raw->h,raw->c);
if(raw->c){
raw->pal=malloc(raw->c*3);
fread(raw->pal,3,raw->c,f);
bpp=1;
} else {
raw->pal=NULL;
bpp=3;
}
raw->bmp=malloc(raw->h*raw->w*bpp);
fread(raw->bmp,raw->h*raw->w*bpp,1,f);
fclose(f);
return raw;
err_out:
if (f)
fclose(f);
free(raw);
return NULL;
}
extern int sub_unicode;
font_desc_t* read_font_desc(const char* fname,float factor,int verbose){
unsigned char sor[1024];
unsigned char sor2[1024];
font_desc_t *desc;
FILE *f = NULL;
char *dn;
char section[64];
int i,j;
int chardb=0;
int fontdb=-1;
int version av_unused;
int first=1;
desc=malloc(sizeof(font_desc_t));if(!desc) goto fail_out;
memset(desc,0,sizeof(font_desc_t));
f=fopen(fname,"rt");if(!f){ mp_msg(MSGT_OSD, MSGL_V, "font: can't open file: %s\n",fname); goto fail_out;}
i = strlen (fname) - 9;
if ((dn = malloc(i+1))){
strncpy (dn, fname, i);
dn[i]='\0';
}
desc->fpath = dn; // search in the same dir as fonts.desc
// set up some defaults, and erase table
desc->charspace=2;
desc->spacewidth=12;
desc->height=0;
for(i=0;i<65536;i++) desc->start[i]=desc->width[i]=desc->font[i]=-1;
section[0]=0;
while(fgets(sor,1020,f)){
unsigned char* p[8];
int pdb=0;
unsigned char *s=sor;
unsigned char *d=sor2;
int ec=' ';
int id=0;
sor[1020]=0;
/* skip files that look like: TTF (0x00, 0x01), PFM (0x00, 0x01), PFB
* (0x80, 0x01), PCF (0x01, 0x66), fon ("MZ"), gzipped (0x1f, 0x8b) */
if (first) {
if (!sor[0] || sor[1] == 1 || (sor[0] == 'M' && sor[1] == 'Z') || (sor[0] == 0x1f && sor[1] == 0x8b) || (sor[0] == 1 && sor[1] == 0x66)) {
mp_msg(MSGT_OSD, MSGL_ERR, "%s doesn't look like a bitmap font description, ignoring.\n", fname);
goto fail_out;
}
first = 0;
}
p[0]=d;++pdb;
while(1){
int c=*s++;
if(c==0 || c==13 || c==10) break;
if(!id){
if(c==39 || c==34){ id=c;continue;} // idezojel
if(c==';' || c=='#') break;
if(c==9) c=' ';
if(c==' '){
if(ec==' ') continue;
*d=0; ++d;
p[pdb]=d;++pdb;
if(pdb>=8) break;
continue;
}
} else {
if(id==c){ id=0;continue;} // idezojel
}
*d=c;d++;
ec=c;
}
if(d==sor2) continue; // skip empty lines
*d=0;
// printf("params=%d sor=%s\n",pdb,sor);
// for(i=0;i<pdb;i++) printf(" param %d = '%s'\n",i,p[i]);
if(pdb==1 && p[0][0]=='['){
int len=strlen(p[0]);
if(len && len<63 && p[0][len-1]==']'){
strcpy(section,p[0]);
mp_msg(MSGT_OSD, MSGL_DBG2, "font: Reading section: %s\n",section);
if(strcmp(section,"[files]")==0){
++fontdb;
if(fontdb>=16){ mp_msg(MSGT_OSD, MSGL_ERR, "font: Too many bitmaps defined.\n");goto fail_out;}
}
continue;
}
}
if(strcmp(section,"[fpath]")==0){
if(pdb==1){
free (desc->fpath); // release previously allocated memory
desc->fpath=strdup(p[0]);
continue;
}
} else
#ifdef __AMIGAOS4__
#define FONT_PATH_SEP ""
#else
//! path seperator for font paths, may not be more than one character
#define FONT_PATH_SEP "/"
#endif
if(strcmp(section,"[files]")==0){
char *default_dir=MPLAYER_DATADIR FONT_PATH_SEP "font";
if(pdb==2 && strcmp(p[0],"alpha")==0){
char *cp;
if (!(cp=malloc(strlen(desc->fpath)+strlen(p[1])+2))) goto fail_out;
snprintf(cp,strlen(desc->fpath)+strlen(p[1])+2,"%s" FONT_PATH_SEP "%s",
desc->fpath,p[1]);
if(!((desc->pic_a[fontdb]=load_raw(cp,verbose)))){
free(cp);
if (!(cp=malloc(strlen(default_dir)+strlen(p[1])+2)))
goto fail_out;
snprintf(cp,strlen(default_dir)+strlen(p[1])+2,"%s" FONT_PATH_SEP "%s",
default_dir,p[1]);
if (!((desc->pic_a[fontdb]=load_raw(cp,verbose)))){
mp_msg(MSGT_OSD, MSGL_ERR, "Can't load font bitmap: %s\n",p[1]);
free(cp);
goto fail_out;
}
}
free(cp);
continue;
}
if(pdb==2 && strcmp(p[0],"bitmap")==0){
char *cp;
if (!(cp=malloc(strlen(desc->fpath)+strlen(p[1])+2))) goto fail_out;
snprintf(cp,strlen(desc->fpath)+strlen(p[1])+2,"%s" FONT_PATH_SEP "%s",
desc->fpath,p[1]);
if(!((desc->pic_b[fontdb]=load_raw(cp,verbose)))){
free(cp);
if (!(cp=malloc(strlen(default_dir)+strlen(p[1])+2)))
goto fail_out;
snprintf(cp,strlen(default_dir)+strlen(p[1])+2,"%s" FONT_PATH_SEP "%s",
default_dir,p[1]);
if (!((desc->pic_b[fontdb]=load_raw(cp,verbose)))){
mp_msg(MSGT_OSD, MSGL_ERR, "Can't load font bitmap: %s\n",p[1]);
free(cp);
goto fail_out;
}
}
free(cp);
continue;
}
} else
if(strcmp(section,"[info]")==0){
if(pdb==2 && strcmp(p[0],"name")==0){
desc->name=strdup(p[1]);
continue;
}
if(pdb==2 && strcmp(p[0],"descversion")==0){
version=atoi(p[1]);
continue;
}
if(pdb==2 && strcmp(p[0],"spacewidth")==0){
desc->spacewidth=atoi(p[1]);
continue;
}
if(pdb==2 && strcmp(p[0],"charspace")==0){
desc->charspace=atoi(p[1]);
continue;
}
if(pdb==2 && strcmp(p[0],"height")==0){
desc->height=atoi(p[1]);
continue;
}
} else
if(strcmp(section,"[characters]")==0){
if(pdb==3){
int chr=p[0][0];
int start=atoi(p[1]);
int end=atoi(p[2]);
if(sub_unicode && (chr>=0x80)) chr=(chr<<8)+p[0][1];
else if(strlen(p[0])!=1) chr=strtol(p[0],NULL,0);
if(end<start) {
mp_msg(MSGT_OSD, MSGL_WARN, "error in font desc: end<start for char '%c'\n",chr);
} else {
desc->start[chr]=start;
desc->width[chr]=end-start+1;
desc->font[chr]=fontdb;
// printf("char %d '%c' start=%d width=%d\n",chr,chr,desc->start[chr],desc->width[chr]);
++chardb;
}
continue;
}
}
mp_msg(MSGT_OSD, MSGL_ERR, "Syntax error in font desc: %s",sor);
goto fail_out;
}
fclose(f);
f = NULL;
if (first == 1) {
mp_msg(MSGT_OSD, MSGL_ERR, "%s is empty or a directory, ignoring.\n", fname);
goto fail_out;
}
//printf("font: pos of U = %d\n",desc->start[218]);
for(i=0;i<=fontdb;i++){
if(!desc->pic_a[i] || !desc->pic_b[i]){
mp_msg(MSGT_OSD, MSGL_ERR, "font: Missing bitmap(s) for sub-font #%d\n",i);
goto fail_out;
}
//if(factor!=1.0f)
{
// re-sample alpha
int f=factor*256.0f;
int size=desc->pic_a[i]->w*desc->pic_a[i]->h;
int j;
mp_msg(MSGT_OSD, MSGL_DBG2, "font: resampling alpha by factor %5.3f (%d) ",factor,f);fflush(stdout);
for(j=0;j<size;j++){
int x=desc->pic_a[i]->bmp[j]; // alpha
int y=desc->pic_b[i]->bmp[j]; // bitmap
#ifdef FAST_OSD
x=(x<(255-f))?0:1;
#else
x=255-((x*f)>>8); // scale
//if(x<0) x=0; else if(x>255) x=255;
//x^=255; // invert
if(x+y>255) x=255-y; // to avoid overflows
//x=0;
//x=((x*f*(255-y))>>16);
//x=((x*f*(255-y))>>16)+y;
//x=(x*f)>>8;if(x<y) x=y;
if(x<1) x=1; else
if(x>=252) x=0;
#endif
desc->pic_a[i]->bmp[j]=x;
// desc->pic_b[i]->bmp[j]=0; // hack
}
mp_msg(MSGT_OSD, MSGL_DBG2, "DONE!\n");
}
if(!desc->height) desc->height=desc->pic_a[i]->h;
}
j='_';if(desc->font[j]<0) j='?';
for(i=0;i<65536;i++)
if(desc->font[i]<0){
desc->start[i]=desc->start[j];
desc->width[i]=desc->width[j];
desc->font[i]=desc->font[j];
}
desc->font[' ']=-1;
desc->width[' ']=desc->spacewidth;
mp_msg(MSGT_OSD, MSGL_V, "Bitmap font %s loaded successfully! (%d chars)\n",fname,chardb);
return desc;
fail_out:
if (f)
fclose(f);
free(desc->fpath);
free(desc->name);
free(desc);
return NULL;
}
#ifndef CONFIG_FREETYPE
void render_one_glyph(font_desc_t *desc, int c) {}
int kerning(font_desc_t *desc, int prevc, int c) { return 0; }
#endif

View File

@ -1,108 +0,0 @@
/*
* This file is part of MPlayer.
*
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPLAYER_FONT_LOAD_H
#define MPLAYER_FONT_LOAD_H
#include "config.h"
#ifdef CONFIG_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
#endif
typedef struct {
unsigned char *bmp;
unsigned char *pal;
int w,h,c;
#ifdef CONFIG_FREETYPE
int charwidth,charheight,pen,baseline,padding;
int current_count, current_alloc;
#endif
} raw_file;
typedef struct font_desc {
#ifdef CONFIG_FREETYPE
int dynamic;
#endif
char *name;
char *fpath;
int spacewidth;
int charspace;
int height;
// char *fname_a;
// char *fname_b;
raw_file* pic_a[16];
raw_file* pic_b[16];
short font[65536];
int start[65536]; // short is not enough for unicode fonts
short width[65536];
int freetype;
#ifdef CONFIG_FREETYPE
int face_cnt;
FT_Face faces[16];
FT_UInt glyph_index[65536];
int max_width, max_height;
struct
{
int g_r;
int o_r;
int g_w;
int o_w;
int o_size;
unsigned volume;
unsigned *g;
unsigned *gt2;
unsigned *om;
unsigned char *omt;
unsigned short *tmp;
} tables;
#endif
} font_desc_t;
extern font_desc_t* vo_font;
extern int vo_image_width;
extern int vo_image_height;
extern int force_load_font;
int init_freetype(void);
int done_freetype(void);
font_desc_t* read_font_desc_ft(const char* fname,int face_index,int movie_width, int movie_height, float font_scale_factor);
void free_font_desc(font_desc_t *desc);
void render_one_glyph(font_desc_t *desc, int c);
int kerning(font_desc_t *desc, int prevc, int c);
void load_font_ft(int width, int height, font_desc_t **desc, const char *name, float font_scale_factor);
void blur(unsigned char *buffer, unsigned short *tmp2, int width, int height,
int stride, int *m2, int r, int mwidth);
raw_file* load_raw(char *name,int verbose);
font_desc_t* read_font_desc(const char* fname,float factor,int verbose);
#endif /* MPLAYER_FONT_LOAD_H */

File diff suppressed because it is too large Load Diff

43
sub/osd_dummy.c Normal file
View File

@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "talloc.h"
#include "sub.h"
void vo_update_text_osd(struct osd_state *osd, mp_osd_obj_t *obj)
{
}
void vo_update_text_teletext(struct osd_state *osd, mp_osd_obj_t *obj)
{
}
void vo_update_text_progbar(struct osd_state *osd, mp_osd_obj_t *obj)
{
}
void vo_update_text_sub(struct osd_state *osd, mp_osd_obj_t *obj)
{
}
void osd_init_backend(struct osd_state *osd)
{
}
void osd_destroy_backend(struct osd_state *osd)
{
}
void osd_font_invalidate(void)
{
}
void osd_font_load(struct osd_state *osd)
{
}
void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function)
{
}

View File

@ -1,969 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "stream/stream.h"
#include "stream/stream_dvdnav.h"
#define OSD_NAV_BOX_ALPHA 0x7f
#include "libmpcodecs/dec_teletext.h"
#include "osdep/timer.h"
#include "talloc.h"
#include "mplayer.h"
#include "path.h"
#include "mp_msg.h"
#include "libvo/video_out.h"
#include "sub.h"
#include "sub/font_load.h"
#include "spudec.h"
#include "libavutil/common.h"
#define FONT_LOAD_DEFER 6
#define NEW_SPLITTING
//static int vo_font_loaded=-1;
font_desc_t* vo_font=NULL;
// Structures needed for the new splitting algorithm.
// osd_text_t contains the single subtitle word.
// osd_text_p is used to mark the lines of subtitles
struct osd_text_t {
int osd_kerning, //kerning with the previous word
osd_length, //orizontal length inside the bbox
text_length, //number of characters
*text; //characters
struct osd_text_t *prev,
*next;
};
struct osd_text_p {
int value;
struct osd_text_t *ott;
struct osd_text_p *prev,
*next;
};
//^
// return the real height of a char:
static inline int get_height(int c,int h){
int font;
if ((font=vo_font->font[c])>=0)
if(h<vo_font->pic_a[font]->h) h=vo_font->pic_a[font]->h;
return h;
}
void vo_update_text_osd(struct osd_state *osd, mp_osd_obj_t *obj)
{
const char *cp = osd->osd_text;
int x=20;
int h=0;
int font;
obj->bbox.x1=obj->x=x;
obj->bbox.y1=obj->y=10;
while (*cp){
uint16_t c=utf8_get_char(&cp);
render_one_glyph(vo_font, c);
x+=vo_font->width[c]+vo_font->charspace;
h=get_height(c,h);
}
obj->bbox.x2=x-vo_font->charspace;
obj->bbox.y2=obj->bbox.y1+h;
obj->flags|=OSDFLAG_BBOX;
osd_alloc_buf(obj);
cp = osd->osd_text;
x = obj->x;
while (*cp){
uint16_t c=utf8_get_char(&cp);
if ((font=vo_font->font[c])>=0)
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;
}
}
static int vo_osd_teletext_scale=0;
// renders char to a big per-object buffer where alpha and bitmap are separated
static void tt_draw_alpha_buf(mp_osd_obj_t* obj, int x0,int y0, int w,int h, unsigned char* src, int stride,int fg,int bg,int alpha)
{
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;
if (x0 < obj->bbox.x1 || x0+w > obj->bbox.x2 || y0 < obj->bbox.y1 || y0+h > obj->bbox.y2) {
mp_msg(MSGT_OSD,MSGL_ERR,"tt osd text out of range: bbox [%d %d %d %d], txt [%d %d %d %d]\n",
obj->bbox.x1, obj->bbox.x2, obj->bbox.y1, obj->bbox.y2,
x0, x0+w, y0, y0+h);
return;
}
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++, b++, a++, bs++) {
*b=(fg-bg)*(*bs)/255+bg;
*a=alpha;
}
b+= dstskip;
a+= dstskip;
bs+= srcskip;
}
}
void vo_update_text_teletext(struct osd_state *osd, mp_osd_obj_t *obj)
{
int h=0,w=0,i,j,font,flashon;
int wm,hm;
int color;
int x,y,x0,y0;
int cols,rows;
int wm12;
int hm13;
int hm23;
int start_row,max_rows;
int b,ax[6],ay[6],aw[6],ah[6];
tt_char tc;
tt_char* tdp=vo_osd_teletext_page;
static const uint8_t colors[8]={1,85,150,226,70,105,179,254};
unsigned char* buf[9];
int dxs = osd->w, dys = osd->h;
obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE;
if (!tdp || !vo_osd_teletext_mode) {
obj->flags&=~OSDFLAG_VISIBLE;
return;
}
flashon=(GetTimer()/1000000)%2;
switch(vo_osd_teletext_half){
case TT_ZOOM_TOP_HALF:
start_row=0;
max_rows=VBI_ROWS/2;
break;
case TT_ZOOM_BOTTOM_HALF:
start_row=VBI_ROWS/2;
max_rows=VBI_ROWS/2;
break;
default:
start_row=0;
max_rows=VBI_ROWS;
break;
}
wm=0;
for(i=start_row;i<max_rows;i++){
for(j=0;j<VBI_COLUMNS;j++){
tc=tdp[i*VBI_COLUMNS+j];
if(!tc.ctl && !tc.gfx)
{
render_one_glyph(vo_font, tc.unicode);
if (wm<vo_font->width[tc.unicode])
wm=vo_font->width[tc.unicode];
}
}
}
hm=vo_font->height+1;
wm=dxs*hm*max_rows/(dys*VBI_COLUMNS);
#ifdef CONFIG_FREETYPE
//very simple teletext font auto scaling
if(!vo_osd_teletext_scale && hm*(max_rows+1)>dys){
osd_font_scale_factor*=1.0*(dys)/((max_rows+1)*hm);
force_load_font=1;
vo_osd_teletext_scale=osd_font_scale_factor;
obj->flags&=~OSDFLAG_VISIBLE;
return;
}
#endif
cols=dxs/wm;
rows=dys/hm;
if(cols>VBI_COLUMNS)
cols=VBI_COLUMNS;
if(rows>max_rows)
rows=max_rows;
w=cols*wm-vo_font->charspace;
h=rows*hm-vo_font->charspace;
if(w<dxs)
x0=(dxs-w)/2;
else
x0=0;
if(h<dys)
y0=(dys-h)/2;
else
y0=0;
wm12=wm>>1;
hm13=(hm+1)/3;
hm23=hm13<<1;
for(i=0;i<6;i+=2){
ax[i+0]=0;
aw[i+0]=wm12;
ax[i+1]=wm12;
aw[i+1]=wm-wm12;
}
for(i=0;i<2;i++){
ay[i+0]=0;
ah[i+0]=hm13;
ay[i+2]=hm13;
ah[i+2]=hm-hm23;
ay[i+4]=hm-hm13;
ah[i+4]=hm13;
}
obj->x = 0;
obj->y = 0;
obj->bbox.x1 = x0;
obj->bbox.y1 = y0;
obj->bbox.x2 = x0+w;
obj->bbox.y2 = y0+h;
obj->flags |= OSDFLAG_BBOX;
osd_alloc_buf(obj);
for(i=0;i<9;i++)
buf[i]=malloc(wm*hm);
//alpha
if(vo_osd_teletext_format==TT_FORMAT_OPAQUE ||vo_osd_teletext_format==TT_FORMAT_OPAQUE_INV)
color=1;
else
color=200;
memset(buf[8],color,wm*hm);
//colors
if(vo_osd_teletext_format==TT_FORMAT_OPAQUE ||vo_osd_teletext_format==TT_FORMAT_TRANSPARENT){
for(i=0;i<8;i++){
memset(buf[i],(unsigned char)(1.0*(255-color)*colors[i]/255),wm*hm);
}
}else{
for(i=0;i<8;i++)
memset(buf[i],(unsigned char)(1.0*(255-color)*colors[7-i]/255),wm*hm);
}
y=y0;
for(i=0;i<rows;i++){
x=x0;
for(j=0;j<cols;j++){
tc=tdp[(i+start_row)*VBI_COLUMNS+j];
if (tc.hidden) { x+=wm; continue;}
if(!tc.gfx || (tc.flh && !flashon)){
/* Rendering one text character */
draw_alpha_buf(obj,x,y,wm,hm,buf[tc.bg],buf[8],wm);
if(tc.unicode!=0x20 && tc.unicode!=0x00 && !tc.ctl &&
(!tc.flh || flashon) &&
(font=vo_font->font[tc.unicode])>=0 && y+hm<dys){
tt_draw_alpha_buf(obj,x,y,vo_font->width[tc.unicode],vo_font->height,
vo_font->pic_b[font]->bmp+vo_font->start[tc.unicode]-vo_font->charspace*vo_font->pic_a[font]->w,
vo_font->pic_b[font]->w,
buf[tc.fg][0],buf[tc.bg][0],buf[8][0]);
}
}else{
/*
Rendering one graphics character
TODO: support for separated graphics symbols (where six rectangles does not touch each other)
+--+ +--+ 87654321
|01| |12| --------
|10| <= |34| <= 00100110 <= 0x26
|01| |56|
+--+ +--+
(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]);
}
// 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 bars
void vo_update_text_progbar(struct osd_state *osd, mp_osd_obj_t *obj){
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=(osd->h-vo_font->height)/2;
int delimw=vo_font->width[OSD_PB_START]
+vo_font->width[OSD_PB_END]
+vo_font->charspace;
int width=(2*osd->w-3*delimw)/3;
int charw=vo_font->width[OSD_PB_0]+vo_font->charspace;
int elems=width/charw;
int x=(osd->w-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
}
osd_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;
}
void vo_update_text_sub(struct osd_state *osd, mp_osd_obj_t *obj){
unsigned char *t;
int c,i,j,l,x,y,font,prevc,counter;
int k;
int xsize;
int dxs = osd->w, dys = osd->h;
int xmin=dxs,xmax=0;
int h,lasth;
int xtblc, utblc;
struct font_desc *sub_font = osd->sub_font;
obj->flags|=OSDFLAG_CHANGED|OSDFLAG_VISIBLE;
if(!vo_sub || !osd->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;
l=vo_sub->lines;
{
struct osd_text_t *osl, *cp_ott, *tmp_ott, *tmp;
struct osd_text_p *otp_sub = NULL, *otp_sub_tmp = NULL, // 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((const 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 = 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 = 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 = 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 = 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 = 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 = 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;
while (tmp->next != NULL) tmp = tmp->next;
tmp->next = otp->ott;
otp->ott->prev = tmp;
//attaching new subtitle line at the end
otp_sub_tmp->next = otp;
otp->prev = otp_sub_tmp;
do
otp_sub_tmp = otp_sub_tmp->next;
while (otp_sub_tmp->next != NULL);
}
}//~ if(osl != NULL)
} // while
// write lines into utbl
xtblc = 0;
utblc = 0;
obj->y = dys;
obj->params.subtitle.lines = 0;
for (tmp_otp = otp_sub; tmp_otp != NULL; tmp_otp = tmp_otp->next) {
if ((obj->params.subtitle.lines++) >= MAX_UCSLINES)
break;
if (h > obj->y) { // out of the screen so end parsing
obj->y -= lasth - sub_font->height; // correct the y position
break;
}
xsize = tmp_otp->value;
obj->params.subtitle.xtbl[xtblc++] = (dxs - xsize) / 2;
if (xmin > (dxs - xsize) / 2)
xmin = (dxs - xsize) / 2;
if (xmax < (dxs + xsize) / 2)
xmax = (dxs + xsize) / 2;
tmp = (tmp_otp->next == NULL) ? NULL : tmp_otp->next->ott;
for (tmp_ott = tmp_otp->ott; tmp_ott != tmp; tmp_ott = tmp_ott->next) {
for (counter = 0; counter < tmp_ott->text_length; ++counter) {
if (utblc > MAX_UCS) {
break;
}
c = tmp_ott->text[counter];
render_one_glyph(sub_font, c);
obj->params.subtitle.utbl[utblc++] = c;
k++;
}
obj->params.subtitle.utbl[utblc++] = ' ';
}
obj->params.subtitle.utbl[utblc - 1] = 0;
obj->y -= sub_font->height;
}
if(obj->params.subtitle.lines)
obj->y = dys - ((obj->params.subtitle.lines - 1) * sub_font->height + sub_font->pic_a[sub_font->font[40]]->h);
// free memory
if (otp_sub != NULL) {
for (tmp = otp_sub->ott; tmp->next != NULL; free(tmp->prev)) {
free(tmp->text);
tmp = tmp->next;
}
free(tmp->text);
free(tmp);
for(pmt = otp_sub; pmt->next != NULL; free(pmt->prev)) {
pmt = pmt->next;
}
free(pmt);
}
}
/// vertical alignment
h = dys - obj->y;
if (sub_alignment == 2)
obj->y = dys * sub_pos / 100 - h;
else if (sub_alignment == 1)
obj->y = dys * sub_pos / 100 - h / 2;
else
obj->y = dys * sub_pos / 100;
if (obj->y < 0)
obj->y = 0;
if (obj->y > dys - h)
obj->y = dys - h;
obj->bbox.y2 = obj->y + h;
// calculate bbox:
if (sub_justify) xmin = 10;
obj->bbox.x1=xmin;
obj->bbox.x2=xmax;
obj->bbox.y1=obj->y;
// obj->bbox.y2=obj->y+obj->params.subtitle.lines*sub_font->height;
obj->flags|=OSDFLAG_BBOX;
osd_alloc_buf(obj);
y = obj->y;
obj->alignment = 0;
switch(vo_sub->alignment) {
case SUB_ALIGNMENT_BOTTOMLEFT:
case SUB_ALIGNMENT_MIDDLELEFT:
case SUB_ALIGNMENT_TOPLEFT:
obj->alignment |= 0x1;
break;
case SUB_ALIGNMENT_BOTTOMRIGHT:
case SUB_ALIGNMENT_MIDDLERIGHT:
case SUB_ALIGNMENT_TOPRIGHT:
obj->alignment |= 0x2;
break;
case SUB_ALIGNMENT_BOTTOMCENTER:
case SUB_ALIGNMENT_MIDDLECENTER:
case SUB_ALIGNMENT_TOPCENTER:
default:
obj->alignment |= 0x0;
}
i=j=0;
if ((l = obj->params.subtitle.lines)) {
for(counter = dxs; i < l; ++i)
if (obj->params.subtitle.xtbl[i] < counter) counter = obj->params.subtitle.xtbl[i];
for (i = 0; i < l; ++i) {
switch (obj->alignment&0x3) {
case 1:
// left
x = counter;
break;
case 2:
// right
x = 2 * obj->params.subtitle.xtbl[i] - counter - ((obj->params.subtitle.xtbl[i] == counter) ? 0 : 1);
break;
default:
//center
x = obj->params.subtitle.xtbl[i];
}
prevc = -1;
while ((c=obj->params.subtitle.utbl[j++])){
x += kerning(sub_font,prevc,c);
if ((font=sub_font->font[c])>=0)
draw_alpha_buf(obj,x,y,
sub_font->width[c],
sub_font->pic_a[font]->h+y<obj->dys ? sub_font->pic_a[font]->h : obj->dys-y,
sub_font->pic_b[font]->bmp+sub_font->start[c],
sub_font->pic_a[font]->bmp+sub_font->start[c],
sub_font->pic_a[font]->w);
x+=sub_font->width[c]+sub_font->charspace;
prevc = c;
}
y+=sub_font->height;
}
}
}
void osd_init_backend(struct osd_state *osd)
{
// check font
#ifdef CONFIG_FREETYPE
init_freetype();
#endif
#ifdef CONFIG_FONTCONFIG
if (font_fontconfig <= 0) {
#endif
#ifdef CONFIG_BITMAP_FONT
if (font_name) {
vo_font = read_font_desc(font_name, font_factor, verbose > 1);
if (!vo_font)
mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "Cannot load bitmap font: %s\n",
filename_recode(font_name));
} else {
// try default:
char *mem_ptr;
vo_font = read_font_desc(mem_ptr = get_path("font/font.desc"),
font_factor, verbose > 1);
free(mem_ptr); // release the buffer created by get_path()
if (!vo_font)
vo_font = read_font_desc(MPLAYER_DATADIR "/font/font.desc",
font_factor, verbose > 1);
}
if (sub_font_name)
osd->sub_font = read_font_desc(sub_font_name, font_factor,
verbose > 1);
else
osd->sub_font = vo_font;
#endif
#ifdef CONFIG_FONTCONFIG
}
#endif
}
void osd_destroy_backend(struct osd_state *osd)
{
#ifdef CONFIG_FREETYPE
current_module = "uninit_font";
if (osd && osd->sub_font != vo_font)
free_font_desc(osd->sub_font);
free_font_desc(vo_font);
vo_font = NULL;
done_freetype();
#endif
}
void osd_font_invalidate(void)
{
#ifdef CONFIG_FREETYPE
force_load_font = 1;
#endif
}
void osd_font_load(struct osd_state *osd)
{
#ifdef CONFIG_FREETYPE
static int defer_counter = 0, prev_dxs = 0, prev_dys = 0;
#endif
#ifdef CONFIG_FREETYPE
// here is the right place to get screen dimensions
int dxs = osd->w, dys = osd->h;
if (((dxs != vo_image_width)
&& (subtitle_autoscale == 2 || subtitle_autoscale == 3))
|| ((dys != vo_image_height)
&& (subtitle_autoscale == 1 || subtitle_autoscale == 3)))
{
// screen dimensions changed
// wait a while to avoid useless reloading of the font
if (dxs == prev_dxs || dys == prev_dys) {
defer_counter++;
} else {
prev_dxs = dxs;
prev_dys = dys;
defer_counter = 0;
}
if (defer_counter >= FONT_LOAD_DEFER) force_load_font = 1;
}
if (force_load_font) {
force_load_font = 0;
load_font_ft(dxs, dys, &vo_font, font_name, osd_font_scale_factor);
if (sub_font_name)
load_font_ft(dxs, dys, &osd->sub_font, sub_font_name, text_font_scale_factor);
else
load_font_ft(dxs, dys, &osd->sub_font, font_name, text_font_scale_factor);
prev_dxs = dxs;
prev_dys = dys;
defer_counter = 0;
} else {
if (!vo_font)
load_font_ft(dxs, dys, &vo_font, font_name, osd_font_scale_factor);
if (!osd->sub_font) {
if (sub_font_name)
load_font_ft(dxs, dys, &osd->sub_font, sub_font_name, text_font_scale_factor);
else
load_font_ft(dxs, dys, &osd->sub_font, font_name, text_font_scale_factor);
}
}
#endif
}
void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function)
{
snprintf(buffer, buffer_size, "%c", osd_function);
}

View File

@ -32,7 +32,6 @@
#include "sub/ass_mp.h"
#include "mp_core.h"
int font_fontconfig = 1;
// Map OSD symbols (e.g. OSD_PLAY) to the glyphs in osd_font_pfb[].
#define OSD_CODEPOINTS 0xE000

View File

@ -151,7 +151,6 @@ extern float font_factor;
extern float sub_delay;
extern float sub_fps;
extern int font_fontconfig;
extern int sub_justify;
void osd_draw_text(struct osd_state *osd, int dxs, int dys,

View File

@ -47,12 +47,6 @@
#include <iconv.h>
char *sub_cp=NULL;
#endif
#ifdef CONFIG_FRIBIDI
#include <fribidi/fribidi.h>
char *fribidi_charset = NULL; ///character set that will be passed to FriBiDi
int flip_hebrew = 1; ///flip subtitles using fribidi
int fribidi_flip_commas = 0; ///flip comma when fribidi is used
#endif
int suboverlap_enabled = 1;
@ -1276,71 +1270,6 @@ subtitle* subcp_recode (subtitle *sub)
}
#endif
#ifdef CONFIG_FRIBIDI
/**
* Do conversion necessary for right-to-left language support via fribidi.
* @param sub subtitle to convert
* @param sub_utf8 whether the subtitle is encoded in UTF-8
* @param from first new subtitle, all lines before this are assumed to be already converted
*/
static subtitle* sub_fribidi (subtitle *sub, int sub_utf8, int from)
{
FriBidiChar logical[LINE_LEN+1], visual[LINE_LEN+1]; // Hopefully these two won't smash the stack
char *ip = NULL, *op = NULL;
size_t len,orig_len;
int l=sub->lines;
int char_set_num;
fribidi_boolean log2vis;
if (!flip_hebrew)
return sub;
fribidi_set_mirroring(1);
fribidi_set_reorder_nsm(0);
if( sub_utf8 == 0 ) {
char_set_num = fribidi_parse_charset (fribidi_charset?fribidi_charset:"ISO8859-8");
}else {
char_set_num = fribidi_parse_charset ("UTF-8");
}
while (l > from) {
ip = sub->text[--l];
orig_len = len = strlen( ip ); // We assume that we don't use full unicode, only UTF-8 or ISO8859-x
if(len > LINE_LEN) {
mp_msg(MSGT_SUBREADER,MSGL_WARN,"SUB: sub->text is longer than LINE_LEN.\n");
l++;
break;
}
len = fribidi_charset_to_unicode (char_set_num, ip, len, logical);
#if FRIBIDI_INTERFACE_VERSION < 3
FriBidiCharType base = fribidi_flip_commas?FRIBIDI_TYPE_ON:FRIBIDI_TYPE_L;
#else
FriBidiParType base = fribidi_flip_commas?FRIBIDI_TYPE_ON:FRIBIDI_TYPE_L;
#endif
log2vis = fribidi_log2vis (logical, len, &base,
/* output */
visual, NULL, NULL, NULL);
if(log2vis) {
len = fribidi_remove_bidi_marks (visual, len, NULL, NULL,
NULL);
if((op = malloc((FFMAX(2*orig_len,2*len) + 1))) == NULL) {
mp_msg(MSGT_SUBREADER,MSGL_WARN,"SUB: error allocating mem.\n");
l++;
break;
}
fribidi_unicode_to_charset ( char_set_num, visual, len,op);
free (ip);
sub->text[l] = op;
}
}
if (!from && l){
for (l = sub->lines; l;)
free (sub->text[--l]);
return ERR;
}
return sub;
}
#endif
static void adjust_subs_time(subtitle* sub, float subtime, float fps, int block,
int sub_num, int sub_uses_time) {
int n,m;
@ -1563,12 +1492,6 @@ sub_data* sub_read_file(char *filename, float fps, struct MPOpts *opts)
if(!sub) break; // EOF
#ifdef CONFIG_ICONV
if ((sub!=ERR) && sub_utf8 == 2) sub=subcp_recode(sub);
#endif
#ifdef CONFIG_FRIBIDI
/* Libass has its own BiDi handling now, and running this before
* giving the subtitle to libass would only break things. */
if (sub != ERR && !opts->ass_enabled)
sub = sub_fribidi(sub, sub_utf8, 0);
#endif
if ( sub == ERR )
{
@ -2157,9 +2080,6 @@ void sub_add_text(subtitle *sub, const char *txt, int len, double endpts) {
int double_newline = 1; // ignore newlines at the beginning
int i, pos;
char *buf;
#ifdef CONFIG_FRIBIDI
int orig_lines = sub->lines;
#endif
if (sub->lines >= SUB_MAX_TEXT) return;
pos = 0;
buf = malloc(MAX_SUBLINE + 1);
@ -2204,9 +2124,6 @@ void sub_add_text(subtitle *sub, const char *txt, int len, double endpts) {
if (sub->lines < SUB_MAX_TEXT &&
strlen(sub->text[sub->lines]))
sub->lines++;
#ifdef CONFIG_FRIBIDI
sub = sub_fribidi(sub, sub_utf8, orig_lines);
#endif
}
/**

View File

@ -79,10 +79,6 @@ typedef struct sub_data {
int sub_errs;
} sub_data;
extern char *fribidi_charset;
extern int flip_hebrew;
extern int fribidi_flip_commas;
struct MPOpts;
sub_data* sub_read_file (char *filename, float pts, struct MPOpts *opts);
subtitle* subcp_recode (subtitle *sub);