summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_parse.c21
-rw-r--r--libass/ass_render.c3
-rw-r--r--libass/ass_render.h2
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