Coverage Report

Created: 2026-09-03 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/harfbuzz/src/hb-ot-kern-table.hh
Line
Count
Source
1
/*
2
 * Copyright © 2017  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
25
 */
26
27
#ifndef HB_OT_KERN_TABLE_HH
28
#define HB_OT_KERN_TABLE_HH
29
30
#include "hb-aat-layout-common.hh"
31
#include "hb-aat-layout-kerx-table.hh"
32
33
34
/*
35
 * kern -- Kerning
36
 * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
37
 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
38
 */
39
#define HB_OT_TAG_kern HB_TAG('k','e','r','n')
40
41
42
namespace OT {
43
44
45
template <typename KernSubTableHeader>
46
struct KernSubTableFormat3
47
{
48
  int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
49
0
  {
50
0
    hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
51
0
    hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (kernValue).as_array (glyphCount);
52
0
    hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (leftClass).as_array (glyphCount);
53
0
    hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8>> (rightClass).as_array (leftClassCount * rightClassCount);
54
55
0
    unsigned int leftC = leftClass[left];
56
0
    unsigned int rightC = rightClass[right];
57
0
    if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount))
58
0
      return 0;
59
0
    unsigned int i = leftC * rightClassCount + rightC;
60
0
    return kernValue[kernIndex[i]];
61
0
  }
Unexecuted instantiation: OT::KernSubTableFormat3<OT::KernOTSubTableHeader>::get_kerning(unsigned int, unsigned int) const
Unexecuted instantiation: OT::KernSubTableFormat3<OT::KernAATSubTableHeader>::get_kerning(unsigned int, unsigned int) const
62
63
  bool apply (AAT::hb_aat_apply_context_t *c) const
64
0
  {
65
0
    TRACE_APPLY (this);
66
67
0
    if (!c->plan->requested_kerning)
68
0
      return false;
69
70
0
    if (header.coverage & header.Backwards)
71
0
      return false;
72
73
0
    hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
74
0
    machine.kern (c->font, c->buffer, c->plan->kern_mask);
75
76
0
    return_trace (true);
77
0
  }
Unexecuted instantiation: OT::KernSubTableFormat3<OT::KernOTSubTableHeader>::apply(AAT::hb_aat_apply_context_t*) const
Unexecuted instantiation: OT::KernSubTableFormat3<OT::KernAATSubTableHeader>::apply(AAT::hb_aat_apply_context_t*) const
78
79
  bool sanitize (hb_sanitize_context_t *c) const
80
0
  {
81
0
    TRACE_SANITIZE (this);
82
0
    return_trace (c->check_struct (this) &&
83
0
      hb_barrier () &&
84
0
      c->check_range (kernValueZ,
85
0
          kernValueCount * sizeof (FWORD) +
86
0
          glyphCount * 2 +
87
0
          leftClassCount * rightClassCount));
88
0
  }
Unexecuted instantiation: OT::KernSubTableFormat3<OT::KernOTSubTableHeader>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: OT::KernSubTableFormat3<OT::KernAATSubTableHeader>::sanitize(hb_sanitize_context_t*) const
89
90
  template <typename set_t>
91
  void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const
92
0
  {
93
0
    if (likely (glyphCount))
94
0
    {
95
0
      left_set.add_range (0, num_glyphs - 1);
96
0
      right_set.add_range (0, num_glyphs - 1);
97
0
    }
98
0
  }
Unexecuted instantiation: void OT::KernSubTableFormat3<OT::KernOTSubTableHeader>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, hb_bit_set_t&, unsigned int) const
Unexecuted instantiation: void OT::KernSubTableFormat3<OT::KernAATSubTableHeader>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, hb_bit_set_t&, unsigned int) const
99
100
  protected:
101
  KernSubTableHeader
102
    header;
103
  HBUINT16  glyphCount; /* The number of glyphs in this font. */
104
  HBUINT8 kernValueCount; /* The number of kerning values. */
105
  HBUINT8 leftClassCount; /* The number of left-hand classes. */
106
  HBUINT8 rightClassCount;/* The number of right-hand classes. */
107
  HBUINT8 flags;    /* Set to zero (reserved for future use). */
108
  UnsizedArrayOf<FWORD>
109
    kernValueZ; /* The kerning values.
110
         * Length kernValueCount. */
111
#if 0
112
  UnsizedArrayOf<HBUINT8>
113
    leftClass;  /* The left-hand classes.
114
         * Length glyphCount. */
115
  UnsizedArrayOf<HBUINT8>
