Coverage Report

Created: 2025-07-07 10:01

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