diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 6592277c3..fb29dba9b 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -368,6 +368,7 @@ hb_face_count hb_face_t hb_face_create hb_face_create_or_fail +hb_face_create_or_fail_using hb_face_create_from_file_or_fail hb_face_create_from_file_or_fail_using hb_face_list_loaders diff --git a/src/hb-face.cc b/src/hb-face.cc index 56ff340ff..0399e720e 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -328,17 +328,29 @@ hb_face_create_from_file_or_fail (const char *file_name, static struct supported_face_loaders_t { char name[9]; - hb_face_t * (*func) (const char *font_file, unsigned face_index); + hb_face_t * (*from_file) (const char *font_file, unsigned face_index); + hb_face_t * (*from_blob) (hb_blob_t *blob, unsigned face_index); } supported_face_loaders[] = { + {"ot", #ifndef HB_NO_OPEN - {"ot", hb_face_create_from_file_or_fail}, + hb_face_create_from_file_or_fail, +#else + nullptr, #endif + hb_face_create_or_fail + }, #ifdef HAVE_FREETYPE - {"ft", hb_ft_face_create_from_file_or_fail}, + {"ft", + hb_ft_face_create_from_file_or_fail, + hb_ft_face_create_from_blob_or_fail + }, #endif #ifdef HAVE_CORETEXT - {"coretext", hb_coretext_face_create_from_file_or_fail}, + {"coretext", + hb_coretext_face_create_from_file_or_fail, + hb_coretext_face_create_from_blob_or_fail + }, #endif }; @@ -368,7 +380,7 @@ static const char *get_default_loader_name () * is used. * * For example, the FreeType ("ft") loader might be able to load - * .woff and .woff2 files if FreeType is built with those features, + * 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 @@ -381,6 +393,7 @@ hb_face_create_from_file_or_fail_using (const char *file_name, unsigned int index, const char *loader_name) { + // Duplicated in hb_face_create_or_fail_using bool retry = false; if (!loader_name || !*loader_name) { @@ -392,8 +405,58 @@ hb_face_create_from_file_or_fail_using (const char *file_name, retry: for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) { - if (!loader_name || !strcmp (supported_face_loaders[i].name, loader_name)) - return supported_face_loaders[i].func (file_name, index); + if (!loader_name || (supported_face_loaders[i].from_file && !strcmp (supported_face_loaders[i].name, loader_name))) + return supported_face_loaders[i].from_file (file_name, index); + } + + if (retry) + { + retry = false; + loader_name = nullptr; + goto retry; + } + + return nullptr; +} + +/** + * hb_face_create_or_fail_using: + * @blob: #hb_blob_t to work upon + * @index: The index of the face within @blob + * @loader_name: (nullable): The name of the loader to use, or `NULL` + * + * A thin wrapper around the face loader functions registered with HarfBuzz. + * If @loader_name is `NULL` or the empty string, 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 loader fails to load the face. + * + * XSince: REPLACEME + **/ +hb_face_t * +hb_face_create_or_fail_using (hb_blob_t *blob, + unsigned int index, + const char *loader_name) +{ + // Duplicated in hb_face_create_from_file_or_fail_using + bool retry = false; + if (!loader_name || !*loader_name) + { + loader_name = get_default_loader_name (); + retry = true; + } + if (loader_name && !*loader_name) loader_name = nullptr; + +retry: + for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++) + { + if (!loader_name || (supported_face_loaders[i].from_blob && !strcmp (supported_face_loaders[i].name, loader_name))) + return supported_face_loaders[i].from_blob (blob, index); } if (retry) diff --git a/src/hb-face.h b/src/hb-face.h index c59ec0c4b..5d39a48cc 100644 --- a/src/hb-face.h +++ b/src/hb-face.h @@ -63,6 +63,11 @@ HB_EXTERN hb_face_t * hb_face_create_or_fail (hb_blob_t *blob, unsigned int index); +HB_EXTERN hb_face_t * +hb_face_create_or_fail_using (hb_blob_t *blob, + unsigned int index, + const char *loader_name); + HB_EXTERN hb_face_t * hb_face_create_from_file_or_fail (const char *file_name, unsigned int index);