1/*
2 * Copyright © 2009 Red Hat, Inc.
3 * Copyright © 2012 Google, Inc.
4 *
5 * This is part of HarfBuzz, a text shaping library.
6 *
7 * Permission is hereby granted, without written agreement and without
8 * license or royalty fees, to use, copy, modify, and distribute this
9 * software and its documentation for any purpose, provided that the
10 * above copyright notice and the following two paragraphs appear in
11 * all copies of this software.
12 *
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE.
18 *
19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 *
25 * Red Hat Author(s): Behdad Esfahbod
26 * Google Author(s): Behdad Esfahbod
27 */
28
29#include "hb.hh"
30
31#include "hb-font.hh"
32#include "hb-machinery.hh"
33
34
35/*
36 * hb_font_funcs_t
37 */
38
39static hb_bool_t
40hb_font_get_font_h_extents_nil (hb_font_t *font HB_UNUSED,
41 void *font_data HB_UNUSED,
42 hb_font_extents_t *metrics,
43 void *user_data HB_UNUSED)
44{
45 memset (metrics, 0, sizeof (*metrics));
46 return false;
47}
48static hb_bool_t
49hb_font_get_font_h_extents_default (hb_font_t *font,
50 void *font_data HB_UNUSED,
51 hb_font_extents_t *metrics,
52 void *user_data HB_UNUSED)
53{
54 hb_bool_t ret = font->parent->get_font_h_extents (metrics);
55 if (ret) {
56 metrics->ascender = font->parent_scale_y_distance (metrics->ascender);
57 metrics->descender = font->parent_scale_y_distance (metrics->descender);
58 metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap);
59 }
60 return ret;
61}
62
63static hb_bool_t
64hb_font_get_font_v_extents_nil (hb_font_t *font HB_UNUSED,
65 void *font_data HB_UNUSED,
66 hb_font_extents_t *metrics,
67 void *user_data HB_UNUSED)
68{
69 memset (metrics, 0, sizeof (*metrics));
70 return false;
71}
72static hb_bool_t
73hb_font_get_font_v_extents_default (hb_font_t *font,
74 void *font_data HB_UNUSED,
75 hb_font_extents_t *metrics,
76 void *user_data HB_UNUSED)
77{
78 hb_bool_t ret = font->parent->get_font_v_extents (metrics);
79 if (ret) {
80 metrics->ascender = font->parent_scale_x_distance (metrics->ascender);
81 metrics->descender = font->parent_scale_x_distance (metrics->descender);
82 metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap);
83 }
84 return ret;
85}
86
87static hb_bool_t
88hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
89 void *font_data HB_UNUSED,
90 hb_codepoint_t unicode,
91 hb_codepoint_t *glyph,
92 void *user_data HB_UNUSED)
93{
94 *glyph = 0;
95 return false;
96}
97static hb_bool_t
98hb_font_get_nominal_glyph_default (hb_font_t *font,
99 void *font_data HB_UNUSED,
100 hb_codepoint_t unicode,
101 hb_codepoint_t *glyph,
102 void *user_data HB_UNUSED)
103{
104 return font->parent->get_nominal_glyph (unicode, glyph);
105}
106
107static hb_bool_t
108hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
109 void *font_data HB_UNUSED,
110 hb_codepoint_t unicode,
111 hb_codepoint_t variation_selector,
112 hb_codepoint_t *glyph,
113 void *user_data HB_UNUSED)
114{
115 *glyph = 0;
116 return false;
117}
118static hb_bool_t
119hb_font_get_variation_glyph_default (hb_font_t *font,
120 void *font_data HB_UNUSED,
121 hb_codepoint_t unicode,
122 hb_codepoint_t variation_selector,
123 hb_codepoint_t *glyph,
124 void *user_data HB_UNUSED)
125{
126 return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
127}
128
129
130static hb_position_t
131hb_font_get_glyph_h_advance_nil (hb_font_t *font,
132 void *font_data HB_UNUSED,
133 hb_codepoint_t glyph HB_UNUSED,
134 void *user_data HB_UNUSED)
135{
136 return font->x_scale;
137}
138static hb_position_t
139hb_font_get_glyph_h_advance_default (hb_font_t *font,
140 void *font_data HB_UNUSED,
141 hb_codepoint_t glyph,
142 void *user_data HB_UNUSED)
143{
144 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
145}
146
147static hb_position_t
148hb_font_get_glyph_v_advance_nil (hb_font_t *font,
149 void *font_data HB_UNUSED,
150 hb_codepoint_t glyph HB_UNUSED,
151 void *user_data HB_UNUSED)
152{
153 /* TODO use font_extents.ascender+descender */
154 return font->y_scale;
155}
156static hb_position_t
157hb_font_get_glyph_v_advance_default (hb_font_t *font,
158 void *font_data HB_UNUSED,
159 hb_codepoint_t glyph,
160 void *user_data HB_UNUSED)
161{
162 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
163}
164
165#define hb_font_get_glyph_h_advances_nil hb_font_get_glyph_h_advances_default
166static void
167hb_font_get_glyph_h_advances_default (hb_font_t* font,
168 void* font_data HB_UNUSED,
169 unsigned int count,
170 hb_codepoint_t *first_glyph,
171 unsigned int glyph_stride,
172 hb_position_t *first_advance,
173 unsigned int advance_stride,
174 void *user_data HB_UNUSED)
175{
176 if (font->has_glyph_h_advance_func ())
177 {
178 for (unsigned int i = 0; i < count; i++)
179 {
180 *first_advance = font->get_glyph_h_advance (*first_glyph);
181 first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
182 first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
183 }
184 return;
185 }
186
187 font->parent->get_glyph_h_advances (count,
188 first_glyph, glyph_stride,
189 first_advance, advance_stride);
190 for (unsigned int i = 0; i < count; i++)
191 {
192 *first_advance = font->parent_scale_x_distance (*first_advance);
193 first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
194 }
195}
196
197#define hb_font_get_glyph_v_advances_nil hb_font_get_glyph_v_advances_default
198static void
199hb_font_get_glyph_v_advances_default (hb_font_t* font,
200 void* font_data HB_UNUSED,
201 unsigned int count,
202 hb_codepoint_t *first_glyph,
203 unsigned int glyph_stride,
204 hb_position_t *first_advance,
205 unsigned int advance_stride,
206 void *user_data HB_UNUSED)
207{
208 if (font->has_glyph_v_advance_func ())
209 {
210 for (unsigned int i = 0; i < count; i++)
211 {
212 *first_advance = font->get_glyph_v_advance (*first_glyph);
213 first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
214 first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
215 }
216 return;
217 }
218
219 font->parent->get_glyph_v_advances (count,
220 first_glyph, glyph_stride,
221 first_advance, advance_stride);
222 for (unsigned int i = 0; i < count; i++)
223 {
224 *first_advance = font->parent_scale_y_distance (*first_advance);
225 first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
226 }
227}
228
229static hb_bool_t
230hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
231 void *font_data HB_UNUSED,
232 hb_codepoint_t glyph,
233 hb_position_t *x,
234 hb_position_t *y,
235 void *user_data HB_UNUSED)
236{
237 *x = *y = 0;
238 return true;
239}
240static hb_bool_t
241hb_font_get_glyph_h_origin_default (hb_font_t *font,
242 void *font_data HB_UNUSED,
243 hb_codepoint_t glyph,
244 hb_position_t *x,
245 hb_position_t *y,
246 void *user_data HB_UNUSED)
247{
248 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
249 if (ret)
250 font->parent_scale_position (x, y);
251 return ret;
252}
253
254static hb_bool_t
255hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
256 void *font_data HB_UNUSED,
257 hb_codepoint_t glyph,
258 hb_position_t *x,
259 hb_position_t *y,
260 void *user_data HB_UNUSED)
261{
262 *x = *y = 0;
263 return false;
264}
265static hb_bool_t
266hb_font_get_glyph_v_origin_default (hb_font_t *font,
267 void *font_data HB_UNUSED,
268 hb_codepoint_t glyph,
269 hb_position_t *x,
270 hb_position_t *y,
271 void *user_data HB_UNUSED)
272{
273 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
274 if (ret)
275 font->parent_scale_position (x, y);
276 return ret;
277}
278
279static hb_position_t
280hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
281 void *font_data HB_UNUSED,
282 hb_codepoint_t left_glyph,
283 hb_codepoint_t right_glyph,
284 void *user_data HB_UNUSED)
285{
286 return 0;
287}
288static hb_position_t
289hb_font_get_glyph_h_kerning_default (hb_font_t *font,
290 void *font_data HB_UNUSED,
291 hb_codepoint_t left_glyph,
292 hb_codepoint_t right_glyph,
293 void *user_data HB_UNUSED)
294{
295 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
296}
297
298static hb_position_t
299hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
300 void *font_data HB_UNUSED,
301 hb_codepoint_t top_glyph,
302 hb_codepoint_t bottom_glyph,
303 void *user_data HB_UNUSED)
304{
305 return 0;
306}
307static hb_position_t
308hb_font_get_glyph_v_kerning_default (hb_font_t *font,
309 void *font_data HB_UNUSED,
310 hb_codepoint_t top_glyph,
311 hb_codepoint_t bottom_glyph,
312 void *user_data HB_UNUSED)
313{
314 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
315}
316
317static hb_bool_t
318hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
319 void *font_data HB_UNUSED,
320 hb_codepoint_t glyph,
321 hb_glyph_extents_t *extents,
322 void *user_data HB_UNUSED)
323{
324 memset (extents, 0, sizeof (*extents));
325 return false;
326}
327static hb_bool_t
328hb_font_get_glyph_extents_default (hb_font_t *font,
329 void *font_data HB_UNUSED,
330 hb_codepoint_t glyph,
331 hb_glyph_extents_t *extents,
332 void *user_data HB_UNUSED)
333{
334 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
335 if (ret) {
336 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
337 font->parent_scale_distance (&extents->width, &extents->height);
338 }
339 return ret;
340}
341
342static hb_bool_t
343hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
344 void *font_data HB_UNUSED,
345 hb_codepoint_t glyph,
346 unsigned int point_index,
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}
354static hb_bool_t
355hb_font_get_glyph_contour_point_default (hb_font_t *font,
356 void *font_data HB_UNUSED,
357 hb_codepoint_t glyph,
358 unsigned int point_index,
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_contour_point (glyph, point_index, x, y);
364 if (ret)
365 font->parent_scale_position (x, y);
366 return ret;
367}
368
369static hb_bool_t
370hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
371 void *font_data HB_UNUSED,
372 hb_codepoint_t glyph,
373 char *name, unsigned int size,
374 void *user_data HB_UNUSED)
375{
376 if (size) *name = '\0';
377 return false;
378}
379static hb_bool_t
380hb_font_get_glyph_name_default (hb_font_t *font,
381 void *font_data HB_UNUSED,
382 hb_codepoint_t glyph,
383 char *name, unsigned int size,
384 void *user_data HB_UNUSED)
385{
386 return font->parent->get_glyph_name (glyph, name, size);
387}
388
389static hb_bool_t
390hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
391 void *font_data HB_UNUSED,
392 const char *name, int len, /* -1 means nul-terminated */
393 hb_codepoint_t *glyph,
394 void *user_data HB_UNUSED)
395{
396 *glyph = 0;
397 return false;
398}
399static hb_bool_t
400hb_font_get_glyph_from_name_default (hb_font_t *font,
401 void *font_data HB_UNUSED,
402 const char *name, int len, /* -1 means nul-terminated */
403 hb_codepoint_t *glyph,
404 void *user_data HB_UNUSED)
405{
406 return font->parent->get_glyph_from_name (name, len, glyph);
407}
408
409DEFINE_NULL_INSTANCE (hb_font_funcs_t) =
410{
411 HB_OBJECT_HEADER_STATIC,
412
413 true, /* immutable */
414
415 {
416#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
417 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
418#undef HB_FONT_FUNC_IMPLEMENT
419 },
420 {
421#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
422 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
423#undef HB_FONT_FUNC_IMPLEMENT
424 },
425 {
426 {
427#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
428 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
429#undef HB_FONT_FUNC_IMPLEMENT
430 }
431 }
432};
433
434static const hb_font_funcs_t _hb_font_funcs_default = {
435 HB_OBJECT_HEADER_STATIC,
436
437 true, /* immutable */
438
439 {
440#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
441 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
442#undef HB_FONT_FUNC_IMPLEMENT
443 },
444 {
445#define HB_FONT_FUNC_IMPLEMENT(name) nullptr,
446 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
447#undef HB_FONT_FUNC_IMPLEMENT
448 },
449 {
450 {
451#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_default,
452 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
453#undef HB_FONT_FUNC_IMPLEMENT
454 }
455 }
456};
457
458
459/**
460 * hb_font_funcs_create: (Xconstructor)
461 *
462 *
463 *
464 * Return value: (transfer full):
465 *
466 * Since: 0.9.2
467 **/
468hb_font_funcs_t *
469hb_font_funcs_create (void)
470{
471 hb_font_funcs_t *ffuncs;
472
473 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
474 return hb_font_funcs_get_empty ();
475
476 ffuncs->get = _hb_font_funcs_default.get;
477
478 return ffuncs;
479}
480
481/**
482 * hb_font_funcs_get_empty:
483 *
484 *
485 *
486 * Return value: (transfer full):
487 *
488 * Since: 0.9.2
489 **/
490hb_font_funcs_t *
491hb_font_funcs_get_empty (void)
492{
493 return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_default);
494}
495
496/**
497 * hb_font_funcs_reference: (skip)
498 * @ffuncs: font functions.
499 *
500 *
501 *
502 * Return value:
503 *
504 * Since: 0.9.2
505 **/
506hb_font_funcs_t *
507hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
508{
509 return hb_object_reference (ffuncs);
510}
511
512/**
513 * hb_font_funcs_destroy: (skip)
514 * @ffuncs: font functions.
515 *
516 *
517 *
518 * Since: 0.9.2
519 **/
520void
521hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
522{
523 if (!hb_object_destroy (ffuncs)) return;
524
525#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
526 ffuncs->destroy.name (ffuncs->user_data.name);
527 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
528#undef HB_FONT_FUNC_IMPLEMENT
529
530 free (ffuncs);
531}
532
533/**
534 * hb_font_funcs_set_user_data: (skip)
535 * @ffuncs: font functions.
536 * @key:
537 * @data:
538 * @destroy:
539 * @replace:
540 *
541 *
542 *
543 * Return value:
544 *
545 * Since: 0.9.2
546 **/
547hb_bool_t
548hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
549 hb_user_data_key_t *key,
550 void * data,
551 hb_destroy_func_t destroy,
552 hb_bool_t replace)
553{
554 return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
555}
556
557/**
558 * hb_font_funcs_get_user_data: (skip)
559 * @ffuncs: font functions.
560 * @key:
561 *
562 *
563 *
564 * Return value: (transfer none):
565 *
566 * Since: 0.9.2
567 **/
568void *
569hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
570 hb_user_data_key_t *key)
571{
572 return hb_object_get_user_data (ffuncs, key);
573}
574
575
576/**
577 * hb_font_funcs_make_immutable:
578 * @ffuncs: font functions.
579 *
580 *
581 *
582 * Since: 0.9.2
583 **/
584void
585hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
586{
587 if (unlikely (hb_object_is_inert (ffuncs)))
588 return;
589
590 ffuncs->immutable = true;
591}
592
593/**
594 * hb_font_funcs_is_immutable:
595 * @ffuncs: font functions.
596 *
597 *
598 *
599 * Return value:
600 *
601 * Since: 0.9.2
602 **/
603hb_bool_t
604hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
605{
606 return ffuncs->immutable;
607}
608
609
610#define HB_FONT_FUNC_IMPLEMENT(name) \
611 \
612void \
613hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
614 hb_font_get_##name##_func_t func, \
615 void *user_data, \
616 hb_destroy_func_t destroy) \
617{ \
618 if (ffuncs->immutable) { \
619 if (destroy) \
620 destroy (user_data); \
621 return; \
622 } \
623 \
624 if (ffuncs->destroy.name) \
625 ffuncs->destroy.name (ffuncs->user_data.name); \
626 \
627 if (func) { \
628 ffuncs->get.f.name = func; \
629 ffuncs->user_data.name = user_data; \
630 ffuncs->destroy.name = destroy; \
631 } else { \
632 ffuncs->get.f.name = hb_font_get_##name##_default; \
633 ffuncs->user_data.name = nullptr; \
634 ffuncs->destroy.name = nullptr; \
635 } \
636}
637
638HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
639#undef HB_FONT_FUNC_IMPLEMENT
640
641bool
642hb_font_t::has_func (unsigned int i)
643{
644 return (this->klass->get.array[i] != _hb_font_funcs_default.get.array[i]) ||
645 (parent && parent != &_hb_Null_hb_font_t && parent->has_func (i));
646}
647
648/* Public getters */
649
650/**
651 * hb_font_get_h_extents:
652 * @font: a font.
653 * @extents: (out):
654 *
655 *
656 *
657 * Return value:
658 *
659 * Since: 1.1.3
660 **/
661hb_bool_t
662hb_font_get_h_extents (hb_font_t *font,
663 hb_font_extents_t *extents)
664{
665 return font->get_font_h_extents (extents);
666}
667
668/**
669 * hb_font_get_v_extents:
670 * @font: a font.
671 * @extents: (out):
672 *
673 *
674 *
675 * Return value:
676 *
677 * Since: 1.1.3
678 **/
679hb_bool_t
680hb_font_get_v_extents (hb_font_t *font,
681 hb_font_extents_t *extents)
682{
683 return font->get_font_v_extents (extents);
684}
685
686/**
687 * hb_font_get_glyph:
688 * @font: a font.
689 * @unicode:
690 * @variation_selector:
691 * @glyph: (out):
692 *
693 *
694 *
695 * Return value:
696 *
697 * Since: 0.9.2
698 **/
699hb_bool_t
700hb_font_get_glyph (hb_font_t *font,
701 hb_codepoint_t unicode, hb_codepoint_t variation_selector,
702 hb_codepoint_t *glyph)
703{
704 if (unlikely (variation_selector))
705 return font->get_variation_glyph (unicode, variation_selector, glyph);
706 return font->get_nominal_glyph (unicode, glyph);
707}
708
709/**
710 * hb_font_get_nominal_glyph:
711 * @font: a font.
712 * @unicode:
713 * @glyph: (out):
714 *
715 *
716 *
717 * Return value:
718 *
719 * Since: 1.2.3
720 **/
721hb_bool_t
722hb_font_get_nominal_glyph (hb_font_t *font,
723 hb_codepoint_t unicode,
724 hb_codepoint_t *glyph)
725{
726 return font->get_nominal_glyph (unicode, glyph);
727}
728
729/**
730 * hb_font_get_variation_glyph:
731 * @font: a font.
732 * @unicode:
733 * @variation_selector:
734 * @glyph: (out):
735 *
736 *
737 *
738 * Return value:
739 *
740 * Since: 1.2.3
741 **/
742hb_bool_t
743hb_font_get_variation_glyph (hb_font_t *font,
744 hb_codepoint_t unicode, hb_codepoint_t variation_selector,
745 hb_codepoint_t *glyph)
746{
747 return font->get_variation_glyph (unicode, variation_selector, glyph);
748}
749
750/**
751 * hb_font_get_glyph_h_advance:
752 * @font: a font.
753 * @glyph:
754 *
755 *
756 *
757 * Return value:
758 *
759 * Since: 0.9.2
760 **/
761hb_position_t
762hb_font_get_glyph_h_advance (hb_font_t *font,
763 hb_codepoint_t glyph)
764{
765 return font->get_glyph_h_advance (glyph);
766}
767
768/**
769 * hb_font_get_glyph_v_advance:
770 * @font: a font.
771 * @glyph:
772 *
773 *
774 *
775 * Return value:
776 *
777 * Since: 0.9.2
778 **/
779hb_position_t
780hb_font_get_glyph_v_advance (hb_font_t *font,
781 hb_codepoint_t glyph)
782{
783 return font->get_glyph_v_advance (glyph);
784}
785
786/**
787 * hb_font_get_glyph_h_advances:
788 * @font: a font.
789 *
790 *
791 *
792 * Since: 1.8.6
793 **/
794void
795hb_font_get_glyph_h_advances (hb_font_t* font,
796 unsigned count,
797 hb_codepoint_t *first_glyph,
798 unsigned glyph_stride,
799 hb_position_t *first_advance,
800 unsigned advance_stride)
801{
802 font->get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
803}
804/**
805 * hb_font_get_glyph_v_advances:
806 * @font: a font.
807 *
808 *
809 *
810 * Since: 1.8.6
811 **/
812void
813hb_font_get_glyph_v_advances (hb_font_t* font,
814 unsigned count,
815 hb_codepoint_t *first_glyph,
816 unsigned glyph_stride,
817 hb_position_t *first_advance,
818 unsigned advance_stride)
819{
820 font->get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
821}
822
823/**
824 * hb_font_get_glyph_h_origin:
825 * @font: a font.
826 * @glyph:
827 * @x: (out):
828 * @y: (out):
829 *
830 *
831 *
832 * Return value:
833 *
834 * Since: 0.9.2
835 **/
836hb_bool_t
837hb_font_get_glyph_h_origin (hb_font_t *font,
838 hb_codepoint_t glyph,
839 hb_position_t *x, hb_position_t *y)
840{
841 return font->get_glyph_h_origin (glyph, x, y);
842}
843
844/**
845 * hb_font_get_glyph_v_origin:
846 * @font: a font.
847 * @glyph:
848 * @x: (out):
849 * @y: (out):
850 *
851 *
852 *
853 * Return value:
854 *
855 * Since: 0.9.2
856 **/
857hb_bool_t
858hb_font_get_glyph_v_origin (hb_font_t *font,
859 hb_codepoint_t glyph,
860 hb_position_t *x, hb_position_t *y)
861{
862 return font->get_glyph_v_origin (glyph, x, y);
863}
864
865/**
866 * hb_font_get_glyph_h_kerning:
867 * @font: a font.
868 * @left_glyph:
869 * @right_glyph:
870 *
871 *
872 *
873 * Return value:
874 *
875 * Since: 0.9.2
876 **/
877hb_position_t
878hb_font_get_glyph_h_kerning (hb_font_t *font,
879 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
880{
881 return font->get_glyph_h_kerning (left_glyph, right_glyph);
882}
883
884/**
885 * hb_font_get_glyph_v_kerning:
886 * @font: a font.
887 * @top_glyph:
888 * @bottom_glyph:
889 *
890 *
891 *
892 * Return value:
893 *
894 * Since: 0.9.2
895 **/
896hb_position_t
897hb_font_get_glyph_v_kerning (hb_font_t *font,
898 hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
899{
900 return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
901}
902
903/**
904 * hb_font_get_glyph_extents:
905 * @font: a font.
906 * @glyph:
907 * @extents: (out):
908 *
909 *
910 *
911 * Return value:
912 *
913 * Since: 0.9.2
914 **/
915hb_bool_t
916hb_font_get_glyph_extents (hb_font_t *font,
917 hb_codepoint_t glyph,
918 hb_glyph_extents_t *extents)
919{
920 return font->get_glyph_extents (glyph, extents);
921}
922
923/**
924 * hb_font_get_glyph_contour_point:
925 * @font: a font.
926 * @glyph:
927 * @point_index:
928 * @x: (out):
929 * @y: (out):
930 *
931 *
932 *
933 * Return value:
934 *
935 * Since: 0.9.2
936 **/
937hb_bool_t
938hb_font_get_glyph_contour_point (hb_font_t *font,
939 hb_codepoint_t glyph, unsigned int point_index,
940 hb_position_t *x, hb_position_t *y)
941{
942 return font->get_glyph_contour_point (glyph, point_index, x, y);
943}
944
945/**
946 * hb_font_get_glyph_name:
947 * @font: a font.
948 * @glyph:
949 * @name: (array length=size):
950 * @size:
951 *
952 *
953 *
954 * Return value:
955 *
956 * Since: 0.9.2
957 **/
958hb_bool_t
959hb_font_get_glyph_name (hb_font_t *font,
960 hb_codepoint_t glyph,
961 char *name, unsigned int size)
962{
963 return font->get_glyph_name (glyph, name, size);
964}
965
966/**
967 * hb_font_get_glyph_from_name:
968 * @font: a font.
969 * @name: (array length=len):
970 * @len:
971 * @glyph: (out):
972 *
973 *
974 *
975 * Return value:
976 *
977 * Since: 0.9.2
978 **/
979hb_bool_t
980hb_font_get_glyph_from_name (hb_font_t *font,
981 const char *name, int len, /* -1 means nul-terminated */
982 hb_codepoint_t *glyph)
983{
984 return font->get_glyph_from_name (name, len, glyph);
985}
986
987
988/* A bit higher-level, and with fallback */
989
990/**
991 * hb_font_get_extents_for_direction:
992 * @font: a font.
993 * @direction:
994 * @extents:
995 *
996 *
997 *
998 * Since: 1.1.3
999 **/
1000void
1001hb_font_get_extents_for_direction (hb_font_t *font,
1002 hb_direction_t direction,
1003 hb_font_extents_t *extents)
1004{
1005 return font->get_extents_for_direction (direction, extents);
1006}
1007/**
1008 * hb_font_get_glyph_advance_for_direction:
1009 * @font: a font.
1010 * @glyph:
1011 * @direction:
1012 * @x: (out):
1013 * @y: (out):
1014 *
1015 *
1016 *
1017 * Since: 0.9.2
1018 **/
1019void
1020hb_font_get_glyph_advance_for_direction (hb_font_t *font,
1021 hb_codepoint_t glyph,
1022 hb_direction_t direction,
1023 hb_position_t *x, hb_position_t *y)
1024{
1025 return font->get_glyph_advance_for_direction (glyph, direction, x, y);
1026}
1027/**
1028 * hb_font_get_glyph_advances_for_direction:
1029 * @font: a font.
1030 * @direction:
1031 *
1032 *
1033 *
1034 * Since: 1.8.6
1035 **/
1036HB_EXTERN void
1037hb_font_get_glyph_advances_for_direction (hb_font_t* font,
1038 hb_direction_t direction,
1039 unsigned count,
1040 hb_codepoint_t *first_glyph,
1041 unsigned glyph_stride,
1042 hb_position_t *first_advance,
1043 unsigned advance_stride)
1044{
1045 font->get_glyph_advances_for_direction (direction, count, first_glyph, glyph_stride, first_advance, advance_stride);
1046}
1047
1048/**
1049 * hb_font_get_glyph_origin_for_direction:
1050 * @font: a font.
1051 * @glyph:
1052 * @direction:
1053 * @x: (out):
1054 * @y: (out):
1055 *
1056 *
1057 *
1058 * Since: 0.9.2
1059 **/
1060void
1061hb_font_get_glyph_origin_for_direction (hb_font_t *font,
1062 hb_codepoint_t glyph,
1063 hb_direction_t direction,
1064 hb_position_t *x, hb_position_t *y)
1065{
1066 return font->get_glyph_origin_for_direction (glyph, direction, x, y);
1067}
1068
1069/**
1070 * hb_font_add_glyph_origin_for_direction:
1071 * @font: a font.
1072 * @glyph:
1073 * @direction:
1074 * @x: (out):
1075 * @y: (out):
1076 *
1077 *
1078 *
1079 * Since: 0.9.2
1080 **/
1081void
1082hb_font_add_glyph_origin_for_direction (hb_font_t *font,
1083 hb_codepoint_t glyph,
1084 hb_direction_t direction,
1085 hb_position_t *x, hb_position_t *y)
1086{
1087 return font->add_glyph_origin_for_direction (glyph, direction, x, y);
1088}
1089
1090/**
1091 * hb_font_subtract_glyph_origin_for_direction:
1092 * @font: a font.
1093 * @glyph:
1094 * @direction:
1095 * @x: (out):
1096 * @y: (out):
1097 *
1098 *
1099 *
1100 * Since: 0.9.2
1101 **/
1102void
1103hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
1104 hb_codepoint_t glyph,
1105 hb_direction_t direction,
1106 hb_position_t *x, hb_position_t *y)
1107{
1108 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
1109}
1110
1111/**
1112 * hb_font_get_glyph_kerning_for_direction:
1113 * @font: a font.
1114 * @first_glyph:
1115 * @second_glyph:
1116 * @direction:
1117 * @x: (out):
1118 * @y: (out):
1119 *
1120 *
1121 *
1122 * Since: 0.9.2
1123 **/
1124void
1125hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
1126 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
1127 hb_direction_t direction,
1128 hb_position_t *x, hb_position_t *y)
1129{
1130 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
1131}
1132
1133/**
1134 * hb_font_get_glyph_extents_for_origin:
1135 * @font: a font.
1136 * @glyph:
1137 * @direction:
1138 * @extents: (out):
1139 *
1140 *
1141 *
1142 * Return value:
1143 *
1144 * Since: 0.9.2
1145 **/
1146hb_bool_t
1147hb_font_get_glyph_extents_for_origin (hb_font_t *font,
1148 hb_codepoint_t glyph,
1149 hb_direction_t direction,
1150 hb_glyph_extents_t *extents)
1151{
1152 return font->get_glyph_extents_for_origin (glyph, direction, extents);
1153}
1154
1155/**
1156 * hb_font_get_glyph_contour_point_for_origin:
1157 * @font: a font.
1158 * @glyph:
1159 * @point_index:
1160 * @direction:
1161 * @x: (out):
1162 * @y: (out):
1163 *
1164 *
1165 *
1166 * Return value:
1167 *
1168 * Since: 0.9.2
1169 **/
1170hb_bool_t
1171hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
1172 hb_codepoint_t glyph, unsigned int point_index,
1173 hb_direction_t direction,
1174 hb_position_t *x, hb_position_t *y)
1175{
1176 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
1177}
1178
1179/* Generates gidDDD if glyph has no name. */
1180/**
1181 * hb_font_glyph_to_string:
1182 * @font: a font.
1183 * @glyph:
1184 * @s: (array length=size):
1185 * @size:
1186 *
1187 *
1188 *
1189 * Since: 0.9.2
1190 **/
1191void
1192hb_font_glyph_to_string (hb_font_t *font,
1193 hb_codepoint_t glyph,
1194 char *s, unsigned int size)
1195{
1196 font->glyph_to_string (glyph, s, size);
1197}
1198
1199/* Parses gidDDD and uniUUUU strings automatically. */
1200/**
1201 * hb_font_glyph_from_string:
1202 * @font: a font.
1203 * @s: (array length=len) (element-type uint8_t):
1204 * @len:
1205 * @glyph: (out):
1206 *
1207 *
1208 *
1209 * Return value:
1210 *
1211 * Since: 0.9.2
1212 **/
1213hb_bool_t
1214hb_font_glyph_from_string (hb_font_t *font,
1215 const char *s, int len, /* -1 means nul-terminated */
1216 hb_codepoint_t *glyph)
1217{
1218 return font->glyph_from_string (s, len, glyph);
1219}
1220
1221
1222/*
1223 * hb_font_t
1224 */
1225
1226DEFINE_NULL_INSTANCE (hb_font_t) =
1227{
1228 HB_OBJECT_HEADER_STATIC,
1229
1230 true, /* immutable */
1231
1232 nullptr, /* parent */
1233 const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
1234
1235 1000, /* x_scale */
1236 1000, /* y_scale */
1237
1238 0, /* x_ppem */
1239 0, /* y_ppem */
1240 0, /* ptem */
1241
1242 0, /* num_coords */
1243 nullptr, /* coords */
1244
1245 const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t), /* klass */
1246 nullptr, /* user_data */
1247 nullptr, /* destroy */
1248
1249 {
1250#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID),
1251#include "hb-shaper-list.hh"
1252#undef HB_SHAPER_IMPLEMENT
1253 }
1254};
1255
1256
1257/**
1258 * hb_font_create: (Xconstructor)
1259 * @face: a face.
1260 *
1261 *
1262 *
1263 * Return value: (transfer full):
1264 *
1265 * Since: 0.9.2
1266 **/
1267hb_font_t *
1268hb_font_create (hb_face_t *face)
1269{
1270 hb_font_t *font;
1271
1272 if (unlikely (!face))
1273 face = hb_face_get_empty ();
1274 if (!(font = hb_object_create<hb_font_t> ()))
1275 return hb_font_get_empty ();
1276
1277 hb_face_make_immutable (face);
1278 font->parent = hb_font_get_empty ();
1279 font->face = hb_face_reference (face);
1280 font->klass = hb_font_funcs_get_empty ();
1281
1282 font->x_scale = font->y_scale = hb_face_get_upem (face);
1283
1284 return font;
1285}
1286
1287/**
1288 * hb_font_create_sub_font:
1289 * @parent: parent font.
1290 *
1291 *
1292 *
1293 * Return value: (transfer full):
1294 *
1295 * Since: 0.9.2
1296 **/
1297hb_font_t *
1298hb_font_create_sub_font (hb_font_t *parent)
1299{
1300 if (unlikely (!parent))
1301 parent = hb_font_get_empty ();
1302
1303 hb_font_t *font = hb_font_create (parent->face);
1304
1305 if (unlikely (hb_object_is_inert (font)))
1306 return font;
1307
1308 font->parent = hb_font_reference (parent);
1309
1310 font->x_scale = parent->x_scale;
1311 font->y_scale = parent->y_scale;
1312 font->x_ppem = parent->x_ppem;
1313 font->y_ppem = parent->y_ppem;
1314 font->ptem = parent->ptem;
1315
1316 font->num_coords = parent->num_coords;
1317 if (!font->num_coords)
1318 font->coords = nullptr;
1319 else
1320 {
1321 unsigned int size = parent->num_coords * sizeof (parent->coords[0]);
1322 font->coords = (int *) malloc (size);
1323 if (unlikely (!font->coords))
1324 font->num_coords = 0;
1325 else
1326 memcpy (font->coords, parent->coords, size);
1327 }
1328
1329 return font;
1330}
1331
1332/**
1333 * hb_font_get_empty:
1334 *
1335 *
1336 *
1337 * Return value: (transfer full)
1338 *
1339 * Since: 0.9.2
1340 **/
1341hb_font_t *
1342hb_font_get_empty (void)
1343{
1344 return const_cast<hb_font_t *> (&Null(hb_font_t));
1345}
1346
1347/**
1348 * hb_font_reference: (skip)
1349 * @font: a font.
1350 *
1351 *
1352 *
1353 * Return value: (transfer full):
1354 *
1355 * Since: 0.9.2
1356 **/
1357hb_font_t *
1358hb_font_reference (hb_font_t *font)
1359{
1360 return hb_object_reference (font);
1361}
1362
1363/**
1364 * hb_font_destroy: (skip)
1365 * @font: a font.
1366 *
1367 *
1368 *
1369 * Since: 0.9.2
1370 **/
1371void
1372hb_font_destroy (hb_font_t *font)
1373{
1374 if (!hb_object_destroy (font)) return;
1375
1376#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
1377#include "hb-shaper-list.hh"
1378#undef HB_SHAPER_IMPLEMENT
1379
1380 if (font->destroy)
1381 font->destroy (font->user_data);
1382
1383 hb_font_destroy (font->parent);
1384 hb_face_destroy (font->face);
1385 hb_font_funcs_destroy (font->klass);
1386
1387 free (font->coords);
1388
1389 free (font);
1390}
1391
1392/**
1393 * hb_font_set_user_data: (skip)
1394 * @font: a font.
1395 * @key:
1396 * @data:
1397 * @destroy:
1398 * @replace:
1399 *
1400 *
1401 *
1402 * Return value:
1403 *
1404 * Since: 0.9.2
1405 **/
1406hb_bool_t
1407hb_font_set_user_data (hb_font_t *font,
1408 hb_user_data_key_t *key,
1409 void * data,
1410 hb_destroy_func_t destroy,
1411 hb_bool_t replace)
1412{
1413 return hb_object_set_user_data (font, key, data, destroy, replace);
1414}
1415
1416/**
1417 * hb_font_get_user_data: (skip)
1418 * @font: a font.
1419 * @key:
1420 *
1421 *
1422 *
1423 * Return value: (transfer none):
1424 *
1425 * Since: 0.9.2
1426 **/
1427void *
1428hb_font_get_user_data (hb_font_t *font,
1429 hb_user_data_key_t *key)
1430{
1431 return hb_object_get_user_data (font, key);
1432}
1433
1434/**
1435 * hb_font_make_immutable:
1436 * @font: a font.
1437 *
1438 *
1439 *
1440 * Since: 0.9.2
1441 **/
1442void
1443hb_font_make_immutable (hb_font_t *font)
1444{
1445 if (unlikely (hb_object_is_inert (font)))
1446 return;
1447
1448 if (font->parent)
1449 hb_font_make_immutable (font->parent);
1450
1451 font->immutable = true;
1452}
1453
1454/**
1455 * hb_font_is_immutable:
1456 * @font: a font.
1457 *
1458 *
1459 *
1460 * Return value:
1461 *
1462 * Since: 0.9.2
1463 **/
1464hb_bool_t
1465hb_font_is_immutable (hb_font_t *font)
1466{
1467 return font->immutable;
1468}
1469
1470/**
1471 * hb_font_set_parent:
1472 * @font: a font.
1473 * @parent: new parent.
1474 *
1475 * Sets parent font of @font.
1476 *
1477 * Since: 1.0.5
1478 **/
1479void
1480hb_font_set_parent (hb_font_t *font,
1481 hb_font_t *parent)
1482{
1483 if (font->immutable)
1484 return;
1485
1486 if (!parent)
1487 parent = hb_font_get_empty ();
1488
1489 hb_font_t *old = font->parent;
1490
1491 font->parent = hb_font_reference (parent);
1492
1493 hb_font_destroy (old);
1494}
1495
1496/**
1497 * hb_font_get_parent:
1498 * @font: a font.
1499 *
1500 *
1501 *
1502 * Return value: (transfer none):
1503 *
1504 * Since: 0.9.2
1505 **/
1506hb_font_t *
1507hb_font_get_parent (hb_font_t *font)
1508{
1509 return font->parent;
1510}
1511
1512/**
1513 * hb_font_set_face:
1514 * @font: a font.
1515 * @face: new face.
1516 *
1517 * Sets font-face of @font.
1518 *
1519 * Since: 1.4.3
1520 **/
1521void
1522hb_font_set_face (hb_font_t *font,
1523 hb_face_t *face)
1524{
1525 if (font->immutable)
1526 return;
1527
1528 if (unlikely (!face))
1529 face = hb_face_get_empty ();
1530
1531 hb_face_t *old = font->face;
1532
1533 font->face = hb_face_reference (face);
1534
1535 hb_face_destroy (old);
1536}
1537
1538/**
1539 * hb_font_get_face:
1540 * @font: a font.
1541 *
1542 *
1543 *
1544 * Return value: (transfer none):
1545 *
1546 * Since: 0.9.2
1547 **/
1548hb_face_t *
1549hb_font_get_face (hb_font_t *font)
1550{
1551 return font->face;
1552}
1553
1554
1555/**
1556 * hb_font_set_funcs:
1557 * @font: a font.
1558 * @klass: (closure font_data) (destroy destroy) (scope notified):
1559 * @font_data:
1560 * @destroy:
1561 *
1562 *
1563 *
1564 * Since: 0.9.2
1565 **/
1566void
1567hb_font_set_funcs (hb_font_t *font,
1568 hb_font_funcs_t *klass,
1569 void *font_data,
1570 hb_destroy_func_t destroy)
1571{
1572 if (font->immutable) {
1573 if (destroy)
1574 destroy (font_data);
1575 return;
1576 }
1577
1578 if (font->destroy)
1579 font->destroy (font->user_data);
1580
1581 if (!klass)
1582 klass = hb_font_funcs_get_empty ();
1583
1584 hb_font_funcs_reference (klass);
1585 hb_font_funcs_destroy (font->klass);
1586 font->klass = klass;
1587 font->user_data = font_data;
1588 font->destroy = destroy;
1589}
1590
1591/**
1592 * hb_font_set_funcs_data:
1593 * @font: a font.
1594 * @font_data: (destroy destroy) (scope notified):
1595 * @destroy:
1596 *
1597 *
1598 *
1599 * Since: 0.9.2
1600 **/
1601void
1602hb_font_set_funcs_data (hb_font_t *font,
1603 void *font_data,
1604 hb_destroy_func_t destroy)
1605{
1606 /* Destroy user_data? */
1607 if (font->immutable) {
1608 if (destroy)
1609 destroy (font_data);
1610 return;
1611 }
1612
1613 if (font->destroy)
1614 font->destroy (font->user_data);
1615
1616 font->user_data = font_data;
1617 font->destroy = destroy;
1618}
1619
1620
1621/**
1622 * hb_font_set_scale:
1623 * @font: a font.
1624 * @x_scale:
1625 * @y_scale:
1626 *
1627 *
1628 *
1629 * Since: 0.9.2
1630 **/
1631void
1632hb_font_set_scale (hb_font_t *font,
1633 int x_scale,
1634 int y_scale)
1635{
1636 if (font->immutable)
1637 return;
1638
1639 font->x_scale = x_scale;
1640 font->y_scale = y_scale;
1641}
1642
1643/**
1644 * hb_font_get_scale:
1645 * @font: a font.
1646 * @x_scale: (out):
1647 * @y_scale: (out):
1648 *
1649 *
1650 *
1651 * Since: 0.9.2
1652 **/
1653void
1654hb_font_get_scale (hb_font_t *font,
1655 int *x_scale,
1656 int *y_scale)
1657{
1658 if (x_scale) *x_scale = font->x_scale;
1659 if (y_scale) *y_scale = font->y_scale;
1660}
1661
1662/**
1663 * hb_font_set_ppem:
1664 * @font: a font.
1665 * @x_ppem:
1666 * @y_ppem:
1667 *
1668 *
1669 *
1670 * Since: 0.9.2
1671 **/
1672void
1673hb_font_set_ppem (hb_font_t *font,
1674 unsigned int x_ppem,
1675 unsigned int y_ppem)
1676{
1677 if (font->immutable)
1678 return;
1679
1680 font->x_ppem = x_ppem;
1681 font->y_ppem = y_ppem;
1682}
1683
1684/**
1685 * hb_font_get_ppem:
1686 * @font: a font.
1687 * @x_ppem: (out):
1688 * @y_ppem: (out):
1689 *
1690 *
1691 *
1692 * Since: 0.9.2
1693 **/
1694void
1695hb_font_get_ppem (hb_font_t *font,
1696 unsigned int *x_ppem,
1697 unsigned int *y_ppem)
1698{
1699 if (x_ppem) *x_ppem = font->x_ppem;
1700 if (y_ppem) *y_ppem = font->y_ppem;
1701}
1702
1703/**
1704 * hb_font_set_ptem:
1705 * @font: a font.
1706 * @ptem:
1707 *
1708 * Sets "point size" of the font.
1709 *
1710 * Since: 1.6.0
1711 **/
1712void
1713hb_font_set_ptem (hb_font_t *font, float ptem)
1714{
1715 if (font->immutable)
1716 return;
1717
1718 font->ptem = ptem;
1719}
1720
1721/**
1722 * hb_font_get_ptem:
1723 * @font: a font.
1724 *
1725 * Gets the "point size" of the font. A value of 0 means unset.
1726 *
1727 * Return value: Point size.
1728 *
1729 * Since: 0.9.2
1730 **/
1731float
1732hb_font_get_ptem (hb_font_t *font)
1733{
1734 return font->ptem;
1735}
1736
1737/*
1738 * Variations
1739 */
1740
1741static void
1742_hb_font_adopt_var_coords_normalized (hb_font_t *font,
1743 int *coords, /* 2.14 normalized */
1744 unsigned int coords_length)
1745{
1746 free (font->coords);
1747
1748 font->coords = coords;
1749 font->num_coords = coords_length;
1750}
1751
1752/**
1753 * hb_font_set_variations:
1754 *
1755 * Since: 1.4.2
1756 */
1757void
1758hb_font_set_variations (hb_font_t *font,
1759 const hb_variation_t *variations,
1760 unsigned int variations_length)
1761{
1762 if (font->immutable)
1763 return;
1764
1765 if (!variations_length)
1766 {
1767 hb_font_set_var_coords_normalized (font, nullptr, 0);
1768 return;
1769 }
1770
1771 unsigned int coords_length = hb_ot_var_get_axis_count (font->face);
1772
1773 int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
1774 if (unlikely (coords_length && !normalized))
1775 return;
1776
1777 hb_ot_var_normalize_variations (font->face,
1778 variations, variations_length,
1779 normalized, coords_length);
1780 _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
1781}
1782
1783/**
1784 * hb_font_set_var_coords_design:
1785 *
1786 * Since: 1.4.2
1787 */
1788void
1789hb_font_set_var_coords_design (hb_font_t *font,
1790 const float *coords,
1791 unsigned int coords_length)
1792{
1793 if (font->immutable)
1794 return;
1795
1796 int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr;
1797 if (unlikely (coords_length && !normalized))
1798 return;
1799
1800 hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
1801 _hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
1802}
1803
1804/**
1805 * hb_font_set_var_coords_normalized:
1806 *
1807 * Since: 1.4.2
1808 */
1809void
1810hb_font_set_var_coords_normalized (hb_font_t *font,
1811 const int *coords, /* 2.14 normalized */
1812 unsigned int coords_length)
1813{
1814 if (font->immutable)
1815 return;
1816
1817 int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr;
1818 if (unlikely (coords_length && !copy))
1819 return;
1820
1821 if (coords_length)
1822 memcpy (copy, coords, coords_length * sizeof (coords[0]));
1823
1824 _hb_font_adopt_var_coords_normalized (font, copy, coords_length);
1825}
1826
1827/**
1828 * hb_font_get_var_coords_normalized:
1829 *
1830 * Return value is valid as long as variation coordinates of the font
1831 * are not modified.
1832 *
1833 * Since: 1.4.2
1834 */
1835const int *
1836hb_font_get_var_coords_normalized (hb_font_t *font,
1837 unsigned int *length)
1838{
1839 if (length)
1840 *length = font->num_coords;
1841
1842 return font->coords;
1843}
1844
1845
1846#ifndef HB_DISABLE_DEPRECATED
1847
1848/*
1849 * Deprecated get_glyph_func():
1850 */
1851
1852struct hb_trampoline_closure_t
1853{
1854 void *user_data;
1855 hb_destroy_func_t destroy;
1856 unsigned int ref_count;
1857};
1858
1859template <typename FuncType>
1860struct hb_trampoline_t
1861{
1862 hb_trampoline_closure_t closure; /* Must be first. */
1863 FuncType func;
1864};
1865
1866template <typename FuncType>
1867static hb_trampoline_t<FuncType> *
1868trampoline_create (FuncType func,
1869 void *user_data,
1870 hb_destroy_func_t destroy)
1871{
1872 typedef hb_trampoline_t<FuncType> trampoline_t;
1873
1874 trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
1875
1876 if (unlikely (!trampoline))
1877 return nullptr;
1878
1879 trampoline->closure.user_data = user_data;
1880 trampoline->closure.destroy = destroy;
1881 trampoline->closure.ref_count = 1;
1882 trampoline->func = func;
1883
1884 return trampoline;
1885}
1886
1887static void
1888trampoline_reference (hb_trampoline_closure_t *closure)
1889{
1890 closure->ref_count++;
1891}
1892
1893static void
1894trampoline_destroy (void *user_data)
1895{
1896 hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
1897
1898 if (--closure->ref_count)
1899 return;
1900
1901 if (closure->destroy)
1902 closure->destroy (closure->user_data);
1903 free (closure);
1904}
1905
1906typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
1907
1908static hb_bool_t
1909hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
1910 void *font_data,
1911 hb_codepoint_t unicode,
1912 hb_codepoint_t *glyph,
1913 void *user_data)
1914{
1915 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
1916 return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
1917}
1918
1919static hb_bool_t
1920hb_font_get_variation_glyph_trampoline (hb_font_t *font,
1921 void *font_data,
1922 hb_codepoint_t unicode,
1923 hb_codepoint_t variation_selector,
1924 hb_codepoint_t *glyph,
1925 void *user_data)
1926{
1927 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
1928 return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
1929}
1930
1931/**
1932 * hb_font_funcs_set_glyph_func:
1933 * @ffuncs: font functions.
1934 * @func: (closure user_data) (destroy destroy) (scope notified):
1935 * @user_data:
1936 * @destroy:
1937 *
1938 * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and
1939 * hb_font_funcs_set_variation_glyph_func() instead.
1940 *
1941 * Since: 0.9.2
1942 * Deprecated: 1.2.3
1943 **/
1944void
1945hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
1946 hb_font_get_glyph_func_t func,
1947 void *user_data, hb_destroy_func_t destroy)
1948{
1949 hb_font_get_glyph_trampoline_t *trampoline;
1950
1951 trampoline = trampoline_create (func, user_data, destroy);
1952 if (unlikely (!trampoline))
1953 {
1954 if (destroy)
1955 destroy (user_data);
1956 return;
1957 }
1958
1959 hb_font_funcs_set_nominal_glyph_func (ffuncs,
1960 hb_font_get_nominal_glyph_trampoline,
1961 trampoline,
1962 trampoline_destroy);
1963
1964 trampoline_reference (&trampoline->closure);
1965 hb_font_funcs_set_variation_glyph_func (ffuncs,
1966 hb_font_get_variation_glyph_trampoline,
1967 trampoline,
1968 trampoline_destroy);
1969}
1970
1971#endif /* HB_DISABLE_DEPRECATED */
1972