summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libass/ass_parse.c13
-rw-r--r--libass/ass_render.c7
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;
}
}