116
    rightClass; /* The right-hand classes.
117
         * Length glyphCount. */
118
  UnsizedArrayOf<HBUINT8>kernIndex;
119
        /* The indices into the kernValue array.
120
         * Length leftClassCount * rightClassCount */
121
#endif
122
  public:
123
  DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
124
};
125
126
template <typename KernSubTableHeader>
127
struct KernSubTable
128
{
129
11.2k
  size_t get_size () const { return u.header.length; }
OT::KernSubTable<OT::KernOTSubTableHeader>::get_size() const
Line
Count
Source
129
11.2k
  size_t get_size () const { return u.header.length; }
Unexecuted instantiation: OT::KernSubTable<OT::KernAATSubTableHeader>::get_size() const
130
533
  unsigned int get_type () const { return u.header.format; }
OT::KernSubTable<OT::KernOTSubTableHeader>::get_type() const
Line
Count
Source
130
533
  unsigned int get_type () const { return u.header.format; }
Unexecuted instantiation: OT::KernSubTable<OT::KernAATSubTableHeader>::get_type() const
131
132
  int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
133
0
  {
134
0
    switch (get_type ()) {
135
0
    /* This method hooks up to hb_font_t's get_h_kerning.  Only support Format0. */
136
0
    case 0: hb_barrier (); return u.format0.get_kerning (left, right);
137
0
    default:return 0;
138
0
    }
139
0
  }
Unexecuted instantiation: OT::KernSubTable<OT::KernOTSubTableHeader>::get_kerning(unsigned int, unsigned int) const
Unexecuted instantiation: OT::KernSubTable<OT::KernAATSubTableHeader>::get_kerning(unsigned int, unsigned int) const
140
141
  template <typename context_t, typename ...Ts>
142
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
143
433
  {
144
433
    unsigned int subtable_type = get_type ();
145
433
    TRACE_DISPATCH (this, subtable_type);
146
433
    switch (subtable_type) {
147
433
    case 0: hb_barrier (); return_trace (c->dispatch (u.format0));
148
0
#ifndef HB_NO_AAT_SHAPE
149
0
    case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
150
0
#endif
151
0
    case 2: hb_barrier (); return_trace (c->dispatch (u.format2));
152
0
#ifndef HB_NO_AAT_SHAPE
153
0
    case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
154
0
#endif
155
0
    default:  return_trace (c->default_return_value ());
156
433
    }
157
433
  }
AAT::hb_aat_apply_context_t::return_t OT::KernSubTable<OT::KernOTSubTableHeader>::dispatch<AAT::hb_aat_apply_context_t>(AAT::hb_aat_apply_context_t*) const
Line
Count
Source
143
383
  {
144
383
    unsigned int subtable_type = get_type ();
145
383
    TRACE_DISPATCH (this, subtable_type);
146
383
    switch (subtable_type) {
147
383
    case 0: hb_barrier (); return_trace (c->dispatch (u.format0));
148
0
#ifndef HB_NO_AAT_SHAPE
149
0
    case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
150
0
#endif
151
0
    case 2: hb_barrier (); return_trace (c->dispatch (u.format2));
152
0
#ifndef HB_NO_AAT_SHAPE
153
0
    case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
154
0
#endif
155
0
    default:  return_trace (c->default_return_value ());
156
383
    }
157
383
  }
Unexecuted instantiation: AAT::hb_aat_apply_context_t::return_t OT::KernSubTable<OT::KernAATSubTableHeader>::dispatch<AAT::hb_aat_apply_context_t>(AAT::hb_aat_apply_context_t*) const
hb_sanitize_context_t::return_t OT::KernSubTable<OT::KernOTSubTableHeader>::dispatch<hb_sanitize_context_t>(hb_sanitize_context_t*) const
Line
Count
Source
143
50
  {
144
50
    unsigned int subtable_type = get_type ();
145
50
    TRACE_DISPATCH (this, subtable_type);
146
50
    switch (subtable_type) {
147
50
    case 0: hb_barrier (); return_trace (c->dispatch (u.format0));
148
0
#ifndef HB_NO_AAT_SHAPE
149
0
    case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
150
0
#endif
151
0
    case 2: hb_barrier (); return_trace (c->dispatch (u.format2));
152
0
#ifndef HB_NO_AAT_SHAPE
153
0
    case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
154
0
#endif
155
0
    default:  return_trace (c->default_return_value ());
156
50
    }
157
50
  }
Unexecuted instantiation: hb_sanitize_context_t::return_t OT::KernSubTable<OT::KernAATSubTableHeader>::dispatch<hb_sanitize_context_t>(hb_sanitize_context_t*) const
158
159
  template <typename set_t>
160
  void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const
161
50
  {
162
50
    unsigned int subtable_type = get_type ();
163
50
    switch (subtable_type) {
164
50
    case 0: hb_barrier (); u.format0.collect_glyphs (left_set, right_set, num_glyphs); return;
165
0
#ifndef HB_NO_AAT_SHAPE
166
0
    case 1: hb_barrier (); u.format1.collect_glyphs (left_set, right_set, num_glyphs); return;
167
0
#endif
168
0
    case 2: hb_barrier (); u.format2.collect_glyphs (left_set, right_set, num_glyphs); return;
169
0
#ifndef HB_NO_AAT_SHAPE
170
0
    case 3: hb_barrier (); u.format3.collect_glyphs (left_set, right_set, num_glyphs); return;
171
0
#endif
172
0
    default:  return;
173
50
    }
174
50
  }
void OT::KernSubTable<OT::KernOTSubTableHeader>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, hb_bit_set_t&, unsigned int) const
Line
Count
Source
161
50
  {
162
50
    unsigned int subtable_type = get_type ();
163
50
    switch (subtable_type) {
164
50
    case 0: hb_barrier (); u.format0.collect_glyphs (left_set, right_set, num_glyphs); return;
165
0
#ifndef HB_NO_AAT_SHAPE
166
0
    case 1: hb_barrier (); u.format1.collect_glyphs (left_set, right_set, num_glyphs); return;
167
0
#endif
168
0
    case 2: hb_barrier (); u.format2.collect_glyphs (left_set, right_set, num_glyphs); return;
169
0
#ifndef HB_NO_AAT_SHAPE
170
0
    case 3: hb_barrier (); u.format3.collect_glyphs (left_set, right_set, num_glyphs); return;
171
0
#endif
172
0
    default:  return;
173
50
    }
174
50
  }
