summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libass/ass_cache.c63
-rw-r--r--libass/ass_cache.h37
-rw-r--r--libass/ass_cache_template.h19
-rw-r--r--libass/ass_render.c47
-rw-r--r--libass/ass_render.h2
-rw-r--r--libass/ass_render_api.c2
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);