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.hh"
     30 
     31 #include "hb-font.hh"
     32 #include "hb-machinery.hh"
     33 
     34 #include "hb-ot.h"
     35 
     36 
     37 /**
     38  * SECTION:hb-font
     39  * @title: hb-font
     40  * @short_description: Font objects
     41  * @include: hb.h
     42  *
     43  * Font objects represent a font face at a certain size and other
     44  * parameters (pixels per EM, points per EM, variation settings.)
     45  * Fonts are created from font faces, and are used as input to
     46  * hb_shape() among other things.
     47  **/
     48 
     49 
     50 /*
     51  * hb_font_funcs_t
     52  */
     53 
     54 static hb_bool_t
     55 hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED,
     56 				void *font_data HB_UNUSED,
     57 				hb_font_extents_t *extents,
     58 				void *user_data HB_UNUSED)
     59 {
     60   memset (extents, 0, sizeof (*extents));
     61   return false;
     62 }
     63 static hb_bool_t
     64 hb_font_get_font_h_extents_default (hb_font_t *font,
     65 				    void *font_data HB_UNUSED,
     66 				    hb_font_extents_t *extents,
     67 				    void *user_data HB_UNUSED)
     68 {
     69   hb_bool_t ret = font->parent->get_font_h_extents (extents);
     70   if (ret) {
     71     extents->ascender = font->parent_scale_y_distance (extents->ascender);
     72     extents->descender = font->parent_scale_y_distance (extents->descender);
     73     extents->line_gap = font->parent_scale_y_distance (extents->line_gap);
     74   }
     75   return ret;
     76 }
     77 
     78 static hb_bool_t
     79 hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED,
     80 				void *font_data HB_UNUSED,
     81 				hb_font_extents_t *extents,
     82 				void *user_data HB_UNUSED)
     83 {
     84   memset (extents, 0, sizeof (*extents));
     85   return false;
     86 }
     87 static hb_bool_t
     88 hb_font_get_font_v_extents_default (hb_font_t *font,
     89 				    void *font_data HB_UNUSED,
     90 				    hb_font_extents_t *extents,
     91 				    void *user_data HB_UNUSED)
     92 {
     93   hb_bool_t ret = font->parent->get_font_v_extents (extents);
     94   if (ret) {
     95     extents->ascender = font->parent_scale_x_distance (extents->ascender);
     96     extents->descender = font->parent_scale_x_distance (extents->descender);
     97     extents->line_gap = font->parent_scale_x_distance (extents->line_gap);
     98   }
     99   return ret;
    100 }
    101 
    102 static hb_bool_t
    103 hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
    104 			       void *font_data HB_UNUSED,
    105 			       hb_codepoint_t unicode HB_UNUSED,
    106 			       hb_codepoint_t *glyph,
    107 			       void *user_data HB_UNUSED)
    108 {
    109   *glyph = 0;
    110   return false;
    111 }
    112 static hb_bool_t
    113 hb_font_get_nominal_glyph_default (hb_font_t *font,
    114 				   void *font_data HB_UNUSED,
    115 				   hb_codepoint_t unicode,
    116 				   hb_codepoint_t *glyph,
    117 				   void *user_data HB_UNUSED)
    118 {
    119   if (font->has_nominal_glyphs_func_set ())
    120   {
    121     return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0);
    122   }
    123   return font->parent->get_nominal_glyph (unicode, glyph);
    124 }
    125 
    126 #define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
    127 static unsigned int
    128 hb_font_get_nominal_glyphs_default (hb_font_t *font,
    129 				    void *font_data HB_UNUSED,
    130 				    unsigned int count,
    131 				    const hb_codepoint_t *first_unicode,
    132 				    unsigned int unicode_stride,
    133 				    hb_codepoint_t *first_glyph,
    134 				    unsigned int glyph_stride,
    135 				    void *user_data HB_UNUSED)
    136 {
    137   if (font->has_nominal_glyph_func_set ())
    138   {
    139     for (unsigned int i = 0; i < count; i++)
    140     {
    141       if (!font->get_nominal_glyph (*first_unicode, first_glyph))
    142         return i;
    143 
    144       first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride);
    145       first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
    146     }
    147     return count;
    148   }
    149 
    150   return font->parent->get_nominal_glyphs (count,
    151 					   first_unicode, unicode_stride,
    152 					   first_glyph, glyph_stride);
    153 }
    154 
    155 static hb_bool_t
    156 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
    157 				 void *font_data HB_UNUSED,
    158 				 hb_codepoint_t unicode HB_UNUSED,
    159 				 hb_codepoint_t variation_selector HB_UNUSED,
    160 				 hb_codepoint_t *glyph,
    161 				 void *user_data HB_UNUSED)
    162 {
    163   *glyph = 0;
    164   return false;
    165 }
    166 static hb_bool_t
    167 hb_font_get_variation_glyph_default (hb_font_t *font,
    168 				     void *font_data HB_UNUSED,
    169 				     hb_codepoint_t unicode,
    170 				     hb_codepoint_t variation_selector,
    171 				     hb_codepoint_t *glyph,
    172 				     void *user_data HB_UNUSED)
    173 {
    174   return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
    175 }
    176 
    177 
    178 static hb_position_t
    179 hb_font_get_glyph_h_advance_nil (hb_font_t *font,
    180 				 void *font_data HB_UNUSED,
    181 				 hb_codepoint_t glyph HB_UNUSED,
    182 				 void *user_data HB_UNUSED)
    183 {
    184   return font->x_scale;
    185 }
    186 static hb_position_t
    187 hb_font_get_glyph_h_advance_default (hb_font_t *font,
    188 				     void *font_data HB_UNUSED,
    189 				     hb_codepoint_t glyph,
    190 				     void *user_data HB_UNUSED)
    191 {
    192   if (font->has_glyph_h_advances_func_set ())
    193   {
    194     hb_position_t ret;
    195     font->get_glyph_h_advances (1, &glyph, 0, &ret, 0);
    196     return ret;
    197   }
    198   return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
    199 }
    200 
    201 static hb_position_t
    202 hb_font_get_glyph_v_advance_nil (hb_font_t *font,
    203 				 void *font_data HB_UNUSED,
    204 				 hb_codepoint_t glyph HB_UNUSED,
    205 				 void *user_data HB_UNUSED)
    206 {
    207   /* TODO use font_extents.ascender+descender */
    208   return font->y_scale;
    209 }
    210 static hb_position_t
    211 hb_font_get_glyph_v_advance_default (hb_font_t *font,
    212 				     void *font_data HB_UNUSED,
    213 				     hb_codepoint_t glyph,
    214 				     void *user_data HB_UNUSED)
    215 {
    216   if (font->has_glyph_v_advances_func_set ())
    217   {
    218     hb_position_t ret;
    219     font->get_glyph_v_advances (1, &glyph, 0, &ret, 0);
    220     return ret;
    221   }
    222   return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
    223 }
    224 
    225 #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default
    226 static void
    227 hb_font_get_glyph_h_advances_default (hb_font_t* font,
    228 				      void* font_data HB_UNUSED,
    229 				      unsigned int count,
    230 				      const hb_codepoint_t *first_glyph,
    231 				      unsigned int glyph_stride,
    232 				      hb_position_t *first_advance,
    233 				      unsigned int advance_stride,
    234 				      void *user_data HB_UNUSED)
    235 {
    236   if (font->has_glyph_h_advance_func_set ())
    237   {
    238     for (unsigned int i = 0; i < count; i++)
    239     {
    240       *first_advance = font->get_glyph_h_advance (*first_glyph);
    241       first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
    242       first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
    243     }
    244     return;
    245   }
    246 
    247   font->parent->get_glyph_h_advances (count,
    248 				      first_glyph, glyph_stride,
    249 				      first_advance, advance_stride);
    250   for (unsigned int i = 0; i < count; i++)
    251   {
    252     *first_advance = font->parent_scale_x_distance (*first_advance);
    253     first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
    254   }
    255 }
    256 
    257 #define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default
    258 static void
    259 hb_font_get_glyph_v_advances_default (hb_font_t* font,
    260 				      void* font_data HB_UNUSED,
    261 				      unsigned int count,
    262 				      const hb_codepoint_t *first_glyph,
    263 				      unsigned int glyph_stride,
    264 				      hb_position_t *first_advance,
    265 				      unsigned int advance_stride,
    266 				      void *user_data HB_UNUSED)
    267 {
    268   if (font->has_glyph_v_advance_func_set ())
    269   {
    270     for (unsigned int i = 0; i < count; i++)
    271     {
    272       *first_advance = font->get_glyph_v_advance (*first_glyph);
    273       first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
    274       first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
    275     }
    276     return;
    277   }
    278 
    279   font->parent->get_glyph_v_advances (count,
    280 				      first_glyph, glyph_stride,
    281 				      first_advance, advance_stride);
    282   for (unsigned int i = 0; i < count; i++)
    283   {
    284     *first_advance = font->parent_scale_y_distance (*first_advance);
    285     first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
    286   }
    287 }
    288 
    289 static hb_bool_t
    290 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
    291 				void *font_data HB_UNUSED,
    292 				hb_codepoint_t glyph HB_UNUSED,
    293 				hb_position_t *x,
    294 				hb_position_t *y,
    295 				void *user_data HB_UNUSED)
    296 {
    297   *x = *y = 0;
    298   return true;
    299 }
    300 static hb_bool_t
    301 hb_font_get_glyph_h_origin_default (hb_font_t *font,
    302 				    void *font_data HB_UNUSED,
    303 				    hb_codepoint_t glyph,
    304 				    hb_position_t *x,
    305 				    hb_position_t *y,
    306 				    void *user_data HB_UNUSED)
    307 {
    308   hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
    309   if (ret)
    310     font->parent_scale_position (x, y);
    311   return ret;
    312 }
    313 
    314 static hb_bool_t
    315 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
    316 				void *font_data HB_UNUSED,
    317 				hb_codepoint_t glyph HB_UNUSED,
    318 				hb_position_t *x,
    319 				hb_position_t *y,
    320 				void *user_data HB_UNUSED)
    321 {
    322   *x = *y = 0;
    323   return false;
    324 }
    325 static hb_bool_t
    326 hb_font_get_glyph_v_origin_default (hb_font_t *font,
    327 				    void *font_data HB_UNUSED,
    328 				    hb_codepoint_t glyph,
    329 				    hb_position_t *x,
    330 				    hb_position_t *y,
    331 				    void *user_data HB_UNUSED)
    332 {
    333   hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
    334   if (ret)
    335     font->parent_scale_position (x, y);
    336   return ret;
    337 }
    338 
    339 static hb_position_t
    340 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
    341 				 void *font_data HB_UNUSED,
    342 				 hb_codepoint_t left_glyph HB_UNUSED,
    343 				 hb_codepoint_t right_glyph HB_UNUSED,
    344 				 void *user_data HB_UNUSED)
    345 {
    346   return 0;
    347 }
    348 static hb_position_t
    349 hb_font_get_glyph_h_kerning_default (hb_font_t *font,
    350 				     void *font_data HB_UNUSED,
    351 				     hb_codepoint_t left_glyph,
    352 				     hb_codepoint_t right_glyph,
    353 				     void *user_data HB_UNUSED)
    354 {
    355   return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
    356 }
    357 
    358 static hb_position_t
    359 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
    360 				 void *font_data HB_UNUSED,
    361 				 hb_codepoint_t top_glyph HB_UNUSED,
    362 				 hb_codepoint_t bottom_glyph HB_UNUSED,
    363 				 void *user_data HB_UNUSED)
    364 {
    365   return 0;
    366 }
    367 static hb_position_t
    368 hb_font_get_glyph_v_kerning_default (hb_font_t *font,
    369 				     void *font_data HB_UNUSED,
    370 				     hb_codepoint_t top_glyph,
    371 				     hb_codepoint_t bottom_glyph,
    372 				     void *user_data HB_UNUSED)
    373 {
    374   return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
    375 }
    376 
    377 static hb_bool_t
    378 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
    379 			       void *font_data HB_UNUSED,
    380 			       hb_codepoint_t glyph HB_UNUSED,
    381 			       hb_glyph_extents_t *extents,
    382 			       void *user_data HB_UNUSED)
    383 {
    384   memset (extents, 0, sizeof (*extents));
    385   return false;
    386 }
    387 static hb_bool_t
    388 hb_font_get_glyph_extents_default (hb_font_t *font,
    389 				   void *font_data HB_UNUSED,
    390 				   hb_codepoint_t glyph,
    391 				   hb_glyph_extents_t *extents,
    392 				   void *user_data HB_UNUSED)
    393 {
    394   hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
    395   if (ret) {
    396     font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
    397     font->parent_scale_distance (&extents->width, &extents->height);
    398   }
    399   return ret;
    400 }
    401 
    402 static hb_bool_t
    403 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
    404 				     void *font_data HB_UNUSED,
    405 				     hb_codepoint_t glyph HB_UNUSED,
    406 				     unsigned int point_index HB_UNUSED,
    407 				     hb_position_t *x,
    408 				     hb_position_t *y,
    409 				     void *user_data HB_UNUSED)
    410 {
    411   *x = *y = 0;
    412   return false;
    413 }
    414 static hb_bool_t
    415 hb_font_get_glyph_contour_point_default (hb_font_t *font,
    416 					 void *font_data HB_UNUSED,
    417 					 hb_codepoint_t glyph,
    418 					 unsigned int point_index,
    419 					 hb_position_t *x,
    420 					 hb_position_t *y,
    421 					 void *user_data HB_UNUSED)
    422 {
    423   hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
    424   if (ret)
    425     font->parent_scale_position (x, y);
    426   return ret;
    427 }
    428 
    429 static hb_bool_t
    430 hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
    431 			    void *font_data HB_UNUSED,
    432 			    hb_codepoint_t glyph HB_UNUSED,
    433 			    char *name, unsigned int size,
    434 			    void *user_data HB_UNUSED)
    435 {
    436   if (size) *name = '\0';
    437   return false;
    438 }
    439 static hb_bool_t
    440 hb_font_get_glyph_name_default (hb_font_t *font,
    441 				void *font_data HB_UNUSED,
    442 				hb_codepoint_t glyph,
    443 				char *name, unsigned int size,
    444 				void *user_data HB_UNUSED)
    445 {
    446   return font->parent->get_glyph_name (glyph, name, size);
    447 }
    448 
    449 static hb_bool_t
    450 hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
    451 				 void *font_data HB_UNUSED,
    452 				 const char *name HB_UNUSED,
    453 				 int len HB_UNUSED, /* -1 means nul-terminated */
    454 				 hb_codepoint_t *glyph,
    455 				 void *user_data HB_UNUSED)
    456 {
    457   *glyph = 0;
    458   return false;
    459 }
    460 static hb_bool_t
    461 hb_font_get_glyph_from_name_default (hb_font_t *font,
    462 				     void *font_data HB_UNUSED,
    463 				     const char *name, int len, /* -1 means nul-terminated */
    464 				     hb_codepoint_t *glyph,
    465 				     void *user_data HB_UNUSED)
    466 {
    467   return font->parent->get_glyph_from_name (name, len, glyph);
    468 }
    469 
    470 DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
    471 {
    472   HB_OBJECT_HEADER_STATIC,
    473 
    474   {
    475 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
    476     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    477 #undef HB_FONT_FUNC_IMPLEMENT
    478   },
    479   {
    480 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
    481     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    482 #undef HB_FONT_FUNC_IMPLEMENT
    483   },
    484   {
    485     {
    486 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
    487       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    488 #undef HB_FONT_FUNC_IMPLEMENT
    489     }
    490   }
    491 };
    492 
    493 static const hb_font_funcs_t _hb_font_funcs_default = {
    494   HB_OBJECT_HEADER_STATIC,
    495 
    496   {
    497 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
    498     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    499 #undef HB_FONT_FUNC_IMPLEMENT
    500   },
    501   {
    502 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
    503     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    504 #undef HB_FONT_FUNC_IMPLEMENT
    505   },
    506   {
    507     {
    508 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default,
    509       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    510 #undef HB_FONT_FUNC_IMPLEMENT
    511     }
    512   }
    513 };
    514 
    515 
    516 /**
    517  * hb_font_funcs_create: (Xconstructor)
    518  *
    519  *
    520  *
    521  * Return value: (transfer full):
    522  *
    523  * Since: 0.9.2
    524  **/
    525 hb_font_funcs_t *
    526 hb_font_funcs_create ()
    527 {
    528   hb_font_funcs_t *ffuncs;
    529 
    530   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
    531     return hb_font_funcs_get_empty ();
    532 
    533   ffuncs->get = _hb_font_funcs_default.get;
    534 
    535   return ffuncs;
    536 }
    537 
    538 /**
    539  * hb_font_funcs_get_empty:
    540  *
    541  *
    542  *
    543  * Return value: (transfer full):
    544  *
    545  * Since: 0.9.2
    546  **/
    547 hb_font_funcs_t *
    548 hb_font_funcs_get_empty ()
    549 {
    550   return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default);
    551 }
    552 
    553 /**
    554  * hb_font_funcs_reference: (skip)
    555  * @ffuncs: font functions.
    556  *
    557  *
    558  *
    559  * Return value:
    560  *
    561  * Since: 0.9.2
    562  **/
    563 hb_font_funcs_t *
    564 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
    565 {
    566   return hb_object_reference (ffuncs);
    567 }
    568 
    569 /**
    570  * hb_font_funcs_destroy: (skip)
    571  * @ffuncs: font functions.
    572  *
    573  *
    574  *
    575  * Since: 0.9.2
    576  **/
    577 void
    578 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
    579 {
    580   if (!hb_object_destroy (ffuncs)) return;
    581 
    582 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
    583   ffuncs->destroy.name (ffuncs->user_data.name);
    584   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    585 #undef HB_FONT_FUNC_IMPLEMENT
    586 
    587   free (ffuncs);
    588 }
    589 
    590 /**
    591  * hb_font_funcs_set_user_data: (skip)
    592  * @ffuncs: font functions.
    593  * @key:
    594  * @data:
    595  * @destroy:
    596  * @replace:
    597  *
    598  *
    599  *
    600  * Return value:
    601  *
    602  * Since: 0.9.2
    603  **/
    604 hb_bool_t
    605 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
    606 			     hb_user_data_key_t *key,
    607 			     void *              data,
    608 			     hb_destroy_func_t   destroy,
    609 			     hb_bool_t           replace)
    610 {
    611   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
    612 }
    613 
    614 /**
    615  * hb_font_funcs_get_user_data: (skip)
    616  * @ffuncs: font functions.
    617  * @key:
    618  *
    619  *
    620  *
    621  * Return value: (transfer none):
    622  *
    623  * Since: 0.9.2
    624  **/
    625 void *
    626 hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
    627 			     hb_user_data_key_t *key)
    628 {
    629   return hb_object_get_user_data (ffuncs, key);
    630 }
    631 
    632 
    633 /**
    634  * hb_font_funcs_make_immutable:
    635  * @ffuncs: font functions.
    636  *
    637  *
    638  *
    639  * Since: 0.9.2
    640  **/
    641 void
    642 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
    643 {
    644   if (hb_object_is_immutable (ffuncs))
    645     return;
    646 
    647   hb_object_make_immutable (ffuncs);
    648 }
    649 
    650 /**
    651  * hb_font_funcs_is_immutable:
    652  * @ffuncs: font functions.
    653  *
    654  *
    655  *
    656  * Return value:
    657  *
    658  * Since: 0.9.2
    659  **/
    660 hb_bool_t
    661 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
    662 {
    663   return hb_object_is_immutable (ffuncs);
    664 }
    665 
    666 
    667 #define HB_FONT_FUNC_IMPLEMENT(name) \
    668                                                                          \
    669 void                                                                     \
    670 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
    671                                  hb_font_get_##name##_func_t  func,      \
    672                                  void                        *user_data, \
    673                                  hb_destroy_func_t            destroy)   \
    674 {                                                                        \
    675   if (hb_object_is_immutable (ffuncs)) {                                 \
    676     if (destroy)                                                         \
    677       destroy (user_data);                                               \
    678     return;                                                              \
    679   }                                                                      \
    680                                                                          \
    681   if (ffuncs->destroy.name)                                              \
    682     ffuncs->destroy.name (ffuncs->user_data.name);                       \
    683                                                                          \
    684   if (func) {                                                            \
    685     ffuncs->get.f.name = func;                                           \
    686     ffuncs->user_data.name = user_data;                                  \
    687     ffuncs->destroy.name = destroy;                                      \
    688   } else {                                                               \
    689     ffuncs->get.f.name = hb_font_get_##name##_default;                   \
    690     ffuncs->user_data.name = nullptr;                                    \
    691     ffuncs->destroy.name = nullptr;                                      \
    692   }                                                                      \
    693 }
    694 
    695 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    696 #undef HB_FONT_FUNC_IMPLEMENT
    697 
    698 bool
    699 hb_font_t::has_func_set (unsigned int i)
    700 {
    701   return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i];
    702 }
    703 
    704 bool
    705 hb_font_t::has_func (unsigned int i)
    706 {
    707   return has_func_set (i) ||
    708 	 (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i));
    709 }
    710 
    711 /* Public getters */
    712 
    713 /**
    714  * hb_font_get_h_extents:
    715  * @font: a font.
    716  * @extents: (out):
    717  *
    718  *
    719  *
    720  * Return value:
    721  *
    722  * Since: 1.1.3
    723  **/
    724 hb_bool_t
    725 hb_font_get_h_extents (hb_font_t *font,
    726 		       hb_font_extents_t *extents)
    727 {
    728   return font->get_font_h_extents (extents);
    729 }
    730 
    731 /**
    732  * hb_font_get_v_extents:
    733  * @font: a font.
    734  * @extents: (out):
    735  *
    736  *
    737  *
    738  * Return value:
    739  *
    740  * Since: 1.1.3
    741  **/
    742 hb_bool_t
    743 hb_font_get_v_extents (hb_font_t *font,
    744 		       hb_font_extents_t *extents)
    745 {
    746   return font->get_font_v_extents (extents);
    747 }
    748 
    749 /**
    750  * hb_font_get_glyph:
    751  * @font: a font.
    752  * @unicode:
    753  * @variation_selector:
    754  * @glyph: (out):
    755  *
    756  *
    757  *
    758  * Return value:
    759  *
    760  * Since: 0.9.2
    761  **/
    762 hb_bool_t
    763 hb_font_get_glyph (hb_font_t *font,
    764 		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
    765 		   hb_codepoint_t *glyph)
    766 {
    767   if (unlikely (variation_selector))
    768     return font->get_variation_glyph (unicode, variation_selector, glyph);
    769   return font->get_nominal_glyph (unicode, glyph);
    770 }
    771 
    772 /**
    773  * hb_font_get_nominal_glyph:
    774  * @font: a font.
    775  * @unicode:
    776  * @glyph: (out):
    777  *
    778  *
    779  *
    780  * Return value:
    781  *
    782  * Since: 1.2.3
    783  **/
    784 hb_bool_t
    785 hb_font_get_nominal_glyph (hb_font_t *font,
    786 			   hb_codepoint_t unicode,
    787 			   hb_codepoint_t *glyph)
    788 {
    789   return font->get_nominal_glyph (unicode, glyph);
    790 }
    791 
    792 /**
    793  * hb_font_get_variation_glyph:
    794  * @font: a font.
    795  * @unicode:
    796  * @variation_selector:
    797  * @glyph: (out):
    798  *
    799  *
    800  *
    801  * Return value:
    802  *
    803  * Since: 1.2.3
    804  **/
    805 hb_bool_t
    806 hb_font_get_variation_glyph (hb_font_t *font,
    807 			     hb_codepoint_t unicode, hb_codepoint_t variation_selector,
    808 			     hb_codepoint_t *glyph)
    809 {
    810   return font->get_variation_glyph (unicode, variation_selector, glyph);
    811 }
    812 
    813 /**
    814  * hb_font_get_glyph_h_advance:
    815  * @font: a font.
    816  * @glyph:
    817  *
    818  *
    819  *
    820  * Return value:
    821  *
    822  * Since: 0.9.2
    823  **/
    824 hb_position_t
    825 hb_font_get_glyph_h_advance (hb_font_t *font,
    826 			     hb_codepoint_t glyph)
    827 {
    828   return font->get_glyph_h_advance (glyph);
    829 }
    830 
    831 /**
    832  * hb_font_get_glyph_v_advance:
    833  * @font: a font.
    834  * @glyph:
    835  *
    836  *
    837  *
    838  * Return value:
    839  *
    840  * Since: 0.9.2
    841  **/
    842 hb_position_t
    843 hb_font_get_glyph_v_advance (hb_font_t *font,
    844 			     hb_codepoint_t glyph)
    845 {
    846   return font->get_glyph_v_advance (glyph);
    847 }
    848 
    849 /**
    850  * hb_font_get_glyph_h_advances:
    851  * @font: a font.
    852  *
    853  *
    854  *
    855  * Since: 1.8.6
    856  **/
    857 void
    858 hb_font_get_glyph_h_advances (hb_font_t* font,
    859 			      unsigned int count,
    860 			      const hb_codepoint_t *first_glyph,
    861 			      unsigned glyph_stride,
    862 			      hb_position_t *first_advance,
    863 			      unsigned advance_stride)
    864 {
    865   font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
    866 }
    867 /**
    868  * hb_font_get_glyph_v_advances:
    869  * @font: a font.
    870  *
    871  *
    872  *
    873  * Since: 1.8.6
    874  **/
    875 void
    876 hb_font_get_glyph_v_advances (hb_font_t* font,
    877 			      unsigned int count,
    878 			      const hb_codepoint_t *first_glyph,
    879 			      unsigned glyph_stride,
    880 			      hb_position_t *first_advance,
    881 			      unsigned advance_stride)
    882 {
    883   font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
    884 }
    885 
    886 /**
    887  * hb_font_get_glyph_h_origin:
    888  * @font: a font.
    889  * @glyph:
    890  * @x: (out):
    891  * @y: (out):
    892  *
    893  *
    894  *
    895  * Return value:
    896  *
    897  * Since: 0.9.2
    898  **/
    899 hb_bool_t
    900 hb_font_get_glyph_h_origin (hb_font_t *font,
    901 			    hb_codepoint_t glyph,
    902 			    hb_position_t *x, hb_position_t *y)
    903 {
    904   return font->get_glyph_h_origin (glyph, x, y);
    905 }
    906 
    907 /**
    908  * hb_font_get_glyph_v_origin:
    909  * @font: a font.
    910  * @glyph:
    911  * @x: (out):
    912  * @y: (out):
    913  *
    914  *
    915  *
    916  * Return value:
    917  *
    918  * Since: 0.9.2
    919  **/
    920 hb_bool_t
    921 hb_font_get_glyph_v_origin (hb_font_t *font,
    922 			    hb_codepoint_t glyph,
    923 			    hb_position_t *x, hb_position_t *y)
    924 {
    925   return font->get_glyph_v_origin (glyph, x, y);
    926 }
    927 
    928 /**
    929  * hb_font_get_glyph_h_kerning:
    930  * @font: a font.
    931  * @left_glyph:
    932  * @right_glyph:
    933  *
    934  *
    935  *
    936  * Return value:
    937  *
    938  * Since: 0.9.2
    939  * Deprecated: 2.0.0
    940  **/
    941 hb_position_t
    942 hb_font_get_glyph_h_kerning (hb_font_t *font,
    943 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
    944 {
    945   return font->get_glyph_h_kerning (left_glyph, right_glyph);
    946 }
    947 
    948 /**
    949  * hb_font_get_glyph_v_kerning:
    950  * @font: a font.
    951  * @top_glyph:
    952  * @bottom_glyph:
    953  *
    954  *
    955  *
    956  * Return value:
    957  *
    958  * Since: 0.9.2
    959  * Deprecated: 2.0.0
    960  **/
    961 hb_position_t
    962 hb_font_get_glyph_v_kerning (hb_font_t *font,
    963 			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
    964 {
    965   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
    966 }
    967 
    968 /**
    969  * hb_font_get_glyph_extents:
    970  * @font: a font.
    971  * @glyph:
    972  * @extents: (out):
    973  *
    974  *
    975  *
    976  * Return value:
    977  *
    978  * Since: 0.9.2
    979  **/
    980 hb_bool_t
    981 hb_font_get_glyph_extents (hb_font_t *font,
    982 			   hb_codepoint_t glyph,
    983 			   hb_glyph_extents_t *extents)
    984 {
    985   return font->get_glyph_extents (glyph, extents);
    986 }
    987 
    988 /**
    989  * hb_font_get_glyph_contour_point:
    990  * @font: a font.
    991  * @glyph:
    992  * @point_index:
    993  * @x: (out):
    994  * @y: (out):
    995  *
    996  *
    997  *
    998  * Return value:
    999  *
   1000  * Since: 0.9.2
   1001  **/
   1002 hb_bool_t
   1003 hb_font_get_glyph_contour_point (hb_font_t *font,
   1004 				 hb_codepoint_t glyph, unsigned int point_index,
   1005 				 hb_position_t *x, hb_position_t *y)
   1006 {
   1007   return font->get_glyph_contour_point (glyph, point_index, x, y);
   1008 }
   1009 
   1010 /**
   1011  * hb_font_get_glyph_name:
   1012  * @font: a font.
   1013  * @glyph:
   1014  * @name: (array length=size):
   1015  * @size:
   1016  *
   1017  *
   1018  *
   1019  * Return value:
   1020  *
   1021  * Since: 0.9.2
   1022  **/
   1023 hb_bool_t
   1024 hb_font_get_glyph_name (hb_font_t *font,
   1025 			hb_codepoint_t glyph,
   1026 			char *name, unsigned int size)
   1027 {
   1028   return font->get_glyph_name (glyph, name, size);
   1029 }
   1030 
   1031 /**
   1032  * hb_font_get_glyph_from_name:
   1033  * @font: a font.
   1034  * @name: (array length=len):
   1035  * @len:
   1036  * @glyph: (out):
   1037  *
   1038  *
   1039  *
   1040  * Return value:
   1041  *
   1042  * Since: 0.9.2
   1043  **/
   1044 hb_bool_t
   1045 hb_font_get_glyph_from_name (hb_font_t *font,
   1046 			     const char *name, int len, /* -1 means nul-terminated */
   1047 			     hb_codepoint_t *glyph)
   1048 {
   1049   return font->get_glyph_from_name (name, len, glyph);
   1050 }
   1051 
   1052 
   1053 /* A bit higher-level, and with fallback */
   1054 
   1055 /**
   1056  * hb_font_get_extents_for_direction:
   1057  * @font: a font.
   1058  * @direction:
   1059  * @extents: (out):
   1060  *
   1061  *
   1062  *
   1063  * Since: 1.1.3
   1064  **/
   1065 void
   1066 hb_font_get_extents_for_direction (hb_font_t *font,
   1067 				   hb_direction_t direction,
   1068 				   hb_font_extents_t *extents)
   1069 {
   1070   return font->get_extents_for_direction (direction, extents);
   1071 }
   1072 /**
   1073  * hb_font_get_glyph_advance_for_direction:
   1074  * @font: a font.
   1075  * @glyph:
   1076  * @direction:
   1077  * @x: (out):
   1078  * @y: (out):
   1079  *
   1080  *
   1081  *
   1082  * Since: 0.9.2
   1083  **/
   1084 void
   1085 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
   1086 					 hb_codepoint_t glyph,
   1087 					 hb_direction_t direction,
   1088 					 hb_position_t *x, hb_position_t *y)
   1089 {
   1090   return font->get_glyph_advance_for_direction (glyph, direction, x, y);
   1091 }
   1092 /**
   1093  * hb_font_get_glyph_advances_for_direction:
   1094  * @font: a font.
   1095  * @direction:
   1096  *
   1097  *
   1098  *
   1099  * Since: 1.8.6
   1100  **/
   1101 HB_EXTERN void
   1102 hb_font_get_glyph_advances_for_direction (hb_font_t* font,
   1103 					  hb_direction_t direction,
   1104 					  unsigned int count,
   1105 					  const hb_codepoint_t *first_glyph,
   1106 					  unsigned glyph_stride,
   1107 					  hb_position_t *first_advance,
   1108 					  unsigned advance_stride)
   1109 {
   1110   font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride);
   1111 }
   1112 
   1113 /**
   1114  * hb_font_get_glyph_origin_for_direction:
   1115  * @font: a font.
   1116  * @glyph:
   1117  * @direction:
   1118  * @x: (out):
   1119  * @y: (out):
   1120  *
   1121  *
   1122  *
   1123  * Since: 0.9.2
   1124  **/
   1125 void
   1126 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
   1127 					hb_codepoint_t glyph,
   1128 					hb_direction_t direction,
   1129 					hb_position_t *x, hb_position_t *y)
   1130 {
   1131   return font->get_glyph_origin_for_direction (glyph, direction, x, y);
   1132 }
   1133 
   1134 /**
   1135  * hb_font_add_glyph_origin_for_direction:
   1136  * @font: a font.
   1137  * @glyph:
   1138  * @direction:
   1139  * @x: (out):
   1140  * @y: (out):
   1141  *
   1142  *
   1143  *
   1144  * Since: 0.9.2
   1145  **/
   1146 void
   1147 hb_font_add_glyph_origin_for_direction (hb_font_t *font,
   1148 					hb_codepoint_t glyph,
   1149 					hb_direction_t direction,
   1150 					hb_position_t *x, hb_position_t *y)
   1151 {
   1152   return font->add_glyph_origin_for_direction (glyph, direction, x, y);
   1153 }
   1154 
   1155 /**
   1156  * hb_font_subtract_glyph_origin_for_direction:
   1157  * @font: a font.
   1158  * @glyph:
   1159  * @direction:
   1160  * @x: (out):
   1161  * @y: (out):
   1162  *
   1163  *
   1164  *
   1165  * Since: 0.9.2
   1166  **/
   1167 void
   1168 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
   1169 					     hb_codepoint_t glyph,
   1170 					     hb_direction_t direction,
   1171 					     hb_position_t *x, hb_position_t *y)
   1172 {
   1173   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
   1174 }
   1175 
   1176 /**
   1177  * hb_font_get_glyph_kerning_for_direction:
   1178  * @font: a font.
   1179  * @first_glyph:
   1180  * @second_glyph:
   1181  * @direction:
   1182  * @x: (out):
   1183  * @y: (out):
   1184  *
   1185  *
   1186  *
   1187  * Since: 0.9.2
   1188  * Deprecated: 2.0.0
   1189  **/
   1190 void
   1191 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
   1192 					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
   1193 					 hb_direction_t direction,
   1194 					 hb_position_t *x, hb_position_t *y)
   1195 {
   1196   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
   1197 }
   1198 
   1199 /**
   1200  * hb_font_get_glyph_extents_for_origin:
   1201  * @font: a font.
   1202  * @glyph:
   1203  * @direction:
   1204  * @extents: (out):
   1205  *
   1206  *
   1207  *
   1208  * Return value:
   1209  *
   1210  * Since: 0.9.2
   1211  **/
   1212 hb_bool_t
   1213 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
   1214 				      hb_codepoint_t glyph,
   1215 				      hb_direction_t direction,
   1216 				      hb_glyph_extents_t *extents)
   1217 {
   1218   return font->get_glyph_extents_for_origin (glyph, direction, extents);
   1219 }
   1220 
   1221 /**
   1222  * hb_font_get_glyph_contour_point_for_origin:
   1223  * @font: a font.
   1224  * @glyph:
   1225  * @point_index:
   1226  * @direction:
   1227  * @x: (out):
   1228  * @y: (out):
   1229  *
   1230  *
   1231  *
   1232  * Return value:
   1233  *
   1234  * Since: 0.9.2
   1235  **/
   1236 hb_bool_t
   1237 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
   1238 					    hb_codepoint_t glyph, unsigned int point_index,
   1239 					    hb_direction_t direction,
   1240 					    hb_position_t *x, hb_position_t *y)
   1241 {
   1242   return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
   1243 }
   1244 
   1245 /* Generates gidDDD if glyph has no name. */
   1246 /**
   1247  * hb_font_glyph_to_string:
   1248  * @font: a font.
   1249  * @glyph:
   1250  * @s: (array length=size):
   1251  * @size:
   1252  *
   1253  *
   1254  *
   1255  * Since: 0.9.2
   1256  **/
   1257 void
   1258 hb_font_glyph_to_string (hb_font_t *font,
   1259 			 hb_codepoint_t glyph,
   1260 			 char *s, unsigned int size)
   1261 {
   1262   font->glyph_to_string (glyph, s, size);
   1263 }
   1264 
   1265 /* Parses gidDDD and uniUUUU strings automatically. */
   1266 /**
   1267  * hb_font_glyph_from_string:
   1268  * @font: a font.
   1269  * @s: (array length=len) (element-type uint8_t):
   1270  * @len:
   1271  * @glyph: (out):
   1272  *
   1273  *
   1274  *
   1275  * Return value:
   1276  *
   1277  * Since: 0.9.2
   1278  **/
   1279 hb_bool_t
   1280 hb_font_glyph_from_string (hb_font_t *font,
   1281 			   const char *s, int len, /* -1 means nul-terminated */
   1282 			   hb_codepoint_t *glyph)
   1283 {
   1284   return font->glyph_from_string (s, len, glyph);
   1285 }
   1286 
   1287 
   1288 /*
   1289  * hb_font_t
   1290  */
   1291 
   1292 DEFINE_NULL_INSTANCE (hb_font_t) =
   1293 {
   1294   HB_OBJECT_HEADER_STATIC,
   1295 
   1296   nullptr, /* parent */
   1297   const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
   1298 
   1299   1000, /* x_scale */
   1300   1000, /* y_scale */
   1301 
   1302   0, /* x_ppem */
   1303   0, /* y_ppem */
   1304   0, /* ptem */
   1305 
   1306   0, /* num_coords */
   1307   nullptr, /* coords */
   1308 
   1309   const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
   1310 
   1311   /* Zero for the rest is fine. */
   1312 };
   1313 
   1314 
   1315 static hb_font_t *
   1316 _hb_font_create (hb_face_t *face)
   1317 {
   1318   hb_font_t *font;
   1319 
   1320   if (unlikely (!face))
   1321     face = hb_face_get_empty ();
   1322   if (!(font = hb_object_create<hb_font_t> ()))
   1323     return hb_font_get_empty ();
   1324 
   1325   hb_face_make_immutable (face);
   1326   font->parent = hb_font_get_empty ();
   1327   font->face = hb_face_reference (face);
   1328   font->klass = hb_font_funcs_get_empty ();
   1329   font->data.init0 (font);
   1330   font->x_scale = font->y_scale = hb_face_get_upem (face);
   1331 
   1332   return font;
   1333 }
   1334 
   1335 /**
   1336  * hb_font_create: (Xconstructor)
   1337  * @face: a face.
   1338  *
   1339  *
   1340  *
   1341  * Return value: (transfer full):
   1342  *
   1343  * Since: 0.9.2
   1344  **/
   1345 hb_font_t *
   1346 hb_font_create (hb_face_t *face)
   1347 {
   1348   hb_font_t *font = _hb_font_create (face);
   1349 
   1350   /* Install our in-house, very lightweight, funcs. */
   1351   hb_ot_font_set_funcs (font);
   1352 
   1353   return font;
   1354 }
   1355 
   1356 /**
   1357  * hb_font_create_sub_font:
   1358  * @parent: parent font.
   1359  *
   1360  *
   1361  *
   1362  * Return value: (transfer full):
   1363  *
   1364  * Since: 0.9.2
   1365  **/
   1366 hb_font_t *
   1367 hb_font_create_sub_font (hb_font_t *parent)
   1368 {
   1369   if (unlikely (!parent))
   1370     parent = hb_font_get_empty ();
   1371 
   1372   hb_font_t *font = _hb_font_create (parent->face);
   1373 
   1374   if (unlikely (hb_object_is_immutable (font)))
   1375     return font;
   1376 
   1377   font->parent = hb_font_reference (parent);
   1378 
   1379   font->x_scale = parent->x_scale;
   1380   font->y_scale = parent->y_scale;
   1381   font->x_ppem = parent->x_ppem;
   1382   font->y_ppem = parent->y_ppem;
   1383   font->ptem = parent->ptem;
   1384 
   1385   font->num_coords = parent->num_coords;
   1386   if (!font->num_coords)
   1387     font->coords = nullptr;
   1388   else
   1389   {
   1390     unsigned int size = parent->num_coords * sizeof (parent->coords[0]);
   1391     font->coords = (int *) malloc (size);
   1392     if (unlikely (!font->coords))
   1393       font->num_coords = 0;
   1394     else
   1395       memcpy (font->coords, parent->coords, size);
   1396   }
   1397 
   1398   return font;
   1399 }
   1400 
   1401 /**
   1402  * hb_font_get_empty:
   1403  *
   1404  *
   1405  *
   1406  * Return value: (transfer full)
   1407  *
   1408  * Since: 0.9.2
   1409  **/
   1410 hb_font_t *
   1411 hb_font_get_empty ()
   1412 {
   1413   return const_cast<hb_font_t *> (&Null(hb_font_t));
   1414 }
   1415 
   1416 /**
   1417  * hb_font_reference: (skip)
   1418  * @font: a font.
   1419  *
   1420  *
   1421  *
   1422  * Return value: (transfer full):
   1423  *
   1424  * Since: 0.9.2
   1425  **/
   1426 hb_font_t *
   1427 hb_font_reference (hb_font_t *font)
   1428 {
   1429   return hb_object_reference (font);
   1430 }
   1431 
   1432 /**
   1433  * hb_font_destroy: (skip)
   1434  * @font: a font.
   1435  *
   1436  *
   1437  *
   1438  * Since: 0.9.2
   1439  **/
   1440 void
   1441 hb_font_destroy (hb_font_t *font)
   1442 {
   1443   if (!hb_object_destroy (font)) return;
   1444 
   1445   font->data.fini ();
   1446 
   1447   if (font->destroy)
   1448     font->destroy (font->user_data);
   1449 
   1450   hb_font_destroy (font->parent);
   1451   hb_face_destroy (font->face);
   1452   hb_font_funcs_destroy (font->klass);
   1453 
   1454   free (font->coords);
   1455 
   1456   free (font);
   1457 }
   1458 
   1459 /**
   1460  * hb_font_set_user_data: (skip)
   1461  * @font: a font.
   1462  * @key:
   1463  * @data:
   1464  * @destroy:
   1465  * @replace:
   1466  *
   1467  *
   1468  *
   1469  * Return value:
   1470  *
   1471  * Since: 0.9.2
   1472  **/
   1473 hb_bool_t
   1474 hb_font_set_user_data (hb_font_t          *font,
   1475 		       hb_user_data_key_t *key,
   1476 		       void *              data,
   1477 		       hb_destroy_func_t   destroy,
   1478 		       hb_bool_t           replace)
   1479 {
   1480   return hb_object_set_user_data (font, key, data, destroy, replace);
   1481 }
   1482 
   1483 /**
   1484  * hb_font_get_user_data: (skip)
   1485  * @font: a font.
   1486  * @key:
   1487  *
   1488  *
   1489  *
   1490  * Return value: (transfer none):
   1491  *
   1492  * Since: 0.9.2
   1493  **/
   1494 void *
   1495 hb_font_get_user_data (hb_font_t          *font,
   1496 		       hb_user_data_key_t *key)
   1497 {
   1498   return hb_object_get_user_data (font, key);
   1499 }
   1500 
   1501 /**
   1502  * hb_font_make_immutable:
   1503  * @font: a font.
   1504  *
   1505  *
   1506  *
   1507  * Since: 0.9.2
   1508  **/
   1509 void
   1510 hb_font_make_immutable (hb_font_t *font)
   1511 {
   1512   if (hb_object_is_immutable (font))
   1513     return;
   1514 
   1515   if (font->parent)
   1516     hb_font_make_immutable (font->parent);
   1517 
   1518   hb_object_make_immutable (font);
   1519 }
   1520 
   1521 /**
   1522  * hb_font_is_immutable:
   1523  * @font: a font.
   1524  *
   1525  *
   1526  *
   1527  * Return value:
   1528  *
   1529  * Since: 0.9.2
   1530  **/
   1531 hb_bool_t
   1532 hb_font_is_immutable (hb_font_t *font)
   1533 {
   1534   return hb_object_is_immutable (font);
   1535 }
   1536 
   1537 /**
   1538  * hb_font_set_parent:
   1539  * @font: a font.
   1540  * @parent: new parent.
   1541  *
   1542  * Sets parent font of @font.
   1543  *
   1544  * Since: 1.0.5
   1545  **/
   1546 void
   1547 hb_font_set_parent (hb_font_t *font,
   1548 		    hb_font_t *parent)
   1549 {
   1550   if (hb_object_is_immutable (font))
   1551     return;
   1552 
   1553   if (!parent)
   1554     parent = hb_font_get_empty ();
   1555 
   1556   hb_font_t *old = font->parent;
   1557 
   1558   font->parent = hb_font_reference (parent);
   1559 
   1560   hb_font_destroy (old);
   1561 }
   1562 
   1563 /**
   1564  * hb_font_get_parent:
   1565  * @font: a font.
   1566  *
   1567  *
   1568  *
   1569  * Return value: (transfer none):
   1570  *
   1571  * Since: 0.9.2
   1572  **/
   1573 hb_font_t *
   1574 hb_font_get_parent (hb_font_t *font)
   1575 {
   1576   return font->parent;
   1577 }
   1578 
   1579 /**
   1580  * hb_font_set_face:
   1581  * @font: a font.
   1582  * @face: new face.
   1583  *
   1584  * Sets font-face of @font.
   1585  *
   1586  * Since: 1.4.3
   1587  **/
   1588 void
   1589 hb_font_set_face (hb_font_t *font,
   1590 		  hb_face_t *face)
   1591 {
   1592   if (hb_object_is_immutable (font))
   1593     return;
   1594 
   1595   if (unlikely (!face))
   1596     face = hb_face_get_empty ();
   1597 
   1598   hb_face_t *old = font->face;
   1599 
   1600   font->face = hb_face_reference (face);
   1601 
   1602   hb_face_destroy (old);
   1603 }
   1604 
   1605 /**
   1606  * hb_font_get_face:
   1607  * @font: a font.
   1608  *
   1609  *
   1610  *
   1611  * Return value: (transfer none):
   1612  *
   1613  * Since: 0.9.2
   1614  **/
   1615 hb_face_t *
   1616 hb_font_get_face (hb_font_t *font)
   1617 {
   1618   return font->face;
   1619 }
   1620 
   1621 
   1622 /**
   1623  * hb_font_set_funcs:
   1624  * @font: a font.
   1625  * @klass: (closure font_data) (destroy destroy) (scope notified):
   1626  * @font_data:
   1627  * @destroy:
   1628  *
   1629  *
   1630  *
   1631  * Since: 0.9.2
   1632  **/
   1633 void
   1634 hb_font_set_funcs (hb_font_t         *font,
   1635 		   hb_font_funcs_t   *klass,
   1636 		   void              *font_data,
   1637 		   hb_destroy_func_t  destroy)
   1638 {
   1639   if (hb_object_is_immutable (font))
   1640   {
   1641     if (destroy)
   1642       destroy (font_data);
   1643     return;
   1644   }
   1645 
   1646   if (font->destroy)
   1647     font->destroy (font->user_data);
   1648 
   1649   if (!klass)
   1650     klass = hb_font_funcs_get_empty ();
   1651 
   1652   hb_font_funcs_reference (klass);
   1653   hb_font_funcs_destroy (font->klass);
   1654   font->klass = klass;
   1655   font->user_data = font_data;
   1656   font->destroy = destroy;
   1657 }
   1658 
   1659 /**
   1660  * hb_font_set_funcs_data:
   1661  * @font: a font.
   1662  * @font_data: (destroy destroy) (scope notified):
   1663  * @destroy:
   1664  *
   1665  *
   1666  *
   1667  * Since: 0.9.2
   1668  **/
   1669 void
   1670 hb_font_set_funcs_data (hb_font_t         *font,
   1671 		        void              *font_data,
   1672 		        hb_destroy_func_t  destroy)
   1673 {
   1674   /* Destroy user_data? */
   1675   if (hb_object_is_immutable (font))
   1676   {
   1677     if (destroy)
   1678       destroy (font_data);
   1679     return;
   1680   }
   1681 
   1682   if (font->destroy)
   1683     font->destroy (font->user_data);
   1684 
   1685   font->user_data = font_data;
   1686   font->destroy = destroy;
   1687 }
   1688 
   1689 
   1690 /**
   1691  * hb_font_set_scale:
   1692  * @font: a font.
   1693  * @x_scale:
   1694  * @y_scale:
   1695  *
   1696  *
   1697  *
   1698  * Since: 0.9.2
   1699  **/
   1700 void
   1701 hb_font_set_scale (hb_font_t *font,
   1702 		   int x_scale,
   1703 		   int y_scale)
   1704 {
   1705   if (hb_object_is_immutable (font))
   1706     return;
   1707 
   1708   font->x_scale = x_scale;
   1709   font->y_scale = y_scale;
   1710 }
   1711 
   1712 /**
   1713  * hb_font_get_scale:
   1714  * @font: a font.
   1715  * @x_scale: (out):
   1716  * @y_scale: (out):
   1717  *
   1718  *
   1719  *
   1720  * Since: 0.9.2
   1721  **/
   1722 void
   1723 hb_font_get_scale (hb_font_t *font,
   1724 		   int *x_scale,
   1725 		   int *y_scale)
   1726 {
   1727   if (x_scale) *x_scale = font->x_scale;
   1728   if (y_scale) *y_scale = font->y_scale;
   1729 }
   1730 
   1731 /**
   1732  * hb_font_set_ppem:
   1733  * @font: a font.
   1734  * @x_ppem:
   1735  * @y_ppem:
   1736  *
   1737  *
   1738  *
   1739  * Since: 0.9.2
   1740  **/
   1741 void
   1742 hb_font_set_ppem (hb_font_t *font,
   1743 		  unsigned int x_ppem,
   1744 		  unsigned int y_ppem)
   1745 {
   1746   if (hb_object_is_immutable (font))
   1747     return;
   1748 
   1749   font->x_ppem = x_ppem;
   1750   font->y_ppem = y_ppem;
   1751 }
   1752 
   1753 /**
   1754  * hb_font_get_ppem:
   1755  * @font: a font.
   1756  * @x_ppem: (out):
   1757  * @y_ppem: (out):
   1758  *
   1759  *
   1760  *
   1761  * Since: 0.9.2
   1762  **/
   1763 void
   1764 hb_font_get_ppem (hb_font_t *font,
   1765 		  unsigned int *x_ppem,
   1766 		  unsigned int *y_ppem)
   1767 {
   1768   if (x_ppem) *x_ppem = font->x_ppem;
   1769   if (y_ppem) *y_ppem = font->y_ppem;
   1770 }
   1771 
   1772 /**
   1773  * hb_font_set_ptem:
   1774  * @font: a font.
   1775  * @ptem: font size in points.
   1776  *
   1777  * Sets "point size" of the font.  Set to 0 to unset.
   1778  *
   1779  * There are 72 points in an inch.
   1780  *
   1781  * Since: 1.6.0
   1782  **/
   1783 void
   1784 hb_font_set_ptem (hb_font_t *font, float ptem)
   1785 {
   1786   if (hb_object_is_immutable (font))
   1787     return;
   1788 
   1789   font->ptem = ptem;
   1790 }
   1791 
   1792 /**
   1793  * hb_font_get_ptem:
   1794  * @font: a font.
   1795  *
   1796  * Gets the "point size" of the font.  A value of 0 means unset.
   1797  *
   1798  * Return value: Point size.
   1799  *
   1800  * Since: 0.9.2
   1801  **/
   1802 float
   1803 hb_font_get_ptem (hb_font_t *font)
   1804 {
   1805   return font->ptem;
   1806 }
   1807 
   1808 /*
   1809  * Variations
   1810  */
   1811 
   1812 static void
   1813 _hb_font_adopt_var_coords_normalized (hb_font_t *font,
   1814 				      int *coords, /* 2.14 normalized */
   1815 				      unsigned int coords_length)
   1816 {
   1817   free (font->coords);
   1818 
   1819   font->coords = coords;
   1820   font->num_coords = coords_length;
   1821 }
   1822 
   1823 /**
   1824  * hb_font_set_variations:
   1825  *
   1826  * Since: 1.4.2
   1827  */
   1828 void
   1829 hb_font_set_variations (hb_font_t *font,
   1830 			const hb_variation_t *variations,
   1831 			unsigned int variations_length)
   1832 {
   1833   if (hb_object_is_immutable (font))
   1834     return;
   1835 
   1836   if (!variations_length)
   1837   {
   1838     hb_font_set_var_coords_normalized (font, nullptr, 0);
   1839     return;
   1840   }
   1841 
   1842   unsigned int coords_length = hb_ot_var_get_axis_count (font->face);
   1843 
   1844   int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
   1845   if (unlikely (coords_length && !normalized))
   1846     return;
   1847 
   1848   hb_ot_var_normalize_variations (font->face,
   1849 				  variations, variations_length,
   1850 				  normalized, coords_length);
   1851   _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
   1852 }
   1853 
   1854 /**
   1855  * hb_font_set_var_coords_design:
   1856  *
   1857  * Since: 1.4.2
   1858  */
   1859 void
   1860 hb_font_set_var_coords_design (hb_font_t *font,
   1861 			       const float *coords,
   1862 			       unsigned int coords_length)
   1863 {
   1864   if (hb_object_is_immutable (font))
   1865     return;
   1866 
   1867   int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
   1868   if (unlikely (coords_length && !normalized))
   1869     return;
   1870 
   1871   hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
   1872   _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
   1873 }
   1874 
   1875 /**
   1876  * hb_font_set_var_coords_normalized:
   1877  *
   1878  * Since: 1.4.2
   1879  */
   1880 void
   1881 hb_font_set_var_coords_normalized (hb_font_t *font,
   1882 				   const int *coords, /* 2.14 normalized */
   1883 				   unsigned int coords_length)
   1884 {
   1885   if (hb_object_is_immutable (font))
   1886     return;
   1887 
   1888   int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr;
   1889   if (unlikely (coords_length && !copy))
   1890     return;
   1891 
   1892   if (coords_length)
   1893     memcpy (copy, coords, coords_length * sizeof (coords[0]));
   1894 
   1895   _hb_font_adopt_var_coords_normalized (font, copy, coords_length);
   1896 }
   1897 
   1898 /**
   1899  * hb_font_get_var_coords_normalized:
   1900  *
   1901  * Return value is valid as long as variation coordinates of the font
   1902  * are not modified.
   1903  *
   1904  * Since: 1.4.2
   1905  */
   1906 const int *
   1907 hb_font_get_var_coords_normalized (hb_font_t *font,
   1908 				   unsigned int *length)
   1909 {
   1910   if (length)
   1911     *length = font->num_coords;
   1912 
   1913   return font->coords;
   1914 }
   1915 
   1916 
   1917 /*
   1918  * Deprecated get_glyph_func():
   1919  */
   1920 
   1921 struct hb_trampoline_closure_t
   1922 {
   1923   void *user_data;
   1924   hb_destroy_func_t destroy;
   1925   unsigned int ref_count;
   1926 };
   1927 
   1928 template <typename FuncType>
   1929 struct hb_trampoline_t
   1930 {
   1931   hb_trampoline_closure_t closure; /* Must be first. */
   1932   FuncType func;
   1933 };
   1934 
   1935 template <typename FuncType>
   1936 static hb_trampoline_t<FuncType> *
   1937 trampoline_create (FuncType           func,
   1938 		   void              *user_data,
   1939 		   hb_destroy_func_t  destroy)
   1940 {
   1941   typedef hb_trampoline_t<FuncType> trampoline_t;
   1942 
   1943   trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
   1944 
   1945   if (unlikely (!trampoline))
   1946     return nullptr;
   1947 
   1948   trampoline->closure.user_data = user_data;
   1949   trampoline->closure.destroy = destroy;
   1950   trampoline->closure.ref_count = 1;
   1951   trampoline->func = func;
   1952 
   1953   return trampoline;
   1954 }
   1955 
   1956 static void
   1957 trampoline_reference (hb_trampoline_closure_t *closure)
   1958 {
   1959   closure->ref_count++;
   1960 }
   1961 
   1962 static void
   1963 trampoline_destroy (void *user_data)
   1964 {
   1965   hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
   1966 
   1967   if (--closure->ref_count)
   1968     return;
   1969 
   1970   if (closure->destroy)
   1971     closure->destroy (closure->user_data);
   1972   free (closure);
   1973 }
   1974 
   1975 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
   1976 
   1977 static hb_bool_t
   1978 hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
   1979 				      void *font_data,
   1980 				      hb_codepoint_t unicode,
   1981 				      hb_codepoint_t *glyph,
   1982 				      void *user_data)
   1983 {
   1984   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
   1985   return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
   1986 }
   1987 
   1988 static hb_bool_t
   1989 hb_font_get_variation_glyph_trampoline (hb_font_t *font,
   1990 					void *font_data,
   1991 					hb_codepoint_t unicode,
   1992 					hb_codepoint_t variation_selector,
   1993 					hb_codepoint_t *glyph,
   1994 					void *user_data)
   1995 {
   1996   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
   1997   return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
   1998 }
   1999 
   2000 /**
   2001  * hb_font_funcs_set_glyph_func:
   2002  * @ffuncs: font functions.
   2003  * @func: (closure user_data) (destroy destroy) (scope notified): callback function.
   2004  * @user_data: data to pass to @func.
   2005  * @destroy: function to call when @user_data is not needed anymore.
   2006  *
   2007  * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
   2008  * hb_font_funcs_set_variation_glyph_func() instead.
   2009  *
   2010  * Since: 0.9.2
   2011  * Deprecated: 1.2.3
   2012  **/
   2013 void
   2014 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
   2015 			      hb_font_get_glyph_func_t func,
   2016 			      void *user_data, hb_destroy_func_t destroy)
   2017 {
   2018   hb_font_get_glyph_trampoline_t *trampoline;
   2019 
   2020   trampoline = trampoline_create (func, user_data, destroy);
   2021   if (unlikely (!trampoline))
   2022   {
   2023     if (destroy)
   2024       destroy (user_data);
   2025     return;
   2026   }
   2027 
   2028   hb_font_funcs_set_nominal_glyph_func (ffuncs,
   2029 					hb_font_get_nominal_glyph_trampoline,
   2030 					trampoline,
   2031 					trampoline_destroy);
   2032 
   2033   trampoline_reference (&trampoline->closure);
   2034   hb_font_funcs_set_variation_glyph_func (ffuncs,
   2035 					  hb_font_get_variation_glyph_trampoline,
   2036 					  trampoline,
   2037 					  trampoline_destroy);
   2038 }
   2039