Coverage Report

Created: 2024-09-27 03:16

/src/harfbuzz/src/hb-aat-layout-common.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2017  Google, Inc.
3
 *
4
 *  This is part of HarfBuzz, a text shaping library.
5
 *
6
 * Permission is hereby granted, without written agreement and without
7
 * license or royalty fees, to use, copy, modify, and distribute this
8
 * software and its documentation for any purpose, provided that the
9
 * above copyright notice and the following two paragraphs appear in
10
 * all copies of this software.
11
 *
12
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16
 * DAMAGE.
17
 *
18
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
 *
24
 * Google Author(s): Behdad Esfahbod
25
 */
26
27
#ifndef HB_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-open-type.hh"
33
34
namespace OT {
35
struct GDEF;
36
};
37
38
namespace AAT {
39
40
using namespace OT;
41
42
43
struct ankr;
44
45
struct hb_aat_apply_context_t :
46
       hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
47
{
48
0
  const char *get_name () { return "APPLY"; }
49
  template <typename T>
50
200k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::RearrangementSubtable<AAT::ExtendedTypes> >(AAT::RearrangementSubtable<AAT::ExtendedTypes> const&)
Line
Count
Source
50
7.85k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::ContextualSubtable<AAT::ExtendedTypes> >(AAT::ContextualSubtable<AAT::ExtendedTypes> const&)
Line
Count
Source
50
12.9k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::LigatureSubtable<AAT::ExtendedTypes> >(AAT::LigatureSubtable<AAT::ExtendedTypes> const&)
Line
Count
Source
50
5.83k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::NoncontextualSubtable<AAT::ExtendedTypes> >(AAT::NoncontextualSubtable<AAT::ExtendedTypes> const&)
Line
Count
Source
50
5.23k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::InsertionSubtable<AAT::ExtendedTypes> >(AAT::InsertionSubtable<AAT::ExtendedTypes> const&)
Line
Count
Source
50
39.2k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::RearrangementSubtable<AAT::ObsoleteTypes> >(AAT::RearrangementSubtable<AAT::ObsoleteTypes> const&)
Line
Count
Source
50
3.04k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::ContextualSubtable<AAT::ObsoleteTypes> >(AAT::ContextualSubtable<AAT::ObsoleteTypes> const&)
Line
Count
Source
50
1.46k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::LigatureSubtable<AAT::ObsoleteTypes> >(AAT::LigatureSubtable<AAT::ObsoleteTypes> const&)
Line
Count
Source
50
330
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::NoncontextualSubtable<AAT::ObsoleteTypes> >(AAT::NoncontextualSubtable<AAT::ObsoleteTypes> const&)
Line
Count
Source
50
827
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::InsertionSubtable<AAT::ObsoleteTypes> >(AAT::InsertionSubtable<AAT::ObsoleteTypes> const&)
Line
Count
Source
50
2.89k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat0<AAT::KerxSubTableHeader> >(AAT::KerxSubTableFormat0<AAT::KerxSubTableHeader> const&)
Line
Count
Source
50
13.6k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader> >(AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader> const&)
Line
Count
Source
50
2.23k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat2<AAT::KerxSubTableHeader> >(AAT::KerxSubTableFormat2<AAT::KerxSubTableHeader> const&)
Line
Count
Source
50
6.43k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader> >(AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader> const&)
Line
Count
Source
50
2.24k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat6<AAT::KerxSubTableHeader> >(AAT::KerxSubTableFormat6<AAT::KerxSubTableHeader> const&)
Line
Count
Source
50
14.9k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<OT::KernOT>(OT::KernOT const&)
Line
Count
Source
50
26.9k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat0<OT::KernOTSubTableHeader> >(AAT::KerxSubTableFormat0<OT::KernOTSubTableHeader> const&)
Line
Count
Source
50
18.5k
  return_t dispatch (const T &obj) { return obj.apply (this); }
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader> >(AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader> const&)
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat2<OT::KernOTSubTableHeader> >(AAT::KerxSubTableFormat2<OT::KernOTSubTableHeader> const&)
Line
Count
Source
50
3.52k
  return_t dispatch (const T &obj) { return obj.apply (this); }
Unexecuted instantiation: bool AAT::hb_aat_apply_context_t::dispatch<OT::KernSubTableFormat3<OT::KernOTSubTableHeader> >(OT::KernSubTableFormat3<OT::KernOTSubTableHeader> const&)
bool AAT::hb_aat_apply_context_t::dispatch<OT::KernAAT>(OT::KernAAT const&)
Line
Count
Source
50
14.4k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat0<OT::KernAATSubTableHeader> >(AAT::KerxSubTableFormat0<OT::KernAATSubTableHeader> const&)
Line
Count
Source
50
5.81k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader> >(AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader> const&)
Line
Count
Source
50
1.90k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<AAT::KerxSubTableFormat2<OT::KernAATSubTableHeader> >(AAT::KerxSubTableFormat2<OT::KernAATSubTableHeader> const&)
Line
Count
Source
50
7.90k
  return_t dispatch (const T &obj) { return obj.apply (this); }
bool AAT::hb_aat_apply_context_t::dispatch<OT::KernSubTableFormat3<OT::KernAATSubTableHeader> >(OT::KernSubTableFormat3<OT::KernAATSubTableHeader> const&)
Line
Count
Source
50
2.14k
  return_t dispatch (const T &obj) { return obj.apply (this); }
51
53.6k
  static return_t default_return_value () { return false; }
52
0
  bool stop_sublookup_iteration (return_t r) const { return r; }
53
54
  const hb_ot_shape_plan_t *plan;
55
  hb_font_t *font;
56
  hb_face_t *face;
57
  hb_buffer_t *buffer;
58
  hb_sanitize_context_t sanitizer;
59
  const ankr *ankr_table;
60
  const OT::GDEF *gdef_table;
61
  const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr;
62
  hb_mask_t subtable_flags = 0;
63
64
  /* Unused. For debug tracing only. */
65
  unsigned int lookup_index;
66
67
  HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
68
              hb_font_t *font_,
69
              hb_buffer_t *buffer_,
70
              hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t)));
71
72
  HB_INTERNAL ~hb_aat_apply_context_t ();
73
74
  HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
75
76
438k
  void set_lookup_index (unsigned int i) { lookup_index = i; }
77
};
78
79
80
/*
81
 * Lookup Table
82
 */
83
84
template <typename T> struct Lookup;
85
86
template <typename T>
87
struct LookupFormat0
88
{
89
  friend struct Lookup<T>;
90
91
  private:
92
  const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
93
13.4M
  {
94
13.4M
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
4.19M
    return &arrayZ[glyph_id];
96
13.4M
  }
AAT::LookupFormat0<OT::IntType<unsigned short, 2u> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
93
8.41M
  {
94
8.41M
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
1.40M
    return &arrayZ[glyph_id];
96
8.41M
  }
AAT::LookupFormat0<OT::HBGlyphID16>::get_value(unsigned int, unsigned int) const
Line
Count
Source
93
4.88M
  {
94
4.88M
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
2.78M
    return &arrayZ[glyph_id];
96
4.88M
  }
AAT::LookupFormat0<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
93
114k
  {
94
114k
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
366
    return &arrayZ[glyph_id];
96
114k
  }
AAT::LookupFormat0<OT::IntType<unsigned int, 4u> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
93
22.5k
  {
94
22.5k
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
279
    return &arrayZ[glyph_id];
96
22.5k
  }
Unexecuted instantiation: AAT::LookupFormat0<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::get_value(unsigned int, unsigned int) const
97
98
  bool sanitize (hb_sanitize_context_t *c) const
99
9.28k
  {
100
9.28k
    TRACE_SANITIZE (this);
101
9.28k
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
102
9.28k
  }
AAT::LookupFormat0<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
99
5.25k
  {
100
5.25k
    TRACE_SANITIZE (this);
101
5.25k
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
102
5.25k
  }
AAT::LookupFormat0<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
99
2.82k
  {
100
2.82k
    TRACE_SANITIZE (this);
101
2.82k
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
102
2.82k
  }
AAT::LookupFormat0<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
99
1.20k
  {
100
1.20k
    TRACE_SANITIZE (this);
101
1.20k
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
102
1.20k
  }
103
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
104
951
  {
105
951
    TRACE_SANITIZE (this);
106
951
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs (), base));
107
951
  }
AAT::LookupFormat0<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
104
951
  {
105
951
    TRACE_SANITIZE (this);
106
951
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs (), base));
107
951
  }
Unexecuted instantiation: AAT::LookupFormat0<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat0<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
108
109
  protected:
110
  HBUINT16  format;   /* Format identifier--format = 0 */
111
  UnsizedArrayOf<T>
112
    arrayZ;   /* Array of lookup values, indexed by glyph index. */
113
  public:
114
  DEFINE_SIZE_UNBOUNDED (2);
115
};
116
117
118
template <typename T>
119
struct LookupSegmentSingle
120
{
121
  static constexpr unsigned TerminationWordCount = 2u;
122
123
  int cmp (hb_codepoint_t g) const
124
37.6k
  { return g < first ? -1 : g <= last ? 0 : +1 ; }
AAT::LookupSegmentSingle<OT::IntType<unsigned short, 2u> >::cmp(unsigned int) const
Line
Count
Source
124
29.5k
  { return g < first ? -1 : g <= last ? 0 : +1 ; }
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::HBGlyphID16>::cmp(unsigned int) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::cmp(unsigned int) const
AAT::LookupSegmentSingle<OT::IntType<unsigned int, 4u> >::cmp(unsigned int) const
Line
Count
Source
124
8.10k
  { return g < first ? -1 : g <= last ? 0 : +1 ; }
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::cmp(unsigned int) const
125
126
  bool sanitize (hb_sanitize_context_t *c) const
127
0
  {
128
0
    TRACE_SANITIZE (this);
129
0
    return_trace (c->check_struct (this) && value.sanitize (c));
130
0
  }
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::IntType<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::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
131
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
132
2.12k
  {
133
2.12k
    TRACE_SANITIZE (this);
134
2.12k
    return_trace (c->check_struct (this) && value.sanitize (c, base));
135
2.12k
  }
AAT::LookupSegmentSingle<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
132
2.12k
  {
133
2.12k
    TRACE_SANITIZE (this);
134
2.12k
    return_trace (c->check_struct (this) && value.sanitize (c, base));
135
2.12k
  }
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
136
137
  HBGlyphID16 last;   /* Last GlyphID in this segment */
138
  HBGlyphID16 first;    /* First GlyphID in this segment */
139
  T   value;    /* The lookup value (only one) */
140
  public:
141
  DEFINE_SIZE_STATIC (4 + T::static_size);
142
};
143
144
template <typename T>
145
struct LookupFormat2
146
{
147
  friend struct Lookup<T>;
148
149
  private:
150
  const T* get_value (hb_codepoint_t glyph_id) const
151
39.3k
  {
152
39.3k
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
39.3k
    return v ? &v->value : nullptr;
154
39.3k
  }
AAT::LookupFormat2<OT::IntType<unsigned short, 2u> >::get_value(unsigned int) const
Line
Count
Source
151
34.9k
  {
152
34.9k
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
34.9k
    return v ? &v->value : nullptr;
154
34.9k
  }
AAT::LookupFormat2<OT::HBGlyphID16>::get_value(unsigned int) const
Line
Count
Source
151
54
  {
152
54
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
54
    return v ? &v->value : nullptr;
154
54
  }
AAT::LookupFormat2<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int) const
Line
Count
Source
151
228
  {
152
228
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
228
    return v ? &v->value : nullptr;
154
228
  }
AAT::LookupFormat2<OT::IntType<unsigned int, 4u> >::get_value(unsigned int) const
Line
Count
Source
151
4.16k
  {
152
4.16k
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
4.16k
    return v ? &v->value : nullptr;
154
4.16k
  }
Unexecuted instantiation: AAT::LookupFormat2<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::get_value(unsigned int) const
155
156
  bool sanitize (hb_sanitize_context_t *c) const
157
924
  {
158
924
    TRACE_SANITIZE (this);
159
924
    return_trace (segments.sanitize (c));
160
924
  }
AAT::LookupFormat2<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
157
683
  {
158
683
    TRACE_SANITIZE (this);
159
683
    return_trace (segments.sanitize (c));
160
683
  }
AAT::LookupFormat2<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
157
27
  {
158
27
    TRACE_SANITIZE (this);
159
27
    return_trace (segments.sanitize (c));
160
27
  }
AAT::LookupFormat2<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
157
214
  {
158
214
    TRACE_SANITIZE (this);
159
214
    return_trace (segments.sanitize (c));
160
214
  }
161
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
162
621
  {
163
621
    TRACE_SANITIZE (this);
164
621
    return_trace (segments.sanitize (c, base));
165
621
  }
AAT::LookupFormat2<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
162
621
  {
163
621
    TRACE_SANITIZE (this);
164
621
    return_trace (segments.sanitize (c, base));
165
621
  }
Unexecuted instantiation: AAT::LookupFormat2<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat2<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
166
167
  protected:
168
  HBUINT16  format;   /* Format identifier--format = 2 */
169
  VarSizedBinSearchArrayOf<LookupSegmentSingle<T>>
170
    segments; /* The actual segments. These must already be sorted,
171
         * according to the first word in each one (the last
172
         * glyph in each segment). */
173
  public:
174
  DEFINE_SIZE_ARRAY (8, segments);
