diff options
-rw-r--r-- | libass/ass_parse.c | 22 | ||||
-rw-r--r-- | libass/ass_parse.h | 1 | ||||
-rw-r--r-- | libass/ass_render.c | 37 |
3 files changed, 35 insertions, 25 deletions
diff --git a/libass/ass_parse.c b/libass/ass_parse.c index da75d29..3966a43 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -253,7 +253,7 @@ static char *parse_vector_clip(ASS_Renderer *render_priv, char *p) * \param p string to parse * \param pwr multiplier for some tag effects (comes from \t tags) */ -static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr) +char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr) { skip_to('\\'); skip('\\'); @@ -999,7 +999,7 @@ void process_karaoke_effects(ASS_Renderer *render_priv) /** - * \brief Get next ucs4 char from string, parsing and executing style overrides + * \brief Get next ucs4 char from string, parsing UTF-8 and escapes * \param str string pointer * \return ucs4 code of the next char * On return str points to the unparsed part of the string @@ -1008,24 +1008,6 @@ unsigned get_next_char(ASS_Renderer *render_priv, char **str) { char *p = *str; unsigned chr; - if (*p == '{') { // '\0' goes here - p++; - while (1) { - p = parse_tag(render_priv, p, 1.); - if (*p == '}') { // end of tag - p++; - if (*p == '{') { - p++; - continue; - } else - break; - } else if (*p != '\\') - ass_msg(render_priv->library, MSGL_V, - "Unable to parse: '%.30s'", p); - if (*p == 0) - break; - } - } if (*p == '\t') { ++p; *str = p; diff --git a/libass/ass_parse.h b/libass/ass_parse.h index fd4fd66..88fcda8 100644 --- a/libass/ass_parse.h +++ b/libass/ass_parse.h @@ -34,6 +34,7 @@ void change_border(ASS_Renderer *render_priv, double border_x, 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); +char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr); 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 02bd111..3e269c1 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -1711,15 +1711,43 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, num_glyphs = 0; p = event->Text; + int in_tag = 0; + // Event parsing. while (1) { // get next char, executing style override // this affects render_context do { - code = get_next_char(render_priv, &p); - if (render_priv->state.drawing_mode && code) - ass_drawing_add_char(drawing, (char) code); - } while (code && render_priv->state.drawing_mode); // skip everything in drawing mode + code = 0; + if (!in_tag && *p == '{') { // '\0' goes here + p++; + in_tag = 1; + } + if (in_tag) { + int prev_drawing_mode = render_priv->state.drawing_mode; + p = parse_tag(render_priv, p, 1.); + if (*p == '}') { // end of tag + p++; + in_tag = 0; + } else if (*p != '\\') { + ass_msg(render_priv->library, MSGL_V, + "Unable to parse: '%.30s'", p); + } + if (prev_drawing_mode && !render_priv->state.drawing_mode) { + // Drawing mode was just disabled. We must exit and draw it + // immediately, instead of letting further tags affect it. + // See bug #47. + break; + } + } else { + code = get_next_char(render_priv, &p); + if (code && render_priv->state.drawing_mode) { + ass_drawing_add_char(drawing, (char) code); + continue; // skip everything in drawing mode + } + break; + } + } while (*p); if (text_info->length >= text_info->max_glyphs) { // Raise maximum number of glyphs @@ -1738,7 +1766,6 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, render_priv->font_scale; drawing->scale_y = render_priv->state.scale_y * render_priv->font_scale; - p--; code = 0xfffc; // object replacement character glyphs[text_info->length].drawing = drawing; } |