summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2012-03-11 06:04:59 +0100
committerGrigori Goronzy <greg@blackbox>2012-03-11 06:04:59 +0100
commit2ba300123f7e6e5b9bbc69976ca4017993af694b (patch)
treea5b8b83ee77a63c71595ddf0abec6f1811954f7f
parent94b4c0d87182cd0bc84cf49cb793a0ab184df502 (diff)
downloadlibass-2ba300123f7e6e5b9bbc69976ca4017993af694b.tar.bz2
libass-2ba300123f7e6e5b9bbc69976ca4017993af694b.tar.xz
Support \rSTYLENAME syntax
This allows to reset to a certain style, instead of the default style for the current line. For some reason, this was completely missing.
-rw-r--r--libass/ass.c24
-rw-r--r--libass/ass_parse.c13
-rw-r--r--libass/ass_render.c43
-rw-r--r--libass/ass_render.h2
-rw-r--r--libass/ass_utils.c24
-rw-r--r--libass/ass_utils.h1
6 files changed, 61 insertions, 46 deletions
diff --git a/libass/ass.c b/libass/ass.c
index 712c16c..bc05d69 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -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;
diff --git a/libass/ass_parse.c b/libass/ass_parse.c
index 92a47b3..d505dd5 100644
--- a/libass/ass_parse.c
+++ b/libass/ass_parse.c
@@ -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)) {
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 599989b..f89c930 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -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;
diff --git a/libass/ass_render.h b/libass/ass_render.h
index c290c4d..6dca2a2 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -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
diff --git a/libass/ass_utils.c b/libass/ass_utils.c
index 4c9d4bc..222e99a 100644
--- a/libass/ass_utils.c
+++ b/libass/ass_utils.c
@@ -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,
diff --git a/libass/ass_utils.h b/libass/ass_utils.h
index 327bb79..a1abde9 100644
--- a/libass/ass_utils.h
+++ b/libass/ass_utils.h
@@ -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,