Coverage Report

Created: 2023-12-14 14:03

/src/harfbuzz/src/hb-ot-font.cc
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2011,2014  Google, Inc.
3
 *
4
 *  This is part of HarfBuzz, a text shaping library.
5
 *
6
 * Permission is hereby granted, without written agreement and without
7
 * license or royalty fees, to use, copy, modify, and distribute this
8
 * software and its documentation for any purpose, provided that the
9
 * above copyright notice and the following two paragraphs appear in
10
 * all copies of this software.
11
 *
12
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16
 * DAMAGE.
17
 *
18
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
 *
24
 * Google Author(s): Behdad Esfahbod, Roozbeh Pournader
25
 */
26
27
#include "hb.hh"
28
29
#ifndef HB_NO_OT_FONT
30
31
#include "hb-ot.h"
32
33
#include "hb-cache.hh"
34
#include "hb-font.hh"
35
#include "hb-machinery.hh"
36
#include "hb-ot-face.hh"
37
38
#include "hb-ot-cmap-table.hh"
39
#include "hb-ot-glyf-table.hh"
40
#include "hb-ot-cff1-table.hh"
41
#include "hb-ot-cff2-table.hh"
42
#include "hb-ot-hmtx-table.hh"
43
#include "hb-ot-post-table.hh"
44
#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
45
#include "hb-ot-vorg-table.hh"
46
#include "OT/Color/CBDT/CBDT.hh"
47
#include "OT/Color/COLR/COLR.hh"
48
#include "OT/Color/sbix/sbix.hh"
49
#include "OT/Color/svg/svg.hh"
50
51
52
/**
53
 * SECTION:hb-ot-font
54
 * @title: hb-ot-font
55
 * @short_description: OpenType font implementation
56
 * @include: hb-ot.h
57
 *
58
 * Functions for using OpenType fonts with hb_shape().  Note that fonts returned
59
 * by hb_font_create() default to using these functions, so most clients would
60
 * never need to call these functions directly.
61
 **/
62
63
using hb_ot_font_cmap_cache_t    = hb_cache_t<21, 16, 8, true>;
64
using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
65
66
static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key;
67
68
struct hb_ot_font_t
69
{
70
  const hb_ot_face_t *ot_face;
71
72
  hb_ot_font_cmap_cache_t *cmap_cache;
73
74
  /* h_advance caching */
75
  mutable hb_atomic_int_t cached_coords_serial;
76
  mutable hb_atomic_ptr_t<hb_ot_font_advance_cache_t> advance_cache;
77
};
78
79
static hb_ot_font_t *
80
_hb_ot_font_create (hb_font_t *font)
81
1.29M
{
82
1.29M
  hb_ot_font_t *ot_font = (hb_ot_font_t *) hb_calloc (1, sizeof (hb_ot_font_t));
83
1.29M
  if (unlikely (!ot_font))
84
15.3k
    return nullptr;
85
86
1.28M
  ot_font->ot_face = &font->face->table;
87
88
  // retry:
89
1.28M
  auto *cmap_cache  = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
90
1.28M
                   &hb_ot_font_cmap_cache_user_data_key);
91
1.28M
  if (!cmap_cache)
92
457k
  {
93
457k
    cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t));
94
457k
    if (unlikely (!cmap_cache)) goto out;
95
451k
    cmap_cache->init ();
96
451k
    if (unlikely (!hb_face_set_user_data (font->face,
97
451k
            &hb_ot_font_cmap_cache_user_data_key,
98
451k
            cmap_cache,
99
451k
            hb_free,
100
451k
            false)))
101
28.5k
    {
102
28.5k
      hb_free (cmap_cache);
103
28.5k
      cmap_cache = nullptr;
104
      /* Normally we would retry here, but that would
105
       * infinite-loop if the face is the empty-face.
106
       * Just let it go and this font will be uncached if it
107
       * happened to collide with another thread creating the
108
       * cache at the same time. */
109
      // goto retry;
110
28.5k
    }
111
451k
  }
112
1.28M
  out:
113
1.28M
  ot_font->cmap_cache = cmap_cache;
114
115
1.28M
  return ot_font;
