Update to libass r28085.

Originally committed to SVN as r2539.
This commit is contained in:
Amar Takhar 2008-12-28 08:09:59 +00:00
parent b17fb34659
commit 1279b910ad
17 changed files with 574 additions and 401 deletions

View file

@ -1,6 +1,6 @@
noinst_LIBRARIES = libass_aegisub.a noinst_LIBRARIES = libass_aegisub.a
AM_CPPFLAGS = @FREETYPE_CFLAGS@ -DHAVE_FONTCONFIG -DUSE_ICONV @FONTCONFIG_CFLAGS@ @ICONV_CFLAGS@ AM_CPPFLAGS = @FREETYPE_CFLAGS@ -DCONFIG_ICONV -DCONFIG_FONTCONFIG @FONTCONFIG_CFLAGS@ @ICONV_CFLAGS@
libass_aegisub_a_SOURCES = \ libass_aegisub_a_SOURCES = \
ass.c \ ass.c \

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h" #include "config.h"
@ -30,7 +32,7 @@
#include <unistd.h> #include <unistd.h>
#include <inttypes.h> #include <inttypes.h>
#ifdef USE_ICONV #ifdef CONFIG_ICONV
#include <iconv.h> #include <iconv.h>
#endif #endif
@ -161,7 +163,7 @@ static void rskip_spaces(char** str, char* limit) {
static int lookup_style(ass_track_t* track, char* name) { static int lookup_style(ass_track_t* track, char* name) {
int i; int i;
if (*name == '*') ++name; // FIXME: what does '*' really mean ? if (*name == '*') ++name; // FIXME: what does '*' really mean ?
for (i=0; i<track->n_styles; ++i) { for (i = track->n_styles - 1; i >= 0; --i) {
// FIXME: mb strcasecmp ? // FIXME: mb strcasecmp ?
if (strcmp(track->styles[i].Name, name) == 0) if (strcmp(track->styles[i].Name, name) == 0)
return i; return i;
@ -482,6 +484,12 @@ static int process_style(ass_track_t* track, char *str)
style->Name = strdup("Default"); style->Name = strdup("Default");
if (!style->FontName) if (!style->FontName)
style->FontName = strdup("Arial"); style->FontName = strdup("Arial");
// skip '@' at the start of the font name
if (*style->FontName == '@') {
p = style->FontName;
style->FontName = strdup(p + 1);
free(p);
}
free(format); free(format);
return 0; return 0;
@ -709,21 +717,33 @@ static int process_text(ass_track_t* track, char* str)
} }
/** /**
* \brief Process CodecPrivate section of subtitle stream * \brief Process a chunk of subtitle stream data.
* \param track track * \param track track
* \param data string to parse * \param data string to parse
* \param size length of data * \param size length of data
CodecPrivate section contains [Stream Info] and [V4+ Styles] ([V4 Styles] for SSA) sections */
*/ void ass_process_data(ass_track_t* track, char* data, int size)
void ass_process_codec_private(ass_track_t* track, char *data, int size)
{ {
char* str = malloc(size + 1); char* str = malloc(size + 1);
memcpy(str, data, size); memcpy(str, data, size);
str[size] = '\0'; str[size] = '\0';
mp_msg(MSGT_ASS, MSGL_V, "event: %s\n", str);
process_text(track, str); process_text(track, str);
free(str); free(str);
}
/**
* \brief Process CodecPrivate section of subtitle stream
* \param track track
* \param data string to parse
* \param size length of data
CodecPrivate section contains [Stream Info] and [V4+ Styles] ([V4 Styles] for SSA) sections
*/
void ass_process_codec_private(ass_track_t* track, char *data, int size)
{
ass_process_data(track, data, size);
if (!track->event_format) { if (!track->event_format) {
// probably an mkv produced by ancient mkvtoolnix // probably an mkv produced by ancient mkvtoolnix
@ -802,7 +822,7 @@ void ass_process_chunk(ass_track_t* track, char *data, int size, long long timec
free(str); free(str);
} }
#ifdef USE_ICONV #ifdef CONFIG_ICONV
/** \brief recode buffer to utf-8 /** \brief recode buffer to utf-8
* constraint: codepage != 0 * constraint: codepage != 0
* \param data pointer to text buffer * \param data pointer to text buffer
@ -818,7 +838,7 @@ static char* sub_recode(char* data, size_t size, char* codepage)
{ {
const char* cp_tmp = codepage; const char* cp_tmp = codepage;
#ifdef HAVE_ENCA #ifdef CONFIG_ENCA
char enca_lang[3], enca_fallback[100]; char enca_lang[3], enca_fallback[100];
if (sscanf(codepage, "enca:%2s:%99s", enca_lang, enca_fallback) == 2 if (sscanf(codepage, "enca:%2s:%99s", enca_lang, enca_fallback) == 2
|| sscanf(codepage, "ENCA:%2s:%99s", enca_lang, enca_fallback) == 2) { || sscanf(codepage, "ENCA:%2s:%99s", enca_lang, enca_fallback) == 2) {
@ -838,16 +858,22 @@ static char* sub_recode(char* data, size_t size, char* codepage)
char* ip; char* ip;
char* op; char* op;
size_t rc; size_t rc;
int clear = 0;
outbuf = malloc(size); outbuf = malloc(osize);
ip = data; ip = data;
op = outbuf; op = outbuf;
while (ileft) { while (1) {
rc = iconv(icdsc, &ip, &ileft, &op, &oleft); if (ileft)
rc = iconv(icdsc, &ip, &ileft, &op, &oleft);
else {// clear the conversion state and leave
clear = 1;
rc = iconv(icdsc, NULL, NULL, &op, &oleft);
}
if (rc == (size_t)(-1)) { if (rc == (size_t)(-1)) {
if (errno == E2BIG) { if (errno == E2BIG) {
int offset = op - outbuf; size_t offset = op - outbuf;
outbuf = (char*)realloc(outbuf, osize + size); outbuf = (char*)realloc(outbuf, osize + size);
op = outbuf + offset; op = outbuf + offset;
osize += size; osize += size;
@ -856,7 +882,9 @@ static char* sub_recode(char* data, size_t size, char* codepage)
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorRecodingFile); mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorRecodingFile);
return NULL; return NULL;
} }
} } else
if (clear)
break;
} }
outbuf[osize - oleft - 1] = 0; outbuf[osize - oleft - 1] = 0;
} }
@ -975,7 +1003,7 @@ ass_track_t* ass_read_memory(ass_library_t* library, char* buf, size_t bufsize,
if (!buf) if (!buf)
return 0; return 0;
#ifdef USE_ICONV #ifdef CONFIG_ICONV
if (codepage) if (codepage)
buf = sub_recode(buf, bufsize, codepage); buf = sub_recode(buf, bufsize, codepage);
if (!buf) if (!buf)
@ -993,7 +1021,7 @@ ass_track_t* ass_read_memory(ass_library_t* library, char* buf, size_t bufsize,
return track; return track;
} }
char* read_file_recode(char* fname, char* codepage, int* size) char* read_file_recode(char* fname, char* codepage, size_t* size)
{ {
char* buf; char* buf;
size_t bufsize; size_t bufsize;
@ -1001,7 +1029,7 @@ char* read_file_recode(char* fname, char* codepage, int* size)
buf = read_file(fname, &bufsize); buf = read_file(fname, &bufsize);
if (!buf) if (!buf)
return 0; return 0;
#ifdef USE_ICONV #ifdef CONFIG_ICONV
if (codepage) { if (codepage) {
char* tmpbuf = sub_recode(buf, bufsize, codepage); char* tmpbuf = sub_recode(buf, bufsize, codepage);
free(buf); free(buf);
@ -1055,7 +1083,7 @@ int ass_read_styles(ass_track_t* track, char* fname, char* codepage)
buf = read_file(fname, &sz); buf = read_file(fname, &sz);
if (!buf) if (!buf)
return 1; return 1;
#ifdef USE_ICONV #ifdef CONFIG_ICONV
if (codepage) { if (codepage) {
char* tmpbuf; char* tmpbuf;
tmpbuf = sub_recode(buf, sz, codepage); tmpbuf = sub_recode(buf, sz, codepage);

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBASS_ASS_H #ifndef LIBASS_ASS_H
#define LIBASS_ASS_H #define LIBASS_ASS_H
@ -93,6 +95,11 @@ void ass_set_line_spacing(ass_renderer_t* priv, double line_spacing);
*/ */
int ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* default_family); int ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* default_family);
/**
* \brief set font lookup defaults, don't use fontconfig even if it is available
*/
int ass_set_fonts_nofc(ass_renderer_t* priv, const char* default_font, const char* default_family);
/** /**
* \brief render a frame, producing a list of ass_image_t * \brief render a frame, producing a list of ass_image_t
* \param priv library * \param priv library
@ -146,6 +153,14 @@ void ass_free_style(ass_track_t* track, int sid);
*/ */
void ass_free_event(ass_track_t* track, int eid); void ass_free_event(ass_track_t* track, int eid);
/**
* \brief Parse a chunk of subtitle stream data.
* \param track track
* \param data string to parse
* \param size length of data
*/
void ass_process_data(ass_track_t* track, char* data, int size);
/** /**
* \brief Parse Codec Private section of subtitle stream * \brief Parse Codec Private section of subtitle stream
* \param track target track * \param track target track
@ -164,7 +179,7 @@ void ass_process_codec_private(ass_track_t* track, char *data, int size);
*/ */
void ass_process_chunk(ass_track_t* track, char *data, int size, long long timecode, long long duration); void ass_process_chunk(ass_track_t* track, char *data, int size, long long timecode, long long duration);
char* read_file_recode(char* fname, char* codepage, int* size); char* read_file_recode(char* fname, char* codepage, size_t* size);
/** /**
* \brief Read subtitles from file. * \brief Read subtitles from file.

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -272,9 +274,10 @@ int glyph_to_bitmap(ass_synth_priv_t* priv, FT_Glyph glyph, FT_Glyph outline_gly
resize_tmp(priv, (*bm_g)->w, (*bm_g)->h); resize_tmp(priv, (*bm_g)->w, (*bm_g)->h);
if (be) { if (be) {
blur((*bm_g)->buffer, priv->tmp, (*bm_g)->w, (*bm_g)->h, (*bm_g)->w, (int*)priv->gt2, priv->g_r, priv->g_w);
if (*bm_o) if (*bm_o)
blur((*bm_o)->buffer, priv->tmp, (*bm_o)->w, (*bm_o)->h, (*bm_o)->w, (int*)priv->gt2, priv->g_r, priv->g_w); blur((*bm_o)->buffer, priv->tmp, (*bm_o)->w, (*bm_o)->h, (*bm_o)->w, (int*)priv->gt2, priv->g_r, priv->g_w);
else
blur((*bm_g)->buffer, priv->tmp, (*bm_g)->w, (*bm_g)->h, (*bm_g)->w, (int*)priv->gt2, priv->g_r, priv->g_w);
} }
if (*bm_o) if (*bm_o)

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBASS_BITMAP_H #ifndef LIBASS_BITMAP_H
#define LIBASS_BITMAP_H #define LIBASS_BITMAP_H

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h" #include "config.h"
@ -84,7 +86,7 @@ static unsigned hashmap_hash(void* buf, size_t len)
static int hashmap_key_compare(void* a, void* b, size_t size) static int hashmap_key_compare(void* a, void* b, size_t size)
{ {
return (memcmp(a, b, size) == 0); return memcmp(a, b, size) == 0;
} }
static void hashmap_item_dtor(void* key, size_t key_size, void* value, size_t value_size) static void hashmap_item_dtor(void* key, size_t key_size, void* value, size_t value_size)

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBASS_CACHE_H #ifndef LIBASS_CACHE_H
#define LIBASS_CACHE_H #define LIBASS_CACHE_H

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h" #include "config.h"
@ -282,7 +284,7 @@ FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch
break; break;
} }
#ifdef HAVE_FONTCONFIG #ifdef CONFIG_FONTCONFIG
if (index == 0) { if (index == 0) {
int face_idx; int face_idx;
mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_GlyphNotFoundReselectingFont, mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_GlyphNotFoundReselectingFont,

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBASS_FONT_H #ifndef LIBASS_FONT_H
#define LIBASS_FONT_H #define LIBASS_FONT_H

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h" #include "config.h"
@ -35,15 +37,13 @@
#include "ass_library.h" #include "ass_library.h"
#include "ass_fontconfig.h" #include "ass_fontconfig.h"
#ifdef HAVE_FONTCONFIG #ifdef CONFIG_FONTCONFIG
#include <fontconfig/fontconfig.h> #include <fontconfig/fontconfig.h>
#include <fontconfig/fcfreetype.h> #include <fontconfig/fcfreetype.h>
#endif #endif
int font_fontconfig = 1;
struct fc_instance_s { struct fc_instance_s {
#ifdef HAVE_FONTCONFIG #ifdef CONFIG_FONTCONFIG
FcConfig* config; FcConfig* config;
#endif #endif
char* family_default; char* family_default;
@ -51,7 +51,17 @@ struct fc_instance_s {
int index_default; int index_default;
}; };
#ifdef HAVE_FONTCONFIG #ifdef CONFIG_FONTCONFIG
// 4yo fontconfig does not have these.
// They are only needed for debug output, anyway.
#ifndef FC_FULLNAME
#define FC_FULLNAME "fullname"
#endif
#ifndef FC_EMBOLDEN
#define FC_EMBOLDEN "embolden"
#endif
/** /**
* \brief Low-level font selection. * \brief Low-level font selection.
* \param priv private data * \param priv private data
@ -67,14 +77,15 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold
{ {
FcBool rc; FcBool rc;
FcResult result; FcResult result;
FcPattern *pat = 0, *rpat; FcPattern *pat = NULL, *rpat = NULL;
int val_i; int r_index, r_slant, r_weight;
FcChar8* val_s; FcChar8 *r_family, *r_style, *r_file, *r_fullname;
FcBool val_b; FcBool r_outline, r_embolden;
FcCharSet* val_cs; FcCharSet* r_charset;
FcFontSet* fset = 0; FcFontSet* fset = NULL;
int curf; int curf;
char* retval = 0; char* retval = NULL;
int family_cnt;
*index = 0; *index = 0;
@ -83,6 +94,30 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold
goto error; goto error;
FcPatternAddString(pat, FC_FAMILY, (const FcChar8*)family); FcPatternAddString(pat, FC_FAMILY, (const FcChar8*)family);
// In SSA/ASS fonts are sometimes referenced by their "full name",
// which is usually a concatenation of family name and font
// style (ex. Ottawa Bold). Full name is available from
// FontConfig pattern element FC_FULLNAME, but it is never
// used for font matching.
// Therefore, I'm removing words from the end of the name one
// by one, and adding shortened names to the pattern. It seems
// that the first value (full name in this case) has
// precedence in matching.
// An alternative approach could be to reimplement FcFontSort
// using FC_FULLNAME instead of FC_FAMILY.
family_cnt = 1;
{
char* s = strdup(family);
char* p = s + strlen(s);
while (--p > s)
if (*p == ' ' || *p == '-') {
*p = '\0';
FcPatternAddString(pat, FC_FAMILY, (const FcChar8*)s);
++ family_cnt;
}
free(s);
}
FcPatternAddBool(pat, FC_OUTLINE, FcTrue); FcPatternAddBool(pat, FC_OUTLINE, FcTrue);
FcPatternAddInteger(pat, FC_SLANT, italic); FcPatternAddInteger(pat, FC_SLANT, italic);
FcPatternAddInteger(pat, FC_WEIGHT, bold); FcPatternAddInteger(pat, FC_WEIGHT, bold);
@ -94,49 +129,88 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold
goto error; goto error;
fset = FcFontSort(priv->config, pat, FcTrue, NULL, &result); fset = FcFontSort(priv->config, pat, FcTrue, NULL, &result);
if (!fset)
goto error;
for (curf = 0; curf < fset->nfont; ++curf) { for (curf = 0; curf < fset->nfont; ++curf) {
rpat = fset->fonts[curf]; FcPattern* curp = fset->fonts[curf];
result = FcPatternGetBool(rpat, FC_OUTLINE, 0, &val_b); result = FcPatternGetBool(curp, FC_OUTLINE, 0, &r_outline);
if (result != FcResultMatch) if (result != FcResultMatch)
continue; continue;
if (val_b != FcTrue) if (r_outline != FcTrue)
continue; continue;
if (!code) if (!code)
break; break;
result = FcPatternGetCharSet(rpat, FC_CHARSET, 0, &val_cs); result = FcPatternGetCharSet(curp, FC_CHARSET, 0, &r_charset);
if (result != FcResultMatch) if (result != FcResultMatch)
continue; continue;
if (FcCharSetHasChar(val_cs, code)) if (FcCharSetHasChar(r_charset, code))
break; break;
} }
if (curf >= fset->nfont) if (curf >= fset->nfont)
goto error; goto error;
rpat = fset->fonts[curf]; #if (FC_VERSION >= 20297)
// Remove all extra family names from original pattern.
result = FcPatternGetInteger(rpat, FC_INDEX, 0, &val_i); // After this, FcFontRenderPrepare will select the most relevant family
if (result != FcResultMatch) // name in case there are more than one of them.
goto error; for (; family_cnt > 1; --family_cnt)
*index = val_i; FcPatternRemove(pat, FC_FAMILY, family_cnt - 1);
#endif
result = FcPatternGetString(rpat, FC_FAMILY, 0, &val_s); rpat = FcFontRenderPrepare(priv->config, pat, fset->fonts[curf]);
if (result != FcResultMatch) if (!rpat)
goto error; goto error;
if (strcasecmp((const char*)val_s, family) != 0) result = FcPatternGetInteger(rpat, FC_INDEX, 0, &r_index);
if (result != FcResultMatch)
goto error;
*index = r_index;
result = FcPatternGetString(rpat, FC_FILE, 0, &r_file);
if (result != FcResultMatch)
goto error;
retval = strdup((const char*)r_file);
result = FcPatternGetString(rpat, FC_FAMILY, 0, &r_family);
if (result != FcResultMatch)
r_family = NULL;
result = FcPatternGetString(rpat, FC_FULLNAME, 0, &r_fullname);
if (result != FcResultMatch)
r_fullname = NULL;
if (!(r_family && strcasecmp((const char*)r_family, family) == 0) &&
!(r_fullname && strcasecmp((const char*)r_fullname, family) == 0))
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_SelectedFontFamilyIsNotTheRequestedOne, mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_SelectedFontFamilyIsNotTheRequestedOne,
(const char*)val_s, family); (const char*)(r_fullname ? r_fullname : r_family), family);
result = FcPatternGetString(rpat, FC_FILE, 0, &val_s); result = FcPatternGetString(rpat, FC_STYLE, 0, &r_style);
if (result != FcResultMatch) if (result != FcResultMatch)
goto error; r_style = NULL;
retval = strdup((const char*)val_s); result = FcPatternGetInteger(rpat, FC_SLANT, 0, &r_slant);
if (result != FcResultMatch)
r_slant = 0;
result = FcPatternGetInteger(rpat, FC_WEIGHT, 0, &r_weight);
if (result != FcResultMatch)
r_weight = 0;
result = FcPatternGetBool(rpat, FC_EMBOLDEN, 0, &r_embolden);
if (result != FcResultMatch)
r_embolden = 0;
mp_msg(MSGT_ASS, MSGL_V, "[ass] Font info: family '%s', style '%s', fullname '%s',"
" slant %d, weight %d%s\n",
(const char*)r_family, (const char*)r_style, (const char*)r_fullname,
r_slant, r_weight, r_embolden ? ", embolden" : "");
error: error:
if (pat) FcPatternDestroy(pat); if (pat) FcPatternDestroy(pat);
if (rpat) FcPatternDestroy(rpat);
if (fset) FcFontSetDestroy(fset); if (fset) FcFontSetDestroy(fset);
return retval; return retval;
} }
@ -155,7 +229,7 @@ char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold,
uint32_t code) uint32_t code)
{ {
char* res = 0; char* res = 0;
if (font_fontconfig < 0) { if (!priv->config) {
*index = priv->index_default; *index = priv->index_default;
return priv->path_default; return priv->path_default;
} }
@ -244,7 +318,7 @@ static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Lib
char* fname; char* fname;
const char* fonts_dir = library->fonts_dir; const char* fonts_dir = library->fonts_dir;
char buf[1000]; char buf[1000];
FILE* fp = 0; FILE* fp = NULL;
if (!fonts_dir) if (!fonts_dir)
return; return;
@ -279,35 +353,39 @@ static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Lib
FcPattern* pattern; FcPattern* pattern;
FcFontSet* fset; FcFontSet* fset;
FcBool res; FcBool res;
int face_index, num_faces = 1;
rc = FT_New_Memory_Face(ftlibrary, (unsigned char*)data, data_size, 0, &face); for (face_index = 0; face_index < num_faces; ++face_index) {
if (rc) { rc = FT_New_Memory_Face(ftlibrary, (unsigned char*)data, data_size, face_index, &face);
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, name); if (rc) {
return; mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, name);
} return;
}
num_faces = face->num_faces;
pattern = FcFreeTypeQueryFace(face, (unsigned char*)name, 0, FcConfigGetBlanks(priv->config));
if (!pattern) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFreeTypeQueryFace");
FT_Done_Face(face);
return;
}
fset = FcConfigGetFonts(priv->config, FcSetSystem); // somehow it failes when asked for FcSetApplication
if (!fset) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcConfigGetFonts");
FT_Done_Face(face);
return;
}
res = FcFontSetAdd(fset, pattern);
if (!res) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFontSetAdd");
FT_Done_Face(face);
return;
}
pattern = FcFreeTypeQueryFace(face, (unsigned char*)name, 0, FcConfigGetBlanks(priv->config));
if (!pattern) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFreeTypeQueryFace");
FT_Done_Face(face); FT_Done_Face(face);
return;
} }
fset = FcConfigGetFonts(priv->config, FcSetSystem); // somehow it failes when asked for FcSetApplication
if (!fset) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcConfigGetFonts");
FT_Done_Face(face);
return;
}
res = FcFontSetAdd(fset, pattern);
if (!res) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FunctionCallFailed, "FcFontSetAdd");
FT_Done_Face(face);
return;
}
FT_Done_Face(face);
#endif #endif
} }
@ -319,19 +397,17 @@ static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Lib
* \param path default font path * \param path default font path
* \return pointer to fontconfig private data * \return pointer to fontconfig private data
*/ */
fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path) fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path, int fc)
{ {
int rc; int rc;
fc_instance_t* priv = calloc(1, sizeof(fc_instance_t)); fc_instance_t* priv = calloc(1, sizeof(fc_instance_t));
const char* dir = library->fonts_dir; const char* dir = library->fonts_dir;
int i; int i;
if (font_fontconfig < 0) { if (!fc) {
mp_msg(MSGT_ASS, MSGL_WARN, mp_msg(MSGT_ASS, MSGL_WARN,
MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed); MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed);
priv->path_default = strdup(path); goto exit;
priv->index_default = 0;
return priv;
} }
rc = FcInit(); rc = FcInit();
@ -340,59 +416,63 @@ fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, con
priv->config = FcConfigGetCurrent(); priv->config = FcConfigGetCurrent();
if (!priv->config) { if (!priv->config) {
mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed); mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed);
return 0; goto exit;
} }
for (i = 0; i < library->num_fontdata; ++i) for (i = 0; i < library->num_fontdata; ++i)
process_fontdata(priv, library, ftlibrary, i); process_fontdata(priv, library, ftlibrary, i);
if (FcDirCacheValid((const FcChar8 *)dir) == FcFalse) if (dir) {
{ if (FcDirCacheValid((const FcChar8 *)dir) == FcFalse)
mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_UpdatingFontCache); {
if (FcGetVersion() >= 20390 && FcGetVersion() < 20400) mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_UpdatingFontCache);
mp_msg(MSGT_ASS, MSGL_WARN, if (FcGetVersion() >= 20390 && FcGetVersion() < 20400)
MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported); mp_msg(MSGT_ASS, MSGL_WARN,
// FontConfig >= 2.4.0 updates cache automatically in FcConfigAppFontAddDir() MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported);
if (FcGetVersion() < 20390) { // FontConfig >= 2.4.0 updates cache automatically in FcConfigAppFontAddDir()
FcFontSet* fcs; if (FcGetVersion() < 20390) {
FcStrSet* fss; FcFontSet* fcs;
fcs = FcFontSetCreate(); FcStrSet* fss;
fss = FcStrSetCreate(); fcs = FcFontSetCreate();
rc = FcStrSetAdd(fss, (const FcChar8*)dir); fss = FcStrSetCreate();
if (!rc) { rc = FcStrSetAdd(fss, (const FcChar8*)dir);
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcStrSetAddFailed); if (!rc) {
goto ErrorFontCache; mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcStrSetAddFailed);
goto ErrorFontCache;
}
rc = FcDirScan(fcs, fss, NULL, FcConfigGetBlanks(priv->config),
(const FcChar8 *)dir, FcFalse);
if (!rc) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirScanFailed);
goto ErrorFontCache;
}
rc = FcDirSave(fcs, fss, (const FcChar8 *)dir);
if (!rc) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirSave);
goto ErrorFontCache;
}
ErrorFontCache:
;
}
} }
rc = FcDirScan(fcs, fss, NULL, FcConfigGetBlanks(priv->config), (const FcChar8 *)dir, FcFalse); rc = FcConfigAppFontAddDir(priv->config, (const FcChar8*)dir);
if (!rc) { if (!rc) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirScanFailed); mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcConfigAppFontAddDirFailed);
goto ErrorFontCache;
}
rc = FcDirSave(fcs, fss, (const FcChar8 *)dir);
if (!rc) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcDirSave);
goto ErrorFontCache;
}
ErrorFontCache:
;
} }
} }
rc = FcConfigAppFontAddDir(priv->config, (const FcChar8*)dir); priv->family_default = family ? strdup(family) : NULL;
if (!rc) { exit:
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcConfigAppFontAddDirFailed); priv->path_default = path ? strdup(path) : NULL;
}
priv->family_default = family ? strdup(family) : 0;
priv->path_default = path ? strdup(path) : 0;
priv->index_default = 0; priv->index_default = 0;
return priv; return priv;
} }
#else // HAVE_FONTCONFIG #else /* CONFIG_FONTCONFIG */
char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index, char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index,
uint32_t code) uint32_t code)
@ -401,7 +481,7 @@ char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold,
return priv->path_default; return priv->path_default;
} }
fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path) fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path, int fc)
{ {
fc_instance_t* priv; fc_instance_t* priv;

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBASS_FONTCONFIG_H #ifndef LIBASS_FONTCONFIG_H
#define LIBASS_FONTCONFIG_H #define LIBASS_FONTCONFIG_H
@ -26,13 +28,13 @@
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#ifdef HAVE_FONTCONFIG #ifdef CONFIG_FONTCONFIG
#include <fontconfig/fontconfig.h> #include <fontconfig/fontconfig.h>
#endif #endif
typedef struct fc_instance_s fc_instance_t; typedef struct fc_instance_s fc_instance_t;
fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path); fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, const char* family, const char* path, int fc);
char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index, uint32_t code); char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index, uint32_t code);
void fontconfig_done(fc_instance_t* priv); void fontconfig_done(fc_instance_t* priv);

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBASS_LIBRARY_H #ifndef LIBASS_LIBRARY_H
#define LIBASS_LIBRARY_H #define LIBASS_LIBRARY_H

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h" #include "config.h"
@ -147,8 +149,8 @@ typedef struct render_context_s {
EVENT_HSCROLL, // "Banner" transition effect, text_width is unlimited EVENT_HSCROLL, // "Banner" transition effect, text_width is unlimited
EVENT_VSCROLL // "Scroll up", "Scroll down" transition effects EVENT_VSCROLL // "Scroll up", "Scroll down" transition effects
} evt_type; } evt_type;
int pos_x, pos_y; // position double pos_x, pos_y; // position
int org_x, org_y; // origin double org_x, org_y; // origin
char have_origin; // origin is explicitly defined; if 0, get_base_point() is used char have_origin; // origin is explicitly defined; if 0, get_base_point() is used
double scale_x, scale_y; double scale_x, scale_y;
double hspacing; // distance between letters, in pixels double hspacing; // distance between letters, in pixels
@ -159,6 +161,7 @@ typedef struct render_context_s {
uint32_t fade; // alpha from \fad uint32_t fade; // alpha from \fad
char be; // blur edges char be; // blur edges
int shadow; int shadow;
int drawing_mode; // not implemented; when != 0 text is discarded, except for style override tags
effect_t effect_type; effect_t effect_type;
int effect_timing; int effect_timing;
@ -454,19 +457,19 @@ static ass_image_t* render_text(text_info_t* text_info, int dst_x, int dst_y)
/** /**
* \brief Mapping between script and screen coordinates * \brief Mapping between script and screen coordinates
*/ */
static int x2scr(int x) { static int x2scr(double x) {
return x*frame_context.orig_width_nocrop / frame_context.track->PlayResX + return x*frame_context.orig_width_nocrop / frame_context.track->PlayResX +
FFMAX(global_settings->left_margin, 0); FFMAX(global_settings->left_margin, 0);
} }
/** /**
* \brief Mapping between script and screen coordinates * \brief Mapping between script and screen coordinates
*/ */
static int y2scr(int y) { static int y2scr(double y) {
return y * frame_context.orig_height_nocrop / frame_context.track->PlayResY + return y * frame_context.orig_height_nocrop / frame_context.track->PlayResY +
FFMAX(global_settings->top_margin, 0); FFMAX(global_settings->top_margin, 0);
} }
// the same for toptitles // the same for toptitles
static int y2scr_top(int y) { static int y2scr_top(double y) {
if (global_settings->use_margins) if (global_settings->use_margins)
return y * frame_context.orig_height_nocrop / frame_context.track->PlayResY; return y * frame_context.orig_height_nocrop / frame_context.track->PlayResY;
else else
@ -474,7 +477,7 @@ static int y2scr_top(int y) {
FFMAX(global_settings->top_margin, 0); FFMAX(global_settings->top_margin, 0);
} }
// the same for subtitles // the same for subtitles
static int y2scr_sub(int y) { static int y2scr_sub(double y) {
if (global_settings->use_margins) if (global_settings->use_margins)
return y * frame_context.orig_height_nocrop / frame_context.track->PlayResY + return y * frame_context.orig_height_nocrop / frame_context.track->PlayResY +
FFMAX(global_settings->top_margin, 0) + FFMAX(global_settings->top_margin, 0) +
@ -677,11 +680,11 @@ static void reset_render_context(void);
* \param pwr multiplier for some tag effects (comes from \t tags) * \param pwr multiplier for some tag effects (comes from \t tags)
*/ */
static char* parse_tag(char* p, double pwr) { static char* parse_tag(char* p, double pwr) {
#define skip_all(x) if (*p == (x)) ++p; else { \ #define skip_to(x) while ((*p != (x)) && (*p != '}') && (*p != 0)) { ++p;}
while ((*p != (x)) && (*p != '}') && (*p != 0)) {++p;} }
#define skip(x) if (*p == (x)) ++p; else { return p; } #define skip(x) if (*p == (x)) ++p; else { return p; }
skip_all('\\'); skip_to('\\');
skip('\\');
if ((*p == '}') || (*p == 0)) if ((*p == '}') || (*p == 0))
return p; return p;
@ -725,7 +728,7 @@ static char* parse_tag(char* p, double pwr) {
} else if (mystrcmp(&p, "move")) { } else if (mystrcmp(&p, "move")) {
int x1, x2, y1, y2; int x1, x2, y1, y2;
long long t1, t2, delta_t, t; long long t1, t2, delta_t, t;
int x, y; double x, y;
double k; double k;
skip('('); skip('(');
x1 = strtol(p, &p, 10); x1 = strtol(p, &p, 10);
@ -785,7 +788,7 @@ static char* parse_tag(char* p, double pwr) {
} else if (mystrcmp(&p, "fn")) { } else if (mystrcmp(&p, "fn")) {
char* start = p; char* start = p;
char* family; char* family;
skip_all('\\'); skip_to('\\');
if (p > start) { if (p > start) {
family = malloc(p - start + 1); family = malloc(p - start + 1);
strncpy(family, start, p - start); strncpy(family, start, p - start);
@ -886,6 +889,7 @@ static char* parse_tag(char* p, double pwr) {
render_context.org_x = v1; render_context.org_x = v1;
render_context.org_y = v2; render_context.org_y = v2;
render_context.have_origin = 1; render_context.have_origin = 1;
render_context.detect_collisions = 0;
} else if (mystrcmp(&p, "t")) { } else if (mystrcmp(&p, "t")) {
double v[3]; double v[3];
int v1, v2; int v1, v2;
@ -926,7 +930,8 @@ static char* parse_tag(char* p, double pwr) {
} }
while (*p == '\\') while (*p == '\\')
p = parse_tag(p, k); // maybe k*pwr ? no, specs forbid nested \t's p = parse_tag(p, k); // maybe k*pwr ? no, specs forbid nested \t's
skip_all(')'); // FIXME: better skip(')'), but much more tags support required skip_to(')'); // in case there is some unknown tag or a comment
skip(')');
} else if (mystrcmp(&p, "clip")) { } else if (mystrcmp(&p, "clip")) {
int x0, y0, x1, y1; int x0, y0, x1, y1;
int res = 1; int res = 1;
@ -1024,12 +1029,19 @@ static char* parse_tag(char* p, double pwr) {
render_context.shadow = val; render_context.shadow = val;
else else
render_context.shadow = render_context.style->Shadow; render_context.shadow = render_context.style->Shadow;
} else if (mystrcmp(&p, "pbo")) {
(void)strtol(p, &p, 10); // ignored
} else if (mystrcmp(&p, "p")) {
int val;
if (!mystrtoi(&p, 10, &val))
val = 0;
render_context.drawing_mode = !!val;
} }
return p; return p;
#undef skip #undef skip
#undef skip_all #undef skip_to
} }
/** /**
@ -1069,7 +1081,7 @@ static unsigned get_next_char(char** str)
p += 2; p += 2;
*str = p; *str = p;
return '\n'; return '\n';
} else if (*(p+1) == 'n') { } else if ((*(p+1) == 'n') || (*(p+1) == 'h')) {
p += 2; p += 2;
*str = p; *str = p;
return ' '; return ' ';
@ -1199,6 +1211,7 @@ static void init_render_context(ass_event_t* event)
render_context.clip_y1 = frame_context.track->PlayResY; render_context.clip_y1 = frame_context.track->PlayResY;
render_context.detect_collisions = 1; render_context.detect_collisions = 1;
render_context.fade = 0; render_context.fade = 0;
render_context.drawing_mode = 0;
render_context.effect_type = EF_NONE; render_context.effect_type = EF_NONE;
render_context.effect_timing = 0; render_context.effect_timing = 0;
render_context.effect_skip_timing = 0; render_context.effect_skip_timing = 0;
@ -1746,7 +1759,9 @@ static int ass_render_event(ass_event_t* event, event_images_t* event_images)
while (1) { while (1) {
// get next char, executing style override // get next char, executing style override
// this affects render_context // this affects render_context
code = get_next_char(&p); do {
code = get_next_char(&p);
} while (code && render_context.drawing_mode); // skip everything in drawing mode
// face could have been changed in get_next_char // face could have been changed in get_next_char
if (!render_context.font) { if (!render_context.font) {
@ -1932,7 +1947,7 @@ static int ass_render_event(ass_event_t* event, event_images_t* event_images)
if (render_context.evt_type == EVENT_POSITIONED) { if (render_context.evt_type == EVENT_POSITIONED) {
int base_x = 0; int base_x = 0;
int base_y = 0; int base_y = 0;
mp_msg(MSGT_ASS, MSGL_DBG2, "positioned event at %d, %d\n", render_context.pos_x, render_context.pos_y); mp_msg(MSGT_ASS, MSGL_DBG2, "positioned event at %f, %f\n", render_context.pos_x, render_context.pos_y);
get_base_point(bbox, alignment, &base_x, &base_y); get_base_point(bbox, alignment, &base_x, &base_y);
device_x = x2scr(render_context.pos_x) - base_x; device_x = x2scr(render_context.pos_x) - base_x;
device_y = y2scr(render_context.pos_y) - base_y; device_y = y2scr(render_context.pos_y) - base_y;
@ -2083,7 +2098,7 @@ void ass_set_line_spacing(ass_renderer_t* priv, double line_spacing)
priv->settings.line_spacing = line_spacing; priv->settings.line_spacing = line_spacing;
} }
int ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* default_family) static int ass_set_fonts_(ass_renderer_t* priv, const char* default_font, const char* default_family, int fc)
{ {
if (priv->settings.default_font) if (priv->settings.default_font)
free(priv->settings.default_font); free(priv->settings.default_font);
@ -2095,11 +2110,21 @@ int ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* de
if (priv->fontconfig_priv) if (priv->fontconfig_priv)
fontconfig_done(priv->fontconfig_priv); fontconfig_done(priv->fontconfig_priv);
priv->fontconfig_priv = fontconfig_init(priv->library, priv->ftlibrary, default_family, default_font); priv->fontconfig_priv = fontconfig_init(priv->library, priv->ftlibrary, default_family, default_font, fc);
return !!priv->fontconfig_priv; return !!priv->fontconfig_priv;
} }
int ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* default_family)
{
return ass_set_fonts_(priv, default_font, default_family, 1);
}
int ass_set_fonts_nofc(ass_renderer_t* priv, const char* default_font, const char* default_family)
{
return ass_set_fonts_(priv, default_font, default_family, 0);
}
/** /**
* \brief Start a new frame * \brief Start a new frame
*/ */

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBASS_TYPES_H #ifndef LIBASS_TYPES_H
#define LIBASS_TYPES_H #define LIBASS_TYPES_H

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h" #include "config.h"

View file

@ -1,22 +1,24 @@
// -*- c-basic-offset: 8; indent-tabs-mode: t -*- // -*- c-basic-offset: 8; indent-tabs-mode: t -*-
// vim:ts=8:sw=8:noet:ai: // vim:ts=8:sw=8:noet:ai:
/* /*
Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
*
This program is free software; you can redistribute it and/or modify * This file is part of libass.
it under the terms of the GNU General Public License as published by *
the Free Software Foundation; either version 2 of the License, or * libass is free software; you can redistribute it and/or modify
(at your option) any later version. * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
This program is distributed in the hope that it will be useful, * (at your option) any later version.
but WITHOUT ANY WARRANTY; without even the implied warranty of *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * libass is distributed in the hope that it will be useful,
GNU General Public License for more details. * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
You should have received a copy of the GNU General Public License * GNU General Public License for more details.
along with this program; if not, write to the Free Software *
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * You should have received a copy of the GNU General Public License along
*/ * with libass; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef LIBASS_UTILS_H #ifndef LIBASS_UTILS_H
#define LIBASS_UTILS_H #define LIBASS_UTILS_H