]> granicus.if.org Git - libass/commitdiff
font: remove dependency on symbol codes
authorDr.Smile <vabnick@gmail.com>
Sun, 19 May 2019 17:21:19 +0000 (20:21 +0300)
committerDr.Smile <vabnick@gmail.com>
Sun, 19 May 2019 17:21:19 +0000 (20:21 +0300)
Leading newlines are now rendered, but still incorrectly:
at full height rather than at half-height as required.

libass/ass_font.c
libass/ass_font.h
libass/ass_render.c

index 3693be3f0bbe63655c72dafb0c87348b6147d429..6b369aa256296ccdc024022ab6247ad66516ee3d 100644 (file)
@@ -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;
index b7bfc10b2a436ab6c01b27dded02c9e7f2bd4a80..dd0c11a8c4b3bcf7463c7945aee5ab2167c120f4 100644 (file)
@@ -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);
 
index c1a70bc926f41ea525883a63c6841b32ac0c863b..0a7cd778b45d3467ca5fb6f553b0c83a742501db 100644 (file)
@@ -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;