summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-07-12 15:19:17 +0200
committerGrigori Goronzy <greg@blackbox>2011-07-12 15:32:02 +0200
commit84fff91fc561efee329a16705e97ca9505ea93ba (patch)
treef4b92381eac1d499cb1e2d7b3d5741c043a03e08
parent8e87db144289d8f7418f4b0dcd2a02d2f7b1d7eb (diff)
downloadlibass-84fff91fc561efee329a16705e97ca9505ea93ba.tar.bz2
libass-84fff91fc561efee329a16705e97ca9505ea93ba.tar.xz
Various small fixes to HarfBuzz rendering
Handle advance of clusters correctly, fix drawings, calculate run direction correctly, fix y offset sign.
-rw-r--r--libass/ass_render.c40
-rw-r--r--libass/ass_render.h1
-rw-r--r--libass/ass_shaper.c14
3 files changed, 31 insertions, 24 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c
index d0f089d..c884d45 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -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);
}
}
}
diff --git a/libass/ass_render.h b/libass/ass_render.h
index 33e046f..87eb3d1 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -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.
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index 7f581f3..e496d35 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -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;
}
}