Coverage Report

Created: 2023-03-06 09:36

/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
94.7k
  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
8.27k
  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
14.7k
  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
9.52k
  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
2.03k
  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
20.0k
  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
1.96k
  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
122
  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
6
  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
509
  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
666
  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
4.39k
  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
476
  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
1.68k
  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
1.17k
  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
2.95k
  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
7.67k
  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
3.69k
  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
962
  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
5.26k
  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
3.40k
  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
121
  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
4.81k
  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
300
  return_t dispatch (const T &obj) { return obj.apply (this); }
51
22.1k
  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
204k
  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
1.65M
  {
94
1.65M
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
863k
    return &arrayZ[glyph_id];
96
1.65M
  }
AAT::LookupFormat0<OT::IntType<unsigned short, 2u> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
93
1.58M
  {
94
1.58M
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
852k
    return &arrayZ[glyph_id];
96
1.58M
  }
AAT::LookupFormat0<OT::HBGlyphID16>::get_value(unsigned int, unsigned int) const
Line
Count
Source
93
65.2k
  {
94
65.2k
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
9.98k
    return &arrayZ[glyph_id];
96
65.2k
  }
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
1.94k
  {
94
1.94k
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
0
    return &arrayZ[glyph_id];
96
1.94k
  }
AAT::LookupFormat0<OT::IntType<unsigned int, 4u> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
93
1.70k
  {
94
1.70k
    if (unlikely (glyph_id >= num_glyphs)) return nullptr;
95
198
    return &arrayZ[glyph_id];
96
1.70k
  }
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
1.79k
  {
100
1.79k
    TRACE_SANITIZE (this);
101
1.79k
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
102
1.79k
  }
AAT::LookupFormat0<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
99
1.32k
  {
100
1.32k
    TRACE_SANITIZE (this);
101
1.32k
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
102
1.32k
  }
AAT::LookupFormat0<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
99
356
  {
100
356
    TRACE_SANITIZE (this);
101
356
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
102
356
  }
AAT::LookupFormat0<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
99
107
  {
100
107
    TRACE_SANITIZE (this);
101
107
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs ()));
102
107
  }
103
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
104
379
  {
105
379
    TRACE_SANITIZE (this);
106
379
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs (), base));
107
379
  }
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
379
  {
105
379
    TRACE_SANITIZE (this);
106
379
    return_trace (arrayZ.sanitize (c, c->get_num_glyphs (), base));
107
379
  }
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
457k
  { return g < first ? -1 : g <= last ? 0 : +1 ; }
AAT::LookupSegmentSingle<OT::IntType<unsigned short, 2u> >::cmp(unsigned int) const
Line
Count
Source
124
457k
  { 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
Unexecuted instantiation: AAT::LookupSegmentSingle<OT::IntType<unsigned int, 4u> >::cmp(unsigned int) const
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
401
  {
133
401
    TRACE_SANITIZE (this);
134
401
    return_trace (c->check_struct (this) && value.sanitize (c, base));
135
401
  }
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
401
  {
133
401
    TRACE_SANITIZE (this);
134
401
    return_trace (c->check_struct (this) && value.sanitize (c, base));
135
401
  }
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
229k
  {
152
229k
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
229k
    return v ? &v->value : nullptr;
154
229k
  }
AAT::LookupFormat2<OT::IntType<unsigned short, 2u> >::get_value(unsigned int) const
Line
Count
Source
151
228k
  {
152
228k
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
228k
    return v ? &v->value : nullptr;
154
228k
  }
Unexecuted instantiation: AAT::LookupFormat2<OT::HBGlyphID16>::get_value(unsigned int) const
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
256
  {
152
256
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
256
    return v ? &v->value : nullptr;
154
256
  }
AAT::LookupFormat2<OT::IntType<unsigned int, 4u> >::get_value(unsigned int) const
Line
Count
Source
151
51
  {
152
51
    const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
153
51
    return v ? &v->value : nullptr;
154
51
  }
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
854
  {
158
854
    TRACE_SANITIZE (this);
159
854
    return_trace (segments.sanitize (c));
160
854
  }
AAT::LookupFormat2<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
157
798
  {
158
798
    TRACE_SANITIZE (this);
159
798
    return_trace (segments.sanitize (c));
160
798
  }
AAT::LookupFormat2<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
157
23
  {
158
23
    TRACE_SANITIZE (this);
159
23
    return_trace (segments.sanitize (c));
160
23
  }
AAT::LookupFormat2<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
157
33
  {
158
33
    TRACE_SANITIZE (this);
159
33
    return_trace (segments.sanitize (c));
160
33
  }
161
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
162
215
  {
163
215
    TRACE_SANITIZE (this);
164
215
    return_trace (segments.sanitize (c, base));
165
215
  }
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
215
  {
163
215
    TRACE_SANITIZE (this);
164
215
    return_trace (segments.sanitize (c, base));
165
215
  }
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
33
  {
184
33
    return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
185
33
  }
AAT::LookupSegmentArray<OT::IntType<unsigned short, 2u> >::get_value(unsigned int, void const*) const
Line
Count
Source
183
33
  {
184
33
    return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
185
33
  }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::HBGlyphID16>::get_value(unsigned int, void const*) const
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
Unexecuted instantiation: AAT::LookupSegmentArray<OT::IntType<unsigned int, 4u> >::get_value(unsigned int, void const*) const
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
357
  { return g < first ? -1 : g <= last ? 0 : +1; }
AAT::LookupSegmentArray<OT::IntType<unsigned short, 2u> >::cmp(unsigned int) const
Line
Count
Source
188
357
  { return g < first ? -1 : g <= last ? 0 : +1; }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::HBGlyphID16>::cmp(unsigned int) const
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
Unexecuted instantiation: AAT::LookupSegmentArray<OT::IntType<unsigned int, 4u> >::cmp(unsigned int) const
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
86
  {
192
86
    TRACE_SANITIZE (this);
193
86
    return_trace (c->check_struct (this) &&
194
86
      first <= last &&
195
86
      valuesZ.sanitize (c, base, last - first + 1));
196
86
  }
AAT::LookupSegmentArray<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
191
63
  {
192
63
    TRACE_SANITIZE (this);
193
63
    return_trace (c->check_struct (this) &&
194
63
      first <= last &&
195
63
      valuesZ.sanitize (c, base, last - first + 1));
196
63
  }
Unexecuted instantiation: AAT::LookupSegmentArray<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*, void const*) const
AAT::LookupSegmentArray<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
191
23
  {
192
23
    TRACE_SANITIZE (this);
193
23
    return_trace (c->check_struct (this) &&
194
23
      first <= last &&
195
23
      valuesZ.sanitize (c, base, last - first + 1));
196
23
  }
197
  template <typename ...Ts>
198
  bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
199
28
  {
200
28
    TRACE_SANITIZE (this);
201
28
    return_trace (c->check_struct (this) &&
202
28
      first <= last &&
203
28
      valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...));
204
28
  }
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
28
  {
200
28
    TRACE_SANITIZE (this);
201
28
    return_trace (c->check_struct (this) &&
202
28
      first <= last &&
203
28
      valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...));
204
28
  }
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
278
  {
223
278
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
224
278
    return v ? v->get_value (glyph_id, this) : nullptr;
225
278
  }
AAT::LookupFormat4<OT::IntType<unsigned short, 2u> >::get_value(unsigned int) const
Line
Count
Source
222
274
  {
223
274
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
224
274
    return v ? v->get_value (glyph_id, this) : nullptr;
225
274
  }
AAT::LookupFormat4<OT::HBGlyphID16>::get_value(unsigned int) const
Line
Count
Source
222
4
  {
223
4
    const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
224
4
    return v ? v->get_value (glyph_id, this) : nullptr;
225
4
  }
Unexecuted instantiation: AAT::LookupFormat4<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int) const
Unexecuted instantiation: AAT::LookupFormat4<OT::IntType<unsigned int, 4u> >::get_value(unsigned int) const
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
94
  {
229
94
    TRACE_SANITIZE (this);
230
94
    return_trace (segments.sanitize (c, this));
231
94
  }
AAT::LookupFormat4<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
228
56
  {
229
56
    TRACE_SANITIZE (this);
230
56
    return_trace (segments.sanitize (c, this));
231
56
  }
AAT::LookupFormat4<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
228
13
  {
229
13
    TRACE_SANITIZE (this);
230
13
    return_trace (segments.sanitize (c, this));
231
13
  }
AAT::LookupFormat4<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
228
25
  {
229
25
    TRACE_SANITIZE (this);
230
25
    return_trace (segments.sanitize (c, this));
231
25
  }
232
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
233
88
  {
234
88
    TRACE_SANITIZE (this);
235
88
    return_trace (segments.sanitize (c, this, base));
236
88
  }
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
88
  {
234
88
    TRACE_SANITIZE (this);
235
88
    return_trace (segments.sanitize (c, this, base));
236
88
  }
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
13.2M
  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
13.2M
  int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
AAT::LookupSingle<OT::HBGlyphID16>::cmp(unsigned int) const
Line
Count
Source
253
8.56k
  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
Unexecuted instantiation: AAT::LookupSingle<OT::IntType<unsigned int, 4u> >::cmp(unsigned int) const
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
114
  {
262
114
    TRACE_SANITIZE (this);
263
114
    return_trace (c->check_struct (this) && value.sanitize (c, base));
264
114
  }
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
114
  {
262
114
    TRACE_SANITIZE (this);
263
114
    return_trace (c->check_struct (this) && value.sanitize (c, base));
264
114
  }
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
4.05M
  {
280
4.05M
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
4.05M
    return v ? &v->value : nullptr;
282
4.05M
  }
