summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libass/ass_parse.c22
-rw-r--r--libass/ass_parse.h1
-rw-r--r--libass/ass_render.c37
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;
}