Imported Upstream version 2.6.7
[platform/upstream/harfbuzz.git] / src / hb-font.cc
1 /*
2  * Copyright © 2009  Red Hat, Inc.
3  * Copyright © 2012  Google, Inc.
4  *
5  *  This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Red Hat Author(s): Behdad Esfahbod
26  * Google Author(s): Behdad Esfahbod
27  */
28
29 #include "hb.hh"
30
31 #include "hb-font.hh"
32 #include "hb-machinery.hh"
33
34 #include "hb-ot.h"
35
36 #include "hb-ot-var-avar-table.hh"
37 #include "hb-ot-var-fvar-table.hh"
38
39
40 /**
41  * SECTION:hb-font
42  * @title: hb-font
43  * @short_description: Font objects
44  * @include: hb.h
45  *
46  * Font objects represent a font face at a certain size and other
47  * parameters (pixels per EM, points per EM, variation settings.)
48  * Fonts are created from font faces, and are used as input to
49  * hb_shape() among other things.
50  **/
51
52
53 /*
54  * hb_font_funcs_t
55  */
56
57 static hb_bool_t
58 hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED,
59                                 void *font_data HB_UNUSED,
60                                 hb_font_extents_t *extents,
61                                 void *user_data HB_UNUSED)
62 {
63   memset (extents, 0, sizeof (*extents));
64   return false;
65 }
66 static hb_bool_t
67 hb_font_get_font_h_extents_default (hb_font_t *font,
68                                     void *font_data HB_UNUSED,
69                                     hb_font_extents_t *extents,
70                                     void *user_data HB_UNUSED)
71 {
72   hb_bool_t ret = font->parent->get_font_h_extents (extents);
73   if (ret) {
74     extents->ascender = font->parent_scale_y_distance (extents->ascender);
75     extents->descender = font->parent_scale_y_distance (extents->descender);
76     extents->line_gap = font->parent_scale_y_distance (extents->line_gap);
77   }
78   return ret;
79 }
80
81 static hb_bool_t
82 hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED,
83                                 void *font_data HB_UNUSED,
84                                 hb_font_extents_t *extents,
85                                 void *user_data HB_UNUSED)
86 {
87   memset (extents, 0, sizeof (*extents));
88   return false;
89 }
90 static hb_bool_t
91 hb_font_get_font_v_extents_default (hb_font_t *font,
92                                     void *font_data HB_UNUSED,
93                                     hb_font_extents_t *extents,
94                                     void *user_data HB_UNUSED)
95 {
96   hb_bool_t ret = font->parent->get_font_v_extents (extents);
97   if (ret) {
98     extents->ascender = font->parent_scale_x_distance (extents->ascender);
99     extents->descender = font->parent_scale_x_distance (extents->descender);
100     extents->line_gap = font->parent_scale_x_distance (extents->line_gap);
101   }
102   return ret;
103 }
104
105 static hb_bool_t
106 hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
107                                void *font_data HB_UNUSED,
108                                hb_codepoint_t unicode HB_UNUSED,
109                                hb_codepoint_t *glyph,
110                                void *user_data HB_UNUSED)
111 {
112   *glyph = 0;
113   return false;
114 }
115 static hb_bool_t
116 hb_font_get_nominal_glyph_default (hb_font_t *font,
117                                    void *font_data HB_UNUSED,
118                                    hb_codepoint_t unicode,
119                                    hb_codepoint_t *glyph,
120                                    void *user_data HB_UNUSED)
121 {
122   if (font->has_nominal_glyphs_func_set ())
123   {
124     return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0);
125   }
126   return font->parent->get_nominal_glyph (unicode, glyph);
127 }
128
129 #define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
130 static unsigned int
131 hb_font_get_nominal_glyphs_default (hb_font_t *font,
132                                     void *font_data HB_UNUSED,
133                                     unsigned int count,
134                                     const hb_codepoint_t *first_unicode,
135                                     unsigned int unicode_stride,
136                                     hb_codepoint_t *first_glyph,
137                                     unsigned int glyph_stride,
138                                     void *user_data HB_UNUSED)
139 {
140   if (font->has_nominal_glyph_func_set ())
141   {
142     for (unsigned int i = 0; i < count; i++)
143     {
144       if (!font->get_nominal_glyph (*first_unicode, first_glyph))
145         return i;
146
147       first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
148       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
149     }
150     return count;
151   }
152
153   return font->parent->get_nominal_glyphs (count,
154                                            first_unicode, unicode_stride,
155                                            first_glyph, glyph_stride);
156 }
157
158 static hb_bool_t
159 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
160                                  void *font_data HB_UNUSED,
161                                  hb_codepoint_t unicode HB_UNUSED,
162                                  hb_codepoint_t variation_selector HB_UNUSED,
163                                  hb_codepoint_t *glyph,
164                                  void *user_data HB_UNUSED)
165 {
166   *glyph = 0;
167   return false;
168 }
169 static hb_bool_t
170 hb_font_get_variation_glyph_default (hb_font_t *font,
171                                      void *font_data HB_UNUSED,
172                                      hb_codepoint_t unicode,
173                                      hb_codepoint_t variation_selector,
174                                      hb_codepoint_t *glyph,
175                                      void *user_data HB_UNUSED)
176 {
177   return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
178 }
179
180
181 static hb_position_t
182 hb_font_get_glyph_h_advance_nil (hb_font_t *font,
183                                  void *font_data HB_UNUSED,
184                                  hb_codepoint_t glyph HB_UNUSED,
185                                  void *user_data HB_UNUSED)
186 {
187   return font->x_scale;
188 }
189 static hb_position_t
190 hb_font_get_glyph_h_advance_default (hb_font_t *font,
191                                      void *font_data HB_UNUSED,
192                                      hb_codepoint_t glyph,
193                                      void *user_data HB_UNUSED)
194 {
195   if (font->has_glyph_h_advances_func_set ())
196   {
197     hb_position_t ret;
198     font->get_glyph_h_advances (1, &glyph, 0, &ret, 0);
199     return ret;
200   }
201   return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
202 }
203
204 static hb_position_t
205 hb_font_get_glyph_v_advance_nil (hb_font_t *font,
206                                  void *font_data HB_UNUSED,
207                                  hb_codepoint_t glyph HB_UNUSED,
208                                  void *user_data HB_UNUSED)
209 {
210   /* TODO use font_extents.ascender+descender */
211   return font->y_scale;
212 }
213 static hb_position_t
214 hb_font_get_glyph_v_advance_default (hb_font_t *font,
215                                      void *font_data HB_UNUSED,
216                                      hb_codepoint_t glyph,
217                                      void *user_data HB_UNUSED)
218 {
219   if (font->has_glyph_v_advances_func_set ())
220   {
221     hb_position_t ret;
222     font->get_glyph_v_advances (1, &glyph, 0, &ret, 0);
223     return ret;
224   }
225   return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
226 }
227
228 #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default
229 static void
230 hb_font_get_glyph_h_advances_default (hb_font_t* font,
231                                       void* font_data HB_UNUSED,
232                                       unsigned int count,
233                                       const hb_codepoint_t *first_glyph,
234                                       unsigned int glyph_stride,
235                                       hb_position_t *first_advance,
236                                       unsigned int advance_stride,
237                                       void *user_data HB_UNUSED)
238 {
239   if (font->has_glyph_h_advance_func_set ())
240   {
241     for (unsigned int i = 0; i < count; i++)
242     {
243       *first_advance = font->get_glyph_h_advance (*first_glyph);
244       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
245       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
246     }
247     return;
248   }
249
250   font->parent->get_glyph_h_advances (count,
251                                       first_glyph, glyph_stride,
252                                       first_advance, advance_stride);
253   for (unsigned int i = 0; i < count; i++)
254   {
255     *first_advance = font->parent_scale_x_distance (*first_advance);
256     first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
257   }
258 }
259
260 #define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default
261 static void
262 hb_font_get_glyph_v_advances_default (hb_font_t* font,
263                                       void* font_data HB_UNUSED,
264                                       unsigned int count,
265                                       const hb_codepoint_t *first_glyph,
266                                       unsigned int glyph_stride,
267                                       hb_position_t *first_advance,
268                                       unsigned int advance_stride,
269                                       void *user_data HB_UNUSED)
270 {
271   if (font->has_glyph_v_advance_func_set ())
272   {
273     for (unsigned int i = 0; i < count; i++)
274     {
275       *first_advance = font->get_glyph_v_advance (*first_glyph);
276       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
277       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
278     }
279     return;
280   }
281
282   font->parent->get_glyph_v_advances (count,
283                                       first_glyph, glyph_stride,
284                                       first_advance, advance_stride);
285   for (unsigned int i = 0; i < count; i++)
286   {
287     *first_advance = font->parent_scale_y_distance (*first_advance);
288     first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
289   }
290 }
291
292 static hb_bool_t
293 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
294                                 void *font_data HB_UNUSED,
295                                 hb_codepoint_t glyph HB_UNUSED,
296                                 hb_position_t *x,
297                                 hb_position_t *y,
298                                 void *user_data HB_UNUSED)
299 {
300   *x = *y = 0;
301   return true;
302 }
303 static hb_bool_t
304 hb_font_get_glyph_h_origin_default (hb_font_t *font,
305                                     void *font_data HB_UNUSED,
306                                     hb_codepoint_t glyph,
307                                     hb_position_t *x,
308                                     hb_position_t *y,
309                                     void *user_data HB_UNUSED)
310 {
311   hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
312   if (ret)
313     font->parent_scale_position (x, y);
314   return ret;
315 }
316
317 static hb_bool_t
318 hb_font_get_glyph_v_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 false;
327 }
328 static hb_bool_t
329 hb_font_get_glyph_v_origin_default (hb_font_t *font,
330                                     void *font_data HB_UNUSED,
331                                     hb_codepoint_t glyph,
332                                     hb_position_t *x,
333                                     hb_position_t *y,
334                                     void *user_data HB_UNUSED)
335 {
336   hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
337   if (ret)
338     font->parent_scale_position (x, y);
339   return ret;
340 }
341
342 static hb_position_t
343 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
344                                  void *font_data HB_UNUSED,
345                                  hb_codepoint_t left_glyph HB_UNUSED,
346                                  hb_codepoint_t right_glyph HB_UNUSED,
347                                  void *user_data HB_UNUSED)
348 {
349   return 0;
350 }
351 static hb_position_t
352 hb_font_get_glyph_h_kerning_default (hb_font_t *font,
353                                      void *font_data HB_UNUSED,
354                                      hb_codepoint_t left_glyph,
355                                      hb_codepoint_t right_glyph,
356                                      void *user_data HB_UNUSED)
357 {
358   return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
359 }
360
361 #ifndef HB_DISABLE_DEPRECATED
362 static hb_position_t
363 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
364                                  void *font_data HB_UNUSED,
365                                  hb_codepoint_t top_glyph HB_UNUSED,
366                                  hb_codepoint_t bottom_glyph HB_UNUSED,
367                                  void *user_data HB_UNUSED)
368 {
369   return 0;
370 }
371 static hb_position_t
372 hb_font_get_glyph_v_kerning_default (hb_font_t *font,
373                                      void *font_data HB_UNUSED,
374                                      hb_codepoint_t top_glyph,
375                                      hb_codepoint_t bottom_glyph,
376                                      void *user_data HB_UNUSED)
377 {
378   return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
379 }
380 #endif
381
382 static hb_bool_t
383 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
384                                void *font_data HB_UNUSED,
385                                hb_codepoint_t glyph HB_UNUSED,
386                                hb_glyph_extents_t *extents,
387                                void *user_data HB_UNUSED)
388 {
389   memset (extents, 0, sizeof (*extents));
390   return false;
391 }
392 static hb_bool_t
393 hb_font_get_glyph_extents_default (hb_font_t *font,
394                                    void *font_data HB_UNUSED,
395                                    hb_codepoint_t glyph,
396                                    hb_glyph_extents_t *extents,
397                                    void *user_data HB_UNUSED)
398 {
399   hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
400   if (ret) {
401     font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
402     font->parent_scale_distance (&extents->width, &extents->height);
403   }
404   return ret;
405 }
406
407 static hb_bool_t
408 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
409                                      void *font_data HB_UNUSED,
410                                      hb_codepoint_t glyph HB_UNUSED,
411                                      unsigned int point_index HB_UNUSED,
412                                      hb_position_t *x,
413                                      hb_position_t *y,
414                                      void *user_data HB_UNUSED)
415 {
416   *x = *y = 0;
417   return false;
418 }
419 static hb_bool_t
420 hb_font_get_glyph_contour_point_default (hb_font_t *font,
421                                          void *font_data HB_UNUSED,
422                                          hb_codepoint_t glyph,
423                                          unsigned int point_index,
424                                          hb_position_t *x,
425                                          hb_position_t *y,
426                                          void *user_data HB_UNUSED)
427 {
428   hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
429   if (ret)
430     font->parent_scale_position (x, y);
431   return ret;
432 }
433
434 static hb_bool_t
435 hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
436                             void *font_data HB_UNUSED,
437                             hb_codepoint_t glyph HB_UNUSED,
438                             char *name, unsigned int size,
439                             void *user_data HB_UNUSED)
440 {
441   if (size) *name = '\0';
442   return false;
443 }
444 static hb_bool_t
445 hb_font_get_glyph_name_default (hb_font_t *font,
446                                 void *font_data HB_UNUSED,
447                                 hb_codepoint_t glyph,
448                                 char *name, unsigned int size,
449                                 void *user_data HB_UNUSED)
450 {
451   return font->parent->get_glyph_name (glyph, name, size);
452 }
453
454 static hb_bool_t
455 hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
456                                  void *font_data HB_UNUSED,
457                                  const char *name HB_UNUSED,
458                                  int len HB_UNUSED, /* -1 means nul-terminated */
459                                  hb_codepoint_t *glyph,
460                                  void *user_data HB_UNUSED)
461 {
462   *glyph = 0;
463   return false;
464 }
465 static hb_bool_t
466 hb_font_get_glyph_from_name_default (hb_font_t *font,
467                                      void *font_data HB_UNUSED,
468                                      const char *name, int len, /* -1 means nul-terminated */
469                                      hb_codepoint_t *glyph,
470                                      void *user_data HB_UNUSED)
471 {
472   return font->parent->get_glyph_from_name (name, len, glyph);
473 }
474
475 DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
476 {
477   HB_OBJECT_HEADER_STATIC,
478
479   {
480 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
481     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
482 #undef HB_FONT_FUNC_IMPLEMENT
483   },
484   {
485 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
486     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
487 #undef HB_FONT_FUNC_IMPLEMENT
488   },
489   {
490     {
491 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
492       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
493 #undef HB_FONT_FUNC_IMPLEMENT
494     }
495   }
496 };
497
498 static const hb_font_funcs_t _hb_font_funcs_default = {
499   HB_OBJECT_HEADER_STATIC,
500
501   {
502 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
503     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
504 #undef HB_FONT_FUNC_IMPLEMENT
505   },
506   {
507 #define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
508     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
509 #undef HB_FONT_FUNC_IMPLEMENT
510   },
511   {
512     {
513 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default,
514       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
515 #undef HB_FONT_FUNC_IMPLEMENT
516     }
517   }
518 };
519
520
521 /**
522  * hb_font_funcs_create: (Xconstructor)
523  *
524  *
525  *
526  * Return value: (transfer full):
527  *
528  * Since: 0.9.2
529  **/
530 hb_font_funcs_t *
531 hb_font_funcs_create ()
532 {
533   hb_font_funcs_t *ffuncs;
534
535   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
536     return hb_font_funcs_get_empty ();
537
538   ffuncs->get = _hb_font_funcs_default.get;
539
540   return ffuncs;
541 }
542
543 /**
544  * hb_font_funcs_get_empty:
545  *
546  *
547  *
548  * Return value: (transfer full):
549  *
550  * Since: 0.9.2
551  **/
552 hb_font_funcs_t *
553 hb_font_funcs_get_empty ()
554 {
555   return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default);
556 }
557
558 /**
559  * hb_font_funcs_reference: (skip)
560  * @ffuncs: font functions.
561  *
562  *
563  *
564  * Return value:
565  *
566  * Since: 0.9.2
567  **/
568 hb_font_funcs_t *
569 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
570 {
571   return hb_object_reference (ffuncs);
572 }
573
574 /**
575  * hb_font_funcs_destroy: (skip)
576  * @ffuncs: font functions.
577  *
578  *
579  *
580  * Since: 0.9.2
581  **/
582 void
583 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
584 {
585   if (!hb_object_destroy (ffuncs)) return;
586
587 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
588   ffuncs->destroy.name (ffuncs->user_data.name);
589   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
590 #undef HB_FONT_FUNC_IMPLEMENT
591
592   free (ffuncs);
593 }
594
595 /**
596  * hb_font_funcs_set_user_data: (skip)
597  * @ffuncs: font functions.
598  * @key:
599  * @data:
600  * @destroy:
601  * @replace:
602  *
603  *
604  *
605  * Return value:
606  *
607  * Since: 0.9.2
608  **/
609 hb_bool_t
610 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
611                              hb_user_data_key_t *key,
612                              void *              data,
613                              hb_destroy_func_t   destroy,
614                              hb_bool_t           replace)
615 {
616   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
617 }
618
619 /**
620  * hb_font_funcs_get_user_data: (skip)
621  * @ffuncs: font functions.
622  * @key:
623  *
624  *
625  *
626  * Return value: (transfer none):
627  *
628  * Since: 0.9.2
629  **/
630 void *
631 hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
632                              hb_user_data_key_t *key)
633 {
634   return hb_object_get_user_data (ffuncs, key);
635 }
636
637
638 /**
639  * hb_font_funcs_make_immutable:
640  * @ffuncs: font functions.
641  *
642  *
643  *
644  * Since: 0.9.2
645  **/
646 void
647 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
648 {
649   if (hb_object_is_immutable (ffuncs))
650     return;
651
652   hb_object_make_immutable (ffuncs);
653 }
654
655 /**
656  * hb_font_funcs_is_immutable:
657  * @ffuncs: font functions.
658  *
659  *
660  *
661  * Return value:
662  *
663  * Since: 0.9.2
664  **/
665 hb_bool_t
666 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
667 {
668   return hb_object_is_immutable (ffuncs);
669 }
670
671
672 #define HB_FONT_FUNC_IMPLEMENT(name) \
673                                                                          \
674 void                                                                     \
675 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
676                                  hb_font_get_##name##_func_t  func,      \
677                                  void                        *user_data, \
678                                  hb_destroy_func_t            destroy)   \
679 {                                                                        \
680   if (hb_object_is_immutable (ffuncs))                                   \
681   {                                                                      \
682     if (destroy)                                                         \
683       destroy (user_data);                                               \
684     return;                                                              \
685   }                                                                      \
686                                                                          \
687   if (ffuncs->destroy.name)                                              \
688     ffuncs->destroy.name (ffuncs->user_data.name);                       \
689                                                                          \
690   if (func) {                                                            \
691     ffuncs->get.f.name = func;                                           \
692     ffuncs->user_data.name = user_data;                                  \
693     ffuncs->destroy.name = destroy;                                      \
694   } else {                                                               \
695     ffuncs->get.f.name = hb_font_get_##name##_default;                   \
696     ffuncs->user_data.name = nullptr;                                    \
697     ffuncs->destroy.name = nullptr;                                      \
698   }                                                                      \
699 }
700
701 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
702 #undef HB_FONT_FUNC_IMPLEMENT
703
704 bool
705 hb_font_t::has_func_set (unsigned int i)
706 {
707   return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i];
708 }
709
710 bool
711 hb_font_t::has_func (unsigned int i)
712 {
713   return has_func_set (i) ||
714          (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i));
715 }
716
717 /* Public getters */
718
719 /**
720  * hb_font_get_h_extents:
721  * @font: a font.
722  * @extents: (out):
723  *
724  *
725  *
726  * Return value:
727  *
728  * Since: 1.1.3
729  **/
730 hb_bool_t
731 hb_font_get_h_extents (hb_font_t *font,
732                        hb_font_extents_t *extents)
733 {
734   return font->get_font_h_extents (extents);
735 }
736
737 /**
738  * hb_font_get_v_extents:
739  * @font: a font.
740  * @extents: (out):
741  *
742  *
743  *
744  * Return value:
745  *
746  * Since: 1.1.3
747  **/
748 hb_bool_t
749 hb_font_get_v_extents (hb_font_t *font,
750                        hb_font_extents_t *extents)
751 {
752   return font->get_font_v_extents (extents);
753 }
754
755 /**
756  * hb_font_get_glyph:
757  * @font: a font.
758  * @unicode:
759  * @variation_selector:
760  * @glyph: (out):
761  *
762  *
763  *
764  * Return value:
765  *
766  * Since: 0.9.2
767  **/
768 hb_bool_t
769 hb_font_get_glyph (hb_font_t *font,
770                    hb_codepoint_t unicode, hb_codepoint_t variation_selector,
771                    hb_codepoint_t *glyph)
772 {
773   if (unlikely (variation_selector))
774     return font->get_variation_glyph (unicode, variation_selector, glyph);
775   return font->get_nominal_glyph (unicode, glyph);
776 }
777
778 /**
779  * hb_font_get_nominal_glyph:
780  * @font: a font.
781  * @unicode:
782  * @glyph: (out):
783  *
784  *
785  *
786  * Return value:
787  *
788  * Since: 1.2.3
789  **/
790 hb_bool_t
791 hb_font_get_nominal_glyph (hb_font_t *font,
792                            hb_codepoint_t unicode,
793                            hb_codepoint_t *glyph)
794 {
795   return font->get_nominal_glyph (unicode, glyph);
796 }
797
798 /**
799  * hb_font_get_nominal_glyphs:
800  * @font: a font.
801  *
802  *
803  *
804  * Return value:
805  *
806  * Since: 2.6.3
807  **/
808 unsigned int
809 hb_font_get_nominal_glyphs (hb_font_t *font,
810                             unsigned int count,
811                             const hb_codepoint_t *first_unicode,
812                             unsigned int unicode_stride,
813                             hb_codepoint_t *first_glyph,
814                             unsigned int glyph_stride)
815 {
816   return font->get_nominal_glyphs (count,
817                                    first_unicode, unicode_stride,
818                                    first_glyph, glyph_stride);
819 }
820
821 /**
822  * hb_font_get_variation_glyph:
823  * @font: a font.
824  * @unicode:
825  * @variation_selector:
826  * @glyph: (out):
827  *
828  *
829  *
830  * Return value:
831  *
832  * Since: 1.2.3
833  **/
834 hb_bool_t
835 hb_font_get_variation_glyph (hb_font_t *font,
836                              hb_codepoint_t unicode, hb_codepoint_t variation_selector,
837                              hb_codepoint_t *glyph)
838 {
839   return font->get_variation_glyph (unicode, variation_selector, glyph);
840 }
841
842 /**
843  * hb_font_get_glyph_h_advance:
844  * @font: a font.
845  * @glyph:
846  *
847  *
848  *
849  * Return value:
850  *
851  * Since: 0.9.2
852  **/
853 hb_position_t
854 hb_font_get_glyph_h_advance (hb_font_t *font,
855                              hb_codepoint_t glyph)
856 {
857   return font->get_glyph_h_advance (glyph);
858 }
859
860 /**
861  * hb_font_get_glyph_v_advance:
862  * @font: a font.
863  * @glyph:
864  *
865  *
866  *
867  * Return value:
868  *
869  * Since: 0.9.2
870  **/
871 hb_position_t
872 hb_font_get_glyph_v_advance (hb_font_t *font,
873                              hb_codepoint_t glyph)
874 {
875   return font->get_glyph_v_advance (glyph);
876 }
877
878 /**
879  * hb_font_get_glyph_h_advances:
880  * @font: a font.
881  *
882  *
883  *
884  * Since: 1.8.6
885  **/
886 void
887 hb_font_get_glyph_h_advances (hb_font_t* font,
888                               unsigned int count,
889                               const hb_codepoint_t *first_glyph,
890                               unsigned glyph_stride,
891                               hb_position_t *first_advance,
892                               unsigned advance_stride)
893 {
894   font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
895 }
896 /**
897  * hb_font_get_glyph_v_advances:
898  * @font: a font.
899  *
900  *
901  *
902  * Since: 1.8.6
903  **/
904 void
905 hb_font_get_glyph_v_advances (hb_font_t* font,
906                               unsigned int count,
907                               const hb_codepoint_t *first_glyph,
908                               unsigned glyph_stride,
909                               hb_position_t *first_advance,
910                               unsigned advance_stride)
911 {
912   font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
913 }
914
915 /**
916  * hb_font_get_glyph_h_origin:
917  * @font: a font.
918  * @glyph:
919  * @x: (out):
920  * @y: (out):
921  *
922  *
923  *
924  * Return value:
925  *
926  * Since: 0.9.2
927  **/
928 hb_bool_t
929 hb_font_get_glyph_h_origin (hb_font_t *font,
930                             hb_codepoint_t glyph,
931                             hb_position_t *x, hb_position_t *y)
932 {
933   return font->get_glyph_h_origin (glyph, x, y);
934 }
935
936 /**
937  * hb_font_get_glyph_v_origin:
938  * @font: a font.
939  * @glyph:
940  * @x: (out):
941  * @y: (out):
942  *
943  *
944  *
945  * Return value:
946  *
947  * Since: 0.9.2
948  **/
949 hb_bool_t
950 hb_font_get_glyph_v_origin (hb_font_t *font,
951                             hb_codepoint_t glyph,
952                             hb_position_t *x, hb_position_t *y)
953 {
954   return font->get_glyph_v_origin (glyph, x, y);
955 }
956
957 /**
958  * hb_font_get_glyph_h_kerning:
959  * @font: a font.
960  * @left_glyph:
961  * @right_glyph:
962  *
963  *
964  *
965  * Return value:
966  *
967  * Since: 0.9.2
968  **/
969 hb_position_t
970 hb_font_get_glyph_h_kerning (hb_font_t *font,
971                              hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
972 {
973   return font->get_glyph_h_kerning (left_glyph, right_glyph);
974 }
975
976 #ifndef HB_DISABLE_DEPRECATED
977 /**
978  * hb_font_get_glyph_v_kerning:
979  * @font: a font.
980  * @top_glyph:
981  * @bottom_glyph:
982  *
983  *
984  *
985  * Return value:
986  *
987  * Since: 0.9.2
988  * Deprecated: 2.0.0
989  **/
990 hb_position_t
991 hb_font_get_glyph_v_kerning (hb_font_t *font,
992                              hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
993 {
994   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
995 }
996 #endif
997
998 /**
999  * hb_font_get_glyph_extents:
1000  * @font: a font.
1001  * @glyph:
1002  * @extents: (out):
1003  *
1004  *
1005  *
1006  * Return value:
1007  *
1008  * Since: 0.9.2
1009  **/
1010 hb_bool_t
1011 hb_font_get_glyph_extents (hb_font_t *font,
1012                            hb_codepoint_t glyph,
1013                            hb_glyph_extents_t *extents)
1014 {
1015   return font->get_glyph_extents (glyph, extents);
1016 }
1017
1018 /**
1019  * hb_font_get_glyph_contour_point:
1020  * @font: a font.
1021  * @glyph:
1022  * @point_index:
1023  * @x: (out):
1024  * @y: (out):
1025  *
1026  *
1027  *
1028  * Return value:
1029  *
1030  * Since: 0.9.2
1031  **/
1032 hb_bool_t
1033 hb_font_get_glyph_contour_point (hb_font_t *font,
1034                                  hb_codepoint_t glyph, unsigned int point_index,
1035                                  hb_position_t *x, hb_position_t *y)
1036 {
1037   return font->get_glyph_contour_point (glyph, point_index, x, y);
1038 }
1039
1040 /**
1041  * hb_font_get_glyph_name:
1042  * @font: a font.
1043  * @glyph:
1044  * @name: (array length=size):
1045  * @size:
1046  *
1047  *
1048  *
1049  * Return value:
1050  *
1051  * Since: 0.9.2
1052  **/
1053 hb_bool_t
1054 hb_font_get_glyph_name (hb_font_t *font,
1055                         hb_codepoint_t glyph,
1056                         char *name, unsigned int size)
1057 {
1058   return font->get_glyph_name (glyph, name, size);
1059 }
1060
1061 /**
1062  * hb_font_get_glyph_from_name:
1063  * @font: a font.
1064  * @name: (array length=len):
1065  * @len:
1066  * @glyph: (out):
1067  *
1068  *
1069  *
1070  * Return value:
1071  *
1072  * Since: 0.9.2
1073  **/
1074 hb_bool_t
1075 hb_font_get_glyph_from_name (hb_font_t *font,
1076                              const char *name, int len, /* -1 means nul-terminated */
1077                              hb_codepoint_t *glyph)
1078 {
1079   return font->get_glyph_from_name (name, len, glyph);
1080 }
1081
1082
1083 /* A bit higher-level, and with fallback */
1084
1085 /**
1086  * hb_font_get_extents_for_direction:
1087  * @font: a font.
1088  * @direction:
1089  * @extents: (out):
1090  *
1091  *
1092  *
1093  * Since: 1.1.3
1094  **/
1095 void
1096 hb_font_get_extents_for_direction (hb_font_t *font,
1097                                    hb_direction_t direction,
1098                                    hb_font_extents_t *extents)
1099 {
1100   return font->get_extents_for_direction (direction, extents);
1101 }
1102 /**
1103  * hb_font_get_glyph_advance_for_direction:
1104  * @font: a font.
1105  * @glyph:
1106  * @direction:
1107  * @x: (out):
1108  * @y: (out):
1109  *
1110  *
1111  *
1112  * Since: 0.9.2
1113  **/
1114 void
1115 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
1116                                          hb_codepoint_t glyph,
1117                                          hb_direction_t direction,
1118                                          hb_position_t *x, hb_position_t *y)
1119 {
1120   return font->get_glyph_advance_for_direction (glyph, direction, x, y);
1121 }
1122 /**
1123  * hb_font_get_glyph_advances_for_direction:
1124  * @font: a font.
1125  * @direction:
1126  *
1127  *
1128  *
1129  * Since: 1.8.6
1130  **/
1131 HB_EXTERN void
1132 hb_font_get_glyph_advances_for_direction (hb_font_t* font,
1133                                           hb_direction_t direction,
1134                                           unsigned int count,
1135                                           const hb_codepoint_t *first_glyph,
1136                                           unsigned glyph_stride,
1137                                           hb_position_t *first_advance,
1138                                           unsigned advance_stride)
1139 {
1140   font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride);
1141 }
1142
1143 /**
1144  * hb_font_get_glyph_origin_for_direction:
1145  * @font: a font.
1146  * @glyph:
1147  * @direction:
1148  * @x: (out):
1149  * @y: (out):
1150  *
1151  *
1152  *
1153  * Since: 0.9.2
1154  **/
1155 void
1156 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
1157                                         hb_codepoint_t glyph,
1158                                         hb_direction_t direction,
1159                                         hb_position_t *x, hb_position_t *y)
1160 {
1161   return font->get_glyph_origin_for_direction (glyph, direction, x, y);
1162 }
1163
1164 /**
1165  * hb_font_add_glyph_origin_for_direction:
1166  * @font: a font.
1167  * @glyph:
1168  * @direction:
1169  * @x: (out):
1170  * @y: (out):
1171  *
1172  *
1173  *
1174  * Since: 0.9.2
1175  **/
1176 void
1177 hb_font_add_glyph_origin_for_direction (hb_font_t *font,
1178                                         hb_codepoint_t glyph,
1179                                         hb_direction_t direction,
1180                                         hb_position_t *x, hb_position_t *y)
1181 {
1182   return font->add_glyph_origin_for_direction (glyph, direction, x, y);
1183 }
1184
1185 /**
1186  * hb_font_subtract_glyph_origin_for_direction:
1187  * @font: a font.
1188  * @glyph:
1189  * @direction:
1190  * @x: (out):
1191  * @y: (out):
1192  *
1193  *
1194  *
1195  * Since: 0.9.2
1196  **/
1197 void
1198 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
1199                                              hb_codepoint_t glyph,
1200                                              hb_direction_t direction,
1201                                              hb_position_t *x, hb_position_t *y)
1202 {
1203   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
1204 }
1205
1206 /**
1207  * hb_font_get_glyph_kerning_for_direction:
1208  * @font: a font.
1209  * @first_glyph:
1210  * @second_glyph:
1211  * @direction:
1212  * @x: (out):
1213  * @y: (out):
1214  *
1215  *
1216  *
1217  * Since: 0.9.2
1218  **/
1219 void
1220 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
1221                                          hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
1222                                          hb_direction_t direction,
1223                                          hb_position_t *x, hb_position_t *y)
1224 {
1225   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
1226 }
1227
1228 /**
1229  * hb_font_get_glyph_extents_for_origin:
1230  * @font: a font.
1231  * @glyph:
1232  * @direction:
1233  * @extents: (out):
1234  *
1235  *
1236  *
1237  * Return value:
1238  *
1239  * Since: 0.9.2
1240  **/
1241 hb_bool_t
1242 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
1243                                       hb_codepoint_t glyph,
1244                                       hb_direction_t direction,
1245                                       hb_glyph_extents_t *extents)
1246 {
1247   return font->get_glyph_extents_for_origin (glyph, direction, extents);
1248 }
1249
1250 /**
1251  * hb_font_get_glyph_contour_point_for_origin:
1252  * @font: a font.
1253  * @glyph:
1254  * @point_index:
1255  * @direction:
1256  * @x: (out):
1257  * @y: (out):
1258  *
1259  *
1260  *
1261  * Return value:
1262  *
1263  * Since: 0.9.2
1264  **/
1265 hb_bool_t
1266 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
1267                                             hb_codepoint_t glyph, unsigned int point_index,
1268                                             hb_direction_t direction,
1269                                             hb_position_t *x, hb_position_t *y)
1270 {
1271   return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
1272 }
1273
1274 /* Generates gidDDD if glyph has no name. */
1275 /**
1276  * hb_font_glyph_to_string:
1277  * @font: a font.
1278  * @glyph:
1279  * @s: (array length=size):
1280  * @size:
1281  *
1282  *
1283  *
1284  * Since: 0.9.2
1285  **/
1286 void
1287 hb_font_glyph_to_string (hb_font_t *font,
1288                          hb_codepoint_t glyph,
1289                          char *s, unsigned int size)
1290 {
1291   font->glyph_to_string (glyph, s, size);
1292 }
1293
1294 /* Parses gidDDD and uniUUUU strings automatically. */
1295 /**
1296  * hb_font_glyph_from_string:
1297  * @font: a font.
1298  * @s: (array length=len) (element-type uint8_t):
1299  * @len:
1300  * @glyph: (out):
1301  *
1302  *
1303  *
1304  * Return value:
1305  *
1306  * Since: 0.9.2
1307  **/
1308 hb_bool_t
1309 hb_font_glyph_from_string (hb_font_t *font,
1310                            const char *s, int len, /* -1 means nul-terminated */
1311                            hb_codepoint_t *glyph)
1312 {
1313   return font->glyph_from_string (s, len, glyph);
1314 }
1315
1316
1317 /*
1318  * hb_font_t
1319  */
1320
1321 DEFINE_NULL_INSTANCE (hb_font_t) =
1322 {
1323   HB_OBJECT_HEADER_STATIC,
1324
1325   nullptr, /* parent */
1326   const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
1327
1328   1000, /* x_scale */
1329   1000, /* y_scale */
1330   1<<16, /* x_mult */
1331   1<<16, /* y_mult */
1332
1333   0, /* x_ppem */
1334   0, /* y_ppem */
1335   0, /* ptem */
1336
1337   0, /* num_coords */
1338   nullptr, /* coords */
1339   nullptr, /* design_coords */
1340
1341   const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
1342
1343   /* Zero for the rest is fine. */
1344 };
1345
1346
1347 static hb_font_t *
1348 _hb_font_create (hb_face_t *face)
1349 {
1350   hb_font_t *font;
1351
1352   if (unlikely (!face))
1353     face = hb_face_get_empty ();
1354   if (!(font = hb_object_create<hb_font_t> ()))
1355     return hb_font_get_empty ();
1356
1357   hb_face_make_immutable (face);
1358   font->parent = hb_font_get_empty ();
1359   font->face = hb_face_reference (face);
1360   font->klass = hb_font_funcs_get_empty ();
1361   font->data.init0 (font);
1362   font->x_scale = font->y_scale = hb_face_get_upem (face);
1363   font->x_mult = font->y_mult = 1 << 16;
1364
1365   return font;
1366 }
1367
1368 /**
1369  * hb_font_create: (Xconstructor)
1370  * @face: a face.
1371  *
1372  *
1373  *
1374  * Return value: (transfer full):
1375  *
1376  * Since: 0.9.2
1377  **/
1378 hb_font_t *
1379 hb_font_create (hb_face_t *face)
1380 {
1381   hb_font_t *font = _hb_font_create (face);
1382
1383 #ifndef HB_NO_OT_FONT
1384   /* Install our in-house, very lightweight, funcs. */
1385   hb_ot_font_set_funcs (font);
1386 #endif
1387
1388   return font;
1389 }
1390
1391 static void
1392 _hb_font_adopt_var_coords (hb_font_t *font,
1393                            int *coords, /* 2.14 normalized */
1394                            float *design_coords,
1395                            unsigned int coords_length)
1396 {
1397   free (font->coords);
1398   free (font->design_coords);
1399
1400   font->coords = coords;
1401   font->design_coords = design_coords;
1402   font->num_coords = coords_length;
1403 }
1404
1405 /**
1406  * hb_font_create_sub_font:
1407  * @parent: parent font.
1408  *
1409  *
1410  *
1411  * Return value: (transfer full):
1412  *
1413  * Since: 0.9.2
1414  **/
1415 hb_font_t *
1416 hb_font_create_sub_font (hb_font_t *parent)
1417 {
1418   if (unlikely (!parent))
1419     parent = hb_font_get_empty ();
1420
1421   hb_font_t *font = _hb_font_create (parent->face);
1422
1423   if (unlikely (hb_object_is_immutable (font)))
1424     return font;
1425
1426   font->parent = hb_font_reference (parent);
1427
1428   font->x_scale = parent->x_scale;
1429   font->y_scale = parent->y_scale;
1430   font->mults_changed ();
1431   font->x_ppem = parent->x_ppem;
1432   font->y_ppem = parent->y_ppem;
1433   font->ptem = parent->ptem;
1434
1435   unsigned int num_coords = parent->num_coords;
1436   if (num_coords)
1437   {
1438     int *coords = (int *) calloc (num_coords, sizeof (parent->coords[0]));
1439     float *design_coords = (float *) calloc (num_coords, sizeof (parent->design_coords[0]));
1440     if (likely (coords && design_coords))
1441     {
1442       memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
1443       memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
1444       _hb_font_adopt_var_coords (font, coords, design_coords, num_coords);
1445     }
1446     else
1447     {
1448       free (coords);
1449       free (design_coords);
1450     }
1451   }
1452
1453   return font;
1454 }
1455
1456 /**
1457  * hb_font_get_empty:
1458  *
1459  *
1460  *
1461  * Return value: (transfer full)
1462  *
1463  * Since: 0.9.2
1464  **/
1465 hb_font_t *
1466 hb_font_get_empty ()
1467 {
1468   return const_cast<hb_font_t *> (&Null (hb_font_t));
1469 }
1470
1471 /**
1472  * hb_font_reference: (skip)
1473  * @font: a font.
1474  *
1475  *
1476  *
1477  * Return value: (transfer full):
1478  *
1479  * Since: 0.9.2
1480  **/
1481 hb_font_t *
1482 hb_font_reference (hb_font_t *font)
1483 {
1484   return hb_object_reference (font);
1485 }
1486
1487 /**
1488  * hb_font_destroy: (skip)
1489  * @font: a font.
1490  *
1491  *
1492  *
1493  * Since: 0.9.2
1494  **/
1495 void
1496 hb_font_destroy (hb_font_t *font)
1497 {
1498   if (!hb_object_destroy (font)) return;
1499
1500   font->data.fini ();
1501
1502   if (font->destroy)
1503     font->destroy (font->user_data);
1504
1505   hb_font_destroy (font->parent);
1506   hb_face_destroy (font->face);
1507   hb_font_funcs_destroy (font->klass);
1508
1509   free (font->coords);
1510   free (font->design_coords);
1511
1512   free (font);
1513 }
1514
1515 /**
1516  * hb_font_set_user_data: (skip)
1517  * @font: a font.
1518  * @key:
1519  * @data:
1520  * @destroy:
1521  * @replace:
1522  *
1523  *
1524  *
1525  * Return value:
1526  *
1527  * Since: 0.9.2
1528  **/
1529 hb_bool_t
1530 hb_font_set_user_data (hb_font_t          *font,
1531                        hb_user_data_key_t *key,
1532                        void *              data,
1533                        hb_destroy_func_t   destroy,
1534                        hb_bool_t           replace)
1535 {
1536   return hb_object_set_user_data (font, key, data, destroy, replace);
1537 }
1538
1539 /**
1540  * hb_font_get_user_data: (skip)
1541  * @font: a font.
1542  * @key:
1543  *
1544  *
1545  *
1546  * Return value: (transfer none):
1547  *
1548  * Since: 0.9.2
1549  **/
1550 void *
1551 hb_font_get_user_data (hb_font_t          *font,
1552                        hb_user_data_key_t *key)
1553 {
1554   return hb_object_get_user_data (font, key);
1555 }
1556
1557 /**
1558  * hb_font_make_immutable:
1559  * @font: a font.
1560  *
1561  *
1562  *
1563  * Since: 0.9.2
1564  **/
1565 void
1566 hb_font_make_immutable (hb_font_t *font)
1567 {
1568   if (hb_object_is_immutable (font))
1569     return;
1570
1571   if (font->parent)
1572     hb_font_make_immutable (font->parent);
1573
1574   hb_object_make_immutable (font);
1575 }
1576
1577 /**
1578  * hb_font_is_immutable:
1579  * @font: a font.
1580  *
1581  *
1582  *
1583  * Return value:
1584  *
1585  * Since: 0.9.2
1586  **/
1587 hb_bool_t
1588 hb_font_is_immutable (hb_font_t *font)
1589 {
1590   return hb_object_is_immutable (font);
1591 }
1592
1593 /**
1594  * hb_font_set_parent:
1595  * @font: a font.
1596  * @parent: new parent.
1597  *
1598  * Sets parent font of @font.
1599  *
1600  * Since: 1.0.5
1601  **/
1602 void
1603 hb_font_set_parent (hb_font_t *font,
1604                     hb_font_t *parent)
1605 {
1606   if (hb_object_is_immutable (font))
1607     return;
1608
1609   if (!parent)
1610     parent = hb_font_get_empty ();
1611
1612   hb_font_t *old = font->parent;
1613
1614   font->parent = hb_font_reference (parent);
1615
1616   hb_font_destroy (old);
1617 }
1618
1619 /**
1620  * hb_font_get_parent:
1621  * @font: a font.
1622  *
1623  *
1624  *
1625  * Return value: (transfer none):
1626  *
1627  * Since: 0.9.2
1628  **/
1629 hb_font_t *
1630 hb_font_get_parent (hb_font_t *font)
1631 {
1632   return font->parent;
1633 }
1634
1635 /**
1636  * hb_font_set_face:
1637  * @font: a font.
1638  * @face: new face.
1639  *
1640  * Sets font-face of @font.
1641  *
1642  * Since: 1.4.3
1643  **/
1644 void
1645 hb_font_set_face (hb_font_t *font,
1646                   hb_face_t *face)
1647 {
1648   if (hb_object_is_immutable (font))
1649     return;
1650
1651   if (unlikely (!face))
1652     face = hb_face_get_empty ();
1653
1654   hb_face_t *old = font->face;
1655
1656   hb_face_make_immutable (face);
1657   font->face = hb_face_reference (face);
1658   font->mults_changed ();
1659
1660   hb_face_destroy (old);
1661 }
1662
1663 /**
1664  * hb_font_get_face:
1665  * @font: a font.
1666  *
1667  *
1668  *
1669  * Return value: (transfer none):
1670  *
1671  * Since: 0.9.2
1672  **/
1673 hb_face_t *
1674 hb_font_get_face (hb_font_t *font)
1675 {
1676   return font->face;
1677 }
1678
1679
1680 /**
1681  * hb_font_set_funcs:
1682  * @font: a font.
1683  * @klass: (closure font_data) (destroy destroy) (scope notified):
1684  * @font_data:
1685  * @destroy:
1686  *
1687  *
1688  *
1689  * Since: 0.9.2
1690  **/
1691 void
1692 hb_font_set_funcs (hb_font_t         *font,
1693                    hb_font_funcs_t   *klass,
1694                    void              *font_data,
1695                    hb_destroy_func_t  destroy)
1696 {
1697   if (hb_object_is_immutable (font))
1698   {
1699     if (destroy)
1700       destroy (font_data);
1701     return;
1702   }
1703
1704   if (font->destroy)
1705     font->destroy (font->user_data);
1706
1707   if (!klass)
1708     klass = hb_font_funcs_get_empty ();
1709
1710   hb_font_funcs_reference (klass);
1711   hb_font_funcs_destroy (font->klass);
1712   font->klass = klass;
1713   font->user_data = font_data;
1714   font->destroy = destroy;
1715 }
1716
1717 /**
1718  * hb_font_set_funcs_data:
1719  * @font: a font.
1720  * @font_data: (destroy destroy) (scope notified):
1721  * @destroy:
1722  *
1723  *
1724  *
1725  * Since: 0.9.2
1726  **/
1727 void
1728 hb_font_set_funcs_data (hb_font_t         *font,
1729                         void              *font_data,
1730                         hb_destroy_func_t  destroy)
1731 {
1732   /* Destroy user_data? */
1733   if (hb_object_is_immutable (font))
1734   {
1735     if (destroy)
1736       destroy (font_data);
1737     return;
1738   }
1739
1740   if (font->destroy)
1741     font->destroy (font->user_data);
1742
1743   font->user_data = font_data;
1744   font->destroy = destroy;
1745 }
1746
1747
1748 /**
1749  * hb_font_set_scale:
1750  * @font: a font.
1751  * @x_scale:
1752  * @y_scale:
1753  *
1754  *
1755  *
1756  * Since: 0.9.2
1757  **/
1758 void
1759 hb_font_set_scale (hb_font_t *font,
1760                    int x_scale,
1761                    int y_scale)
1762 {
1763   if (hb_object_is_immutable (font))
1764     return;
1765
1766   font->x_scale = x_scale;
1767   font->y_scale = y_scale;
1768   font->mults_changed ();
1769 }
1770
1771 /**
1772  * hb_font_get_scale:
1773  * @font: a font.
1774  * @x_scale: (out):
1775  * @y_scale: (out):
1776  *
1777  *
1778  *
1779  * Since: 0.9.2
1780  **/
1781 void
1782 hb_font_get_scale (hb_font_t *font,
1783                    int *x_scale,
1784                    int *y_scale)
1785 {
1786   if (x_scale) *x_scale = font->x_scale;
1787   if (y_scale) *y_scale = font->y_scale;
1788 }
1789
1790 /**
1791  * hb_font_set_ppem:
1792  * @font: a font.
1793  * @x_ppem:
1794  * @y_ppem:
1795  *
1796  *
1797  *
1798  * Since: 0.9.2
1799  **/
1800 void
1801 hb_font_set_ppem (hb_font_t *font,
1802                   unsigned int x_ppem,
1803                   unsigned int y_ppem)
1804 {
1805   if (hb_object_is_immutable (font))
1806     return;
1807
1808   font->x_ppem = x_ppem;
1809   font->y_ppem = y_ppem;
1810 }
1811
1812 /**
1813  * hb_font_get_ppem:
1814  * @font: a font.
1815  * @x_ppem: (out):
1816  * @y_ppem: (out):
1817  *
1818  *
1819  *
1820  * Since: 0.9.2
1821  **/
1822 void
1823 hb_font_get_ppem (hb_font_t *font,
1824                   unsigned int *x_ppem,
1825                   unsigned int *y_ppem)
1826 {
1827   if (x_ppem) *x_ppem = font->x_ppem;
1828   if (y_ppem) *y_ppem = font->y_ppem;
1829 }
1830
1831 /**
1832  * hb_font_set_ptem:
1833  * @font: a font.
1834  * @ptem: font size in points.
1835  *
1836  * Sets "point size" of the font.  Set to 0 to unset.
1837  *
1838  * There are 72 points in an inch.
1839  *
1840  * Since: 1.6.0
1841  **/
1842 void
1843 hb_font_set_ptem (hb_font_t *font, float ptem)
1844 {
1845   if (hb_object_is_immutable (font))
1846     return;
1847
1848   font->ptem = ptem;
1849 }
1850
1851 /**
1852  * hb_font_get_ptem:
1853  * @font: a font.
1854  *
1855  * Gets the "point size" of the font.  A value of 0 means unset.
1856  *
1857  * Return value: Point size.
1858  *
1859  * Since: 0.9.2
1860  **/
1861 float
1862 hb_font_get_ptem (hb_font_t *font)
1863 {
1864   return font->ptem;
1865 }
1866
1867 #ifndef HB_NO_VAR
1868 /*
1869  * Variations
1870  */
1871
1872 /**
1873  * hb_font_set_variations:
1874  *
1875  * Since: 1.4.2
1876  */
1877 void
1878 hb_font_set_variations (hb_font_t *font,
1879                         const hb_variation_t *variations,
1880                         unsigned int variations_length)
1881 {
1882   if (hb_object_is_immutable (font))
1883     return;
1884
1885   if (!variations_length)
1886   {
1887     hb_font_set_var_coords_normalized (font, nullptr, 0);
1888     return;
1889   }
1890
1891   unsigned int coords_length = hb_ot_var_get_axis_count (font->face);
1892
1893   int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
1894   float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr;
1895
1896   if (unlikely (coords_length && !(normalized && design_coords)))
1897   {
1898     free (normalized);
1899     free (design_coords);
1900     return;
1901   }
1902
1903   const OT::fvar &fvar = *font->face->table.fvar;
1904   for (unsigned int i = 0; i < variations_length; i++)
1905   {
1906     hb_ot_var_axis_info_t info;
1907     if (hb_ot_var_find_axis_info (font->face, variations[i].tag, &info) &&
1908         info.axis_index < coords_length)
1909     {
1910       float v = variations[i].value;
1911       design_coords[info.axis_index] = v;
1912       normalized[info.axis_index] = fvar.normalize_axis_value (info.axis_index, v);
1913     }
1914   }
1915   font->face->table.avar->map_coords (normalized, coords_length);
1916
1917   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
1918 }
1919
1920 /**
1921  * hb_font_set_var_coords_design:
1922  *
1923  * Since: 1.4.2
1924  */
1925 void
1926 hb_font_set_var_coords_design (hb_font_t *font,
1927                                const float *coords,
1928                                unsigned int coords_length)
1929 {
1930   if (hb_object_is_immutable (font))
1931     return;
1932
1933   int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
1934   float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr;
1935
1936   if (unlikely (coords_length && !(normalized && design_coords)))
1937   {
1938     free (normalized);
1939     free (design_coords);
1940     return;
1941   }
1942
1943   if (coords_length)
1944     memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
1945
1946   hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
1947   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
1948 }
1949
1950 /**
1951  * hb_font_set_var_named_instance:
1952  * @font: a font.
1953  * @instance_index: named instance index.
1954  *
1955  * Sets design coords of a font from a named instance index.
1956  *
1957  * Since: 2.6.0
1958  */
1959 void
1960 hb_font_set_var_named_instance (hb_font_t *font,
1961                                 unsigned instance_index)
1962 {
1963   if (hb_object_is_immutable (font))
1964     return;
1965
1966   unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr);
1967
1968   float *coords = coords_length ? (float *) calloc (coords_length, sizeof (float)) : nullptr;
1969   if (unlikely (coords_length && !coords))
1970     return;
1971
1972   hb_ot_var_named_instance_get_design_coords (font->face, instance_index, &coords_length, coords);
1973   hb_font_set_var_coords_design (font, coords, coords_length);
1974   free (coords);
1975 }
1976
1977 /**
1978  * hb_font_set_var_coords_normalized:
1979  *
1980  * Since: 1.4.2
1981  */
1982 void
1983 hb_font_set_var_coords_normalized (hb_font_t *font,
1984                                    const int *coords, /* 2.14 normalized */
1985                                    unsigned int coords_length)
1986 {
1987   if (hb_object_is_immutable (font))
1988     return;
1989
1990   int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr;
1991   int *unmapped = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr;
1992   float *design_coords = coords_length ? (float *) calloc (coords_length, sizeof (design_coords[0])) : nullptr;
1993
1994   if (unlikely (coords_length && !(copy && unmapped && design_coords)))
1995   {
1996     free (copy);
1997     free (unmapped);
1998     free (design_coords);
1999     return;
2000   }
2001
2002   if (coords_length)
2003   {
2004     memcpy (copy, coords, coords_length * sizeof (coords[0]));
2005     memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
2006   }
2007
2008   /* Best effort design coords simulation */
2009   font->face->table.avar->unmap_coords (unmapped, coords_length);
2010   for (unsigned int i = 0; i < coords_length; ++i)
2011     design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]);
2012   free (unmapped);
2013
2014   _hb_font_adopt_var_coords (font, copy, design_coords, coords_length);
2015 }
2016
2017 /**
2018  * hb_font_get_var_coords_normalized:
2019  *
2020  * Return value is valid as long as variation coordinates of the font
2021  * are not modified.
2022  *
2023  * Since: 1.4.2
2024  */
2025 const int *
2026 hb_font_get_var_coords_normalized (hb_font_t *font,
2027                                    unsigned int *length)
2028 {
2029   if (length)
2030     *length = font->num_coords;
2031
2032   return font->coords;
2033 }
2034
2035 #ifdef HB_EXPERIMENTAL_API
2036 /**
2037  * hb_font_get_var_coords_design:
2038  *
2039  * Return value is valid as long as variation coordinates of the font
2040  * are not modified.
2041  *
2042  * Since: EXPERIMENTAL
2043  */
2044 const float *
2045 hb_font_get_var_coords_design (hb_font_t *font,
2046                                unsigned int *length)
2047 {
2048   if (length)
2049     *length = font->num_coords;
2050
2051   return font->design_coords;
2052 }
2053 #endif
2054 #endif
2055
2056 #ifndef HB_DISABLE_DEPRECATED
2057 /*
2058  * Deprecated get_glyph_func():
2059  */
2060
2061 struct hb_trampoline_closure_t
2062 {
2063   void *user_data;
2064   hb_destroy_func_t destroy;
2065   unsigned int ref_count;
2066 };
2067
2068 template <typename FuncType>
2069 struct hb_trampoline_t
2070 {
2071   hb_trampoline_closure_t closure; /* Must be first. */
2072   FuncType func;
2073 };
2074
2075 template <typename FuncType>
2076 static hb_trampoline_t<FuncType> *
2077 trampoline_create (FuncType           func,
2078                    void              *user_data,
2079                    hb_destroy_func_t  destroy)
2080 {
2081   typedef hb_trampoline_t<FuncType> trampoline_t;
2082
2083   trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
2084
2085   if (unlikely (!trampoline))
2086     return nullptr;
2087
2088   trampoline->closure.user_data = user_data;
2089   trampoline->closure.destroy = destroy;
2090   trampoline->closure.ref_count = 1;
2091   trampoline->func = func;
2092
2093   return trampoline;
2094 }
2095
2096 static void
2097 trampoline_reference (hb_trampoline_closure_t *closure)
2098 {
2099   closure->ref_count++;
2100 }
2101
2102 static void
2103 trampoline_destroy (void *user_data)
2104 {
2105   hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
2106
2107   if (--closure->ref_count)
2108     return;
2109
2110   if (closure->destroy)
2111     closure->destroy (closure->user_data);
2112   free (closure);
2113 }
2114
2115 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
2116
2117 static hb_bool_t
2118 hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
2119                                       void *font_data,
2120                                       hb_codepoint_t unicode,
2121                                       hb_codepoint_t *glyph,
2122                                       void *user_data)
2123 {
2124   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
2125   return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
2126 }
2127
2128 static hb_bool_t
2129 hb_font_get_variation_glyph_trampoline (hb_font_t *font,
2130                                         void *font_data,
2131                                         hb_codepoint_t unicode,
2132                                         hb_codepoint_t variation_selector,
2133                                         hb_codepoint_t *glyph,
2134                                         void *user_data)
2135 {
2136   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
2137   return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
2138 }
2139
2140 /**
2141  * hb_font_funcs_set_glyph_func:
2142  * @ffuncs: font functions.
2143  * @func: (closure user_data) (destroy destroy) (scope notified): callback function.
2144  * @user_data: data to pass to @func.
2145  * @destroy: function to call when @user_data is not needed anymore.
2146  *
2147  * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
2148  * hb_font_funcs_set_variation_glyph_func() instead.
2149  *
2150  * Since: 0.9.2
2151  * Deprecated: 1.2.3
2152  **/
2153 void
2154 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
2155                               hb_font_get_glyph_func_t func,
2156                               void *user_data, hb_destroy_func_t destroy)
2157 {
2158   if (hb_object_is_immutable (ffuncs))
2159   {
2160     if (destroy)
2161       destroy (user_data);
2162     return;
2163   }
2164
2165   hb_font_get_glyph_trampoline_t *trampoline;
2166
2167   trampoline = trampoline_create (func, user_data, destroy);
2168   if (unlikely (!trampoline))
2169   {
2170     if (destroy)
2171       destroy (user_data);
2172     return;
2173   }
2174
2175   hb_font_funcs_set_nominal_glyph_func (ffuncs,
2176                                         hb_font_get_nominal_glyph_trampoline,
2177                                         trampoline,
2178                                         trampoline_destroy);
2179
2180   trampoline_reference (&trampoline->closure);
2181   hb_font_funcs_set_variation_glyph_func (ffuncs,
2182                                           hb_font_get_variation_glyph_trampoline,
2183                                           trampoline,
2184                                           trampoline_destroy);
2185 }
2186 #endif