summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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