diff options
-rw-r--r-- | libass/ass.c | 119 | ||||
-rw-r--r-- | libass/ass.h | 4 | ||||
-rw-r--r-- | libass/ass_bitmap.c | 19 | ||||
-rw-r--r-- | libass/ass_bitmap.h | 10 | ||||
-rw-r--r-- | libass/ass_cache.c | 35 | ||||
-rw-r--r-- | libass/ass_cache.h | 12 | ||||
-rw-r--r-- | libass/ass_drawing.c | 6 | ||||
-rw-r--r-- | libass/ass_drawing.h | 1 | ||||
-rw-r--r-- | libass/ass_font.c | 32 | ||||
-rw-r--r-- | libass/ass_fontconfig.c | 75 | ||||
-rw-r--r-- | libass/ass_fontconfig.h | 7 | ||||
-rw-r--r-- | libass/ass_library.c | 28 | ||||
-rw-r--r-- | libass/ass_library.h | 3 | ||||
-rw-r--r-- | libass/ass_render.c | 112 | ||||
-rw-r--r-- | libass/ass_utils.c | 31 | ||||
-rw-r--r-- | libass/ass_utils.h | 13 | ||||
-rw-r--r-- | libass/libass.sym | 1 | ||||
-rw-r--r-- | test/test.cpp | 11 |
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) && !( |