]> granicus.if.org Git - libass/commitdiff
Support \rSTYLENAME syntax
authorGrigori Goronzy <greg@blackbox>
Sun, 11 Mar 2012 05:04:59 +0000 (06:04 +0100)
committerGrigori Goronzy <greg@blackbox>
Sun, 11 Mar 2012 05:04:59 +0000 (06:04 +0100)
This allows to reset to a certain style, instead of the default style
for the current line. For some reason, this was completely missing.

libass/ass.c
libass/ass_parse.c
libass/ass_render.c
libass/ass_render.h
libass/ass_utils.c
libass/ass_utils.h

index 712c16cb2724f19aecd3ab49e30c602bad3d79c2..bc05d691e721cb112ebbb63d9377ee4ee9a9aa2f 100644 (file)
@@ -191,30 +191,6 @@ static void set_default_style(ASS_Style *style)
     style->MarginL = style->MarginR = style->MarginV = 20;
 }
 
-/**
- * \brief find style by name
- * \param track track
- * \param name style name
- * \return index in track->styles
- * Returnes 0 if no styles found => expects at least 1 style.
- * Parsing code always adds "Default" style in the end.
- */
-static int lookup_style(ASS_Track *track, char *name)
-{
-    int i;
-    if (*name == '*')
-        ++name;                 // FIXME: what does '*' really mean ?
-    for (i = track->n_styles - 1; i >= 0; --i) {
-        if (strcmp(track->styles[i].Name, name) == 0)
-            return i;
-    }
-    i = track->default_style;
-    ass_msg(track->library, MSGL_WARN,
-            "[%p]: Warning: no style named '%s' found, using '%s'",
-            track, name, track->styles[i].Name);
-    return i;                   // use the first style
-}
-
 static uint32_t string2color(ASS_Library *library, char *p)
 {
     uint32_t tmp;
index 92a47b3aebda8ccbf84335b5ec03b6db5872eaa1..d505dd5c5ab7ed780905bc619bce4e8d02c2d8ba 100644 (file)
@@ -730,7 +730,18 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
         ass_msg(render_priv->library, MSGL_DBG2, "single c/a at %f: %c%c = %X",
                pwr, n, cmd, render_priv->state.c[cidx]);
     } else if (mystrcmp(&p, "r")) {
-        reset_render_context(render_priv);
+        char *start = p;
+        char *style;
+        skip_to('\\');
+        if (p > start) {
+            style = malloc(p - start + 1);
+            strncpy(style, start, p - start);
+            style[p - start] = '\0';
+            reset_render_context(render_priv,
+                    render_priv->track->styles + lookup_style(render_priv->track, style));
+            free(style);
+        } else
+            reset_render_context(render_priv, NULL);
     } else if (mystrcmp(&p, "be")) {
         int val;
         if (mystrtoi(&p, &val)) {
index 599989b4d6882c30fcd7fa3f734d58cd724bfe37..f89c9302601e26827da1088301b9ad583800c757 100644 (file)
@@ -839,39 +839,42 @@ static void compute_string_bbox(TextInfo *text, DBBox *bbox)
  * \brief partially reset render_context to style values
  * Works like {\r}: resets some style overrides
  */
-void reset_render_context(ASS_Renderer *render_priv)
+void reset_render_context(ASS_Renderer *render_priv, ASS_Style *style)
 {
-    render_priv->state.c[0] = render_priv->state.style->PrimaryColour;
-    render_priv->state.c[1] = render_priv->state.style->SecondaryColour;
-    render_priv->state.c[2] = render_priv->state.style->OutlineColour;
-    render_priv->state.c[3] = render_priv->state.style->BackColour;
+    if (!style)
+        style = render_priv->state.style;
+
+    render_priv->state.c[0] = style->PrimaryColour;
+    render_priv->state.c[1] = style->SecondaryColour;
+    render_priv->state.c[2] = style->OutlineColour;
+    render_priv->state.c[3] = style->BackColour;
     render_priv->state.flags =
-        (render_priv->state.style->Underline ? DECO_UNDERLINE : 0) |
-        (render_priv->state.style->StrikeOut ? DECO_STRIKETHROUGH : 0);
-    render_priv->state.font_size = render_priv->state.style->FontSize;
+        (style->Underline ? DECO_UNDERLINE : 0) |
+        (style->StrikeOut ? DECO_STRIKETHROUGH : 0);
+    render_priv->state.font_size = style->FontSize;
 
     free(render_priv->state.family);
     render_priv->state.family = NULL;
-    render_priv->state.family = strdup(render_priv->state.style->FontName);
+    render_priv->state.family = strdup(style->FontName);
     render_priv->state.treat_family_as_pattern =
-        render_priv->state.style->treat_fontname_as_pattern;
-    render_priv->state.bold = render_priv->state.style->Bold;
-    render_priv->state.italic = render_priv->state.style->Italic;
+        style->treat_fontname_as_pattern;
+    render_priv->state.bold = style->Bold;
+    render_priv->state.italic = style->Italic;
     update_font(render_priv);
 
     change_border(render_priv, -1., -1.);
-    render_priv->state.scale_x = render_priv->state.style->ScaleX;
-    render_priv->state.scale_y = render_priv->state.style->ScaleY;
-    render_priv->state.hspacing = render_priv->state.style->Spacing;
+    render_priv->state.scale_x = style->ScaleX;
+    render_priv->state.scale_y = style->ScaleY;
+    render_priv->state.hspacing = style->Spacing;
     render_priv->state.be = 0;
     render_priv->state.blur = 0.0;
-    render_priv->state.shadow_x = render_priv->state.style->Shadow;
-    render_priv->state.shadow_y = render_priv->state.style->Shadow;
+    render_priv->state.shadow_x = style->Shadow;
+    render_priv->state.shadow_y = style->Shadow;
     render_priv->state.frx = render_priv->state.fry = 0.;
-    render_priv->state.frz = M_PI * render_priv->state.style->Angle / 180.;
+    render_priv->state.frz = M_PI * style->Angle / 180.;
     render_priv->state.fax = render_priv->state.fay = 0.;
     render_priv->state.wrap_style = render_priv->track->WrapStyle;
-    render_priv->state.font_encoding = render_priv->state.style->Encoding;
+    render_priv->state.font_encoding = style->Encoding;
 }
 
 /**
@@ -884,7 +887,7 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event)
     render_priv->state.style = render_priv->track->styles + event->Style;
     render_priv->state.parsed_tags = 0;
 
-    reset_render_context(render_priv);
+    reset_render_context(render_priv, render_priv->state.style);
 
     render_priv->state.evt_type = EVENT_NORMAL;
     render_priv->state.alignment = render_priv->state.style->Alignment;
index c290c4d26dc795b4aa32a6719a1073959b730b9d..6dca2a2205bdb22242a42d33b18ce7cdd3a6cc72 100644 (file)
@@ -290,7 +290,7 @@ typedef struct {
     int ha, hb;                 // left and width
 } Segment;
 
-void reset_render_context(ASS_Renderer *render_priv);
+void reset_render_context(ASS_Renderer *render_priv, ASS_Style *style);
 void ass_free_images(ASS_Image *img);
 
 // XXX: this is actually in ass.c, includes should be fixed later on
index 4c9d4bcc62843443f956260e5b974f68c7f2feae..222e99a39a5a67fbbb72e019d81d1acd16b38f2c 100644 (file)
@@ -160,6 +160,30 @@ unsigned ass_utf8_get_char(char **str)
     return c;
 }
 
+/**
+ * \brief find style by name
+ * \param track track
+ * \param name style name
+ * \return index in track->styles
+ * Returnes 0 if no styles found => expects at least 1 style.
+ * Parsing code always adds "Default" style in the end.
+ */
+int lookup_style(ASS_Track *track, char *name)
+{
+    int i;
+    if (*name == '*')
+        ++name;                 // FIXME: what does '*' really mean ?
+    for (i = track->n_styles - 1; i >= 0; --i) {
+        if (strcmp(track->styles[i].Name, name) == 0)
+            return i;
+    }
+    i = track->default_style;
+    ass_msg(track->library, MSGL_WARN,
+            "[%p]: Warning: no style named '%s' found, using '%s'",
+            track, name, track->styles[i].Name);
+    return i;                   // use the first style
+}
+
 #ifdef CONFIG_ENCA
 void *ass_guess_buffer_cp(ASS_Library *library, unsigned char *buffer,
                           int buflen, char *preferred_language,
index 327bb79cf415fb0b9dd3d57bbe7b7cff3e129390..a1abde96e0ea36c9b05ae396eb67682425a56e87 100644 (file)
@@ -51,6 +51,7 @@ int strtocolor(ASS_Library *library, char **q, uint32_t *res, int hex);
 char parse_bool(char *str);
 unsigned ass_utf8_get_char(char **str);
 void ass_msg(ASS_Library *priv, int lvl, char *fmt, ...);
+int lookup_style(ASS_Track *track, char *name);
 #ifdef CONFIG_ENCA
 void *ass_guess_buffer_cp(ASS_Library *library, unsigned char *buffer,
                           int buflen, char *preferred_language,