static void bitmap_destruct(void *key, void *value)
{
BitmapHashValue *v = value;
+ BitmapHashKey *k = key;
if (v->bm)
ass_free_bitmap(v->bm);
if (v->bm_o)
ass_free_bitmap(v->bm_o);
if (v->bm_s)
ass_free_bitmap(v->bm_s);
+ if (k->type == BITMAP_CLIP)
+ free(k->u.clip.text);
free(key);
free(value);
}
return 0;
}
+static unsigned bitmap_hash(void *key, size_t key_size)
+{
+ BitmapHashKey *k = key;
+ switch (k->type) {
+ case BITMAP_OUTLINE: return outline_bitmap_hash(&k->u, key_size);
+ case BITMAP_CLIP: return clip_bitmap_hash(&k->u, key_size);
+ default: return 0;
+ }
+}
+
+static unsigned bitmap_compare (void *a, void *b, size_t key_size)
+{
+ BitmapHashKey *ak = a;
+ BitmapHashKey *bk = b;
+ if (ak->type != bk->type) return 0;
+ switch (ak->type) {
+ case BITMAP_OUTLINE: return outline_bitmap_compare(&ak->u, &bk->u, key_size);
+ case BITMAP_CLIP: return clip_bitmap_compare(&ak->u, &bk->u, key_size);
+ default: return 0;
+ }
+}
+
// composite cache
static void composite_destruct(void *key, void *value)
{
-// describes a bitmap; bitmaps with equivalents structs are considered identical
-START(bitmap, bitmap_hash_key)
+// describes an outline bitmap
+START(outline_bitmap, outline_bitmap_hash_key)
GENERIC(OutlineHashValue *, outline)
GENERIC(char, be) // blur edges
GENERIC(double, blur) // gaussian blur
GENERIC(int, shift_y)
FTVECTOR(advance) // subpixel shift vector
FTVECTOR(shadow_offset) // shadow subpixel shift
-END(BitmapHashKey)
+END(OutlineBitmapHashKey)
+
+// describe a clip mask bitmap
+START(clip_bitmap, clip_bitmap_hash_key)
+ STRING(text)
+END(ClipMaskHashKey)
// describes an outline glyph
START(glyph, glyph_hash_key)
Bitmap *clip_bm = NULL;
ASS_Image *cur;
ASS_Drawing *drawing = render_priv->state.clip_drawing;
- //GlyphHashKey key;
- //GlyphHashValue *val;
+ BitmapHashKey key;
+ BitmapHashValue *val;
int error;
if (!drawing)
return;
- // FIXME: reimplement cache
-#if 0
// Try to get mask from cache
- ass_drawing_hash(drawing);
memset(&key, 0, sizeof(key));
- key.ch = -2;
- key.drawing_hash = drawing->hash;
- val = ass_cache_get(render_priv->cache.glyph_cache, &key);
+ key.type = BITMAP_CLIP;
+ key.u.clip.text = strdup(drawing->text);
+ val = ass_cache_get(render_priv->cache.bitmap_cache, &key);
if (val) {
- clip_bm = (FT_BitmapGlyph) val->glyph;
+ clip_bm = val->bm;
} else {
-#endif
- //GlyphHashValue v;
+ BitmapHashValue v;
// Not found in cache, parse and rasterize it
outline = ass_drawing_parse(drawing, 1);
"Clip vector rasterization failed: %d. Skipping.", error);
}
- //clip_bm = (FT_BitmapGlyph) glyph;
-
-#if 0
// Add to cache
memset(&v, 0, sizeof(v));
- v.glyph = glyph;
- ass_cache_put(render_priv->cache.glyph_cache, &key, &v);
+ v.bm = clip_bm;
+ ass_cache_put(render_priv->cache.bitmap_cache, &key, &v);
}
-#endif
blend_vector_error:
if (!clip_bm) goto blend_vector_exit;
}
blend_vector_exit:
- ass_free_bitmap(clip_bm);
ass_drawing_free(render_priv->state.clip_drawing);
render_priv->state.clip_drawing = 0;
}
fill_glyph_hash(render_priv, &key, drawing, symbol);
val = ass_cache_get(render_priv->cache.outline_cache, &key);
if (val) {
- info->hash_key.outline = val;
+ info->hash_key.u.outline.outline = val;
info->outline = val->outline;
info->border = val->border;
info->bbox = val->bbox_scaled;
v.asc = drawing->asc;
v.desc = drawing->desc;
}
- info->hash_key.outline =
+ info->hash_key.u.outline.outline =
ass_cache_put(render_priv->cache.outline_cache, &key, &v);
}
}
get_bitmap_glyph(ASS_Renderer *render_priv, GlyphInfo *info)
{
BitmapHashValue *val;
- BitmapHashKey *key = &info->hash_key;
+ OutlineBitmapHashKey *key = &info->hash_key.u.outline;
val = ass_cache_get(render_priv->cache.bitmap_cache, key);
* Prepare bitmap hash key of a glyph
*/
static void
-fill_bitmap_hash(ASS_Renderer *priv, BitmapHashKey *hash_key)
+fill_bitmap_hash(ASS_Renderer *priv, OutlineBitmapHashKey *hash_key)
{
hash_key->frx = rot_key(priv->state.frx);
hash_key->fry = rot_key(priv->state.fry);
}
// fill bitmap hash
- fill_bitmap_hash(render_priv, &glyphs[text_info->length].hash_key);
+ glyphs[text_info->length].hash_key.type = BITMAP_OUTLINE;
+ fill_bitmap_hash(render_priv, &glyphs[text_info->length].hash_key.u.outline);
text_info->length++;
for (i = 0; i < text_info->length; ++i) {
GlyphInfo *info = glyphs + i;
+ OutlineBitmapHashKey *key = &info->hash_key.u.outline;
- if (info->hash_key.frx || info->hash_key.fry
- || info->hash_key.frz || info->hash_key.fax
- || info->hash_key.fay) {
- info->hash_key.shift_x = info->pos.x + double_to_d6(device_x - center.x);
- info->hash_key.shift_y =
- -(info->pos.y + double_to_d6(device_y - center.y));
+ if (key->frx || key->fry || key->frz || key->fax || key->fay) {
+ key->shift_x = info->pos.x + double_to_d6(device_x - center.x);
+ key->shift_y = -(info->pos.y + double_to_d6(device_y - center.y));
} else {
- info->hash_key.shift_x = 0;
- info->hash_key.shift_y = 0;
+ key->shift_x = 0;
+ key->shift_y = 0;
}
}
}
device_x *= render_priv->font_scale_x;
for (i = 0; i < text_info->length; ++i) {
GlyphInfo *g = glyphs + i;
+ OutlineBitmapHashKey *key = &g->hash_key.u.outline;
g->pos.x *= render_priv->font_scale_x;
- g->hash_key.advance.x =
+ key->advance.x =
double_to_d6(device_x - (int) device_x +
d6_to_double(g->pos.x & SUBPIXEL_MASK)) & ~SUBPIXEL_ACCURACY;
- g->hash_key.advance.y =
+ key->advance.y =
double_to_d6(device_y - (int) device_y +
d6_to_double(g->pos.y & SUBPIXEL_MASK)) & ~SUBPIXEL_ACCURACY;
get_bitmap_glyph(render_priv, glyphs + i);