diff options
Diffstat (limited to 'libass')
-rw-r--r-- | libass/ass_parse.c | 21 | ||||
-rw-r--r-- | libass/ass_render.c | 3 | ||||
-rw-r--r-- | libass/ass_render.h | 2 |
3 files changed, 25 insertions, 1 deletions
diff --git a/libass/ass_parse.c b/libass/ass_parse.c index f43831e..a7437c6 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -790,6 +790,14 @@ char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr, val = render_priv->state.style->Italic; render_priv->state.italic = val; update_font(render_priv); + } else if (tag("kt")) { + // v4++ + double val = 0; + if (nargs) + val = argtod(*args) * 10; + render_priv->state.effect_skip_timing = dtoi32(val); + render_priv->state.effect_timing = 0; + render_priv->state.reset_effect = true; } else if (tag("kf") || tag("K")) { double val = 100; if (nargs) @@ -975,9 +983,16 @@ void process_karaoke_effects(ASS_Renderer *render_priv) int32_t timing = 0, skip_timing = 0; Effect effect_type = EF_NONE; GlyphInfo *last_boundary = NULL; + bool has_reset = false; 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) { + + if (render_priv->text_info.glyphs[i].reset_effect) { + has_reset = true; + skip_timing = 0; + } + // 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, @@ -997,10 +1012,14 @@ void process_karaoke_effects(ASS_Renderer *render_priv) if (effect_type == EF_NONE) continue; + if (start->reset_effect) + timing = 0; + long long tm_start = timing + start->effect_skip_timing; long long tm_end = tm_start + start->effect_timing; - timing = tm_end + skip_timing; + timing = !has_reset * tm_end + skip_timing; skip_timing = 0; + has_reset = false; if (effect_type != EF_KARAOKE_KF) tm_end = tm_start; diff --git a/libass/ass_render.c b/libass/ass_render.c index 7e452df..4f3f20d 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1099,6 +1099,7 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event) render_priv->state.effect_type = EF_NONE; render_priv->state.effect_timing = 0; render_priv->state.effect_skip_timing = 0; + render_priv->state.reset_effect = false; apply_transition_effects(render_priv, event); render_priv->state.explicit = render_priv->state.evt_type != EVENT_NORMAL || @@ -2113,6 +2114,7 @@ static bool parse_events(ASS_Renderer *render_priv, ASS_Event *event) info->effect_type = render_priv->state.effect_type; info->effect_timing = render_priv->state.effect_timing; info->effect_skip_timing = render_priv->state.effect_skip_timing; + info->reset_effect = render_priv->state.reset_effect; // VSFilter compatibility: font glyphs use PlayResY scaling in both dimensions info->font_size = fabs(render_priv->state.font_size * render_priv->screen_scale_y); @@ -2153,6 +2155,7 @@ static bool parse_events(ASS_Renderer *render_priv, ASS_Event *event) render_priv->state.effect_type = EF_NONE; render_priv->state.effect_timing = 0; render_priv->state.effect_skip_timing = 0; + render_priv->state.reset_effect = false; } return true; diff --git a/libass/ass_render.h b/libass/ass_render.h index e86219f..e9fe6dc 100644 --- a/libass/ass_render.h +++ b/libass/ass_render.h @@ -151,6 +151,7 @@ typedef struct glyph_info { // after process_karaoke_effects: distance in subpixels from the karaoke origin. // part of the glyph to the left of it is displayed in a different color. int32_t effect_skip_timing; // delay after the end of last karaoke word + bool reset_effect; int asc, desc; // font max ascender and descender int be; // blur edges double blur; // gaussian blur @@ -254,6 +255,7 @@ typedef struct { Effect effect_type; int32_t effect_timing; int32_t effect_skip_timing; + bool reset_effect; enum { SCROLL_LR, // left-to-right |