Imported Upstream version 1.4.6
[platform/upstream/harfbuzz.git] / src / hb-coretext.cc
index 9097cce..8f2483b 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 #define HB_SHAPER coretext
-#define hb_coretext_shaper_face_data_t CGFont
 #include "hb-shaper-impl-private.hh"
 
 #include "hb-coretext.h"
@@ -70,14 +69,37 @@ hb_coretext_face_create (CGFontRef cg_font)
 }
 
 
-HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
-HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext, font)
 
 
 /*
  * shaper face data
  */
 
+static CTFontDescriptorRef
+get_last_resort_font_desc (void)
+{
+  // TODO Handle allocation failures?
+  CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0);
+  CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault,
+                                          (const void **) &last_resort,
+                                          1,
+                                          &kCFTypeArrayCallBacks);
+  CFRelease (last_resort);
+  CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
+                                                  (const void **) &kCTFontCascadeListAttribute,
+                                                  (const void **) &cascade_list,
+                                                  1,
+                                                  &kCFTypeDictionaryKeyCallBacks,
+                                                  &kCFTypeDictionaryValueCallBacks);
+  CFRelease (cascade_list);
+
+  CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
+  CFRelease (attributes);
+  return font_desc;
+}
+
 static void
 release_data (void *info, const void *data, size_t size)
 {
@@ -87,14 +109,13 @@ release_data (void *info, const void *data, size_t size)
   hb_blob_destroy ((hb_blob_t *) info);
 }
 
-hb_coretext_shaper_face_data_t *
-_hb_coretext_shaper_face_data_create (hb_face_t *face)
+static CGFontRef
+create_cg_font (hb_face_t *face)
 {
-  hb_coretext_shaper_face_data_t *data = NULL;
-
+  CGFontRef cg_font = NULL;
   if (face->destroy == (hb_destroy_func_t) CGFontRelease)
   {
-    data = CGFontRetain ((CGFontRef) face->user_data);
+    cg_font = CGFontRetain ((CGFontRef) face->user_data);
   }
   else
   {
@@ -107,13 +128,114 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face)
     CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
     if (likely (provider))
     {
-      data = CGFontCreateWithDataProvider (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)
+{
+  CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
+  if (unlikely (!ct_font)) {
+    DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
+    return NULL;
+  }
+
+  /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter
+   * bug indicate that the cascade list reconfiguration occasionally causes
+   * crashes in CoreText on OS X 10.9, thus let's skip this step on older
+   * operating system versions. Except for the emoji font, where _not_
+   * reconfiguring the cascade list causes CoreText crashes. For details, see
+   * crbug.com/549610 */
+  // 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);
+    if (!isEmojiFont)
+      return ct_font;
+  }
 
-  if (unlikely (!data)) {
-    DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
+  CFURLRef original_url = (CFURLRef)CTFontCopyAttribute(ct_font, kCTFontURLAttribute);
+
+  /* Create font copy with cascade list that has LastResort first; this speeds up CoreText
+   * font fallback which we don't need anyway. */
+  {
+    CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc ();
+    CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, last_resort_font_desc);
+    CFRelease (last_resort_font_desc);
+    if (new_ct_font)
+    {
+      /* The CTFontCreateCopyWithAttributes call fails to stay on the same font
+       * when reconfiguring the cascade list and may switch to a different font
+       * when there are fonts that go by the same name, since the descriptor is
+       * just name and size.
+       *
+       * Avoid reconfiguring the cascade lists if the new font is outside the
+       * system locations that we cannot access from the sandboxed renderer
+       * process in Blink. This can be detected by the new file URL location
+       * that the newly found font points to. */
+      CFURLRef new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
+      // Keep reconfigured font if URL cannot be retrieved (seems to be the case
+      // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606
+      if (!original_url || !new_url || CFEqual (original_url, new_url)) {
+        CFRelease (ct_font);
+        ct_font = new_ct_font;
+      } else {
+        CFRelease (new_ct_font);
+        DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
+      }
+      if (new_url)
+        CFRelease (new_url);
+    }
+    else
+      DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed");
+  }
+
+  if (original_url)
+    CFRelease (original_url);
+  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;
+
+  data->cg_font = create_cg_font (face);
+  if (unlikely (!data->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;
@@ -122,15 +244,20 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face)
 void
 _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
 {
-  CFRelease (data);
+  CFRelease (data->ct_font);
+  CFRelease (data->cg_font);
+  free (data);
 }
 
+/*
+ * Since: 0.9.10
+ */
 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;
+  return face_data->cg_font;
 }
 
 
@@ -138,37 +265,17 @@ hb_coretext_face_get_cg_font (hb_face_t *face)
  * shaper font data
  */
 
-struct hb_coretext_shaper_font_data_t {
-  CTFontRef ct_font;
-};
+struct hb_coretext_shaper_font_data_t {};
 
 hb_coretext_shaper_font_data_t *
-_hb_coretext_shaper_font_data_create (hb_font_t *font)
+_hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED)
 {
-  if (unlikely (!hb_coretext_shaper_face_data_ensure (font->face))) return NULL;
-
-  hb_coretext_shaper_font_data_t *data = (hb_coretext_shaper_font_data_t *) calloc (1, sizeof (hb_coretext_shaper_font_data_t));
-  if (unlikely (!data))
-    return NULL;
-
-  hb_face_t *face = font->face;
-  hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
-
-  data->ct_font = CTFontCreateWithGraphicsFont (face_data, font->y_scale, NULL, NULL);
-  if (unlikely (!data->ct_font)) {
-    DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
-    free (data);
-    return NULL;
-  }
-
-  return data;
+  return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
 
 void
 _hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
 {
-  CFRelease (data->ct_font);
-  free (data);
 }
 
 
@@ -181,7 +288,9 @@ struct hb_coretext_shaper_shape_plan_data_t {};
 hb_coretext_shaper_shape_plan_data_t *
 _hb_coretext_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)
+                                            unsigned int        num_user_features HB_UNUSED,
+                                            const int          *coords HB_UNUSED,
+                                            unsigned int        num_coords HB_UNUSED)
 {
   return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }
