changeset 20477:de4a66d99f41

Libass interface reworked: - ass_instance_t renamed to ass_renderer_t - ass_library_t introduced - use of mplayer-specific global variables limited to ass_mp.c
author eugeni
date Sat, 28 Oct 2006 15:07:18 +0000
parents 1fd76553550d
children c8bc7d300bb3
files libass/Makefile libass/ass.c libass/ass.h libass/ass_library.c libass/ass_library.h libass/ass_mp.c libass/ass_mp.h libass/ass_render.c libass/ass_types.h libmpcodecs/vf_ass.c libmpcodecs/vf_vo.c libmpdemux/demux_mkv.c mplayer.c
diffstat 13 files changed, 261 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/libass/Makefile	Sat Oct 28 14:20:15 2006 +0000
+++ b/libass/Makefile	Sat Oct 28 15:07:18 2006 +0000
@@ -5,7 +5,7 @@
 
 LIBS=$(LIBNAME)
 
-SRCS=ass.c ass_cache.c ass_fontconfig.c ass_render.c ass_utils.c ass_mp.c ass_bitmap.c
+SRCS=ass.c ass_cache.c ass_fontconfig.c ass_render.c ass_utils.c ass_mp.c ass_bitmap.c ass_library.c
 
 OBJS=$(SRCS:.c=.o)
 
--- a/libass/ass.c	Sat Oct 28 14:20:15 2006 +0000
+++ b/libass/ass.c	Sat Oct 28 15:07:18 2006 +0000
@@ -36,18 +36,14 @@
 
 #ifdef USE_ICONV
 #include <iconv.h>
-extern char *sub_cp;
 #endif
-extern int extract_embedded_fonts;
-extern char** ass_force_style_list;
 
 #include "mp_msg.h"
 #include "ass.h"
 #include "ass_utils.h"
+#include "ass_library.h"
 #include "libvo/sub.h" // for utf8_get_char
 
