summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorDan Oscarsson <DanOscarsson@users.noreply.github.com>2016-10-05 13:52:47 +0200
committerwm4 <wm4@nowhere>2016-11-12 18:42:55 +0100
commite54c123d5a08b6212533ddcced2cb1a50fa3d2b2 (patch)
treeb6132f98f88924239d8f5c6fcb4cd2d96afd5d49 /libass
parent35dc4dd0e14e3afb4a2c7e319a3f4110e20c7cf2 (diff)
downloadlibass-e54c123d5a08b6212533ddcced2cb1a50fa3d2b2.tar.bz2
libass-e54c123d5a08b6212533ddcced2cb1a50fa3d2b2.tar.xz
Add text justification
Subtitle recommendations often include that multi line subtitles should be left justified as this is easier for the eyes. This is also the standard used by several television companies. This add the possibility to define how subtitles are to be justified, independently of where they are aligned. The most common way could be to set justify to left, and have alignment to center. But you can, for example, have alignment to left and justify to center, giving subtitles to the left but justifed on the center (instead of normal left justified). Using justify right and alignment of center, might be good choice for Arabic. If justify is not defined, all works like before. If justify is defined, subtitles are aligned as defined by alignment and justified as defined by justify. ASS is not extended by this, justify can only be defined by setting Justify to wanted justification.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass.c1
-rw-r--r--libass/ass.h4
-rw-r--r--libass/ass_render.c40
-rw-r--r--libass/ass_render.h1
-rw-r--r--libass/ass_types.h5
5 files changed, 48 insertions, 3 deletions
diff --git a/libass/ass.c b/libass/ass.c
index f42fd4b..1cb0d4c 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -449,6 +449,7 @@ void ass_process_force_style(ASS_Track *track)
FPVAL(Angle)
INTVAL(BorderStyle)
INTVAL(Alignment)
+ INTVAL(Justify)
INTVAL(MarginL)
INTVAL(MarginR)
INTVAL(MarginV)
diff --git a/libass/ass.h b/libass/ass.h
index 24a4618..912a7a1 100644
--- a/libass/ass.h
+++ b/libass/ass.h
@@ -166,6 +166,10 @@ typedef enum {
* resolution given by the ASS_Track.
*/
ASS_OVERRIDE_FULL_STYLE = 1 << 9,
+ /**
+ * On dialogue events override: Justify
+ */
+ ASS_OVERRIDE_BIT_JUSTIFY = 1 << 10,
} ASS_OverrideBits;
/**
diff --git a/libass/ass_render.c b/libass/ass_render.c
index d57bdac..d0f827d 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -784,6 +784,9 @@ static ASS_Style *handle_selective_style_overrides(ASS_Renderer *render_priv,
if (requested & ASS_OVERRIDE_BIT_ALIGNMENT)
new->Alignment = user->Alignment;
+ if (requested & ASS_OVERRIDE_BIT_JUSTIFY)
+ new->Justify = user->Justify;
+
if (requested & ASS_OVERRIDE_BIT_MARGINS) {
new->MarginL = user->MarginL;
new->MarginR = user->MarginR;
@@ -886,6 +889,7 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event)
render_priv->state.wrap_style = render_priv->track->WrapStyle;
render_priv->state.alignment = render_priv->state.style->Alignment;
+ render_priv->state.justify = render_priv->state.style->Justify;
render_priv->state.pos_x = 0;
render_priv->state.pos_y = 0;
render_priv->state.org_x = 0;
@@ -2071,19 +2075,49 @@ static void align_lines(ASS_Renderer *render_priv, double max_text_width)
double width = 0;
int last_break = -1;
int halign = render_priv->state.alignment & 3;
+ int justify = render_priv->state.justify;
+ double max_width = 0;
if (render_priv->state.evt_type == EVENT_HSCROLL)
return;
for (i = 0; i <= text_info->length; ++i) { // (text_info->length + 1) is the end of the last line
if ((i == text_info->length) || glyphs[i].linebreak) {
+ max_width = FFMAX(max_width,width);
+ width = 0;
+ }
+ if (i < text_info->length && !glyphs[i].skip &&
+ glyphs[i].symbol != '\n' && glyphs[i].symbol != 0) {
+ width += d6_to_double(glyphs[i].cluster_advance.x);
+ }
+ }
+ for (i = 0; i <= text_info->length; ++i) { // (text_info->length + 1) is the end of the last line
+ if ((i == text_info->length) || glyphs[i].linebreak) {
double shift = 0;
if (halign == HALIGN_LEFT) { // left aligned, no action
- shift = 0;
+ if (justify == ASS_JUSTIFY_RIGHT) {
+ shift = max_width - width;
+ } else if (justify == ASS_JUSTIFY_CENTER) {
+ shift = (max_width - width) / 2.0;
+ } else {
+ shift = 0;
+ }
} else if (halign == HALIGN_RIGHT) { // right aligned
- shift = max_text_width - width;
+ if (justify == ASS_JUSTIFY_LEFT) {
+ shift = max_text_width - max_width;
+ } else if (justify == ASS_JUSTIFY_CENTER) {
+ shift = max_text_width - max_width + (max_width - width) / 2.0;
+ } else {
+ shift = max_text_width - width;
+ }
} else if (halign == HALIGN_CENTER) { // centered
- shift = (max_text_width - width) / 2.0;
+ if (justify == ASS_JUSTIFY_LEFT) {
+ shift = (max_text_width - max_width) / 2.0;
+ } else if (justify == ASS_JUSTIFY_RIGHT) {
+ shift = (max_text_width - max_width) / 2.0 + max_width - width;
+ } else {
+ shift = (max_text_width - width) / 2.0;
+ }
}
for (j = last_break + 1; j < i; ++j) {
GlyphInfo *info = glyphs + j;
diff --git a/libass/ass_render.h b/libass/ass_render.h
index 6e3963e..fad554b 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -220,6 +220,7 @@ typedef struct {
FT_Stroker stroker;
int stroker_radius; // last stroker radius, for caching stroker objects
int alignment; // alignment overrides go here; if zero, style value will be used
+ int justify; // justify instructions
double frx, fry, frz;
double fax, fay; // text shearing
enum {
diff --git a/libass/ass_types.h b/libass/ass_types.h
index f4a6ae5..88951a7 100644
--- a/libass/ass_types.h
+++ b/libass/ass_types.h
@@ -28,6 +28,10 @@
#define HALIGN_LEFT 1
#define HALIGN_CENTER 2
#define HALIGN_RIGHT 3
+#define ASS_JUSTIFY_AUTO 0
+#define ASS_JUSTIFY_LEFT 1
+#define ASS_JUSTIFY_CENTER 2
+#define ASS_JUSTIFY_RIGHT 3
#define FONT_WEIGHT_LIGHT 300
#define FONT_WEIGHT_MEDIUM 400
@@ -73,6 +77,7 @@ typedef struct ass_style {
int Encoding;
int treat_fontname_as_pattern;
double Blur;
+ int Justify;
} ASS_Style;