116
1.28M
}
117
118
static void
119
_hb_ot_font_destroy (void *font_data)
120
1.28M
{
121
1.28M
  hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data;
122
123
1.28M
  auto *cache = ot_font->advance_cache.get_relaxed ();
124
1.28M
  if (cache)
125
36.8k
    hb_free (cache);
126
127
1.28M
  hb_free (ot_font);
128
1.28M
}
129
130
static hb_bool_t
131
hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
132
       void *font_data,
133
       hb_codepoint_t unicode,
134
       hb_codepoint_t *glyph,
135
       void *user_data HB_UNUSED)
136
30.0M
{
137
30.0M
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
138
30.0M
  const hb_ot_face_t *ot_face = ot_font->ot_face;
139
30.0M
  return ot_face->cmap->get_nominal_glyph (unicode, glyph, ot_font->cmap_cache);
140
30.0M
}
141
142
static unsigned int
143
hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
144
        void *font_data,
145
        unsigned int count,
146
        const hb_codepoint_t *first_unicode,
147
        unsigned int unicode_stride,
148
        hb_codepoint_t *first_glyph,
149
        unsigned int glyph_stride,
150
        void *user_data HB_UNUSED)
151
7.66M
{
152
7.66M
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
153
7.66M
  const hb_ot_face_t *ot_face = ot_font->ot_face;
154
7.66M
  return ot_face->cmap->get_nominal_glyphs (count,
155
7.66M
              first_unicode, unicode_stride,
156
7.66M
              first_glyph, glyph_stride,
157
7.66M
              ot_font->cmap_cache);
158
7.66M
}
159
160
static hb_bool_t
161
hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
162
         void *font_data,
163
         hb_codepoint_t unicode,
164
         hb_codepoint_t variation_selector,
165
         hb_codepoint_t *glyph,
166
         void *user_data HB_UNUSED)
167
437k
{
168
437k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
169
437k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
170
437k
  return ot_face->cmap->get_variation_glyph (unicode,
171
437k
                                             variation_selector, glyph,
172
437k
                                             ot_font->cmap_cache);
173
437k
}
174
175
static void
176
hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
177
          unsigned count,
178
          const hb_codepoint_t *first_glyph,
179
          unsigned glyph_stride,
180
          hb_position_t *first_advance,
181
          unsigned advance_stride,
182
          void *user_data HB_UNUSED)
183
9.00M
{
184
9.00M
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
185
9.00M
  const hb_ot_face_t *ot_face = ot_font->ot_face;
186
9.00M
  const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
187
188
9.00M
#ifndef HB_NO_VAR
189
9.00M
  const OT::HVAR &HVAR = *hmtx.var_table;
190
9.00M
  const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
191
9.00M
  OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
192
193
9.00M
  bool use_cache = font->num_coords;
194
#else
195
  OT::VariationStore::cache_t *varStore_cache = nullptr;
196
  bool use_cache = false;
197
#endif
198
199
9.00M
  hb_ot_font_advance_cache_t *cache = nullptr;
200
9.00M
  if (use_cache)
201
390k
  {
202
390k
  retry:
203
390k
    cache = ot_font->advance_cache.get_acquire ();
204
390k
    if (unlikely (!cache))
205
40.2k
    {
206
40.2k
      cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t));
207
40.2k
      if (unlikely (!cache))
208
3.41k
      {
209
3.41k
  use_cache = false;
210
3.41k
  goto out;
211
3.41k
      }
212
213
36.8k
      cache->init ();
214
36.8k
      if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache)))
215
0
      {
216
0
  hb_free (cache);
217
0
  goto retry;
218
0
      }
219
36.8k
      ot_font->cached_coords_serial.set_release (font->serial_coords);
220
36.8k
    }
221
390k
  }
222
9.00M
  out:
223
224
9.00M
  if (!use_cache)
225
8.61M
  {
226
356M
    for (unsigned int i = 0; i < count; i++)
227
347M
    {
228
347M
      *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache));
229
347M
      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
230
347M
      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
231
347M
    }
232
8.61M
  }
233
387k
  else
234
387k
  { /* Use cache. */
235
387k
    if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords)
