diff options
-rw-r--r-- | libass/ass_cache.c | 63 | ||||
-rw-r--r-- | libass/ass_cache.h | 37 | ||||
-rw-r--r-- | libass/ass_cache_template.h | 19 | ||||
-rw-r--r-- | libass/ass_render.c | 47 | ||||
-rw-r--r-- | libass/ass_render.h | 2 | ||||
-rw-r--r-- | libass/ass_render_api.c | 2 |
6 files changed, 112 insertions, 58 deletions
diff --git a/libass/ass_cache.c b/libass/ass_cache.c index 5ea4f1d..15f7376 100644 --- a/libass/ass_cache.c +++ b/libass/ass_cache.c @@ -29,7 +29,7 @@ #include "ass_cache.h" // type-specific functions -// create hash/compare functions for bitmap, glyph and composite cache +// create hash/compare functions for bitmap, outline and composite cache #define CREATE_HASH_FUNCTIONS #include "ass_cache_template.h" #define CREATE_COMPARISON_FUNCTIONS @@ -96,41 +96,56 @@ static size_t bitmap_size(void *value, size_t value_size) return 0; } -// glyph cache -static void glyph_destruct(void *key, void *value) +// composite cache +static void composite_destruct(void *key, void *value) { - GlyphHashValue *v = value; - if (v->outline) - outline_free(v->lib, v->outline); - if (v->border) - outline_free(v->lib, v->border); + CompositeHashValue *v = value; + free(v->a); + free(v->b); free(key); free(value); } -static size_t glyph_size(void *value, size_t value_size) +// outline cache + +static unsigned outline_hash(void *key, size_t key_size) { -#if 0 - GlyphHashValue *val = value; - if (val->glyph && val->glyph->format == FT_GLYPH_FORMAT_BITMAP) { - FT_Bitmap *bitmap = &((FT_BitmapGlyph) val->glyph)->bitmap; - return bitmap->rows * bitmap->pitch; + OutlineHashKey *k = key; + switch (k->type) { + case OUTLINE_GLYPH: return glyph_hash(&k->u, key_size); + case OUTLINE_DRAWING: return drawing_hash(&k->u, key_size); + default: return 0; } -#endif - return 0; } -// composite cache -static void composite_destruct(void *key, void *value) +static unsigned outline_compare(void *a, void *b, size_t key_size) { - CompositeHashValue *v = value; - free(v->a); - free(v->b); + OutlineHashKey *ak = a; + OutlineHashKey *bk = b; + if (ak->type != bk->type) return 0; + switch (ak->type) { + case OUTLINE_GLYPH: return glyph_compare(&ak->u, &bk->u, key_size); + case OUTLINE_DRAWING: return drawing_compare(&ak->u, &bk->u, key_size); + default: return 0; + } +} + +static void outline_destruct(void *key, void *value) +{ + OutlineHashValue *v = value; + OutlineHashKey *k = key; + if (v->outline) + outline_free(v->lib, v->outline); + if (v->border) + outline_free(v->lib, v->border); + if (k->type == OUTLINE_DRAWING) + free(k->u.drawing.text); free(key); free(value); } + // Cache data typedef struct cache_item { void *key; @@ -279,10 +294,10 @@ Cache *ass_font_cache_create(void) (ItemSize)NULL, sizeof(ASS_FontDesc), sizeof(ASS_Font)); } -Cache *ass_glyph_cache_create(void) +Cache *ass_outline_cache_create(void) { - return ass_cache_create(glyph_hash, glyph_compare, glyph_destruct, - glyph_size, sizeof(GlyphHashKey), sizeof(GlyphHashValue)); + return ass_cache_create(outline_hash, outline_compare, outline_destruct, + NULL, sizeof(OutlineHashKey), sizeof(OutlineHashValue)); } Cache *ass_bitmap_cache_create(void) diff --git a/libass/ass_cache.h b/libass/ass_cache.h index cf2c400..0ad7cae 100644 --- a/libass/ass_cache.h +++ b/libass/ass_cache.h @@ -26,10 +26,31 @@ typedef struct cache Cache; -// Create definitions for bitmap, glyph and composite hash keys +// Create definitions for bitmap, outline and composite hash keys #define CREATE_STRUCT_DEFINITIONS #include "ass_cache_template.h" +// Type-specific function pointers +typedef unsigned(*HashFunction)(void *key, size_t key_size); +typedef size_t(*ItemSize)(void *value, size_t value_size); +typedef unsigned(*HashCompare)(void *a, void *b, size_t key_size); +typedef void(*CacheItemDestructor)(void *key, void *value); + +// cache hash keys + +typedef struct outline_hash_key { + enum { + OUTLINE_GLYPH, + OUTLINE_DRAWING, + } type; + union { + GlyphHashKey glyph; + DrawingHashKey drawing; + } u; +} OutlineHashKey; + +// cache values + typedef struct { Bitmap *bm; // the actual bitmaps Bitmap *bm_o; @@ -46,15 +67,9 @@ typedef struct { FT_Outline *outline; FT_Outline *border; FT_BBox bbox_scaled; // bbox after scaling, but before rotation - FT_Vector advance; // 26.6, advance distance to the next bitmap in line - int asc, desc; // ascender/descender of a drawing -} GlyphHashValue; - -// Type-specific function pointers -typedef unsigned(*HashFunction)(void *key, size_t key_size); -typedef size_t(*ItemSize)(void *value, size_t value_size); -typedef unsigned(*HashCompare)(void *a, void *b, size_t key_size); -typedef void(*CacheItemDestructor)(void *key, void *value); + FT_Vector advance; // 26.6, advance distance to the next outline in line + int asc, desc; // ascender/descender +} OutlineHashValue; Cache *ass_cache_create(HashFunction hash_func, HashCompare compare_func, CacheItemDestructor destruct_func, ItemSize size_func, @@ -66,7 +81,7 @@ void ass_cache_stats(Cache *cache, size_t *size, unsigned *hits, unsigned *misses, unsigned *count); void ass_cache_done(Cache *cache); Cache *ass_font_cache_create(void); -Cache *ass_glyph_cache_create(void); +Cache *ass_outline_cache_create(void); Cache *ass_bitmap_cache_create(void); Cache *ass_composite_cache_create(void); diff --git a/libass/ass_cache_template.h b/libass/ass_cache_template.h index 9243ada..cdb5826 100644 --- a/libass/ass_cache_template.h +++ b/libass/ass_cache_template.h @@ -4,6 +4,8 @@ typedef struct structname { #define GENERIC(type, member) \ type member; +#define STRING(member) \ + char *member; #define FTVECTOR(member) \ FT_Vector member; #define BITMAPHASHKEY(member) \ @@ -21,6 +23,8 @@ return // conditions follow #define GENERIC(type, member) \ a->member == b->member && +#define STRING(member) \ + strcmp(a->member, b->member) == 0 && #define FTVECTOR(member) \ a->member.x == b->member.x && a->member.y == b->member.y && #define BITMAPHASHKEY(member) \ @@ -38,6 +42,8 @@ unsigned hval = FNV1_32A_INIT; #define GENERIC(type, member) \ hval = fnv_32a_buf(&p->member, sizeof(p->member), hval); +#define STRING(member) \ + hval = fnv_32a_str(p->member, hval); #define FTVECTOR(member) GENERIC(, member.x); GENERIC(, member.y); #define BITMAPHASHKEY(member) { \ unsigned temp = bitmap_hash(&p->member, sizeof(p->member)); \ @@ -98,6 +104,18 @@ START(glyph, glyph_hash_key) GENERIC(unsigned, border_style) END(GlyphHashKey) +// describes an outline drawing +START(drawing, drawing_hash_key) + GENERIC(unsigned, scale_x) + GENERIC(unsigned, scale_y) + GENERIC(int, pbo) + FTVECTOR(outline) + GENERIC(unsigned, border_style) + GENERIC(int, scale) + GENERIC(unsigned, hash) + STRING(text) +END(DrawingHashKey) + // Cache for composited bitmaps START(composite, composite_hash_key) GENERIC(int, aw) @@ -117,6 +135,7 @@ END(CompositeHashKey) #undef START #undef GENERIC +#undef STRING #undef FTVECTOR #undef BITMAPHASHKEY #undef END diff --git a/libass/ass_render.c b/libass/ass_render.c index b036bf2..55d9596 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -63,7 +63,7 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library) priv->cache.font_cache = ass_font_cache_create(); priv->cache.bitmap_cache = ass_bitmap_cache_create(); priv->cache.composite_cache = ass_composite_cache_create(); - priv->cache.glyph_cache = ass_glyph_cache_create(); + priv->cache.outline_cache = ass_outline_cache_create(); priv->cache.glyph_max = GLYPH_CACHE_MAX; priv->cache.bitmap_max_size = BITMAP_CACHE_MAX_SIZE; @@ -102,7 +102,7 @@ void ass_renderer_done(ASS_Renderer *render_priv) ass_cache_done(render_priv->cache.font_cache); ass_cache_done(render_priv->cache.bitmap_cache); ass_cache_done(render_priv->cache.composite_cache); - ass_cache_done(render_priv->cache.glyph_cache); + ass_cache_done(render_priv->cache.outline_cache); ass_free_images(render_priv->images_root); ass_free_images(render_priv->prev_images_root); @@ -536,8 +536,8 @@ static void blend_vector_clip(ASS_Renderer *render_priv, Bitmap *clip_bm = NULL; ASS_Image *cur; ASS_Drawing *drawing = render_priv->state.clip_drawing; - GlyphHashKey key; - GlyphHashValue *val; + //GlyphHashKey key; + //GlyphHashValue *val; int error; if (!drawing) @@ -556,7 +556,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, clip_bm = (FT_BitmapGlyph) val->glyph; } else { #endif - GlyphHashValue v; + //GlyphHashValue v; // Not found in cache, parse and rasterize it outline = ass_drawing_parse(drawing, 1); @@ -1004,20 +1004,24 @@ static void stroke_outline(ASS_Renderer *render_priv, FT_Outline *outline, * \brief Prepare glyph hash */ static void -fill_glyph_hash(ASS_Renderer *priv, GlyphHashKey *key, +fill_glyph_hash(ASS_Renderer *priv, OutlineHashKey *outline_key, ASS_Drawing *drawing, uint32_t ch) { if (drawing->hash) { + DrawingHashKey *key = &outline_key->u.drawing; + outline_key->type = OUTLINE_DRAWING; key->scale_x = double_to_d16(priv->state.scale_x); key->scale_y = double_to_d16(priv->state.scale_y); - key->outline.x = priv->state.border_x * 0xFFFF; - key->outline.y = priv->state.border_y * 0xFFFF; + key->outline.x = double_to_d16(priv->state.border_x); + key->outline.y = double_to_d16(priv->state.border_y); key->border_style = priv->state.style->BorderStyle; - key->drawing_hash = drawing->hash; - // not very clean, but works - key->size = drawing->scale; - key->ch = -1; + key->hash = drawing->hash; + key->text = strdup(drawing->text); + key->pbo = drawing->pbo; + key->scale = drawing->scale; } else { + GlyphHashKey *key = &outline_key->u.glyph; + outline_key->type = OUTLINE_GLYPH; key->font = priv->state.font; key->size = priv->state.font_size; key->ch = ch; @@ -1025,8 +1029,8 @@ fill_glyph_hash(ASS_Renderer *priv, GlyphHashKey *key, key->italic = priv->state.italic; key->scale_x = double_to_d16(priv->state.scale_x); key->scale_y = double_to_d16(priv->state.scale_y); - key->outline.x = priv->state.border_x * 0xFFFF; - key->outline.y = priv->state.border_y * 0xFFFF; + key->outline.x = double_to_d16(priv->state.border_x); + key->outline.y = double_to_d16(priv->state.border_y); key->flags = priv->state.flags; key->border_style = priv->state.style->BorderStyle; } @@ -1045,14 +1049,14 @@ static void get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info, ASS_Drawing *drawing) { - GlyphHashValue *val; - GlyphHashKey key; + OutlineHashValue *val; + OutlineHashKey key; memset(&key, 0, sizeof(key)); memset(info, 0, sizeof(GlyphInfo)); fill_glyph_hash(render_priv, &key, drawing, symbol); - val = ass_cache_get(render_priv->cache.glyph_cache, &key); + val = ass_cache_get(render_priv->cache.outline_cache, &key); if (val) { info->outline = val->outline; info->border = val->border; @@ -1064,7 +1068,7 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info, drawing->desc = val->desc; } } else { - GlyphHashValue v; + OutlineHashValue v; if (drawing->hash) { if(!ass_drawing_parse(drawing, 0)) return; @@ -1103,7 +1107,8 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info, render_priv->border_scale)); } else if ((render_priv->state.border_x > 0 || render_priv->state.border_y > 0) - && key.scale_x && key.scale_y) { + && double_to_d6(render_priv->state.scale_x) + && double_to_d6(render_priv->state.scale_y)) { outline_copy(render_priv->ftlibrary, info->outline, &info->border); stroke_outline(render_priv, info->border, @@ -1123,7 +1128,7 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info, v.asc = drawing->asc; v.desc = drawing->desc; } - ass_cache_put(render_priv->cache.glyph_cache, &key, &v); + ass_cache_put(render_priv->cache.outline_cache, &key, &v); } } @@ -2067,7 +2072,7 @@ static void check_cache_limits(ASS_Renderer *priv, CacheStore *cache) ass_free_images(priv->prev_images_root); priv->prev_images_root = 0; } - ass_cache_empty(cache->glyph_cache, cache->glyph_max); + ass_cache_empty(cache->outline_cache, cache->glyph_max); } /** diff --git a/libass/ass_render.h b/libass/ass_render.h index 0876589..de2377a 100644 --- a/libass/ass_render.h +++ b/libass/ass_render.h @@ -204,7 +204,7 @@ typedef struct { typedef struct { Cache *font_cache; - Cache *glyph_cache; + Cache *outline_cache; Cache *bitmap_cache; Cache *composite_cache; size_t glyph_max; diff --git a/libass/ass_render_api.c b/libass/ass_render_api.c index 5995d31..5b02b46 100644 --- a/libass/ass_render_api.c +++ b/libass/ass_render_api.c @@ -25,7 +25,7 @@ static void ass_reconfigure(ASS_Renderer *priv) ASS_Settings *settings = &priv->settings; priv->render_id++; - ass_cache_empty(priv->cache.glyph_cache, 0); + ass_cache_empty(priv->cache.outline_cache, 0); ass_cache_empty(priv->cache.bitmap_cache, 0); ass_cache_empty(priv->cache.composite_cache, 0); ass_free_images(priv->prev_images_root); |