From cad1caedb22f94458eefaa9f8afcc31fd180a206 Mon Sep 17 00:00:00 2001 From: Oleg Oshmyan Date: Thu, 4 Sep 2014 22:02:21 +0200 Subject: Fix caching of combined bitmaps after complex shaping --- libass/ass_cache.c | 2 +- libass/ass_cache_template.h | 10 +++++++++- libass/ass_render.c | 18 ++++++++++-------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libass/ass_cache.c b/libass/ass_cache.c index 6baa924..e5e77fc 100644 --- a/libass/ass_cache.c +++ b/libass/ass_cache.c @@ -132,7 +132,7 @@ static void composite_destruct(void *key, void *value) ass_free_bitmap(v->bm_o); if (v->bm_s) ass_free_bitmap(v->bm_s); - free(k->str); + free(k->str.data); free(key); free(value); } diff --git a/libass/ass_cache_template.h b/libass/ass_cache_template.h index c91c897..29b534c 100644 --- a/libass/ass_cache_template.h +++ b/libass/ass_cache_template.h @@ -6,6 +6,8 @@ type member; #define STRING(member) \ char *member; +#define BINSTRING(member) \ + struct { size_t size; void *data; } member; #define FTVECTOR(member) \ FT_Vector member; #define BITMAPHASHKEY(member) \ @@ -25,6 +27,9 @@ a->member == b->member && #define STRING(member) \ strcmp(a->member, b->member) == 0 && +#define BINSTRING(member) \ + a->member.size == b->member.size && \ + memcmp(a->member.data, b->member.data, a->member.size) == 0 && #define FTVECTOR(member) \ a->member.x == b->member.x && a->member.y == b->member.y && #define BITMAPHASHKEY(member) \ @@ -44,6 +49,9 @@ hval = fnv_32a_buf(&p->member, sizeof(p->member), hval); #define STRING(member) \ hval = fnv_32a_str(p->member, hval); +#define BINSTRING(member) \ + hval = fnv_32a_buf(&p->member.size, sizeof(p->member.size), hval); \ + hval = fnv_32a_buf(p->member.data, p->member.size, hval); #define FTVECTOR(member) GENERIC(, member.x); GENERIC(, member.y); #define BITMAPHASHKEY(member) { \ unsigned temp = bitmap_hash(&p->member, sizeof(p->member)); \ @@ -152,7 +160,7 @@ START(composite, composite_hash_key) GENERIC(int, shift_x) GENERIC(int, shift_y) FTVECTOR(advance) - STRING(str) + BINSTRING(str) END(CompositeHashKey) #undef START diff --git a/libass/ass_render.c b/libass/ass_render.c index 832ba79..0cec412 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1103,7 +1103,8 @@ static void fill_composite_hash(CompositeHashKey *hk, CombinedBitmapInfo *info) hk->border_style = info->border_style; hk->has_outline = info->has_outline; hk->is_drawing = info->is_drawing; - hk->str = info->str; + hk->str.size = info->str_length; + hk->str.data = info->str; hk->chars = info->chars; hk->shadow_x = info->shadow_x; hk->shadow_y = info->shadow_y; @@ -2447,9 +2448,10 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, current_info->bm = current_info->bm_o = current_info->bm_s = NULL; - current_info->max_str_length = MAX_STR_LENGTH_INITIAL; + current_info->max_str_length = + MAX_STR_LENGTH_INITIAL * sizeof(info->glyph_index); current_info->str_length = 0; - current_info->str = malloc(MAX_STR_LENGTH_INITIAL); + current_info->str = malloc(current_info->max_str_length); current_info->chars = 0; current_info->w = current_info->h = current_info->o_w = current_info->o_h = 0; @@ -2459,19 +2461,19 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, if(info->drawing){ free(current_info->str); current_info->str = strdup(info->drawing->text); + current_info->str_length = strlen(info->drawing->text); current_info->is_drawing = 1; ass_drawing_free(info->drawing); }else{ - current_info->str_length += - ass_utf8_put_char( - current_info->str + current_info->str_length, - info->symbol); + int length = current_info->str_length; current_info->chars++; - if(current_info->str_length > current_info->max_str_length - 5){ + current_info->str_length += sizeof(info->glyph_index); + if(current_info->str_length > current_info->max_str_length){ current_info->max_str_length *= 2; current_info->str = realloc(current_info->str, current_info->max_str_length); } + *(int *)(current_info->str + length) = info->glyph_index; } current_info->has_outline = current_info->has_outline || !!info->bm_o; -- cgit v1.2.3