summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-08-08 01:09:24 +0200
committerGrigori Goronzy <greg@blackbox>2011-08-08 01:16:37 +0200
commitdcebd5fe2a3bc278ab99bd76b66daa0915c98469 (patch)
treed957bcd037886c0cd4c23b0c7fed5bdede77a057
parent0d391f67d3d1c87cd8e8cff907bd7c6b3b1f9cd8 (diff)
downloadlibass-dcebd5fe2a3bc278ab99bd76b66daa0915c98469.tar.bz2
libass-dcebd5fe2a3bc278ab99bd76b66daa0915c98469.tar.xz
Add compile time switch for HarfBuzz support
Now that it's possible to switch shapers at runtime, it also becomes a lot easier to disable them at compile time. Add ifdefs and build system changes so that HarfBuzz can be safely disabled. It's autodetected now and enabled if available. This shuffles a bit of code around, but there are no functional changes. Note that FriBidi remains mandatory for the time being, but this shouldn't pose any problems, since it is a small and very portable library without any special dependencies.
-rw-r--r--configure.ac25
-rw-r--r--libass/ass_render.c4
-rw-r--r--libass/ass_render_api.c2
-rw-r--r--libass/ass_shaper.c109
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)
*/