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