summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr.Smile <vabnick@gmail.com>2019-05-20 00:50:49 +0300
committerDr.Smile <vabnick@gmail.com>2019-05-20 00:50:49 +0300
commitb69d38118e9f241e864774d56ece71b3dd114888 (patch)
treeac18bc2d4485f29acc7e5cbe8cedf989311d8731
parentc80f332798238731e1ddf1b541748f3d5c8030f3 (diff)
downloadlibass-b69d38118e9f241e864774d56ece71b3dd114888.tar.bz2
libass-b69d38118e9f241e864774d56ece71b3dd114888.tar.xz
renderer: move outline stroking immediately before rasterization
-rw-r--r--libass/ass_render.c120
-rw-r--r--libass/ass_render.h5
2 files changed, 58 insertions, 67 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 4badaad..cb6bd34 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -1147,8 +1147,8 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
}
info->outline = val;
- info->outline_transform.scale = scale;
- info->outline_transform.offset = offset;
+ info->transform.scale = scale;
+ info->transform.offset = offset;
info->bbox.x_min = lrint(val->cbox.x_min * scale.x + offset.x);
info->bbox.y_min = lrint(val->cbox.y_min * scale.y + offset.y);
@@ -1161,62 +1161,6 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
}
info->asc = lrint(asc * scale.y);
info->desc = lrint(desc * scale.y);
-
- if (info->border_style == 3) {
- key.type = OUTLINE_BOX;
- val = ass_cache_get(priv->cache.outline_cache, &key, priv);
- if (!val || !val->valid) {
- ass_cache_dec_ref(val);
- return;
- }
-
- double w = 64 * priv->border_scale;
- ASS_DVector bord = { info->border_x * w, info->border_y * w };
- double width = info->hspacing_scaled + info->advance.x;
- double height = info->asc + info->desc;
-
- ASS_DVector orig_scale;
- orig_scale.x = info->scale_x * info->scale_fix;
- orig_scale.y = info->scale_y * info->scale_fix;
-
- // Emulate the WTFish behavior of VSFilter, i.e. double-scale
- // the sizes of the opaque box.
- bord.x *= orig_scale.x;
- bord.y *= orig_scale.y;
- width *= orig_scale.x;
- height *= orig_scale.y;
-
- // to avoid gaps
- bord.x = FFMAX(64, bord.x);
- bord.y = FFMAX(64, bord.y);
-
- scale.x = (width + 2 * bord.x) / 64;
- scale.y = (height + 2 * bord.y) / 64;
- offset.x = -bord.x;
- offset.y = -bord.y - info->asc;
- } else {
- key.type = OUTLINE_BORDER;
- BorderHashKey *k = &key.u.border;
- k->outline = val;
-
- // XXX: account for full transformation instead of only scale
- scale.x = frexp(scale.x, &k->scale_ord_x);
- scale.y = frexp(scale.y, &k->scale_ord_y);
-
- double w = priv->border_scale * (64 / STROKER_PRECISION);
- k->border.x = lrint(w * info->border_x / scale.x);
- k->border.y = lrint(w * info->border_y / scale.y);
-
- val = ass_cache_get(priv->cache.outline_cache, &key, priv);
- if (!val || !val->valid) {
- ass_cache_dec_ref(val);
- return;
- }
- }
-
- info->border = val;
- info->border_transform.scale = scale;
- info->border_transform.offset = offset;
}
size_t ass_outline_construct(void *key, void *value, void *priv)
@@ -1379,15 +1323,65 @@ get_bitmap_glyph(ASS_Renderer *render_priv, GlyphInfo *info)
{
if (!info->outline || info->symbol == '\n' || info->symbol == 0 || info->skip) {
ass_cache_dec_ref(info->outline);
- ass_cache_dec_ref(info->border);
return;
}
+ ASS_Transform tr;
+ OutlineHashKey key;
+ if (info->border_style == 3) {
+ key.type = OUTLINE_BOX;
+
+ double w = 64 * render_priv->border_scale;
+ ASS_DVector bord = { info->border_x * w, info->border_y * w };
+ double width = info->hspacing_scaled + info->advance.x;
+ double height = info->asc + info->desc;
+
+ ASS_DVector orig_scale;
+ orig_scale.x = info->scale_x * info->scale_fix;
+ orig_scale.y = info->scale_y * info->scale_fix;
+
+ // Emulate the WTFish behavior of VSFilter, i.e. double-scale
+ // the sizes of the opaque box.
+ bord.x *= orig_scale.x;
+ bord.y *= orig_scale.y;
+ width *= orig_scale.x;
+ height *= orig_scale.y;
+
+ // to avoid gaps
+ bord.x = FFMAX(64, bord.x);
+ bord.y = FFMAX(64, bord.y);
+
+ tr.scale.x = (width + 2 * bord.x) / 64;
+ tr.scale.y = (height + 2 * bord.y) / 64;
+ tr.offset.x = -bord.x;
+ tr.offset.y = -bord.y - info->asc;
+ } else {
+ key.type = OUTLINE_BORDER;
+ BorderHashKey *k = &key.u.border;
+ k->outline = info->outline;
+
+ // XXX: account for full transformation instead of only scale
+ tr.scale.x = frexp(info->transform.scale.x, &k->scale_ord_x);
+ tr.scale.y = frexp(info->transform.scale.y, &k->scale_ord_y);
+ tr.offset = info->transform.offset;
+
+ double w = render_priv->border_scale * (64 / STROKER_PRECISION);
+ k->border.x = lrint(w * info->border_x / tr.scale.x);
+ k->border.y = lrint(w * info->border_y / tr.scale.y);
+ }
+
+ OutlineHashValue *border =
+ ass_cache_get(render_priv->cache.outline_cache, &key, render_priv);
+ if (!border || !border->valid) {
+ ass_cache_dec_ref(border);
+ border = NULL;
+ }
+
double m[3][3];
calc_transform_matrix(render_priv, info, m);
- info->image = get_bitmap(render_priv, info->outline, &info->outline_transform, m);
- info->image_o = get_bitmap(render_priv, info->border, &info->border_transform, m);
+ info->image = get_bitmap(render_priv, info->outline, &info->transform, m);
+ info->image_o = get_bitmap(render_priv, border, &tr, m);
}
size_t ass_bitmap_construct(void *key, void *value, void *priv)
@@ -2161,10 +2155,8 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv,
GlyphInfo *info = text_info->glyphs + i;
if (info->linebreak) linebreak = 1;
if (info->skip) {
- for (; info; info = info->next) {
+ for (; info; info = info->next)
ass_cache_dec_ref(info->outline);
- ass_cache_dec_ref(info->border);
- }
continue;
}
for (; info; info = info->next) {
diff --git a/libass/ass_render.h b/libass/ass_render.h
index f8d84f9..5779017 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -134,9 +134,8 @@ typedef struct glyph_info {
char *drawing_text;
int drawing_scale;
int drawing_pbo;
- OutlineHashValue *outline, *border;
- ASS_Transform outline_transform;
- ASS_Transform border_transform;
+ OutlineHashValue *outline;
+ ASS_Transform transform;
ASS_Rect bbox;
ASS_Vector pos;
ASS_Vector offset;