Provide configuration option to dynamically load the HarfBuzz library.

We now request HarfBuzz version 2.6.8 (published in June 2020) or newer to
simplify the setup; this version introduced function
`hb_ot_layout_lookup_get_glyph_alternates`, which we need for the adjustment
database of the auto-hinter.

No CMake support yet for dynamic loading.

* include/freetype/config/ftoption.h, devel/ftoption.h
  (FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC): New configuration macro.

* builds/unix/configure.raw: Implement `--with-harfbuzz=dynamic`.
  This gets tested automatically if we can't link with `libharfbuzz`.
  (ft_option_set, ft_option_unset): Refine.
  Require at least HarfBuzz version 2.6.8.

* meson.build: Do the same as `configure.raw`.
* meson_options.txt: Updated.

* CMakeLists.txt: Require at least HarfBuzz version 2.6.8.
This commit is contained in:
Behdad Esfahbod (بهداد اسفهبد) 2025-04-26 13:53:24 +02:00 committed by Werner Lemberg
parent 97bb53ee0a
commit 5d2fd7608a
6 changed files with 120 additions and 17 deletions

View file

@ -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 ()

View file

@ -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"

View file

@ -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.

View file

@ -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.

View file

@ -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')

View file

@ -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'