Coverage Report

Created: 2025-07-07 10:01

/work/workdir/UnpackedTarball/harfbuzz/src/hb-ot-kern-table.hh
Line
Count
Source (jump to first uncovered line)
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
    set_t set;
94
0
    if (likely (glyphCount))
95
0
      set.add_range (0, glyphCount - 1);
96
0
    left_set.union_ (set);
97
0
    right_set.union_ (set);
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
23.7M
  unsigned int get_size () const { return u.header.length; }
OT::KernSubTable<OT::KernOTSubTableHeader>::get_size() const
Line
Count
Source
129
23.7M
  unsigned int get_size () const { return u.header.length; }
Unexecuted instantiation: OT::KernSubTable<OT::KernAATSubTableHeader>::get_size() const
130
2.47M
  unsigned int get_type () const { return u.header.format; }
OT::KernSubTable<OT::KernOTSubTableHeader>::get_type() const
Line
Count
Source
130
2.47M
  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
2.46M
  {
144
2.46M
    unsigned int subtable_type = get_type ();
145
2.46M
    TRACE_DISPATCH (this, subtable_type);
146
2.46M
    switch (subtable_type) {
147
2.46M
    case 0: return_trace (c->dispatch (u.format0));
148
0
#ifndef HB_NO_AAT_SHAPE
149
0
    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
150
0
#endif
151
0
    case 2: return_trace (c->dispatch (u.format2));
152
0
#ifndef HB_NO_AAT_SHAPE
153
0
    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
154
0
#endif
155
0
    default:  return_trace (c->default_return_value ());
156
2.46M
    }
157
2.46M
  }
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
2.46M
  {
144
2.46M
    unsigned int subtable_type = get_type ();
145
2.46M
    TRACE_DISPATCH (this, subtable_type);
146
2.46M
    switch (subtable_type) {
147
2.46M
    case 0: return_trace (c->dispatch (u.format0));
148
0
#ifndef HB_NO_AAT_SHAPE
149
0
    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
150
0
#endif
151
0
    case 2: return_trace (c->dispatch (u.format2));
152
0
#ifndef HB_NO_AAT_SHAPE
153
0
    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
154
0
#endif
155
0
    default:  return_trace (c->default_return_value ());
156
2.46M
    }
157
2.46M
  }
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
60
  {
144
60
    unsigned int subtable_type = get_type ();
145
60
    TRACE_DISPATCH (this, subtable_type);
146
60
    switch (subtable_type) {
147
60
    case 0: return_trace (c->dispatch (u.format0));
148
0
#ifndef HB_NO_AAT_SHAPE
149
0
    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
150
0
#endif
151
0
    case 2: return_trace (c->dispatch (u.format2));
152
0
#ifndef HB_NO_AAT_SHAPE
153
0
    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
154
0
#endif
155
0
    default:  return_trace (c->default_return_value ());
156
60
    }
157
60
  }
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
60
  {
162
60
    unsigned int subtable_type = get_type ();
163
60
    switch (subtable_type) {
164
60
    case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return;
165
0
    case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return;
166
0
    case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return;
167
0
    case 3: u.format3.collect_glyphs (left_set, right_set, num_glyphs); return;
168
0
    default:  return;
169
60
    }
170
60
  }
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
60
  {
162
60
    unsigned int subtable_type = get_type ();
163
60
    switch (subtable_type) {
164
60
    case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return;
165
0
    case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return;
166
0
    case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return;
167
0
    case 3: u.format3.collect_glyphs (left_set, right_set, num_glyphs); return;
168
0
    default:  return;
169
60
    }
170
60
  }
Unexecuted instantiation: void OT::KernSubTable<OT::KernAATSubTableHeader>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, hb_bit_set_t&, unsigned int) const
171
172
  bool sanitize (hb_sanitize_context_t *c) const
173
60
  {
174
60
    TRACE_SANITIZE (this);
175
60
    if (unlikely (!(u.header.sanitize (c) &&
176
60
        hb_barrier () &&
177
60
        u.header.length >= u.header.min_size &&
178
60
        c->check_range (this, u.header.length)))) return_trace (false);
179
180
60
    return_trace (dispatch (c));
181
60
  }
OT::KernSubTable<OT::KernOTSubTableHeader>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
173
60
  {
174
60
    TRACE_SANITIZE (this);
175
60
    if (unlikely (!(u.header.sanitize (c) &&
176
60
        hb_barrier () &&
177
60
        u.header.length >= u.header.min_size &&
178
60
        c->check_range (this, u.header.length)))) return_trace (false);
179
180
60
    return_trace (dispatch (c));
181
60
  }
Unexecuted instantiation: OT::KernSubTable<OT::KernAATSubTableHeader>::sanitize(hb_sanitize_context_t*) const
182
183
  public:
