diff options
author | Grigori Goronzy <greg@blackbox> | 2009-08-12 02:59:00 +0200 |
---|---|---|
committer | Grigori Goronzy <greg@blackbox> | 2009-08-12 02:59:00 +0200 |
commit | 1934927c0532c9493e6985a632d66ce4a945930b (patch) | |
tree | db87b9950ead3e25b232494ba170d071c8ce921b /libass/ass_render.c | |
parent | ceefa4d7517a611de4c27c7de416a4ca7d22eeef (diff) | |
download | libass-1934927c0532c9493e6985a632d66ce4a945930b.tar.bz2 libass-1934927c0532c9493e6985a632d66ce4a945930b.tar.xz |
Implement BorderStyle 3
The "opaque box" border style renders an opaque box in the glyph area
instead of rendering a regular stroked border. This implementation
replaces the glyph outline by an outline that contains only one
rectangle with the size of the glyph, plus optional extra border.
Diffstat (limited to 'libass/ass_render.c')
-rw-r--r-- | libass/ass_render.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c index a7557fe9..51ba9f85 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -885,7 +885,8 @@ static void change_border(ASS_Renderer *render_priv, double border_x, return; if (border_x < 0 && border_y < 0) { - if (render_priv->state.style->BorderStyle == 1) + if (render_priv->state.style->BorderStyle == 1 || + render_priv->state.style->BorderStyle == 3) border_x = border_y = render_priv->state.style->Outline; else border_x = border_y = 1.; @@ -1877,6 +1878,43 @@ static void fix_freetype_stroker(FT_OutlineGlyph glyph, int border_x, } /* + * Replace the outline of a glyph by a contour which makes up a simple + * opaque rectangle. + */ +static void draw_opaque_box(ASS_Renderer *render_priv, uint32_t ch, + FT_Glyph glyph, int sx, int sy) +{ + int asc = 0, desc = 0; + int i; + int adv = d16_to_d6(glyph->advance.x); + FT_OutlineGlyph og = (FT_OutlineGlyph) glyph; + FT_Outline *ol; + + // to avoid gaps + sx = FFMAX(64, sx); + sy = FFMAX(64, sy); + + ass_font_get_asc_desc(render_priv->state.font, ch, &asc, &desc); + FT_Vector points[4] = { + { .x = -sx, .y = asc + sy }, + { .x = adv + sx, .y = asc + sy }, + { .x = adv + sx, .y = -desc - sy }, + { .x = -sx, .y = -desc - sy }, + }; + + FT_Outline_Done(render_priv->ftlibrary, &og->outline); + FT_Outline_New(render_priv->ftlibrary, 4, 1, &og->outline); + + ol = &og->outline; + ol->n_points = ol->n_contours = 0; + for (i = 0; i < 4; i++) { + ol->points[ol->n_points] = points[i]; + ol->tags[ol->n_points++] = 1; + } + ol->contours[ol->n_contours++] = ol->n_points - 1; +} + +/* * Stroke an outline glyph in x/y direction. Applies various fixups to get * around limitations of the FreeType stroker. */ @@ -1986,8 +2024,15 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, info->advance.y = d16_to_d6(info->glyph->advance.y); FT_Glyph_Get_CBox(info->glyph, FT_GLYPH_BBOX_SUBPIXELS, &info->bbox); - if (render_priv->state.border_x > 0 || - render_priv->state.border_y > 0) { + if (render_priv->state.style->BorderStyle == 3) { + FT_Glyph_Copy(info->glyph, &info->outline_glyph); + draw_opaque_box(render_priv, symbol, info->outline_glyph, + double_to_d6(render_priv->state.border_x * + render_priv->border_scale), + double_to_d6(render_priv->state.border_y * + render_priv->border_scale)); + } else if (render_priv->state.border_x > 0 || + render_priv->state.border_y > 0) { FT_Glyph_Copy(info->glyph, &info->outline_glyph); stroke_outline_glyph(render_priv, |