diff options
-rw-r--r-- | configure.ac | 25 | ||||
-rw-r--r-- | libass/ass_render.c | 4 | ||||
-rw-r--r-- | libass/ass_render_api.c | 2 | ||||
-rw-r--r-- | libass/ass_shaper.c | 109 |
4 files changed, 87 insertions, 53 deletions
diff --git a/configure.ac b/configure.ac index 56655ee..d9496fc 100644 --- a/configure.ac +++ b/configure.ac @@ -40,8 +40,8 @@ AC_ARG_ENABLE([enca], AS_HELP_STRING([--disable-enca], [disable enca (charset autodetect) support @<:@default=check@:>@])) AC_ARG_ENABLE([fontconfig], AS_HELP_STRING([--disable-fontconfig], [disable fontconfig support @<:@default=enabled@:>@])) -AC_ARG_ENABLE([fribidi], AS_HELP_STRING([--disable-fribidi], - [disable bidi support @<:@default=enabled@:>@])) +AC_ARG_ENABLE([harfbuzz], AS_HELP_STRING([--disable-harfbuzz], + [disable HarfBuzz support @<:@default=check@:>@])) PKG_CHECK_MODULES([FREETYPE], freetype2 >= 9.10.3, [ CFLAGS="$CFLAGS $FREETYPE_CFLAGS" @@ -49,6 +49,12 @@ PKG_CHECK_MODULES([FREETYPE], freetype2 >= 9.10.3, [ AC_DEFINE(CONFIG_FREETYPE, 1, [found freetype2 via pkg-config]) ]) +PKG_CHECK_MODULES([FRIBIDI], fribidi >= 0.19.0, [ + CFLAGS="$CFLAGS $FRIBIDI_CFLAGS" + LIBS="$LIBS $FRIBIDI_LIBS" + AC_DEFINE(CONFIG_FRIBIDI, 1, [found fribidi via pkg-config]) + ]) + if test x$enable_fontconfig != xno; then PKG_CHECK_MODULES([FONTCONFIG], fontconfig >= 2.4.2, [ CFLAGS="$CFLAGS $FONTCONFIG_CFLAGS" @@ -58,22 +64,13 @@ PKG_CHECK_MODULES([FONTCONFIG], fontconfig >= 2.4.2, [ ]) fi -if test x$enable_fribidi != xno; then -PKG_CHECK_MODULES([FRIBIDI], fribidi >= 0.19.0, [ - CFLAGS="$CFLAGS $FRIBIDI_CFLAGS" - LIBS="$LIBS $FRIBIDI_LIBS" - AC_DEFINE(CONFIG_FRIBIDI, 1, [found fribidi via pkg-config]) - fribidi=true - ]) -fi - if test x$enable_harfbuzz != xno; then PKG_CHECK_MODULES([HARFBUZZ], harfbuzz >= 0.7.0, [ CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS" LIBS="$LIBS $HARFBUZZ_LIBS" AC_DEFINE(CONFIG_HARFBUZZ, 1, [found harfbuzz-ng via pkg-config]) harfbuzz=true - ]) + ], [harfbuzz=false]) fi if test x$enable_enca != xno; then @@ -98,15 +95,13 @@ AM_CONDITIONAL([HAVE_LIBPNG], [test x$libpng = xtrue]) # Add dependent libraries to pkg-config for static linking PKG_REQUIRES="freetype2 >= 9.6.3" +PKG_REQUIRES="fribidi >= 0.19.0, ${PKG_REQUIRES}" if test x$enca = xtrue; then PKG_REQUIRES="enca, ${PKG_REQUIRES}" fi if test x$fontconfig = xtrue; then PKG_REQUIRES="fontconfig >= 2.2.0, ${PKG_REQUIRES}" fi -if test x$fribidi = xtrue; then - PKG_REQUIRES="fribidi >= 0.19.0, ${PKG_REQUIRES}" -fi if test x$harfbuzz = xtrue; then PKG_REQUIRES="harfbuzz >= 0.7.0, ${PKG_REQUIRES}" fi diff --git a/libass/ass_render.c b/libass/ass_render.c index 85d30b4..0bc7d38 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -77,7 +77,11 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library) priv->shaper = ass_shaper_new(0); ass_shaper_info(library); +#ifdef CONFIG_HARFBUZZ priv->settings.shaper = ASS_SHAPING_COMPLEX; +#else + priv->settings.shaper = ASS_SHAPING_SIMPLE; +#endif ass_init_exit: if (priv) diff --git a/libass/ass_render_api.c b/libass/ass_render_api.c index 1d8cba6..8bf9e5d 100644 --- a/libass/ass_render_api.c +++ b/libass/ass_render_api.c @@ -60,11 +60,13 @@ void ass_set_frame_size(ASS_Renderer *priv, int w, int h) void ass_set_shaper(ASS_Renderer *priv, ASS_ShapingLevel level) { +#ifdef CONFIG_HARFBUZZ // select the complex shaper for illegal values if (level == ASS_SHAPING_SIMPLE || level == ASS_SHAPING_COMPLEX) priv->settings.shaper = level; else priv->settings.shaper = ASS_SHAPING_COMPLEX; +#endif } void ass_set_margins(ASS_Renderer *priv, int t, int b, int l, int r) diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c index f6724d3..4eb99f7 100644 --- a/libass/ass_shaper.c +++ b/libass/ass_shaper.c @@ -16,8 +16,9 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "config.h" + #include <fribidi/fribidi.h> -#include <hb-ft.h> #include "ass_shaper.h" #include "ass_render.h" @@ -27,15 +28,19 @@ #define MAX_RUNS 50 +#ifdef CONFIG_HARFBUZZ +#include <hb-ft.h> enum { VERT = 0, VKNA, KERN }; #define NUM_FEATURES 3 +#endif struct ass_shaper { ASS_ShapingLevel shaping_level; + // FriBidi log2vis int n_glyphs; FriBidiChar *event_text; @@ -43,14 +48,19 @@ struct ass_shaper { FriBidiLevel *emblevels; FriBidiStrIndex *cmap; FriBidiParType base_direction; + +#ifdef CONFIG_HARFBUZZ // OpenType features int n_features; hb_feature_t *features; hb_language_t language; + // Glyph metrics cache, to speed up shaping Cache *metrics_cache; +#endif }; +#ifdef CONFIG_HARFBUZZ struct ass_shaper_metrics_data { Cache *metrics_cache; GlyphMetricsHashKey hash_key; @@ -61,14 +71,19 @@ struct ass_shaper_font_data { hb_font_funcs_t *font_funcs[ASS_FONT_MAX_FACES]; struct ass_shaper_metrics_data *metrics_data[ASS_FONT_MAX_FACES]; }; +#endif /** * \brief Print version information */ void ass_shaper_info(ASS_Library *lib) { - ass_msg(lib, MSGL_V, "Complex text layout enabled, using FriBidi " - FRIBIDI_VERSION " HarfBuzz-ng %s", hb_version_string()); + ass_msg(lib, MSGL_V, "Shaper: FriBidi " + FRIBIDI_VERSION " (SIMPLE)" +#ifdef CONFIG_HARFBUZZ + " HarfBuzz-ng %s (COMPLEX)", hb_version_string() +#endif + ); } /** @@ -86,55 +101,24 @@ static void check_allocations(ASS_Shaper *shaper, size_t new_size) } /** - * \brief set up the HarfBuzz OpenType feature list with some - * standard features. - */ -static void init_features(ASS_Shaper *shaper) -{ - shaper->features = calloc(sizeof(hb_feature_t), NUM_FEATURES); - - shaper->n_features = NUM_FEATURES; - shaper->features[VERT].tag = HB_TAG('v', 'e', 'r', 't'); - shaper->features[VERT].end = INT_MAX; - shaper->features[VKNA].tag = HB_TAG('v', 'k', 'n', 'a'); - shaper->features[VKNA].end = INT_MAX; - shaper->features[KERN].tag = HB_TAG('k', 'e', 'r', 'n'); - shaper->features[KERN].end = INT_MAX; -} - -/** - * \brief Create a new shaper instance and preallocate data structures - * \param prealloc preallocation size - */ -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); - - shaper->metrics_cache = ass_glyph_metrics_cache_create(); - - return shaper; -} - -/** * \brief Free shaper and related data */ void ass_shaper_free(ASS_Shaper *shaper) { +#ifdef CONFIG_HARFBUZZ ass_cache_done(shaper->metrics_cache); + free(shaper->features); +#endif free(shaper->event_text); free(shaper->ctypes); free(shaper->emblevels); free(shaper->cmap); - free(shaper->features); free(shaper); } void ass_shaper_font_data_free(ASS_ShaperFontData *priv) { +#ifdef CONFIG_HARFBUZZ int i; for (i = 0; i < ASS_FONT_MAX_FACES; i++) if (priv->fonts[i]) { @@ -143,6 +127,25 @@ void ass_shaper_font_data_free(ASS_ShaperFontData *priv) hb_font_funcs_destroy(priv->font_funcs[i]); } free(priv); +#endif +} + +#ifdef CONFIG_HARFBUZZ +/** + * \brief set up the HarfBuzz OpenType feature list with some + * standard features. + */ +static void init_features(ASS_Shaper *shaper) +{ + shaper->features = calloc(sizeof(hb_feature_t), NUM_FEATURES); + + shaper->n_features = NUM_FEATURES; + shaper->features[VERT].tag = HB_TAG('v', 'e', 'r', 't'); + shaper->features[VERT].end = INT_MAX; + shaper->features[VKNA].tag = HB_TAG('v', 'k', 'n', 'a'); + shaper->features[VKNA].end = INT_MAX; + shaper->features[KERN].tag = HB_TAG('k', 'e', 'r', 'n'); + shaper->features[KERN].end = INT_MAX; } /** @@ -482,6 +485,7 @@ static void shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len) } } +#endif /** * \brief Shape event text with FriBidi. Does mirroring and simple @@ -517,7 +521,9 @@ static void shape_fribidi(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len) */ void ass_shaper_set_kerning(ASS_Shaper *shaper, int kern) { +#ifdef CONFIG_HARFBUZZ shaper->features[KERN].value = !!kern; +#endif } /** @@ -564,7 +570,9 @@ void ass_shaper_set_base_direction(ASS_Shaper *shaper, FriBidiParType dir) */ void ass_shaper_set_language(ASS_Shaper *shaper, const char *code) { +#ifdef CONFIG_HARFBUZZ shaper->language = hb_language_from_string(code); +#endif } /** @@ -607,6 +615,7 @@ void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) glyphs[i].shape_run_id += shaper->emblevels[i]; } +#ifdef CONFIG_HARFBUZZ switch (shaper->shaping_level) { case ASS_SHAPING_SIMPLE: shape_fribidi(shaper, glyphs, text_info->length); @@ -615,6 +624,10 @@ void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) shape_harfbuzz(shaper, glyphs, text_info->length); break; } +#else + shape_fribidi(shaper, glyphs, text_info->length); +#endif + // clean up for (i = 0; i < text_info->length; i++) { @@ -629,6 +642,26 @@ void ass_shaper_shape(ASS_Shaper *shaper, TextInfo *text_info) } /** + * \brief Create a new shaper instance and preallocate data structures + * \param prealloc preallocation size + */ +ASS_Shaper *ass_shaper_new(size_t prealloc) +{ + ASS_Shaper *shaper = calloc(sizeof(*shaper), 1); + + shaper->base_direction = FRIBIDI_PAR_ON; + check_allocations(shaper, prealloc); + +#ifdef CONFIG_HARFBUZZ + init_features(shaper); + shaper->metrics_cache = ass_glyph_metrics_cache_create(); +#endif + + return shaper; +} + + +/** * \brief clean up additional data temporarily needed for shaping and * (e.g. additional glyphs allocated) */ |