Coverage Report

Created: 2023-06-07 06:14

/src/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh
Line
Count
Source (jump to first uncovered line)
1
#ifndef OT_LAYOUT_GSUB_SUBSTLOOKUP_HH
2
#define OT_LAYOUT_GSUB_SUBSTLOOKUP_HH
3
4
#include "Common.hh"
5
#include "SubstLookupSubTable.hh"
6
7
namespace OT {
8
namespace Layout {
9
namespace GSUB_impl {
10
11
struct SubstLookup : Lookup
12
{
13
  using SubTable = SubstLookupSubTable;
14
15
  bool sanitize (hb_sanitize_context_t *c) const
16
59
  { return Lookup::sanitize<SubTable> (c); }
17
18
  const SubTable& get_subtable (unsigned int i) const
19
0
  { return Lookup::get_subtable<SubTable> (i); }
20
21
  static inline bool lookup_type_is_reverse (unsigned int lookup_type)
22
0
  { return lookup_type == SubTable::ReverseChainSingle; }
23
24
  bool is_reverse () const
25
0
  {
26
0
    unsigned int type = get_type ();
27
0
    if (unlikely (type == SubTable::Extension))
28
0
      return get_subtable (0).u.extension.is_reverse ();
29
0
    return lookup_type_is_reverse (type);
30
0
  }
31
32
  bool may_have_non_1to1 () const
33
0
  {
34
0
    hb_have_non_1to1_context_t c;
35
0
    return dispatch (&c);
36
0
  }
37
38
  bool apply (hb_ot_apply_context_t *c) const
39
0
  {
40
0
    TRACE_APPLY (this);
41
0
    return_trace (dispatch (c));
42
0
  }
43
44
  bool intersects (const hb_set_t *glyphs) const
45
0
  {
46
0
    hb_intersects_context_t c (glyphs);
47
0
    return dispatch (&c);
48
0
  }
49
50
  hb_closure_context_t::return_t closure (hb_closure_context_t *c, unsigned int this_index) const
51
0
  {
52
0
    if (!c->should_visit_lookup (this_index))
53
0
      return hb_closure_context_t::default_return_value ();
54
55
0
    c->set_recurse_func (dispatch_closure_recurse_func);
56
57
0
    hb_closure_context_t::return_t ret = dispatch (c);
58
59
0
    c->flush ();
60
61
0
    return ret;
62
0
  }
63
64
  hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
65
0
  {
66
0
    if (c->is_lookup_visited (this_index))
67
0
      return hb_closure_lookups_context_t::default_return_value ();
68
0
69
0
    c->set_lookup_visited (this_index);
70
0
    if (!intersects (c->glyphs))
71
0
    {
72
0
      c->set_lookup_inactive (this_index);
73
0
      return hb_closure_lookups_context_t::default_return_value ();
74
0
    }
75
0
76
0
    hb_closure_lookups_context_t::return_t ret = dispatch (c);
77
0
    return ret;
78
0
  }
79
80
  hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
81
0
  {
82
0
    c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
83
0
    return dispatch (c);
84
0
  }
85
86
  template <typename set_t>
87
  void collect_coverage (set_t *glyphs) const
88
  {
89
    hb_collect_coverage_context_t<set_t> c (glyphs);
90
    dispatch (&c);
91
  }
92
93
  bool would_apply (hb_would_apply_context_t *c,
94
                    const hb_ot_layout_lookup_accelerator_t *accel) const
95
0
  {
96
0
    if (unlikely (!c->len)) return false;
97
0
    if (!accel->may_have (c->glyphs[0])) return false;
98
0
      return dispatch (c);
99
0
  }
100
101
  template<typename Glyphs, typename Substitutes,
102
     hb_requires (hb_is_sorted_source_of (Glyphs,
103
            const hb_codepoint_t) &&
104
      hb_is_source_of (Substitutes,
105
           const hb_codepoint_t))>
106
  bool serialize_single (hb_serialize_context_t *c,
107
                         uint32_t lookup_props,
108
                         Glyphs glyphs,
109
                         Substitutes substitutes)
110
0
  {
111
0
    TRACE_SERIALIZE (this);
112
0
    if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
113
0
    if (c->push<SubTable> ()->u.single.serialize (c, hb_zip (glyphs, substitutes)))
114
0
    {
115
0
      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
116
0
      return_trace (true);
117
0
    }
118
0
    c->pop_discard ();
119
0
    return_trace (false);
120
0
  }
121
122
  template<typename Iterator,
123
           hb_requires (hb_is_sorted_iterator (Iterator))>
124
  bool serialize (hb_serialize_context_t *c,
125
      uint32_t lookup_props,
126
      Iterator it)
127
  {
128
    TRACE_SERIALIZE (this);
129
    if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false);
130
    if (c->push<SubTable> ()->u.multiple.
131
        serialize (c, it))
132
    {
133
      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
134
      return_trace (true);
135
    }
136
    c->pop_discard ();
137
    return_trace (false);
138
  }
139
140
  bool serialize_alternate (hb_serialize_context_t *c,
141
                            uint32_t lookup_props,
142
                            hb_sorted_array_t<const HBGlyphID16> glyphs,
143
                            hb_array_t<const unsigned int> alternate_len_list,
144
                            hb_array_t<const HBGlyphID16> alternate_glyphs_list)
145
0
  {
146
0
    TRACE_SERIALIZE (this);
147
0
    if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false);
148
0
149
0
    if (c->push<SubTable> ()->u.alternate.
150
0
        serialize (c,
151
0
                   glyphs,
152
0
                   alternate_len_list,
153
0
                   alternate_glyphs_list))
154
0
    {
155
0
      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
156
0
      return_trace (true);
157
0
    }
158
0
    c->pop_discard ();
159
0
    return_trace (false);
160
0
  }
161
162
  bool serialize_ligature (hb_serialize_context_t *c,
163
                           uint32_t lookup_props,
164
                           hb_sorted_array_t<const HBGlyphID16> first_glyphs,
165
                           hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
166
                           hb_array_t<const HBGlyphID16> ligatures_list,
167
                           hb_array_t<const unsigned int> component_count_list,
168
                           hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
169
0
  {
170
0
    TRACE_SERIALIZE (this);
171
0
    if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
172
0
    if (c->push<SubTable> ()->u.ligature.
173
0
        serialize (c,
174
0
                   first_glyphs,
175
0
                   ligature_per_first_glyph_count_list,
176
0
                   ligatures_list,
177
0
                   component_count_list,
178
0
                   component_list))
179
0
    {
180
0
      c->add_link (get_subtables<SubTable> ()[0], c->pop_pack ());
181
0
      return_trace (true);
182
0
    }
183
0
    c->pop_discard ();
184
0
    return_trace (false);
185
0
  }
186
187
  template <typename context_t>
188
  static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
189
190
  static inline typename hb_closure_context_t::return_t closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index);
191
192
  static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *covered_seq_indices, unsigned seq_index, unsigned end_index)
193
0
  {
194
0
    if (!c->should_visit_lookup (lookup_index))
195
0
      return hb_empty_t ();
196
197
0
    hb_closure_context_t::return_t ret = closure_glyphs_recurse_func (c, lookup_index, covered_seq_indices, seq_index, end_index);
198
199
    /* While in theory we should flush here, it will cause timeouts because a recursive
200
     * lookup can keep growing the glyph set.  Skip, and outer loop will retry up to
201
     * HB_CLOSURE_MAX_STAGES time, which should be enough for every realistic font. */
202
    //c->flush ();
203
204
0
    return ret;
205
0
  }
206
207
  template <typename context_t, typename ...Ts>
208
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
209
2
  { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
Unexecuted instantiation: OT::hb_have_non_1to1_context_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<OT::hb_have_non_1to1_context_t>(OT::hb_have_non_1to1_context_t*) const
Unexecuted instantiation: OT::hb_ot_apply_context_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<OT::hb_ot_apply_context_t>(OT::hb_ot_apply_context_t*) const
Unexecuted instantiation: OT::hb_intersects_context_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<OT::hb_intersects_context_t>(OT::hb_intersects_context_t*) const
Unexecuted instantiation: OT::hb_closure_context_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<OT::hb_closure_context_t>(OT::hb_closure_context_t*) const
Unexecuted instantiation: OT::hb_closure_lookups_context_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<OT::hb_closure_lookups_context_t>(OT::hb_closure_lookups_context_t*) const
Unexecuted instantiation: OT::hb_collect_glyphs_context_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<OT::hb_collect_glyphs_context_t>(OT::hb_collect_glyphs_context_t*) const
Unexecuted instantiation: OT::hb_would_apply_context_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<OT::hb_would_apply_context_t>(OT::hb_would_apply_context_t*) const
OT::hb_accelerate_subtables_context_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<OT::hb_accelerate_subtables_context_t>(OT::hb_accelerate_subtables_context_t*) const
Line
Count
Source
209
2
  { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
Unexecuted instantiation: hb_get_glyph_alternates_dispatch_t::return_t OT::Layout::GSUB_impl::SubstLookup::dispatch<hb_get_glyph_alternates_dispatch_t, unsigned int&, unsigned int&, unsigned int*&, unsigned int*&>(hb_get_glyph_alternates_dispatch_t*, unsigned int&, unsigned int&, unsigned int*&, unsigned int*&) const
210
211
  bool subset (hb_subset_context_t *c) const
212
0
  { return Lookup::subset<SubTable> (c); }
213
};
214
215
216
}
217
}
218
}
219
220
#endif  /* OT_LAYOUT_GSUB_SUBSTLOOKUP_HH */