Unexecuted instantiation: void OT::KernSubTable<OT::KernAATSubTableHeader>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, hb_bit_set_t&, unsigned int) const
175
176
  bool sanitize (hb_sanitize_context_t *c) const
177
50
  {
178
50
    TRACE_SANITIZE (this);
179
50
    if (unlikely (!(u.header.sanitize (c) &&
180
50
        hb_barrier () &&
181
50
        u.header.length >= u.header.min_size &&
182
50
        c->check_range (this, u.header.length)))) return_trace (false);
183
184
50
    return_trace (dispatch (c));
185
50
  }
OT::KernSubTable<OT::KernOTSubTableHeader>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
177
50
  {
178
50
    TRACE_SANITIZE (this);
179
50
    if (unlikely (!(u.header.sanitize (c) &&
180
50
        hb_barrier () &&
181
50
        u.header.length >= u.header.min_size &&
182
50
        c->check_range (this, u.header.length)))) return_trace (false);
183
184
50
    return_trace (dispatch (c));
185
50
  }
Unexecuted instantiation: OT::KernSubTable<OT::KernAATSubTableHeader>::sanitize(hb_sanitize_context_t*) const
186
187
  public:
188
  union {
189
  KernSubTableHeader        header;
190
  AAT::KerxSubTableFormat0<KernSubTableHeader>  format0;
191
#ifndef HB_NO_AAT_SHAPE
192
  AAT::KerxSubTableFormat1<KernSubTableHeader>  format1;
193
#endif
194
  AAT::KerxSubTableFormat2<KernSubTableHeader>  format2;
195
#ifndef HB_NO_AAT_SHAPE
196
  KernSubTableFormat3<KernSubTableHeader> format3;
197
#endif
198
  } u;
199
  public:
200
  DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
