summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-08-01 15:51:27 +0200
committerGrigori Goronzy <greg@blackbox>2011-08-01 15:51:27 +0200
commitc979365946b2dc2499ede862b6f7da15f9bc0ed1 (patch)
tree688d0ecc6d17dbdd2df22719a2702ecba29a8b69
parentd7544850775344879dd3049046c5b7ce2d52d3b3 (diff)
downloadlibass-c979365946b2dc2499ede862b6f7da15f9bc0ed1.tar.bz2
libass-c979365946b2dc2499ede862b6f7da15f9bc0ed1.tar.xz
Support language hint in the Script Info section
Parse a hint in the form "Language: xx" with xx being an ISO 639-1 language code, and pass it to HarfBuzz. This can be useful to render scripts with language-specific character variants.
-rw-r--r--libass/ass.c8
-rw-r--r--libass/ass_render.c2
-rw-r--r--libass/ass_shaper.c13
-rw-r--r--libass/ass_shaper.h1
-rw-r--r--libass/ass_types.h1
5 files changed, 25 insertions, 0 deletions
diff --git a/libass/ass.c b/libass/ass.c
index e262cc3..712c16c 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -28,6 +28,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <inttypes.h>
+#include <ctype.h>
#ifdef CONFIG_ICONV
#include <iconv.h>
@@ -69,6 +70,7 @@ void ass_free_track(ASS_Track *track)
}
free(track->style_format);
free(track->event_format);
+ free(track->Language);
if (track->styles) {
for (i = 0; i < track->n_styles; ++i)
ass_free_style(track, i);
@@ -595,6 +597,12 @@ static int process_info_line(ASS_Track *track, char *str)
track->ScaledBorderAndShadow = parse_bool(str + 22);
} else if (!strncmp(str, "Kerning:", 8)) {
track->Kerning = parse_bool(str + 8);
+ } else if (!strncmp(str, "Language:", 9)) {
+ char *p = str + 9;
+ while (*p && isspace(*p)) p++;
+ track->Language = malloc(3);
+ strncpy(track->Language, p, 2);
+ track->Language[2] = 0;
}
return 0;
}
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 8d82a74..8d55667 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -2269,6 +2269,8 @@ ass_start_frame(ASS_Renderer *render_priv, ASS_Track *track,
render_priv->border_scale = 1.;
ass_shaper_set_kerning(render_priv->shaper, track->Kerning);
+ if (track->Language)
+ ass_shaper_set_language(render_priv->shaper, track->Language);
// PAR correction
render_priv->font_scale_x = render_priv->settings.aspect /
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index 15dc549..16026f5 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -45,6 +45,7 @@ struct ass_shaper {
// OpenType features
int n_features;
hb_feature_t *features;
+ hb_language_t language;
// Glyph metrics cache, to speed up shaping
Cache *metrics_cache;
};
@@ -428,6 +429,7 @@ static void shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
set_run_features(shaper, glyphs + k);
hb_buffer_set_direction(runs[run].buf, direction ? HB_DIRECTION_RTL :
HB_DIRECTION_LTR);
+ hb_buffer_set_language(runs[run].buf, shaper->language);
hb_buffer_add_utf32(runs[run].buf, shaper->event_text + k, i - k + 1,
0, i - k + 1);
hb_shape(runs[run].font, runs[run].buf, shaper->features,
@@ -559,6 +561,17 @@ void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir)
}
/**
+ * \brief Set language hint. Some languages have specific character variants,
+ * like Serbian Cyrillic.
+ * \param lang ISO 639-1 two-letter language code
+ */
+void ass_shaper_set_language(ASS_Shaper *shaper, const char *code)
+{
+ printf("setting language to '%s'\n", code);
+ shaper->language = hb_language_from_string(code);
+}
+
+/**
* \brief Shape an event's text. Calculates directional runs and shapes them.
* \param text_info event's text
*/
diff --git a/libass/ass_shaper.h b/libass/ass_shaper.h
index 894822d..7e8bcc6 100644
--- a/libass/ass_shaper.h
+++ b/libass/ass_shaper.h
@@ -31,6 +31,7 @@ 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_set_language(ASS_Shaper *shaper, const char *code);
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);
diff --git a/libass/ass_types.h b/libass/ass_types.h
index 6a6f1ae..20fd825 100644
--- a/libass/ass_types.h
+++ b/libass/ass_types.h
@@ -112,6 +112,7 @@ typedef struct ass_track {
int WrapStyle;
int ScaledBorderAndShadow;
int Kerning;
+ char *Language;
int default_style; // index of default style
char *name; // file name in case of external subs, 0 for streams