diff options
-rw-r--r-- | libass/ass_parse.c | 13 | ||||
-rw-r--r-- | libass/ass_render.c | 7 |
2 files changed, 16 insertions, 4 deletions
diff --git a/libass/ass_parse.c b/libass/ass_parse.c index 11d7f1b..5666ca6 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -974,13 +974,19 @@ void process_karaoke_effects(ASS_Renderer *render_priv) { long long tm_current = render_priv->time - render_priv->state.event->Start; - int timing = 0; + int timing = 0, skip_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].starts_new_run) + !render_priv->text_info.glyphs[i].starts_new_run) { + // VSFilter compatibility: if we have \k12345\k0 without a run + // break, subsequent text is still part of the same karaoke word, + // the current word's starting and ending time stay unchanged, + // but the starting time of the next karaoke word is advanced. + skip_timing += render_priv->text_info.glyphs[i].effect_skip_timing; continue; + } GlyphInfo *start = last_boundary; GlyphInfo *end = render_priv->text_info.glyphs + i; @@ -995,7 +1001,8 @@ void process_karaoke_effects(ASS_Renderer *render_priv) long long tm_start = timing + start->effect_skip_timing; long long tm_end = tm_start + start->effect_timing; - timing = tm_end; + timing = tm_end + skip_timing; + skip_timing = 0; if (effect_type != EF_KARAOKE_KF) tm_end = tm_start; diff --git a/libass/ass_render.c b/libass/ass_render.c index a324935..0ef7158 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1855,12 +1855,15 @@ fix_glyph_scaling(ASS_Renderer *priv, GlyphInfo *glyph) // Initial run splitting based purely on the characters' styles static void split_style_runs(ASS_Renderer *render_priv) { + Effect last_effect_type = render_priv->text_info.glyphs[0].effect_type; render_priv->text_info.glyphs[0].starts_new_run = true; for (int i = 1; i < render_priv->text_info.length; i++) { GlyphInfo *info = render_priv->text_info.glyphs + i; GlyphInfo *last = render_priv->text_info.glyphs + (i - 1); + Effect effect_type = info->effect_type; info->starts_new_run = - info->effect_type != EF_NONE || + info->effect_timing || // but ignore effect_skip_timing + (effect_type != EF_NONE && effect_type != last_effect_type) || info->drawing_text || last->drawing_text || strcmp(last->font->desc.family, info->font->desc.family) || @@ -1888,6 +1891,8 @@ static void split_style_runs(ASS_Renderer *render_priv) last->italic != info->italic || last->bold != info->bold || ((last->flags ^ info->flags) & ~DECO_ROTATE); + if (effect_type != EF_NONE) + last_effect_type = effect_type; } } |