201
};
202
203
204
struct KernOTSubTableHeader
205
{
206
  static constexpr bool apple = false;
207
  typedef AAT::ObsoleteTypes Types;
208
209
0
  unsigned   tuple_count () const { return 0; }
210
10.6k
  bool     is_horizontal () const { return (coverage & Horizontal); }
211
212
  enum Coverage
213
  {
214
    Horizontal  = 0x01u,
215
    Minimum = 0x02u,
216
    CrossStream = 0x04u,
217
    Override  = 0x08u,
218
219
    /* Not supported: */
220
    Backwards = 0x00u,
221
    Variation = 0x00u,
222
  };
223
224
  bool sanitize (hb_sanitize_context_t *c) const
225
100
  {
226
100
    TRACE_SANITIZE (this);
227
100
    return_trace (c->check_struct (this));
228
100
  }
229
230
  public:
231
  HBUINT16  versionZ; /* Unused. */
232
  HBUINT16  length;   /* Length of the subtable (including this header). */
233
  HBUINT8 format;   /* Subtable format. */
234
  HBUINT8 coverage; /* Coverage bits. */
235
  public:
236
  DEFINE_SIZE_STATIC (6);
237
};
238
239
struct KernOT : AAT::KerxTable<KernOT>
240
{
241
  friend struct AAT::KerxTable<KernOT>;
242
243
  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
244
  static constexpr unsigned minVersion = 0u;
245
246
  typedef KernOTSubTableHeader SubTableHeader;
247
  typedef SubTableHeader::Types Types;
248
  typedef KernSubTable<SubTableHeader> SubTable;
249
250
  protected:
251
  HBUINT16  version;  /* Version--0x0000u */
252
  HBUINT16  tableCount; /* Number of subtables in the kerning table. */
253
  SubTable  firstSubTable;  /* Subtables. */
254
  public:
255
  DEFINE_SIZE_MIN (4);
256
};
257
258
259
struct KernAATSubTableHeader
260
{
261
  static constexpr bool apple = true;
262
  typedef AAT::ObsoleteTypes Types;
263
264
0
  unsigned   tuple_count () const { return 0; }
265
0
  bool     is_horizontal () const { return !(coverage & Vertical); }
266
267
  enum Coverage
268
  {
269
    Vertical  = 0x80u,
270
    CrossStream = 0x40u,
271
    Variation = 0x20u,
272
273
    /* Not supported: */
274
    Backwards = 0x00u,
275
  };
276
277
  bool sanitize (hb_sanitize_context_t *c) const
278
0
  {
279
0
    TRACE_SANITIZE (this);
280
0
    return_trace (c->check_struct (this));
281
0
  }
282
283
  public:
284
  HBUINT32  length;   /* Length of the subtable (including this header). */
285
  HBUINT8 coverage; /* Coverage bits. */
286
  HBUINT8 format;   /* Subtable format. */
287
  HBUINT16  tupleIndex; /* The tuple index (used for variations fonts).
288
         * This value specifies which tuple this subtable covers.
289
         * Note: We don't implement. */
290
  public:
291
  DEFINE_SIZE_STATIC (8);
292
};
293
294
struct KernAAT : AAT::KerxTable<KernAAT>
295
{
296
  friend struct AAT::KerxTable<KernAAT>;
297
298
  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
299
  static constexpr unsigned minVersion = 0x00010000u;
300
301
  typedef KernAATSubTableHeader SubTableHeader;
302
  typedef SubTableHeader::Types Types;
303
  typedef KernSubTable<SubTableHeader> SubTable;
304
305
  protected:
306
  HBUINT32  version;  /* Version--0x00010000u */
307
  HBUINT32  tableCount; /* Number of subtables in the kerning table. */
308
  SubTable  firstSubTable;  /* Subtables. */
309
  public:
310
  DEFINE_SIZE_MIN (8);
311
};
312
313
struct kern
314
{
315
  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
316
317
251
  bool     has_data () const { return u.version32.v; }
318
3.42k
  unsigned get_type () const { return u.major.v; }
319
320
  bool has_state_machine () const
321
17
  {
322
17
    switch (get_type ()) {
323
17
    case 0: hb_barrier (); return u.ot.has_state_machine ();
324
0
#ifndef HB_NO_AAT_SHAPE
325
0
    case 1: hb_barrier (); return u.aat.has_state_machine ();
326
0
#endif
327
0
    default:return false;
328
17
    }
329
17
  }
330
331
  bool has_cross_stream () const
332
0
  {
333
0
    switch (get_type ()) {
334
0
    case 0: hb_barrier (); return u.ot.has_cross_stream ();
335
0
#ifndef HB_NO_AAT_SHAPE
336
0
    case 1: hb_barrier (); return u.aat.has_cross_stream ();
337
0
#endif
338
0
    default:return false;
339
0
    }
340
0
  }
341
342
  int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
343
0
  {
344
0
    switch (get_type ()) {
345
0
    case 0: hb_barrier (); return u.ot.get_h_kerning (left, right);
346
0
#ifndef HB_NO_AAT_SHAPE
347
0
    case 1: hb_barrier (); return u.aat.get_h_kerning (left, right);
348
0
#endif
349
0
    default:return 0;
350
0
    }
351
0
  }
352
353
  bool apply (AAT::hb_aat_apply_context_t *c,
354
        const AAT::kern_accelerator_data_t &accel_data) const
355
3.24k
  { return dispatch (c, accel_data); }
356
357
  template <typename context_t, typename ...Ts>
358
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
359
3.25k
  {
360
3.25k
    unsigned int subtable_type = get_type ();
361
3.25k
    TRACE_DISPATCH (this, subtable_type);
362
3.25k
    switch (subtable_type) {
363
3.25k
    case 0: hb_barrier (); return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
364
0
#ifndef HB_NO_AAT_SHAPE
365
0
    case 1: hb_barrier (); return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
366
0
#endif
367
0
    default:  return_trace (c->default_return_value ());
368
3.25k
    }
369
3.25k
  }
AAT::hb_aat_apply_context_t::return_t OT::kern::dispatch<AAT::hb_aat_apply_context_t, AAT::kern_accelerator_data_t const&>(AAT::hb_aat_apply_context_t*, AAT::kern_accelerator_data_t const&) const
Line
Count
Source
359
3.24k
  {
360
3.24k
    unsigned int subtable_type = get_type ();
361
3.24k
    TRACE_DISPATCH (this, subtable_type);
362
3.24k
    switch (subtable_type) {
363
3.24k
    case 0: hb_barrier (); return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
364
0
#ifndef HB_NO_AAT_SHAPE
365
0
    case 1: hb_barrier (); return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
366
0
#endif
367
0
    default:  return_trace (c->default_return_value ());
368
3.24k
    }
369
3.24k
  }
hb_sanitize_context_t::return_t OT::kern::dispatch<hb_sanitize_context_t>(hb_sanitize_context_t*) const
Line
Count
Source
359
17
  {
360
17
    unsigned int subtable_type = get_type ();
361
17
    TRACE_DISPATCH (this, subtable_type);
362
17
    switch (subtable_type) {
363
17
    case 0: hb_barrier (); return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
364
0
#ifndef HB_NO_AAT_SHAPE
365
0
    case 1: hb_barrier (); return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
366
0
#endif
367
0
    default:  return_trace (c->default_return_value ());
368
17
    }
369
17
  }
370
371
  bool sanitize (hb_sanitize_context_t *c) const
372
17
  {
373
17
    TRACE_SANITIZE (this);
374
17
    if (!u.version32.v.sanitize (c)) return_trace (false);
375
17
    hb_barrier ();
376
17
    return_trace (dispatch (c));
377
17
  }
378
379
  AAT::kern_accelerator_data_t create_accelerator_data (unsigned num_glyphs) const
380
153
  {
381
153
    switch (get_type ()) {
382
153
    case 0: hb_barrier (); return u.ot.create_accelerator_data (num_glyphs);
383
0
#ifndef HB_NO_AAT_SHAPE
384
0
    case 1: hb_barrier (); return u.aat.create_accelerator_data (num_glyphs);
385
0
#endif
386
0
    default:return AAT::kern_accelerator_data_t ();
387
153
    }
388
153
  }
389
390
  struct accelerator_t
391
  {
392
    accelerator_t (hb_face_t *face)
393
153
    {
394
153
      hb_sanitize_context_t sc;
395
153
      this->table = sc.reference_table<kern> (face);
396
153
      this->accel_data = this->table->create_accelerator_data (face->get_num_glyphs ());
397
153
    }
398
    ~accelerator_t ()
399
153
    {
400
153
      this->table.destroy ();
401
153
    }
402
403
3.24k
    hb_blob_t *get_blob () const { return table.get_blob (); }
404
405
    bool apply (AAT::hb_aat_apply_context_t *c) const
406
3.24k
    {
407
3.24k
      return table->apply (c, accel_data);
408
3.24k
    }
409
410
    hb_blob_ptr_t<kern> table;
411
    AAT::kern_accelerator_data_t accel_data;
412
    AAT::hb_aat_scratch_t scratch;
413
  };
414
415
  protected:
416
  union {
417
  struct { HBUINT32 v; }  version32;
418
  struct { HBUINT16 v; }  major;
419
  KernOT    ot;
420
#ifndef HB_NO_AAT_SHAPE
421
  KernAAT   aat;
422
#endif
423
  } u;
424
  public:
425
  DEFINE_SIZE_UNION (4, version32.v);
426
};
427
428
struct kern_accelerator_t : kern::accelerator_t {
429
153
  kern_accelerator_t (hb_face_t *face) : kern::accelerator_t (face) {}
430
};
431
432
} /* namespace OT */
433
434
435
#endif /* HB_OT_KERN_TABLE_HH */