• 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.hh"
30 
31 #include "hb-font.hh"
32 #include "hb-draw.hh"
33 #include "hb-machinery.hh"
34 
35 #include "hb-ot.h"
36 
37 #include "hb-ot-var-avar-table.hh"
38 #include "hb-ot-var-fvar-table.hh"
39 
40 
41 /**
42  * SECTION:hb-font
43  * @title: hb-font
44  * @short_description: Font objects
45  * @include: hb.h
46  *
47  * Functions for working with font objects.
48  *
49  * A font object represents a font face at a specific size and with
50  * certain other parameters (pixels-per-em, points-per-em, variation
51  * settings) specified. Font objects are created from font face
52  * objects, and are used as input to hb_shape(), among other things.
53  *
54  * Client programs can optionally pass in their own functions that
55  * implement the basic, lower-level queries of font objects. This set
56  * of font functions is defined by the virtual methods in
57  * #hb_font_funcs_t.
58  *
59  * HarfBuzz provides a built-in set of lightweight default
60  * functions for each method in #hb_font_funcs_t.
61  **/
62 
63 
64 /*
65  * hb_font_funcs_t
66  */
67 
68 static hb_bool_t
hb_font_get_font_h_extents_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_font_extents_t * extents,void * user_data HB_UNUSED)69 hb_font_get_font_h_extents_nil (hb_font_t         *font HB_UNUSED,
70 				void              *font_data HB_UNUSED,
71 				hb_font_extents_t *extents,
72 				void              *user_data HB_UNUSED)
73 {
74   hb_memset (extents, 0, sizeof (*extents));
75   return false;
76 }
77 
78 static hb_bool_t
hb_font_get_font_h_extents_default(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * extents,void * user_data HB_UNUSED)79 hb_font_get_font_h_extents_default (hb_font_t         *font,
80 				    void              *font_data HB_UNUSED,
81 				    hb_font_extents_t *extents,
82 				    void              *user_data HB_UNUSED)
83 {
84   hb_bool_t ret = font->parent->get_font_h_extents (extents);
85   if (ret) {
86     extents->ascender = font->parent_scale_y_distance (extents->ascender);
87     extents->descender = font->parent_scale_y_distance (extents->descender);
88     extents->line_gap = font->parent_scale_y_distance (extents->line_gap);
89   }
90   return ret;
91 }
92 
93 static hb_bool_t
hb_font_get_font_v_extents_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_font_extents_t * extents,void * user_data HB_UNUSED)94 hb_font_get_font_v_extents_nil (hb_font_t         *font HB_UNUSED,
95 				void              *font_data HB_UNUSED,
96 				hb_font_extents_t *extents,
97 				void              *user_data HB_UNUSED)
98 {
99   hb_memset (extents, 0, sizeof (*extents));
100   return false;
101 }
102 
103 static hb_bool_t
hb_font_get_font_v_extents_default(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * extents,void * user_data HB_UNUSED)104 hb_font_get_font_v_extents_default (hb_font_t         *font,
105 				    void              *font_data HB_UNUSED,
106 				    hb_font_extents_t *extents,
107 				    void              *user_data HB_UNUSED)
108 {
109   hb_bool_t ret = font->parent->get_font_v_extents (extents);
110   if (ret) {
111     extents->ascender = font->parent_scale_x_distance (extents->ascender);
112     extents->descender = font->parent_scale_x_distance (extents->descender);
113     extents->line_gap = font->parent_scale_x_distance (extents->line_gap);
114   }
115   return ret;
116 }
117 
118 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_UNUSED,hb_codepoint_t * glyph,void * user_data HB_UNUSED)119 hb_font_get_nominal_glyph_nil (hb_font_t      *font HB_UNUSED,
120 			       void           *font_data HB_UNUSED,
121 			       hb_codepoint_t  unicode HB_UNUSED,
122 			       hb_codepoint_t *glyph,
123 			       void           *user_data HB_UNUSED)
124 {
125   *glyph = 0;
126   return false;
127 }
128 
129 static hb_bool_t
hb_font_get_nominal_glyph_default(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t * glyph,void * user_data HB_UNUSED)130 hb_font_get_nominal_glyph_default (hb_font_t      *font,
131 				   void           *font_data HB_UNUSED,
132 				   hb_codepoint_t  unicode,
133 				   hb_codepoint_t *glyph,
134 				   void           *user_data HB_UNUSED)
135 {
136   if (font->has_nominal_glyphs_func_set ())
137   {
138     return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0);
139   }
140   return font->parent->get_nominal_glyph (unicode, glyph);
141 }
142 
143 #define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
144 
145 static unsigned int
hb_font_get_nominal_glyphs_default(hb_font_t * font,void * font_data HB_UNUSED,unsigned int count,const hb_codepoint_t * first_unicode,unsigned int unicode_stride,hb_codepoint_t * first_glyph,unsigned int glyph_stride,void * user_data HB_UNUSED)146 hb_font_get_nominal_glyphs_default (hb_font_t            *font,
147 				    void                 *font_data HB_UNUSED,
148 				    unsigned int          count,
149 				    const hb_codepoint_t *first_unicode,
150 				    unsigned int          unicode_stride,
151 				    hb_codepoint_t       *first_glyph,
152 				    unsigned int          glyph_stride,
153 				    void                 *user_data HB_UNUSED)
154 {
155   if (font->has_nominal_glyph_func_set ())
156   {
157     for (unsigned int i = 0; i < count; i++)
158     {
159       if (!font->get_nominal_glyph (*first_unicode, first_glyph))
160 	return i;
161 
162       first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
163       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
164     }
165     return count;
166   }
167 
168   return font->parent->get_nominal_glyphs (count,
169 					   first_unicode, unicode_stride,
170 					   first_glyph, glyph_stride);
171 }
172 
173 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_UNUSED,hb_codepoint_t variation_selector HB_UNUSED,hb_codepoint_t * glyph,void * user_data HB_UNUSED)174 hb_font_get_variation_glyph_nil (hb_font_t      *font HB_UNUSED,
175 				 void           *font_data HB_UNUSED,
176 				 hb_codepoint_t  unicode HB_UNUSED,
177 				 hb_codepoint_t  variation_selector HB_UNUSED,
178 				 hb_codepoint_t *glyph,
179 				 void           *user_data HB_UNUSED)
180 {
181   *glyph = 0;
182   return false;
183 }
184 
185 static hb_bool_t
hb_font_get_variation_glyph_default(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)186 hb_font_get_variation_glyph_default (hb_font_t      *font,
187 				     void           *font_data HB_UNUSED,
188 				     hb_codepoint_t  unicode,
189 				     hb_codepoint_t  variation_selector,
190 				     hb_codepoint_t *glyph,
191 				     void           *user_data HB_UNUSED)
192 {
193   return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
194 }
195 
196 
197 static hb_position_t
hb_font_get_glyph_h_advance_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph HB_UNUSED,void * user_data HB_UNUSED)198 hb_font_get_glyph_h_advance_nil (hb_font_t      *font,
199 				 void           *font_data HB_UNUSED,
200 				 hb_codepoint_t  glyph HB_UNUSED,
201 				 void           *user_data HB_UNUSED)
202 {
203   return font->x_scale;
204 }
205 
206 static hb_position_t
hb_font_get_glyph_h_advance_default(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)207 hb_font_get_glyph_h_advance_default (hb_font_t      *font,
208 				     void           *font_data HB_UNUSED,
209 				     hb_codepoint_t  glyph,
210 				     void           *user_data HB_UNUSED)
211 {
212   if (font->has_glyph_h_advances_func_set ())
213   {
214     hb_position_t ret;
215     font->get_glyph_h_advances (1, &glyph, 0, &ret, 0);
216     return ret;
217   }
218   return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
219 }
220 
221 static hb_position_t
hb_font_get_glyph_v_advance_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph HB_UNUSED,void * user_data HB_UNUSED)222 hb_font_get_glyph_v_advance_nil (hb_font_t      *font,
223 				 void           *font_data HB_UNUSED,
224 				 hb_codepoint_t  glyph HB_UNUSED,
225 				 void           *user_data HB_UNUSED)
226 {
227   /* TODO use font_extents.ascender+descender */
228   return font->y_scale;
229 }
230 
231 static hb_position_t
hb_font_get_glyph_v_advance_default(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)232 hb_font_get_glyph_v_advance_default (hb_font_t      *font,
233 				     void           *font_data HB_UNUSED,
234 				     hb_codepoint_t  glyph,
235 				     void           *user_data HB_UNUSED)
236 {
237   if (font->has_glyph_v_advances_func_set ())
238   {
239     hb_position_t ret;
240     font->get_glyph_v_advances (1, &glyph, 0, &ret, 0);
241     return ret;
242   }
243   return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
244 }
245 
246 #define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default
247 
248 static void
hb_font_get_glyph_h_advances_default(hb_font_t * font,void * font_data HB_UNUSED,unsigned int count,const hb_codepoint_t * first_glyph,unsigned int glyph_stride,hb_position_t * first_advance,unsigned int advance_stride,void * user_data HB_UNUSED)249 hb_font_get_glyph_h_advances_default (hb_font_t*            font,
250 				      void*                 font_data HB_UNUSED,
251 				      unsigned int          count,
252 				      const hb_codepoint_t *first_glyph,
253 				      unsigned int          glyph_stride,
254 				      hb_position_t        *first_advance,
255 				      unsigned int          advance_stride,
256 				      void                 *user_data HB_UNUSED)
257 {
258   if (font->has_glyph_h_advance_func_set ())
259   {
260     for (unsigned int i = 0; i < count; i++)
261     {
262       *first_advance = font->get_glyph_h_advance (*first_glyph);
263       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
264       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
265     }
266     return;
267   }
268 
269   font->parent->get_glyph_h_advances (count,
270 				      first_glyph, glyph_stride,
271 				      first_advance, advance_stride);
272   for (unsigned int i = 0; i < count; i++)
273   {
274     *first_advance = font->parent_scale_x_distance (*first_advance);
275     first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
276   }
277 }
278 
279 #define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default
280 static void
hb_font_get_glyph_v_advances_default(hb_font_t * font,void * font_data HB_UNUSED,unsigned int count,const hb_codepoint_t * first_glyph,unsigned int glyph_stride,hb_position_t * first_advance,unsigned int advance_stride,void * user_data HB_UNUSED)281 hb_font_get_glyph_v_advances_default (hb_font_t*            font,
282 				      void*                 font_data HB_UNUSED,
283 				      unsigned int          count,
284 				      const hb_codepoint_t *first_glyph,
285 				      unsigned int          glyph_stride,
286 				      hb_position_t        *first_advance,
287 				      unsigned int          advance_stride,
288 				      void                 *user_data HB_UNUSED)
289 {
290   if (font->has_glyph_v_advance_func_set ())
291   {
292     for (unsigned int i = 0; i < count; i++)
293     {
294       *first_advance = font->get_glyph_v_advance (*first_glyph);
295       first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
296       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
297     }
298     return;
299   }
300 
301   font->parent->get_glyph_v_advances (count,
302 				      first_glyph, glyph_stride,
303 				      first_advance, advance_stride);
304   for (unsigned int i = 0; i < count; i++)
305   {
306     *first_advance = font->parent_scale_y_distance (*first_advance);
307     first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
308   }
309 }
310 
311 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_UNUSED,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)312 hb_font_get_glyph_h_origin_nil (hb_font_t      *font HB_UNUSED,
313 				void           *font_data HB_UNUSED,
314 				hb_codepoint_t  glyph HB_UNUSED,
315 				hb_position_t  *x,
316 				hb_position_t  *y,
317 				void           *user_data HB_UNUSED)
318 {
319   *x = *y = 0;
320   return true;
321 }
322 
323 static hb_bool_t
hb_font_get_glyph_h_origin_default(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)324 hb_font_get_glyph_h_origin_default (hb_font_t      *font,
325 				    void           *font_data HB_UNUSED,
326 				    hb_codepoint_t  glyph,
327 				    hb_position_t  *x,
328 				    hb_position_t  *y,
329 				    void           *user_data HB_UNUSED)
330 {
331   hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
332   if (ret)
333     font->parent_scale_position (x, y);
334   return ret;
335 }
336 
337 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_UNUSED,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)338 hb_font_get_glyph_v_origin_nil (hb_font_t      *font HB_UNUSED,
339 				void           *font_data HB_UNUSED,
340 				hb_codepoint_t  glyph HB_UNUSED,
341 				hb_position_t  *x,
342 				hb_position_t  *y,
343 				void           *user_data HB_UNUSED)
344 {
345   *x = *y = 0;
346   return false;
347 }
348 
349 static hb_bool_t
hb_font_get_glyph_v_origin_default(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)350 hb_font_get_glyph_v_origin_default (hb_font_t      *font,
351 				    void           *font_data HB_UNUSED,
352 				    hb_codepoint_t  glyph,
353 				    hb_position_t  *x,
354 				    hb_position_t  *y,
355 				    void           *user_data HB_UNUSED)
356 {
357   hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
358   if (ret)
359     font->parent_scale_position (x, y);
360   return ret;
361 }
362 
363 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_UNUSED,hb_codepoint_t right_glyph HB_UNUSED,void * user_data HB_UNUSED)364 hb_font_get_glyph_h_kerning_nil (hb_font_t      *font HB_UNUSED,
365 				 void           *font_data HB_UNUSED,
366 				 hb_codepoint_t  left_glyph HB_UNUSED,
367 				 hb_codepoint_t  right_glyph HB_UNUSED,
368 				 void           *user_data HB_UNUSED)
369 {
370   return 0;
371 }
372 
373 static hb_position_t
hb_font_get_glyph_h_kerning_default(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph,void * user_data HB_UNUSED)374 hb_font_get_glyph_h_kerning_default (hb_font_t      *font,
375 				     void           *font_data HB_UNUSED,
376 				     hb_codepoint_t  left_glyph,
377 				     hb_codepoint_t  right_glyph,
378 				     void           *user_data HB_UNUSED)
379 {
380   return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
381 }
382 
383 #ifndef HB_DISABLE_DEPRECATED
384 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_UNUSED,hb_codepoint_t bottom_glyph HB_UNUSED,void * user_data HB_UNUSED)385 hb_font_get_glyph_v_kerning_nil (hb_font_t      *font HB_UNUSED,
386 				 void           *font_data HB_UNUSED,
387 				 hb_codepoint_t  top_glyph HB_UNUSED,
388 				 hb_codepoint_t  bottom_glyph HB_UNUSED,
389 				 void           *user_data HB_UNUSED)
390 {
391   return 0;
392 }
393 
394 static hb_position_t
hb_font_get_glyph_v_kerning_default(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph,void * user_data HB_UNUSED)395 hb_font_get_glyph_v_kerning_default (hb_font_t      *font,
396 				     void           *font_data HB_UNUSED,
397 				     hb_codepoint_t  top_glyph,
398 				     hb_codepoint_t  bottom_glyph,
399 				     void           *user_data HB_UNUSED)
400 {
401   return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
402 }
403 #endif
404 
405 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_UNUSED,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)406 hb_font_get_glyph_extents_nil (hb_font_t          *font HB_UNUSED,
407 			       void               *font_data HB_UNUSED,
408 			       hb_codepoint_t      glyph HB_UNUSED,
409 			       hb_glyph_extents_t *extents,
410 			       void               *user_data HB_UNUSED)
411 {
412   hb_memset (extents, 0, sizeof (*extents));
413   return false;
414 }
415 
416 static hb_bool_t
hb_font_get_glyph_extents_default(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)417 hb_font_get_glyph_extents_default (hb_font_t          *font,
418 				   void               *font_data HB_UNUSED,
419 				   hb_codepoint_t      glyph,
420 				   hb_glyph_extents_t *extents,
421 				   void               *user_data HB_UNUSED)
422 {
423   hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
424   if (ret) {
425     font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
426     font->parent_scale_distance (&extents->width, &extents->height);
427   }
428   return ret;
429 }
430 
431 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 HB_UNUSED,unsigned int point_index HB_UNUSED,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)432 hb_font_get_glyph_contour_point_nil (hb_font_t      *font HB_UNUSED,
433 				     void           *font_data HB_UNUSED,
434 				     hb_codepoint_t  glyph HB_UNUSED,
435 				     unsigned int    point_index HB_UNUSED,
436 				     hb_position_t  *x,
437 				     hb_position_t  *y,
438 				     void           *user_data HB_UNUSED)
439 {
440   *x = *y = 0;
441   return false;
442 }
443 
444 static hb_bool_t
hb_font_get_glyph_contour_point_default(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)445 hb_font_get_glyph_contour_point_default (hb_font_t      *font,
446 					 void           *font_data HB_UNUSED,
447 					 hb_codepoint_t  glyph,
448 					 unsigned int    point_index,
449 					 hb_position_t  *x,
450 					 hb_position_t  *y,
451 					 void           *user_data HB_UNUSED)
452 {
453   hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
454   if (ret)
455     font->parent_scale_position (x, y);
456   return ret;
457 }
458 
459 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 HB_UNUSED,char * name,unsigned int size,void * user_data HB_UNUSED)460 hb_font_get_glyph_name_nil (hb_font_t      *font HB_UNUSED,
461 			    void           *font_data HB_UNUSED,
462 			    hb_codepoint_t  glyph HB_UNUSED,
463 			    char           *name,
464 			    unsigned int    size,
465 			    void           *user_data HB_UNUSED)
466 {
467   if (size) *name = '\0';
468   return false;
469 }
470 
471 static hb_bool_t
hb_font_get_glyph_name_default(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,char * name,unsigned int size,void * user_data HB_UNUSED)472 hb_font_get_glyph_name_default (hb_font_t      *font,
473 				void           *font_data HB_UNUSED,
474 				hb_codepoint_t  glyph,
475 				char           *name,
476 				unsigned int    size,
477 				void           *user_data HB_UNUSED)
478 {
479   return font->parent->get_glyph_name (glyph, name, size);
480 }
481 
482 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 HB_UNUSED,int len HB_UNUSED,hb_codepoint_t * glyph,void * user_data HB_UNUSED)483 hb_font_get_glyph_from_name_nil (hb_font_t      *font HB_UNUSED,
484 				 void           *font_data HB_UNUSED,
485 				 const char     *name HB_UNUSED,
486 				 int             len HB_UNUSED, /* -1 means nul-terminated */
487 				 hb_codepoint_t *glyph,
488 				 void           *user_data HB_UNUSED)
489 {
490   *glyph = 0;
491   return false;
492 }
493 
494 static hb_bool_t
hb_font_get_glyph_from_name_default(hb_font_t * font,void * font_data HB_UNUSED,const char * name,int len,hb_codepoint_t * glyph,void * user_data HB_UNUSED)495 hb_font_get_glyph_from_name_default (hb_font_t      *font,
496 				     void           *font_data HB_UNUSED,
497 				     const char     *name,
498 				     int             len, /* -1 means nul-terminated */
499 				     hb_codepoint_t *glyph,
500 				     void           *user_data HB_UNUSED)
501 {
502   return font->parent->get_glyph_from_name (name, len, glyph);
503 }
504 
505 static void
hb_font_get_glyph_shape_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_draw_funcs_t * draw_funcs,void * draw_data,void * user_data HB_UNUSED)506 hb_font_get_glyph_shape_nil (hb_font_t       *font HB_UNUSED,
507 			     void            *font_data HB_UNUSED,
508 			     hb_codepoint_t   glyph,
509 			     hb_draw_funcs_t *draw_funcs,
510 			     void            *draw_data,
511 			     void            *user_data HB_UNUSED)
512 {
513 }
514 
515 
516 typedef struct hb_font_get_glyph_shape_default_adaptor_t {
517   hb_draw_funcs_t *draw_funcs;
518   void		  *draw_data;
519   float		   x_scale;
520   float		   y_scale;
521   float		   slant;
522 } hb_font_get_glyph_shape_default_adaptor_t;
523 
524 static void
hb_draw_move_to_default(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st,float to_x,float to_y,void * user_data HB_UNUSED)525 hb_draw_move_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED,
526 			 void *draw_data,
527 			 hb_draw_state_t *st,
528 			 float to_x, float to_y,
529 			 void *user_data HB_UNUSED)
530 {
531   hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
532   float x_scale = adaptor->x_scale;
533   float y_scale = adaptor->y_scale;
534   float slant   = adaptor->slant;
535 
536   adaptor->draw_funcs->emit_move_to (adaptor->draw_data, *st,
537 				     x_scale * to_x + slant * to_y, y_scale * to_y);
538 }
539 
540 static void
hb_draw_line_to_default(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st,float to_x,float to_y,void * user_data HB_UNUSED)541 hb_draw_line_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
542 			 hb_draw_state_t *st,
543 			 float to_x, float to_y,
544 			 void *user_data HB_UNUSED)
545 {
546   hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
547   float x_scale = adaptor->x_scale;
548   float y_scale = adaptor->y_scale;
549   float slant   = adaptor->slant;
550 
551   st->current_x = st->current_x * x_scale + st->current_y * slant;
552   st->current_y = st->current_y * y_scale;
553 
554   adaptor->draw_funcs->emit_line_to (adaptor->draw_data, *st,
555 				     x_scale * to_x + slant * to_y, y_scale * to_y);
556 }
557 
558 static void
hb_draw_quadratic_to_default(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st,float control_x,float control_y,float to_x,float to_y,void * user_data HB_UNUSED)559 hb_draw_quadratic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
560 			      hb_draw_state_t *st,
561 			      float control_x, float control_y,
562 			      float to_x, float to_y,
563 			      void *user_data HB_UNUSED)
564 {
565   hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
566   float x_scale = adaptor->x_scale;
567   float y_scale = adaptor->y_scale;
568   float slant   = adaptor->slant;
569 
570   st->current_x = st->current_x * x_scale + st->current_y * slant;
571   st->current_y = st->current_y * y_scale;
572 
573   adaptor->draw_funcs->emit_quadratic_to (adaptor->draw_data, *st,
574 					  x_scale * control_x + slant * control_y, y_scale * control_y,
575 					  x_scale * to_x + slant * to_y, y_scale * to_y);
576 }
577 
578 static void
hb_draw_cubic_to_default(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st,float control1_x,float control1_y,float control2_x,float control2_y,float to_x,float to_y,void * user_data HB_UNUSED)579 hb_draw_cubic_to_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
580 			  hb_draw_state_t *st,
581 			  float control1_x, float control1_y,
582 			  float control2_x, float control2_y,
583 			  float to_x, float to_y,
584 			  void *user_data HB_UNUSED)
585 {
586   hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
587   float x_scale = adaptor->x_scale;
588   float y_scale = adaptor->y_scale;
589   float slant   = adaptor->slant;
590 
591   st->current_x = st->current_x * x_scale + st->current_y * slant;
592   st->current_y = st->current_y * y_scale;
593 
594   adaptor->draw_funcs->emit_cubic_to (adaptor->draw_data, *st,
595 				      x_scale * control1_x + slant * control1_y, y_scale * control1_y,
596 				      x_scale * control2_x + slant * control2_y, y_scale * control2_y,
597 				      x_scale * to_x + slant * to_y, y_scale * to_y);
598 }
599 
600 static void
hb_draw_close_path_default(hb_draw_funcs_t * dfuncs HB_UNUSED,void * draw_data,hb_draw_state_t * st,void * user_data HB_UNUSED)601 hb_draw_close_path_default (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data,
602 			    hb_draw_state_t *st,
603 			    void *user_data HB_UNUSED)
604 {
605   hb_font_get_glyph_shape_default_adaptor_t *adaptor = (hb_font_get_glyph_shape_default_adaptor_t *) draw_data;
606 
607   adaptor->draw_funcs->emit_close_path (adaptor->draw_data, *st);
608 }
609 
610 static const hb_draw_funcs_t _hb_draw_funcs_default = {
611   HB_OBJECT_HEADER_STATIC,
612 
613   {
614 #define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_default,
615     HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
616 #undef HB_DRAW_FUNC_IMPLEMENT
617   }
618 };
619 
620 static void
hb_font_get_glyph_shape_default(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_draw_funcs_t * draw_funcs,void * draw_data,void * user_data HB_UNUSED)621 hb_font_get_glyph_shape_default (hb_font_t       *font,
622 				 void            *font_data HB_UNUSED,
623 				 hb_codepoint_t   glyph,
624 				 hb_draw_funcs_t *draw_funcs,
625 				 void            *draw_data,
626 				 void            *user_data HB_UNUSED)
627 {
628   hb_font_get_glyph_shape_default_adaptor_t adaptor = {
629     draw_funcs,
630     draw_data,
631     font->parent->x_scale ? (float) font->x_scale / (float) font->parent->x_scale : 0.f,
632     font->parent->y_scale ? (float) font->y_scale / (float) font->parent->y_scale : 0.f,
633     font->parent->y_scale ? (font->slant - font->parent->slant) *
634 			    (float) font->x_scale / (float) font->parent->y_scale : 0.f
635   };
636 
637   font->parent->get_glyph_shape (glyph,
638 				 const_cast<hb_draw_funcs_t *> (&_hb_draw_funcs_default),
639 				 &adaptor);
640 }
641 
642 DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
643 {
644   HB_OBJECT_HEADER_STATIC,
645 
646   nullptr,
647   nullptr,
648   {
649     {
650 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
651       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
652 #undef HB_FONT_FUNC_IMPLEMENT
653     }
654   }
655 };
656 
657 static const hb_font_funcs_t _hb_font_funcs_default = {
658   HB_OBJECT_HEADER_STATIC,
659 
660   nullptr,
661   nullptr,
662   {
663     {
664 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default,
665       HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
666 #undef HB_FONT_FUNC_IMPLEMENT
667     }
668   }
669 };
670 
671 
672 /**
673  * hb_font_funcs_create:
674  *
675  * Creates a new #hb_font_funcs_t structure of font functions.
676  *
677  * Return value: (transfer full): The font-functions structure
678  *
679  * Since: 0.9.2
680  **/
681 hb_font_funcs_t *
hb_font_funcs_create()682 hb_font_funcs_create ()
683 {
684   hb_font_funcs_t *ffuncs;
685 
686   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
687     return hb_font_funcs_get_empty ();
688 
689   ffuncs->get = _hb_font_funcs_default.get;
690 
691   return ffuncs;
692 }
693 
694 /**
695  * hb_font_funcs_get_empty:
696  *
697  * Fetches an empty font-functions structure.
698  *
699  * Return value: (transfer full): The font-functions structure
700  *
701  * Since: 0.9.2
702  **/
703 hb_font_funcs_t *
hb_font_funcs_get_empty()704 hb_font_funcs_get_empty ()
705 {
706   return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default);
707 }
708 
709 /**
710  * hb_font_funcs_reference: (skip)
711  * @ffuncs: The font-functions structure
712  *
713  * Increases the reference count on a font-functions structure.
714  *
715  * Return value: The font-functions structure
716  *
717  * Since: 0.9.2
718  **/
719 hb_font_funcs_t *
hb_font_funcs_reference(hb_font_funcs_t * ffuncs)720 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
721 {
722   return hb_object_reference (ffuncs);
723 }
724 
725 /**
726  * hb_font_funcs_destroy: (skip)
727  * @ffuncs: The font-functions structure
728  *
729  * Decreases the reference count on a font-functions structure. When
730  * the reference count reaches zero, the font-functions structure is
731  * destroyed, freeing all memory.
732  *
733  * Since: 0.9.2
734  **/
735 void
hb_font_funcs_destroy(hb_font_funcs_t * ffuncs)736 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
737 {
738   if (!hb_object_destroy (ffuncs)) return;
739 
740   if (ffuncs->destroy)
741   {
742 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy->name) \
743     ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name);
744     HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
745 #undef HB_FONT_FUNC_IMPLEMENT
746   }
747 
748   hb_free (ffuncs->destroy);
749   hb_free (ffuncs->user_data);
750 
751   hb_free (ffuncs);
752 }
753 
754 /**
755  * hb_font_funcs_set_user_data: (skip)
756  * @ffuncs: The font-functions structure
757  * @key: The user-data key to set
758  * @data: A pointer to the user data set
759  * @destroy: (nullable): A callback to call when @data is not needed anymore
760  * @replace: Whether to replace an existing data with the same key
761  *
762  * Attaches a user-data key/data pair to the specified font-functions structure.
763  *
764  * Return value: `true` if success, `false` otherwise
765  *
766  * Since: 0.9.2
767  **/
768 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)769 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
770 			     hb_user_data_key_t *key,
771 			     void *              data,
772 			     hb_destroy_func_t   destroy /* May be NULL. */,
773 			     hb_bool_t           replace)
774 {
775   return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
776 }
777 
778 /**
779  * hb_font_funcs_get_user_data: (skip)
780  * @ffuncs: The font-functions structure
781  * @key: The user-data key to query
782  *
783  * Fetches the user data associated with the specified key,
784  * attached to the specified font-functions structure.
785  *
786  * Return value: (transfer none): A pointer to the user data
787  *
788  * Since: 0.9.2
789  **/
790 void *
hb_font_funcs_get_user_data(const hb_font_funcs_t * ffuncs,hb_user_data_key_t * key)791 hb_font_funcs_get_user_data (const hb_font_funcs_t *ffuncs,
792 			     hb_user_data_key_t    *key)
793 {
794   return hb_object_get_user_data (ffuncs, key);
795 }
796 
797 
798 /**
799  * hb_font_funcs_make_immutable:
800  * @ffuncs: The font-functions structure
801  *
802  * Makes a font-functions structure immutable.
803  *
804  * Since: 0.9.2
805  **/
806 void
hb_font_funcs_make_immutable(hb_font_funcs_t * ffuncs)807 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
808 {
809   if (hb_object_is_immutable (ffuncs))
810     return;
811 
812   hb_object_make_immutable (ffuncs);
813 }
814 
815 /**
816  * hb_font_funcs_is_immutable:
817  * @ffuncs: The font-functions structure
818  *
819  * Tests whether a font-functions structure is immutable.
820  *
821  * Return value: `true` if @ffuncs is immutable, `false` otherwise
822  *
823  * Since: 0.9.2
824  **/
825 hb_bool_t
hb_font_funcs_is_immutable(hb_font_funcs_t * ffuncs)826 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
827 {
828   return hb_object_is_immutable (ffuncs);
829 }
830 
831 
832 static bool
_hb_font_funcs_set_preamble(hb_font_funcs_t * ffuncs,bool func_is_null,void ** user_data,hb_destroy_func_t * destroy)833 _hb_font_funcs_set_preamble (hb_font_funcs_t    *ffuncs,
834 			     bool                func_is_null,
835 			     void              **user_data,
836 			     hb_destroy_func_t  *destroy)
837 {
838   if (hb_object_is_immutable (ffuncs))
839   {
840     if (*destroy)
841       (*destroy) (*user_data);
842     return false;
843   }
844 
845   if (func_is_null)
846   {
847     if (*destroy)
848       (*destroy) (*user_data);
849     *destroy = nullptr;
850     *user_data = nullptr;
851   }
852 
853   return true;
854 }
855 
856 static bool
_hb_font_funcs_set_middle(hb_font_funcs_t * ffuncs,void * user_data,hb_destroy_func_t destroy)857 _hb_font_funcs_set_middle (hb_font_funcs_t   *ffuncs,
858 			   void              *user_data,
859 			   hb_destroy_func_t  destroy)
860 {
861   if (user_data && !ffuncs->user_data)
862   {
863     ffuncs->user_data = (decltype (ffuncs->user_data)) hb_calloc (1, sizeof (*ffuncs->user_data));
864     if (unlikely (!ffuncs->user_data))
865       goto fail;
866   }
867   if (destroy && !ffuncs->destroy)
868   {
869     ffuncs->destroy = (decltype (ffuncs->destroy)) hb_calloc (1, sizeof (*ffuncs->destroy));
870     if (unlikely (!ffuncs->destroy))
871       goto fail;
872   }
873 
874   return true;
875 
876 fail:
877   if (destroy)
878     (destroy) (user_data);
879   return false;
880 }
881 
882 #define HB_FONT_FUNC_IMPLEMENT(name) \
883 									 \
884 void                                                                     \
885 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
886 				 hb_font_get_##name##_func_t  func,      \
887 				 void                        *user_data, \
888 				 hb_destroy_func_t            destroy)   \
889 {                                                                        \
890   if (!_hb_font_funcs_set_preamble (ffuncs, !func, &user_data, &destroy))\
891       return;                                                            \
892 									 \
893   if (ffuncs->destroy && ffuncs->destroy->name)                          \
894     ffuncs->destroy->name (!ffuncs->user_data ? nullptr : ffuncs->user_data->name); \
895                                                                          \
896   if (!_hb_font_funcs_set_middle (ffuncs, user_data, destroy))           \
897       return;                                                            \
898 									 \
899   if (func)                                                              \
900     ffuncs->get.f.name = func;                                           \
901   else                                                                   \
902     ffuncs->get.f.name = hb_font_get_##name##_default;                   \
903 									 \
904   if (ffuncs->user_data)                                                 \
905     ffuncs->user_data->name = user_data;                                 \
906   if (ffuncs->destroy)                                                   \
907     ffuncs->destroy->name = destroy;                                     \
908 }
909 
910 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
911 #undef HB_FONT_FUNC_IMPLEMENT
912 
913 bool
has_func_set(unsigned int i)914 hb_font_t::has_func_set (unsigned int i)
915 {
916   return this->klass->get.array[i] != _hb_font_funcs_default.get.array[i];
917 }
918 
919 bool
has_func(unsigned int i)920 hb_font_t::has_func (unsigned int i)
921 {
922   return has_func_set (i) ||
923 	 (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i));
924 }
925 
926 /* Public getters */
927 
928 /**
929  * hb_font_get_h_extents:
930  * @font: #hb_font_t to work upon
931  * @extents: (out): The font extents retrieved
932  *
933  * Fetches the extents for a specified font, for horizontal
934  * text segments.
935  *
936  * Return value: `true` if data found, `false` otherwise
937  *
938  * Since: 1.1.3
939  **/
940 hb_bool_t
hb_font_get_h_extents(hb_font_t * font,hb_font_extents_t * extents)941 hb_font_get_h_extents (hb_font_t         *font,
942 		       hb_font_extents_t *extents)
943 {
944   return font->get_font_h_extents (extents);
945 }
946 
947 /**
948  * hb_font_get_v_extents:
949  * @font: #hb_font_t to work upon
950  * @extents: (out): The font extents retrieved
951  *
952  * Fetches the extents for a specified font, for vertical
953  * text segments.
954  *
955  * Return value: `true` if data found, `false` otherwise
956  *
957  * Since: 1.1.3
958  **/
959 hb_bool_t
hb_font_get_v_extents(hb_font_t * font,hb_font_extents_t * extents)960 hb_font_get_v_extents (hb_font_t         *font,
961 		       hb_font_extents_t *extents)
962 {
963   return font->get_font_v_extents (extents);
964 }
965 
966 /**
967  * hb_font_get_glyph:
968  * @font: #hb_font_t to work upon
969  * @unicode: The Unicode code point to query
970  * @variation_selector: A variation-selector code point
971  * @glyph: (out): The glyph ID retrieved
972  *
973  * Fetches the glyph ID for a Unicode code point in the specified
974  * font, with an optional variation selector.
975  *
976  * If @variation_selector is 0, calls hb_font_get_nominal_glyph();
977  * otherwise calls hb_font_get_variation_glyph().
978  *
979  * Return value: `true` if data found, `false` otherwise
980  *
981  * Since: 0.9.2
982  **/
983 hb_bool_t
hb_font_get_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph)984 hb_font_get_glyph (hb_font_t      *font,
985 		   hb_codepoint_t  unicode,
986 		   hb_codepoint_t  variation_selector,
987 		   hb_codepoint_t *glyph)
988 {
989   if (unlikely (variation_selector))
990     return font->get_variation_glyph (unicode, variation_selector, glyph);
991   return font->get_nominal_glyph (unicode, glyph);
992 }
993 
994 /**
995  * hb_font_get_nominal_glyph:
996  * @font: #hb_font_t to work upon
997  * @unicode: The Unicode code point to query
998  * @glyph: (out): The glyph ID retrieved
999  *
1000  * Fetches the nominal glyph ID for a Unicode code point in the
1001  * specified font.
1002  *
1003  * This version of the function should not be used to fetch glyph IDs
1004  * for code points modified by variation selectors. For variation-selector
1005  * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph().
1006  *
1007  * Return value: `true` if data found, `false` otherwise
1008  *
1009  * Since: 1.2.3
1010  **/
1011 hb_bool_t
hb_font_get_nominal_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t * glyph)1012 hb_font_get_nominal_glyph (hb_font_t      *font,
1013 			   hb_codepoint_t  unicode,
1014 			   hb_codepoint_t *glyph)
1015 {
1016   return font->get_nominal_glyph (unicode, glyph);
1017 }
1018 
1019 /**
1020  * hb_font_get_nominal_glyphs:
1021  * @font: #hb_font_t to work upon
1022  * @count: number of code points to query
1023  * @first_unicode: The first Unicode code point to query
1024  * @unicode_stride: The stride between successive code points
1025  * @first_glyph: (out): The first glyph ID retrieved
1026  * @glyph_stride: The stride between successive glyph IDs
1027  *
1028  * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph
1029  * IDs must be returned in a #hb_codepoint_t output parameter.
1030  *
1031  * Return value: the number of code points processed
1032  *
1033  * Since: 2.6.3
1034  **/
1035 unsigned int
hb_font_get_nominal_glyphs(hb_font_t * font,unsigned int count,const hb_codepoint_t * first_unicode,unsigned int unicode_stride,hb_codepoint_t * first_glyph,unsigned int glyph_stride)1036 hb_font_get_nominal_glyphs (hb_font_t *font,
1037 			    unsigned int count,
1038 			    const hb_codepoint_t *first_unicode,
1039 			    unsigned int unicode_stride,
1040 			    hb_codepoint_t *first_glyph,
1041 			    unsigned int glyph_stride)
1042 {
1043   return font->get_nominal_glyphs (count,
1044 				   first_unicode, unicode_stride,
1045 				   first_glyph, glyph_stride);
1046 }
1047 
1048 /**
1049  * hb_font_get_variation_glyph:
1050  * @font: #hb_font_t to work upon
1051  * @unicode: The Unicode code point to query
1052  * @variation_selector: The  variation-selector code point to query
1053  * @glyph: (out): The glyph ID retrieved
1054  *
1055  * Fetches the glyph ID for a Unicode code point when followed by
1056  * by the specified variation-selector code point, in the specified
1057  * font.
1058  *
1059  * Return value: `true` if data found, `false` otherwise
1060  *
1061  * Since: 1.2.3
1062  **/
1063 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)1064 hb_font_get_variation_glyph (hb_font_t      *font,
1065 			     hb_codepoint_t  unicode,
1066 			     hb_codepoint_t  variation_selector,
1067 			     hb_codepoint_t *glyph)
1068 {
1069   return font->get_variation_glyph (unicode, variation_selector, glyph);
1070 }
1071 
1072 /**
1073  * hb_font_get_glyph_h_advance:
1074  * @font: #hb_font_t to work upon
1075  * @glyph: The glyph ID to query
1076  *
1077  * Fetches the advance for a glyph ID in the specified font,
1078  * for horizontal text segments.
1079  *
1080  * Return value: The advance of @glyph within @font
1081  *
1082  * Since: 0.9.2
1083  **/
1084 hb_position_t
hb_font_get_glyph_h_advance(hb_font_t * font,hb_codepoint_t glyph)1085 hb_font_get_glyph_h_advance (hb_font_t      *font,
1086 			     hb_codepoint_t  glyph)
1087 {
1088   return font->get_glyph_h_advance (glyph);
1089 }
1090 
1091 /**
1092  * hb_font_get_glyph_v_advance:
1093  * @font: #hb_font_t to work upon
1094  * @glyph: The glyph ID to query
1095  *
1096  * Fetches the advance for a glyph ID in the specified font,
1097  * for vertical text segments.
1098  *
1099  * Return value: The advance of @glyph within @font
1100  *
1101  * Since: 0.9.2
1102  **/
1103 hb_position_t
hb_font_get_glyph_v_advance(hb_font_t * font,hb_codepoint_t glyph)1104 hb_font_get_glyph_v_advance (hb_font_t      *font,
1105 			     hb_codepoint_t  glyph)
1106 {
1107   return font->get_glyph_v_advance (glyph);
1108 }
1109 
1110 /**
1111  * hb_font_get_glyph_h_advances:
1112  * @font: #hb_font_t to work upon
1113  * @count: The number of glyph IDs in the sequence queried
1114  * @first_glyph: The first glyph ID to query
1115  * @glyph_stride: The stride between successive glyph IDs
1116  * @first_advance: (out): The first advance retrieved
1117  * @advance_stride: The stride between successive advances
1118  *
1119  * Fetches the advances for a sequence of glyph IDs in the specified
1120  * font, for horizontal text segments.
1121  *
1122  * Since: 1.8.6
1123  **/
1124 void
hb_font_get_glyph_h_advances(hb_font_t * font,unsigned int count,const hb_codepoint_t * first_glyph,unsigned glyph_stride,hb_position_t * first_advance,unsigned advance_stride)1125 hb_font_get_glyph_h_advances (hb_font_t*            font,
1126 			      unsigned int          count,
1127 			      const hb_codepoint_t *first_glyph,
1128 			      unsigned              glyph_stride,
1129 			      hb_position_t        *first_advance,
1130 			      unsigned              advance_stride)
1131 {
1132   font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
1133 }
1134 /**
1135  * hb_font_get_glyph_v_advances:
1136  * @font: #hb_font_t to work upon
1137  * @count: The number of glyph IDs in the sequence queried
1138  * @first_glyph: The first glyph ID to query
1139  * @glyph_stride: The stride between successive glyph IDs
1140  * @first_advance: (out): The first advance retrieved
1141  * @advance_stride: (out): The stride between successive advances
1142  *
1143  * Fetches the advances for a sequence of glyph IDs in the specified
1144  * font, for vertical text segments.
1145  *
1146  * Since: 1.8.6
1147  **/
1148 void
hb_font_get_glyph_v_advances(hb_font_t * font,unsigned int count,const hb_codepoint_t * first_glyph,unsigned glyph_stride,hb_position_t * first_advance,unsigned advance_stride)1149 hb_font_get_glyph_v_advances (hb_font_t*            font,
1150 			      unsigned int          count,
1151 			      const hb_codepoint_t *first_glyph,
1152 			      unsigned              glyph_stride,
1153 			      hb_position_t        *first_advance,
1154 			      unsigned              advance_stride)
1155 {
1156   font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
1157 }
1158 
1159 /**
1160  * hb_font_get_glyph_h_origin:
1161  * @font: #hb_font_t to work upon
1162  * @glyph: The glyph ID to query
1163  * @x: (out): The X coordinate of the origin
1164  * @y: (out): The Y coordinate of the origin
1165  *
1166  * Fetches the (X,Y) coordinates of the origin for a glyph ID
1167  * in the specified font, for horizontal text segments.
1168  *
1169  * Return value: `true` if data found, `false` otherwise
1170  *
1171  * Since: 0.9.2
1172  **/
1173 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)1174 hb_font_get_glyph_h_origin (hb_font_t      *font,
1175 			    hb_codepoint_t  glyph,
1176 			    hb_position_t  *x,
1177 			    hb_position_t  *y)
1178 {
1179   return font->get_glyph_h_origin (glyph, x, y);
1180 }
1181 
1182 /**
1183  * hb_font_get_glyph_v_origin:
1184  * @font: #hb_font_t to work upon
1185  * @glyph: The glyph ID to query
1186  * @x: (out): The X coordinate of the origin
1187  * @y: (out): The Y coordinate of the origin
1188  *
1189  * Fetches the (X,Y) coordinates of the origin for a glyph ID
1190  * in the specified font, for vertical text segments.
1191  *
1192  * Return value: `true` if data found, `false` otherwise
1193  *
1194  * Since: 0.9.2
1195  **/
1196 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)1197 hb_font_get_glyph_v_origin (hb_font_t      *font,
1198 			    hb_codepoint_t  glyph,
1199 			    hb_position_t  *x,
1200 			    hb_position_t  *y)
1201 {
1202   return font->get_glyph_v_origin (glyph, x, y);
1203 }
1204 
1205 /**
1206  * hb_font_get_glyph_h_kerning:
1207  * @font: #hb_font_t to work upon
1208  * @left_glyph: The glyph ID of the left glyph in the glyph pair
1209  * @right_glyph: The glyph ID of the right glyph in the glyph pair
1210  *
1211  * Fetches the kerning-adjustment value for a glyph-pair in
1212  * the specified font, for horizontal text segments.
1213  *
1214  * <note>It handles legacy kerning only (as returned by the corresponding
1215  * #hb_font_funcs_t function).</note>
1216  *
1217  * Return value: The kerning adjustment value
1218  *
1219  * Since: 0.9.2
1220  **/
1221 hb_position_t
hb_font_get_glyph_h_kerning(hb_font_t * font,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph)1222 hb_font_get_glyph_h_kerning (hb_font_t      *font,
1223 			     hb_codepoint_t  left_glyph,
1224 			     hb_codepoint_t  right_glyph)
1225 {
1226   return font->get_glyph_h_kerning (left_glyph, right_glyph);
1227 }
1228 
1229 #ifndef HB_DISABLE_DEPRECATED
1230 /**
1231  * hb_font_get_glyph_v_kerning:
1232  * @font: #hb_font_t to work upon
1233  * @top_glyph: The glyph ID of the top glyph in the glyph pair
1234  * @bottom_glyph: The glyph ID of the bottom glyph in the glyph pair
1235  *
1236  * Fetches the kerning-adjustment value for a glyph-pair in
1237  * the specified font, for vertical text segments.
1238  *
1239  * <note>It handles legacy kerning only (as returned by the corresponding
1240  * #hb_font_funcs_t function).</note>
1241  *
1242  * Return value: The kerning adjustment value
1243  *
1244  * Since: 0.9.2
1245  * Deprecated: 2.0.0
1246  **/
1247 hb_position_t
hb_font_get_glyph_v_kerning(hb_font_t * font,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph)1248 hb_font_get_glyph_v_kerning (hb_font_t      *font,
1249 			     hb_codepoint_t  top_glyph,
1250 			     hb_codepoint_t  bottom_glyph)
1251 {
1252   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
1253 }
1254 #endif
1255 
1256 /**
1257  * hb_font_get_glyph_extents:
1258  * @font: #hb_font_t to work upon
1259  * @glyph: The glyph ID to query
1260  * @extents: (out): The #hb_glyph_extents_t retrieved
1261  *
1262  * Fetches the #hb_glyph_extents_t data for a glyph ID
1263  * in the specified font.
1264  *
1265  * Return value: `true` if data found, `false` otherwise
1266  *
1267  * Since: 0.9.2
1268  **/
1269 hb_bool_t
hb_font_get_glyph_extents(hb_font_t * font,hb_codepoint_t glyph,hb_glyph_extents_t * extents)1270 hb_font_get_glyph_extents (hb_font_t          *font,
1271 			   hb_codepoint_t      glyph,
1272 			   hb_glyph_extents_t *extents)
1273 {
1274   return font->get_glyph_extents (glyph, extents);
1275 }
1276 
1277 /**
1278  * hb_font_get_glyph_contour_point:
1279  * @font: #hb_font_t to work upon
1280  * @glyph: The glyph ID to query
1281  * @point_index: The contour-point index to query
1282  * @x: (out): The X value retrieved for the contour point
1283  * @y: (out): The Y value retrieved for the contour point
1284  *
1285  * Fetches the (x,y) coordinates of a specified contour-point index
1286  * in the specified glyph, within the specified font.
1287  *
1288  * Return value: `true` if data found, `false` otherwise
1289  *
1290  * Since: 0.9.2
1291  **/
1292 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)1293 hb_font_get_glyph_contour_point (hb_font_t      *font,
1294 				 hb_codepoint_t  glyph,
1295 				 unsigned int    point_index,
1296 				 hb_position_t  *x,
1297 				 hb_position_t  *y)
1298 {
1299   return font->get_glyph_contour_point (glyph, point_index, x, y);
1300 }
1301 
1302 /**
1303  * hb_font_get_glyph_name:
1304  * @font: #hb_font_t to work upon
1305  * @glyph: The glyph ID to query
1306  * @name: (out) (array length=size): Name string retrieved for the glyph ID
1307  * @size: Length of the glyph-name string retrieved
1308  *
1309  * Fetches the glyph-name string for a glyph ID in the specified @font.
1310  *
1311  * Return value: `true` if data found, `false` otherwise
1312  *
1313  * Since: 0.9.2
1314  **/
1315 hb_bool_t
hb_font_get_glyph_name(hb_font_t * font,hb_codepoint_t glyph,char * name,unsigned int size)1316 hb_font_get_glyph_name (hb_font_t      *font,
1317 			hb_codepoint_t  glyph,
1318 			char           *name,
1319 			unsigned int    size)
1320 {
1321   return font->get_glyph_name (glyph, name, size);
1322 }
1323 
1324 /**
1325  * hb_font_get_glyph_from_name:
1326  * @font: #hb_font_t to work upon
1327  * @name: (array length=len): The name string to query
1328  * @len: The length of the name queried
1329  * @glyph: (out): The glyph ID retrieved
1330  *
1331  * Fetches the glyph ID that corresponds to a name string in the specified @font.
1332  *
1333  * <note>Note: @len == -1 means the name string is null-terminated.</note>
1334  *
1335  * Return value: `true` if data found, `false` otherwise
1336  *
1337  * Since: 0.9.2
1338  **/
1339 hb_bool_t
hb_font_get_glyph_from_name(hb_font_t * font,const char * name,int len,hb_codepoint_t * glyph)1340 hb_font_get_glyph_from_name (hb_font_t      *font,
1341 			     const char     *name,
1342 			     int             len, /* -1 means nul-terminated */
1343 			     hb_codepoint_t *glyph)
1344 {
1345   return font->get_glyph_from_name (name, len, glyph);
1346 }
1347 
1348 /**
1349  * hb_font_get_glyph_shape:
1350  * @font: #hb_font_t to work upon
1351  * @glyph: : The glyph ID
1352  * @dfuncs: #hb_draw_funcs_t to draw to
1353  * @draw_data: User data to pass to draw callbacks
1354  *
1355  * Fetches the glyph shape that corresponds to a glyph in the specified @font.
1356  * The shape is returned by way of calls to the callbacks of the @dfuncs
1357  * objects, with @draw_data passed to them.
1358  *
1359  * Since: 4.0.0
1360  **/
1361 void
hb_font_get_glyph_shape(hb_font_t * font,hb_codepoint_t glyph,hb_draw_funcs_t * dfuncs,void * draw_data)1362 hb_font_get_glyph_shape (hb_font_t *font,
1363 			 hb_codepoint_t glyph,
1364 			 hb_draw_funcs_t *dfuncs, void *draw_data)
1365 {
1366   font->get_glyph_shape (glyph, dfuncs, draw_data);
1367 }
1368 
1369 /* A bit higher-level, and with fallback */
1370 
1371 /**
1372  * hb_font_get_extents_for_direction:
1373  * @font: #hb_font_t to work upon
1374  * @direction: The direction of the text segment
1375  * @extents: (out): The #hb_font_extents_t retrieved
1376  *
1377  * Fetches the extents for a font in a text segment of the
1378  * specified direction.
1379  *
1380  * Calls the appropriate direction-specific variant (horizontal
1381  * or vertical) depending on the value of @direction.
1382  *
1383  * Since: 1.1.3
1384  **/
1385 void
hb_font_get_extents_for_direction(hb_font_t * font,hb_direction_t direction,hb_font_extents_t * extents)1386 hb_font_get_extents_for_direction (hb_font_t         *font,
1387 				   hb_direction_t     direction,
1388 				   hb_font_extents_t *extents)
1389 {
1390   font->get_extents_for_direction (direction, extents);
1391 }
1392 /**
1393  * hb_font_get_glyph_advance_for_direction:
1394  * @font: #hb_font_t to work upon
1395  * @glyph: The glyph ID to query
1396  * @direction: The direction of the text segment
1397  * @x: (out): The horizontal advance retrieved
1398  * @y: (out):  The vertical advance retrieved
1399  *
1400  * Fetches the advance for a glyph ID from the specified font,
1401  * in a text segment of the specified direction.
1402  *
1403  * Calls the appropriate direction-specific variant (horizontal
1404  * or vertical) depending on the value of @direction.
1405  *
1406  * Since: 0.9.2
1407  **/
1408 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)1409 hb_font_get_glyph_advance_for_direction (hb_font_t      *font,
1410 					 hb_codepoint_t  glyph,
1411 					 hb_direction_t  direction,
1412 					 hb_position_t  *x,
1413 					 hb_position_t  *y)
1414 {
1415   font->get_glyph_advance_for_direction (glyph, direction, x, y);
1416 }
1417 /**
1418  * hb_font_get_glyph_advances_for_direction:
1419  * @font: #hb_font_t to work upon
1420  * @direction: The direction of the text segment
1421  * @count: The number of glyph IDs in the sequence queried
1422  * @first_glyph: The first glyph ID to query
1423  * @glyph_stride: The stride between successive glyph IDs
1424  * @first_advance: (out): The first advance retrieved
1425  * @advance_stride: (out): The stride between successive advances
1426  *
1427  * Fetches the advances for a sequence of glyph IDs in the specified
1428  * font, in a text segment of the specified direction.
1429  *
1430  * Calls the appropriate direction-specific variant (horizontal
1431  * or vertical) depending on the value of @direction.
1432  *
1433  * Since: 1.8.6
1434  **/
1435 HB_EXTERN void
hb_font_get_glyph_advances_for_direction(hb_font_t * font,hb_direction_t direction,unsigned int count,const hb_codepoint_t * first_glyph,unsigned glyph_stride,hb_position_t * first_advance,unsigned advance_stride)1436 hb_font_get_glyph_advances_for_direction (hb_font_t*            font,
1437 					  hb_direction_t        direction,
1438 					  unsigned int          count,
1439 					  const hb_codepoint_t *first_glyph,
1440 					  unsigned              glyph_stride,
1441 					  hb_position_t        *first_advance,
1442 					  unsigned              advance_stride)
1443 {
1444   font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride);
1445 }
1446 
1447 /**
1448  * hb_font_get_glyph_origin_for_direction:
1449  * @font: #hb_font_t to work upon
1450  * @glyph: The glyph ID to query
1451  * @direction: The direction of the text segment
1452  * @x: (out): The X coordinate retrieved for the origin
1453  * @y: (out): The Y coordinate retrieved for the origin
1454  *
1455  * Fetches the (X,Y) coordinates of the origin for a glyph in
1456  * the specified font.
1457  *
1458  * Calls the appropriate direction-specific variant (horizontal
1459  * or vertical) depending on the value of @direction.
1460  *
1461  * Since: 0.9.2
1462  **/
1463 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)1464 hb_font_get_glyph_origin_for_direction (hb_font_t      *font,
1465 					hb_codepoint_t  glyph,
1466 					hb_direction_t  direction,
1467 					hb_position_t  *x,
1468 					hb_position_t  *y)
1469 {
1470   return font->get_glyph_origin_for_direction (glyph, direction, x, y);
1471 }
1472 
1473 /**
1474  * hb_font_add_glyph_origin_for_direction:
1475  * @font: #hb_font_t to work upon
1476  * @glyph: The glyph ID to query
1477  * @direction: The direction of the text segment
1478  * @x: (inout): Input = The original X coordinate
1479  *     Output = The X coordinate plus the X-coordinate of the origin
1480  * @y: (inout): Input = The original Y coordinate
1481  *     Output = The Y coordinate plus the Y-coordinate of the origin
1482  *
1483  * Adds the origin coordinates to an (X,Y) point coordinate, in
1484  * the specified glyph ID in the specified font.
1485  *
1486  * Calls the appropriate direction-specific variant (horizontal
1487  * or vertical) depending on the value of @direction.
1488  *
1489  * Since: 0.9.2
1490  **/
1491 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)1492 hb_font_add_glyph_origin_for_direction (hb_font_t      *font,
1493 					hb_codepoint_t  glyph,
1494 					hb_direction_t  direction,
1495 					hb_position_t  *x,
1496 					hb_position_t  *y)
1497 {
1498   return font->add_glyph_origin_for_direction (glyph, direction, x, y);
1499 }
1500 
1501 /**
1502  * hb_font_subtract_glyph_origin_for_direction:
1503  * @font: #hb_font_t to work upon
1504  * @glyph: The glyph ID to query
1505  * @direction: The direction of the text segment
1506  * @x: (inout): Input = The original X coordinate
1507  *     Output = The X coordinate minus the X-coordinate of the origin
1508  * @y: (inout): Input = The original Y coordinate
1509  *     Output = The Y coordinate minus the Y-coordinate of the origin
1510  *
1511  * Subtracts the origin coordinates from an (X,Y) point coordinate,
1512  * in the specified glyph ID in the specified font.
1513  *
1514  * Calls the appropriate direction-specific variant (horizontal
1515  * or vertical) depending on the value of @direction.
1516  *
1517  * Since: 0.9.2
1518  **/
1519 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)1520 hb_font_subtract_glyph_origin_for_direction (hb_font_t      *font,
1521 					     hb_codepoint_t  glyph,
1522 					     hb_direction_t  direction,
1523 					     hb_position_t  *x,
1524 					     hb_position_t  *y)
1525 {
1526   return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
1527 }
1528 
1529 /**
1530  * hb_font_get_glyph_kerning_for_direction:
1531  * @font: #hb_font_t to work upon
1532  * @first_glyph: The glyph ID of the first glyph in the glyph pair to query
1533  * @second_glyph: The glyph ID of the second glyph in the glyph pair to query
1534  * @direction: The direction of the text segment
1535  * @x: (out): The horizontal kerning-adjustment value retrieved
1536  * @y: (out): The vertical kerning-adjustment value retrieved
1537  *
1538  * Fetches the kerning-adjustment value for a glyph-pair in the specified font.
1539  *
1540  * Calls the appropriate direction-specific variant (horizontal
1541  * or vertical) depending on the value of @direction.
1542  *
1543  * Since: 0.9.2
1544  **/
1545 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)1546 hb_font_get_glyph_kerning_for_direction (hb_font_t      *font,
1547 					 hb_codepoint_t  first_glyph,
1548 					 hb_codepoint_t  second_glyph,
1549 					 hb_direction_t  direction,
1550 					 hb_position_t  *x,
1551 					 hb_position_t  *y)
1552 {
1553   return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
1554 }
1555 
1556 /**
1557  * hb_font_get_glyph_extents_for_origin:
1558  * @font: #hb_font_t to work upon
1559  * @glyph: The glyph ID to query
1560  * @direction: The direction of the text segment
1561  * @extents: (out): The #hb_glyph_extents_t retrieved
1562  *
1563  * Fetches the #hb_glyph_extents_t data for a glyph ID
1564  * in the specified font, with respect to the origin in
1565  * a text segment in the specified direction.
1566  *
1567  * Calls the appropriate direction-specific variant (horizontal
1568  * or vertical) depending on the value of @direction.
1569  *
1570  * Return value: `true` if data found, `false` otherwise
1571  *
1572  * Since: 0.9.2
1573  **/
1574 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)1575 hb_font_get_glyph_extents_for_origin (hb_font_t          *font,
1576 				      hb_codepoint_t      glyph,
1577 				      hb_direction_t      direction,
1578 				      hb_glyph_extents_t *extents)
1579 {
1580   return font->get_glyph_extents_for_origin (glyph, direction, extents);
1581 }
1582 
1583 /**
1584  * hb_font_get_glyph_contour_point_for_origin:
1585  * @font: #hb_font_t to work upon
1586  * @glyph: The glyph ID to query
1587  * @point_index: The contour-point index to query
1588  * @direction: The direction of the text segment
1589  * @x: (out): The X value retrieved for the contour point
1590  * @y: (out): The Y value retrieved for the contour point
1591  *
1592  * Fetches the (X,Y) coordinates of a specified contour-point index
1593  * in the specified glyph ID in the specified font, with respect
1594  * to the origin in a text segment in the specified direction.
1595  *
1596  * Calls the appropriate direction-specific variant (horizontal
1597  * or vertical) depending on the value of @direction.
1598  *
1599  * Return value: `true` if data found, `false` otherwise
1600  *
1601  * Since: 0.9.2
1602  **/
1603 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)1604 hb_font_get_glyph_contour_point_for_origin (hb_font_t      *font,
1605 					    hb_codepoint_t  glyph,
1606 					    unsigned int    point_index,
1607 					    hb_direction_t  direction,
1608 					    hb_position_t  *x,
1609 					    hb_position_t  *y)
1610 {
1611   return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
1612 }
1613 
1614 /**
1615  * hb_font_glyph_to_string:
1616  * @font: #hb_font_t to work upon
1617  * @glyph: The glyph ID to query
1618  * @s: (out) (array length=size): The string containing the glyph name
1619  * @size: Length of string @s
1620  *
1621  * Fetches the name of the specified glyph ID in @font and returns
1622  * it in string @s.
1623  *
1624  * If the glyph ID has no name in @font, a string of the form `gidDDD` is
1625  * generated, with `DDD` being the glyph ID.
1626  *
1627  * Since: 0.9.2
1628  **/
1629 void
hb_font_glyph_to_string(hb_font_t * font,hb_codepoint_t glyph,char * s,unsigned int size)1630 hb_font_glyph_to_string (hb_font_t      *font,
1631 			 hb_codepoint_t  glyph,
1632 			 char           *s,
1633 			 unsigned int    size)
1634 {
1635   font->glyph_to_string (glyph, s, size);
1636 }
1637 
1638 /**
1639  * hb_font_glyph_from_string:
1640  * @font: #hb_font_t to work upon
1641  * @s: (array length=len) (element-type uint8_t): string to query
1642  * @len: The length of the string @s
1643  * @glyph: (out): The glyph ID corresponding to the string requested
1644  *
1645  * Fetches the glyph ID from @font that matches the specified string.
1646  * Strings of the format `gidDDD` or `uniUUUU` are parsed automatically.
1647  *
1648  * <note>Note: @len == -1 means the string is null-terminated.</note>
1649  *
1650  * Return value: `true` if data found, `false` otherwise
1651  *
1652  * Since: 0.9.2
1653  **/
1654 hb_bool_t
hb_font_glyph_from_string(hb_font_t * font,const char * s,int len,hb_codepoint_t * glyph)1655 hb_font_glyph_from_string (hb_font_t      *font,
1656 			   const char     *s,
1657 			   int             len,
1658 			   hb_codepoint_t *glyph)
1659 {
1660   return font->glyph_from_string (s, len, glyph);
1661 }
1662 
1663 
1664 /*
1665  * hb_font_t
1666  */
1667 
1668 DEFINE_NULL_INSTANCE (hb_font_t) =
1669 {
1670   HB_OBJECT_HEADER_STATIC,
1671 
1672   0, /* serial */
1673   0, /* serial_coords */
1674 
1675   nullptr, /* parent */
1676   const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
1677 
1678   1000, /* x_scale */
1679   1000, /* y_scale */
1680   0., /* slant */
1681   0., /* slant_xy; */
1682   1.f, /* x_multf */
1683   1.f, /* y_multf */
1684   1<<16, /* x_mult */
1685   1<<16, /* y_mult */
1686 
1687   0, /* x_ppem */
1688   0, /* y_ppem */
1689   0, /* ptem */
1690 
1691   0, /* num_coords */
1692   nullptr, /* coords */
1693   nullptr, /* design_coords */
1694 
1695   const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
1696 
1697   /* Zero for the rest is fine. */
1698 };
1699 
1700 
1701 static hb_font_t *
_hb_font_create(hb_face_t * face)1702 _hb_font_create (hb_face_t *face)
1703 {
1704   hb_font_t *font;
1705 
1706   if (unlikely (!face))
1707     face = hb_face_get_empty ();
1708 
1709   if (!(font = hb_object_create<hb_font_t> ()))
1710     return hb_font_get_empty ();
1711 
1712   hb_face_make_immutable (face);
1713   font->parent = hb_font_get_empty ();
1714   font->face = hb_face_reference (face);
1715   font->klass = hb_font_funcs_get_empty ();
1716   font->data.init0 (font);
1717   font->x_scale = font->y_scale = face->get_upem ();
1718   font->x_multf = font->y_multf = 1.f;
1719   font->x_mult = font->y_mult = 1 << 16;
1720 
1721   return font;
1722 }
1723 
1724 /**
1725  * hb_font_create:
1726  * @face: a face.
1727  *
1728  * Constructs a new font object from the specified face.
1729  *
1730  * <note>Note: If @face's index value (as passed to hb_face_create()
1731  * has non-zero top 16-bits, those bits minus one are passed to
1732  * hb_font_set_var_named_instance(), effectively loading a named-instance
1733  * of a variable font, instead of the default-instance.  This allows
1734  * specifying which named-instance to load by default when creating the
1735  * face.</note>
1736  *
1737  * Return value: (transfer full): The new font object
1738  *
1739  * Since: 0.9.2
1740  **/
1741 hb_font_t *
hb_font_create(hb_face_t * face)1742 hb_font_create (hb_face_t *face)
1743 {
1744   hb_font_t *font = _hb_font_create (face);
1745 
1746 #ifndef HB_NO_OT_FONT
1747   /* Install our in-house, very lightweight, funcs. */
1748   hb_ot_font_set_funcs (font);
1749 #endif
1750 
1751 #ifndef HB_NO_VAR
1752   if (face && face->index >> 16)
1753     hb_font_set_var_named_instance (font, (face->index >> 16) - 1);
1754 #endif
1755 
1756   return font;
1757 }
1758 
1759 static void
_hb_font_adopt_var_coords(hb_font_t * font,int * coords,float * design_coords,unsigned int coords_length)1760 _hb_font_adopt_var_coords (hb_font_t *font,
1761 			   int *coords, /* 2.14 normalized */
1762 			   float *design_coords,
1763 			   unsigned int coords_length)
1764 {
1765   hb_free (font->coords);
1766   hb_free (font->design_coords);
1767 
1768   font->coords = coords;
1769   font->design_coords = design_coords;
1770   font->num_coords = coords_length;
1771 
1772   font->mults_changed (); // Easiest to call this to drop cached data
1773 }
1774 
1775 /**
1776  * hb_font_create_sub_font:
1777  * @parent: The parent font object
1778  *
1779  * Constructs a sub-font font object from the specified @parent font,
1780  * replicating the parent's properties.
1781  *
1782  * Return value: (transfer full): The new sub-font font object
1783  *
1784  * Since: 0.9.2
1785  **/
1786 hb_font_t *
hb_font_create_sub_font(hb_font_t * parent)1787 hb_font_create_sub_font (hb_font_t *parent)
1788 {
1789   if (unlikely (!parent))
1790     parent = hb_font_get_empty ();
1791 
1792   hb_font_t *font = _hb_font_create (parent->face);
1793 
1794   if (unlikely (hb_object_is_immutable (font)))
1795     return font;
1796 
1797   font->parent = hb_font_reference (parent);
1798 
1799   font->x_scale = parent->x_scale;
1800   font->y_scale = parent->y_scale;
1801   font->slant = parent->slant;
1802   font->x_ppem = parent->x_ppem;
1803   font->y_ppem = parent->y_ppem;
1804   font->ptem = parent->ptem;
1805 
1806   unsigned int num_coords = parent->num_coords;
1807   if (num_coords)
1808   {
1809     int *coords = (int *) hb_calloc (num_coords, sizeof (parent->coords[0]));
1810     float *design_coords = (float *) hb_calloc (num_coords, sizeof (parent->design_coords[0]));
1811     if (likely (coords && design_coords))
1812     {
1813       hb_memcpy (coords, parent->coords, num_coords * sizeof (parent->coords[0]));
1814       hb_memcpy (design_coords, parent->design_coords, num_coords * sizeof (parent->design_coords[0]));
1815       _hb_font_adopt_var_coords (font, coords, design_coords, num_coords);
1816     }
1817     else
1818     {
1819       hb_free (coords);
1820       hb_free (design_coords);
1821     }
1822   }
1823 
1824   font->mults_changed ();
1825 
1826   return font;
1827 }
1828 
1829 /**
1830  * hb_font_get_empty:
1831  *
1832  * Fetches the empty font object.
1833  *
1834  * Return value: (transfer full): The empty font object
1835  *
1836  * Since: 0.9.2
1837  **/
1838 hb_font_t *
hb_font_get_empty()1839 hb_font_get_empty ()
1840 {
1841   return const_cast<hb_font_t *> (&Null (hb_font_t));
1842 }
1843 
1844 /**
1845  * hb_font_reference: (skip)
1846  * @font: #hb_font_t to work upon
1847  *
1848  * Increases the reference count on the given font object.
1849  *
1850  * Return value: (transfer full): The @font object
1851  *
1852  * Since: 0.9.2
1853  **/
1854 hb_font_t *
hb_font_reference(hb_font_t * font)1855 hb_font_reference (hb_font_t *font)
1856 {
1857   return hb_object_reference (font);
1858 }
1859 
1860 /**
1861  * hb_font_destroy: (skip)
1862  * @font: #hb_font_t to work upon
1863  *
1864  * Decreases the reference count on the given font object. When the
1865  * reference count reaches zero, the font is destroyed,
1866  * freeing all memory.
1867  *
1868  * Since: 0.9.2
1869  **/
1870 void
hb_font_destroy(hb_font_t * font)1871 hb_font_destroy (hb_font_t *font)
1872 {
1873   if (!hb_object_destroy (font)) return;
1874 
1875   font->data.fini ();
1876 
1877   if (font->destroy)
1878     font->destroy (font->user_data);
1879 
1880   hb_font_destroy (font->parent);
1881   hb_face_destroy (font->face);
1882   hb_font_funcs_destroy (font->klass);
1883 
1884   hb_free (font->coords);
1885   hb_free (font->design_coords);
1886 
1887   hb_free (font);
1888 }
1889 
1890 /**
1891  * hb_font_set_user_data: (skip)
1892  * @font: #hb_font_t to work upon
1893  * @key: The user-data key
1894  * @data: A pointer to the user data
1895  * @destroy: (nullable): A callback to call when @data is not needed anymore
1896  * @replace: Whether to replace an existing data with the same key
1897  *
1898  * Attaches a user-data key/data pair to the specified font object.
1899  *
1900  * Return value: `true` if success, `false` otherwise
1901  *
1902  * Since: 0.9.2
1903  **/
1904 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)1905 hb_font_set_user_data (hb_font_t          *font,
1906 		       hb_user_data_key_t *key,
1907 		       void *              data,
1908 		       hb_destroy_func_t   destroy /* May be NULL. */,
1909 		       hb_bool_t           replace)
1910 {
1911   if (!hb_object_is_immutable (font))
1912     font->serial++;
1913 
1914   return hb_object_set_user_data (font, key, data, destroy, replace);
1915 }
1916 
1917 /**
1918  * hb_font_get_user_data: (skip)
1919  * @font: #hb_font_t to work upon
1920  * @key: The user-data key to query
1921  *
1922  * Fetches the user-data object associated with the specified key,
1923  * attached to the specified font object.
1924  *
1925  * Return value: (transfer none): Pointer to the user data
1926  *
1927  * Since: 0.9.2
1928  **/
1929 void *
hb_font_get_user_data(const hb_font_t * font,hb_user_data_key_t * key)1930 hb_font_get_user_data (const hb_font_t    *font,
1931 		       hb_user_data_key_t *key)
1932 {
1933   return hb_object_get_user_data (font, key);
1934 }
1935 
1936 /**
1937  * hb_font_make_immutable:
1938  * @font: #hb_font_t to work upon
1939  *
1940  * Makes @font immutable.
1941  *
1942  * Since: 0.9.2
1943  **/
1944 void
hb_font_make_immutable(hb_font_t * font)1945 hb_font_make_immutable (hb_font_t *font)
1946 {
1947   if (hb_object_is_immutable (font))
1948     return;
1949 
1950   if (font->parent)
1951     hb_font_make_immutable (font->parent);
1952 
1953   hb_object_make_immutable (font);
1954 }
1955 
1956 /**
1957  * hb_font_is_immutable:
1958  * @font: #hb_font_t to work upon
1959  *
1960  * Tests whether a font object is immutable.
1961  *
1962  * Return value: `true` if @font is immutable, `false` otherwise
1963  *
1964  * Since: 0.9.2
1965  **/
1966 hb_bool_t
hb_font_is_immutable(hb_font_t * font)1967 hb_font_is_immutable (hb_font_t *font)
1968 {
1969   return hb_object_is_immutable (font);
1970 }
1971 
1972 /**
1973  * hb_font_get_serial:
1974  * @font: #hb_font_t to work upon
1975  *
1976  * Returns the internal serial number of the font. The serial
1977  * number is increased every time a setting on the font is
1978  * changed, using a setter function.
1979  *
1980  * Return value: serial number
1981  *
1982  * Since: 4.4.0
1983  **/
1984 unsigned int
hb_font_get_serial(hb_font_t * font)1985 hb_font_get_serial (hb_font_t *font)
1986 {
1987   return font->serial;
1988 }
1989 
1990 /**
1991  * hb_font_changed:
1992  * @font: #hb_font_t to work upon
1993  *
1994  * Notifies the @font that underlying font data has changed.
1995  * This has the effect of increasing the serial as returned
1996  * by hb_font_get_serial(), which invalidates internal caches.
1997  *
1998  * Since: 4.4.0
1999  **/
2000 void
hb_font_changed(hb_font_t * font)2001 hb_font_changed (hb_font_t *font)
2002 {
2003   if (hb_object_is_immutable (font))
2004     return;
2005 
2006   font->serial++;
2007 
2008   font->mults_changed ();
2009 }
2010 
2011 /**
2012  * hb_font_set_parent:
2013  * @font: #hb_font_t to work upon
2014  * @parent: The parent font object to assign
2015  *
2016  * Sets the parent font of @font.
2017  *
2018  * Since: 1.0.5
2019  **/
2020 void
hb_font_set_parent(hb_font_t * font,hb_font_t * parent)2021 hb_font_set_parent (hb_font_t *font,
2022 		    hb_font_t *parent)
2023 {
2024   if (hb_object_is_immutable (font))
2025     return;
2026 
2027   if (parent == font->parent)
2028     return;
2029 
2030   font->serial++;
2031 
2032   if (!parent)
2033     parent = hb_font_get_empty ();
2034 
2035   hb_font_t *old = font->parent;
2036 
2037   font->parent = hb_font_reference (parent);
2038 
2039   hb_font_destroy (old);
2040 }
2041 
2042 /**
2043  * hb_font_get_parent:
2044  * @font: #hb_font_t to work upon
2045  *
2046  * Fetches the parent font of @font.
2047  *
2048  * Return value: (transfer none): The parent font object
2049  *
2050  * Since: 0.9.2
2051  **/
2052 hb_font_t *
hb_font_get_parent(hb_font_t * font)2053 hb_font_get_parent (hb_font_t *font)
2054 {
2055   return font->parent;
2056 }
2057 
2058 /**
2059  * hb_font_set_face:
2060  * @font: #hb_font_t to work upon
2061  * @face: The #hb_face_t to assign
2062  *
2063  * Sets @face as the font-face value of @font.
2064  *
2065  * Since: 1.4.3
2066  **/
2067 void
hb_font_set_face(hb_font_t * font,hb_face_t * face)2068 hb_font_set_face (hb_font_t *font,
2069 		  hb_face_t *face)
2070 {
2071   if (hb_object_is_immutable (font))
2072     return;
2073 
2074   if (face == font->face)
2075     return;
2076 
2077   font->serial++;
2078 
2079   if (unlikely (!face))
2080     face = hb_face_get_empty ();
2081 
2082   hb_face_t *old = font->face;
2083 
2084   hb_face_make_immutable (face);
2085   font->face = hb_face_reference (face);
2086   font->mults_changed ();
2087 
2088   hb_face_destroy (old);
2089 }
2090 
2091 /**
2092  * hb_font_get_face:
2093  * @font: #hb_font_t to work upon
2094  *
2095  * Fetches the face associated with the specified font object.
2096  *
2097  * Return value: (transfer none): The #hb_face_t value
2098  *
2099  * Since: 0.9.2
2100  **/
2101 hb_face_t *
hb_font_get_face(hb_font_t * font)2102 hb_font_get_face (hb_font_t *font)
2103 {
2104   return font->face;
2105 }
2106 
2107 
2108 /**
2109  * hb_font_set_funcs:
2110  * @font: #hb_font_t to work upon
2111  * @klass: (closure font_data) (destroy destroy) (scope notified): The font-functions structure.
2112  * @font_data: Data to attach to @font
2113  * @destroy: (nullable): The function to call when @font_data is not needed anymore
2114  *
2115  * Replaces the font-functions structure attached to a font, updating
2116  * the font's user-data with @font-data and the @destroy callback.
2117  *
2118  * Since: 0.9.2
2119  **/
2120 void
hb_font_set_funcs(hb_font_t * font,hb_font_funcs_t * klass,void * font_data,hb_destroy_func_t destroy)2121 hb_font_set_funcs (hb_font_t         *font,
2122 		   hb_font_funcs_t   *klass,
2123 		   void              *font_data,
2124 		   hb_destroy_func_t  destroy /* May be NULL. */)
2125 {
2126   if (hb_object_is_immutable (font))
2127   {
2128     if (destroy)
2129       destroy (font_data);
2130     return;
2131   }
2132 
2133   font->serial++;
2134 
2135   if (font->destroy)
2136     font->destroy (font->user_data);
2137 
2138   if (!klass)
2139     klass = hb_font_funcs_get_empty ();
2140 
2141   hb_font_funcs_reference (klass);
2142   hb_font_funcs_destroy (font->klass);
2143   font->klass = klass;
2144   font->user_data = font_data;
2145   font->destroy = destroy;
2146 }
2147 
2148 /**
2149  * hb_font_set_funcs_data:
2150  * @font: #hb_font_t to work upon
2151  * @font_data: (destroy destroy) (scope notified): Data to attach to @font
2152  * @destroy: (nullable): The function to call when @font_data is not needed anymore
2153  *
2154  * Replaces the user data attached to a font, updating the font's
2155  * @destroy callback.
2156  *
2157  * Since: 0.9.2
2158  **/
2159 void
hb_font_set_funcs_data(hb_font_t * font,void * font_data,hb_destroy_func_t destroy)2160 hb_font_set_funcs_data (hb_font_t         *font,
2161 		        void              *font_data,
2162 		        hb_destroy_func_t  destroy /* May be NULL. */)
2163 {
2164   /* Destroy user_data? */
2165   if (hb_object_is_immutable (font))
2166   {
2167     if (destroy)
2168       destroy (font_data);
2169     return;
2170   }
2171 
2172   font->serial++;
2173 
2174   if (font->destroy)
2175     font->destroy (font->user_data);
2176 
2177   font->user_data = font_data;
2178   font->destroy = destroy;
2179 }
2180 
2181 
2182 /**
2183  * hb_font_set_scale:
2184  * @font: #hb_font_t to work upon
2185  * @x_scale: Horizontal scale value to assign
2186  * @y_scale: Vertical scale value to assign
2187  *
2188  * Sets the horizontal and vertical scale of a font.
2189  *
2190  * Since: 0.9.2
2191  **/
2192 void
hb_font_set_scale(hb_font_t * font,int x_scale,int y_scale)2193 hb_font_set_scale (hb_font_t *font,
2194 		   int        x_scale,
2195 		   int        y_scale)
2196 {
2197   if (hb_object_is_immutable (font))
2198     return;
2199 
2200   if (font->x_scale == x_scale && font->y_scale == y_scale)
2201     return;
2202 
2203   font->serial++;
2204 
2205   font->x_scale = x_scale;
2206   font->y_scale = y_scale;
2207   font->mults_changed ();
2208 }
2209 
2210 /**
2211  * hb_font_get_scale:
2212  * @font: #hb_font_t to work upon
2213  * @x_scale: (out): Horizontal scale value
2214  * @y_scale: (out): Vertical scale value
2215  *
2216  * Fetches the horizontal and vertical scale of a font.
2217  *
2218  * Since: 0.9.2
2219  **/
2220 void
hb_font_get_scale(hb_font_t * font,int * x_scale,int * y_scale)2221 hb_font_get_scale (hb_font_t *font,
2222 		   int       *x_scale,
2223 		   int       *y_scale)
2224 {
2225   if (x_scale) *x_scale = font->x_scale;
2226   if (y_scale) *y_scale = font->y_scale;
2227 }
2228 
2229 /**
2230  * hb_font_set_ppem:
2231  * @font: #hb_font_t to work upon
2232  * @x_ppem: Horizontal ppem value to assign
2233  * @y_ppem: Vertical ppem value to assign
2234  *
2235  * Sets the horizontal and vertical pixels-per-em (ppem) of a font.
2236  *
2237  * Since: 0.9.2
2238  **/
2239 void
hb_font_set_ppem(hb_font_t * font,unsigned int x_ppem,unsigned int y_ppem)2240 hb_font_set_ppem (hb_font_t    *font,
2241 		  unsigned int  x_ppem,
2242 		  unsigned int  y_ppem)
2243 {
2244   if (hb_object_is_immutable (font))
2245     return;
2246 
2247   if (font->x_ppem == x_ppem && font->y_ppem == y_ppem)
2248     return;
2249 
2250   font->serial++;
2251 
2252   font->x_ppem = x_ppem;
2253   font->y_ppem = y_ppem;
2254 }
2255 
2256 /**
2257  * hb_font_get_ppem:
2258  * @font: #hb_font_t to work upon
2259  * @x_ppem: (out): Horizontal ppem value
2260  * @y_ppem: (out): Vertical ppem value
2261  *
2262  * Fetches the horizontal and vertical points-per-em (ppem) of a font.
2263  *
2264  * Since: 0.9.2
2265  **/
2266 void
hb_font_get_ppem(hb_font_t * font,unsigned int * x_ppem,unsigned int * y_ppem)2267 hb_font_get_ppem (hb_font_t    *font,
2268 		  unsigned int *x_ppem,
2269 		  unsigned int *y_ppem)
2270 {
2271   if (x_ppem) *x_ppem = font->x_ppem;
2272   if (y_ppem) *y_ppem = font->y_ppem;
2273 }
2274 
2275 /**
2276  * hb_font_set_ptem:
2277  * @font: #hb_font_t to work upon
2278  * @ptem: font size in points.
2279  *
2280  * Sets the "point size" of a font. Set to zero to unset.
2281  * Used in CoreText to implement optical sizing.
2282  *
2283  * <note>Note: There are 72 points in an inch.</note>
2284  *
2285  * Since: 1.6.0
2286  **/
2287 void
hb_font_set_ptem(hb_font_t * font,float ptem)2288 hb_font_set_ptem (hb_font_t *font,
2289 		  float      ptem)
2290 {
2291   if (hb_object_is_immutable (font))
2292     return;
2293 
2294   if (font->ptem == ptem)
2295     return;
2296 
2297   font->serial++;
2298 
2299   font->ptem = ptem;
2300 }
2301 
2302 /**
2303  * hb_font_get_ptem:
2304  * @font: #hb_font_t to work upon
2305  *
2306  * Fetches the "point size" of a font. Used in CoreText to
2307  * implement optical sizing.
2308  *
2309  * Return value: Point size.  A value of zero means "not set."
2310  *
2311  * Since: 1.6.0
2312  **/
2313 float
hb_font_get_ptem(hb_font_t * font)2314 hb_font_get_ptem (hb_font_t *font)
2315 {
2316   return font->ptem;
2317 }
2318 
2319 /**
2320  * hb_font_set_synthetic_slant:
2321  * @font: #hb_font_t to work upon
2322  * @slant: synthetic slant value.
2323  *
2324  * Sets the "synthetic slant" of a font.  By default is zero.
2325  * Synthetic slant is the graphical skew applied to the font
2326  * at rendering time.
2327  *
2328  * HarfBuzz needs to know this value to adjust shaping results,
2329  * metrics, and style values to match the slanted rendering.
2330  *
2331  * <note>Note: The glyph shape fetched via the
2332  * hb_font_get_glyph_shape() is slanted to reflect this value
2333  * as well.</note>
2334  *
2335  * <note>Note: The slant value is a ratio.  For example, a
2336  * 20% slant would be represented as a 0.2 value.</note>
2337  *
2338  * Since: 3.3.0
2339  **/
2340 HB_EXTERN void
hb_font_set_synthetic_slant(hb_font_t * font,float slant)2341 hb_font_set_synthetic_slant (hb_font_t *font, float slant)
2342 {
2343   if (hb_object_is_immutable (font))
2344     return;
2345 
2346   if (font->slant == slant)
2347     return;
2348 
2349   font->serial++;
2350 
2351   font->slant = slant;
2352   font->mults_changed ();
2353 }
2354 
2355 /**
2356  * hb_font_get_synthetic_slant:
2357  * @font: #hb_font_t to work upon
2358  *
2359  * Fetches the "synthetic slant" of a font.
2360  *
2361  * Return value: Synthetic slant.  By default is zero.
2362  *
2363  * Since: 3.3.0
2364  **/
2365 HB_EXTERN float
hb_font_get_synthetic_slant(hb_font_t * font)2366 hb_font_get_synthetic_slant (hb_font_t *font)
2367 {
2368   return font->slant;
2369 }
2370 
2371 #ifndef HB_NO_VAR
2372 /*
2373  * Variations
2374  */
2375 
2376 /**
2377  * hb_font_set_variations:
2378  * @font: #hb_font_t to work upon
2379  * @variations: (array length=variations_length): Array of variation settings to apply
2380  * @variations_length: Number of variations to apply
2381  *
2382  * Applies a list of font-variation settings to a font.
2383  *
2384  * Note that this overrides all existing variations set on @font.
2385  * Axes not included in @variations will be effectively set to their
2386  * default values.
2387  *
2388  * Since: 1.4.2
2389  */
2390 void
hb_font_set_variations(hb_font_t * font,const hb_variation_t * variations,unsigned int variations_length)2391 hb_font_set_variations (hb_font_t            *font,
2392 			const hb_variation_t *variations,
2393 			unsigned int          variations_length)
2394 {
2395   if (hb_object_is_immutable (font))
2396     return;
2397 
2398   font->serial_coords = ++font->serial;
2399 
2400   if (!variations_length)
2401   {
2402     hb_font_set_var_coords_normalized (font, nullptr, 0);
2403     return;
2404   }
2405 
2406   const OT::fvar &fvar = *font->face->table.fvar;
2407   auto axes = fvar.get_axes ();
2408   const unsigned coords_length = axes.length;
2409 
2410   int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
2411   float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
2412 
2413   if (unlikely (coords_length && !(normalized && design_coords)))
2414   {
2415     hb_free (normalized);
2416     hb_free (design_coords);
2417     return;
2418   }
2419 
2420   /* Initialize design coords to default from fvar. */
2421   for (unsigned int i = 0; i < coords_length; i++)
2422     design_coords[i] = axes[i].get_default ();
2423 
2424   for (unsigned int i = 0; i < variations_length; i++)
2425   {
2426     const auto tag = variations[i].tag;
2427     const auto v = variations[i].value;
2428     for (unsigned axis_index = 0; axis_index < coords_length; axis_index++)
2429       if (axes[axis_index].axisTag == tag)
2430       {
2431 	design_coords[axis_index] = v;
2432 	normalized[axis_index] = fvar.normalize_axis_value (axis_index, v);
2433       }
2434   }
2435   font->face->table.avar->map_coords (normalized, coords_length);
2436 
2437   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
2438 }
2439 
2440 /**
2441  * hb_font_set_var_coords_design:
2442  * @font: #hb_font_t to work upon
2443  * @coords: (array length=coords_length): Array of variation coordinates to apply
2444  * @coords_length: Number of coordinates to apply
2445  *
2446  * Applies a list of variation coordinates (in design-space units)
2447  * to a font.
2448  *
2449  * Note that this overrides all existing variations set on @font.
2450  * Axes not included in @coords will be effectively set to their
2451  * default values.
2452  *
2453  * Since: 1.4.2
2454  */
2455 void
hb_font_set_var_coords_design(hb_font_t * font,const float * coords,unsigned int coords_length)2456 hb_font_set_var_coords_design (hb_font_t    *font,
2457 			       const float  *coords,
2458 			       unsigned int  coords_length)
2459 {
2460   if (hb_object_is_immutable (font))
2461     return;
2462 
2463   font->serial_coords = ++font->serial;
2464 
2465   int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
2466   float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
2467 
2468   if (unlikely (coords_length && !(normalized && design_coords)))
2469   {
2470     hb_free (normalized);
2471     hb_free (design_coords);
2472     return;
2473   }
2474 
2475   if (coords_length)
2476     hb_memcpy (design_coords, coords, coords_length * sizeof (font->design_coords[0]));
2477 
2478   hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
2479   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
2480 }
2481 
2482 /**
2483  * hb_font_set_var_named_instance:
2484  * @font: a font.
2485  * @instance_index: named instance index.
2486  *
2487  * Sets design coords of a font from a named instance index.
2488  *
2489  * Since: 2.6.0
2490  */
2491 void
hb_font_set_var_named_instance(hb_font_t * font,unsigned instance_index)2492 hb_font_set_var_named_instance (hb_font_t *font,
2493 				unsigned instance_index)
2494 {
2495   if (hb_object_is_immutable (font))
2496     return;
2497 
2498   font->serial_coords = ++font->serial;
2499 
2500   unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr);
2501 
2502   float *coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
2503   if (unlikely (coords_length && !coords))
2504     return;
2505 
2506   hb_ot_var_named_instance_get_design_coords (font->face, instance_index, &coords_length, coords);
2507   hb_font_set_var_coords_design (font, coords, coords_length);
2508   hb_free (coords);
2509 }
2510 
2511 /**
2512  * hb_font_set_var_coords_normalized:
2513  * @font: #hb_font_t to work upon
2514  * @coords: (array length=coords_length): Array of variation coordinates to apply
2515  * @coords_length: Number of coordinates to apply
2516  *
2517  * Applies a list of variation coordinates (in normalized units)
2518  * to a font.
2519  *
2520  * Note that this overrides all existing variations set on @font.
2521  * Axes not included in @coords will be effectively set to their
2522  * default values.
2523  *
2524  * <note>Note: Coordinates should be normalized to 2.14.</note>
2525  *
2526  * Since: 1.4.2
2527  */
2528 void
hb_font_set_var_coords_normalized(hb_font_t * font,const int * coords,unsigned int coords_length)2529 hb_font_set_var_coords_normalized (hb_font_t    *font,
2530 				   const int    *coords, /* 2.14 normalized */
2531 				   unsigned int  coords_length)
2532 {
2533   if (hb_object_is_immutable (font))
2534     return;
2535 
2536   font->serial_coords = ++font->serial;
2537 
2538   int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
2539   int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
2540   float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr;
2541 
2542   if (unlikely (coords_length && !(copy && unmapped && design_coords)))
2543   {
2544     hb_free (copy);
2545     hb_free (unmapped);
2546     hb_free (design_coords);
2547     return;
2548   }
2549 
2550   if (coords_length)
2551   {
2552     hb_memcpy (copy, coords, coords_length * sizeof (coords[0]));
2553     hb_memcpy (unmapped, coords, coords_length * sizeof (coords[0]));
2554   }
2555 
2556   /* Best effort design coords simulation */
2557   font->face->table.avar->unmap_coords (unmapped, coords_length);
2558   for (unsigned int i = 0; i < coords_length; ++i)
2559     design_coords[i] = font->face->table.fvar->unnormalize_axis_value (i, unmapped[i]);
2560   hb_free (unmapped);
2561 
2562   _hb_font_adopt_var_coords (font, copy, design_coords, coords_length);
2563 }
2564 
2565 /**
2566  * hb_font_get_var_coords_normalized:
2567  * @font: #hb_font_t to work upon
2568  * @length: (out): Number of coordinates retrieved
2569  *
2570  * Fetches the list of normalized variation coordinates currently
2571  * set on a font.
2572  *
2573  * Note that this returned array may only contain values for some
2574  * (or none) of the axes; omitted axes effectively have zero values.
2575  *
2576  * Return value is valid as long as variation coordinates of the font
2577  * are not modified.
2578  *
2579  * Return value: coordinates array
2580  *
2581  * Since: 1.4.2
2582  */
2583 const int *
hb_font_get_var_coords_normalized(hb_font_t * font,unsigned int * length)2584 hb_font_get_var_coords_normalized (hb_font_t    *font,
2585 				   unsigned int *length)
2586 {
2587   if (length)
2588     *length = font->num_coords;
2589 
2590   return font->coords;
2591 }
2592 
2593 /**
2594  * hb_font_get_var_coords_design:
2595  * @font: #hb_font_t to work upon
2596  * @length: (out): Number of coordinates retrieved
2597  *
2598  * Fetches the list of variation coordinates (in design-space units) currently
2599  * set on a font.
2600  *
2601  * Note that this returned array may only contain values for some
2602  * (or none) of the axes; omitted axes effectively have their default
2603  * values.
2604  *
2605  * Return value is valid as long as variation coordinates of the font
2606  * are not modified.
2607  *
2608  * Return value: coordinates array
2609  *
2610  * Since: 3.3.0
2611  */
2612 const float *
hb_font_get_var_coords_design(hb_font_t * font,unsigned int * length)2613 hb_font_get_var_coords_design (hb_font_t *font,
2614 			       unsigned int *length)
2615 {
2616   if (length)
2617     *length = font->num_coords;
2618 
2619   return font->design_coords;
2620 }
2621 #endif
2622 
2623 #ifndef HB_DISABLE_DEPRECATED
2624 /*
2625  * Deprecated get_glyph_func():
2626  */
2627 
2628 struct hb_trampoline_closure_t
2629 {
2630   void *user_data;
2631   hb_destroy_func_t destroy;
2632   unsigned int ref_count;
2633 };
2634 
2635 template <typename FuncType>
2636 struct hb_trampoline_t
2637 {
2638   hb_trampoline_closure_t closure; /* Must be first. */
2639   FuncType func;
2640 };
2641 
2642 template <typename FuncType>
2643 static hb_trampoline_t<FuncType> *
trampoline_create(FuncType func,void * user_data,hb_destroy_func_t destroy)2644 trampoline_create (FuncType           func,
2645 		   void              *user_data,
2646 		   hb_destroy_func_t  destroy)
2647 {
2648   typedef hb_trampoline_t<FuncType> trampoline_t;
2649 
2650   trampoline_t *trampoline = (trampoline_t *) hb_calloc (1, sizeof (trampoline_t));
2651 
2652   if (unlikely (!trampoline))
2653     return nullptr;
2654 
2655   trampoline->closure.user_data = user_data;
2656   trampoline->closure.destroy = destroy;
2657   trampoline->closure.ref_count = 1;
2658   trampoline->func = func;
2659 
2660   return trampoline;
2661 }
2662 
2663 static void
trampoline_reference(hb_trampoline_closure_t * closure)2664 trampoline_reference (hb_trampoline_closure_t *closure)
2665 {
2666   closure->ref_count++;
2667 }
2668 
2669 static void
trampoline_destroy(void * user_data)2670 trampoline_destroy (void *user_data)
2671 {
2672   hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
2673 
2674   if (--closure->ref_count)
2675     return;
2676 
2677   if (closure->destroy)
2678     closure->destroy (closure->user_data);
2679   hb_free (closure);
2680 }
2681 
2682 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
2683 
2684 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)2685 hb_font_get_nominal_glyph_trampoline (hb_font_t      *font,
2686 				      void           *font_data,
2687 				      hb_codepoint_t  unicode,
2688 				      hb_codepoint_t *glyph,
2689 				      void           *user_data)
2690 {
2691   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
2692   return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
2693 }
2694 
2695 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)2696 hb_font_get_variation_glyph_trampoline (hb_font_t      *font,
2697 					void           *font_data,
2698 					hb_codepoint_t  unicode,
2699 					hb_codepoint_t  variation_selector,
2700 					hb_codepoint_t *glyph,
2701 					void           *user_data)
2702 {
2703   hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
2704   return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
2705 }
2706 
2707 /**
2708  * hb_font_funcs_set_glyph_func:
2709  * @ffuncs: The font-functions structure
2710  * @func: (closure user_data) (destroy destroy) (scope notified): callback function
2711  * @user_data: data to pass to @func
2712  * @destroy: (nullable): function to call when @user_data is not needed anymore
2713  *
2714  * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
2715  * hb_font_funcs_set_variation_glyph_func() instead.
2716  *
2717  * Since: 0.9.2
2718  * Deprecated: 1.2.3
2719  **/
2720 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)2721 hb_font_funcs_set_glyph_func (hb_font_funcs_t          *ffuncs,
2722 			      hb_font_get_glyph_func_t  func,
2723 			      void                     *user_data,
2724 			      hb_destroy_func_t         destroy /* May be NULL. */)
2725 {
2726   if (hb_object_is_immutable (ffuncs))
2727   {
2728     if (destroy)
2729       destroy (user_data);
2730     return;
2731   }
2732 
2733   hb_font_get_glyph_trampoline_t *trampoline;
2734 
2735   trampoline = trampoline_create (func, user_data, destroy);
2736   if (unlikely (!trampoline))
2737   {
2738     if (destroy)
2739       destroy (user_data);
2740     return;
2741   }
2742 
2743   /* Since we pass it to two destroying functions. */
2744   trampoline_reference (&trampoline->closure);
2745 
2746   hb_font_funcs_set_nominal_glyph_func (ffuncs,
2747 					hb_font_get_nominal_glyph_trampoline,
2748 					trampoline,
2749 					trampoline_destroy);
2750 
2751   hb_font_funcs_set_variation_glyph_func (ffuncs,
2752 					  hb_font_get_variation_glyph_trampoline,
2753 					  trampoline,
2754 					  trampoline_destroy);
2755 }
2756 #endif
2757