summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2020-10-18 04:46:32 +0300
committerOleg Oshmyan <chortos@inbox.lv>2020-10-27 01:24:11 +0200
commitef20577a502731f28de0a4ffc2c737389b1dd4a0 (patch)
treeb3ee8b43b4846dafccd176a5a79a540567fe4951
parent9554d9844121a688a2fb79b2323203602bb08d17 (diff)
downloadlibass-ef20577a502731f28de0a4ffc2c737389b1dd4a0.tar.bz2
libass-ef20577a502731f28de0a4ffc2c737389b1dd4a0.tar.xz
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.
-rw-r--r--libass/ass_parse.c14
-rw-r--r--libass/ass_render.c6
2 files changed, 13 insertions, 7 deletions
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);