236
0
    {
237
0
      ot_font->advance_cache->init ();
238
0
      ot_font->cached_coords_serial.set_release (font->serial_coords);
239
0
    }
240
241
2.05M
    for (unsigned int i = 0; i < count; i++)
242
1.66M
    {
243
1.66M
      hb_position_t v;
244
1.66M
      unsigned cv;
245
1.66M
      if (ot_font->advance_cache->get (*first_glyph, &cv))
246
1.36M
  v = cv;
247
298k
      else
248
298k
      {
249
298k
        v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache);
250
298k
  ot_font->advance_cache->set (*first_glyph, v);
251
298k
      }
252
1.66M
      *first_advance = font->em_scale_x (v);
253
1.66M
      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
254
1.66M
      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
255
1.66M
    }
256
387k
  }
257
258
9.00M
#ifndef HB_NO_VAR
259
9.00M
  OT::VariationStore::destroy_cache (varStore_cache);
260
9.00M
#endif
261
9.00M
}
262
263
#ifndef HB_NO_VERTICAL
264
static void
265
hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
266
          unsigned count,
267
          const hb_codepoint_t *first_glyph,
268
          unsigned glyph_stride,
269
          hb_position_t *first_advance,
270
          unsigned advance_stride,
271
          void *user_data HB_UNUSED)
272
431k
{
273
431k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
274
431k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
275
431k
  const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
276
277
431k
  if (vmtx.has_data ())
278
3.86k
  {
279
3.86k
#ifndef HB_NO_VAR
280
3.86k
    const OT::VVAR &VVAR = *vmtx.var_table;
281
3.86k
    const OT::VariationStore &varStore = &VVAR + VVAR.varStore;
282
3.86k
    OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr;
283
#else
284
    OT::VariationStore::cache_t *varStore_cache = nullptr;
285
#endif
286
287
7.72k
    for (unsigned int i = 0; i < count; i++)
288
3.86k
    {
289
3.86k
      *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache));
290
3.86k
      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
291
3.86k
      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
292
3.86k
    }
293
294
3.86k
#ifndef HB_NO_VAR
295
3.86k
    OT::VariationStore::destroy_cache (varStore_cache);
296
3.86k
#endif
297
3.86k
  }
298
427k
  else
299
427k
  {
300
427k
    hb_font_extents_t font_extents;
301
427k
    font->get_h_extents_with_fallback (&font_extents);
302
427k
    hb_position_t advance = -(font_extents.ascender - font_extents.descender);
303
304
854k
    for (unsigned int i = 0; i < count; i++)
305
427k
    {
306
427k
      *first_advance = advance;
307
427k
      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
308
427k
      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
309
427k
    }
310
427k
  }
311
431k
}
312
#endif
313
314
#ifndef HB_NO_VERTICAL
315
static hb_bool_t
316
hb_ot_get_glyph_v_origin (hb_font_t *font,
317
        void *font_data,
318
        hb_codepoint_t glyph,
319
        hb_position_t *x,
320
        hb_position_t *y,
321
        void *user_data HB_UNUSED)
322
431k
{
323
431k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
324
431k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
325
326
431k
  *x = font->get_glyph_h_advance (glyph) / 2;
327
328
431k
  const OT::VORG &VORG = *ot_face->VORG;
329
431k
  if (VORG.has_data ())
330
2.41k
  {
331
2.41k
    float delta = 0;
332
333
2.41k
#ifndef HB_NO_VAR
334
2.41k
    const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
335
2.41k
    const OT::VVAR &VVAR = *vmtx.var_table;
336
2.41k
    if (font->num_coords)
337
11
      VVAR.get_vorg_delta_unscaled (glyph,
338
11
            font->coords, font->num_coords,
339
11
            &delta);
340
2.41k
#endif
341
342
2.41k
    *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta);
343
2.41k
    return true;
344
2.41k
  }
345
346
428k
  hb_glyph_extents_t extents = {0};
347
428k
  if (ot_face->glyf->get_extents (font, glyph, &extents))
348
35.2k
  {
349
35.2k
    const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
350
35.2k
    int tsb = 0;
351
35.2k
    if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb))
