Coverage Report

Created: 2024-09-14 10:54

/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
282k
{
82
282k
  hb_ot_font_t *ot_font = (hb_ot_font_t *) hb_calloc (1, sizeof (hb_ot_font_t));
83
282k
  if (unlikely (!ot_font))
84
1.15k
    return nullptr;
85
86
280k
  ot_font->ot_face = &font->face->table;
87
88
  // retry:
89
280k
  auto *cmap_cache  = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
90
280k
                   &hb_ot_font_cmap_cache_user_data_key);
91
280k
  if (!cmap_cache)
92
95.5k
  {
93
95.5k
    cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t));
94
95.5k
    if (unlikely (!cmap_cache)) goto out;
95
95.0k
    cmap_cache->init ();
96
95.0k
    if (unlikely (!hb_face_set_user_data (font->face,
97
95.0k
            &hb_ot_font_cmap_cache_user_data_key,
98
95.0k
            cmap_cache,
99
95.0k
            hb_free,
100
95.0k
            false)))
101
1.73k
    {
102
1.73k
      hb_free (cmap_cache);
103
1.73k
      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
1.73k
    }
111
95.0k
  }
112
280k
  out:
113
280k
  ot_font->cmap_cache = cmap_cache;
114
115
280k
  return ot_font;
116
280k
}
117
118
static void
119
_hb_ot_font_destroy (void *font_data)
120
280k
{
121
280k
  hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data;
122
123
280k
  auto *cache = ot_font->advance_cache.get_relaxed ();
124
280k
  if (cache)
125
4.48k
    hb_free (cache);
126
127
280k
  hb_free (ot_font);
128
280k
}
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
5.71M
{
137
5.71M
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
138
5.71M
  const hb_ot_face_t *ot_face = ot_font->ot_face;
139
5.71M
  return ot_face->cmap->get_nominal_glyph (unicode, glyph, ot_font->cmap_cache);
140
5.71M
}
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
1.90M
{
152
1.90M
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
153
1.90M
  const hb_ot_face_t *ot_face = ot_font->ot_face;
154
1.90M
  return ot_face->cmap->get_nominal_glyphs (count,
155
1.90M
              first_unicode, unicode_stride,
156
1.90M
              first_glyph, glyph_stride,
157
1.90M
              ot_font->cmap_cache);
158
1.90M
}
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
94.4k
{
168
94.4k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
169
94.4k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
170
94.4k
  return ot_face->cmap->get_variation_glyph (unicode,
171
94.4k
                                             variation_selector, glyph,
172
94.4k
                                             ot_font->cmap_cache);
173
94.4k
}
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
2.17M
{
184
2.17M
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
185
2.17M
  const hb_ot_face_t *ot_face = ot_font->ot_face;
186
2.17M
  const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
187
188
2.17M
#ifndef HB_NO_VAR
189
2.17M
  const OT::HVAR &HVAR = *hmtx.var_table;
190
2.17M
  const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
191
2.17M
  OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
192
193
2.17M
  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
2.17M
  hb_ot_font_advance_cache_t *cache = nullptr;
200
2.17M
  if (use_cache)
201
50.9k
  {
202
50.9k
  retry:
203
50.9k
    cache = ot_font->advance_cache.get_acquire ();
204
50.9k
    if (unlikely (!cache))
205
4.71k
    {
206
4.71k
      cache = (hb_ot_font_advance_cache_t *) hb_malloc (sizeof (hb_ot_font_advance_cache_t));
207
4.71k
      if (unlikely (!cache))
208
236
      {
209
236
  use_cache = false;
210
236
  goto out;
211
236
      }
212
213
4.48k
      cache->init ();
214
4.48k
      if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache)))
215
0
      {
216
0
  hb_free (cache);
217
0
  goto retry;
218
0
      }
219
4.48k
      ot_font->cached_coords_serial.set_release (font->serial_coords);
220
4.48k
    }
221
50.9k
  }
222
2.17M
  out:
223
224
2.17M
  if (!use_cache)
