Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/workdir/UnpackedTarball/harfbuzz/src/hb-aat-layout-common.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_AAT_LAYOUT_COMMON_HH
28
#define HB_AAT_LAYOUT_COMMON_HH
29
30
#include "hb-aat-layout.hh"
31
#include "hb-aat-map.hh"
32
#include "hb-ot-layout-common.hh"
33
#include "hb-ot-layout-gdef-table.hh"
34
#include "hb-open-type.hh"
35
#include "hb-cache.hh"
36
#include "hb-bit-set.hh"
37
#include "hb-bit-page.hh"
38
39
40
namespace OT {
41
struct GDEF;
42
};
43
44
namespace AAT {
45
46
using namespace OT;
47
48
struct ankr;
49
50
using hb_aat_class_cache_t = hb_ot_layout_mapping_cache_t;
51
52
struct hb_aat_scratch_t
53
{
54
472
  hb_aat_scratch_t () = default;
55
  hb_aat_scratch_t (const hb_aat_scratch_t &) = delete;
56
57
  hb_aat_scratch_t (hb_aat_scratch_t &&o)
58
0
  {
59
0
    buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ());
60
0
    o.buffer_glyph_set.set_relaxed (nullptr);
61
0
  }
62
  hb_aat_scratch_t & operator = (hb_aat_scratch_t &&o)
63
118
  {
64
118
    buffer_glyph_set.set_relaxed (o.buffer_glyph_set.get_relaxed ());
65
118
    o.buffer_glyph_set.set_relaxed (nullptr);
66
118
    return *this;
67
118
  }
68
  ~hb_aat_scratch_t ()
69
118
  {
70
118
    auto *s = buffer_glyph_set.get_relaxed ();
71
118
    if (unlikely (!s))
72
118
      return;
73
0
    s->fini ();
74
0
    hb_free (s);
75
0
  }
76
77
  hb_bit_set_t *create_buffer_glyph_set () const
78
21.0M
  {
79
21.0M
    hb_bit_set_t *s = buffer_glyph_set.get_acquire ();
80
21.0M
    if (s && buffer_glyph_set.cmpexch (s, nullptr))
81
21.0M
    {
82
21.0M
      s->clear ();
83
21.0M
      return s;
84
21.0M
    }
85
86
59
    s = (hb_bit_set_t *) hb_calloc (1, sizeof (hb_bit_set_t));
87
59
    if (unlikely (!s))
88
0
      return nullptr;
89
59
    s->init ();
90
91
59
    return s;
92
59
  }
93
  void destroy_buffer_glyph_set (hb_bit_set_t *s) const
94
21.0M
  {
95
21.0M
    if (unlikely (!s))
96
0
      return;
97
21.0M
    if (buffer_glyph_set.cmpexch (nullptr, s))
98
21.0M
      return;
99
0
    s->fini ();
100
0
    hb_free (s);
101
0
  }
102
103
  mutable hb_atomic_t<hb_bit_set_t *> buffer_glyph_set;
104
};
105
106
enum { DELETED_GLYPH = 0xFFFF };
107
108
0
#define HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED HB_BUFFER_SCRATCH_FLAG_SHAPER0
109
110
struct hb_aat_apply_context_t :
111
       hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