AAT::LookupFormat6<OT::IntType<unsigned short, 2u> >::get_value(unsigned int) const
Line
Count
Source
279
4.04M
  {
280
4.04M
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
4.04M
    return v ? &v->value : nullptr;
282
4.04M
  }
AAT::LookupFormat6<OT::HBGlyphID16>::get_value(unsigned int) const
Line
Count
Source
279
6.98k
  {
280
6.98k
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
6.98k
    return v ? &v->value : nullptr;
282
6.98k
  }
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
102
  {
280
102
    const LookupSingle<T> *v = entries.bsearch (glyph_id);
281
102
    return v ? &v->value : nullptr;
282
102
  }
Unexecuted instantiation: AAT::LookupFormat6<OT::IntType<unsigned int, 4u> >::get_value(unsigned int) const
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.99k
  {
286
2.99k
    TRACE_SANITIZE (this);
287
2.99k
    return_trace (entries.sanitize (c));
288
2.99k
  }
AAT::LookupFormat6<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
285
2.67k
  {
286
2.67k
    TRACE_SANITIZE (this);
287
2.67k
    return_trace (entries.sanitize (c));
288
2.67k
  }
AAT::LookupFormat6<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
285
303
  {
286
303
    TRACE_SANITIZE (this);
287
303
    return_trace (entries.sanitize (c));
288
303
  }
AAT::LookupFormat6<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
285
13
  {
286
13
    TRACE_SANITIZE (this);
287
13
    return_trace (entries.sanitize (c));
288
13
  }
289
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
290
101
  {
291
101
    TRACE_SANITIZE (this);
292
101
    return_trace (entries.sanitize (c, base));
293
101
  }
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
101
  {
291
101
    TRACE_SANITIZE (this);
292
101
    return_trace (entries.sanitize (c, base));
293
101
  }
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
10.4M
  {
311
10.4M
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
5.71M
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
10.4M
  }
AAT::LookupFormat8<OT::IntType<unsigned short, 2u> >::get_value(unsigned int) const
Line
Count
Source
310
9.00M
  {
311
9.00M
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
4.52M
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
9.00M
  }
AAT::LookupFormat8<OT::HBGlyphID16>::get_value(unsigned int) const
Line
Count
Source
310
1.47M
  {
311
1.47M
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
1.18M
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
1.47M
  }
Unexecuted instantiation: AAT::LookupFormat8<OT::OffsetTo<OT::ArrayOf<AAT::Anchor, OT::IntType<unsigned int, 4u> >, OT::IntType<unsigned short, 2u>, false> >::get_value(unsigned int) const
AAT::LookupFormat8<OT::IntType<unsigned int, 4u> >::get_value(unsigned int) const
Line
Count
Source
310
33
  {
311
33
    return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
312
33
     &valueArrayZ[glyph_id - firstGlyph] : nullptr;
313
33
  }
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
3.44k
  {
317
3.44k
    TRACE_SANITIZE (this);
318
3.44k
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
319
3.44k
  }
AAT::LookupFormat8<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
316
2.27k
  {
317
2.27k
    TRACE_SANITIZE (this);
318
2.27k
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
319
2.27k
  }
AAT::LookupFormat8<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
316
1.16k
  {
317
1.16k
    TRACE_SANITIZE (this);
318
1.16k
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
319
1.16k
  }
AAT::LookupFormat8<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
316
11
  {
317
11
    TRACE_SANITIZE (this);
318
11
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
319
11
  }
320
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
321
49
  {
322
49
    TRACE_SANITIZE (this);
323
49
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount, base));
324
49
  }
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
49
  {
322
49
    TRACE_SANITIZE (this);
323
49
    return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount, base));
324
49
  }
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
353
  {
346
353
    if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
347
185
      return Null (T);
348
349
168
    const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
350
351
168
    unsigned int v = 0;
352
168
    unsigned int count = valueSize;
353
366
    for (unsigned int i = 0; i < count; i++)
354
198
      v = (v << 8) | *p++;
355
356
168
    return v;
357
353
  }
AAT::LookupFormat10<OT::IntType<unsigned int, 4u> >::get_value_or_null(unsigned int) const
Line
Count
Source
345
134
  {
346
134
    if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
347
83
      return Null (T);
348
349
51
    const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
350
351
51
    unsigned int v = 0;
352
51
    unsigned int count = valueSize;
353
51
    for (unsigned int i = 0; i < count; i++)
354
0
      v = (v << 8) | *p++;
355
356
51
    return v;
357
134
  }
AAT::LookupFormat10<OT::IntType<unsigned short, 2u> >::get_value_or_null(unsigned int) const
Line
Count
Source
345
219
  {
346
219
    if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
347
102
      return Null (T);
348
349
117
    const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
350
351
117
    unsigned int v = 0;
352
117
    unsigned int count = valueSize;
353
315
    for (unsigned int i = 0; i < count; i++)
354
198
      v = (v << 8) | *p++;
355
356
117
    return v;
357
219
  }
358
359
  bool sanitize (hb_sanitize_context_t *c) const
360
68
  {
361
68
    TRACE_SANITIZE (this);
362
68
    return_trace (c->check_struct (this) &&
363
68
      valueSize <= 4 &&
364
68
      valueArrayZ.sanitize (c, glyphCount * valueSize));
365
68
  }
AAT::LookupFormat10<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
360
47
  {
361
47
    TRACE_SANITIZE (this);
362
47
    return_trace (c->check_struct (this) &&
363
47
      valueSize <= 4 &&
364
47
      valueArrayZ.sanitize (c, glyphCount * valueSize));
365
47
  }
AAT::LookupFormat10<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
360
9
  {
361
9
    TRACE_SANITIZE (this);
362
9
    return_trace (c->check_struct (this) &&
363
9
      valueSize <= 4 &&
364
9
      valueArrayZ.sanitize (c, glyphCount * valueSize));
365
9
  }
AAT::LookupFormat10<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
360
12
  {
361
12
    TRACE_SANITIZE (this);
362
12
    return_trace (c->check_struct (this) &&
363
12
      valueSize <= 4 &&
364
12
      valueArrayZ.sanitize (c, glyphCount * valueSize));
365
12
  }
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
17.1M
  {
385
17.1M
    switch (u.format) {
386
1.65M
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
229k
    case 2: return u.format2.get_value (glyph_id);
388
278
    case 4: return u.format4.get_value (glyph_id);
389
4.05M
    case 6: return u.format6.get_value (glyph_id);
390
10.4M
    case 8: return u.format8.get_value (glyph_id);
391
728k
    default:return nullptr;
392
17.1M
    }
393
17.1M
  }
AAT::Lookup<OT::IntType<unsigned short, 2u> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
384
15.2M
  {
385
15.2M
    switch (u.format) {
386
1.58M
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
228k
    case 2: return u.format2.get_value (glyph_id);
388
274
    case 4: return u.format4.get_value (glyph_id);
389
4.04M
    case 6: return u.format6.get_value (glyph_id);
390
9.00M
    case 8: return u.format8.get_value (glyph_id);
391
401k
    default:return nullptr;
392
15.2M
    }
393
15.2M
  }
AAT::Lookup<OT::HBGlyphID16>::get_value(unsigned int, unsigned int) const
Line
Count
Source
384
1.85M
  {
385
1.85M
    switch (u.format) {
386
65.2k
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
0
    case 2: return u.format2.get_value (glyph_id);
388
4
    case 4: return u.format4.get_value (glyph_id);
389
6.98k
    case 6: return u.format6.get_value (glyph_id);
390
1.47M
    case 8: return u.format8.get_value (glyph_id);
391
315k
    default:return nullptr;
392
1.85M
    }
393
1.85M
  }
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
12.6k
  {
385
12.6k
    switch (u.format) {
386
1.94k
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
256
    case 2: return u.format2.get_value (glyph_id);
388
0
    case 4: return u.format4.get_value (glyph_id);
389
102
    case 6: return u.format6.get_value (glyph_id);
390
0
    case 8: return u.format8.get_value (glyph_id);
391
10.3k
    default:return nullptr;
392
12.6k
    }
393
12.6k
  }
AAT::Lookup<OT::IntType<unsigned int, 4u> >::get_value(unsigned int, unsigned int) const
Line
Count
Source
384
3.06k
  {
385
3.06k
    switch (u.format) {
386
1.70k
    case 0: return u.format0.get_value (glyph_id, num_glyphs);
387
51
    case 2: return u.format2.get_value (glyph_id);
388
0
    case 4: return u.format4.get_value (glyph_id);
389
0
    case 6: return u.format6.get_value (glyph_id);
390
33
    case 8: return u.format8.get_value (glyph_id);
391
1.27k
    default:return nullptr;
392
3.06k
    }
393
3.06k
  }
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
7.43k
  {
397
7.43k
    switch (u.format) {
398
      /* Format 10 cannot return a pointer. */
399
353
      case 10: return u.format10.get_value_or_null (glyph_id);
400
7.08k
      default:
401
7.08k
      const T *v = get_value (glyph_id, num_glyphs);
402
7.08k
      return v ? *v : Null (T);
403
7.43k
    }
404
7.43k
  }
AAT::Lookup<OT::IntType<unsigned int, 4u> >::get_value_or_null(unsigned int, unsigned int) const
Line
Count
Source
396
3.20k
  {
397
3.20k
    switch (u.format) {
398
      /* Format 10 cannot return a pointer. */
399
134
      case 10: return u.format10.get_value_or_null (glyph_id);
400
3.06k
      default:
401
3.06k
      const T *v = get_value (glyph_id, num_glyphs);
402
3.06k
      return v ? *v : Null (T);
403
3.20k
    }
404
3.20k
  }