352
511
    {
353
511
      *y = extents.y_bearing + font->em_scale_y (tsb);
354
511
      return true;
355
511
    }
356
357
34.7k
    hb_font_extents_t font_extents;
358
34.7k
    font->get_h_extents_with_fallback (&font_extents);
359
34.7k
    hb_position_t advance = font_extents.ascender - font_extents.descender;
360
34.7k
    int diff = advance - -extents.height;
361
34.7k
    *y = extents.y_bearing + (diff >> 1);
362
34.7k
    return true;
363
35.2k
  }
364
365
393k
  hb_font_extents_t font_extents;
366
393k
  font->get_h_extents_with_fallback (&font_extents);
367
393k
  *y = font_extents.ascender;
368
369
393k
  return true;
370
428k
}
371
#endif
372
373
static hb_bool_t
374
hb_ot_get_glyph_extents (hb_font_t *font,
375
       void *font_data,
376
       hb_codepoint_t glyph,
377
       hb_glyph_extents_t *extents,
378
       void *user_data HB_UNUSED)
379
1.12M
{
380
1.12M
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
381
1.12M
  const hb_ot_face_t *ot_face = ot_font->ot_face;
382
383
1.12M
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
384
1.12M
  if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
385
1.12M
  if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
386
1.12M
#endif
387
1.12M
#if !defined(HB_NO_COLOR)
388
1.12M
  if (ot_face->COLR->get_extents (font, glyph, extents)) return true;
389
1.08M
#endif
390
1.08M
  if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
391
634k
#ifndef HB_NO_OT_FONT_CFF
392
634k
  if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
393
586k
  if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
394
571k
#endif
395
396
571k
  return false;
397
586k
}
398
399
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
400
static hb_bool_t
401
hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
402
          void *font_data,
403
          hb_codepoint_t glyph,
404
          char *name, unsigned int size,
405
          void *user_data HB_UNUSED)
406
431k
{
407
431k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
408
431k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
409
410
431k
  if (ot_face->post->get_glyph_name (glyph, name, size)) return true;
411
418k
#ifndef HB_NO_OT_FONT_CFF
412
418k
  if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true;
413
396k
#endif
414
396k
  return false;
415
418k
}
416
static hb_bool_t
417
hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
418
         void *font_data,
419
         const char *name, int len,
420
         hb_codepoint_t *glyph,
421
         void *user_data HB_UNUSED)
422
431k
{
423
431k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
424
431k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
425
426
431k
  if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true;
427
428k
#ifndef HB_NO_OT_FONT_CFF
428
428k
    if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true;
429
427k
#endif
430
427k
  return false;
431
428k
}
432
#endif
433
434
static hb_bool_t
435
hb_ot_get_font_h_extents (hb_font_t *font,
436
        void *font_data HB_UNUSED,
437
        hb_font_extents_t *metrics,
438
        void *user_data HB_UNUSED)
439
855k
{
440
855k
  return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) &&
441
855k
   _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) &&
442
855k
   _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap);
443
855k
}
444
445
#ifndef HB_NO_VERTICAL
446
static hb_bool_t
447
hb_ot_get_font_v_extents (hb_font_t *font,
448
        void *font_data HB_UNUSED,
449
        hb_font_extents_t *metrics,
450
        void *user_data HB_UNUSED)
451
0
{
452
0
  return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_ASCENDER, &metrics->ascender) &&
453
0
   _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_DESCENDER, &metrics->descender) &&
454
0
   _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap);
455
0
}
456
#endif
457
458
#ifndef HB_NO_DRAW
459
static void
460
hb_ot_draw_glyph (hb_font_t *font,
461
      void *font_data HB_UNUSED,
462
      hb_codepoint_t glyph,
463
      hb_draw_funcs_t *draw_funcs, void *draw_data,
464
      void *user_data)
