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