AAT::Lookup<OT::IntType<unsigned short, 2u> >::get_value_or_null(unsigned int, unsigned int) const
Line
Count
Source
396
4.23k
  {
397
4.23k
    switch (u.format) {
398
      /* Format 10 cannot return a pointer. */
399
219
      case 10: return u.format10.get_value_or_null (glyph_id);
400
4.01k
      default:
401
4.01k
      const T *v = get_value (glyph_id, num_glyphs);
402
4.01k
      return v ? *v : Null (T);
403
4.23k
    }
404
4.23k
  }
405
406
  typename T::type get_class (hb_codepoint_t glyph_id,
407
            unsigned int num_glyphs,
408
            unsigned int outOfRange) const
409
15.2M
  {
410
15.2M
    const T *v = get_value (glyph_id, num_glyphs);
411
15.2M
    return v ? *v : outOfRange;
412
15.2M
  }
413
414
  bool sanitize (hb_sanitize_context_t *c) const
415
10.0k
  {
416
10.0k
    TRACE_SANITIZE (this);
417
10.0k
    if (!u.format.sanitize (c)) return_trace (false);
418
9.88k
    switch (u.format) {
419
1.79k
    case 0: return_trace (u.format0.sanitize (c));
420
854
    case 2: return_trace (u.format2.sanitize (c));
421
94
    case 4: return_trace (u.format4.sanitize (c));
422
2.99k
    case 6: return_trace (u.format6.sanitize (c));
423
3.44k
    case 8: return_trace (u.format8.sanitize (c));
424
68
    case 10: return_trace (u.format10.sanitize (c));
425
643
    default:return_trace (true);
426
9.88k
    }
427
9.88k
  }
AAT::Lookup<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
415
7.68k
  {
416
7.68k
    TRACE_SANITIZE (this);
417
7.68k
    if (!u.format.sanitize (c)) return_trace (false);
418
7.58k
    switch (u.format) {
419
1.32k
    case 0: return_trace (u.format0.sanitize (c));
420
798
    case 2: return_trace (u.format2.sanitize (c));
421
56
    case 4: return_trace (u.format4.sanitize (c));
422
2.67k
    case 6: return_trace (u.format6.sanitize (c));
423
2.27k
    case 8: return_trace (u.format8.sanitize (c));
424
47
    case 10: return_trace (u.format10.sanitize (c));
425
406
    default:return_trace (true);
426
7.58k
    }
427
7.58k
  }
AAT::Lookup<OT::HBGlyphID16>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
415
2.01k
  {
416
2.01k
    TRACE_SANITIZE (this);
417
2.01k
    if (!u.format.sanitize (c)) return_trace (false);
418
1.97k
    switch (u.format) {
419
356
    case 0: return_trace (u.format0.sanitize (c));
420
23
    case 2: return_trace (u.format2.sanitize (c));
421
13
    case 4: return_trace (u.format4.sanitize (c));
422
303
    case 6: return_trace (u.format6.sanitize (c));
423
1.16k
    case 8: return_trace (u.format8.sanitize (c));
424
9
    case 10: return_trace (u.format10.sanitize (c));
425
108
    default:return_trace (true);
426
1.97k
    }
427
1.97k
  }
AAT::Lookup<OT::IntType<unsigned int, 4u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
415
360
  {
416
360
    TRACE_SANITIZE (this);
417
360
    if (!u.format.sanitize (c)) return_trace (false);
418
330
    switch (u.format) {
419
107
    case 0: return_trace (u.format0.sanitize (c));
420
33
    case 2: return_trace (u.format2.sanitize (c));
421
25
    case 4: return_trace (u.format4.sanitize (c));
422
13
    case 6: return_trace (u.format6.sanitize (c));
423
11
    case 8: return_trace (u.format8.sanitize (c));
424
12
    case 10: return_trace (u.format10.sanitize (c));
425
129
    default:return_trace (true);
426
330
    }
427
330
  }
