From 461c2b20044359b80df8217a7565c7b8a60a1f0b Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 18 Jul 2014 03:13:19 +0300 Subject: Update bundled HarfBuzz-NG copy to 0.9.32 - Unicode 7.0 support - New shapers - Multiple improvements in Arabic, Indic, and Hebrew shapers - Build fixes, optimizations, etc. Change-Id: I0ba14b619c3e6fb35cddd9d65e694af41197d6ae Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 200 +++++++++++++++++++++++----- 1 file changed, 164 insertions(+), 36 deletions(-) (limited to 'src/3rdparty/harfbuzz-ng/src/hb-coretext.cc') diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index 2507cd1d9f..e2cd2777ed 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -31,18 +31,12 @@ #include "hb-coretext.h" -#include "hb-face-private.hh" - #ifndef HB_DEBUG_CORETEXT #define HB_DEBUG_CORETEXT (HB_DEBUG+0) #endif -HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face) -HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font) - - typedef bool (*qt_get_font_table_func_t) (void *user_data, unsigned int tag, unsigned char *buffer, unsigned int *length); struct FontEngineFaceData { @@ -56,6 +50,42 @@ struct CoreTextFontEngineData { }; +static void +release_table_data (void *user_data) +{ + CFDataRef cf_data = reinterpret_cast (user_data); + CFRelease(cf_data); +} + +static hb_blob_t * +reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +{ + CGFontRef cg_font = reinterpret_cast (user_data); + CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag); + if (unlikely (!cf_data)) + return NULL; + + const char *data = reinterpret_cast (CFDataGetBytePtr (cf_data)); + const size_t length = CFDataGetLength (cf_data); + if (!data || !length) + return NULL; + + return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, + reinterpret_cast (const_cast<__CFData *> (cf_data)), + release_table_data); +} + +hb_face_t * +hb_coretext_face_create (CGFontRef cg_font) +{ + return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), (hb_destroy_func_t) CGFontRelease); +} + + +HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face) +HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font) + + /* * shaper face data */ @@ -76,31 +106,33 @@ release_data (void *info, const void *data, size_t size) hb_coretext_shaper_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { - hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT); - /* Umm, we just reference the table to check whether it exists. - * Maybe add better API for this? */ - if (!hb_blob_get_length (mort_blob)) - { - hb_blob_destroy (mort_blob); - mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX); - if (!hb_blob_get_length (mort_blob)) - { - hb_blob_destroy (mort_blob); - return NULL; - } - } - hb_blob_destroy (mort_blob); - hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) calloc (1, sizeof (hb_coretext_shaper_face_data_t)); if (unlikely (!data)) return NULL; - +#if 0 + if (face->destroy == (hb_destroy_func_t) CGFontRelease) + { + data->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); + data->cg_font = CGFontCreateWithDataProvider (provider); + CGDataProviderRelease (provider); + } +#else FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; data->cg_font = coreTextFontEngineData->cgFont; if (likely (data->cg_font)) CFRetain (data->cg_font); - +#endif if (unlikely (!data->cg_font)) { DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); free (data); @@ -144,13 +176,17 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) return NULL; hb_face_t *face = font->face; +#if 0 + hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); + data->ct_font = CTFontCreateWithGraphicsFont (face_data->cg_font, font->y_scale, NULL, NULL); +#else FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; data->ct_font = coreTextFontEngineData->ctFont; if (likely (data->ct_font)) CFRetain (data->ct_font); - +#endif if (unlikely (!data->ct_font)) { DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); free (data); @@ -468,7 +504,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, event->start = false; event->feature = feature; } - feature_events.sort (); + feature_events.qsort (); /* Add a strategic final event. */ { active_feature_t feature; @@ -498,14 +534,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, if (unlikely (!range)) goto fail_features; - unsigned int offset = feature_records.len; - if (active_features.len) { CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); /* TODO sort and resolve conflicting features? */ - /* active_features.sort (); */ + /* active_features.qsort (); */ for (unsigned int j = 0; j < active_features.len; j++) { CFStringRef keys[2] = { @@ -603,13 +637,13 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, for (unsigned int i = 0; i < buffer->len; i++) { hb_codepoint_t c = buffer->info[i].codepoint; buffer->info[i].utf16_index() = chars_len; - if (likely (c < 0x10000)) + if (likely (c <= 0xFFFFu)) pchars[chars_len++] = c; - else if (unlikely (c >= 0x110000)) - pchars[chars_len++] = 0xFFFD; + else if (unlikely (c > 0x10FFFFu)) + pchars[chars_len++] = 0xFFFDu; else { - pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10); - pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1)); + pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); + pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1)); } } @@ -635,7 +669,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_codepoint_t c = buffer->info[i].codepoint; unsigned int cluster = buffer->info[i].cluster; log_clusters[chars_len++] = cluster; - if (c >= 0x10000 && c < 0x110000) + if (hb_in_range (c, 0x10000u, 0x10FFFFu)) log_clusters[chars_len++] = cluster; /* Surrogates. */ } @@ -705,10 +739,10 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, for (CFIndex j = range.location; j < range.location + range.length; j++) { UniChar ch = CFStringGetCharacterAtIndex (string_ref, j); - if (hb_in_range (ch, 0xDC00, 0xDFFF) && range.location < j) + if (hb_in_range (ch, 0xDC00u, 0xDFFFu) && range.location < j) { ch = CFStringGetCharacterAtIndex (string_ref, j - 1); - if (hb_in_range (ch, 0xD800, 0xDBFF)) + if (hb_in_range (ch, 0xD800u, 0xDBFFu)) /* This is the second of a surrogate pair. Don't need .notdef * for this one. */ continue; @@ -866,3 +900,97 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, return true; } + + +/* + * AAT shaper + */ + +HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face) +HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font) + + +/* + * shaper face data + */ + +struct hb_coretext_aat_shaper_face_data_t {}; + +hb_coretext_aat_shaper_face_data_t * +_hb_coretext_aat_shaper_face_data_create (hb_face_t *face) +{ + hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT); + /* Umm, we just reference the table to check whether it exists. + * Maybe add better API for this? */ + if (!hb_blob_get_length (mort_blob)) + { + hb_blob_destroy (mort_blob); + mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX); + if (!hb_blob_get_length (mort_blob)) + { + hb_blob_destroy (mort_blob); + return NULL; + } + } + hb_blob_destroy (mort_blob); + + return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL; +} + +void +_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper font data + */ + +struct hb_coretext_aat_shaper_font_data_t {}; + +hb_coretext_aat_shaper_font_data_t * +_hb_coretext_aat_shaper_font_data_create (hb_font_t *font) +{ + return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL; +} + +void +_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper shape_plan data + */ + +struct hb_coretext_aat_shaper_shape_plan_data_t {}; + +hb_coretext_aat_shaper_shape_plan_data_t * +_hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, + const hb_feature_t *user_features HB_UNUSED, + unsigned int num_user_features HB_UNUSED) +{ + return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper + */ + +hb_bool_t +_hb_coretext_aat_shape (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + return _hb_coretext_shape (shape_plan, font, buffer, features, num_features); +} -- cgit v1.2.3