Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2009  Red Hat, Inc.
      3  * Copyright  2012  Google, Inc.
      4  *
      5  *  This is part of HarfBuzz, a text shaping library.
      6  *
      7  * Permission is hereby granted, without written agreement and without
      8  * license or royalty fees, to use, copy, modify, and distribute this
      9  * software and its documentation for any purpose, provided that the
     10  * above copyright notice and the following two paragraphs appear in
     11  * all copies of this software.
     12  *
     13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     17  * DAMAGE.
     18  *
     19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     24  *
     25  * Red Hat Author(s): Behdad Esfahbod
     26  * Google Author(s): Behdad Esfahbod
     27  */
     28 
     29 #include "hb-private.hh"
     30 
     31 #include "hb-font-private.hh"
     32 
     33 
     34 /*
     35  * hb_font_funcs_t
     36  */
     37 
     38 static hb_bool_t
     39 hb_font_get_font_h_extents_nil (hb_font_t *font,
     40 				void *font_data HB_UNUSED,
     41 				hb_font_extents_t *metrics,
     42 				void *user_data HB_UNUSED)
     43 {
     44   memset (metrics, 0, sizeof (*metrics));
     45   return false;
     46 }
     47 static hb_bool_t
     48 hb_font_get_font_h_extents_parent (hb_font_t *font,
     49 				   void *font_data HB_UNUSED,
     50 				   hb_font_extents_t *metrics,
     51 				   void *user_data HB_UNUSED)
     52 {
     53   hb_bool_t ret = font->parent->get_font_h_extents (metrics);
     54   if (ret) {
     55     metrics->ascender = font->parent_scale_y_distance (metrics->ascender);
     56     metrics->descender = font->parent_scale_y_distance (metrics->descender);
     57     metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap);
     58   }
     59   return ret;
     60 }
     61 
     62 static hb_bool_t
     63 hb_font_get_font_v_extents_nil (hb_font_t *font,
     64 				void *font_data HB_UNUSED,
     65 				hb_font_extents_t *metrics,
     66 				void *user_data HB_UNUSED)
     67 {
     68   memset (metrics, 0, sizeof (*metrics));
     69   return false;
     70 }
     71 static hb_bool_t
     72 hb_font_get_font_v_extents_parent (hb_font_t *font,
     73 				   void *font_data HB_UNUSED,
     74 				   hb_font_extents_t *metrics,
     75 				   void *user_data HB_UNUSED)
     76 {
     77   hb_bool_t ret = font->parent->get_font_v_extents (metrics);
     78   if (ret) {
     79     metrics->ascender = font->parent_scale_x_distance (metrics->ascender);
     80     metrics->descender = font->parent_scale_x_distance (metrics->descender);
     81     metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap);
     82   }
     83   return ret;
     84 }
     85 
     86 static hb_bool_t
     87 hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
     88 			       void *font_data HB_UNUSED,
     89 			       hb_codepoint_t unicode,
     90 			       hb_codepoint_t *glyph,
     91 			       void *user_data HB_UNUSED)
     92 {
     93   *glyph = 0;
     94   return false;
     95 }
     96 static hb_bool_t
     97 hb_font_get_nominal_glyph_parent (hb_font_t *font,
     98 				  void *font_data HB_UNUSED,
     99 				  hb_codepoint_t unicode,
    100 				  hb_codepoint_t *glyph,
    101 				  void *user_data HB_UNUSED)
    102 {
    103   return font->parent->get_nominal_glyph (unicode, glyph);
    104 }
    105 
    106 static hb_bool_t
    107 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
    108 				 void *font_data HB_UNUSED,
    109 				 hb_codepoint_t unicode,
    110 				 hb_codepoint_t variation_selector,
    111 				 hb_codepoint_t *glyph,
    112 				 void *user_data HB_UNUSED)
    113 {
    114   *glyph = 0;
    115   return false;
    116 }
    117 static hb_bool_t
    118 hb_font_get_variation_glyph_parent (hb_font_t *font,
    119 				    void *font_data HB_UNUSED,
    120 				    hb_codepoint_t unicode,
    121 				    hb_codepoint_t variation_selector,
    122 				    hb_codepoint_t *glyph,
    123 				    void *user_data HB_UNUSED)
    124 {
    125   return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
    126 }
    127 
    128 
    129 static hb_position_t
    130 hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
    131 				 void *font_data HB_UNUSED,
    132 				 hb_codepoint_t glyph,
    133 				 void *user_data HB_UNUSED)
    134 {
    135   return font->x_scale;
    136 }
    137 static hb_position_t
    138 hb_font_get_glyph_h_advance_parent (hb_font_t *font,
    139 				    void *font_data HB_UNUSED,
    140 				    hb_codepoint_t glyph,
    141 				    void *user_data HB_UNUSED)
    142 {
    143   return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
    144 }
    145 
    146 static hb_position_t
    147 hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
    148 				 void *font_data HB_UNUSED,
    149 				 hb_codepoint_t glyph,
    150 				 void *user_data HB_UNUSED)
    151 {
    152   /* TODO use font_extents.ascender+descender */
    153   return font->y_scale;
    154 }
    155 static hb_position_t
    156 hb_font_get_glyph_v_advance_parent (hb_font_t *font,
    157 				    void *font_data HB_UNUSED,
    158 				    hb_codepoint_t glyph,
    159 				    void *user_data HB_UNUSED)
    160 {
    161   return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
    162 }
    163 
    164 static hb_bool_t
    165 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
    166 				void *font_data HB_UNUSED,
    167 				hb_codepoint_t glyph,
    168 				hb_position_t *x,
    169 				hb_position_t *y,
    170 				void *user_data HB_UNUSED)
    171 {
    172   *x = *y = 0;
    173   return true;
    174 }
    175 static hb_bool_t
    176 hb_font_get_glyph_h_origin_parent (hb_font_t *font,
    177 				   void *font_data HB_UNUSED,
    178 				   hb_codepoint_t glyph,
    179 				   hb_position_t *x,
    180 				   hb_position_t *y,
    181 				   void *user_data HB_UNUSED)
    182 {
    183   hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
    184   if (ret)
    185     font->parent_scale_position (x, y);
    186   return ret;
    187 }
    188 
    189 static hb_bool_t
    190 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
    191 				void *font_data HB_UNUSED,
    192 				hb_codepoint_t glyph,
    193 				hb_position_t *x,
    194 				hb_position_t *y,
    195 				void *user_data HB_UNUSED)
    196 {
    197   *x = *y = 0;
    198   return false;
    199 }
    200 static hb_bool_t
    201 hb_font_get_glyph_v_origin_parent (hb_font_t *font,
    202 				   void *font_data HB_UNUSED,
    203 				   hb_codepoint_t glyph,
    204 				   hb_position_t *x,
    205 				   hb_position_t *y,
    206 				   void *user_data HB_UNUSED)
    207 {
    208   hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
    209   if (ret)
    210     font->parent_scale_position (x, y);
    211   return ret;
    212 }
    213 
    214 static hb_position_t
    215 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
    216 				 void *font_data HB_UNUSED,
    217 				 hb_codepoint_t left_glyph,
    218 				 hb_codepoint_t right_glyph,
    219 				 void *user_data HB_UNUSED)
    220 {
    221   return 0;
    222 }
    223 static hb_position_t
    224 hb_font_get_glyph_h_kerning_parent (hb_font_t *font,
    225 				    void *font_data HB_UNUSED,
    226 				    hb_codepoint_t left_glyph,
    227 				    hb_codepoint_t right_glyph,
    228 				    void *user_data HB_UNUSED)
    229 {
    230   return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
    231 }
    232 
    233 static hb_position_t
    234 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
    235 				 void *font_data HB_UNUSED,
    236 				 hb_codepoint_t top_glyph,
    237 				 hb_codepoint_t bottom_glyph,
    238 				 void *user_data HB_UNUSED)
    239 {
    240   return 0;
    241 }
    242 static hb_position_t
    243 hb_font_get_glyph_v_kerning_parent (hb_font_t *font,
    244 				    void *font_data HB_UNUSED,
    245 				    hb_codepoint_t top_glyph,
    246 				    hb_codepoint_t bottom_glyph,
    247 				    void *user_data HB_UNUSED)
    248 {
    249   return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
    250 }
    251 
    252 static hb_bool_t
    253 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
    254 			       void *font_data HB_UNUSED,
    255 			       hb_codepoint_t glyph,
    256 			       hb_glyph_extents_t *extents,
    257 			       void *user_data HB_UNUSED)
    258 {
    259   memset (extents, 0, sizeof (*extents));
    260   return false;
    261 }
    262 static hb_bool_t
    263 hb_font_get_glyph_extents_parent (hb_font_t *font,
    264 				  void *font_data HB_UNUSED,
    265 				  hb_codepoint_t glyph,
    266 				  hb_glyph_extents_t *extents,
    267 				  void *user_data HB_UNUSED)
    268 {
    269   hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
    270   if (ret) {
    271     font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
    272     font->parent_scale_distance (&extents->width, &extents->height);
    273   }
    274   return ret;
    275 }
    276 
    277 static hb_bool_t
    278 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
    279 				     void *font_data HB_UNUSED,
    280 				     hb_codepoint_t glyph,
    281 				     unsigned int point_index,
    282 				     hb_position_t *x,
    283 				     hb_position_t *y,
    284 				     void *user_data HB_UNUSED)
    285 {
    286   *x = *y = 0;
    287   return false;
    288 }
    289 static hb_bool_t
    290 hb_font_get_glyph_contour_point_parent (hb_font_t *font,
    291 					void *font_data HB_UNUSED,
    292 					hb_codepoint_t glyph,
    293 					unsigned int point_index,
    294 					hb_position_t *x,
    295 					hb_position_t *y,
    296 					void *user_data HB_UNUSED)
    297 {
    298   hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
    299   if (ret)
    300     font->parent_scale_position (x, y);
    301   return ret;
    302 }
    303 
    304 static hb_bool_t
    305 hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
    306 			    void *font_data HB_UNUSED,
    307 			    hb_codepoint_t glyph,
    308 			    char *name, unsigned int size,
    309 			    void *user_data HB_UNUSED)
    310 {
    311   if (size) *name = '\0';
    312   return false;
    313 }
    314 static hb_bool_t
    315 hb_font_get_glyph_name_parent (hb_font_t *font,
    316 			       void *font_data HB_UNUSED,
    317 			       hb_codepoint_t glyph,
    318 			       char *name, unsigned int size,
    319 			       void *user_data HB_UNUSED)
    320 {
    321   return font->parent->get_glyph_name (glyph, name, size);
    322 }
    323 
    324 static hb_bool_t
    325 hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
    326 				 void *font_data HB_UNUSED,
    327 				 const char *name, int len, /* -1 means nul-terminated */
    328 				 hb_codepoint_t *glyph,
    329 				 void *user_data HB_UNUSED)
    330 {
    331   *glyph = 0;
    332   return false;
    333 }
    334 static hb_bool_t
    335 hb_font_get_glyph_from_name_parent (hb_font_t *font,
    336 				    void *font_data HB_UNUSED,
    337 				    const char *name, int len, /* -1 means nul-terminated */
    338 				    hb_codepoint_t *glyph,
    339 				    void *user_data HB_UNUSED)
    340 {
    341   return font->parent->get_glyph_from_name (name, len, glyph);
    342 }
    343 
    344 static const hb_font_funcs_t _hb_font_funcs_nil = {
    345   HB_OBJECT_HEADER_STATIC,
    346 
    347   true, /* immutable */
    348 
    349   {
    350 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
    351     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    352 #undef HB_FONT_FUNC_IMPLEMENT
    353   },
    354   {
    355 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
    356     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    357 #undef HB_FONT_FUNC_IMPLEMENT
    358   },
    359   {
    360     {
    361 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
    362       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    363 #undef HB_FONT_FUNC_IMPLEMENT
    364     }
    365   }
    366 };
    367 static const hb_font_funcs_t _hb_font_funcs_parent = {
    368   HB_OBJECT_HEADER_STATIC,
    369 
    370   true, /* immutable */
    371 
    372   {
    373 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
    374     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    375 #undef HB_FONT_FUNC_IMPLEMENT
    376   },
    377   {
    378 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
    379     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    380 #undef HB_FONT_FUNC_IMPLEMENT
    381   },
    382   {
    383     {
    384 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_parent,
    385       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    386 #undef HB_FONT_FUNC_IMPLEMENT
    387     }
    388   }
    389 };
    390 
    391 
    392 /**
    393  * hb_font_funcs_create: (Xconstructor)
    394  *
    395  *
    396  *
    397  * Return value: (transfer full):
    398  *
    399  * Since: 0.9.2
    400  **/
    401 hb_font_funcs_t *
    402 hb_font_funcs_create (void)
    403 {
    404   hb_font_funcs_t *ffuncs;
    405 
    406   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
    407     return hb_font_funcs_get_empty ();
    408 
    409   ffuncs->get = _hb_font_funcs_parent.get;
    410 
    411   return ffuncs;
    412 }
    413 
    414 /**
    415  * hb_font_funcs_get_empty:
    416  *
    417  *
    418  *
    419  * Return value: (transfer full):
    420  *
    421  * Since: 0.9.2
    422  **/
    423 hb_font_funcs_t *
    424 hb_font_funcs_get_empty (void)
    425 {
    426   return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_parent);
    427 }
    428 
    429 /**
    430  * hb_font_funcs_reference: (skip)
    431  * @ffuncs: font functions.
    432  *
    433  *
    434  *
    435  * Return value:
    436  *
    437  * Since: 0.9.2
    438  **/
    439 hb_font_funcs_t *
    440 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
    441 {
    442   return hb_object_reference (ffuncs);
    443 }
    444 
    445 /**
    446  * hb_font_funcs_destroy: (skip)
    447  * @ffuncs: font functions.
    448  *
    449  *
    450  *
    451  * Since: 0.9.2
    452  **/
    453 void
    454 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
    455 {
    456   if (!hb_object_destroy (ffuncs)) return;
    457 
    458 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
    459   ffuncs->destroy.name (ffuncs->user_data.name);
    460   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    461 #undef HB_FONT_FUNC_IMPLEMENT
    462 
    463   free (ffuncs);
    464 }
    465 
    466 /**
    467  * hb_font_funcs_set_user_data: (skip)
    468  * @ffuncs: font functions.
    469  * @key:
    470  * @data:
    471  * @destroy:
    472  * @replace:
    473  *
    474  *
    475  *
    476  * Return value:
    477  *
    478  * Since: 0.9.2
    479  **/
    480 hb_bool_t
    481 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
    482 			     hb_user_data_key_t *key,
    483 			     void *              data,
    484 			     hb_destroy_func_t   destroy,
    485 			     hb_bool_t           replace)
    486 {
    487   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
    488 }
    489 
    490 /**
    491  * hb_font_funcs_get_user_data: (skip)
    492  * @ffuncs: font functions.
    493  * @key:
    494  *
    495  *
    496  *
    497  * Return value: (transfer none):
    498  *
    499  * Since: 0.9.2
    500  **/
    501 void *
    502 hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
    503 			     hb_user_data_key_t *key)
    504 {
    505   return hb_object_get_user_data (ffuncs, key);
    506 }
    507 
    508 
    509 /**
    510  * hb_font_funcs_make_immutable:
    511  * @ffuncs: font functions.
    512  *
    513  *
    514  *
    515  * Since: 0.9.2
    516  **/
    517 void
    518 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
    519 {
    520   if (unlikely (hb_object_is_inert (ffuncs)))
    521     return;
    522 
    523   ffuncs->immutable = true;
    524 }
    525 
    526 /**
    527  * hb_font_funcs_is_immutable:
    528  * @ffuncs: font functions.
    529  *
    530  *
    531  *
    532  * Return value:
    533  *
    534  * Since: 0.9.2
    535  **/
    536 hb_bool_t
    537 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
    538 {
    539   return ffuncs->immutable;
    540 }
    541 
    542 
    543 #define HB_FONT_FUNC_IMPLEMENT(name) \
    544                                                                          \
    545 void                                                                     \
    546 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
    547                                  hb_font_get_##name##_func_t  func,      \
    548                                  void                        *user_data, \
    549                                  hb_destroy_func_t            destroy)   \
    550 {                                                                        \
    551   if (ffuncs->immutable) {                                               \
    552     if (destroy)                                                         \
    553       destroy (user_data);                                               \
    554     return;                                                              \
    555   }                                                                      \
    556                                                                          \
    557   if (ffuncs->destroy.name)                                              \
    558     ffuncs->destroy.name (ffuncs->user_data.name);                       \
    559                                                                          \
    560   if (func) {                                                            \
    561     ffuncs->get.f.name = func;                                           \
    562     ffuncs->user_data.name = user_data;                                  \
    563     ffuncs->destroy.name = destroy;                                      \
    564   } else {                                                               \
    565     ffuncs->get.f.name = hb_font_get_##name##_parent;                    \
    566     ffuncs->user_data.name = NULL;                                       \
    567     ffuncs->destroy.name = NULL;                                         \
    568   }                                                                      \
    569 }
    570 
    571 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    572 #undef HB_FONT_FUNC_IMPLEMENT
    573 
    574 bool
    575 hb_font_t::has_func (unsigned int i)
    576 {
    577   if (parent && parent != hb_font_get_empty () && parent->has_func (i))
    578     return true;
    579   return this->klass->get.array[i] != _hb_font_funcs_parent.get.array[i];
    580 }
    581 
    582 /* Public getters */
    583 
    584 /**
    585  * hb_font_get_h_extents:
    586  * @font: a font.
    587  * @extents: (out):
    588  *
    589  *
    590  *
    591  * Return value:
    592  *
    593  * Since: 1.1.3
    594  **/
    595 hb_bool_t
    596 hb_font_get_h_extents (hb_font_t *font,
    597 		       hb_font_extents_t *extents)
    598 {
    599   return font->get_font_h_extents (extents);
    600 }
    601 
    602 /**
    603  * hb_font_get_v_extents:
    604  * @font: a font.
    605  * @extents: (out):
    606  *
    607  *
    608  *
    609  * Return value:
    610  *
    611  * Since: 1.1.3
    612  **/
    613 hb_bool_t
    614 hb_font_get_v_extents (hb_font_t *font,
    615 		       hb_font_extents_t *extents)
    616 {
    617   return font->get_font_v_extents (extents);
    618 }
    619 
    620 /**
    621  * hb_font_get_glyph:
    622  * @font: a font.
    623  * @unicode:
    624  * @variation_selector:
    625  * @glyph: (out):
    626  *
    627  *
    628  *
    629  * Return value:
    630  *
    631  * Since: 0.9.2
    632  **/
    633 hb_bool_t
    634 hb_font_get_glyph (hb_font_t *font,
    635 		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
    636 		   hb_codepoint_t *glyph)
    637 {
    638   if (unlikely (variation_selector))
    639     return font->get_variation_glyph (unicode, variation_selector, glyph);
    640   return font->get_nominal_glyph (unicode, glyph);
    641 }
    642 
    643 /**
    644  * hb_font_get_nominal_glyph:
    645  * @font: a font.
    646  * @unicode:
    647  * @glyph: (out):
    648  *
    649  *
    650  *
    651  * Return value:
    652  *
    653  * Since: 1.2.3
    654  **/
    655 hb_bool_t
    656 hb_font_get_nominal_glyph (hb_font_t *font,
    657 			   hb_codepoint_t unicode,
    658 			   hb_codepoint_t *glyph)
    659 {
    660   return font->get_nominal_glyph (unicode, glyph);
    661 }
    662 
    663 /**
    664  * hb_font_get_variation_glyph:
    665  * @font: a font.
    666  * @unicode:
    667  * @variation_selector:
    668  * @glyph: (out):
    669  *
    670  *
    671  *
    672  * Return value:
    673  *
    674  * Since: 1.2.3
    675  **/
    676 hb_bool_t
    677 hb_font_get_variation_glyph (hb_font_t *font,
    678 			     hb_codepoint_t unicode, hb_codepoint_t variation_selector,
    679 			     hb_codepoint_t *glyph)
    680 {
    681   return font->get_variation_glyph (unicode, variation_selector, glyph);
    682 }
    683 
    684 /**
    685  * hb_font_get_glyph_h_advance:
    686  * @font: a font.
    687  * @glyph:
    688  *
    689  *
    690  *
    691  * Return value:
    692  *
    693  * Since: 0.9.2
    694  **/
    695 hb_position_t
    696 hb_font_get_glyph_h_advance (hb_font_t *font,
    697 			     hb_codepoint_t glyph)
    698 {
    699   return font->get_glyph_h_advance (glyph);
    700 }
    701 
    702 /**
    703  * hb_font_get_glyph_v_advance:
    704  * @font: a font.
    705  * @glyph:
    706  *
    707  *
    708  *
    709  * Return value:
    710  *
    711  * Since: 0.9.2
    712  **/
    713 hb_position_t
    714 hb_font_get_glyph_v_advance (hb_font_t *font,
    715 			     hb_codepoint_t glyph)
    716 {
    717   return font->get_glyph_v_advance (glyph);
    718 }
    719 
    720 /**
    721  * hb_font_get_glyph_h_origin:
    722  * @font: a font.
    723  * @glyph:
    724  * @x: (out):
    725  * @y: (out):
    726  *
    727  *
    728  *
    729  * Return value:
    730  *
    731  * Since: 0.9.2
    732  **/
    733 hb_bool_t
    734 hb_font_get_glyph_h_origin (hb_font_t *font,
    735 			    hb_codepoint_t glyph,
    736 			    hb_position_t *x, hb_position_t *y)
    737 {
    738   return font->get_glyph_h_origin (glyph, x, y);
    739 }
    740 
    741 /**
    742  * hb_font_get_glyph_v_origin:
    743  * @font: a font.
    744  * @glyph:
    745  * @x: (out):
    746  * @y: (out):
    747  *
    748  *
    749  *
    750  * Return value:
    751  *
    752  * Since: 0.9.2
    753  **/
    754 hb_bool_t
    755 hb_font_get_glyph_v_origin (hb_font_t *font,
    756 			    hb_codepoint_t glyph,
    757 			    hb_position_t *x, hb_position_t *y)
    758 {
    759   return font->get_glyph_v_origin (glyph, x, y);
    760 }
    761 
    762 /**
    763  * hb_font_get_glyph_h_kerning:
    764  * @font: a font.
    765  * @left_glyph:
    766  * @right_glyph:
    767  *
    768  *
    769  *
    770  * Return value:
    771  *
    772  * Since: 0.9.2
    773  **/
    774 hb_position_t
    775 hb_font_get_glyph_h_kerning (hb_font_t *font,
    776 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
    777 {
    778   return font->get_glyph_h_kerning (left_glyph, right_glyph);
    779 }
    780 
    781 /**
    782  * hb_font_get_glyph_v_kerning:
    783  * @font: a font.
    784  * @top_glyph:
    785  * @bottom_glyph:
    786  *
    787  *
    788  *
    789  * Return value:
    790  *
    791  * Since: 0.9.2
    792  **/
    793 hb_position_t
    794 hb_font_get_glyph_v_kerning (hb_font_t *font,
    795 			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
    796 {
    797   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
    798 }
    799 
    800 /**
    801  * hb_font_get_glyph_extents:
    802  * @font: a font.
    803  * @glyph:
    804  * @extents: (out):
    805  *
    806  *
    807  *
    808  * Return value:
    809  *
    810  * Since: 0.9.2
    811  **/
    812 hb_bool_t
    813 hb_font_get_glyph_extents (hb_font_t *font,
    814 			   hb_codepoint_t glyph,
    815 			   hb_glyph_extents_t *extents)
    816 {
    817   return font->get_glyph_extents (glyph, extents);
    818 }
    819 
    820 /**
    821  * hb_font_get_glyph_contour_point:
    822  * @font: a font.
    823  * @glyph:
    824  * @point_index:
    825  * @x: (out):
    826  * @y: (out):
    827  *
    828  *
    829  *
    830  * Return value:
    831  *
    832  * Since: 0.9.2
    833  **/
    834 hb_bool_t
    835 hb_font_get_glyph_contour_point (hb_font_t *font,
    836 				 hb_codepoint_t glyph, unsigned int point_index,
    837 				 hb_position_t *x, hb_position_t *y)
    838 {
    839   return font->get_glyph_contour_point (glyph, point_index, x, y);
    840 }
    841 
    842 /**
    843  * hb_font_get_glyph_name:
    844  * @font: a font.
    845  * @glyph:
    846  * @name: (array length=size):
    847  * @size:
    848  *
    849  *
    850  *
    851  * Return value:
    852  *
    853  * Since: 0.9.2
    854  **/
    855 hb_bool_t
    856 hb_font_get_glyph_name (hb_font_t *font,
    857 			hb_codepoint_t glyph,
    858 			char *name, unsigned int size)
    859 {
    860   return font->get_glyph_name (glyph, name, size);
    861 }
    862 
    863 /**
    864  * hb_font_get_glyph_from_name:
    865  * @font: a font.
    866  * @name: (array length=len):
    867  * @len:
    868  * @glyph: (out):
    869  *
    870  *
    871  *
    872  * Return value:
    873  *
    874  * Since: 0.9.2
    875  **/
    876 hb_bool_t
    877 hb_font_get_glyph_from_name (hb_font_t *font,
    878 			     const char *name, int len, /* -1 means nul-terminated */
    879 			     hb_codepoint_t *glyph)
    880 {
    881   return font->get_glyph_from_name (name, len, glyph);
    882 }
    883 
    884 
    885 /* A bit higher-level, and with fallback */
    886 
    887 /**
    888  * hb_font_get_extents_for_direction:
    889  * @font: a font.
    890  * @direction:
    891  * @extents:
    892  *
    893  *
    894  *
    895  * Since: 1.1.3
    896  **/
    897 void
    898 hb_font_get_extents_for_direction (hb_font_t *font,
    899 				   hb_direction_t direction,
    900 				   hb_font_extents_t *extents)
    901 {
    902   return font->get_extents_for_direction (direction, extents);
    903 }
    904 /**
    905  * hb_font_get_glyph_advance_for_direction:
    906  * @font: a font.
    907  * @glyph:
    908  * @direction:
    909  * @x: (out):
    910  * @y: (out):
    911  *
    912  *
    913  *
    914  * Since: 0.9.2
    915  **/
    916 void
    917 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
    918 					 hb_codepoint_t glyph,
    919 					 hb_direction_t direction,
    920 					 hb_position_t *x, hb_position_t *y)
    921 {
    922   return font->get_glyph_advance_for_direction (glyph, direction, x, y);
    923 }
    924 
    925 /**
    926  * hb_font_get_glyph_origin_for_direction:
    927  * @font: a font.
    928  * @glyph:
    929  * @direction:
    930  * @x: (out):
    931  * @y: (out):
    932  *
    933  *
    934  *
    935  * Since: 0.9.2
    936  **/
    937 void
    938 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
    939 					hb_codepoint_t glyph,
    940 					hb_direction_t direction,
    941 					hb_position_t *x, hb_position_t *y)
    942 {
    943   return font->get_glyph_origin_for_direction (glyph, direction, x, y);
    944 }
    945 
    946 /**
    947  * hb_font_add_glyph_origin_for_direction:
    948  * @font: a font.
    949  * @glyph:
    950  * @direction:
    951  * @x: (out):
    952  * @y: (out):
    953  *
    954  *
    955  *
    956  * Since: 0.9.2
    957  **/
    958 void
    959 hb_font_add_glyph_origin_for_direction (hb_font_t *font,
    960 					hb_codepoint_t glyph,
    961 					hb_direction_t direction,
    962 					hb_position_t *x, hb_position_t *y)
    963 {
    964   return font->add_glyph_origin_for_direction (glyph, direction, x, y);
    965 }
    966 
    967 /**
    968  * hb_font_subtract_glyph_origin_for_direction:
    969  * @font: a font.
    970  * @glyph:
    971  * @direction:
    972  * @x: (out):
    973  * @y: (out):
    974  *
    975  *
    976  *
    977  * Since: 0.9.2
    978  **/
    979 void
    980 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
    981 					     hb_codepoint_t glyph,
    982 					     hb_direction_t direction,
    983 					     hb_position_t *x, hb_position_t *y)
    984 {
    985   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
    986 }
    987 
    988 /**
    989  * hb_font_get_glyph_kerning_for_direction:
    990  * @font: a font.
    991  * @first_glyph:
    992  * @second_glyph:
    993  * @direction:
    994  * @x: (out):
    995  * @y: (out):
    996  *
    997  *
    998  *
    999  * Since: 0.9.2
   1000  **/
   1001 void
   1002 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
   1003 					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
   1004 					 hb_direction_t direction,
   1005 					 hb_position_t *x, hb_position_t *y)
   1006 {
   1007   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
   1008 }
   1009 
   1010 /**
   1011  * hb_font_get_glyph_extents_for_origin:
   1012  * @font: a font.
   1013  * @glyph:
   1014  * @direction:
   1015  * @extents: (out):
   1016  *
   1017  *
   1018  *
   1019  * Return value:
   1020  *
   1021  * Since: 0.9.2
   1022  **/
   1023 hb_bool_t
   1024 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
   1025 				      hb_codepoint_t glyph,
   1026 				      hb_direction_t direction,
   1027 				      hb_glyph_extents_t *extents)
   1028 {
   1029   return font->get_glyph_extents_for_origin (glyph, direction, extents);
   1030 }
   1031 
   1032 /**
   1033  * hb_font_get_glyph_contour_point_for_origin:
   1034  * @font: a font.
   1035  * @glyph:
   1036  * @point_index:
   1037  * @direction:
   1038  * @x: (out):
   1039  * @y: (out):
   1040  *
   1041  *
   1042  *
   1043  * Return value:
   1044  *
   1045  * Since: 0.9.2
   1046  **/
   1047 hb_bool_t
   1048 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
   1049 					    hb_codepoint_t glyph, unsigned int point_index,
   1050 					    hb_direction_t direction,
   1051 					    hb_position_t *x, hb_position_t *y)
   1052 {
   1053   return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
   1054 }
   1055 
   1056 /* Generates gidDDD if glyph has no name. */
   1057 /**
   1058  * hb_font_glyph_to_string:
   1059  * @font: a font.
   1060  * @glyph:
   1061  * @s: (array length=size):
   1062  * @size:
   1063  *
   1064  *
   1065  *
   1066  * Since: 0.9.2
   1067  **/
   1068 void
   1069 hb_font_glyph_to_string (hb_font_t *font,
   1070 			 hb_codepoint_t glyph,
   1071 			 char *s, unsigned int size)
   1072 {
   1073   font->glyph_to_string (glyph, s, size);
   1074 }
   1075 
   1076 /* Parses gidDDD and uniUUUU strings automatically. */
   1077 /**
   1078  * hb_font_glyph_from_string:
   1079  * @font: a font.
   1080  * @s: (array length=len) (element-type uint8_t):
   1081  * @len:
   1082  * @glyph: (out):
   1083  *
   1084  *
   1085  *
   1086  * Return value:
   1087  *
   1088  * Since: 0.9.2
   1089  **/
   1090 hb_bool_t
   1091 hb_font_glyph_from_string (hb_font_t *font,
   1092 			   const char *s, int len, /* -1 means nul-terminated */
   1093 			   hb_codepoint_t *glyph)
   1094 {
   1095   return font->glyph_from_string (s, len, glyph);
   1096 }
   1097 
   1098 
   1099 /*
   1100  * hb_font_t
   1101  */
   1102 
   1103 /**
   1104  * hb_font_create: (Xconstructor)
   1105  * @face: a face.
   1106  *
   1107  *
   1108  *
   1109  * Return value: (transfer full):
   1110  *
   1111  * Since: 0.9.2
   1112  **/
   1113 hb_font_t *
   1114 hb_font_create (hb_face_t *face)
   1115 {
   1116   hb_font_t *font;
   1117 
   1118   if (unlikely (!face))
   1119     face = hb_face_get_empty ();
   1120   if (!(font = hb_object_create<hb_font_t> ()))
   1121     return hb_font_get_empty ();
   1122 
   1123   hb_face_make_immutable (face);
   1124   font->parent = hb_font_get_empty ();
   1125   font->face = hb_face_reference (face);
   1126   font->klass = hb_font_funcs_get_empty ();
   1127 
   1128   font->x_scale = font->y_scale = hb_face_get_upem (face);
   1129 
   1130   return font;
   1131 }
   1132 
   1133 /**
   1134  * hb_font_create_sub_font:
   1135  * @parent: parent font.
   1136  *
   1137  *
   1138  *
   1139  * Return value: (transfer full):
   1140  *
   1141  * Since: 0.9.2
   1142  **/
   1143 hb_font_t *
   1144 hb_font_create_sub_font (hb_font_t *parent)
   1145 {
   1146   if (unlikely (!parent))
   1147     parent = hb_font_get_empty ();
   1148 
   1149   hb_font_t *font = hb_font_create (parent->face);
   1150 
   1151   if (unlikely (hb_object_is_inert (font)))
   1152     return font;
   1153 
   1154   font->parent = hb_font_reference (parent);
   1155 
   1156   font->x_scale = parent->x_scale;
   1157   font->y_scale = parent->y_scale;
   1158   font->x_ppem = parent->x_ppem;
   1159   font->y_ppem = parent->y_ppem;
   1160 
   1161   /* TODO: copy variation coordinates. */
   1162 
   1163   return font;
   1164 }
   1165 
   1166 /**
   1167  * hb_font_get_empty:
   1168  *
   1169  *
   1170  *
   1171  * Return value: (transfer full)
   1172  *
   1173  * Since: 0.9.2
   1174  **/
   1175 hb_font_t *
   1176 hb_font_get_empty (void)
   1177 {
   1178   static const hb_font_t _hb_font_nil = {
   1179     HB_OBJECT_HEADER_STATIC,
   1180 
   1181     true, /* immutable */
   1182 
   1183     NULL, /* parent */
   1184     const_cast<hb_face_t *> (&_hb_face_nil),
   1185 
   1186     1000, /* x_scale */
   1187     1000, /* y_scale */
   1188 
   1189     0, /* x_ppem */
   1190     0, /* y_ppem */
   1191 
   1192     0, /* num_coords */
   1193     NULL, /* coords */
   1194 
   1195     const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
   1196     NULL, /* user_data */
   1197     NULL, /* destroy */
   1198 
   1199     {
   1200 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
   1201 #include "hb-shaper-list.hh"
   1202 #undef HB_SHAPER_IMPLEMENT
   1203     }
   1204   };
   1205 
   1206   return const_cast<hb_font_t *> (&_hb_font_nil);
   1207 }
   1208 
   1209 /**
   1210  * hb_font_reference: (skip)
   1211  * @font: a font.
   1212  *
   1213  *
   1214  *
   1215  * Return value: (transfer full):
   1216  *
   1217  * Since: 0.9.2
   1218  **/
   1219 hb_font_t *
   1220 hb_font_reference (hb_font_t *font)
   1221 {
   1222   return hb_object_reference (font);
   1223 }
   1224 
   1225 /**
   1226  * hb_font_destroy: (skip)
   1227  * @font: a font.
   1228  *
   1229  *
   1230  *
   1231  * Since: 0.9.2
   1232  **/
   1233 void
   1234 hb_font_destroy (hb_font_t *font)
   1235 {
   1236   if (!hb_object_destroy (font)) return;
   1237 
   1238 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
   1239 #include "hb-shaper-list.hh"
   1240 #undef HB_SHAPER_IMPLEMENT
   1241 
   1242   if (font->destroy)
   1243     font->destroy (font->user_data);
   1244 
   1245   hb_font_destroy (font->parent);
   1246   hb_face_destroy (font->face);
   1247   hb_font_funcs_destroy (font->klass);
   1248 
   1249   free (font->coords);
   1250 
   1251   free (font);
   1252 }
   1253 
   1254 /**
   1255  * hb_font_set_user_data: (skip)
   1256  * @font: a font.
   1257  * @key:
   1258  * @data:
   1259  * @destroy:
   1260  * @replace:
   1261  *
   1262  *
   1263  *
   1264  * Return value:
   1265  *
   1266  * Since: 0.9.2
   1267  **/
   1268 hb_bool_t
   1269 hb_font_set_user_data (hb_font_t          *font,
   1270 		       hb_user_data_key_t *key,
   1271 		       void *              data,
   1272 		       hb_destroy_func_t   destroy,
   1273 		       hb_bool_t           replace)
   1274 {
   1275   return hb_object_set_user_data (font, key, data, destroy, replace);
   1276 }
   1277 
   1278 /**
   1279  * hb_font_get_user_data: (skip)
   1280  * @font: a font.
   1281  * @key:
   1282  *
   1283  *
   1284  *
   1285  * Return value: (transfer none):
   1286  *
   1287  * Since: 0.9.2
   1288  **/
   1289 void *
   1290 hb_font_get_user_data (hb_font_t          *font,
   1291 		       hb_user_data_key_t *key)
   1292 {
   1293   return hb_object_get_user_data (font, key);
   1294 }
   1295 
   1296 /**
   1297  * hb_font_make_immutable:
   1298  * @font: a font.
   1299  *
   1300  *
   1301  *
   1302  * Since: 0.9.2
   1303  **/
   1304 void
   1305 hb_font_make_immutable (hb_font_t *font)
   1306 {
   1307   if (unlikely (hb_object_is_inert (font)))
   1308     return;
   1309 
   1310   if (font->parent)
   1311     hb_font_make_immutable (font->parent);
   1312 
   1313   font->immutable = true;
   1314 }
   1315 
   1316 /**
   1317  * hb_font_is_immutable:
   1318  * @font: a font.
   1319  *
   1320  *
   1321  *
   1322  * Return value:
   1323  *
   1324  * Since: 0.9.2
   1325  **/
   1326 hb_bool_t
   1327 hb_font_is_immutable (hb_font_t *font)
   1328 {
   1329   return font->immutable;
   1330 }
   1331 
   1332 /**
   1333  * hb_font_set_parent:
   1334  * @font: a font.
   1335  * @parent: new parent.
   1336  *
   1337  * Sets parent font of @font.
   1338  *
   1339  * Since: 1.0.5
   1340  **/
   1341 void
   1342 hb_font_set_parent (hb_font_t *font,
   1343 		    hb_font_t *parent)
   1344 {
   1345   if (font->immutable)
   1346     return;
   1347 
   1348   if (!parent)
   1349     parent = hb_font_get_empty ();
   1350 
   1351   hb_font_t *old = font->parent;
   1352 
   1353   font->parent = hb_font_reference (parent);
   1354 
   1355   hb_font_destroy (old);
   1356 }
   1357 
   1358 /**
   1359  * hb_font_get_parent:
   1360  * @font: a font.
   1361  *
   1362  *
   1363  *
   1364  * Return value: (transfer none):
   1365  *
   1366  * Since: 0.9.2
   1367  **/
   1368 hb_font_t *
   1369 hb_font_get_parent (hb_font_t *font)
   1370 {
   1371   return font->parent;
   1372 }
   1373 
   1374 /**
   1375  * hb_font_get_face:
   1376  * @font: a font.
   1377  *
   1378  *
   1379  *
   1380  * Return value: (transfer none):
   1381  *
   1382  * Since: 0.9.2
   1383  **/
   1384 hb_face_t *
   1385 hb_font_get_face (hb_font_t *font)
   1386 {
   1387   return font->face;
   1388 }
   1389 
   1390 
   1391 /**
   1392  * hb_font_set_funcs:
   1393  * @font: a font.
   1394  * @klass: (closure font_data) (destroy destroy) (scope notified):
   1395  * @font_data:
   1396  * @destroy:
   1397  *
   1398  *
   1399  *
   1400  * Since: 0.9.2
   1401  **/
   1402 void
   1403 hb_font_set_funcs (hb_font_t         *font,
   1404 		   hb_font_funcs_t   *klass,
   1405 		   void              *font_data,
   1406 		   hb_destroy_func_t  destroy)
   1407 {
   1408   if (font->immutable) {
   1409     if (destroy)
   1410       destroy (font_data);
   1411     return;
   1412   }
   1413 
   1414   if (font->destroy)
   1415     font->destroy (font->user_data);
   1416 
   1417   if (!klass)
   1418     klass = hb_font_funcs_get_empty ();
   1419 
   1420   hb_font_funcs_reference (klass);
   1421   hb_font_funcs_destroy (font->klass);
   1422   font->klass = klass;
   1423   font->user_data = font_data;
   1424   font->destroy = destroy;
   1425 }
   1426 
   1427 /**
   1428  * hb_font_set_funcs_data:
   1429  * @font: a font.
   1430  * @font_data: (destroy destroy) (scope notified):
   1431  * @destroy:
   1432  *
   1433  *
   1434  *
   1435  * Since: 0.9.2
   1436  **/
   1437 void
   1438 hb_font_set_funcs_data (hb_font_t         *font,
   1439 		        void              *font_data,
   1440 		        hb_destroy_func_t  destroy)
   1441 {
   1442   /* Destroy user_data? */
   1443   if (font->immutable) {
   1444     if (destroy)
   1445       destroy (font_data);
   1446     return;
   1447   }
   1448 
   1449   if (font->destroy)
   1450     font->destroy (font->user_data);
   1451 
   1452   font->user_data = font_data;
   1453   font->destroy = destroy;
   1454 }
   1455 
   1456 
   1457 /**
   1458  * hb_font_set_scale:
   1459  * @font: a font.
   1460  * @x_scale:
   1461  * @y_scale:
   1462  *
   1463  *
   1464  *
   1465  * Since: 0.9.2
   1466  **/
   1467 void
   1468 hb_font_set_scale (hb_font_t *font,
   1469 		   int x_scale,
   1470 		   int y_scale)
   1471 {
   1472   if (font->immutable)
   1473     return;
   1474 
   1475   font->x_scale = x_scale;
   1476   font->y_scale = y_scale;
   1477 }
   1478 
   1479 /**
   1480  * hb_font_get_scale:
   1481  * @font: a font.
   1482  * @x_scale: (out):
   1483  * @y_scale: (out):
   1484  *
   1485  *
   1486  *
   1487  * Since: 0.9.2
   1488  **/
   1489 void
   1490 hb_font_get_scale (hb_font_t *font,
   1491 		   int *x_scale,
   1492 		   int *y_scale)
   1493 {
   1494   if (x_scale) *x_scale = font->x_scale;
   1495   if (y_scale) *y_scale = font->y_scale;
   1496 }
   1497 
   1498 /**
   1499  * hb_font_set_ppem:
   1500  * @font: a font.
   1501  * @x_ppem:
   1502  * @y_ppem:
   1503  *
   1504  *
   1505  *
   1506  * Since: 0.9.2
   1507  **/
   1508 void
   1509 hb_font_set_ppem (hb_font_t *font,
   1510 		  unsigned int x_ppem,
   1511 		  unsigned int y_ppem)
   1512 {
   1513   if (font->immutable)
   1514     return;
   1515 
   1516   font->x_ppem = x_ppem;
   1517   font->y_ppem = y_ppem;
   1518 }
   1519 
   1520 /**
   1521  * hb_font_get_ppem:
   1522  * @font: a font.
   1523  * @x_ppem: (out):
   1524  * @y_ppem: (out):
   1525  *
   1526  *
   1527  *
   1528  * Since: 0.9.2
   1529  **/
   1530 void
   1531 hb_font_get_ppem (hb_font_t *font,
   1532 		  unsigned int *x_ppem,
   1533 		  unsigned int *y_ppem)
   1534 {
   1535   if (x_ppem) *x_ppem = font->x_ppem;
   1536   if (y_ppem) *y_ppem = font->y_ppem;
   1537 }
   1538 
   1539 /*
   1540  * Variations
   1541  */
   1542 
   1543 static void
   1544 _hb_font_adopt_var_coords_normalized (hb_font_t *font,
   1545 				      int *coords, /* 2.14 normalized */
   1546 				      unsigned int coords_length)
   1547 {
   1548   free (font->coords);
   1549 
   1550   font->coords = coords;
   1551   font->num_coords = coords_length;
   1552 }
   1553 
   1554 /**
   1555  * hb_font_set_variations:
   1556  *
   1557  * Since: 1.4.2
   1558  */
   1559 void
   1560 hb_font_set_variations (hb_font_t *font,
   1561 			const hb_variation_t *variations,
   1562 			unsigned int variations_length)
   1563 {
   1564   if (font->immutable)
   1565     return;
   1566 
   1567   if (!variations_length)
   1568   {
   1569     hb_font_set_var_coords_normalized (font, NULL, 0);
   1570     return;
   1571   }
   1572 
   1573   unsigned int coords_length = hb_ot_var_get_axis_count (font->face);
   1574 
   1575   int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : NULL;
   1576   if (unlikely (coords_length && !normalized))
   1577     return;
   1578 
   1579   hb_ot_var_normalize_variations (font->face,
   1580 				  variations, variations_length,
   1581 				  normalized, coords_length);
   1582   _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
   1583 }
   1584 
   1585 /**
   1586  * hb_font_set_var_coords_design:
   1587  *
   1588  * Since: 1.4.2
   1589  */
   1590 void
   1591 hb_font_set_var_coords_design (hb_font_t *font,
   1592 			       const float *coords,
   1593 			       unsigned int coords_length)
   1594 {
   1595   if (font->immutable)
   1596     return;
   1597 
   1598   int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : NULL;
   1599   if (unlikely (coords_length && !normalized))
   1600     return;
   1601 
   1602   hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
   1603   _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
   1604 }
   1605 
   1606 /**
   1607  * hb_font_set_var_coords_normalized:
   1608  *
   1609  * Since: 1.4.2
   1610  */
   1611 void
   1612 hb_font_set_var_coords_normalized (hb_font_t *font,
   1613 				   const int *coords, /* 2.14 normalized */
   1614 				   unsigned int coords_length)
   1615 {
   1616   if (font->immutable)
   1617     return;
   1618 
   1619   int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : NULL;
   1620   if (unlikely (coords_length && !copy))
   1621     return;
   1622 
   1623   if (coords_length)
   1624     memcpy (copy, coords, coords_length * sizeof (coords[0]));
   1625 
   1626   _hb_font_adopt_var_coords_normalized (font, copy, coords_length);
   1627 }
   1628 
   1629 /**
   1630  * hb_font_set_var_coords_normalized:
   1631  *
   1632  * Return value is valid as long as variation coordinates of the font
   1633  * are not modified.
   1634  *
   1635  * Since: 1.4.2
   1636  */
   1637 const int *
   1638 hb_font_get_var_coords_normalized (hb_font_t *font,
   1639 				   unsigned int *length)
   1640 {
   1641   if (length)
   1642     *length = font->num_coords;
   1643 
   1644   return font->coords;
   1645 }
   1646 
   1647 
   1648 #ifndef HB_DISABLE_DEPRECATED
   1649 
   1650 /*
   1651  * Deprecated get_glyph_func():
   1652  */
   1653 
   1654 struct hb_trampoline_closure_t
   1655 {
   1656   void *user_data;
   1657   hb_destroy_func_t destroy;
   1658   unsigned int ref_count;
   1659 };
   1660 
   1661 template <typename FuncType>
   1662 struct hb_trampoline_t
   1663 {
   1664   hb_trampoline_closure_t closure; /* Must be first. */
   1665   FuncType func;
   1666 };
   1667 
   1668 template <typename FuncType>
   1669 static hb_trampoline_t<FuncType> *
   1670 trampoline_create (FuncType           func,
   1671 		   void              *user_data,
   1672 		   hb_destroy_func_t  destroy)
   1673 {
   1674   typedef hb_trampoline_t<FuncType> trampoline_t;
   1675 
   1676   trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
   1677 
   1678   if (unlikely (!trampoline))
   1679     return NULL;
   1680 
   1681   trampoline->closure.user_data = user_data;
   1682   trampoline->closure.destroy = destroy;
   1683   trampoline->closure.ref_count = 1;
   1684   trampoline->func = func;
   1685 
   1686   return trampoline;
   1687 }
   1688 
   1689 static void
   1690 trampoline_reference (hb_trampoline_closure_t *closure)
   1691 {
   1692   closure->ref_count++;
   1693 }
   1694 
   1695 static void
   1696 trampoline_destroy (void *user_data)
   1697 {
   1698   hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
   1699 
   1700   if (--closure->ref_count)
   1701     return;
   1702 
   1703   if (closure->destroy)
   1704     closure->destroy (closure->user_data);
   1705   free (closure);
   1706 }
   1707 
   1708 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
   1709 
   1710 static hb_bool_t
   1711 hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
   1712 				      void *font_data,
   1713 				      hb_codepoint_t unicode,
   1714 				      hb_codepoint_t *glyph,
   1715 				      void *user_data)
   1716 {
   1717   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
   1718   return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
   1719 }
   1720 
   1721 static hb_bool_t
   1722 hb_font_get_variation_glyph_trampoline (hb_font_t *font,
   1723 					void *font_data,
   1724 					hb_codepoint_t unicode,
   1725 					hb_codepoint_t variation_selector,
   1726 					hb_codepoint_t *glyph,
   1727 					void *user_data)
   1728 {
   1729   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
   1730   return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
   1731 }
   1732 
   1733 /**
   1734  * hb_font_funcs_set_glyph_func:
   1735  * @ffuncs: font functions.
   1736  * @func: (closure user_data) (destroy destroy) (scope notified):
   1737  * @user_data:
   1738  * @destroy:
   1739  *
   1740  * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
   1741  * hb_font_funcs_set_variation_glyph_func() instead.
   1742  *
   1743  * Since: 0.9.2
   1744  * Deprecated: 1.2.3
   1745  **/
   1746 void
   1747 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
   1748 			      hb_font_get_glyph_func_t func,
   1749 			      void *user_data, hb_destroy_func_t destroy)
   1750 {
   1751   hb_font_get_glyph_trampoline_t *trampoline;
   1752 
   1753   trampoline = trampoline_create (func, user_data, destroy);
   1754   if (unlikely (!trampoline))
   1755   {
   1756     if (destroy)
   1757       destroy (user_data);
   1758     return;
   1759   }
   1760 
   1761   hb_font_funcs_set_nominal_glyph_func (ffuncs,
   1762 					hb_font_get_nominal_glyph_trampoline,
   1763 					trampoline,
   1764 					trampoline_destroy);
   1765 
   1766   trampoline_reference (&trampoline->closure);
   1767   hb_font_funcs_set_variation_glyph_func (ffuncs,
   1768 					  hb_font_get_variation_glyph_trampoline,
   1769 					  trampoline,
   1770 					  trampoline_destroy);
   1771 }
   1772 
   1773 #endif /* HB_DISABLE_DEPRECATED */
   1774