Basic @font support
authorGrigori Goronzy <greg@blackbox>
Thu, 18 Feb 2010 04:27:16 +0000 (05:27 +0100)
committerGrigori Goronzy <greg@blackbox>
Sat, 10 Apr 2010 23:59:28 +0000 (01:59 +0200)
Do not skip '@' at the start of a font name in styles; detect '@' at
font name start and set a new attribute in ASS_Font accordingly.
Rotate affected glyphs after loading and calculate a suitable advance.

libass/ass.c
libass/ass_cache.c
libass/ass_font.c
libass/ass_font.h
libass/ass_parse.c

index 14117764dd79261f02e595d84c8e7a2ca715ad0f..2efddcd2bb19e381df13bafd4ca74cf39a38aedd 100644 (file)
@@ -536,12 +536,6 @@ static int process_style(ASS_Track *track, char *str)
         style->Name = strdup("Default");
     if (!style->FontName)
         style->FontName = strdup("Arial");
-    // skip '@' at the start of the font name
-    if (*style->FontName == '@') {
-        p = style->FontName;
-        style->FontName = strdup(p + 1);
-        free(p);
-    }
     free(format);
     return 0;
 
index 643d9912ed2d2819a091a8a5bd345223a304f951..025273529bcf6ebc2dfcc5f646aab39572ed6388 100644 (file)
@@ -156,6 +156,8 @@ static int font_compare(void *key1, void *key2, size_t key_size)
         return 0;
     if (a->treat_family_as_pattern != b->treat_family_as_pattern)
         return 0;
+    if (a->vertical != b->vertical)
+        return 0;
     return 1;
 }
 
index bb2b96a97d74bee5641ed36e4cb7e93bb757edb4..109390f7133aeec649b61a0aa648231fcc52f3a4 100644 (file)
@@ -188,6 +188,7 @@ ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
     font.desc.treat_family_as_pattern = desc->treat_family_as_pattern;
     font.desc.bold = desc->bold;
     font.desc.italic = desc->italic;
+    font.desc.vertical = desc->vertical;
 
     font.scale_x = font.scale_y = 1.;
     font.v.x = font.v.y = 0;
@@ -207,11 +208,20 @@ ASS_Font *ass_font_new(void *font_cache, ASS_Library *library,
 void ass_font_set_transform(ASS_Font *font, double scale_x,
                             double scale_y, FT_Vector *v)
 {
-    font->scale_x = scale_x;
-    font->scale_y = scale_y;
-    if (v) {
-        font->v.x = v->x;
-        font->v.y = v->y;
+    if (font->desc.vertical) {
+        font->scale_x = scale_y;
+        font->scale_y = scale_x;
+        if (v) {
+            font->v.x = v->y;
+            font->v.y = v->x;
+        }
+    } else {
+        font->scale_x = scale_x;
+        font->scale_y = scale_y;
+        if (v) {
+            font->v.x = v->x;
+            font->v.y = v->y;
+        }
     }
     update_transform(font);
 }
@@ -414,6 +424,7 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
     FT_Glyph glyph;
     FT_Face face = 0;
     int flags = 0;
+    int vertical = font->desc.vertical;
 
     if (ch < 0x20)
         return 0;
@@ -488,6 +499,15 @@ FT_Glyph ass_font_get_glyph(void *fontconfig_priv, ASS_Font *font,
         return 0;
     }
 
+    if (vertical) {
+        FT_Matrix m = { 0, double_to_d16(-1.0), double_to_d16(1.0), 0 };
+        FT_Outline_Transform(&((FT_OutlineGlyph) glyph)->outline, &m);
+        FT_Outline_Translate(&((FT_OutlineGlyph) glyph)->outline,
+                             face->glyph->metrics.vertAdvance * font->scale_y,
+                             0);
+        glyph->advance.x = face->glyph->linearVertAdvance * font->scale_y;
+    }
+
     ass_strike_outline_glyph(face, font, glyph, deco & DECO_UNDERLINE,
                              deco & DECO_STRIKETHROUGH);
 
@@ -502,6 +522,9 @@ FT_Vector ass_font_get_kerning(ASS_Font *font, uint32_t c1, uint32_t c2)
     FT_Vector v = { 0, 0 };
     int i;
 
+    if (font->desc.vertical)
+        return v;
+
     for (i = 0; i < font->n_faces; ++i) {
         FT_Face face = font->faces[i];
         int i1 = FT_Get_Char_Index(face, c1);
index ca0c213a093527e24cb0a94be28c76b0d8ddfaaf..b16b9879cf4a5f157aedc9d7c35fbd44d5a06605 100644 (file)
@@ -36,6 +36,7 @@ typedef struct {
     unsigned bold;
     unsigned italic;
     int treat_family_as_pattern;
+    int vertical;               // @font vertical layout
 } ASS_FontDesc;
 
 typedef struct {
index e5d1b1699ce279f7d68b1eec6dca4150f7ef4418..ac502e7e603c5d01fe29ff5ac9d8bb9bc257d06f 100644 (file)
@@ -68,9 +68,15 @@ void update_font(ASS_Renderer *render_priv)
 {
     unsigned val;
     ASS_FontDesc desc;
-    desc.family = strdup(render_priv->state.family);
-    desc.treat_family_as_pattern =
-        render_priv->state.treat_family_as_pattern;
+    desc.treat_family_as_pattern = render_priv->state.treat_family_as_pattern;
+
+    if (render_priv->state.family[0] == '@') {
+        desc.vertical = 1;
+        desc.family = strdup(render_priv->state.family + 1);
+    } else {
+        desc.vertical = 0;
+        desc.family = strdup(render_priv->state.family);
+    }
 
     val = render_priv->state.bold;
     // 0 = normal, 1 = bold, >1 = exact weight