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