summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-07-14 00:01:11 +0200
committerGrigori Goronzy <greg@blackbox>2011-07-15 14:59:07 +0200
commitb1f12a86374015305347ce83cad96f2eb35b0212 (patch)
treeeff4f4cd842ea291a887e41ec59af82f59c0859c
parent93c1573cca573024a93db82a712d724a79e8a6e6 (diff)
downloadlibass-b1f12a86374015305347ce83cad96f2eb35b0212.tar.bz2
libass-b1f12a86374015305347ce83cad96f2eb35b0212.tar.xz
Use the "font encoding" property as a base direction hint
ASS specifies a "font encoding", both in the styles as well as with the \fe override tag. This font encoding is very Windows-specific and libass doesn't use it for charmap matching or anything like that. However, it can be useful for hinting the base direction of text. Make Hebrew and Arabic encodings switch to RTL base direction, other languages to LTR and use neutral base direction for the autodetect setting.
-rw-r--r--libass/ass_parse.c5
-rw-r--r--libass/ass_render.c3
-rw-r--r--libass/ass_render.h1
-rw-r--r--libass/ass_shaper.c37
-rw-r--r--libass/ass_shaper.h2
5 files changed, 45 insertions, 3 deletions
diff --git a/libass/ass_parse.c b/libass/ass_parse.c
index afa0019..274d84d 100644
--- a/libass/ass_parse.c
+++ b/libass/ass_parse.c
@@ -819,6 +819,11 @@ static char *parse_tag(ASS_Renderer *render_priv, char *p, double pwr)
if (!mystrtoi(&p, &val))
val = render_priv->track->WrapStyle;
render_priv->state.wrap_style = val;
+ } else if (mystrcmp(&p, "fe")) {
+ int val;
+ if (!mystrtoi(&p, &val))
+ val = render_priv->state.style->Encoding;
+ render_priv->state.font_encoding = val;
}
return p;
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 68d747d..3d23e29 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -898,6 +898,7 @@ void reset_render_context(ASS_Renderer *render_priv)
render_priv->state.frz = M_PI * render_priv->state.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;
}
/**
@@ -1835,6 +1836,8 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
}
// Find shape runs and shape text
+ ass_shaper_set_base_direction(render_priv->shaper,
+ resolve_base_direction(render_priv->state.font_encoding));
ass_shaper_find_runs(render_priv->shaper, render_priv, glyphs,
text_info->length);
ass_shaper_shape(render_priv->shaper, text_info);
diff --git a/libass/ass_render.h b/libass/ass_render.h
index 1c49823..05c4974 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -224,6 +224,7 @@ typedef struct {
unsigned italic;
int treat_family_as_pattern;
int wrap_style;
+ int font_encoding;
} RenderContext;
typedef struct {
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index 802f118..9a4e8d5 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -40,6 +40,7 @@ struct ass_shaper {
FriBidiCharType *ctypes;
FriBidiLevel *emblevels;
FriBidiStrIndex *cmap;
+ FriBidiParType base_direction;
// OpenType features
int n_features;
hb_feature_t *features;
@@ -93,8 +94,10 @@ ASS_Shaper *ass_shaper_new(size_t prealloc)
{
ASS_Shaper *shaper = calloc(sizeof(*shaper), 1);
+ shaper->base_direction = FRIBIDI_PAR_ON;
init_features(shaper);
check_allocations(shaper, prealloc);
+
return shaper;
}
@@ -287,6 +290,15 @@ void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv,
}
/**
+ * \brief Set base direction (paragraph direction) of the text.
+ * \param dir base direction
+ */
+void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir)
+{
+ shaper->base_direction = dir;
+}
+
+/**
* \brief Shape an event's text. Calculates directional runs and shapes them.
* \param text_info event's text
*/
@@ -305,7 +317,7 @@ void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info)
// embedding levels should be calculated paragraph by paragraph
if (glyphs[i].symbol == '\n' || i == text_info->length - 1) {
//printf("paragraph from %d to %d\n", last_break, i);
- dir = FRIBIDI_PAR_ON;
+ dir = shaper->base_direction;
fribidi_get_bidi_types(shaper->event_text + last_break,
i - last_break + 1, shaper->ctypes + last_break);
fribidi_get_par_embedding_levels(shaper->ctypes + last_break,
@@ -368,7 +380,6 @@ void ass_shaper_cleanup(ASS_Shaper *shaper, TextInfo *text_info)
FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info)
{
int i;
- FriBidiParType dir;
// Initialize reorder map
for (i = 0; i < text_info->length; i++)
@@ -378,7 +389,7 @@ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info)
for (i = 0; i < text_info->n_lines; i++) {
LineInfo *line = text_info->lines + i;
int level;
- dir = FRIBIDI_PAR_ON;
+ FriBidiParType dir = FRIBIDI_PAR_ON;
// FIXME: we should actually specify
// the correct paragraph base direction
@@ -399,3 +410,23 @@ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info)
return shaper->cmap;
}
+
+/**
+ * \brief Resolve a Windows font encoding number to a suitable
+ * base direction. 177 and 178 are Hebrew and Arabic respectively, and
+ * they map to RTL. 1 is autodetection and is mapped to just that.
+ * Everything else is mapped to LTR.
+ * \param enc Windows font encoding
+ */
+FriBidiParType resolve_base_direction(int enc)
+{
+ switch (enc) {
+ case 1:
+ return FRIBIDI_PAR_ON;
+ case 177:
+ case 178:
+ return FRIBIDI_PAR_RTL;
+ default:
+ return FRIBIDI_PAR_LTR;
+ }
+}
diff --git a/libass/ass_shaper.h b/libass/ass_shaper.h
index cbfcdd7..a5bb462 100644
--- a/libass/ass_shaper.h
+++ b/libass/ass_shaper.h
@@ -30,8 +30,10 @@ void ass_shaper_free(ASS_Shaper *shaper);
void ass_shaper_set_kerning(ASS_Shaper *shaper, int kern);
void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv,
GlyphInfo *glyphs, size_t len);
+void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir);
void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info);
void ass_shaper_cleanup(ASS_Shaper *shaper, TextInfo *text_info);
FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info);
+FriBidiParType resolve_base_direction(int font_encoding);
#endif