summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorDr.Smile <vabnick@gmail.com>2017-04-08 20:55:41 +0300
committerDr.Smile <vabnick@gmail.com>2017-07-31 06:27:24 +0300
commitabfa6cfdb045d16383b72c78b2ee60929c575a87 (patch)
treeb403ec197b68725ee0ae8bdc3007fed1e10133ac /libass
parent49eb2d2ecdc12d2dcd3af8ca00067cb4161679ff (diff)
downloadlibass-abfa6cfdb045d16383b72c78b2ee60929c575a87.tar.bz2
libass-abfa6cfdb045d16383b72c78b2ee60929c575a87.tar.xz
renderer: fix handling of empty outlines
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_bitmap.c26
-rw-r--r--libass/ass_bitmap.h6
-rw-r--r--libass/ass_cache.h2
-rw-r--r--libass/ass_render.c45
4 files changed, 41 insertions, 38 deletions
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c
index f369e25..7d991bf 100644
--- a/libass/ass_bitmap.c
+++ b/libass/ass_bitmap.c
@@ -202,15 +202,6 @@ Bitmap *outline_to_bitmap(ASS_Renderer *render_priv,
if (bord < 0 || bord > INT_MAX / 2)
return NULL;
-
- if (rst->x_min >= rst->x_max || rst->y_min >= rst->y_max) {
- Bitmap *bm = alloc_bitmap(render_priv->engine, 2 * bord, 2 * bord, true);
- if (!bm)
- return NULL;
- bm->left = bm->top = -bord;
- return bm;
- }
-
if (rst->x_max > INT_MAX - 63 || rst->y_max > INT_MAX - 63)
return NULL;
@@ -443,9 +434,9 @@ int be_padding(int be)
return FFMAX(128 - be, 0);
}
-int outline_to_bitmap2(ASS_Renderer *render_priv, ASS_Outline *outline,
- ASS_Outline *border1, ASS_Outline *border2,
- Bitmap **bm_g, Bitmap **bm_o)
+bool outline_to_bitmap2(ASS_Renderer *render_priv, ASS_Outline *outline,
+ ASS_Outline *border1, ASS_Outline *border2,
+ Bitmap **bm_g, Bitmap **bm_o)
{
assert(bm_g && bm_o);
*bm_g = *bm_o = NULL;
@@ -457,19 +448,20 @@ int outline_to_bitmap2(ASS_Renderer *render_priv, ASS_Outline *outline,
if (border2 && !border2->n_points)
border2 = NULL;
- if (outline)
+ if (outline) {
*bm_g = outline_to_bitmap(render_priv, outline, NULL, 1);
- if (!*bm_g)
- return 1;
+ if (!*bm_g)
+ return false;
+ }
if (border1 || border2) {
*bm_o = outline_to_bitmap(render_priv, border1, border2, 1);
if (!*bm_o) {
- return 1;
+ return false;
}
}
- return 0;
+ return true;
}
/**
diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h
index 04cb51b..8dc1b19 100644
--- a/libass/ass_bitmap.h
+++ b/libass/ass_bitmap.h
@@ -117,9 +117,9 @@ void ass_synth_blur(const BitmapEngine *engine, int opaque_box, int be,
* \param bm_g out: pointer to the bitmap of original glyph is returned here
* \param bm_o out: pointer to the bitmap of border glyph is returned here
*/
-int outline_to_bitmap2(ASS_Renderer *render_priv, ASS_Outline *outline,
- ASS_Outline *border1, ASS_Outline *border2,
- Bitmap **bm_g, Bitmap **bm_o);
+bool outline_to_bitmap2(ASS_Renderer *render_priv, ASS_Outline *outline,
+ ASS_Outline *border1, ASS_Outline *border2,
+ Bitmap **bm_g, Bitmap **bm_o);
int be_padding(int be);
void be_blur_pre(uint8_t *buf, intptr_t w,
diff --git a/libass/ass_cache.h b/libass/ass_cache.h
index 64751df..03e58c7 100644
--- a/libass/ass_cache.h
+++ b/libass/ass_cache.h
@@ -30,6 +30,7 @@ typedef struct cache Cache;
// cache values
typedef struct {
+ bool valid;
Bitmap *bm; // the actual bitmaps
Bitmap *bm_o;
} BitmapHashValue;
@@ -41,6 +42,7 @@ typedef struct {
} CompositeHashValue;
typedef struct {
+ bool valid;
ASS_Outline outline;
ASS_Outline border[2];
FT_BBox bbox_scaled; // bbox after scaling, but before rotation
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 7e8f634..1369a82 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -1030,12 +1030,12 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
if (info->drawing) {
ASS_Drawing *drawing = info->drawing;
ass_drawing_hash(drawing);
- if(!ass_drawing_parse(drawing, 0)) {
+ if(!ass_drawing_parse(drawing, 0) ||
+ !outline_copy(&val->outline, &drawing->outline)) {
ass_cache_commit(val, 1);
ass_cache_dec_ref(val);
return;
}
- outline_copy(&val->outline, &drawing->outline);
val->advance.x = drawing->advance.x;
val->advance.y = drawing->advance.y;
val->asc = drawing->asc;
@@ -1050,7 +1050,12 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
info->symbol, info->face_index, info->glyph_index,
priv->settings.hinting, info->flags);
if (glyph != NULL) {
- outline_convert(&val->outline, &((FT_OutlineGlyph) glyph)->outline);
+ FT_Outline *src = &((FT_OutlineGlyph) glyph)->outline;
+ if (!outline_convert(&val->outline, src)) {
+ ass_cache_commit(val, 1);
+ ass_cache_dec_ref(val);
+ return;
+ }
if (priv->settings.shaper == ASS_SHAPING_SIMPLE) {
val->advance.x = d16_to_d6(glyph->advance.x);
val->advance.y = d16_to_d6(glyph->advance.y);
@@ -1062,12 +1067,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
val->desc *= info->scale_y;
}
}
-
- if (!val->outline.n_points) {
- ass_cache_commit(val, 1);
- ass_cache_dec_ref(val);
- return;
- }
+ val->valid = true;
outline_get_cbox(&val->outline, &val->bbox_scaled);
@@ -1082,7 +1082,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
double_to_d6(info->border_x * priv->border_scale),
double_to_d6(info->border_y * priv->border_scale));
- } else if ((info->border_x > 0 || info->border_y > 0)
+ } else if (val->outline.n_points && (info->border_x > 0 || info->border_y > 0)
&& double_to_d6(info->scale_x) && double_to_d6(info->scale_y)) {
const int eps = 16;
int xbord = double_to_d6(info->border_x * priv->border_scale);
@@ -1101,9 +1101,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info)
}
ass_cache_commit(val, 1);
- }
-
- if (!val->outline.n_points) {
+ } else if (!val->valid) {
ass_cache_dec_ref(val);
return;
}
@@ -1209,10 +1207,21 @@ get_bitmap_glyph(ASS_Renderer *render_priv, GlyphInfo *info)
OutlineBitmapHashKey *key = &info->hash_key.u.outline;
if (ass_cache_get(render_priv->cache.bitmap_cache, &info->hash_key, &val)) {
info->image = val;
+ if (!val->valid)
+ info->symbol = 0;
return;
}
- if (!val)
+ if (!val) {
+ info->symbol = 0;
return;
+ }
+ if (!info->outline) {
+ memset(val, 0, sizeof(*val));
+ ass_cache_commit(val, sizeof(BitmapHashKey) + sizeof(BitmapHashValue));
+ info->image = val;
+ info->symbol = 0;
+ return;
+ }
const int n_outlines = 3;
ASS_Outline outline[n_outlines];
@@ -1244,10 +1253,10 @@ get_bitmap_glyph(ASS_Renderer *render_priv, GlyphInfo *info)
outline_translate(&outline[i], key->advance.x, -key->advance.y);
// render glyph
- int error = outline_to_bitmap2(render_priv,
- &outline[0], &outline[1], &outline[2],
- &val->bm, &val->bm_o);
- if (error)
+ val->valid = outline_to_bitmap2(render_priv,
+ &outline[0], &outline[1], &outline[2],
+ &val->bm, &val->bm_o);
+ if (!val->valid)
info->symbol = 0;
ass_cache_commit(val, bitmap_size(val->bm) + bitmap_size(val->bm_o) +