From 96601ede589799cb84cec4a616467c9e08412509 Mon Sep 17 00:00:00 2001 From: "Dr.Smile" Date: Sat, 19 Sep 2015 03:08:29 +0300 Subject: cache: keep ref_count of all active objects nonzero --- libass/ass_cache.c | 115 +++++++++++++++++++++++++++++----------------------- libass/ass_cache.h | 6 +-- libass/ass_font.c | 11 +++-- libass/ass_parse.c | 2 +- libass/ass_render.c | 78 +++++++++++++++++++++++++---------- libass/ass_render.h | 4 +- libass/ass_shaper.c | 54 ++++++++++++------------ 7 files changed, 164 insertions(+), 106 deletions(-) (limited to 'libass') diff --git a/libass/ass_cache.c b/libass/ass_cache.c index ce742e6..18904d2 100644 --- a/libass/ass_cache.c +++ b/libass/ass_cache.c @@ -63,12 +63,14 @@ static unsigned font_compare(void *key1, void *key2, size_t key_size) return 1; } -static bool font_key_copy(void *dst, void *src, size_t key_size) +static bool font_key_move(void *dst, void *src, size_t key_size) { - memcpy(dst, src, key_size); - ASS_FontDesc *d = dst, *s = src; - d->family = strdup(s->family); - return d->family; + ASS_FontDesc *k = src; + if (dst) + memcpy(dst, src, key_size); + else + free(k->family); + return true; } static void font_destruct(void *key, void *value) @@ -99,21 +101,19 @@ static unsigned bitmap_compare(void *a, void *b, size_t key_size) } } -static bool bitmap_key_copy(void *dst, void *src, size_t key_size) +static bool bitmap_key_move(void *dst, void *src, size_t key_size) { - memcpy(dst, src, key_size); BitmapHashKey *d = dst, *s = src; - switch (s->type) { - case BITMAP_OUTLINE: - ass_cache_inc_ref(s->u.outline.outline); - break; - case BITMAP_CLIP: - d->u.clip.text = strdup(s->u.clip.text); - if (!d->u.clip.text) - return false; - break; + if (!dst) { + if (s->type == BITMAP_OUTLINE) + ass_cache_dec_ref(s->u.outline.outline); + return true; } - return true; + memcpy(dst, src, key_size); + if (s->type != BITMAP_CLIP) + return true; + d->u.clip.text = strdup(s->u.clip.text); + return d->u.clip.text; } static void bitmap_destruct(void *key, void *value) @@ -158,12 +158,16 @@ static unsigned composite_compare(void *a, void *b, size_t key_size) return filter_compare(&ak->filter, &bk->filter, key_size); } -static bool composite_key_copy(void *dst, void *src, size_t key_size) +static bool composite_key_move(void *dst, void *src, size_t key_size) { - memcpy(dst, src, key_size); + if (dst) { + memcpy(dst, src, key_size); + return true; + } CompositeHashKey *k = src; for (size_t i = 0; i < k->bitmap_count; i++) - ass_cache_inc_ref(k->bitmaps[i].image); + ass_cache_dec_ref(k->bitmaps[i].image); + free(k->bitmaps); return true; } @@ -205,21 +209,19 @@ static unsigned outline_compare(void *a, void *b, size_t key_size) } } -static bool outline_key_copy(void *dst, void *src, size_t key_size) +static bool outline_key_move(void *dst, void *src, size_t key_size) { - memcpy(dst, src, key_size); OutlineHashKey *d = dst, *s = src; - switch (s->type) { - case OUTLINE_GLYPH: - ass_cache_inc_ref(s->u.glyph.font); - break; - case OUTLINE_DRAWING: - d->u.drawing.text = strdup(s->u.drawing.text); - if (!d->u.drawing.text) - return false; - break; + if (!dst) { + if (s->type == OUTLINE_GLYPH) + ass_cache_dec_ref(s->u.glyph.font); + return true; } - return true; + memcpy(dst, src, key_size); + if (s->type != OUTLINE_DRAWING) + return true; + d->u.drawing.text = strdup(s->u.drawing.text); + return d->u.drawing.text; } static void outline_destruct(void *key, void *value) @@ -238,8 +240,10 @@ static void outline_destruct(void *key, void *value) // glyph metric cache -static bool glyph_metric_key_copy(void *dst, void *src, size_t key_size) +static bool glyph_metric_key_move(void *dst, void *src, size_t key_size) { + if (!dst) + return true; memcpy(dst, src, key_size); GlyphMetricsHashKey *k = src; ass_cache_inc_ref(k->font); @@ -269,7 +273,7 @@ struct cache { HashFunction hash_func; HashCompare compare_func; - CacheKeyCopy copy_func; + CacheKeyMove key_move_func; CacheItemDestructor destruct_func; size_t key_size; size_t value_size; @@ -306,9 +310,10 @@ static unsigned compare_simple(void *a, void *b, size_t key_size) } // Default copy function -static bool copy_simple(void *dst, void *src, size_t key_size) +static bool key_move_simple(void *dst, void *src, size_t key_size) { - memcpy(dst, src, key_size); + if (dst) + memcpy(dst, src, key_size); return true; } @@ -320,7 +325,7 @@ static void destruct_simple(void *key, void *value) // Create a cache with type-specific hash/compare/destruct/size functions Cache *ass_cache_create(HashFunction hash_func, HashCompare compare_func, - CacheKeyCopy copy_func, CacheItemDestructor destruct_func, + CacheKeyMove key_move_func, CacheItemDestructor destruct_func, size_t key_size, size_t value_size) { Cache *cache = calloc(1, sizeof(*cache)); @@ -330,7 +335,7 @@ Cache *ass_cache_create(HashFunction hash_func, HashCompare compare_func, cache->queue_last = &cache->queue_first; cache->hash_func = hash_func ? hash_func : hash_simple; cache->compare_func = compare_func ? compare_func : compare_simple; - cache->copy_func = copy_func ? copy_func : copy_simple; + cache->key_move_func = key_move_func ? key_move_func : key_move_simple; cache->destruct_func = destruct_func ? destruct_func : destruct_simple; cache->key_size = key_size; cache->value_size = value_size; @@ -363,7 +368,9 @@ bool ass_cache_get(Cache *cache, void *key, void *value_ptr) item->queue_next = NULL; } cache->hits++; + cache->key_move_func(NULL, key, cache->key_size); *value = (char *) item + CACHE_ITEM_SIZE; + item->ref_count++; return true; } item = item->next; @@ -372,12 +379,13 @@ bool ass_cache_get(Cache *cache, void *key, void *value_ptr) item = malloc(key_offs + cache->key_size); if (!item) { + cache->key_move_func(NULL, key, cache->key_size); *value = NULL; return false; } item->size = 0; item->cache = cache; - if (!cache->copy_func((char *) item + key_offs, key, cache->key_size)) { + if (!cache->key_move_func((char *) item + key_offs, key, cache->key_size)) { free(item); *value = NULL; return false; @@ -391,16 +399,13 @@ bool ass_cache_get(Cache *cache, void *key, void *value_ptr) item->next = *bucketptr; *bucketptr = item; - *cache->queue_last = item; - item->queue_prev = cache->queue_last; - cache->queue_last = &item->queue_next; + item->queue_prev = NULL; item->queue_next = NULL; - - item->ref_count = 0; + item->ref_count = 1; return false; } -void *ass_cache_get_key(void *value) +void *ass_cache_key(void *value) { CacheItem *item = value_to_item(value); return (char *) value + align_cache(item->cache->value_size); @@ -414,6 +419,10 @@ void ass_cache_commit(void *value, size_t item_size) Cache *cache = item->cache; cache->cache_size += item_size; cache->items++; + + *cache->queue_last = item; + item->queue_prev = cache->queue_last; + cache->queue_last = &item->queue_next; } static inline void destroy_item(Cache *cache, CacheItem *item) @@ -426,6 +435,8 @@ static inline void destroy_item(Cache *cache, CacheItem *item) void ass_cache_inc_ref(void *value) { + if (!value) + return; CacheItem *item = value_to_item(value); assert(item->size); item->ref_count++; @@ -433,6 +444,8 @@ void ass_cache_inc_ref(void *value) void ass_cache_dec_ref(void *value) { + if (!value) + return; CacheItem *item = value_to_item(value); assert(item->size && item->ref_count); @@ -498,7 +511,7 @@ void ass_cache_empty(Cache *cache) for (int i = 0; i < cache->buckets; i++) { CacheItem *item = cache->map[i]; while (item) { - assert(item->size); + assert(item->size && !item->ref_count); CacheItem *next = item->next; destroy_item(cache, item); item = next; @@ -522,34 +535,34 @@ void ass_cache_done(Cache *cache) Cache *ass_font_cache_create(void) { return ass_cache_create(font_hash, font_compare, - font_key_copy, font_destruct, + font_key_move, font_destruct, sizeof(ASS_FontDesc), sizeof(ASS_Font)); } Cache *ass_outline_cache_create(void) { return ass_cache_create(outline_hash, outline_compare, - outline_key_copy, outline_destruct, + outline_key_move, outline_destruct, sizeof(OutlineHashKey), sizeof(OutlineHashValue)); } Cache *ass_glyph_metrics_cache_create(void) { return ass_cache_create(glyph_metrics_hash, glyph_metrics_compare, - glyph_metric_key_copy, glyph_metric_destruct, + glyph_metric_key_move, glyph_metric_destruct, sizeof(GlyphMetricsHashKey), sizeof(GlyphMetricsHashValue)); } Cache *ass_bitmap_cache_create(void) { return ass_cache_create(bitmap_hash, bitmap_compare, - bitmap_key_copy, bitmap_destruct, + bitmap_key_move, bitmap_destruct, sizeof(BitmapHashKey), sizeof(BitmapHashValue)); } Cache *ass_composite_cache_create(void) { return ass_cache_create(composite_hash, composite_compare, - composite_key_copy, composite_destruct, + composite_key_move, composite_destruct, sizeof(CompositeHashKey), sizeof(CompositeHashValue)); } diff --git a/libass/ass_cache.h b/libass/ass_cache.h index 6cea269..cd72533 100644 --- a/libass/ass_cache.h +++ b/libass/ass_cache.h @@ -58,7 +58,7 @@ typedef struct { // Type-specific function pointers typedef unsigned(*HashFunction)(void *key, size_t key_size); typedef unsigned(*HashCompare)(void *a, void *b, size_t key_size); -typedef bool(*CacheKeyCopy)(void *dst, void *src, size_t key_size); +typedef bool(*CacheKeyMove)(void *dst, void *src, size_t key_size); typedef void(*CacheItemDestructor)(void *key, void *value); // cache hash keys @@ -104,10 +104,10 @@ typedef struct { } CompositeHashKey; Cache *ass_cache_create(HashFunction hash_func, HashCompare compare_func, - CacheKeyCopy copy_func, CacheItemDestructor destruct_func, + CacheKeyMove copy_func, CacheItemDestructor destruct_func, size_t key_size, size_t value_size); bool ass_cache_get(Cache *cache, void *key, void *value_ptr); -void *ass_cache_get_key(void *value); +void *ass_cache_key(void *value); void ass_cache_commit(void *value, size_t item_size); void ass_cache_inc_ref(void *value); void ass_cache_dec_ref(void *value); diff --git a/libass/ass_font.c b/libass/ass_font.c index d9dc7ba..5889b49 100644 --- a/libass/ass_font.c +++ b/libass/ass_font.c @@ -229,8 +229,12 @@ ASS_Font *ass_font_new(Cache *font_cache, ASS_Library *library, ASS_FontDesc *desc) { ASS_Font *font; - if (ass_cache_get(font_cache, desc, &font)) - return font->desc.family ? font : NULL; + if (ass_cache_get(font_cache, desc, &font)) { + if (font->desc.family) + return font; + ass_cache_dec_ref(font); + return NULL; + } if (!font) return NULL; @@ -238,7 +242,7 @@ ASS_Font *ass_font_new(Cache *font_cache, ASS_Library *library, font->ftlibrary = ftlibrary; font->shaper_priv = NULL; font->n_faces = 0; - ASS_FontDesc *new_desc = ass_cache_get_key(font); + ASS_FontDesc *new_desc = ass_cache_key(font); font->desc.family = new_desc->family; font->desc.bold = desc->bold; font->desc.italic = desc->italic; @@ -252,6 +256,7 @@ ASS_Font *ass_font_new(Cache *font_cache, ASS_Library *library, if (error == -1) { font->desc.family = NULL; ass_cache_commit(font, 1); + ass_cache_dec_ref(font); return NULL; } ass_cache_commit(font, 1); diff --git a/libass/ass_parse.c b/libass/ass_parse.c index e6db422..5698669 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -127,11 +127,11 @@ void update_font(ASS_Renderer *render_priv) val = 0; // normal desc.italic = val; + ass_cache_dec_ref(render_priv->state.font); render_priv->state.font = ass_font_new(render_priv->cache.font_cache, render_priv->library, render_priv->ftlibrary, render_priv->fontselect, &desc); - free(desc.family); if (render_priv->state.font) change_font_size(render_priv, render_priv->state.font_size); diff --git a/libass/ass_render.c b/libass/ass_render.c index 53d2681..29a5a3d 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -515,6 +515,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, ass_msg(render_priv->library, MSGL_WARN, "Clip vector parsing failed. Skipping."); ass_cache_commit(val, sizeof(BitmapHashKey) + sizeof(BitmapHashValue)); + ass_cache_dec_ref(val); return; } @@ -534,7 +535,10 @@ static void blend_vector_clip(ASS_Renderer *render_priv, } Bitmap *clip_bm = val->bm; - if (!clip_bm) return; + if (!clip_bm) { + ass_cache_dec_ref(val); + return; + } // Iterate through bitmaps and blend/clip them for (ASS_Image *cur = head; cur; cur = cur->next) { @@ -582,7 +586,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, nbuffer = ass_aligned_alloc(32, as * ah); if (!free_list_add(render_priv, nbuffer)) { ass_aligned_free(nbuffer); - return; + break; } // Blend together @@ -604,7 +608,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, nbuffer = ass_aligned_alloc(align, ns * h); if (!free_list_add(render_priv, nbuffer)) { ass_aligned_free(nbuffer); - return; + break; } // Blend together @@ -620,6 +624,8 @@ static void blend_vector_clip(ASS_Renderer *render_priv, } cur->bitmap = nbuffer; } + + ass_cache_dec_ref(val); } /** @@ -685,6 +691,11 @@ static ASS_Image *render_text(ASS_Renderer *render_priv) *tail = 0; blend_vector_clip(render_priv, head); + for (int i = 0; i < text_info->n_bitmaps; ++i) { + CombinedBitmapInfo *info = &text_info->combined_bitmaps[i]; + ass_cache_dec_ref(info->image); // XXX: not thread safe + } + return head; } @@ -921,9 +932,11 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event) static void free_render_context(ASS_Renderer *render_priv) { + ass_cache_dec_ref(render_priv->state.font); free(render_priv->state.family); ass_drawing_free(render_priv->state.clip_drawing); + render_priv->state.font = NULL; render_priv->state.family = NULL; render_priv->state.clip_drawing = NULL; @@ -1168,6 +1181,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) ass_drawing_hash(drawing); if(!ass_drawing_parse(drawing, 0)) { ass_cache_commit(val, 1); + ass_cache_dec_ref(val); return; } val->outline = outline_copy(&drawing->outline); @@ -1200,6 +1214,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) if (!val->outline) { ass_cache_commit(val, 1); + ass_cache_dec_ref(val); return; } @@ -1212,6 +1227,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) free(val->outline); val->outline = NULL; ass_cache_commit(val, 1); + ass_cache_dec_ref(val); return; } @@ -1238,8 +1254,10 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) ass_cache_commit(val, 1); } - if (!val->outline) + if (!val->outline) { + ass_cache_dec_ref(val); return; + } info->hash_key.u.outline.outline = val; info->outline = val->outline; @@ -1903,6 +1921,8 @@ static int parse_events(ASS_Renderer *render_priv, ASS_Event *event) // Fill glyph information info->symbol = code; info->font = render_priv->state.font; + if (!info->drawing) + ass_cache_inc_ref(info->font); for (i = 0; i < 4; ++i) { uint32_t clr = render_priv->state.c[i]; // VSFilter compatibility: apply fade only when it's positive @@ -2166,10 +2186,14 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, CombinedBitmapInfo *combined_info = text_info->combined_bitmaps; CombinedBitmapInfo *current_info = NULL; GlyphInfo *last_info = NULL; - for (int i = 0; i < text_info->length; ++i) { + for (int i = 0; i < text_info->length; i++) { GlyphInfo *info = text_info->glyphs + i; if (info->linebreak) linebreak = 1; - if (info->skip) continue; + if (info->skip) { + for (; info; info = info->next) + ass_cache_dec_ref(info->hash_key.u.outline.outline); + continue; + } for (; info; info = info->next) { OutlineBitmapHashKey *key = &info->hash_key.u.outline; @@ -2185,8 +2209,10 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, last_info = NULL; if (nb_bitmaps >= text_info->max_bitmaps) { size_t new_size = 2 * text_info->max_bitmaps; - if (!ASS_REALLOC_ARRAY(text_info->combined_bitmaps, new_size)) + if (!ASS_REALLOC_ARRAY(text_info->combined_bitmaps, new_size)) { + ass_cache_dec_ref(info->image); continue; + } text_info->max_bitmaps = new_size; combined_info = text_info->combined_bitmaps; } @@ -2217,49 +2243,56 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, current_info->x = current_info->y = INT_MAX; rectangle_reset(¤t_info->rect); rectangle_reset(¤t_info->rect_o); - current_info->bm = current_info->bm_o = current_info->bm_s = NULL; current_info->n_bm = current_info->n_bm_o = 0; + current_info->bm = current_info->bm_o = current_info->bm_s = NULL; + current_info->image = NULL; current_info->bitmap_count = current_info->max_bitmap_count = 0; current_info->bitmaps = malloc(MAX_SUB_BITMAPS_INITIAL * sizeof(BitmapRef)); - if (!current_info->bitmaps) + if (!current_info->bitmaps) { + ass_cache_dec_ref(info->image); continue; + } current_info->max_bitmap_count = MAX_SUB_BITMAPS_INITIAL; - ++nb_bitmaps; + nb_bitmaps++; } last_info = info; - if (!info->image || !current_info) + if (!info->image || !current_info) { + ass_cache_dec_ref(info->image); continue; + } if (current_info->bitmap_count >= current_info->max_bitmap_count) { size_t new_size = 2 * current_info->max_bitmap_count; - if (!ASS_REALLOC_ARRAY(current_info->bitmaps, new_size)) + if (!ASS_REALLOC_ARRAY(current_info->bitmaps, new_size)) { + ass_cache_dec_ref(info->image); continue; + } current_info->max_bitmap_count = new_size; } current_info->bitmaps[current_info->bitmap_count].image = info->image; current_info->bitmaps[current_info->bitmap_count].x = x; current_info->bitmaps[current_info->bitmap_count].y = y; - ++current_info->bitmap_count; + current_info->bitmap_count++; current_info->x = FFMIN(current_info->x, x); current_info->y = FFMIN(current_info->y, y); if (info->image->bm) { rectangle_combine(¤t_info->rect, info->image->bm, x, y); - ++current_info->n_bm; + current_info->n_bm++; } if (info->image->bm_o) { rectangle_combine(¤t_info->rect_o, info->image->bm_o, x, y); - ++current_info->n_bm_o; + current_info->n_bm_o++; } } } - for (int i = 0; i < nb_bitmaps; ++i) { + for (int i = 0; i < nb_bitmaps; i++) { CombinedBitmapInfo *info = &combined_info[i]; - for (int j = 0; j < info->bitmap_count; ++j) { + for (int j = 0; j < info->bitmap_count; j++) { info->bitmaps[j].x -= info->x; info->bitmaps[j].y -= info->y; } @@ -2271,7 +2304,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, info->bm = hv->bm; info->bm_o = hv->bm_o; info->bm_s = hv->bm_s; - free(info->bitmaps); + info->image = hv; continue; } if (!hv) @@ -2279,7 +2312,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, int bord = be_padding(info->filter.be); if (!bord && info->n_bm == 1) { - for (int j = 0; j < info->bitmap_count; ++j) { + for (int j = 0; j < info->bitmap_count; j++) { if (!info->bitmaps[j].image->bm) continue; info->bm = copy_bitmap(render_priv->engine, info->bitmaps[j].image->bm); @@ -2297,7 +2330,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, if (dst) { dst->left = info->rect.x_min - info->x - bord; dst->top = info->rect.y_min - info->y - bord; - for (int j = 0; j < info->bitmap_count; ++j) { + for (int j = 0; j < info->bitmap_count; j++) { Bitmap *src = info->bitmaps[j].image->bm; if (!src) continue; @@ -2313,7 +2346,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, } } if (!bord && info->n_bm_o == 1) { - for (int j = 0; j < info->bitmap_count; ++j) { + for (int j = 0; j < info->bitmap_count; j++) { if (!info->bitmaps[j].image->bm_o) continue; info->bm_o = copy_bitmap(render_priv->engine, info->bitmaps[j].image->bm_o); @@ -2331,7 +2364,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, if (dst) { dst->left = info->rect_o.x_min - info->x - bord; dst->top = info->rect_o.y_min - info->y - bord; - for (int j = 0; j < info->bitmap_count; ++j) { + for (int j = 0; j < info->bitmap_count; j++) { Bitmap *src = info->bitmaps[j].image->bm_o; if (!src) continue; @@ -2360,6 +2393,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, ass_cache_commit(hv, bitmap_size(hv->bm) + bitmap_size(hv->bm_o) + bitmap_size(hv->bm_s) + sizeof(CompositeHashKey) + sizeof(CompositeHashValue)); + info->image = hv; } text_info->n_bitmaps = nb_bitmaps; diff --git a/libass/ass_render.h b/libass/ass_render.h index 83dd1d8..ac7d347 100644 --- a/libass/ass_render.h +++ b/libass/ass_render.h @@ -125,8 +125,10 @@ typedef struct { int x, y; Rectangle rect, rect_o; - Bitmap *bm, *bm_o, *bm_s; // glyphs, outline, shadow bitmaps size_t n_bm, n_bm_o; + + Bitmap *bm, *bm_o, *bm_s; // glyphs, outline, shadow bitmaps + CompositeHashValue *image; } CombinedBitmapInfo; // describes a glyph diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c index 8cb8654..95222ae 100644 --- a/libass/ass_shaper.c +++ b/libass/ass_shaper.c @@ -208,8 +208,12 @@ get_cached_metrics(struct ass_shaper_metrics_data *metrics, FT_Face face, { GlyphMetricsHashValue *val; metrics->hash_key.glyph_index = glyph; - if (ass_cache_get(metrics->metrics_cache, &metrics->hash_key, &val)) - return val->metrics.width < 0 ? NULL : val; + if (ass_cache_get(metrics->metrics_cache, &metrics->hash_key, &val)) { + if (val->metrics.width >= 0) + return val; + ass_cache_dec_ref(val); + return NULL; + } if (!val) return NULL; @@ -219,6 +223,7 @@ get_cached_metrics(struct ass_shaper_metrics_data *metrics, FT_Face face, if (FT_Load_Glyph(face, glyph, load_flags)) { val->metrics.width = -1; ass_cache_commit(val, 1); + ass_cache_dec_ref(val); return NULL; } @@ -244,12 +249,13 @@ get_glyph(hb_font_t *font, void *font_data, hb_codepoint_t unicode, *glyph = FT_Face_GetCharVariantIndex(face, ass_font_index_magic(face, unicode), variation); else *glyph = FT_Get_Char_Index(face, ass_font_index_magic(face, unicode)); + if (!*glyph) + return false; // rotate glyph advances for @fonts while we still know the Unicode codepoints - if (*glyph != 0) - get_cached_metrics(metrics_priv, face, unicode, *glyph); - - return *glyph != 0; + GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, unicode, *glyph); + ass_cache_dec_ref(metrics); + return true; } static hb_position_t @@ -259,11 +265,12 @@ cached_h_advance(hb_font_t *font, void *font_data, hb_codepoint_t glyph, FT_Face face = font_data; struct ass_shaper_metrics_data *metrics_priv = user_data; GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, 0, glyph); - if (!metrics) return 0; - return metrics->metrics.horiAdvance; + hb_position_t advance = metrics->metrics.horiAdvance; + ass_cache_dec_ref(metrics); + return advance; } static hb_position_t @@ -273,19 +280,19 @@ cached_v_advance(hb_font_t *font, void *font_data, hb_codepoint_t glyph, FT_Face face = font_data; struct ass_shaper_metrics_data *metrics_priv = user_data; GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, 0, glyph); - if (!metrics) return 0; - return metrics->metrics.vertAdvance; - + hb_position_t advance = metrics->metrics.vertAdvance; + ass_cache_dec_ref(metrics); + return advance; } static hb_bool_t cached_h_origin(hb_font_t *font, void *font_data, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y, void *user_data) { - return 1; + return true; } static hb_bool_t @@ -295,14 +302,13 @@ cached_v_origin(hb_font_t *font, void *font_data, hb_codepoint_t glyph, FT_Face face = font_data; struct ass_shaper_metrics_data *metrics_priv = user_data; GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, 0, glyph); - if (!metrics) - return 0; + return false; *x = metrics->metrics.horiBearingX - metrics->metrics.vertBearingX; *y = metrics->metrics.horiBearingY - (-metrics->metrics.vertBearingY); - - return 1; + ass_cache_dec_ref(metrics); + return true; } static hb_position_t @@ -312,7 +318,7 @@ get_h_kerning(hb_font_t *font, void *font_data, hb_codepoint_t first, FT_Face face = font_data; FT_Vector kern; - if (FT_Get_Kerning (face, first, second, FT_KERNING_DEFAULT, &kern)) + if (FT_Get_Kerning(face, first, second, FT_KERNING_DEFAULT, &kern)) return 0; return kern.x; @@ -332,16 +338,15 @@ cached_extents(hb_font_t *font, void *font_data, hb_codepoint_t glyph, FT_Face face = font_data; struct ass_shaper_metrics_data *metrics_priv = user_data; GlyphMetricsHashValue *metrics = get_cached_metrics(metrics_priv, face, 0, glyph); - if (!metrics) - return 0; + return false; extents->x_bearing = metrics->metrics.horiBearingX; extents->y_bearing = metrics->metrics.horiBearingY; extents->width = metrics->metrics.width; extents->height = -metrics->metrics.height; - - return 1; + ass_cache_dec_ref(metrics); + return true; } static hb_bool_t @@ -354,15 +359,14 @@ get_contour_point(hb_font_t *font, void *font_data, hb_codepoint_t glyph, | FT_LOAD_IGNORE_TRANSFORM; if (FT_Load_Glyph(face, glyph, load_flags)) - return 0; + return false; if (point_index >= (unsigned)face->glyph->outline.n_points) - return 0; + return false; *x = face->glyph->outline.points[point_index].x; *y = face->glyph->outline.points[point_index].y; - - return 1; + return true; } /** -- cgit v1.2.3