summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,
+ const char *family, int treat_family_as_pattern,
+ unsigned bold, unsigned italic, int *index,
+ uint32_t code)
{
FcBool rc;
FcResult result;
@@ -193,7 +194,7 @@ static char *_select_font(fc_instance_t *priv, const char *family,
if (!treat_family_as_pattern &&
!(r_family && strcasecmp((const char *) r_family, family) == 0) &&
!(