Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2009  Red Hat, Inc.
      3  * Copyright  2012  Google, Inc.
      4  *
      5  *  This is part of HarfBuzz, a text shaping library.
      6  *
      7  * Permission is hereby granted, without written agreement and without
      8  * license or royalty fees, to use, copy, modify, and distribute this
      9  * software and its documentation for any purpose, provided that the
     10  * above copyright notice and the following two paragraphs appear in
     11  * all copies of this software.
     12  *
     13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     17  * DAMAGE.
     18  *
     19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     24  *
     25  * Red Hat Author(s): Behdad Esfahbod
     26  * Google Author(s): Behdad Esfahbod
     27  */
     28 
     29 #include "hb-private.hh"
     30 
     31 #include "hb-ot-layout-private.hh"
     32 
     33 #include "hb-font-private.hh"
     34 #include "hb-open-file-private.hh"
     35 #include "hb-ot-head-table.hh"
     36 #include "hb-ot-maxp-table.hh"
     37 
     38 #include "hb-cache-private.hh"
     39 
     40 #include <string.h>
     41 
     42 
     43 /*
     44  * hb_font_funcs_t
     45  */
     46 
     47 static hb_bool_t
     48 hb_font_get_glyph_nil (hb_font_t *font,
     49 		       void *font_data HB_UNUSED,
     50 		       hb_codepoint_t unicode,
     51 		       hb_codepoint_t variation_selector,
     52 		       hb_codepoint_t *glyph,
     53 		       void *user_data HB_UNUSED)
     54 {
     55   if (font->parent)
     56     return font->parent->get_glyph (unicode, variation_selector, glyph);
     57 
     58   *glyph = 0;
     59   return false;
     60 }
     61 
     62 static hb_position_t
     63 hb_font_get_glyph_h_advance_nil (hb_font_t *font,
     64 				 void *font_data HB_UNUSED,
     65 				 hb_codepoint_t glyph,
     66 				 void *user_data HB_UNUSED)
     67 {
     68   if (font->parent)
     69     return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
     70 
     71   return font->x_scale;
     72 }
     73 
     74 static hb_position_t
     75 hb_font_get_glyph_v_advance_nil (hb_font_t *font,
     76 				 void *font_data HB_UNUSED,
     77 				 hb_codepoint_t glyph,
     78 				 void *user_data HB_UNUSED)
     79 {
     80   if (font->parent)
     81     return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
     82 
     83   return font->y_scale;
     84 }
     85 
     86 static hb_bool_t
     87 hb_font_get_glyph_h_origin_nil (hb_font_t *font,
     88 				void *font_data HB_UNUSED,
     89 				hb_codepoint_t glyph,
     90 				hb_position_t *x,
     91 				hb_position_t *y,
     92 				void *user_data HB_UNUSED)
     93 {
     94   if (font->parent) {
     95     hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
     96     if (ret)
     97       font->parent_scale_position (x, y);
     98     return ret;
     99   }
    100 
    101   *x = *y = 0;
    102   return false;
    103 }
    104 
    105 static hb_bool_t
    106 hb_font_get_glyph_v_origin_nil (hb_font_t *font,
    107 				void *font_data HB_UNUSED,
    108 				hb_codepoint_t glyph,
    109 				hb_position_t *x,
    110 				hb_position_t *y,
    111 				void *user_data HB_UNUSED)
    112 {
    113   if (font->parent) {
    114     hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
    115     if (ret)
    116       font->parent_scale_position (x, y);
    117     return ret;
    118   }
    119 
    120   *x = *y = 0;
    121   return false;
    122 }
    123 
    124 static hb_position_t
    125 hb_font_get_glyph_h_kerning_nil (hb_font_t *font,
    126 				 void *font_data HB_UNUSED,
    127 				 hb_codepoint_t left_glyph,
    128 				 hb_codepoint_t right_glyph,
    129 				 void *user_data HB_UNUSED)
    130 {
    131   if (font->parent)
    132     return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
    133 
    134   return 0;
    135 }
    136 
    137 static hb_position_t
    138 hb_font_get_glyph_v_kerning_nil (hb_font_t *font,
    139 				 void *font_data HB_UNUSED,
    140 				 hb_codepoint_t top_glyph,
    141 				 hb_codepoint_t bottom_glyph,
    142 				 void *user_data HB_UNUSED)
    143 {
    144   if (font->parent)
    145     return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
    146 
    147   return 0;
    148 }
    149 
    150 static hb_bool_t
    151 hb_font_get_glyph_extents_nil (hb_font_t *font,
    152 			       void *font_data HB_UNUSED,
    153 			       hb_codepoint_t glyph,
    154 			       hb_glyph_extents_t *extents,
    155 			       void *user_data HB_UNUSED)
    156 {
    157   if (font->parent) {
    158     hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
    159     if (ret) {
    160       font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
    161       font->parent_scale_distance (&extents->width, &extents->height);
    162     }
    163     return ret;
    164   }
    165 
    166   memset (extents, 0, sizeof (*extents));
    167   return false;
    168 }
    169 
    170 static hb_bool_t
    171 hb_font_get_glyph_contour_point_nil (hb_font_t *font,
    172 				     void *font_data HB_UNUSED,
    173 				     hb_codepoint_t glyph,
    174 				     unsigned int point_index,
    175 				     hb_position_t *x,
    176 				     hb_position_t *y,
    177 				     void *user_data HB_UNUSED)
    178 {
    179   if (font->parent) {
    180     hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
    181     if (ret)
    182       font->parent_scale_position (x, y);
    183     return ret;
    184   }
    185 
    186   *x = *y = 0;
    187   return false;
    188 }
    189 
    190 static hb_bool_t
    191 hb_font_get_glyph_name_nil (hb_font_t *font,
    192 			    void *font_data HB_UNUSED,
    193 			    hb_codepoint_t glyph,
    194 			    char *name, unsigned int size,
    195 			    void *user_data HB_UNUSED)
    196 {
    197   if (font->parent)
    198     return font->parent->get_glyph_name (glyph, name, size);
    199 
    200   if (size) *name = '\0';
    201   return false;
    202 }
    203 
    204 static hb_bool_t
    205 hb_font_get_glyph_from_name_nil (hb_font_t *font,
    206 				 void *font_data HB_UNUSED,
    207 				 const char *name, int len, /* -1 means nul-terminated */
    208 				 hb_codepoint_t *glyph,
    209 				 void *user_data HB_UNUSED)
    210 {
    211   if (font->parent)
    212     return font->parent->get_glyph_from_name (name, len, glyph);
    213 
    214   *glyph = 0;
    215   return false;
    216 }
    217 
    218 
    219 static const hb_font_funcs_t _hb_font_funcs_nil = {
    220   HB_OBJECT_HEADER_STATIC,
    221 
    222   true, /* immutable */
    223 
    224   {
    225 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
    226     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    227 #undef HB_FONT_FUNC_IMPLEMENT
    228   }
    229 };
    230 
    231 
    232 /**
    233  * hb_font_funcs_create: (Xconstructor)
    234  *
    235  *
    236  *
    237  * Return value: (transfer full):
    238  *
    239  * Since: 1.0
    240  **/
    241 hb_font_funcs_t *
    242 hb_font_funcs_create (void)
    243 {
    244   hb_font_funcs_t *ffuncs;
    245 
    246   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
    247     return hb_font_funcs_get_empty ();
    248 
    249   ffuncs->get = _hb_font_funcs_nil.get;
    250 
    251   return ffuncs;
    252 }
    253 
    254 /**
    255  * hb_font_funcs_get_empty:
    256  *
    257  *
    258  *
    259  * Return value: (transfer full):
    260  *
    261  * Since: 1.0
    262  **/
    263 hb_font_funcs_t *
    264 hb_font_funcs_get_empty (void)
    265 {
    266   return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
    267 }
    268 
    269 /**
    270  * hb_font_funcs_reference: (skip)
    271  * @ffuncs: font functions.
    272  *
    273  *
    274  *
    275  * Return value:
    276  *
    277  * Since: 1.0
    278  **/
    279 hb_font_funcs_t *
    280 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
    281 {
    282   return hb_object_reference (ffuncs);
    283 }
    284 
    285 /**
    286  * hb_font_funcs_destroy: (skip)
    287  * @ffuncs: font functions.
    288  *
    289  *
    290  *
    291  * Since: 1.0
    292  **/
    293 void
    294 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
    295 {
    296   if (!hb_object_destroy (ffuncs)) return;
    297 
    298 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
    299   ffuncs->destroy.name (ffuncs->user_data.name);
    300   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    301 #undef HB_FONT_FUNC_IMPLEMENT
    302 
    303   free (ffuncs);
    304 }
    305 
    306 /**
    307  * hb_font_funcs_set_user_data: (skip)
    308  * @ffuncs: font functions.
    309  * @key:
    310  * @data:
    311  * @destroy:
    312  * @replace:
    313  *
    314  *
    315  *
    316  * Return value:
    317  *
    318  * Since: 1.0
    319  **/
    320 hb_bool_t
    321 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
    322 			     hb_user_data_key_t *key,
    323 			     void *              data,
    324 			     hb_destroy_func_t   destroy,
    325 			     hb_bool_t           replace)
    326 {
    327   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
    328 }
    329 
    330 /**
    331  * hb_font_funcs_get_user_data: (skip)
    332  * @ffuncs: font functions.
    333  * @key:
    334  *
    335  *
    336  *
    337  * Return value: (transfer none):
    338  *
    339  * Since: 1.0
    340  **/
    341 void *
    342 hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
    343 			     hb_user_data_key_t *key)
    344 {
    345   return hb_object_get_user_data (ffuncs, key);
    346 }
    347 
    348 
    349 /**
    350  * hb_font_funcs_make_immutable:
    351  * @ffuncs: font functions.
    352  *
    353  *
    354  *
    355  * Since: 1.0
    356  **/
    357 void
    358 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
    359 {
    360   if (unlikely (hb_object_is_inert (ffuncs)))
    361     return;
    362 
    363   ffuncs->immutable = true;
    364 }
    365 
    366 /**
    367  * hb_font_funcs_is_immutable:
    368  * @ffuncs: font functions.
    369  *
    370  *
    371  *
    372  * Return value:
    373  *
    374  * Since: 1.0
    375  **/
    376 hb_bool_t
    377 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
    378 {
    379   return ffuncs->immutable;
    380 }
    381 
    382 
    383 #define HB_FONT_FUNC_IMPLEMENT(name) \
    384                                                                          \
    385 void                                                                     \
    386 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
    387                                  hb_font_get_##name##_func_t  func,      \
    388                                  void                        *user_data, \
    389                                  hb_destroy_func_t            destroy)   \
    390 {                                                                        \
    391   if (ffuncs->immutable) {                                               \
    392     if (destroy)                                                         \
    393       destroy (user_data);                                               \
    394     return;                                                              \
    395   }                                                                      \
    396                                                                          \
    397   if (ffuncs->destroy.name)                                              \
    398     ffuncs->destroy.name (ffuncs->user_data.name);                       \
    399                                                                          \
    400   if (func) {                                                            \
    401     ffuncs->get.name = func;                                             \
    402     ffuncs->user_data.name = user_data;                                  \
    403     ffuncs->destroy.name = destroy;                                      \
    404   } else {                                                               \
    405     ffuncs->get.name = hb_font_get_##name##_nil;                         \
    406     ffuncs->user_data.name = NULL;                                       \
    407     ffuncs->destroy.name = NULL;                                         \
    408   }                                                                      \
    409 }
    410 
    411 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
    412 #undef HB_FONT_FUNC_IMPLEMENT
    413 
    414 
    415 /* Public getters */
    416 
    417 /**
    418  * hb_font_get_glyph:
    419  * @font: a font.
    420  * @unicode:
    421  * @variation_selector:
    422  * @glyph: (out):
    423  *
    424  *
    425  *
    426  * Return value:
    427  *
    428  * Since: 1.0
    429  **/
    430 hb_bool_t
    431 hb_font_get_glyph (hb_font_t *font,
    432 		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
    433 		   hb_codepoint_t *glyph)
    434 {
    435   return font->get_glyph (unicode, variation_selector, glyph);
    436 }
    437 
    438 /**
    439  * hb_font_get_glyph_h_advance:
    440  * @font: a font.
    441  * @glyph:
    442  *
    443  *
    444  *
    445  * Return value:
    446  *
    447  * Since: 1.0
    448  **/
    449 hb_position_t
    450 hb_font_get_glyph_h_advance (hb_font_t *font,
    451 			     hb_codepoint_t glyph)
    452 {
    453   return font->get_glyph_h_advance (glyph);
    454 }
    455 
    456 /**
    457  * hb_font_get_glyph_v_advance:
    458  * @font: a font.
    459  * @glyph:
    460  *
    461  *
    462  *
    463  * Return value:
    464  *
    465  * Since: 1.0
    466  **/
    467 hb_position_t
    468 hb_font_get_glyph_v_advance (hb_font_t *font,
    469 			     hb_codepoint_t glyph)
    470 {
    471   return font->get_glyph_v_advance (glyph);
    472 }
    473 
    474 /**
    475  * hb_font_get_glyph_h_origin:
    476  * @font: a font.
    477  * @glyph:
    478  * @x: (out):
    479  * @y: (out):
    480  *
    481  *
    482  *
    483  * Return value:
    484  *
    485  * Since: 1.0
    486  **/
    487 hb_bool_t
    488 hb_font_get_glyph_h_origin (hb_font_t *font,
    489 			    hb_codepoint_t glyph,
    490 			    hb_position_t *x, hb_position_t *y)
    491 {
    492   return font->get_glyph_h_origin (glyph, x, y);
    493 }
    494 
    495 /**
    496  * hb_font_get_glyph_v_origin:
    497  * @font: a font.
    498  * @glyph:
    499  * @x: (out):
    500  * @y: (out):
    501  *
    502  *
    503  *
    504  * Return value:
    505  *
    506  * Since: 1.0
    507  **/
    508 hb_bool_t
    509 hb_font_get_glyph_v_origin (hb_font_t *font,
    510 			    hb_codepoint_t glyph,
    511 			    hb_position_t *x, hb_position_t *y)
    512 {
    513   return font->get_glyph_v_origin (glyph, x, y);
    514 }
    515 
    516 /**
    517  * hb_font_get_glyph_h_kerning:
    518  * @font: a font.
    519  * @left_glyph:
    520  * @right_glyph:
    521  *
    522  *
    523  *
    524  * Return value:
    525  *
    526  * Since: 1.0
    527  **/
    528 hb_position_t
    529 hb_font_get_glyph_h_kerning (hb_font_t *font,
    530 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
    531 {
    532   return font->get_glyph_h_kerning (left_glyph, right_glyph);
    533 }
    534 
    535 /**
    536  * hb_font_get_glyph_v_kerning:
    537  * @font: a font.
    538  * @top_glyph:
    539  * @bottom_glyph:
    540  *
    541  *
    542  *
    543  * Return value:
    544  *
    545  * Since: 1.0
    546  **/
    547 hb_position_t
    548 hb_font_get_glyph_v_kerning (hb_font_t *font,
    549 			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
    550 {
    551   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
    552 }
    553 
    554 /**
    555  * hb_font_get_glyph_extents:
    556  * @font: a font.
    557  * @glyph:
    558  * @extents: (out):
    559  *
    560  *
    561  *
    562  * Return value:
    563  *
    564  * Since: 1.0
    565  **/
    566 hb_bool_t
    567 hb_font_get_glyph_extents (hb_font_t *font,
    568 			   hb_codepoint_t glyph,
    569 			   hb_glyph_extents_t *extents)
    570 {
    571   return font->get_glyph_extents (glyph, extents);
    572 }
    573 
    574 /**
    575  * hb_font_get_glyph_contour_point:
    576  * @font: a font.
    577  * @glyph:
    578  * @point_index:
    579  * @x: (out):
    580  * @y: (out):
    581  *
    582  *
    583  *
    584  * Return value:
    585  *
    586  * Since: 1.0
    587  **/
    588 hb_bool_t
    589 hb_font_get_glyph_contour_point (hb_font_t *font,
    590 				 hb_codepoint_t glyph, unsigned int point_index,
    591 				 hb_position_t *x, hb_position_t *y)
    592 {
    593   return font->get_glyph_contour_point (glyph, point_index, x, y);
    594 }
    595 
    596 /**
    597  * hb_font_get_glyph_name:
    598  * @font: a font.
    599  * @glyph:
    600  * @name: (array length=size):
    601  * @size:
    602  *
    603  *
    604  *
    605  * Return value:
    606  *
    607  * Since: 1.0
    608  **/
    609 hb_bool_t
    610 hb_font_get_glyph_name (hb_font_t *font,
    611 			hb_codepoint_t glyph,
    612 			char *name, unsigned int size)
    613 {
    614   return font->get_glyph_name (glyph, name, size);
    615 }
    616 
    617 /**
    618  * hb_font_get_glyph_from_name:
    619  * @font: a font.
    620  * @name: (array length=len):
    621  * @len:
    622  * @glyph: (out):
    623  *
    624  *
    625  *
    626  * Return value:
    627  *
    628  * Since: 1.0
    629  **/
    630 hb_bool_t
    631 hb_font_get_glyph_from_name (hb_font_t *font,
    632 			     const char *name, int len, /* -1 means nul-terminated */
    633 			     hb_codepoint_t *glyph)
    634 {
    635   return font->get_glyph_from_name (name, len, glyph);
    636 }
    637 
    638 
    639 /* A bit higher-level, and with fallback */
    640 
    641 /**
    642  * hb_font_get_glyph_advance_for_direction:
    643  * @font: a font.
    644  * @glyph:
    645  * @direction:
    646  * @x: (out):
    647  * @y: (out):
    648  *
    649  *
    650  *
    651  * Since: 1.0
    652  **/
    653 void
    654 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
    655 					 hb_codepoint_t glyph,
    656 					 hb_direction_t direction,
    657 					 hb_position_t *x, hb_position_t *y)
    658 {
    659   return font->get_glyph_advance_for_direction (glyph, direction, x, y);
    660 }
    661 
    662 /**
    663  * hb_font_get_glyph_origin_for_direction:
    664  * @font: a font.
    665  * @glyph:
    666  * @direction:
    667  * @x: (out):
    668  * @y: (out):
    669  *
    670  *
    671  *
    672  * Since: 1.0
    673  **/
    674 void
    675 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
    676 					hb_codepoint_t glyph,
    677 					hb_direction_t direction,
    678 					hb_position_t *x, hb_position_t *y)
    679 {
    680   return font->get_glyph_origin_for_direction (glyph, direction, x, y);
    681 }
    682 
    683 /**
    684  * hb_font_add_glyph_origin_for_direction:
    685  * @font: a font.
    686  * @glyph:
    687  * @direction:
    688  * @x: (out):
    689  * @y: (out):
    690  *
    691  *
    692  *
    693  * Since: 1.0
    694  **/
    695 void
    696 hb_font_add_glyph_origin_for_direction (hb_font_t *font,
    697 					hb_codepoint_t glyph,
    698 					hb_direction_t direction,
    699 					hb_position_t *x, hb_position_t *y)
    700 {
    701   return font->add_glyph_origin_for_direction (glyph, direction, x, y);
    702 }
    703 
    704 /**
    705  * hb_font_subtract_glyph_origin_for_direction:
    706  * @font: a font.
    707  * @glyph:
    708  * @direction:
    709  * @x: (out):
    710  * @y: (out):
    711  *
    712  *
    713  *
    714  * Since: 1.0
    715  **/
    716 void
    717 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
    718 					     hb_codepoint_t glyph,
    719 					     hb_direction_t direction,
    720 					     hb_position_t *x, hb_position_t *y)
    721 {
    722   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
    723 }
    724 
    725 /**
    726  * hb_font_get_glyph_kerning_for_direction:
    727  * @font: a font.
    728  * @first_glyph:
    729  * @second_glyph:
    730  * @direction:
    731  * @x: (out):
    732  * @y: (out):
    733  *
    734  *
    735  *
    736  * Since: 1.0
    737  **/
    738 void
    739 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
    740 					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
    741 					 hb_direction_t direction,
    742 					 hb_position_t *x, hb_position_t *y)
    743 {
    744   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
    745 }
    746 
    747 /**
    748  * hb_font_get_glyph_extents_for_origin:
    749  * @font: a font.
    750  * @glyph:
    751  * @direction:
    752  * @extents: (out):
    753  *
    754  *
    755  *
    756  * Return value:
    757  *
    758  * Since: 1.0
    759  **/
    760 hb_bool_t
    761 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
    762 				      hb_codepoint_t glyph,
    763 				      hb_direction_t direction,
    764 				      hb_glyph_extents_t *extents)
    765 {
    766   return font->get_glyph_extents_for_origin (glyph, direction, extents);
    767 }
    768 
    769 /**
    770  * hb_font_get_glyph_contour_point_for_origin:
    771  * @font: a font.
    772  * @glyph:
    773  * @point_index:
    774  * @direction:
    775  * @x: (out):
    776  * @y: (out):
    777  *
    778  *
    779  *
    780  * Return value:
    781  *
    782  * Since: 1.0
    783  **/
    784 hb_bool_t
    785 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
    786 					    hb_codepoint_t glyph, unsigned int point_index,
    787 					    hb_direction_t direction,
    788 					    hb_position_t *x, hb_position_t *y)
    789 {
    790   return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
    791 }
    792 
    793 /* Generates gidDDD if glyph has no name. */
    794 /**
    795  * hb_font_glyph_to_string:
    796  * @font: a font.
    797  * @glyph:
    798  * @s: (array length=size):
    799  * @size:
    800  *
    801  *
    802  *
    803  * Since: 1.0
    804  **/
    805 void
    806 hb_font_glyph_to_string (hb_font_t *font,
    807 			 hb_codepoint_t glyph,
    808 			 char *s, unsigned int size)
    809 {
    810   font->glyph_to_string (glyph, s, size);
    811 }
    812 
    813 /* Parses gidDDD and uniUUUU strings automatically. */
    814 /**
    815  * hb_font_glyph_from_string:
    816  * @font: a font.
    817  * @s: (array length=len):
    818  * @len:
    819  * @glyph: (out):
    820  *
    821  *
    822  *
    823  * Return value:
    824  *
    825  * Since: 1.0
    826  **/
    827 hb_bool_t
    828 hb_font_glyph_from_string (hb_font_t *font,
    829 			   const char *s, int len, /* -1 means nul-terminated */
    830 			   hb_codepoint_t *glyph)
    831 {
    832   return font->glyph_from_string (s, len, glyph);
    833 }
    834 
    835 
    836 /*
    837  * hb_font_t
    838  */
    839 
    840 /**
    841  * hb_font_create: (Xconstructor)
    842  * @face: a face.
    843  *
    844  *
    845  *
    846  * Return value: (transfer full):
    847  *
    848  * Since: 1.0
    849  **/
    850 hb_font_t *
    851 hb_font_create (hb_face_t *face)
    852 {
    853   hb_font_t *font;
    854 
    855   if (unlikely (!face))
    856     face = hb_face_get_empty ();
    857   if (unlikely (hb_object_is_inert (face)))
    858     return hb_font_get_empty ();
    859   if (!(font = hb_object_create<hb_font_t> ()))
    860     return hb_font_get_empty ();
    861 
    862   hb_face_make_immutable (face);
    863   font->face = hb_face_reference (face);
    864   font->klass = hb_font_funcs_get_empty ();
    865 
    866   return font;
    867 }
    868 
    869 /**
    870  * hb_font_create_sub_font:
    871  * @parent: parent font.
    872  *
    873  *
    874  *
    875  * Return value: (transfer full):
    876  *
    877  * Since: 1.0
    878  **/
    879 hb_font_t *
    880 hb_font_create_sub_font (hb_font_t *parent)
    881 {
    882   if (unlikely (!parent))
    883     return hb_font_get_empty ();
    884 
    885   hb_font_t *font = hb_font_create (parent->face);
    886 
    887   if (unlikely (hb_object_is_inert (font)))
    888     return font;
    889 
    890   hb_font_make_immutable (parent);
    891   font->parent = hb_font_reference (parent);
    892 
    893   font->x_scale = parent->x_scale;
    894   font->y_scale = parent->y_scale;
    895   font->x_ppem = parent->x_ppem;
    896   font->y_ppem = parent->y_ppem;
    897 
    898   return font;
    899 }
    900 
    901 /**
    902  * hb_font_get_empty:
    903  *
    904  *
    905  *
    906  * Return value: (transfer full)
    907  *
    908  * Since: 1.0
    909  **/
    910 hb_font_t *
    911 hb_font_get_empty (void)
    912 {
    913   static const hb_font_t _hb_font_nil = {
    914     HB_OBJECT_HEADER_STATIC,
    915 
    916     true, /* immutable */
    917 
    918     NULL, /* parent */
    919     const_cast<hb_face_t *> (&_hb_face_nil),
    920 
    921     0, /* x_scale */
    922     0, /* y_scale */
    923 
    924     0, /* x_ppem */
    925     0, /* y_ppem */
    926 
    927     const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
    928     NULL, /* user_data */
    929     NULL, /* destroy */
    930 
    931     {
    932 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
    933 #include "hb-shaper-list.hh"
    934 #undef HB_SHAPER_IMPLEMENT
    935     }
    936   };
    937 
    938   return const_cast<hb_font_t *> (&_hb_font_nil);
    939 }
    940 
    941 /**
    942  * hb_font_reference: (skip)
    943  * @font: a font.
    944  *
    945  *
    946  *
    947  * Return value: (transfer full):
    948  *
    949  * Since: 1.0
    950  **/
    951 hb_font_t *
    952 hb_font_reference (hb_font_t *font)
    953 {
    954   return hb_object_reference (font);
    955 }
    956 
    957 /**
    958  * hb_font_destroy: (skip)
    959  * @font: a font.
    960  *
    961  *
    962  *
    963  * Since: 1.0
    964  **/
    965 void
    966 hb_font_destroy (hb_font_t *font)
    967 {
    968   if (!hb_object_destroy (font)) return;
    969 
    970 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
    971 #include "hb-shaper-list.hh"
    972 #undef HB_SHAPER_IMPLEMENT
    973 
    974   if (font->destroy)
    975     font->destroy (font->user_data);
    976 
    977   hb_font_destroy (font->parent);
    978   hb_face_destroy (font->face);
    979   hb_font_funcs_destroy (font->klass);
    980 
    981   free (font);
    982 }
    983 
    984 /**
    985  * hb_font_set_user_data: (skip)
    986  * @font: a font.
    987  * @key:
    988  * @data:
    989  * @destroy:
    990  * @replace:
    991  *
    992  *
    993  *
    994  * Return value:
    995  *
    996  * Since: 1.0
    997  **/
    998 hb_bool_t
    999 hb_font_set_user_data (hb_font_t          *font,
   1000 		       hb_user_data_key_t *key,
   1001 		       void *              data,
   1002 		       hb_destroy_func_t   destroy,
   1003 		       hb_bool_t           replace)
   1004 {
   1005   return hb_object_set_user_data (font, key, data, destroy, replace);
   1006 }
   1007 
   1008 /**
   1009  * hb_font_get_user_data: (skip)
   1010  * @font: a font.
   1011  * @key:
   1012  *
   1013  *
   1014  *
   1015  * Return value: (transfer none):
   1016  *
   1017  * Since: 1.0
   1018  **/
   1019 void *
   1020 hb_font_get_user_data (hb_font_t          *font,
   1021 		       hb_user_data_key_t *key)
   1022 {
   1023   return hb_object_get_user_data (font, key);
   1024 }
   1025 
   1026 /**
   1027  * hb_font_make_immutable:
   1028  * @font: a font.
   1029  *
   1030  *
   1031  *
   1032  * Since: 1.0
   1033  **/
   1034 void
   1035 hb_font_make_immutable (hb_font_t *font)
   1036 {
   1037   if (unlikely (hb_object_is_inert (font)))
   1038     return;
   1039 
   1040   font->immutable = true;
   1041 }
   1042 
   1043 /**
   1044  * hb_font_is_immutable:
   1045  * @font: a font.
   1046  *
   1047  *
   1048  *
   1049  * Return value:
   1050  *
   1051  * Since: 1.0
   1052  **/
   1053 hb_bool_t
   1054 hb_font_is_immutable (hb_font_t *font)
   1055 {
   1056   return font->immutable;
   1057 }
   1058 
   1059 /**
   1060  * hb_font_get_parent:
   1061  * @font: a font.
   1062  *
   1063  *
   1064  *
   1065  * Return value: (transfer none):
   1066  *
   1067  * Since: 1.0
   1068  **/
   1069 hb_font_t *
   1070 hb_font_get_parent (hb_font_t *font)
   1071 {
   1072   return font->parent;
   1073 }
   1074 
   1075 /**
   1076  * hb_font_get_face:
   1077  * @font: a font.
   1078  *
   1079  *
   1080  *
   1081  * Return value: (transfer none):
   1082  *
   1083  * Since: 1.0
   1084  **/
   1085 hb_face_t *
   1086 hb_font_get_face (hb_font_t *font)
   1087 {
   1088   return font->face;
   1089 }
   1090 
   1091 
   1092 /**
   1093  * hb_font_set_funcs:
   1094  * @font: a font.
   1095  * @klass: (closure font_data) (destroy destroy) (scope notified):
   1096  * @font_data:
   1097  * @destroy:
   1098  *
   1099  *
   1100  *
   1101  * Since: 1.0
   1102  **/
   1103 void
   1104 hb_font_set_funcs (hb_font_t         *font,
   1105 		   hb_font_funcs_t   *klass,
   1106 		   void              *font_data,
   1107 		   hb_destroy_func_t  destroy)
   1108 {
   1109   if (font->immutable) {
   1110     if (destroy)
   1111       destroy (font_data);
   1112     return;
   1113   }
   1114 
   1115   if (font->destroy)
   1116     font->destroy (font->user_data);
   1117 
   1118   if (!klass)
   1119     klass = hb_font_funcs_get_empty ();
   1120 
   1121   hb_font_funcs_reference (klass);
   1122   hb_font_funcs_destroy (font->klass);
   1123   font->klass = klass;
   1124   font->user_data = font_data;
   1125   font->destroy = destroy;
   1126 }
   1127 
   1128 /**
   1129  * hb_font_set_funcs_data:
   1130  * @font: a font.
   1131  * @font_data: (destroy destroy) (scope notified):
   1132  * @destroy:
   1133  *
   1134  *
   1135  *
   1136  * Since: 1.0
   1137  **/
   1138 void
   1139 hb_font_set_funcs_data (hb_font_t         *font,
   1140 		        void              *font_data,
   1141 		        hb_destroy_func_t  destroy)
   1142 {
   1143   /* Destroy user_data? */
   1144   if (font->immutable) {
   1145     if (destroy)
   1146       destroy (font_data);
   1147     return;
   1148   }
   1149 
   1150   if (font->destroy)
   1151     font->destroy (font->user_data);
   1152 
   1153   font->user_data = font_data;
   1154   font->destroy = destroy;
   1155 }
   1156 
   1157 
   1158 /**
   1159  * hb_font_set_scale:
   1160  * @font: a font.
   1161  * @x_scale:
   1162  * @y_scale:
   1163  *
   1164  *
   1165  *
   1166  * Since: 1.0
   1167  **/
   1168 void
   1169 hb_font_set_scale (hb_font_t *font,
   1170 		   int x_scale,
   1171 		   int y_scale)
   1172 {
   1173   if (font->immutable)
   1174     return;
   1175 
   1176   font->x_scale = x_scale;
   1177   font->y_scale = y_scale;
   1178 }
   1179 
   1180 /**
   1181  * hb_font_get_scale:
   1182  * @font: a font.
   1183  * @x_scale: (out):
   1184  * @y_scale: (out):
   1185  *
   1186  *
   1187  *
   1188  * Since: 1.0
   1189  **/
   1190 void
   1191 hb_font_get_scale (hb_font_t *font,
   1192 		   int *x_scale,
   1193 		   int *y_scale)
   1194 {
   1195   if (x_scale) *x_scale = font->x_scale;
   1196   if (y_scale) *y_scale = font->y_scale;
   1197 }
   1198 
   1199 /**
   1200  * hb_font_set_ppem:
   1201  * @font: a font.
   1202  * @x_ppem:
   1203  * @y_ppem:
   1204  *
   1205  *
   1206  *
   1207  * Since: 1.0
   1208  **/
   1209 void
   1210 hb_font_set_ppem (hb_font_t *font,
   1211 		  unsigned int x_ppem,
   1212 		  unsigned int y_ppem)
   1213 {
   1214   if (font->immutable)
   1215     return;
   1216 
   1217   font->x_ppem = x_ppem;
   1218   font->y_ppem = y_ppem;
   1219 }
   1220 
   1221 /**
   1222  * hb_font_get_ppem:
   1223  * @font: a font.
   1224  * @x_ppem: (out):
   1225  * @y_ppem: (out):
   1226  *
   1227  *
   1228  *
   1229  * Since: 1.0
   1230  **/
   1231 void
   1232 hb_font_get_ppem (hb_font_t *font,
   1233 		  unsigned int *x_ppem,
   1234 		  unsigned int *y_ppem)
   1235 {
   1236   if (x_ppem) *x_ppem = font->x_ppem;
   1237   if (y_ppem) *y_ppem = font->y_ppem;
   1238 }
   1239