[SCM] LibASS packaging branch, master, updated. debian/0.9.8-1-5-ga719cdb

xtophe-guest at users.alioth.debian.org xtophe-guest at users.alioth.debian.org
Wed Mar 3 16:22:15 UTC 2010


The following commit has been merged in the master branch:
commit 03235b6fe95c091949a8e81d4bd04dc829705ecb
Author: Christophe Mutricy <xtophe at videolan.org>
Date:   Wed Mar 3 16:48:43 2010 +0100

    Imported Upstream version 0.9.9

diff --git a/Changelog b/Changelog
index ca1ba53..f95d23b 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,14 @@
+libass (0.9.9)
+ * Parse numbers in a locale-independent way
+ * Remove support for freetype < 2.2.1, fontconfig < 2.4.1; this especially
+   means libass will not extract fonts into the file system anymore
+ * Disable script file size limit
+ * Match fonts against the full name ("name for humans")
+ * Reset clip mode after \iclip
+ * Improve VSFilter compatibility
+ * Update API documentation
+ * A couple of smaller fixes and cleanups
+
 libass (0.9.8)
  * Support \q override tag
  * Support wrap style 1 (i.e. wrap, but do not equalize line lengths)
diff --git a/configure b/configure
index 4e096d0..9f76be1 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for libass 0.9.8.
+# Generated by GNU Autoconf 2.61 for libass 0.9.9.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -722,8 +722,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='libass'
 PACKAGE_TARNAME='libass'
-PACKAGE_VERSION='0.9.8'
-PACKAGE_STRING='libass 0.9.8'
+PACKAGE_VERSION='0.9.9'
+PACKAGE_STRING='libass 0.9.9'
 PACKAGE_BUGREPORT=''
 
 # Factoring default headers for most tests.