184
  union {
185
  KernSubTableHeader        header;
186
  AAT::KerxSubTableFormat0<KernSubTableHeader>  format0;
187
  AAT::KerxSubTableFormat1<KernSubTableHeader>  format1;
188
  AAT::KerxSubTableFormat2<KernSubTableHeader>  format2;
189
  KernSubTableFormat3<KernSubTableHeader> format3;
190
  } u;
191
  public:
192
  DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
193
};
194
195
196
struct KernOTSubTableHeader
197
{
198
  static constexpr bool apple = false;
199
  typedef AAT::ObsoleteTypes Types;
200
201
218k
  unsigned   tuple_count () const { return 0; }
202
23.7M
  bool     is_horizontal () const { return (coverage & Horizontal); }
203
204
  enum Coverage
205
  {
206
    Horizontal  = 0x01u,
207
    Minimum = 0x02u,
208
    CrossStream = 0x04u,
209
    Override  = 0x08u,
210
211
    /* Not supported: */
212
    Backwards = 0x00u,
213
    Variation = 0x00u,
214
  };
215
216
  bool sanitize (hb_sanitize_context_t *c) const
217
120
  {
218
120
    TRACE_SANITIZE (this);
219
120
    return_trace (c->check_struct (this));
220
120
  }
221
222
  public:
223
  HBUINT16  versionZ; /* Unused. */
224
  HBUINT16  length;   /* Length of the subtable (including this header). */
225
  HBUINT8 format;   /* Subtable format. */
226
  HBUINT8 coverage; /* Coverage bits. */
227
  public:
228
  DEFINE_SIZE_STATIC (6);
229
};
230
231
struct KernOT : AAT::KerxTable<KernOT>
232
{
233
  friend struct AAT::KerxTable<KernOT>;
234
235
  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
236
  static constexpr unsigned minVersion = 0u;
237
238
  typedef KernOTSubTableHeader SubTableHeader;
239
  typedef SubTableHeader::Types Types;
240
  typedef KernSubTable<SubTableHeader> SubTable;
241
242
  protected:
243
  HBUINT16  version;  /* Version--0x0000u */
244
  HBUINT16  tableCount; /* Number of subtables in the kerning table. */
245
  SubTable  firstSubTable;  /* Subtables. */
246
  public:
247
  DEFINE_SIZE_MIN (4);
248
};
249
250
251
struct KernAATSubTableHeader
252
{
253
  static constexpr bool apple = true;
254
  typedef AAT::ObsoleteTypes Types;
255
256
0
  unsigned   tuple_count () const { return 0; }
257
0
  bool     is_horizontal () const { return !(coverage & Vertical); }
258
259
  enum Coverage
260
  {
261
    Vertical  = 0x80u,
262
    CrossStream = 0x40u,
263
    Variation = 0x20u,
264
265
    /* Not supported: */
266
    Backwards = 0x00u,
267
  };
268
269
  bool sanitize (hb_sanitize_context_t *c) const
270
0
  {
271
0
    TRACE_SANITIZE (this);
272
0
    return_trace (c->check_struct (this));
273
0
  }
274
275
  public:
276
  HBUINT32  length;   /* Length of the subtable (including this header). */
277
  HBUINT8 coverage; /* Coverage bits. */
278
  HBUINT8 format;   /* Subtable format. */
279
  HBUINT16  tupleIndex; /* The tuple index (used for variations fonts).
280
         * This value specifies which tuple this subtable covers.
281
         * Note: We don't implement. */
282
  public:
283
  DEFINE_SIZE_STATIC (8);
284
};
285
286
struct KernAAT : AAT::KerxTable<KernAAT>
287
{
288
  friend struct AAT::KerxTable<KernAAT>;
289
290
  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
291
  static constexpr unsigned minVersion = 0x00010000u;
292
293
  typedef KernAATSubTableHeader SubTableHeader;
294
  typedef SubTableHeader::Types Types;
295
  typedef KernSubTable<SubTableHeader> SubTable;
296
297
  protected:
298
  HBUINT32  version;  /* Version--0x00010000u */
299
  HBUINT32  tableCount; /* Number of subtables in the kerning table. */
300
  SubTable  firstSubTable;  /* Subtables. */
301
  public:
302
  DEFINE_SIZE_MIN (8);
303
};
304
305
struct kern
306
{
307
  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
308
309
7.86k
  bool     has_data () const { return u.version32; }
310
23.7M
  unsigned get_type () const { return u.major; }
311
312
  bool has_state_machine () const
313
7.55k
  {
314
7.55k
    switch (get_type ()) {
315
7.55k
    case 0: hb_barrier (); return u.ot.has_state_machine ();
316
0
#ifndef HB_NO_AAT_SHAPE
317
0
    case 1: hb_barrier (); return u.aat.has_state_machine ();
318
0
#endif
319
0
    default:return false;
320
7.55k
    }
321
7.55k
  }
322
323
  bool has_cross_stream () const
324
0
  {
325
0
    switch (get_type ()) {
326
0
    case 0: hb_barrier (); return u.ot.has_cross_stream ();
327
0
#ifndef HB_NO_AAT_SHAPE
328
0
    case 1: hb_barrier (); return u.aat.has_cross_stream ();
329
0
#endif
330
0
    default:return false;
331
0
    }
332
0
  }
333
334
  int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
335
0
  {
336
0
    switch (get_type ()) {
337
0
    case 0: hb_barrier (); return u.ot.get_h_kerning (left, right);
338
0
#ifndef HB_NO_AAT_SHAPE
339
0
    case 1: hb_barrier (); return u.aat.get_h_kerning (left, right);
340
0
#endif
341
0
    default:return 0;
342
0
    }
343
0
  }
344
345
  bool apply (AAT::hb_aat_apply_context_t *c,
346
        const AAT::kern_accelerator_data_t &accel_data) const
347
23.7M
  { return dispatch (c, accel_data); }
348
349
  template <typename context_t, typename ...Ts>
350
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
351
23.7M
  {
352
23.7M
    unsigned int subtable_type = get_type ();
353
23.7M
    TRACE_DISPATCH (this, subtable_type);
354
23.7M
    switch (subtable_type) {
355
23.7M
    case 0: return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
356
0
#ifndef HB_NO_AAT_SHAPE
357
0
    case 1: return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
358
0
#endif
359
0
    default:  return_trace (c->default_return_value ());
360
23.7M
    }
361
23.7M
  }
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
351
23.7M
  {
352
23.7M
    unsigned int subtable_type = get_type ();
353
23.7M
    TRACE_DISPATCH (this, subtable_type);
354
23.7M
    switch (subtable_type) {
355
23.7M
    case 0: return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
356
0
#ifndef HB_NO_AAT_SHAPE
357
0
    case 1: return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
358
0
#endif
359
0
    default:  return_trace (c->default_return_value ());
360
23.7M
    }
361
23.7M
  }
hb_sanitize_context_t::return_t OT::kern::dispatch<hb_sanitize_context_t>(hb_sanitize_context_t*) const
Line
Count
Source
351
60
  {
352
60
    unsigned int subtable_type = get_type ();
353
60
    TRACE_DISPATCH (this, subtable_type);
354
60
    switch (subtable_type) {
355
60
    case 0: return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
356
0
#ifndef HB_NO_AAT_SHAPE
357
0
    case 1: return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
358
0
#endif
359
0
    default:  return_trace (c->default_return_value ());
360
60
    }
361
60
  }
362
363
  bool sanitize (hb_sanitize_context_t *c) const
364
60
  {
365
60
    TRACE_SANITIZE (this);
366
60
    if (!u.version32.sanitize (c)) return_trace (false);
367
60
    hb_barrier ();
368
60
    return_trace (dispatch (c));
369
60
  }
370
371
  AAT::kern_accelerator_data_t create_accelerator_data (unsigned num_glyphs) const
372
60
  {
373
60
    switch (get_type ()) {
374
60
    case 0: hb_barrier (); return u.ot.create_accelerator_data (num_glyphs);
375
0
#ifndef HB_NO_AAT_SHAPE
376
0
    case 1: hb_barrier (); return u.aat.create_accelerator_data (num_glyphs);
377
0
#endif
378
0
    default:return AAT::kern_accelerator_data_t ();
379
60
    }
380
60
  }
381
382
  struct accelerator_t
383
  {
384
    accelerator_t (hb_face_t *face)
385
60
    {
386
60
      hb_sanitize_context_t sc;
387
60
      this->table = sc.reference_table<kern> (face);
388
60
      this->accel_data = this->table->create_accelerator_data (face->get_num_glyphs ());
389
60
    }
390
    ~accelerator_t ()
391
0
    {
392
0
      this->table.destroy ();
393
0
    }
394
395
23.7M
    hb_blob_t *get_blob () const { return table.get_blob (); }
396
397
    bool apply (AAT::hb_aat_apply_context_t *c) const
398
23.7M
    {
399
23.7M
      return table->apply (c, accel_data);
400
23.7M
    }
401
402
    hb_blob_ptr_t<kern> table;
403
    AAT::kern_accelerator_data_t accel_data;
404
    AAT::hb_aat_scratch_t scratch;
405
  };
406
407
  protected:
408
  union {
409
  HBUINT32    version32;
410
  HBUINT16    major;
411
  KernOT    ot;
412
#ifndef HB_NO_AAT_SHAPE
413
  KernAAT   aat;
414
#endif
415
  } u;
416
  public:
417
  DEFINE_SIZE_UNION (4, version32);
418
};
419
420
struct kern_accelerator_t : kern::accelerator_t {
421
60
  kern_accelerator_t (hb_face_t *face) : kern::accelerator_t (face) {}
422
};
423
424
} /* namespace OT */
425
426
427
#endif /* HB_OT_KERN_TABLE_HH */