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