@@ -194,9 +303,10 @@ _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_
 CTFontRef
 hb_coretext_font_get_ct_font (hb_font_t *font)
 {
-  if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL;
-  hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
-  return font_data->ct_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;
 }
 
 
@@ -327,7 +437,7 @@ struct range_record_t {
 #define kUpperCaseType                         38
 
 /* Table data courtesy of Apple. */
-struct feature_mapping_t {
+static const struct feature_mapping_t {
     FourCharCode otFeatureTag;
     uint16_t aatFeatureType;
     uint16_t selectorToEnable;
@@ -429,7 +539,10 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
 {
   hb_face_t *face = font->face;
   hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
-  hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+
+  CGFloat ct_font_size = CTFontGetSize (face_data->ct_font);
+  CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
+  CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
 
   /* Attach marks to their bases, to match the 'ot' shaper.
    * Adapted from hb-ot-shape:hb_form_clusters().
@@ -438,6 +551,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
    * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will
    * continue pointing to B2 even though B2 was merged into B1's
    * cluster... */
+  if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
   {
     hb_unicode_funcs_t *unicode = buffer->unicode;
     unsigned int count = buffer->len;
@@ -560,7 +674,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
          CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
          CFRelease (attributes);
 
-         range->font = CTFontCreateCopyWithAttributes (font_data->ct_font, 0.0, NULL, font_desc);
+         range->font = CTFontCreateCopyWithAttributes (face_data->ct_font, 0.0, NULL, font_desc);
          CFRelease (font_desc);
        }
        else
@@ -621,7 +735,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
       pchars[chars_len++] = 0xFFFDu;
     else {
       pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
-      pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1));
+      pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
     }
   }
 
@@ -678,7 +792,6 @@ resize_and_retry:
     scratch += old_scratch_used;
     scratch_size -= old_scratch_used;
   }
