From 1279b910ad14da64624414ed68aa32aea720a7bd Mon Sep 17 00:00:00 2001 From: Amar Takhar Date: Sun, 28 Dec 2008 08:09:59 +0000 Subject: [PATCH] Update to libass r28085. Originally committed to SVN as r2539. --- libass/Makefile.am | 2 +- libass/ass.c | 94 +++++++----- libass/ass.h | 49 ++++--- libass/ass_bitmap.c | 37 ++--- libass/ass_bitmap.h | 34 +++-- libass/ass_cache.c | 36 ++--- libass/ass_cache.h | 34 +++-- libass/ass_font.c | 36 ++--- libass/ass_font.h | 34 +++-- libass/ass_fontconfig.c | 318 +++++++++++++++++++++++++--------------- libass/ass_fontconfig.h | 38 ++--- libass/ass_library.c | 34 +++-- libass/ass_library.h | 34 +++-- libass/ass_render.c | 93 +++++++----- libass/ass_types.h | 34 +++-- libass/ass_utils.c | 34 +++-- libass/ass_utils.h | 34 +++-- 17 files changed, 574 insertions(+), 401 deletions(-) diff --git a/libass/Makefile.am b/libass/Makefile.am index fd12c1d92..ba7d9946a 100644 --- a/libass/Makefile.am +++ b/libass/Makefile.am @@ -1,6 +1,6 @@ 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 = \ ass.c \ diff --git a/libass/ass.c b/libass/ass.c index 14f6c1587..8022dfc9b 100644 --- a/libass/ass.c +++ b/libass/ass.c @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include "config.h" @@ -30,7 +32,7 @@ #include #include -#ifdef USE_ICONV +#ifdef CONFIG_ICONV #include #endif @@ -161,7 +163,7 @@ static void rskip_spaces(char** str, char* limit) { static int lookup_style(ass_track_t* track, char* name) { int i; if (*name == '*') ++name; // FIXME: what does '*' really mean ? - for (i=0; in_styles; ++i) { + for (i = track->n_styles - 1; i >= 0; --i) { // FIXME: mb strcasecmp ? if (strcmp(track->styles[i].Name, name) == 0) return i; @@ -482,6 +484,12 @@ static int process_style(ass_track_t* track, char *str) style->Name = strdup("Default"); if (!style->FontName) 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); 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 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) +*/ +void ass_process_data(ass_track_t* track, char* data, int size) { char* str = malloc(size + 1); memcpy(str, data, size); str[size] = '\0'; + mp_msg(MSGT_ASS, MSGL_V, "event: %s\n", str); process_text(track, 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) { // 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); } -#ifdef USE_ICONV +#ifdef CONFIG_ICONV /** \brief recode buffer to utf-8 * constraint: codepage != 0 * \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; -#ifdef HAVE_ENCA +#ifdef CONFIG_ENCA char enca_lang[3], enca_fallback[100]; if (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* op; size_t rc; + int clear = 0; - outbuf = malloc(size); + outbuf = malloc(osize); ip = data; op = outbuf; - while (ileft) { - rc = iconv(icdsc, &ip, &ileft, &op, &oleft); + while (1) { + 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 (errno == E2BIG) { - int offset = op - outbuf; + size_t offset = op - outbuf; outbuf = (char*)realloc(outbuf, osize + size); op = outbuf + offset; 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); return NULL; } - } + } else + if (clear) + break; } 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) return 0; -#ifdef USE_ICONV +#ifdef CONFIG_ICONV if (codepage) buf = sub_recode(buf, bufsize, codepage); if (!buf) @@ -993,7 +1021,7 @@ ass_track_t* ass_read_memory(ass_library_t* library, char* buf, size_t bufsize, 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; size_t bufsize; @@ -1001,7 +1029,7 @@ char* read_file_recode(char* fname, char* codepage, int* size) buf = read_file(fname, &bufsize); if (!buf) return 0; -#ifdef USE_ICONV +#ifdef CONFIG_ICONV if (codepage) { char* tmpbuf = sub_recode(buf, bufsize, codepage); free(buf); @@ -1055,7 +1083,7 @@ int ass_read_styles(ass_track_t* track, char* fname, char* codepage) buf = read_file(fname, &sz); if (!buf) return 1; -#ifdef USE_ICONV +#ifdef CONFIG_ICONV if (codepage) { char* tmpbuf; tmpbuf = sub_recode(buf, sz, codepage); diff --git a/libass/ass.h b/libass/ass.h index 851be6681..4bdea3a4a 100644 --- a/libass/ass.h +++ b/libass/ass.h @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef 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); +/** + * \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 * \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); +/** + * \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 * \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); -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. diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c index f84b453b3..3d85300d1 100644 --- a/libass/ass_bitmap.c +++ b/libass/ass_bitmap.c @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include #include @@ -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); 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) 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) diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h index 634d7e41b..73f9de4df 100644 --- a/libass/ass_bitmap.h +++ b/libass/ass_bitmap.h @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef LIBASS_BITMAP_H #define LIBASS_BITMAP_H diff --git a/libass/ass_cache.c b/libass/ass_cache.c index a61f9f90c..41645c4a4 100644 --- a/libass/ass_cache.c +++ b/libass/ass_cache.c @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #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) { - 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) diff --git a/libass/ass_cache.h b/libass/ass_cache.h index 289753ef6..5f6a2ddd9 100644 --- a/libass/ass_cache.h +++ b/libass/ass_cache.h @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef LIBASS_CACHE_H #define LIBASS_CACHE_H diff --git a/libass/ass_font.c b/libass/ass_font.c index 4339621cd..f2214a345 100644 --- a/libass/ass_font.c +++ b/libass/ass_font.c @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include "config.h" @@ -282,7 +284,7 @@ FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch break; } -#ifdef HAVE_FONTCONFIG +#ifdef CONFIG_FONTCONFIG if (index == 0) { int face_idx; mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_GlyphNotFoundReselectingFont, diff --git a/libass/ass_font.h b/libass/ass_font.h index cafdc6577..03396a6f2 100644 --- a/libass/ass_font.h +++ b/libass/ass_font.h @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef LIBASS_FONT_H #define LIBASS_FONT_H diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c index 5b01cb899..9a7bddecc 100644 --- a/libass/ass_fontconfig.c +++ b/libass/ass_fontconfig.c @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include "config.h" @@ -35,15 +37,13 @@ #include "ass_library.h" #include "ass_fontconfig.h" -#ifdef HAVE_FONTCONFIG +#ifdef CONFIG_FONTCONFIG #include #include #endif -int font_fontconfig = 1; - struct fc_instance_s { -#ifdef HAVE_FONTCONFIG +#ifdef CONFIG_FONTCONFIG FcConfig* config; #endif char* family_default; @@ -51,7 +51,17 @@ struct fc_instance_s { 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. * \param priv private data @@ -67,14 +77,15 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold { FcBool rc; FcResult result; - FcPattern *pat = 0, *rpat; - int val_i; - FcChar8* val_s; - FcBool val_b; - FcCharSet* val_cs; - FcFontSet* fset = 0; + FcPattern *pat = NULL, *rpat = NULL; + int r_index, r_slant, r_weight; + FcChar8 *r_family, *r_style, *r_file, *r_fullname; + FcBool r_outline, r_embolden; + FcCharSet* r_charset; + FcFontSet* fset = NULL; int curf; - char* retval = 0; + char* retval = NULL; + int family_cnt; *index = 0; @@ -83,6 +94,30 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold goto error; 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); FcPatternAddInteger(pat, FC_SLANT, italic); FcPatternAddInteger(pat, FC_WEIGHT, bold); @@ -94,49 +129,88 @@ static char* _select_font(fc_instance_t* priv, const char* family, unsigned bold goto error; fset = FcFontSort(priv->config, pat, FcTrue, NULL, &result); + if (!fset) + goto error; for (curf = 0; curf < fset->nfont; ++curf) { - rpat = fset->fonts[curf]; - - result = FcPatternGetBool(rpat, FC_OUTLINE, 0, &val_b); + FcPattern* curp = fset->fonts[curf]; + + result = FcPatternGetBool(curp, FC_OUTLINE, 0, &r_outline); if (result != FcResultMatch) continue; - if (val_b != FcTrue) + if (r_outline != FcTrue) continue; if (!code) break; - result = FcPatternGetCharSet(rpat, FC_CHARSET, 0, &val_cs); + result = FcPatternGetCharSet(curp, FC_CHARSET, 0, &r_charset); if (result != FcResultMatch) continue; - if (FcCharSetHasChar(val_cs, code)) + if (FcCharSetHasChar(r_charset, code)) break; } if (curf >= fset->nfont) goto error; - rpat = fset->fonts[curf]; - - result = FcPatternGetInteger(rpat, FC_INDEX, 0, &val_i); - if (result != FcResultMatch) - goto error; - *index = val_i; +#if (FC_VERSION >= 20297) + // Remove all extra family names from original pattern. + // After this, FcFontRenderPrepare will select the most relevant family + // name in case there are more than one of them. + for (; family_cnt > 1; --family_cnt) + FcPatternRemove(pat, FC_FAMILY, family_cnt - 1); +#endif - result = FcPatternGetString(rpat, FC_FAMILY, 0, &val_s); - if (result != FcResultMatch) + rpat = FcFontRenderPrepare(priv->config, pat, fset->fonts[curf]); + if (!rpat) 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, - (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) - goto error; - - retval = strdup((const char*)val_s); + r_style = NULL; + + 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: if (pat) FcPatternDestroy(pat); + if (rpat) FcPatternDestroy(rpat); if (fset) FcFontSetDestroy(fset); return retval; } @@ -155,7 +229,7 @@ char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, uint32_t code) { char* res = 0; - if (font_fontconfig < 0) { + if (!priv->config) { *index = priv->index_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; const char* fonts_dir = library->fonts_dir; char buf[1000]; - FILE* fp = 0; + FILE* fp = NULL; if (!fonts_dir) return; @@ -279,35 +353,39 @@ static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Lib FcPattern* pattern; FcFontSet* fset; FcBool res; + int face_index, num_faces = 1; - rc = FT_New_Memory_Face(ftlibrary, (unsigned char*)data, data_size, 0, &face); - if (rc) { - mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorOpeningMemoryFont, name); - return; - } + for (face_index = 0; face_index < num_faces; ++face_index) { + rc = FT_New_Memory_Face(ftlibrary, (unsigned char*)data, data_size, face_index, &face); + if (rc) { + 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); - 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 } @@ -319,19 +397,17 @@ static void process_fontdata(fc_instance_t* priv, ass_library_t* library, FT_Lib * \param path default font path * \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; fc_instance_t* priv = calloc(1, sizeof(fc_instance_t)); const char* dir = library->fonts_dir; int i; - if (font_fontconfig < 0) { + if (!fc) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed); - priv->path_default = strdup(path); - priv->index_default = 0; - return priv; + goto exit; } rc = FcInit(); @@ -340,59 +416,63 @@ fc_instance_t* fontconfig_init(ass_library_t* library, FT_Library ftlibrary, con priv->config = FcConfigGetCurrent(); if (!priv->config) { mp_msg(MSGT_ASS, MSGL_FATAL, MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed); - return 0; + goto exit; } for (i = 0; i < library->num_fontdata; ++i) process_fontdata(priv, library, ftlibrary, i); - 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_WARN, - MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported); - // FontConfig >= 2.4.0 updates cache automatically in FcConfigAppFontAddDir() - if (FcGetVersion() < 20390) { - FcFontSet* fcs; - FcStrSet* fss; - fcs = FcFontSetCreate(); - fss = FcStrSetCreate(); - rc = FcStrSetAdd(fss, (const FcChar8*)dir); - if (!rc) { - mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcStrSetAddFailed); - goto ErrorFontCache; + 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_WARN, + MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported); + // FontConfig >= 2.4.0 updates cache automatically in FcConfigAppFontAddDir() + if (FcGetVersion() < 20390) { + FcFontSet* fcs; + FcStrSet* fss; + fcs = FcFontSetCreate(); + fss = FcStrSetCreate(); + rc = FcStrSetAdd(fss, (const FcChar8*)dir); + if (!rc) { + 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); - 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 = FcConfigAppFontAddDir(priv->config, (const FcChar8*)dir); + if (!rc) { + mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcConfigAppFontAddDirFailed); } } - rc = FcConfigAppFontAddDir(priv->config, (const FcChar8*)dir); - if (!rc) { - mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FcConfigAppFontAddDirFailed); - } - - priv->family_default = family ? strdup(family) : 0; - priv->path_default = path ? strdup(path) : 0; + priv->family_default = family ? strdup(family) : NULL; +exit: + priv->path_default = path ? strdup(path) : NULL; priv->index_default = 0; return priv; } -#else // HAVE_FONTCONFIG +#else /* CONFIG_FONTCONFIG */ char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, unsigned italic, int* index, uint32_t code) @@ -401,7 +481,7 @@ char* fontconfig_select(fc_instance_t* priv, const char* family, unsigned bold, 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; diff --git a/libass/ass_fontconfig.h b/libass/ass_fontconfig.h index 3806f2468..e9a1ce156 100644 --- a/libass/ass_fontconfig.h +++ b/libass/ass_fontconfig.h @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef LIBASS_FONTCONFIG_H #define LIBASS_FONTCONFIG_H @@ -26,13 +28,13 @@ #include #include FT_FREETYPE_H -#ifdef HAVE_FONTCONFIG +#ifdef CONFIG_FONTCONFIG #include #endif 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); void fontconfig_done(fc_instance_t* priv); diff --git a/libass/ass_library.c b/libass/ass_library.c index cda928704..8c6af464a 100644 --- a/libass/ass_library.c +++ b/libass/ass_library.c @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include #include diff --git a/libass/ass_library.h b/libass/ass_library.h index adab0fdc4..ecf46f342 100644 --- a/libass/ass_library.h +++ b/libass/ass_library.h @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef LIBASS_LIBRARY_H #define LIBASS_LIBRARY_H diff --git a/libass/ass_render.c b/libass/ass_render.c index 05657294a..380690724 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include "config.h" @@ -147,8 +149,8 @@ typedef struct render_context_s { EVENT_HSCROLL, // "Banner" transition effect, text_width is unlimited EVENT_VSCROLL // "Scroll up", "Scroll down" transition effects } evt_type; - int pos_x, pos_y; // position - int org_x, org_y; // origin + double pos_x, pos_y; // position + double org_x, org_y; // origin char have_origin; // origin is explicitly defined; if 0, get_base_point() is used double scale_x, scale_y; double hspacing; // distance between letters, in pixels @@ -159,6 +161,7 @@ typedef struct render_context_s { uint32_t fade; // alpha from \fad char be; // blur edges int shadow; + int drawing_mode; // not implemented; when != 0 text is discarded, except for style override tags effect_t effect_type; 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 */ -static int x2scr(int x) { +static int x2scr(double x) { return x*frame_context.orig_width_nocrop / frame_context.track->PlayResX + FFMAX(global_settings->left_margin, 0); } /** * \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 + FFMAX(global_settings->top_margin, 0); } // the same for toptitles -static int y2scr_top(int y) { +static int y2scr_top(double y) { if (global_settings->use_margins) return y * frame_context.orig_height_nocrop / frame_context.track->PlayResY; else @@ -474,7 +477,7 @@ static int y2scr_top(int y) { FFMAX(global_settings->top_margin, 0); } // the same for subtitles -static int y2scr_sub(int y) { +static int y2scr_sub(double y) { if (global_settings->use_margins) return y * frame_context.orig_height_nocrop / frame_context.track->PlayResY + 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) */ static char* parse_tag(char* p, double pwr) { -#define skip_all(x) if (*p == (x)) ++p; else { \ - while ((*p != (x)) && (*p != '}') && (*p != 0)) {++p;} } +#define skip_to(x) while ((*p != (x)) && (*p != '}') && (*p != 0)) { ++p;} #define skip(x) if (*p == (x)) ++p; else { return p; } - skip_all('\\'); + skip_to('\\'); + skip('\\'); if ((*p == '}') || (*p == 0)) return p; @@ -725,7 +728,7 @@ static char* parse_tag(char* p, double pwr) { } else if (mystrcmp(&p, "move")) { int x1, x2, y1, y2; long long t1, t2, delta_t, t; - int x, y; + double x, y; double k; skip('('); x1 = strtol(p, &p, 10); @@ -785,7 +788,7 @@ static char* parse_tag(char* p, double pwr) { } else if (mystrcmp(&p, "fn")) { char* start = p; char* family; - skip_all('\\'); + skip_to('\\'); if (p > start) { family = malloc(p - start + 1); 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_y = v2; render_context.have_origin = 1; + render_context.detect_collisions = 0; } else if (mystrcmp(&p, "t")) { double v[3]; int v1, v2; @@ -926,7 +930,8 @@ static char* parse_tag(char* p, double pwr) { } while (*p == '\\') 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")) { int x0, y0, x1, y1; int res = 1; @@ -1024,12 +1029,19 @@ static char* parse_tag(char* p, double pwr) { render_context.shadow = val; else 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; #undef skip -#undef skip_all +#undef skip_to } /** @@ -1069,7 +1081,7 @@ static unsigned get_next_char(char** str) p += 2; *str = p; return '\n'; - } else if (*(p+1) == 'n') { + } else if ((*(p+1) == 'n') || (*(p+1) == 'h')) { p += 2; *str = p; return ' '; @@ -1199,6 +1211,7 @@ static void init_render_context(ass_event_t* event) render_context.clip_y1 = frame_context.track->PlayResY; render_context.detect_collisions = 1; render_context.fade = 0; + render_context.drawing_mode = 0; render_context.effect_type = EF_NONE; render_context.effect_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) { // get next char, executing style override // 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 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) { int base_x = 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); device_x = x2scr(render_context.pos_x) - base_x; 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; } -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) 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) 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; } +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 */ diff --git a/libass/ass_types.h b/libass/ass_types.h index 23e107412..870fab4ca 100644 --- a/libass/ass_types.h +++ b/libass/ass_types.h @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef LIBASS_TYPES_H #define LIBASS_TYPES_H diff --git a/libass/ass_utils.c b/libass/ass_utils.c index f22fa8e68..d48685c63 100644 --- a/libass/ass_utils.c +++ b/libass/ass_utils.c @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include "config.h" diff --git a/libass/ass_utils.h b/libass/ass_utils.h index 7d6ffb681..d7501c485 100644 --- a/libass/ass_utils.h +++ b/libass/ass_utils.h @@ -1,22 +1,24 @@ // -*- c-basic-offset: 8; indent-tabs-mode: t -*- // vim:ts=8:sw=8:noet:ai: /* - Copyright (C) 2006 Evgeniy Stepanov - - This program 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. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + * Copyright (C) 2006 Evgeniy Stepanov + * + * This file is part of libass. + * + * libass 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. + * + * libass 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 libass; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #ifndef LIBASS_UTILS_H #define LIBASS_UTILS_H