diff --git a/CMakeLists.txt b/CMakeLists.txt index fa46044ce..f0a6cf1c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,7 +241,7 @@ endif () include(FindPkgConfig) if (NOT FT_DISABLE_HARFBUZZ) - set(HARFBUZZ_MIN_VERSION "2.0.0") + set(HARFBUZZ_MIN_VERSION "2.6.8") if (FT_REQUIRE_HARFBUZZ) find_package(HarfBuzz ${HARFBUZZ_MIN_VERSION} REQUIRED) else () diff --git a/builds/unix/configure.raw b/builds/unix/configure.raw index 46d957245..0232eadda 100644 --- a/builds/unix/configure.raw +++ b/builds/unix/configure.raw @@ -429,13 +429,13 @@ fi # check for system libharfbuzz AC_ARG_WITH([harfbuzz], - [AS_HELP_STRING([--with-harfbuzz=@<:@yes|no|auto@:>@], + [AS_HELP_STRING([--with-harfbuzz=@<:@yes|dynamic|no|auto@:>@], [improve auto-hinting of OpenType fonts @<:@default=auto@:>@])], [], [with_harfbuzz=auto]) have_harfbuzz=no if test x"$with_harfbuzz" = xyes -o x"$with_harfbuzz" = xauto; then - harfbuzz_pkg="harfbuzz >= 2.0.0" + harfbuzz_pkg="harfbuzz >= 2.6.8" have_harfbuzz_pkg=no if test x"$HARFBUZZ_CFLAGS" = x -a x"$HARFBUZZ_LIBS" = x; then @@ -465,10 +465,24 @@ if test x"$with_harfbuzz" = xyes -o x"$with_harfbuzz" = xauto; then fi fi -if test x"$with_harfbuzz" = xyes -a "$have_harfbuzz" = no; then - AC_MSG_ERROR([harfbuzz support requested but library not found]) +have_harfbuzz_dynamic=no +if test x"$have_harfbuzz" = xno; then + if test x"$with_harfbuzz" = xdynamic -o x"$with_harfbuzz" = xauto; then + # Check for libdl + AC_CHECK_LIB([dl], [dlopen], [have_harfbuzz_dynamic=yes]) + if test x"$have_harfbuzz_dynamic" = xyes; then + have_harfbuzz="yes (dynamic)" + HARFBUZZ_CFLAGS= + HARFBUZZ_LIBS="-ldl" + fi + fi fi +if test x"$have_harfbuzz" = xno; then + if test x"$with_harfbuzz" != xno -a "$with_harfbuzz" != xauto; then + AC_MSG_ERROR([harfbuzz support requested but library not found]) + fi +fi # check for system libbrotlidec @@ -1074,13 +1088,13 @@ AC_SUBST([build_libtool_libs]) ftoption_set() { - regexp="-e \\\"s|.*#.*def.*$1.*|#define $1|\\\"" + regexp="-e \\\"s|.*#.*def.*$1\>.*|#define $1|\\\"" FTOPTION_H_SED="$FTOPTION_H_SED $regexp" } ftoption_unset() { - regexp="-e \\\"s|.*#.*def.*$1.*|/* #undef $1 */|\\\"" + regexp="-e \\\"s|.*#.*def.*$1\>.*|/* #undef $1 */|\\\"" FTOPTION_H_SED="$FTOPTION_H_SED $regexp" } @@ -1112,6 +1126,11 @@ if test "$have_harfbuzz" != no; then else ftoption_unset FT_CONFIG_OPTION_USE_HARFBUZZ fi +if test "$have_harfbuzz_dynamic" != no; then + ftoption_set FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC +else + ftoption_unset FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC +fi if test "$have_brotli" != no; then CFLAGS="$CFLAGS $BROTLI_CFLAGS" LDFLAGS="$LDFLAGS $BROTLI_LIBS" diff --git a/devel/ftoption.h b/devel/ftoption.h index caa450955..44809a47f 100644 --- a/devel/ftoption.h +++ b/devel/ftoption.h @@ -293,6 +293,31 @@ FT_BEGIN_HEADER #define FT_CONFIG_OPTION_USE_HARFBUZZ + /************************************************************************** + * + * HarfBuzz dynamic support. + * + * Define this macro if you want the HarfBuzz library to be loaded at + * runtime instead of being linked to FreeType. + * + * This option has no effect if `FT_CONFIG_OPTION_USE_HARFBUZZ` is not + * defined. + * + * When this option is enabled, FreeType will try to load the HarfBuzz + * library at runtime, using `dlopen` or `LoadLibrary`, depending on the + * platform. On Microsoft platforms, the library name looked up is + * `libharfbuzz-0.dll`. On Apple platforms, the library name looked up + * is `libharfbuzz.0.dylib`. On all other platforms, the library name + * looked up is `libharfbuzz.so.0`. This name can be overridden by + * defining the macro `FT_LIBHARFBUZZ` at FreeType compilation time. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +#define FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC + + /************************************************************************** * * Brotli support. diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index eb4e32d80..9afd74f29 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -293,6 +293,31 @@ FT_BEGIN_HEADER /* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ + /************************************************************************** + * + * HarfBuzz dynamic support. + * + * Define this macro if you want the HarfBuzz library to be loaded at + * runtime instead of being linked to FreeType. + * + * This option has no effect if `FT_CONFIG_OPTION_USE_HARFBUZZ` is not + * defined. + * + * When this option is enabled, FreeType will try to load the HarfBuzz + * library at runtime, using `dlopen` or `LoadLibrary`, depending on the + * platform. On Microsoft platforms, the library name looked up is + * `libharfbuzz-0.dll`. On Apple platforms, the library name looked up + * is `libharfbuzz.0.dylib`. On all other platforms, the library name + * looked up is `libharfbuzz.so.0`. This name can be overridden by + * defining the macro `FT_LIBHARFBUZZ` at FreeType compilation time. + * + * If you use a build system like cmake or the `configure` script, + * options set by those programs have precedence, overwriting the value + * here with the configured one. + */ +/* #define FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC */ + + /************************************************************************** * * Brotli support. diff --git a/meson.build b/meson.build index cfbb5b9f5..a9bf932c8 100644 --- a/meson.build +++ b/meson.build @@ -348,15 +348,48 @@ if libpng_dep.found() ft2_deps += [libpng_dep] endif -# Harfbuzz support. -harfbuzz_dep = dependency('harfbuzz', - version: '>= 2.0.0', - required: get_option('harfbuzz'), - default_options: ['freetype=disabled']) +# HarfBuzz support. +harfbuzz_opt = get_option('harfbuzz') +harfbuzz_dep = disabler() -if harfbuzz_dep.found() - ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_HARFBUZZ'] - ft2_deps += [harfbuzz_dep] +if harfbuzz_opt == 'enabled' or harfbuzz_opt == 'auto' + harfbuzz_dep = dependency('harfbuzz', + version: '>= 2.6.8', + required: harfbuzz_opt == 'enabled', + default_options: ['freetype=disabled']) + if harfbuzz_dep.found() + harfbuzz_opt = 'YES' + ftoption_command += ['--enable=FT_CONFIG_OPTION_USE_HARFBUZZ'] + ft2_deps += [harfbuzz_dep] + endif +endif + +if not harfbuzz_dep.found() and \ + (harfbuzz_opt == 'dynamic' or harfbuzz_opt == 'auto') + # On Windows we don't need libdl, but on other platforms we need it. + if host_machine.system() == 'windows' + harfbuzz_opt = 'dynamic' + ftoption_command += [ + '--enable=FT_CONFIG_OPTION_USE_HARFBUZZ', + '--enable=FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC', + ] + else + harfbuzz_dep = meson.get_compiler('c').find_library('dl', + required: harfbuzz_opt == 'dynamic', + ) + if harfbuzz_dep.found() + harfbuzz_opt = 'dynamic' + ftoption_command += [ + '--enable=FT_CONFIG_OPTION_USE_HARFBUZZ', + '--enable=FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC', + ] + ft2_deps += [harfbuzz_dep] + endif + endif +endif + +if harfbuzz_opt == 'disabled' or harfbuzz_opt == 'auto' + harfbuzz_opt = 'NO' endif # Brotli decompression support. @@ -489,7 +522,7 @@ summary({'OS': host_machine.system(), summary({'Zlib': zlib_option, 'Bzip2': bzip2_dep.found(), 'Png': libpng_dep.found(), - 'Harfbuzz': harfbuzz_dep.found(), + 'HarfBuzz': harfbuzz_opt, 'Brotli': brotli_dep.found(), }, bool_yn: true, section: 'Used Libraries') diff --git a/meson_options.txt b/meson_options.txt index d4aeb4a8b..45b4acbe6 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -23,7 +23,8 @@ option('bzip2', description: 'Support reading bzip2-compressed font files') option('harfbuzz', - type: 'feature', + type: 'combo', + choices: ['auto', 'enabled', 'dynamic', 'disabled'], value: 'auto', description: 'Use Harfbuzz library to improve auto-hinting;' + ' if available, many glyphs not directly addressable'