From ef20577a502731f28de0a4ffc2c737389b1dd4a0 Mon Sep 17 00:00:00 2001 From: Oleg Oshmyan Date: Sun, 18 Oct 2020 04:46:32 +0300 Subject: process_karaoke_effects: honor starts_new_run This matches VSFilter. In particular, compared to what we did before, karaoke blocks additionally end when an override tag changes something, as well as on any line break (after the trimmed leading whitespace on the new line) and after any trimmed leading whitespace on the first line. The text that follows the break has a zero karaoke duration, and its karaoke effect starts immediately after the karaoke effect ends for the block before the break. --- libass/ass_parse.c | 14 ++++++++++---- libass/ass_render.c | 6 +++--- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'libass') diff --git a/libass/ass_parse.c b/libass/ass_parse.c index 6b05f95..20cbff6 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -975,10 +975,11 @@ void process_karaoke_effects(ASS_Renderer *render_priv) int tm_current = render_priv->time - render_priv->state.event->Start; int timing = 0; + Effect effect_type = EF_NONE; GlyphInfo *last_boundary = NULL; for (int i = 0; i <= render_priv->text_info.length; i++) { if (i < render_priv->text_info.length && - render_priv->text_info.glyphs[i].effect_type == EF_NONE) + !render_priv->text_info.glyphs[i].starts_new_run) continue; GlyphInfo *start = last_boundary; @@ -987,6 +988,11 @@ void process_karaoke_effects(ASS_Renderer *render_priv) if (!start) continue; + if (start->effect_type != EF_NONE) + effect_type = start->effect_type; + if (effect_type == EF_NONE) + continue; + int tm_start = timing + start->effect_skip_timing; int tm_end = tm_start + start->effect_timing; timing = tm_end; @@ -999,9 +1005,9 @@ void process_karaoke_effects(ASS_Renderer *render_priv) } int x; - if (start->effect_type == EF_KARAOKE || start->effect_type == EF_KARAOKE_KO) { + if (effect_type == EF_KARAOKE || effect_type == EF_KARAOKE_KO) { x = tm_current < tm_start ? x_start : x_end + 1; - } else if (start->effect_type == EF_KARAOKE_KF) { + } else if (effect_type == EF_KARAOKE_KF) { double dt = (double) (tm_current - tm_start) / (tm_end - tm_start); x = x_start + (x_end - x_start) * dt; } else { @@ -1011,7 +1017,7 @@ void process_karaoke_effects(ASS_Renderer *render_priv) } for (GlyphInfo *info = start; info < end; info++) { - info->effect_type = start->effect_type; + info->effect_type = effect_type; info->effect_timing = x - d6_to_int(info->pos.x); } } diff --git a/libass/ass_render.c b/libass/ass_render.c index f529ffe..001f1b0 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -2625,9 +2625,6 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, preliminary_layout(render_priv); - // depends on glyph x coordinates being monotonous, so it should be done before line wrap - process_karaoke_effects(render_priv); - int valign = render_priv->state.alignment & 12; int MarginL = @@ -2645,6 +2642,9 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, // wrap lines wrap_lines_smart(render_priv, max_text_width); + // depends on glyph x coordinates being monotonous within runs, so it should be done before reorder + process_karaoke_effects(render_priv); + reorder_text(render_priv); align_lines(render_priv, max_text_width); -- cgit v1.2.3