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
hb_font_get_glyph_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph,void * user_data HB_UNUSED)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
hb_font_get_glyph_h_advance_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)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
hb_font_get_glyph_v_advance_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)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
hb_font_get_glyph_h_origin_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)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
hb_font_get_glyph_v_origin_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)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
hb_font_get_glyph_h_kerning_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph,void * user_data HB_UNUSED)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
hb_font_get_glyph_v_kerning_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph,void * user_data HB_UNUSED)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
hb_font_get_glyph_extents_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)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
hb_font_get_glyph_contour_point_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,unsigned int point_index,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)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
hb_font_get_glyph_name_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,char * name,unsigned int size,void * user_data HB_UNUSED)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
hb_font_get_glyph_from_name_nil(hb_font_t * font,void * font_data HB_UNUSED,const char * name,int len,hb_codepoint_t * glyph,void * user_data HB_UNUSED)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 *
hb_font_funcs_create(void)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 *
hb_font_funcs_get_empty(void)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 *
hb_font_funcs_reference(hb_font_funcs_t * ffuncs)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
hb_font_funcs_destroy(hb_font_funcs_t * ffuncs)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
hb_font_funcs_set_user_data(hb_font_funcs_t * ffuncs,hb_user_data_key_t * key,void * data,hb_destroy_func_t destroy,hb_bool_t replace)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 *
hb_font_funcs_get_user_data(hb_font_funcs_t * ffuncs,hb_user_data_key_t * key)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
hb_font_funcs_make_immutable(hb_font_funcs_t * ffuncs)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
hb_font_funcs_is_immutable(hb_font_funcs_t * ffuncs)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
hb_font_get_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph)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
hb_font_get_glyph_h_advance(hb_font_t * font,hb_codepoint_t glyph)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
hb_font_get_glyph_v_advance(hb_font_t * font,hb_codepoint_t glyph)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
hb_font_get_glyph_h_origin(hb_font_t * font,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y)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
hb_font_get_glyph_v_origin(hb_font_t * font,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y)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
hb_font_get_glyph_h_kerning(hb_font_t * font,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph)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
hb_font_get_glyph_v_kerning(hb_font_t * font,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph)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
hb_font_get_glyph_extents(hb_font_t * font,hb_codepoint_t glyph,hb_glyph_extents_t * extents)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
hb_font_get_glyph_contour_point(hb_font_t * font,hb_codepoint_t glyph,unsigned int point_index,hb_position_t * x,hb_position_t * y)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
hb_font_get_glyph_name(hb_font_t * font,hb_codepoint_t glyph,char * name,unsigned int size)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
hb_font_get_glyph_from_name(hb_font_t * font,const char * name,int len,hb_codepoint_t * glyph)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
hb_font_get_glyph_advance_for_direction(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)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
hb_font_get_glyph_origin_for_direction(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)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
hb_font_add_glyph_origin_for_direction(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)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
hb_font_subtract_glyph_origin_for_direction(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)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
hb_font_get_glyph_kerning_for_direction(hb_font_t * font,hb_codepoint_t first_glyph,hb_codepoint_t second_glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)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
hb_font_get_glyph_extents_for_origin(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_glyph_extents_t * extents)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
hb_font_get_glyph_contour_point_for_origin(hb_font_t * font,hb_codepoint_t glyph,unsigned int point_index,hb_direction_t direction,hb_position_t * x,hb_position_t * y)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
hb_font_glyph_to_string(hb_font_t * font,hb_codepoint_t glyph,char * s,unsigned int size)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
hb_font_glyph_from_string(hb_font_t * font,const char * s,int len,hb_codepoint_t * glyph)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 *
hb_font_create(hb_face_t * face)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 *
hb_font_create_sub_font(hb_font_t * parent)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 *
hb_font_get_empty(void)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 *
hb_font_reference(hb_font_t * font)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
hb_font_destroy(hb_font_t * font)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
hb_font_set_user_data(hb_font_t * font,hb_user_data_key_t * key,void * data,hb_destroy_func_t destroy,hb_bool_t replace)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 *
hb_font_get_user_data(hb_font_t * font,hb_user_data_key_t * key)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
hb_font_make_immutable(hb_font_t * font)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
hb_font_is_immutable(hb_font_t * font)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 *
hb_font_get_parent(hb_font_t * font)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 *
hb_font_get_face(hb_font_t * font)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
hb_font_set_funcs(hb_font_t * font,hb_font_funcs_t * klass,void * font_data,hb_destroy_func_t destroy)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
hb_font_set_funcs_data(hb_font_t * font,void * font_data,hb_destroy_func_t destroy)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
hb_font_set_scale(hb_font_t * font,int x_scale,int y_scale)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
hb_font_get_scale(hb_font_t * font,int * x_scale,int * y_scale)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
hb_font_set_ppem(hb_font_t * font,unsigned int x_ppem,unsigned int y_ppem)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
hb_font_get_ppem(hb_font_t * font,unsigned int * x_ppem,unsigned int * y_ppem)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 }
1239