Revert "Imported Upstream version 1.2.7"
[platform/upstream/harfbuzz.git] / src / hb-font.cc
1 /*
2  * Copyright © 2009  Red Hat, Inc.
3  * Copyright © 2012  Google, Inc.
4  *
5  *  This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Red Hat Author(s): Behdad Esfahbod
26  * Google Author(s): Behdad Esfahbod
27  */
28
29 #include "hb-private.hh"
30
31 #include "hb-ot-layout-private.hh"
32
33 #include "hb-font-private.hh"
34 #include "hb-open-file-private.hh"
35 #include "hb-ot-head-table.hh"
36 #include "hb-ot-maxp-table.hh"
37
38 #include "hb-cache-private.hh"
39
40 #include <string.h>
41
42
43 /*
44  * hb_font_funcs_t
45  */
46
47 static hb_bool_t
48 hb_font_get_glyph_nil (hb_font_t *font,
49                        void *font_data HB_UNUSED,
50                        hb_codepoint_t unicode,
51                        hb_codepoint_t variation_selector,
52                        hb_codepoint_t *glyph,
53                        void *user_data HB_UNUSED)
54 {
55   if (font->parent)
56     return font->parent->get_glyph (unicode, variation_selector, glyph);
57
58   *glyph = 0;
59   return false;
60 }
61
62 static hb_position_t
63 hb_font_get_glyph_h_advance_nil (hb_font_t *font,
64                                  void *font_data HB_UNUSED,
65                                  hb_codepoint_t glyph,
66                                  void *user_data HB_UNUSED)
67 {
68   if (font->parent)
69     return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
70
71   return font->x_scale;
72 }
73
74 static hb_position_t
75 hb_font_get_glyph_v_advance_nil (hb_font_t *font,
76                                  void *font_data HB_UNUSED,
77                                  hb_codepoint_t glyph,
78                                  void *user_data HB_UNUSED)
79 {
80   if (font->parent)
81     return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
82
83   return font->y_scale;
84 }
85
86 static hb_bool_t
87 hb_font_get_glyph_h_origin_nil (hb_font_t *font,
88                                 void *font_data HB_UNUSED,
89                                 hb_codepoint_t glyph,
90                                 hb_position_t *x,
91                                 hb_position_t *y,
92                                 void *user_data HB_UNUSED)
93 {
94   if (font->parent) {
95     hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
96     if (ret)
97       font->parent_scale_position (x, y);
98     return ret;
99   }
100
101   *x = *y = 0;
102   return false;
103 }
104
105 static hb_bool_t
106 hb_font_get_glyph_v_origin_nil (hb_font_t *font,
107                                 void *font_data HB_UNUSED,
108                                 hb_codepoint_t glyph,
109                                 hb_position_t *x,
110                                 hb_position_t *y,
111                                 void *user_data HB_UNUSED)
112 {
113   if (font->parent) {
114     hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
115     if (ret)
116       font->parent_scale_position (x, y);
117     return ret;
118   }
119
120   *x = *y = 0;
121   return false;
122 }
123
124 static hb_position_t
125 hb_font_get_glyph_h_kerning_nil (hb_font_t *font,
126                                  void *font_data HB_UNUSED,
127                                  hb_codepoint_t left_glyph,
128                                  hb_codepoint_t right_glyph,
129                                  void *user_data HB_UNUSED)
130 {
131   if (font->parent)
132     return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
133
134   return 0;
135 }
136
137 static hb_position_t
138 hb_font_get_glyph_v_kerning_nil (hb_font_t *font,
139                                  void *font_data HB_UNUSED,
140                                  hb_codepoint_t top_glyph,
141                                  hb_codepoint_t bottom_glyph,
142                                  void *user_data HB_UNUSED)
143 {
144   if (font->parent)
145     return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
146
147   return 0;
148 }
149
150 static hb_bool_t
151 hb_font_get_glyph_extents_nil (hb_font_t *font,
152                                void *font_data HB_UNUSED,
153                                hb_codepoint_t glyph,
154                                hb_glyph_extents_t *extents,
155                                void *user_data HB_UNUSED)
156 {
157   if (font->parent) {
158     hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
159     if (ret) {
160       font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
161       font->parent_scale_distance (&extents->width, &extents->height);
162     }
163     return ret;
164   }
165
166   memset (extents, 0, sizeof (*extents));
167   return false;
168 }
169
170 static hb_bool_t
171 hb_font_get_glyph_contour_point_nil (hb_font_t *font,
172                                      void *font_data HB_UNUSED,
173                                      hb_codepoint_t glyph,
174                                      unsigned int point_index,
175                                      hb_position_t *x,
176                                      hb_position_t *y,
177                                      void *user_data HB_UNUSED)
178 {
179   if (font->parent) {
180     hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
181     if (ret)
182       font->parent_scale_position (x, y);
183     return ret;
184   }
185
186   *x = *y = 0;
187   return false;
188 }
189
190 static hb_bool_t
191 hb_font_get_glyph_name_nil (hb_font_t *font,
192                             void *font_data HB_UNUSED,
193                             hb_codepoint_t glyph,
194                             char *name, unsigned int size,
195                             void *user_data HB_UNUSED)
196 {
197   if (font->parent)
198     return font->parent->get_glyph_name (glyph, name, size);
199
200   if (size) *name = '\0';
201   return false;
202 }
203
204 static hb_bool_t
205 hb_font_get_glyph_from_name_nil (hb_font_t *font,
206                                  void *font_data HB_UNUSED,
207                                  const char *name, int len, /* -1 means nul-terminated */
208                                  hb_codepoint_t *glyph,
209                                  void *user_data HB_UNUSED)
210 {
211   if (font->parent)
212     return font->parent->get_glyph_from_name (name, len, glyph);
213
214   *glyph = 0;
215   return false;
216 }
217
218
219 static const hb_font_funcs_t _hb_font_funcs_nil = {
220   HB_OBJECT_HEADER_STATIC,
221
222   true, /* immutable */
223
224   {
225 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
226     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
227 #undef HB_FONT_FUNC_IMPLEMENT
228   }
229 };
230
231
232 /**
233  * hb_font_funcs_create: (Xconstructor)
234  *
235  * 
236  *
237  * Return value: (transfer full): 
238  *
239  * Since: 1.0
240  **/
241 hb_font_funcs_t *
242 hb_font_funcs_create (void)
243 {
244   hb_font_funcs_t *ffuncs;
245
246   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
247     return hb_font_funcs_get_empty ();
248
249   ffuncs->get = _hb_font_funcs_nil.get;
250
251   return ffuncs;
252 }
253
254 /**
255  * hb_font_funcs_get_empty:
256  *
257  * 
258  *
259  * Return value: (transfer full): 
260  *
261  * Since: 1.0
262  **/
263 hb_font_funcs_t *
264 hb_font_funcs_get_empty (void)
265 {
266   return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
267 }
268
269 /**
270  * hb_font_funcs_reference: (skip)
271  * @ffuncs: font functions.
272  *
273  * 
274  *
275  * Return value: 
276  *
277  * Since: 1.0
278  **/
279 hb_font_funcs_t *
280 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
281 {
282   return hb_object_reference (ffuncs);
283 }
284
285 /**
286  * hb_font_funcs_destroy: (skip)
287  * @ffuncs: font functions.
288  *
289  * 
290  *
291  * Since: 1.0
292  **/
293 void
294 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
295 {
296   if (!hb_object_destroy (ffuncs)) return;
297
298 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
299   ffuncs->destroy.name (ffuncs->user_data.name);
300   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
301 #undef HB_FONT_FUNC_IMPLEMENT
302
303   free (ffuncs);
304 }
305
306 /**
307  * hb_font_funcs_set_user_data: (skip)
308  * @ffuncs: font functions.
309  * @key: 
310  * @data: 
311  * @destroy: 
312  * @replace: 
313  *
314  * 
315  *
316  * Return value: 
317  *
318  * Since: 1.0
319  **/
320 hb_bool_t
321 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
322                              hb_user_data_key_t *key,
323                              void *              data,
324                              hb_destroy_func_t   destroy,
325                              hb_bool_t           replace)
326 {
327   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
328 }
329
330 /**
331  * hb_font_funcs_get_user_data: (skip)
332  * @ffuncs: font functions.
333  * @key: 
334  *
335  * 
336  *
337  * Return value: (transfer none): 
338  *
339  * Since: 1.0
340  **/
341 void *
342 hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
343                              hb_user_data_key_t *key)
344 {
345   return hb_object_get_user_data (ffuncs, key);
346 }
347
348
349 /**
350  * hb_font_funcs_make_immutable:
351  * @ffuncs: font functions.
352  *
353  * 
354  *
355  * Since: 1.0
356  **/
357 void
358 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
359 {
360   if (unlikely (hb_object_is_inert (ffuncs)))
361     return;
362
363   ffuncs->immutable = true;
364 }
365
366 /**
367  * hb_font_funcs_is_immutable:
368  * @ffuncs: font functions.
369  *
370  * 
371  *
372  * Return value: 
373  *
374  * Since: 1.0
375  **/
376 hb_bool_t
377 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
378 {
379   return ffuncs->immutable;
380 }
381
382
383 #define HB_FONT_FUNC_IMPLEMENT(name) \
384                                                                          \
385 void                                                                     \
386 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
387                                  hb_font_get_##name##_func_t  func,      \
388                                  void                        *user_data, \
389                                  hb_destroy_func_t            destroy)   \
390 {                                                                        \
391   if (ffuncs->immutable) {                                               \
392     if (destroy)                                                         \
393       destroy (user_data);                                               \
394     return;                                                              \
395   }                                                                      \
396                                                                          \
397   if (ffuncs->destroy.name)                                              \
398     ffuncs->destroy.name (ffuncs->user_data.name);                       \
399                                                                          \
400   if (func) {                                                            \
401     ffuncs->get.name = func;                                             \
402     ffuncs->user_data.name = user_data;                                  \
403     ffuncs->destroy.name = destroy;                                      \
404   } else {                                                               \
405     ffuncs->get.name = hb_font_get_##name##_nil;                         \
406     ffuncs->user_data.name = NULL;                                       \
407     ffuncs->destroy.name = NULL;                                         \
408   }                                                                      \
409 }
410
411 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
412 #undef HB_FONT_FUNC_IMPLEMENT
413
414
415 /* Public getters */
416
417 /**
418  * hb_font_get_glyph:
419  * @font: a font.
420  * @unicode: 
421  * @variation_selector: 
422  * @glyph: (out): 
423  *
424  * 
425  *
426  * Return value: 
427  *
428  * Since: 1.0
429  **/
430 hb_bool_t
431 hb_font_get_glyph (hb_font_t *font,
432                    hb_codepoint_t unicode, hb_codepoint_t variation_selector,
433                    hb_codepoint_t *glyph)
434 {
435   return font->get_glyph (unicode, variation_selector, glyph);
436 }
437
438 /**
439  * hb_font_get_glyph_h_advance:
440  * @font: a font.
441  * @glyph: 
442  *
443  * 
444  *
445  * Return value: 
446  *
447  * Since: 1.0
448  **/
449 hb_position_t
450 hb_font_get_glyph_h_advance (hb_font_t *font,
451                              hb_codepoint_t glyph)
452 {
453   return font->get_glyph_h_advance (glyph);
454 }
455
456 /**
457  * hb_font_get_glyph_v_advance:
458  * @font: a font.
459  * @glyph: 
460  *
461  * 
462  *
463  * Return value: 
464  *
465  * Since: 1.0
466  **/
467 hb_position_t
468 hb_font_get_glyph_v_advance (hb_font_t *font,
469                              hb_codepoint_t glyph)
470 {
471   return font->get_glyph_v_advance (glyph);
472 }
473
474 /**
475  * hb_font_get_glyph_h_origin:
476  * @font: a font.
477  * @glyph: 
478  * @x: (out): 
479  * @y: (out): 
480  *
481  * 
482  *
483  * Return value: 
484  *
485  * Since: 1.0
486  **/
487 hb_bool_t
488 hb_font_get_glyph_h_origin (hb_font_t *font,
489                             hb_codepoint_t glyph,
490                             hb_position_t *x, hb_position_t *y)
491 {
492   return font->get_glyph_h_origin (glyph, x, y);
493 }
494
495 /**
496  * hb_font_get_glyph_v_origin:
497  * @font: a font.
498  * @glyph: 
499  * @x: (out): 
500  * @y: (out): 
501  *
502  * 
503  *
504  * Return value: 
505  *
506  * Since: 1.0
507  **/
508 hb_bool_t
509 hb_font_get_glyph_v_origin (hb_font_t *font,
510                             hb_codepoint_t glyph,
511                             hb_position_t *x, hb_position_t *y)
512 {
513   return font->get_glyph_v_origin (glyph, x, y);
514 }
515
516 /**
517  * hb_font_get_glyph_h_kerning:
518  * @font: a font.
519  * @left_glyph: 
520  * @right_glyph: 
521  *
522  * 
523  *
524  * Return value: 
525  *
526  * Since: 1.0
527  **/
528 hb_position_t
529 hb_font_get_glyph_h_kerning (hb_font_t *font,
530                              hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
531 {
532   return font->get_glyph_h_kerning (left_glyph, right_glyph);
533 }
534
535 /**
536  * hb_font_get_glyph_v_kerning:
537  * @font: a font.
538  * @top_glyph: 
539  * @bottom_glyph: 
540  *
541  * 
542  *
543  * Return value: 
544  *
545  * Since: 1.0
546  **/
547 hb_position_t
548 hb_font_get_glyph_v_kerning (hb_font_t *font,
549                              hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
550 {
551   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
552 }
553
554 /**
555  * hb_font_get_glyph_extents:
556  * @font: a font.
557  * @glyph: 
558  * @extents: (out): 
559  *
560  * 
561  *
562  * Return value: 
563  *
564  * Since: 1.0
565  **/
566 hb_bool_t
567 hb_font_get_glyph_extents (hb_font_t *font,
568                            hb_codepoint_t glyph,
569                            hb_glyph_extents_t *extents)
570 {
571   return font->get_glyph_extents (glyph, extents);
572 }
573
574 /**
575  * hb_font_get_glyph_contour_point:
576  * @font: a font.
577  * @glyph: 
578  * @point_index: 
579  * @x: (out): 
580  * @y: (out): 
581  *
582  * 
583  *
584  * Return value: 
585  *
586  * Since: 1.0
587  **/
588 hb_bool_t
589 hb_font_get_glyph_contour_point (hb_font_t *font,
590                                  hb_codepoint_t glyph, unsigned int point_index,
591                                  hb_position_t *x, hb_position_t *y)
592 {
593   return font->get_glyph_contour_point (glyph, point_index, x, y);
594 }
595
596 /**
597  * hb_font_get_glyph_name:
598  * @font: a font.
599  * @glyph: 
600  * @name: (array length=size): 
601  * @size: 
602  *
603  * 
604  *
605  * Return value: 
606  *
607  * Since: 1.0
608  **/
609 hb_bool_t
610 hb_font_get_glyph_name (hb_font_t *font,
611                         hb_codepoint_t glyph,
612                         char *name, unsigned int size)
613 {
614   return font->get_glyph_name (glyph, name, size);
615 }
616
617 /**
618  * hb_font_get_glyph_from_name:
619  * @font: a font.
620  * @name: (array length=len): 
621  * @len: 
622  * @glyph: (out): 
623  *
624  * 
625  *
626  * Return value: 
627  *
628  * Since: 1.0
629  **/
630 hb_bool_t
631 hb_font_get_glyph_from_name (hb_font_t *font,
632                              const char *name, int len, /* -1 means nul-terminated */
633                              hb_codepoint_t *glyph)
634 {
635   return font->get_glyph_from_name (name, len, glyph);
636 }
637
638
639 /* A bit higher-level, and with fallback */
640
641 /**
642  * hb_font_get_glyph_advance_for_direction:
643  * @font: a font.
644  * @glyph: 
645  * @direction: 
646  * @x: (out): 
647  * @y: (out): 
648  *
649  * 
650  *
651  * Since: 1.0
652  **/
653 void
654 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
655                                          hb_codepoint_t glyph,
656                                          hb_direction_t direction,
657                                          hb_position_t *x, hb_position_t *y)
658 {
659   return font->get_glyph_advance_for_direction (glyph, direction, x, y);
660 }
661
662 /**
663  * hb_font_get_glyph_origin_for_direction:
664  * @font: a font.
665  * @glyph: 
666  * @direction: 
667  * @x: (out): 
668  * @y: (out): 
669  *
670  * 
671  *
672  * Since: 1.0
673  **/
674 void
675 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
676                                         hb_codepoint_t glyph,
677                                         hb_direction_t direction,
678                                         hb_position_t *x, hb_position_t *y)
679 {
680   return font->get_glyph_origin_for_direction (glyph, direction, x, y);
681 }
682
683 /**
684  * hb_font_add_glyph_origin_for_direction:
685  * @font: a font.
686  * @glyph: 
687  * @direction: 
688  * @x: (out): 
689  * @y: (out): 
690  *
691  * 
692  *
693  * Since: 1.0
694  **/
695 void
696 hb_font_add_glyph_origin_for_direction (hb_font_t *font,
697                                         hb_codepoint_t glyph,
698                                         hb_direction_t direction,
699                                         hb_position_t *x, hb_position_t *y)
700 {
701   return font->add_glyph_origin_for_direction (glyph, direction, x, y);
702 }
703
704 /**
705  * hb_font_subtract_glyph_origin_for_direction:
706  * @font: a font.
707  * @glyph: 
708  * @direction: 
709  * @x: (out): 
710  * @y: (out): 
711  *
712  * 
713  *
714  * Since: 1.0
715  **/
716 void
717 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
718                                              hb_codepoint_t glyph,
719                                              hb_direction_t direction,
720                                              hb_position_t *x, hb_position_t *y)
721 {
722   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
723 }
724
725 /**
726  * hb_font_get_glyph_kerning_for_direction:
727  * @font: a font.
728  * @first_glyph: 
729  * @second_glyph: 
730  * @direction: 
731  * @x: (out): 
732  * @y: (out): 
733  *
734  * 
735  *
736  * Since: 1.0
737  **/
738 void
739 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
740                                          hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
741                                          hb_direction_t direction,
742                                          hb_position_t *x, hb_position_t *y)
743 {
744   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
745 }
746
747 /**
748  * hb_font_get_glyph_extents_for_origin:
749  * @font: a font.
750  * @glyph: 
751  * @direction: 
752  * @extents: (out): 
753  *
754  * 
755  *
756  * Return value: 
757  *
758  * Since: 1.0
759  **/
760 hb_bool_t
761 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
762                                       hb_codepoint_t glyph,
763                                       hb_direction_t direction,
764                                       hb_glyph_extents_t *extents)
765 {
766   return font->get_glyph_extents_for_origin (glyph, direction, extents);
767 }
768
769 /**
770  * hb_font_get_glyph_contour_point_for_origin:
771  * @font: a font.
772  * @glyph: 
773  * @point_index: 
774  * @direction: 
775  * @x: (out): 
776  * @y: (out): 
777  *
778  * 
779  *
780  * Return value: 
781  *
782  * Since: 1.0
783  **/
784 hb_bool_t
785 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
786                                             hb_codepoint_t glyph, unsigned int point_index,
787                                             hb_direction_t direction,
788                                             hb_position_t *x, hb_position_t *y)
789 {
790   return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
791 }
792
793 /* Generates gidDDD if glyph has no name. */
794 /**
795  * hb_font_glyph_to_string:
796  * @font: a font.
797  * @glyph: 
798  * @s: (array length=size): 
799  * @size: 
800  *
801  * 
802  *
803  * Since: 1.0
804  **/
805 void
806 hb_font_glyph_to_string (hb_font_t *font,
807                          hb_codepoint_t glyph,
808                          char *s, unsigned int size)
809 {
810   font->glyph_to_string (glyph, s, size);
811 }
812
813 /* Parses gidDDD and uniUUUU strings automatically. */
814 /**
815  * hb_font_glyph_from_string:
816  * @font: a font.
817  * @s: (array length=len): 
818  * @len: 
819  * @glyph: (out): 
820  *
821  * 
822  *
823  * Return value: 
824  *
825  * Since: 1.0
826  **/
827 hb_bool_t
828 hb_font_glyph_from_string (hb_font_t *font,
829                            const char *s, int len, /* -1 means nul-terminated */
830                            hb_codepoint_t *glyph)
831 {
832   return font->glyph_from_string (s, len, glyph);
833 }
834
835
836 /*
837  * hb_font_t
838  */
839
840 /**
841  * hb_font_create: (Xconstructor)
842  * @face: a face.
843  *
844  * 
845  *
846  * Return value: (transfer full): 
847  *
848  * Since: 1.0
849  **/
850 hb_font_t *
851 hb_font_create (hb_face_t *face)
852 {
853   hb_font_t *font;
854
855   if (unlikely (!face))
856     face = hb_face_get_empty ();
857   if (unlikely (hb_object_is_inert (face)))
858     return hb_font_get_empty ();
859   if (!(font = hb_object_create<hb_font_t> ()))
860     return hb_font_get_empty ();
861
862   hb_face_make_immutable (face);
863   font->face = hb_face_reference (face);
864   font->klass = hb_font_funcs_get_empty ();
865
866   return font;
867 }
868
869 /**
870  * hb_font_create_sub_font:
871  * @parent: parent font.
872  *
873  * 
874  *
875  * Return value: (transfer full): 
876  *
877  * Since: 1.0
878  **/
879 hb_font_t *
880 hb_font_create_sub_font (hb_font_t *parent)
881 {
882   if (unlikely (!parent))
883     return hb_font_get_empty ();
884
885   hb_font_t *font = hb_font_create (parent->face);
886
887   if (unlikely (hb_object_is_inert (font)))
888     return font;
889
890   hb_font_make_immutable (parent);
891   font->parent = hb_font_reference (parent);
892
893   font->x_scale = parent->x_scale;
894   font->y_scale = parent->y_scale;
895   font->x_ppem = parent->x_ppem;
896   font->y_ppem = parent->y_ppem;
897
898   return font;
899 }
900
901 /**
902  * hb_font_get_empty:
903  *
904  * 
905  *
906  * Return value: (transfer full)
907  *
908  * Since: 1.0
909  **/
910 hb_font_t *
911 hb_font_get_empty (void)
912 {
913   static const hb_font_t _hb_font_nil = {
914     HB_OBJECT_HEADER_STATIC,
915
916     true, /* immutable */
917
918     NULL, /* parent */
919     const_cast<hb_face_t *> (&_hb_face_nil),
920
921     0, /* x_scale */
922     0, /* y_scale */
923
924     0, /* x_ppem */
925     0, /* y_ppem */
926
927     const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
928     NULL, /* user_data */
929     NULL, /* destroy */
930
931     {
932 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
933 #include "hb-shaper-list.hh"
934 #undef HB_SHAPER_IMPLEMENT
935     }
936   };
937
938   return const_cast<hb_font_t *> (&_hb_font_nil);
939 }
940
941 /**
942  * hb_font_reference: (skip)
943  * @font: a font.
944  *
945  * 
946  *
947  * Return value: (transfer full): 
948  *
949  * Since: 1.0
950  **/
951 hb_font_t *
952 hb_font_reference (hb_font_t *font)
953 {
954   return hb_object_reference (font);
955 }
956
957 /**
958  * hb_font_destroy: (skip)
959  * @font: a font.
960  *
961  * 
962  *
963  * Since: 1.0
964  **/
965 void
966 hb_font_destroy (hb_font_t *font)
967 {
968   if (!hb_object_destroy (font)) return;
969
970 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
971 #include "hb-shaper-list.hh"
972 #undef HB_SHAPER_IMPLEMENT
973
974   if (font->destroy)
975     font->destroy (font->user_data);
976
977   hb_font_destroy (font->parent);
978   hb_face_destroy (font->face);
979   hb_font_funcs_destroy (font->klass);
980
981   free (font);
982 }
983
984 /**
985  * hb_font_set_user_data: (skip)
986  * @font: a font.
987  * @key: 
988  * @data: 
989  * @destroy: 
990  * @replace: 
991  *
992  * 
993  *
994  * Return value: 
995  *
996  * Since: 1.0
997  **/
998 hb_bool_t
999 hb_font_set_user_data (hb_font_t          *font,
1000                        hb_user_data_key_t *key,
1001                        void *              data,
1002                        hb_destroy_func_t   destroy,
1003                        hb_bool_t           replace)
1004 {
1005   return hb_object_set_user_data (font, key, data, destroy, replace);
1006 }
1007
1008 /**
1009  * hb_font_get_user_data: (skip)
1010  * @font: a font.
1011  * @key: 
1012  *
1013  * 
1014  *
1015  * Return value: (transfer none): 
1016  *
1017  * Since: 1.0
1018  **/
1019 void *
1020 hb_font_get_user_data (hb_font_t          *font,
1021                        hb_user_data_key_t *key)
1022 {
1023   return hb_object_get_user_data (font, key);
1024 }
1025
1026 /**
1027  * hb_font_make_immutable:
1028  * @font: a font.
1029  *
1030  * 
1031  *
1032  * Since: 1.0
1033  **/
1034 void
1035 hb_font_make_immutable (hb_font_t *font)
1036 {
1037   if (unlikely (hb_object_is_inert (font)))
1038     return;
1039
1040   font->immutable = true;
1041 }
1042
1043 /**
1044  * hb_font_is_immutable:
1045  * @font: a font.
1046  *
1047  * 
1048  *
1049  * Return value: 
1050  *
1051  * Since: 1.0
1052  **/
1053 hb_bool_t
1054 hb_font_is_immutable (hb_font_t *font)
1055 {
1056   return font->immutable;
1057 }
1058
1059 /**
1060  * hb_font_get_parent:
1061  * @font: a font.
1062  *
1063  * 
1064  *
1065  * Return value: (transfer none): 
1066  *
1067  * Since: 1.0
1068  **/
1069 hb_font_t *
1070 hb_font_get_parent (hb_font_t *font)
1071 {
1072   return font->parent;
1073 }
1074
1075 /**
1076  * hb_font_get_face:
1077  * @font: a font.
1078  *
1079  * 
1080  *
1081  * Return value: (transfer none): 
1082  *
1083  * Since: 1.0
1084  **/
1085 hb_face_t *
1086 hb_font_get_face (hb_font_t *font)
1087 {
1088   return font->face;
1089 }
1090
1091
1092 /**
1093  * hb_font_set_funcs:
1094  * @font: a font.
1095  * @klass: (closure font_data) (destroy destroy) (scope notified):
1096  * @font_data: 
1097  * @destroy: 
1098  *
1099  * 
1100  *
1101  * Since: 1.0
1102  **/
1103 void
1104 hb_font_set_funcs (hb_font_t         *font,
1105                    hb_font_funcs_t   *klass,
1106                    void              *font_data,
1107                    hb_destroy_func_t  destroy)
1108 {
1109   if (font->immutable) {
1110     if (destroy)
1111       destroy (font_data);
1112     return;
1113   }
1114
1115   if (font->destroy)
1116     font->destroy (font->user_data);
1117
1118   if (!klass)
1119     klass = hb_font_funcs_get_empty ();
1120
1121   hb_font_funcs_reference (klass);
1122   hb_font_funcs_destroy (font->klass);
1123   font->klass = klass;
1124   font->user_data = font_data;
1125   font->destroy = destroy;
1126 }
1127
1128 /**
1129  * hb_font_set_funcs_data:
1130  * @font: a font.
1131  * @font_data: (destroy destroy) (scope notified):
1132  * @destroy: 
1133  *
1134  * 
1135  *
1136  * Since: 1.0
1137  **/
1138 void
1139 hb_font_set_funcs_data (hb_font_t         *font,
1140                         void              *font_data,
1141                         hb_destroy_func_t  destroy)
1142 {
1143   /* Destroy user_data? */
1144   if (font->immutable) {
1145     if (destroy)
1146       destroy (font_data);
1147     return;
1148   }
1149
1150   if (font->destroy)
1151     font->destroy (font->user_data);
1152
1153   font->user_data = font_data;
1154   font->destroy = destroy;
1155 }
1156
1157
1158 /**
1159  * hb_font_set_scale:
1160  * @font: a font.
1161  * @x_scale: 
1162  * @y_scale: 
1163  *
1164  * 
1165  *
1166  * Since: 1.0
1167  **/
1168 void
1169 hb_font_set_scale (hb_font_t *font,
1170                    int x_scale,
1171                    int y_scale)
1172 {
1173   if (font->immutable)
1174     return;
1175
1176   font->x_scale = x_scale;
1177   font->y_scale = y_scale;
1178 }
1179
1180 /**
1181  * hb_font_get_scale:
1182  * @font: a font.
1183  * @x_scale: (out): 
1184  * @y_scale: (out): 
1185  *
1186  * 
1187  *
1188  * Since: 1.0
1189  **/
1190 void
1191 hb_font_get_scale (hb_font_t *font,
1192                    int *x_scale,
1193                    int *y_scale)
1194 {
1195   if (x_scale) *x_scale = font->x_scale;
1196   if (y_scale) *y_scale = font->y_scale;
1197 }
1198
1199 /**
1200  * hb_font_set_ppem:
1201  * @font: a font.
1202  * @x_ppem: 
1203  * @y_ppem: 
1204  *
1205  * 
1206  *
1207  * Since: 1.0
1208  **/
1209 void
1210 hb_font_set_ppem (hb_font_t *font,
1211                   unsigned int x_ppem,
1212                   unsigned int y_ppem)
1213 {
1214   if (font->immutable)
1215     return;
1216
1217   font->x_ppem = x_ppem;
1218   font->y_ppem = y_ppem;
1219 }
1220
1221 /**
1222  * hb_font_get_ppem:
1223  * @font: a font.
1224  * @x_ppem: (out): 
1225  * @y_ppem: (out): 
1226  *
1227  * 
1228  *
1229  * Since: 1.0
1230  **/
1231 void
1232 hb_font_get_ppem (hb_font_t *font,
1233                   unsigned int *x_ppem,
1234                   unsigned int *y_ppem)
1235 {
1236   if (x_ppem) *x_ppem = font->x_ppem;
1237   if (y_ppem) *y_ppem = font->y_ppem;
1238 }