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