]> granicus.if.org Git - libass/commitdiff
Various small fixes to HarfBuzz rendering
authorGrigori Goronzy <greg@blackbox>
Tue, 12 Jul 2011 13:19:17 +0000 (15:19 +0200)
committerGrigori Goronzy <greg@blackbox>
Tue, 12 Jul 2011 13:32:02 +0000 (15:32 +0200)
Handle advance of clusters correctly, fix drawings, calculate run
direction correctly, fix y offset sign.

libass/ass_render.c
libass/ass_render.h
libass/ass_shaper.c

index d0f089d111d6fc29322e77647918a907b0427670..c884d45bee78ebfe91516fd769690771864c6156 100644 (file)
@@ -1115,10 +1115,9 @@ get_outline_glyph(ASS_Renderer *render_priv, GlyphInfo *info)
         info->outline = val->outline;
         info->border = val->border;
         info->bbox = val->bbox_scaled;
-        // XXX: more elegant solution?
         if (info->drawing) {
-            info->advance.x = info->drawing->advance.x;
-            info->advance.y = info->drawing->advance.y;
+            info->cluster_advance.x = info->advance.x = val->advance.x;
+            info->cluster_advance.y = info->advance.y = val->advance.y;
         }
         info->asc = val->asc;
         info->desc = val->desc;
@@ -1131,8 +1130,8 @@ get_outline_glyph(ASS_Renderer *render_priv, GlyphInfo *info)
                 return;
             outline_copy(render_priv->ftlibrary, &drawing->outline,
                     &info->outline);
-            info->advance.x = drawing->advance.x;
-            info->advance.y = drawing->advance.y;
+            info->cluster_advance.x = info->advance.x = drawing->advance.x;
+            info->cluster_advance.y = info->advance.y = drawing->advance.y;
             info->asc = drawing->asc;
             info->desc = drawing->desc;
             ass_drawing_free(drawing);
@@ -1189,7 +1188,7 @@ get_outline_glyph(ASS_Renderer *render_priv, GlyphInfo *info)
         v.lib = render_priv->ftlibrary;
         v.outline = info->outline;
         v.border = info->border;
-        v.advance = info->advance;
+        v.advance = info->cluster_advance;
         v.bbox_scaled = info->bbox;
         v.asc = info->asc;
         v.desc = info->desc;
@@ -1881,10 +1880,10 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
         info = glyphs + i;
 
         // add displacement for vertical shearing
-        info->advance.y += (info->fay * info->scale_y) * info->advance.x;
+        info->cluster_advance.y += (info->fay * info->scale_y) * info->cluster_advance.x;
 
         // add horizontal letter spacing
-        info->advance.x += double_to_d6(render_priv->state.hspacing *
+        info->cluster_advance.x += double_to_d6(render_priv->state.hspacing *
                 render_priv->font_scale * info->scale_x);
 
     }
@@ -1895,6 +1894,7 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
     pen.y = 0;
     for (i = 0; i < text_info->length; i++) {
         GlyphInfo *info = glyphs + i;
+        FT_Vector cluster_pen = pen;
         while (info) {
 
 #if 0
@@ -1912,8 +1912,11 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
             }
 #endif
 
-            info->pos.x = pen.x;
-            info->pos.y = pen.y;
+            info->pos.x = cluster_pen.x;
+            info->pos.y = cluster_pen.y;
+
+            cluster_pen.x += info->advance.x;
+            cluster_pen.y += info->advance.y;
 
             // fill bitmap hash
             info->hash_key.type = BITMAP_OUTLINE;
@@ -1922,8 +1925,8 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
             info = info->next;
         }
         info = glyphs + i;
-        pen.x += info->advance.x;
-        pen.y += info->advance.y;
+        pen.x += info->cluster_advance.x;
+        pen.y += info->cluster_advance.y;
         previous = info->symbol;
     }
 
@@ -1977,14 +1980,17 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
             lineno++;
         }
         if (info->skip) continue;
