[autofit] Enable dynamic loading of HarfBuzz. (2/2)

Handle the case where loading HarfBuzz dynamically fails.

* src/autofit/ft-hb.c, src/autofit/ft-hb.h (ft_hb_enabled): New function.

* src/autofit/afglobal.c (af_face_globals_new, af_face_globals_free):
  Guard HarfBuzz functions with `ft_hb_enabled`.

* src/autofit/aflatin.c (af_latin_metrics_init_widths,
  af_latin_metrics_init_blues, af_latin_metrics_check_digits): Simplify
  setup of `shaper_buf`.
  Guard calls of `af_shaper_buf_create` with `ft_hb_enabled`.

* src/autofit/afcjk.c (af_cjk_metrics_init_widths,
  af_cjk_metrics_init_blues, af_cjk_metrics_check_digits): Dito.

* src/autofit/afshaper.c: Guard all HarfBuzz function calls with
  `ft_hb_enabled`.
This commit is contained in:
Behdad Esfahbod (بهداد اسفهبد) 2025-04-28 07:24:41 +02:00 committed by Werner Lemberg
parent 7651fe00be
commit 97bb53ee0a
6 changed files with 90 additions and 60 deletions

View file

@ -90,12 +90,8 @@
/* If HarfBuzz is not available, we need a pointer to a single */
/* unsigned long value. */
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
void* shaper_buf;
#else
FT_ULong shaper_buf_;
void* shaper_buf = &shaper_buf_;
#endif
const char* p;
@ -105,9 +101,8 @@
p = script_class->standard_charstring;
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
shaper_buf = af_shaper_buf_create( metrics->root.globals );
#endif
if ( ft_hb_enabled( metrics->root.globals ) )
shaper_buf = af_shaper_buf_create( metrics->root.globals );
/* We check a list of standard characters. The first match wins. */
@ -297,12 +292,8 @@
/* If HarfBuzz is not available, we need a pointer to a single */
/* unsigned long value. */
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
void* shaper_buf;
#else
FT_ULong shaper_buf_;
void* shaper_buf = &shaper_buf_;
#endif
/* we walk over the blue character strings as specified in the */
@ -313,9 +304,8 @@
FT_TRACE5(( "==========================\n" ));
FT_TRACE5(( "\n" ));
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
shaper_buf = af_shaper_buf_create( metrics->root.globals );
#endif
if ( ft_hb_enabled( metrics->root.globals ) )
shaper_buf = af_shaper_buf_create( metrics->root.globals );
for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ )
{
@ -572,12 +562,8 @@
/* If HarfBuzz is not available, we need a pointer to a single */
/* unsigned long value. */
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
void* shaper_buf;
#else
FT_ULong shaper_buf_;
void* shaper_buf = &shaper_buf_;
#endif
/* in all supported charmaps, digits have character codes 0x30-0x39 */
const char digits[] = "0 1 2 3 4 5 6 7 8 9";
@ -588,9 +574,8 @@
p = digits;
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
shaper_buf = af_shaper_buf_create( metrics->root.globals );
#endif
if ( ft_hb_enabled( metrics->root.globals ) )
shaper_buf = af_shaper_buf_create( metrics->root.globals );
while ( *p )
{

View file

@ -22,6 +22,10 @@
#include "afws-decl.h"
#include <freetype/internal/ftdebug.h>
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
# include "ft-hb-ft.h"
#endif
/**************************************************************************
*
@ -356,8 +360,16 @@
globals->scale_down_factor = 0;
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
globals->hb_font = ft_hb_ft_font_create( globals );
globals->hb_buf = hb( buffer_create )();
if ( ft_hb_enabled ( globals ) )
{
globals->hb_font = ft_hb_ft_font_create( globals );
globals->hb_buf = hb( buffer_create )();
}
else
{
globals->hb_font = NULL;
globals->hb_buf = NULL;
}
#endif
error = af_face_globals_compute_style_coverage( globals );
@ -405,8 +417,11 @@
}
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
hb( font_destroy )( globals->hb_font );
hb( buffer_destroy )( globals->hb_buf );
if ( ft_hb_enabled ( globals ) )
{
hb( font_destroy )( globals->hb_font );
hb( buffer_destroy )( globals->hb_buf );
}
#endif
/* no need to free `globals->glyph_styles'; */

View file

@ -82,12 +82,8 @@
/* If HarfBuzz is not available, we need a pointer to a single */
/* unsigned long value. */
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
void* shaper_buf;
#else
FT_ULong shaper_buf_;
void* shaper_buf = &shaper_buf_;
#endif
const char* p;
@ -98,9 +94,9 @@
p = script_class->standard_charstring;
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
shaper_buf = af_shaper_buf_create( metrics->root.globals );
#endif
if ( ft_hb_enabled ( metrics->root.globals ) )
shaper_buf = af_shaper_buf_create( metrics->root.globals );
/*
* We check a list of standard characters to catch features like
* `c2sc' (small caps from caps) that don't contain lowercase letters
@ -335,12 +331,8 @@
/* If HarfBuzz is not available, we need a pointer to a single */
/* unsigned long value. */
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
void* shaper_buf;
#else
FT_ULong shaper_buf_;
void* shaper_buf = &shaper_buf_;
#endif
/* we walk over the blue character strings as specified in the */
@ -350,9 +342,8 @@
FT_TRACE5(( "============================\n" ));
FT_TRACE5(( "\n" ));
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
shaper_buf = af_shaper_buf_create( metrics->root.globals );
#endif
if ( ft_hb_enabled ( metrics->root.globals ) )
shaper_buf = af_shaper_buf_create( metrics->root.globals );
for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ )
{
@ -1071,12 +1062,8 @@
/* If HarfBuzz is not available, we need a pointer to a single */
/* unsigned long value. */
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
void* shaper_buf;
#else
FT_ULong shaper_buf_;
void* shaper_buf = &shaper_buf_;
#endif
/* in all supported charmaps, digits have character codes 0x30-0x39 */
const char digits[] = "0 1 2 3 4 5 6 7 8 9";
@ -1087,9 +1074,8 @@
p = digits;
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
shaper_buf = af_shaper_buf_create( metrics->root.globals );
#endif
if ( ft_hb_enabled ( metrics->root.globals ) )
shaper_buf = af_shaper_buf_create( metrics->root.globals );
while ( *p )
{

View file

@ -699,15 +699,17 @@
FT_Bool default_script )
{
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
return af_shaper_get_coverage_hb( globals,
style_class,
gstyles,
default_script );
#endif
return af_shaper_get_coverage_nohb( globals,
if ( ft_hb_enabled( globals ) )
return af_shaper_get_coverage_hb( globals,
style_class,
gstyles,
default_script );
else
#endif
return af_shaper_get_coverage_nohb( globals,
style_class,
gstyles,
default_script );
}
@ -715,9 +717,11 @@
af_shaper_buf_create( AF_FaceGlobals globals )
{
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
return af_shaper_buf_create_hb( globals );
if ( ft_hb_enabled( globals ) )
return af_shaper_buf_create_hb( globals );
else
#endif
return af_shaper_buf_create_nohb( globals );
return af_shaper_buf_create_nohb( globals );
}
@ -726,9 +730,11 @@
void* buf )
{
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
af_shaper_buf_destroy_hb( globals, buf );
if ( ft_hb_enabled( globals ) )
af_shaper_buf_destroy_hb( globals, buf );
else
#endif
af_shaper_buf_destroy_nohb( globals, buf );
af_shaper_buf_destroy_nohb( globals, buf );
}
@ -739,9 +745,11 @@
unsigned int* count )
{
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
return af_shaper_get_cluster_hb( p, metrics, buf_, count );
if ( ft_hb_enabled( metrics->globals ) )
return af_shaper_get_cluster_hb( p, metrics, buf_, count );
else
#endif
return af_shaper_get_cluster_nohb( p, metrics, buf_, count );
return af_shaper_get_cluster_nohb( p, metrics, buf_, count );
}
@ -753,9 +761,18 @@
FT_Long* y_offset )
{
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
return af_shaper_get_elem_hb( metrics, buf_, idx, advance, y_offset );
if ( ft_hb_enabled( metrics->globals ) )
return af_shaper_get_elem_hb( metrics,
buf_,
idx,
advance,
y_offset );
#endif
return af_shaper_get_elem_nohb( metrics, buf_, idx, advance, y_offset );
return af_shaper_get_elem_nohb( metrics,
buf_,
idx,
advance,
y_offset );
}

View file

@ -153,12 +153,33 @@
}
}
FT_LOCAL_DEF( FT_Bool )
ft_hb_enabled( struct AF_FaceGlobalsRec_ *globals )
{
return globals->module->hb_funcs != NULL;
}
#ifndef _WIN32
# if defined( __GNUC__ )
# pragma GCC diagnostic pop
# endif
#endif
#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC */
FT_LOCAL_DEF( FT_Bool )
ft_hb_enabled( struct AF_FaceGlobalsRec_ *globals )
{
FT_UNUSED( globals );
#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
return TRUE;
#else
return FALSE;
#endif
}
#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ_DYNAMIC */

View file

@ -68,6 +68,12 @@ FT_BEGIN_HEADER
#endif /* FT_CONFIG_OPTION_USE_HARFBUZZ */
struct AF_FaceGlobalsRec_;
FT_LOCAL( FT_Bool )
ft_hb_enabled( struct AF_FaceGlobalsRec_ *globals );
FT_END_HEADER
#endif /* FT_HB_H */