tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hb-font.cc (100087B)


      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-draw.hh"
     33 #include "hb-paint.hh"
     34 #include "hb-machinery.hh"
     35 
     36 #include "hb-ot.h"
     37 
     38 #include "hb-ot-var-avar-table.hh"
     39 #include "hb-ot-var-fvar-table.hh"
     40 
     41 #ifndef HB_NO_OT_FONT
     42 #include "hb-ot.h"
     43 #endif
     44 #ifdef HAVE_FREETYPE
     45 #include "hb-ft.h"
     46 #endif
     47 #ifdef HAVE_FONTATIONS
     48 #include "hb-fontations.h"
     49 #endif
     50 #ifdef HAVE_CORETEXT
     51 #include "hb-coretext.h"
     52 #endif
     53 #ifdef HAVE_DIRECTWRITE
     54 #include "hb-directwrite.h"
     55 #endif
     56 
     57 
     58 /**
     59 * SECTION:hb-font
     60 * @title: hb-font
     61 * @short_description: Font objects
     62 * @include: hb.h
     63 *
     64 * Functions for working with font objects.
     65 *
     66 * A font object represents a font face at a specific size and with
     67 * certain other parameters (pixels-per-em, points-per-em, variation
     68 * settings) specified. Font objects are created from font face
     69 * objects, and are used as input to hb_shape(), among other things.
     70 *
     71 * Client programs can optionally pass in their own functions that
     72 * implement the basic, lower-level queries of font objects. This set
     73 * of font functions is defined by the virtual methods in
     74 * #hb_font_funcs_t.
     75 *
     76 * HarfBuzz provides a built-in set of lightweight default
     77 * functions for each method in #hb_font_funcs_t.
     78 *
     79 * The default font functions are implemented in terms of the
     80 * #hb_font_funcs_t methods of the parent font object.  This allows
     81 * client programs to override only the methods they need to, and
     82 * otherwise inherit the parent font's implementation, if any.
     83 **/
     84 
     85 
     86 /*
     87 * hb_font_funcs_t
     88 */
     89 
     90 static hb_bool_t
     91 hb_font_get_font_h_extents_nil (hb_font_t         *font HB_UNUSED,
     92 			void              *font_data HB_UNUSED,
     93 			hb_font_extents_t *extents,
     94 			void              *user_data HB_UNUSED)
     95 {
     96  hb_memset (extents, 0, sizeof (*extents));
     97  return false;
     98 }
     99 
    100 static hb_bool_t
    101 hb_font_get_font_h_extents_default (hb_font_t         *font,
    102 			    void              *font_data HB_UNUSED,
    103 			    hb_font_extents_t *extents,
    104 			    void              *user_data HB_UNUSED)
    105 {
    106  hb_bool_t ret = font->parent->get_font_h_extents (extents, false);
    107  if (ret) {
    108    extents->ascender = font->parent_scale_y_distance (extents->ascender);
    109    extents->descender = font->parent_scale_y_distance (extents->descender);
    110    extents->line_gap = font->parent_scale_y_distance (extents->line_gap);
    111  }
    112  return ret;
    113 }
    114 
    115 static hb_bool_t
    116 hb_font_get_font_v_extents_nil (hb_font_t         *font HB_UNUSED,
    117 			void              *font_data HB_UNUSED,
    118 			hb_font_extents_t *extents,
    119 			void              *user_data HB_UNUSED)
    120 {
    121  hb_memset (extents, 0, sizeof (*extents));
    122  return false;
    123 }
    124 
    125 static hb_bool_t
    126 hb_font_get_font_v_extents_default (hb_font_t         *font,
    127 			    void              *font_data HB_UNUSED,
    128 			    hb_font_extents_t *extents,
    129 			    void              *user_data HB_UNUSED)
    130 {
    131  hb_bool_t ret = font->parent->get_font_v_extents (extents, false);
    132  if (ret) {
    133    extents->ascender = font->parent_scale_x_distance (extents->ascender);
    134    extents->descender = font->parent_scale_x_distance (extents->descender);
    135    extents->line_gap = font->parent_scale_x_distance (extents->line_gap);
    136  }
    137  return ret;
    138 }
    139 
    140 static hb_bool_t
    141 hb_font_get_nominal_glyph_nil (hb_font_t      *font HB_UNUSED,
    142 		       void           *font_data HB_UNUSED,
    143 		       hb_codepoint_t  unicode HB_UNUSED,
    144 		       hb_codepoint_t *glyph,
    145 		       void           *user_data HB_UNUSED)
    146 {
    147  *glyph = 0;
    148  return false;
    149 }
    150 
    151 static hb_bool_t
    152 hb_font_get_nominal_glyph_default (hb_font_t      *font,
    153 			   void           *font_data HB_UNUSED,
    154 			   hb_codepoint_t  unicode,
    155 			   hb_codepoint_t *glyph,
    156 			   void           *user_data HB_UNUSED)
    157 {
    158  if (font->has_nominal_glyphs_func_set ())
    159  {
    160    return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0);
    161  }
    162  return font->parent->get_nominal_glyph (unicode, glyph);
    163 }
    164 
    165 #define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
    166 
    167 static unsigned int
    168 hb_font_get_nominal_glyphs_default (hb_font_t            *font,
    169 			    void                 *font_data HB_UNUSED,
    170 			    unsigned int          count,
    171 			    const hb_codepoint_t *first_unicode,
    172 			    unsigned int          unicode_stride,
    173 			    hb_codepoint_t       *first_glyph,
    174 			    unsigned int          glyph_stride,
    175 			    void                 *user_data HB_UNUSED)
    176 {
    177  if (font->has_nominal_glyph_func_set ())
    178  {
    179    for (unsigned int i = 0; i < count; i++)
    180    {
    181      if (!font->get_nominal_glyph (*first_unicode, first_glyph))
    182 return i;
    183 
    184      first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
    185      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
    186    }
    187    return count;
    188  }
    189 
    190  return font->parent->get_nominal_glyphs (count,
    191 				   first_unicode, unicode_stride,
    192 				   first_glyph, glyph_stride);
    193 }
    194 
    195 static hb_bool_t
    196 hb_font_get_variation_glyph_nil (hb_font_t      *font HB_UNUSED,
    197 			 void           *font_data HB_UNUSED,
    198 			 hb_codepoint_t  unicode HB_UNUSED,
    199 			 hb_codepoint_t  variation_selector HB_UNUSED,
    200 			 hb_codepoint_t *glyph,
    201 			 void           *user_data HB_UNUSED)
    202 {
    203  *glyph = 0;
    204  return false;
    205 }
    206 
    207 static hb_bool_t
    208 hb_font_get_variation_glyph_default (hb_font_t      *font,
    209 			     void           *font_data HB_UNUSED,
    210 			     hb_codepoint_t  unicode,
    211 			     hb_codepoint_t  variation_selector,
    212 			     hb_codepoint_t *glyph,
    213 			     void           *user_data HB_UNUSED)
    214 {
    215  return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
    216 }
    217 
    218 
    219 static hb_position_t
    220 hb_font_get_glyph_h_advance_nil (hb_font_t      *font,
    221 			 void           *font_data HB_UNUSED,
    222 			 hb_codepoint_t  glyph HB_UNUSED,
    223 			 void           *user_data HB_UNUSED)
    224 {
    225  return font->x_scale;
    226 }
    227 
    228 static hb_position_t
    229 hb_font_get_glyph_h_advance_default (hb_font_t      *font,
    230 			     void           *font_data HB_UNUSED,
    231 			     hb_codepoint_t  glyph,
    232 			     void           *user_data HB_UNUSED)
    233 {
    234  if (font->has_glyph_h_advances_func_set ())
    235  {
    236    hb_position_t ret;
    237    font->get_glyph_h_advances (1, &glyph, 0, &ret, 0, false);
    238    return ret;
    239  }
    240  return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph, false));
    241 }
    242 
    243 static hb_position_t
    244 hb_font_get_glyph_v_advance_nil (hb_font_t      *font,
    245 			 void           *font_data HB_UNUSED,
    246 			 hb_codepoint_t  glyph HB_UNUSED,
    247 			 void           *user_data HB_UNUSED)
    248 {
    249  return -font->y_scale;
    250 }
    251 
    252 static hb_position_t
    253 hb_font_get_glyph_v_advance_default (hb_font_t      *font,
    254 			     void           *font_data HB_UNUSED,
    255 			     hb_codepoint_t  glyph,
    256 			     void           *user_data HB_UNUSED)
    257 {
    258  if (font->has_glyph_v_advances_func_set ())
    259  {
    260    hb_position_t ret;
    261    font->get_glyph_v_advances (1, &glyph, 0, &ret, 0, false);
    262    return ret;
    263  }
    264  return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph, false));
    265 }
    266 
    267 #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default
    268 
    269 static void
    270 hb_font_get_glyph_h_advances_default (hb_font_t*            font,
    271 			      void*                 font_data HB_UNUSED,
    272 			      unsigned int          count,
    273 			      const hb_codepoint_t *first_glyph,
    274 			      unsigned int          glyph_stride,
    275 			      hb_position_t        *first_advance,
    276 			      unsigned int          advance_stride,
    277 			      void                 *user_data HB_UNUSED)
    278 {
    279  if (font->has_glyph_h_advance_func_set ())
    280  {
    281    for (unsigned int i = 0; i < count; i++)
    282    {
    283      *first_advance = font->get_glyph_h_advance (*first_glyph, false);
    284      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
    285      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
    286    }
    287    return;
    288  }
    289 
    290  font->parent->get_glyph_h_advances (count,
    291 			      first_glyph, glyph_stride,
    292 			      first_advance, advance_stride,
    293 			      false);
    294  for (unsigned int i = 0; i < count; i++)
    295  {
    296    *first_advance = font->parent_scale_x_distance (*first_advance);
    297    first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
    298  }
    299 }
    300 
    301 #define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default
    302 static void
    303 hb_font_get_glyph_v_advances_default (hb_font_t*            font,
    304 			      void*                 font_data HB_UNUSED,
    305 			      unsigned int          count,
    306 			      const hb_codepoint_t *first_glyph,
    307 			      unsigned int          glyph_stride,
    308 			      hb_position_t        *first_advance,
    309 			      unsigned int          advance_stride,
    310 			      void                 *user_data HB_UNUSED)
    311 {
    312  if (font->has_glyph_v_advance_func_set ())
    313  {
    314    for (unsigned int i = 0; i < count; i++)
    315    {
    316      *first_advance = font->get_glyph_v_advance (*first_glyph, false);
    317      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
    318      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
    319    }
    320    return;
    321  }
    322 
    323  font->parent->get_glyph_v_advances (count,
    324 			      first_glyph, glyph_stride,
    325 			      first_advance, advance_stride,
    326 			      false);
    327  for (unsigned int i = 0; i < count; i++)
    328  {
    329    *first_advance = font->parent_scale_y_distance (*first_advance);
    330    first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
    331  }
    332 }
    333 
    334 static hb_bool_t
    335 hb_font_get_glyph_h_origin_nil (hb_font_t      *font HB_UNUSED,
    336 			void           *font_data HB_UNUSED,
    337 			hb_codepoint_t  glyph HB_UNUSED,
    338 			hb_position_t  *x,
    339 			hb_position_t  *y,
    340 			void           *user_data HB_UNUSED)
    341 {
    342  *x = *y = 0;
    343  return true;
    344 }
    345 
    346 static hb_bool_t
    347 hb_font_get_glyph_h_origin_default (hb_font_t      *font,
    348 			    void           *font_data HB_UNUSED,
    349 			    hb_codepoint_t  glyph,
    350 			    hb_position_t  *x,
    351 			    hb_position_t  *y,
    352 			    void           *user_data HB_UNUSED)
    353 {
    354  if (font->has_glyph_h_origins_func_set ())
    355  {
    356    return font->get_glyph_h_origins (1, &glyph, 0, x, 0, y, 0, false);
    357  }
    358  hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
    359  if (ret)
    360    font->parent_scale_position (x, y);
    361  return ret;
    362 }
    363 
    364 static hb_bool_t
    365 hb_font_get_glyph_v_origin_nil (hb_font_t      *font HB_UNUSED,
    366 			void           *font_data HB_UNUSED,
    367 			hb_codepoint_t  glyph HB_UNUSED,
    368 			hb_position_t  *x,
    369 			hb_position_t  *y,
    370 			void           *user_data HB_UNUSED)
    371 {
    372  return false;
    373 }
    374 
    375 static hb_bool_t
    376 hb_font_get_glyph_v_origin_default (hb_font_t      *font,
    377 			    void           *font_data HB_UNUSED,
    378 			    hb_codepoint_t  glyph,
    379 			    hb_position_t  *x,
    380 			    hb_position_t  *y,
    381 			    void           *user_data HB_UNUSED)
    382 {
    383  if (font->has_glyph_v_origins_func_set ())
    384  {
    385    return font->get_glyph_v_origins (1, &glyph, 0, x, 0, y, 0, false);
    386  }
    387  hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
    388  if (ret)
    389    font->parent_scale_position (x, y);
    390  return ret;
    391 }
    392 
    393 #define hb_font_get_glyph_h_origins_nil hb_font_get_glyph_h_origins_default
    394 
    395 static hb_bool_t
    396 hb_font_get_glyph_h_origins_default (hb_font_t *font HB_UNUSED,
    397 			     void *font_data HB_UNUSED,
    398 			     unsigned int count,
    399 			     const hb_codepoint_t *first_glyph HB_UNUSED,
    400 			     unsigned glyph_stride HB_UNUSED,
    401 			     hb_position_t *first_x,
    402 			     unsigned x_stride,
    403 			     hb_position_t *first_y,
    404 			     unsigned y_stride,
    405 			     void *user_data HB_UNUSED)
    406 {
    407  if (font->has_glyph_h_origin_func_set ())
    408  {
    409    for (unsigned int i = 0; i < count; i++)
    410    {
    411      font->get_glyph_h_origin (*first_glyph, first_x, first_y, false);
    412      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
    413      first_x = &StructAtOffsetUnaligned<hb_position_t> (first_x, x_stride);
    414      first_y = &StructAtOffsetUnaligned<hb_position_t> (first_y, y_stride);
    415    }
    416    return true;
    417  }
    418 
    419  hb_bool_t ret = font->parent->get_glyph_h_origins (count,
    420 					     first_glyph, glyph_stride,
    421 					     first_x, x_stride,
    422 					     first_y, y_stride);
    423  if (ret)
    424  {
    425    for (unsigned i = 0; i < count; i++)
    426    {
    427      font->parent_scale_position (first_x, first_y);
    428      first_x = &StructAtOffsetUnaligned<hb_position_t> (first_x, x_stride);
    429      first_y = &StructAtOffsetUnaligned<hb_position_t> (first_y, y_stride);
    430    }
    431  }
    432  return ret;
    433 }
    434 
    435 #define hb_font_get_glyph_v_origins_nil hb_font_get_glyph_v_origins_default
    436 
    437 static hb_bool_t
    438 hb_font_get_glyph_v_origins_default (hb_font_t *font HB_UNUSED,
    439 			     void *font_data HB_UNUSED,
    440 			     unsigned int count,
    441 			     const hb_codepoint_t *first_glyph HB_UNUSED,
    442 			     unsigned glyph_stride HB_UNUSED,
    443 			     hb_position_t *first_x,
    444 			     unsigned x_stride,
    445 			     hb_position_t *first_y,
    446 			     unsigned y_stride,
    447 			     void *user_data HB_UNUSED)
    448 {
    449  if (font->has_glyph_v_origin_func_set ())
    450  {
    451    for (unsigned int i = 0; i < count; i++)
    452    {
    453      font->get_glyph_v_origin (*first_glyph, first_x, first_y, false);
    454      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
    455      first_x = &StructAtOffsetUnaligned<hb_position_t> (first_x, x_stride);
    456      first_y = &StructAtOffsetUnaligned<hb_position_t> (first_y, y_stride);
    457    }
    458    return true;
    459  }
    460 
    461  hb_bool_t ret = font->parent->get_glyph_v_origins (count,
    462 					     first_glyph, glyph_stride,
    463 					     first_x, x_stride,
    464 					     first_y, y_stride);
    465  if (ret)
    466  {
    467    for (unsigned i = 0; i < count; i++)
    468    {
    469      font->parent_scale_position (first_x, first_y);
    470      first_x = &StructAtOffsetUnaligned<hb_position_t> (first_x, x_stride);
    471      first_y = &StructAtOffsetUnaligned<hb_position_t> (first_y, y_stride);
    472    }
    473  }
    474  return ret;
    475 }
    476 
    477 static hb_position_t
    478 hb_font_get_glyph_h_kerning_nil (hb_font_t      *font HB_UNUSED,
    479 			 void           *font_data HB_UNUSED,
    480 			 hb_codepoint_t  left_glyph HB_UNUSED,
    481 			 hb_codepoint_t  right_glyph HB_UNUSED,
    482 			 void           *user_data HB_UNUSED)
    483 {
    484  return 0;
    485 }
    486 
    487 static hb_position_t
    488 hb_font_get_glyph_h_kerning_default (hb_font_t      *font,
    489 			     void           *font_data HB_UNUSED,
    490 			     hb_codepoint_t  left_glyph,
    491 			     hb_codepoint_t  right_glyph,
    492 			     void           *user_data HB_UNUSED)
    493 {
    494  return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
    495 }
    496 
    497 #ifndef HB_DISABLE_DEPRECATED
    498 static hb_position_t
    499 hb_font_get_glyph_v_kerning_nil (hb_font_t      *font HB_UNUSED,
    500 			 void           *font_data HB_UNUSED,
    501 			 hb_codepoint_t  top_glyph HB_UNUSED,
    502 			 hb_codepoint_t  bottom_glyph HB_UNUSED,
    503 			 void           *user_data HB_UNUSED)
    504 {
    505  return 0;
    506 }
    507 
    508 static hb_position_t
    509 hb_font_get_glyph_v_kerning_default (hb_font_t      *font,
    510 			     void           *font_data HB_UNUSED,
    511 			     hb_codepoint_t  top_glyph,
    512 			     hb_codepoint_t  bottom_glyph,
    513 			     void           *user_data HB_UNUSED)
    514 {
    515  return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
    516 }
    517 #endif
    518 
    519 static hb_bool_t
    520 hb_font_get_glyph_extents_nil (hb_font_t          *font HB_UNUSED,
    521 		       void               *font_data HB_UNUSED,
    522 		       hb_codepoint_t      glyph HB_UNUSED,
    523 		       hb_glyph_extents_t *extents,
    524 		       void               *user_data HB_UNUSED)
    525 {
    526  hb_memset (extents, 0, sizeof (*extents));
    527  return false;
    528 }
    529 
    530 static hb_bool_t
    531 hb_font_get_glyph_extents_default (hb_font_t          *font,
    532 			   void               *font_data HB_UNUSED,
    533 			   hb_codepoint_t      glyph,
    534 			   hb_glyph_extents_t *extents,
    535 			   void               *user_data HB_UNUSED)
    536 {
    537  hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents, false);
    538  if (ret) {
    539    font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
    540    font->parent_scale_distance (&extents->width, &extents->height);
    541  }
    542  return ret;
    543 }
    544 
    545 static hb_bool_t
    546 hb_font_get_glyph_contour_point_nil (hb_font_t      *font HB_UNUSED,
    547 			     void           *font_data HB_UNUSED,
    548 			     hb_codepoint_t  glyph HB_UNUSED,
    549 			     unsigned int    point_index HB_UNUSED,
    550 			     hb_position_t  *x,
    551 			     hb_position_t  *y,
    552 			     void           *user_data HB_UNUSED)
    553 {
    554  *x = *y = 0;
    555  return false;
    556 }
    557 
    558 static hb_bool_t
    559 hb_font_get_glyph_contour_point_default (hb_font_t      *font,
    560 				 void           *font_data HB_UNUSED,
    561 				 hb_codepoint_t  glyph,
    562 				 unsigned int    point_index,
    563 				 hb_position_t  *x,
    564 				 hb_position_t  *y,
    565 				 void           *user_data HB_UNUSED)
    566 {
    567  hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y, false);
    568  if (ret)
    569    font->parent_scale_position (x, y);
    570  return ret;
    571 }
    572 
    573 static hb_bool_t
    574 hb_font_get_glyph_name_nil (hb_font_t      *font HB_UNUSED,
    575 		    void           *font_data HB_UNUSED,
    576 		    hb_codepoint_t  glyph HB_UNUSED,
    577 		    char           *name,
    578 		    unsigned int    size,
    579 		    void           *user_data HB_UNUSED)
    580 {
    581  if (size) *name = '\0';
    582  return false;
    583 }
    584 
    585 static hb_bool_t
    586 hb_font_get_glyph_name_default (hb_font_t      *font,
    587 			void           *font_data HB_UNUSED,
    588 			hb_codepoint_t  glyph,
    589 			char           *name,
    590 			unsigned int    size,
    591 			void           *user_data HB_UNUSED)
    592 {
    593  return font->parent->get_glyph_name (glyph, name, size);
    594 }
    595 
    596 static hb_bool_t
    597 hb_font_get_glyph_from_name_nil (hb_font_t      *font HB_UNUSED,
    598 			 void           *font_data HB_UNUSED,
    599 			 const char     *name HB_UNUSED,
    600 			 int             len HB_UNUSED, /* -1 means nul-terminated */
    601 			 hb_codepoint_t *glyph,
    602 			 void           *user_data HB_UNUSED)
    603 {
    604  *glyph = 0;
    605  return false;
    606 }
    607 
    608 static hb_bool_t
    609 hb_font_get_glyph_from_name_default (hb_font_t      *font,
    610 			     void           *font_data HB_UNUSED,
    611 			     const char     *name,
    612 			     int             len, /* -1 means nul-terminated */
    613 			     hb_codepoint_t *glyph,
    614 			     void           *user_data HB_UNUSED)
    615 {
    616  return font->parent->get_glyph_from_name (name, len, glyph);
    617 }
    618 
    619 static hb_bool_t
    620 hb_font_draw_glyph_or_fail_nil (hb_font_t       *font HB_UNUSED,
    621 			void            *font_data HB_UNUSED,
    622 			hb_codepoint_t   glyph,
    623 			hb_draw_funcs_t *draw_funcs,
    624 			void            *draw_data,
    625 			void            *user_data HB_UNUSED)
    626 {
    627  return false;
    628 }
    629 
    630 static hb_bool_t
    631 hb_font_paint_glyph_or_fail_nil (hb_font_t *font HB_UNUSED,
    632 			 void *font_data HB_UNUSED,
    633 			 hb_codepoint_t glyph HB_UNUSED,
    634 			 hb_paint_funcs_t *paint_funcs HB_UNUSED,
    635 			 void *paint_data HB_UNUSED,
    636 			 unsigned int palette HB_UNUSED,
    637 			 hb_color_t foreground HB_UNUSED,
    638 			 void *user_data HB_UNUSED)
    639 {
    640  return false;
    641 }
    642 
    643 typedef struct hb_font_draw_glyph_default_adaptor_t {
    644  hb_draw_funcs_t *draw_funcs;
    645  void		  *draw_data;
    646  float		   x_scale;
    647  float		   y_scale;
    648 } hb_font_draw_glyph_default_adaptor_t;
    649 
    650 static void
    651 hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED,
    652 		 void *draw_data,
    653 		 hb_draw_state_t *st,
    654 		 float to_x, float to_y,
    655 		 void *user_data HB_UNUSED)
    656 {
    657  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
    658  float x_scale = adaptor->x_scale;
    659  float y_scale = adaptor->y_scale;
    660 
    661  adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st,
    662 			     x_scale * to_x, y_scale * to_y);
    663 }
    664 
    665 static void
    666 hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
    667 		 hb_draw_state_t *st,
    668 		 float to_x, float to_y,
    669 		 void *user_data HB_UNUSED)
    670 {
    671  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
    672  float x_scale = adaptor->x_scale;
    673  float y_scale = adaptor->y_scale;
    674 
    675  st->current_x = st->current_x * x_scale;
    676  st->current_y = st->current_y * y_scale;
    677 
    678  adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st,
    679 			     x_scale * to_x, y_scale * to_y);
    680 }
    681 
    682 static void
    683 hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
    684 		      hb_draw_state_t *st,
    685 		      float control_x, float control_y,
    686 		      float to_x, float to_y,
    687 		      void *user_data HB_UNUSED)
    688 {
    689  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
    690  float x_scale = adaptor->x_scale;
    691  float y_scale = adaptor->y_scale;
    692 
    693  st->current_x = st->current_x * x_scale;
    694  st->current_y = st->current_y * y_scale;
    695 
    696  adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st,
    697 				  x_scale * control_x, y_scale * control_y,
    698 				  x_scale * to_x, y_scale * to_y);
    699 }
    700 
    701 static void
    702 hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
    703 		  hb_draw_state_t *st,
    704 		  float control1_x, float control1_y,
    705 		  float control2_x, float control2_y,
    706 		  float to_x, float to_y,
    707 		  void *user_data HB_UNUSED)
    708 {
    709  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
    710  float x_scale = adaptor->x_scale;
    711  float y_scale = adaptor->y_scale;
    712 
    713  st->current_x = st->current_x * x_scale;
    714  st->current_y = st->current_y * y_scale;
    715 
    716  adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st,
    717 			      x_scale * control1_x, y_scale * control1_y,
    718 			      x_scale * control2_x, y_scale * control2_y,
    719 			      x_scale * to_x, y_scale * to_y);
    720 }
    721 
    722 static void
    723 hb_draw_close_path_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
    724 		    hb_draw_state_t *st,
    725 		    void *user_data HB_UNUSED)
    726 {
    727  hb_font_draw_glyph_default_adaptor_t *adaptor = (hb_font_draw_glyph_default_adaptor_t *) draw_data;
    728 
    729  adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st);
    730 }
    731 
    732 static const hb_draw_funcs_t _hb_draw_funcs_default = {
    733  HB_OBJECT_HEADER_STATIC,
    734 
    735  {
    736 #define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_default,
    737    HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
    738 #undef HB_DRAW_FUNC_IMPLEMENT
    739  }
    740 };
    741 
    742 static hb_bool_t
    743 hb_font_draw_glyph_or_fail_default (hb_font_t       *font,
    744 			    void            *font_data HB_UNUSED,
    745 			    hb_codepoint_t   glyph,
    746 			    hb_draw_funcs_t *draw_funcs,
    747 			    void            *draw_data,
    748 			    void            *user_data HB_UNUSED)
    749 {
    750  hb_font_draw_glyph_default_adaptor_t adaptor = {
    751    draw_funcs,
    752    draw_data,
    753    font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f,
    754    font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f
    755  };
    756 
    757  return font->parent->draw_glyph_or_fail (glyph,
    758 				   const_cast<hb_draw_funcs_t *> (&_hb_draw_funcs_default),
    759 				   &adaptor,
    760 				   false);
    761 }
    762 
    763 static hb_bool_t
    764 hb_font_paint_glyph_or_fail_default (hb_font_t *font,
    765 			     void *font_data,
    766 			     hb_codepoint_t glyph,
    767 			     hb_paint_funcs_t *paint_funcs,
    768 			     void *paint_data,
    769 			     unsigned int palette,
    770 			     hb_color_t foreground,
    771 			     void *user_data)
    772 {
    773  paint_funcs->push_transform (paint_data,
    774    font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0, 0,
    775    0, font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0,
    776    0, 0);
    777 
    778  bool ret = font->parent->paint_glyph_or_fail (glyph, paint_funcs, paint_data, palette, foreground);
    779 
    780  paint_funcs->pop_transform (paint_data);
    781 
    782  return ret;
    783 }
    784 
    785 DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
    786 {
    787  HB_OBJECT_HEADER_STATIC,
    788 
    789  nullptr,
    790  nullptr,
    791  {
    792    {
    793 #define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_nil,
    794      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    795 #undef HB_FONT_FUNC_IMPLEMENT
    796    }
    797  }
    798 };
    799 
    800 static const hb_font_funcs_t _hb_font_funcs_default = {
    801  HB_OBJECT_HEADER_STATIC,
    802 
    803  nullptr,
    804  nullptr,
    805  {
    806    {
    807 #define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_default,
    808      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    809 #undef HB_FONT_FUNC_IMPLEMENT
    810    }
    811  }
    812 };
    813 
    814 
    815 /**
    816 * hb_font_funcs_create:
    817 *
    818 * Creates a new #hb_font_funcs_t structure of font functions.
    819 *
    820 * Return value: (transfer full): The font-functions structure
    821 *
    822 * Since: 0.9.2
    823 **/
    824 hb_font_funcs_t *
    825 hb_font_funcs_create ()
    826 {
    827  hb_font_funcs_t *ffuncs;
    828 
    829  if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
    830    return hb_font_funcs_get_empty ();
    831 
    832  ffuncs->get = _hb_font_funcs_default.get;
    833 
    834  return ffuncs;
    835 }
    836 
    837 /**
    838 * hb_font_funcs_get_empty:
    839 *
    840 * Fetches an empty font-functions structure.
    841 *
    842 * Return value: (transfer full): The font-functions structure
    843 *
    844 * Since: 0.9.2
    845 **/
    846 hb_font_funcs_t *
    847 hb_font_funcs_get_empty ()
    848 {
    849  return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default);
    850 }
    851 
    852 /**
    853 * hb_font_funcs_reference: (skip)
    854 * @ffuncs: The font-functions structure
    855 *
    856 * Increases the reference count on a font-functions structure.
    857 *
    858 * Return value: The font-functions structure
    859 *
    860 * Since: 0.9.2
    861 **/
    862 hb_font_funcs_t *
    863 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
    864 {
    865  return hb_object_reference (ffuncs);
    866 }
    867 
    868 /**
    869 * hb_font_funcs_destroy: (skip)
    870 * @ffuncs: The font-functions structure
    871 *
    872 * Decreases the reference count on a font-functions structure. When
    873 * the reference count reaches zero, the font-functions structure is
    874 * destroyed, freeing all memory.
    875 *
    876 * Since: 0.9.2
    877 **/
    878 void
    879 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
    880 {
    881  if (!hb_object_destroy (ffuncs)) return;
    882 
    883  if (ffuncs->destroy)
    884  {
    885 #define HB_FONT_FUNC_IMPLEMENT(get_,name) if (ffuncs->destroy->name) \
    886    ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name);
    887    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    888 #undef HB_FONT_FUNC_IMPLEMENT
    889  }
    890 
    891  hb_free (ffuncs->destroy);
    892  hb_free (ffuncs->user_data);
    893 
    894  hb_free (ffuncs);
    895 }
    896 
    897 /**
    898 * hb_font_funcs_set_user_data: (skip)
    899 * @ffuncs: The font-functions structure
    900 * @key: The user-data key to set
    901 * @data: A pointer to the user data set
    902 * @destroy: (nullable): A callback to call when @data is not needed anymore
    903 * @replace: Whether to replace an existing data with the same key
    904 *
    905 * Attaches a user-data key/data pair to the specified font-functions structure.
    906 *
    907 * Return value: `true` if success, `false` otherwise
    908 *
    909 * Since: 0.9.2
    910 **/
    911 hb_bool_t
    912 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
    913 		     hb_user_data_key_t *key,
    914 		     void *              data,
    915 		     hb_destroy_func_t   destroy /* May be NULL. */,
    916 		     hb_bool_t           replace)
    917 {
    918  return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
    919 }
    920 
    921 /**
    922 * hb_font_funcs_get_user_data: (skip)
    923 * @ffuncs: The font-functions structure
    924 * @key: The user-data key to query
    925 *
    926 * Fetches the user data associated with the specified key,
    927 * attached to the specified font-functions structure.
    928 *
    929 * Return value: (transfer none): A pointer to the user data
    930 *
    931 * Since: 0.9.2
    932 **/
    933 void *
    934 hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs,
    935 		     hb_user_data_key_t    *key)
    936 {
    937  return hb_object_get_user_data (ffuncs, key);
    938 }
    939 
    940 
    941 /**
    942 * hb_font_funcs_make_immutable:
    943 * @ffuncs: The font-functions structure
    944 *
    945 * Makes a font-functions structure immutable.
    946 *
    947 * Since: 0.9.2
    948 **/
    949 void
    950 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
    951 {
    952  if (hb_object_is_immutable (ffuncs))
    953    return;
    954 
    955  hb_object_make_immutable (ffuncs);
    956 }
    957 
    958 /**
    959 * hb_font_funcs_is_immutable:
    960 * @ffuncs: The font-functions structure
    961 *
    962 * Tests whether a font-functions structure is immutable.
    963 *
    964 * Return value: `true` if @ffuncs is immutable, `false` otherwise
    965 *
    966 * Since: 0.9.2
    967 **/
    968 hb_bool_t
    969 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
    970 {
    971  return hb_object_is_immutable (ffuncs);
    972 }
    973 
    974 
    975 static bool
    976 _hb_font_funcs_set_preamble (hb_font_funcs_t    *ffuncs,
    977 		     bool                func_is_null,
    978 		     void              **user_data,
    979 		     hb_destroy_func_t  *destroy)
    980 {
    981  if (hb_object_is_immutable (ffuncs))
    982  {
    983    if (*destroy)
    984      (*destroy) (*user_data);
    985    return false;
    986  }
    987 
    988  if (func_is_null)
    989  {
    990    if (*destroy)
    991      (*destroy) (*user_data);
    992    *destroy = nullptr;
    993    *user_data = nullptr;
    994  }
    995 
    996  return true;
    997 }
    998 
    999 static bool
   1000 _hb_font_funcs_set_middle (hb_font_funcs_t   *ffuncs,
   1001 		   void              *user_data,
   1002 		   hb_destroy_func_t  destroy)
   1003 {
   1004  if (user_data && !ffuncs->user_data)
   1005  {
   1006    ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data));
   1007    if (unlikely (!ffuncs->user_data))
   1008      goto fail;
   1009  }
   1010  if (destroy && !ffuncs->destroy)
   1011  {
   1012    ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy));
   1013    if (unlikely (!ffuncs->destroy))
   1014      goto fail;
   1015  }
   1016 
   1017  return true;
   1018 
   1019 fail:
   1020  if (destroy)
   1021    (destroy) (user_data);
   1022  return false;
   1023 }
   1024 
   1025 #define HB_FONT_FUNC_IMPLEMENT(get_,name) \
   1026 								 \
   1027 void                                                                     \
   1028 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
   1029 			 hb_font_##get_##name##_func_t func,     \
   1030 			 void                        *user_data, \
   1031 			 hb_destroy_func_t            destroy)   \
   1032 {                                                                        \
   1033  if (!_hb_font_funcs_set_preamble (ffuncs, !func, &user_data, &destroy))\
   1034      return;                                                            \
   1035 								 \
   1036  if (ffuncs->destroy && ffuncs->destroy->name)                          \
   1037    ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \
   1038                                                                         \
   1039  if (!_hb_font_funcs_set_middle (ffuncs, user_data, destroy))           \
   1040      return;                                                            \
   1041 								 \
   1042  if (func)                                                              \
   1043    ffuncs->get.f.name = func;                                           \
   1044  else                                                                   \
   1045    ffuncs->get.f.name = hb_font_##get_##name##_default;                   \
   1046 								 \
   1047  if (ffuncs->user_data)                                                 \
   1048    ffuncs->user_data->name = user_data;                                 \
   1049  if (ffuncs->destroy)                                                   \
   1050    ffuncs->destroy->name = destroy;                                     \
   1051 }
   1052 
   1053 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
   1054 #undef HB_FONT_FUNC_IMPLEMENT
   1055 
   1056 bool
   1057 hb_font_t::has_func_set (unsigned int i)
   1058 {
   1059  return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i];
   1060 }
   1061 
   1062 bool
   1063 hb_font_t::has_func (unsigned int i)
   1064 {
   1065  return has_func_set (i) ||
   1066  (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i));
   1067 }
   1068 
   1069 /* Public getters */
   1070 
   1071 /**
   1072 * hb_font_get_h_extents:
   1073 * @font: #hb_font_t to work upon
   1074 * @extents: (out): The font extents retrieved
   1075 *
   1076 * Fetches the extents for a specified font, for horizontal
   1077 * text segments.
   1078 *
   1079 * Return value: `true` if data found, `false` otherwise
   1080 *
   1081 * Since: 1.1.3
   1082 **/
   1083 hb_bool_t
   1084 hb_font_get_h_extents (hb_font_t         *font,
   1085 	       hb_font_extents_t *extents)
   1086 {
   1087  return font->get_font_h_extents (extents);
   1088 }
   1089 
   1090 /**
   1091 * hb_font_get_v_extents:
   1092 * @font: #hb_font_t to work upon
   1093 * @extents: (out): The font extents retrieved
   1094 *
   1095 * Fetches the extents for a specified font, for vertical
   1096 * text segments.
   1097 *
   1098 * Return value: `true` if data found, `false` otherwise
   1099 *
   1100 * Since: 1.1.3
   1101 **/
   1102 hb_bool_t
   1103 hb_font_get_v_extents (hb_font_t         *font,
   1104 	       hb_font_extents_t *extents)
   1105 {
   1106  return font->get_font_v_extents (extents);
   1107 }
   1108 
   1109 /**
   1110 * hb_font_get_glyph:
   1111 * @font: #hb_font_t to work upon
   1112 * @unicode: The Unicode code point to query
   1113 * @variation_selector: A variation-selector code point
   1114 * @glyph: (out): The glyph ID retrieved
   1115 *
   1116 * Fetches the glyph ID for a Unicode code point in the specified
   1117 * font, with an optional variation selector.
   1118 *
   1119 * If @variation_selector is 0, calls hb_font_get_nominal_glyph();
   1120 * otherwise calls hb_font_get_variation_glyph().
   1121 *
   1122 * Return value: `true` if data found, `false` otherwise
   1123 *
   1124 * Since: 0.9.2
   1125 **/
   1126 hb_bool_t
   1127 hb_font_get_glyph (hb_font_t      *font,
   1128 	   hb_codepoint_t  unicode,
   1129 	   hb_codepoint_t  variation_selector,
   1130 	   hb_codepoint_t *glyph)
   1131 {
   1132  if (unlikely (variation_selector))
   1133    return font->get_variation_glyph (unicode, variation_selector, glyph);
   1134  return font->get_nominal_glyph (unicode, glyph);
   1135 }
   1136 
   1137 /**
   1138 * hb_font_get_nominal_glyph:
   1139 * @font: #hb_font_t to work upon
   1140 * @unicode: The Unicode code point to query
   1141 * @glyph: (out): The glyph ID retrieved
   1142 *
   1143 * Fetches the nominal glyph ID for a Unicode code point in the
   1144 * specified font.
   1145 *
   1146 * This version of the function should not be used to fetch glyph IDs
   1147 * for code points modified by variation selectors. For variation-selector
   1148 * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph().
   1149 *
   1150 * Return value: `true` if data found, `false` otherwise
   1151 *
   1152 * Since: 1.2.3
   1153 **/
   1154 hb_bool_t
   1155 hb_font_get_nominal_glyph (hb_font_t      *font,
   1156 		   hb_codepoint_t  unicode,
   1157 		   hb_codepoint_t *glyph)
   1158 {
   1159  return font->get_nominal_glyph (unicode, glyph);
   1160 }
   1161 
   1162 /**
   1163 * hb_font_get_nominal_glyphs:
   1164 * @font: #hb_font_t to work upon
   1165 * @count: number of code points to query
   1166 * @first_unicode: The first Unicode code point to query
   1167 * @unicode_stride: The stride between successive code points
   1168 * @first_glyph: (out): The first glyph ID retrieved
   1169 * @glyph_stride: The stride between successive glyph IDs
   1170 *
   1171 * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph
   1172 * IDs must be returned in a #hb_codepoint_t output parameter. Stops at the
   1173 * first unsupported glyph ID.
   1174 *
   1175 * Return value: the number of code points processed
   1176 *
   1177 * Since: 2.6.3
   1178 **/
   1179 unsigned int
   1180 hb_font_get_nominal_glyphs (hb_font_t *font,
   1181 		    unsigned int count,
   1182 		    const hb_codepoint_t *first_unicode,
   1183 		    unsigned int unicode_stride,
   1184 		    hb_codepoint_t *first_glyph,
   1185 		    unsigned int glyph_stride)
   1186 {
   1187  return font->get_nominal_glyphs (count,
   1188 			   first_unicode, unicode_stride,
   1189 			   first_glyph, glyph_stride);
   1190 }
   1191 
   1192 /**
   1193 * hb_font_get_variation_glyph:
   1194 * @font: #hb_font_t to work upon
   1195 * @unicode: The Unicode code point to query
   1196 * @variation_selector: The  variation-selector code point to query
   1197 * @glyph: (out): The glyph ID retrieved
   1198 *
   1199 * Fetches the glyph ID for a Unicode code point when followed by
   1200 * by the specified variation-selector code point, in the specified
   1201 * font.
   1202 *
   1203 * Return value: `true` if data found, `false` otherwise
   1204 *
   1205 * Since: 1.2.3
   1206 **/
   1207 hb_bool_t
   1208 hb_font_get_variation_glyph (hb_font_t      *font,
   1209 		     hb_codepoint_t  unicode,
   1210 		     hb_codepoint_t  variation_selector,
   1211 		     hb_codepoint_t *glyph)
   1212 {
   1213  return font->get_variation_glyph (unicode, variation_selector, glyph);
   1214 }
   1215 
   1216 /**
   1217 * hb_font_get_glyph_h_advance:
   1218 * @font: #hb_font_t to work upon
   1219 * @glyph: The glyph ID to query
   1220 *
   1221 * Fetches the advance for a glyph ID in the specified font,
   1222 * for horizontal text segments.
   1223 *
   1224 * Return value: The advance of @glyph within @font
   1225 *
   1226 * Since: 0.9.2
   1227 **/
   1228 hb_position_t
   1229 hb_font_get_glyph_h_advance (hb_font_t      *font,
   1230 		     hb_codepoint_t  glyph)
   1231 {
   1232  return font->get_glyph_h_advance (glyph);
   1233 }
   1234 
   1235 /**
   1236 * hb_font_get_glyph_v_advance:
   1237 * @font: #hb_font_t to work upon
   1238 * @glyph: The glyph ID to query
   1239 *
   1240 * Fetches the advance for a glyph ID in the specified font,
   1241 * for vertical text segments.
   1242 *
   1243 * Return value: The advance of @glyph within @font
   1244 *
   1245 * Since: 0.9.2
   1246 **/
   1247 hb_position_t
   1248 hb_font_get_glyph_v_advance (hb_font_t      *font,
   1249 		     hb_codepoint_t  glyph)
   1250 {
   1251  return font->get_glyph_v_advance (glyph);
   1252 }
   1253 
   1254 /**
   1255 * hb_font_get_glyph_h_advances:
   1256 * @font: #hb_font_t to work upon
   1257 * @count: The number of glyph IDs in the sequence queried
   1258 * @first_glyph: The first glyph ID to query
   1259 * @glyph_stride: The stride between successive glyph IDs
   1260 * @first_advance: (out): The first advance retrieved
   1261 * @advance_stride: The stride between successive advances
   1262 *
   1263 * Fetches the advances for a sequence of glyph IDs in the specified
   1264 * font, for horizontal text segments.
   1265 *
   1266 * Since: 1.8.6
   1267 **/
   1268 void
   1269 hb_font_get_glyph_h_advances (hb_font_t*            font,
   1270 		      unsigned int          count,
   1271 		      const hb_codepoint_t *first_glyph,
   1272 		      unsigned              glyph_stride,
   1273 		      hb_position_t        *first_advance,
   1274 		      unsigned              advance_stride)
   1275 {
   1276  font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
   1277 }
   1278 /**
   1279 * hb_font_get_glyph_v_advances:
   1280 * @font: #hb_font_t to work upon
   1281 * @count: The number of glyph IDs in the sequence queried
   1282 * @first_glyph: The first glyph ID to query
   1283 * @glyph_stride: The stride between successive glyph IDs
   1284 * @first_advance: (out): The first advance retrieved
   1285 * @advance_stride: (out): The stride between successive advances
   1286 *
   1287 * Fetches the advances for a sequence of glyph IDs in the specified
   1288 * font, for vertical text segments.
   1289 *
   1290 * Since: 1.8.6
   1291 **/
   1292 void
   1293 hb_font_get_glyph_v_advances (hb_font_t*            font,
   1294 		      unsigned int          count,
   1295 		      const hb_codepoint_t *first_glyph,
   1296 		      unsigned              glyph_stride,
   1297 		      hb_position_t        *first_advance,
   1298 		      unsigned              advance_stride)
   1299 {
   1300  font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
   1301 }
   1302 
   1303 /**
   1304 * hb_font_get_glyph_h_origin:
   1305 * @font: #hb_font_t to work upon
   1306 * @glyph: The glyph ID to query
   1307 * @x: (out): The X coordinate of the origin
   1308 * @y: (out): The Y coordinate of the origin
   1309 *
   1310 * Fetches the (X,Y) coordinates of the origin for a glyph ID
   1311 * in the specified font, for horizontal text segments.
   1312 *
   1313 * Return value: `true` if data found, `false` otherwise
   1314 *
   1315 * Since: 0.9.2
   1316 **/
   1317 hb_bool_t
   1318 hb_font_get_glyph_h_origin (hb_font_t      *font,
   1319 		    hb_codepoint_t  glyph,
   1320 		    hb_position_t  *x,
   1321 		    hb_position_t  *y)
   1322 {
   1323  return font->get_glyph_h_origin (glyph, x, y);
   1324 }
   1325 
   1326 /**
   1327 * hb_font_get_glyph_v_origin:
   1328 * @font: #hb_font_t to work upon
   1329 * @glyph: The glyph ID to query
   1330 * @x: (out): The X coordinate of the origin
   1331 * @y: (out): The Y coordinate of the origin
   1332 *
   1333 * Fetches the (X,Y) coordinates of the origin for a glyph ID
   1334 * in the specified font, for vertical text segments.
   1335 *
   1336 * Return value: `true` if data found, `false` otherwise
   1337 *
   1338 * Since: 0.9.2
   1339 **/
   1340 hb_bool_t
   1341 hb_font_get_glyph_v_origin (hb_font_t      *font,
   1342 		    hb_codepoint_t  glyph,
   1343 		    hb_position_t  *x,
   1344 		    hb_position_t  *y)
   1345 {
   1346  return font->get_glyph_v_origin (glyph, x, y);
   1347 }
   1348 
   1349 /**
   1350 * hb_font_get_glyph_h_origins:
   1351 * @font: #hb_font_t to work upon
   1352 * @count: The number of glyph IDs in the sequence queried
   1353 * @first_glyph: The first glyph ID to query
   1354 * @glyph_stride: The stride between successive glyph IDs
   1355 * @first_x: (out): The first X coordinate of the origin retrieved
   1356 * @x_stride: The stride between successive X coordinates
   1357 * @first_y: (out): The first Y coordinate of the origin retrieved
   1358 * @y_stride: The stride between successive Y coordinates
   1359 *
   1360 * Fetches the (X,Y) coordinates of the origin for requested glyph IDs
   1361 * in the specified font, for horizontal text segments.
   1362 *
   1363 * Return value: `true` if data found, `false` otherwise
   1364 *
   1365 * Since: 11.3.0
   1366 **/
   1367 hb_bool_t
   1368 hb_font_get_glyph_h_origins (hb_font_t      *font,
   1369 		     unsigned int    count,
   1370 		     const hb_codepoint_t *first_glyph,
   1371 		     unsigned int    glyph_stride,
   1372 		     hb_position_t  *first_x,
   1373 		     unsigned int    x_stride,
   1374 		     hb_position_t  *first_y,
   1375 		     unsigned int    y_stride)
   1376 
   1377 {
   1378  return font->get_glyph_h_origins (count,
   1379 			    first_glyph, glyph_stride,
   1380 			    first_x, x_stride,
   1381 			    first_y, y_stride);
   1382 }
   1383 
   1384 /**
   1385 * hb_font_get_glyph_v_origins:
   1386 * @font: #hb_font_t to work upon
   1387 * @count: The number of glyph IDs in the sequence queried
   1388 * @first_glyph: The first glyph ID to query
   1389 * @glyph_stride: The stride between successive glyph IDs
   1390 * @first_x: (out): The first X coordinate of the origin retrieved
   1391 * @x_stride: The stride between successive X coordinates
   1392 * @first_y: (out): The first Y coordinate of the origin retrieved
   1393 * @y_stride: The stride between successive Y coordinates
   1394 *
   1395 * Fetches the (X,Y) coordinates of the origin for requested glyph IDs
   1396 * in the specified font, for vertical text segments.
   1397 *
   1398 * Return value: `true` if data found, `false` otherwise
   1399 *
   1400 * Since: 11.3.0
   1401 **/
   1402 hb_bool_t
   1403 hb_font_get_glyph_v_origins (hb_font_t      *font,
   1404 		     unsigned int    count,
   1405 		     const hb_codepoint_t *first_glyph,
   1406 		     unsigned int    glyph_stride,
   1407 		     hb_position_t  *first_x,
   1408 		     unsigned int    x_stride,
   1409 		     hb_position_t  *first_y,
   1410 		     unsigned int    y_stride)
   1411 
   1412 {
   1413  return font->get_glyph_v_origins (count,
   1414 			    first_glyph, glyph_stride,
   1415 			    first_x, x_stride,
   1416 			    first_y, y_stride);
   1417 }
   1418 
   1419 
   1420 /**
   1421 * hb_font_get_glyph_h_kerning:
   1422 * @font: #hb_font_t to work upon
   1423 * @left_glyph: The glyph ID of the left glyph in the glyph pair
   1424 * @right_glyph: The glyph ID of the right glyph in the glyph pair
   1425 *
   1426 * Fetches the kerning-adjustment value for a glyph-pair in
   1427 * the specified font, for horizontal text segments.
   1428 *
   1429 * <note>It handles legacy kerning only (as returned by the corresponding
   1430 * #hb_font_funcs_t function).</note>
   1431 *
   1432 * Return value: The kerning adjustment value
   1433 *
   1434 * Since: 0.9.2
   1435 **/
   1436 hb_position_t
   1437 hb_font_get_glyph_h_kerning (hb_font_t      *font,
   1438 		     hb_codepoint_t  left_glyph,
   1439 		     hb_codepoint_t  right_glyph)
   1440 {
   1441  return font->get_glyph_h_kerning (left_glyph, right_glyph);
   1442 }
   1443 
   1444 #ifndef HB_DISABLE_DEPRECATED
   1445 /**
   1446 * hb_font_get_glyph_v_kerning:
   1447 * @font: #hb_font_t to work upon
   1448 * @top_glyph: The glyph ID of the top glyph in the glyph pair
   1449 * @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair
   1450 *
   1451 * Fetches the kerning-adjustment value for a glyph-pair in
   1452 * the specified font, for vertical text segments.
   1453 *
   1454 * <note>It handles legacy kerning only (as returned by the corresponding
   1455 * #hb_font_funcs_t function).</note>
   1456 *
   1457 * Return value: The kerning adjustment value
   1458 *
   1459 * Since: 0.9.2
   1460 * Deprecated: 2.0.0
   1461 **/
   1462 hb_position_t
   1463 hb_font_get_glyph_v_kerning (hb_font_t      *font,
   1464 		     hb_codepoint_t  top_glyph,
   1465 		     hb_codepoint_t  bottom_glyph)
   1466 {
   1467  return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
   1468 }
   1469 #endif
   1470 
   1471 /**
   1472 * hb_font_get_glyph_extents:
   1473 * @font: #hb_font_t to work upon
   1474 * @glyph: The glyph ID to query
   1475 * @extents: (out): The #hb_glyph_extents_t retrieved
   1476 *
   1477 * Fetches the #hb_glyph_extents_t data for a glyph ID
   1478 * in the specified font.
   1479 *
   1480 * Return value: `true` if data found, `false` otherwise
   1481 *
   1482 * Since: 0.9.2
   1483 **/
   1484 hb_bool_t
   1485 hb_font_get_glyph_extents (hb_font_t          *font,
   1486 		   hb_codepoint_t      glyph,
   1487 		   hb_glyph_extents_t *extents)
   1488 {
   1489  return font->get_glyph_extents (glyph, extents);
   1490 }
   1491 
   1492 /**
   1493 * hb_font_get_glyph_contour_point:
   1494 * @font: #hb_font_t to work upon
   1495 * @glyph: The glyph ID to query
   1496 * @point_index: The contour-point index to query
   1497 * @x: (out): The X value retrieved for the contour point
   1498 * @y: (out): The Y value retrieved for the contour point
   1499 *
   1500 * Fetches the (x,y) coordinates of a specified contour-point index
   1501 * in the specified glyph, within the specified font.
   1502 *
   1503 * Return value: `true` if data found, `false` otherwise
   1504 *
   1505 * Since: 0.9.2
   1506 **/
   1507 hb_bool_t
   1508 hb_font_get_glyph_contour_point (hb_font_t      *font,
   1509 			 hb_codepoint_t  glyph,
   1510 			 unsigned int    point_index,
   1511 			 hb_position_t  *x,
   1512 			 hb_position_t  *y)
   1513 {
   1514  return font->get_glyph_contour_point (glyph, point_index, x, y);
   1515 }
   1516 
   1517 /**
   1518 * hb_font_get_glyph_name:
   1519 * @font: #hb_font_t to work upon
   1520 * @glyph: The glyph ID to query
   1521 * @name: (out) (array length=size): Name string retrieved for the glyph ID
   1522 * @size: Length of the glyph-name string retrieved
   1523 *
   1524 * Fetches the glyph-name string for a glyph ID in the specified @font.
   1525 *
   1526 * According to the OpenType specification, glyph names are limited to 63
   1527 * characters and can only contain (a subset of) ASCII.
   1528 *
   1529 * Return value: `true` if data found, `false` otherwise
   1530 *
   1531 * Since: 0.9.2
   1532 **/
   1533 hb_bool_t
   1534 hb_font_get_glyph_name (hb_font_t      *font,
   1535 		hb_codepoint_t  glyph,
   1536 		char           *name,
   1537 		unsigned int    size)
   1538 {
   1539  return font->get_glyph_name (glyph, name, size);
   1540 }
   1541 
   1542 /**
   1543 * hb_font_get_glyph_from_name:
   1544 * @font: #hb_font_t to work upon
   1545 * @name: (array length=len): The name string to query
   1546 * @len: The length of the name queried
   1547 * @glyph: (out): The glyph ID retrieved
   1548 *
   1549 * Fetches the glyph ID that corresponds to a name string in the specified @font.
   1550 *
   1551 * <note>Note: @len == -1 means the name string is null-terminated.</note>
   1552 *
   1553 * Return value: `true` if data found, `false` otherwise
   1554 *
   1555 * Since: 0.9.2
   1556 **/
   1557 hb_bool_t
   1558 hb_font_get_glyph_from_name (hb_font_t      *font,
   1559 		     const char     *name,
   1560 		     int             len, /* -1 means nul-terminated */
   1561 		     hb_codepoint_t *glyph)
   1562 {
   1563  return font->get_glyph_from_name (name, len, glyph);
   1564 }
   1565 
   1566 #ifndef HB_DISABLE_DEPRECATED
   1567 /**
   1568 * hb_font_get_glyph_shape:
   1569 * @font: #hb_font_t to work upon
   1570 * @glyph: The glyph ID
   1571 * @dfuncs: #hb_draw_funcs_t to draw to
   1572 * @draw_data: User data to pass to draw callbacks
   1573 *
   1574 * Fetches the glyph shape that corresponds to a glyph in the specified @font.
   1575 * The shape is returned by way of calls to the callbacks of the @dfuncs
   1576 * objects, with @draw_data passed to them.
   1577 *
   1578 * Since: 4.0.0
   1579 * Deprecated: 7.0.0: Use hb_font_draw_glyph() instead
   1580 */
   1581 void
   1582 hb_font_get_glyph_shape (hb_font_t *font,
   1583 	         hb_codepoint_t glyph,
   1584 	         hb_draw_funcs_t *dfuncs, void *draw_data)
   1585 {
   1586  hb_font_draw_glyph (font, glyph, dfuncs, draw_data);
   1587 }
   1588 #endif
   1589 
   1590 /**
   1591 * hb_font_draw_glyph_or_fail:
   1592 * @font: #hb_font_t to work upon
   1593 * @glyph: The glyph ID
   1594 * @dfuncs: #hb_draw_funcs_t to draw to
   1595 * @draw_data: User data to pass to draw callbacks
   1596 *
   1597 * Draws the outline that corresponds to a glyph in the specified @font.
   1598 *
   1599 * This is a newer name for hb_font_draw_glyph(), that returns `false`
   1600 * if the font has no outlines for the glyph.
   1601 *
   1602 * The outline is returned by way of calls to the callbacks of the @dfuncs
   1603 * objects, with @draw_data passed to them.
   1604 *
   1605 * Return value: `true` if glyph was drawn, `false` otherwise
   1606 *
   1607 * Since: 11.2.0
   1608 **/
   1609 hb_bool_t
   1610 hb_font_draw_glyph_or_fail (hb_font_t *font,
   1611 		    hb_codepoint_t glyph,
   1612 		    hb_draw_funcs_t *dfuncs, void *draw_data)
   1613 {
   1614  return font->draw_glyph_or_fail (glyph, dfuncs, draw_data);
   1615 }
   1616 
   1617 /**
   1618 * hb_font_paint_glyph_or_fail:
   1619 * @font: #hb_font_t to work upon
   1620 * @glyph: The glyph ID
   1621 * @pfuncs: #hb_paint_funcs_t to paint with
   1622 * @paint_data: User data to pass to paint callbacks
   1623 * @palette_index: The index of the font's color palette to use
   1624 * @foreground: The foreground color, unpremultipled
   1625 *
   1626 * Paints a color glyph.
   1627 *
   1628 * This function is similar to, but lower-level than,
   1629 * hb_font_paint_glyph(). It is suitable for clients that
   1630 * need more control.  If there are no color glyphs available,
   1631 * it will return `false`. The client can then fall back to
   1632 * hb_font_draw_glyph_or_fail() for the monochrome outline glyph.
   1633 *
   1634 * The painting instructions are returned by way of calls to
   1635 * the callbacks of the @funcs object, with @paint_data passed
   1636 * to them.
   1637 *
   1638 * If the font has color palettes (see hb_ot_color_has_palettes()),
   1639 * then @palette_index selects the palette to use. If the font only
   1640 * has one palette, this will be 0.
   1641 *
   1642 * Return value: `true` if glyph was painted, `false` otherwise
   1643 *
   1644 * Since: 11.2.0
   1645 */
   1646 hb_bool_t
   1647 hb_font_paint_glyph_or_fail (hb_font_t *font,
   1648 		     hb_codepoint_t glyph,
   1649 		     hb_paint_funcs_t *pfuncs, void *paint_data,
   1650 		     unsigned int palette_index,
   1651 		     hb_color_t foreground)
   1652 {
   1653  return font->paint_glyph_or_fail (glyph, pfuncs, paint_data, palette_index, foreground);
   1654 }
   1655 
   1656 /* A bit higher-level, and with fallback */
   1657 
   1658 void
   1659 hb_font_t::paint_glyph (hb_codepoint_t glyph,
   1660 		hb_paint_funcs_t *paint_funcs, void *paint_data,
   1661 		unsigned int palette,
   1662 		hb_color_t foreground)
   1663 {
   1664  if (paint_glyph_or_fail (glyph,
   1665 		   paint_funcs, paint_data,
   1666 		   palette, foreground))
   1667    return;
   1668 
   1669  /* Fallback for outline glyph. */
   1670  paint_funcs->push_clip_glyph (paint_data, glyph, this);
   1671  paint_funcs->color (paint_data, true, foreground);
   1672  paint_funcs->pop_clip (paint_data);
   1673 }
   1674 
   1675 
   1676 /**
   1677 * hb_font_draw_glyph:
   1678 * @font: #hb_font_t to work upon
   1679 * @glyph: The glyph ID
   1680 * @dfuncs: #hb_draw_funcs_t to draw to
   1681 * @draw_data: User data to pass to draw callbacks
   1682 *
   1683 * Draws the outline that corresponds to a glyph in the specified @font.
   1684 *
   1685 * This is an older name for hb_font_draw_glyph_or_fail(), with no
   1686 * return value.
   1687 *
   1688 * The outline is returned by way of calls to the callbacks of the @dfuncs
   1689 * objects, with @draw_data passed to them.
   1690 *
   1691 * Since: 7.0.0
   1692 **/
   1693 void
   1694 hb_font_draw_glyph (hb_font_t *font,
   1695 	    hb_codepoint_t glyph,
   1696 	    hb_draw_funcs_t *dfuncs, void *draw_data)
   1697 {
   1698  (void) hb_font_draw_glyph_or_fail (font, glyph, dfuncs, draw_data);
   1699 }
   1700 
   1701 /**
   1702 * hb_font_paint_glyph:
   1703 * @font: #hb_font_t to work upon
   1704 * @glyph: The glyph ID
   1705 * @pfuncs: #hb_paint_funcs_t to paint with
   1706 * @paint_data: User data to pass to paint callbacks
   1707 * @palette_index: The index of the font's color palette to use
   1708 * @foreground: The foreground color, unpremultipled
   1709 *
   1710 * Paints the glyph. This function is similar to
   1711 * hb_font_paint_glyph_or_fail(), but if painting a color glyph
   1712 * failed, it will fall back to painting an outline monochrome
   1713 * glyph.
   1714 *
   1715 * The painting instructions are returned by way of calls to
   1716 * the callbacks of the @funcs object, with @paint_data passed
   1717 * to them.
   1718 *
   1719 * If the font has color palettes (see hb_ot_color_has_palettes()),
   1720 * then @palette_index selects the palette to use. If the font only
   1721 * has one palette, this will be 0.
   1722 *
   1723 * Since: 7.0.0
   1724 */
   1725 void
   1726 hb_font_paint_glyph (hb_font_t *font,
   1727                     hb_codepoint_t glyph,
   1728                     hb_paint_funcs_t *pfuncs, void *paint_data,
   1729                     unsigned int palette_index,
   1730                     hb_color_t foreground)
   1731 {
   1732  font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground);
   1733 }
   1734 
   1735 /**
   1736 * hb_font_get_extents_for_direction:
   1737 * @font: #hb_font_t to work upon
   1738 * @direction: The direction of the text segment
   1739 * @extents: (out): The #hb_font_extents_t retrieved
   1740 *
   1741 * Fetches the extents for a font in a text segment of the
   1742 * specified direction.
   1743 *
   1744 * Calls the appropriate direction-specific variant (horizontal
   1745 * or vertical) depending on the value of @direction.
   1746 *
   1747 * Since: 1.1.3
   1748 **/
   1749 void
   1750 hb_font_get_extents_for_direction (hb_font_t         *font,
   1751 			   hb_direction_t     direction,
   1752 			   hb_font_extents_t *extents)
   1753 {
   1754  font->get_extents_for_direction (direction, extents);
   1755 }
   1756 /**
   1757 * hb_font_get_glyph_advance_for_direction:
   1758 * @font: #hb_font_t to work upon
   1759 * @glyph: The glyph ID to query
   1760 * @direction: The direction of the text segment
   1761 * @x: (out): The horizontal advance retrieved
   1762 * @y: (out):  The vertical advance retrieved
   1763 *
   1764 * Fetches the advance for a glyph ID from the specified font,
   1765 * in a text segment of the specified direction.
   1766 *
   1767 * Calls the appropriate direction-specific variant (horizontal
   1768 * or vertical) depending on the value of @direction.
   1769 *
   1770 * Since: 0.9.2
   1771 **/
   1772 void
   1773 hb_font_get_glyph_advance_for_direction (hb_font_t      *font,
   1774 				 hb_codepoint_t  glyph,
   1775 				 hb_direction_t  direction,
   1776 				 hb_position_t  *x,
   1777 				 hb_position_t  *y)
   1778 {
   1779  font->get_glyph_advance_for_direction (glyph, direction, x, y);
   1780 }
   1781 /**
   1782 * hb_font_get_glyph_advances_for_direction:
   1783 * @font: #hb_font_t to work upon
   1784 * @direction: The direction of the text segment
   1785 * @count: The number of glyph IDs in the sequence queried
   1786 * @first_glyph: The first glyph ID to query
   1787 * @glyph_stride: The stride between successive glyph IDs
   1788 * @first_advance: (out): The first advance retrieved
   1789 * @advance_stride: (out): The stride between successive advances
   1790 *
   1791 * Fetches the advances for a sequence of glyph IDs in the specified
   1792 * font, in a text segment of the specified direction.
   1793 *
   1794 * Calls the appropriate direction-specific variant (horizontal
   1795 * or vertical) depending on the value of @direction.
   1796 *
   1797 * Since: 1.8.6
   1798 **/
   1799 HB_EXTERN void
   1800 hb_font_get_glyph_advances_for_direction (hb_font_t*            font,
   1801 				  hb_direction_t        direction,
   1802 				  unsigned int          count,
   1803 				  const hb_codepoint_t *first_glyph,
   1804 				  unsigned              glyph_stride,
   1805 				  hb_position_t        *first_advance,
   1806 				  unsigned              advance_stride)
   1807 {
   1808  font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride);
   1809 }
   1810 
   1811 /**
   1812 * hb_font_get_glyph_origin_for_direction:
   1813 * @font: #hb_font_t to work upon
   1814 * @glyph: The glyph ID to query
   1815 * @direction: The direction of the text segment
   1816 * @x: (out): The X coordinate retrieved for the origin
   1817 * @y: (out): The Y coordinate retrieved for the origin
   1818 *
   1819 * Fetches the (X,Y) coordinates of the origin for a glyph in
   1820 * the specified font.
   1821 *
   1822 * Calls the appropriate direction-specific variant (horizontal
   1823 * or vertical) depending on the value of @direction.
   1824 *
   1825 * Since: 0.9.2
   1826 **/
   1827 void
   1828 hb_font_get_glyph_origin_for_direction (hb_font_t      *font,
   1829 				hb_codepoint_t  glyph,
   1830 				hb_direction_t  direction,
   1831 				hb_position_t  *x,
   1832 				hb_position_t  *y)
   1833 {
   1834  return font->get_glyph_origin_for_direction (glyph, direction, x, y);
   1835 }
   1836 
   1837 /**
   1838 * hb_font_add_glyph_origin_for_direction:
   1839 * @font: #hb_font_t to work upon
   1840 * @glyph: The glyph ID to query
   1841 * @direction: The direction of the text segment
   1842 * @x: (inout): Input = The original X coordinate
   1843 *     Output = The X coordinate plus the X-coordinate of the origin
   1844 * @y: (inout): Input = The original Y coordinate
   1845 *     Output = The Y coordinate plus the Y-coordinate of the origin
   1846 *
   1847 * Adds the origin coordinates to an (X,Y) point coordinate, in
   1848 * the specified glyph ID in the specified font.
   1849 *
   1850 * Calls the appropriate direction-specific variant (horizontal
   1851 * or vertical) depending on the value of @direction.
   1852 *
   1853 * Since: 0.9.2
   1854 **/
   1855 void
   1856 hb_font_add_glyph_origin_for_direction (hb_font_t      *font,
   1857 				hb_codepoint_t  glyph,
   1858 				hb_direction_t  direction,
   1859 				hb_position_t  *x,
   1860 				hb_position_t  *y)
   1861 {
   1862  return font->add_glyph_origin_for_direction (glyph, direction, x, y);
   1863 }
   1864 
   1865 /**
   1866 * hb_font_subtract_glyph_origin_for_direction:
   1867 * @font: #hb_font_t to work upon
   1868 * @glyph: The glyph ID to query
   1869 * @direction: The direction of the text segment
   1870 * @x: (inout): Input = The original X coordinate
   1871 *     Output = The X coordinate minus the X-coordinate of the origin
   1872 * @y: (inout): Input = The original Y coordinate
   1873 *     Output = The Y coordinate minus the Y-coordinate of the origin
   1874 *
   1875 * Subtracts the origin coordinates from an (X,Y) point coordinate,
   1876 * in the specified glyph ID in the specified font.
   1877 *
   1878 * Calls the appropriate direction-specific variant (horizontal
   1879 * or vertical) depending on the value of @direction.
   1880 *
   1881 * Since: 0.9.2
   1882 **/
   1883 void
   1884 hb_font_subtract_glyph_origin_for_direction (hb_font_t      *font,
   1885 				     hb_codepoint_t  glyph,
   1886 				     hb_direction_t  direction,
   1887 				     hb_position_t  *x,
   1888 				     hb_position_t  *y)
   1889 {
   1890  return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
   1891 }
   1892 
   1893 /**
   1894 * hb_font_get_glyph_kerning_for_direction:
   1895 * @font: #hb_font_t to work upon
   1896 * @first_glyph: The glyph ID of the first glyph in the glyph pair to query
   1897 * @second_glyph: The glyph ID of the second glyph in the glyph pair to query
   1898 * @direction: The direction of the text segment
   1899 * @x: (out): The horizontal kerning-adjustment value retrieved
   1900 * @y: (out): The vertical kerning-adjustment value retrieved
   1901 *
   1902 * Fetches the kerning-adjustment value for a glyph-pair in the specified font.
   1903 *
   1904 * Calls the appropriate direction-specific variant (horizontal
   1905 * or vertical) depending on the value of @direction.
   1906 *
   1907 * Since: 0.9.2
   1908 **/
   1909 void
   1910 hb_font_get_glyph_kerning_for_direction (hb_font_t      *font,
   1911 				 hb_codepoint_t  first_glyph,
   1912 				 hb_codepoint_t  second_glyph,
   1913 				 hb_direction_t  direction,
   1914 				 hb_position_t  *x,
   1915 				 hb_position_t  *y)
   1916 {
   1917  return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
   1918 }
   1919 
   1920 /**
   1921 * hb_font_get_glyph_extents_for_origin:
   1922 * @font: #hb_font_t to work upon
   1923 * @glyph: The glyph ID to query
   1924 * @direction: The direction of the text segment
   1925 * @extents: (out): The #hb_glyph_extents_t retrieved
   1926 *
   1927 * Fetches the #hb_glyph_extents_t data for a glyph ID
   1928 * in the specified font, with respect to the origin in
   1929 * a text segment in the specified direction.
   1930 *
   1931 * Calls the appropriate direction-specific variant (horizontal
   1932 * or vertical) depending on the value of @direction.
   1933 *
   1934 * Return value: `true` if data found, `false` otherwise
   1935 *
   1936 * Since: 0.9.2
   1937 **/
   1938 hb_bool_t
   1939 hb_font_get_glyph_extents_for_origin (hb_font_t          *font,
   1940 			      hb_codepoint_t      glyph,
   1941 			      hb_direction_t      direction,
   1942 			      hb_glyph_extents_t *extents)
   1943 {
   1944  return font->get_glyph_extents_for_origin (glyph, direction, extents);
   1945 }
   1946 
   1947 /**
   1948 * hb_font_get_glyph_contour_point_for_origin:
   1949 * @font: #hb_font_t to work upon
   1950 * @glyph: The glyph ID to query
   1951 * @point_index: The contour-point index to query
   1952 * @direction: The direction of the text segment
   1953 * @x: (out): The X value retrieved for the contour point
   1954 * @y: (out): The Y value retrieved for the contour point
   1955 *
   1956 * Fetches the (X,Y) coordinates of a specified contour-point index
   1957 * in the specified glyph ID in the specified font, with respect
   1958 * to the origin in a text segment in the specified direction.
   1959 *
   1960 * Calls the appropriate direction-specific variant (horizontal
   1961 * or vertical) depending on the value of @direction.
   1962 *
   1963 * Return value: `true` if data found, `false` otherwise
   1964 *
   1965 * Since: 0.9.2
   1966 **/
   1967 hb_bool_t
   1968 hb_font_get_glyph_contour_point_for_origin (hb_font_t      *font,
   1969 				    hb_codepoint_t  glyph,
   1970 				    unsigned int    point_index,
   1971 				    hb_direction_t  direction,
   1972 				    hb_position_t  *x,
   1973 				    hb_position_t  *y)
   1974 {
   1975  return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
   1976 }
   1977 
   1978 /**
   1979 * hb_font_glyph_to_string:
   1980 * @font: #hb_font_t to work upon
   1981 * @glyph: The glyph ID to query
   1982 * @s: (out) (array length=size): The string containing the glyph name
   1983 * @size: Length of string @s
   1984 *
   1985 * Fetches the name of the specified glyph ID in @font and returns
   1986 * it in string @s.
   1987 *
   1988 * If the glyph ID has no name in @font, a string of the form `gidDDD` is
   1989 * generated, with `DDD` being the glyph ID.
   1990 *
   1991 * According to the OpenType specification, glyph names are limited to 63
   1992 * characters and can only contain (a subset of) ASCII.
   1993 *
   1994 * Since: 0.9.2
   1995 **/
   1996 void
   1997 hb_font_glyph_to_string (hb_font_t      *font,
   1998 		 hb_codepoint_t  glyph,
   1999 		 char           *s,
   2000 		 unsigned int    size)
   2001 {
   2002  font->glyph_to_string (glyph, s, size);
   2003 }
   2004 
   2005 /**
   2006 * hb_font_glyph_from_string:
   2007 * @font: #hb_font_t to work upon
   2008 * @s: (array length=len) (element-type uint8_t): string to query
   2009 * @len: The length of the string @s
   2010 * @glyph: (out): The glyph ID corresponding to the string requested
   2011 *
   2012 * Fetches the glyph ID from @font that matches the specified string.
   2013 * Strings of the format `gidDDD` or `uniUUUU` are parsed automatically.
   2014 *
   2015 * <note>Note: @len == -1 means the string is null-terminated.</note>
   2016 *
   2017 * Return value: `true` if data found, `false` otherwise
   2018 *
   2019 * Since: 0.9.2
   2020 **/
   2021 hb_bool_t
   2022 hb_font_glyph_from_string (hb_font_t      *font,
   2023 		   const char     *s,
   2024 		   int             len,
   2025 		   hb_codepoint_t *glyph)
   2026 {
   2027  return font->glyph_from_string (s, len, glyph);
   2028 }
   2029 
   2030 
   2031 /*
   2032 * hb_font_t
   2033 */
   2034 
   2035 DEFINE_NULL_INSTANCE (hb_font_t) =
   2036 {
   2037  HB_OBJECT_HEADER_STATIC,
   2038 
   2039  0, /* serial */
   2040  0, /* serial_coords */
   2041 
   2042  nullptr, /* parent */
   2043  const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
   2044 
   2045  1000, /* x_scale */
   2046  1000, /* y_scale */
   2047  false, /* is_synthetic */
   2048  0.f, /* x_embolden */
   2049  0.f, /* y_embolden */
   2050  true, /* embolden_in_place */
   2051  0, /* x_strength */
   2052  0, /* y_strength */
   2053  0.f, /* slant */
   2054  0.f, /* slant_xy; */
   2055  1.f, /* x_multf */
   2056  1.f, /* y_multf */
   2057  1<<16, /* x_mult */
   2058  1<<16, /* y_mult */
   2059 
   2060  0, /* x_ppem */
   2061  0, /* y_ppem */
   2062  0, /* ptem */
   2063 
   2064  HB_FONT_NO_VAR_NAMED_INSTANCE, /* instance_index */
   2065  false, /* has_nonzero_coords */
   2066  0, /* num_coords */
   2067  nullptr, /* coords */
   2068  nullptr, /* design_coords */
   2069 
   2070  const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
   2071 
   2072  /* Zero for the rest is fine. */
   2073 };
   2074 
   2075 
   2076 static hb_font_t *
   2077 _hb_font_create (hb_face_t *face)
   2078 {
   2079  hb_font_t *font;
   2080 
   2081  if (unlikely (!face))
   2082    face = hb_face_get_empty ();
   2083 
   2084  if (!(font = hb_object_create<hb_font_t> ()))
   2085    return hb_font_get_empty ();
   2086 
   2087  hb_face_make_immutable (face);
   2088  font->parent = hb_font_get_empty ();
   2089  font->face = hb_face_reference (face);
   2090  font->klass = hb_font_funcs_get_empty ();
   2091  font->data.init0 (font);
   2092  font->x_scale = font->y_scale = face->get_upem ();
   2093  font->embolden_in_place = true;
   2094  font->x_multf = font->y_multf = 1.f;
   2095  font->x_mult = font->y_mult = 1 << 16;
   2096  font->instance_index = HB_FONT_NO_VAR_NAMED_INSTANCE;
   2097 
   2098  return font;
   2099 }
   2100 
   2101 /**
   2102 * hb_font_create:
   2103 * @face: a face.
   2104 *
   2105 * Constructs a new font object from the specified face.
   2106 *
   2107 * <note>Note: If @face's index value (as passed to hb_face_create()
   2108 * has non-zero top 16-bits, those bits minus one are passed to
   2109 * hb_font_set_var_named_instance(), effectively loading a named-instance
   2110 * of a variable font, instead of the default-instance.  This allows
   2111 * specifying which named-instance to load by default when creating the
   2112 * face.</note>
   2113 *
   2114 * Return value: (transfer full): The new font object
   2115 *
   2116 * Since: 0.9.2
   2117 **/
   2118 hb_font_t *
   2119 hb_font_create (hb_face_t *face)
   2120 {
   2121  hb_font_t *font = _hb_font_create (face);
   2122 
   2123  hb_font_set_funcs_using (font, nullptr);
   2124 
   2125 #ifndef HB_NO_VAR
   2126  // Initialize variations.
   2127  if (likely (face))
   2128  {
   2129    if (face->index >> 16)
   2130      hb_font_set_var_named_instance (font, (face->index >> 16) - 1);
   2131    else
   2132      hb_font_set_variations (font, nullptr, 0);
   2133  }
   2134 #endif
   2135 
   2136  return font;
   2137 }
   2138 
   2139 static void
   2140 _hb_font_adopt_var_coords (hb_font_t *font,
   2141 		   int *coords, /* 2.14 normalized */
   2142 		   float *design_coords,
   2143 		   unsigned int coords_length)
   2144 {
   2145  hb_free (font->coords);
   2146  hb_free (font->design_coords);
   2147 
   2148  font->coords = coords;
   2149  font->design_coords = design_coords;
   2150  font->num_coords = coords_length;
   2151  font->has_nonzero_coords = hb_any (hb_array (coords, coords_length));
   2152 
   2153  font->changed ();
   2154  font->serial_coords = font->serial;
   2155 }
   2156 
   2157 /**
   2158 * hb_font_create_sub_font:
   2159 * @parent: The parent font object
   2160 *
   2161 * Constructs a sub-font font object from the specified @parent font,
   2162 * replicating the parent's properties.
   2163 *
   2164 * Return value: (transfer full): The new sub-font font object
   2165 *
   2166 * Since: 0.9.2
   2167 **/
   2168 hb_font_t *
   2169 hb_font_create_sub_font (hb_font_t *parent)
   2170 {
   2171  if (unlikely (!parent))
   2172    parent = hb_font_get_empty ();
   2173 
   2174  hb_font_t *font = _hb_font_create (parent->face);
   2175 
   2176  if (unlikely (hb_object_is_immutable (font)))
   2177    return font;
   2178 
   2179  font->parent = hb_font_reference (parent);
   2180 
   2181  font->x_scale = parent->x_scale;
   2182  font->y_scale = parent->y_scale;
   2183  font->x_embolden = parent->x_embolden;
   2184  font->y_embolden = parent->y_embolden;
   2185  font->embolden_in_place = parent->embolden_in_place;
   2186  font->slant = parent->slant;
   2187  font->x_ppem = parent->x_ppem;
   2188  font->y_ppem = parent->y_ppem;
   2189  font->ptem = parent->ptem;
   2190 
   2191  unsigned int num_coords = parent->num_coords;
   2192  if (num_coords)
   2193  {
   2194    int *coords = (int *) hb_calloc (num_coords, sizeof (parent->coords[0]));
   2195    float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0]));
   2196    if (likely (coords && design_coords))
   2197    {
   2198      hb_memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
   2199      hb_memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
   2200      _hb_font_adopt_var_coords (font, coords, design_coords, num_coords);
   2201    }
   2202    else
   2203    {
   2204      hb_free (coords);
   2205      hb_free (design_coords);
   2206    }
   2207  }
   2208 
   2209  font->changed ();
   2210  font->serial_coords = font->serial;
   2211 
   2212  return font;
   2213 }
   2214 
   2215 /**
   2216 * hb_font_get_empty:
   2217 *
   2218 * Fetches the empty font object.
   2219 *
   2220 * Return value: (transfer full): The empty font object
   2221 *
   2222 * Since: 0.9.2
   2223 **/
   2224 hb_font_t *
   2225 hb_font_get_empty ()
   2226 {
   2227  return const_cast<hb_font_t *> (&Null (hb_font_t));
   2228 }
   2229 
   2230 /**
   2231 * hb_font_reference: (skip)
   2232 * @font: #hb_font_t to work upon
   2233 *
   2234 * Increases the reference count on the given font object.
   2235 *
   2236 * Return value: (transfer full): The @font object
   2237 *
   2238 * Since: 0.9.2
   2239 **/
   2240 hb_font_t *
   2241 hb_font_reference (hb_font_t *font)
   2242 {
   2243  return hb_object_reference (font);
   2244 }
   2245 
   2246 /**
   2247 * hb_font_destroy: (skip)
   2248 * @font: #hb_font_t to work upon
   2249 *
   2250 * Decreases the reference count on the given font object. When the
   2251 * reference count reaches zero, the font is destroyed,
   2252 * freeing all memory.
   2253 *
   2254 * Since: 0.9.2
   2255 **/
   2256 void
   2257 hb_font_destroy (hb_font_t *font)
   2258 {
   2259  if (!hb_object_destroy (font)) return;
   2260 
   2261  font->data.fini ();
   2262 
   2263  if (font->destroy)
   2264    font->destroy (font->user_data);
   2265 
   2266  hb_font_destroy (font->parent);
   2267  hb_face_destroy (font->face);
   2268  hb_font_funcs_destroy (font->klass);
   2269 
   2270  hb_free (font->coords);
   2271  hb_free (font->design_coords);
   2272 
   2273  hb_free (font);
   2274 }
   2275 
   2276 /**
   2277 * hb_font_set_user_data: (skip)
   2278 * @font: #hb_font_t to work upon
   2279 * @key: The user-data key
   2280 * @data: A pointer to the user data
   2281 * @destroy: (nullable): A callback to call when @data is not needed anymore
   2282 * @replace: Whether to replace an existing data with the same key
   2283 *
   2284 * Attaches a user-data key/data pair to the specified font object.
   2285 *
   2286 * Return value: `true` if success, `false` otherwise
   2287 *
   2288 * Since: 0.9.2
   2289 **/
   2290 hb_bool_t
   2291 hb_font_set_user_data (hb_font_t          *font,
   2292 	       hb_user_data_key_t *key,
   2293 	       void *              data,
   2294 	       hb_destroy_func_t   destroy /* May be NULL. */,
   2295 	       hb_bool_t           replace)
   2296 {
   2297  if (!hb_object_is_immutable (font))
   2298    font->changed ();
   2299 
   2300  return hb_object_set_user_data (font, key, data, destroy, replace);
   2301 }
   2302 
   2303 /**
   2304 * hb_font_get_user_data: (skip)
   2305 * @font: #hb_font_t to work upon
   2306 * @key: The user-data key to query
   2307 *
   2308 * Fetches the user-data object associated with the specified key,
   2309 * attached to the specified font object.
   2310 *
   2311 * Return value: (transfer none): Pointer to the user data
   2312 *
   2313 * Since: 0.9.2
   2314 **/
   2315 void *
   2316 hb_font_get_user_data (const hb_font_t    *font,
   2317 	       hb_user_data_key_t *key)
   2318 {
   2319  return hb_object_get_user_data (font, key);
   2320 }
   2321 
   2322 /**
   2323 * hb_font_make_immutable:
   2324 * @font: #hb_font_t to work upon
   2325 *
   2326 * Makes @font immutable.
   2327 *
   2328 * Since: 0.9.2
   2329 **/
   2330 void
   2331 hb_font_make_immutable (hb_font_t *font)
   2332 {
   2333  if (hb_object_is_immutable (font))
   2334    return;
   2335 
   2336  if (font->parent)
   2337    hb_font_make_immutable (font->parent);
   2338 
   2339  hb_object_make_immutable (font);
   2340 }
   2341 
   2342 /**
   2343 * hb_font_is_immutable:
   2344 * @font: #hb_font_t to work upon
   2345 *
   2346 * Tests whether a font object is immutable.
   2347 *
   2348 * Return value: `true` if @font is immutable, `false` otherwise
   2349 *
   2350 * Since: 0.9.2
   2351 **/
   2352 hb_bool_t
   2353 hb_font_is_immutable (hb_font_t *font)
   2354 {
   2355  return hb_object_is_immutable (font);
   2356 }
   2357 
   2358 /**
   2359 * hb_font_get_serial:
   2360 * @font: #hb_font_t to work upon
   2361 *
   2362 * Returns the internal serial number of the font. The serial
   2363 * number is increased every time a setting on the font is
   2364 * changed, using a setter function.
   2365 *
   2366 * Return value: serial number
   2367 *
   2368 * Since: 4.4.0
   2369 **/
   2370 unsigned int
   2371 hb_font_get_serial (hb_font_t *font)
   2372 {
   2373  return font->serial.get_acquire ();
   2374 }
   2375 
   2376 /**
   2377 * hb_font_changed:
   2378 * @font: #hb_font_t to work upon
   2379 *
   2380 * Notifies the @font that underlying font data has changed.
   2381 * This has the effect of increasing the serial as returned
   2382 * by hb_font_get_serial(), which invalidates internal caches.
   2383 *
   2384 * Since: 4.4.0
   2385 **/
   2386 void
   2387 hb_font_changed (hb_font_t *font)
   2388 {
   2389  if (hb_object_is_immutable (font))
   2390    return;
   2391 
   2392  font->changed ();
   2393 }
   2394 
   2395 /**
   2396 * hb_font_set_parent:
   2397 * @font: #hb_font_t to work upon
   2398 * @parent: The parent font object to assign
   2399 *
   2400 * Sets the parent font of @font.
   2401 *
   2402 * Since: 1.0.5
   2403 **/
   2404 void
   2405 hb_font_set_parent (hb_font_t *font,
   2406 	    hb_font_t *parent)
   2407 {
   2408  if (hb_object_is_immutable (font))
   2409    return;
   2410 
   2411  if (parent == font->parent)
   2412    return;
   2413 
   2414  if (!parent)
   2415    parent = hb_font_get_empty ();
   2416 
   2417  hb_font_t *old = font->parent;
   2418 
   2419  font->parent = hb_font_reference (parent);
   2420 
   2421  hb_font_destroy (old);
   2422 
   2423  font->changed ();
   2424 }
   2425 
   2426 /**
   2427 * hb_font_get_parent:
   2428 * @font: #hb_font_t to work upon
   2429 *
   2430 * Fetches the parent font of @font.
   2431 *
   2432 * Return value: (transfer none): The parent font object
   2433 *
   2434 * Since: 0.9.2
   2435 **/
   2436 hb_font_t *
   2437 hb_font_get_parent (hb_font_t *font)
   2438 {
   2439  return font->parent;
   2440 }
   2441 
   2442 /**
   2443 * hb_font_set_face:
   2444 * @font: #hb_font_t to work upon
   2445 * @face: The #hb_face_t to assign
   2446 *
   2447 * Sets @face as the font-face value of @font.
   2448 *
   2449 * Since: 1.4.3
   2450 **/
   2451 void
   2452 hb_font_set_face (hb_font_t *font,
   2453 	  hb_face_t *face)
   2454 {
   2455  if (hb_object_is_immutable (font))
   2456    return;
   2457 
   2458  if (face == font->face)
   2459    return;
   2460 
   2461  if (unlikely (!face))
   2462    face = hb_face_get_empty ();
   2463 
   2464  hb_face_t *old = font->face;
   2465 
   2466  hb_face_make_immutable (face);
   2467  font->face = hb_face_reference (face);
   2468  font->changed ();
   2469 
   2470  hb_face_destroy (old);
   2471 
   2472  font->changed ();
   2473  font->serial_coords = font->serial;
   2474 }
   2475 
   2476 /**
   2477 * hb_font_get_face:
   2478 * @font: #hb_font_t to work upon
   2479 *
   2480 * Fetches the face associated with the specified font object.
   2481 *
   2482 * Return value: (transfer none): The #hb_face_t value
   2483 *
   2484 * Since: 0.9.2
   2485 **/
   2486 hb_face_t *
   2487 hb_font_get_face (hb_font_t *font)
   2488 {
   2489  return font->face;
   2490 }
   2491 
   2492 
   2493 /**
   2494 * hb_font_set_funcs:
   2495 * @font: #hb_font_t to work upon
   2496 * @klass: (closure font_data) (destroy destroy) (scope notified): The font-functions structure.
   2497 * @font_data: Data to attach to @font
   2498 * @destroy: (nullable): The function to call when @font_data is not needed anymore
   2499 *
   2500 * Replaces the font-functions structure attached to a font, updating
   2501 * the font's user-data with @font-data and the @destroy callback.
   2502 *
   2503 * Since: 0.9.2
   2504 **/
   2505 void
   2506 hb_font_set_funcs (hb_font_t         *font,
   2507 	   hb_font_funcs_t   *klass,
   2508 	   void              *font_data,
   2509 	   hb_destroy_func_t  destroy /* May be NULL. */)
   2510 {
   2511  if (hb_object_is_immutable (font))
   2512  {
   2513    if (destroy)
   2514      destroy (font_data);
   2515    return;
   2516  }
   2517 
   2518  if (font->destroy)
   2519    font->destroy (font->user_data);
   2520 
   2521  if (!klass)
   2522    klass = hb_font_funcs_get_empty ();
   2523 
   2524  hb_font_funcs_reference (klass);
   2525  hb_font_funcs_destroy (font->klass);
   2526  font->klass = klass;
   2527  font->user_data = font_data;
   2528  font->destroy = destroy;
   2529 
   2530  font->changed ();
   2531 }
   2532 
   2533 /**
   2534 * hb_font_set_funcs_data:
   2535 * @font: #hb_font_t to work upon
   2536 * @font_data: (destroy destroy) (scope notified): Data to attach to @font
   2537 * @destroy: (nullable): The function to call when @font_data is not needed anymore
   2538 *
   2539 * Replaces the user data attached to a font, updating the font's
   2540 * @destroy callback.
   2541 *
   2542 * Since: 0.9.2
   2543 **/
   2544 void
   2545 hb_font_set_funcs_data (hb_font_t         *font,
   2546 	        void              *font_data,
   2547 	        hb_destroy_func_t  destroy /* May be NULL. */)
   2548 {
   2549  /* Destroy user_data? */
   2550  if (hb_object_is_immutable (font))
   2551  {
   2552    if (destroy)
   2553      destroy (font_data);
   2554    return;
   2555  }
   2556 
   2557  if (font->destroy)
   2558    font->destroy (font->user_data);
   2559 
   2560  font->user_data = font_data;
   2561  font->destroy = destroy;
   2562 
   2563  font->changed ();
   2564 }
   2565 
   2566 static const struct supported_font_funcs_t {
   2567 char name[16];
   2568 void (*func) (hb_font_t *);
   2569 } supported_font_funcs[] =
   2570 {
   2571 #ifndef HB_NO_OT_FONT
   2572  {"ot",	hb_ot_font_set_funcs},
   2573 #endif
   2574 #ifdef HAVE_FREETYPE
   2575  {"ft",	hb_ft_font_set_funcs},
   2576 #endif
   2577 #ifdef HAVE_FONTATIONS
   2578  {"fontations",hb_fontations_font_set_funcs},
   2579 #endif
   2580 #ifdef HAVE_CORETEXT
   2581  {"coretext",	hb_coretext_font_set_funcs},
   2582 #endif
   2583 #ifdef HAVE_DIRECTWRITE
   2584  {"directwrite",hb_directwrite_font_set_funcs},
   2585 #endif
   2586 };
   2587 
   2588 static const char *get_default_funcs_name ()
   2589 {
   2590  static hb_atomic_t<const char *> static_funcs_name;
   2591  const char *name = static_funcs_name.get_acquire ();
   2592  if (!name)
   2593  {
   2594    name = getenv ("HB_FONT_FUNCS");
   2595    if (!name)
   2596      name = "";
   2597    if (!static_funcs_name.cmpexch (nullptr, name))
   2598      name = static_funcs_name.get_acquire ();
   2599  }
   2600  return name;
   2601 }
   2602 
   2603 /**
   2604 * hb_font_set_funcs_using:
   2605 * @font: #hb_font_t to work upon
   2606 * @name: The name of the font-functions structure to use, or `NULL`
   2607 *
   2608 * Sets the font-functions structure to use for a font, based on the
   2609 * specified name.
   2610 *
   2611 * If @name is `NULL` or the empty string, the default (first) functioning font-functions
   2612 * are used.  This default can be changed by setting the `HB_FONT_FUNCS` environment
   2613 * variable to the name of the desired font-functions.
   2614 *
   2615 * Return value: `true` if the font-functions was found and set, `false` otherwise
   2616 *
   2617 * Since: 11.0.0
   2618 **/
   2619 hb_bool_t
   2620 hb_font_set_funcs_using (hb_font_t  *font,
   2621 		 const char *name)
   2622 {
   2623  if (unlikely (hb_object_is_immutable (font)))
   2624    return false;
   2625 
   2626  bool retry = false;
   2627 
   2628  if (!name || !*name)
   2629  {
   2630    name = get_default_funcs_name ();
   2631    retry = true;
   2632  }
   2633  if (name && !*name) name = nullptr;
   2634 
   2635 retry:
   2636  for (unsigned i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++)
   2637    if (!name || strcmp (supported_font_funcs[i].name, name) == 0)
   2638    {
   2639      supported_font_funcs[i].func (font);
   2640      if (name || font->klass != hb_font_funcs_get_empty ())
   2641 return true;
   2642    }
   2643 
   2644  if (retry)
   2645  {
   2646    retry = false;
   2647    name = nullptr;
   2648    goto retry;
   2649  }
   2650 
   2651  return false;
   2652 }
   2653 
   2654 static inline void free_static_font_funcs_list ();
   2655 
   2656 static const char * const nil_font_funcs_list[] = {nullptr};
   2657 
   2658 static struct hb_font_funcs_list_lazy_loader_t : hb_lazy_loader_t<const char *,
   2659 							  hb_font_funcs_list_lazy_loader_t>
   2660 {
   2661  static const char ** create ()
   2662  {
   2663    const char **font_funcs_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_font_funcs), sizeof (const char *));
   2664    if (unlikely (!font_funcs_list))
   2665      return nullptr;
   2666 
   2667    unsigned i;
   2668    for (i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++)
   2669      font_funcs_list[i] = supported_font_funcs[i].name;
   2670    font_funcs_list[i] = nullptr;
   2671 
   2672    hb_atexit (free_static_font_funcs_list);
   2673 
   2674    return font_funcs_list;
   2675  }
   2676  static void destroy (const char **l)
   2677  { hb_free (l); }
   2678  static const char * const * get_null ()
   2679  { return nil_font_funcs_list; }
   2680 } static_font_funcs_list;
   2681 
   2682 static inline
   2683 void free_static_font_funcs_list ()
   2684 {
   2685  static_font_funcs_list.free_instance ();
   2686 }
   2687 
   2688 /**
   2689 * hb_font_list_funcs:
   2690 *
   2691 * Retrieves the list of font functions supported by HarfBuzz.
   2692 *
   2693 * Return value: (transfer none) (array zero-terminated=1): a
   2694 *    `NULL`-terminated array of supported font functions
   2695 *    constant strings. The returned array is owned by HarfBuzz
   2696 *    and should not be modified or freed.
   2697 *
   2698 * Since: 11.0.0
   2699 **/
   2700 const char **
   2701 hb_font_list_funcs ()
   2702 {
   2703  return static_font_funcs_list.get_unconst ();
   2704 }
   2705 
   2706 /**
   2707 * hb_font_set_scale:
   2708 * @font: #hb_font_t to work upon
   2709 * @x_scale: Horizontal scale value to assign
   2710 * @y_scale: Vertical scale value to assign
   2711 *
   2712 * Sets the horizontal and vertical scale of a font.
   2713 *
   2714 * The font scale is a number related to, but not the same as,
   2715 * font size. Typically the client establishes a scale factor
   2716 * to be used between the two. For example, 64, or 256, which
   2717 * would be the fractional-precision part of the font scale.
   2718 * This is necessary because #hb_position_t values are integer
   2719 * types and you need to leave room for fractional values
   2720 * in there.
   2721 *
   2722 * For example, to set the font size to 20, with 64
   2723 * levels of fractional precision you would call
   2724 * `hb_font_set_scale(font, 20 * 64, 20 * 64)`.
   2725 *
   2726 * In the example above, even what font size 20 means is up to
   2727 * you. It might be 20 pixels, or 20 points, or 20 millimeters.
   2728 * HarfBuzz does not care about that.  You can set the point
   2729 * size of the font using hb_font_set_ptem(), and the pixel
   2730 * size using hb_font_set_ppem().
   2731 *
   2732 * The choice of scale is yours but needs to be consistent between
   2733 * what you set here, and what you expect out of #hb_position_t
   2734 * as well has draw / paint API output values.
   2735 *
   2736 * Fonts default to a scale equal to the UPEM value of their face.
   2737 * A font with this setting is sometimes called an "unscaled" font.
   2738 *
   2739 * Since: 0.9.2
   2740 **/
   2741 void
   2742 hb_font_set_scale (hb_font_t *font,
   2743 	   int        x_scale,
   2744 	   int        y_scale)
   2745 {
   2746  if (hb_object_is_immutable (font))
   2747    return;
   2748 
   2749  if (font->x_scale == x_scale && font->y_scale == y_scale)
   2750    return;
   2751 
   2752  font->x_scale = x_scale;
   2753  font->y_scale = y_scale;
   2754 
   2755  font->changed ();
   2756 }
   2757 
   2758 /**
   2759 * hb_font_get_scale:
   2760 * @font: #hb_font_t to work upon
   2761 * @x_scale: (out): Horizontal scale value
   2762 * @y_scale: (out): Vertical scale value
   2763 *
   2764 * Fetches the horizontal and vertical scale of a font.
   2765 *
   2766 * Since: 0.9.2
   2767 **/
   2768 void
   2769 hb_font_get_scale (hb_font_t *font,
   2770 	   int       *x_scale,
   2771 	   int       *y_scale)
   2772 {
   2773  if (x_scale) *x_scale = font->x_scale;
   2774  if (y_scale) *y_scale = font->y_scale;
   2775 }
   2776 
   2777 /**
   2778 * hb_font_set_ppem:
   2779 * @font: #hb_font_t to work upon
   2780 * @x_ppem: Horizontal ppem value to assign
   2781 * @y_ppem: Vertical ppem value to assign
   2782 *
   2783 * Sets the horizontal and vertical pixels-per-em (PPEM) of a font.
   2784 *
   2785 * These values are used for pixel-size-specific adjustment to
   2786 * shaping and draw results, though for the most part they are
   2787 * unused and can be left unset.
   2788 *
   2789 * Since: 0.9.2
   2790 **/
   2791 void
   2792 hb_font_set_ppem (hb_font_t    *font,
   2793 	  unsigned int  x_ppem,
   2794 	  unsigned int  y_ppem)
   2795 {
   2796  if (hb_object_is_immutable (font))
   2797    return;
   2798 
   2799  if (font->x_ppem == x_ppem && font->y_ppem == y_ppem)
   2800    return;
   2801 
   2802  font->x_ppem = x_ppem;
   2803  font->y_ppem = y_ppem;
   2804 
   2805  font->changed ();
   2806 }
   2807 
   2808 /**
   2809 * hb_font_get_ppem:
   2810 * @font: #hb_font_t to work upon
   2811 * @x_ppem: (out): Horizontal ppem value
   2812 * @y_ppem: (out): Vertical ppem value
   2813 *
   2814 * Fetches the horizontal and vertical points-per-em (ppem) of a font.
   2815 *
   2816 * Since: 0.9.2
   2817 **/
   2818 void
   2819 hb_font_get_ppem (hb_font_t    *font,
   2820 	  unsigned int *x_ppem,
   2821 	  unsigned int *y_ppem)
   2822 {
   2823  if (x_ppem) *x_ppem = font->x_ppem;
   2824  if (y_ppem) *y_ppem = font->y_ppem;
   2825 }
   2826 
   2827 /**
   2828 * hb_font_set_ptem:
   2829 * @font: #hb_font_t to work upon
   2830 * @ptem: font size in points.
   2831 *
   2832 * Sets the "point size" of a font. Set to zero to unset.
   2833 * Used in CoreText to implement optical sizing.
   2834 *
   2835 * <note>Note: There are 72 points in an inch.</note>
   2836 *
   2837 * Since: 1.6.0
   2838 **/
   2839 void
   2840 hb_font_set_ptem (hb_font_t *font,
   2841 	  float      ptem)
   2842 {
   2843  if (hb_object_is_immutable (font))
   2844    return;
   2845 
   2846  if (font->ptem == ptem)
   2847    return;
   2848 
   2849  font->ptem = ptem;
   2850 
   2851  font->changed ();
   2852 }
   2853 
   2854 /**
   2855 * hb_font_get_ptem:
   2856 * @font: #hb_font_t to work upon
   2857 *
   2858 * Fetches the "point size" of a font. Used in CoreText to
   2859 * implement optical sizing.
   2860 *
   2861 * Return value: Point size.  A value of zero means "not set."
   2862 *
   2863 * Since: 1.6.0
   2864 **/
   2865 float
   2866 hb_font_get_ptem (hb_font_t *font)
   2867 {
   2868  return font->ptem;
   2869 }
   2870 
   2871 /**
   2872 * hb_font_is_synthetic:
   2873 * @font: #hb_font_t to work upon
   2874 *
   2875 * Tests whether a font is synthetic. A synthetic font is one
   2876 * that has either synthetic slant or synthetic bold set on it.
   2877 *
   2878 * Return value: `true` if the font is synthetic, `false` otherwise.
   2879 *
   2880 * Since: 11.2.0
   2881 */
   2882 hb_bool_t
   2883 hb_font_is_synthetic (hb_font_t *font)
   2884 {
   2885  return font->is_synthetic;
   2886 }
   2887 
   2888 /**
   2889 * hb_font_set_synthetic_bold:
   2890 * @font: #hb_font_t to work upon
   2891 * @x_embolden: the amount to embolden horizontally
   2892 * @y_embolden: the amount to embolden vertically
   2893 * @in_place: whether to embolden glyphs in-place
   2894 *
   2895 * Sets the "synthetic boldness" of a font.
   2896 *
   2897 * Positive values for @x_embolden / @y_embolden make a font
   2898 * bolder, negative values thinner. Typical values are in the
   2899 * 0.01 to 0.05 range. The default value is zero.
   2900 *
   2901 * Synthetic boldness is applied by offsetting the contour
   2902 * points of the glyph shape.
   2903 *
   2904 * Synthetic boldness is applied when rendering a glyph via
   2905 * hb_font_draw_glyph_or_fail().
   2906 *
   2907 * If @in_place is `false`, then glyph advance-widths are also
   2908 * adjusted, otherwise they are not.  The in-place mode is
   2909 * useful for simulating [font grading](https://fonts.google.com/knowledge/glossary/grade).
   2910 *
   2911 *
   2912 * Since: 7.0.0
   2913 **/
   2914 void
   2915 hb_font_set_synthetic_bold (hb_font_t *font,
   2916 		    float x_embolden,
   2917 		    float y_embolden,
   2918 		    hb_bool_t in_place)
   2919 {
   2920  if (hb_object_is_immutable (font))
   2921    return;
   2922 
   2923  if (font->x_embolden == x_embolden &&
   2924      font->y_embolden == y_embolden &&
   2925      font->embolden_in_place == (bool) in_place)
   2926    return;
   2927 
   2928  font->x_embolden = x_embolden;
   2929  font->y_embolden = y_embolden;
   2930  font->embolden_in_place = in_place;
   2931 
   2932  font->changed ();
   2933 }
   2934 
   2935 /**
   2936 * hb_font_get_synthetic_bold:
   2937 * @font: #hb_font_t to work upon
   2938 * @x_embolden: (out): return location for horizontal value
   2939 * @y_embolden: (out): return location for vertical value
   2940 * @in_place: (out): return location for in-place value
   2941 *
   2942 * Fetches the "synthetic boldness" parameters of a font.
   2943 *
   2944 * Since: 7.0.0
   2945 **/
   2946 void
   2947 hb_font_get_synthetic_bold (hb_font_t *font,
   2948 		    float *x_embolden,
   2949 		    float *y_embolden,
   2950 		    hb_bool_t *in_place)
   2951 {
   2952  if (x_embolden) *x_embolden = font->x_embolden;
   2953  if (y_embolden) *y_embolden = font->y_embolden;
   2954  if (in_place) *in_place = font->embolden_in_place;
   2955 }
   2956 
   2957 /**
   2958 * hb_font_set_synthetic_slant:
   2959 * @font: #hb_font_t to work upon
   2960 * @slant: synthetic slant value.
   2961 *
   2962 * Sets the "synthetic slant" of a font.  By default is zero.
   2963 * Synthetic slant is the graphical skew applied to the font
   2964 * at rendering time.
   2965 *
   2966 * HarfBuzz needs to know this value to adjust shaping results,
   2967 * metrics, and style values to match the slanted rendering.
   2968 *
   2969 * <note>Note: The glyph shape fetched via the hb_font_draw_glyph_or_fail()
   2970 * function is slanted to reflect this value as well.</note>
   2971 *
   2972 * <note>Note: The slant value is a ratio.  For example, a
   2973 * 20% slant would be represented as a 0.2 value.</note>
   2974 *
   2975 * Since: 3.3.0
   2976 **/
   2977 HB_EXTERN void
   2978 hb_font_set_synthetic_slant (hb_font_t *font, float slant)
   2979 {
   2980  if (hb_object_is_immutable (font))
   2981    return;
   2982 
   2983  if (font->slant == slant)
   2984    return;
   2985 
   2986  font->slant = slant;
   2987 
   2988  font->changed ();
   2989 }
   2990 
   2991 /**
   2992 * hb_font_get_synthetic_slant:
   2993 * @font: #hb_font_t to work upon
   2994 *
   2995 * Fetches the "synthetic slant" of a font.
   2996 *
   2997 * Return value: Synthetic slant.  By default is zero.
   2998 *
   2999 * Since: 3.3.0
   3000 **/
   3001 HB_EXTERN float
   3002 hb_font_get_synthetic_slant (hb_font_t *font)
   3003 {
   3004  return font->slant;
   3005 }
   3006 
   3007 #ifndef HB_NO_VAR
   3008 /*
   3009 * Variations
   3010 */
   3011 
   3012 /**
   3013 * hb_font_set_variations:
   3014 * @font: #hb_font_t to work upon
   3015 * @variations: (array length=variations_length): Array of variation settings to apply
   3016 * @variations_length: Number of variations to apply
   3017 *
   3018 * Applies a list of font-variation settings to a font.
   3019 *
   3020 * Note that this overrides all existing variations set on @font.
   3021 * Axes not included in @variations will be effectively set to their
   3022 * default values.
   3023 *
   3024 * Since: 1.4.2
   3025 */
   3026 void
   3027 hb_font_set_variations (hb_font_t            *font,
   3028 		const hb_variation_t *variations,
   3029 		unsigned int          variations_length)
   3030 {
   3031  if (hb_object_is_immutable (font))
   3032    return;
   3033 
   3034  const OT::fvar &fvar = *font->face->table.fvar;
   3035  auto axes = fvar.get_axes ();
   3036  const unsigned coords_length = axes.length;
   3037 
   3038  int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
   3039  float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
   3040 
   3041  if (unlikely (coords_length && !(normalized && design_coords)))
   3042  {
   3043    hb_free (normalized);
   3044    hb_free (design_coords);
   3045    return;
   3046  }
   3047 
   3048  /* Initialize design coords. */
   3049  for (unsigned int i = 0; i < coords_length; i++)
   3050    design_coords[i] = axes[i].get_default ();
   3051  if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE)
   3052  {
   3053    unsigned count = coords_length;
   3054    /* This may fail if index is out-of-range;
   3055     * That's why we initialize design_coords from fvar above
   3056     * unconditionally. */
   3057    hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index,
   3058 					&count, design_coords);
   3059  }
   3060 
   3061  for (unsigned int i = 0; i < variations_length; i++)
   3062  {
   3063    const auto tag = variations[i].tag;
   3064    const auto v = variations[i].value;
   3065    for (unsigned axis_index = 0; axis_index < coords_length; axis_index++)
   3066      if (axes[axis_index].axisTag == tag)
   3067 design_coords[axis_index] = v;
   3068  }
   3069 
   3070  hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
   3071  _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
   3072 }
   3073 
   3074 /**
   3075 * hb_font_set_variation:
   3076 * @font: #hb_font_t to work upon
   3077 * @tag: The #hb_tag_t tag of the variation-axis name
   3078 * @value: The value of the variation axis
   3079 *
   3080 * Change the value of one variation axis on the font.
   3081 *
   3082 * Note: This function is expensive to be called repeatedly.
   3083 *   If you want to set multiple variation axes at the same time,
   3084 *   use hb_font_set_variations() instead.
   3085 *
   3086 * Since: 7.1.0
   3087 */
   3088 void
   3089 hb_font_set_variation (hb_font_t *font,
   3090 	       hb_tag_t tag,
   3091 	       float    value)
   3092 {
   3093  if (hb_object_is_immutable (font))
   3094    return;
   3095 
   3096  // TODO Share some of this code with set_variations()
   3097 
   3098  const OT::fvar &fvar = *font->face->table.fvar;
   3099  auto axes = fvar.get_axes ();
   3100  const unsigned coords_length = axes.length;
   3101 
   3102  int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
   3103  float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
   3104 
   3105  if (unlikely (coords_length && !(normalized && design_coords)))
   3106  {
   3107    hb_free (normalized);
   3108    hb_free (design_coords);
   3109    return;
   3110  }
   3111 
   3112  /* Initialize design coords. */
   3113  if (font->design_coords)
   3114  {
   3115    assert (coords_length == font->num_coords);
   3116    for (unsigned int i = 0; i < coords_length; i++)
   3117      design_coords[i] = font->design_coords[i];
   3118  }
   3119  else
   3120  {
   3121    for (unsigned int i = 0; i < coords_length; i++)
   3122      design_coords[i] = axes[i].get_default ();
   3123    if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE)
   3124    {
   3125      unsigned count = coords_length;
   3126      /* This may fail if index is out-of-range;
   3127       * That's why we initialize design_coords from fvar above
   3128       * unconditionally. */
   3129      hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index,
   3130 					  &count, design_coords);
   3131    }
   3132  }
   3133 
   3134  for (unsigned axis_index = 0; axis_index < coords_length; axis_index++)
   3135    if (axes[axis_index].axisTag == tag)
   3136      design_coords[axis_index] = value;
   3137 
   3138  hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
   3139  _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
   3140 }
   3141 
   3142 /**
   3143 * hb_font_set_var_coords_design:
   3144 * @font: #hb_font_t to work upon
   3145 * @coords: (array length=coords_length): Array of variation coordinates to apply
   3146 * @coords_length: Number of coordinates to apply
   3147 *
   3148 * Applies a list of variation coordinates (in design-space units)
   3149 * to a font.
   3150 *
   3151 * Note that this overrides all existing variations set on @font.
   3152 * Axes not included in @coords will be effectively set to their
   3153 * default values.
   3154 *
   3155 * Since: 1.4.2
   3156 */
   3157 void
   3158 hb_font_set_var_coords_design (hb_font_t    *font,
   3159 		       const float  *coords,
   3160 		       unsigned int  input_coords_length)
   3161 {
   3162  if (hb_object_is_immutable (font))
   3163    return;
   3164 
   3165  const OT::fvar &fvar = *font->face->table.fvar;
   3166  auto axes = fvar.get_axes ();
   3167  const unsigned coords_length = axes.length;
   3168 
   3169  input_coords_length = hb_min (input_coords_length, coords_length);
   3170  int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
   3171  float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
   3172 
   3173  if (unlikely (coords_length && !(normalized && design_coords)))
   3174  {
   3175    hb_free (normalized);
   3176    hb_free (design_coords);
   3177    return;
   3178  }
   3179 
   3180  if (input_coords_length)
   3181    hb_memcpy (design_coords, coords, input_coords_length * sizeof (font->design_coords[0]));
   3182  // Fill in the rest with default values
   3183  for (unsigned int i = input_coords_length; i < coords_length; i++)
   3184    design_coords[i] = axes[i].get_default ();
   3185 
   3186  hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
   3187  _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
   3188 }
   3189 
   3190 /**
   3191 * hb_font_set_var_named_instance:
   3192 * @font: a font.
   3193 * @instance_index: named instance index.
   3194 *
   3195 * Sets design coords of a font from a named-instance index.
   3196 *
   3197 * Since: 2.6.0
   3198 */
   3199 void
   3200 hb_font_set_var_named_instance (hb_font_t *font,
   3201 			unsigned int instance_index)
   3202 {
   3203  if (hb_object_is_immutable (font))
   3204    return;
   3205 
   3206  if (font->instance_index == instance_index)
   3207    return;
   3208 
   3209  font->instance_index = instance_index;
   3210  hb_font_set_variations (font, nullptr, 0);
   3211 }
   3212 
   3213 /**
   3214 * hb_font_get_var_named_instance:
   3215 * @font: a font.
   3216 *
   3217 * Returns the currently-set named-instance index of the font.
   3218 *
   3219 * Return value: Named-instance index or %HB_FONT_NO_VAR_NAMED_INSTANCE.
   3220 *
   3221 * Since: 7.0.0
   3222 **/
   3223 unsigned int
   3224 hb_font_get_var_named_instance (hb_font_t *font)
   3225 {
   3226  return font->instance_index;
   3227 }
   3228 
   3229 /**
   3230 * hb_font_set_var_coords_normalized:
   3231 * @font: #hb_font_t to work upon
   3232 * @coords: (array length=coords_length): Array of variation coordinates to apply
   3233 * @coords_length: Number of coordinates to apply
   3234 *
   3235 * Applies a list of variation coordinates (in normalized units)
   3236 * to a font.
   3237 *
   3238 * Note that this overrides all existing variations set on @font.
   3239 * Axes not included in @coords will be effectively set to their
   3240 * default values.
   3241 *
   3242 * <note>Note: Coordinates should be normalized to 2.14.</note>
   3243 *
   3244 * Since: 1.4.2
   3245 */
   3246 void
   3247 hb_font_set_var_coords_normalized (hb_font_t    *font,
   3248 			   const int    *coords, /* 2.14 normalized */
   3249 			   unsigned int  input_coords_length)
   3250 {
   3251  if (hb_object_is_immutable (font))
   3252    return;
   3253 
   3254  const OT::fvar &fvar = *font->face->table.fvar;
   3255  auto axes = fvar.get_axes ();
   3256  unsigned coords_length = axes.length;
   3257 
   3258  input_coords_length = hb_min (input_coords_length, coords_length);
   3259  int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
   3260  float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr;
   3261 
   3262  if (unlikely (coords_length && !(copy && design_coords)))
   3263  {
   3264    hb_free (copy);
   3265    hb_free (design_coords);
   3266    return;
   3267  }
   3268 
   3269  if (input_coords_length)
   3270    hb_memcpy (copy, coords, input_coords_length * sizeof (coords[0]));
   3271 
   3272  for (unsigned int i = 0; i < coords_length; ++i)
   3273    design_coords[i] = NAN;
   3274 
   3275  _hb_font_adopt_var_coords (font, copy, design_coords, coords_length);
   3276 }
   3277 
   3278 /**
   3279 * hb_font_get_var_coords_normalized:
   3280 * @font: #hb_font_t to work upon
   3281 * @length: (out): Number of coordinates retrieved
   3282 *
   3283 * Fetches the list of normalized variation coordinates currently
   3284 * set on a font.
   3285 *
   3286 * <note>Note that if no variation coordinates are set, this function may
   3287 * return %NULL.</note>
   3288 *
   3289 * Return value is valid as long as variation coordinates of the font
   3290 * are not modified.
   3291 *
   3292 * Return value: coordinates array
   3293 *
   3294 * Since: 1.4.2
   3295 */
   3296 const int *
   3297 hb_font_get_var_coords_normalized (hb_font_t    *font,
   3298 			   unsigned int *length)
   3299 {
   3300  if (length)
   3301    *length = font->num_coords;
   3302 
   3303  return font->coords;
   3304 }
   3305 
   3306 /**
   3307 * hb_font_get_var_coords_design:
   3308 * @font: #hb_font_t to work upon
   3309 * @length: (out): Number of coordinates retrieved
   3310 *
   3311 * Fetches the list of variation coordinates (in design-space units) currently
   3312 * set on a font.
   3313 *
   3314 * <note>Note that if no variation coordinates are set, this function may
   3315 * return %NULL.</note>
   3316 *
   3317 * <note>If variations have been set on the font using normalized coordinates
   3318 * (i.e. via hb_font_set_var_coords_normalized()), the design coordinates will
   3319 * have NaN (Not a Number) values.</note>
   3320 *
   3321 * Return value is valid as long as variation coordinates of the font
   3322 * are not modified.
   3323 *
   3324 * Return value: coordinates array
   3325 *
   3326 * Since: 3.3.0
   3327 */
   3328 const float *
   3329 hb_font_get_var_coords_design (hb_font_t *font,
   3330 		       unsigned int *length)
   3331 {
   3332  if (length)
   3333    *length = font->num_coords;
   3334 
   3335  return font->design_coords;
   3336 }
   3337 #endif
   3338 
   3339 #ifndef HB_DISABLE_DEPRECATED
   3340 /*
   3341 * Deprecated get_glyph_func():
   3342 */
   3343 
   3344 struct hb_trampoline_closure_t
   3345 {
   3346  void *user_data;
   3347  hb_destroy_func_t destroy;
   3348  unsigned int ref_count;
   3349 };
   3350 
   3351 template <typename FuncType>
   3352 struct hb_trampoline_t
   3353 {
   3354  hb_trampoline_closure_t closure; /* Must be first. */
   3355  FuncType func;
   3356 };
   3357 
   3358 template <typename FuncType>
   3359 static hb_trampoline_t<FuncType> *
   3360 trampoline_create (FuncType           func,
   3361 	   void              *user_data,
   3362 	   hb_destroy_func_t  destroy)
   3363 {
   3364  typedef hb_trampoline_t<FuncType> trampoline_t;
   3365 
   3366  trampoline_t *trampoline = (trampoline_t *) hb_calloc (1, sizeof (trampoline_t));
   3367 
   3368  if (unlikely (!trampoline))
   3369    return nullptr;
   3370 
   3371  trampoline->closure.user_data = user_data;
   3372  trampoline->closure.destroy = destroy;
   3373  trampoline->closure.ref_count = 1;
   3374  trampoline->func = func;
   3375 
   3376  return trampoline;
   3377 }
   3378 
   3379 static void
   3380 trampoline_reference (hb_trampoline_closure_t *closure)
   3381 {
   3382  closure->ref_count++;
   3383 }
   3384 
   3385 static void
   3386 trampoline_destroy (void *user_data)
   3387 {
   3388  hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
   3389 
   3390  if (--closure->ref_count)
   3391    return;
   3392 
   3393  if (closure->destroy)
   3394    closure->destroy (closure->user_data);
   3395  hb_free (closure);
   3396 }
   3397 
   3398 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
   3399 
   3400 static hb_bool_t
   3401 hb_font_get_nominal_glyph_trampoline (hb_font_t      *font,
   3402 			      void           *font_data,
   3403 			      hb_codepoint_t  unicode,
   3404 			      hb_codepoint_t *glyph,
   3405 			      void           *user_data)
   3406 {
   3407  hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
   3408  return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
   3409 }
   3410 
   3411 static hb_bool_t
   3412 hb_font_get_variation_glyph_trampoline (hb_font_t      *font,
   3413 				void           *font_data,
   3414 				hb_codepoint_t  unicode,
   3415 				hb_codepoint_t  variation_selector,
   3416 				hb_codepoint_t *glyph,
   3417 				void           *user_data)
   3418 {
   3419  hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
   3420  return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
   3421 }
   3422 
   3423 /**
   3424 * hb_font_funcs_set_glyph_func:
   3425 * @ffuncs: The font-functions structure
   3426 * @func: (closure user_data) (destroy destroy) (scope notified): callback function
   3427 * @user_data: data to pass to @func
   3428 * @destroy: (nullable): function to call when @user_data is not needed anymore
   3429 *
   3430 * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
   3431 * hb_font_funcs_set_variation_glyph_func() instead.
   3432 *
   3433 * Since: 0.9.2
   3434 * Deprecated: 1.2.3
   3435 **/
   3436 void
   3437 hb_font_funcs_set_glyph_func (hb_font_funcs_t          *ffuncs,
   3438 		      hb_font_get_glyph_func_t  func,
   3439 		      void                     *user_data,
   3440 		      hb_destroy_func_t         destroy /* May be NULL. */)
   3441 {
   3442  if (hb_object_is_immutable (ffuncs))
   3443  {
   3444    if (destroy)
   3445      destroy (user_data);
   3446    return;
   3447  }
   3448 
   3449  hb_font_get_glyph_trampoline_t *trampoline;
   3450 
   3451  trampoline = trampoline_create (func, user_data, destroy);
   3452  if (unlikely (!trampoline))
   3453  {
   3454    if (destroy)
   3455      destroy (user_data);
   3456    return;
   3457  }
   3458 
   3459  /* Since we pass it to two destroying functions. */
   3460  trampoline_reference (&trampoline->closure);
   3461 
   3462  hb_font_funcs_set_nominal_glyph_func (ffuncs,
   3463 				hb_font_get_nominal_glyph_trampoline,
   3464 				trampoline,
   3465 				trampoline_destroy);
   3466 
   3467  hb_font_funcs_set_variation_glyph_func (ffuncs,
   3468 				  hb_font_get_variation_glyph_trampoline,
   3469 				  trampoline,
   3470 				  trampoline_destroy);
   3471 }
   3472 #endif
   3473 
   3474 
   3475 #ifndef HB_DISABLE_DEPRECATED
   3476 
   3477 struct hb_draw_glyph_closure_t
   3478 {
   3479  hb_font_draw_glyph_func_t func;
   3480  void *user_data;
   3481  hb_destroy_func_t destroy;
   3482 };
   3483 static hb_bool_t
   3484 hb_font_draw_glyph_trampoline (hb_font_t       *font,
   3485 		       void            *font_data,
   3486 		       hb_codepoint_t   glyph,
   3487 		       hb_draw_funcs_t *draw_funcs,
   3488 		       void            *draw_data,
   3489 		       void            *user_data)
   3490 {
   3491  hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) user_data;
   3492  closure->func (font, font_data, glyph, draw_funcs, draw_data, closure->user_data);
   3493  return true;
   3494 }
   3495 static void
   3496 hb_font_draw_glyph_closure_destroy (void *user_data)
   3497 {
   3498  hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) user_data;
   3499 
   3500  if (closure->destroy)
   3501    closure->destroy (closure->user_data);
   3502  hb_free (closure);
   3503 }
   3504 static void
   3505 _hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t           *ffuncs,
   3506 			    hb_font_draw_glyph_func_t  func,
   3507 			    void                      *user_data,
   3508 			    hb_destroy_func_t          destroy /* May be NULL. */)
   3509 {
   3510  if (hb_object_is_immutable (ffuncs))
   3511  {
   3512    if (destroy)
   3513      destroy (user_data);
   3514    return;
   3515  }
   3516  hb_draw_glyph_closure_t *closure = (hb_draw_glyph_closure_t *) hb_calloc (1, sizeof (hb_draw_glyph_closure_t));
   3517  if (unlikely (!closure))
   3518  {
   3519    if (destroy)
   3520      destroy (user_data);
   3521    return;
   3522  }
   3523  closure->func = func;
   3524  closure->user_data = user_data;
   3525  closure->destroy = destroy;
   3526 
   3527  hb_font_funcs_set_draw_glyph_or_fail_func (ffuncs,
   3528 				     hb_font_draw_glyph_trampoline,
   3529 				     closure,
   3530 				     hb_font_draw_glyph_closure_destroy);
   3531 }
   3532 void
   3533 hb_font_funcs_set_draw_glyph_func (hb_font_funcs_t           *ffuncs,
   3534                                   hb_font_draw_glyph_func_t  func,
   3535                                   void                      *user_data,
   3536                                   hb_destroy_func_t          destroy /* May be NULL. */)
   3537 {
   3538  _hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy);
   3539 }
   3540 void
   3541 hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t               *ffuncs,
   3542                                   hb_font_get_glyph_shape_func_t  func,
   3543                                   void                           *user_data,
   3544                                   hb_destroy_func_t               destroy /* May be NULL. */)
   3545 {
   3546  _hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy);
   3547 }
   3548 
   3549 struct hb_paint_glyph_closure_t
   3550 {
   3551  hb_font_paint_glyph_func_t func;
   3552  void *user_data;
   3553  hb_destroy_func_t destroy;
   3554 };
   3555 static hb_bool_t
   3556 hb_font_paint_glyph_trampoline (hb_font_t        *font,
   3557 			void *font_data,
   3558 			hb_codepoint_t glyph,
   3559 			hb_paint_funcs_t *paint_funcs,
   3560 			void *paint_data,
   3561 			unsigned int palette,
   3562 			hb_color_t foreground,
   3563 			void *user_data)
   3564 {
   3565  hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) user_data;
   3566  closure->func (font, font_data, glyph, paint_funcs, paint_data, palette, foreground, closure->user_data);
   3567  return true;
   3568 }
   3569 static void
   3570 hb_font_paint_glyph_closure_destroy (void *user_data)
   3571 {
   3572  hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) user_data;
   3573 
   3574  if (closure->destroy)
   3575    closure->destroy (closure->user_data);
   3576  hb_free (closure);
   3577 }
   3578 void
   3579 hb_font_funcs_set_paint_glyph_func (hb_font_funcs_t           *ffuncs,
   3580 			    hb_font_paint_glyph_func_t  func,
   3581 			    void                      *user_data,
   3582 			    hb_destroy_func_t          destroy /* May be NULL. */)
   3583 {
   3584  if (hb_object_is_immutable (ffuncs))
   3585  {
   3586    if (destroy)
   3587      destroy (user_data);
   3588    return;
   3589  }
   3590  hb_paint_glyph_closure_t *closure = (hb_paint_glyph_closure_t *) hb_calloc (1, sizeof (hb_paint_glyph_closure_t));
   3591  if (unlikely (!closure))
   3592  {
   3593    if (destroy)
   3594      destroy (user_data);
   3595    return;
   3596  }
   3597  closure->func = func;
   3598  closure->user_data = user_data;
   3599  closure->destroy = destroy;
   3600 
   3601  hb_font_funcs_set_paint_glyph_or_fail_func (ffuncs,
   3602 				      hb_font_paint_glyph_trampoline,
   3603 				      closure,
   3604 				      hb_font_paint_glyph_closure_destroy);
   3605 }
   3606 #endif