From 6b9d9f7259595f7b6fd98204559224be9e791412 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 9 Mar 2025 01:40:23 -0700 Subject: [PATCH] [face] Add HB_FACE_LOADER env var --- perf/hb-benchmark.hh | 17 +---------------- src/hb-face.cc | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/perf/hb-benchmark.hh b/perf/hb-benchmark.hh index 28860476d..c976831c0 100644 --- a/perf/hb-benchmark.hh +++ b/perf/hb-benchmark.hh @@ -56,22 +56,7 @@ static inline hb_face_t * hb_benchmark_face_create_from_file_or_fail (const char *font_path, unsigned face_index) { - const char *loader = getenv ("HB_FACE_LOADER"); - if (loader && !*loader) - loader = nullptr; - -#ifdef HAVE_FREETYPE - if (loader && !strcmp (loader, "ft")) - return hb_ft_face_create_from_file_or_fail (font_path, face_index); -#endif -#ifdef HAVE_CORETEXT - if (loader && !strcmp (loader, "coretext")) - return hb_coretext_face_create_from_file_or_fail (font_path, face_index); -#endif - if (!loader || !strcmp (loader, "ot")) - return hb_face_create_from_file_or_fail (font_path, face_index); - - assert (false); + return hb_face_create_from_file_or_fail_using (font_path, face_index, nullptr); } HB_END_DECLS diff --git a/src/hb-face.cc b/src/hb-face.cc index 190a9c52f..a738e9c28 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -352,6 +352,10 @@ static struct supported_face_loaders_t { * A thin wrapper around the face loader functions registered with HarfBuzz. * If @loader_name is `NULL`, the first available loader is used. * + * For example, the FreeType ("ft") loader might be able to load + * .woff and .woff2 files if FreeType is built with those features, + * whereas the OpenType ("ot") loader will not. + * * Return value: (transfer full): The new face object, or `NULL` if * the file cannot be read or the loader fails to load the face. * @@ -360,15 +364,40 @@ static struct supported_face_loaders_t { hb_face_t * hb_face_create_from_file_or_fail_using (const char *file_name, unsigned int index, - const char *loader_name) + const char *name) { - if (loader_name && !*loader_name) - loader_name = nullptr; + bool retry = false; + + if (!name || !*name) + { + static hb_atomic_ptr_t static_funcs_name; + name = static_funcs_name.get_acquire (); + if (!name) + { + name = getenv ("HB_FACE_LOADER"); + if (!name) + name = ""; + if (!static_funcs_name.cmpexch (nullptr, name)) + name = static_funcs_name.get_acquire (); + } + retry = true; + } + if (name && !*name) name = nullptr; + +retry: for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) { - if (!loader_name || !strcmp (supported_face_loaders[i].name, loader_name)) + if (!name || !strcmp (supported_face_loaders[i].name, name)) return supported_face_loaders[i].func (file_name, index); } + + if (retry) + { + retry = false; + name = nullptr; + goto retry; + } + return nullptr; }