@@ -1402,7 +1402,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libass 0.9.8 to adapt to many kinds of systems.
+\`configure' configures libass 0.9.9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1472,7 +1472,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libass 0.9.8:";;
+     short | recursive ) echo "Configuration of libass 0.9.9:";;
    esac
   cat <<\_ACEOF
 
@@ -1587,7 +1587,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libass configure 0.9.8
+libass configure 0.9.9
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1601,7 +1601,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libass $as_me 0.9.8, which was
+It was created by libass $as_me 0.9.9, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2291,7 +2291,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libass'
- VERSION='0.9.8'
+ VERSION='0.9.9'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -15733,12 +15733,12 @@ if test -n "$PKG_CONFIG"; then
         pkg_cv_FREETYPE_CFLAGS="$FREETYPE_CFLAGS"
     else
         if test -n "$PKG_CONFIG" && \
-    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"freetype2 >= 9.6.3\"") >&5
-  ($PKG_CONFIG --exists --print-errors "freetype2 >= 9.6.3") 2>&5
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"freetype2 >= 9.10.3\"") >&5
+  ($PKG_CONFIG --exists --print-errors "freetype2 >= 9.10.3") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  pkg_cv_FREETYPE_CFLAGS=`$PKG_CONFIG --cflags "freetype2 >= 9.6.3" 2>/dev/null`
+  pkg_cv_FREETYPE_CFLAGS=`$PKG_CONFIG --cflags "freetype2 >= 9.10.3" 2>/dev/null`
 else
   pkg_failed=yes
 fi
@@ -15751,12 +15751,12 @@ if test -n "$PKG_CONFIG"; then
         pkg_cv_FREETYPE_LIBS="$FREETYPE_LIBS"
     else
         if test -n "$PKG_CONFIG" && \
-    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"freetype2 >= 9.6.3\"") >&5
-  ($PKG_CONFIG --exists --print-errors "freetype2 >= 9.6.3") 2>&5
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"freetype2 >= 9.10.3\"") >&5
+  ($PKG_CONFIG --exists --print-errors "freetype2 >= 9.10.3") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  pkg_cv_FREETYPE_LIBS=`$PKG_CONFIG --libs "freetype2 >= 9.6.3" 2>/dev/null`
+  pkg_cv_FREETYPE_LIBS=`$PKG_CONFIG --libs "freetype2 >= 9.10.3" 2>/dev/null`
 else
   pkg_failed=yes
 fi
@@ -15775,14 +15775,14 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        FREETYPE_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "freetype2 >= 9.6.3"`
+	        FREETYPE_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "freetype2 >= 9.10.3"`
         else
-	        FREETYPE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "freetype2 >= 9.6.3"`
+	        FREETYPE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "freetype2 >= 9.10.3"`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$FREETYPE_PKG_ERRORS" >&5
 
-	{ { echo "$as_me:$LINENO: error: Package requirements (freetype2 >= 9.6.3) were not met:
+	{ { echo "$as_me:$LINENO: error: Package requirements (freetype2 >= 9.10.3) were not met:
 
 $FREETYPE_PKG_ERRORS
 
@@ -15793,7 +15793,7 @@ Alternatively, you may set the environment variables FREETYPE_CFLAGS
 and FREETYPE_LIBS to avoid the need to call pkg-config.
 See the pkg-config man page for more details.
 " >&5
-echo "$as_me: error: Package requirements (freetype2 >= 9.6.3) were not met:
+echo "$as_me: error: Package requirements (freetype2 >= 9.10.3) were not met:
 
 $FREETYPE_PKG_ERRORS
 
@@ -15854,12 +15854,12 @@ if test -n "$PKG_CONFIG"; then
         pkg_cv_FONTCONFIG_CFLAGS="$FONTCONFIG_CFLAGS"
     else
         if test -n "$PKG_CONFIG" && \
-    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.2.0\"") >&5
-  ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.2.0") 2>&5
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.4.2\"") >&5
+  ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.4.2") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  pkg_cv_FONTCONFIG_CFLAGS=`$PKG_CONFIG --cflags "fontconfig >= 2.2.0" 2>/dev/null`
+  pkg_cv_FONTCONFIG_CFLAGS=`$PKG_CONFIG --cflags "fontconfig >= 2.4.2" 2>/dev/null`
 else
   pkg_failed=yes
 fi
@@ -15872,12 +15872,12 @@ if test -n "$PKG_CONFIG"; then
         pkg_cv_FONTCONFIG_LIBS="$FONTCONFIG_LIBS"
     else
         if test -n "$PKG_CONFIG" && \
-    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.2.0\"") >&5
-  ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.2.0") 2>&5
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"fontconfig >= 2.4.2\"") >&5
+  ($PKG_CONFIG --exists --print-errors "fontconfig >= 2.4.2") 2>&5
   ac_status=$?
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; then
-  pkg_cv_FONTCONFIG_LIBS=`$PKG_CONFIG --libs "fontconfig >= 2.2.0" 2>/dev/null`
+  pkg_cv_FONTCONFIG_LIBS=`$PKG_CONFIG --libs "fontconfig >= 2.4.2" 2>/dev/null`
 else
   pkg_failed=yes
 fi
@@ -15896,9 +15896,9 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "fontconfig >= 2.2.0"`
+	        FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "fontconfig >= 2.4.2"`
         else
-	        FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "fontconfig >= 2.2.0"`
+	        FONTCONFIG_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "fontconfig >= 2.4.2"`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$FONTCONFIG_PKG_ERRORS" >&5
@@ -16674,7 +16674,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libass $as_me 0.9.8, which was
+This file was extended by libass $as_me 0.9.9, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16727,7 +16727,7 @@ Report bugs to <bug-autoconf at gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-libass config.status 0.9.8
+libass config.status 0.9.9
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/configure.ac b/configure.ac
index 7698492..c1f7ab2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(libass, 0.9.8)
+AC_INIT(libass, 0.9.9)
 AM_INIT_AUTOMAKE
 AC_CONFIG_MACRO_DIR([shave])
 # Disable C++/Fortran checks
@@ -41,14 +41,14 @@ AC_ARG_ENABLE([enca], AS_HELP_STRING([--disable-enca],
 AC_ARG_ENABLE([fontconfig], AS_HELP_STRING([--disable-fontconfig],
     [disable fontconfig support @<:@default=check@:>@]))
 
-PKG_CHECK_MODULES([FREETYPE], freetype2 >= 9.6.3, [
+PKG_CHECK_MODULES([FREETYPE], freetype2 >= 9.10.3, [
     CFLAGS="$CFLAGS $FREETYPE_CFLAGS"
     LIBS="$LIBS $FREETYPE_LIBS"
     AC_DEFINE(CONFIG_FREETYPE, 1, [found freetype2 via pkg-config])
     ])
 
 if test x$enable_fontconfig != xno; then
-PKG_CHECK_MODULES([FONTCONFIG], fontconfig >= 2.2.0, [
+PKG_CHECK_MODULES([FONTCONFIG], fontconfig >= 2.4.2, [
     CFLAGS="$CFLAGS $FONTCONFIG_CFLAGS"
     LIBS="$LIBS $FONTCONFIG_LIBS"
     AC_DEFINE(CONFIG_FONTCONFIG, 1, [found fontconfig via pkg-config])
diff --git a/libass/Makefile.am b/libass/Makefile.am
index 0cf613e..10b5c5b 100644
--- a/libass/Makefile.am
+++ b/libass/Makefile.am
@@ -8,7 +8,7 @@ libass_la_SOURCES = ass.c ass_cache.c ass_font.c ass_fontconfig.c ass_render.c \
                     ass_cache.h ass_fontconfig.h ass_font.h ass.h \
                     ass_library.h ass_types.h ass_utils.h ass_drawing.c \
                     ass_drawing.h ass_cache_template.h ass_render.h \
-                    ass_parse.c ass_parse.h
+                    ass_parse.c ass_parse.h ass_strtod.c
 libass_la_LDFLAGS = -version-info $(LIBASS_LT_CURRENT):$(LIBASS_LT_REVISION):$(LIBASS_LT_AGE)
 libass_la_LDFLAGS += -export-symbols $(srcdir)/libass.sym
 
diff --git a/libass/Makefile.in b/libass/Makefile.in
index a162f3c..bddb1ff 100644
--- a/libass/Makefile.in
+++ b/libass/Makefile.in
@@ -56,7 +56,7 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
 libass_la_LIBADD =
 am_libass_la_OBJECTS = ass.lo ass_cache.lo ass_font.lo \
 	ass_fontconfig.lo ass_render.lo ass_utils.lo ass_bitmap.lo \
-	ass_library.lo ass_drawing.lo ass_parse.lo
+	ass_library.lo ass_drawing.lo ass_parse.lo ass_strtod.lo
 libass_la_OBJECTS = $(am_libass_la_OBJECTS)
 libass_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -209,7 +209,7 @@ libass_la_SOURCES = ass.c ass_cache.c ass_font.c ass_fontconfig.c ass_render.c \
                     ass_cache.h ass_fontconfig.h ass_font.h ass.h \
                     ass_library.h ass_types.h ass_utils.h ass_drawing.c \
                     ass_drawing.h ass_cache_template.h ass_render.h \
-                    ass_parse.c ass_parse.h
+                    ass_parse.c ass_parse.h ass_strtod.c
 
 libass_la_LDFLAGS = -version-info \
 	$(LIBASS_LT_CURRENT):$(LIBASS_LT_REVISION):$(LIBASS_LT_AGE) \
@@ -295,6 +295,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ass_library.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ass_parse.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ass_render.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ass_strtod.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ass_utils.Plo at am__quote@
 
 .c.o:
diff --git a/libass/ass.c b/libass/ass.c
index f7f5bcc..1411776 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -38,6 +38,8 @@
 #include "ass_utils.h"
 #include "ass_library.h"
 
+#define ass_atof(STR) (ass_strtod((STR),NULL))
+
 typedef enum {
     PST_UNKNOWN = 0,
     PST_INFO,
@@ -250,7 +252,7 @@ static int numpad2align(int val)
 		ass_msg(track->library, MSGL_DBG2, "%s = %s", #name, token);
 
 #define INTVAL(name) ANYVAL(name,atoi)
-#define FPVAL(name) ANYVAL(name,atof)
+#define FPVAL(name) ANYVAL(name,ass_atof)
 #define TIMEVAL(name) \
 	} else if (strcasecmp(tname, #name) == 0) { \
 		target->name = string2timecode(track->library, token); \
@@ -384,7 +386,7 @@ void ass_process_force_style(ASS_Track *track)
         else if (!strcasecmp(*fs, "PlayResY"))
             track->PlayResY = atoi(token);
         else if (!strcasecmp(*fs, "Timer"))
-            track->Timer = atof(token);
+            track->Timer = ass_atof(token);
         else if (!strcasecmp(*fs, "WrapStyle"))
             track->WrapStyle = atoi(token);
         else if (!strcasecmp(*fs, "ScaledBorderAndShadow"))
@@ -568,7 +570,7 @@ static int process_info_line(ASS_Track *track, char *str)
     } else if (!strncmp(str, "PlayResY:", 9)) {
         track->PlayResY = atoi(str + 9);
     } else if (!strncmp(str, "Timer:", 6)) {
-        track->Timer = atof(str + 6);
+        track->Timer = ass_atof(str + 6);
     } else if (!strncmp(str, "WrapStyle:", 10)) {
         track->WrapStyle = atoi(str + 10);
     } else if (!strncmp(str, "ScaledBorderAndShadow:", 22)) {
@@ -1019,14 +1021,6 @@ static char *read_file(ASS_Library *library, char *fname, size_t *bufsize)
     sz = ftell(fp);
     rewind(fp);
 
-    if (sz > 10 * 1024 * 1024) {
-        ass_msg(library, MSGL_INFO,
-               "ass_read_file(%s): Refusing to load subtitles "
-               "larger than 10MiB", fname);
-        fclose(fp);
-        return 0;
-    }
-
     ass_msg(library, MSGL_V, "File size: %ld", sz);
 
     buf = malloc(sz + 1);
@@ -1100,12 +1094,13 @@ ASS_Track *ass_read_memory(ASS_Library *library, char *buf,
         return 0;
 
 #ifdef CONFIG_ICONV
-    if (codepage)
+    if (codepage) {
         buf = sub_recode(library, buf, bufsize, codepage);
-    if (!buf)
-        return 0;
-    else
-        need_free = 1;
+        if (!buf)
+            return 0;
+        else
+            need_free = 1;
+    }
 #endif
     track = parse_memory(library, buf);
     if (need_free)
diff --git a/libass/ass.h b/libass/ass.h
index 3684b44..a16bad4 100644
--- a/libass/ass.h
+++ b/libass/ass.h
@@ -25,7 +25,7 @@
 #include <stdarg.h>
 #include "ass_types.h"
 
-#define LIBASS_VERSION 0x00908000
+#define LIBASS_VERSION 0x00909000
 
 /*
  * A linked list of images produced by an ass renderer.
@@ -49,7 +49,7 @@ typedef struct ass_image {
 } ASS_Image;
 
 /*
- * Hintint type. (see ass_set_hinting below)
+ * Hinting type. (see ass_set_hinting below)
  *
  * FreeType's native hinter is still buggy sometimes and it is recommended
  * to use the light autohinter, ASS_HINTING_LIGHT, instead.  For best
@@ -75,11 +75,13 @@ ASS_Library *ass_library_init(void);
 void ass_library_done(ASS_Library *priv);
 
 /**
- * \brief Set private font directory.
- * It is used for saving embedded fonts and also in font lookup.
+ * \brief Set additional fonts directory.
+ * Optional directory that will be scanned for fonts recursively.  The fonts
+ * found are used for font lookup.
+ * NOTE: A valid font directory is not needed to support embedded fonts.
  *
  * \param priv library handle
- * \param fonts_dir private directory for font extraction
+ * \param fonts_dir directory with additional fonts
  */
 void ass_set_fonts_dir(ASS_Library *priv, const char *fonts_dir);
 
@@ -195,11 +197,16 @@ void ass_set_line_spacing(ASS_Renderer *priv, double line_spacing);
 
 /**
  * \brief Set font lookup defaults.
+ * \param default_font path to default font to use. Must be supplied if
+ * fontconfig is disabled or unavailable.
+ * \param default_family fallback font family for fontconfig, or NULL
  * \param fc whether to use fontconfig
  * \param config path to fontconfig configuration file, or NULL.  Only relevant
  * if fontconfig is used.
  * \param update whether fontconfig cache should be built/updated now.  Only
  * relevant if fontconfig is used.
+ *
+ * NOTE: font lookup must be configured before an ASS_Renderer can be used.
  */
 void ass_set_fonts(ASS_Renderer *priv, const char *default_font,
                    const char *default_family, int fc, const char *config,
@@ -294,7 +301,8 @@ void ass_free_event(ASS_Track *track, int eid);
 void ass_process_data(ASS_Track *track, char *data, int size);
 
 /**
- * \brief Parse Codec Private section of subtitle stream.
+ * \brief Parse Codec Private section of the subtitle stream, in Matroska
+ * format.  See the Matroska specification for details.
  * \param track target track
  * \param data string to parse
  * \param size length of data
@@ -302,8 +310,8 @@ void ass_process_data(ASS_Track *track, char *data, int size);
 void ass_process_codec_private(ASS_Track *track, char *data, int size);
 
 /**
- * \brief Parse a chunk of subtitle stream data. In Matroska,
- * this contains exactly 1 event (or a commentary).
+ * \brief Parse a chunk of subtitle stream data. A chunk contains exactly one
+ * event in Matroska format.  See the Matroska specification for details.
  * \param track track
  * \param data string to parse
  * \param size length of data
diff --git a/libass/ass_drawing.c b/libass/ass_drawing.c
index 8c5f062..a3207c7 100644
--- a/libass/ass_drawing.c
+++ b/libass/ass_drawing.c
@@ -41,14 +41,15 @@ static void drawing_make_glyph(ASS_Drawing *drawing, void *fontconfig_priv,
     // This is hacky...
     glyph = (FT_OutlineGlyph) ass_font_get_glyph(fontconfig_priv, font,
                                                  (uint32_t) ' ', hint, 0);
-
-    FT_Outline_Done(drawing->ftlibrary, &glyph->outline);
-    FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS,
-                   GLYPH_INITIAL_CONTOURS, &glyph->outline);
-
-    glyph->outline.n_contours = 0;
-    glyph->outline.n_points = 0;
-    glyph->root.advance.x = glyph->root.advance.y = 0;
+    if (glyph) {
+        FT_Outline_Done(drawing->ftlibrary, &glyph->outline);
+        FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS,
+                       GLYPH_INITIAL_CONTOURS, &glyph->outline);
+
+        glyph->outline.n_contours = 0;
+        glyph->outline.n_points = 0;
+        glyph->root.advance.x = glyph->root.advance.y = 0;
+    }
     drawing->glyph = glyph;
 }
 
@@ -363,15 +364,17 @@ static void drawing_evaluate_curve(ASS_Drawing *drawing,
 ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font,
                              ASS_Hinting hint, FT_Library lib)
 {
-    ASS_Drawing* drawing;
+    ASS_Drawing *drawing;
 
     drawing = calloc(1, sizeof(*drawing));
     drawing->text = calloc(1, DRAWING_INITIAL_SIZE);
     drawing->size = DRAWING_INITIAL_SIZE;
 
     drawing->ftlibrary = lib;
-    drawing->library = font->library;
-    drawing_make_glyph(drawing, fontconfig_priv, font, hint);
+    if (font) {
+        drawing->library = font->library;
+        drawing_make_glyph(drawing, fontconfig_priv, font, hint);
+    }
 
     drawing->scale_x = 1.;
     drawing->scale_y = 1.;
@@ -386,8 +389,11 @@ ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font,
  */
 void ass_drawing_free(ASS_Drawing* drawing)
 {
-    FT_Done_Glyph((FT_Glyph) drawing->glyph);
-    free(drawing->text);
+    if (drawing) {
+        if (drawing->glyph)
+            FT_Done_Glyph((FT_Glyph) drawing->glyph);
+        free(drawing->text);
+    }
     free(drawing);
 }
 
@@ -423,6 +429,9 @@ FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode)
     ASS_DrawingToken *token;
     FT_Vector pen = {0, 0};
 
+    if (!drawing->glyph)
+        return NULL;
+
     drawing->tokens = drawing_tokenize(drawing->text);
     drawing_prepare(drawing);
 
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 7d848a2..7db1f07 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -218,7 +218,6 @@ void ass_font_set_transform(ASS_Font *font, double scale_x,
 
 static void face_set_size(FT_Face face, double size)
 {
-#if (FREETYPE_MAJOR > 2) || ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR > 1))
     TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
     TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
     double mscale = 1.;
@@ -241,9 +240,6 @@ static void face_set_size(FT_Face face, double size)
     m->ascender /= mscale;
     m->descender /= mscale;
     m->height /= mscale;
-#else
-    FT_Set_Char_Size(face, 0, double_to_d6(size), 0, 0);
-#endif
 }
 
 /**
@@ -476,10 +472,6 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
                 index);
         return 0;
     }
-#if (FREETYPE_MAJOR > 2) || \
-    ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR >= 2)) || \
-    ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 1) && (FREETYPE_PATCH >= 10))
-// FreeType >= 2.1.10 required
     if (!(face->style_flags & FT_STYLE_FLAG_ITALIC) &&
         (font->desc.italic > 55)) {
         FT_GlyphSlot_Oblique(face->glyph);
@@ -489,7 +481,6 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
         (font->desc.bold > 80)) {
         ass_glyph_embolden(face->glyph);
     }
-#endif
     error = FT_Get_Glyph(face->glyph, &glyph);
     if (error) {
         ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d",
diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c
index 006be97..0150b2e 100644
--- a/libass/ass_fontconfig.c
+++ b/libass/ass_fontconfig.c
@@ -51,14 +51,46 @@ struct fc_instance {
 
 #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 Case-insensitive match ASS/SSA font family against full name. (also
+ * known as "name for humans")
+ *
+ * \param lib library instance
+ * \param priv fontconfig instance
+ * \param family font family
+ * \return font set
+ */
+static FcFontSet *match_fullname(ASS_Library *lib, FCInstance *priv,
+                                 const char *family)
+{
+    FcFontSet *sets[2];
+    FcFontSet *result = FcFontSetCreate();
+    int nsets = 0;
+    int i, fi;
+
+    if ((sets[nsets] = FcConfigGetFonts(priv->config, FcSetSystem)))
+        nsets++;
+    if ((sets[nsets] = FcConfigGetFonts(priv->config, FcSetApplication)))
+        nsets++;
+
+    // Run over font sets and patterns and try to match against full name
+    for (i = 0; i < nsets; i++) {
+        FcFontSet *set = sets[i];
+        for (fi = 0; fi < set->nfont; fi++) {
+            FcPattern *pat = set->fonts[fi];
+            char *fullname;
+            int pi = 0;
+            while (FcPatternGetString(pat, FC_FULLNAME, pi++,
+                   (FcChar8 **) &fullname) == FcResultMatch)
+                if (strcasecmp(fullname, family) == 0) {
+                    FcFontSetAdd(result, FcPatternDuplicate(pat));
+                    break;
+                }
+        }
+    }
+
+    return result;
+}
 
 /**
  * \brief Low-level font selection.
@@ -71,7 +103,7 @@ struct fc_instance {
  * \param code: the character that should be present in the font, can be 0
  * \return font file path
 */
-static char *_select_font(ASS_Library *library, FCInstance *priv,
+static char *select_font(ASS_Library *library, FCInstance *priv,
                           const char *family, int treat_family_as_pattern,
                           unsigned bold, unsigned italic, int *index,
                           uint32_t code)
@@ -83,7 +115,7 @@ static char *_select_font(ASS_Library *library, FCInstance *priv,
     FcChar8 *r_family, *r_style, *r_file, *r_fullname;
     FcBool r_outline, r_embolden;
     FcCharSet *r_charset;
-    FcFontSet *fset = NULL;
+    FcFontSet *ffullname = NULL, *fsorted = NULL, *fset = NULL;
     int curf;
     char *retval = NULL;
     int family_cnt = 0;
@@ -135,10 +167,23 @@ static char *_select_font(ASS_Library *library, FCInstance *priv,
     if (!rc)
         goto error;
 
-    fset = FcFontSort(priv->config, pat, FcTrue, NULL, &result);
-    if (!fset)
+    fsorted = FcFontSort(priv->config, pat, FcTrue, NULL, &result);
+    ffullname = match_fullname(library, priv, family);
+    if (!fsorted || !ffullname)
         goto error;
 
+    fset = FcFontSetCreate();
+    for (curf = 0; curf < ffullname->nfont; ++curf) {
+        FcPattern *curp = ffullname->fonts[curf];
+        FcPatternReference(curp);
+        FcFontSetAdd(fset, curp);
+    }
+    for (curf = 0; curf < fsorted->nfont; ++curf) {
+        FcPattern *curp = fsorted->fonts[curf];
+        FcPatternReference(curp);
+        FcFontSetAdd(fset, curp);
+    }
+
     for (curf = 0; curf < fset->nfont; ++curf) {
         FcPattern *curp = fset->fonts[curf];
 
@@ -159,7 +204,6 @@ static char *_select_font(ASS_Library *library, FCInstance *priv,
     if (curf >= fset->nfont)
         goto error;
 
-#if (FC_VERSION >= 20297)
     if (!treat_family_as_pattern) {
         // Remove all extra family names from original pattern.
         // After this, FcFontRenderPrepare will select the most relevant family
@@ -167,7 +211,6 @@ static char *_select_font(ASS_Library *library, FCInstance *priv,
         for (; family_cnt > 1; --family_cnt)
             FcPatternRemove(pat, FC_FAMILY, family_cnt - 1);
     }
-#endif
 
     rpat = FcFontRenderPrepare(priv->config, pat, fset->fonts[curf]);
     if (!rpat)
@@ -226,6 +269,10 @@ static char *_select_font(ASS_Library *library, FCInstance *priv,
         FcPatternDestroy(pat);
     if (rpat)
         FcPatternDestroy(rpat);
+    if (fsorted)
+        FcFontSetDestroy(fsorted);
+    if (ffullname)
+        FcFontSetDestroy(ffullname);
     if (fset)
         FcFontSetDestroy(fset);
     return retval;
@@ -250,15 +297,16 @@ char *fontconfig_select(ASS_Library *library, FCInstance *priv,
     char *res = 0;
     if (!priv->config) {
         *index = priv->index_default;
-        return priv->path_default;
+        res = priv->path_default ? strdup(priv->path_default) : 0;
+        return res;
     }
     if (family && *family)
         res =
-            _select_font(library, priv, family, treat_family_as_pattern,
+            select_font(library, priv, family, treat_family_as_pattern,
                          bold, italic, index, code);
     if (!res && priv->family_default) {
         res =
-            _select_font(library, priv, priv->family_default, 0, bold,
+            select_font(library, priv, priv->family_default, 0, bold,
                          italic, index, code);
         if (res)
             ass_msg(library, MSGL_WARN, "fontconfig_select: Using default "
@@ -266,14 +314,14 @@ char *fontconfig_select(ASS_Library *library, FCInstance *priv,
                     family, bold, italic, res, *index);
     }
     if (!res && priv->path_default) {
-        res = priv->path_default;
+        res = strdup(priv->path_default);
         *index = priv->index_default;
         ass_msg(library, MSGL_WARN, "fontconfig_select: Using default font: "
                 "(%s, %d, %d) -> %s, %d", family, bold, italic,
                 res, *index);
     }
     if (!res) {
-        res = _select_font(library, priv, "Arial", 0, bold, italic,
+        res = select_font(library, priv, "Arial", 0, bold, italic,
                            index, code);
         if (res)
             ass_msg(library, MSGL_WARN, "fontconfig_select: Using 'Arial' "
@@ -287,49 +335,14 @@ char *fontconfig_select(ASS_Library *library, FCInstance *priv,
     return res;
 }
 
-#if (FC_VERSION < 20402)
-static char *validate_fname(char *name)
-{
-    char *fname;
-    char *p;
-    char *q;
-    unsigned code;
-    int sz = strlen(name);
-
-    q = fname = malloc(sz + 1);
-    p = name;
-    while (*p) {
-        code = ass_utf8_get_char(&p);
-        if (code == 0)
-            break;
-        if ((code > 0x7F) ||
-            (code == '\\') ||
-            (code == '/') ||
-            (code == ':') ||
-            (code == '*') ||
-            (code == '?') ||
-            (code == '<') ||
-            (code == '>') || (code == '|') || (code == 0)) {
-            *q++ = '_';
-        } else {
-            *q++ = code;
-        }
-        if (p - name > sz)
-            break;
-    }
-    *q = 0;
-    return fname;
-}
-#endif
-
 /**
  * \brief Process memory font.
  * \param priv private data
  * \param library library object
  * \param ftlibrary freetype library object
  * \param idx index of the processed font in library->fontdata
- * With FontConfig >= 2.4.2, builds a font pattern in memory via FT_New_Memory_Face/FcFreeTypeQueryFace.
- * With older FontConfig versions, save the font to ~/.mplayer/fonts.
+ *
+ * Builds a font pattern in memory via FT_New_Memory_Face/FcFreeTypeQueryFace.
 */
 static void process_fontdata(FCInstance *priv, ASS_Library *library,
                              FT_Library ftlibrary, int idx)
@@ -339,44 +352,6 @@ static void process_fontdata(FCInstance *priv, ASS_Library *library,
     const char *data = library->fontdata[idx].data;
     int data_size = library->fontdata[idx].size;
 
-#if (FC_VERSION < 20402)
-    struct stat st;
-    char *fname;
-    const char *fonts_dir = library->fonts_dir;
-    char buf[1000];
-    FILE *fp = NULL;
-
-    if (!fonts_dir)
-        return;
-    rc = stat(fonts_dir, &st);
-    if (rc) {
-        int res;
-#ifndef __MINGW32__
-        res = mkdir(fonts_dir, 0700);
-#else
-        res = mkdir(fonts_dir);
-#endif
-        if (res) {
-            ass_msg(library, MSGL_WARN, "Failed to create directory '%s'",
-                    fonts_dir);
-        }
-    } else if (!S_ISDIR(st.st_mode)) {
-        ass_msg(library, MSGL_WARN, "Not a directory: '%s'", fonts_dir);
-    }
-
-    fname = validate_fname((char *) name);
-
-    snprintf(buf, 1000, "%s/%s", fonts_dir, fname);
-    free(fname);
-
-    fp = fopen(buf, "wb");
-    if (!fp)
-        return;
-
-    fwrite(data, data_size, 1, fp);
-    fclose(fp);
-
-#else                           // (FC_VERSION >= 20402)
     FT_Face face;
     FcPattern *pattern;
     FcFontSet *fset;
@@ -418,7 +393,6 @@ static void process_fontdata(FCInstance *priv, ASS_Library *library,
 
         FT_Done_Face(face);
     }
-#endif
 }
 
 /**
@@ -472,40 +446,7 @@ FCInstance *fontconfig_init(ASS_Library *library,
         process_fontdata(priv, library, ftlibrary, i);
 
     if (dir) {
-        if (FcDirCacheValid((const FcChar8 *) dir) == FcFalse) {
-            ass_msg(library, MSGL_INFO, "Updating font cache");
-            if (FcGetVersion() >= 20390 && FcGetVersion() < 20400)
-                ass_msg(library, MSGL_WARN, "Beta versions of fontconfig"
-                        "are not supported. Update before reporting any bugs");
-            // 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) {
-                    ass_msg(library, MSGL_WARN, "%s failed", "FcStrSetAdd");
-                    goto ErrorFontCache;
-                }
-
-                rc = FcDirScan(fcs, fss, NULL,
-                               FcConfigGetBlanks(priv->config),
-                               (const FcChar8 *) dir, FcFalse);
-                if (!rc) {
-                    ass_msg(library, MSGL_WARN, "%s failed", "FcDirScan");
-                    goto ErrorFontCache;
-                }
-
-                rc = FcDirSave(fcs, fss, (const FcChar8 *) dir);
-                if (!rc) {
-                    ass_msg(library, MSGL_WARN, "%s failed", "FcDirSave");
-                    goto ErrorFontCache;
-                }
-              ErrorFontCache:
-                ;
-            }
-        }
+        ass_msg(library, MSGL_V, "Updating font cache");
 
         rc = FcConfigAppFontAddDir(priv->config, (const FcChar8 *) dir);
         if (!rc) {
@@ -534,7 +475,8 @@ char *fontconfig_select(ASS_Library *library, FCInstance *priv,
                         uint32_t code)
 {
     *index = priv->index_default;
-    return priv->path_default;
+    char* res = priv->path_default ? strdup(priv->path_default) : 0;
+    return res;
 }
 
 FCInstance *fontconfig_init(ASS_Library *library,
@@ -549,7 +491,7 @@ FCInstance *fontconfig_init(ASS_Library *library,
 
     priv = calloc(1, sizeof(FCInstance));
 
-    priv->path_default = strdup(path);
+    priv->path_default = path ? strdup(path) : 0;
     priv->index_default = 0;
     return priv;
 }
diff --git a/libass/ass_parse.c b/libass/ass_parse.c
index 535e16f..e5d1b16 100644
--- a/libass/ass_parse.c
+++ b/libass/ass_parse.c
@@ -123,15 +123,9 @@ void change_border(ASS_Renderer *render_priv, double border_x,
     if (bord > 0 && border_x == border_y) {
         if (!render_priv->state.stroker) {
             int error;
-#if (FREETYPE_MAJOR > 2) || ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR > 1))
             error =
                 FT_Stroker_New(render_priv->ftlibrary,
                                &render_priv->state.stroker);
-#else                           // < 2.2
-            error =
-                FT_Stroker_New(render_priv->state.font->faces[0]->
-                               memory, &render_priv->state.stroker);
-#endif
             if (error) {
                 ass_msg(render_priv->library, MSGL_V,
                         "failed to get stroker");
@@ -164,7 +158,7 @@ inline void change_alpha(uint32_t *var, uint32_t new, double pwr)
 {
     *var =
         (_r(*var) << 24) + (_g(*var) << 16) + (_b(*var) << 8) +
-        (_a(*var) * (1 - pwr) + _a(new) * pwr);
+        (uint32_t) (_a(*var) * (1 - pwr) + _a(new) * pwr);
 }
 
 /**
@@ -233,20 +227,20 @@ static char *parse_vector_clip(ASS_Renderer *render_priv, char *p)
     while (*p != ')' && *p != '}' && p != 0)
         ass_drawing_add_char(drawing, *p++);
     skipopt(')');
-    ass_drawing_parse(drawing, 1);
-
-    // We need to translate the clip according to screen borders
-    if (render_priv->settings.left_margin != 0 ||
-        render_priv->settings.top_margin != 0) {
-        FT_Vector trans = {
-            .x = int_to_d6(render_priv->settings.left_margin),
-            .y = -int_to_d6(render_priv->settings.top_margin),
-        };
-        FT_Outline_Translate(&drawing->glyph->outline, trans.x, trans.y);
+    if (ass_drawing_parse(drawing, 1)) {
+        // We need to translate the clip according to screen borders
+        if (render_priv->settings.left_margin != 0 ||
+            render_priv->settings.top_margin != 0) {
+            FT_Vector trans = {
+                .x = int_to_d6(render_priv->settings.left_margin),
+                .y = -int_to_d6(render_priv->settings.top_margin),
+            };
+            FT_Outline_Translate(&drawing->glyph->outline, trans.x, trans.y);
+        }
+        ass_msg(render_priv->library, MSGL_DBG2,
+                "Parsed vector clip: scale %d, scales (%f, %f) string [%s]\n",
+                scale, drawing->scale_x, drawing->scale_y, drawing->text);
     }
-    ass_msg(render_priv->library, MSGL_DBG2,
-            "Parsed vector clip: scale %d, scales (%f, %f) string [%s]\n",
-            scale, drawing->scale_x, drawing->scale_y, drawing->text);
 
     return p;
 }
@@ -592,7 +586,7 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         for (cnt = 0; cnt < 3; ++cnt) {
             if (*p == '\\')
                 break;
-            v[cnt] = strtod(p, &p);
+            mystrtod(&p, &v[cnt]);
             skip(',');
         }
         if (cnt == 3) {
diff --git a/libass/ass_render.c b/libass/ass_render.c
index c2756fd..64e78a9 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -123,9 +123,11 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
         calloc(MAX_GLYPHS_INITIAL, sizeof(GlyphInfo));
     priv->text_info.lines = calloc(MAX_LINES_INITIAL, sizeof(LineInfo));
 
+    priv->settings.font_size_coeff = 1.;
+
   ass_init_exit:
     if (priv)
-        ass_msg(library, MSGL_INFO, "Init");
+        ass_msg(library, MSGL_V, "Init");
     else
         ass_msg(library, MSGL_ERR, "Init failed");
 
@@ -538,7 +540,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv,
     FT_Glyph_Copy((FT_Glyph) drawing->glyph, &glyph);
     error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
     if (error) {
-        ass_msg(render_priv->library, MSGL_V,
+        ass_msg(render_priv->library, MSGL_WARN,
             "Clip vector rasterization failed: %d. Skipping.", error);
         goto blend_vector_exit;
     }
@@ -871,6 +873,7 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event)
     render_priv->state.clip_y0 = 0;
     render_priv->state.clip_x1 = render_priv->track->PlayResX;
     render_priv->state.clip_y1 = render_priv->track->PlayResY;
+    render_priv->state.clip_mode = 0;
     render_priv->state.detect_collisions = 1;
     render_priv->state.fade = 0;
     render_priv->state.drawing_mode = 0;
@@ -1132,7 +1135,8 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info,
     } else {
         GlyphHashValue v;
         if (drawing->hash) {
-            ass_drawing_parse(drawing, 0);
+            if(!ass_drawing_parse(drawing, 0))
+                return;
             FT_Glyph_Copy((FT_Glyph) drawing->glyph, &info->glyph);
         } else {
             info->glyph =
@@ -1156,8 +1160,9 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info,
                                          render_priv->border_scale),
                             double_to_d6(render_priv->state.border_y *
                                          render_priv->border_scale));
-        } else if (render_priv->state.border_x > 0 ||
-                   render_priv->state.border_y > 0) {
+        } else if ((render_priv->state.border_x > 0
+                    || render_priv->state.border_y > 0)
+                   && key.scale_x && key.scale_y) {
 
             FT_Glyph_Copy(info->glyph, &info->outline_glyph);
             stroke_outline_glyph(render_priv,
@@ -1905,23 +1910,23 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
                 drawing->hash;
         text_info->glyphs[text_info->length].hash_key.ch = code;
         text_info->glyphs[text_info->length].hash_key.outline.x =
-            render_priv->state.border_x * 0xFFFF;
+            double_to_d16(render_priv->state.border_x);
         text_info->glyphs[text_info->length].hash_key.outline.y =
-            render_priv->state.border_y * 0xFFFF;
+            double_to_d16(render_priv->state.border_y);
         text_info->glyphs[text_info->length].hash_key.scale_x =
-            render_priv->state.scale_x * 0xFFFF;
+            double_to_d16(render_priv->state.scale_x);
         text_info->glyphs[text_info->length].hash_key.scale_y =
-            render_priv->state.scale_y * 0xFFFF;
+            double_to_d16(render_priv->state.scale_y);
         text_info->glyphs[text_info->length].hash_key.frx =
-            render_priv->state.frx * 0xFFFF;
+            rot_key(render_priv->state.frx);
         text_info->glyphs[text_info->length].hash_key.fry =
-            render_priv->state.fry * 0xFFFF;
+            rot_key(render_priv->state.fry);
         text_info->glyphs[text_info->length].hash_key.frz =
-            render_priv->state.frz * 0xFFFF;
+            rot_key(render_priv->state.frz);
         text_info->glyphs[text_info->length].hash_key.fax =
-            render_priv->state.fax * 0xFFFF;
+            double_to_d16(render_priv->state.fax);
         text_info->glyphs[text_info->length].hash_key.fay =
-            render_priv->state.fay * 0xFFFF;
+            double_to_d16(render_priv->state.fay);
         text_info->glyphs[text_info->length].hash_key.advance.x = pen.x;
         text_info->glyphs[text_info->length].hash_key.advance.y = pen.y;
         text_info->glyphs[text_info->length].hash_key.be =
@@ -2070,7 +2075,7 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
             double scr_y;
             if (valign != VALIGN_SUB)
                 ass_msg(render_priv->library, MSGL_V,
-                       "Invalid valign, supposing 0 (subtitle)");
+                       "Invalid valign, assuming 0 (subtitle)");
             scr_y =
                 y2scr_sub(render_priv,
                           render_priv->track->PlayResY - MarginV);
@@ -2209,6 +2214,8 @@ static void ass_free_images(ASS_Image *img)
 
 static void ass_reconfigure(ASS_Renderer *priv)
 {
+    ASS_Settings *settings = &priv->settings;
+
     priv->render_id++;
     priv->cache.glyph_cache =
         ass_glyph_cache_reset(priv->cache.glyph_cache);
@@ -2218,6 +2225,19 @@ static void ass_reconfigure(ASS_Renderer *priv)
         ass_composite_cache_reset(priv->cache.composite_cache);
     ass_free_images(priv->prev_images_root);
     priv->prev_images_root = 0;
+
+    priv->width = settings->frame_width;
+    priv->height = settings->frame_height;
+    priv->orig_width = settings->frame_width - settings->left_margin -
+        settings->right_margin;
+    priv->orig_height = settings->frame_height - settings->top_margin -
+        settings->bottom_margin;
+    priv->orig_width_nocrop =
+        settings->frame_width - FFMAX(settings->left_margin, 0) -
+        FFMAX(settings->right_margin, 0);
+    priv->orig_height_nocrop =
+        settings->frame_height - FFMAX(settings->top_margin, 0) -
+        FFMAX(settings->bottom_margin, 0);
 }
 
 void ass_set_frame_size(ASS_Renderer *priv, int w, int h)
@@ -2321,27 +2341,14 @@ ass_start_frame(ASS_Renderer *render_priv, ASS_Track *track,
     if (render_priv->library != track->library)
         return 1;
 
+    if (!render_priv->fontconfig_priv)
+        return 1;
+
     free_list_clear(render_priv);
 
     if (track->n_events == 0)
         return 1;               // nothing to do
 
-    render_priv->width = settings_priv->frame_width;
-    render_priv->height = settings_priv->frame_height;
-    render_priv->orig_width =
-        settings_priv->frame_width - settings_priv->left_margin -
-        settings_priv->right_margin;
-    render_priv->orig_height =
-        settings_priv->frame_height - settings_priv->top_margin -
-        settings_priv->bottom_margin;
-    render_priv->orig_width_nocrop =
-        settings_priv->frame_width - FFMAX(settings_priv->left_margin,
-                                           0) -
-        FFMAX(settings_priv->right_margin, 0);
-    render_priv->orig_height_nocrop =
-        settings_priv->frame_height - FFMAX(settings_priv->top_margin,
-                                            0) -
-        FFMAX(settings_priv->bottom_margin, 0);
     render_priv->track = track;
     render_priv->time = now;
 
@@ -2503,7 +2510,7 @@ fix_collisions(ASS_Renderer *render_priv, EventImages *imgs, int cnt)
             s.hb = priv->left + priv->width;
             if (priv->height != imgs[i].height) {       // no, it's not
                 ass_msg(render_priv->library, MSGL_WARN,
-                        "Warning! Event height has changed");
+                        "Event height has changed");
                 priv->top = 0;
                 priv->height = 0;
                 priv->left = 0;
diff --git a/libass/ass_strtod.c b/libass/ass_strtod.c
new file mode 100644
index 0000000..f55b37a
--- /dev/null
+++ b/libass/ass_strtod.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 1988-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies.  The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without
+ * express or implied warranty.
+ *
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+
+const
+static int maxExponent = 511;   /* Largest possible base 10 exponent.  Any
+                                 * exponent larger than this will already
+                                 * produce underflow or overflow, so there's
+                                 * no need to worry about additional digits.
+                                 */
+
+const
+static double powersOf10[] = {  /* Table giving binary powers of 10.  Entry */
+    10.,                        /* is 10^2^i.  Used to convert decimal */
+    100.,                       /* exponents into floating-point numbers. */
+    1.0e4,
+    1.0e8,
+    1.0e16,
+    1.0e32,
+    1.0e64,
+    1.0e128,
+    1.0e256
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strtod --
+ *
+ * This procedure converts a floating-point number from an ASCII
+ * decimal representation to internal double-precision format.
+ *
+ * Results:
+ * The return value is the double-precision floating-point
+ * representation of the characters in string.  If endPtr isn't
+ * NULL, then *endPtr is filled in with the address of the
+ * next character after the last one that was part of the
+ * floating-point number.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+double
+ass_strtod(string, endPtr)
+    const char *string;     /* A decimal ASCII floating-point number,
+                             * optionally preceded by white space.
+                             * Must have form "-I.FE-X", where I is the
+                             * integer part of the mantissa, F is the
+                             * fractional part of the mantissa, and X
+                             * is the exponent.  Either of the signs
+                             * may be "+", "-", or omitted.  Either I
+                             * or F may be omitted, or both.  The decimal
+                             * point isn't necessary unless F is present.
+                             * The "E" may actually be an "e".  E and X
+                             * may both be omitted (but not just one).
+                             */
+    char **endPtr;          /* If non-NULL, store terminating character's
+                             * address here. */
+{
+    int sign, expSign = 0;
+    double fraction, dblExp, *d;
+    register const char *p;
+    register int c;
+    int exp = 0;            /* Exponent read from "EX" field. */
+    int fracExp = 0;        /* Exponent that derives from the fractional
+                             * part.  Under normal circumstatnces, it is
+                             * the negative of the number of digits in F.
+                             * However, if I is very long, the last digits
+                             * of I get dropped (otherwise a long I with a
+                             * large negative exponent could cause an
+                             * unnecessary overflow on I alone).  In this
+                             * case, fracExp is incremented one for each
+                             * dropped digit. */
+    int mantSize;       /* Number of digits in mantissa. */
+    int decPt;          /* Number of mantissa digits BEFORE decimal
+                         * point. */
+    const char *pExp;       /* Temporarily holds location of exponent
+                             * in string. */
+
+    /*
+     * Strip off leading blanks and check for a sign.
+     */
+
+    p = string;
+    while (isspace(*p)) {
+        p += 1;
+    }
+    if (*p == '-') {
+        sign = 1;
+        p += 1;
+    } else {
+        if (*p == '+') {
+            p += 1;
+        }
+        sign = 0;
+    }
+
+    /*
+     * Count the number of digits in the mantissa (including the decimal
+     * point), and also locate the decimal point.
+     */
+
+    decPt = -1;
+    for (mantSize = 0; ; mantSize += 1)
+    {
+        c = *p;
+        if (!isdigit(c)) {
+            if ((c != '.') || (decPt >= 0)) {
+                break;
+            }
+            decPt = mantSize;
+        }
+        p += 1;
+    }
+
+    /*
+     * Now suck up the digits in the mantissa.  Use two integers to
+     * collect 9 digits each (this is faster than using floating-point).
+     * If the mantissa has more than 18 digits, ignore the extras, since
+     * they can't affect the value anyway.
+     */
+
+    pExp  = p;
+    p -= mantSize;
+    if (decPt < 0) {
+        decPt = mantSize;
+    } else {
+        mantSize -= 1;      /* One of the digits was the point. */
+    }
+    if (mantSize > 18) {
+        fracExp = decPt - 18;
+        mantSize = 18;
+    } else {
+        fracExp = decPt - mantSize;
+    }
+    if (mantSize == 0) {
+        fraction = 0.0;
+        p = string;
+        goto done;
+    } else {
+        int frac1, frac2;
+        frac1 = 0;
+        for ( ; mantSize > 9; mantSize -= 1)
+        {
+            c = *p;
+            p += 1;
+            if (c == '.') {
+                c = *p;
+                p += 1;
+            }
+            frac1 = 10*frac1 + (c - '0');
+        }
+        frac2 = 0;
+        for (; mantSize > 0; mantSize -= 1)
+        {
+            c = *p;
+            p += 1;
+            if (c == '.') {
+                c = *p;
+                p += 1;
+            }
+            frac2 = 10*frac2 + (c - '0');
+        }
+        fraction = (1.0e9 * frac1) + frac2;
+    }
+
+    /*
+     * Skim off the exponent.
+     */
+
+    p = pExp;
+    if ((*p == 'E') || (*p == 'e')) {
+        p += 1;
+        if (*p == '-') {
+            expSign = 1;
+            p += 1;
+        } else {
+            if (*p == '+') {
+                p += 1;
+            }
+            expSign = 0;
+        }
+        while (isdigit(*p)) {
+            exp = exp * 10 + (*p - '0');
+            p += 1;
+        }
+    }
+    if (expSign) {
+        exp = fracExp - exp;
+    } else {
+        exp = fracExp + exp;
+    }
+
+    /*
+     * Generate a floating-point number that represents the exponent.
+     * Do this by processing the exponent one bit at a time to combine
+     * many powers of 2 of 10. Then combine the exponent with the
+     * fraction.
+     */
+
+    if (exp < 0) {
+        expSign = 1;
+        exp = -exp;
+    } else {
+        expSign = 0;
+    }
+    if (exp > maxExponent) {
+        exp = maxExponent;
+        errno = ERANGE;
+    }
+    dblExp = 1.0;
+    for (d = (double *) powersOf10; exp != 0; exp >>= 1, d += 1) {
+        if (exp & 01) {
+            dblExp *= *d;
+        }
+    }
+    if (expSign) {
+        fraction /= dblExp;
+    } else {
+        fraction *= dblExp;
+    }
+
+done:
+    if (endPtr != NULL) {
+        *endPtr = (char *) p;
+    }
+
+    if (sign) {
+        return -fraction;
+    }
+    return fraction;
+}
diff --git a/libass/ass_utils.c b/libass/ass_utils.c
index 6ca78b8..59fdbdf 100644
--- a/libass/ass_utils.c
+++ b/libass/ass_utils.c
@@ -34,7 +34,7 @@ int mystrtoi(char **p, int *res)
 {
     double temp_res;
     char *start = *p;
-    temp_res = strtod(*p, p);
+    temp_res = ass_strtod(*p, p);
     *res = (int) (temp_res + (temp_res > 0 ? 0.5 : -0.5));
     if (*p != start)
         return 1;
@@ -46,7 +46,7 @@ int mystrtoll(char **p, long long *res)
 {
     double temp_res;
     char *start = *p;
-    temp_res = strtod(*p, p);
+    temp_res = ass_strtod(*p, p);
     *res = (int) (temp_res + (temp_res > 0 ? 0.5 : -0.5));
     if (*p != start)
         return 1;
@@ -67,7 +67,7 @@ int mystrtou32(char **p, int base, uint32_t *res)
 int mystrtod(char **p, double *res)
 {
     char *start = *p;
-    *res = strtod(*p, p);
+    *res = ass_strtod(*p, p);
     if (*p != start)
         return 1;
     else
diff --git a/libass/ass_utils.h b/libass/ass_utils.h
index bade578..ad8574c 100644
--- a/libass/ass_utils.h
+++ b/libass/ass_utils.h
@@ -59,6 +59,9 @@ void *ass_guess_buffer_cp(ASS_Library *library, unsigned char *buffer,
                           char *fallback);
 #endif
 
+/* defined in ass_strtod.c */
+double ass_strtod(const char *string, char **endPtr);
+
 static inline int d6_to_int(int x)
 {
     return (x + 32) >> 6;
@@ -99,6 +102,21 @@ static inline int double_to_d16(double x)
 {
     return (int) (x * 0x10000);
 }
+static inline double d22_to_double(int x)
+{
+    return ((double) x) / 0x400000;
+}
+static inline int double_to_d22(double x)
+{
+    return (int) (x * 0x400000);
+}
+
+// Calculate cache key for a rotational angle in degrees
+static inline int rot_key(double a)
+{
+    const int m = double_to_d22(360.0);
+    return double_to_d22(a) % m;
+}
 
 #define FNV1_32A_INIT (unsigned)0x811c9dc5
 
diff --git a/test/test.c b/test/test.c
index fbe4caa..e2a88d1 100644
--- a/test/test.c
+++ b/test/test.c
@@ -78,9 +78,6 @@ static void init(int frame_w, int frame_h)
         exit(1);
     }
 
-    ass_set_fonts_dir(ass_library, "");
-    ass_set_extract_fonts(ass_library, 0);
-    ass_set_style_overrides(ass_library, NULL);
     ass_set_message_cb(ass_library, msg_callback, NULL);
 
     ass_renderer = ass_renderer_init(ass_library);
@@ -90,9 +87,6 @@ static void init(int frame_w, int frame_h)
     }
 
     ass_set_frame_size(ass_renderer, frame_w, frame_h);
-    ass_set_margins(ass_renderer, 0, 0, 0, 0);
-    ass_set_use_margins(ass_renderer, 0);
-    ass_set_font_scale(ass_renderer, 1.);
     ass_set_fonts(ass_renderer, NULL, "Sans", 1, NULL, 1);
 }
 

-- 
LibASS packaging



More information about the pkg-multimedia-commits mailing list