-char *get_path(char *);
-
 typedef enum {PST_UNKNOWN = 0, PST_INFO, PST_STYLES, PST_EVENTS, PST_FONTS} parser_state_t;
 
 struct parser_priv_s {
@@ -327,10 +323,11 @@
 	char **fs, *eq, *dt, *style, *tname, *token;
 	ass_style_t* target;
 	int sid;
+	char** list = track->library->style_overrides;
 	
-	if (!ass_force_style_list) return;
+	if (!list) return;
 	
-	for (fs = ass_force_style_list; *fs; ++fs) {
+	for (fs = list; *fs; ++fs) {
 		eq = strchr(*fs, '=');
 		if (!eq)
 			continue;
@@ -577,8 +574,8 @@
 	dsize = q - buf;
 	assert(dsize <= size / 4 * 3 + 2);
 	
-	if (extract_embedded_fonts)
-		ass_process_font(track->parser_priv->fontname, (char*)buf, dsize);
+	if (track->library->extract_fonts)
+		ass_process_font(track->library, track->parser_priv->fontname, (char*)buf, dsize);
 
 error_decode_font:
 	if (buf) free(buf);
@@ -795,24 +792,24 @@
 
 #ifdef USE_ICONV
 /** \brief recode buffer to utf-8
- * constraint: sub_cp != 0
+ * constraint: codepage != 0
  * \param data pointer to text buffer
  * \param size buffer size
  * \return a pointer to recoded buffer, caller is responsible for freeing it
 **/
-static char* sub_recode(char* data, size_t size)
+static char* sub_recode(char* data, size_t size, char* codepage)
 {
 	static iconv_t icdsc = (iconv_t)(-1);
 	char* tocp = "UTF-8";
 	char* outbuf;
-	assert(sub_cp);
+	assert(codepage);
 
 	{
-		char* cp_tmp = sub_cp;
+		char* cp_tmp = codepage;
 #ifdef HAVE_ENCA
 		char enca_lang[3], enca_fallback[100];
-		if (sscanf(sub_cp, "enca:%2s:%99s", enca_lang, enca_fallback) == 2
-				|| sscanf(sub_cp, "ENCA:%2s:%99s", enca_lang, enca_fallback) == 2) {
+		if (sscanf(codepage, "enca:%2s:%99s", enca_lang, enca_fallback) == 2
+				|| sscanf(codepage, "ENCA:%2s:%99s", enca_lang, enca_fallback) == 2) {
 			cp_tmp = guess_buffer_cp((unsigned char*)data, size, enca_lang, enca_fallback);
 		}
 #endif
@@ -868,7 +865,7 @@
 /**
  * \brief read file contents into newly allocated buffer, recoding to utf-8
  */
-static char* read_file(char* fname)
+static char* read_file(char* fname, char* codepage)
 {
 	int res;
 	long sz;
@@ -915,8 +912,8 @@
 	fclose(fp);
 	
 #ifdef USE_ICONV
-	if (sub_cp) {
-		char* tmpbuf = sub_recode(buf, sz);
+	if (codepage) {
+		char* tmpbuf = sub_recode(buf, sz, codepage);
 		free(buf);
 		buf = tmpbuf;
 	}
@@ -929,17 +926,17 @@
  * \param fname file name
  * \return newly allocated track
 */ 
-ass_track_t* ass_read_file(char* fname)
+ass_track_t* ass_read_file(ass_library_t* library, char* fname, char* codepage)
 {
 	char* buf;
 	ass_track_t* track;
 	int i;
 	
-	buf = read_file(fname);
+	buf = read_file(fname, codepage);
 	if (!buf)
 		return 0;
 	
-	track = ass_new_track();
+	track = ass_new_track(library);
 	track->name = strdup(fname);
 	
 	// process header
@@ -971,12 +968,12 @@
 /**
  * \brief read styles from file into already initialized track
  */
-int ass_read_styles(ass_track_t* track, char* fname)
+int ass_read_styles(ass_track_t* track, char* fname, char* codepage)
 {
 	char* buf;
 	parser_state_t old_state;
 
-	buf = read_file(fname);
+	buf = read_file(fname, codepage);
 	if (!buf)
 		return 1;
 
@@ -1030,15 +1027,17 @@
  * \param data binary font data
  * \param data_size data size
 */ 
-void ass_process_font(const char* name, char* data, int data_size)
+void ass_process_font(ass_library_t* library, const char* name, char* data, int data_size)
 {
 	char buf[1000];
 	FILE* fp = 0;
 	int rc;
 	struct stat st;
 	char* fname;
+	const char* fonts_dir = library->fonts_dir;
 
-	char* fonts_dir = get_path("fonts");
+	if (!fonts_dir)
+		return;
 	rc = stat(fonts_dir, &st);
 	if (rc) {
 		int res;
@@ -1058,7 +1057,6 @@
 
 	snprintf(buf, 1000, "%s/%s", fonts_dir, fname);
 	free(fname);
-	free(fonts_dir);
 
 	fp = fopen(buf, "wb");
 	if (!fp) return;
@@ -1086,8 +1084,9 @@
 	return ((long long)track->events[i].Start) - now;
 }
 
-ass_track_t* ass_new_track(void) {
+ass_track_t* ass_new_track(ass_library_t* library) {
 	ass_track_t* track = calloc(1, sizeof(ass_track_t));
+	track->library = library;
 	track->parser_priv = calloc(1, sizeof(parser_priv_t));
 	return track;
 }
--- a/libass/ass.h	Sat Oct 28 14:20:15 2006 +0000
+++ b/libass/ass.h	Sat Oct 28 15:07:18 2006 +0000
@@ -23,8 +23,8 @@
 
 #include "ass_types.h"
 
-/// Libass "library object". Contents are private.
-typedef struct ass_instance_s ass_instance_t;
+/// Libass renderer object. Contents are private.
+typedef struct ass_renderer_s ass_renderer_t;
 
 /// a linked list of images produced by ass renderer
 typedef struct ass_image_s {
@@ -41,20 +41,47 @@
  * \brief initialize the library
  * \return library handle or NULL if failed
  */
-ass_instance_t* ass_init(void);
+ass_library_t* ass_library_init(void);
 
 /**
  * \brief finalize the library
  * \param priv library handle
  */
-void ass_done(ass_instance_t* priv);
+void ass_library_done(ass_library_t*);
+
+/**
+ * \brief set private font directory
+ * It is used for saving embedded fonts and also in font lookup.
+ */
+void ass_set_fonts_dir(ass_library_t* priv, const char* fonts_dir);
+
+void ass_set_extract_fonts(ass_library_t* priv, int extract);
+
+void ass_set_style_overrides(ass_library_t* priv, char** list);
 
-void ass_set_frame_size(ass_instance_t* priv, int w, int h);
-void ass_set_margins(ass_instance_t* priv, int t, int b, int l, int r);
-void ass_set_use_margins(ass_instance_t* priv, int use);
-void ass_set_aspect_ratio(ass_instance_t* priv, double ar);
-void ass_set_font_scale(ass_instance_t* priv, double font_scale);
-int  ass_set_fonts(ass_instance_t* priv, const char* fonts_dir, const char* default_font, const char* default_family);
+/**
+ * \brief initialize the renderer
+ * \param priv library handle
+ * \return renderer handle or NULL if failed
+ */
+ass_renderer_t* ass_renderer_init(ass_library_t*);
+
+/**
+ * \brief finalize the renderer
+ * \param priv renderer handle
+ */
+void ass_renderer_done(ass_renderer_t* priv);
+
+void ass_set_frame_size(ass_renderer_t* priv, int w, int h);
+void ass_set_margins(ass_renderer_t* priv, int t, int b, int l, int r);
+void ass_set_use_margins(ass_renderer_t* priv, int use);
+void ass_set_aspect_ratio(ass_renderer_t* priv, double ar);
+void ass_set_font_scale(ass_renderer_t* priv, double font_scale);
+
+/**
+ * \brief set font lookup defaults
+ */
+int  ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* default_family);
 
 /**
  * \brief render a frame, producing a list of ass_image_t
@@ -62,16 +89,16 @@
  * \param track subtitle track
  * \param now video timestamp in milliseconds
  */
-ass_image_t* ass_render_frame(ass_instance_t *priv, ass_track_t* track, long long now);
+ass_image_t* ass_render_frame(ass_renderer_t *priv, ass_track_t* track, long long now);
 
 
-// The following functions operate on track objects and do not need an ass_instance //
+// The following functions operate on track objects and do not need an ass_renderer //
 
 /**
  * \brief allocate a new empty track object
  * \return pointer to empty track
  */
-ass_track_t* ass_new_track(void);
+ass_track_t* ass_new_track(ass_library_t*);
 
 /**
  * \brief deallocate track and all its child objects (styles and events)
@@ -132,13 +159,13 @@
  * \param fname file name
  * \return newly allocated track
 */
-ass_track_t* ass_read_file(char* fname);
+ass_track_t* ass_read_file(ass_library_t* library, char* fname, char* codepage);
 
 /**
  * \brief read styles from file into already initialized track
  * \return 0 on success
  */
-int ass_read_styles(ass_track_t* track, char* fname);
+int ass_read_styles(ass_track_t* track, char* fname, char* codepage);
 
 /**
  * \brief Process embedded matroska font. Saves it to ~/.mplayer/fonts.
@@ -146,7 +173,7 @@
  * \param data binary font data
  * \param data_size data size
 */
-void ass_process_font(const char* name, char* data, int data_size);
+void ass_process_font(ass_library_t* library, const char* name, char* data, int data_size);
 
 /**
  * \brief Calculates timeshift from now to the start of some other subtitle event, depending on movement parameter
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libass/ass_library.c	Sat Oct 28 15:07:18 2006 +0000
@@ -0,0 +1,72 @@
+// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
+// vim:ts=8:sw=8:noet:ai:
+/*
+  Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
+
+  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
+*/
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ass.h"
+#include "ass_library.h"
+
+
+ass_library_t* ass_library_init(void)
+{
+	return calloc(1, sizeof(ass_library_t));
+}
+
+void ass_library_done(ass_library_t* priv)
+{
+	if (priv) free(priv);
+}
+
+void ass_set_fonts_dir(ass_library_t* priv, const char* fonts_dir)
+{
+	if (priv->fonts_dir)
+		free(priv->fonts_dir);
+
+	priv->fonts_dir = fonts_dir ? strdup(fonts_dir) : 0;
+}
+
+void ass_set_extract_fonts(ass_library_t* priv, int extract)
+{
+	priv->extract_fonts = !!extract;
+}
+
+void ass_set_style_overrides(ass_library_t* priv, char** list)
+{
+	char** p;
+	char** q;
+	int cnt;
+	
+	if (priv->style_overrides) {
+		for (p = priv->style_overrides; *p; ++p)
+			free(*p);
+		free(priv->style_overrides);
+	}
+	
+	if (!list) return;
+
+	for (p = list, cnt = 0; *p; ++p, ++cnt) {}
+
+	priv->style_overrides = malloc(cnt * sizeof(char*));
+	for (p = list, q = priv->style_overrides; *p; ++p, ++q)
+		*q = strdup(*p);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libass/ass_library.h	Sat Oct 28 15:07:18 2006 +0000
@@ -0,0 +1,31 @@
+// -*- c-basic-offset: 8; indent-tabs-mode: t -*-
+// vim:ts=8:sw=8:noet:ai:
+/*
+  Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com>
+
+  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
+*/
+
+#ifndef __ASS_LIBRARY_H__
+#define __ASS_LIBRARY_H__
+
+struct ass_library_s {
+	char* fonts_dir;
+	int extract_fonts;
+	char** style_overrides;
+};
+
+#endif
+
--- a/libass/ass_mp.c	Sat Oct 28 14:20:15 2006 +0000
+++ b/libass/ass_mp.c	Sat Oct 28 15:07:18 2006 +0000
@@ -27,8 +27,10 @@
 #include "ass.h"
 #include "ass_utils.h"
 #include "ass_mp.h"
+#include "ass_library.h"
 
 // libass-related command line options
+ass_library_t* ass_library;
 int ass_enabled = 0;
 float ass_font_scale = 1.;
 float ass_line_spacing = 0.;
@@ -50,11 +52,17 @@
 extern float text_font_scale_factor;
 extern int subtitle_autoscale;
 
+#ifdef USE_ICONV
+extern char* sub_cp;
+#else
+static char* sub_cp = 0;
+#endif
+
 extern double ass_internal_font_size_coeff; 
 extern void process_force_style(ass_track_t* track);
 
-ass_track_t* ass_default_track() {
-	ass_track_t* track = ass_new_track();
+ass_track_t* ass_default_track(ass_library_t* library) {
+	ass_track_t* track = ass_new_track(library);
 
 	track->track_type = TRACK_TYPE_ASS;
 	track->Timer = 100.;
@@ -63,7 +71,7 @@
 	track->WrapStyle = 0;
 
 	if (ass_styles_file)
-		ass_read_styles(track, ass_styles_file);
+		ass_read_styles(track, ass_styles_file, sub_cp);
 
 	if (track->n_styles == 0) {
 		ass_style_t* style;
@@ -182,11 +190,11 @@
  * \param fps video framerate
  * \return newly allocated ass_track, filled with subtitles from subdata
  */
-ass_track_t* ass_read_subdata(sub_data* subdata, double fps) {
+ass_track_t* ass_read_subdata(ass_library_t* library, sub_data* subdata, double fps) {
 	ass_track_t* track;
 	int i;
 
-	track = ass_default_track();
+	track = ass_default_track(library);
 	track->name = subdata->filename ? strdup(subdata->filename) : 0;
 
 	for (i = 0; i < subdata->sub_num; ++i) {
@@ -203,9 +211,7 @@
 
 char *get_path(char *);
 
-extern char *font_name;
-
-void ass_configure(ass_instance_t* priv, int w, int h) {
+void ass_configure(ass_renderer_t* priv, int w, int h) {
 	char *dir, *path, *family;
 	ass_set_frame_size(priv, w, h);
 	ass_set_margins(priv, ass_top_margin, ass_bottom_margin, 0, 0);
@@ -218,7 +224,7 @@
 	if (font_fontconfig && font_name) family = strdup(font_name);
 	else family = 0;
 
-	ass_set_fonts(priv, dir, path, family);
+	ass_set_fonts(priv, path, family);
 
 	free(dir);
 	free(path);
--- a/libass/ass_mp.h	Sat Oct 28 14:20:15 2006 +0000
+++ b/libass/ass_mp.h	Sat Oct 28 15:07:18 2006 +0000
@@ -23,6 +23,7 @@
 
 #include "subreader.h"
 
+extern ass_library_t* ass_library;
 extern int ass_enabled;
 extern float ass_font_scale;
 extern float ass_line_spacing;
@@ -35,11 +36,11 @@
 extern char* ass_border_color;
 extern char* ass_styles_file;
 
-ass_track_t* ass_default_track();
+ass_track_t* ass_default_track(ass_library_t* library);
 int ass_process_subtitle(ass_track_t* track, subtitle* sub);
-ass_track_t* ass_read_subdata(sub_data* subdata, double fps);
+ass_track_t* ass_read_subdata(ass_library_t* library, sub_data* subdata, double fps);
 
-void ass_configure(ass_instance_t* priv, int w, int h);
+void ass_configure(ass_renderer_t* priv, int w, int h);
 
 #endif
 
--- a/libass/ass_render.c	Sat Oct 28 14:20:15 2006 +0000
+++ b/libass/ass_render.c	Sat Oct 28 15:07:18 2006 +0000
@@ -36,6 +36,7 @@
 #include "ass_cache.h"
 #include "ass_utils.h"
 #include "ass_fontconfig.h"
+#include "ass_library.h"
 
 #include "libvo/sub.h" // for utf8_get_char
 
@@ -56,13 +57,14 @@
 	int use_margins; // 0 - place all subtitles inside original frame
 	                 // 1 - use margins for placing toptitles and subtitles
 	double aspect; // frame aspect ratio, d_width / d_height.
-	char* fonts_dir;
+
 	char* default_font;
 	char* default_family;
 } ass_settings_t;
 
-struct ass_instance_s {
-	FT_Library library;
+struct ass_renderer_s {
+	ass_library_t* library;
+	FT_Library ftlibrary;
 	fc_instance_t* fontconfig_priv;
 	ass_settings_t settings;
 	int render_id;
@@ -166,7 +168,7 @@
 
 // frame-global data
 typedef struct frame_context_s {
-	ass_instance_t* ass_priv;
+	ass_renderer_t* ass_priv;
 	int width, height; // screen dimensions
 	int orig_height; // frame height ( = screen height - margins )
 	int orig_width; // frame width ( = screen width - margins )
@@ -177,7 +179,7 @@
 	double border_scale;
 } frame_context_t;
 
-static ass_instance_t* ass_instance;
+static ass_renderer_t* ass_renderer;
 static ass_settings_t* global_settings;
 static text_info_t text_info;
 static render_context_t render_context;
@@ -219,11 +221,11 @@
 	}
 }
 
-ass_instance_t* ass_init(void)
+ass_renderer_t* ass_renderer_init(ass_library_t* library)
 {
 	int error;
 	FT_Library ft;
-	ass_instance_t* priv = 0;
+	ass_renderer_t* priv = 0;
 	
 	memset(&render_context, 0, sizeof(render_context));
 	memset(&frame_context, 0, sizeof(frame_context));
@@ -235,7 +237,7 @@
 		goto ass_init_exit;
 	}
 
-	priv = calloc(1, sizeof(ass_instance_t));
+	priv = calloc(1, sizeof(ass_renderer_t));
 	if (!priv) {
 		FT_Done_FreeType(ft);
 		goto ass_init_exit;
@@ -243,7 +245,8 @@
 
 	priv->synth_priv = ass_synth_init();
 
-	priv->library = ft;
+	priv->library = library;
+	priv->ftlibrary = ft;
 	// images_root and related stuff is zero-filled in calloc
 	
 	ass_face_cache_init();
@@ -258,7 +261,7 @@
 	return priv;
 }
 
-void ass_done(ass_instance_t* priv)
+void ass_renderer_done(ass_renderer_t* priv)
 {
 	ass_face_cache_done();
 	ass_glyph_cache_done();
@@ -266,7 +269,7 @@
 		FT_Stroker_Done(render_context.stroker);
 		render_context.stroker = 0;
 	}
-	if (priv && priv->library) FT_Done_FreeType(priv->library);
+	if (priv && priv->ftlibrary) FT_Done_FreeType(priv->ftlibrary);
 	if (priv && priv->fontconfig_priv) fontconfig_done(priv->fontconfig_priv);
 	if (priv && priv->synth_priv) ass_synth_done(priv->synth_priv);
 	if (priv) free(priv);
@@ -388,7 +391,7 @@
 		if (text_info->glyphs[i].glyph) {
 			if ((text_info->glyphs[i].symbol == '\n') || (text_info->glyphs[i].symbol == 0))
 				continue;
-			error = glyph_to_bitmap(ass_instance->synth_priv,
+			error = glyph_to_bitmap(ass_renderer->synth_priv,
 					text_info->glyphs[i].glyph, text_info->glyphs[i].outline_glyph,
 					&text_info->glyphs[i].bm, &text_info->glyphs[i].bm_o,
 					&text_info->glyphs[i].bm_s, text_info->glyphs[i].be);
@@ -566,7 +569,7 @@
 {
 	int error;
 	unsigned val;
-	ass_instance_t* priv = frame_context.ass_priv;
+	ass_renderer_t* priv = frame_context.ass_priv;
 	face_desc_t desc;
 	desc.family = strdup(render_context.family);
 
@@ -581,7 +584,7 @@
 	else if (val == 1) val = 110; //italic
 	desc.italic = val;
 
-	error = ass_new_face(priv->library, priv->fontconfig_priv, &desc, &(render_context.face));
+	error = ass_new_face(priv->ftlibrary, priv->fontconfig_priv, &desc, &(render_context.face));
 	if (error) {
 		render_context.face = 0;
 	}
@@ -615,7 +618,7 @@
 		if (!render_context.stroker) {
 			int error;
 #if (FREETYPE_MAJOR > 2) || ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR > 1))
-			error = FT_Stroker_New( ass_instance->library, &render_context.stroker );
+			error = FT_Stroker_New( ass_renderer->ftlibrary, &render_context.stroker );
 #else // < 2.2
 			error = FT_Stroker_New( render_context.face->memory, &render_context.stroker );
 #endif
@@ -1903,13 +1906,13 @@
 	return 0;
 }
 
-static void ass_reconfigure(ass_instance_t* priv)
+static void ass_reconfigure(ass_renderer_t* priv)
 {
 	priv->render_id = ++last_render_id;
 	ass_glyph_cache_reset();
 }
 
-void ass_set_frame_size(ass_instance_t* priv, int w, int h)
+void ass_set_frame_size(ass_renderer_t* priv, int w, int h)
 {
 	if (priv->settings.frame_width != w || priv->settings.frame_height != h) {
 		priv->settings.frame_width = w;
@@ -1920,7 +1923,7 @@
 	}
 }
 
-void ass_set_margins(ass_instance_t* priv, int t, int b, int l, int r)
+void ass_set_margins(ass_renderer_t* priv, int t, int b, int l, int r)
 {
 	if (priv->settings.left_margin != l ||
 	    priv->settings.right_margin != r ||
@@ -1934,12 +1937,12 @@
 	}
 }
 
-void ass_set_use_margins(ass_instance_t* priv, int use)
+void ass_set_use_margins(ass_renderer_t* priv, int use)
 {
 	priv->settings.use_margins = use;
 }
 
-void ass_set_aspect_ratio(ass_instance_t* priv, double ar)
+void ass_set_aspect_ratio(ass_renderer_t* priv, double ar)
 {
 	if (priv->settings.aspect != ar) {
 		priv->settings.aspect = ar;
@@ -1947,7 +1950,7 @@
 	}
 }
 
-void ass_set_font_scale(ass_instance_t* priv, double font_scale)
+void ass_set_font_scale(ass_renderer_t* priv, double font_scale)
 {
 	if (priv->settings.font_size_coeff != font_scale) {
 		priv->settings.font_size_coeff = font_scale;
@@ -1955,22 +1958,19 @@
 	}
 }
 
-int ass_set_fonts(ass_instance_t* priv, const char* fonts_dir, const char* default_font, const char* default_family)
+int ass_set_fonts(ass_renderer_t* priv, const char* default_font, const char* default_family)
 {
-	if (priv->settings.fonts_dir)
-		free(priv->settings.fonts_dir);
 	if (priv->settings.default_font)
 		free(priv->settings.default_font);
 	if (priv->settings.default_family)
 		free(priv->settings.default_family);
 
-	priv->settings.fonts_dir = fonts_dir ? strdup(fonts_dir) : 0;
 	priv->settings.default_font = default_font ? strdup(default_font) : 0;
 	priv->settings.default_family = default_family ? strdup(default_family) : 0;
 
 	if (priv->fontconfig_priv)
 		fontconfig_done(priv->fontconfig_priv);
-	priv->fontconfig_priv = fontconfig_init(fonts_dir, default_family, default_font);
+	priv->fontconfig_priv = fontconfig_init(priv->library->fonts_dir, default_family, default_font);
 
 	return !!priv->fontconfig_priv;
 }
@@ -1978,11 +1978,11 @@
 /**
  * \brief Start a new frame
  */
-static int ass_start_frame(ass_instance_t *priv, ass_track_t* track, long long now)
+static int ass_start_frame(ass_renderer_t *priv, ass_track_t* track, long long now)
 {
 	ass_image_t* img;
 
-	ass_instance = priv;
+	ass_renderer = priv;
 	global_settings = &priv->settings;
 
 	if (!priv->settings.frame_width && !priv->settings.frame_height)
@@ -2044,9 +2044,9 @@
 	if (!event->render_priv)
 		event->render_priv = calloc(1, sizeof(render_priv_t));
 	// FIXME: check render_id
-	if (ass_instance->render_id != event->render_priv->render_id) {
+	if (ass_renderer->render_id != event->render_priv->render_id) {
 		memset(event->render_priv, 0, sizeof(render_priv_t));
-		event->render_priv->render_id = ass_instance->render_id;
+		event->render_priv->render_id = ass_renderer->render_id;
 	}
 	return event->render_priv;
 }
@@ -2191,7 +2191,7 @@
  * \param track track
  * \param now current video timestamp (ms)
  */
-ass_image_t* ass_render_frame(ass_instance_t *priv, ass_track_t* track, long long now)
+ass_image_t* ass_render_frame(ass_renderer_t *priv, ass_track_t* track, long long now)
 {
 	int i, cnt, rc;
 	event_images_t eimg[MAX_EVENTS];
@@ -2232,7 +2232,7 @@
 		fix_collisions(last, eimg + cnt - last);
 
 	// concat lists
-	tail = &ass_instance->images_root;
+	tail = &ass_renderer->images_root;
 	for (i = 0; i < cnt; ++i) {
 		ass_image_t* cur = eimg[i].imgs;
 		while (cur) {
@@ -2242,6 +2242,6 @@
 		}
 	}
 	
-	return ass_instance->images_root;
+	return ass_renderer->images_root;
 }
 
--- a/libass/ass_types.h	Sat Oct 28 14:20:15 2006 +0000
+++ b/libass/ass_types.h	Sat Oct 28 15:07:18 2006 +0000
@@ -79,6 +79,8 @@
 
 typedef struct parser_priv_s parser_priv_t;
 
+typedef struct ass_library_s ass_library_t;
+
 /// ass track represent either an external script or a matroska subtitle stream (no real difference between them)
 /// it can be used in rendering after the headers are parsed (i.e. events format line read)
 typedef struct ass_track_s {
@@ -104,6 +106,7 @@
 	int default_style; // index of default style
 	char* name; // file name in case of external subs, 0 for streams
 
+	ass_library_t* library;
 	parser_priv_t* parser_priv;
 } ass_track_t;
 
--- a/libmpcodecs/vf_ass.c	Sat Oct 28 14:20:15 2006 +0000
+++ b/libmpcodecs/vf_ass.c	Sat Oct 28 15:07:18 2006 +0000
@@ -60,7 +60,7 @@
 	// 0 = insert always
 	int auto_insert;
 
-	ass_instance_t* ass_priv;
+	ass_renderer_t* ass_priv;
 
 	unsigned char* planes[3];
 	unsigned char* dirty_rows;
@@ -349,7 +349,7 @@
 {
 	switch (request) {
 	case VFCTRL_INIT_EOSD:
-		vf->priv->ass_priv = ass_init();
+		vf->priv->ass_priv = ass_renderer_init((ass_library_t*)data);
 		return vf->priv->ass_priv ? CONTROL_TRUE : CONTROL_FALSE;
 	case VFCTRL_DRAW_EOSD:
 		if (vf->priv->ass_priv) return CONTROL_TRUE;
@@ -361,7 +361,7 @@
 static void uninit(struct vf_instance_s* vf)
 {
 	if (vf->priv->ass_priv)
-		ass_done(vf->priv->ass_priv);
+		ass_renderer_done(vf->priv->ass_priv);
 	if (vf->priv->planes[1])
 		free(vf->priv->planes[1]);
 	if (vf->priv->planes[2])
--- a/libmpcodecs/vf_vo.c	Sat Oct 28 14:20:15 2006 +0000
+++ b/libmpcodecs/vf_vo.c	Sat Oct 28 15:07:18 2006 +0000
@@ -29,7 +29,7 @@
 struct vf_priv_s {
     vf_vo_data_t* vf_vo_data;
 #ifdef USE_ASS
-    ass_instance_t* ass_priv;
+    ass_renderer_t* ass_priv;
 #endif
 };
 #define video_out (vf->priv->vf_vo_data->vo)
@@ -107,7 +107,7 @@
 #ifdef USE_ASS
     case VFCTRL_INIT_EOSD:
     {
-        vf->priv->ass_priv = ass_init();
+        vf->priv->ass_priv = ass_renderer_init((ass_library_t*)data);
         if (!vf->priv->ass_priv) return CONTROL_FALSE;
         return CONTROL_TRUE;
     }
@@ -185,7 +185,7 @@
     if (vf->priv) {
 #ifdef USE_ASS
         if (vf->priv->ass_priv)
-            ass_done(vf->priv->ass_priv);
+            ass_renderer_done(vf->priv->ass_priv);
 #endif
         free(vf->priv);
     }
--- a/libmpdemux/demux_mkv.c	Sat Oct 28 14:20:15 2006 +0000
+++ b/libmpdemux/demux_mkv.c	Sat Oct 28 15:07:18 2006 +0000
@@ -1624,7 +1624,7 @@
               if (extract_embedded_fonts && name && data && data_size &&
                   mime && (strcmp(mime, "application/x-truetype-font") == 0 ||
                   strcmp(mime, "application/x-font") == 0))
-                ass_process_font(name, data, data_size);
+                ass_process_font(ass_library, name, data, data_size);
 #endif
               break;
             }
@@ -2385,7 +2385,7 @@
 
       if (track->subtitle_type == MATROSKA_SUBTYPE_SSA)
         {
-      track->sh_sub.ass_track = ass_new_track();
+      track->sh_sub.ass_track = ass_new_track(ass_library);
       size = track->private_size;
       m = demux_mkv_decode (track,track->private_data,&buffer,&size,2);
       if (buffer && m)
@@ -2398,7 +2398,7 @@
         }
       else
         {
-          track->sh_sub.ass_track = ass_default_track();
+          track->sh_sub.ass_track = ass_default_track(ass_library);
         }
     }
 }
--- a/mplayer.c	Sat Oct 28 14:20:15 2006 +0000
+++ b/mplayer.c	Sat Oct 28 15:07:18 2006 +0000
@@ -705,6 +705,12 @@
 #endif
   free_osd_list();
 
+#ifdef USE_ASS
+if(ass_enabled) {
+  ass_library_done(ass_library);
+}
+#endif
+
   current_module="exit_player";
 
 // free mplayer config
@@ -978,9 +984,13 @@
     subd = sub_read_file(filename, fps);
 #ifdef USE_ASS
     if (ass_enabled)
-        asst = ass_read_file(filename);
+#ifdef USE_ICONV
+        asst = ass_read_file(ass_library, filename, sub_cp);
+#else
+        asst = ass_read_file(ass_library, filename, 0);
+#endif
     if (ass_enabled && subd && !asst)
-        asst = ass_read_subdata(subd, fps);
+        asst = ass_read_subdata(ass_library, subd, fps);
 
     if (!asst && !subd && !silent)
 #else
@@ -3099,6 +3109,17 @@
 #endif /* USE_OSD */
   vo_init_osd();
 
+#ifdef USE_ASS
+if(ass_enabled) {
+  char* path = get_path("fonts");
+  ass_library = ass_library_init();
+  ass_set_fonts_dir(ass_library, path);
+  ass_set_extract_fonts(ass_library, extract_embedded_fonts);
+  ass_set_style_overrides(ass_library, ass_force_style_list);
+  free(path);
+}
+#endif
+
 #ifdef HAVE_RTC
   if(!nortc)
   {
@@ -3882,7 +3903,7 @@
 
 #ifdef USE_ASS
 if (ass_enabled)
-  ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, 0);
+  ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, ass_library);
 #endif
 
 current_module="init_video_codec";