[coretext] Move CT_Font to font data
authorBehdad Esfahbod <behdad@behdad.org>
Wed, 11 Oct 2017 11:05:59 +0000 (13:05 +0200)
committerBehdad Esfahbod <behdad@behdad.org>
Wed, 11 Oct 2017 11:05:59 +0000 (13:05 +0200)
Towards implementing optical sizing.  Untested; won't compile.

https://github.com/behdad/harfbuzz/issues/360

src/hb-coretext.cc

index 10859e1..3f1c671 100644 (file)
@@ -203,51 +203,26 @@ 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;
-};
+typedef CGFontRef hb_coretext_shaper_face_data_t;
 
 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;
+  hb_coretext_shaper_face_data_t *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, HB_CORETEXT_FONT_SIZE);
-  if (unlikely (!data->ct_font))
-  {
-    DEBUG_MSG (CORETEXT, face, "CTFont creation failed.");
-    CFRelease (data->cg_font);
-    free (data);
     return NULL;
   }
 
-  return data;
+  return cg_font;
 }
 
 void
-_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
+_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *cg_font)
 {
-  CFRelease (data->ct_font);
-  CFRelease (data->cg_font);
-  free (data);
+  CFRelease (cg_font);
 }
 
 /*
@@ -257,8 +232,8 @@ 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;
+  hb_coretext_shaper_face_data_t *cg_font = HB_SHAPER_DATA_GET (face);
+  return cg_font;
 }
 
 
@@ -266,17 +241,31 @@ hb_coretext_face_get_cg_font (hb_face_t *face)
  * shaper font data
  */
 
-struct hb_coretext_shaper_font_data_t {};
+typedef CTFontRef 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;
+  if (unlikely (!hb_coretext_shaper_face_data_ensure (font->face))) return NULL;
+  hb_coretext_shaper_face_data_t *cg_font = HB_SHAPER_DATA_GET (face);
+
+  float ptem = font->ptem < 0 ? HB_CORETEXT_FONT_SIZE : font->ptem;
+
+  hb_coretext_shaper_font_data_t *ct_font = create_ct_font (cg_font, ptem);
+
+  if (unlikely (!ct_font))
+  {
+    DEBUG_MSG (CORETEXT, font, "CGFont creation failed..");
+    return NULL;
+  }
+
+  return ct_font;
 }
 
 void
-_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
+_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *ct_font)
 {
+  CFRelease (ct_font);
 }
 
 
@@ -304,10 +293,9 @@ _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;
+  hb_coretext_shaper_font_data_t *ct_font = HB_SHAPER_DATA_GET (font);
+  return ct_font;
 }
 
 
@@ -539,9 +527,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);
+  hb_coretext_shaper_face_data_t *cg_font = HB_SHAPER_DATA_GET (face);
+  hb_coretext_shaper_font_data_t *ct_font = 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;
 
@@ -676,7 +665,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
@@ -830,7 +819,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)
       {
@@ -948,7 +937,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
@@ -986,13 +975,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);