From 84fff91fc561efee329a16705e97ca9505ea93ba Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Tue, 12 Jul 2011 15:19:17 +0200 Subject: Various small fixes to HarfBuzz rendering Handle advance of clusters correctly, fix drawings, calculate run direction correctly, fix y offset sign. --- libass/ass_render.c | 40 +++++++++++++++++++++++----------------- libass/ass_render.h | 1 + libass/ass_shaper.c | 14 +++++++------- 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; } } -- cgit v1.2.3