+        FT_Vector cluster_pen = pen;
         while (info) {
-            info->pos.x = info->offset.x + pen.x;
-            info->pos.y = info->offset.y + pen.y;
+            info->pos.x = info->offset.x + cluster_pen.x;
+            info->pos.y = info->offset.y + cluster_pen.y;
+            cluster_pen.x += info->advance.x;
+            cluster_pen.y += info->advance.y;
             info = info->next;
         }
         info = glyphs + cmap[i];
-        pen.x += info->advance.x;
-        pen.y += info->advance.y;
+        pen.x += info->cluster_advance.x;
+        pen.y += info->cluster_advance.y;
     }
 
     // align lines
@@ -2013,7 +2019,7 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
             }
             if (i < text_info->length && !glyphs[i].skip &&
                     glyphs[i].symbol != '\n' && glyphs[i].symbol != 0) {
-                width += d6_to_double(glyphs[i].advance.x);
+                width += d6_to_double(glyphs[i].cluster_advance.x);
             }
         }
     }
index 33e046f7f53235d5b97b61ce0decaa2f147db365..87eb3d1161a23e6bef0c347f991edc54e97c715c 100644 (file)
@@ -115,6 +115,7 @@ typedef struct glyph_info {
     char linebreak;             // the first (leading) glyph of some line ?
     uint32_t c[4];              // colors
     FT_Vector advance;          // 26.6
+    FT_Vector cluster_advance;
     Effect effect_type;
     int effect_timing;          // time duration of current karaoke word
     // after process_karaoke_effects: distance in pixels from the glyph origin.
index 7f581f3f8856c29b65772c65f9225ae001d485ec..e496d35decdabf1bd8e44f4ebad44d293d377708 100644 (file)
@@ -98,6 +98,7 @@ void ass_shaper_shape(TextInfo *text_info, FriBidiCharType *ctypes,
         // get length and level of the current run
         int k = i;
         int level = glyphs[i].shape_run_id;
+        int direction = emblevels[k] % 2;
         while (i < (text_info->length - 1) && level == glyphs[i+1].shape_run_id)
             i++;
         //printf("run %d from %d to %d with level %d\n", run, k, i, level);
@@ -106,7 +107,7 @@ void ass_shaper_shape(TextInfo *text_info, FriBidiCharType *ctypes,
         runs[run].end    = i;
         runs[run].buf    = hb_buffer_create(i - k + 1);
         runs[run].font   = hb_ft_font_create(run_font, NULL);
-        hb_buffer_set_direction(runs[run].buf, (level % 2) ? HB_DIRECTION_RTL :
+        hb_buffer_set_direction(runs[run].buf, direction ? HB_DIRECTION_RTL :
                 HB_DIRECTION_LTR);
         hb_buffer_add_utf32(runs[run].buf, event_text + k, i - k + 1,
                 0, i - k + 1);
@@ -130,7 +131,6 @@ void ass_shaper_shape(TextInfo *text_info, FriBidiCharType *ctypes,
             int idx = glyph_info[j].cluster + runs[i].offset;
             GlyphInfo *info = glyphs + idx;
             GlyphInfo *root = info;
-
 #if 0
             printf("run %d cluster %d codepoint %d -> '%c'\n", i, idx,
                     glyph_info[j].codepoint, event_text[idx]);
@@ -155,13 +155,13 @@ void ass_shaper_shape(TextInfo *text_info, FriBidiCharType *ctypes,
             info->skip = 0;
             info->glyph_index = glyph_info[j].codepoint;
             info->offset.x    = pos[j].x_offset * info->scale_x;
-            info->offset.y    = pos[j].y_offset * info->scale_y;
+            info->offset.y    = -pos[j].y_offset * info->scale_y;
             info->advance.x   = pos[j].x_advance * info->scale_x;
-            info->advance.y   = pos[j].y_advance * info->scale_y;
+            info->advance.y   = -pos[j].y_advance * info->scale_y;
 
-            // accumulate maximum advance in the root glyph
-            root->advance.x = FFMAX(root->advance.x, info->advance.x);
-            root->advance.y = FFMAX(root->advance.y, info->advance.y);
+            // accumulate advance in the root glyph
+            root->cluster_advance.x += info->advance.x;
+            root->cluster_advance.y += info->advance.y;
         }
     }