From c6e1dca7d0baae3f3324c722624e337a3e417f65 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Mon, 6 Jun 2011 22:10:02 +0200 Subject: refactor: move karaoke effect parsing into event parser --- libass/ass_parse.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ libass/ass_parse.h | 1 + libass/ass_render.c | 70 ---------------------------------------------------- 3 files changed, 72 insertions(+), 70 deletions(-) diff --git a/libass/ass_parse.c b/libass/ass_parse.c index 55e8fd1..7a6dd25 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -889,6 +889,77 @@ void apply_transition_effects(ASS_Renderer *render_priv, ASS_Event *event) } +/** + * \brief determine karaoke effects + * Karaoke effects cannot be calculated during parse stage (get_next_char()), + * so they are done in a separate step. + * Parse stage: when karaoke style override is found, its parameters are stored in the next glyph's + * (the first glyph of the karaoke word)'s effect_type and effect_timing. + * This function: + * 1. sets effect_type for all glyphs in the word (_karaoke_ word) + * 2. sets effect_timing for all glyphs to x coordinate of the border line between the left and right karaoke parts + * (left part is filled with PrimaryColour, right one - with SecondaryColour). + */ +void process_karaoke_effects(ASS_Renderer *render_priv) +{ + GlyphInfo *cur, *cur2; + GlyphInfo *s1, *e1; // start and end of the current word + GlyphInfo *s2; // start of the next word + int i; + int timing; // current timing + int tm_start, tm_end; // timings at start and end of the current word + int tm_current; + double dt; + int x; + int x_start, x_end; + + tm_current = render_priv->time - render_priv->state.event->Start; + timing = 0; + s1 = s2 = 0; + for (i = 0; i <= render_priv->text_info.length; ++i) { + cur = render_priv->text_info.glyphs + i; + if ((i == render_priv->text_info.length) + || (cur->effect_type != EF_NONE)) { + s1 = s2; + s2 = cur; + if (s1) { + e1 = s2 - 1; + tm_start = timing + s1->effect_skip_timing; + tm_end = tm_start + s1->effect_timing; + timing = tm_end; + x_start = 1000000; + x_end = -1000000; + for (cur2 = s1; cur2 <= e1; ++cur2) { + x_start = FFMIN(x_start, d6_to_int(cur2->bbox.xMin + cur2->pos.x)); + x_end = FFMAX(x_end, d6_to_int(cur2->bbox.xMax + cur2->pos.x)); + } + + dt = (tm_current - tm_start); + if ((s1->effect_type == EF_KARAOKE) + || (s1->effect_type == EF_KARAOKE_KO)) { + if (dt > 0) + x = x_end + 1; + else + x = x_start; + } else if (s1->effect_type == EF_KARAOKE_KF) { + dt /= (tm_end - tm_start); + x = x_start + (x_end - x_start) * dt; + } else { + ass_msg(render_priv->library, MSGL_ERR, + "Unknown effect type"); + continue; + } + + for (cur2 = s1; cur2 <= e1; ++cur2) { + cur2->effect_type = s1->effect_type; + cur2->effect_timing = x - d6_to_int(cur2->pos.x); + } + } + } + } +} + + /** * \brief Get next ucs4 char from string, parsing and executing style overrides * \param str string pointer diff --git a/libass/ass_parse.h b/libass/ass_parse.h index c65b565..b0e4e14 100644 --- a/libass/ass_parse.h +++ b/libass/ass_parse.h @@ -30,6 +30,7 @@ void update_font(ASS_Renderer *render_priv); void change_border(ASS_Renderer *render_priv, double border_x, double border_y); void apply_transition_effects(ASS_Renderer *render_priv, ASS_Event *event); +void process_karaoke_effects(ASS_Renderer *render_priv); unsigned get_next_char(ASS_Renderer *render_priv, char **str); extern void change_alpha(uint32_t *var, uint32_t new, double pwr); extern uint32_t mult_alpha(uint32_t a, uint32_t b); diff --git a/libass/ass_render.c b/libass/ass_render.c index 0db6303..ccd3629 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1569,76 +1569,6 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width) } } -/** - * \brief determine karaoke effects - * Karaoke effects cannot be calculated during parse stage (get_next_char()), - * so they are done in a separate step. - * Parse stage: when karaoke style override is found, its parameters are stored in the next glyph's - * (the first glyph of the karaoke word)'s effect_type and effect_timing. - * This function: - * 1. sets effect_type for all glyphs in the word (_karaoke_ word) - * 2. sets effect_timing for all glyphs to x coordinate of the border line between the left and right karaoke parts - * (left part is filled with PrimaryColour, right one - with SecondaryColour). - */ -static void process_karaoke_effects(ASS_Renderer *render_priv) -{ - GlyphInfo *cur, *cur2; - GlyphInfo *s1, *e1; // start and end of the current word - GlyphInfo *s2; // start of the next word - int i; - int timing; // current timing - int tm_start, tm_end; // timings at start and end of the current word - int tm_current; - double dt; - int x; - int x_start, x_end; - - tm_current = render_priv->time - render_priv->state.event->Start; - timing = 0; - s1 = s2 = 0; - for (i = 0; i <= render_priv->text_info.length; ++i) { - cur = render_priv->text_info.glyphs + i; - if ((i == render_priv->text_info.length) - || (cur->effect_type != EF_NONE)) { - s1 = s2; - s2 = cur; - if (s1) { - e1 = s2 - 1; - tm_start = timing + s1->effect_skip_timing; - tm_end = tm_start + s1->effect_timing; - timing = tm_end; - x_start = 1000000; - x_end = -1000000; - for (cur2 = s1; cur2 <= e1; ++cur2) { - x_start = FFMIN(x_start, d6_to_int(cur2->bbox.xMin + cur2->pos.x)); - x_end = FFMAX(x_end, d6_to_int(cur2->bbox.xMax + cur2->pos.x)); - } - - dt = (tm_current - tm_start); - if ((s1->effect_type == EF_KARAOKE) - || (s1->effect_type == EF_KARAOKE_KO)) { - if (dt > 0) - x = x_end + 1; - else - x = x_start; - } else if (s1->effect_type == EF_KARAOKE_KF) { - dt /= (tm_end - tm_start); - x = x_start + (x_end - x_start) * dt; - } else { - ass_msg(render_priv->library, MSGL_ERR, - "Unknown effect type"); - continue; - } - - for (cur2 = s1; cur2 <= e1; ++cur2) { - cur2->effect_type = s1->effect_type; - cur2->effect_timing = x - d6_to_int(cur2->pos.x); - } - } - } - } -} - /** * \brief Calculate base point for positioning and rotation * \param bbox text bbox -- cgit v1.2.3