225
2.12M
  {
226
12.9M
    for (unsigned int i = 0; i < count; i++)
227
10.8M
    {
228
10.8M
      *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache));
229
10.8M
      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
230
10.8M
      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
231
10.8M
    }
232
2.12M
  }
233
50.7k
  else
234
50.7k
  { /* Use cache. */
235
50.7k
    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
175k
    for (unsigned int i = 0; i < count; i++)
242
124k
    {
243
124k
      hb_position_t v;
244
124k
      unsigned cv;
245
124k
      if (ot_font->advance_cache->get (*first_glyph, &cv))
246
101k
  v = cv;
247
22.8k
      else
248
22.8k
      {
249
22.8k
        v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache);
250
22.8k
  ot_font->advance_cache->set (*first_glyph, v);
251
22.8k
      }
252
124k
      *first_advance = font->em_scale_x (v);
253
124k
      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
254
124k
      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
255
124k
    }
256
50.7k
  }
257
258
2.17M
#ifndef HB_NO_VAR
259
2.17M
  OT::VariationStore::destroy_cache (varStore_cache);
260
2.17M
#endif
261
2.17M
}
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
93.8k
{
273
93.8k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
274
93.8k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
275
93.8k
  const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
276
277
93.8k
  if (vmtx.has_data ())
278
1.76k
  {
279
1.76k
#ifndef HB_NO_VAR
280
1.76k
    const OT::VVAR &VVAR = *vmtx.var_table;
281
1.76k
    const OT::VariationStore &varStore = &VVAR + VVAR.varStore;
282
1.76k
    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
3.52k
    for (unsigned int i = 0; i < count; i++)
288
1.76k
    {
289
1.76k
      *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache));
290
1.76k
      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
291
1.76k
      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
292
1.76k
    }
293
294
1.76k
#ifndef HB_NO_VAR
295
1.76k
    OT::VariationStore::destroy_cache (varStore_cache);
296
1.76k
#endif
297
1.76k
  }
298
92.0k
  else
299
92.0k
  {
300
92.0k
    hb_font_extents_t font_extents;
301
92.0k
    font->get_h_extents_with_fallback (&font_extents);
302
92.0k
    hb_position_t advance = -(font_extents.ascender - font_extents.descender);
303
304
184k
    for (unsigned int i = 0; i < count; i++)
305
92.0k
    {
306
92.0k
      *first_advance = advance;
307
92.0k
      first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
308
92.0k
      first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
309
92.0k
    }
310
92.0k
  }
311
93.8k
}
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
93.8k
{
323
93.8k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
324
93.8k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
325
326
93.8k
  *x = font->get_glyph_h_advance (glyph) / 2;
327
328
93.8k
  const OT::VORG &VORG = *ot_face->VORG;
329
93.8k
  if (VORG.has_data ())
330
824
  {
331
824
    float delta = 0;
332
333
824
#ifndef HB_NO_VAR
334
824
    const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
335
824
    const OT::VVAR &VVAR = *vmtx.var_table;
336
824
    if (font->num_coords)
337
0
      VVAR.get_vorg_delta_unscaled (glyph,
338
0
            font->coords, font->num_coords,
339
0
            &delta);
340
824
#endif
341
342
824
    *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta);
343
824
    return true;
344
824
  }
345
346
93.0k
  hb_glyph_extents_t extents = {0};
347
93.0k
  if (ot_face->glyf->get_extents (font, glyph, &extents))
348
3.72k
  {
349
3.72k
    const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
350
3.72k
    int tsb = 0;
351
3.72k
    if (vmtx.get_leading_bearing_with_var_unscaled (font, glyph, &tsb))
352
0
    {
353
0
      *y = extents.y_bearing + font->em_scale_y (tsb);
354
0
      return true;
355
0
    }
356
357
3.72k
    hb_font_extents_t font_extents;
358
3.72k
    font->get_h_extents_with_fallback (&font_extents);
359
3.72k
    hb_position_t advance = font_extents.ascender - font_extents.descender;
360
3.72k
    int diff = advance - -extents.height;
361
3.72k
    *y = extents.y_bearing + (diff >> 1);
362
3.72k
    return true;
363
3.72k
  }