-retry:
   {
     string_ref = CFStringCreateWithCharactersNoCopy (NULL,
                                                     pchars, chars_len,
@@ -718,7 +831,7 @@ retry:
        CFRelease (lang);
       }
       CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
-                                     kCTFontAttributeName, font_data->ct_font);
+                                     kCTFontAttributeName, face_data->ct_font);
 
       if (num_features)
       {
@@ -776,6 +889,18 @@ retry:
 
     buffer->len = 0;
     uint32_t status_and = ~0, status_or = 0;
+    double advances_so_far = 0;
+    /* For right-to-left runs, CoreText returns the glyphs positioned such that
+     * any trailing whitespace is to the left of (0,0).  Adjust coordinate system
+     * to fix for that.  Test with any RTL string with trailing spaces.
+     * https://code.google.com/p/chromium/issues/detail?id=469028
+     */
+    if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+    {
+      advances_so_far -= CTLineGetTrailingWhitespaceWidth (line);
+      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
+         advances_so_far = -advances_so_far;
+    }
 
     const CFRange range_all = CFRangeMake (0, 0);
 
@@ -786,6 +911,10 @@ retry:
       status_or  |= run_status;
       status_and &= run_status;
       DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
+      double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL);
+      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
+         run_advance = -run_advance;
+      DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
 
       /* CoreText does automatic font fallback (AKA "cascading") for  characters
        * not supported by the requested font, and provides no way to turn it off,
@@ -795,7 +924,7 @@ retry:
        */
       CFDictionaryRef attributes = CTRunGetAttributes (run);
       CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
-      if (!CFEqual (run_ct_font, font_data->ct_font))
+      if (!CFEqual (run_ct_font, face_data->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
@@ -815,15 +944,11 @@ retry:
         * backend.
         *
         * However, even that wouldn't work if we were passed in the CGFont to
-        * begin with.
-        *
-        * Webkit uses a slightly different approach: it installs LastResort
-        * as fallback chain, and then checks PS name of used font against
-        * LastResort.  That one is safe for any font except for LastResort,
-        * as opposed to ours, which can fail if we are using any uninstalled
-        * font that has the same name as an installed font.
+        * construct a hb_face to begin with.
         *
         * See: http://github.com/behdad/harfbuzz/pull/36
+        *
+        * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098
         */
        bool matched = false;
        for (unsigned int i = 0; i < range_records.len; i++)
@@ -837,13 +962,13 @@ retry:
          CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
          if (run_cg_font)
          {
-           matched = CFEqual (run_cg_font, face_data);
+           matched = CFEqual (run_cg_font, face_data->cg_font);
            CFRelease (run_cg_font);
          }
        }
        if (!matched)
        {
-         CFStringRef font_ps_name = CTFontCopyName (font_data->ct_font, kCTFontPostScriptNameKey);
+         CFStringRef font_ps_name = CTFontCopyName (face_data->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);
@@ -860,8 +985,14 @@ retry:
            goto resize_and_retry;
          hb_glyph_info_t *info = buffer->info + buffer->len;
 
-         CGGlyph notdef = 0;
-         double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, &notdef, NULL, 1);
+         hb_codepoint_t notdef = 0;
+         hb_direction_t dir = buffer->props.direction;
+         hb_position_t x_advance, y_advance, x_offset, y_offset;
+         hb_font_get_glyph_advance_for_direction (font, notdef, dir, &x_advance, &y_advance);
+         hb_font_get_glyph_origin_for_direction (font, notdef, dir, &x_offset, &y_offset);
+         hb_position_t advance = x_advance + y_advance;
+         x_offset = -x_offset;
+         y_offset = -y_offset;
 
          unsigned int old_len = buffer->len;
          for (CFIndex j = range.location; j < range.location + range.length; j++)
@@ -875,19 +1006,22 @@ retry:
                   * for this one. */
                  continue;
              }
+             if (buffer->unicode->is_default_ignorable (ch))
+               continue;
 
              info->codepoint = notdef;
              info->cluster = log_clusters[j];
 
              info->mask = advance;
-             info->var1.u32 = 0;
-             info->var2.u32 = 0;
+             info->var1.i32 = x_offset;
+             info->var2.i32 = y_offset;
 
              info++;
              buffer->len++;
          }
          if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
            buffer->reverse_range (old_len, buffer->len);
+         advances_so_far += run_advance;
          continue;
        }
       }
@@ -917,7 +1051,7 @@ retry:
   scratch_size = scratch_size_saved; \
   scratch = scratch_saved;
 