428
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
429
933
  {
430
933
    TRACE_SANITIZE (this);
431
933
    if (!u.format.sanitize (c)) return_trace (false);
432
882
    switch (u.format) {
433
379
    case 0: return_trace (u.format0.sanitize (c, base));
434
215
    case 2: return_trace (u.format2.sanitize (c, base));
435
88
    case 4: return_trace (u.format4.sanitize (c, base));
436
101
    case 6: return_trace (u.format6.sanitize (c, base));
437
49
    case 8: return_trace (u.format8.sanitize (c, base));
438
20
    case 10: return_trace (false); /* We don't support format10 here currently. */
439
30
    default:return_trace (true);
440
882
    }
441
882
  }
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
933
  {
430
933
    TRACE_SANITIZE (this);
431
933
    if (!u.format.sanitize (c)) return_trace (false);
432
882
    switch (u.format) {
433
379
    case 0: return_trace (u.format0.sanitize (c, base));
434
215
    case 2: return_trace (u.format2.sanitize (c, base));
435
88
    case 4: return_trace (u.format4.sanitize (c, base));
436
101
    case 6: return_trace (u.format6.sanitize (c, base));
437
49
    case 8: return_trace (u.format8.sanitize (c, base));
438
20
    case 10: return_trace (false); /* We don't support format10 here currently. */
439
30
    default:return_trace (true);
440
882
    }
441
882
  }
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
22.9M
  { 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.82M
  { 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
4.10M
  { 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
3.38M
  { 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
4.59M
  { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / (int) nClasses; }
AAT::StateTable<AAT::ObsoleteTypes, void>::new_state(unsigned int) const
Line
Count
Source
529
3.63M
  { 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
201k
  { 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
971k
  { 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
1.45M
  { 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
1.80M
  { 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
20.0M
  {
533
20.0M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
19.8M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
20.0M
  }
AAT::StateTable<AAT::ExtendedTypes, void>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
2.48M
  {
533
2.48M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
2.48M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
2.48M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
3.98M
  {
533
3.98M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
3.98M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
3.98M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
3.13M
  {
533
3.13M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
3.13M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
3.13M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
4.21M
  {
533
4.21M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
4.18M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
4.21M
  }
AAT::StateTable<AAT::ObsoleteTypes, void>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
3.58M
  {
533
3.58M
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
3.47M
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
3.58M
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
197k
  {
533
197k
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
197k
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
197k
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
967k
  {
533
967k
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
967k
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
967k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
778k
  {
533
778k
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
778k
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
778k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::get_class(unsigned int, unsigned int) const
Line
Count
Source
532
685k
  {
533
685k
    if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
534
685k
    return (this+classTable).get_class (glyph_id, num_glyphs, 1);
535
685k
  }
536
537
  const Entry<Extra> *get_entries () const
538
1.48k
  { return (this+entryTable).arrayZ; }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_entries() const
Line
Count
Source
538
1.48k
  { 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
30.6M
  {
542
30.6M
    if (unlikely (klass >= nClasses))
543
1.30M
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
30.6M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
30.6M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
30.6M
    unsigned int entry = states[state * nClasses + klass];
549
30.6M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
30.6M
    return entries[entry];
552
30.6M
  }
AAT::StateTable<AAT::ExtendedTypes, void>::get_entry(int, unsigned int) const
Line
Count
Source
541
4.67M
  {
542
4.67M
    if (unlikely (klass >= nClasses))
543
214k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
4.67M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
4.67M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
4.67M
    unsigned int entry = states[state * nClasses + klass];
549
4.67M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
4.67M
    return entries[entry];
552
4.67M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
6.35M
  {
542
6.35M
    if (unlikely (klass >= nClasses))
543
78.9k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
6.35M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
6.35M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
6.35M
    unsigned int entry = states[state * nClasses + klass];
549
6.35M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
6.35M
    return entries[entry];
552
6.35M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
5.24M
  {
542
5.24M
    if (unlikely (klass >= nClasses))
543
85.8k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
5.24M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
5.24M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
5.24M
    unsigned int entry = states[state * nClasses + klass];
549
5.24M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
5.24M
    return entries[entry];
552
5.24M
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
6.73M
  {
542
6.73M
    if (unlikely (klass >= nClasses))
543
180k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
6.73M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
6.73M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
6.73M
    unsigned int entry = states[state * nClasses + klass];
549
6.73M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
6.73M
    return entries[entry];
552
6.73M
  }
AAT::StateTable<AAT::ObsoleteTypes, void>::get_entry(int, unsigned int) const
Line
Count
Source
541
4.83M
  {
542
4.83M
    if (unlikely (klass >= nClasses))
543
12.2k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
4.83M
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
4.83M
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
4.83M
    unsigned int entry = states[state * nClasses + klass];
549
4.83M
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
4.83M
    return entries[entry];
552
4.83M
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
197k
  {
542
197k
    if (unlikely (klass >= nClasses))
543
0
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
197k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
197k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
197k
    unsigned int entry = states[state * nClasses + klass];
549
197k
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
197k
    return entries[entry];
552
197k
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
968k
  {
542
968k
    if (unlikely (klass >= nClasses))
543
0
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
968k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
968k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
968k
    unsigned int entry = states[state * nClasses + klass];
549
968k
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
968k
    return entries[entry];
552
968k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
779k
  {
542
779k
    if (unlikely (klass >= nClasses))
543
111k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
779k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
779k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
779k
    unsigned int entry = states[state * nClasses + klass];
549
779k
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
779k
    return entries[entry];
552
779k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::get_entry(int, unsigned int) const
Line
Count
Source
541
853k
  {
542
853k
    if (unlikely (klass >= nClasses))
543
623k
      klass = StateTable::CLASS_OUT_OF_BOUNDS;
544
545
853k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
546
853k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
547
548
853k
    unsigned int entry = states[state * nClasses + klass];
549
853k
    DEBUG_MSG (APPLY, nullptr, "e%u", entry);
550
551
853k
    return entries[entry];
552
853k
  }
553
554
  bool sanitize (hb_sanitize_context_t *c,
555
     unsigned int *num_entries_out = nullptr) const
556
8.70k
  {
557
8.70k
    TRACE_SANITIZE (this);
558
8.70k
    if (unlikely (!(c->check_struct (this) &&
559
8.70k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
8.70k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
8.09k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
8.09k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
8.09k
    unsigned int num_classes = nClasses;
566
8.09k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
61
      return_trace (false);
568
8.03k
    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
8.03k
    int min_state = 0;
585
8.03k
    int max_state = 0;
586
8.03k
    unsigned int num_entries = 0;
587
588
8.03k
    int state_pos = 0;
589
8.03k
    int state_neg = 0;
590
8.03k
    unsigned int entry = 0;
591
20.0k
    while (min_state < state_neg || state_pos <= max_state)
592
13.1k
    {
593
13.1k
      if (min_state < state_neg)
594
70
      {
595
  /* Negative states. */
596
70
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
70
    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
13.1k
      if (state_pos <= max_state)
615
13.1k
      {
616
  /* Positive states. */
617
13.1k
  if (unlikely (!c->check_range (states,
618
13.1k
               max_state + 1,
619
13.1k
               row_stride)))
620
566
    return_trace (false);
621
12.5k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
12.5k
  { /* Sweep new states. */
624
12.5k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
12.5k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
12.5k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
8.10M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
8.09M
      num_entries = hb_max (num_entries, *p + 1u);
631
12.5k
    state_pos = max_state + 1;
632
12.5k
  }
633
12.5k
      }
634
635
12.5k
      if (unlikely (!c->check_array (entries, num_entries)))
636
502
  return_trace (false);
637
12.0k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
12.0k
      { /* Sweep new entries. */
640
12.0k
  const Entry<Extra> *stop = &entries[num_entries];
641
1.89M
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
1.88M
  {
643
1.88M
    int newState = new_state (p->newState);
644
1.88M
    min_state = hb_min (min_state, newState);
645
1.88M
    max_state = hb_max (max_state, newState);
646
1.88M
  }
647
12.0k
  entry = num_entries;
648
12.0k
      }
649
12.0k
    }
650
651
6.89k
    if (num_entries_out)
652
1.51k
      *num_entries_out = num_entries;
653
654
6.89k
    return_trace (true);
655
8.03k
  }
AAT::StateTable<AAT::ExtendedTypes, void>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
1.02k
  {
557
1.02k
    TRACE_SANITIZE (this);
558
1.02k
    if (unlikely (!(c->check_struct (this) &&
559
1.02k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
1.02k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
971
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
971
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
971
    unsigned int num_classes = nClasses;
566
971
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
10
      return_trace (false);
568
961
    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
961
    int min_state = 0;
585
961
    int max_state = 0;
586
961
    unsigned int num_entries = 0;
587
588
961
    int state_pos = 0;
589
961
    int state_neg = 0;
590
961
    unsigned int entry = 0;
591
2.45k
    while (min_state < state_neg || state_pos <= max_state)
592
1.59k
    {
593
1.59k
      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.59k
      if (state_pos <= max_state)
615
1.59k
      {
616
  /* Positive states. */
617
1.59k
  if (unlikely (!c->check_range (states,
618
1.59k
               max_state + 1,
619
1.59k
               row_stride)))
620
54
    return_trace (false);
621
1.54k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
1.54k
  { /* Sweep new states. */
624
1.54k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
1.54k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
1.54k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
17.0k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
15.5k
      num_entries = hb_max (num_entries, *p + 1u);
631
1.54k
    state_pos = max_state + 1;
632
1.54k
  }
633
1.54k
      }
634
635
1.54k
      if (unlikely (!c->check_array (entries, num_entries)))
636
46
  return_trace (false);
637
1.49k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
1.49k
      { /* Sweep new entries. */
640
1.49k
  const Entry<Extra> *stop = &entries[num_entries];
641
7.93k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
6.44k
  {
643
6.44k
    int newState = new_state (p->newState);
644
6.44k
    min_state = hb_min (min_state, newState);
645
6.44k
    max_state = hb_max (max_state, newState);
646
6.44k
  }
647
1.49k
  entry = num_entries;
648
1.49k
      }
649
1.49k
    }
650
651
861
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
861
    return_trace (true);
655
961
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::ContextualSubtable<AAT::ExtendedTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
1.69k
  {
557
1.69k
    TRACE_SANITIZE (this);
558
1.69k
    if (unlikely (!(c->check_struct (this) &&
559
1.69k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
1.69k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
1.62k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
1.62k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
1.62k
    unsigned int num_classes = nClasses;
566
1.62k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
10
      return_trace (false);
568
1.61k
    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.61k
    int min_state = 0;
585
1.61k
    int max_state = 0;
586
1.61k
    unsigned int num_entries = 0;
587
588
1.61k
    int state_pos = 0;
589
1.61k
    int state_neg = 0;
590
1.61k
    unsigned int entry = 0;
591
4.28k
    while (min_state < state_neg || state_pos <= max_state)
592
2.79k
    {
593
2.79k
      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.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
66
    return_trace (false);
621
2.72k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
2.72k
  { /* Sweep new states. */
624
2.72k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
2.72k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
2.72k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
23.7k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
21.0k
      num_entries = hb_max (num_entries, *p + 1u);
631
2.72k
    state_pos = max_state + 1;
632
2.72k
  }
633
2.72k
      }
634
635
2.72k
      if (unlikely (!c->check_array (entries, num_entries)))
636
64
  return_trace (false);
637
2.66k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
2.66k
      { /* Sweep new entries. */
640
2.66k
  const Entry<Extra> *stop = &entries[num_entries];
641
8.10k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
5.44k
  {
643
5.44k
    int newState = new_state (p->newState);
644
5.44k
    min_state = hb_min (min_state, newState);
645
5.44k
    max_state = hb_max (max_state, newState);
646
5.44k
  }
647
2.66k
  entry = num_entries;
648
2.66k
      }
649
2.66k
    }
650
651
1.48k
    if (num_entries_out)
652
1.48k
      *num_entries_out = num_entries;
653
654
1.48k
    return_trace (true);
655
1.61k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::LigatureEntry<true>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
1.21k
  {
557
1.21k
    TRACE_SANITIZE (this);
558
1.21k
    if (unlikely (!(c->check_struct (this) &&
559
1.21k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
1.21k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
1.17k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
1.17k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
1.17k
    unsigned int num_classes = nClasses;
566
1.17k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
11
      return_trace (false);
568
1.16k
    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.16k
    int min_state = 0;
585
1.16k
    int max_state = 0;
586
1.16k
    unsigned int num_entries = 0;
587
588
1.16k
    int state_pos = 0;
589
1.16k
    int state_neg = 0;
590
1.16k
    unsigned int entry = 0;
591
3.50k
    while (min_state < state_neg || state_pos <= max_state)
592
2.45k
    {
593
2.45k
      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.45k
      if (state_pos <= max_state)
615
2.45k
      {
616
  /* Positive states. */
617
2.45k
  if (unlikely (!c->check_range (states,
618
2.45k
               max_state + 1,
619
2.45k
               row_stride)))
620
78
    return_trace (false);
621
2.37k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
2.37k
  { /* Sweep new states. */
624
2.37k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
2.37k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
2.37k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
438k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
435k
      num_entries = hb_max (num_entries, *p + 1u);
631
2.37k
    state_pos = max_state + 1;
632
2.37k
  }
633
2.37k
      }
634
635
2.37k
      if (unlikely (!c->check_array (entries, num_entries)))
636
36
  return_trace (false);
637
2.33k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
2.33k
      { /* Sweep new entries. */
640
2.33k
  const Entry<Extra> *stop = &entries[num_entries];
641
49.8k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
47.4k
  {
643
47.4k
    int newState = new_state (p->newState);
644
47.4k
    min_state = hb_min (min_state, newState);
645
47.4k
    max_state = hb_max (max_state, newState);
646
47.4k
  }
647
2.33k
  entry = num_entries;
648
2.33k
      }
649
2.33k
    }
650
651
1.05k
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
1.05k
    return_trace (true);
655
1.16k
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::InsertionSubtable<AAT::ExtendedTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
2.25k
  {
557
2.25k
    TRACE_SANITIZE (this);
558
2.25k
    if (unlikely (!(c->check_struct (this) &&
559
2.25k
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
2.25k
        classTable.sanitize (c, this)))) return_trace (false);
561
562
2.18k
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
2.18k
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
2.18k
    unsigned int num_classes = nClasses;
566
2.18k
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
10
      return_trace (false);
568
2.17k
    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.17k
    int min_state = 0;
585
2.17k
    int max_state = 0;
586
2.17k
    unsigned int num_entries = 0;
587
588
2.17k
    int state_pos = 0;
589
2.17k
    int state_neg = 0;
590
2.17k
    unsigned int entry = 0;
591
5.13k
    while (min_state < state_neg || state_pos <= max_state)
592
3.09k
    {
593
3.09k
      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
3.09k
      if (state_pos <= max_state)
615
3.09k
      {
616
  /* Positive states. */
617
3.09k
  if (unlikely (!c->check_range (states,
618
3.09k
               max_state + 1,
619
3.09k
               row_stride)))
620
35
    return_trace (false);
621
3.05k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
3.05k
  { /* Sweep new states. */
624
3.05k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
3.05k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
3.05k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
30.0k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
26.9k
      num_entries = hb_max (num_entries, *p + 1u);
631
3.05k
    state_pos = max_state + 1;
632
3.05k
  }
633
3.05k
      }
634
635
3.05k
      if (unlikely (!c->check_array (entries, num_entries)))
636
90
  return_trace (false);
637
2.96k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
2.96k
      { /* Sweep new entries. */
640
2.96k
  const Entry<Extra> *stop = &entries[num_entries];
641
10.2k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
7.25k
  {
643
7.25k
    int newState = new_state (p->newState);
644
7.25k
    min_state = hb_min (min_state, newState);
645
7.25k
    max_state = hb_max (max_state, newState);
646
7.25k
  }
647
2.96k
  entry = num_entries;
648
2.96k
      }
649
2.96k
    }
650
651
2.04k
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
2.04k
    return_trace (true);
655
2.17k
  }
AAT::StateTable<AAT::ObsoleteTypes, void>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
834
  {
557
834
    TRACE_SANITIZE (this);
558
834
    if (unlikely (!(c->check_struct (this) &&
559
834
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
834
        classTable.sanitize (c, this)))) return_trace (false);
561
562
740
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
740
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
740
    unsigned int num_classes = nClasses;
566
740
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
0
      return_trace (false);
568
740
    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
740
    int min_state = 0;
585
740
    int max_state = 0;
586
740
    unsigned int num_entries = 0;
587
588
740
    int state_pos = 0;
589
740
    int state_neg = 0;
590
740
    unsigned int entry = 0;
591
2.01k
    while (min_state < state_neg || state_pos <= max_state)
592
1.42k
    {
593
1.42k
      if (min_state < state_neg)
594
46
      {
595
  /* Negative states. */
596
46
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
46
    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.38k
      if (state_pos <= max_state)
615
1.38k
      {
616
  /* Positive states. */
617
1.38k
  if (unlikely (!c->check_range (states,
618
1.38k
               max_state + 1,
619
1.38k
               row_stride)))
620
73
    return_trace (false);
621
1.30k
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
1.30k
  { /* Sweep new states. */
624
1.30k
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
1.30k
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
1.30k
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
1.44M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
1.44M
      num_entries = hb_max (num_entries, *p + 1u);
631
1.30k
    state_pos = max_state + 1;
632
1.30k
  }
633
1.30k
      }
634
635
1.30k
      if (unlikely (!c->check_array (entries, num_entries)))
636
33
  return_trace (false);
637
1.27k
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
1.27k
      { /* Sweep new entries. */
640
1.27k
  const Entry<Extra> *stop = &entries[num_entries];
641
25.9k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
24.7k
  {
643
24.7k
    int newState = new_state (p->newState);
644
24.7k
    min_state = hb_min (min_state, newState);
645
24.7k
    max_state = hb_max (max_state, newState);
646
24.7k
  }
647
1.27k
  entry = num_entries;
648
1.27k
      }
649
1.27k
    }
650
651
588
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
588
    return_trace (true);
655
740
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::ContextualSubtable<AAT::ObsoleteTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
196
  {
557
196
    TRACE_SANITIZE (this);
558
196
    if (unlikely (!(c->check_struct (this) &&
559
196
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
196
        classTable.sanitize (c, this)))) return_trace (false);
561
562
138
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
138
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
138
    unsigned int num_classes = nClasses;
566
138
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
0
      return_trace (false);
568
138
    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
138
    int min_state = 0;
585
138
    int max_state = 0;
586
138
    unsigned int num_entries = 0;
587
588
138
    int state_pos = 0;
589
138
    int state_neg = 0;
590
138
    unsigned int entry = 0;
591
242
    while (min_state < state_neg || state_pos <= max_state)
592
211
    {
593
211
      if (min_state < state_neg)
594
18
      {
595
  /* Negative states. */
596
18
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
18
    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
193
      if (state_pos <= max_state)
615
193
      {
616
  /* Positive states. */
617
193
  if (unlikely (!c->check_range (states,
618
193
               max_state + 1,
619
193
               row_stride)))
620
50
    return_trace (false);
621
143
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
143
  { /* Sweep new states. */
624
143
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
143
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
143
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
105k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
105k
      num_entries = hb_max (num_entries, *p + 1u);
631
143
    state_pos = max_state + 1;
632
143
  }
633
143
      }
634
635
143
      if (unlikely (!c->check_array (entries, num_entries)))
636
39
  return_trace (false);
637
104
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
104
      { /* Sweep new entries. */
640
104
  const Entry<Extra> *stop = &entries[num_entries];
641
4.20k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
4.10k
  {
643
4.10k
    int newState = new_state (p->newState);
644
4.10k
    min_state = hb_min (min_state, newState);
645
4.10k
    max_state = hb_max (max_state, newState);
646
4.10k
  }
647
104
  entry = num_entries;
648
104
      }
649
104
    }
650
651
31
    if (num_entries_out)
652
31
      *num_entries_out = num_entries;
653
654
31
    return_trace (true);
655
138
  }
AAT::StateTable<AAT::ObsoleteTypes, AAT::InsertionSubtable<AAT::ObsoleteTypes>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
439
  {
557
439
    TRACE_SANITIZE (this);
558
439
    if (unlikely (!(c->check_struct (this) &&
559
439
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
439
        classTable.sanitize (c, this)))) return_trace (false);
561
562
396
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
396
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
396
    unsigned int num_classes = nClasses;
566
396
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
0
      return_trace (false);
568
396
    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
396
    int min_state = 0;
585
396
    int max_state = 0;
586
396
    unsigned int num_entries = 0;
587
588
396
    int state_pos = 0;
589
396
    int state_neg = 0;
590
396
    unsigned int entry = 0;
591
761
    while (min_state < state_neg || state_pos <= max_state)
592
472
    {
593
472
      if (min_state < state_neg)
594
6
      {
595
  /* Negative states. */
596
6
  if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes)))
597
6
    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
466
      if (state_pos <= max_state)
615
466
      {
616
  /* Positive states. */
617
466
  if (unlikely (!c->check_range (states,
618
466
               max_state + 1,
619
466
               row_stride)))
620
62
    return_trace (false);
621
404
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
404
  { /* Sweep new states. */
624
404
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
404
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
404
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
123k
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
123k
      num_entries = hb_max (num_entries, *p + 1u);
631
404
    state_pos = max_state + 1;
632
404
  }
633
404
      }
634
635
404
      if (unlikely (!c->check_array (entries, num_entries)))
636
39
  return_trace (false);
637
365
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
365
      { /* Sweep new entries. */
640
365
  const Entry<Extra> *stop = &entries[num_entries];
641
3.52k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
3.15k
  {
643
3.15k
    int newState = new_state (p->newState);
644
3.15k
    min_state = hb_min (min_state, newState);
645
3.15k
    max_state = hb_max (max_state, newState);
646
3.15k
  }
647
365
  entry = num_entries;
648
365
      }
649
365
    }
650
651
289
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
289
    return_trace (true);
655
396
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::Format1Entry<true>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
316
  {
557
316
    TRACE_SANITIZE (this);
558
316
    if (unlikely (!(c->check_struct (this) &&
559
316
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
316
        classTable.sanitize (c, this)))) return_trace (false);
561
562
260
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
260
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
260
    unsigned int num_classes = nClasses;
566
260
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
10
      return_trace (false);
568
250
    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
250
    int min_state = 0;
585
250
    int max_state = 0;
586
250
    unsigned int num_entries = 0;
587
588
250
    int state_pos = 0;
589
250
    int state_neg = 0;
590
250
    unsigned int entry = 0;
591
477
    while (min_state < state_neg || state_pos <= max_state)
592
369
    {
593
369
      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
369
      if (state_pos <= max_state)
615
369
      {
616
  /* Positive states. */
617
369
  if (unlikely (!c->check_range (states,
618
369
               max_state + 1,
619
369
               row_stride)))
620
68
    return_trace (false);
621
301
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
301
  { /* Sweep new states. */
624
301
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
301
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
301
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
1.90M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
1.90M
      num_entries = hb_max (num_entries, *p + 1u);
631
301
    state_pos = max_state + 1;
632
301
  }
633
301
      }
634
635
301
      if (unlikely (!c->check_array (entries, num_entries)))
636
74
  return_trace (false);
637
227
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
227
      { /* Sweep new entries. */
640
227
  const Entry<Extra> *stop = &entries[num_entries];
641
674k
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
673k
  {
643
673k
    int newState = new_state (p->newState);
644
673k
    min_state = hb_min (min_state, newState);
645
673k
    max_state = hb_max (max_state, newState);
646
673k
  }
647
227
  entry = num_entries;
648
227
      }
649
227
    }
650
651
108
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
108
    return_trace (true);
655
250
  }
AAT::StateTable<AAT::ExtendedTypes, AAT::KerxSubTableFormat4<AAT::KerxSubTableHeader>::EntryData>::sanitize(hb_sanitize_context_t*, unsigned int*) const
Line
Count
Source
556
729
  {
557
729
    TRACE_SANITIZE (this);
558
729
    if (unlikely (!(c->check_struct (this) &&
559
729
        nClasses >= 4 /* Ensure pre-defined classes fit.  */ &&
560
729
        classTable.sanitize (c, this)))) return_trace (false);
561
562
602
    const HBUSHORT *states = (this+stateArrayTable).arrayZ;
563
602
    const Entry<Extra> *entries = (this+entryTable).arrayZ;
564
565
602
    unsigned int num_classes = nClasses;
566
602
    if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
567
10
      return_trace (false);
568
592
    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
592
    int min_state = 0;
585
592
    int max_state = 0;
586
592
    unsigned int num_entries = 0;
587
588
592
    int state_pos = 0;
589
592
    int state_neg = 0;
590
592
    unsigned int entry = 0;
591
1.20k
    while (min_state < state_neg || state_pos <= max_state)
592
776
    {
593
776
      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
776
      if (state_pos <= max_state)
615
776
      {
616
  /* Positive states. */
617
776
  if (unlikely (!c->check_range (states,
618
776
               max_state + 1,
619
776
               row_stride)))
620
80
    return_trace (false);
621
696
  if ((c->max_ops -= max_state - state_pos + 1) <= 0)
622
0
    return_trace (false);
623
696
  { /* Sweep new states. */
624
696
    if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes)))
625
0
      return_trace (false);
626
696
    const HBUSHORT *stop = &states[(max_state + 1) * num_classes];
627
696
    if (unlikely (stop < states))
628
0
      return_trace (false);
629
4.01M
    for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
630
4.01M
      num_entries = hb_max (num_entries, *p + 1u);
631
696
    state_pos = max_state + 1;
632
696
  }
633
696
      }
634
635
696
      if (unlikely (!c->check_array (entries, num_entries)))
636
81
  return_trace (false);
637
615
      if ((c->max_ops -= num_entries - entry) <= 0)
638
0
  return_trace (false);
639
615
      { /* Sweep new entries. */
640
615
  const Entry<Extra> *stop = &entries[num_entries];
641
1.11M
  for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
642
1.11M
  {
643
1.11M
    int newState = new_state (p->newState);
644
1.11M
    min_state = hb_min (min_state, newState);
645
1.11M
    max_state = hb_max (max_state, newState);
646
1.11M
  }
647
615
  entry = num_entries;
648
615
      }
649
615
    }
650
651
431
    if (num_entries_out)
652
0
      *num_entries_out = num_entries;
653
654
431
    return_trace (true);
655
592
  }
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
4.65M
  {
676
4.65M
    unsigned int i = glyph_id - firstGlyph;
677
4.65M
    return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
678
4.65M
  }
AAT::ClassTable<OT::IntType<unsigned char, 1u> >::get_class(unsigned int, unsigned int) const
Line
Count
Source
675
4.63M
  {
676
4.63M
    unsigned int i = glyph_id - firstGlyph;
677
4.63M
    return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
678
4.63M
  }
AAT::ClassTable<OT::IntType<unsigned short, 2u> >::get_class(unsigned int, unsigned int) const
Line
Count
Source
675
21.1k
  {
676
21.1k
    unsigned int i = glyph_id - firstGlyph;
677
21.1k
    return i >= classArray.len ? outOfRange : classArray.arrayZ[i];
678
21.1k
  }
679
  unsigned int get_class (hb_codepoint_t glyph_id,
680
        unsigned int num_glyphs HB_UNUSED,
681
        unsigned int outOfRange) const
682
4.65M
  {
683
4.65M
    return get_class (glyph_id, outOfRange);
684
4.65M
  }
AAT::ClassTable<OT::IntType<unsigned char, 1u> >::get_class(unsigned int, unsigned int, unsigned int) const
Line
Count
Source
682
4.63M
  {
683
4.63M
    return get_class (glyph_id, outOfRange);
684
4.63M
  }
AAT::ClassTable<OT::IntType<unsigned short, 2u> >::get_class(unsigned int, unsigned int, unsigned int) const
Line
Count
Source
682
21.1k
  {
683
21.1k
    return get_class (glyph_id, outOfRange);
684
21.1k
  }
685
  bool sanitize (hb_sanitize_context_t *c) const
686
2.26k
  {
687
2.26k
    TRACE_SANITIZE (this);
688
2.26k
    return_trace (c->check_struct (this) && classArray.sanitize (c));
689
2.26k
  }
AAT::ClassTable<OT::IntType<unsigned char, 1u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
686
1.36k
  {
687
1.36k
    TRACE_SANITIZE (this);
688
1.36k
    return_trace (c->check_struct (this) && classArray.sanitize (c));
689
1.36k
  }
AAT::ClassTable<OT::IntType<unsigned short, 2u> >::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
686
898
  {
687
898
    TRACE_SANITIZE (this);
688
898
    return_trace (c->check_struct (this) && classArray.sanitize (c));
689
898
  }
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
461k
  {
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
461k
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
716
14.2k
      return INT_MAX / T::static_size;
717
718
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
719
446k
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
720
461k
  }
unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
Line
Count
Source
710
395k
  {
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
395k
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
716
7.39k
      return INT_MAX / T::static_size;
717
718
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
719
387k
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
720
395k
  }
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::IntType<unsigned int, 4u> >(unsigned int, void const*, OT::IntType<unsigned int, 4u> const*)
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::IntType<unsigned short, 2u> >(unsigned int, void const*, OT::IntType<unsigned short, 2u> const*)
unsigned int AAT::ObsoleteTypes::offsetToIndex<OT::IntType<short, 2u> >(unsigned int, void const*, OT::IntType<short, 2u> const*)
Line
Count
Source
710
65.9k
  {
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
65.9k
    if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
716
6.85k
      return INT_MAX / T::static_size;
717
718
    /* https://github.com/harfbuzz/harfbuzz/issues/2816 */
719
59.0k
    return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
720
65.9k
  }
721
  template <typename T>
722
  static unsigned int byteOffsetToIndex (unsigned int offset,
723
           const void *base,
724
           const T *array)
725
55.3k
  {
726
55.3k
    return offsetToIndex (offset, base, array);
727
55.3k
  }
728
  template <typename T>
729
  static unsigned int wordOffsetToIndex (unsigned int offset,
730
           const void *base,
731
           const T *array)
732
395k
  {
733
395k
    return offsetToIndex (2 * offset, base, array);
734
395k
  }
unsigned int AAT::ObsoleteTypes::wordOffsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
Line
Count
Source
732
395k
  {
733
395k
    return offsetToIndex (2 * offset, base, array);
734
395k
  }
Unexecuted instantiation: unsigned int AAT::ObsoleteTypes::wordOffsetToIndex<OT::IntType<unsigned short, 2u> >(unsigned int, void const*, OT::IntType<unsigned short, 2u> const*)
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
1.23M
  {
749
1.23M
    return offset;
750
1.23M
  }
unsigned int AAT::ExtendedTypes::offsetToIndex<OT::IntType<unsigned int, 4u> >(unsigned int, void const*, OT::IntType<unsigned int, 4u> const*)
Line
Count
Source
748
1.15M
  {
749
1.15M
    return offset;
750
1.15M
  }
unsigned int AAT::ExtendedTypes::offsetToIndex<OT::HBGlyphID16>(unsigned int, void const*, OT::HBGlyphID16 const*)
Line
Count
Source
748
74.7k
  {
749
74.7k
    return offset;
750
74.7k
  }
unsigned int AAT::ExtendedTypes::offsetToIndex<OT::IntType<short, 2u> >(unsigned int, void const*, OT::IntType<short, 2u> const*)
Line
Count
Source
748
2.92k
  {
749
2.92k
    return offset;
750
2.92k
  }
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
443k
  {
756
443k
    return offset / 2;
757
443k
  }
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
900k
  {
763
900k
    return offset;
764
900k
  }
unsigned int AAT::ExtendedTypes::wordOffsetToIndex<OT::IntType<unsigned short, 2u> >(unsigned int, void const*, OT::IntType<unsigned short, 2u> const*)
Line
Count
Source
762
900k
  {
763
900k
    return offset;
764
900k
  }
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
56.8k
        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
8.27k
        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
14.7k
        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
9.52k
        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
20.0k
        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
2.02k
        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
122
        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
666
        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
306
        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
1.17k
        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
56.8k
  {
783
56.8k
    if (!c->in_place)
784
30.2k
      buffer->clear_output ();
785
786
56.8k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
56.8k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
20.0M
    for (buffer->idx = 0; buffer->successful;)
790
20.0M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
20.0M
      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
20.0M
      unsigned int klass = buffer->idx < buffer->len ?
818
20.0M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
20.0M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
20.0M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
20.0M
      const EntryT &entry = machine.get_entry (state, klass);
822
20.0M
      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
20.0M
      const EntryT *wouldbe_entry;
853
20.0M
      bool safe_to_break =
854
  /* 1. */
855
20.0M
  !c->is_actionable (this, entry)
856
20.0M
      &&
857
  /* 2. */
858
20.0M
  (
859
    /* 2a. */
860
9.67M
    state == StateTableT::STATE_START_OF_TEXT
861
9.67M
  ||
862
    /* 2b. */
863
9.67M
    (
864
1.71M
      (entry.flags & context_t::DontAdvance) &&
865
1.71M
      next_state == StateTableT::STATE_START_OF_TEXT
866
1.71M
    )
867
9.67M
  ||
868
    /* 2c. */
869
9.67M
    (
870
1.35M
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
1.35M
    ,
872
      /* 2c'. */
873
1.35M
      !c->is_actionable (this, *wouldbe_entry)
874
1.35M
    &&
875
      /* 2c". */
876
1.35M
      (
877
1.00M
        next_state == machine.new_state (wouldbe_entry->newState)
878
1.00M
      &&
879
1.00M
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
1.00M
      )
881
1.35M
    )
882
9.67M
  )
883
20.0M
      &&
884
  /* 3. */
885
20.0M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
20.0M
      ;
887
888
20.0M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
5.82M
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
20.0M
      c->transition (this, entry);
892
893
20.0M
      state = next_state;
894
20.0M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
20.0M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
56.8k
  break;
898
899
20.0M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
3.94M
  (void) buffer->next_glyph ();
901
20.0M
    }
902
903
56.8k
    if (!c->in_place)
904
30.2k
      buffer->sync ();
905
56.8k
  }
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
8.27k
  {
783
8.27k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
8.27k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
8.27k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
2.49M
    for (buffer->idx = 0; buffer->successful;)
790
2.49M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
2.49M
      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.49M
      unsigned int klass = buffer->idx < buffer->len ?
818
2.48M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
2.49M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
2.49M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
2.49M
      const EntryT &entry = machine.get_entry (state, klass);
822
2.49M
      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.49M
      const EntryT *wouldbe_entry;
853
2.49M
      bool safe_to_break =
854
  /* 1. */
855
2.49M
  !c->is_actionable (this, entry)
856
2.49M
      &&
857
  /* 2. */
858
2.49M
  (
859
    /* 2a. */
860
1.85M
    state == StateTableT::STATE_START_OF_TEXT
861
1.85M
  ||
862
    /* 2b. */
863
1.85M
    (
864
376k
      (entry.flags & context_t::DontAdvance) &&
865
376k
      next_state == StateTableT::STATE_START_OF_TEXT
866
376k
    )
867
1.85M
  ||
868
    /* 2c. */
869
1.85M
    (
870
358k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
358k
    ,
872
      /* 2c'. */
873
358k
      !c->is_actionable (this, *wouldbe_entry)
874
358k
    &&
875
      /* 2c". */
876
358k
      (
877
322k
        next_state == machine.new_state (wouldbe_entry->newState)
878
322k
      &&
879
322k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
322k
      )
881
358k
    )
882
1.85M
  )
883
2.49M
      &&
884
  /* 3. */
885
2.49M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
2.49M
      ;
887
888
2.49M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
306k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
2.49M
      c->transition (this, entry);
892
893
2.49M
      state = next_state;
894
2.49M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
2.49M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
8.27k
  break;
898
899
2.48M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
42.9k
  (void) buffer->next_glyph ();
901
2.48M
    }
902
903
8.27k
    if (!c->in_place)
904
0
      buffer->sync ();
905
8.27k
  }
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
14.7k
  {
783
14.7k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
14.7k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
14.7k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
4.00M
    for (buffer->idx = 0; buffer->successful;)
790
4.00M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
4.00M
      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
4.00M
      unsigned int klass = buffer->idx < buffer->len ?
818
3.98M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
4.00M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
4.00M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
4.00M
      const EntryT &entry = machine.get_entry (state, klass);
822
4.00M
      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
4.00M
      const EntryT *wouldbe_entry;
853
4.00M
      bool safe_to_break =
854
  /* 1. */
855
4.00M
  !c->is_actionable (this, entry)
856
4.00M
      &&
857
  /* 2. */
858
4.00M
  (
859
    /* 2a. */
860
2.35M
    state == StateTableT::STATE_START_OF_TEXT
861
2.35M
  ||
862
    /* 2b. */
863
2.35M
    (
864
94.8k
      (entry.flags & context_t::DontAdvance) &&
865
94.8k
      next_state == StateTableT::STATE_START_OF_TEXT
866
94.8k
    )
867
2.35M
  ||
868
    /* 2c. */
869
2.35M
    (
870
94.8k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
94.8k
    ,
872
      /* 2c'. */
873
94.8k
      !c->is_actionable (this, *wouldbe_entry)
874
94.8k
    &&
875
      /* 2c". */
876
94.8k
      (
877
94.4k
        next_state == machine.new_state (wouldbe_entry->newState)
878
94.4k
      &&
879
94.4k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
94.4k
      )
881
94.8k
    )
882
2.35M
  )
883
4.00M
      &&
884
  /* 3. */
885
4.00M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
4.00M
      ;
887
888
4.00M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
225k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
4.00M
      c->transition (this, entry);
892
893
4.00M
      state = next_state;
894
4.00M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
4.00M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
14.7k
  break;
898
899
3.98M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
58.5k
  (void) buffer->next_glyph ();
901
3.98M
    }
902
903
14.7k
    if (!c->in_place)
904
0
      buffer->sync ();
905
14.7k
  }
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
9.52k
  {
783
9.52k
    if (!c->in_place)
784
9.52k
      buffer->clear_output ();
785
786
9.52k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
9.52k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
3.14M
    for (buffer->idx = 0; buffer->successful;)
790
3.14M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
3.14M
      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.14M
      unsigned int klass = buffer->idx < buffer->len ?
818
3.13M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
3.14M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
3.14M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
3.14M
      const EntryT &entry = machine.get_entry (state, klass);
822
3.14M
      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.14M
      const EntryT *wouldbe_entry;
853
3.14M
      bool safe_to_break =
854
  /* 1. */
855
3.14M
  !c->is_actionable (this, entry)
856
3.14M
      &&
857
  /* 2. */
858
3.14M
  (
859
    /* 2a. */
860
1.90M
    state == StateTableT::STATE_START_OF_TEXT
861
1.90M
  ||
862
    /* 2b. */
863
1.90M
    (
864
513k
      (entry.flags & context_t::DontAdvance) &&
865
513k
      next_state == StateTableT::STATE_START_OF_TEXT
866
513k
    )
867
1.90M
  ||
868
    /* 2c. */
869
1.90M
    (
870
201k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
201k
    ,
872
      /* 2c'. */
873
201k
      !c->is_actionable (this, *wouldbe_entry)
874
201k
    &&
875
      /* 2c". */
876
201k
      (
877
201k
        next_state == machine.new_state (wouldbe_entry->newState)
878
201k
      &&
879
201k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
201k
      )
881
201k
    )
882
1.90M
  )
883
3.14M
      &&
884
  /* 3. */
885
3.14M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
3.14M
      ;
887
888
3.14M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
395k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
3.14M
      c->transition (this, entry);
892
893
3.14M
      state = next_state;
894
3.14M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
3.14M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
9.52k
  break;
898
899
3.13M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
35.7k
  (void) buffer->next_glyph ();
901
3.13M
    }
902
903
9.52k
    if (!c->in_place)
904
9.52k
      buffer->sync ();
905
9.52k
  }
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
20.0k
  {
783
20.0k
    if (!c->in_place)
784
20.0k
      buffer->clear_output ();
785
786
20.0k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
20.0k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
4.23M
    for (buffer->idx = 0; buffer->successful;)
790
4.23M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
4.23M
      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
4.23M
      unsigned int klass = buffer->idx < buffer->len ?
818
4.21M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
4.23M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
4.23M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
4.23M
      const EntryT &entry = machine.get_entry (state, klass);
822
4.23M
      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
4.23M
      const EntryT *wouldbe_entry;
853
4.23M
      bool safe_to_break =
854
  /* 1. */
855
4.23M
  !c->is_actionable (this, entry)
856
4.23M
      &&
857
  /* 2. */
858
4.23M
  (
859
    /* 2a. */
860
2.15M
    state == StateTableT::STATE_START_OF_TEXT
861
2.15M
  ||
862
    /* 2b. */
863
2.15M
    (
864
662k
      (entry.flags & context_t::DontAdvance) &&
865
662k
      next_state == StateTableT::STATE_START_OF_TEXT
866
662k
    )
867
2.15M
  ||
868
    /* 2c. */
869
2.15M
    (
870
636k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
636k
    ,
872
      /* 2c'. */
873
636k
      !c->is_actionable (this, *wouldbe_entry)
874
636k
    &&
875
      /* 2c". */
876
636k
      (
877
354k
        next_state == machine.new_state (wouldbe_entry->newState)
878
354k
      &&
879
354k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
354k
      )
881
636k
    )
882
2.15M
  )
883
4.23M
      &&
884
  /* 3. */
885
4.23M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
4.23M
      ;
887
888
4.23M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
1.70M
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
4.23M
      c->transition (this, entry);
892
893
4.23M
      state = next_state;
894
4.23M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
4.23M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
20.0k
  break;
898
899
4.21M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
1.54M
  (void) buffer->next_glyph ();
901
4.21M
    }
902
903
20.0k
    if (!c->in_place)
904
20.0k
      buffer->sync ();
905
20.0k
  }
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
1.96k
  {
783
1.96k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
1.96k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
1.96k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
3.52M
    for (buffer->idx = 0; buffer->successful;)
790
3.52M
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
3.52M
      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.52M
      unsigned int klass = buffer->idx < buffer->len ?
818
3.52M
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
3.52M
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
3.52M
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
3.52M
      const EntryT &entry = machine.get_entry (state, klass);
822
3.52M
      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.52M
      const EntryT *wouldbe_entry;
853
3.52M
      bool safe_to_break =
854
  /* 1. */
855
3.52M
  !c->is_actionable (this, entry)
856
3.52M
      &&
857
  /* 2. */
858
3.52M
  (
859
    /* 2a. */
860
1.25M
    state == StateTableT::STATE_START_OF_TEXT
861
1.25M
  ||
862
    /* 2b. */
863
1.25M
    (
864
65.4k
      (entry.flags & context_t::DontAdvance) &&
865
65.4k
      next_state == StateTableT::STATE_START_OF_TEXT
866
65.4k
    )
867
1.25M
  ||
868
    /* 2c. */
869
1.25M
    (
870
63.3k
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
63.3k
    ,
872
      /* 2c'. */
873
63.3k
      !c->is_actionable (this, *wouldbe_entry)
874
63.3k
    &&
875
      /* 2c". */
876
63.3k
      (
877
30.6k
        next_state == machine.new_state (wouldbe_entry->newState)
878
30.6k
      &&
879
30.6k
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
30.6k
      )
881
63.3k
    )
882
1.25M
  )
883
3.52M
      &&
884
  /* 3. */
885
3.52M
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
3.52M
      ;
887
888
3.52M
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
2.17M
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
3.52M
      c->transition (this, entry);
892
893
3.52M
      state = next_state;
894
3.52M
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
3.52M
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
1.96k
  break;
898
899
3.52M
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
2.03M
  (void) buffer->next_glyph ();
901
3.52M
    }
902
903
1.96k
    if (!c->in_place)
904
0
      buffer->sync ();
905
1.96k
  }
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
122
  {
783
122
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
122
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
122
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
197k
    for (buffer->idx = 0; buffer->successful;)
790
197k
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
197k
      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
197k
      unsigned int klass = buffer->idx < buffer->len ?
818
197k
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
197k
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
197k
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
197k
      const EntryT &entry = machine.get_entry (state, klass);
822
197k
      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
197k
      const EntryT *wouldbe_entry;
853
197k
      bool safe_to_break =
854
  /* 1. */
855
197k
  !c->is_actionable (this, entry)
856
197k
      &&
857
  /* 2. */
858
197k
  (
859
    /* 2a. */
860
122
    state == StateTableT::STATE_START_OF_TEXT
861
122
  ||
862
    /* 2b. */
863
122
    (
864
97
      (entry.flags & context_t::DontAdvance) &&
865
97
      next_state == StateTableT::STATE_START_OF_TEXT
866
97
    )
867
122
  ||
868
    /* 2c. */
869
122
    (
870
97
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
97
    ,
872
      /* 2c'. */
873
97
      !c->is_actionable (this, *wouldbe_entry)
874
97
    &&
875
      /* 2c". */
876
97
      (
877
97
        next_state == machine.new_state (wouldbe_entry->newState)
878
97
      &&
879
97
        (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
880
97
      )
881
97
    )
882
122
  )
883
197k
      &&
884
  /* 3. */
885
197k
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
197k
      ;
887
888
197k
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
197k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
197k
      c->transition (this, entry);
892
893
197k
      state = next_state;
894
197k
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
197k
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
122
  break;
898
899
197k
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
197k
  (void) buffer->next_glyph ();
901
197k
    }
902
903
122
    if (!c->in_place)
904
0
      buffer->sync ();
905
122
  }
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
6
  {
783
6
    if (!c->in_place)
784
6
      buffer->clear_output ();
785
786
6
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
6
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
114
    for (buffer->idx = 0; buffer->successful;)
790
114
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
114
      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
114
      unsigned int klass = buffer->idx < buffer->len ?
818
108
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
114
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
114
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
114
      const EntryT &entry = machine.get_entry (state, klass);
822
114
      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
114
      const EntryT *wouldbe_entry;
853
114
      bool safe_to_break =
854
  /* 1. */
855
114
  !c->is_actionable (this, entry)
856
114
      &&
857
  /* 2. */
858
114
  (
859
    /* 2a. */
860
28
    state == StateTableT::STATE_START_OF_TEXT
861
28
  ||
862
    /* 2b. */
863
28
    (
864
28
      (entry.flags & context_t::DontAdvance) &&
865
28
      next_state == StateTableT::STATE_START_OF_TEXT
866
28
    )
867
28
  ||
868
    /* 2c. */
869
28
    (
870
28
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
28
    ,
872
      /* 2c'. */
873
28
      !c->is_actionable (this, *wouldbe_entry)
874
28
    &&
875
      /* 2c". */
876
28
      (
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
28
    )
882
28
  )
883
114
      &&
884
  /* 3. */
885
114
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
114
      ;
887
888
114
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
102
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
114
      c->transition (this, entry);
892
893
114
      state = next_state;
894
114
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
114
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
6
  break;
898
899
108
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
108
  (void) buffer->next_glyph ();
901
108
    }
902
903
6
    if (!c->in_place)
904
6
      buffer->sync ();
905
6
  }
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
666
  {
783
666
    if (!c->in_place)
784
666
      buffer->clear_output ();
785
786
666
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
666
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
968k
    for (buffer->idx = 0; buffer->successful;)
790
968k
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
968k
      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
968k
      unsigned int klass = buffer->idx < buffer->len ?
818
967k
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
968k
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
968k
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
968k
      const EntryT &entry = machine.get_entry (state, klass);
822
968k
      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
968k
      const EntryT *wouldbe_entry;
853
968k
      bool safe_to_break =
854
  /* 1. */
855
968k
  !c->is_actionable (this, entry)
856
968k
      &&
857
  /* 2. */
858
968k
  (
859
    /* 2a. */
860
324
    state == StateTableT::STATE_START_OF_TEXT
861
324
  ||
862
    /* 2b. */
863
324
    (
864
0
      (entry.flags & context_t::DontAdvance) &&
865
0
      next_state == StateTableT::STATE_START_OF_TEXT
866
0
    )
867
324
  ||
868
    /* 2c. */
869
324
    (
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
324
  )
883
968k
      &&
884
  /* 3. */
885
968k
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
968k
      ;
887
888
968k
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
797k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
968k
      c->transition (this, entry);
892
893
968k
      state = next_state;
894
968k
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
968k
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
666
  break;
898
899
967k
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
7.36k
  (void) buffer->next_glyph ();
901
967k
    }
902
903
666
    if (!c->in_place)
904
666
      buffer->sync ();
905
666
  }
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
306
  {
783
306
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
306
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
306
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
779k
    for (buffer->idx = 0; buffer->successful;)
790
779k
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
779k
      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
779k
      unsigned int klass = buffer->idx < buffer->len ?
818
778k
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
779k
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
779k
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
779k
      const EntryT &entry = machine.get_entry (state, klass);
822
779k
      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
779k
      const EntryT *wouldbe_entry;
853
779k
      bool safe_to_break =
854
  /* 1. */
855
779k
  !c->is_actionable (this, entry)
856
779k
      &&
857
  /* 2. */
858
779k
  (
859
    /* 2a. */
860
366
    state == StateTableT::STATE_START_OF_TEXT
861
366
  ||
862
    /* 2b. */
863
366
    (
864
26
      (entry.flags & context_t::DontAdvance) &&
865
26
      next_state == StateTableT::STATE_START_OF_TEXT
866
26
    )
867
366
  ||
868
    /* 2c. */
869
366
    (
870
26
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
26
    ,
872
      /* 2c'. */
873
26
      !c->is_actionable (this, *wouldbe_entry)
874
26
    &&
875
      /* 2c". */
876
26
      (
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
26
    )
882
366
  )
883
779k
      &&
884
  /* 3. */
885
779k
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
779k
      ;
887
888
779k
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
4.37k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
779k
      c->transition (this, entry);
892
893
779k
      state = next_state;
894
779k
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
779k
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
306
  break;
898
899
778k
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
4.52k
  (void) buffer->next_glyph ();
901
778k
    }
902
903
306
    if (!c->in_place)
904
0
      buffer->sync ();
905
306
  }
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
1.17k
  {
783
1.17k
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
1.17k
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
1.17k
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
686k
    for (buffer->idx = 0; buffer->successful;)
790
686k
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
686k
      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
686k
      unsigned int klass = buffer->idx < buffer->len ?
818
685k
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
686k
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
686k
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
686k
      const EntryT &entry = machine.get_entry (state, klass);
822
686k
      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
686k
      const EntryT *wouldbe_entry;
853
686k
      bool safe_to_break =
854
  /* 1. */
855
686k
  !c->is_actionable (this, entry)
856
686k
      &&
857
  /* 2. */
858
686k
  (
859
    /* 2a. */
860
166k
    state == StateTableT::STATE_START_OF_TEXT
861
166k
  ||
862
    /* 2b. */
863
166k
    (
864
47
      (entry.flags & context_t::DontAdvance) &&
865
47
      next_state == StateTableT::STATE_START_OF_TEXT
866
47
    )
867
166k
  ||
868
    /* 2c. */
869
166k
    (
870
47
      wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
871
47
    ,
872
      /* 2c'. */
873
47
      !c->is_actionable (this, *wouldbe_entry)
874
47
    &&
875
      /* 2c". */
876
47
      (
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
47
    )
882
166k
  )
883
686k
      &&
884
  /* 3. */
885
686k
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
686k
      ;
887
888
686k
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
20.8k
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
686k
      c->transition (this, entry);
892
893
686k
      state = next_state;
894
686k
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
686k
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
1.17k
  break;
898
899
685k
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
21.1k
  (void) buffer->next_glyph ();
901
685k
    }
902
903
1.17k
    if (!c->in_place)
904
0
      buffer->sync ();
905
1.17k
  }
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
57
  {
783
57
    if (!c->in_place)
784
0
      buffer->clear_output ();
785
786
57
    int state = StateTableT::STATE_START_OF_TEXT;
787
    // If there's only one range, we already checked the flag.
788
57
    auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
789
56.0k
    for (buffer->idx = 0; buffer->successful;)
790
56.0k
    {
791
      /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
792
56.0k
      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
56.0k
      unsigned int klass = buffer->idx < buffer->len ?
818
55.9k
         machine.get_class (buffer->cur().codepoint, num_glyphs) :
819
56.0k
         (unsigned) StateTableT::CLASS_END_OF_TEXT;
820
56.0k
      DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
821
56.0k
      const EntryT &entry = machine.get_entry (state, klass);
822
56.0k
      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
56.0k
      const EntryT *wouldbe_entry;
853
56.0k
      bool safe_to_break =
854
  /* 1. */
855
56.0k
  !c->is_actionable (this, entry)
856
56.0k
      &&
857
  /* 2. */
858
56.0k
  (
859
    /* 2a. */
860
94
    state == StateTableT::STATE_START_OF_TEXT
861
94
  ||
862
    /* 2b. */
863
94
    (
864
0
      (entry.flags & context_t::DontAdvance) &&
865
0
      next_state == StateTableT::STATE_START_OF_TEXT
866
0
    )
867
94
  ||
868
    /* 2c. */
869
94
    (
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
94
  )
883
56.0k
      &&
884
  /* 3. */
885
56.0k
  !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
886
56.0k
      ;
887
888
56.0k
      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
889
606
  buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
890
891
56.0k
      c->transition (this, entry);
892
893
56.0k
      state = next_state;
894
56.0k
      DEBUG_MSG (APPLY, nullptr, "s%d", state);
895
896
56.0k
      if (buffer->idx == buffer->len || unlikely (!buffer->successful))
897
57
  break;
898
899
55.9k
      if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
900
696
  (void) buffer->next_glyph ();
901
55.9k
    }
902
903
57
    if (!c->in_place)
904
0
      buffer->sync ();
905
57
  }
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 */