diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 736f66179..6592277c3 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -347,6 +347,7 @@ HB_CORETEXT_TAG_MORT HB_CORETEXT_TAG_MORX hb_coretext_face_create hb_coretext_face_create_from_file_or_fail +hb_coretext_face_create_from_blob_or_fail hb_coretext_font_create hb_coretext_face_get_cg_font hb_coretext_font_get_ct_font diff --git a/src/hb-coretext-shape.cc b/src/hb-coretext-shape.cc index 2e029fe2b..33296c77c 100644 --- a/src/hb-coretext-shape.cc +++ b/src/hb-coretext-shape.cc @@ -160,30 +160,42 @@ release_data (void *info, const void *data, size_t size) hb_blob_destroy ((hb_blob_t *) info); } +static CGFontRef +create_cg_font (hb_blob_t *blob, unsigned int index) +{ + if (unlikely (index != 0)) + return nullptr; // How? + + hb_blob_make_immutable (blob); + unsigned int blob_length; + const char *blob_data = hb_blob_get_data (blob, &blob_length); + if (unlikely (!blob_length)) + DEBUG_MSG (CORETEXT, blob, "Empty blob"); + + hb_blob_reference (blob); + CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); + CGFontRef cg_font = nullptr; + if (likely (provider)) + { + cg_font = CGFontCreateWithDataProvider (provider); + if (unlikely (!cg_font)) + DEBUG_MSG (CORETEXT, blob, "CGFontCreateWithDataProvider() failed"); + CGDataProviderRelease (provider); + } + return cg_font; +} + static CGFontRef create_cg_font (hb_face_t *face) { CGFontRef cg_font = nullptr; if (face->destroy == _hb_cg_font_release) - { cg_font = CGFontRetain ((CGFontRef) face->user_data); - } else { hb_blob_t *blob = hb_face_reference_blob (face); - unsigned int blob_length; - const char *blob_data = hb_blob_get_data (blob, &blob_length); - if (unlikely (!blob_length)) - DEBUG_MSG (CORETEXT, face, "Face has empty blob"); - - CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); - if (likely (provider)) - { - cg_font = CGFontCreateWithDataProvider (provider); - if (unlikely (!cg_font)) - DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); - CGDataProviderRelease (provider); - } + cg_font = create_cg_font (blob, face->index); + hb_blob_destroy (blob); } return cg_font; } @@ -404,6 +416,40 @@ hb_coretext_face_create_from_file_or_fail (const char *file_name, return face; } +/** + * hb_coretext_face_create_from_blob_or_fail: + * @blob: A blob containing the font data + * @index: The index of the face within the blob + * + * Creates an #hb_face_t face object from the specified + * blob and face index. + * + * This is similar in functionality to hb_face_create_from_blob_or_fail(), + * but uses the CoreText library for loading the font data. + * + * Note that currently only @index equal to 0 is supported. + * + * Return value: (transfer full): The new face object, or `NULL` if + * no face is found at the specified index or the blob cannot be read. + * + * XSince: REPLACEME + */ +hb_face_t * +hb_coretext_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index) +{ + auto cg_font = create_cg_font (blob, index); + if (unlikely (!cg_font)) + return nullptr; + + hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); + if (unlikely (hb_face_is_immutable (face))) + return nullptr; + + return face; +} + /** * hb_coretext_face_get_cg_font: * @face: The #hb_face_t to work upon diff --git a/src/hb-coretext.h b/src/hb-coretext.h index 3626f1c12..a7c7fee76 100644 --- a/src/hb-coretext.h +++ b/src/hb-coretext.h @@ -84,6 +84,10 @@ HB_EXTERN hb_face_t * hb_coretext_face_create_from_file_or_fail (const char *file_name, unsigned int index); +HB_EXTERN hb_face_t * +hb_coretext_face_create_from_blob_or_fail (hb_blob_t *blob, + unsigned int index); + HB_EXTERN hb_font_t * hb_coretext_font_create (CTFontRef ct_font);