Imported Upstream version 3.4.0
[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.hh"
30
31 #include "hb-font.hh"
32 #include "hb-machinery.hh"
33
34 #include "hb-ot.h"
35
36 #include "hb-ot-var-avar-table.hh"
37 #include "hb-ot-var-fvar-table.hh"
38
39
40 /**
41  * SECTION:hb-font
42  * @title: hb-font
43  * @short_description: Font objects
44  * @include: hb.h
45  *
46  * Functions for working with font objects.
47  *
48  * A font object represents a font face at a specific size and with
49  * certain other parameters (pixels-per-em, points-per-em, variation
50  * settings) specified. Font objects are created from font face
51  * objects, and are used as input to hb_shape(), among other things.
52  *
53  * Client programs can optionally pass in their own functions that
54  * implement the basic, lower-level queries of font objects. This set
55  * of font functions is defined by the virtual methods in
56  * #hb_font_funcs_t.
57  *
58  * HarfBuzz provides a built-in set of lightweight default
59  * functions for each method in #hb_font_funcs_t.
60  **/
61
62
63 /*
64  * hb_font_funcs_t
65  */
66
67 static hb_bool_t
68 hb_font_get_font_h_extents_nil (hb_font_t         *font HB_UNUSED,
69                                 void              *font_data HB_UNUSED,
70                                 hb_font_extents_t *extents,
71                                 void              *user_data HB_UNUSED)
72 {
73   memset (extents, 0, sizeof (*extents));
74   return false;
75 }
76
77 static hb_bool_t
78 hb_font_get_font_h_extents_default (hb_font_t         *font,
79                                     void              *font_data HB_UNUSED,
80                                     hb_font_extents_t *extents,
81                                     void              *user_data HB_UNUSED)
82 {
83   hb_bool_t ret = font->parent->get_font_h_extents (extents);
84   if (ret) {
85     extents->ascender = font->parent_scale_y_distance (extents->ascender);
86     extents->descender = font->parent_scale_y_distance (extents->descender);
87     extents->line_gap = font->parent_scale_y_distance (extents->line_gap);
88   }
89   return ret;
90 }
91
92 static hb_bool_t
93 hb_font_get_font_v_extents_nil (hb_font_t         *font HB_UNUSED,
94                                 void              *font_data HB_UNUSED,
95                                 hb_font_extents_t *extents,
96                                 void              *user_data HB_UNUSED)
97 {
98   memset (extents, 0, sizeof (*extents));
99   return false;
100 }
101
102 static hb_bool_t
103 hb_font_get_font_v_extents_default (hb_font_t         *font,
104                                     void              *font_data HB_UNUSED,
105                                     hb_font_extents_t *extents,
106                                     void              *user_data HB_UNUSED)
107 {
108   hb_bool_t ret = font->parent->get_font_v_extents (extents);
109   if (ret) {
110     extents->ascender = font->parent_scale_x_distance (extents->ascender);
111     extents->descender = font->parent_scale_x_distance (extents->descender);
112     extents->line_gap = font->parent_scale_x_distance (extents->line_gap);
113   }
114   return ret;
115 }
116
117 static hb_bool_t
118 hb_font_get_nominal_glyph_nil (hb_font_t      *font HB_UNUSED,
119                                void           *font_data HB_UNUSED,
120                                hb_codepoint_t  unicode HB_UNUSED,
121                                hb_codepoint_t *glyph,
122                                void           *user_data HB_UNUSED)
123 {
124   *glyph = 0;
125   return false;
126 }
127
128 static hb_bool_t
129 hb_font_get_nominal_glyph_default (hb_font_t      *font,
130                                    void           *font_data HB_UNUSED,
131                                    hb_codepoint_t  unicode,
132                                    hb_codepoint_t *glyph,
133                                    void           *user_data HB_UNUSED)
134 {
135   if (font->has_nominal_glyphs_func_set ())
136   {
137     return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0);
138   }
139   return font->parent->get_nominal_glyph (unicode, glyph);
140 }
141
142 #define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
143
144 static unsigned int
145 hb_font_get_nominal_glyphs_default (hb_font_t            *font,
146                                     void                 *font_data HB_UNUSED,
147                                     unsigned int          count,
148                                     const hb_codepoint_t *first_unicode,
149                                     unsigned int          unicode_stride,
150                                     hb_codepoint_t       *first_glyph,
151                                     unsigned int          glyph_stride,
152                                     void                 *user_data HB_UNUSED)
153 {
154   if (font->has_nominal_glyph_func_set ())
155   {
156     for (unsigned int i = 0; i < count; i++)
157     {
158       if (!font->get_nominal_glyph (*first_unicode, first_glyph))
159         return i;
160
161       first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
162       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
163     }
164     return count;
165   }
166
167   return font->parent->get_nominal_glyphs (count,
168                                            first_unicode, unicode_stride,
169                                            first_glyph, glyph_stride);
170 }
171
172 static hb_bool_t
173 hb_font_get_variation_glyph_nil (hb_font_t      *font HB_UNUSED,
174                                  void           *font_data HB_UNUSED,
175                                  hb_codepoint_t  unicode HB_UNUSED,
176                                  hb_codepoint_t  variation_selector HB_UNUSED,
177                                  hb_codepoint_t *glyph,
178                                  void           *user_data HB_UNUSED)
179 {
180   *glyph = 0;
181   return false;
182 }
183
184 static hb_bool_t
185 hb_font_get_variation_glyph_default (hb_font_t      *font,
186                                      void           *font_data HB_UNUSED,
187                                      hb_codepoint_t  unicode,
188                                      hb_codepoint_t  variation_selector,
189                                      hb_codepoint_t *glyph,
190                                      void           *user_data HB_UNUSED)
191 {
192   return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
193 }
194
195
196 static hb_position_t
197 hb_font_get_glyph_h_advance_nil (hb_font_t      *font,
198                                  void           *font_data HB_UNUSED,
199                                  hb_codepoint_t  glyph HB_UNUSED,
200                                  void           *user_data HB_UNUSED)
201 {
202   return font->x_scale;
203 }
204
205 static hb_position_t
206 hb_font_get_glyph_h_advance_default (hb_font_t      *font,
207                                      void           *font_data HB_UNUSED,
208                                      hb_codepoint_t  glyph,
209                                      void           *user_data HB_UNUSED)
210 {
211   if (font->has_glyph_h_advances_func_set ())
212   {
213     hb_position_t ret;
214     font->get_glyph_h_advances (1, &glyph, 0, &ret, 0);
215     return ret;
216   }
217   return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
218 }
219
220 static hb_position_t
221 hb_font_get_glyph_v_advance_nil (hb_font_t      *font,
222                                  void           *font_data HB_UNUSED,
223                                  hb_codepoint_t  glyph HB_UNUSED,
224                                  void           *user_data HB_UNUSED)
225 {
226   /* TODO use font_extents.ascender+descender */
227   return font->y_scale;
228 }
229
230 static hb_position_t
231 hb_font_get_glyph_v_advance_default (hb_font_t      *font,
232                                      void           *font_data HB_UNUSED,
233                                      hb_codepoint_t  glyph,
234                                      void           *user_data HB_UNUSED)
235 {
236   if (font->has_glyph_v_advances_func_set ())
237   {
238     hb_position_t ret;
239     font->get_glyph_v_advances (1, &glyph, 0, &ret, 0);
240     return ret;
241   }
242   return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
243 }
244
245 #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default
246
247 static void
248 hb_font_get_glyph_h_advances_default (hb_font_t*            font,
249                                       void*                 font_data HB_UNUSED,
250                                       unsigned int          count,
251                                       const hb_codepoint_t *first_glyph,
252                                       unsigned int          glyph_stride,
253                                       hb_position_t        *first_advance,
254                                       unsigned int          advance_stride,
255                                       void                 *user_data HB_UNUSED)
256 {
257   if (font->has_glyph_h_advance_func_set ())
258   {
259     for (unsigned int i = 0; i < count; i++)
260     {
261       *first_advance = font->get_glyph_h_advance (*first_glyph);
262       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
263       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
264     }
265     return;
266   }
267
268   font->parent->get_glyph_h_advances (count,
269                                       first_glyph, glyph_stride,
270                                       first_advance, advance_stride);
271   for (unsigned int i = 0; i < count; i++)
272   {
273     *first_advance = font->parent_scale_x_distance (*first_advance);
274     first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
275   }
276 }
277
278 #define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default
279 static void
280 hb_font_get_glyph_v_advances_default (hb_font_t*            font,
281                                       void*                 font_data HB_UNUSED,
282                                       unsigned int          count,
283                                       const hb_codepoint_t *first_glyph,
284                                       unsigned int          glyph_stride,
285                                       hb_position_t        *first_advance,
286                                       unsigned int          advance_stride,
287                                       void                 *user_data HB_UNUSED)
288 {
289   if (font->has_glyph_v_advance_func_set ())
290   {
291     for (unsigned int i = 0; i < count; i++)
292     {
293       *first_advance = font->get_glyph_v_advance (*first_glyph);
294       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
295       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
296     }
297     return;
298   }
299
300   font->parent->get_glyph_v_advances (count,
301                                       first_glyph, glyph_stride,
302                                       first_advance, advance_stride);
303   for (unsigned int i = 0; i < count; i++)
304   {
305     *first_advance = font->parent_scale_y_distance (*first_advance);
306     first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
307   }
308 }
309
310 static hb_bool_t
311 hb_font_get_glyph_h_origin_nil (hb_font_t      *font HB_UNUSED,
312                                 void           *font_data HB_UNUSED,
313                                 hb_codepoint_t  glyph HB_UNUSED,
314                                 hb_position_t  *x,
315                                 hb_position_t  *y,
316                                 void           *user_data HB_UNUSED)
317 {
318   *x = *y = 0;
319   return true;
320 }
321
322 static hb_bool_t
323 hb_font_get_glyph_h_origin_default (hb_font_t      *font,
324                                     void           *font_data HB_UNUSED,
325                                     hb_codepoint_t  glyph,
326                                     hb_position_t  *x,
327                                     hb_position_t  *y,
328                                     void           *user_data HB_UNUSED)
329 {
330   hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
331   if (ret)
332     font->parent_scale_position (x, y);
333   return ret;
334 }
335
336 static hb_bool_t
337 hb_font_get_glyph_v_origin_nil (hb_font_t      *font HB_UNUSED,
338                                 void           *font_data HB_UNUSED,
339                                 hb_codepoint_t  glyph HB_UNUSED,
340                                 hb_position_t  *x,
341                                 hb_position_t  *y,
342                                 void           *user_data HB_UNUSED)
343 {
344   *x = *y = 0;
345   return false;
346 }
347
348 static hb_bool_t
349 hb_font_get_glyph_v_origin_default (hb_font_t      *font,
350                                     void           *font_data HB_UNUSED,
351                                     hb_codepoint_t  glyph,
352                                     hb_position_t  *x,
353                                     hb_position_t  *y,
354                                     void           *user_data HB_UNUSED)
355 {
356   hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
357   if (ret)
358     font->parent_scale_position (x, y);
359   return ret;
360 }
361
362 static hb_position_t
363 hb_font_get_glyph_h_kerning_nil (hb_font_t      *font HB_UNUSED,
364                                  void           *font_data HB_UNUSED,
365                                  hb_codepoint_t  left_glyph HB_UNUSED,
366                                  hb_codepoint_t  right_glyph HB_UNUSED,
367                                  void           *user_data HB_UNUSED)
368 {
369   return 0;
370 }
371
372 static hb_position_t
373 hb_font_get_glyph_h_kerning_default (hb_font_t      *font,
374                                      void           *font_data HB_UNUSED,
375                                      hb_codepoint_t  left_glyph,
376                                      hb_codepoint_t  right_glyph,
377                                      void           *user_data HB_UNUSED)
378 {
379   return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
380 }
381
382 #ifndef HB_DISABLE_DEPRECATED
383 static hb_position_t
384 hb_font_get_glyph_v_kerning_nil (hb_font_t      *font HB_UNUSED,
385                                  void           *font_data HB_UNUSED,
386                                  hb_codepoint_t  top_glyph HB_UNUSED,
387                                  hb_codepoint_t  bottom_glyph HB_UNUSED,
388                                  void           *user_data HB_UNUSED)
389 {
390   return 0;
391 }
392
393 static hb_position_t
394 hb_font_get_glyph_v_kerning_default (hb_font_t      *font,
395                                      void           *font_data HB_UNUSED,
396                                      hb_codepoint_t  top_glyph,
397                                      hb_codepoint_t  bottom_glyph,
398                                      void           *user_data HB_UNUSED)
399 {
400   return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
401 }
402 #endif
403
404 static hb_bool_t
405 hb_font_get_glyph_extents_nil (hb_font_t          *font HB_UNUSED,
406                                void               *font_data HB_UNUSED,
407                                hb_codepoint_t      glyph HB_UNUSED,
408                                hb_glyph_extents_t *extents,
409                                void               *user_data HB_UNUSED)
410 {
411   memset (extents, 0, sizeof (*extents));
412   return false;
413 }
414
415 static hb_bool_t
416 hb_font_get_glyph_extents_default (hb_font_t          *font,
417                                    void               *font_data HB_UNUSED,
418                                    hb_codepoint_t      glyph,
419                                    hb_glyph_extents_t *extents,
420                                    void               *user_data HB_UNUSED)
421 {
422   hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
423   if (ret) {
424     font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
425     font->parent_scale_distance (&extents->width, &extents->height);
426   }
427   return ret;
428 }
429
430 static hb_bool_t
431 hb_font_get_glyph_contour_point_nil (hb_font_t      *font HB_UNUSED,
432                                      void           *font_data HB_UNUSED,
433                                      hb_codepoint_t  glyph HB_UNUSED,
434                                      unsigned int    point_index HB_UNUSED,
435                                      hb_position_t  *x,
436                                      hb_position_t  *y,
437                                      void           *user_data HB_UNUSED)
438 {
439   *x = *y = 0;
440   return false;
441 }
442
443 static hb_bool_t
444 hb_font_get_glyph_contour_point_default (hb_font_t      *font,
445                                          void           *font_data HB_UNUSED,
446                                          hb_codepoint_t  glyph,
447                                          unsigned int    point_index,
448                                          hb_position_t  *x,
449                                          hb_position_t  *y,
450                                          void           *user_data HB_UNUSED)
451 {
452   hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
453   if (ret)
454     font->parent_scale_position (x, y);
455   return ret;
456 }
457
458 static hb_bool_t
459 hb_font_get_glyph_name_nil (hb_font_t      *font HB_UNUSED,
460                             void           *font_data HB_UNUSED,
461                             hb_codepoint_t  glyph HB_UNUSED,
462                             char           *name,
463                             unsigned int    size,
464                             void           *user_data HB_UNUSED)
465 {
466   if (size) *name = '\0';
467   return false;
468 }
469
470 static hb_bool_t
471 hb_font_get_glyph_name_default (hb_font_t      *font,
472                                 void           *font_data HB_UNUSED,
473                                 hb_codepoint_t  glyph,
474                                 char           *name,
475                                 unsigned int    size,
476                                 void           *user_data HB_UNUSED)
477 {
478   return font->parent->get_glyph_name (glyph, name, size);
479 }
480
481 static hb_bool_t
482 hb_font_get_glyph_from_name_nil (hb_font_t      *font HB_UNUSED,
483                                  void           *font_data HB_UNUSED,
484                                  const char     *name HB_UNUSED,
485                                  int             len HB_UNUSED, /* -1 means nul-terminated */
486                                  hb_codepoint_t *glyph,
487                                  void           *user_data HB_UNUSED)
488 {
489   *glyph = 0;
490   return false;
491 }
492
493 static hb_bool_t
494 hb_font_get_glyph_from_name_default (hb_font_t      *font,
495                                      void           *font_data HB_UNUSED,
496                                      const char     *name,
497                                      int             len, /* -1 means nul-terminated */
498                                      hb_codepoint_t *glyph,
499                                      void           *user_data HB_UNUSED)
500 {
501   return font->parent->get_glyph_from_name (name, len, glyph);
502 }
503
504 DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
505 {
506   HB_OBJECT_HEADER_STATIC,
507
508   {
509 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
510     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
511 #undef HB_FONT_FUNC_IMPLEMENT
512   },
513   {
514 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
515     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
516 #undef HB_FONT_FUNC_IMPLEMENT
517   },
518   {
519     {
520 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
521       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
522 #undef HB_FONT_FUNC_IMPLEMENT
523     }
524   }
525 };
526
527 static const hb_font_funcs_t _hb_font_funcs_default = {
528   HB_OBJECT_HEADER_STATIC,
529
530   {
531 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
532     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
533 #undef HB_FONT_FUNC_IMPLEMENT
534   },
535   {
536 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
537     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
538 #undef HB_FONT_FUNC_IMPLEMENT
539   },
540   {
541     {
542 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default,
543       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
544 #undef HB_FONT_FUNC_IMPLEMENT
545     }
546   }
547 };
548
549
550 /**
551  * hb_font_funcs_create: (Xconstructor)
552  *
553  * Creates a new #hb_font_funcs_t structure of font functions.
554  *
555  * Return value: (transfer full): The font-functions structure
556  *
557  * Since: 0.9.2
558  **/
559 hb_font_funcs_t *
560 hb_font_funcs_create ()
561 {
562   hb_font_funcs_t *ffuncs;
563
564   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
565     return hb_font_funcs_get_empty ();
566
567   ffuncs->get = _hb_font_funcs_default.get;
568
569   return ffuncs;
570 }
571
572 /**
573  * hb_font_funcs_get_empty:
574  *
575  * Fetches an empty font-functions structure.
576  *
577  * Return value: (transfer full): The font-functions structure
578  *
579  * Since: 0.9.2
580  **/
581 hb_font_funcs_t *
582 hb_font_funcs_get_empty ()
583 {
584   return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default);
585 }
586
587 /**
588  * hb_font_funcs_reference: (skip)
589  * @ffuncs: The font-functions structure
590  *
591  * Increases the reference count on a font-functions structure.
592  *
593  * Return value: The font-functions structure
594  *
595  * Since: 0.9.2
596  **/
597 hb_font_funcs_t *
598 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
599 {
600   return hb_object_reference (ffuncs);
601 }
602
603 /**
604  * hb_font_funcs_destroy: (skip)
605  * @ffuncs: The font-functions structure
606  *
607  * Decreases the reference count on a font-functions structure. When
608  * the reference count reaches zero, the font-functions structure is
609  * destroyed, freeing all memory.
610  *
611  * Since: 0.9.2
612  **/
613 void
614 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
615 {
616   if (!hb_object_destroy (ffuncs)) return;
617
618 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
619   ffuncs->destroy.name (ffuncs->user_data.name);
620   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
621 #undef HB_FONT_FUNC_IMPLEMENT
622
623   hb_free (ffuncs);
624 }
625
626 /**
627  * hb_font_funcs_set_user_data: (skip)
628  * @ffuncs: The font-functions structure
629  * @key: The user-data key to set
630  * @data: A pointer to the user data set
631  * @destroy: (nullable): A callback to call when @data is not needed anymore
632  * @replace: Whether to replace an existing data with the same key
633  *
634  * Attaches a user-data key/data pair to the specified font-functions structure.
635  *
636  * Return value: %true if success, %false otherwise
637  *
638  * Since: 0.9.2
639  **/
640 hb_bool_t
641 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
642                              hb_user_data_key_t *key,
643                              void *              data,
644                              hb_destroy_func_t   destroy /* May be NULL. */,
645                              hb_bool_t           replace)
646 {
647   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
648 }
649
650 /**
651  * hb_font_funcs_get_user_data: (skip)
652  * @ffuncs: The font-functions structure
653  * @key: The user-data key to query
654  *
655  * Fetches the user data associated with the specified key,
656  * attached to the specified font-functions structure.
657  *
658  * Return value: (transfer none): A pointer to the user data
659  *
660  * Since: 0.9.2
661  **/
662 void *
663 hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
664                              hb_user_data_key_t *key)
665 {
666   return hb_object_get_user_data (ffuncs, key);
667 }
668
669
670 /**
671  * hb_font_funcs_make_immutable:
672  * @ffuncs: The font-functions structure
673  *
674  * Makes a font-functions structure immutable.
675  *
676  * Since: 0.9.2
677  **/
678 void
679 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
680 {
681   if (hb_object_is_immutable (ffuncs))
682     return;
683
684   hb_object_make_immutable (ffuncs);
685 }
686
687 /**
688  * hb_font_funcs_is_immutable:
689  * @ffuncs: The font-functions structure
690  *
691  * Tests whether a font-functions structure is immutable.
692  *
693  * Return value: %true if @ffuncs is immutable, %false otherwise
694  *
695  * Since: 0.9.2
696  **/
697 hb_bool_t
698 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
699 {
700   return hb_object_is_immutable (ffuncs);
701 }
702
703
704 #define HB_FONT_FUNC_IMPLEMENT(name) \
705                                                                          \
706 void                                                                     \
707 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
708                                  hb_font_get_##name##_func_t  func,      \
709                                  void                        *user_data, \
710                                  hb_destroy_func_t            destroy)   \
711 {                                                                        \
712   if (hb_object_is_immutable (ffuncs))                                   \
713   {                                                                      \
714     if (destroy)                                                         \
715       destroy (user_data);                                               \
716     return;                                                              \
717   }                                                                      \
718                                                                          \
719   if (ffuncs->destroy.name)                                              \
720     ffuncs->destroy.name (ffuncs->user_data.name);                       \
721                                                                          \
722   if (func) {                                                            \
723     ffuncs->get.f.name = func;                                           \
724     ffuncs->user_data.name = user_data;                                  \
725     ffuncs->destroy.name = destroy;                                      \
726   } else {                                                               \
727     ffuncs->get.f.name = hb_font_get_##name##_default;                   \
728     ffuncs->user_data.name = nullptr;                                    \
729     ffuncs->destroy.name = nullptr;                                      \
730   }                                                                      \
731 }
732
733 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
734 #undef HB_FONT_FUNC_IMPLEMENT
735
736 bool
737 hb_font_t::has_func_set (unsigned int i)
738 {
739   return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i];
740 }
741
742 bool
743 hb_font_t::has_func (unsigned int i)
744 {
745   return has_func_set (i) ||
746          (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i));
747 }
748
749 /* Public getters */
750
751 /**
752  * hb_font_get_h_extents:
753  * @font: #hb_font_t to work upon
754  * @extents: (out): The font extents retrieved
755  *
756  * Fetches the extents for a specified font, for horizontal
757  * text segments.
758  *
759  * Return value: %true if data found, %false otherwise
760  *
761  * Since: 1.1.3
762  **/
763 hb_bool_t
764 hb_font_get_h_extents (hb_font_t         *font,
765                        hb_font_extents_t *extents)
766 {
767   return font->get_font_h_extents (extents);
768 }
769
770 /**
771  * hb_font_get_v_extents:
772  * @font: #hb_font_t to work upon
773  * @extents: (out): The font extents retrieved
774  *
775  * Fetches the extents for a specified font, for vertical
776  * text segments.
777  *
778  * Return value: %true if data found, %false otherwise
779  *
780  * Since: 1.1.3
781  **/
782 hb_bool_t
783 hb_font_get_v_extents (hb_font_t         *font,
784                        hb_font_extents_t *extents)
785 {
786   return font->get_font_v_extents (extents);
787 }
788
789 /**
790  * hb_font_get_glyph:
791  * @font: #hb_font_t to work upon
792  * @unicode: The Unicode code point to query
793  * @variation_selector: A variation-selector code point
794  * @glyph: (out): The glyph ID retrieved
795  *
796  * Fetches the glyph ID for a Unicode code point in the specified
797  * font, with an optional variation selector.
798  *
799  * If @variation_selector is 0, calls hb_font_get_nominal_glyph();
800  * otherwise calls hb_font_get_variation_glyph().
801  *
802  * Return value: %true if data found, %false otherwise
803  *
804  * Since: 0.9.2
805  **/
806 hb_bool_t
807 hb_font_get_glyph (hb_font_t      *font,
808                    hb_codepoint_t  unicode,
809                    hb_codepoint_t  variation_selector,
810                    hb_codepoint_t *glyph)
811 {
812   if (unlikely (variation_selector))
813     return font->get_variation_glyph (unicode, variation_selector, glyph);
814   return font->get_nominal_glyph (unicode, glyph);
815 }
816
817 /**
818  * hb_font_get_nominal_glyph:
819  * @font: #hb_font_t to work upon
820  * @unicode: The Unicode code point to query
821  * @glyph: (out): The glyph ID retrieved
822  *
823  * Fetches the nominal glyph ID for a Unicode code point in the
824  * specified font.
825  *
826  * This version of the function should not be used to fetch glyph IDs
827  * for code points modified by variation selectors. For variation-selector
828  * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph().
829  *
830  * Return value: %true if data found, %false otherwise
831  *
832  * Since: 1.2.3
833  **/
834 hb_bool_t
835 hb_font_get_nominal_glyph (hb_font_t      *font,
836                            hb_codepoint_t  unicode,
837                            hb_codepoint_t *glyph)
838 {
839   return font->get_nominal_glyph (unicode, glyph);
840 }
841
842 /**
843  * hb_font_get_nominal_glyphs:
844  * @font: #hb_font_t to work upon
845  * @count: number of code points to query
846  * @first_unicode: The first Unicode code point to query
847  * @unicode_stride: The stride between successive code points
848  * @first_glyph: (out): The first glyph ID retrieved
849  * @glyph_stride: The stride between successive glyph IDs
850  *
851  * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph
852  * IDs must be returned in a #hb_codepoint_t output parameter.
853  *
854  * Return value: the number of code points processed
855  *
856  * Since: 2.6.3
857  **/
858 unsigned int
859 hb_font_get_nominal_glyphs (hb_font_t *font,
860                             unsigned int count,
861                             const hb_codepoint_t *first_unicode,
862                             unsigned int unicode_stride,
863                             hb_codepoint_t *first_glyph,
864                             unsigned int glyph_stride)
865 {
866   return font->get_nominal_glyphs (count,
867                                    first_unicode, unicode_stride,
868                                    first_glyph, glyph_stride);
869 }
870
871 /**
872  * hb_font_get_variation_glyph:
873  * @font: #hb_font_t to work upon
874  * @unicode: The Unicode code point to query
875  * @variation_selector: The  variation-selector code point to query
876  * @glyph: (out): The glyph ID retrieved
877  *
878  * Fetches the glyph ID for a Unicode code point when followed by
879  * by the specified variation-selector code point, in the specified
880  * font.
881  *
882  * Return value: %true if data found, %false otherwise
883  *
884  * Since: 1.2.3
885  **/
886 hb_bool_t
887 hb_font_get_variation_glyph (hb_font_t      *font,
888                              hb_codepoint_t  unicode,
889                              hb_codepoint_t  variation_selector,
890                              hb_codepoint_t *glyph)
891 {
892   return font->get_variation_glyph (unicode, variation_selector, glyph);
893 }
894
895 /**
896  * hb_font_get_glyph_h_advance:
897  * @font: #hb_font_t to work upon
898  * @glyph: The glyph ID to query
899  *
900  * Fetches the advance for a glyph ID in the specified font,
901  * for horizontal text segments.
902  *
903  * Return value: The advance of @glyph within @font
904  *
905  * Since: 0.9.2
906  **/
907 hb_position_t
908 hb_font_get_glyph_h_advance (hb_font_t      *font,
909                              hb_codepoint_t  glyph)
910 {
911   return font->get_glyph_h_advance (glyph);
912 }
913
914 /**
915  * hb_font_get_glyph_v_advance:
916  * @font: #hb_font_t to work upon
917  * @glyph: The glyph ID to query
918  *
919  * Fetches the advance for a glyph ID in the specified font,
920  * for vertical text segments.
921  *
922  * Return value: The advance of @glyph within @font
923  *
924  * Since: 0.9.2
925  **/
926 hb_position_t
927 hb_font_get_glyph_v_advance (hb_font_t      *font,
928                              hb_codepoint_t  glyph)
929 {
930   return font->get_glyph_v_advance (glyph);
931 }
932
933 /**
934  * hb_font_get_glyph_h_advances:
935  * @font: #hb_font_t to work upon
936  * @count: The number of glyph IDs in the sequence queried
937  * @first_glyph: The first glyph ID to query
938  * @glyph_stride: The stride between successive glyph IDs
939  * @first_advance: (out): The first advance retrieved
940  * @advance_stride: The stride between successive advances
941  *
942  * Fetches the advances for a sequence of glyph IDs in the specified
943  * font, for horizontal text segments.
944  *
945  * Since: 1.8.6
946  **/
947 void
948 hb_font_get_glyph_h_advances (hb_font_t*            font,
949                               unsigned int          count,
950                               const hb_codepoint_t *first_glyph,
951                               unsigned              glyph_stride,
952                               hb_position_t        *first_advance,
953                               unsigned              advance_stride)
954 {
955   font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
956 }
957 /**
958  * hb_font_get_glyph_v_advances:
959  * @font: #hb_font_t to work upon
960  * @count: The number of glyph IDs in the sequence queried
961  * @first_glyph: The first glyph ID to query
962  * @glyph_stride: The stride between successive glyph IDs
963  * @first_advance: (out): The first advance retrieved
964  * @advance_stride: (out): The stride between successive advances
965  *
966  * Fetches the advances for a sequence of glyph IDs in the specified
967  * font, for vertical text segments.
968  *
969  * Since: 1.8.6
970  **/
971 void
972 hb_font_get_glyph_v_advances (hb_font_t*            font,
973                               unsigned int          count,
974                               const hb_codepoint_t *first_glyph,
975                               unsigned              glyph_stride,
976                               hb_position_t        *first_advance,
977                               unsigned              advance_stride)
978 {
979   font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
980 }
981
982 /**
983  * hb_font_get_glyph_h_origin:
984  * @font: #hb_font_t to work upon
985  * @glyph: The glyph ID to query
986  * @x: (out): The X coordinate of the origin
987  * @y: (out): The Y coordinate of the origin
988  *
989  * Fetches the (X,Y) coordinates of the origin for a glyph ID
990  * in the specified font, for horizontal text segments.
991  *
992  * Return value: %true if data found, %false otherwise
993  *
994  * Since: 0.9.2
995  **/
996 hb_bool_t
997 hb_font_get_glyph_h_origin (hb_font_t      *font,
998                             hb_codepoint_t  glyph,
999                             hb_position_t  *x,
1000                             hb_position_t  *y)
1001 {
1002   return font->get_glyph_h_origin (glyph, x, y);
1003 }
1004
1005 /**
1006  * hb_font_get_glyph_v_origin:
1007  * @font: #hb_font_t to work upon
1008  * @glyph: The glyph ID to query
1009  * @x: (out): The X coordinate of the origin
1010  * @y: (out): The Y coordinate of the origin
1011  *
1012  * Fetches the (X,Y) coordinates of the origin for a glyph ID
1013  * in the specified font, for vertical text segments.
1014  *
1015  * Return value: %true if data found, %false otherwise
1016  *
1017  * Since: 0.9.2
1018  **/
1019 hb_bool_t
1020 hb_font_get_glyph_v_origin (hb_font_t      *font,
1021                             hb_codepoint_t  glyph,
1022                             hb_position_t  *x,
1023                             hb_position_t  *y)
1024 {
1025   return font->get_glyph_v_origin (glyph, x, y);
1026 }
1027
1028 /**
1029  * hb_font_get_glyph_h_kerning:
1030  * @font: #hb_font_t to work upon
1031  * @left_glyph: The glyph ID of the left glyph in the glyph pair
1032  * @right_glyph: The glyph ID of the right glyph in the glyph pair
1033  *
1034  * Fetches the kerning-adjustment value for a glyph-pair in
1035  * the specified font, for horizontal text segments.
1036  *
1037  * <note>It handles legacy kerning only (as returned by the corresponding
1038  * #hb_font_funcs_t function).</note>
1039  *
1040  * Return value: The kerning adjustment value
1041  *
1042  * Since: 0.9.2
1043  **/
1044 hb_position_t
1045 hb_font_get_glyph_h_kerning (hb_font_t      *font,
1046                              hb_codepoint_t  left_glyph,
1047                              hb_codepoint_t  right_glyph)
1048 {
1049   return font->get_glyph_h_kerning (left_glyph, right_glyph);
1050 }
1051
1052 #ifndef HB_DISABLE_DEPRECATED
1053 /**
1054  * hb_font_get_glyph_v_kerning:
1055  * @font: #hb_font_t to work upon
1056  * @top_glyph: The glyph ID of the top glyph in the glyph pair
1057  * @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair
1058  *
1059  * Fetches the kerning-adjustment value for a glyph-pair in
1060  * the specified font, for vertical text segments.
1061  *
1062  * <note>It handles legacy kerning only (as returned by the corresponding
1063  * #hb_font_funcs_t function).</note>
1064  *
1065  * Return value: The kerning adjustment value
1066  *
1067  * Since: 0.9.2
1068  * Deprecated: 2.0.0
1069  **/
1070 hb_position_t
1071 hb_font_get_glyph_v_kerning (hb_font_t      *font,
1072                              hb_codepoint_t  top_glyph,
1073                              hb_codepoint_t  bottom_glyph)
1074 {
1075   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
1076 }
1077 #endif
1078
1079 /**
1080  * hb_font_get_glyph_extents:
1081  * @font: #hb_font_t to work upon
1082  * @glyph: The glyph ID to query
1083  * @extents: (out): The #hb_glyph_extents_t retrieved
1084  *
1085  * Fetches the #hb_glyph_extents_t data for a glyph ID
1086  * in the specified font.
1087  *
1088  * Return value: %true if data found, %false otherwise
1089  *
1090  * Since: 0.9.2
1091  **/
1092 hb_bool_t
1093 hb_font_get_glyph_extents (hb_font_t          *font,
1094                            hb_codepoint_t      glyph,
1095                            hb_glyph_extents_t *extents)
1096 {
1097   return font->get_glyph_extents (glyph, extents);
1098 }
1099
1100 /**
1101  * hb_font_get_glyph_contour_point:
1102  * @font: #hb_font_t to work upon
1103  * @glyph: The glyph ID to query
1104  * @point_index: The contour-point index to query
1105  * @x: (out): The X value retrieved for the contour point
1106  * @y: (out): The Y value retrieved for the contour point
1107  *
1108  * Fetches the (x,y) coordinates of a specified contour-point index
1109  * in the specified glyph, within the specified font.
1110  *
1111  * Return value: %true if data found, %false otherwise
1112  *
1113  * Since: 0.9.2
1114  **/
1115 hb_bool_t
1116 hb_font_get_glyph_contour_point (hb_font_t      *font,
1117                                  hb_codepoint_t  glyph,
1118                                  unsigned int    point_index,
1119                                  hb_position_t  *x,
1120                                  hb_position_t  *y)
1121 {
1122   return font->get_glyph_contour_point (glyph, point_index, x, y);
1123 }
1124
1125 /**
1126  * hb_font_get_glyph_name:
1127  * @font: #hb_font_t to work upon
1128  * @glyph: The glyph ID to query
1129  * @name: (out) (array length=size): Name string retrieved for the glyph ID
1130  * @size: Length of the glyph-name string retrieved
1131  *
1132  * Fetches the glyph-name string for a glyph ID in the specified @font.
1133  *
1134  * Return value: %true if data found, %false otherwise
1135  *
1136  * Since: 0.9.2
1137  **/
1138 hb_bool_t
1139 hb_font_get_glyph_name (hb_font_t      *font,
1140                         hb_codepoint_t  glyph,
1141                         char           *name,
1142                         unsigned int    size)
1143 {
1144   return font->get_glyph_name (glyph, name, size);
1145 }
1146
1147 /**
1148  * hb_font_get_glyph_from_name:
1149  * @font: #hb_font_t to work upon
1150  * @name: (array length=len): The name string to query
1151  * @len: The length of the name queried
1152  * @glyph: (out): The glyph ID retrieved
1153  *
1154  * Fetches the glyph ID that corresponds to a name string in the specified @font.
1155  *
1156  * <note>Note: @len == -1 means the name string is null-terminated.</note>
1157  *
1158  * Return value: %true if data found, %false otherwise
1159  *
1160  * Since: 0.9.2
1161  **/
1162 hb_bool_t
1163 hb_font_get_glyph_from_name (hb_font_t      *font,
1164                              const char     *name,
1165                              int             len, /* -1 means nul-terminated */
1166                              hb_codepoint_t *glyph)
1167 {
1168   return font->get_glyph_from_name (name, len, glyph);
1169 }
1170
1171
1172 /* A bit higher-level, and with fallback */
1173
1174 /**
1175  * hb_font_get_extents_for_direction:
1176  * @font: #hb_font_t to work upon
1177  * @direction: The direction of the text segment
1178  * @extents: (out): The #hb_font_extents_t retrieved
1179  *
1180  * Fetches the extents for a font in a text segment of the
1181  * specified direction.
1182  *
1183  * Calls the appropriate direction-specific variant (horizontal
1184  * or vertical) depending on the value of @direction.
1185  *
1186  * Since: 1.1.3
1187  **/
1188 void
1189 hb_font_get_extents_for_direction (hb_font_t         *font,
1190                                    hb_direction_t     direction,
1191                                    hb_font_extents_t *extents)
1192 {
1193   return font->get_extents_for_direction (direction, extents);
1194 }
1195 /**
1196  * hb_font_get_glyph_advance_for_direction:
1197  * @font: #hb_font_t to work upon
1198  * @glyph: The glyph ID to query
1199  * @direction: The direction of the text segment
1200  * @x: (out): The horizontal advance retrieved
1201  * @y: (out):  The vertical advance retrieved
1202  *
1203  * Fetches the advance for a glyph ID from the specified font,
1204  * in a text segment of the specified direction.
1205  *
1206  * Calls the appropriate direction-specific variant (horizontal
1207  * or vertical) depending on the value of @direction.
1208  *
1209  * Since: 0.9.2
1210  **/
1211 void
1212 hb_font_get_glyph_advance_for_direction (hb_font_t      *font,
1213                                          hb_codepoint_t  glyph,
1214                                          hb_direction_t  direction,
1215                                          hb_position_t  *x,
1216                                          hb_position_t  *y)
1217 {
1218   return font->get_glyph_advance_for_direction (glyph, direction, x, y);
1219 }
1220 /**
1221  * hb_font_get_glyph_advances_for_direction:
1222  * @font: #hb_font_t to work upon
1223  * @direction: The direction of the text segment
1224  * @count: The number of glyph IDs in the sequence queried
1225  * @first_glyph: The first glyph ID to query
1226  * @glyph_stride: The stride between successive glyph IDs
1227  * @first_advance: (out): The first advance retrieved
1228  * @advance_stride: (out): The stride between successive advances
1229  *
1230  * Fetches the advances for a sequence of glyph IDs in the specified
1231  * font, in a text segment of the specified direction.
1232  *
1233  * Calls the appropriate direction-specific variant (horizontal
1234  * or vertical) depending on the value of @direction.
1235  *
1236  * Since: 1.8.6
1237  **/
1238 HB_EXTERN void
1239 hb_font_get_glyph_advances_for_direction (hb_font_t*            font,
1240                                           hb_direction_t        direction,
1241                                           unsigned int          count,
1242                                           const hb_codepoint_t *first_glyph,
1243                                           unsigned              glyph_stride,
1244                                           hb_position_t        *first_advance,
1245                                           unsigned              advance_stride)
1246 {
1247   font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride);
1248 }
1249
1250 /**
1251  * hb_font_get_glyph_origin_for_direction:
1252  * @font: #hb_font_t to work upon
1253  * @glyph: The glyph ID to query
1254  * @direction: The direction of the text segment
1255  * @x: (out): The X coordinate retrieved for the origin
1256  * @y: (out): The Y coordinate retrieved for the origin
1257  *
1258  * Fetches the (X,Y) coordinates of the origin for a glyph in
1259  * the specified font.
1260  *
1261  * Calls the appropriate direction-specific variant (horizontal
1262  * or vertical) depending on the value of @direction.
1263  *
1264  * Since: 0.9.2
1265  **/
1266 void
1267 hb_font_get_glyph_origin_for_direction (hb_font_t      *font,
1268                                         hb_codepoint_t  glyph,
1269                                         hb_direction_t  direction,
1270                                         hb_position_t  *x,
1271                                         hb_position_t  *y)
1272 {
1273   return font->get_glyph_origin_for_direction (glyph, direction, x, y);
1274 }
1275
1276 /**
1277  * hb_font_add_glyph_origin_for_direction:
1278  * @font: #hb_font_t to work upon
1279  * @glyph: The glyph ID to query
1280  * @direction: The direction of the text segment
1281  * @x: (inout): Input = The original X coordinate
1282  *     Output = The X coordinate plus the X-coordinate of the origin
1283  * @y: (inout): Input = The original Y coordinate
1284  *     Output = The Y coordinate plus the Y-coordinate of the origin
1285  *
1286  * Adds the origin coordinates to an (X,Y) point coordinate, in
1287  * the specified glyph ID in the specified font.
1288  *
1289  * Calls the appropriate direction-specific variant (horizontal
1290  * or vertical) depending on the value of @direction.
1291  *
1292  * Since: 0.9.2
1293  **/
1294 void
1295 hb_font_add_glyph_origin_for_direction (hb_font_t      *font,
1296                                         hb_codepoint_t  glyph,
1297                                         hb_direction_t  direction,
1298                                         hb_position_t  *x,
1299                                         hb_position_t  *y)
1300 {
1301   return font->add_glyph_origin_for_direction (glyph, direction, x, y);
1302 }
1303
1304 /**
1305  * hb_font_subtract_glyph_origin_for_direction:
1306  * @font: #hb_font_t to work upon
1307  * @glyph: The glyph ID to query
1308  * @direction: The direction of the text segment
1309  * @x: (inout): Input = The original X coordinate
1310  *     Output = The X coordinate minus the X-coordinate of the origin
1311  * @y: (inout): Input = The original Y coordinate
1312  *     Output = The Y coordinate minus the Y-coordinate of the origin
1313  *
1314  * Subtracts the origin coordinates from an (X,Y) point coordinate,
1315  * in the specified glyph ID in the specified font.
1316  *
1317  * Calls the appropriate direction-specific variant (horizontal
1318  * or vertical) depending on the value of @direction.
1319  *
1320  * Since: 0.9.2
1321  **/
1322 void
1323 hb_font_subtract_glyph_origin_for_direction (hb_font_t      *font,
1324                                              hb_codepoint_t  glyph,
1325                                              hb_direction_t  direction,
1326                                              hb_position_t  *x,
1327                                              hb_position_t  *y)
1328 {
1329   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
1330 }
1331
1332 /**
1333  * hb_font_get_glyph_kerning_for_direction:
1334  * @font: #hb_font_t to work upon
1335  * @first_glyph: The glyph ID of the first glyph in the glyph pair to query
1336  * @second_glyph: The glyph ID of the second glyph in the glyph pair to query
1337  * @direction: The direction of the text segment
1338  * @x: (out): The horizontal kerning-adjustment value retrieved
1339  * @y: (out): The vertical kerning-adjustment value retrieved
1340  *
1341  * Fetches the kerning-adjustment value for a glyph-pair in the specified font.
1342  *
1343  * Calls the appropriate direction-specific variant (horizontal
1344  * or vertical) depending on the value of @direction.
1345  *
1346  * Since: 0.9.2
1347  **/
1348 void
1349 hb_font_get_glyph_kerning_for_direction (hb_font_t      *font,
1350                                          hb_codepoint_t  first_glyph,
1351                                          hb_codepoint_t  second_glyph,
1352                                          hb_direction_t  direction,
1353                                          hb_position_t  *x,
1354                                          hb_position_t  *y)
1355 {
1356   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
1357 }
1358
1359 /**
1360  * hb_font_get_glyph_extents_for_origin:
1361  * @font: #hb_font_t to work upon
1362  * @glyph: The glyph ID to query
1363  * @direction: The direction of the text segment
1364  * @extents: (out): The #hb_glyph_extents_t retrieved
1365  *
1366  * Fetches the #hb_glyph_extents_t data for a glyph ID
1367  * in the specified font, with respect to the origin in
1368  * a text segment in the specified direction.
1369  *
1370  * Calls the appropriate direction-specific variant (horizontal
1371  * or vertical) depending on the value of @direction.
1372  *
1373  * Return value: %true if data found, %false otherwise
1374  *
1375  * Since: 0.9.2
1376  **/
1377 hb_bool_t
1378 hb_font_get_glyph_extents_for_origin (hb_font_t          *font,
1379                                       hb_codepoint_t      glyph,
1380                                       hb_direction_t      direction,
1381                                       hb_glyph_extents_t *extents)
1382 {
1383   return font->get_glyph_extents_for_origin (glyph, direction, extents);
1384 }
1385
1386 /**
1387  * hb_font_get_glyph_contour_point_for_origin:
1388  * @font: #hb_font_t to work upon
1389  * @glyph: The glyph ID to query
1390  * @point_index: The contour-point index to query
1391  * @direction: The direction of the text segment
1392  * @x: (out): The X value retrieved for the contour point
1393  * @y: (out): The Y value retrieved for the contour point
1394  *
1395  * Fetches the (X,Y) coordinates of a specified contour-point index
1396  * in the specified glyph ID in the specified font, with respect
1397  * to the origin in a text segment in the specified direction.
1398  *
1399  * Calls the appropriate direction-specific variant (horizontal
1400  * or vertical) depending on the value of @direction.
1401  *
1402  * Return value: %true if data found, %false otherwise
1403  *
1404  * Since: 0.9.2
1405  **/
1406 hb_bool_t
1407 hb_font_get_glyph_contour_point_for_origin (hb_font_t      *font,
1408                                             hb_codepoint_t  glyph,
1409                                             unsigned int    point_index,
1410                                             hb_direction_t  direction,
1411                                             hb_position_t  *x,
1412                                             hb_position_t  *y)
1413 {
1414   return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
1415 }
1416
1417 /**
1418  * hb_font_glyph_to_string:
1419  * @font: #hb_font_t to work upon
1420  * @glyph: The glyph ID to query
1421  * @s: (out) (array length=size): The string containing the glyph name
1422  * @size: Length of string @s
1423  *
1424  * Fetches the name of the specified glyph ID in @font and returns
1425  * it in string @s.
1426  *
1427  * If the glyph ID has no name in @font, a string of the form `gidDDD` is
1428  * generated, with `DDD` being the glyph ID.
1429  *
1430  * Since: 0.9.2
1431  **/
1432 void
1433 hb_font_glyph_to_string (hb_font_t      *font,
1434                          hb_codepoint_t  glyph,
1435                          char           *s,
1436                          unsigned int    size)
1437 {
1438   font->glyph_to_string (glyph, s, size);
1439 }
1440
1441 /**
1442  * hb_font_glyph_from_string:
1443  * @font: #hb_font_t to work upon
1444  * @s: (array length=len) (element-type uint8_t): string to query
1445  * @len: The length of the string @s
1446  * @glyph: (out): The glyph ID corresponding to the string requested
1447  *
1448  * Fetches the glyph ID from @font that matches the specified string.
1449  * Strings of the format `gidDDD` or `uniUUUU` are parsed automatically.
1450  *
1451  * <note>Note: @len == -1 means the string is null-terminated.</note>
1452  *
1453  * Return value: %true if data found, %false otherwise
1454  *
1455  * Since: 0.9.2
1456  **/
1457 hb_bool_t
1458 hb_font_glyph_from_string (hb_font_t      *font,
1459                            const char     *s,
1460                            int             len,
1461                            hb_codepoint_t *glyph)
1462 {
1463   return font->glyph_from_string (s, len, glyph);
1464 }
1465
1466
1467 /*
1468  * hb_font_t
1469  */
1470
1471 DEFINE_NULL_INSTANCE (hb_font_t) =
1472 {
1473   HB_OBJECT_HEADER_STATIC,
1474
1475   nullptr, /* parent */
1476   const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
1477
1478   1000, /* x_scale */
1479   1000, /* y_scale */
1480   0., /* slant */
1481   0., /* slant_xy; */
1482   1<<16, /* x_mult */
1483   1<<16, /* y_mult */
1484
1485   0, /* x_ppem */
1486   0, /* y_ppem */
1487   0, /* ptem */
1488
1489   0, /* num_coords */
1490   nullptr, /* coords */
1491   nullptr, /* design_coords */
1492
1493   const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
1494
1495   /* Zero for the rest is fine. */
1496 };
1497
1498
1499 static hb_font_t *
1500 _hb_font_create (hb_face_t *face)
1501 {
1502   hb_font_t *font;
1503
1504   if (unlikely (!face))
1505     face = hb_face_get_empty ();
1506   if (!(font = hb_object_create<hb_font_t> ()))
1507     return hb_font_get_empty ();
1508
1509   hb_face_make_immutable (face);
1510   font->parent = hb_font_get_empty ();
1511   font->face = hb_face_reference (face);
1512   font->klass = hb_font_funcs_get_empty ();
1513   font->data.init0 (font);
1514   font->x_scale = font->y_scale = hb_face_get_upem (face);
1515   font->x_mult = font->y_mult = 1 << 16;
1516
1517   return font;
1518 }
1519
1520 /**
1521  * hb_font_create: (Xconstructor)
1522  * @face: a face.
1523  *
1524  * Constructs a new font object from the specified face.
1525  *
1526  * <note>Note: If @face's index value (as passed to hb_face_create()
1527  * has non-zero top 16-bits, those bits minus one are passed to
1528  * hb_font_set_var_named_instance(), effectively loading a named-instance
1529  * of a variable font, instead of the default-instance.  This allows
1530  * specifying which named-instance to load by default when creating the
1531  * face.</note>
1532  *
1533  * Return value: (transfer full): The new font object
1534  *
1535  * Since: 0.9.2
1536  **/
1537 hb_font_t *
1538 hb_font_create (hb_face_t *face)
1539 {
1540   hb_font_t *font = _hb_font_create (face);
1541
1542 #ifndef HB_NO_OT_FONT
1543   /* Install our in-house, very lightweight, funcs. */
1544   hb_ot_font_set_funcs (font);
1545 #endif
1546
1547 #ifndef HB_NO_VAR
1548   if (face && face->index >> 16)
1549     hb_font_set_var_named_instance (font, (face->index >> 16) - 1);
1550 #endif
1551
1552   return font;
1553 }
1554
1555 static void
1556 _hb_font_adopt_var_coords (hb_font_t *font,
1557                            int *coords, /* 2.14 normalized */
1558                            float *design_coords,
1559                            unsigned int coords_length)
1560 {
1561   hb_free (font->coords);
1562   hb_free (font->design_coords);
1563
1564   font->coords = coords;
1565   font->design_coords = design_coords;
1566   font->num_coords = coords_length;
1567 }
1568
1569 /**
1570  * hb_font_create_sub_font:
1571  * @parent: The parent font object
1572  *
1573  * Constructs a sub-font font object from the specified @parent font,
1574  * replicating the parent's properties.
1575  *
1576  * Return value: (transfer full): The new sub-font font object
1577  *
1578  * Since: 0.9.2
1579  **/
1580 hb_font_t *
1581 hb_font_create_sub_font (hb_font_t *parent)
1582 {
1583   if (unlikely (!parent))
1584     parent = hb_font_get_empty ();
1585
1586   hb_font_t *font = _hb_font_create (parent->face);
1587
1588   if (unlikely (hb_object_is_immutable (font)))
1589     return font;
1590
1591   font->parent = hb_font_reference (parent);
1592
1593   font->x_scale = parent->x_scale;
1594   font->y_scale = parent->y_scale;
1595   font->slant = parent->slant;
1596   font->mults_changed ();
1597   font->x_ppem = parent->x_ppem;
1598   font->y_ppem = parent->y_ppem;
1599   font->ptem = parent->ptem;
1600
1601   unsigned int num_coords = parent->num_coords;
1602   if (num_coords)
1603   {
1604     int *coords = (int *) hb_calloc (num_coords, sizeof (parent->coords[0]));
1605     float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0]));
1606     if (likely (coords && design_coords))
1607     {
1608       memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
1609       memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
1610       _hb_font_adopt_var_coords (font, coords, design_coords, num_coords);
1611     }
1612     else
1613     {
1614       hb_free (coords);
1615       hb_free (design_coords);
1616     }
1617   }
1618
1619   return font;
1620 }
1621
1622 /**
1623  * hb_font_get_empty:
1624  *
1625  * Fetches the empty font object.
1626  *
1627  * Return value: (transfer full): The empty font object
1628  *
1629  * Since: 0.9.2
1630  **/
1631 hb_font_t *
1632 hb_font_get_empty ()
1633 {
1634   return const_cast<hb_font_t *> (&Null (hb_font_t));
1635 }
1636
1637 /**
1638  * hb_font_reference: (skip)
1639  * @font: #hb_font_t to work upon
1640  *
1641  * Increases the reference count on the given font object.
1642  *
1643  * Return value: (transfer full): The @font object
1644  *
1645  * Since: 0.9.2
1646  **/
1647 hb_font_t *
1648 hb_font_reference (hb_font_t *font)
1649 {
1650   return hb_object_reference (font);
1651 }
1652
1653 /**
1654  * hb_font_destroy: (skip)
1655  * @font: #hb_font_t to work upon
1656  *
1657  * Decreases the reference count on the given font object. When the
1658  * reference count reaches zero, the font is destroyed,
1659  * freeing all memory.
1660  *
1661  * Since: 0.9.2
1662  **/
1663 void
1664 hb_font_destroy (hb_font_t *font)
1665 {
1666   if (!hb_object_destroy (font)) return;
1667
1668   font->data.fini ();
1669
1670   if (font->destroy)
1671     font->destroy (font->user_data);
1672
1673   hb_font_destroy (font->parent);
1674   hb_face_destroy (font->face);
1675   hb_font_funcs_destroy (font->klass);
1676
1677   hb_free (font->coords);
1678   hb_free (font->design_coords);
1679
1680   hb_free (font);
1681 }
1682
1683 /**
1684  * hb_font_set_user_data: (skip)
1685  * @font: #hb_font_t to work upon
1686  * @key: The user-data key
1687  * @data: A pointer to the user data
1688  * @destroy: (nullable): A callback to call when @data is not needed anymore
1689  * @replace: Whether to replace an existing data with the same key
1690  *
1691  * Attaches a user-data key/data pair to the specified font object.
1692  *
1693  * Return value: %true if success, %false otherwise
1694  *
1695  * Since: 0.9.2
1696  **/
1697 hb_bool_t
1698 hb_font_set_user_data (hb_font_t          *font,
1699                        hb_user_data_key_t *key,
1700                        void *              data,
1701                        hb_destroy_func_t   destroy /* May be NULL. */,
1702                        hb_bool_t           replace)
1703 {
1704   return hb_object_set_user_data (font, key, data, destroy, replace);
1705 }
1706
1707 /**
1708  * hb_font_get_user_data: (skip)
1709  * @font: #hb_font_t to work upon
1710  * @key: The user-data key to query
1711  *
1712  * Fetches the user-data object associated with the specified key,
1713  * attached to the specified font object.
1714  *
1715  * Return value: (transfer none): Pointer to the user data
1716  *
1717  * Since: 0.9.2
1718  **/
1719 void *
1720 hb_font_get_user_data (hb_font_t          *font,
1721                        hb_user_data_key_t *key)
1722 {
1723   return hb_object_get_user_data (font, key);
1724 }
1725
1726 /**
1727  * hb_font_make_immutable:
1728  * @font: #hb_font_t to work upon
1729  *
1730  * Makes @font immutable.
1731  *
1732  * Since: 0.9.2
1733  **/
1734 void
1735 hb_font_make_immutable (hb_font_t *font)
1736 {
1737   if (hb_object_is_immutable (font))
1738     return;
1739
1740   if (font->parent)
1741     hb_font_make_immutable (font->parent);
1742
1743   hb_object_make_immutable (font);
1744 }
1745
1746 /**
1747  * hb_font_is_immutable:
1748  * @font: #hb_font_t to work upon
1749  *
1750  * Tests whether a font object is immutable.
1751  *
1752  * Return value: %true if @font is immutable, %false otherwise
1753  *
1754  * Since: 0.9.2
1755  **/
1756 hb_bool_t
1757 hb_font_is_immutable (hb_font_t *font)
1758 {
1759   return hb_object_is_immutable (font);
1760 }
1761
1762 /**
1763  * hb_font_set_parent:
1764  * @font: #hb_font_t to work upon
1765  * @parent: The parent font object to assign
1766  *
1767  * Sets the parent font of @font.
1768  *
1769  * Since: 1.0.5
1770  **/
1771 void
1772 hb_font_set_parent (hb_font_t *font,
1773                     hb_font_t *parent)
1774 {
1775   if (hb_object_is_immutable (font))
1776     return;
1777
1778   if (!parent)
1779     parent = hb_font_get_empty ();
1780
1781   hb_font_t *old = font->parent;
1782
1783   font->parent = hb_font_reference (parent);
1784
1785   hb_font_destroy (old);
1786 }
1787
1788 /**
1789  * hb_font_get_parent:
1790  * @font: #hb_font_t to work upon
1791  *
1792  * Fetches the parent font of @font.
1793  *
1794  * Return value: (transfer none): The parent font object
1795  *
1796  * Since: 0.9.2
1797  **/
1798 hb_font_t *
1799 hb_font_get_parent (hb_font_t *font)
1800 {
1801   return font->parent;
1802 }
1803
1804 /**
1805  * hb_font_set_face:
1806  * @font: #hb_font_t to work upon
1807  * @face: The #hb_face_t to assign
1808  *
1809  * Sets @face as the font-face value of @font.
1810  *
1811  * Since: 1.4.3
1812  **/
1813 void
1814 hb_font_set_face (hb_font_t *font,
1815                   hb_face_t *face)
1816 {
1817   if (hb_object_is_immutable (font))
1818     return;
1819
1820   if (unlikely (!face))
1821     face = hb_face_get_empty ();
1822
1823   hb_face_t *old = font->face;
1824
1825   hb_face_make_immutable (face);
1826   font->face = hb_face_reference (face);
1827   font->mults_changed ();
1828
1829   hb_face_destroy (old);
1830 }
1831
1832 /**
1833  * hb_font_get_face:
1834  * @font: #hb_font_t to work upon
1835  *
1836  * Fetches the face associated with the specified font object.
1837  *
1838  * Return value: (transfer none): The #hb_face_t value
1839  *
1840  * Since: 0.9.2
1841  **/
1842 hb_face_t *
1843 hb_font_get_face (hb_font_t *font)
1844 {
1845   return font->face;
1846 }
1847
1848
1849 /**
1850  * hb_font_set_funcs:
1851  * @font: #hb_font_t to work upon
1852  * @klass: (closure font_data) (destroy destroy) (scope notified): The font-functions structure.
1853  * @font_data: Data to attach to @font
1854  * @destroy: (nullable): The function to call when @font_data is not needed anymore
1855  *
1856  * Replaces the font-functions structure attached to a font, updating
1857  * the font's user-data with @font-data and the @destroy callback.
1858  *
1859  * Since: 0.9.2
1860  **/
1861 void
1862 hb_font_set_funcs (hb_font_t         *font,
1863                    hb_font_funcs_t   *klass,
1864                    void              *font_data,
1865                    hb_destroy_func_t  destroy /* May be NULL. */)
1866 {
1867   if (hb_object_is_immutable (font))
1868   {
1869     if (destroy)
1870       destroy (font_data);
1871     return;
1872   }
1873
1874   if (font->destroy)
1875     font->destroy (font->user_data);
1876
1877   if (!klass)
1878     klass = hb_font_funcs_get_empty ();
1879
1880   hb_font_funcs_reference (klass);
1881   hb_font_funcs_destroy (font->klass);
1882   font->klass = klass;
1883   font->user_data = font_data;
1884   font->destroy = destroy;
1885 }
1886
1887 /**
1888  * hb_font_set_funcs_data:
1889  * @font: #hb_font_t to work upon
1890  * @font_data: (destroy destroy) (scope notified): Data to attach to @font
1891  * @destroy: (nullable): The function to call when @font_data is not needed anymore
1892  *
1893  * Replaces the user data attached to a font, updating the font's
1894  * @destroy callback.
1895  *
1896  * Since: 0.9.2
1897  **/
1898 void
1899 hb_font_set_funcs_data (hb_font_t         *font,
1900                         void              *font_data,
1901                         hb_destroy_func_t  destroy /* May be NULL. */)
1902 {
1903   /* Destroy user_data? */
1904   if (hb_object_is_immutable (font))
1905   {
1906     if (destroy)
1907       destroy (font_data);
1908     return;
1909   }
1910
1911   if (font->destroy)
1912     font->destroy (font->user_data);
1913
1914   font->user_data = font_data;
1915   font->destroy = destroy;
1916 }
1917
1918
1919 /**
1920  * hb_font_set_scale:
1921  * @font: #hb_font_t to work upon
1922  * @x_scale: Horizontal scale value to assign
1923  * @y_scale: Vertical scale value to assign
1924  *
1925  * Sets the horizontal and vertical scale of a font.
1926  *
1927  * Since: 0.9.2
1928  **/
1929 void
1930 hb_font_set_scale (hb_font_t *font,
1931                    int        x_scale,
1932                    int        y_scale)
1933 {
1934   if (hb_object_is_immutable (font))
1935     return;
1936
1937   font->x_scale = x_scale;
1938   font->y_scale = y_scale;
1939   font->mults_changed ();
1940 }
1941
1942 /**
1943  * hb_font_get_scale:
1944  * @font: #hb_font_t to work upon
1945  * @x_scale: (out): Horizontal scale value
1946  * @y_scale: (out): Vertical scale value
1947  *
1948  * Fetches the horizontal and vertical scale of a font.
1949  *
1950  * Since: 0.9.2
1951  **/
1952 void
1953 hb_font_get_scale (hb_font_t *font,
1954                    int       *x_scale,
1955                    int       *y_scale)
1956 {
1957   if (x_scale) *x_scale = font->x_scale;
1958   if (y_scale) *y_scale = font->y_scale;
1959 }
1960
1961 /**
1962  * hb_font_set_ppem:
1963  * @font: #hb_font_t to work upon
1964  * @x_ppem: Horizontal ppem value to assign
1965  * @y_ppem: Vertical ppem value to assign
1966  *
1967  * Sets the horizontal and vertical pixels-per-em (ppem) of a font.
1968  *
1969  * Since: 0.9.2
1970  **/
1971 void
1972 hb_font_set_ppem (hb_font_t    *font,
1973                   unsigned int  x_ppem,
1974                   unsigned int  y_ppem)
1975 {
1976   if (hb_object_is_immutable (font))
1977     return;
1978
1979   font->x_ppem = x_ppem;
1980   font->y_ppem = y_ppem;
1981 }
1982
1983 /**
1984  * hb_font_get_ppem:
1985  * @font: #hb_font_t to work upon
1986  * @x_ppem: (out): Horizontal ppem value
1987  * @y_ppem: (out): Vertical ppem value
1988  *
1989  * Fetches the horizontal and vertical points-per-em (ppem) of a font.
1990  *
1991  * Since: 0.9.2
1992  **/
1993 void
1994 hb_font_get_ppem (hb_font_t    *font,
1995                   unsigned int *x_ppem,
1996                   unsigned int *y_ppem)
1997 {
1998   if (x_ppem) *x_ppem = font->x_ppem;
1999   if (y_ppem) *y_ppem = font->y_ppem;
2000 }
2001
2002 /**
2003  * hb_font_set_ptem:
2004  * @font: #hb_font_t to work upon
2005  * @ptem: font size in points.
2006  *
2007  * Sets the "point size" of a font. Set to zero to unset.
2008  * Used in CoreText to implement optical sizing.
2009  *
2010  * <note>Note: There are 72 points in an inch.</note>
2011  *
2012  * Since: 1.6.0
2013  **/
2014 void
2015 hb_font_set_ptem (hb_font_t *font,
2016                   float      ptem)
2017 {
2018   if (hb_object_is_immutable (font))
2019     return;
2020
2021   font->ptem = ptem;
2022 }
2023
2024 /**
2025  * hb_font_get_ptem:
2026  * @font: #hb_font_t to work upon
2027  *
2028  * Fetches the "point size" of a font. Used in CoreText to
2029  * implement optical sizing.
2030  *
2031  * Return value: Point size.  A value of zero means "not set."
2032  *
2033  * Since: 1.6.0
2034  **/
2035 float
2036 hb_font_get_ptem (hb_font_t *font)
2037 {
2038   return font->ptem;
2039 }
2040
2041 /**
2042  * hb_font_set_synthetic_slant:
2043  * @font: #hb_font_t to work upon
2044  * @slant: synthetic slant value.
2045  *
2046  * Sets the "synthetic slant" of a font.  By default is zero.
2047  * Synthetic slant is the graphical skew that the renderer
2048  * applies to the font at rendering time.
2049  *
2050  * HarfBuzz needs to know this value to adjust shaping results,
2051  * metrics, and style values to match the slanted rendering.
2052  *
2053  * <note>Note: The slant value is a ratio.  For example, a
2054  * 20% slant would be represented as a 0.2 value.</note>
2055  *
2056  * Since: 3.3.0
2057  **/
2058 HB_EXTERN void
2059 hb_font_set_synthetic_slant (hb_font_t *font, float slant)
2060 {
2061   if (hb_object_is_immutable (font))
2062     return;
2063
2064   font->slant = slant;
2065   font->mults_changed ();
2066 }
2067
2068 /**
2069  * hb_font_get_synthetic_slant:
2070  * @font: #hb_font_t to work upon
2071  *
2072  * Fetches the "synthetic slant" of a font.
2073  *
2074  * Return value: Synthetic slant.  By default is zero.
2075  *
2076  * Since: 3.3.0
2077  **/
2078 HB_EXTERN float
2079 hb_font_get_synthetic_slant (hb_font_t *font)
2080 {
2081   return font->slant;
2082 }
2083
2084 #ifndef HB_NO_VAR
2085 /*
2086  * Variations
2087  */
2088
2089 /**
2090  * hb_font_set_variations:
2091  * @font: #hb_font_t to work upon
2092  * @variations: (array length=variations_length): Array of variation settings to apply
2093  * @variations_length: Number of variations to apply
2094  *
2095  * Applies a list of font-variation settings to a font.
2096  *
2097  * Note that this overrides all existing variations set on @font.
2098  * Axes not included in @variations will be effectively set to their
2099  * default values.
2100  *
2101  * Since: 1.4.2
2102  */
2103 void
2104 hb_font_set_variations (hb_font_t            *font,
2105                         const hb_variation_t *variations,
2106                         unsigned int          variations_length)
2107 {
2108   if (hb_object_is_immutable (font))
2109     return;
2110
2111   if (!variations_length)
2112   {
2113     hb_font_set_var_coords_normalized (font, nullptr, 0);
2114     return;
2115   }
2116
2117   const OT::fvar &fvar = *font->face->table.fvar;
2118   auto axes = fvar.get_axes ();
2119   const unsigned coords_length = axes.length;
2120
2121   int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
2122   float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
2123
2124   if (unlikely (coords_length && !(normalized && design_coords)))
2125   {
2126     hb_free (normalized);
2127     hb_free (design_coords);
2128     return;
2129   }
2130
2131   for (unsigned int i = 0; i < variations_length; i++)
2132   {
2133     const auto tag = variations[i].tag;
2134     const auto v = variations[i].value;
2135     for (unsigned axis_index = 0; axis_index < coords_length; axis_index++)
2136       if (axes[axis_index].axisTag == tag)
2137       {
2138         design_coords[axis_index] = v;
2139         normalized[axis_index] = fvar.normalize_axis_value (axis_index, v);
2140       }
2141   }
2142   font->face->table.avar->map_coords (normalized, coords_length);
2143
2144   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
2145 }
2146
2147 /**
2148  * hb_font_set_var_coords_design:
2149  * @font: #hb_font_t to work upon
2150  * @coords: (array length=coords_length): Array of variation coordinates to apply
2151  * @coords_length: Number of coordinates to apply
2152  *
2153  * Applies a list of variation coordinates (in design-space units)
2154  * to a font.
2155  *
2156  * Note that this overrides all existing variations set on @font.
2157  * Axes not included in @coords will be effectively set to their
2158  * default values.
2159  *
2160  * Since: 1.4.2
2161  */
2162 void
2163 hb_font_set_var_coords_design (hb_font_t    *font,
2164                                const float  *coords,
2165                                unsigned int  coords_length)
2166 {
2167   if (hb_object_is_immutable (font))
2168     return;
2169
2170   int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
2171   float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
2172
2173   if (unlikely (coords_length && !(normalized && design_coords)))
2174   {
2175     hb_free (normalized);
2176     hb_free (design_coords);
2177     return;
2178   }
2179
2180   if (coords_length)
2181     memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
2182
2183   hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
2184   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
2185 }
2186
2187 /**
2188  * hb_font_set_var_named_instance:
2189  * @font: a font.
2190  * @instance_index: named instance index.
2191  *
2192  * Sets design coords of a font from a named instance index.
2193  *
2194  * Since: 2.6.0
2195  */
2196 void
2197 hb_font_set_var_named_instance (hb_font_t *font,
2198                                 unsigned instance_index)
2199 {
2200   if (hb_object_is_immutable (font))
2201     return;
2202
2203   unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr);
2204
2205   float *coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
2206   if (unlikely (coords_length && !coords))
2207     return;
2208
2209   hb_ot_var_named_instance_get_design_coords (font->face, instance_index, &coords_length, coords);
2210   hb_font_set_var_coords_design (font, coords, coords_length);
2211   hb_free (coords);
2212 }
2213
2214 /**
2215  * hb_font_set_var_coords_normalized:
2216  * @font: #hb_font_t to work upon
2217  * @coords: (array length=coords_length): Array of variation coordinates to apply
2218  * @coords_length: Number of coordinates to apply
2219  *
2220  * Applies a list of variation coordinates (in normalized units)
2221  * to a font.
2222  *
2223  * Note that this overrides all existing variations set on @font.
2224  * Axes not included in @coords will be effectively set to their
2225  * default values.
2226  *
2227  * <note>Note: Coordinates should be normalized to 2.14.</note>
2228  *
2229  * Since: 1.4.2
2230  */
2231 void
2232 hb_font_set_var_coords_normalized (hb_font_t    *font,
2233                                    const int    *coords, /* 2.14 normalized */
2234                                    unsigned int  coords_length)
2235 {
2236   if (hb_object_is_immutable (font))
2237     return;
2238
2239   int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
2240   int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
2241   float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr;
2242
2243   if (unlikely (coords_length && !(copy && unmapped && design_coords)))
2244   {
2245     hb_free (copy);
2246     hb_free (unmapped);
2247     hb_free (design_coords);
2248     return;
2249   }
2250
2251   if (coords_length)
2252   {
2253     memcpy (copy, coords, coords_length * sizeof (coords[0]));
2254     memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
2255   }
2256
2257   /* Best effort design coords simulation */
2258   font->face->table.avar->unmap_coords (unmapped, coords_length);
2259   for (unsigned int i = 0; i < coords_length; ++i)
2260     design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]);
2261   hb_free (unmapped);
2262
2263   _hb_font_adopt_var_coords (font, copy, design_coords, coords_length);
2264 }
2265
2266 /**
2267  * hb_font_get_var_coords_normalized:
2268  * @font: #hb_font_t to work upon
2269  * @length: (out): Number of coordinates retrieved
2270  *
2271  * Fetches the list of normalized variation coordinates currently
2272  * set on a font.
2273  *
2274  * Note that this returned array may only contain values for some
2275  * (or none) of the axes; omitted axes effectively have zero values.
2276  *
2277  * Return value is valid as long as variation coordinates of the font
2278  * are not modified.
2279  *
2280  * Return value: coordinates array
2281  *
2282  * Since: 1.4.2
2283  */
2284 const int *
2285 hb_font_get_var_coords_normalized (hb_font_t    *font,
2286                                    unsigned int *length)
2287 {
2288   if (length)
2289     *length = font->num_coords;
2290
2291   return font->coords;
2292 }
2293
2294 /**
2295  * hb_font_get_var_coords_design:
2296  * @font: #hb_font_t to work upon
2297  * @length: (out): Number of coordinates retrieved
2298  *
2299  * Fetches the list of variation coordinates (in design-space units) currently
2300  * set on a font.
2301  *
2302  * Note that this returned array may only contain values for some
2303  * (or none) of the axes; omitted axes effectively have their default
2304  * values.
2305  *
2306  * Return value is valid as long as variation coordinates of the font
2307  * are not modified.
2308  *
2309  * Return value: coordinates array
2310  *
2311  * Since: 3.3.0
2312  */
2313 const float *
2314 hb_font_get_var_coords_design (hb_font_t *font,
2315                                unsigned int *length)
2316 {
2317   if (length)
2318     *length = font->num_coords;
2319
2320   return font->design_coords;
2321 }
2322 #endif
2323
2324 #ifndef HB_DISABLE_DEPRECATED
2325 /*
2326  * Deprecated get_glyph_func():
2327  */
2328
2329 struct hb_trampoline_closure_t
2330 {
2331   void *user_data;
2332   hb_destroy_func_t destroy;
2333   unsigned int ref_count;
2334 };
2335
2336 template <typename FuncType>
2337 struct hb_trampoline_t
2338 {
2339   hb_trampoline_closure_t closure; /* Must be first. */
2340   FuncType func;
2341 };
2342
2343 template <typename FuncType>
2344 static hb_trampoline_t<FuncType> *
2345 trampoline_create (FuncType           func,
2346                    void              *user_data,
2347                    hb_destroy_func_t  destroy)
2348 {
2349   typedef hb_trampoline_t<FuncType> trampoline_t;
2350
2351   trampoline_t *trampoline = (trampoline_t *) hb_calloc (1, sizeof (trampoline_t));
2352
2353   if (unlikely (!trampoline))
2354     return nullptr;
2355
2356   trampoline->closure.user_data = user_data;
2357   trampoline->closure.destroy = destroy;
2358   trampoline->closure.ref_count = 1;
2359   trampoline->func = func;
2360
2361   return trampoline;
2362 }
2363
2364 static void
2365 trampoline_reference (hb_trampoline_closure_t *closure)
2366 {
2367   closure->ref_count++;
2368 }
2369
2370 static void
2371 trampoline_destroy (void *user_data)
2372 {
2373   hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
2374
2375   if (--closure->ref_count)
2376     return;
2377
2378   if (closure->destroy)
2379     closure->destroy (closure->user_data);
2380   hb_free (closure);
2381 }
2382
2383 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
2384
2385 static hb_bool_t
2386 hb_font_get_nominal_glyph_trampoline (hb_font_t      *font,
2387                                       void           *font_data,
2388                                       hb_codepoint_t  unicode,
2389                                       hb_codepoint_t *glyph,
2390                                       void           *user_data)
2391 {
2392   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
2393   return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
2394 }
2395
2396 static hb_bool_t
2397 hb_font_get_variation_glyph_trampoline (hb_font_t      *font,
2398                                         void           *font_data,
2399                                         hb_codepoint_t  unicode,
2400                                         hb_codepoint_t  variation_selector,
2401                                         hb_codepoint_t *glyph,
2402                                         void           *user_data)
2403 {
2404   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
2405   return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
2406 }
2407
2408 /**
2409  * hb_font_funcs_set_glyph_func:
2410  * @ffuncs: The font-functions structure
2411  * @func: (closure user_data) (destroy destroy) (scope notified): callback function
2412  * @user_data: data to pass to @func
2413  * @destroy: (nullable): function to call when @user_data is not needed anymore
2414  *
2415  * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
2416  * hb_font_funcs_set_variation_glyph_func() instead.
2417  *
2418  * Since: 0.9.2
2419  * Deprecated: 1.2.3
2420  **/
2421 void
2422 hb_font_funcs_set_glyph_func (hb_font_funcs_t          *ffuncs,
2423                               hb_font_get_glyph_func_t  func,
2424                               void                     *user_data,
2425                               hb_destroy_func_t         destroy /* May be NULL. */)
2426 {
2427   if (hb_object_is_immutable (ffuncs))
2428   {
2429     if (destroy)
2430       destroy (user_data);
2431     return;
2432   }
2433
2434   hb_font_get_glyph_trampoline_t *trampoline;
2435
2436   trampoline = trampoline_create (func, user_data, destroy);
2437   if (unlikely (!trampoline))
2438   {
2439     if (destroy)
2440       destroy (user_data);
2441     return;
2442   }
2443
2444   hb_font_funcs_set_nominal_glyph_func (ffuncs,
2445                                         hb_font_get_nominal_glyph_trampoline,
2446                                         trampoline,
2447                                         trampoline_destroy);
2448
2449   trampoline_reference (&trampoline->closure);
2450   hb_font_funcs_set_variation_glyph_func (ffuncs,
2451                                           hb_font_get_variation_glyph_trampoline,
2452                                           trampoline,
2453                                           trampoline_destroy);
2454 }
2455 #endif