-      {
+      { /* Setup glyphs */
         SCRATCH_SAVE();
        const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL;
        if (!glyphs) {
@@ -941,6 +1075,11 @@ retry:
        SCRATCH_RESTORE();
       }
       {
+        /* Setup positions.
+        * Note that CoreText does not return advances for glyphs.  As such,
+        * for all but last glyph, we use the delta position to next glyph as
+        * advance (in the advance direction only), and for last glyph we set
+        * whatever is needed to make the whole run's advance add up. */
         SCRATCH_SAVE();
        const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL;
        if (!positions) {
@@ -948,33 +1087,41 @@ retry:
          CTRunGetPositions (run, range_all, position_buf);
          positions = position_buf;
        }
-       double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL);
-       DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
        hb_glyph_info_t *info = run_info;
        if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
        {
+         hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult;
          for (unsigned int j = 0; j < num_glyphs; j++)
          {
-           double advance = (j + 1 < num_glyphs ? positions[j + 1].x : positions[0].x + run_advance) - positions[j].x;
-           info->mask = advance;
-           info->var1.u32 = positions[0].x; /* Yes, zero. */
-           info->var2.u32 = positions[j].y;
+           double advance;
+           if (likely (j + 1 < num_glyphs))
+             advance = positions[j + 1].x - positions[j].x;
+           else /* last glyph */
+             advance = run_advance - (positions[j].x - positions[0].x);
+           info->mask = advance * x_mult;
+           info->var1.i32 = x_offset;
+           info->var2.i32 = positions[j].y * y_mult;
            info++;
          }
        }
        else
        {
-         run_advance = -run_advance;
+         hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult;
          for (unsigned int j = 0; j < num_glyphs; j++)
          {
-           double advance = (j + 1 < num_glyphs ? positions[j + 1].y : positions[0].y + run_advance) - positions[j].y;
-           info->mask = advance;
-           info->var1.u32 = positions[j].x;
-           info->var2.u32 = positions[0].y; /* Yes, zero. */
+           double advance;
+           if (likely (j + 1 < num_glyphs))
+             advance = positions[j + 1].y - positions[j].y;
+           else /* last glyph */
+             advance = run_advance - (positions[j].y - positions[0].y);
+           info->mask = advance * y_mult;
+           info->var1.i32 = positions[j].x * x_mult;
+           info->var2.i32 = y_offset;
            info++;
          }
        }
        SCRATCH_RESTORE();
+       advances_so_far += run_advance;
       }
 #undef SCRATCH_RESTORE
 #undef SCRATCH_SAVE
@@ -984,10 +1131,20 @@ retry:
       buffer->len += num_glyphs;
     }
 
-    /* Make sure all runs had the expected direction. */
-    bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
-    assert (bool (status_and & kCTRunStatusRightToLeft) == backward);
-    assert (bool (status_or  & kCTRunStatusRightToLeft) == backward);
+    /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel,
+     * or if it does, it doesn't resepct it.  So we get runs with wrong
+     * directions.  As such, disable the assert...  It wouldn't crash, but
+     * cursoring will be off...
+     *
+     * http://crbug.com/419769
+     */
+    if (0)
+    {
+      /* Make sure all runs had the expected direction. */
+      bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+      assert (bool (status_and & kCTRunStatusRightToLeft) == backward);
+      assert (bool (status_or  & kCTRunStatusRightToLeft) == backward);
+    }
 
     buffer->clear_positions ();
 
@@ -998,16 +1155,16 @@ retry:
       for (unsigned int i = 0; i < count; i++)
       {
        pos->x_advance = info->mask;
-       pos->x_offset = info->var1.u32;
-       pos->y_offset = info->var2.u32;
+       pos->x_offset = info->var1.i32;
+       pos->y_offset = info->var2.i32;
        info++, pos++;
       }
     else
       for (unsigned int i = 0; i < count; i++)
       {
        pos->y_advance = info->mask;
-       pos->x_offset = info->var1.u32;
-       pos->y_offset = info->var2.u32;
+       pos->x_offset = info->var1.i32;
+       pos->y_offset = info->var2.i32;
        info++, pos++;
       }
 
@@ -1065,9 +1222,8 @@ fail:
  * AAT shaper
  */
 
-HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face)
-HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font)
-
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, face)
+HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font)
 
 /*
  * shaper face data
@@ -1129,7 +1285,9 @@ 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)
+                                            unsigned int        num_user_features HB_UNUSED,
+                                            const int          *coords HB_UNUSED,
+                                            unsigned int        num_coords HB_UNUSED)
 {
   return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
 }