/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 */ |