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