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