465
1.66M
{
466
1.66M
  hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
467
1.66M
  if (font->face->table.glyf->get_path (font, glyph, draw_session)) return;
468
1.61M
#ifndef HB_NO_CFF
469
1.61M
  if (font->face->table.cff1->get_path (font, glyph, draw_session)) return;
470
1.60M
  if (font->face->table.cff2->get_path (font, glyph, draw_session)) return;
471
1.60M
#endif
472
1.60M
}
473
#endif
474
475
#ifndef HB_NO_PAINT
476
static void
477
hb_ot_paint_glyph (hb_font_t *font,
478
                   void *font_data,
479
                   hb_codepoint_t glyph,
480
                   hb_paint_funcs_t *paint_funcs, void *paint_data,
481
                   unsigned int palette,
482
                   hb_color_t foreground,
483
                   void *user_data)
484
0
{
485
0
#ifndef HB_NO_COLOR
486
0
  if (font->face->table.COLR->paint_glyph (font, glyph, paint_funcs, paint_data, palette, foreground)) return;
487
0
  if (font->face->table.SVG->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
488
0
#ifndef HB_NO_OT_FONT_BITMAP
489
0
  if (font->face->table.CBDT->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
490
0
  if (font->face->table.sbix->paint_glyph (font, glyph, paint_funcs, paint_data)) return;
491
0
#endif
492
0
#endif
493
0
  if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
494
0
#ifndef HB_NO_CFF
495
0
  if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
496
0
  if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
497
0
#endif
498
0
}
499
#endif
500
501
static inline void free_static_ot_funcs ();
502
503
static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t>
504
{
505
  static hb_font_funcs_t *create ()
506
1.85k
  {
507
1.85k
    hb_font_funcs_t *funcs = hb_font_funcs_create ();
508
509
1.85k
    hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
510
1.85k
    hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr);
511
1.85k
    hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
512
513
1.85k
    hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
514
1.85k
    hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr);
515
    //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
516
517
1.85k
#ifndef HB_NO_VERTICAL
518
1.85k
    hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
519
1.85k
    hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
520
1.85k
    hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
521
1.85k
#endif
522
523
1.85k
#ifndef HB_NO_DRAW
524
1.85k
    hb_font_funcs_set_draw_glyph_func (funcs, hb_ot_draw_glyph, nullptr, nullptr);
525
1.85k
#endif
526
527
1.85k
#ifndef HB_NO_PAINT
528
1.85k
    hb_font_funcs_set_paint_glyph_func (funcs, hb_ot_paint_glyph, nullptr, nullptr);
529
1.85k
#endif
530
531
1.85k
    hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
532
    //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
533
534
1.85k
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
535
1.85k
    hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
536
1.85k
    hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
537
1.85k
#endif
538
539
1.85k
    hb_font_funcs_make_immutable (funcs);
540
541
1.85k
    hb_atexit (free_static_ot_funcs);
542
543
1.85k
    return funcs;
544
1.85k
  }
545
} static_ot_funcs;
546
547
static inline
548
void free_static_ot_funcs ()
549
0
{
550
0
  static_ot_funcs.free_instance ();
551
0
}
552
553
static hb_font_funcs_t *
554
_hb_ot_get_font_funcs ()
555
1.28M
{
556
1.28M
  return static_ot_funcs.get_unconst ();
557
1.28M
}
558
559
560
/**
561
 * hb_ot_font_set_funcs:
562
 * @font: #hb_font_t to work upon
563
 *
564
 * Sets the font functions to use when working with @font. 
565
 *
566
 * Since: 0.9.28
567
 **/
568
void
569
hb_ot_font_set_funcs (hb_font_t *font)
570
1.29M
{
571
1.29M
  hb_ot_font_t *ot_font = _hb_ot_font_create (font);
572
1.29M
  if (unlikely (!ot_font))
573
15.3k
    return;
574
575
1.28M
  hb_font_set_funcs (font,
576
1.28M
         _hb_ot_get_font_funcs (),
577
1.28M
         ot_font,
578
1.28M
         _hb_ot_font_destroy);
579
1.28M
}
580
581
#ifndef HB_NO_VAR
582
bool
583
_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical,
584
               int *lsb)
585
0
{
586
0
  return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb);
587
0
}
588
589
unsigned
590
_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
591
197k
{
592
197k
  return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical);
593
197k
}
594
#endif
595
596
597
#endif