175
};
176
177
template <typename T>
178
struct LookupSegmentArray
179
{
180
  static constexpr unsigned TerminationWordCount = 2u;
181
182
  const T* get_value (hb_codepoint_t glyph_id, const void *base) const
183
870
  {
184
870
    return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
185
870
  }
AAT::LookupSegmentArray<OT::IntType<unsigned short, 2u> >::get_value(unsigned int, void const*) const
Line
Count
Source
183
416
  {
184
416
    return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
185
416
  }
AAT::LookupSegmentArray<OT::HBGlyphID16>::get_value(unsigned int, void const*) const
Line
Count
Source
183
70
  {
184
70
    return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
185
70
  }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int, void const*) const
AAT::LookupSegmentArray<OT::IntType<unsigned int, 4u> >::get_value(unsigned int, void const*) const
Line
Count
Source
183
384
  {
184
384
    return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
185
384
  }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::get_value(unsigned int, void const*) const
186
187
  int cmp (hb_codepoint_t g) const
188
2.09k
  { return g < first ? -1 : g <= last ? 0 : +1; }
AAT::LookupSegmentArray<OT::IntType<unsigned short, 2u> >::cmp(unsigned int) const
Line
Count
Source
188
1.14k
  { return g < first ? -1 : g <= last ? 0 : +1; }
AAT::LookupSegmentArray<OT::HBGlyphID16>::cmp(unsigned int) const
Line
Count
Source
188
70
  { return g < first ? -1 : g <= last ? 0 : +1; }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::cmp(unsigned int) const
AAT::LookupSegmentArray<OT::IntType<unsigned int, 4u> >::cmp(unsigned int) const
Line
Count
Source
188
872
  { return g < first ? -1 : g <= last ? 0 : +1; }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::cmp(unsigned int) const
189
190
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
191
917
  {
192
917
    TRACE_SANITIZE (this);
193
917
    return_trace (c->check_struct (this) &&
194
917
      first <= last &&
195
917
      valuesZ.sanitize (c, base, last - first + 1));
196
917
  }
AAT::LookupSegmentArray<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
191
476
  {
192
476
    TRACE_SANITIZE (this);
193
476
    return_trace (c->check_struct (this) &&
194
476
      first <= last &&
195
476
      valuesZ.sanitize (c, base, last - first + 1));
196
476
  }
AAT::LookupSegmentArray<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
191
15
  {
192
15
    TRACE_SANITIZE (this);
193
15
    return_trace (c->check_struct (this) &&
194
15
      first <= last &&
195
15
      valuesZ.sanitize (c, base, last - first + 1));
196
15
  }
AAT::LookupSegmentArray<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
191
426
  {
192
426
    TRACE_SANITIZE (this);
193
426
    return_trace (c->check_struct (this) &&
194
426
      first <= last &&
195
426
      valuesZ.sanitize (c, base, last - first + 1));
196
426
  }
197
  template <typename ...Ts>
198
  bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
199
1.65k
  {
200
1.65k
    TRACE_SANITIZE (this);
201
1.65k
    return_trace (c->check_struct (this) &&
202
1.65k
      first <= last &&
203
1.65k
      valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...));
204
1.65k
  }
bool AAT::LookupSegmentArray<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize<void const*&>(hb_sanitize_context_t*, void const*, void const*&) const
Line
Count
Source
199
1.65k
  {
200
1.65k
    TRACE_SANITIZE (this);
201
1.65k
    return_trace (c->check_struct (this) &&
202
1.65k
      first <= last &&
203
1.65k
      valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...));
204
1.65k
  }
Unexecuted instantiation: bool AAT::LookupSegmentArray<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize<void const*&>(hb_sanitize_context_t*, void const*, void const*&) const
Unexecuted instantiation: bool AAT::LookupSegmentArray<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize<void const*&>(hb_sanitize_context_t*, void const*, void const*&) const
205
206
  HBGlyphID16 last;   /* Last GlyphID in this segment */
207
  HBGlyphID16 first;    /* First GlyphID in this segment */
208
  NNOffset16To<UnsizedArrayOf<T>>
209
    valuesZ;  /* A 16-bit offset from the start of
210
         * the table to the data. */
211
  public:
212
  DEFINE_SIZE_STATIC (6);
213
};
214
215
template <typename T>
216
struct LookupFormat4
217
{
218
  friend struct Lookup<T>;
219
220
  private:
221
  const T* get_value (hb_codepoint_t glyph_id) const
222
53.1k
  {
223
53.1k
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
224
53.1k
    return v ? v->get_value (glyph_id, this) : nullptr;
225
53.1k
  }
AAT::LookupFormat4<OT::IntType<unsigned short, 2u> >::get_value(unsigned int) const
Line
Count
Source
222
1.77k
  {
223
1.77k
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
224
1.77k
    return v ? v->get_value (glyph_id, this) : nullptr;
225
1.77k
  }
AAT::LookupFormat4<OT::HBGlyphID16>::get_value(unsigned int) const
Line
Count
Source
222
49.7k
  {
223
49.7k
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
224
49.7k
    return v ? v->get_value (glyph_id, this) : nullptr;
225
49.7k
  }
AAT::LookupFormat4<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int) const
Line
Count
Source
222
132
  {
223
132
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
224
132
    return v ? v->get_value (glyph_id, this) : nullptr;
225
132
  }
AAT::LookupFormat4<OT::IntType<unsigned int, 4u> >::get_value(unsigned int) const
Line
Count
Source
222
1.50k
  {
223
1.50k
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
224
1.50k
    return v ? v->get_value (glyph_id, this) : nullptr;
225
1.50k
  }
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::get_value(unsigned int) const
226
227
  bool sanitize (hb_sanitize_context_t *c) const
228
494
  {
229
494
    TRACE_SANITIZE (this);
230
494
    return_trace (segments.sanitize (c, this));
231
494
  }
AAT::LookupFormat4<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
228
249
  {
229
249
    TRACE_SANITIZE (this);
230
249
    return_trace (segments.sanitize (c, this));
231
249
  }
AAT::LookupFormat4<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
228
47
  {
229
47
    TRACE_SANITIZE (this);
230
47
    return_trace (segments.sanitize (c, this));
231
47
  }
AAT::LookupFormat4<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
228
198
  {
229
198
    TRACE_SANITIZE (this);
230
198
    return_trace (segments.sanitize (c, this));
231
198
  }
232
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
233
531
  {
234
531
    TRACE_SANITIZE (this);
235
531
    return_trace (segments.sanitize (c, this, base));
236
531
  }
AAT::LookupFormat4<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
233
531
  {
234
531
    TRACE_SANITIZE (this);
235
531
    return_trace (segments.sanitize (c, this, base));
236
531
  }
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
237
238
  protected:
239
  HBUINT16  format;   /* Format identifier--format = 4 */
240
  VarSizedBinSearchArrayOf<LookupSegmentArray<T>>
241
    segments; /* The actual segments. These must already be sorted,
242
         * according to the first word in each one (the last
243
         * glyph in each segment). */
244
  public:
245
  DEFINE_SIZE_ARRAY (8, segments);
246
};
247
248
template <typename T>
249
struct LookupSingle
250
{
251
  static constexpr unsigned TerminationWordCount = 1u;
252
253
6.01M
  int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
AAT::LookupSingle<OT::IntType<unsigned short, 2u> >::cmp(unsigned int) const
Line
Count
Source
253
5.99M
  int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
AAT::LookupSingle<OT::HBGlyphID16>::cmp(unsigned int) const
Line
Count
Source
253
13.6k
  int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::cmp(unsigned int) const
AAT::LookupSingle<OT::IntType<unsigned int, 4u> >::cmp(unsigned int) const
Line
Count
Source
253
8.09k
  int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::cmp(unsigned int) const
254
255
  bool sanitize (hb_sanitize_context_t *c) const
256
0
  {
257
0
    TRACE_SANITIZE (this);
258
0
    return_trace (c->check_struct (this) && value.sanitize (c));
259
0
  }
Unexecuted instantiation: AAT::LookupSingle<OT::IntType<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::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
260
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
261
1.41k
  {
262
1.41k
    TRACE_SANITIZE (this);
263
1.41k
    return_trace (c->check_struct (this) && value.sanitize (c, base));
264
1.41k
  }
AAT::LookupSingle<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
261
1.41k
  {
262
1.41k
    TRACE_SANITIZE (this);
263
1.41k
    return_trace (c->check_struct (this) && value.sanitize (c, base));
264
1.41k
  }
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupSingle<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
265
266
  HBGlyphID16 glyph;    /* Last GlyphID */
267
  T   value;    /* The lookup value (only one) */
268
  public:
269
  DEFINE_SIZE_STATIC (2 + T::static_size);
270
};
271
272
template <typename T>
273
struct LookupFormat6
274
{
275
  friend struct Lookup<T>;
276
277
  private:
278
  const T* get_value (hb_codepoint_t glyph_id) const
279
3.44M
  {
280
3.44M
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
3.44M
    return v ? &v->value : nullptr;
282
3.44M
  }
AAT::LookupFormat6<OT::IntType<unsigned short, 2u> >::get_value(unsigned int) const
Line
Count
Source
279
3.43M
  {
280
3.43M
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
3.43M
    return v ? &v->value : nullptr;
282
3.43M
  }
AAT::LookupFormat6<OT::HBGlyphID16>::get_value(unsigned int) const
Line
Count
Source
279
9.06k
  {
280
9.06k
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
9.06k
    return v ? &v->value : nullptr;
282
9.06k
  }
AAT::LookupFormat6<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int) const
Line
Count
Source
279
132
  {
280
132
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
132
    return v ? &v->value : nullptr;
282
132
  }
AAT::LookupFormat6<OT::IntType<unsigned int, 4u> >::get_value(unsigned int) const
Line
Count
Source
279
3.64k
  {
280
3.64k
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
3.64k
    return v ? &v->value : nullptr;
282
3.64k
  }
Unexecuted instantiation: AAT::LookupFormat6<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::get_value(unsigned int) const
283
284
  bool sanitize (hb_sanitize_context_t *c) const
285
2.98k
  {
286
2.98k
    TRACE_SANITIZE (this);
287
2.98k
    return_trace (entries.sanitize (c));
288
2.98k
  }
AAT::LookupFormat6<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
285
2.39k
  {
286
2.39k
    TRACE_SANITIZE (this);
287
2.39k
    return_trace (entries.sanitize (c));
288
2.39k
  }
AAT::LookupFormat6<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
285
390
  {
286
390
    TRACE_SANITIZE (this);
287
390
    return_trace (entries.sanitize (c));
288
390
  }
AAT::LookupFormat6<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
285
193
  {
286
193
    TRACE_SANITIZE (this);
287
193
    return_trace (entries.sanitize (c));
288
193
  }
289
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
290
457
  {
291
457
    TRACE_SANITIZE (this);
292
457
    return_trace (entries.sanitize (c, base));
293
457
  }
AAT::LookupFormat6<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
290
457
  {
291
457
    TRACE_SANITIZE (this);
292
457
    return_trace (entries.sanitize (c, base));
293
457
  }
Unexecuted instantiation: AAT::LookupFormat6<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat6<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
294
295
  protected:
296
  HBUINT16  format;   /* Format identifier--format = 6 */
297
  VarSizedBinSearchArrayOf<LookupSingle<T>>
298
    entries;  /* The actual entries, sorted by glyph index. */
299
  public:
300
  DEFINE_SIZE_ARRAY (8, entries);
301
};
302
303
template <typename T>
304
struct LookupFormat8
305
{
306
  friend struct Lookup<T>;
307
308
  private:
309
  const T* get_value (hb_codepoint_t glyph_id) const
310
13.9M
  {
311
13.9M
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
9.35M
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
13.9M
  }
AAT::LookupFormat8<OT::IntType<unsigned short, 2u> >::get_value(unsigned int) const
Line
Count
Source
310
12.7M
  {
311
12.7M
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
8.80M
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
12.7M
  }
AAT::LookupFormat8<OT::HBGlyphID16>::get_value(unsigned int) const
Line
Count
Source
310
1.19M
  {
311
1.19M
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
646k
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
1.19M
  }
AAT::LookupFormat8<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int) const
Line
Count
Source
310
68
  {
311
68
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
68
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
68
  }
AAT::LookupFormat8<OT::IntType<unsigned int, 4u> >::get_value(unsigned int) const
Line
Count
Source
310
1.95k
  {
311
1.95k
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
1.29k
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
1.95k
  }
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::get_value(unsigned int) const
314
315
  bool sanitize (hb_sanitize_context_t *c) const
316
7.34k
  {
317
7.34k
    TRACE_SANITIZE (this);
318
7.34k
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
319
7.34k
  }
AAT::LookupFormat8<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
316
6.65k
  {
317
6.65k
    TRACE_SANITIZE (this);
318
6.65k
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
319
6.65k
  }
AAT::LookupFormat8<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
316
566
  {
317
566
    TRACE_SANITIZE (this);
318
566
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
319
566
  }
AAT::LookupFormat8<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
316
124
  {
317
124
    TRACE_SANITIZE (this);
318
124
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
319
124
  }
320
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
321
301
  {
322
301
    TRACE_SANITIZE (this);
323
301
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount, base));
324
301
  }
AAT::LookupFormat8<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
321
301
  {
322
301
    TRACE_SANITIZE (this);
323
301
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount, base));
324
301
  }
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
325
326
  protected:
327
  HBUINT16  format;   /* Format identifier--format = 8 */
328
  HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
329
  HBUINT16  glyphCount; /* Total number of glyphs (equivalent to the last
330
         * glyph minus the value of firstGlyph plus 1). */