364
365
89.3k
  hb_font_extents_t font_extents;
366
89.3k
  font->get_h_extents_with_fallback (&font_extents);
367
89.3k
  *y = font_extents.ascender;
368
369
89.3k
  return true;
370
93.0k
}
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
111k
{
380
111k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
381
111k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
382
383
111k
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
384
111k
  if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
385
111k
  if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
386
111k
#endif
387
111k
#if !defined(HB_NO_COLOR)
388
111k
  if (ot_face->COLR->get_extents (font, glyph, extents)) return true;
389
110k
#endif
390
110k
  if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
391
103k
#ifndef HB_NO_OT_FONT_CFF
392
103k
  if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
393
88.7k
  if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
394
87.5k
#endif
395
396
87.5k
  return false;
397
88.7k
}
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
93.8k
{
407
93.8k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
408
93.8k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
409
410
93.8k
  if (ot_face->post->get_glyph_name (glyph, name, size)) return true;
411
92.2k
#ifndef HB_NO_OT_FONT_CFF
412
92.2k
  if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true;
413
84.6k
#endif
414
84.6k
  return false;
415
92.2k
}
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
93.8k
{
423
93.8k
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
424
93.8k
  const hb_ot_face_t *ot_face = ot_font->ot_face;
425
426
93.8k
  if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true;
427
93.7k
#ifndef HB_NO_OT_FONT_CFF
428
93.7k
    if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true;
429
93.5k
#endif
430
93.5k
  return false;
431
93.7k
}
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
185k
{
440
185k
  return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &metrics->ascender) &&
441
185k
   _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, &metrics->descender) &&
442
185k
   _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap);
443
185k
}
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
94.5k
{
466
94.5k
  hb_draw_session_t draw_session (draw_funcs, draw_data, font->slant_xy);
467
94.5k
  if (font->face->table.glyf->get_path (font, glyph, draw_session)) return;
468
90.6k
#ifndef HB_NO_CFF
469
90.6k
  if (font->face->table.cff1->get_path (font, glyph, draw_session)) return;
470
83.3k
  if (font->face->table.cff2->get_path (font, glyph, draw_session)) return;
471
83.3k
#endif
472
83.3k
}
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
175
  {
507
175
    hb_font_funcs_t *funcs = hb_font_funcs_create ();
508
509
175
    hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
510
175
    hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr);
511
175
    hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
512
513
175
    hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
514
175
    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
175
#ifndef HB_NO_VERTICAL
518
175
    hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
519
175
    hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
520
175
    hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
521
175
#endif
522
523
175
#ifndef HB_NO_DRAW
524
175
    hb_font_funcs_set_draw_glyph_func (funcs, hb_ot_draw_glyph, nullptr, nullptr);
525
175
#endif
526
527
175
#ifndef HB_NO_PAINT
528
175
    hb_font_funcs_set_paint_glyph_func (funcs, hb_ot_paint_glyph, nullptr, nullptr);
529
175
#endif
530
531
175
    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
175
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
535
175
    hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
536
175
    hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
537
175
#endif
538
539
175
    hb_font_funcs_make_immutable (funcs);
540
541
175
    hb_atexit (free_static_ot_funcs);
542
543
175
    return funcs;
544
175
  }
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
280k
{
556
280k
  return static_ot_funcs.get_unconst ();
557
280k
}
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
282k
{
571
282k
  hb_ot_font_t *ot_font = _hb_ot_font_create (font);
572
282k
  if (unlikely (!ot_font))
573
1.15k
    return;
574
575
280k
  hb_font_set_funcs (font,
576
280k
         _hb_ot_get_font_funcs (),
577
280k
         ot_font,
578
280k
         _hb_ot_font_destroy);
579
280k
}
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
11.7k
{
592
11.7k
  return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical);
593
11.7k
}
594
#endif
595
596
597
#endif