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