Coverage Report

Created: 2023-03-02 15:18

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