summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-coretext.cc')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.cc200
1 files changed, 164 insertions, 36 deletions
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<CFDataRef> (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<CGFontRef> (user_data);
+ CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
+ if (unlikely (!cf_data))
+ return NULL;
+
+ const char *data = reinterpret_cast<const char*> (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<void *> (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<UniChar> (ch, 0xDC00, 0xDFFF) && range.location < j)
+ if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j)
{
ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
- if (hb_in_range<UniChar> (ch, 0xD800, 0xDBFF))
+ if (hb_in_range<UniChar> (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);
+}