summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2017-10-13 22:53:19 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2017-10-13 22:53:19 +0000
commit1031c01a2674825fe7037630e3f37f05fd1e739c (patch)
treeebfef9c9c109565c30c9b2bc8b601a703aafa487 /Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
parenteb1d91e185ce0b605a76da41e16cf0eb736edc06 (diff)
harfbuzz-1.6.0
git-svn-id: svn://tug.org/texlive/trunk@45535 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc157
1 files changed, 92 insertions, 65 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
index ba96d3994ee..22661407dea 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc
@@ -30,12 +30,27 @@
#include "hb-shaper-impl-private.hh"
#include "hb-coretext.h"
+#include <math.h>
#ifndef HB_DEBUG_CORETEXT
#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
#endif
+/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
+#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
+
+static CGFloat
+coretext_font_size (float ptem)
+{
+ /* CoreText points are CSS pixels (96 per inch),
+ * NOT typographic points (72 per inch).
+ *
+ * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
+ */
+ ptem *= 96.f / 72.f;
+ return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem;
+}
static void
release_table_data (void *user_data)
@@ -62,16 +77,22 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
release_table_data);
}
+static void
+_hb_cg_font_release (void *data)
+{
+ CGFontRelease ((CGFontRef) 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);
+ return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
}
-
HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
-HB_SHAPER_DATA_ENSURE_DEFINE(coretext, font)
-
+HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
+ fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size (font->ptem)) <= .5
+)
/*
* shaper face data
@@ -113,7 +134,7 @@ static CGFontRef
create_cg_font (hb_face_t *face)
{
CGFontRef cg_font = NULL;
- if (face->destroy == (hb_destroy_func_t) CGFontRelease)
+ if (face->destroy == _hb_cg_font_release)
{
cg_font = CGFontRetain ((CGFontRef) face->user_data);
}
@@ -140,7 +161,33 @@ create_cg_font (hb_face_t *face)
static CTFontRef
create_ct_font (CGFontRef cg_font, CGFloat font_size)
{
- CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
+ CTFontRef ct_font = NULL;
+
+ /* CoreText does not enable trak table usage / tracking when creating a CTFont
+ * using CTFontCreateWithGraphicsFont. The only way of enabling tracking seems
+ * to be through the CTFontCreateUIFontForLanguage call. */
+ CFStringRef cg_postscript_name = CGFontCopyPostScriptName (cg_font);
+ if (CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSText")) ||
+ CFStringHasPrefix (cg_postscript_name, CFSTR (".SFNSDisplay")))
+ {
+ CTFontUIFontType font_type = kCTFontUIFontSystem;
+ if (CFStringHasSuffix (cg_postscript_name, CFSTR ("-Bold")))
+ font_type = kCTFontUIFontEmphasizedSystem;
+
+ ct_font = CTFontCreateUIFontForLanguage (font_type, font_size, NULL);
+ CFStringRef ct_result_name = CTFontCopyPostScriptName(ct_font);
+ if (CFStringCompare (ct_result_name, cg_postscript_name, 0) != kCFCompareEqualTo)
+ {
+ CFRelease(ct_font);
+ ct_font = NULL;
+ }
+ CFRelease (ct_result_name);
+ }
+ CFRelease (cg_postscript_name);
+
+ if (!ct_font)
+ ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
+
if (unlikely (!ct_font)) {
DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
return NULL;
@@ -202,51 +249,24 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
return ct_font;
}
-struct hb_coretext_shaper_face_data_t {
- CGFontRef cg_font;
- CTFontRef ct_font;
-};
-
hb_coretext_shaper_face_data_t *
_hb_coretext_shaper_face_data_create (hb_face_t *face)
{
- 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;
+ CGFontRef cg_font = create_cg_font (face);
- data->cg_font = create_cg_font (face);
- if (unlikely (!data->cg_font))
+ if (unlikely (!cg_font))
{
DEBUG_MSG (CORETEXT, face, "CGFont creation failed..");
- free (data);
- return NULL;
- }
-
- /* We use 36pt size instead of UPEM, because CoreText implements the 'trak' table,
- * which can make the font too tight at large sizes. 36pt should be a good semi-neutral
- * size.
- *
- * 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.);
- if (unlikely (!data->ct_font))
- {
- DEBUG_MSG (CORETEXT, face, "CTFont creation failed.");
- CFRelease (data->cg_font);
- free (data);
return NULL;
}
- return data;
+ return (hb_coretext_shaper_face_data_t *) cg_font;
}
void
_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
{
- CFRelease (data->ct_font);
- CFRelease (data->cg_font);
- free (data);
+ CFRelease ((CGFontRef) data);
}
/*
@@ -256,8 +276,7 @@ CGFontRef
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 (CGFontRef) HB_SHAPER_DATA_GET (face);
}
@@ -265,17 +284,28 @@ hb_coretext_face_get_cg_font (hb_face_t *face)
* shaper font data
*/
-struct hb_coretext_shaper_font_data_t {};
-
hb_coretext_shaper_font_data_t *
-_hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED)
+_hb_coretext_shaper_font_data_create (hb_font_t *font)
{
- return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+ hb_face_t *face = font->face;
+ if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
+ CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
+
+ CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size (font->ptem));
+
+ if (unlikely (!ct_font))
+ {
+ DEBUG_MSG (CORETEXT, font, "CGFont creation failed..");
+ return NULL;
+ }
+
+ return (hb_coretext_shaper_font_data_t *) ct_font;
}
void
_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
{
+ CFRelease ((CTFontRef) data);
}
@@ -303,10 +333,8 @@ _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_
CTFontRef
hb_coretext_font_get_ct_font (hb_font_t *font)
{
- hb_face_t *face = font->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->ct_font;
+ if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL;
+ return (CTFontRef)HB_SHAPER_DATA_GET (font);
}
@@ -538,9 +566,10 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
unsigned int num_features)
{
hb_face_t *face = font->face;
- hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+ CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
+ CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font);
- CGFloat ct_font_size = CTFontGetSize (face_data->ct_font);
+ CGFloat ct_font_size = CTFontGetSize (ct_font);
CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
@@ -675,7 +704,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
CFRelease (attributes);
- range->font = CTFontCreateCopyWithAttributes (face_data->ct_font, 0.0, NULL, font_desc);
+ range->font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, font_desc);
CFRelease (font_desc);
}
else
@@ -829,7 +858,7 @@ resize_and_retry:
CFRelease (lang);
}
CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
- kCTFontAttributeName, face_data->ct_font);
+ kCTFontAttributeName, ct_font);
if (num_features && range_records.len)
{
@@ -947,7 +976,7 @@ resize_and_retry:
*/
CFDictionaryRef attributes = CTRunGetAttributes (run);
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
- if (!CFEqual (run_ct_font, face_data->ct_font))
+ if (!CFEqual (run_ct_font, ct_font))
{
/* The run doesn't use our main font instance. We have to figure out
* whether font fallback happened, or this is just CoreText giving us
@@ -985,13 +1014,13 @@ resize_and_retry:
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
if (run_cg_font)
{
- matched = CFEqual (run_cg_font, face_data->cg_font);
+ matched = CFEqual (run_cg_font, cg_font);
CFRelease (run_cg_font);
}
}
if (!matched)
{
- CFStringRef font_ps_name = CTFontCopyName (face_data->ct_font, kCTFontPostScriptNameKey);
+ CFStringRef font_ps_name = CTFontCopyName (ct_font, kCTFontPostScriptNameKey);
CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey);
CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0);
CFRelease (run_ps_name);
@@ -1263,22 +1292,20 @@ 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))
+ static const hb_tag_t tags[] = {HB_CORETEXT_TAG_MORX, HB_CORETEXT_TAG_MORT, HB_CORETEXT_TAG_KERX};
+
+ for (unsigned int i = 0; i < ARRAY_LENGTH (tags); i++)
{
- hb_blob_destroy (mort_blob);
- mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
- if (!hb_blob_get_length (mort_blob))
+ hb_blob_t *blob = face->reference_table (tags[i]);
+ if (hb_blob_get_length (blob))
{
- hb_blob_destroy (mort_blob);
- return NULL;
+ hb_blob_destroy (blob);
+ return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
}
+ hb_blob_destroy (blob);
}
- 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;
+ return NULL;
}
void