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_font_h_extents_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)48 hb_font_get_font_h_extents_nil (hb_font_t *font,
49 				void *font_data HB_UNUSED,
50 				hb_font_extents_t *metrics,
51 				void *user_data HB_UNUSED)
52 {
53   memset (metrics, 0, sizeof (*metrics));
54   return false;
55 }
56 static hb_bool_t
hb_font_get_font_h_extents_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)57 hb_font_get_font_h_extents_parent (hb_font_t *font,
58 				   void *font_data HB_UNUSED,
59 				   hb_font_extents_t *metrics,
60 				   void *user_data HB_UNUSED)
61 {
62   hb_bool_t ret = font->parent->get_font_h_extents (metrics);
63   if (ret) {
64     metrics->ascender = font->parent_scale_y_distance (metrics->ascender);
65     metrics->descender = font->parent_scale_y_distance (metrics->descender);
66     metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap);
67   }
68   return ret;
69 }
70 
71 static hb_bool_t
hb_font_get_font_v_extents_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)72 hb_font_get_font_v_extents_nil (hb_font_t *font,
73 				void *font_data HB_UNUSED,
74 				hb_font_extents_t *metrics,
75 				void *user_data HB_UNUSED)
76 {
77   memset (metrics, 0, sizeof (*metrics));
78   return false;
79 }
80 static hb_bool_t
hb_font_get_font_v_extents_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)81 hb_font_get_font_v_extents_parent (hb_font_t *font,
82 				   void *font_data HB_UNUSED,
83 				   hb_font_extents_t *metrics,
84 				   void *user_data HB_UNUSED)
85 {
86   hb_bool_t ret = font->parent->get_font_v_extents (metrics);
87   if (ret) {
88     metrics->ascender = font->parent_scale_x_distance (metrics->ascender);
89     metrics->descender = font->parent_scale_x_distance (metrics->descender);
90     metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap);
91   }
92   return ret;
93 }
94 
95 static hb_bool_t
hb_font_get_nominal_glyph_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t * glyph,void * user_data HB_UNUSED)96 hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
97 			       void *font_data HB_UNUSED,
98 			       hb_codepoint_t unicode,
99 			       hb_codepoint_t *glyph,
100 			       void *user_data HB_UNUSED)
101 {
102   *glyph = 0;
103   return false;
104 }
105 static hb_bool_t
hb_font_get_nominal_glyph_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t * glyph,void * user_data HB_UNUSED)106 hb_font_get_nominal_glyph_parent (hb_font_t *font,
107 				  void *font_data HB_UNUSED,
108 				  hb_codepoint_t unicode,
109 				  hb_codepoint_t *glyph,
110 				  void *user_data HB_UNUSED)
111 {
112   return font->parent->get_nominal_glyph (unicode, glyph);
113 }
114 
115 static hb_bool_t
hb_font_get_variation_glyph_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph,void * user_data HB_UNUSED)116 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
117 				 void *font_data HB_UNUSED,
118 				 hb_codepoint_t unicode,
119 				 hb_codepoint_t variation_selector,
120 				 hb_codepoint_t *glyph,
121 				 void *user_data HB_UNUSED)
122 {
123   *glyph = 0;
124   return false;
125 }
126 static hb_bool_t
hb_font_get_variation_glyph_parent(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)127 hb_font_get_variation_glyph_parent (hb_font_t *font,
128 				    void *font_data HB_UNUSED,
129 				    hb_codepoint_t unicode,
130 				    hb_codepoint_t variation_selector,
131 				    hb_codepoint_t *glyph,
132 				    void *user_data HB_UNUSED)
133 {
134   return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
135 }
136 
137 
138 static hb_position_t
hb_font_get_glyph_h_advance_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)139 hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
140 				 void *font_data HB_UNUSED,
141 				 hb_codepoint_t glyph,
142 				 void *user_data HB_UNUSED)
143 {
144   return font->x_scale;
145 }
146 static hb_position_t
hb_font_get_glyph_h_advance_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)147 hb_font_get_glyph_h_advance_parent (hb_font_t *font,
148 				    void *font_data HB_UNUSED,
149 				    hb_codepoint_t glyph,
150 				    void *user_data HB_UNUSED)
151 {
152   return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
153 }
154 
155 static hb_position_t
hb_font_get_glyph_v_advance_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)156 hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
157 				 void *font_data HB_UNUSED,
158 				 hb_codepoint_t glyph,
159 				 void *user_data HB_UNUSED)
160 {
161   return font->y_scale;
162 }
163 static hb_position_t
hb_font_get_glyph_v_advance_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)164 hb_font_get_glyph_v_advance_parent (hb_font_t *font,
165 				    void *font_data HB_UNUSED,
166 				    hb_codepoint_t glyph,
167 				    void *user_data HB_UNUSED)
168 {
169   return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
170 }
171 
172 static hb_bool_t
hb_font_get_glyph_h_origin_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)173 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
174 				void *font_data HB_UNUSED,
175 				hb_codepoint_t glyph,
176 				hb_position_t *x,
177 				hb_position_t *y,
178 				void *user_data HB_UNUSED)
179 {
180   *x = *y = 0;
181   return true;
182 }
183 static hb_bool_t
hb_font_get_glyph_h_origin_parent(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)184 hb_font_get_glyph_h_origin_parent (hb_font_t *font,
185 				   void *font_data HB_UNUSED,
186 				   hb_codepoint_t glyph,
187 				   hb_position_t *x,
188 				   hb_position_t *y,
189 				   void *user_data HB_UNUSED)
190 {
191   hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
192   if (ret)
193     font->parent_scale_position (x, y);
194   return ret;
195 }
196 
197 static hb_bool_t
hb_font_get_glyph_v_origin_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)198 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
199 				void *font_data HB_UNUSED,
200 				hb_codepoint_t glyph,
201 				hb_position_t *x,
202 				hb_position_t *y,
203 				void *user_data HB_UNUSED)
204 {
205   *x = *y = 0;
206   return false;
207 }
208 static hb_bool_t
hb_font_get_glyph_v_origin_parent(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)209 hb_font_get_glyph_v_origin_parent (hb_font_t *font,
210 				   void *font_data HB_UNUSED,
211 				   hb_codepoint_t glyph,
212 				   hb_position_t *x,
213 				   hb_position_t *y,
214 				   void *user_data HB_UNUSED)
215 {
216   hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
217   if (ret)
218     font->parent_scale_position (x, y);
219   return ret;
220 }
221 
222 static hb_position_t
hb_font_get_glyph_h_kerning_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph,void * user_data HB_UNUSED)223 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
224 				 void *font_data HB_UNUSED,
225 				 hb_codepoint_t left_glyph,
226 				 hb_codepoint_t right_glyph,
227 				 void *user_data HB_UNUSED)
228 {
229   return 0;
230 }
231 static hb_position_t
hb_font_get_glyph_h_kerning_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph,void * user_data HB_UNUSED)232 hb_font_get_glyph_h_kerning_parent (hb_font_t *font,
233 				    void *font_data HB_UNUSED,
234 				    hb_codepoint_t left_glyph,
235 				    hb_codepoint_t right_glyph,
236 				    void *user_data HB_UNUSED)
237 {
238   return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
239 }
240 
241 static hb_position_t
hb_font_get_glyph_v_kerning_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph,void * user_data HB_UNUSED)242 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
243 				 void *font_data HB_UNUSED,
244 				 hb_codepoint_t top_glyph,
245 				 hb_codepoint_t bottom_glyph,
246 				 void *user_data HB_UNUSED)
247 {
248   return 0;
249 }
250 static hb_position_t
hb_font_get_glyph_v_kerning_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph,void * user_data HB_UNUSED)251 hb_font_get_glyph_v_kerning_parent (hb_font_t *font,
252 				    void *font_data HB_UNUSED,
253 				    hb_codepoint_t top_glyph,
254 				    hb_codepoint_t bottom_glyph,
255 				    void *user_data HB_UNUSED)
256 {
257   return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
258 }
259 
260 static hb_bool_t
hb_font_get_glyph_extents_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)261 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
262 			       void *font_data HB_UNUSED,
263 			       hb_codepoint_t glyph,
264 			       hb_glyph_extents_t *extents,
265 			       void *user_data HB_UNUSED)
266 {
267   memset (extents, 0, sizeof (*extents));
268   return false;
269 }
270 static hb_bool_t
hb_font_get_glyph_extents_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)271 hb_font_get_glyph_extents_parent (hb_font_t *font,
272 				  void *font_data HB_UNUSED,
273 				  hb_codepoint_t glyph,
274 				  hb_glyph_extents_t *extents,
275 				  void *user_data HB_UNUSED)
276 {
277   hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
278   if (ret) {
279     font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
280     font->parent_scale_distance (&extents->width, &extents->height);
281   }
282   return ret;
283 }
284 
285 static hb_bool_t
hb_font_get_glyph_contour_point_nil(hb_font_t * font HB_UNUSED,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)286 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
287 				     void *font_data HB_UNUSED,
288 				     hb_codepoint_t glyph,
289 				     unsigned int point_index,
290 				     hb_position_t *x,
291 				     hb_position_t *y,
292 				     void *user_data HB_UNUSED)
293 {
294   *x = *y = 0;
295   return false;
296 }
297 static hb_bool_t
hb_font_get_glyph_contour_point_parent(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)298 hb_font_get_glyph_contour_point_parent (hb_font_t *font,
299 					void *font_data HB_UNUSED,
300 					hb_codepoint_t glyph,
301 					unsigned int point_index,
302 					hb_position_t *x,
303 					hb_position_t *y,
304 					void *user_data HB_UNUSED)
305 {
306   hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
307   if (ret)
308     font->parent_scale_position (x, y);
309   return ret;
310 }
311 
312 static hb_bool_t
hb_font_get_glyph_name_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,char * name,unsigned int size,void * user_data HB_UNUSED)313 hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
314 			    void *font_data HB_UNUSED,
315 			    hb_codepoint_t glyph,
316 			    char *name, unsigned int size,
317 			    void *user_data HB_UNUSED)
318 {
319   if (size) *name = '\0';
320   return false;
321 }
322 static hb_bool_t
hb_font_get_glyph_name_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,char * name,unsigned int size,void * user_data HB_UNUSED)323 hb_font_get_glyph_name_parent (hb_font_t *font,
324 			       void *font_data HB_UNUSED,
325 			       hb_codepoint_t glyph,
326 			       char *name, unsigned int size,
327 			       void *user_data HB_UNUSED)
328 {
329   return font->parent->get_glyph_name (glyph, name, size);
330 }
331 
332 static hb_bool_t
hb_font_get_glyph_from_name_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,const char * name,int len,hb_codepoint_t * glyph,void * user_data HB_UNUSED)333 hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
334 				 void *font_data HB_UNUSED,
335 				 const char *name, int len, /* -1 means nul-terminated */
336 				 hb_codepoint_t *glyph,
337 				 void *user_data HB_UNUSED)
338 {
339   *glyph = 0;
340   return false;
341 }
342 static hb_bool_t
hb_font_get_glyph_from_name_parent(hb_font_t * font,void * font_data HB_UNUSED,const char * name,int len,hb_codepoint_t * glyph,void * user_data HB_UNUSED)343 hb_font_get_glyph_from_name_parent (hb_font_t *font,
344 				    void *font_data HB_UNUSED,
345 				    const char *name, int len, /* -1 means nul-terminated */
346 				    hb_codepoint_t *glyph,
347 				    void *user_data HB_UNUSED)
348 {
349   return font->parent->get_glyph_from_name (name, len, glyph);
350 }
351 
352 static const hb_font_funcs_t _hb_font_funcs_nil = {
353   HB_OBJECT_HEADER_STATIC,
354 
355   true, /* immutable */
356 
357   {
358 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
359     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
360 #undef HB_FONT_FUNC_IMPLEMENT
361   },
362   {
363 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
364     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
365 #undef HB_FONT_FUNC_IMPLEMENT
366   },
367   {
368     {
369 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
370       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
371 #undef HB_FONT_FUNC_IMPLEMENT
372     }
373   }
374 };
375 static const hb_font_funcs_t _hb_font_funcs_parent = {
376   HB_OBJECT_HEADER_STATIC,
377 
378   true, /* immutable */
379 
380   {
381 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
382     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
383 #undef HB_FONT_FUNC_IMPLEMENT
384   },
385   {
386 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
387     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
388 #undef HB_FONT_FUNC_IMPLEMENT
389   },
390   {
391     {
392 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_parent,
393       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
394 #undef HB_FONT_FUNC_IMPLEMENT
395     }
396   }
397 };
398 
399 
400 /**
401  * hb_font_funcs_create: (Xconstructor)
402  *
403  *
404  *
405  * Return value: (transfer full):
406  *
407  * Since: 0.9.2
408  **/
409 hb_font_funcs_t *
hb_font_funcs_create(void)410 hb_font_funcs_create (void)
411 {
412   hb_font_funcs_t *ffuncs;
413 
414   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
415     return hb_font_funcs_get_empty ();
416 
417   ffuncs->get = _hb_font_funcs_parent.get;
418 
419   return ffuncs;
420 }
421 
422 /**
423  * hb_font_funcs_get_empty:
424  *
425  *
426  *
427  * Return value: (transfer full):
428  *
429  * Since: 0.9.2
430  **/
431 hb_font_funcs_t *
hb_font_funcs_get_empty(void)432 hb_font_funcs_get_empty (void)
433 {
434   return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_parent);
435 }
436 
437 /**
438  * hb_font_funcs_reference: (skip)
439  * @ffuncs: font functions.
440  *
441  *
442  *
443  * Return value:
444  *
445  * Since: 0.9.2
446  **/
447 hb_font_funcs_t *
hb_font_funcs_reference(hb_font_funcs_t * ffuncs)448 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
449 {
450   return hb_object_reference (ffuncs);
451 }
452 
453 /**
454  * hb_font_funcs_destroy: (skip)
455  * @ffuncs: font functions.
456  *
457  *
458  *
459  * Since: 0.9.2
460  **/
461 void
hb_font_funcs_destroy(hb_font_funcs_t * ffuncs)462 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
463 {
464   if (!hb_object_destroy (ffuncs)) return;
465 
466 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
467   ffuncs->destroy.name (ffuncs->user_data.name);
468   HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
469 #undef HB_FONT_FUNC_IMPLEMENT
470 
471   free (ffuncs);
472 }
473 
474 /**
475  * hb_font_funcs_set_user_data: (skip)
476  * @ffuncs: font functions.
477  * @key:
478  * @data:
479  * @destroy:
480  * @replace:
481  *
482  *
483  *
484  * Return value:
485  *
486  * Since: 0.9.2
487  **/
488 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)489 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
490 			     hb_user_data_key_t *key,
491 			     void *              data,
492 			     hb_destroy_func_t   destroy,
493 			     hb_bool_t           replace)
494 {
495   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
496 }
497 
498 /**
499  * hb_font_funcs_get_user_data: (skip)
500  * @ffuncs: font functions.
501  * @key:
502  *
503  *
504  *
505  * Return value: (transfer none):
506  *
507  * Since: 0.9.2
508  **/
509 void *
hb_font_funcs_get_user_data(hb_font_funcs_t * ffuncs,hb_user_data_key_t * key)510 hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
511 			     hb_user_data_key_t *key)
512 {
513   return hb_object_get_user_data (ffuncs, key);
514 }
515 
516 
517 /**
518  * hb_font_funcs_make_immutable:
519  * @ffuncs: font functions.
520  *
521  *
522  *
523  * Since: 0.9.2
524  **/
525 void
hb_font_funcs_make_immutable(hb_font_funcs_t * ffuncs)526 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
527 {
528   if (unlikely (hb_object_is_inert (ffuncs)))
529     return;
530 
531   ffuncs->immutable = true;
532 }
533 
534 /**
535  * hb_font_funcs_is_immutable:
536  * @ffuncs: font functions.
537  *
538  *
539  *
540  * Return value:
541  *
542  * Since: 0.9.2
543  **/
544 hb_bool_t
hb_font_funcs_is_immutable(hb_font_funcs_t * ffuncs)545 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
546 {
547   return ffuncs->immutable;
548 }
549 
550 
551 #define HB_FONT_FUNC_IMPLEMENT(name) \
552                                                                          \
553 void                                                                     \
554 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
555                                  hb_font_get_##name##_func_t  func,      \
556                                  void                        *user_data, \
557                                  hb_destroy_func_t            destroy)   \
558 {                                                                        \
559   if (ffuncs->immutable) {                                               \
560     if (destroy)                                                         \
561       destroy (user_data);                                               \
562     return;                                                              \
563   }                                                                      \
564                                                                          \
565   if (ffuncs->destroy.name)                                              \
566     ffuncs->destroy.name (ffuncs->user_data.name);                       \
567                                                                          \
568   if (func) {                                                            \
569     ffuncs->get.f.name = func;                                           \
570     ffuncs->user_data.name = user_data;                                  \
571     ffuncs->destroy.name = destroy;                                      \
572   } else {                                                               \
573     ffuncs->get.f.name = hb_font_get_##name##_parent;                    \
574     ffuncs->user_data.name = NULL;                                       \
575     ffuncs->destroy.name = NULL;                                         \
576   }                                                                      \
577 }
578 
579 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
580 #undef HB_FONT_FUNC_IMPLEMENT
581 
582 bool
has_func(unsigned int i)583 hb_font_t::has_func (unsigned int i)
584 {
585   if (parent && parent != hb_font_get_empty () && parent->has_func (i))
586     return true;
587   return this->klass->get.array[i] != _hb_font_funcs_parent.get.array[i];
588 }
589 
590 /* Public getters */
591 
592 /**
593  * hb_font_get_h_extents:
594  * @font: a font.
595  * @extents: (out):
596  *
597  *
598  *
599  * Return value:
600  *
601  * Since: 1.1.3
602  **/
603 hb_bool_t
hb_font_get_h_extents(hb_font_t * font,hb_font_extents_t * extents)604 hb_font_get_h_extents (hb_font_t *font,
605 		       hb_font_extents_t *extents)
606 {
607   return font->get_font_h_extents (extents);
608 }
609 
610 /**
611  * hb_font_get_v_extents:
612  * @font: a font.
613  * @extents: (out):
614  *
615  *
616  *
617  * Return value:
618  *
619  * Since: 1.1.3
620  **/
621 hb_bool_t
hb_font_get_v_extents(hb_font_t * font,hb_font_extents_t * extents)622 hb_font_get_v_extents (hb_font_t *font,
623 		       hb_font_extents_t *extents)
624 {
625   return font->get_font_v_extents (extents);
626 }
627 
628 /**
629  * hb_font_get_glyph:
630  * @font: a font.
631  * @unicode:
632  * @variation_selector:
633  * @glyph: (out):
634  *
635  *
636  *
637  * Return value:
638  *
639  * Since: 0.9.2
640  **/
641 hb_bool_t
hb_font_get_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph)642 hb_font_get_glyph (hb_font_t *font,
643 		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
644 		   hb_codepoint_t *glyph)
645 {
646   if (unlikely (variation_selector))
647     return font->get_variation_glyph (unicode, variation_selector, glyph);
648   return font->get_nominal_glyph (unicode, glyph);
649 }
650 
651 /**
652  * hb_font_get_nominal_glyph:
653  * @font: a font.
654  * @unicode:
655  * @glyph: (out):
656  *
657  *
658  *
659  * Return value:
660  *
661  * Since: 1.2.3
662  **/
663 hb_bool_t
hb_font_get_nominal_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t * glyph)664 hb_font_get_nominal_glyph (hb_font_t *font,
665 			   hb_codepoint_t unicode,
666 			   hb_codepoint_t *glyph)
667 {
668   return font->get_nominal_glyph (unicode, glyph);
669 }
670 
671 /**
672  * hb_font_get_variation_glyph:
673  * @font: a font.
674  * @unicode:
675  * @variation_selector:
676  * @glyph: (out):
677  *
678  *
679  *
680  * Return value:
681  *
682  * Since: 1.2.3
683  **/
684 hb_bool_t
hb_font_get_variation_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph)685 hb_font_get_variation_glyph (hb_font_t *font,
686 			     hb_codepoint_t unicode, hb_codepoint_t variation_selector,
687 			     hb_codepoint_t *glyph)
688 {
689   return font->get_variation_glyph (unicode, variation_selector, glyph);
690 }
691 
692 /**
693  * hb_font_get_glyph_h_advance:
694  * @font: a font.
695  * @glyph:
696  *
697  *
698  *
699  * Return value:
700  *
701  * Since: 0.9.2
702  **/
703 hb_position_t
hb_font_get_glyph_h_advance(hb_font_t * font,hb_codepoint_t glyph)704 hb_font_get_glyph_h_advance (hb_font_t *font,
705 			     hb_codepoint_t glyph)
706 {
707   return font->get_glyph_h_advance (glyph);
708 }
709 
710 /**
711  * hb_font_get_glyph_v_advance:
712  * @font: a font.
713  * @glyph:
714  *
715  *
716  *
717  * Return value:
718  *
719  * Since: 0.9.2
720  **/
721 hb_position_t
hb_font_get_glyph_v_advance(hb_font_t * font,hb_codepoint_t glyph)722 hb_font_get_glyph_v_advance (hb_font_t *font,
723 			     hb_codepoint_t glyph)
724 {
725   return font->get_glyph_v_advance (glyph);
726 }
727 
728 /**
729  * hb_font_get_glyph_h_origin:
730  * @font: a font.
731  * @glyph:
732  * @x: (out):
733  * @y: (out):
734  *
735  *
736  *
737  * Return value:
738  *
739  * Since: 0.9.2
740  **/
741 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)742 hb_font_get_glyph_h_origin (hb_font_t *font,
743 			    hb_codepoint_t glyph,
744 			    hb_position_t *x, hb_position_t *y)
745 {
746   return font->get_glyph_h_origin (glyph, x, y);
747 }
748 
749 /**
750  * hb_font_get_glyph_v_origin:
751  * @font: a font.
752  * @glyph:
753  * @x: (out):
754  * @y: (out):
755  *
756  *
757  *
758  * Return value:
759  *
760  * Since: 0.9.2
761  **/
762 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)763 hb_font_get_glyph_v_origin (hb_font_t *font,
764 			    hb_codepoint_t glyph,
765 			    hb_position_t *x, hb_position_t *y)
766 {
767   return font->get_glyph_v_origin (glyph, x, y);
768 }
769 
770 /**
771  * hb_font_get_glyph_h_kerning:
772  * @font: a font.
773  * @left_glyph:
774  * @right_glyph:
775  *
776  *
777  *
778  * Return value:
779  *
780  * Since: 0.9.2
781  **/
782 hb_position_t
hb_font_get_glyph_h_kerning(hb_font_t * font,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph)783 hb_font_get_glyph_h_kerning (hb_font_t *font,
784 			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
785 {
786   return font->get_glyph_h_kerning (left_glyph, right_glyph);
787 }
788 
789 /**
790  * hb_font_get_glyph_v_kerning:
791  * @font: a font.
792  * @top_glyph:
793  * @bottom_glyph:
794  *
795  *
796  *
797  * Return value:
798  *
799  * Since: 0.9.2
800  **/
801 hb_position_t
hb_font_get_glyph_v_kerning(hb_font_t * font,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph)802 hb_font_get_glyph_v_kerning (hb_font_t *font,
803 			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
804 {
805   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
806 }
807 
808 /**
809  * hb_font_get_glyph_extents:
810  * @font: a font.
811  * @glyph:
812  * @extents: (out):
813  *
814  *
815  *
816  * Return value:
817  *
818  * Since: 0.9.2
819  **/
820 hb_bool_t
hb_font_get_glyph_extents(hb_font_t * font,hb_codepoint_t glyph,hb_glyph_extents_t * extents)821 hb_font_get_glyph_extents (hb_font_t *font,
822 			   hb_codepoint_t glyph,
823 			   hb_glyph_extents_t *extents)
824 {
825   return font->get_glyph_extents (glyph, extents);
826 }
827 
828 /**
829  * hb_font_get_glyph_contour_point:
830  * @font: a font.
831  * @glyph:
832  * @point_index:
833  * @x: (out):
834  * @y: (out):
835  *
836  *
837  *
838  * Return value:
839  *
840  * Since: 0.9.2
841  **/
842 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)843 hb_font_get_glyph_contour_point (hb_font_t *font,
844 				 hb_codepoint_t glyph, unsigned int point_index,
845 				 hb_position_t *x, hb_position_t *y)
846 {
847   return font->get_glyph_contour_point (glyph, point_index, x, y);
848 }
849 
850 /**
851  * hb_font_get_glyph_name:
852  * @font: a font.
853  * @glyph:
854  * @name: (array length=size):
855  * @size:
856  *
857  *
858  *
859  * Return value:
860  *
861  * Since: 0.9.2
862  **/
863 hb_bool_t
hb_font_get_glyph_name(hb_font_t * font,hb_codepoint_t glyph,char * name,unsigned int size)864 hb_font_get_glyph_name (hb_font_t *font,
865 			hb_codepoint_t glyph,
866 			char *name, unsigned int size)
867 {
868   return font->get_glyph_name (glyph, name, size);
869 }
870 
871 /**
872  * hb_font_get_glyph_from_name:
873  * @font: a font.
874  * @name: (array length=len):
875  * @len:
876  * @glyph: (out):
877  *
878  *
879  *
880  * Return value:
881  *
882  * Since: 0.9.2
883  **/
884 hb_bool_t
hb_font_get_glyph_from_name(hb_font_t * font,const char * name,int len,hb_codepoint_t * glyph)885 hb_font_get_glyph_from_name (hb_font_t *font,
886 			     const char *name, int len, /* -1 means nul-terminated */
887 			     hb_codepoint_t *glyph)
888 {
889   return font->get_glyph_from_name (name, len, glyph);
890 }
891 
892 
893 /* A bit higher-level, and with fallback */
894 
895 /**
896  * hb_font_get_extents_for_direction:
897  * @font: a font.
898  * @direction:
899  * @extents:
900  *
901  *
902  *
903  * Since: 1.1.3
904  **/
905 void
hb_font_get_extents_for_direction(hb_font_t * font,hb_direction_t direction,hb_font_extents_t * extents)906 hb_font_get_extents_for_direction (hb_font_t *font,
907 				   hb_direction_t direction,
908 				   hb_font_extents_t *extents)
909 {
910   return font->get_extents_for_direction (direction, extents);
911 }
912 /**
913  * hb_font_get_glyph_advance_for_direction:
914  * @font: a font.
915  * @glyph:
916  * @direction:
917  * @x: (out):
918  * @y: (out):
919  *
920  *
921  *
922  * Since: 0.9.2
923  **/
924 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)925 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
926 					 hb_codepoint_t glyph,
927 					 hb_direction_t direction,
928 					 hb_position_t *x, hb_position_t *y)
929 {
930   return font->get_glyph_advance_for_direction (glyph, direction, x, y);
931 }
932 
933 /**
934  * hb_font_get_glyph_origin_for_direction:
935  * @font: a font.
936  * @glyph:
937  * @direction:
938  * @x: (out):
939  * @y: (out):
940  *
941  *
942  *
943  * Since: 0.9.2
944  **/
945 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)946 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
947 					hb_codepoint_t glyph,
948 					hb_direction_t direction,
949 					hb_position_t *x, hb_position_t *y)
950 {
951   return font->get_glyph_origin_for_direction (glyph, direction, x, y);
952 }
953 
954 /**
955  * hb_font_add_glyph_origin_for_direction:
956  * @font: a font.
957  * @glyph:
958  * @direction:
959  * @x: (out):
960  * @y: (out):
961  *
962  *
963  *
964  * Since: 0.9.2
965  **/
966 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)967 hb_font_add_glyph_origin_for_direction (hb_font_t *font,
968 					hb_codepoint_t glyph,
969 					hb_direction_t direction,
970 					hb_position_t *x, hb_position_t *y)
971 {
972   return font->add_glyph_origin_for_direction (glyph, direction, x, y);
973 }
974 
975 /**
976  * hb_font_subtract_glyph_origin_for_direction:
977  * @font: a font.
978  * @glyph:
979  * @direction:
980  * @x: (out):
981  * @y: (out):
982  *
983  *
984  *
985  * Since: 0.9.2
986  **/
987 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)988 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
989 					     hb_codepoint_t glyph,
990 					     hb_direction_t direction,
991 					     hb_position_t *x, hb_position_t *y)
992 {
993   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
994 }
995 
996 /**
997  * hb_font_get_glyph_kerning_for_direction:
998  * @font: a font.
999  * @first_glyph:
1000  * @second_glyph:
1001  * @direction:
1002  * @x: (out):
1003  * @y: (out):
1004  *
1005  *
1006  *
1007  * Since: 0.9.2
1008  **/
1009 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)1010 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
1011 					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
1012 					 hb_direction_t direction,
1013 					 hb_position_t *x, hb_position_t *y)
1014 {
1015   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
1016 }
1017 
1018 /**
1019  * hb_font_get_glyph_extents_for_origin:
1020  * @font: a font.
1021  * @glyph:
1022  * @direction:
1023  * @extents: (out):
1024  *
1025  *
1026  *
1027  * Return value:
1028  *
1029  * Since: 0.9.2
1030  **/
1031 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)1032 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
1033 				      hb_codepoint_t glyph,
1034 				      hb_direction_t direction,
1035 				      hb_glyph_extents_t *extents)
1036 {
1037   return font->get_glyph_extents_for_origin (glyph, direction, extents);
1038 }
1039 
1040 /**
1041  * hb_font_get_glyph_contour_point_for_origin:
1042  * @font: a font.
1043  * @glyph:
1044  * @point_index:
1045  * @direction:
1046  * @x: (out):
1047  * @y: (out):
1048  *
1049  *
1050  *
1051  * Return value:
1052  *
1053  * Since: 0.9.2
1054  **/
1055 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)1056 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
1057 					    hb_codepoint_t glyph, unsigned int point_index,
1058 					    hb_direction_t direction,
1059 					    hb_position_t *x, hb_position_t *y)
1060 {
1061   return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
1062 }
1063 
1064 /* Generates gidDDD if glyph has no name. */
1065 /**
1066  * hb_font_glyph_to_string:
1067  * @font: a font.
1068  * @glyph:
1069  * @s: (array length=size):
1070  * @size:
1071  *
1072  *
1073  *
1074  * Since: 0.9.2
1075  **/
1076 void
hb_font_glyph_to_string(hb_font_t * font,hb_codepoint_t glyph,char * s,unsigned int size)1077 hb_font_glyph_to_string (hb_font_t *font,
1078 			 hb_codepoint_t glyph,
1079 			 char *s, unsigned int size)
1080 {
1081   font->glyph_to_string (glyph, s, size);
1082 }
1083 
1084 /* Parses gidDDD and uniUUUU strings automatically. */
1085 /**
1086  * hb_font_glyph_from_string:
1087  * @font: a font.
1088  * @s: (array length=len) (element-type uint8_t):
1089  * @len:
1090  * @glyph: (out):
1091  *
1092  *
1093  *
1094  * Return value:
1095  *
1096  * Since: 0.9.2
1097  **/
1098 hb_bool_t
hb_font_glyph_from_string(hb_font_t * font,const char * s,int len,hb_codepoint_t * glyph)1099 hb_font_glyph_from_string (hb_font_t *font,
1100 			   const char *s, int len, /* -1 means nul-terminated */
1101 			   hb_codepoint_t *glyph)
1102 {
1103   return font->glyph_from_string (s, len, glyph);
1104 }
1105 
1106 
1107 /*
1108  * hb_font_t
1109  */
1110 
1111 /**
1112  * hb_font_create: (Xconstructor)
1113  * @face: a face.
1114  *
1115  *
1116  *
1117  * Return value: (transfer full):
1118  *
1119  * Since: 0.9.2
1120  **/
1121 hb_font_t *
hb_font_create(hb_face_t * face)1122 hb_font_create (hb_face_t *face)
1123 {
1124   hb_font_t *font;
1125 
1126   if (unlikely (!face))
1127     face = hb_face_get_empty ();
1128   if (!(font = hb_object_create<hb_font_t> ()))
1129     return hb_font_get_empty ();
1130 
1131   hb_face_make_immutable (face);
1132   font->parent = hb_font_get_empty ();
1133   font->face = hb_face_reference (face);
1134   font->klass = hb_font_funcs_get_empty ();
1135 
1136   font->x_scale = font->y_scale = hb_face_get_upem (face);
1137 
1138   return font;
1139 }
1140 
1141 /**
1142  * hb_font_create_sub_font:
1143  * @parent: parent font.
1144  *
1145  *
1146  *
1147  * Return value: (transfer full):
1148  *
1149  * Since: 0.9.2
1150  **/
1151 hb_font_t *
hb_font_create_sub_font(hb_font_t * parent)1152 hb_font_create_sub_font (hb_font_t *parent)
1153 {
1154   if (unlikely (!parent))
1155     parent = hb_font_get_empty ();
1156 
1157   hb_font_t *font = hb_font_create (parent->face);
1158 
1159   if (unlikely (hb_object_is_inert (font)))
1160     return font;
1161 
1162   font->parent = hb_font_reference (parent);
1163 
1164   font->x_scale = parent->x_scale;
1165   font->y_scale = parent->y_scale;
1166   font->x_ppem = parent->x_ppem;
1167   font->y_ppem = parent->y_ppem;
1168 
1169   return font;
1170 }
1171 
1172 /**
1173  * hb_font_get_empty:
1174  *
1175  *
1176  *
1177  * Return value: (transfer full)
1178  *
1179  * Since: 0.9.2
1180  **/
1181 hb_font_t *
hb_font_get_empty(void)1182 hb_font_get_empty (void)
1183 {
1184   static const hb_font_t _hb_font_nil = {
1185     HB_OBJECT_HEADER_STATIC,
1186 
1187     true, /* immutable */
1188 
1189     NULL, /* parent */
1190     const_cast<hb_face_t *> (&_hb_face_nil),
1191 
1192     1000, /* x_scale */
1193     1000, /* y_scale */
1194 
1195     0, /* x_ppem */
1196     0, /* y_ppem */
1197 
1198     const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
1199     NULL, /* user_data */
1200     NULL, /* destroy */
1201 
1202     {
1203 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
1204 #include "hb-shaper-list.hh"
1205 #undef HB_SHAPER_IMPLEMENT
1206     }
1207   };
1208 
1209   return const_cast<hb_font_t *> (&_hb_font_nil);
1210 }
1211 
1212 /**
1213  * hb_font_reference: (skip)
1214  * @font: a font.
1215  *
1216  *
1217  *
1218  * Return value: (transfer full):
1219  *
1220  * Since: 0.9.2
1221  **/
1222 hb_font_t *
hb_font_reference(hb_font_t * font)1223 hb_font_reference (hb_font_t *font)
1224 {
1225   return hb_object_reference (font);
1226 }
1227 
1228 /**
1229  * hb_font_destroy: (skip)
1230  * @font: a font.
1231  *
1232  *
1233  *
1234  * Since: 0.9.2
1235  **/
1236 void
hb_font_destroy(hb_font_t * font)1237 hb_font_destroy (hb_font_t *font)
1238 {
1239   if (!hb_object_destroy (font)) return;
1240 
1241 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
1242 #include "hb-shaper-list.hh"
1243 #undef HB_SHAPER_IMPLEMENT
1244 
1245   if (font->destroy)
1246     font->destroy (font->user_data);
1247 
1248   hb_font_destroy (font->parent);
1249   hb_face_destroy (font->face);
1250   hb_font_funcs_destroy (font->klass);
1251 
1252   free (font);
1253 }
1254 
1255 /**
1256  * hb_font_set_user_data: (skip)
1257  * @font: a font.
1258  * @key:
1259  * @data:
1260  * @destroy:
1261  * @replace:
1262  *
1263  *
1264  *
1265  * Return value:
1266  *
1267  * Since: 0.9.2
1268  **/
1269 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)1270 hb_font_set_user_data (hb_font_t          *font,
1271 		       hb_user_data_key_t *key,
1272 		       void *              data,
1273 		       hb_destroy_func_t   destroy,
1274 		       hb_bool_t           replace)
1275 {
1276   return hb_object_set_user_data (font, key, data, destroy, replace);
1277 }
1278 
1279 /**
1280  * hb_font_get_user_data: (skip)
1281  * @font: a font.
1282  * @key:
1283  *
1284  *
1285  *
1286  * Return value: (transfer none):
1287  *
1288  * Since: 0.9.2
1289  **/
1290 void *
hb_font_get_user_data(hb_font_t * font,hb_user_data_key_t * key)1291 hb_font_get_user_data (hb_font_t          *font,
1292 		       hb_user_data_key_t *key)
1293 {
1294   return hb_object_get_user_data (font, key);
1295 }
1296 
1297 /**
1298  * hb_font_make_immutable:
1299  * @font: a font.
1300  *
1301  *
1302  *
1303  * Since: 0.9.2
1304  **/
1305 void
hb_font_make_immutable(hb_font_t * font)1306 hb_font_make_immutable (hb_font_t *font)
1307 {
1308   if (unlikely (hb_object_is_inert (font)))
1309     return;
1310 
1311   if (font->parent)
1312     hb_font_make_immutable (font->parent);
1313 
1314   font->immutable = true;
1315 }
1316 
1317 /**
1318  * hb_font_is_immutable:
1319  * @font: a font.
1320  *
1321  *
1322  *
1323  * Return value:
1324  *
1325  * Since: 0.9.2
1326  **/
1327 hb_bool_t
hb_font_is_immutable(hb_font_t * font)1328 hb_font_is_immutable (hb_font_t *font)
1329 {
1330   return font->immutable;
1331 }
1332 
1333 /**
1334  * hb_font_set_parent:
1335  * @font: a font.
1336  * @parent: new parent.
1337  *
1338  * Sets parent font of @font.
1339  *
1340  * Since: 1.0.5
1341  **/
1342 void
hb_font_set_parent(hb_font_t * font,hb_font_t * parent)1343 hb_font_set_parent (hb_font_t *font,
1344 		    hb_font_t *parent)
1345 {
1346   if (font->immutable)
1347     return;
1348 
1349   if (!parent)
1350     parent = hb_font_get_empty ();
1351 
1352   hb_font_t *old = font->parent;
1353 
1354   font->parent = hb_font_reference (parent);
1355 
1356   hb_font_destroy (old);
1357 }
1358 
1359 /**
1360  * hb_font_get_parent:
1361  * @font: a font.
1362  *
1363  *
1364  *
1365  * Return value: (transfer none):
1366  *
1367  * Since: 0.9.2
1368  **/
1369 hb_font_t *
hb_font_get_parent(hb_font_t * font)1370 hb_font_get_parent (hb_font_t *font)
1371 {
1372   return font->parent;
1373 }
1374 
1375 /**
1376  * hb_font_get_face:
1377  * @font: a font.
1378  *
1379  *
1380  *
1381  * Return value: (transfer none):
1382  *
1383  * Since: 0.9.2
1384  **/
1385 hb_face_t *
hb_font_get_face(hb_font_t * font)1386 hb_font_get_face (hb_font_t *font)
1387 {
1388   return font->face;
1389 }
1390 
1391 
1392 /**
1393  * hb_font_set_funcs:
1394  * @font: a font.
1395  * @klass: (closure font_data) (destroy destroy) (scope notified):
1396  * @font_data:
1397  * @destroy:
1398  *
1399  *
1400  *
1401  * Since: 0.9.2
1402  **/
1403 void
hb_font_set_funcs(hb_font_t * font,hb_font_funcs_t * klass,void * font_data,hb_destroy_func_t destroy)1404 hb_font_set_funcs (hb_font_t         *font,
1405 		   hb_font_funcs_t   *klass,
1406 		   void              *font_data,
1407 		   hb_destroy_func_t  destroy)
1408 {
1409   if (font->immutable) {
1410     if (destroy)
1411       destroy (font_data);
1412     return;
1413   }
1414 
1415   if (font->destroy)
1416     font->destroy (font->user_data);
1417 
1418   if (!klass)
1419     klass = hb_font_funcs_get_empty ();
1420 
1421   hb_font_funcs_reference (klass);
1422   hb_font_funcs_destroy (font->klass);
1423   font->klass = klass;
1424   font->user_data = font_data;
1425   font->destroy = destroy;
1426 }
1427 
1428 /**
1429  * hb_font_set_funcs_data:
1430  * @font: a font.
1431  * @font_data: (destroy destroy) (scope notified):
1432  * @destroy:
1433  *
1434  *
1435  *
1436  * Since: 0.9.2
1437  **/
1438 void
hb_font_set_funcs_data(hb_font_t * font,void * font_data,hb_destroy_func_t destroy)1439 hb_font_set_funcs_data (hb_font_t         *font,
1440 		        void              *font_data,
1441 		        hb_destroy_func_t  destroy)
1442 {
1443   /* Destroy user_data? */
1444   if (font->immutable) {
1445     if (destroy)
1446       destroy (font_data);
1447     return;
1448   }
1449 
1450   if (font->destroy)
1451     font->destroy (font->user_data);
1452 
1453   font->user_data = font_data;
1454   font->destroy = destroy;
1455 }
1456 
1457 
1458 /**
1459  * hb_font_set_scale:
1460  * @font: a font.
1461  * @x_scale:
1462  * @y_scale:
1463  *
1464  *
1465  *
1466  * Since: 0.9.2
1467  **/
1468 void
hb_font_set_scale(hb_font_t * font,int x_scale,int y_scale)1469 hb_font_set_scale (hb_font_t *font,
1470 		   int x_scale,
1471 		   int y_scale)
1472 {
1473   if (font->immutable)
1474     return;
1475 
1476   font->x_scale = x_scale;
1477   font->y_scale = y_scale;
1478 }
1479 
1480 /**
1481  * hb_font_get_scale:
1482  * @font: a font.
1483  * @x_scale: (out):
1484  * @y_scale: (out):
1485  *
1486  *
1487  *
1488  * Since: 0.9.2
1489  **/
1490 void
hb_font_get_scale(hb_font_t * font,int * x_scale,int * y_scale)1491 hb_font_get_scale (hb_font_t *font,
1492 		   int *x_scale,
1493 		   int *y_scale)
1494 {
1495   if (x_scale) *x_scale = font->x_scale;
1496   if (y_scale) *y_scale = font->y_scale;
1497 }
1498 
1499 /**
1500  * hb_font_set_ppem:
1501  * @font: a font.
1502  * @x_ppem:
1503  * @y_ppem:
1504  *
1505  *
1506  *
1507  * Since: 0.9.2
1508  **/
1509 void
hb_font_set_ppem(hb_font_t * font,unsigned int x_ppem,unsigned int y_ppem)1510 hb_font_set_ppem (hb_font_t *font,
1511 		  unsigned int x_ppem,
1512 		  unsigned int y_ppem)
1513 {
1514   if (font->immutable)
1515     return;
1516 
1517   font->x_ppem = x_ppem;
1518   font->y_ppem = y_ppem;
1519 }
1520 
1521 /**
1522  * hb_font_get_ppem:
1523  * @font: a font.
1524  * @x_ppem: (out):
1525  * @y_ppem: (out):
1526  *
1527  *
1528  *
1529  * Since: 0.9.2
1530  **/
1531 void
hb_font_get_ppem(hb_font_t * font,unsigned int * x_ppem,unsigned int * y_ppem)1532 hb_font_get_ppem (hb_font_t *font,
1533 		  unsigned int *x_ppem,
1534 		  unsigned int *y_ppem)
1535 {
1536   if (x_ppem) *x_ppem = font->x_ppem;
1537   if (y_ppem) *y_ppem = font->y_ppem;
1538 }
1539 
1540 
1541 #ifndef HB_DISABLE_DEPRECATED
1542 
1543 /*
1544  * Deprecated get_glyph_func():
1545  */
1546 
1547 struct hb_trampoline_closure_t
1548 {
1549   void *user_data;
1550   hb_destroy_func_t destroy;
1551   unsigned int ref_count;
1552 };
1553 
1554 template <typename FuncType>
1555 struct hb_trampoline_t
1556 {
1557   hb_trampoline_closure_t closure; /* Must be first. */
1558   FuncType func;
1559 };
1560 
1561 template <typename FuncType>
1562 static hb_trampoline_t<FuncType> *
trampoline_create(FuncType func,void * user_data,hb_destroy_func_t destroy)1563 trampoline_create (FuncType           func,
1564 		   void              *user_data,
1565 		   hb_destroy_func_t  destroy)
1566 {
1567   typedef hb_trampoline_t<FuncType> trampoline_t;
1568 
1569   trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
1570 
1571   if (unlikely (!trampoline))
1572     return NULL;
1573 
1574   trampoline->closure.user_data = user_data;
1575   trampoline->closure.destroy = destroy;
1576   trampoline->closure.ref_count = 1;
1577   trampoline->func = func;
1578 
1579   return trampoline;
1580 }
1581 
1582 static void
trampoline_reference(hb_trampoline_closure_t * closure)1583 trampoline_reference (hb_trampoline_closure_t *closure)
1584 {
1585   closure->ref_count++;
1586 }
1587 
1588 static void
trampoline_destroy(void * user_data)1589 trampoline_destroy (void *user_data)
1590 {
1591   hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
1592 
1593   if (--closure->ref_count)
1594     return;
1595 
1596   if (closure->destroy)
1597     closure->destroy (closure->user_data);
1598   free (closure);
1599 }
1600 
1601 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
1602 
1603 static hb_bool_t
hb_font_get_nominal_glyph_trampoline(hb_font_t * font,void * font_data,hb_codepoint_t unicode,hb_codepoint_t * glyph,void * user_data)1604 hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
1605 				      void *font_data,
1606 				      hb_codepoint_t unicode,
1607 				      hb_codepoint_t *glyph,
1608 				      void *user_data)
1609 {
1610   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
1611   return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
1612 }
1613 
1614 static hb_bool_t
hb_font_get_variation_glyph_trampoline(hb_font_t * font,void * font_data,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph,void * user_data)1615 hb_font_get_variation_glyph_trampoline (hb_font_t *font,
1616 					void *font_data,
1617 					hb_codepoint_t unicode,
1618 					hb_codepoint_t variation_selector,
1619 					hb_codepoint_t *glyph,
1620 					void *user_data)
1621 {
1622   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
1623   return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
1624 }
1625 
1626 /**
1627  * hb_font_funcs_set_glyph_func:
1628  * @ffuncs: font functions.
1629  * @func: (closure user_data) (destroy destroy) (scope notified):
1630  * @user_data:
1631  * @destroy:
1632  *
1633  * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
1634  * hb_font_funcs_set_variation_glyph_func() instead.
1635  *
1636  * Since: 0.9.2
1637  * Deprecated: 1.2.3
1638  **/
1639 void
hb_font_funcs_set_glyph_func(hb_font_funcs_t * ffuncs,hb_font_get_glyph_func_t func,void * user_data,hb_destroy_func_t destroy)1640 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
1641 			      hb_font_get_glyph_func_t func,
1642 			      void *user_data, hb_destroy_func_t destroy)
1643 {
1644   hb_font_get_glyph_trampoline_t *trampoline;
1645 
1646   trampoline = trampoline_create (func, user_data, destroy);
1647   if (unlikely (!trampoline))
1648   {
1649     if (destroy)
1650       destroy (user_data);
1651     return;
1652   }
1653 
1654   hb_font_funcs_set_nominal_glyph_func (ffuncs,
1655 					hb_font_get_nominal_glyph_trampoline,
1656 					trampoline,
1657 					trampoline_destroy);
1658 
1659   trampoline_reference (&trampoline->closure);
1660   hb_font_funcs_set_variation_glyph_func (ffuncs,
1661 					  hb_font_get_variation_glyph_trampoline,
1662 					  trampoline,
1663 					  trampoline_destroy);
1664 }
1665 
1666 #endif /* HB_DISABLE_DEPRECATED */
1667