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