112
{
113
0
  const char *get_name () { return "APPLY"; }
114
  template <typename T, typename ...Ts>
115
  return_t dispatch (const T &obj, Ts&&... ds)
116
23.1M
  { return obj.apply (this, std::forward<Ts> (ds)...); }
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::RearrangementSubtable<AAT::ExtendedTypes>>(AAT::RearrangementSubtable<AAT::ExtendedTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::ContextualSubtable<AAT::ExtendedTypes>>(AAT::ContextualSubtable<AAT::ExtendedTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::LigatureSubtable<AAT::ExtendedTypes>>(AAT::LigatureSubtable<AAT::ExtendedTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::NoncontextualSubtable<AAT::ExtendedTypes>>(AAT::NoncontextualSubtable<AAT::ExtendedTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::InsertionSubtable<AAT::ExtendedTypes>>(AAT::InsertionSubtable<AAT::ExtendedTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::RearrangementSubtable<AAT::ObsoleteTypes>>(AAT::RearrangementSubtable<AAT::ObsoleteTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::ContextualSubtable<AAT::ObsoleteTypes>>(AAT::ContextualSubtable<AAT::ObsoleteTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::LigatureSubtable<AAT::ObsoleteTypes>>(AAT::LigatureSubtable<AAT::ObsoleteTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::NoncontextualSubtable<AAT::ObsoleteTypes>>(AAT::NoncontextualSubtable<AAT::ObsoleteTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::InsertionSubtable<AAT::ObsoleteTypes>>(AAT::InsertionSubtable<AAT::ObsoleteTypes> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat0<AAT::KerxSubTableHeader>>(AAT::KerxSubTableFormat0<AAT::KerxSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader>>(AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat2<AAT::KerxSubTableHeader>>(AAT::KerxSubTableFormat2<AAT::KerxSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>>(AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat6<AAT::KerxSubTableHeader>>(AAT::KerxSubTableFormat6<AAT::KerxSubTableHeader> const&)
bool AAT::hb_aat_apply_context_t::dispatch<OT::KernOT, AAT::kern_accelerator_data_t const&>(OT::KernOT const&, AAT::kern_accelerator_data_t const&)
Line
Count
Source
116
21.0M
  { return obj.apply (this, std::forward<Ts> (ds)...); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat0<OT::KernOTSubTableHeader>>(AAT::KerxSubTableFormat0<OT::KernOTSubTableHeader> const&)
Line
Count
Source
116
2.11M
  { return obj.apply (this, std::forward<Ts> (ds)...); }
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader>>(AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat2<OT::KernOTSubTableHeader>>(AAT::KerxSubTableFormat2<OT::KernOTSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<OT::KernSubTableFormat3<OT::KernOTSubTableHeader>>(OT::KernSubTableFormat3<OT::KernOTSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<OT::KernAAT, AAT::kern_accelerator_data_t const&>(OT::KernAAT const&, AAT::kern_accelerator_data_t const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat0<OT::KernAATSubTableHeader>>(AAT::KerxSubTableFormat0<OT::KernAATSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader>>(AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat2<OT::KernAATSubTableHeader>>(AAT::KerxSubTableFormat2<OT::KernAATSubTableHeader> const&)
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<OT::KernSubTableFormat3<OT::KernAATSubTableHeader>>(OT::KernSubTableFormat3<OT::KernAATSubTableHeader> const&)
117
0
  static return_t default_return_value () { return false; }
118
0
  bool stop_sublookup_iteration (return_t r) const { return r; }
119
120
  const hb_ot_shape_plan_t *plan;
121
  hb_font_t *font;
122
  hb_face_t *face;
123
  hb_buffer_t *buffer;
124
  hb_sanitize_context_t sanitizer;
125
  const ankr *ankr_table;
126
  const OT::GDEF &gdef;
127
  bool has_glyph_classes;
128
  const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr;
129
  hb_mask_t subtable_flags = 0;
130
  bool buffer_is_reversed = false;
131
  // Caches
132
  bool using_buffer_glyph_set = false;
133
  hb_bit_set_t *buffer_glyph_set = nullptr;
134
  const hb_bit_set_t *first_set = nullptr;
135
  const hb_bit_set_t *second_set = nullptr;
136
  hb_aat_class_cache_t *machine_class_cache = nullptr;
137
138
  /* Unused. For debug tracing only. */
139
  unsigned int lookup_index;
140
141
  HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
142
              hb_font_t *font_,
143
              hb_buffer_t *buffer_,
144
              hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t)));
145
146
  HB_INTERNAL ~hb_aat_apply_context_t ();
147
148
  HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
149
150
42.0M
  void set_lookup_index (unsigned int i) { lookup_index = i; }
151
152
  void reverse_buffer ()
153
35.2k
  {
154
35.2k
    buffer->reverse ();
155
35.2k
    buffer_is_reversed = !buffer_is_reversed;
156
35.2k
  }
157
158
  void setup_buffer_glyph_set ()
159
21.0M
  {
160
21.0M
    using_buffer_glyph_set = buffer->len >= 4 && buffer_glyph_set;
161
162
21.0M
    if (likely (using_buffer_glyph_set))
163
2.56M
      buffer->collect_codepoints (*buffer_glyph_set);
164
21.0M
  }
165
  bool buffer_intersects_machine () const
166
19.4M
  {
167
19.4M
    if (likely (using_buffer_glyph_set))
168
2.47M
      return buffer_glyph_set->intersects (*first_set);
169
170
    // Faster for shorter buffers.
171
36.0M
    for (unsigned i = 0; i < buffer->len; i++)
172
20.2M
      if (first_set->has (buffer->info[i].codepoint))
173
1.12M
  return true;
174
15.8M
    return false;
175
16.9M
  }
176
177
  template <typename T>
178
  HB_NODISCARD bool output_glyphs (unsigned int count,
179
           const T *glyphs)
180
0
  {
181
0
    if (likely (using_buffer_glyph_set))
182
0
      buffer_glyph_set->add_array (glyphs, count);
183
0
    for (unsigned int i = 0; i < count; i++)
184
0
    {
185
0
      if (glyphs[i] == DELETED_GLYPH)
186
0
      {
187
0
        buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED;
188
0
  _hb_glyph_info_set_aat_deleted (&buffer->cur());
189
0
      }
190
0
      else
191
0
      {
192
0
#ifndef HB_NO_OT_LAYOUT
193
0
  if (has_glyph_classes)
194
0
    _hb_glyph_info_set_glyph_props (&buffer->cur(),
195
0
            gdef.get_glyph_props (glyphs[i]));
196
0
#endif
197
0
      }
198
0
      if (unlikely (!buffer->output_glyph (glyphs[i]))) return false;
199
0
    }
200
0
    return true;
201
0
  }
202
203
  HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph)
204
0
  {
205
0
    if (glyph == DELETED_GLYPH)
206
0
    {
207
0
      buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED;
208
0
      _hb_glyph_info_set_aat_deleted (&buffer->cur());
209
0
    }
210
211
0
    if (likely (using_buffer_glyph_set))
212
0
      buffer_glyph_set->add (glyph);
213
0
#ifndef HB_NO_OT_LAYOUT
214
0
    if (has_glyph_classes)
215
0
      _hb_glyph_info_set_glyph_props (&buffer->cur(),
216
0
              gdef.get_glyph_props (glyph));
217
0
#endif
218
0
    return buffer->replace_glyph (glyph);
219
0
  }
220
221
  HB_NODISCARD bool delete_glyph ()
222
0
  {
223
0
    buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED;
224
0
    _hb_glyph_info_set_aat_deleted (&buffer->cur());
225
0
    return buffer->replace_glyph (DELETED_GLYPH);
226
0
  }
227
228
  void replace_glyph_inplace (unsigned i, hb_codepoint_t glyph)
229
0
  {
230
0
    buffer->info[i].codepoint = glyph;
231
0
    if (likely (using_buffer_glyph_set))
232
0
      buffer_glyph_set->add (glyph);
233
0
#ifndef HB_NO_OT_LAYOUT
234
0
    if (has_glyph_classes)
235
0
      _hb_glyph_info_set_glyph_props (&buffer->info[i],
236
0
              gdef.get_glyph_props (glyph));
237
0
#endif
238
0
  }
239
};
240
241
242
/*
243
 * Lookup Table
244
 */
245
246
template <typename T> struct Lookup;
247
248
template <typename T>
249
struct LookupFormat0
250
{
251
  friend struct Lookup<T>;
252
253
  private:
254
  const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
255
0
  {
256
0
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
257
0
    return &arrayZ[glyph_id];
258
0
  }
Unexecuted instantiation: AAT::LookupFormat0<OT::NumType<true, unsigned short, 2u> >::get_value(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::LookupFormat0<OT::HBGlyphID16>::get_value(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::LookupFormat0<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::get_value(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::LookupFormat0<OT::NumType<true, unsigned int, 4u> >::get_value(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::LookupFormat0<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::get_value(unsigned int, unsigned int) const
259
260
  template <typename set_t>
261
  void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const
262
0
  {
263
0
    glyphs.add_range (0, num_glyphs - 1);
264
0
  }
Unexecuted instantiation: void AAT::LookupFormat0<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, unsigned int) const
Unexecuted instantiation: void AAT::LookupFormat0<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, unsigned int) const
Unexecuted instantiation: void AAT::LookupFormat0<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, unsigned int) const
265
  template <typename set_t, typename filter_t>
266
  void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const
267
0
  {
268
0
    for (unsigned i = 0; i < num_glyphs; i++)
269
0
      if (filter (arrayZ[i]))
270
0
  glyphs.add (i);
271
0
  }
272
273
  bool sanitize (hb_sanitize_context_t *c) const
274
0
  {
275
0
    TRACE_SANITIZE (this);
276
0
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
277
0
  }
Unexecuted instantiation: AAT::LookupFormat0<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat0<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat0<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
278
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
279
0
  {
280
0
    TRACE_SANITIZE (this);
281
0
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs (), base));
282
0
  }
Unexecuted instantiation: AAT::LookupFormat0<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat0<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat0<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
283
284
  protected:
285
  HBUINT16  format;   /* Format identifier--format = 0 */
286
  UnsizedArrayOf<T>
287
    arrayZ;   /* Array of lookup values, indexed by glyph index. */
288
  public:
289
  DEFINE_SIZE_UNBOUNDED (2);
290
};
291
292
293
template <typename T>
294
struct LookupSegmentSingle
295
{
296
  static constexpr unsigned TerminationWordCount = 2u;
297
298
  int cmp (hb_codepoint_t g) const
299
0
  { return g < first ? -1 : g <= last ? 0 : +1 ; }
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::NumType<true, unsigned short, 2u> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::HBGlyphID16>::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::NumType<true, unsigned int, 4u> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::cmp(unsigned int) const
300
301
  template <typename set_t>
302
  void collect_glyphs (set_t &glyphs) const
303
0
  {
304
0
    if (first == DELETED_GLYPH) return;
305
0
    glyphs.add_range (first, last);
306
0
  }
Unexecuted instantiation: void AAT::LookupSegmentSingle<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupSegmentSingle<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupSegmentSingle<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
307
  template <typename set_t, typename filter_t>
308
  void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
309
0
  {
310
0
    if (first == DELETED_GLYPH) return;
311
0
    if (!filter (value)) return;
312
0
    glyphs.add_range (first, last);
313
0
  }
314
315
  bool sanitize (hb_sanitize_context_t *c) const
316
0
  {
317
0
    TRACE_SANITIZE (this);
318
0
    return_trace (c->check_struct (this) && value.sanitize (c));
319
0
  }
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
320
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
321
0
  {
322
0
    TRACE_SANITIZE (this);
323
0
    return_trace (c->check_struct (this) && value.sanitize (c, base));
324
0
  }
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
325
326
  HBGlyphID16 last;   /* Last GlyphID in this segment */
327
  HBGlyphID16 first;    /* First GlyphID in this segment */
328
  T   value;    /* The lookup value (only one) */
329
  public:
330
  DEFINE_SIZE_STATIC (4 + T::static_size);
331
};
332
333
template <typename T>
334
struct LookupFormat2
335
{
336
  friend struct Lookup<T>;
337
338
  private:
339
  const T* get_value (hb_codepoint_t glyph_id) const
340
0
  {
341
0
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
342
0
    return v ? &v->value : nullptr;
343
0
  }
Unexecuted instantiation: AAT::LookupFormat2<OT::NumType<true, unsigned short, 2u> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat2<OT::HBGlyphID16>::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat2<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat2<OT::NumType<true, unsigned int, 4u> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat2<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::get_value(unsigned int) const
344
345
  template <typename set_t>
346
  void collect_glyphs (set_t &glyphs) const
347
0
  {
348
0
    unsigned count = segments.get_length ();
349
0
    for (unsigned int i = 0; i < count; i++)
350
0
      segments[i].collect_glyphs (glyphs);
351
0
  }
Unexecuted instantiation: void AAT::LookupFormat2<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat2<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat2<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
352
  template <typename set_t, typename filter_t>
353
  void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
354
0
  {
355
0
    unsigned count = segments.get_length ();
356
0
    for (unsigned int i = 0; i < count; i++)
357
0
      segments[i].collect_glyphs_filtered (glyphs, filter);
358
0
  }
359
360
  bool sanitize (hb_sanitize_context_t *c) const
361
0
  {
362
0
    TRACE_SANITIZE (this);
363
0
    return_trace (segments.sanitize (c));
364
0
  }
Unexecuted instantiation: AAT::LookupFormat2<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat2<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat2<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
365
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
366
0
  {
367
0
    TRACE_SANITIZE (this);
368
0
    return_trace (segments.sanitize (c, base));
369
0
  }
Unexecuted instantiation: AAT::LookupFormat2<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat2<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat2<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
370
371
  protected:
372
  HBUINT16  format;   /* Format identifier--format = 2 */
373
  VarSizedBinSearchArrayOf<LookupSegmentSingle<T>>
374
    segments; /* The actual segments. These must already be sorted,
375
         * according to the first word in each one (the last
376
         * glyph in each segment). */
377
  public:
378
  DEFINE_SIZE_ARRAY (8, segments);
379
};
380
381
template <typename T>
382
struct LookupSegmentArray
383
{
384
  static constexpr unsigned TerminationWordCount = 2u;
385
386
  const T* get_value (hb_codepoint_t glyph_id, const void *base) const
387
0
  {
388
0
    return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
389
0
  }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::NumType<true, unsigned short, 2u> >::get_value(unsigned int, void const*) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::HBGlyphID16>::get_value(unsigned int, void const*) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::get_value(unsigned int, void const*) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::NumType<true, unsigned int, 4u> >::get_value(unsigned int, void const*) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::get_value(unsigned int, void const*) const
390
391
  template <typename set_t>
392
  void collect_glyphs (set_t &glyphs) const
393
0
  {
394
0
    if (first == DELETED_GLYPH) return;
395
0
    glyphs.add_range (first, last);
396
0
  }
Unexecuted instantiation: void AAT::LookupSegmentArray<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupSegmentArray<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupSegmentArray<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
397
  template <typename set_t, typename filter_t>
398
  void collect_glyphs_filtered (set_t &glyphs, const void *base, const filter_t &filter) const
399
0
  {
400
0
    if (first == DELETED_GLYPH) return;
401
0
    const auto &values = base+valuesZ;
402
0
    for (hb_codepoint_t i = first; i <= last; i++)
403
0
      if (filter (values[i - first]))
404
0
  glyphs.add (i);
405
0
  }
406
407
  int cmp (hb_codepoint_t g) const
408
0
  { return g < first ? -1 : g <= last ? 0 : +1; }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::NumType<true, unsigned short, 2u> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::HBGlyphID16>::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::NumType<true, unsigned int, 4u> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::cmp(unsigned int) const
409
410
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
411
0
  {
412
0
    TRACE_SANITIZE (this);
413
0
    return_trace (c->check_struct (this) &&
414
0
      hb_barrier () &&
415
0
      first <= last &&
416
0
      valuesZ.sanitize (c, base, last - first + 1));
417
0
  }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupSegmentArray<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*, void const*) const
418
  template <typename ...Ts>
419
  bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
420
0
  {
421
0
    TRACE_SANITIZE (this);
422
0
    return_trace (c->check_struct (this) &&
423
0
      hb_barrier () &&
424
0
      first <= last &&
425
0
      valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...));
426
0
  }
Unexecuted instantiation: bool AAT::LookupSegmentArray<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize<void const*&>(hb_sanitize_context_t*, void const*, void const*&) const
Unexecuted instantiation: bool AAT::LookupSegmentArray<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize<void const*&>(hb_sanitize_context_t*, void const*, void const*&) const
Unexecuted instantiation: bool AAT::LookupSegmentArray<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize<void const*&>(hb_sanitize_context_t*, void const*, void const*&) const
427
428
  HBGlyphID16 last;   /* Last GlyphID in this segment */
429
  HBGlyphID16 first;    /* First GlyphID in this segment */
430
  NNOffset16To<UnsizedArrayOf<T>>
431
    valuesZ;  /* A 16-bit offset from the start of
432
         * the table to the data. */
433
  public:
434
  DEFINE_SIZE_STATIC (6);
435
};
436
437
template <typename T>
438
struct LookupFormat4
439
{
440
  friend struct Lookup<T>;
441
442
  private:
443
  const T* get_value (hb_codepoint_t glyph_id) const
444
0
  {
445
0
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
446
0
    return v ? v->get_value (glyph_id, this) : nullptr;
447
0
  }
Unexecuted instantiation: AAT::LookupFormat4<OT::NumType<true, unsigned short, 2u> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat4<OT::HBGlyphID16>::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat4<OT::NumType<true, unsigned int, 4u> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::get_value(unsigned int) const
448
449
  template <typename set_t>
450
  void collect_glyphs (set_t &glyphs) const
451
0
  {
452
0
    unsigned count = segments.get_length ();
453
0
    for (unsigned i = 0; i < count; i++)
454
0
      segments[i].collect_glyphs (glyphs);
455
0
  }
Unexecuted instantiation: void AAT::LookupFormat4<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat4<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat4<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
456
  template <typename set_t, typename filter_t>
457
  void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
458
0
  {
459
0
    unsigned count = segments.get_length ();
460
0
    for (unsigned i = 0; i < count; i++)
461
0
      segments[i].collect_glyphs_filtered (glyphs, this, filter);
462
0
  }
463
464
  bool sanitize (hb_sanitize_context_t *c) const
465
0
  {
466
0
    TRACE_SANITIZE (this);
467
0
    return_trace (segments.sanitize (c, this));
468
0
  }
Unexecuted instantiation: AAT::LookupFormat4<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat4<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat4<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
469
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
470
0
  {
471
0
    TRACE_SANITIZE (this);
472
0
    return_trace (segments.sanitize (c, this, base));
473
0
  }
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
474
475
  protected:
476
  HBUINT16  format;   /* Format identifier--format = 4 */
477
  VarSizedBinSearchArrayOf<LookupSegmentArray<T>>
478
    segments; /* The actual segments. These must already be sorted,
479
         * according to the first word in each one (the last
480
         * glyph in each segment). */
481
  public:
482
  DEFINE_SIZE_ARRAY (8, segments);
483
};
484
485
template <typename T>
486
struct LookupSingle
487
{
488
  static constexpr unsigned TerminationWordCount = 1u;
489
490
0
  int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
Unexecuted instantiation: AAT::LookupSingle<OT::NumType<true, unsigned short, 2u> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSingle<OT::HBGlyphID16>::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSingle<OT::NumType<true, unsigned int, 4u> >::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::cmp(unsigned int) const
491
492
  template <typename set_t>
493
  void collect_glyphs (set_t &glyphs) const
494
0
  {
495
0
    if (glyph == DELETED_GLYPH) return;
496
0
    glyphs.add (glyph);
497
0
  }
Unexecuted instantiation: void AAT::LookupSingle<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupSingle<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupSingle<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
498
  template <typename set_t, typename filter_t>
499
  void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
500
0
  {
501
0
    if (glyph == DELETED_GLYPH) return;
502
0
    if (!filter (value)) return;
503
0
    glyphs.add (glyph);
504
0
  }
505
506
  bool sanitize (hb_sanitize_context_t *c) const
507
0
  {
508
0
    TRACE_SANITIZE (this);
509
0
    return_trace (c->check_struct (this) && value.sanitize (c));
510
0
  }
Unexecuted instantiation: AAT::LookupSingle<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupSingle<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupSingle<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
511
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
512
0
  {
513
0
    TRACE_SANITIZE (this);
514
0
    return_trace (c->check_struct (this) && value.sanitize (c, base));
515
0
  }
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
516
517
  HBGlyphID16 glyph;    /* Last GlyphID */
518
  T   value;    /* The lookup value (only one) */
519
  public:
520
  DEFINE_SIZE_STATIC (2 + T::static_size);
521
};
522
523
template <typename T>
524
struct LookupFormat6
525
{
526
  friend struct Lookup<T>;
527
528
  private:
529
  const T* get_value (hb_codepoint_t glyph_id) const
530
0
  {
531
0
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
532
0
    return v ? &v->value : nullptr;
533
0
  }
Unexecuted instantiation: AAT::LookupFormat6<OT::NumType<true, unsigned short, 2u> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat6<OT::HBGlyphID16>::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat6<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat6<OT::NumType<true, unsigned int, 4u> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat6<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::get_value(unsigned int) const
534
535
  template <typename set_t>
536
  void collect_glyphs (set_t &glyphs) const
537
0
  {
538
0
    unsigned count = entries.get_length ();
539
0
    for (unsigned i = 0; i < count; i++)
540
0
      entries[i].collect_glyphs (glyphs);
541
0
  }
Unexecuted instantiation: void AAT::LookupFormat6<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat6<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat6<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
542
  template <typename set_t, typename filter_t>
543
  void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
544
0
  {
545
0
    unsigned count = entries.get_length ();
546
0
    for (unsigned i = 0; i < count; i++)
547
0
      entries[i].collect_glyphs_filtered (glyphs, filter);
548
0
  }
549
550
  bool sanitize (hb_sanitize_context_t *c) const
551
0
  {
552
0
    TRACE_SANITIZE (this);
553
0
    return_trace (entries.sanitize (c));
554
0
  }
Unexecuted instantiation: AAT::LookupFormat6<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat6<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat6<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
555
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
556
0
  {
557
0
    TRACE_SANITIZE (this);
558
0
    return_trace (entries.sanitize (c, base));
559
0
  }
Unexecuted instantiation: AAT::LookupFormat6<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat6<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat6<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
560
561
  protected:
562
  HBUINT16  format;   /* Format identifier--format = 6 */
563
  VarSizedBinSearchArrayOf<LookupSingle<T>>
564
    entries;  /* The actual entries, sorted by glyph index. */
565
  public:
566
  DEFINE_SIZE_ARRAY (8, entries);
567
};
568
569
template <typename T>
570
struct LookupFormat8
571
{
572
  friend struct Lookup<T>;
573
574
  private:
575
  const T* get_value (hb_codepoint_t glyph_id) const
576
0
  {
577
0
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
578
0
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
579
0
  }
Unexecuted instantiation: AAT::LookupFormat8<OT::NumType<true, unsigned short, 2u> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat8<OT::HBGlyphID16>::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat8<OT::NumType<true, unsigned int, 4u> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::get_value(unsigned int) const
580
581
  template <typename set_t>
582
  void collect_glyphs (set_t &glyphs) const
583
0
  {
584
0
    if (unlikely (!glyphCount)) return;
585
0
    if (firstGlyph == DELETED_GLYPH) return;
586
0
    glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1);
587
0
  }
Unexecuted instantiation: void AAT::LookupFormat8<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat8<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat8<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
588
  template <typename set_t, typename filter_t>
589
  void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
590
0
  {
591
0
    if (unlikely (!glyphCount)) return;
592
0
    if (firstGlyph == DELETED_GLYPH) return;
593
0
    const T *p = valueArrayZ.arrayZ;
594
0
    for (unsigned i = 0; i < glyphCount; i++)
595
0
      if (filter (p[i]))
596
0
  glyphs.add (firstGlyph + i);
597
0
  }
598
599
  bool sanitize (hb_sanitize_context_t *c) const
600
0
  {
601
0
    TRACE_SANITIZE (this);
602
0
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
603
0
  }
Unexecuted instantiation: AAT::LookupFormat8<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat8<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat8<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
604
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
605
0
  {
606
0
    TRACE_SANITIZE (this);
607
0
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount, base));
608
0
  }
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
609
610
  protected:
611
  HBUINT16  format;   /* Format identifier--format = 8 */
612
  HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
613
  HBUINT16  glyphCount; /* Total number of glyphs (equivalent to the last
614
         * glyph minus the value of firstGlyph plus 1). */
615
  UnsizedArrayOf<T>
616
    valueArrayZ;  /* The lookup values (indexed by the glyph index
617
         * minus the value of firstGlyph). */
618
  public:
619
  DEFINE_SIZE_ARRAY (6, valueArrayZ);
620
};
621
622
template <typename T>
623
struct LookupFormat10
624
{
625
  friend struct Lookup<T>;
626
627
  private:
628
  const typename T::type get_value_or_null (hb_codepoint_t glyph_id) const
629
0
  {
630
0
    if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
631
0
      return Null (T);
632
633
0
    const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
634
635
0
    unsigned int v = 0;
636
0
    unsigned int count = valueSize;
637
0
    for (unsigned int i = 0; i < count; i++)
638
0
      v = (v << 8) | *p++;
639
640
0
    return v;
641
0
  }
Unexecuted instantiation: AAT::LookupFormat10<OT::NumType<true, unsigned int, 4u> >::get_value_or_null(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat10<OT::NumType<true, unsigned short, 2u> >::get_value_or_null(unsigned int) const
642
643
  template <typename set_t>
644
  void collect_glyphs (set_t &glyphs) const
645
0
  {
646
0
    if (unlikely (!glyphCount)) return;
647
0
    if (firstGlyph == DELETED_GLYPH) return;
648
0
    glyphs.add_range (firstGlyph, firstGlyph + glyphCount - 1);
649
0
  }
Unexecuted instantiation: void AAT::LookupFormat10<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat10<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
Unexecuted instantiation: void AAT::LookupFormat10<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&) const
650
651
  template <typename set_t, typename filter_t>
652
  void collect_glyphs_filtered (set_t &glyphs, const filter_t &filter) const
653
0
  {
654
0
    if (unlikely (!glyphCount)) return;
655
0
    if (firstGlyph == DELETED_GLYPH) return;
656
0
    const HBUINT8 *p = valueArrayZ.arrayZ;
657
0
    for (unsigned i = 0; i < glyphCount; i++)
658
0
    {
659
0
      unsigned int v = 0;
660
0
      unsigned int count = valueSize;
661
0
      for (unsigned int j = 0; j < count; j++)
662
0
  v = (v << 8) | *p++;
663
0
      if (filter (v))
664
0
  glyphs.add (firstGlyph + i);
665
0
    }
666
0
  }
667
668
  bool sanitize (hb_sanitize_context_t *c) const
669
0
  {
670
0
    TRACE_SANITIZE (this);
671
0
    return_trace (c->check_struct (this) &&
672
0
      hb_barrier () &&
673
0
      valueSize <= 4 &&
674
0
      valueArrayZ.sanitize (c, glyphCount * valueSize));
675
0
  }
Unexecuted instantiation: AAT::LookupFormat10<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat10<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::LookupFormat10<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
676
677
  protected:
678
  HBUINT16  format;   /* Format identifier--format = 8 */
679
  HBUINT16  valueSize;  /* Byte size of each value. */
680
  HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
681
  HBUINT16  glyphCount; /* Total number of glyphs (equivalent to the last
682
         * glyph minus the value of firstGlyph plus 1). */
683
  UnsizedArrayOf<HBUINT8>
684
    valueArrayZ;  /* The lookup values (indexed by the glyph index
685
         * minus the value of firstGlyph). */
686
  public:
687
  DEFINE_SIZE_ARRAY (8, valueArrayZ);
688
};
689
690
template <typename T>
691
struct Lookup
692
{
693
  const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
694
0
  {
695
0
    switch (u.format) {
696
0
    case 0: hb_barrier (); return u.format0.get_value (glyph_id, num_glyphs);
697
0
    case 2: hb_barrier (); return u.format2.get_value (glyph_id);
698
0
    case 4: hb_barrier (); return u.format4.get_value (glyph_id);
699
0
    case 6: hb_barrier (); return u.format6.get_value (glyph_id);
700
0
    case 8: hb_barrier (); return u.format8.get_value (glyph_id);
701
0
    default:return nullptr;
702
0
    }
703
0
  }
Unexecuted instantiation: AAT::Lookup<OT::NumType<true, unsigned short, 2u> >::get_value(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::Lookup<OT::HBGlyphID16>::get_value(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::Lookup<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::get_value(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::Lookup<OT::NumType<true, unsigned int, 4u> >::get_value(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::Lookup<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::get_value(unsigned int, unsigned int) const
704
705
  const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
706
0
  {
707
0
    switch (u.format) {
708
      /* Format 10 cannot return a pointer. */
709
0
      case 10: hb_barrier (); return u.format10.get_value_or_null (glyph_id);
710
0
      default:
711
0
      const T *v = get_value (glyph_id, num_glyphs);
712
0
      return v ? *v : Null (T);
713
0
    }
714
0
  }
Unexecuted instantiation: AAT::Lookup<OT::NumType<true, unsigned int, 4u> >::get_value_or_null(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::Lookup<OT::NumType<true, unsigned short, 2u> >::get_value_or_null(unsigned int, unsigned int) const
715
716
  template <typename set_t>
717
  void collect_glyphs (set_t &glyphs, unsigned int num_glyphs) const
718
0
  {
719
0
    switch (u.format) {
720
0
    case 0: hb_barrier (); u.format0.collect_glyphs (glyphs, num_glyphs); return;
721
0
    case 2: hb_barrier (); u.format2.collect_glyphs (glyphs); return;
722
0
    case 4: hb_barrier (); u.format4.collect_glyphs (glyphs); return;
723
0
    case 6: hb_barrier (); u.format6.collect_glyphs (glyphs); return;
724
0
    case 8: hb_barrier (); u.format8.collect_glyphs (glyphs); return;
725
0
    case 10: hb_barrier (); u.format10.collect_glyphs (glyphs); return;
726
0
    default:return;
727
0
    }
728
0
  }
Unexecuted instantiation: void AAT::Lookup<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, unsigned int) const
Unexecuted instantiation: void AAT::Lookup<OT::HBGlyphID16>::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, unsigned int) const
Unexecuted instantiation: void AAT::Lookup<OT::NumType<true, unsigned int, 4u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, unsigned int) const
729
  template <typename set_t, typename filter_t>
730
  void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const
731
0
  {
732
0
    switch (u.format) {
733
0
    case 0: hb_barrier (); u.format0.collect_glyphs_filtered (glyphs, num_glyphs, filter); return;
734
0
    case 2: hb_barrier (); u.format2.collect_glyphs_filtered (glyphs, filter); return;
735
0
    case 4: hb_barrier (); u.format4.collect_glyphs_filtered (glyphs, filter); return;
736
0
    case 6: hb_barrier (); u.format6.collect_glyphs_filtered (glyphs, filter); return;
737
0
    case 8: hb_barrier (); u.format8.collect_glyphs_filtered (glyphs, filter); return;
738
0
    case 10: hb_barrier (); u.format10.collect_glyphs_filtered (glyphs, filter); return;
739
0
    default:return;
740
0
    }
741
0
  }
742
743
  typename T::type get_class (hb_codepoint_t glyph_id,
744
            unsigned int num_glyphs,
745
            unsigned int outOfRange) const
746
0
  {
747
0
    const T *v = get_value (glyph_id, num_glyphs);
748
0
    return v ? *v : outOfRange;
749
0
  }
750
751
  bool sanitize (hb_sanitize_context_t *c) const
752
0
  {
753
0
    TRACE_SANITIZE (this);
754
0
    if (!u.format.sanitize (c)) return_trace (false);
755
0
    hb_barrier ();
756
0
    switch (u.format) {
757
0
    case 0: hb_barrier (); return_trace (u.format0.sanitize (c));
758
0
    case 2: hb_barrier (); return_trace (u.format2.sanitize (c));
759
0
    case 4: hb_barrier (); return_trace (u.format4.sanitize (c));
760
0
    case 6: hb_barrier (); return_trace (u.format6.sanitize (c));
761
0
    case 8: hb_barrier (); return_trace (u.format8.sanitize (c));
762
0
    case 10: hb_barrier (); return_trace (u.format10.sanitize (c));
763
0
    default:return_trace (true);
764
0
    }
765
0
  }
Unexecuted instantiation: AAT::Lookup<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::Lookup<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::Lookup<OT::NumType<true, unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
766
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
767
0
  {
768
0
    TRACE_SANITIZE (this);
769
0
    if (!u.format.sanitize (c)) return_trace (false);
770
0
    hb_barrier ();
771
0
    switch (u.format) {
772
0
    case 0: hb_barrier (); return_trace (u.format0.sanitize (c, base));
773
0
    case 2: hb_barrier (); return_trace (u.format2.sanitize (c, base));
774
0
    case 4: hb_barrier (); return_trace (u.format4.sanitize (c, base));
775
0
    case 6: hb_barrier (); return_trace (u.format6.sanitize (c, base));
776
0
    case 8: hb_barrier (); return_trace (u.format8.sanitize (c, base));
777
0
    case 10: return_trace (false); /* We don't support format10 here currently. */
778
0
    default:return_trace (true);
779
0
    }
780
0
  }
Unexecuted instantiation: AAT::Lookup<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::Lookup<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::NumType<true, unsigned int, 4u> >, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::Lookup<OT::OffsetTo<AAT::OpticalBounds, OT::NumType<true, unsigned short, 2u>, void, true> >::sanitize(hb_sanitize_context_t*, void const*) const
781
782
  protected:
783
  union {
784
  HBUINT16    format;   /* Format identifier */
785
  LookupFormat0<T>  format0;
786
  LookupFormat2<T>  format2;
787
  LookupFormat4<T>  format4;
788
  LookupFormat6<T>  format6;
789
  LookupFormat8<T>  format8;
790
  LookupFormat10<T> format10;
791
  } u;
792
  public:
793
  DEFINE_SIZE_UNION (2, format);
794
};
795
DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2);
796
797
/*
798
 * (Extended) State Table
799
 */
800
801
template <typename T>
802
struct Entry
803
{
804
  // This doesn't seem like it's ever called.
805
  bool sanitize (hb_sanitize_context_t *c) const
806
  {
807
    TRACE_SANITIZE (this);
808
    /* Note, we don't recurse-sanitize data because we don't access it.
809
     * That said, in our DEFINE_SIZE_STATIC we access T::static_size,
810
     * which ensures that data has a simple sanitize(). To be determined
811
     * if I need to remove that as well.
812
     *
813
     * HOWEVER! Because we are a template, our DEFINE_SIZE_STATIC
814
     * assertion wouldn't be checked, hence the line below. */
815
    static_assert (T::static_size, "");
816
817
    return_trace (c->check_struct (this));
818
  }
819
820
  public:
821
  HBUINT16  newState; /* Byte offset from beginning of state table
822
         * to the new state. Really?!?! Or just state
823
         * number?  The latter in morx for sure. */
824
  HBUINT16  flags;    /* Table specific. */
825
  T   data;   /* Optional offsets to per-glyph tables. */
826
  public:
827
  DEFINE_SIZE_STATIC (4 + T::static_size);
828
};
829
830
template <>
831
struct Entry<void>
832
{
833
  // This does seem like it's ever called.
834
  bool sanitize (hb_sanitize_context_t *c) const
835
0
  {
836
0
    TRACE_SANITIZE (this);
837
0
    return_trace (c->check_struct (this));
838
0
  }
839
840
  public:
841
  HBUINT16  newState; /* Byte offset from beginning of state table to the new state. */
842
  HBUINT16  flags;    /* Table specific. */
843
  public:
844
  DEFINE_SIZE_STATIC (4);
845
};
846
847
enum Class
848
{
849
  CLASS_END_OF_TEXT = 0,
850
  CLASS_OUT_OF_BOUNDS = 1,
851
  CLASS_DELETED_GLYPH = 2,
852
  CLASS_END_OF_LINE = 3,
853
};
854
855
template <typename Types, typename Extra>
856
struct StateTable
857
{
858
  typedef typename Types::HBUINT HBUINT;
859
  typedef typename Types::HBUSHORT HBUSHORT;
860
  typedef typename Types::ClassTypeNarrow ClassType;
861
862
  enum State
863
  {
864
    STATE_START_OF_TEXT = 0,
865
    STATE_START_OF_LINE = 1,
866
  };
867
868
  template <typename set_t, typename table_t>
869
  void collect_initial_glyphs (set_t &glyphs, unsigned num_glyphs, const table_t &table) const
870
0
  {
871
0
    unsigned num_classes = nClasses;
872
873
0
    if (unlikely (num_classes > hb_bit_page_t::BITS))
874
0
    {
875
0
      (this+classTable).collect_glyphs (glyphs, num_glyphs);
876
0
      return;
877
0
    }
878
879
    // Collect all classes going out from the start state.
880
0
    hb_bit_page_t filter;
881
882
0
    for (unsigned i = 0; i < num_classes; i++)
883
0
    {
884
0
      const auto &entry = get_entry (STATE_START_OF_TEXT, i);
885
0
      if (new_state (entry.newState) == STATE_START_OF_TEXT &&
886
0
    !table.is_action_initiable (entry) && !table.is_actionable (entry))
887
0
  continue;
888
889
0
      filter.add (i);
890
0
    }
891
892
    // And glyphs in those classes.
893
894
0
    if (filter (CLASS_DELETED_GLYPH))
895
0
      glyphs.add (DELETED_GLYPH);
896
897
0
    (this+classTable).collect_glyphs_filtered (glyphs, num_glyphs, filter);
898
0
  }
Unexecuted instantiation: void AAT::StateTable<AAT::ExtendedTypes, void>::collect_initial_glyphs<hb_bit_set_t, AAT::RearrangementSubtable<AAT::ExtendedTypes> >(hb_bit_set_t&, unsigned int, AAT::RearrangementSubtable<AAT::ExtendedTypes> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::collect_initial_glyphs<hb_bit_set_t, AAT::ContextualSubtable<AAT::ExtendedTypes> >(hb_bit_set_t&, unsigned int, AAT::ContextualSubtable<AAT::ExtendedTypes> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::collect_initial_glyphs<hb_bit_set_t, AAT::LigatureSubtable<AAT::ExtendedTypes> >(hb_bit_set_t&, unsigned int, AAT::LigatureSubtable<AAT::ExtendedTypes> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::collect_initial_glyphs<hb_bit_set_t, AAT::InsertionSubtable<AAT::ExtendedTypes> >(hb_bit_set_t&, unsigned int, AAT::InsertionSubtable<AAT::ExtendedTypes> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ObsoleteTypes, void>::collect_initial_glyphs<hb_bit_set_t, AAT::RearrangementSubtable<AAT::ObsoleteTypes> >(hb_bit_set_t&, unsigned int, AAT::RearrangementSubtable<AAT::ObsoleteTypes> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::collect_initial_glyphs<hb_bit_set_t, AAT::ContextualSubtable<AAT::ObsoleteTypes> >(hb_bit_set_t&, unsigned int, AAT::ContextualSubtable<AAT::ObsoleteTypes> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ObsoleteTypes, void>::collect_initial_glyphs<hb_bit_set_t, AAT::LigatureSubtable<AAT::ObsoleteTypes> >(hb_bit_set_t&, unsigned int, AAT::LigatureSubtable<AAT::ObsoleteTypes> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::collect_initial_glyphs<hb_bit_set_t, AAT::InsertionSubtable<AAT::ObsoleteTypes> >(hb_bit_set_t&, unsigned int, AAT::InsertionSubtable<AAT::ObsoleteTypes> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::collect_initial_glyphs<hb_bit_set_t, AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader> >(hb_bit_set_t&, unsigned int, AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::collect_initial_glyphs<hb_bit_set_t, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader> >(hb_bit_set_t&, unsigned int, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ObsoleteTypes, void>::collect_initial_glyphs<hb_bit_set_t, AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader> >(hb_bit_set_t&, unsigned int, AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader> const&) const
Unexecuted instantiation: void AAT::StateTable<AAT::ObsoleteTypes, void>::collect_initial_glyphs<hb_bit_set_t, AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader> >(hb_bit_set_t&, unsigned int, AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader> const&) const
899
900
  int new_state (unsigned int newState) const
901
0
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, void>::new_state(unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::new_state(unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::new_state(unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::new_state(unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, void>::new_state(unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::new_state(unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::new_state(unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::new_state(unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::new_state(unsigned int) const
902
903
  unsigned int get_class (hb_codepoint_t glyph_id,
904
        unsigned int num_glyphs,
905
        hb_aat_class_cache_t *cache = nullptr) const
906
0
  {
907
0
    unsigned klass;
908
0
    if (cache && cache->get (glyph_id, &klass)) return klass;
909
0
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
910
0
    klass = (this+classTable).get_class (glyph_id, num_glyphs, CLASS_OUT_OF_BOUNDS);
911
0
    if (cache) cache->set (glyph_id, klass);
912
0
    return klass;
913
0
  }
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, void>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, void>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::get_class(unsigned int, unsigned int, hb_cache_t<15u, 8u, 7u, true>*) const
914
915
  const Entry<Extra> *get_entries () const
916
0
  { return (this+entryTable).arrayZ; }
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_entries() const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::get_entries() const
917
918
  const Entry<Extra> &get_entry (int state, unsigned int klass) const
919
0
  {
920
0
    unsigned n_classes = nClasses;
921
0
    if (unlikely (klass >= n_classes))
922
0
      klass = CLASS_OUT_OF_BOUNDS;
923
924
0
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
925
0
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
926
927
0
    unsigned int entry = states[state * n_classes + klass];
928
0
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
929
930
0
    return entries[entry];
931
0
  }
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, void>::get_entry(int, unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_entry(int, unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::get_entry(int, unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::get_entry(int, unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, void>::get_entry(int, unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::get_entry(int, unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::get_entry(int, unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::get_entry(int, unsigned int) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::get_entry(int, unsigned int) const
932
933
  bool sanitize (hb_sanitize_context_t *c,
934
     unsigned int *num_entries_out = nullptr) const
935
0
  {
936
0
    TRACE_SANITIZE (this);
937
0
    if (unlikely (!(c->check_struct (this) &&
938
0
        hb_barrier () &&
939
0
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
940
0
        classTable.sanitize (c, this)))) return_trace (false);
941
942
0
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
943
0
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
944
945
0
    unsigned int num_classes = nClasses;
946
0
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
947
0
      return_trace (false);
948
0
    unsigned int row_stride = num_classes * states[0].static_size;
949
950
    /* Apple 'kern' table has this peculiarity:
951
     *
952
     * "Because the stateTableOffset in the state table header is (strictly
953
     * speaking) redundant, some 'kern' tables use it to record an initial
954
     * state where that should not be StartOfText. To determine if this is
955
     * done, calculate what the stateTableOffset should be. If it's different
956
     * from the actual stateTableOffset, use it as the initial state."
957
     *
958
     * We implement this by calling the initial state zero, but allow *negative*
959
     * states if the start state indeed was not the first state.  Since the code
960
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
961
     * tables are not affected since those address states by index, not offset.
962
     */
963
964
0
    int min_state = 0;
965
0
    int max_state = 0;
966
0
    unsigned int num_entries = 0;
967
968
0
    int state_pos = 0;
969
0
    int state_neg = 0;
970
0
    unsigned int entry = 0;
971
0
    while (min_state < state_neg || state_pos <= max_state)
972
0
    {
973
0
      if (min_state < state_neg)
974
0
      {
975
  /* Negative states. */
976
0
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
977
0
    return_trace (false);
978
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
979
0
               -min_state,
980
0
               row_stride)))
981
0
    return_trace (false);
982
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
983
0
    return_trace (false);
984
0
  { /* Sweep new states. */
985
0
    const HBUSHORT *stop = &states[min_state * num_classes];
986
0
    if (unlikely (stop > states))
987
0
      return_trace (false);
988
0
    for (const HBUSHORT *p = states; stop < p; p--)
989
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
990
0
    state_neg = min_state;
991
0
  }
992
0
      }
993
994
0
      if (state_pos <= max_state)
995
0
      {
996
  /* Positive states. */
997
0
  if (unlikely (!c->check_range (states,
998
0
               max_state + 1,
999
0
               row_stride)))
1000
0
    return_trace (false);
1001
0
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
1002
0
    return_trace (false);
1003
0
  { /* Sweep new states. */
1004
0
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
1005
0
      return_trace (false);
1006
0
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
1007
0
    if (unlikely (stop < states))
1008
0
      return_trace (false);
1009
0
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
1010
0
      num_entries = hb_max (num_entries, *p + 1u);
1011
0
    state_pos = max_state + 1;
1012
0
  }
1013
0
      }
1014
1015
0
      if (unlikely (!c->check_array (entries, num_entries)))
1016
0
  return_trace (false);
1017
0
      if ((c->max_ops -= num_entries - entry) <= 0)
1018
0
  return_trace (false);
1019
0
      { /* Sweep new entries. */
1020
0
  const Entry<Extra> *stop = &entries[num_entries];
1021
0
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
1022
0
  {
1023
0
    int newState = new_state (p->newState);
1024
0
    min_state = hb_min (min_state, newState);
1025
0
    max_state = hb_max (max_state, newState);
1026
0
  }
1027
0
  entry = num_entries;
1028
0
      }
1029
0
    }
1030
1031
0
    if (num_entries_out)
1032
0
      *num_entries_out = num_entries;
1033
1034
0
    return_trace (true);
1035
0
  }
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, void>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, void>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Unexecuted instantiation: AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
1036
1037
  protected:
1038
  HBUINT  nClasses; /* Number of classes, which is the number of indices
1039
         * in a single line in the state array. */
1040
  NNOffsetTo<ClassType, HBUINT>
1041
    classTable; /* Offset to the class table. */
1042
  NNOffsetTo<UnsizedArrayOf<HBUSHORT>, HBUINT>
1043
    stateArrayTable;/* Offset to the state array. */
1044
  NNOffsetTo<UnsizedArrayOf<Entry<Extra>>, HBUINT>
1045
    entryTable; /* Offset to the entry array. */
1046
1047
  public:
1048
  DEFINE_SIZE_STATIC (4 * sizeof (HBUINT));
1049
};
1050
1051
template <typename HBUCHAR>
1052
struct ClassTable
1053
{
1054
  unsigned int get_class (hb_codepoint_t glyph_id, unsigned int outOfRange) const
1055
0
  {
1056
0
    unsigned int i = glyph_id - firstGlyph;
1057
0
    return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
1058
0
  }
Unexecuted instantiation: AAT::ClassTable<OT::NumType<true, unsigned char, 1u> >::get_class(unsigned int, unsigned int) const
Unexecuted instantiation: AAT::ClassTable<OT::NumType<true, unsigned short, 2u> >::get_class(unsigned int, unsigned int) const
1059
  unsigned int get_class (hb_codepoint_t glyph_id,
1060
        unsigned int num_glyphs HB_UNUSED,
1061
        unsigned int outOfRange) const
1062
0
  {
1063
0
    return get_class (glyph_id, outOfRange);
1064
0
  }
Unexecuted instantiation: AAT::ClassTable<OT::NumType<true, unsigned char, 1u> >::get_class(unsigned int, unsigned int, unsigned int) const
Unexecuted instantiation: AAT::ClassTable<OT::NumType<true, unsigned short, 2u> >::get_class(unsigned int, unsigned int, unsigned int) const
1065
1066
  template <typename set_t>
1067
  void collect_glyphs (set_t &glyphs, unsigned num_glyphs) const
1068
0
  {
1069
0
    for (unsigned i = 0; i < classArray.len; i++)
1070
0
      if (classArray.arrayZ[i] != CLASS_OUT_OF_BOUNDS)
1071
0
  glyphs.add (firstGlyph + i);
1072
0
  }
Unexecuted instantiation: void AAT::ClassTable<OT::NumType<true, unsigned char, 1u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, unsigned int) const
Unexecuted instantiation: void AAT::ClassTable<OT::NumType<true, unsigned short, 2u> >::collect_glyphs<hb_bit_set_t>(hb_bit_set_t&, unsigned int) const
1073
  template <typename set_t, typename filter_t>
1074
  void collect_glyphs_filtered (set_t &glyphs, unsigned num_glyphs, const filter_t &filter) const
1075
0
  {
1076
0
    for (unsigned i = 0; i < classArray.len; i++)
1077
0
      if (filter (classArray.arrayZ[i]))
1078
0
  glyphs.add (firstGlyph + i);
1079
0
  }
1080
1081
  bool sanitize (hb_sanitize_context_t *c) const
1082
0
  {
1083
0
    TRACE_SANITIZE (this);
1084
0
    return_trace (c->check_struct (this) && classArray.sanitize (c));
1085
0
  }
Unexecuted instantiation: AAT::ClassTable<OT::NumType<true, unsigned char, 1u> >::sanitize(hb_sanitize_context_t*) const
Unexecuted instantiation: AAT::ClassTable<OT::NumType<true, unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
1086
  protected:
1087
  HBGlyphID16   firstGlyph; /* First glyph index included in the trimmed array. */
1088
  Array16Of<HBUCHAR>  classArray; /* The class codes (indexed by glyph index minus
1089
           * firstGlyph). */
1090
  public:
1091
  DEFINE_SIZE_ARRAY (4, classArray);
1092
};
1093
1094
struct SubtableGlyphCoverage
1095
{
1096
  bool sanitize (hb_sanitize_context_t *c, unsigned subtable_count) const
1097
0
  {
1098
0
    TRACE_SANITIZE (this);
1099
1100
0
    if (unlikely (!c->check_array (&subtableOffsets, subtable_count)))
1101
0
      return_trace (false);
1102
1103
0
    unsigned bytes = (c->get_num_glyphs () + CHAR_BIT - 1) / CHAR_BIT;
1104
0
    for (unsigned i = 0; i < subtable_count; i++)
1105
0
    {
1106
0
      uint32_t offset = (uint32_t) subtableOffsets[i];
1107
      // A font file called SFNSDisplay.ttf has value 0xFFFFFFFF in the offsets.
1108
      // Just ignore it.
1109
0
      if (offset == 0 || offset == 0xFFFFFFFF)
1110
0
        continue;
1111
0
      if (unlikely (!subtableOffsets[i].sanitize (c, this, bytes)))
1112
0
        return_trace (false);
1113
0
    }
1114
1115
0
    return_trace (true);
1116
0
  }
1117
  protected:
1118
  UnsizedArrayOf<NNOffset32To<UnsizedArrayOf<HBUINT8>>> subtableOffsets;
1119
              /* Array of offsets from the beginning of the
1120
               * subtable glyph coverage table to the glyph
1121
               * coverage bitfield for a given subtable; there
1122
               * is one offset for each subtable in the chain */
1123
  /* UnsizedArrayOf<HBUINT8> coverageBitfields; *//* The individual coverage bitfields. */
1124
  public:
1125
  DEFINE_SIZE_ARRAY (0, subtableOffsets);
1126
};
1127
1128
struct ObsoleteTypes
1129
{
1130
  static constexpr bool extended = false;
1131
  typedef HBUINT16 HBUINT;
1132
  typedef HBUINT8 HBUSHORT;
1133
  typedef ClassTable<HBUINT8> ClassTypeNarrow;
1134
  typedef ClassTable<HBUINT16> ClassTypeWide;
1135
1136
  template <typename T>
1137
  static unsigned int offsetToIndex (unsigned int offset,
1138
             const void *base,
1139
             const T *array)
1140
0
  {
1141
    /* https://github.com/harfbuzz/harfbuzz/issues/3483 */
1142
    /* If offset is less than base, return an offset that would
1143
     * result in an address half a 32bit address-space away,
1144
     * to make sure sanitize fails even on 32bit builds. */
1145
0
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
1146
0
      return INT_MAX / T::static_size;
1147
1148
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
1149
0
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
1150
0
  }
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::NumType<true, unsigned int, 4u> >(unsigned int, void const*, OT::NumType<true, unsigned int, 4u> const*)
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::NumType<true, unsigned short, 2u> >(unsigned int, void const*, OT::NumType<true, unsigned short, 2u> const*)
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::NumType<true, short, 2u> >(unsigned int, void const*, OT::NumType<true, short, 2u> const*)
1151
  template <typename T>
1152
  static unsigned int byteOffsetToIndex (unsigned int offset,
1153
           const void *base,
1154
           const T *array)
1155
0
  {
1156
0
    return offsetToIndex (offset, base, array);
1157
0
  }
1158
  template <typename T>
1159
  static unsigned int wordOffsetToIndex (unsigned int offset,
1160
           const void *base,
1161
           const T *array)
1162
0
  {
1163
0
    return offsetToIndex (2 * offset, base, array);
1164
0
  }
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::wordOffsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::wordOffsetToIndex<OT::NumType<true, unsigned short, 2u> >(unsigned int, void const*, OT::NumType<true, unsigned short, 2u> const*)
1165
};
1166
struct ExtendedTypes
1167
{
1168
  static constexpr bool extended = true;
1169
  typedef HBUINT32 HBUINT;
1170
  typedef HBUINT16 HBUSHORT;
1171
  typedef Lookup<HBUINT16> ClassTypeNarrow;
1172
  typedef Lookup<HBUINT16> ClassTypeWide;
1173
1174
  template <typename T>
1175
  static unsigned int offsetToIndex (unsigned int offset,
1176
             const void *base HB_UNUSED,
1177
             const T *array HB_UNUSED)
1178
0
  {
1179
0
    return offset;
1180
0
  }
Unexecuted instantiation: unsigned int AAT::ExtendedTypes::offsetToIndex<OT::NumType<true, unsigned int, 4u> >(unsigned int, void const*, OT::NumType<true, unsigned int, 4u> const*)
Unexecuted instantiation: unsigned int AAT::ExtendedTypes::offsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
Unexecuted instantiation: unsigned int AAT::ExtendedTypes::offsetToIndex<OT::NumType<true, short, 2u> >(unsigned int, void const*, OT::NumType<true, short, 2u> const*)
1181
  template <typename T>
1182
  static unsigned int byteOffsetToIndex (unsigned int offset,
1183
           const void *base HB_UNUSED,
1184
           const T *array HB_UNUSED)
1185
0
  {
1186
0
    return offset / 2;
1187
0
  }
1188
  template <typename T>
1189
  static unsigned int wordOffsetToIndex (unsigned int offset,
1190
           const void *base HB_UNUSED,
1191
           const T *array HB_UNUSED)
1192
0
  {
1193
0
    return offset;
1194
0
  }
Unexecuted instantiation: unsigned int AAT::ExtendedTypes::wordOffsetToIndex<OT::NumType<true, unsigned short, 2u> >(unsigned int, void const*, OT::NumType<true, unsigned short, 2u> const*)
Unexecuted instantiation: unsigned int AAT::ExtendedTypes::wordOffsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
1195
};
1196
1197
template <typename Types, typename EntryData, typename Flags>
1198
struct StateTableDriver
1199
{
1200
  using StateTableT = StateTable<Types, EntryData>;
1201
  using EntryT = Entry<EntryData>;
1202
1203
  StateTableDriver (const StateTableT &machine_,
1204
        hb_face_t *face_) :
1205
0
        machine (machine_),
1206
0
        num_glyphs (face_->get_num_glyphs ()) {}
Unexecuted instantiation: AAT::StateTableDriver<AAT::ExtendedTypes, void, AAT::RearrangementSubtable<AAT::ExtendedTypes>::Flags>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, void> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData, AAT::ContextualSubtable<AAT::ExtendedTypes>::Flags>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData, AAT::LigatureSubtable<AAT::ExtendedTypes>::Flags>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData, AAT::InsertionSubtable<AAT::ExtendedTypes>::Flags>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ObsoleteTypes, void, AAT::RearrangementSubtable<AAT::ObsoleteTypes>::Flags>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, void> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData, AAT::ContextualSubtable<AAT::ObsoleteTypes>::Flags>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ObsoleteTypes, void, AAT::LigatureSubtable<AAT::ObsoleteTypes>::Flags>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, void> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData, AAT::InsertionSubtable<AAT::ObsoleteTypes>::Flags>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData, AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader>::Flags>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::Flags>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ObsoleteTypes, void, AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader>::Flags>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, void> const&, hb_face_t*)
Unexecuted instantiation: AAT::StateTableDriver<AAT::ObsoleteTypes, void, AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader>::Flags>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, void> const&, hb_face_t*)
1207
1208
  template <typename context_t>
1209
  void drive (context_t *c, hb_aat_apply_context_t *ac)
1210
0
  {
1211
0
    hb_buffer_t *buffer = ac->buffer;
1212
1213
0
    if (!c->in_place)
1214
0
      buffer->clear_output ();
1215
1216
0
    int state = StateTableT::STATE_START_OF_TEXT;
1217
    // If there's only one range, we already checked the flag.
1218
0
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
1219
0
    for (buffer->idx = 0; buffer->successful;)
1220
0
    {
1221
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
1222
0
      if (last_range)
1223
0
      {
1224
0
  auto *range = last_range;
1225
0
  if (buffer->idx < buffer->len)
1226
0
  {
1227
0
    unsigned cluster = buffer->cur().cluster;
1228
0
    while (cluster < range->cluster_first)
1229
0
      range--;
1230
0
    while (cluster > range->cluster_last)
1231
0
      range++;
1232
1233
1234
0
    last_range = range;
1235
0
  }
1236
0
  if (!(range->flags & ac->subtable_flags))
1237
0
  {
1238
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
1239
0
      break;
1240
1241
0
    state = StateTableT::STATE_START_OF_TEXT;
1242
0
    (void) buffer->next_glyph ();
1243
0
    continue;
1244
0
  }
1245
0
      }
1246
1247
0
      unsigned int klass = likely (buffer->idx < buffer->len) ?
1248
0
         machine.get_class (buffer->cur().codepoint, num_glyphs, ac->machine_class_cache) :
1249
0
         (unsigned) CLASS_END_OF_TEXT;
1250
0
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
1251
0
      const EntryT &entry = machine.get_entry (state, klass);
1252
0
      const int next_state = machine.new_state (entry.newState);
1253
1254
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
1255
       *
1256
       * 1. There was no action in this transition; and
1257
       *
1258
       * 2. If we break before current glyph, the results will be the same. That
1259
       *    is guaranteed if:
1260
       *
1261
       *    2a. We were already in start-of-text state; or
1262
       *
1263
       *    2b. We are epsilon-transitioning to start-of-text state; or
1264
       *
1265
       *    2c. Starting from start-of-text state seeing current glyph:
1266
       *
1267
       *        2c'. There won't be any actions; and
1268
       *
1269
       *        2c". We would end up in the same state that we were going to end up
1270
       *             in now, including whether epsilon-transitioning.
1271
       *
1272
       *    and
1273
       *
1274
       * 3. If we break before current glyph, there won't be any end-of-text action
1275
       *    after previous glyph.
1276
       *
1277
       * This triples the transitions we need to look up, but is worth returning
1278
       * granular unsafe-to-break results. See eg.:
1279
       *
1280
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
1281
       */
1282
0
      const EntryT *wouldbe_entry;
1283
0
      bool is_safe_to_break =
1284
0
      (
1285
          /* 1. */
1286
0
          !c->table->is_actionable (entry) &&
1287
1288
          /* 2. */
1289
          // This one is meh, I know...
1290
0
    (
1291
0
                 state == StateTableT::STATE_START_OF_TEXT
1292
0
              || ((entry.flags & Flags::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT)
1293
0
              || (
1294
        /* 2c. */
1295
0
        wouldbe_entry = &machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass)
1296
0
        ,
1297
        /* 2c'. */
1298
0
        !c->table->is_actionable (*wouldbe_entry) &&
1299
        /* 2c". */
1300
0
        (
1301
0
          next_state == machine.new_state(wouldbe_entry->newState) &&
1302
0
          (entry.flags & Flags::DontAdvance) == (wouldbe_entry->flags & Flags::DontAdvance)
1303
0
        )
1304
0
     )
1305
0
    ) &&
1306
1307
          /* 3. */
1308
0
          !c->table->is_actionable (machine.get_entry (state, CLASS_END_OF_TEXT))
1309
0
      );
1310
1311
0
      if (!is_safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
1312
0
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
1313
1314
0
      c->transition (buffer, this, entry);
1315
1316
0
      state = next_state;
1317
0
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
1318
1319
0
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
1320
0
  break;
1321
1322
0
      if (!(entry.flags & Flags::DontAdvance) || buffer->max_ops-- <= 0)
1323
0
  (void) buffer->next_glyph ();
1324
0
    }
1325
1326
0
    if (!c->in_place)
1327
0
      buffer->sync ();
1328
0
  }
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ExtendedTypes, void, AAT::RearrangementSubtable<AAT::ExtendedTypes>::Flags>::drive<AAT::RearrangementSubtable<AAT::ExtendedTypes>::driver_context_t>(AAT::RearrangementSubtable<AAT::ExtendedTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData, AAT::ContextualSubtable<AAT::ExtendedTypes>::Flags>::drive<AAT::ContextualSubtable<AAT::ExtendedTypes>::driver_context_t>(AAT::ContextualSubtable<AAT::ExtendedTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData, AAT::LigatureSubtable<AAT::ExtendedTypes>::Flags>::drive<AAT::LigatureSubtable<AAT::ExtendedTypes>::driver_context_t>(AAT::LigatureSubtable<AAT::ExtendedTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData, AAT::InsertionSubtable<AAT::ExtendedTypes>::Flags>::drive<AAT::InsertionSubtable<AAT::ExtendedTypes>::driver_context_t>(AAT::InsertionSubtable<AAT::ExtendedTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ObsoleteTypes, void, AAT::RearrangementSubtable<AAT::ObsoleteTypes>::Flags>::drive<AAT::RearrangementSubtable<AAT::ObsoleteTypes>::driver_context_t>(AAT::RearrangementSubtable<AAT::ObsoleteTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData, AAT::ContextualSubtable<AAT::ObsoleteTypes>::Flags>::drive<AAT::ContextualSubtable<AAT::ObsoleteTypes>::driver_context_t>(AAT::ContextualSubtable<AAT::ObsoleteTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ObsoleteTypes, void, AAT::LigatureSubtable<AAT::ObsoleteTypes>::Flags>::drive<AAT::LigatureSubtable<AAT::ObsoleteTypes>::driver_context_t>(AAT::LigatureSubtable<AAT::ObsoleteTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData, AAT::InsertionSubtable<AAT::ObsoleteTypes>::Flags>::drive<AAT::InsertionSubtable<AAT::ObsoleteTypes>::driver_context_t>(AAT::InsertionSubtable<AAT::ObsoleteTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData, AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader>::Flags>::drive<AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader>::driver_context_t>(AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::Flags>::drive<AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::driver_context_t>(AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ObsoleteTypes, void, AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader>::Flags>::drive<AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader>::driver_context_t>(AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ObsoleteTypes, void, AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader>::Flags>::drive<AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader>::driver_context_t>(AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader>::driver_context_t*, AAT::hb_aat_apply_context_t*)
1329
1330
  public:
1331
  const StateTableT &machine;
1332
  unsigned int num_glyphs;
1333
};
1334
1335
1336
} /* namespace AAT */
1337
1338
1339
#endif /* HB_AAT_LAYOUT_COMMON_HH */