331
  UnsizedArrayOf<T>
332
    valueArrayZ;  /* The lookup values (indexed by the glyph index
333
         * minus the value of firstGlyph). */
334
  public:
335
  DEFINE_SIZE_ARRAY (6, valueArrayZ);
336
};
337
338
template <typename T>
339
struct LookupFormat10
340
{
341
  friend struct Lookup<T>;
342
343
  private:
344
  const typename T::type get_value_or_null (hb_codepoint_t glyph_id) const
345
7.18k
  {
346
7.18k
    if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
347
3.74k
      return Null (T);
348
349
3.44k
    const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
350
351
3.44k
    unsigned int v = 0;
352
3.44k
    unsigned int count = valueSize;
353
7.55k
    for (unsigned int i = 0; i < count; i++)
354
4.11k
      v = (v << 8) | *p++;
355
356
3.44k
    return v;
357
7.18k
  }
AAT::LookupFormat10<OT::IntType<unsigned int, 4u> >::get_value_or_null(unsigned int) const
Line
Count
Source
345
3.93k
  {
346
3.93k
    if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
347
1.97k
      return Null (T);
348
349
1.95k
    const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
350
351
1.95k
    unsigned int v = 0;
352
1.95k
    unsigned int count = valueSize;
353
3.94k
    for (unsigned int i = 0; i < count; i++)
354
1.98k
      v = (v << 8) | *p++;
355
356
1.95k
    return v;
357
3.93k
  }
AAT::LookupFormat10<OT::IntType<unsigned short, 2u> >::get_value_or_null(unsigned int) const
Line
Count
Source
345
3.25k
  {
346
3.25k
    if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
347
1.76k
      return Null (T);
348
349
1.48k
    const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
350
351
1.48k
    unsigned int v = 0;
352
1.48k
    unsigned int count = valueSize;
353
3.61k
    for (unsigned int i = 0; i < count; i++)
354
2.12k
      v = (v << 8) | *p++;
355
356
1.48k
    return v;
357
3.25k
  }
358
359
  bool sanitize (hb_sanitize_context_t *c) const
360
424
  {
361
424
    TRACE_SANITIZE (this);
362
424
    return_trace (c->check_struct (this) &&
363
424
      valueSize <= 4 &&
364
424
      valueArrayZ.sanitize (c, glyphCount * valueSize));
365
424
  }
AAT::LookupFormat10<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
360
204
  {
361
204
    TRACE_SANITIZE (this);
362
204
    return_trace (c->check_struct (this) &&
363
204
      valueSize <= 4 &&
364
204
      valueArrayZ.sanitize (c, glyphCount * valueSize));
365
204
  }
AAT::LookupFormat10<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
360
17
  {
361
17
    TRACE_SANITIZE (this);
362
17
    return_trace (c->check_struct (this) &&
363
17
      valueSize <= 4 &&
364
17
      valueArrayZ.sanitize (c, glyphCount * valueSize));
365
17
  }
AAT::LookupFormat10<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
360
203
  {
361
203
    TRACE_SANITIZE (this);
362
203
    return_trace (c->check_struct (this) &&
363
203
      valueSize <= 4 &&
364
203
      valueArrayZ.sanitize (c, glyphCount * valueSize));
365
203
  }
366
367
  protected:
368
  HBUINT16  format;   /* Format identifier--format = 8 */
369
  HBUINT16  valueSize;  /* Byte size of each value. */
370
  HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
371
  HBUINT16  glyphCount; /* Total number of glyphs (equivalent to the last
372
         * glyph minus the value of firstGlyph plus 1). */
373
  UnsizedArrayOf<HBUINT8>
374
    valueArrayZ;  /* The lookup values (indexed by the glyph index
375
         * minus the value of firstGlyph). */
376
  public:
377
  DEFINE_SIZE_ARRAY (8, valueArrayZ);
378
};
379
380
template <typename T>
381
struct Lookup
382
{
383
  const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
384
34.0M
  {
385
34.0M
    switch (u.format) {
386
13.4M
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
39.3k
    case 2: return u.format2.get_value (glyph_id);
388
53.1k
    case 4: return u.format4.get_value (glyph_id);
389
3.44M
    case 6: return u.format6.get_value (glyph_id);
390
13.9M
    case 8: return u.format8.get_value (glyph_id);
391
3.12M
    default:return nullptr;
392
34.0M
    }
393
34.0M
  }
AAT::Lookup<OT::IntType<unsigned short, 2u> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
384
27.1M
  {
385
27.1M
    switch (u.format) {
386
8.41M
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
34.9k
    case 2: return u.format2.get_value (glyph_id);
388
1.77k
    case 4: return u.format4.get_value (glyph_id);
389
3.43M
    case 6: return u.format6.get_value (glyph_id);
390
12.7M
    case 8: return u.format8.get_value (glyph_id);
391
2.52M
    default:return nullptr;
392
27.1M
    }
393
27.1M
  }
AAT::Lookup<OT::HBGlyphID16>::get_value(unsigned int, unsigned int) const
Line
Count
Source
384
6.35M
  {
385
6.35M
    switch (u.format) {
386
4.88M
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
54
    case 2: return u.format2.get_value (glyph_id);
388
49.7k
    case 4: return u.format4.get_value (glyph_id);
389
9.06k
    case 6: return u.format6.get_value (glyph_id);
390
1.19M
    case 8: return u.format8.get_value (glyph_id);
391
224k
    default:return nullptr;
392
6.35M
    }
393
6.35M
  }
AAT::Lookup<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
384
487k
  {
385
487k
    switch (u.format) {
386
114k
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
228
    case 2: return u.format2.get_value (glyph_id);
388
132
    case 4: return u.format4.get_value (glyph_id);
389
132
    case 6: return u.format6.get_value (glyph_id);
390
68
    case 8: return u.format8.get_value (glyph_id);
391
372k
    default:return nullptr;
392
487k
    }
393
487k
  }
AAT::Lookup<OT::IntType<unsigned int, 4u> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
384
38.1k
  {
385
38.1k
    switch (u.format) {
386
22.5k
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
4.16k
    case 2: return u.format2.get_value (glyph_id);
388
1.50k
    case 4: return u.format4.get_value (glyph_id);
389
3.64k
    case 6: return u.format6.get_value (glyph_id);
390
1.95k
    case 8: return u.format8.get_value (glyph_id);
391
4.34k
    default:return nullptr;
392
38.1k
    }
393
38.1k
  }
Unexecuted instantiation: AAT::Lookup<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::get_value(unsigned int, unsigned int) const
394
395
  const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
396
69.6k
  {
397
69.6k
    switch (u.format) {
398
      /* Format 10 cannot return a pointer. */
399
7.18k
      case 10: return u.format10.get_value_or_null (glyph_id);
400
62.4k
      default:
401
62.4k
      const T *v = get_value (glyph_id, num_glyphs);
402
62.4k
      return v ? *v : Null (T);
403
69.6k
    }
404
69.6k
  }
AAT::Lookup<OT::IntType<unsigned int, 4u> >::get_value_or_null(unsigned int, unsigned int) const
Line
Count
Source
396
42.0k
  {
397
42.0k
    switch (u.format) {
398
      /* Format 10 cannot return a pointer. */
399
3.93k
      case 10: return u.format10.get_value_or_null (glyph_id);
400
38.1k
      default:
401
38.1k
      const T *v = get_value (glyph_id, num_glyphs);
402
38.1k
      return v ? *v : Null (T);
403
42.0k
    }
404
42.0k
  }
AAT::Lookup<OT::IntType<unsigned short, 2u> >::get_value_or_null(unsigned int, unsigned int) const
Line
Count
Source
396
27.5k
  {
397
27.5k
    switch (u.format) {
398
      /* Format 10 cannot return a pointer. */
399
3.25k
      case 10: return u.format10.get_value_or_null (glyph_id);
400
24.2k
      default:
401
24.2k
      const T *v = get_value (glyph_id, num_glyphs);
402
24.2k
      return v ? *v : Null (T);
403
27.5k
    }
404
27.5k
  }
405
406
  typename T::type get_class (hb_codepoint_t glyph_id,
407
            unsigned int num_glyphs,
408
            unsigned int outOfRange) const
409
27.1M
  {
410
27.1M
    const T *v = get_value (glyph_id, num_glyphs);
411
27.1M
    return v ? *v : outOfRange;
412
27.1M
  }
413
414
  bool sanitize (hb_sanitize_context_t *c) const
415
23.8k
  {
416
23.8k
    TRACE_SANITIZE (this);
417
23.8k
    if (!u.format.sanitize (c)) return_trace (false);
418
23.5k
    switch (u.format) {
419
9.28k
    case 0: return_trace (u.format0.sanitize (c));
420
924
    case 2: return_trace (u.format2.sanitize (c));
421
494
    case 4: return_trace (u.format4.sanitize (c));
422
2.98k
    case 6: return_trace (u.format6.sanitize (c));
423
7.34k
    case 8: return_trace (u.format8.sanitize (c));
424
424
    case 10: return_trace (u.format10.sanitize (c));
425
2.14k
    default:return_trace (true);
426
23.5k
    }
427
23.5k
  }
AAT::Lookup<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
415
17.0k
  {
416
17.0k
    TRACE_SANITIZE (this);
417
17.0k
    if (!u.format.sanitize (c)) return_trace (false);
418
16.9k
    switch (u.format) {
419
5.25k
    case 0: return_trace (u.format0.sanitize (c));
420
683
    case 2: return_trace (u.format2.sanitize (c));
421
249
    case 4: return_trace (u.format4.sanitize (c));
422
2.39k
    case 6: return_trace (u.format6.sanitize (c));
423
6.65k
    case 8: return_trace (u.format8.sanitize (c));
424
204
    case 10: return_trace (u.format10.sanitize (c));
425
1.47k
    default:return_trace (true);
426
16.9k
    }
427
16.9k
  }
AAT::Lookup<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
415
4.28k
  {
416
4.28k
    TRACE_SANITIZE (this);
417
4.28k
    if (!u.format.sanitize (c)) return_trace (false);
418
4.22k
    switch (u.format) {
419
2.82k
    case 0: return_trace (u.format0.sanitize (c));
420
27
    case 2: return_trace (u.format2.sanitize (c));
421
47
    case 4: return_trace (u.format4.sanitize (c));
422
390
    case 6: return_trace (u.format6.sanitize (c));
423
566
    case 8: return_trace (u.format8.sanitize (c));
424
17
    case 10: return_trace (u.format10.sanitize (c));
425
351
    default:return_trace (true);
426
4.22k
    }
427
4.22k
  }
AAT::Lookup<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
415
2.51k
  {
416
2.51k
    TRACE_SANITIZE (this);
417
2.51k
    if (!u.format.sanitize (c)) return_trace (false);
418
2.45k
    switch (u.format) {
419
1.20k
    case 0: return_trace (u.format0.sanitize (c));
420
214
    case 2: return_trace (u.format2.sanitize (c));
421
198
    case 4: return_trace (u.format4.sanitize (c));
422
193
    case 6: return_trace (u.format6.sanitize (c));
423
124
    case 8: return_trace (u.format8.sanitize (c));
424
203
    case 10: return_trace (u.format10.sanitize (c));
425
319
    default:return_trace (true);
426
2.45k
    }
427
2.45k
  }
428
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
429
3.75k
  {
430
3.75k
    TRACE_SANITIZE (this);
431
3.75k
    if (!u.format.sanitize (c)) return_trace (false);
432
3.66k
    switch (u.format) {
433
951
    case 0: return_trace (u.format0.sanitize (c, base));
434
621
    case 2: return_trace (u.format2.sanitize (c, base));
435
531
    case 4: return_trace (u.format4.sanitize (c, base));
436
457
    case 6: return_trace (u.format6.sanitize (c, base));
437
301
    case 8: return_trace (u.format8.sanitize (c, base));
438
43
    case 10: return_trace (false); /* We don't support format10 here currently. */
439
761
    default:return_trace (true);
440
3.66k
    }
441
3.66k
  }
AAT::Lookup<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
429
3.75k
  {
430
3.75k
    TRACE_SANITIZE (this);
431
3.75k
    if (!u.format.sanitize (c)) return_trace (false);
432
3.66k
    switch (u.format) {
433
951
    case 0: return_trace (u.format0.sanitize (c, base));
434
621
    case 2: return_trace (u.format2.sanitize (c, base));
435
531
    case 4: return_trace (u.format4.sanitize (c, base));
436
457
    case 6: return_trace (u.format6.sanitize (c, base));
437
301
    case 8: return_trace (u.format8.sanitize (c, base));
438
43
    case 10: return_trace (false); /* We don't support format10 here currently. */
439
761
    default:return_trace (true);
440
3.66k
    }
441
3.66k
  }
Unexecuted instantiation: AAT::Lookup<OT::OffsetTo<OT::ArrayOf<AAT::WidthDeltaPair, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: AAT::Lookup<OT::OffsetTo<AAT::OpticalBounds, OT::IntType<unsigned short, 2u>, true> >::sanitize(hb_sanitize_context_t*, void const*) const
442
443
  protected:
444
  union {
445
  HBUINT16    format;   /* Format identifier */
446
  LookupFormat0<T>  format0;
447
  LookupFormat2<T>  format2;
448
  LookupFormat4<T>  format4;
449
  LookupFormat6<T>  format6;
450
  LookupFormat8<T>  format8;
451
  LookupFormat10<T> format10;
452
  } u;
453
  public:
454
  DEFINE_SIZE_UNION (2, format);
455
};
456
DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2);
457
458
enum { DELETED_GLYPH = 0xFFFF };
459
460
/*
461
 * (Extended) State Table
462
 */
