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