summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2009-07-11 02:18:51 +0200
committerGrigori Goronzy <greg@blackbox>2009-07-11 02:22:18 +0200
commit2c412cdab94a7bb27c5a1e04ab902295215de888 (patch)
treec1372ebf5e6473b287e152a40c88587f3470d237
parent613a22ab9b96453c10de6d75b43067652ad6d7db (diff)
downloadlibass-2c412cdab94a7bb27c5a1e04ab902295215de888.tar.bz2
libass-2c412cdab94a7bb27c5a1e04ab902295215de888.tar.xz
Message callback funtionality
Introduce functionality for providing a message callback that is used for passing messages to the controlling application instead of simply printing them to standard output. The function pointer to the callback is stored in the ass_library_t instance. ass_msg needs access to it, so in many places the library instance needs to be passed around now. The default behavior is the old one: messages of MSGL_INFO or lower are printed to the standard output, prefixed with "[ass]".
-rw-r--r--libass/ass.c119
-rw-r--r--libass/ass.h4
-rw-r--r--libass/ass_bitmap.c19
-rw-r--r--libass/ass_bitmap.h10
-rw-r--r--libass/ass_cache.c35
-rw-r--r--libass/ass_cache.h12
-rw-r--r--libass/ass_drawing.c6
-rw-r--r--libass/ass_drawing.h1
-rw-r--r--libass/ass_font.c32
-rw-r--r--libass/ass_fontconfig.c75
-rw-r--r--libass/ass_fontconfig.h7
-rw-r--r--libass/ass_library.c28
-rw-r--r--libass/ass_library.h3
-rw-r--r--libass/ass_render.c112
-rw-r--r--libass/ass_utils.c31
-rw-r--r--libass/ass_utils.h13
-rw-r--r--libass/libass.sym1
-rw-r--r--test/test.cpp11
18 files changed, 308 insertions, 211 deletions
diff --git a/libass/ass.c b/libass/ass.c
index 135232f..9eaa7b0 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -182,26 +182,26 @@ static int lookup_style(ass_track_t *track, char *name)
return i;
}
i = track->default_style;
- ass_msg(MSGL_WARN,
+ ass_msg(track->library, MSGL_WARN,
"[%p]: Warning: no style named '%s' found, using '%s'",
track, name, track->styles[i].Name);
return i; // use the first style
}
-static uint32_t string2color(char *p)
+static uint32_t string2color(ass_library_t *library, char *p)
{
uint32_t tmp;
- (void) strtocolor(&p, &tmp);
+ (void) strtocolor(library, &p, &tmp);
return tmp;
}
-static long long string2timecode(char *p)
+static long long string2timecode(ass_library_t *library, char *p)
{
unsigned h, m, s, ms;
long long tm;
int res = sscanf(p, "%1d:%2d:%2d.%2d", &h, &m, &s, &ms);
if (res < 4) {
- ass_msg(MSGL_WARN, "Bad timestamp");
+ ass_msg(library, MSGL_WARN, "Bad timestamp");
return 0;
}
tm = ((h * 60 + m) * 60 + s) * 1000 + ms * 10;
@@ -229,22 +229,30 @@ static int numpad2align(int val)
#define ANYVAL(name,func) \
} else if (strcasecmp(tname, #name) == 0) { \
target->name = func(token); \
- ass_msg(MSGL_DBG2, "%s = %s", #name, token);
+ ass_msg(track->library, MSGL_DBG2, "%s = %s", #name, token);
#define STRVAL(name) \
} else if (strcasecmp(tname, #name) == 0) { \
if (target->name != NULL) free(target->name); \
target->name = strdup(token); \
- ass_msg(MSGL_DBG2, "%s = %s", #name, token);
+ ass_msg(track->library, MSGL_DBG2, "%s = %s", #name, token);
+
+#define COLORVAL(name) \
+ } else if (strcasecmp(tname, #name) == 0) { \
+ target->name = string2color(track->library, token); \
+ ass_msg(track->library, MSGL_DBG2, "%s = %s", #name, token);
-#define COLORVAL(name) ANYVAL(name,string2color)
#define INTVAL(name) ANYVAL(name,atoi)
#define FPVAL(name) ANYVAL(name,atof)
-#define TIMEVAL(name) ANYVAL(name,string2timecode)
+#define TIMEVAL(name) \
+ } else if (strcasecmp(tname, #name) == 0) { \
+ target->name = string2timecode(track->library, token); \
+ ass_msg(track->library, MSGL_DBG2, "%s = %s", #name, token);
+
#define STYLEVAL(name) \
} else if (strcasecmp(tname, #name) == 0) { \
target->name = lookup_style(track, token); \
- ass_msg(MSGL_DBG2, "%s = %s", #name, token);
+ ass_msg(track->library, MSGL_DBG2, "%s = %s", #name, token);
#define ALIAS(alias,name) \
if (strcasecmp(tname, #alias) == 0) {tname = #name;}
@@ -318,7 +326,7 @@ static int process_event_tail(ass_track_t *track, ass_event_t *event,
if (last >= event->Text && *last == '\r')
*last = 0;
}
- ass_msg(MSGL_DBG2, "Text = %s", event->Text);
+ ass_msg(track->library, MSGL_DBG2, "Text = %s", event->Text);
event->Duration -= event->Start;
free(format);
return 0; // "Text" is always the last
@@ -458,7 +466,7 @@ static int process_style(ass_track_t *track, char *str)
q = format = strdup(track->style_format);
- ass_msg(MSGL_V, "[%p] Style: %s", track, str);
+ ass_msg(track->library, MSGL_V, "[%p] Style: %s", track, str);
sid = ass_alloc_style(track);
@@ -535,7 +543,7 @@ static int process_styles_line(ass_track_t *track, char *str)
char *p = str + 7;
skip_spaces(&p);
track->style_format = strdup(p);
- ass_msg(MSGL_DBG2, "Style format: %s",
+ ass_msg(track->library, MSGL_DBG2, "Style format: %s",
track->style_format);
} else if (!strncmp(str, "Style:", 6)) {
char *p = str + 6;
@@ -565,14 +573,13 @@ static void event_format_fallback(ass_track_t *track)
{
track->parser_priv->state = PST_EVENTS;
if (track->track_type == TRACK_TYPE_SSA)
- track->event_format =
- strdup
- ("Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text");
+ track->event_format = strdup("Format: Marked, Start, End, Style, "
+ "Name, MarginL, MarginR, MarginV, Effect, Text");
else
- track->event_format =
- strdup
- ("Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text");
- ass_msg(MSGL_V, "No event format found, using fallback");
+ track->event_format = strdup("Format: Layer, Start, End, Style, "
+ "Actor, MarginL, MarginR, MarginV, Effect, Text");
+ ass_msg(track->library, MSGL_V,
+ "No event format found, using fallback");
}
static int process_events_line(ass_track_t *track, char *str)
@@ -581,7 +588,7 @@ static int process_events_line(ass_track_t *track, char *str)
char *p = str + 7;
skip_spaces(&p);
track->event_format = strdup(p);
- ass_msg(MSGL_DBG2, "Event format: %s", track->event_format);
+ ass_msg(track->library, MSGL_DBG2, "Event format: %s", track->event_format);
} else if (!strncmp(str, "Dialogue:", 9)) {
// This should never be reached for embedded subtitles.
// They have slightly different format and are parsed in ass_process_chunk,
@@ -601,7 +608,7 @@ static int process_events_line(ass_track_t *track, char *str)
process_event_tail(track, event, str, 0);
} else {
- ass_msg(MSGL_V, "Not understood: '%s'", str);
+ ass_msg(track->library, MSGL_V, "Not understood: '%s'", str);
}
return 0;
}
@@ -636,11 +643,11 @@ static int decode_font(ass_track_t *track)
int dsize; // decoded size
unsigned char *buf = 0;
- ass_msg(MSGL_V, "Font: %d bytes encoded data",
- track->parser_priv->fontdata_used);
+ ass_msg(track->library, MSGL_V, "Font: %d bytes encoded data",
+ track->parser_priv->fontdata_used);
size = track->parser_priv->fontdata_used;
if (size % 4 == 1) {
- ass_msg(MSGL_ERR, "Bad encoded data size");
+ ass_msg(track->library, MSGL_ERR, "Bad encoded data size");
goto error_decode_font;
}
buf = malloc(size / 4 * 3 + 2);
@@ -686,19 +693,20 @@ static int process_fonts_line(ass_track_t *track, char *str)
decode_font(track);
}
track->parser_priv->fontname = strdup(p);
- ass_msg(MSGL_V, "Fontname: %s",
+ ass_msg(track->library, MSGL_V, "Fontname: %s",
track->parser_priv->fontname);
return 0;
}
if (!track->parser_priv->fontname) {
- ass_msg(MSGL_V, "Not understood: '%s'", str);
+ ass_msg(track->library, MSGL_V, "Not understood: '%s'", str);
return 0;
}
len = strlen(str);
if (len > 80) {
- ass_msg(MSGL_WARN, "Font line too long: %d, %s", len, str);
+ ass_msg(track->library, MSGL_WARN, "Font line too long: %d, %s",
+ len, str);
return 0;
}
if (track->parser_priv->fontdata_used + len >
@@ -801,7 +809,7 @@ void ass_process_data(ass_track_t *track, char *data, int size)
memcpy(str, data, size);
str[size] = '\0';
- ass_msg(MSGL_V, "Event: %s", str);
+ ass_msg(track->library, MSGL_V, "Event: %s", str);
process_text(track, str);
free(str);
}
@@ -852,14 +860,14 @@ void ass_process_chunk(ass_track_t *track, char *data, int size,
ass_event_t *event;
if (!track->event_format) {
- ass_msg(MSGL_WARN, "Event format header missing");
+ ass_msg(track->library, MSGL_WARN, "Event format header missing");
return;
}
str = malloc(size + 1);
memcpy(str, data, size);
str[size] = '\0';
- ass_msg(MSGL_V, "Event at %" PRId64 ", +%" PRId64 ": %s",
+ ass_msg(track->library, MSGL_V, "Event at %" PRId64 ", +%" PRId64 ": %s",
(int64_t) timecode, (int64_t) duration, str);
eid = ass_alloc_event(track);
@@ -898,7 +906,8 @@ void ass_process_chunk(ass_track_t *track, char *data, int size,
* \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, char *codepage)
+static char *sub_recode(ass_library_t *library, char *data, size_t size,
+ char *codepage)
{
iconv_t icdsc;
char *tocp = "UTF-8";
@@ -913,14 +922,14 @@ static char *sub_recode(char *data, size_t size, char *codepage)
|| sscanf(codepage, "ENCA:%2s:%99s", enca_lang,
enca_fallback) == 2) {
cp_tmp =
- ass_guess_buffer_cp((unsigned char *) data, size, enca_lang,
- enca_fallback);
+ ass_guess_buffer_cp(library, (unsigned char *) data, size,
+ enca_lang, enca_fallback);
}
#endif
if ((icdsc = iconv_open(tocp, cp_tmp)) != (iconv_t) (-1)) {
- ass_msg(MSGL_V, "Opened iconv descriptor");
+ ass_msg(library, MSGL_V, "Opened iconv descriptor");
} else
- ass_msg(MSGL_ERR, "Error opening iconv descriptor");
+ ass_msg(library, MSGL_ERR, "Error opening iconv descriptor");
}
{
@@ -951,7 +960,7 @@ static char *sub_recode(char *data, size_t size, char *codepage)
osize += size;
oleft += size;
} else {
- ass_msg(MSGL_WARN, "Error recoding file");
+ ass_msg(library, MSGL_WARN, "Error recoding file");
return NULL;
}
} else if (clear)
@@ -963,7 +972,7 @@ static char *sub_recode(char *data, size_t size, char *codepage)
if (icdsc != (iconv_t) (-1)) {
(void) iconv_close(icdsc);
icdsc = (iconv_t) (-1);
- ass_msg(MSGL_V, "Closed iconv descriptor");
+ ass_msg(library, MSGL_V, "Closed iconv descriptor");
}
return outbuf;
@@ -976,7 +985,7 @@ static char *sub_recode(char *data, size_t size, char *codepage)
* \param bufsize out: file size
* \return pointer to file contents. Caller is responsible for its deallocation.
*/
-static char *read_file(char *fname, size_t *bufsize)
+static char *read_file(ass_library_t *library, char *fname, size_t *bufsize)
{
int res;
long sz;
@@ -985,12 +994,14 @@ static char *read_file(char *fname, size_t *bufsize)
FILE *fp = fopen(fname, "rb");
if (!fp) {
- ass_msg(MSGL_WARN, "ass_read_file(%s): fopen failed", fname);
+ ass_msg(library, MSGL_WARN,
+ "ass_read_file(%s): fopen failed", fname);
return 0;
}
res = fseek(fp, 0, SEEK_END);
if (res == -1) {
- ass_msg(MSGL_WARN, "ass_read_file(%s): fseek failed", fname);
+ ass_msg(library, MSGL_WARN,
+ "ass_read_file(%s): fseek failed", fname);
fclose(fp);
return 0;
}
@@ -999,14 +1010,14 @@ static char *read_file(char *fname, size_t *bufsize)
rewind(fp);
if (sz > 10 * 1024 * 1024) {
- ass_msg(MSGL_INFO,
+ ass_msg(library, MSGL_INFO,
"ass_read_file(%s): Refusing to load subtitles "
"larger than 10MiB", fname);
fclose(fp);
return 0;
}
- ass_msg(MSGL_V, "File size: %ld", sz);
+ ass_msg(library, MSGL_V, "File size: %ld", sz);
buf = malloc(sz + 1);
assert(buf);
@@ -1014,7 +1025,7 @@ static char *read_file(char *fname, size_t *bufsize)
do {
res = fread(buf + bytes_read, 1, sz - bytes_read, fp);
if (res <= 0) {
- ass_msg(MSGL_INFO, "Read failed, %d: %s", errno,
+ ass_msg(library, MSGL_INFO, "Read failed, %d: %s", errno,
strerror(errno));
fclose(fp);
free(buf);
@@ -1080,7 +1091,7 @@ ass_track_t *ass_read_memory(ass_library_t *library, char *buf,
#ifdef CONFIG_ICONV
if (codepage)
- buf = sub_recode(buf, bufsize, codepage);
+ buf = sub_recode(library, buf, bufsize, codepage);
if (!buf)
return 0;
else
@@ -1092,23 +1103,24 @@ ass_track_t *ass_read_memory(ass_library_t *library, char *buf,
if (!track)
return 0;
- ass_msg(MSGL_INFO, "Added subtitle file: "
+ ass_msg(library, MSGL_INFO, "Added subtitle file: "
"<memory> (%d styles, %d events)",
track->n_styles, track->n_events);
return track;
}
-static char *read_file_recode(char *fname, char *codepage, size_t *size)
+static char *read_file_recode(ass_library_t *library, char *fname,
+ char *codepage, size_t *size)
{
char *buf;
size_t bufsize;
- buf = read_file(fname, &bufsize);
+ buf = read_file(library, fname, &bufsize);
if (!buf)
return 0;
#ifdef CONFIG_ICONV
if (codepage) {
- char *tmpbuf = sub_recode(buf, bufsize, codepage);
+ char *tmpbuf = sub_recode(library, buf, bufsize, codepage);
free(buf);
buf = tmpbuf;
}
@@ -1133,7 +1145,7 @@ ass_track_t *ass_read_file(ass_library_t *library, char *fname,
ass_track_t *track;
size_t bufsize;
- buf = read_file_recode(fname, codepage, &bufsize);
+ buf = read_file_recode(library, fname, codepage, &bufsize);
if (!buf)
return 0;
track = parse_memory(library, buf);
@@ -1143,7 +1155,8 @@ ass_track_t *ass_read_file(ass_library_t *library, char *fname,
track->name = strdup(fname);
- ass_msg(MSGL_INFO, "Added subtitle file: '%s' (%d styles, %d events)",
+ ass_msg(library, MSGL_INFO,
+ "Added subtitle file: '%s' (%d styles, %d events)",
fname, track->n_styles, track->n_events);
return track;
@@ -1158,13 +1171,13 @@ int ass_read_styles(ass_track_t *track, char *fname, char *codepage)
parser_state_t old_state;
size_t sz;
- buf = read_file(fname, &sz);
+ buf = read_file(track->library, fname, &sz);
if (!buf)
return 1;
#ifdef CONFIG_ICONV
if (codepage) {
char *tmpbuf;
- tmpbuf = sub_recode(buf, sz, codepage);
+ tmpbuf = sub_recode(track->library, buf, sz, codepage);
free(buf);
buf = tmpbuf;
}
diff --git a/libass/ass.h b/libass/ass.h
index d911e99..e0160d6 100644
--- a/libass/ass.h
+++ b/libass/ass.h
@@ -22,6 +22,7 @@
#define LIBASS_ASS_H
#include <stdio.h>
+#include <stdarg.h>
#include "ass_types.h"
/// Libass renderer object. Contents are private.
@@ -69,6 +70,9 @@ void ass_set_style_overrides(ass_library_t *priv, char **list);
void ass_process_force_style(ass_track_t *track);
+void ass_set_message_cb(ass_library_t *priv,
+ void (*msg_cb)(int, char *, va_list *));
+
/**
* \brief initialize the renderer
* \param priv library handle
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c
index a72caad..c8cd8be 100644
--- a/libass/ass_bitmap.c
+++ b/libass/ass_bitmap.c
@@ -165,7 +165,7 @@ static bitmap_t *copy_bitmap(const bitmap_t *src)
return dst;
}
-static int check_glyph_area(FT_Glyph glyph)
+static int check_glyph_area(ass_library_t *library, FT_Glyph glyph)
{
FT_BBox bbox;
long long dx, dy;
@@ -173,14 +173,15 @@ static int check_glyph_area(FT_Glyph glyph)
dx = bbox.xMax - bbox.xMin;
dy = bbox.yMax - bbox.yMin;
if (dx * dy > 8000000) {
- ass_msg(MSGL_WARN, "Glyph bounding box too large: %dx%dpx",
+ ass_msg(library, MSGL_WARN, "Glyph bounding box too large: %dx%dpx",
(int) dx, (int) dy);
return 1;
} else
return 0;
}
-static bitmap_t *glyph_to_bitmap_internal(FT_Glyph glyph, int bord)
+static bitmap_t *glyph_to_bitmap_internal(ass_library_t *library,
+ FT_Glyph glyph, int bord)
{
FT_BitmapGlyph bg;
FT_Bitmap *bit;
@@ -191,11 +192,11 @@ static bitmap_t *glyph_to_bitmap_internal(FT_Glyph glyph, int bord)
int i;
int error;
- if (check_glyph_area(glyph))
+ if (check_glyph_area(library, glyph))
return 0;
error = FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 0);
if (error) {
- ass_msg(MSGL_WARN, "FT_Glyph_To_Bitmap error %d",
+ ass_msg(library, MSGL_WARN, "FT_Glyph_To_Bitmap error %d",
error);
return 0;
}
@@ -203,7 +204,7 @@ static bitmap_t *glyph_to_bitmap_internal(FT_Glyph glyph, int bord)
bg = (FT_BitmapGlyph) glyph;
bit = &(bg->bitmap);
if (bit->pixel_mode != FT_PIXEL_MODE_GRAY) {
- ass_msg(MSGL_WARN, "Unsupported pixel mode: %d",
+ ass_msg(library, MSGL_WARN, "Unsupported pixel mode: %d",
(int) (bit->pixel_mode));
FT_Done_Glyph(glyph);
return 0;
@@ -471,7 +472,7 @@ static void be_blur(unsigned char *buf, int w, int h)
}
}
-int glyph_to_bitmap(ass_synth_priv_t *priv_blur,
+int glyph_to_bitmap(ass_library_t *library, ass_synth_priv_t *priv_blur,
FT_Glyph glyph, FT_Glyph outline_glyph,
bitmap_t **bm_g, bitmap_t **bm_o, bitmap_t **bm_s,
int be, double blur_radius, FT_Vector shadow_offset)
@@ -487,12 +488,12 @@ int glyph_to_bitmap(ass_synth_priv_t *priv_blur,
*bm_g = *bm_o = *bm_s = 0;
if (glyph)
- *bm_g = glyph_to_bitmap_internal(glyph, bord);
+ *bm_g = glyph_to_bitmap_internal(library, glyph, bord);
if (!*bm_g)
return 1;
if (outline_glyph) {
- *bm_o = glyph_to_bitmap_internal(outline_glyph, bord);
+ *bm_o = glyph_to_bitmap_internal(library, outline_glyph, bord);
if (!*bm_o) {
ass_free_bitmap(*bm_g);
return 1;
diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h
index f6b1380..2e34a5c 100644
--- a/libass/ass_bitmap.h
+++ b/libass/ass_bitmap.h
@@ -24,6 +24,8 @@
#include <ft2build.h>
#include FT_GLYPH_H
+#include "ass.h"
+
typedef struct ass_synth_priv_s ass_synth_priv_t;
ass_synth_priv_t *ass_synth_init(double);
@@ -44,10 +46,10 @@ typedef struct bitmap_s {
* \param bm_g out: pointer to the bitmap of glyph shadow is returned here
* \param be 1 = produces blurred bitmaps, 0 = normal bitmaps
*/
-int glyph_to_bitmap(ass_synth_priv_t *priv_blur, FT_Glyph glyph,
- FT_Glyph outline_glyph, bitmap_t **bm_g,
- bitmap_t **bm_o, bitmap_t **bm_s, int be,
- double blur_radius, FT_Vector shadow_offset);
+int glyph_to_bitmap(ass_library_t *library, ass_synth_priv_t *priv_blur,
+ FT_Glyph glyph, FT_Glyph outline_glyph,
+ bitmap_t **bm_g, bitmap_t **bm_o, bitmap_t **bm_s,
+ int be, double blur_radius, FT_Vector shadow_offset);
void ass_free_bitmap(bitmap_t *bm);
diff --git a/libass/ass_cache.c b/libass/ass_cache.c
index adee0cc..ed44a2f 100644
--- a/libass/ass_cache.c
+++ b/libass/ass_cache.c
@@ -51,12 +51,14 @@ static void hashmap_item_dtor(void *key, size_t key_size, void *value,
free(value);
}
-hashmap_t *hashmap_init(size_t key_size, size_t value_size, int nbuckets,
+hashmap_t *hashmap_init(ass_library_t *library, size_t key_size,
+ size_t value_size, int nbuckets,
hashmap_item_dtor_t item_dtor,
hashmap_key_compare_t key_compare,
hashmap_hash_t hash)
{
hashmap_t *map = calloc(1, sizeof(hashmap_t));
+ map->library = library;
map->nbuckets = nbuckets;
map->key_size = key_size;
map->value_size = value_size;
@@ -72,7 +74,7 @@ void hashmap_done(hashmap_t *map)
int i;
// print stats
if (map->count > 0 || map->hit_count + map->miss_count > 0)
- ass_msg(MSGL_V,
+ ass_msg(map->library, MSGL_V,
"cache statistics: \n total accesses: %d\n hits: %d\n "
"misses: %d\n object count: %d",
map->hit_count + map->miss_count, map->hit_count,
@@ -179,10 +181,10 @@ void *ass_font_cache_add(hashmap_t *font_cache, ass_font_t *font)
return hashmap_insert(font_cache, &(font->desc), font);
}
-hashmap_t *ass_font_cache_init(void)
+hashmap_t *ass_font_cache_init(ass_library_t *library)
{
hashmap_t *font_cache;
- font_cache = hashmap_init(sizeof(ass_font_desc_t),
+ font_cache = hashmap_init(library, sizeof(ass_font_desc_t),
sizeof(ass_font_t),
1000,
font_hash_dtor, font_compare, font_desc_hash);
@@ -235,10 +237,11 @@ bitmap_hash_val_t *cache_find_bitmap(hashmap_t *bitmap_cache,
return hashmap_find(bitmap_cache, key);
}
-hashmap_t *ass_bitmap_cache_init(void)
+hashmap_t *ass_bitmap_cache_init(ass_library_t *library)
{
hashmap_t *bitmap_cache;
- bitmap_cache = hashmap_init(sizeof(bitmap_hash_key_t),
+ bitmap_cache = hashmap_init(library,
+ sizeof(bitmap_hash_key_t),
sizeof(bitmap_hash_val_t),
0xFFFF + 13,
bitmap_hash_dtor, bitmap_compare,
@@ -253,8 +256,10 @@ void ass_bitmap_cache_done(hashmap_t *bitmap_cache)
hashmap_t *ass_bitmap_cache_reset(hashmap_t *bitmap_cache)
{
+ ass_library_t *lib = bitmap_cache->library;
+
ass_bitmap_cache_done(bitmap_cache);
- return ass_bitmap_cache_init();
+ return ass_bitmap_cache_init(lib);
}
//---------------------------------
@@ -289,10 +294,10 @@ glyph_hash_val_t *cache_find_glyph(hashmap_t *glyph_cache,
return hashmap_find(glyph_cache, key);
}
-hashmap_t *ass_glyph_cache_init(void)
+hashmap_t *ass_glyph_cache_init(ass_library_t *library)
{
hashmap_t *glyph_cache;
- glyph_cache = hashmap_init(sizeof(glyph_hash_key_t),
+ glyph_cache = hashmap_init(library, sizeof(glyph_hash_key_t),
sizeof(glyph_hash_val_t),
0xFFFF + 13,
glyph_hash_dtor, glyph_compare, glyph_hash);
@@ -306,8 +311,10 @@ void ass_glyph_cache_done(hashmap_t *glyph_cache)
hashmap_t *ass_glyph_cache_reset(hashmap_t *glyph_cache)
{
+ ass_library_t *lib = glyph_cache->library;
+
ass_glyph_cache_done(glyph_cache);
- return ass_glyph_cache_init();
+ return ass_glyph_cache_init(lib);
}
@@ -342,10 +349,10 @@ composite_hash_val_t *cache_find_composite(hashmap_t *composite_cache,
return hashmap_find(composite_cache, key);
}
-hashmap_t *ass_composite_cache_init(void)
+hashmap_t *ass_composite_cache_init(ass_library_t *library)
{
hashmap_t *composite_cache;
- composite_cache = hashmap_init(sizeof(composite_hash_key_t),
+ composite_cache = hashmap_init(library, sizeof(composite_hash_key_t),
sizeof(composite_hash_val_t),
0xFFFF + 13,
composite_hash_dtor, composite_compare,
@@ -360,6 +367,8 @@ void ass_composite_cache_done(hashmap_t *composite_cache)
hashmap_t *ass_composite_cache_reset(hashmap_t *composite_cache)
{
+ ass_library_t *lib = composite_cache->library;
+
ass_composite_cache_done(composite_cache);
- return ass_composite_cache_init();
+ return ass_composite_cache_init(lib);
}
diff --git a/libass/ass_cache.h b/libass/ass_cache.h
index d8de97a..004a4b6 100644
--- a/libass/ass_cache.h
+++ b/libass/ass_cache.h
@@ -49,9 +49,11 @@ typedef struct hashmap_s {
int hit_count;
int miss_count;
int count;
+ ass_library_t *library;
} hashmap_t;
-hashmap_t *hashmap_init(size_t key_size, size_t value_size, int nbuckets,
+hashmap_t *hashmap_init(ass_library_t *library, size_t key_size,
+ size_t value_size, int nbuckets,
hashmap_item_dtor_t item_dtor,
hashmap_key_compare_t key_compare,
hashmap_hash_t hash);
@@ -59,7 +61,7 @@ void hashmap_done(hashmap_t *map);
void *hashmap_insert(hashmap_t *map, void *key, void *value);
void *hashmap_find(hashmap_t *map, void *key);
-hashmap_t *ass_font_cache_init(void);
+hashmap_t *ass_font_cache_init(ass_library_t *library);
ass_font_t *ass_font_cache_find(hashmap_t *, ass_font_desc_t *desc);
void *ass_font_cache_add(hashmap_t *, ass_font_t *font);
void ass_font_cache_done(hashmap_t *);
@@ -74,7 +76,7 @@ typedef struct bitmap_hash_val_s {
bitmap_t *bm_s;
} bitmap_hash_val_t;
-hashmap_t *ass_bitmap_cache_init(void);
+hashmap_t *ass_bitmap_cache_init(ass_library_t *library);
void *cache_add_bitmap(hashmap_t *, bitmap_hash_key_t *key,
bitmap_hash_val_t *val);
bitmap_hash_val_t *cache_find_bitmap(hashmap_t *bitmap_cache,
@@ -88,7 +90,7 @@ typedef struct composite_hash_val_s {
unsigned char *b;
} composite_hash_val_t;
-hashmap_t *ass_composite_cache_init(void);
+hashmap_t *ass_composite_cache_init(ass_library_t *library);
void *cache_add_composite(hashmap_t *, composite_hash_key_t *key,
composite_hash_val_t *val);
composite_hash_val_t *cache_find_composite(hashmap_t *composite_cache,
@@ -105,7 +107,7 @@ typedef struct glyph_hash_val_s {
int asc, desc; // ascender/descender of a drawing
} glyph_hash_val_t;
-hashmap_t *ass_glyph_cache_init(void);
+hashmap_t *ass_glyph_cache_init(ass_library_t *library);
void *cache_add_glyph(hashmap_t *, glyph_hash_key_t *key,
glyph_hash_val_t *val);
glyph_hash_val_t *cache_find_glyph(hashmap_t *glyph_cache,
diff --git a/libass/ass_drawing.c b/libass/ass_drawing.c
index c05a962..f75bbd9 100644
--- a/libass/ass_drawing.c
+++ b/libass/ass_drawing.c
@@ -139,8 +139,9 @@ static void drawing_finish(ass_drawing_t *drawing)
for (i = 0; i < ol->n_points; i++)
ol->points[i].y += offset;
- ass_msg(MSGL_V, "Parsed drawing with %d points and %d contours",
- ol->n_points, ol->n_contours);
+ ass_msg(drawing->library, MSGL_V,
+ "Parsed drawing with %d points and %d contours", ol->n_points,
+ ol->n_contours);
}
/*
@@ -364,6 +365,7 @@ ass_drawing_t *ass_drawing_new(void *fontconfig_priv, ass_font_t *font,
drawing->size = DRAWING_INITIAL_SIZE;
drawing->ftlibrary = lib;
+ drawing->library = font->library;
drawing_make_glyph(drawing, fontconfig_priv, font, hint);
drawing->scale_x = 1.;
diff --git a/libass/ass_drawing.h b/libass/ass_drawing.h
index 323c05d..dfd68f0 100644
--- a/libass/ass_drawing.h
+++ b/libass/ass_drawing.h
@@ -58,6 +58,7 @@ typedef struct ass_drawing_s {
// private
FT_Library ftlibrary; // FT library instance, needed for font ops
+ ass_library_t *library;
int size; // current buffer size
ass_drawing_token_t *tokens; // tokenized drawing
int max_points; // current maximum size
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 76c4793..34ae292 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -39,7 +39,7 @@
* Select Microfost Unicode CharMap, if the font has one.
* Otherwise, let FreeType decide.
*/
-static void charmap_magic(FT_Face face)
+static void charmap_magic(ass_library_t *library, FT_Face face)
{
int i;
for (i = 0; i < face->num_charmaps; ++i) {
@@ -56,10 +56,11 @@ static void charmap_magic(FT_Face face)
if (!face->charmap) {
if (face->num_charmaps == 0) {
- ass_msg(MSGL_WARN, "Font face with no charmaps");
+ ass_msg(library, MSGL_WARN, "Font face with no charmaps");
return;
}
- ass_msg(MSGL_WARN, "No charmap autodetected, trying the first one");
+ ass_msg(library, MSGL_WARN,
+ "No charmap autodetected, trying the first one");
FT_Set_Charmap(face, face->charmaps[0]);
return;
}
@@ -125,7 +126,7 @@ static int add_face(void *fc_priv, ass_font_t *font, uint32_t ch)
return -1;
path =
- fontconfig_select(fc_priv, font->desc.family,
+ fontconfig_select(font->library, fc_priv, font->desc.family,
font->desc.treat_family_as_pattern,
font->desc.bold, font->desc.italic, &index, ch);
if (!path)
@@ -140,19 +141,21 @@ static int add_face(void *fc_priv, ass_font_t *font, uint32_t ch)
font->library->fontdata[mem_idx].size, 0,
&face);
if (error) {
- ass_msg(MSGL_WARN, "Error opening memory font: '%s'", path);
+ ass_msg(font->library, MSGL_WARN,
+ "Error opening memory font: '%s'", path);
free(path);
return -1;
}
} else {
error = FT_New_Face(font->ftlibrary, path, index, &face);
if (error) {
- ass_msg(MSGL_WARN, "Error opening font: '%s', %d", path, index);
+ ass_msg(font->library, MSGL_WARN,
+ "Error opening font: '%s', %d", path, index);
free(path);
return -1;
}
}
- charmap_magic(face);
+ charmap_magic(font->library, face);
buggy_font_workaround(face);
font->faces[font->n_faces++] = face;
@@ -384,7 +387,7 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ass_font_t *font,
#ifdef CONFIG_FONTCONFIG
if (index == 0) {
int face_idx;
- ass_msg(MSGL_INFO,
+ ass_msg(font->library, MSGL_INFO,
"Glyph 0x%X not found, selecting one more "
"font for (%s, %d, %d)", ch, font->desc.family,
font->desc.bold, font->desc.italic);
@@ -393,9 +396,10 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ass_font_t *font,
face = font->faces[face_idx];
index = FT_Get_Char_Index(face, ch);
if (index == 0) {
- ass_msg(MSGL_ERR, "Glyph 0x%X not found in font "
- "for (%s, %d, %d)", ch, font->desc.family,
- font->desc.bold, font->desc.italic);
+ ass_msg(font->library, MSGL_ERR,
+ "Glyph 0x%X not found in font for (%s, %d, %d)",
+ ch, font->desc.family, font->desc.bold,
+ font->desc.italic);
}
}
}
@@ -418,7 +422,8 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ass_font_t *font,
error = FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP | flags);
if (error) {
- ass_msg(MSGL_WARN, "Error loading glyph, index %d", index);
+ ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d",
+ index);
return 0;
}
#if (FREETYPE_MAJOR > 2) || \
@@ -432,7 +437,8 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ass_font_t *font,
#endif
error = FT_Get_Glyph(face->glyph, &glyph);
if (error) {
- ass_msg(MSGL_WARN, "Error loading glyph, index %d", index);
+ ass_msg(font->library, MSGL_WARN, "Error loading glyph, index %d",
+ index);
return 0;
}
diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c
index e23c4f2..d8d64e2 100644
--- a/libass/ass_fontconfig.c
+++ b/libass/ass_fontconfig.c
@@ -71,9 +71,10 @@ struct fc_instance_s {
* \param code: the character that should be present in the font, can be 0
* \return font file path
*/
-static char *_select_font(fc_instance_t *priv, const char *family,
- int treat_family_as_pattern, unsigned bold,
- unsigned italic, int *index, uint32_t code)
+static char *_select_font(ass_library_t *library, fc_instance_t *priv,