463
464
template <typename T>
465
struct Entry
466
{
467
  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
468
  {
469
    TRACE_SANITIZE (this);
470
    /* Note, we don't recurse-sanitize data because we don't access it.
471
     * That said, in our DEFINE_SIZE_STATIC we access T::static_size,
472
     * which ensures that data has a simple sanitize(). To be determined
473
     * if I need to remove that as well.
474
     *
475
     * HOWEVER! Because we are a template, our DEFINE_SIZE_STATIC
476
     * assertion wouldn't be checked, hence the line below. */
477
    static_assert (T::static_size, "");
478
479
    return_trace (c->check_struct (this));
480
  }
481
482
  public:
483
  HBUINT16  newState; /* Byte offset from beginning of state table
484
         * to the new state. Really?!?! Or just state
485
         * number?  The latter in morx for sure. */
486
  HBUINT16  flags;    /* Table specific. */
487
  T   data;   /* Optional offsets to per-glyph tables. */
488
  public:
489
  DEFINE_SIZE_STATIC (4 + T::static_size);
490
};
491
492
template <>
493
struct Entry<void>
494
{
495
  bool sanitize (hb_sanitize_context_t *c, unsigned int count /*XXX Unused?*/) const
496
0
  {
497
0
    TRACE_SANITIZE (this);
498
0
    return_trace (c->check_struct (this));
499
0
  }
500
501
  public:
502
  HBUINT16  newState; /* Byte offset from beginning of state table to the new state. */
503
  HBUINT16  flags;    /* Table specific. */
504
  public:
505
  DEFINE_SIZE_STATIC (4);
506
};
507
508
template <typename Types, typename Extra>
509
struct StateTable
510
{
511
  typedef typename Types::HBUINT HBUINT;
512
  typedef typename Types::HBUSHORT HBUSHORT;
513
  typedef typename Types::ClassTypeNarrow ClassType;
514
515
  enum State
516
  {
517
    STATE_START_OF_TEXT = 0,
518
    STATE_START_OF_LINE = 1,
519
  };
520
  enum Class
521
  {
522
    CLASS_END_OF_TEXT = 0,
523
    CLASS_OUT_OF_BOUNDS = 1,
524
    CLASS_DELETED_GLYPH = 2,
525
    CLASS_END_OF_LINE = 3,
526
  };
527
528
  int new_state (unsigned int newState) const
529
49.2M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ExtendedTypes, void>::new_state(unsigned int) const
Line
Count
Source
529
2.85M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::new_state(unsigned int) const
Line
Count
Source
529
6.71M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::new_state(unsigned int) const
Line
Count
Source
529
598k
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::new_state(unsigned int) const
Line
Count
Source
529
11.8M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ObsoleteTypes, void>::new_state(unsigned int) const
Line
Count
Source
529
11.7M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::new_state(unsigned int) const
Line
Count
Source
529
2.10M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::new_state(unsigned int) const
Line
Count
Source
529
5.72M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::new_state(unsigned int) const
Line
Count
Source
529
4.06M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::new_state(unsigned int) const
Line
Count
Source
529
3.49M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
530
531
  unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
532
45.6M
  {
533
45.6M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
45.5M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
45.6M
  }
AAT::StateTable<AAT::ExtendedTypes, void>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
2.84M
  {
533
2.84M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
2.84M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
2.84M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
6.69M
  {
533
6.69M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
6.65M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
6.69M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
569k
  {
533
569k
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
569k
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
569k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
10.8M
  {
533
10.8M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
10.8M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
10.8M
  }
AAT::StateTable<AAT::ObsoleteTypes, void>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
11.1M
  {
533
11.1M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
11.1M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
11.1M
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
2.06M
  {
533
2.06M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
1.99M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
2.06M
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
5.22M
  {
533
5.22M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
5.22M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
5.22M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
3.31M
  {
533
3.31M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
3.31M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
3.31M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
2.90M
  {
533
2.90M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
2.90M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
2.90M
  }
536
537
  const Entry<Extra> *get_entries () const
538
1.97k
  { return (this+entryTable).arrayZ; }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_entries() const
Line
Count
Source
538
1.97k
  { return (this+entryTable).arrayZ; }
Unexecuted instantiation: AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::get_entries() const
539
540
  const Entry<Extra> &get_entry (int state, unsigned int klass) const
541
69.3M
  {
542
69.3M
    if (unlikely (klass >= nClasses))
543
1.33M
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
69.3M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
69.3M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
69.3M
    unsigned int entry = states[state * nClasses + klass];
549
69.3M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
69.3M
    return entries[entry];
552
69.3M
  }
AAT::StateTable<AAT::ExtendedTypes, void>::get_entry(int, unsigned int) const
Line
Count
Source
541
5.40M
  {
542
5.40M
    if (unlikely (klass >= nClasses))
543
162k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
5.40M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
5.40M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
5.40M
    unsigned int entry = states[state * nClasses + klass];
549
5.40M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
5.40M
    return entries[entry];
552
5.40M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
9.13M
  {
542
9.13M
    if (unlikely (klass >= nClasses))
543
58.4k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
9.13M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
9.13M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
9.13M
    unsigned int entry = states[state * nClasses + klass];
549
9.13M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
9.13M
    return entries[entry];
552
9.13M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
987k
  {
542
987k
    if (unlikely (klass >= nClasses))
543
1.16k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
987k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
987k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
987k
    unsigned int entry = states[state * nClasses + klass];
549
987k
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
987k
    return entries[entry];
552
987k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
20.0M
  {
542
20.0M
    if (unlikely (klass >= nClasses))
543
140k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
20.0M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
20.0M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
20.0M
    unsigned int entry = states[state * nClasses + klass];
549
20.0M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
20.0M
    return entries[entry];
552
20.0M
  }
AAT::StateTable<AAT::ObsoleteTypes, void>::get_entry(int, unsigned int) const
Line
Count
Source
541
13.5M
  {
542
13.5M
    if (unlikely (klass >= nClasses))
543
365k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
13.5M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
13.5M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
13.5M
    unsigned int entry = states[state * nClasses + klass];
549
13.5M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
13.5M
    return entries[entry];
552
13.5M
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
2.14M
  {
542
2.14M
    if (unlikely (klass >= nClasses))
543
179
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
2.14M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
2.14M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
2.14M
    unsigned int entry = states[state * nClasses + klass];
549
2.14M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
2.14M
    return entries[entry];
552
2.14M
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
8.71M
  {
542
8.71M
    if (unlikely (klass >= nClasses))
543
95.1k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
8.71M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
8.71M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
8.71M
    unsigned int entry = states[state * nClasses + klass];
549
8.71M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
8.71M
    return entries[entry];
552
8.71M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
5.42M
  {
542
5.42M
    if (unlikely (klass >= nClasses))
543
148k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
5.42M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
5.42M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
5.42M
    unsigned int entry = states[state * nClasses + klass];
549
5.42M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
5.42M
    return entries[entry];
552
5.42M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
4.01M
  {
542
4.01M
    if (unlikely (klass >= nClasses))
543
359k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
4.01M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
4.01M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
4.01M
    unsigned int entry = states[state * nClasses + klass];
549
4.01M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
4.01M
    return entries[entry];
552
4.01M
  }
553
554
  bool sanitize (hb_sanitize_context_t *c,
555
     unsigned int *num_entries_out = nullptr) const
556
17.1k
  {
557
17.1k
    TRACE_SANITIZE (this);
558
17.1k
    if (unlikely (!(c->check_struct (this) &&
559
17.1k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
17.1k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
16.4k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
16.4k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
16.4k
    unsigned int num_classes = nClasses;
566
16.4k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
76
      return_trace (false);
568
16.3k
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
16.3k
    int min_state = 0;
585
16.3k
    int max_state = 0;
586
16.3k
    unsigned int num_entries = 0;
587
588
16.3k
    int state_pos = 0;
589
16.3k
    int state_neg = 0;
590
16.3k
    unsigned int entry = 0;
591
36.7k
    while (min_state < state_neg || state_pos <= max_state)
592
22.6k
    {
593
22.6k
      if (min_state < state_neg)
594
295
      {
595
  /* Negative states. */
596
295
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
295
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
22.3k
      if (state_pos <= max_state)
615
22.3k
      {
616
  /* Positive states. */
617
22.3k
  if (unlikely (!c->check_range (states,
618
22.3k
               max_state + 1,
619
22.3k
               row_stride)))
620
1.05k
    return_trace (false);
621
21.3k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
21.3k
  { /* Sweep new states. */
624
21.3k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
21.3k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
21.3k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
44.3M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
44.3M
      num_entries = hb_max (num_entries, *p + 1u);
631
21.3k
    state_pos = max_state + 1;
632
21.3k
  }
633
21.3k
      }
634
635
21.3k
      if (unlikely (!c->check_array (entries, num_entries)))
636
948
  return_trace (false);
637
20.3k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
20.3k
      { /* Sweep new entries. */
640
20.3k
  const Entry<Extra> *stop = &entries[num_entries];
641
1.37M
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
1.35M
  {
643
1.35M
    int newState = new_state (p->newState);
644
1.35M
    min_state = hb_min (min_state, newState);
645
1.35M
    max_state = hb_max (max_state, newState);
646
1.35M
  }
647
20.3k
  entry = num_entries;
648
20.3k
      }
649
20.3k
    }
650
651
14.0k
    if (num_entries_out)
652
2.40k
      *num_entries_out = num_entries;
653
654
14.0k
    return_trace (true);
655
16.3k
  }
AAT::StateTable<AAT::ExtendedTypes, void>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
1.11k
  {
557
1.11k
    TRACE_SANITIZE (this);
558
1.11k
    if (unlikely (!(c->check_struct (this) &&
559
1.11k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
1.11k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
1.05k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
1.05k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
1.05k
    unsigned int num_classes = nClasses;
566
1.05k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
14
      return_trace (false);
568
1.04k
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
1.04k
    int min_state = 0;
585
1.04k
    int max_state = 0;
586
1.04k
    unsigned int num_entries = 0;
587
588
1.04k
    int state_pos = 0;
589
1.04k
    int state_neg = 0;
590
1.04k
    unsigned int entry = 0;
591
2.31k
    while (min_state < state_neg || state_pos <= max_state)
592
1.52k
    {
593
1.52k
      if (min_state < state_neg)
594
0
      {
595
  /* Negative states. */
596
0
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
0
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
1.52k
      if (state_pos <= max_state)
615
1.52k
      {
616
  /* Positive states. */
617
1.52k
  if (unlikely (!c->check_range (states,
618
1.52k
               max_state + 1,
619
1.52k
               row_stride)))
620
140
    return_trace (false);
621
1.38k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
1.38k
  { /* Sweep new states. */
624
1.38k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
1.38k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
1.38k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
16.1k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
14.7k
      num_entries = hb_max (num_entries, *p + 1u);
631
1.38k
    state_pos = max_state + 1;
632
1.38k
  }
633
1.38k
      }
634
635
1.38k
      if (unlikely (!c->check_array (entries, num_entries)))
636
117
  return_trace (false);
637
1.26k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
1.26k
      { /* Sweep new entries. */
640
1.26k
  const Entry<Extra> *stop = &entries[num_entries];
641
7.86k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
6.60k
  {
643
6.60k
    int newState = new_state (p->newState);
644
6.60k
    min_state = hb_min (min_state, newState);
645
6.60k
    max_state = hb_max (max_state, newState);
646
6.60k
  }
647
1.26k
  entry = num_entries;
648
1.26k
      }
649
1.26k
    }
650
651
788
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
788
    return_trace (true);
655
1.04k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
2.27k
  {
557
2.27k
    TRACE_SANITIZE (this);
558
2.27k
    if (unlikely (!(c->check_struct (this) &&
559
2.27k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
2.27k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
2.20k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
2.20k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
2.20k
    unsigned int num_classes = nClasses;
566
2.20k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
12
      return_trace (false);
568
2.18k
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
2.18k
    int min_state = 0;
585
2.18k
    int max_state = 0;
586
2.18k
    unsigned int num_entries = 0;
587
588
2.18k
    int state_pos = 0;
589
2.18k
    int state_neg = 0;
590
2.18k
    unsigned int entry = 0;
591
4.97k
    while (min_state < state_neg || state_pos <= max_state)
592
2.99k
    {
593
2.99k
      if (min_state < state_neg)
594
0
      {
595
  /* Negative states. */
596
0
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
0
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
2.99k
      if (state_pos <= max_state)
615
2.99k
      {
616
  /* Positive states. */
617
2.99k
  if (unlikely (!c->check_range (states,
618
2.99k
               max_state + 1,
619
2.99k
               row_stride)))
620
97
    return_trace (false);
621
2.90k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
2.90k
  { /* Sweep new states. */
624
2.90k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
2.90k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
2.90k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
22.2k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
19.3k
      num_entries = hb_max (num_entries, *p + 1u);
631
2.90k
    state_pos = max_state + 1;
632
2.90k
  }
633
2.90k
      }
634
635
2.90k
      if (unlikely (!c->check_array (entries, num_entries)))
636
113
  return_trace (false);
637
2.78k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
2.78k
      { /* Sweep new entries. */
640
2.78k
  const Entry<Extra> *stop = &entries[num_entries];
641
7.93k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
5.14k
  {
643
5.14k
    int newState = new_state (p->newState);
644
5.14k
    min_state = hb_min (min_state, newState);
645
5.14k
    max_state = hb_max (max_state, newState);
646
5.14k
  }
647
2.78k
  entry = num_entries;
648
2.78k
      }
649
2.78k
    }
650
651
1.97k
    if (num_entries_out)
652
1.97k
      *num_entries_out = num_entries;
653
654
1.97k
    return_trace (true);
655
2.18k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
900
  {
557
900
    TRACE_SANITIZE (this);
558
900
    if (unlikely (!(c->check_struct (this) &&
559
900
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
900
        classTable.sanitize (c, this)))) return_trace (false);
561
562
864
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
864
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
864
    unsigned int num_classes = nClasses;
566
864
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
10
      return_trace (false);
568
854
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
854
    int min_state = 0;
585
854
    int max_state = 0;
586
854
    unsigned int num_entries = 0;
587
588
854
    int state_pos = 0;
589
854
    int state_neg = 0;
590
854
    unsigned int entry = 0;
591
2.35k
    while (min_state < state_neg || state_pos <= max_state)
592
1.70k
    {
593
1.70k
      if (min_state < state_neg)
594
0
      {
595
  /* Negative states. */
596
0
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
0
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
1.70k
      if (state_pos <= max_state)
615
1.70k
      {
616
  /* Positive states. */
617
1.70k
  if (unlikely (!c->check_range (states,
618
1.70k
               max_state + 1,
619
1.70k
               row_stride)))
620
91
    return_trace (false);
621
1.61k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
1.61k
  { /* Sweep new states. */
624
1.61k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
1.61k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
1.61k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
201k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
200k
      num_entries = hb_max (num_entries, *p + 1u);
631
1.61k
    state_pos = max_state + 1;
632
1.61k
  }
633
1.61k
      }
634
635
1.61k
      if (unlikely (!c->check_array (entries, num_entries)))
636
106
  return_trace (false);
637
1.50k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
1.50k
      { /* Sweep new entries. */
640
1.50k
  const Entry<Extra> *stop = &entries[num_entries];
641
23.3k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
21.8k
  {
643
21.8k
    int newState = new_state (p->newState);
644
21.8k
    min_state = hb_min (min_state, newState);
645
21.8k
    max_state = hb_max (max_state, newState);
646
21.8k
  }
647
1.50k
  entry = num_entries;
648
1.50k
      }
649
1.50k
    }
650
651
657
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
657
    return_trace (true);
655
854
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
6.97k
  {
557
6.97k
    TRACE_SANITIZE (this);
558
6.97k
    if (unlikely (!(c->check_struct (this) &&
559
6.97k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
6.97k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
6.89k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
6.89k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
6.89k
    unsigned int num_classes = nClasses;
566
6.89k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
14
      return_trace (false);
568
6.87k
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
6.87k
    int min_state = 0;
585
6.87k
    int max_state = 0;
586
6.87k
    unsigned int num_entries = 0;
587
588
6.87k
    int state_pos = 0;
589
6.87k
    int state_neg = 0;
590
6.87k
    unsigned int entry = 0;
591
14.3k
    while (min_state < state_neg || state_pos <= max_state)
592
7.72k
    {
593
7.72k
      if (min_state < state_neg)
594
0
      {
595
  /* Negative states. */
596
0
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
0
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
7.72k
      if (state_pos <= max_state)
615
7.72k
      {
616
  /* Positive states. */
617
7.72k
  if (unlikely (!c->check_range (states,
618
7.72k
               max_state + 1,
619
7.72k
               row_stride)))
620
93
    return_trace (false);
621
7.63k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
7.63k
  { /* Sweep new states. */
624
7.63k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
7.63k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
7.63k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
54.1k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
46.4k
      num_entries = hb_max (num_entries, *p + 1u);
631
7.63k
    state_pos = max_state + 1;
632
7.63k
  }
633
7.63k
      }
634
635
7.63k
      if (unlikely (!c->check_array (entries, num_entries)))
636
159
  return_trace (false);
637
7.47k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
7.47k
      { /* Sweep new entries. */
640
7.47k
  const Entry<Extra> *stop = &entries[num_entries];
641
24.2k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
16.7k
  {
643
16.7k
    int newState = new_state (p->newState);
644
16.7k
    min_state = hb_min (min_state, newState);
645
16.7k
    max_state = hb_max (max_state, newState);
646
16.7k
  }
647
7.47k
  entry = num_entries;
648
7.47k
      }
649
7.47k
    }
650
651
6.62k
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
6.62k
    return_trace (true);
655
6.87k
  }
AAT::StateTable<AAT::ObsoleteTypes, void>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
1.59k
  {
557
1.59k
    TRACE_SANITIZE (this);
558
1.59k
    if (unlikely (!(c->check_struct (this) &&
559
1.59k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
1.59k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
1.47k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
1.47k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
1.47k
    unsigned int num_classes = nClasses;
566
1.47k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
0
      return_trace (false);
568
1.47k
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
1.47k
    int min_state = 0;
585
1.47k
    int max_state = 0;
586
1.47k
    unsigned int num_entries = 0;
587
588
1.47k
    int state_pos = 0;
589
1.47k
    int state_neg = 0;
590
1.47k
    unsigned int entry = 0;
591
4.09k
    while (min_state < state_neg || state_pos <= max_state)
592
2.96k
    {
593
2.96k
      if (min_state < state_neg)
594
168
      {
595
  /* Negative states. */
596
168
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
168
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
2.79k
      if (state_pos <= max_state)
615
2.79k
      {
616
  /* Positive states. */
617
2.79k
  if (unlikely (!c->check_range (states,
618
2.79k
               max_state + 1,
619
2.79k
               row_stride)))
620
125
    return_trace (false);
621
2.66k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
2.66k
  { /* Sweep new states. */
624
2.66k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
2.66k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
2.66k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
33.7M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
33.7M
      num_entries = hb_max (num_entries, *p + 1u);
631
2.66k
    state_pos = max_state + 1;
632
2.66k
  }
633
2.66k
      }
634
635
2.66k
      if (unlikely (!c->check_array (entries, num_entries)))
636
51
  return_trace (false);
637
2.61k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
2.61k
      { /* Sweep new entries. */
640
2.61k
  const Entry<Extra> *stop = &entries[num_entries];
641
221k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
219k
  {
643
219k
    int newState = new_state (p->newState);
644
219k
    min_state = hb_min (min_state, newState);
645
219k
    max_state = hb_max (max_state, newState);
646
219k
  }
647
2.61k
  entry = num_entries;
648
2.61k
      }
649
2.61k
    }
650
651
1.12k
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
1.12k
    return_trace (true);
655
1.47k
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
666
  {
557
666
    TRACE_SANITIZE (this);
558
666
    if (unlikely (!(c->check_struct (this) &&
559
666
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
666
        classTable.sanitize (c, this)))) return_trace (false);
561
562
612
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
612
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
612
    unsigned int num_classes = nClasses;
566
612
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
0
      return_trace (false);
568
612
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
612
    int min_state = 0;
585
612
    int max_state = 0;
586
612
    unsigned int num_entries = 0;
587
588
612
    int state_pos = 0;
589
612
    int state_neg = 0;
590
612
    unsigned int entry = 0;
591
1.45k
    while (min_state < state_neg || state_pos <= max_state)
592
1.03k
    {
593
1.03k
      if (min_state < state_neg)
594
71
      {
595
  /* Negative states. */
596
71
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
71
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
959
      if (state_pos <= max_state)
615
959
      {
616
  /* Positive states. */
617
959
  if (unlikely (!c->check_range (states,
618
959
               max_state + 1,
619
959
               row_stride)))
620
79
    return_trace (false);
621
880
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
880
  { /* Sweep new states. */
624
880
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
880
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
880
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
1.59M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
1.58M
      num_entries = hb_max (num_entries, *p + 1u);
631
880
    state_pos = max_state + 1;
632
880
  }
633
880
      }
634
635
880
      if (unlikely (!c->check_array (entries, num_entries)))
636
41
  return_trace (false);
637
839
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
839
      { /* Sweep new entries. */
640
839
  const Entry<Extra> *stop = &entries[num_entries];
641
35.0k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
34.1k
  {
643
34.1k
    int newState = new_state (p->newState);
644
34.1k
    min_state = hb_min (min_state, newState);
645
34.1k
    max_state = hb_max (max_state, newState);
646
34.1k
  }
647
839
  entry = num_entries;
648
839
      }
649
839
    }
650
651
421
    if (num_entries_out)
652
421
      *num_entries_out = num_entries;
653
654
421
    return_trace (true);
655
612
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
982
  {
557
982
    TRACE_SANITIZE (this);
558
982
    if (unlikely (!(c->check_struct (this) &&
559
982
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
982
        classTable.sanitize (c, this)))) return_trace (false);
561
562
941
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
941
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
941
    unsigned int num_classes = nClasses;
566
941
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
0
      return_trace (false);
568
941
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
941
    int min_state = 0;
585
941
    int max_state = 0;
586
941
    unsigned int num_entries = 0;
587
588
941
    int state_pos = 0;
589
941
    int state_neg = 0;
590
941
    unsigned int entry = 0;
591
2.28k
    while (min_state < state_neg || state_pos <= max_state)
592
1.50k
    {
593
1.50k
      if (min_state < state_neg)
594
56
      {
595
  /* Negative states. */
596
56
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
56
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
1.44k
      if (state_pos <= max_state)
615
1.44k
      {
616
  /* Positive states. */
617
1.44k
  if (unlikely (!c->check_range (states,
618
1.44k
               max_state + 1,
619
1.44k
               row_stride)))
620
66
    return_trace (false);
621
1.37k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
1.37k
  { /* Sweep new states. */
624
1.37k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
1.37k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
1.37k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
6.40M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
6.40M
      num_entries = hb_max (num_entries, *p + 1u);
631
1.37k
    state_pos = max_state + 1;
632
1.37k
  }
633
1.37k
      }
634
635
1.37k
      if (unlikely (!c->check_array (entries, num_entries)))
636
33
  return_trace (false);
637
1.34k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
1.34k
      { /* Sweep new entries. */
640
1.34k
  const Entry<Extra> *stop = &entries[num_entries];
641
133k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
132k
  {
643
132k
    int newState = new_state (p->newState);
644
132k
    min_state = hb_min (min_state, newState);
645
132k
    max_state = hb_max (max_state, newState);
646
132k
  }
647
1.34k
  entry = num_entries;
648
1.34k
      }
649
1.34k
    }
650
651
786
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
786
    return_trace (true);
655
941
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
991
  {
557
991
    TRACE_SANITIZE (this);
558
991
    if (unlikely (!(c->check_struct (this) &&
559
991
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
991
        classTable.sanitize (c, this)))) return_trace (false);
561
562
891
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
891
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
891
    unsigned int num_classes = nClasses;
566
891
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
14
      return_trace (false);
568
877
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
877
    int min_state = 0;
585
877
    int max_state = 0;
586
877
    unsigned int num_entries = 0;
587
588
877
    int state_pos = 0;
589
877
    int state_neg = 0;
590
877
    unsigned int entry = 0;
591
1.86k
    while (min_state < state_neg || state_pos <= max_state)
592
1.31k
    {
593
1.31k
      if (min_state < state_neg)
594
0
      {
595
  /* Negative states. */
596
0
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
0
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
1.31k
      if (state_pos <= max_state)
615
1.31k
      {
616
  /* Positive states. */
617
1.31k
  if (unlikely (!c->check_range (states,
618
1.31k
               max_state + 1,
619
1.31k
               row_stride)))
620
175
    return_trace (false);
621
1.13k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
1.13k
  { /* Sweep new states. */
624
1.13k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
1.13k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
1.13k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
779k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
778k
      num_entries = hb_max (num_entries, *p + 1u);
631
1.13k
    state_pos = max_state + 1;
632
1.13k
  }
633
1.13k
      }
634
635
1.13k
      if (unlikely (!c->check_array (entries, num_entries)))
636
152
  return_trace (false);
637
987
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
987
      { /* Sweep new entries. */
640
987
  const Entry<Extra> *stop = &entries[num_entries];
641
335k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
334k
  {
643
334k
    int newState = new_state (p->newState);
644
334k
    min_state = hb_min (min_state, newState);
645
334k
    max_state = hb_max (max_state, newState);
646
334k
  }
647
987
  entry = num_entries;
648
987
      }
649
987
    }
650
651
550
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
550
    return_trace (true);
655
877
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
1.65k
  {
557
1.65k
    TRACE_SANITIZE (this);
558
1.65k
    if (unlikely (!(c->check_struct (this) &&
559
1.65k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
1.65k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
1.47k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
1.47k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
1.47k
    unsigned int num_classes = nClasses;
566
1.47k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
12
      return_trace (false);
568
1.46k
    unsigned int row_stride = num_classes * states[0].static_size;
569
570
    /* Apple 'kern' table has this peculiarity:
571
     *
572
     * "Because the stateTableOffset in the state table header is (strictly
573
     * speaking) redundant, some 'kern' tables use it to record an initial
574
     * state where that should not be StartOfText. To determine if this is
575
     * done, calculate what the stateTableOffset should be. If it's different
576
     * from the actual stateTableOffset, use it as the initial state."
577
     *
578
     * We implement this by calling the initial state zero, but allow *negative*
579
     * states if the start state indeed was not the first state.  Since the code
580
     * is shared, this will also apply to 'mort' table.  The 'kerx' / 'morx'
581
     * tables are not affected since those address states by index, not offset.
582
     */
583
584
1.46k
    int min_state = 0;
585
1.46k
    int max_state = 0;
586
1.46k
    unsigned int num_entries = 0;
587
588
1.46k
    int state_pos = 0;
589
1.46k
    int state_neg = 0;
590
1.46k
    unsigned int entry = 0;
591
3.03k
    while (min_state < state_neg || state_pos <= max_state)
592
1.92k
    {
593
1.92k
      if (min_state < state_neg)
594
0
      {
595
  /* Negative states. */
596
0
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
0
    return_trace (false);
598
0
  if (unlikely (!c->check_range (&states[min_state * num_classes],
599
0
               -min_state,
600
0
               row_stride)))
601
0
    return_trace (false);
602
0
  if ((c->max_ops -= state_neg - min_state) <= 0)
603
0
    return_trace (false);
604
0
  { /* Sweep new states. */
605
0
    const HBUSHORT *stop = &states[min_state * num_classes];
606
0
    if (unlikely (stop > states))
607
0
      return_trace (false);
608
0
    for (const HBUSHORT *p = states; stop < p; p--)
609
0
      num_entries = hb_max (num_entries, *(p - 1) + 1u);
610
0
    state_neg = min_state;
611
0
  }
612
0
      }
613
614
1.92k
      if (state_pos <= max_state)
615
1.92k
      {
616
  /* Positive states. */
617
1.92k
  if (unlikely (!c->check_range (states,
618
1.92k
               max_state + 1,
619
1.92k
               row_stride)))
620
184
    return_trace (false);
621
1.74k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
1.74k
  { /* Sweep new states. */
624
1.74k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
1.74k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
1.74k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
1.56M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
1.56M
      num_entries = hb_max (num_entries, *p + 1u);
631
1.74k
    state_pos = max_state + 1;
632
1.74k
  }
633
1.74k
      }
634
635
1.74k
      if (unlikely (!c->check_array (entries, num_entries)))
636
176
  return_trace (false);
637
1.56k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
1.56k
      { /* Sweep new entries. */
640
1.56k
  const Entry<Extra> *stop = &entries[num_entries];
641
582k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
580k
  {
643
580k
    int newState = new_state (p->newState);
644
580k
    min_state = hb_min (min_state, newState);
645
580k
    max_state = hb_max (max_state, newState);
646
580k
  }
647
1.56k
  entry = num_entries;
648
1.56k
      }
649
1.56k
    }
650
651
1.10k
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
1.10k
    return_trace (true);
655
1.46k
  }
656
657
  protected:
658
  HBUINT  nClasses; /* Number of classes, which is the number of indices
659
         * in a single line in the state array. */
660
  NNOffsetTo<ClassType, HBUINT>
661
    classTable; /* Offset to the class table. */
662
  NNOffsetTo<UnsizedArrayOf<HBUSHORT>, HBUINT>
663
    stateArrayTable;/* Offset to the state array. */
664
  NNOffsetTo<UnsizedArrayOf<Entry<Extra>>, HBUINT>
665
    entryTable; /* Offset to the entry array. */
666
667
  public:
668
  DEFINE_SIZE_STATIC (4 * sizeof (HBUINT));
669
};
670
671
template <typename HBUCHAR>
672
struct ClassTable
673
{
674
  unsigned int get_class (hb_codepoint_t glyph_id, unsigned int outOfRange) const
675
18.4M
  {
676
18.4M
    unsigned int i = glyph_id - firstGlyph;
677
18.4M
    return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
678
18.4M
  }
AAT::ClassTable<OT::IntType<unsigned char, 1u> >::get_class(unsigned int, unsigned int) const
Line
Count
Source
675
18.4M
  {
676
18.4M
    unsigned int i = glyph_id - firstGlyph;
677
18.4M
    return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
678
18.4M
  }
AAT::ClassTable<OT::IntType<unsigned short, 2u> >::get_class(unsigned int, unsigned int) const
Line
Count
Source
675
51.3k
  {
676
51.3k
    unsigned int i = glyph_id - firstGlyph;
677
51.3k
    return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
678
51.3k
  }
679
  unsigned int get_class (hb_codepoint_t glyph_id,
680
        unsigned int num_glyphs HB_UNUSED,
681
        unsigned int outOfRange) const
682
18.4M
  {
683
18.4M
    return get_class (glyph_id, outOfRange);
684
18.4M
  }
AAT::ClassTable<OT::IntType<unsigned char, 1u> >::get_class(unsigned int, unsigned int, unsigned int) const
Line
Count
Source
682
18.4M
  {
683
18.4M
    return get_class (glyph_id, outOfRange);
684
18.4M
  }
AAT::ClassTable<OT::IntType<unsigned short, 2u> >::get_class(unsigned int, unsigned int, unsigned int) const
Line
Count
Source
682
51.3k
  {
683
51.3k
    return get_class (glyph_id, outOfRange);
684
51.3k
  }
685
  bool sanitize (hb_sanitize_context_t *c) const
686
5.61k
  {
687
5.61k
    TRACE_SANITIZE (this);
688
5.61k
    return_trace (c->check_struct (this) && classArray.sanitize (c));
689
5.61k
  }
AAT::ClassTable<OT::IntType<unsigned char, 1u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
686
3.13k
  {
687
3.13k
    TRACE_SANITIZE (this);
688
3.13k
    return_trace (c->check_struct (this) && classArray.sanitize (c));
689
3.13k
  }
AAT::ClassTable<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
686
2.48k
  {
687
2.48k
    TRACE_SANITIZE (this);
688
2.48k
    return_trace (c->check_struct (this) && classArray.sanitize (c));
689
2.48k
  }
690
  protected:
691
  HBGlyphID16   firstGlyph; /* First glyph index included in the trimmed array. */
692
  Array16Of<HBUCHAR>  classArray; /* The class codes (indexed by glyph index minus
693
           * firstGlyph). */
694
  public:
695
  DEFINE_SIZE_ARRAY (4, classArray);
696
};
697
698
struct ObsoleteTypes
699
{
700
  static constexpr bool extended = false;
701
  typedef HBUINT16 HBUINT;
702
  typedef HBUINT8 HBUSHORT;
703
  typedef ClassTable<HBUINT8> ClassTypeNarrow;
704
  typedef ClassTable<HBUINT16> ClassTypeWide;
705
706
  template <typename T>
707
  static unsigned int offsetToIndex (unsigned int offset,
708
             const void *base,
709
             const T *array)
710
6.32M
  {
711
    /* https://github.com/harfbuzz/harfbuzz/issues/3483 */
712
    /* If offset is less than base, return an offset that would
713
     * result in an address half a 32bit address-space away,
714
     * to make sure sanitize fails even on 32bit builds. */
715
6.32M
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
716
1.59M
      return INT_MAX / T::static_size;
717
718
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
719
4.73M
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
720
6.32M
  }
unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
Line
Count
Source
710
4.13M
  {
711
    /* https://github.com/harfbuzz/harfbuzz/issues/3483 */
712
    /* If offset is less than base, return an offset that would
713
     * result in an address half a 32bit address-space away,
714
     * to make sure sanitize fails even on 32bit builds. */
715
4.13M
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
716
963k
      return INT_MAX / T::static_size;
717
718
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
719
3.16M
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
720
4.13M
  }
unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::IntType<unsigned int, 4u> >(unsigned int, void const*, OT::IntType<unsigned int, 4u> const*)
Line
Count
Source
710
615k
  {
711
    /* https://github.com/harfbuzz/harfbuzz/issues/3483 */
712
    /* If offset is less than base, return an offset that would
713
     * result in an address half a 32bit address-space away,
714
     * to make sure sanitize fails even on 32bit builds. */
715
615k
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
716
54
      return INT_MAX / T::static_size;
717
718
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
719
615k
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
720
615k
  }
unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::IntType<unsigned short, 2u> >(unsigned int, void const*, OT::IntType<unsigned short, 2u> const*)
Line
Count
Source
710
131
  {
711
    /* https://github.com/harfbuzz/harfbuzz/issues/3483 */
712
    /* If offset is less than base, return an offset that would
713
     * result in an address half a 32bit address-space away,
714
     * to make sure sanitize fails even on 32bit builds. */
715
131
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
716
66
      return INT_MAX / T::static_size;
717
718
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
719
65
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
720
131
  }
unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::IntType<short, 2u> >(unsigned int, void const*, OT::IntType<short, 2u> const*)
Line
Count
Source
710
1.57M
  {
711
    /* https://github.com/harfbuzz/harfbuzz/issues/3483 */
712
    /* If offset is less than base, return an offset that would
713
     * result in an address half a 32bit address-space away,
714
     * to make sure sanitize fails even on 32bit builds. */
715
1.57M
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
716
627k
      return INT_MAX / T::static_size;
717
718
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
719
949k
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
720
1.57M
  }
721
  template <typename T>
722
  static unsigned int byteOffsetToIndex (unsigned int offset,
723
           const void *base,
724
           const T *array)
725
1.55M
  {
726
1.55M
    return offsetToIndex (offset, base, array);
727
1.55M
  }
728
  template <typename T>
729
  static unsigned int wordOffsetToIndex (unsigned int offset,
730
           const void *base,
731
           const T *array)
732
4.13M
  {
733
4.13M
    return offsetToIndex (2 * offset, base, array);
734
4.13M
  }
unsigned int AAT::ObsoleteTypes::wordOffsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
Line
Count
Source
732
4.13M
  {
733
4.13M
    return offsetToIndex (2 * offset, base, array);
734
4.13M
  }
unsigned int AAT::ObsoleteTypes::wordOffsetToIndex<OT::IntType<unsigned short, 2u> >(unsigned int, void const*, OT::IntType<unsigned short, 2u> const*)
Line
Count
Source
732
131
  {
733
131
    return offsetToIndex (2 * offset, base, array);
734
131
  }
735
};
736
struct ExtendedTypes
737
{
738
  static constexpr bool extended = true;
739
  typedef HBUINT32 HBUINT;
740
  typedef HBUINT16 HBUSHORT;
741
  typedef Lookup<HBUINT16> ClassTypeNarrow;
742
  typedef Lookup<HBUINT16> ClassTypeWide;
743
744
  template <typename T>
745
  static unsigned int offsetToIndex (unsigned int offset,
746
             const void *base HB_UNUSED,
747
             const T *array HB_UNUSED)
748
54.3k
  {
749
54.3k
    return offset;
750
54.3k
  }
unsigned int AAT::ExtendedTypes::offsetToIndex<OT::IntType<unsigned int, 4u> >(unsigned int, void const*, OT::IntType<unsigned int, 4u> const*)
Line
Count
Source
748
39.0k
  {
749
39.0k
    return offset;
750
39.0k
  }
Unexecuted instantiation: unsigned int AAT::ExtendedTypes::offsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
unsigned int AAT::ExtendedTypes::offsetToIndex<OT::IntType<short, 2u> >(unsigned int, void const*, OT::IntType<short, 2u> const*)
Line
Count
Source
748
15.3k
  {
749
15.3k
    return offset;
750
15.3k
  }
751
  template <typename T>
752
  static unsigned int byteOffsetToIndex (unsigned int offset,
753
           const void *base HB_UNUSED,
754
           const T *array HB_UNUSED)
755
1.20M
  {
756
1.20M
    return offset / 2;
757
1.20M
  }
758
  template <typename T>
759
  static unsigned int wordOffsetToIndex (unsigned int offset,
760
           const void *base HB_UNUSED,
761
           const T *array HB_UNUSED)
762
62
  {
763
62
    return offset;
764
62
  }
unsigned int AAT::ExtendedTypes::wordOffsetToIndex<OT::IntType<unsigned short, 2u> >(unsigned int, void const*, OT::IntType<unsigned short, 2u> const*)
Line
Count
Source
762
62
  {
763
62
    return offset;
764
62
  }
Unexecuted instantiation: unsigned int AAT::ExtendedTypes::wordOffsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
765
};
766
767
template <typename Types, typename EntryData>
768
struct StateTableDriver
769
{
770
  using StateTableT = StateTable<Types, EntryData>;
771
  using EntryT = Entry<EntryData>;
772
773
  StateTableDriver (const StateTableT &machine_,
774
        hb_buffer_t *buffer_,
775
        hb_face_t *face_) :
776
        machine (machine_),
777
        buffer (buffer_),
778
79.0k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ExtendedTypes, void>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, void> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
7.85k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
12.9k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
5.83k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
39.2k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ObsoleteTypes, void>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, void> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
4.93k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
1.46k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::StateTableDriver(AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
2.89k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
1.61k
        num_glyphs (face_->get_num_glyphs ()) {}
AAT::StateTableDriver<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::StateTableDriver(AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData> const&, hb_buffer_t*, hb_face_t*)
Line
Count
Source
778
2.24k
        num_glyphs (face_->get_num_glyphs ()) {}
779
780
  template <typename context_t>
781
  void drive (context_t *c, hb_aat_apply_context_t *ac)
782
79.0k
  {
783
79.0k
    if (!c->in_place)
784
48.3k
      buffer->clear_output ();
785
786
79.0k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
79.0k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
46.2M
    for (buffer->idx = 0; buffer->successful;)
790
46.2M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
46.2M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
46.2M
      unsigned int klass = buffer->idx < buffer->len ?
818
45.6M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
46.2M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
46.2M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
46.2M
      const EntryT &entry = machine.get_entry (state, klass);
822
46.2M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
46.2M
      const EntryT *wouldbe_entry;
853
46.2M
      bool safe_to_break =
854
  /* 1. */
855
46.2M
  !c->is_actionable (this, entry)
856
46.2M
      &&
857
  /* 2. */
858
46.2M
  (
859
    /* 2a. */
860
21.8M
    state == StateTableT::STATE_START_OF_TEXT
861
21.8M
  ||
862
    /* 2b. */
863
21.8M
    (
864
1.98M
      (entry.flags & context_t::DontAdvance) &&
865
1.98M
      next_state == StateTableT::STATE_START_OF_TEXT
866
1.98M
    )
867
21.8M
  ||
868
    /* 2c. */
869
21.8M
    (
870
1.83M
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
1.83M
    ,
872
      /* 2c'. */
873
1.83M
      !c->is_actionable (this, *wouldbe_entry)
874
1.83M
    &&
875
      /* 2c". */
876
1.83M
      (
877
1.57M
        next_state == machine.new_state (wouldbe_entry->newState)
878
1.57M
      &&
879
1.57M
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
1.57M
      )
881
1.83M
    )
882
21.8M
  )
883
46.2M
      &&
884
  /* 3. */
885
46.2M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
46.2M
      ;
887
888
46.2M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
8.33M
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
46.2M
      c->transition (this, entry);
892
893
46.2M
      state = next_state;
894
46.2M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
46.2M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
79.0k
  break;
898
899
46.2M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
7.59M
  (void) buffer->next_glyph ();
901
46.2M
    }
902
903
79.0k
    if (!c->in_place)
904
48.3k
      buffer->sync ();
905
79.0k
  }
void AAT::StateTableDriver<AAT::ExtendedTypes, void>::drive<AAT::RearrangementSubtable<AAT::ExtendedTypes>::driver_context_t>(AAT::RearrangementSubtable<AAT::ExtendedTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
7.85k
  {
783
7.85k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
7.85k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
7.85k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
2.84M
    for (buffer->idx = 0; buffer->successful;)
790
2.84M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
2.84M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
2.84M
      unsigned int klass = buffer->idx < buffer->len ?
818
2.84M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
2.84M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
2.84M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
2.84M
      const EntryT &entry = machine.get_entry (state, klass);
822
2.84M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
2.84M
      const EntryT *wouldbe_entry;
853
2.84M
      bool safe_to_break =
854
  /* 1. */
855
2.84M
  !c->is_actionable (this, entry)
856
2.84M
      &&
857
  /* 2. */
858
2.84M
  (
859
    /* 2a. */
860
2.55M
    state == StateTableT::STATE_START_OF_TEXT
861
2.55M
  ||
862
    /* 2b. */
863
2.55M
    (
864
3.08k
      (entry.flags & context_t::DontAdvance) &&
865
3.08k
      next_state == StateTableT::STATE_START_OF_TEXT
866
3.08k
    )
867
2.55M
  ||
868
    /* 2c. */
869
2.55M
    (
870
3.08k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
3.08k
    ,
872
      /* 2c'. */
873
3.08k
      !c->is_actionable (this, *wouldbe_entry)
874
3.08k
    &&
875
      /* 2c". */
876
3.08k
      (
877
3.03k
        next_state == machine.new_state (wouldbe_entry->newState)
878
3.03k
      &&
879
3.03k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
3.03k
      )
881
3.08k
    )
882
2.55M
  )
883
2.84M
      &&
884
  /* 3. */
885
2.84M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
2.84M
      ;
887
888
2.84M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
156k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
2.84M
      c->transition (this, entry);
892
893
2.84M
      state = next_state;
894
2.84M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
2.84M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
7.85k
  break;
898
899
2.84M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
32.9k
  (void) buffer->next_glyph ();
901
2.84M
    }
902
903
7.85k
    if (!c->in_place)
904
0
      buffer->sync ();
905
7.85k
  }
void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::drive<AAT::ContextualSubtable<AAT::ExtendedTypes>::driver_context_t>(AAT::ContextualSubtable<AAT::ExtendedTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
12.9k
  {
783
12.9k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
12.9k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
12.9k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
6.70M
    for (buffer->idx = 0; buffer->successful;)
790
6.70M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
6.70M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
6.70M
      unsigned int klass = buffer->idx < buffer->len ?
818
6.69M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
6.70M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
6.70M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
6.70M
      const EntryT &entry = machine.get_entry (state, klass);
822
6.70M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
6.70M
      const EntryT *wouldbe_entry;
853
6.70M
      bool safe_to_break =
854
  /* 1. */
855
6.70M
  !c->is_actionable (this, entry)
856
6.70M
      &&
857
  /* 2. */
858
6.70M
  (
859
    /* 2a. */
860
2.42M
    state == StateTableT::STATE_START_OF_TEXT
861
2.42M
  ||
862
    /* 2b. */
863
2.42M
    (
864
2.23k
      (entry.flags & context_t::DontAdvance) &&
865
2.23k
      next_state == StateTableT::STATE_START_OF_TEXT
866
2.23k
    )
867
2.42M
  ||
868
    /* 2c. */
869
2.42M
    (
870
2.18k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
2.18k
    ,
872
      /* 2c'. */
873
2.18k
      !c->is_actionable (this, *wouldbe_entry)
874
2.18k
    &&
875
      /* 2c". */
876
2.18k
      (
877
1.97k
        next_state == machine.new_state (wouldbe_entry->newState)
878
1.97k
      &&
879
1.97k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
1.97k
      )
881
2.18k
    )
882
2.42M
  )
883
6.70M
      &&
884
  /* 3. */
885
6.70M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
6.70M
      ;
887
888
6.70M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
470k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
6.70M
      c->transition (this, entry);
892
893
6.70M
      state = next_state;
894
6.70M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
6.70M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
12.9k
  break;
898
899
6.69M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
58.2k
  (void) buffer->next_glyph ();
901
6.69M
    }
902
903
12.9k
    if (!c->in_place)
904
0
      buffer->sync ();
905
12.9k
  }
void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::drive<AAT::LigatureSubtable<AAT::ExtendedTypes>::driver_context_t>(AAT::LigatureSubtable<AAT::ExtendedTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
5.83k
  {
783
5.83k
    if (!c->in_place)
784
5.83k
      buffer->clear_output ();
785
786
5.83k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
5.83k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
575k
    for (buffer->idx = 0; buffer->successful;)
790
575k
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
575k
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
575k
      unsigned int klass = buffer->idx < buffer->len ?
818
569k
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
575k
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
575k
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
575k
      const EntryT &entry = machine.get_entry (state, klass);
822
575k
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
575k
      const EntryT *wouldbe_entry;
853
575k
      bool safe_to_break =
854
  /* 1. */
855
575k
  !c->is_actionable (this, entry)
856
575k
      &&
857
  /* 2. */
858
575k
  (
859
    /* 2a. */
860
411k
    state == StateTableT::STATE_START_OF_TEXT
861
411k
  ||
862
    /* 2b. */
863
411k
    (
864
1.50k
      (entry.flags & context_t::DontAdvance) &&
865
1.50k
      next_state == StateTableT::STATE_START_OF_TEXT
866
1.50k
    )
867
411k
  ||
868
    /* 2c. */
869
411k
    (
870
740
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
740
    ,
872
      /* 2c'. */
873
740
      !c->is_actionable (this, *wouldbe_entry)
874
740
    &&
875
      /* 2c". */
876
740
      (
877
706
        next_state == machine.new_state (wouldbe_entry->newState)
878
706
      &&
879
706
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
706
      )
881
740
    )
882
411k
  )
883
575k
      &&
884
  /* 3. */
885
575k
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
575k
      ;
887
888
575k
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
40.5k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
575k
      c->transition (this, entry);
892
893
575k
      state = next_state;
894
575k
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
575k
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
5.83k
  break;
898
899
569k
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
20.2k
  (void) buffer->next_glyph ();
901
569k
    }
902
903
5.83k
    if (!c->in_place)
904
5.83k
      buffer->sync ();
905
5.83k
  }
void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::drive<AAT::InsertionSubtable<AAT::ExtendedTypes>::driver_context_t>(AAT::InsertionSubtable<AAT::ExtendedTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
39.2k
  {
783
39.2k
    if (!c->in_place)
784
39.2k
      buffer->clear_output ();
785
786
39.2k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
39.2k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
11.4M
    for (buffer->idx = 0; buffer->successful;)
790
11.4M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
11.4M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
11.4M
      unsigned int klass = buffer->idx < buffer->len ?
818
10.8M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
11.4M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
11.4M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
11.4M
      const EntryT &entry = machine.get_entry (state, klass);
822
11.4M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
11.4M
      const EntryT *wouldbe_entry;
853
11.4M
      bool safe_to_break =
854
  /* 1. */
855
11.4M
  !c->is_actionable (this, entry)
856
11.4M
      &&
857
  /* 2. */
858
11.4M
  (
859
    /* 2a. */
860
8.18M
    state == StateTableT::STATE_START_OF_TEXT
861
8.18M
  ||
862
    /* 2b. */
863
8.18M
    (
864
541k
      (entry.flags & context_t::DontAdvance) &&
865
541k
      next_state == StateTableT::STATE_START_OF_TEXT
866
541k
    )
867
8.18M
  ||
868
    /* 2c. */
869
8.18M
    (
870
541k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
541k
    ,
872
      /* 2c'. */
873
541k
      !c->is_actionable (this, *wouldbe_entry)
874
541k
    &&
875
      /* 2c". */
876
541k
      (
877
480k
        next_state == machine.new_state (wouldbe_entry->newState)
878
480k
      &&
879
480k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
480k
      )
881
541k
    )
882
8.18M
  )
883
11.4M
      &&
884
  /* 3. */
885
11.4M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
11.4M
      ;
887
888
11.4M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
2.25M
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
11.4M
      c->transition (this, entry);
892
893
11.4M
      state = next_state;
894
11.4M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
11.4M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
39.2k
  break;
898
899
11.3M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
4.68M
  (void) buffer->next_glyph ();
901
11.3M
    }
902
903
39.2k
    if (!c->in_place)
904
39.2k
      buffer->sync ();
905
39.2k
  }
void AAT::StateTableDriver<AAT::ObsoleteTypes, void>::drive<AAT::RearrangementSubtable<AAT::ObsoleteTypes>::driver_context_t>(AAT::RearrangementSubtable<AAT::ObsoleteTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
3.04k
  {
783
3.04k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
3.04k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
3.04k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
7.07M
    for (buffer->idx = 0; buffer->successful;)
790
7.07M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
7.07M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
7.07M
      unsigned int klass = buffer->idx < buffer->len ?
818
7.06M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
7.07M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
7.07M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
7.07M
      const EntryT &entry = machine.get_entry (state, klass);
822
7.07M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
7.07M
      const EntryT *wouldbe_entry;
853
7.07M
      bool safe_to_break =
854
  /* 1. */
855
7.07M
  !c->is_actionable (this, entry)
856
7.07M
      &&
857
  /* 2. */
858
7.07M
  (
859
    /* 2a. */
860
1.77M
    state == StateTableT::STATE_START_OF_TEXT
861
1.77M
  ||
862
    /* 2b. */
863
1.77M
    (
864
482k
      (entry.flags & context_t::DontAdvance) &&
865
482k
      next_state == StateTableT::STATE_START_OF_TEXT
866
482k
    )
867
1.77M
  ||
868
    /* 2c. */
869
1.77M
    (
870
391k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
391k
    ,
872
      /* 2c'. */
873
391k
      !c->is_actionable (this, *wouldbe_entry)
874
391k
    &&
875
      /* 2c". */
876
391k
      (
877
326k
        next_state == machine.new_state (wouldbe_entry->newState)
878
326k
      &&
879
326k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
326k
      )
881
391k
    )
882
1.77M
  )
883
7.07M
      &&
884
  /* 3. */
885
7.07M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
7.07M
      ;
887
888
7.07M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
1.48M
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
7.07M
      c->transition (this, entry);
892
893
7.07M
      state = next_state;
894
7.07M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
7.07M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
3.04k
  break;
898
899
7.06M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
1.25M
  (void) buffer->next_glyph ();
901
7.06M
    }
902
903
3.04k
    if (!c->in_place)
904
0
      buffer->sync ();
905
3.04k
  }
void AAT::StateTableDriver<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::drive<AAT::ContextualSubtable<AAT::ObsoleteTypes>::driver_context_t>(AAT::ContextualSubtable<AAT::ObsoleteTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
1.46k
  {
783
1.46k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
1.46k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
1.46k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
2.06M
    for (buffer->idx = 0; buffer->successful;)
790
2.06M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
2.06M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
2.06M
      unsigned int klass = buffer->idx < buffer->len ?
818
2.06M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
2.06M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
2.06M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
2.06M
      const EntryT &entry = machine.get_entry (state, klass);
822
2.06M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
2.06M
      const EntryT *wouldbe_entry;
853
2.06M
      bool safe_to_break =
854
  /* 1. */
855
2.06M
  !c->is_actionable (this, entry)
856
2.06M
      &&
857
  /* 2. */
858
2.06M
  (
859
    /* 2a. */
860
76.2k
    state == StateTableT::STATE_START_OF_TEXT
861
76.2k
  ||
862
    /* 2b. */
863
76.2k
    (
864
516
      (entry.flags & context_t::DontAdvance) &&
865
516
      next_state == StateTableT::STATE_START_OF_TEXT
866
516
    )
867
76.2k
  ||
868
    /* 2c. */
869
76.2k
    (
870
516
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
516
    ,
872
      /* 2c'. */
873
516
      !c->is_actionable (this, *wouldbe_entry)
874
516
    &&
875
      /* 2c". */
876
516
      (
877
516
        next_state == machine.new_state (wouldbe_entry->newState)
878
516
      &&
879
516
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
516
      )
881
516
    )
882
76.2k
  )
883
2.06M
      &&
884
  /* 3. */
885
2.06M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
2.06M
      ;
887
888
2.06M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
235k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
2.06M
      c->transition (this, entry);
892
893
2.06M
      state = next_state;
894
2.06M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
2.06M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
1.46k
  break;
898
899
2.06M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
27.8k
  (void) buffer->next_glyph ();
901
2.06M
    }
902
903
1.46k
    if (!c->in_place)
904
0
      buffer->sync ();
905
1.46k
  }
void AAT::StateTableDriver<AAT::ObsoleteTypes, void>::drive<AAT::LigatureSubtable<AAT::ObsoleteTypes>::driver_context_t>(AAT::LigatureSubtable<AAT::ObsoleteTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
330
  {
783
330
    if (!c->in_place)
784
330
      buffer->clear_output ();
785
786
330
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
330
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
934k
    for (buffer->idx = 0; buffer->successful;)
790
934k
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
934k
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
934k
      unsigned int klass = buffer->idx < buffer->len ?
818
934k
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
934k
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
934k
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
934k
      const EntryT &entry = machine.get_entry (state, klass);
822
934k
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
934k
      const EntryT *wouldbe_entry;
853
934k
      bool safe_to_break =
854
  /* 1. */
855
934k
  !c->is_actionable (this, entry)
856
934k
      &&
857
  /* 2. */
858
934k
  (
859
    /* 2a. */
860
231
    state == StateTableT::STATE_START_OF_TEXT
861
231
  ||
862
    /* 2b. */
863
231
    (
864
0
      (entry.flags & context_t::DontAdvance) &&
865
0
      next_state == StateTableT::STATE_START_OF_TEXT
866
0
    )
867
231
  ||
868
    /* 2c. */
869
231
    (
870
0
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
0
    ,
872
      /* 2c'. */
873
0
      !c->is_actionable (this, *wouldbe_entry)
874
0
    &&
875
      /* 2c". */
876
0
      (
877
0
        next_state == machine.new_state (wouldbe_entry->newState)
878
0
      &&
879
0
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
0
      )
881
0
    )
882
231
  )
883
934k
      &&
884
  /* 3. */
885
934k
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
934k
      ;
887
888
934k
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
996
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
934k
      c->transition (this, entry);
892
893
934k
      state = next_state;
894
934k
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
934k
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
330
  break;
898
899
934k
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
1.35k
  (void) buffer->next_glyph ();
901
934k
    }
902
903
330
    if (!c->in_place)
904
330
      buffer->sync ();
905
330
  }
void AAT::StateTableDriver<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::drive<AAT::InsertionSubtable<AAT::ObsoleteTypes>::driver_context_t>(AAT::InsertionSubtable<AAT::ObsoleteTypes>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
2.89k
  {
783
2.89k
    if (!c->in_place)
784
2.89k
      buffer->clear_output ();
785
786
2.89k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
2.89k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
5.27M
    for (buffer->idx = 0; buffer->successful;)
790
5.27M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
5.27M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
5.27M
      unsigned int klass = buffer->idx < buffer->len ?
818
5.22M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
5.27M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
5.27M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
5.27M
      const EntryT &entry = machine.get_entry (state, klass);
822
5.27M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
5.27M
      const EntryT *wouldbe_entry;
853
5.27M
      bool safe_to_break =
854
  /* 1. */
855
5.27M
  !c->is_actionable (this, entry)
856
5.27M
      &&
857
  /* 2. */
858
5.27M
  (
859
    /* 2a. */
860
3.17M
    state == StateTableT::STATE_START_OF_TEXT
861
3.17M
  ||
862
    /* 2b. */
863
3.17M
    (
864
443k
      (entry.flags & context_t::DontAdvance) &&
865
443k
      next_state == StateTableT::STATE_START_OF_TEXT
866
443k
    )
867
3.17M
  ||
868
    /* 2c. */
869
3.17M
    (
870
393k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
393k
    ,
872
      /* 2c'. */
873
393k
      !c->is_actionable (this, *wouldbe_entry)
874
393k
    &&
875
      /* 2c". */
876
393k
      (
877
317k
        next_state == machine.new_state (wouldbe_entry->newState)
878
317k
      &&
879
317k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
317k
      )
881
393k
    )
882
3.17M
  )
883
5.27M
      &&
884
  /* 3. */
885
5.27M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
5.27M
      ;
887
888
5.27M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
2.14M
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
5.27M
      c->transition (this, entry);
892
893
5.27M
      state = next_state;
894
5.27M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
5.27M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
2.88k
  break;
898
899
5.27M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
1.43M
  (void) buffer->next_glyph ();
901
5.27M
    }
902
903
2.89k
    if (!c->in_place)
904
2.89k
      buffer->sync ();
905
2.89k
  }
void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::drive<AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader>::driver_context_t>(AAT::KerxSubTableFormat1<AAT::KerxSubTableHeader>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
1.61k
  {
783
1.61k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
1.61k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
1.61k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
3.31M
    for (buffer->idx = 0; buffer->successful;)
790
3.31M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
3.31M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
3.31M
      unsigned int klass = buffer->idx < buffer->len ?
818
3.31M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
3.31M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
3.31M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
3.31M
      const EntryT &entry = machine.get_entry (state, klass);
822
3.31M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
3.31M
      const EntryT *wouldbe_entry;
853
3.31M
      bool safe_to_break =
854
  /* 1. */
855
3.31M
  !c->is_actionable (this, entry)
856
3.31M
      &&
857
  /* 2. */
858
3.31M
  (
859
    /* 2a. */
860
1.68M
    state == StateTableT::STATE_START_OF_TEXT
861
1.68M
  ||
862
    /* 2b. */
863
1.68M
    (
864
477k
      (entry.flags & context_t::DontAdvance) &&
865
477k
      next_state == StateTableT::STATE_START_OF_TEXT
866
477k
    )
867
1.68M
  ||
868
    /* 2c. */
869
1.68M
    (
870
477k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
477k
    ,
872
      /* 2c'. */
873
477k
      !c->is_actionable (this, *wouldbe_entry)
874
477k
    &&
875
      /* 2c". */
876
477k
      (
877
422k
        next_state == machine.new_state (wouldbe_entry->newState)
878
422k
      &&
879
422k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
422k
      )
881
477k
    )
882
1.68M
  )
883
3.31M
      &&
884
  /* 3. */
885
3.31M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
3.31M
      ;
887
888
3.31M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
72.7k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
3.31M
      c->transition (this, entry);
892
893
3.31M
      state = next_state;
894
3.31M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
3.31M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
1.61k
  break;
898
899
3.31M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
18.2k
  (void) buffer->next_glyph ();
901
3.31M
    }
902
903
1.61k
    if (!c->in_place)
904
0
      buffer->sync ();
905
1.61k
  }
void AAT::StateTableDriver<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::drive<AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::driver_context_t>(AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
2.24k
  {
783
2.24k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
2.24k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
2.24k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
2.90M
    for (buffer->idx = 0; buffer->successful;)
790
2.90M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
2.90M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
2.90M
      unsigned int klass = buffer->idx < buffer->len ?
818
2.90M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
2.90M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
2.90M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
2.90M
      const EntryT &entry = machine.get_entry (state, klass);
822
2.90M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
2.90M
      const EntryT *wouldbe_entry;
853
2.90M
      bool safe_to_break =
854
  /* 1. */
855
2.90M
  !c->is_actionable (this, entry)
856
2.90M
      &&
857
  /* 2. */
858
2.90M
  (
859
    /* 2a. */
860
1.10M
    state == StateTableT::STATE_START_OF_TEXT
861
1.10M
  ||
862
    /* 2b. */
863
1.10M
    (
864
267
      (entry.flags & context_t::DontAdvance) &&
865
267
      next_state == StateTableT::STATE_START_OF_TEXT
866
267
    )
867
1.10M
  ||
868
    /* 2c. */
869
1.10M
    (
870
267
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
267
    ,
872
      /* 2c'. */
873
267
      !c->is_actionable (this, *wouldbe_entry)
874
267
    &&
875
      /* 2c". */
876
267
      (
877
267
        next_state == machine.new_state (wouldbe_entry->newState)
878
267
      &&
879
267
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
267
      )
881
267
    )
882
1.10M
  )
883
2.90M
      &&
884
  /* 3. */
885
2.90M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
2.90M
      ;
887
888
2.90M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
199k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
2.90M
      c->transition (this, entry);
892
893
2.90M
      state = next_state;
894
2.90M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
2.90M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
2.24k
  break;
898
899
2.90M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
38.1k
  (void) buffer->next_glyph ();
901
2.90M
    }
902
903
2.24k
    if (!c->in_place)
904
0
      buffer->sync ();
905
2.24k
  }
Unexecuted instantiation: void AAT::StateTableDriver<AAT::ObsoleteTypes, void>::drive<AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader>::driver_context_t>(AAT::KerxSubTableFormat1<OT::KernOTSubTableHeader>::driver_context_t*, AAT::hb_aat_apply_context_t*)
void AAT::StateTableDriver<AAT::ObsoleteTypes, void>::drive<AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader>::driver_context_t>(AAT::KerxSubTableFormat1<OT::KernAATSubTableHeader>::driver_context_t*, AAT::hb_aat_apply_context_t*)
Line
Count
Source
782
1.55k
  {
783
1.55k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
1.55k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
1.55k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
3.19M
    for (buffer->idx = 0; buffer->successful;)
790
3.19M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
3.19M
      if (last_range)
793
0
      {
794
0
  auto *range = last_range;
795
0
  if (buffer->idx < buffer->len)
796
0
  {
797
0
    unsigned cluster = buffer->cur().cluster;
798
0
    while (cluster < range->cluster_first)
799
0
      range--;
800
0
    while (cluster > range->cluster_last)
801
0
      range++;
802
803
804
0
    last_range = range;
805
0
  }
806
0
  if (!(range->flags & ac->subtable_flags))
807
0
  {
808
0
    if (buffer->idx == buffer->len || unlikely (!buffer->successful))
809
0
      break;
810
811
0
    state = StateTableT::STATE_START_OF_TEXT;
812
0
    (void) buffer->next_glyph ();
813
0
    continue;
814
0
  }
815
0
      }
816
817
3.19M
      unsigned int klass = buffer->idx < buffer->len ?
818
3.18M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
3.19M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
3.19M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
3.19M
      const EntryT &entry = machine.get_entry (state, klass);
822
3.19M
      const int next_state = machine.new_state (entry.newState);
823
824
      /* Conditions under which it's guaranteed safe-to-break before current glyph:
825
       *
826
       * 1. There was no action in this transition; and
827
       *
828
       * 2. If we break before current glyph, the results will be the same. That
829
       *    is guaranteed if:
830
       *
831
       *    2a. We were already in start-of-text state; or
832
       *
833
       *    2b. We are epsilon-transitioning to start-of-text state; or
834
       *
835
       *    2c. Starting from start-of-text state seeing current glyph:
836
       *
837
       *        2c'. There won't be any actions; and
838
       *
839
       *        2c". We would end up in the same state that we were going to end up
840
       *             in now, including whether epsilon-transitioning.
841
       *
842
       *    and
843
       *
844
       * 3. If we break before current glyph, there won't be any end-of-text action
845
       *    after previous glyph.
846
       *
847
       * This triples the transitions we need to look up, but is worth returning
848
       * granular unsafe-to-break results. See eg.:
849
       *
850
       *   https://github.com/harfbuzz/harfbuzz/issues/2860
851
       */
852
3.19M
      const EntryT *wouldbe_entry;
853
3.19M
      bool safe_to_break =
854
  /* 1. */
855
3.19M
  !c->is_actionable (this, entry)
856
3.19M
      &&
857
  /* 2. */
858
3.19M
  (
859
    /* 2a. */
860
434k
    state == StateTableT::STATE_START_OF_TEXT
861
434k
  ||
862
    /* 2b. */
863
434k
    (
864
29.6k
      (entry.flags & context_t::DontAdvance) &&
865
29.6k
      next_state == StateTableT::STATE_START_OF_TEXT
866
29.6k
    )
867
434k
  ||
868
    /* 2c. */
869
434k
    (
870
20.5k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
20.5k
    ,
872
      /* 2c'. */
873
20.5k
      !c->is_actionable (this, *wouldbe_entry)
874
20.5k
    &&
875
      /* 2c". */
876
20.5k
      (
877
19.5k
        next_state == machine.new_state (wouldbe_entry->newState)
878
19.5k
      &&
879
19.5k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
19.5k
      )
881
20.5k
    )
882
434k
  )
883
3.19M
      &&
884
  /* 3. */
885
3.19M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
3.19M
      ;
887
888
3.19M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
1.28M
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
3.19M
      c->transition (this, entry);
892
893
3.19M
      state = next_state;
894
3.19M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
3.19M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
1.55k
  break;
898
899
3.18M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
17.0k
  (void) buffer->next_glyph ();
901
3.18M
    }
902
903
1.55k
    if (!c->in_place)
904
0
      buffer->sync ();
905
1.55k
  }
906
907
  public:
908
  const StateTableT &machine;
909
  hb_buffer_t *buffer;
910
  unsigned int num_glyphs;
911
};
912
913
914
} /* namespace AAT */
915
916
917
#endif /* HB_AAT_LAYOUT_COMMON_HH */