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 | |
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.
-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 a7557fe..51ba9f8 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, |