From e8d98dafb8d4d1fd80e9d398cfbef7db1e2ccb73 Mon Sep 17 00:00:00 2001 From: "Dr.Smile" Date: Sun, 19 May 2019 20:21:19 +0300 Subject: font: remove dependency on symbol codes Leading newlines are now rendered, but still incorrectly: at full height rather than at half-height as required. --- libass/ass_font.c | 42 +++++++++++++++++------------------------- libass/ass_font.h | 10 +++++----- libass/ass_render.c | 8 +++++--- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/libass/ass_font.c b/libass/ass_font.c index 3693be3..6b369aa 100644 --- a/libass/ass_font.c +++ b/libass/ass_font.c @@ -317,30 +317,23 @@ void ass_font_set_size(ASS_Font *font, double size) /** * \brief Get maximal font ascender and descender. - * \param ch character code - * The values are extracted from the font face that provides glyphs for the given character **/ -void ass_font_get_asc_desc(ASS_Font *font, uint32_t ch, int *asc, - int *desc) +void ass_font_get_asc_desc(ASS_Font *font, int face_index, + int *asc, int *desc) { - int i; - for (i = 0; i < font->n_faces; ++i) { - FT_Face face = font->faces[i]; - TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); - if (FT_Get_Char_Index(face, ass_font_index_magic(face, ch))) { - int y_scale = face->size->metrics.y_scale; - if (os2) { - *asc = FT_MulFix((short)os2->usWinAscent, y_scale); - *desc = FT_MulFix((short)os2->usWinDescent, y_scale); - } else { - *asc = FT_MulFix(face->ascender, y_scale); - *desc = FT_MulFix(-face->descender, y_scale); - } - return; - } + FT_Long a, d; + FT_Face face = font->faces[face_index]; + TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); + if (os2) { + a = (short) os2->usWinAscent; + d = (short) os2->usWinDescent; + } else { + a = face->ascender; + d = -face->descender; } - - *asc = *desc = 0; + int y_scale = face->size->metrics.y_scale; + *asc = FT_MulFix(a, y_scale); + *desc = FT_MulFix(d, y_scale); } static void add_line(FT_Outline *ol, int bear, int advance, int dir, int pos, int size) { @@ -525,14 +518,13 @@ int ass_font_get_index(ASS_FontSelector *fontsel, ASS_Font *font, * \brief Get a glyph * \param ch character code **/ -FT_Glyph ass_font_get_glyph(ASS_Font *font, uint32_t ch, int face_index, - int index, ASS_Hinting hinting, int deco) +FT_Glyph ass_font_get_glyph(ASS_Font *font, int face_index, int index, + ASS_Hinting hinting, int deco) { int error; FT_Glyph glyph; FT_Face face = font->faces[face_index]; int flags = 0; - int vertical = font->desc.vertical; flags = FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_IGNORE_TRANSFORM; @@ -573,7 +565,7 @@ FT_Glyph ass_font_get_glyph(ASS_Font *font, uint32_t ch, int face_index, } // Rotate glyph, if needed - if (vertical && ch >= VERTICAL_LOWER_BOUND) { + if (deco & DECO_ROTATE) { FT_Matrix m = { 0, double_to_d16(-1.0), double_to_d16(1.0), 0 }; TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); int desc = 0; diff --git a/libass/ass_font.h b/libass/ass_font.h index b7bfc10..dd0c11a 100644 --- a/libass/ass_font.h +++ b/libass/ass_font.h @@ -35,8 +35,9 @@ typedef struct ass_font_desc ASS_FontDesc; #define VERTICAL_LOWER_BOUND 0x02f1 #define ASS_FONT_MAX_FACES 10 -#define DECO_UNDERLINE 1 +#define DECO_UNDERLINE 1 #define DECO_STRIKETHROUGH 2 +#define DECO_ROTATE 4 struct ass_font_desc { char *family; @@ -64,13 +65,12 @@ ASS_Font *ass_font_new(Cache *font_cache, ASS_Library *library, void ass_font_set_transform(ASS_Font *font, double scale_x, double scale_y); void ass_face_set_size(FT_Face face, double size); void ass_font_set_size(ASS_Font *font, double size); -void ass_font_get_asc_desc(ASS_Font *font, uint32_t ch, int *asc, - int *desc); +void ass_font_get_asc_desc(ASS_Font *font, int face_index, + int *asc, int *desc); int ass_font_get_index(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t symbol, int *face_index, int *glyph_index); uint32_t ass_font_index_magic(FT_Face face, uint32_t symbol); -FT_Glyph ass_font_get_glyph(ASS_Font *font, - uint32_t ch, int face_index, int index, +FT_Glyph ass_font_get_glyph(ASS_Font *font, int face_index, int index, ASS_Hinting hinting, int deco); void ass_font_clear(ASS_Font *font); diff --git a/libass/ass_render.c b/libass/ass_render.c index c1a70bc..0a7cd77 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1055,7 +1055,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) ass_font_set_transform(info->font, info->scale_x, info->scale_y); FT_Glyph glyph = ass_font_get_glyph(info->font, - info->symbol, info->face_index, info->glyph_index, + info->face_index, info->glyph_index, priv->settings.hinting, info->flags); if (glyph != NULL) { FT_Outline *src = &((FT_OutlineGlyph) glyph)->outline; @@ -1067,7 +1067,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) if (priv->settings.shaper == ASS_SHAPING_SIMPLE) val->advance = d16_to_d6(glyph->advance.x); FT_Done_Glyph(glyph); - ass_font_get_asc_desc(info->font, info->symbol, + ass_font_get_asc_desc(info->font, info->face_index, &val->asc, &val->desc); val->asc *= info->scale_y; val->desc *= info->scale_y; @@ -1659,7 +1659,7 @@ static bool is_new_bm_run(GlyphInfo *info, GlyphInfo *last) last->hspacing != info->hspacing || last->italic != info->italic || last->bold != info->bold || - last->flags != info->flags; + ((last->flags ^ info->flags) & ~DECO_ROTATE); } static void make_shadow_bitmap(CombinedBitmapInfo *info, ASS_Renderer *render_priv) @@ -1793,6 +1793,8 @@ static bool parse_events(ASS_Renderer *render_priv, ASS_Event *event) info->bold = render_priv->state.bold; info->italic = render_priv->state.italic; info->flags = render_priv->state.flags; + if (info->font->desc.vertical && code >= VERTICAL_LOWER_BOUND) + info->flags |= DECO_ROTATE; info->frx = render_priv->state.frx; info->fry = render_priv->state.fry; info->frz = render_priv->state.frz; -- cgit v1.2.3