Index: third_party/harfbuzz-ng/src/hb-coretext.cc |
diff --git a/third_party/harfbuzz-ng/src/hb-coretext.cc b/third_party/harfbuzz-ng/src/hb-coretext.cc |
index ee7f91cc9a7a3a9f1e84ebb6abc92ea3d9ded413..3f214935c31209c4b63a7bae051895a57aafefe3 100644 |
--- a/third_party/harfbuzz-ng/src/hb-coretext.cc |
+++ b/third_party/harfbuzz-ng/src/hb-coretext.cc |
@@ -1,6 +1,7 @@ |
/* |
* Copyright © 2012,2013 Mozilla Foundation. |
* Copyright © 2012,2013 Google, Inc. |
+ * Copyright © 2016 Ebrahim Byagowi |
* |
* This is part of HarfBuzz, a text shaping library. |
* |
@@ -47,8 +48,8 @@ release_table_data (void *user_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<CGFontRef> (user_data); |
- CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag); |
+ CTFontRef ct_font = reinterpret_cast<CTFontRef> (user_data); |
+ CFDataRef cf_data = CTFontCopyTable (ct_font, tag, kCTFontTableOptionNoOptions); |
if (unlikely (!cf_data)) |
return NULL; |
@@ -62,10 +63,34 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) |
release_table_data); |
} |
+static void |
+hb_face_ct_font_destroyer (void *user_data) |
+{ |
+ CTFontRef ct_font = reinterpret_cast<CTFontRef> (user_data); |
+ CFRelease (ct_font); |
+} |
+ |
+/* |
+ * Since: 0.9.2 |
+ */ |
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); |
+ return hb_face_create_for_tables (reference_table, |
+ (void*) CTFontCreateWithGraphicsFont (cg_font, 36., 0, 0), |
+ hb_face_ct_font_destroyer); |
+ |
+} |
+ |
+/* |
+ * Since: 1.3.4 |
+ */ |
+hb_face_t * |
+hb_coretext_face_create_from_ct_font (CTFontRef ct_font) |
+{ |
+ return hb_face_create_for_tables (reference_table, |
+ (void*) CFRetain (ct_font), |
+ hb_face_ct_font_destroyer); |
} |
@@ -100,49 +125,12 @@ get_last_resort_font_desc (void) |
return font_desc; |
} |
-static void |
-release_data (void *info, const void *data, size_t size) |
-{ |
- assert (hb_blob_get_length ((hb_blob_t *) info) == size && |
- hb_blob_get_data ((hb_blob_t *) info, NULL) == data); |
- |
- hb_blob_destroy ((hb_blob_t *) info); |
-} |
- |
-static CGFontRef |
-create_cg_font (hb_face_t *face) |
-{ |
- CGFontRef cg_font = NULL; |
- if (face->destroy == (hb_destroy_func_t) CGFontRelease) |
- { |
- 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); |
- } |
- } |
- return cg_font; |
-} |
- |
static CTFontRef |
-create_ct_font (CGFontRef cg_font, CGFloat font_size) |
+create_ct_font (CTFontDescriptorRef ct_font_descriptor, CGFloat font_size) |
{ |
- CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL); |
+ CTFontRef ct_font = CTFontCreateWithFontDescriptor (ct_font_descriptor, font_size, NULL); |
if (unlikely (!ct_font)) { |
- DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed"); |
+ DEBUG_MSG (CORETEXT, ct_font_descriptor, "Font CTFontCreateWithFontDescriptor() failed"); |
return NULL; |
} |
@@ -152,7 +140,8 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) |
* operating system versions. Except for the emoji font, where _not_ |
* reconfiguring the cascade list causes CoreText crashes. For details, see |
* crbug.com/549610 */ |
- if (&CTGetCoreTextVersion != NULL && CTGetCoreTextVersion() < kCTVersionNumber10_10) { |
+ // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h |
+ if (&CTGetCoreTextVersion != NULL && CTGetCoreTextVersion() < 0x00070000) { |
CFStringRef fontName = CTFontCopyPostScriptName (ct_font); |
bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; |
CFRelease (fontName); |
@@ -202,8 +191,8 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size) |
} |
struct hb_coretext_shaper_face_data_t { |
- CGFontRef cg_font; |
CTFontRef ct_font; |
+ hb_blob_t *blob; |
}; |
hb_coretext_shaper_face_data_t * |
@@ -213,10 +202,38 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face) |
if (unlikely (!data)) |
return NULL; |
- data->cg_font = create_cg_font (face); |
- if (unlikely (!data->cg_font)) |
+ if (face->destroy == hb_face_ct_font_destroyer) |
{ |
- DEBUG_MSG (CORETEXT, face, "CGFont creation failed.."); |
+ data->ct_font = reinterpret_cast<CTFontRef> (CFRetain (face->user_data)); |
+ return data; |
+ } |
+ |
+ data->blob = hb_face_reference_blob (face); |
+ unsigned int blob_length; |
+ const char *blob_data = hb_blob_get_data (data->blob, &blob_length); |
+ if (unlikely (!blob_length)) |
+ { |
+ DEBUG_MSG (CORETEXT, face, "Face has empty blob"); |
+ free (data); |
+ return NULL; |
+ } |
+ |
+ CFDataRef cf_data = CFDataCreateWithBytesNoCopy (kCFAllocatorDefault, |
+ reinterpret_cast<const UInt8*> (blob_data), |
+ blob_length, |
+ kCFAllocatorNull); |
+ if (unlikely (!cf_data)) |
+ { |
+ DEBUG_MSG (CORETEXT, face, "CFDataRef creation failed."); |
+ free (data); |
+ return NULL; |
+ } |
+ |
+ CTFontDescriptorRef ct_font_descriptor = CTFontManagerCreateFontDescriptorFromData (cf_data); |
+ if (unlikely (!ct_font_descriptor)) |
+ { |
+ DEBUG_MSG (CORETEXT, face, "CTFontDescriptorRef creation failed."); |
+ CFRelease (cf_data); |
free (data); |
return NULL; |
} |
@@ -228,23 +245,30 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face) |
* Since we always create CTFont at a fixed size, our CTFont lives in face_data |
* instead of font_data. Which is good, because when people change scale on |
* hb_font_t, we won't need to update our CTFont. */ |
- data->ct_font = create_ct_font (data->cg_font, 36.); |
+ data->ct_font = create_ct_font (ct_font_descriptor, 36.); |
if (unlikely (!data->ct_font)) |
{ |
DEBUG_MSG (CORETEXT, face, "CTFont creation failed."); |
- CFRelease (data->cg_font); |
+ CFRelease (ct_font_descriptor); |
+ CFRelease (cf_data); |
+ hb_blob_destroy (data->blob); |
free (data); |
return NULL; |
} |
+ CFRelease (ct_font_descriptor); |
+ CFRelease (cf_data); |
+ |
return data; |
} |
void |
_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data) |
{ |
- CFRelease (data->ct_font); |
- CFRelease (data->cg_font); |
+ if (data->ct_font) |
+ CFRelease (data->ct_font); |
+ if (data->blob) |
+ hb_blob_destroy (data->blob); |
free (data); |
} |
@@ -256,7 +280,7 @@ hb_coretext_face_get_cg_font (hb_face_t *face) |
{ |
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL; |
hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); |
- return face_data->cg_font; |
+ return CTFontCopyGraphicsFont (face_data->ct_font, NULL); |
} |
@@ -297,6 +321,9 @@ _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_ |
{ |
} |
+/* |
+ * Since: 0.9.2 |
+ */ |
CTFontRef |
hb_coretext_font_get_ct_font (hb_font_t *font) |
{ |
@@ -790,7 +817,7 @@ resize_and_retry: |
scratch_size -= old_scratch_used; |
} |
{ |
- string_ref = CFStringCreateWithCharactersNoCopy (NULL, |
+ string_ref = CFStringCreateWithCharactersNoCopy (kCFAllocatorDefault, |
pchars, chars_len, |
kCFAllocatorNull); |
if (unlikely (!string_ref)) |
@@ -822,7 +849,10 @@ resize_and_retry: |
kCFStringEncodingUTF8, |
kCFAllocatorNull); |
if (unlikely (!lang)) |
+ { |
+ CFRelease (attr_string); |
FAIL ("CFStringCreateWithCStringNoCopy failed"); |
+ } |
CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), |
kCTLanguageAttributeName, lang); |
CFRelease (lang); |
@@ -866,7 +896,10 @@ resize_and_retry: |
&kCFTypeDictionaryKeyCallBacks, |
&kCFTypeDictionaryValueCallBacks); |
if (unlikely (!options)) |
+ { |
+ CFRelease (attr_string); |
FAIL ("CFDictionaryCreate failed"); |
+ } |
CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options); |
CFRelease (options); |
@@ -956,12 +989,7 @@ resize_and_retry: |
} |
if (!matched) |
{ |
- CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0); |
- if (run_cg_font) |
- { |
- matched = CFEqual (run_cg_font, face_data->cg_font); |
- CFRelease (run_cg_font); |
- } |
+ matched = CFEqual (run_ct_font, face_data->ct_font); |
} |
if (!matched) |
{ |