summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-02-26 20:49:18 +0100
committerwm4 <wm4@nowhere>2015-02-26 21:18:49 +0100
commit51a93b5571acf51d3c7fe841d3e1e34720524c23 (patch)
treec53e64261140c251f3b0077b278f66605d99b819 /libass
parent230f855fd3a80a6acfefe753b778b422191be26f (diff)
downloadlibass-51a93b5571acf51d3c7fe841d3e1e34720524c23.tar.bz2
libass-51a93b5571acf51d3c7fe841d3e1e34720524c23.tar.xz
Allow more fine grained control over style overrides
Add tons of ASS_OVERRIDE_ flags, which control whether certain ASS_Style fields are copied when doing selective style overrides with ass_set_selective_style_override_enabled(). This comes with some cleanup. It should be fully backwards-compatible.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass.h87
-rw-r--r--libass/ass_render.c97
-rw-r--r--libass/ass_render.h4
-rw-r--r--libass/ass_render_api.c1
4 files changed, 143 insertions, 46 deletions
diff --git a/libass/ass.h b/libass/ass.h
index ca9d8af..80f9247 100644
--- a/libass/ass.h
+++ b/libass/ass.h
@@ -23,7 +23,7 @@
#include <stdarg.h>
#include "ass_types.h"
-#define LIBASS_VERSION 0x01201000
+#define LIBASS_VERSION 0x01201001
#ifdef __cplusplus
extern "C" {
@@ -96,8 +96,75 @@ typedef enum {
* ass_set_selective_style_override_enabled() for details.
*/
typedef enum {
- ASS_OVERRIDE_BIT_STYLE = 1,
- ASS_OVERRIDE_BIT_FONT_SIZE = 2,
+ /**
+ * Default mode (with no other bits set). All selective override features
+ * as well as the style set with ass_set_selective_style_override() are
+ * disabled, but traditional overrides like ass_set_font_scale() are
+ * applied unconditionally.
+ */
+ ASS_OVERRIDE_DEFAULT = 0,
+ /**
+ * Apply the style as set with ass_set_selective_style_override() on events
+ * which look like dialogue. Other style overrides are also applied this
+ * way, except ass_set_font_scale(). How ass_set_font_scale() is applied
+ * depends on the ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE flag.
+ *
+ * This is equivalent to setting all of the following bits:
+ *
+ * ASS_OVERRIDE_BIT_FONT_NAME
+ * ASS_OVERRIDE_BIT_FONT_SIZE_FIELDS
+ * ASS_OVERRIDE_BIT_COLORS
+ * ASS_OVERRIDE_BIT_BORDER
+ * ASS_OVERRIDE_BIT_ATTRIBUTES
+ */
+ ASS_OVERRIDE_BIT_STYLE = 1 << 0,
+ /**
+ * Apply ass_set_font_scale() only on events which look like dialogue.
+ * If not set, the font scale is applied to all events. (The behavior and
+ * name of this flag are unintuitive, but exist for compatibility)
+ */
+ ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE = 1 << 1,
+ /**
+ * Old alias for ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE. Deprecated. Do not use.
+ */
+ ASS_OVERRIDE_BIT_FONT_SIZE = 1 << 1,
+ /**
+ * On dialogue events override: FontSize, Spacing, Blur, ScaleX, ScaleY
+ */
+ ASS_OVERRIDE_BIT_FONT_SIZE_FIELDS = 1 << 2,
+ /**
+ * On dialogue events override: FontName, treat_fontname_as_pattern
+ */
+ ASS_OVERRIDE_BIT_FONT_NAME = 1 << 3,
+ /**
+ * On dialogue events override: PrimaryColour, SecondaryColour, OutlineColour, BackColour
+ */
+ ASS_OVERRIDE_BIT_COLORS = 1 << 4,
+ /**
+ * On dialogue events override: Bold, Italic, Underline, StrikeOut
+ */
+ ASS_OVERRIDE_BIT_ATTRIBUTES = 1 << 5,
+ /**
+ * On dialogue events override: BorderStyle, Outline, Shadow
+ */
+ ASS_OVERRIDE_BIT_BORDER = 1 << 6,
+ /**
+ * On dialogue events override: Alignment
+ */
+ ASS_OVERRIDE_BIT_ALIGNMENT = 1 << 7,
+ /**
+ * On dialogue events override: MarginL, MarginR, MarginV
+ */
+ ASS_OVERRIDE_BIT_MARGINS = 1 << 8,
+ /**
+ * Unconditionally replace all fields of all styles with the one provided
+ * with ass_set_selective_style_override().
+ * Does not apply ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE.
+ * Add ASS_OVERRIDE_BIT_FONT_SIZE_FIELDS and ASS_OVERRIDE_BIT_BORDER if
+ * you want FontSize, Spacing, Outline, Shadow to be scaled to the script
+ * resolution given by the ASS_Track.
+ */
+ ASS_OVERRIDE_FULL_STYLE = 1 << 9,
} ASS_OverrideBits;
/**
@@ -345,19 +412,7 @@ void ass_set_fonts(ASS_Renderer *priv, const char *default_font,
* only be implemented on "best effort" basis, and has to rely on
* heuristics that can easily break.
* \param priv renderer handle
- * \param bits bit mask comprised of ASS_OverrideBits values. If the value is
- * 0, all override features are disabled, and libass will behave like libass
- * versions before this feature was introduced. Possible values:
- * ASS_OVERRIDE_BIT_STYLE: apply the style as set with
- * ass_set_selective_style_override() on events which look like
- * dialogue. Other style overrides are also applied this way, except
- * ass_set_font_scale(). How ass_set_font_scale() is applied depends
- * on the ASS_OVERRIDE_BIT_FONT_SIZE flag.
- * ASS_OVERRIDE_BIT_FONT_SIZE: apply ass_set_font_scale() only on events
- * which look like dialogue. If not set, it is applied to all
- * events.
- * 0: ignore ass_set_selective_style_override(), but apply all other
- * overrides (traditional behavior).
+ * \param bits bit mask comprised of ASS_OverrideBits values.
*/
void ass_set_selective_style_override_enabled(ASS_Renderer *priv, int bits);
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 3e54710..b03fc30 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -139,6 +139,7 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
priv->text_info.lines = calloc(MAX_LINES_INITIAL, sizeof(LineInfo));
priv->settings.font_size_coeff = 1.;
+ priv->settings.selective_style_overrides = ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE;
priv->shaper = ass_shaper_new(0);
ass_shaper_info(library);
@@ -750,55 +751,95 @@ static ASS_Style *handle_selective_style_overrides(ASS_Renderer *render_priv,
ASS_Style *rstyle)
{
// The script style is the one the event was declared with.
- // The rstyle is either NULL, or the style used with a \r tag.
ASS_Style *script = render_priv->track->styles +
render_priv->state.event->Style;
+ // The user style was set with ass_set_selective_style_override().
+ ASS_Style *user = &render_priv->user_override_style;
ASS_Style *new = &render_priv->state.override_style_temp_storage;
int explicit = event_is_positioned(render_priv->state.event->Text);
int requested = render_priv->settings.selective_style_overrides;
double scale;
+ user->Name = "OverrideStyle"; // name insignificant
+
+ // Either the event's style, or the style forced with a \r tag.
if (!rstyle)
rstyle = script;
- render_priv->state.style = script;
- render_priv->state.overrides = ASS_OVERRIDE_BIT_FONT_SIZE; // odd default
-
- if (explicit && (requested & ASS_OVERRIDE_BIT_FONT_SIZE))
- render_priv->state.overrides &= ~(unsigned)ASS_OVERRIDE_BIT_FONT_SIZE;
-
- if (!explicit && (requested & ASS_OVERRIDE_BIT_STYLE))
- render_priv->state.overrides |= ASS_OVERRIDE_BIT_STYLE;
-
- if (!(render_priv->state.overrides & ASS_OVERRIDE_BIT_STYLE))
- return rstyle;
-
// Create a new style that contains a mix of the original style and
// user_style (the user's override style). Copy only fields from the
// script's style that are deemed necessary.
- *new = render_priv->user_override_style;
+ *new = *rstyle;
+
+ render_priv->state.apply_font_scale =
+ !explicit || !(requested & ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE);
- new->Bold = rstyle->Bold;
- new->StrikeOut = rstyle->StrikeOut;
- new->Underline = rstyle->Underline;
- new->Angle = rstyle->Angle;
+ // On positioned events, do not apply most overrides.
+ if (explicit)
+ requested = 0;
- new->MarginL = rstyle->MarginL;
- new->MarginR = rstyle->MarginR;
- new->MarginV = rstyle->MarginV;
- new->Alignment = rstyle->Alignment;
- new->Encoding = rstyle->Encoding;
+ if (requested & ASS_OVERRIDE_BIT_STYLE)
+ requested |= ASS_OVERRIDE_BIT_FONT_NAME |
+ ASS_OVERRIDE_BIT_FONT_SIZE_FIELDS |
+ ASS_OVERRIDE_BIT_COLORS |
+ ASS_OVERRIDE_BIT_BORDER |
+ ASS_OVERRIDE_BIT_ATTRIBUTES;
+
+ // Copies fields even not covered by any of the other bits.
+ if (requested & ASS_OVERRIDE_FULL_STYLE)
+ *new = *user;
// The user style is supposed to be independent of the script resolution.
// Treat the user style's values as if they were specified for a script with
// PlayResY=288, and rescale the values to the current script.
scale = render_priv->track->PlayResY / 288.0;
- new->FontSize *= scale;
- new->Spacing *= scale;
- new->Outline *= scale;
- new->Shadow *= scale;
+
+ if (requested & ASS_OVERRIDE_BIT_FONT_SIZE_FIELDS) {
+ new->FontSize = user->FontSize * scale;
+ new->Spacing = user->Spacing * scale;
+ new->ScaleX = user->ScaleX;
+ new->ScaleY = user->ScaleY;
+ }
+
+ if (requested & ASS_OVERRIDE_BIT_FONT_NAME) {
+ new->FontName = user->FontName;
+ new->treat_fontname_as_pattern = user->treat_fontname_as_pattern;
+ }
+
+ if (requested & ASS_OVERRIDE_BIT_COLORS) {
+ new->PrimaryColour = user->PrimaryColour;
+ new->SecondaryColour = user->SecondaryColour;
+ new->OutlineColour = user->OutlineColour;
+ new->BackColour = user->BackColour;
+ }
+
+ if (requested & ASS_OVERRIDE_BIT_ATTRIBUTES) {
+ new->Bold = user->Bold;
+ new->Italic = user->Italic;
+ new->Underline = user->Underline;
+ new->StrikeOut = user->StrikeOut;
+ }
+
+ if (requested & ASS_OVERRIDE_BIT_BORDER) {
+ new->BorderStyle = user->BorderStyle;
+ new->Outline = user->Outline * scale;
+ new->Shadow = user->Shadow * scale;
+ }
+
+ if (requested & ASS_OVERRIDE_BIT_ALIGNMENT)
+ new->Alignment = user->Alignment;
+
+ if (requested & ASS_OVERRIDE_BIT_MARGINS) {
+ new->MarginL = user->MarginL;
+ new->MarginR = user->MarginR;
+ new->MarginV = user->MarginV;
+ }
+
+ if (!new->FontName)
+ new->FontName = rstyle->FontName;
render_priv->state.style = new;
+ render_priv->state.overrides = requested;
return new;
}
@@ -823,7 +864,7 @@ static void init_font_scale(ASS_Renderer *render_priv)
if (!settings_priv->storage_height)
render_priv->blur_scale = render_priv->border_scale;
- if (render_priv->state.overrides & ASS_OVERRIDE_BIT_FONT_SIZE) {
+ if (render_priv->state.apply_font_scale) {
render_priv->font_scale *= settings_priv->font_size_coeff;
render_priv->border_scale *= settings_priv->font_size_coeff;
render_priv->blur_scale *= settings_priv->font_size_coeff;
diff --git a/libass/ass_render.h b/libass/ass_render.h
index b0892ce..d7416e1 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -85,7 +85,7 @@ typedef struct {
double par; // user defined pixel aspect ratio (0 = unset)
ASS_Hinting hinting;
ASS_ShapingLevel shaper;
- int selective_style_overrides;
+ int selective_style_overrides; // ASS_OVERRIDE_* flags
char *default_font;
char *default_family;
@@ -273,6 +273,8 @@ typedef struct {
// combination of ASS_OVERRIDE_BIT_* flags that apply right now
unsigned overrides;
+ // whether to apply font_scale
+ int apply_font_scale;
// used to store RenderContext.style when doing selective style overrides
ASS_Style override_style_temp_storage;
diff --git a/libass/ass_render_api.c b/libass/ass_render_api.c
index 8802629..2db653a 100644
--- a/libass/ass_render_api.c
+++ b/libass/ass_render_api.c
@@ -165,7 +165,6 @@ void ass_set_selective_style_override(ASS_Renderer *priv, ASS_Style *style)
free(user_style->FontName);
*user_style = *style;
user_style->FontName = strdup(user_style->FontName);
- user_style->Name = "OverrideStyle"; // name insignificant
}
int ass_fonts_update(ASS_Renderer *render_priv)