Coverage Report

Created: 2023-05-18 19:03

/src/harfbuzz/src/hb-ot-layout-common.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2007,2008,2009  Red Hat, Inc.
3
 * Copyright © 2010,2012  Google, Inc.
4
 *
5
 *  This is part of HarfBuzz, a text shaping library.
6
 *
7
 * Permission is hereby granted, without written agreement and without
8
 * license or royalty fees, to use, copy, modify, and distribute this
9
 * software and its documentation for any purpose, provided that the
10
 * above copyright notice and the following two paragraphs appear in
11
 * all copies of this software.
12
 *
13
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17
 * DAMAGE.
18
 *
19
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24
 *
25
 * Red Hat Author(s): Behdad Esfahbod
26
 * Google Author(s): Behdad Esfahbod
27
 */
28
29
#ifndef HB_OT_LAYOUT_COMMON_HH
30
#define HB_OT_LAYOUT_COMMON_HH
31
32
#include "hb.hh"
33
#include "hb-ot-layout.hh"
34
#include "hb-open-type.hh"
35
#include "hb-set.hh"
36
#include "hb-bimap.hh"
37
38
#include "OT/Layout/Common/Coverage.hh"
39
#include "OT/Layout/types.hh"
40
41
// TODO(garretrieger): cleanup these after migration.
42
using OT::Layout::Common::Coverage;
43
using OT::Layout::Common::RangeRecord;
44
using OT::Layout::SmallTypes;
45
using OT::Layout::MediumTypes;
46
47
48
namespace OT {
49
50
template<typename Iterator>
51
static inline bool ClassDef_serialize (hb_serialize_context_t *c,
52
               Iterator it);
53
54
static bool ClassDef_remap_and_serialize (
55
    hb_serialize_context_t *c,
56
    const hb_set_t &klasses,
57
    bool use_class_zero,
58
    hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
59
    hb_map_t *klass_map /*IN/OUT*/);
60
61
struct hb_collect_feature_substitutes_with_var_context_t
62
{
63
  const hb_map_t *axes_index_tag_map;
64
  const hb_hashmap_t<hb_tag_t, int> *axes_location;
65
  hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *record_cond_idx_map;
66
  hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
67
68
  // not stored in subset_plan
69
  hb_set_t *feature_indices;
70
  bool apply;
71
  unsigned cur_record_idx;
72
  hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> *conditionset_map;
73
};
74
75
struct hb_prune_langsys_context_t
76
{
77
  hb_prune_langsys_context_t (const void         *table_,
78
                              hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map_,
79
                              const hb_map_t     *duplicate_feature_map_,
80
                              hb_set_t           *new_collected_feature_indexes_)
81
      :table (table_),
82
      script_langsys_map (script_langsys_map_),
83
      duplicate_feature_map (duplicate_feature_map_),
84
      new_feature_indexes (new_collected_feature_indexes_),
85
0
      script_count (0),langsys_feature_count (0) {}
86
87
  bool visitScript ()
88
0
  { return script_count++ < HB_MAX_SCRIPTS; }
89
90
  bool visitLangsys (unsigned feature_count)
91
0
  {
92
0
    langsys_feature_count += feature_count;
93
0
    return langsys_feature_count < HB_MAX_LANGSYS_FEATURE_COUNT;
94
0
  }
95
96
  public:
97
  const void *table;
98
  hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
99
  const hb_map_t     *duplicate_feature_map;
100
  hb_set_t           *new_feature_indexes;
101
102
  private:
103
  unsigned script_count;
104
  unsigned langsys_feature_count;
105
};
106
107
struct hb_subset_layout_context_t :
108
  hb_dispatch_context_t<hb_subset_layout_context_t, hb_empty_t, HB_DEBUG_SUBSET>
109
{
110
0
  const char *get_name () { return "SUBSET_LAYOUT"; }
111
0
  static return_t default_return_value () { return hb_empty_t (); }
112
113
  bool visitScript ()
114
0
  {
115
0
    return script_count++ < HB_MAX_SCRIPTS;
116
0
  }
117
118
  bool visitLangSys ()
119
0
  {
120
0
    return langsys_count++ < HB_MAX_LANGSYS;
121
0
  }
122
123
  bool visitFeatureIndex (int count)
124
0
  {
125
0
    feature_index_count += count;
126
0
    return feature_index_count < HB_MAX_FEATURE_INDICES;
127
0
  }
128
129
  bool visitLookupIndex()
130
0
  {
131
0
    lookup_index_count++;
132
0
    return lookup_index_count < HB_MAX_LOOKUP_VISIT_COUNT;
133
0
  }
134
135
  hb_subset_context_t *subset_context;
136
  const hb_tag_t table_tag;
137
  const hb_map_t *lookup_index_map;
138
  const hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
139
  const hb_map_t *feature_index_map;
140
  const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
141
  hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map;
142
143
  unsigned cur_script_index;
144
  unsigned cur_feature_var_record_idx;
145
146
  hb_subset_layout_context_t (hb_subset_context_t *c_,
147
            hb_tag_t tag_) :
148
        subset_context (c_),
149
        table_tag (tag_),
150
        cur_script_index (0xFFFFu),
151
        cur_feature_var_record_idx (0u),
152
        script_count (0),
153
        langsys_count (0),
154
        feature_index_count (0),
155
        lookup_index_count (0)
156
0
  {
157
0
    if (tag_ == HB_OT_TAG_GSUB)
158
0
    {
159
0
      lookup_index_map = &c_->plan->gsub_lookups;
160
0
      script_langsys_map = &c_->plan->gsub_langsys;
161
0
      feature_index_map = &c_->plan->gsub_features;
162
0
      feature_substitutes_map = &c_->plan->gsub_feature_substitutes_map;
163
0
      feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gsub_feature_record_cond_idx_map;
164
0
    }
165
0
    else
166
0
    {
167
0
      lookup_index_map = &c_->plan->gpos_lookups;
168
0
      script_langsys_map = &c_->plan->gpos_langsys;
169
0
      feature_index_map = &c_->plan->gpos_features;
170
0
      feature_substitutes_map = &c_->plan->gpos_feature_substitutes_map;
171
0
      feature_record_cond_idx_map = c_->plan->user_axes_location.is_empty () ? nullptr : &c_->plan->gpos_feature_record_cond_idx_map;
172
0
    }
173
0
  }
174
175
  private:
176
  unsigned script_count;
177
  unsigned langsys_count;
178
  unsigned feature_index_count;
179
  unsigned lookup_index_count;
180
};
181
182
struct VariationStore;
183
struct hb_collect_variation_indices_context_t :
184
       hb_dispatch_context_t<hb_collect_variation_indices_context_t>
185
{
186
  template <typename T>
187
0
  return_t dispatch (const T &obj) { obj.collect_variation_indices (this); return hb_empty_t (); }
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::SinglePosFormat1>(OT::Layout::GPOS_impl::SinglePosFormat1 const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::SinglePosFormat2>(OT::Layout::GPOS_impl::SinglePosFormat2 const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::PairPosFormat1_3<OT::Layout::SmallTypes> >(OT::Layout::GPOS_impl::PairPosFormat1_3<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::PairPosFormat2_4<OT::Layout::SmallTypes> >(OT::Layout::GPOS_impl::PairPosFormat2_4<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::PairPosFormat1_3<OT::Layout::MediumTypes> >(OT::Layout::GPOS_impl::PairPosFormat1_3<OT::Layout::MediumTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::PairPosFormat2_4<OT::Layout::MediumTypes> >(OT::Layout::GPOS_impl::PairPosFormat2_4<OT::Layout::MediumTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::CursivePosFormat1>(OT::Layout::GPOS_impl::CursivePosFormat1 const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::MarkBasePosFormat1_2<OT::Layout::SmallTypes> >(OT::Layout::GPOS_impl::MarkBasePosFormat1_2<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::MarkBasePosFormat1_2<OT::Layout::MediumTypes> >(OT::Layout::GPOS_impl::MarkBasePosFormat1_2<OT::Layout::MediumTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::MarkLigPosFormat1_2<OT::Layout::SmallTypes> >(OT::Layout::GPOS_impl::MarkLigPosFormat1_2<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::MarkLigPosFormat1_2<OT::Layout::MediumTypes> >(OT::Layout::GPOS_impl::MarkLigPosFormat1_2<OT::Layout::MediumTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes> >(OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes> >(OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ContextFormat1_4<OT::Layout::SmallTypes> >(OT::ContextFormat1_4<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ContextFormat2_5<OT::Layout::SmallTypes> >(OT::ContextFormat2_5<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ContextFormat3>(OT::ContextFormat3 const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ContextFormat1_4<OT::Layout::MediumTypes> >(OT::ContextFormat1_4<OT::Layout::MediumTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ContextFormat2_5<OT::Layout::MediumTypes> >(OT::ContextFormat2_5<OT::Layout::MediumTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ChainContextFormat1_4<OT::Layout::SmallTypes> >(OT::ChainContextFormat1_4<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ChainContextFormat2_5<OT::Layout::SmallTypes> >(OT::ChainContextFormat2_5<OT::Layout::SmallTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ChainContextFormat3>(OT::ChainContextFormat3 const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ChainContextFormat1_4<OT::Layout::MediumTypes> >(OT::ChainContextFormat1_4<OT::Layout::MediumTypes> const&)
Unexecuted instantiation: hb_empty_t OT::hb_collect_variation_indices_context_t::dispatch<OT::ChainContextFormat2_5<OT::Layout::MediumTypes> >(OT::ChainContextFormat2_5<OT::Layout::MediumTypes> const&)
188
0
  static return_t default_return_value () { return hb_empty_t (); }
189
190
  hb_set_t *layout_variation_indices;
191
  hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map;
192
  hb_font_t *font;
193
  const VariationStore *var_store;
194
  const hb_set_t *glyph_set;
195
  const hb_map_t *gpos_lookups;
196
  float *store_cache;
197
198
  hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_,
199
            hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map_,
200
            hb_font_t *font_,
201
            const VariationStore *var_store_,
202
            const hb_set_t *glyph_set_,
203
            const hb_map_t *gpos_lookups_,
204
            float *store_cache_) :
205
          layout_variation_indices (layout_variation_indices_),
206
          varidx_delta_map (varidx_delta_map_),
207
          font (font_),
208
          var_store (var_store_),
209
          glyph_set (glyph_set_),
210
          gpos_lookups (gpos_lookups_),
211
0
          store_cache (store_cache_) {}
212
};
213
214
template<typename OutputArray>
215
struct subset_offset_array_t
216
{
217
  subset_offset_array_t (hb_subset_context_t *subset_context_,
218
       OutputArray& out_,
219
       const void *base_) : subset_context (subset_context_),
220
                out (out_), base (base_) {}
221
222
  template <typename T>
223
  bool operator () (T&& offset)
224
0
  {
225
0
    auto snap = subset_context->serializer->snapshot ();
226
0
    auto *o = out.serialize_append (subset_context->serializer);
227
0
    if (unlikely (!o)) return false;
228
0
    bool ret = o->serialize_subset (subset_context, offset, base);
229
0
    if (!ret)
230
0
    {
231
0
      out.pop ();
232
0
      subset_context->serializer->revert (snap);
233
0
    }
234
0
    return ret;
235
0
  }
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true> const&>(OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > >::operator()<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u>, true> const&>(OT::OffsetTo<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> > >::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> > >::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u>, true> const&)
236
237
  private:
238
  hb_subset_context_t *subset_context;
239
  OutputArray &out;
240
  const void *base;
241
};
242
243
244
template<typename OutputArray, typename Arg>
245
struct subset_offset_array_arg_t
246
{
247
  subset_offset_array_arg_t (hb_subset_context_t *subset_context_,
248
           OutputArray& out_,
249
           const void *base_,
250
           Arg &&arg_) : subset_context (subset_context_), out (out_),
251
            base (base_), arg (arg_) {}
252
253
  template <typename T>
254
  bool operator () (T&& offset)
255
0
  {
256
0
    auto snap = subset_context->serializer->snapshot ();
257
0
    auto *o = out.serialize_append (subset_context->serializer);
258
0
    if (unlikely (!o)) return false;
259
0
    bool ret = o->serialize_subset (subset_context, offset, base, arg);
260
0
    if (!ret)
261
0
    {
262
0
      out.pop ();
263
0
      subset_context->serializer->revert (snap);
264
0
    }
265
0
    return ret;
266
0
  }
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>::operator()<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>::operator()<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>::operator()<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&>(OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>::operator()<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>::operator()<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&>(OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true> const&)
Unexecuted instantiation: bool OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>::operator()<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true> const&>(OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true> const&)
267
268
  private:
269
  hb_subset_context_t *subset_context;
270
  OutputArray &out;
271
  const void *base;
272
  Arg &&arg;
273
};
274
275
/*
276
 * Helper to subset an array of offsets. Subsets the thing pointed to by each offset
277
 * and discards the offset in the array if the subset operation results in an empty
278
 * thing.
279
 */
280
struct
281
{
282
  template<typename OutputArray>
283
  subset_offset_array_t<OutputArray>
284
  operator () (hb_subset_context_t *subset_context, OutputArray& out,
285
         const void *base) const
286
0
  { return subset_offset_array_t<OutputArray> (subset_context, out, base); }
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> >&, void const*) const
Unexecuted instantiation: hb-common.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-font.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-color.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> >&, void const*) const
Unexecuted instantiation: hb-ot-font.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> >&, void const*) const
Unexecuted instantiation: hb-ot-math.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-metrics.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-var.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-cff1-table.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-cff2-table.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::AlternateSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> >&, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Condition, OT::IntType<unsigned int, 4u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::AttachPoint, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::CaretValue, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_t<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::LigGlyph, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_t<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > > OT::$_39::operator()<OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> > >(hb_subset_context_t*, OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> >&, void const*) const
287
288
  /* Variant with one extra argument passed to serialize_subset */
289
  template<typename OutputArray, typename Arg>
290
  subset_offset_array_arg_t<OutputArray, Arg>
291
  operator () (hb_subset_context_t *subset_context, OutputArray& out,
292
         const void *base, Arg &&arg) const
293
0
  { return subset_offset_array_arg_t<OutputArray, Arg> (subset_context, out, base, arg); }
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::LigatureSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::Ligature<OT::Layout::MediumTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, unsigned int&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, unsigned int&) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::RuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::SmallTypes>, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_offset_array_arg_t<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&> OT::$_39::operator()<OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >, hb_map_t const*&>(hb_subset_context_t*, OT::ArrayOf<OT::OffsetTo<OT::ChainRuleSet<OT::Layout::MediumTypes>, OT::IntType<unsigned int, 3u>, true>, OT::IntType<unsigned short, 2u> >&, void const*, hb_map_t const*&) const
294
}
295
HB_FUNCOBJ (subset_offset_array);
296
297
template<typename OutputArray>
298
struct subset_record_array_t
299
{
300
  subset_record_array_t (hb_subset_layout_context_t *c_, OutputArray* out_,
301
       const void *base_) : subset_layout_context (c_),
302
                out (out_), base (base_) {}
303
304
  template <typename T>
305
  void
306
  operator () (T&& record)
307
0
  {
308
0
    auto snap = subset_layout_context->subset_context->serializer->snapshot ();
309
0
    bool ret = record.subset (subset_layout_context, base);
310
0
    if (!ret) subset_layout_context->subset_context->serializer->revert (snap);
311
0
    else out->len++;
312
0
  }
Unexecuted instantiation: void OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> >::operator()<OT::Record<OT::LangSys> const&>(OT::Record<OT::LangSys> const&)
Unexecuted instantiation: void OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >::operator()<OT::FeatureTableSubstitutionRecord const&>(OT::FeatureTableSubstitutionRecord const&)
Unexecuted instantiation: void OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >::operator()<OT::FeatureVariationRecord const&>(OT::FeatureVariationRecord const&)
313
314
  private:
315
  hb_subset_layout_context_t *subset_layout_context;
316
  OutputArray *out;
317
  const void *base;
318
};
319
320
template<typename OutputArray, typename Arg>
321
struct subset_record_array_arg_t
322
{
323
  subset_record_array_arg_t (hb_subset_layout_context_t *c_, OutputArray* out_,
324
           const void *base_,
325
           Arg &&arg_) : subset_layout_context (c_),
326
             out (out_), base (base_), arg (arg_) {}
327
328
  template <typename T>
329
  void
330
  operator () (T&& record)
331
0
  {
332
0
    auto snap = subset_layout_context->subset_context->serializer->snapshot ();
333
0
    bool ret = record.subset (subset_layout_context, base, arg);
334
0
    if (!ret) subset_layout_context->subset_context->serializer->revert (snap);
335
0
    else out->len++;
336
0
  }
337
338
  private:
339
  hb_subset_layout_context_t *subset_layout_context;
340
  OutputArray *out;
341
  const void *base;
342
  Arg &&arg;
343
};
344
345
/*
346
 * Helper to subset a RecordList/record array. Subsets each Record in the array and
347
 * discards the record if the subset operation returns false.
348
 */
349
struct
350
{
351
  template<typename OutputArray>
352
  subset_record_array_t<OutputArray>
353
  operator () (hb_subset_layout_context_t *c, OutputArray* out,
354
         const void *base) const
355
0
  { return subset_record_array_t<OutputArray> (c, out, base); }
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_37::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-common.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_37::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-common.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-common.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-face.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_38::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-face.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-face.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-font.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_38::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-font.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-font.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-color.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_37::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-color.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-color.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_37::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-font.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_37::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-font.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-font.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_37::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-math.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_38::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-math.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-math.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-metrics.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_38::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-metrics.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-metrics.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-var.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_38::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-var.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-var.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-cff1-table.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_38::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-cff1-table.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-cff1-table.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-cff2-table.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_38::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-cff2-table.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-cff2-table.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_38::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_38::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_record_array_t<OT::RecordArrayOf<OT::LangSys> > OT::$_37::operator()<OT::RecordArrayOf<OT::LangSys> >(OT::hb_subset_layout_context_t*, OT::RecordArrayOf<OT::LangSys>*, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureTableSubstitutionRecord, OT::IntType<unsigned short, 2u> >*, void const*) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_record_array_t<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > > OT::$_37::operator()<OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> > >(OT::hb_subset_layout_context_t*, OT::ArrayOf<OT::FeatureVariationRecord, OT::IntType<unsigned int, 4u> >*, void const*) const
356
357
  /* Variant with one extra argument passed to subset */
358
  template<typename OutputArray, typename Arg>
359
  subset_record_array_arg_t<OutputArray, Arg>
360
  operator () (hb_subset_layout_context_t *c, OutputArray* out,
361
               const void *base, Arg &&arg) const
362
0
  { return subset_record_array_arg_t<OutputArray, Arg> (c, out, base, arg); }
Unexecuted instantiation: hb-aat-layout.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_37::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-common.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_37::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-face.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_38::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-font.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_38::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-color.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_37::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-face.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_37::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-font.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_37::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-layout.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_37::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-math.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_38::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-metrics.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_38::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-var.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_38::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-cff1-table.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_38::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-cff2-table.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_38::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_38::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::subset_record_array_arg_t<OT::RecordListOfFeature, OT::Feature const*&> OT::$_37::operator()<OT::RecordListOfFeature, OT::Feature const*&>(OT::hb_subset_layout_context_t*, OT::RecordListOfFeature*, void const*, OT::Feature const*&) const
363
}
364
HB_FUNCOBJ (subset_record_array);
365
366
367
template<typename OutputArray>
368
struct serialize_math_record_array_t
369
{
370
  serialize_math_record_array_t (hb_serialize_context_t *serialize_context_,
371
                         OutputArray& out_,
372
                         const void *base_) : serialize_context (serialize_context_),
373
                                              out (out_), base (base_) {}
374
375
  template <typename T>
376
  bool operator () (T&& record)
377
0
  {
378
0
    if (!serialize_context->copy (record, base)) return false;
379
0
    out.len++;
380
0
    return true;
381
0
  }
Unexecuted instantiation: bool OT::serialize_math_record_array_t<OT::ArrayOf<OT::MathValueRecord, OT::IntType<unsigned short, 2u> > >::operator()<OT::MathValueRecord const&>(OT::MathValueRecord const&)
Unexecuted instantiation: bool OT::serialize_math_record_array_t<OT::ArrayOf<OT::MathKernInfoRecord, OT::IntType<unsigned short, 2u> > >::operator()<OT::MathKernInfoRecord const&>(OT::MathKernInfoRecord const&)
382
383
  private:
384
  hb_serialize_context_t *serialize_context;
385
  OutputArray &out;
386
  const void *base;
387
};
388
389
/*
390
 * Helper to serialize an array of MATH records.
391
 */
392
struct
393
{
394
  template<typename OutputArray>
395
  serialize_math_record_array_t<OutputArray>
396
  operator () (hb_serialize_context_t *serialize_context, OutputArray& out,
397
               const void *base) const
398
0
  { return serialize_math_record_array_t<OutputArray> (serialize_context, out, base); }
Unexecuted instantiation: hb-ot-math.cc:OT::serialize_math_record_array_t<OT::ArrayOf<OT::MathValueRecord, OT::IntType<unsigned short, 2u> > > OT::$_40::operator()<OT::ArrayOf<OT::MathValueRecord, OT::IntType<unsigned short, 2u> > >(hb_serialize_context_t*, OT::ArrayOf<OT::MathValueRecord, OT::IntType<unsigned short, 2u> >&, void const*) const
Unexecuted instantiation: hb-ot-math.cc:OT::serialize_math_record_array_t<OT::ArrayOf<OT::MathKernInfoRecord, OT::IntType<unsigned short, 2u> > > OT::$_40::operator()<OT::ArrayOf<OT::MathKernInfoRecord, OT::IntType<unsigned short, 2u> > >(hb_serialize_context_t*, OT::ArrayOf<OT::MathKernInfoRecord, OT::IntType<unsigned short, 2u> >&, void const*) const
399
400
}
401
HB_FUNCOBJ (serialize_math_record_array);
402
403
/*
404
 *
405
 * OpenType Layout Common Table Formats
406
 *
407
 */
408
409
410
/*
411
 * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
412
 */
413
414
struct IndexArray : Array16Of<Index>
415
{
416
  bool intersects (const hb_map_t *indexes) const
417
0
  { return hb_any (*this, indexes); }
418
419
  template <typename Iterator,
420
      hb_requires (hb_is_iterator (Iterator))>
421
  void serialize (hb_serialize_context_t *c,
422
      hb_subset_layout_context_t *l,
423
      Iterator it)
424
0
  {
425
0
    if (!it) return;
426
0
    if (unlikely (!c->extend_min ((*this)))) return;
427
0
428
0
    for (const auto _ : it)
429
0
    {
430
0
      if (!l->visitLookupIndex()) break;
431
0
432
0
      Index i;
433
0
      i = _;
434
0
      c->copy (i);
435
0
      this->len++;
436
0
    }
437
0
  }
Unexecuted instantiation: hb-aat-layout.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-common.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-face.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-font.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-color.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-face.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-font.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-layout.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-math.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-metrics.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-var.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-cff1-table.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-cff2-table.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_10 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-shaper-arabic.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
Unexecuted instantiation: hb-ot-shape-fallback.cc:void OT::IndexArray::serialize<hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>, (void*)0>(hb_serialize_context_t*, OT::hb_subset_layout_context_t*, hb_map_iter_t<hb_filter_iter_t<hb_array_t<OT::Index const>, hb_map_t const*&, $_11 const&, (void*)0>, hb_map_t const*&, (hb_function_sortedness_t)0, (void*)0>)
438
439
  unsigned int get_indexes (unsigned int start_offset,
440
          unsigned int *_count /* IN/OUT */,
441
          unsigned int *_indexes /* OUT */) const
442
139k
  {
443
139k
    if (_count)
444
139k
    {
445
139k
      + this->as_array ().sub_array (start_offset, _count)
446
139k
      | hb_sink (hb_array (_indexes, *_count))
447
139k
      ;
448
139k
    }
449
139k
    return this->len;
450
139k
  }
451
452
  void add_indexes_to (hb_set_t* output /* OUT */) const
453
0
  {
454
0
    output->add_array (as_array ());
455
0
  }
456
};
457
458
459
/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
460
struct FeatureParamsSize
461
{
462
  bool sanitize (hb_sanitize_context_t *c) const
463
340
  {
464
340
    TRACE_SANITIZE (this);
465
340
    if (unlikely (!c->check_struct (this))) return_trace (false);
466
467
    /* This subtable has some "history", if you will.  Some earlier versions of
468
     * Adobe tools calculated the offset of the FeatureParams subtable from the
469
     * beginning of the FeatureList table!  Now, that is dealt with in the
470
     * Feature implementation.  But we still need to be able to tell junk from
471
     * real data.  Note: We don't check that the nameID actually exists.
472
     *
473
     * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk :
474
     *
475
     * Yes, it is correct that a new version of the AFDKO (version 2.0) will be
476
     * coming out soon, and that the makeotf program will build a font with a
477
     * 'size' feature that is correct by the specification.
478
     *
479
     * The specification for this feature tag is in the "OpenType Layout Tag
480
     * Registry". You can see a copy of this at:
481
     * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size
482
     *
483
     * Here is one set of rules to determine if the 'size' feature is built
484
     * correctly, or as by the older versions of MakeOTF. You may be able to do
485
     * better.
486
     *
487
     * Assume that the offset to the size feature is according to specification,
488
     * and make the following value checks. If it fails, assume the size
489
     * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it.
490
     * If this fails, reject the 'size' feature. The older makeOTF's calculated the
491
     * offset from the beginning of the FeatureList table, rather than from the
492
     * beginning of the 'size' Feature table.
493
     *
494
     * If "design size" == 0:
495
     *     fails check
496
     *
497
     * Else if ("subfamily identifier" == 0 and
498
     *     "range start" == 0 and
499
     *     "range end" == 0 and
500
     *     "range start" == 0 and
501
     *     "menu name ID" == 0)
502
     *     passes check: this is the format used when there is a design size
503
     * specified, but there is no recommended size range.
504
     *
505
     * Else if ("design size" <  "range start" or
506
     *     "design size" >   "range end" or
507
     *     "range end" <= "range start" or
508
     *     "menu name ID"  < 256 or
509
     *     "menu name ID"  > 32767 or
510
     *     menu name ID is not a name ID which is actually in the name table)
511
     *     fails test
512
     * Else
513
     *     passes test.
514
     */
515
516
340
    if (!designSize)
517
0
      return_trace (false);
518
340
    else if (subfamilyID == 0 &&
519
340
       subfamilyNameID == 0 &&
520
340
       rangeStart == 0 &&
521
340
       rangeEnd == 0)
522
340
      return_trace (true);
523
0
    else if (designSize < rangeStart ||
524
0
       designSize > rangeEnd ||
525
0
       subfamilyNameID < 256 ||
526
0
       subfamilyNameID > 32767)
527
0
      return_trace (false);
528
0
    else
529
0
      return_trace (true);
530
340
  }
531
532
  bool subset (hb_subset_context_t *c) const
533
0
  {
534
0
    TRACE_SUBSET (this);
535
0
    return_trace ((bool) c->serializer->embed (*this));
536
0
  }
537
538
  HBUINT16  designSize; /* Represents the design size in 720/inch
539
         * units (decipoints).  The design size entry
540
         * must be non-zero.  When there is a design
541
         * size but no recommended size range, the
542
         * rest of the array will consist of zeros. */
543
  HBUINT16  subfamilyID;  /* Has no independent meaning, but serves
544
         * as an identifier that associates fonts
545
         * in a subfamily. All fonts which share a
546
         * Preferred or Font Family name and which
547
         * differ only by size range shall have the
548
         * same subfamily value, and no fonts which
549
         * differ in weight or style shall have the
550
         * same subfamily value. If this value is
551
         * zero, the remaining fields in the array
552
         * will be ignored. */
553
  NameID  subfamilyNameID;/* If the preceding value is non-zero, this
554
         * value must be set in the range 256 - 32767
555
         * (inclusive). It records the value of a
556
         * field in the name table, which must
557
         * contain English-language strings encoded
558
         * in Windows Unicode and Macintosh Roman,
559
         * and may contain additional strings
560
         * localized to other scripts and languages.
561
         * Each of these strings is the name an
562
         * application should use, in combination
563
         * with the family name, to represent the
564
         * subfamily in a menu.  Applications will
565
         * choose the appropriate version based on
566
         * their selection criteria. */
567
  HBUINT16  rangeStart; /* Large end of the recommended usage range
568
         * (inclusive), stored in 720/inch units
569
         * (decipoints). */
570
  HBUINT16  rangeEnd; /* Small end of the recommended usage range
571
           (exclusive), stored in 720/inch units
572
         * (decipoints). */
573
  public:
574
  DEFINE_SIZE_STATIC (10);
575
};
576
577
/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#ssxx */
578
struct FeatureParamsStylisticSet
579
{
580
  bool sanitize (hb_sanitize_context_t *c) const
581
3.68k
  {
582
3.68k
    TRACE_SANITIZE (this);
583
    /* Right now minorVersion is at zero.  Which means, any table supports
584
     * the uiNameID field. */
585
3.68k
    return_trace (c->check_struct (this));
586
3.68k
  }
587
588
  bool subset (hb_subset_context_t *c) const
589
0
  {
590
0
    TRACE_SUBSET (this);
591
0
    return_trace ((bool) c->serializer->embed (*this));
592
0
  }
593
594
  HBUINT16  version;  /* (set to 0): This corresponds to a “minor”
595
         * version number. Additional data may be
596
         * added to the end of this Feature Parameters
597
         * table in the future. */
598
599
  NameID  uiNameID; /* The 'name' table name ID that specifies a
600
         * string (or strings, for multiple languages)
601
         * for a user-interface label for this
602
         * feature.  The values of uiLabelNameId and
603
         * sampleTextNameId are expected to be in the
604
         * font-specific name ID range (256-32767),
605
         * though that is not a requirement in this
606
         * Feature Parameters specification. The
607
         * user-interface label for the feature can
608
         * be provided in multiple languages. An
609
         * English string should be included as a
610
         * fallback. The string should be kept to a
611
         * minimal length to fit comfortably with
612
         * different application interfaces. */
613
  public:
614
  DEFINE_SIZE_STATIC (4);
615
};
616
617
/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99 */
618
struct FeatureParamsCharacterVariants
619
{
620
  unsigned
621
  get_characters (unsigned start_offset, unsigned *char_count, hb_codepoint_t *chars) const
622
19.7k
  {
623
19.7k
    if (char_count)
624
19.7k
    {
625
19.7k
      + characters.as_array ().sub_array (start_offset, char_count)
626
19.7k
      | hb_sink (hb_array (chars, *char_count))
627
19.7k
      ;
628
19.7k
    }
629
19.7k
    return characters.len;
630
19.7k
  }
631
632
  unsigned get_size () const
633
0
  { return min_size + characters.len * HBUINT24::static_size; }
634
635
  bool subset (hb_subset_context_t *c) const
636
0
  {
637
0
    TRACE_SUBSET (this);
638
0
    return_trace ((bool) c->serializer->embed (*this));
639
0
  }
640
641
  bool sanitize (hb_sanitize_context_t *c) const
642
14.7k
  {
643
14.7k
    TRACE_SANITIZE (this);
644
14.7k
    return_trace (c->check_struct (this) &&
645
14.7k
      characters.sanitize (c));
646
14.7k
  }
647
648
  HBUINT16  format;     /* Format number is set to 0. */
649
  NameID  featUILableNameID;  /* The ‘name’ table name ID that
650
           * specifies a string (or strings,
651
           * for multiple languages) for a
652
           * user-interface label for this
653
           * feature. (May be NULL.) */
654
  NameID  featUITooltipTextNameID;/* The ‘name’ table name ID that
655
           * specifies a string (or strings,
656
           * for multiple languages) that an
657
           * application can use for tooltip
658
           * text for this feature. (May be
659
           * nullptr.) */
660
  NameID  sampleTextNameID; /* The ‘name’ table name ID that
661
           * specifies sample text that
662
           * illustrates the effect of this
663
           * feature. (May be NULL.) */
664
  HBUINT16  numNamedParameters; /* Number of named parameters. (May
665
           * be zero.) */
666
  NameID  firstParamUILabelNameID;/* The first ‘name’ table name ID
667
           * used to specify strings for
668
           * user-interface labels for the
669
           * feature parameters. (Must be zero
670
           * if numParameters is zero.) */
671
  Array16Of<HBUINT24>
672
    characters;   /* Array of the Unicode Scalar Value
673
           * of the characters for which this
674
           * feature provides glyph variants.
675
           * (May be zero.) */
676
  public:
677
  DEFINE_SIZE_ARRAY (14, characters);
678
};
679
680
struct FeatureParams
681
{
682
  bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const
683
215k
  {
684
#ifdef HB_NO_LAYOUT_FEATURE_PARAMS
685
    return true;
686
#endif
687
215k
    TRACE_SANITIZE (this);
688
215k
    if (tag == HB_TAG ('s','i','z','e'))
689
340
      return_trace (u.size.sanitize (c));
690
215k
    if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
691
3.68k
      return_trace (u.stylisticSet.sanitize (c));
692
211k
    if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
693
14.7k
      return_trace (u.characterVariants.sanitize (c));
694
211k
    return_trace (true);
695
211k
  }
696
697
  bool subset (hb_subset_context_t *c, const Tag* tag) const
698
0
  {
699
0
    TRACE_SUBSET (this);
700
0
    if (!tag) return_trace (false);
701
0
    if (*tag == HB_TAG ('s','i','z','e'))
702
0
      return_trace (u.size.subset (c));
703
0
    if ((*tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
704
0
      return_trace (u.stylisticSet.subset (c));
705
0
    if ((*tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
706
0
      return_trace (u.characterVariants.subset (c));
707
0
    return_trace (false);
708
0
  }
709
710
#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
711
  const FeatureParamsSize& get_size_params (hb_tag_t tag) const
712
60
  {
713
60
    if (tag == HB_TAG ('s','i','z','e'))
714
60
      return u.size;
715
0
    return Null (FeatureParamsSize);
716
60
  }
717
  const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
718
80
  {
719
80
    if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
720
0
      return u.stylisticSet;
721
80
    return Null (FeatureParamsStylisticSet);
722
80
  }
723
  const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
724
19.7k
  {
725
19.7k
    if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
726
160
      return u.characterVariants;
727
19.6k
    return Null (FeatureParamsCharacterVariants);
728
19.7k
  }
729
#endif
730
731
  private:
732
  union {
733
  FeatureParamsSize     size;
734
  FeatureParamsStylisticSet   stylisticSet;
735
  FeatureParamsCharacterVariants  characterVariants;
736
  } u;
737
  public:
738
  DEFINE_SIZE_MIN (0);
739
};
740
741
struct Record_sanitize_closure_t {
742
  hb_tag_t tag;
743
  const void *list_base;
744
};
745
746
struct Feature
747
{
748
  unsigned int get_lookup_count () const
749
0
  { return lookupIndex.len; }
750
  hb_tag_t get_lookup_index (unsigned int i) const
751
0
  { return lookupIndex[i]; }
752
  unsigned int get_lookup_indexes (unsigned int start_index,
753
           unsigned int *lookup_count /* IN/OUT */,
754
           unsigned int *lookup_tags /* OUT */) const
755
119k
  { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
756
  void add_lookup_indexes_to (hb_set_t *lookup_indexes) const
757
0
  { lookupIndex.add_indexes_to (lookup_indexes); }
758
759
  const FeatureParams &get_feature_params () const
760
39.4k
  { return this+featureParams; }
761
762
  bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const
763
0
  { return lookupIndex.intersects (lookup_indexes); }
764
765
  bool subset (hb_subset_context_t         *c,
766
         hb_subset_layout_context_t  *l,
767
         const Tag                   *tag = nullptr) const
768
0
  {
769
0
    TRACE_SUBSET (this);
770
0
    auto *out = c->serializer->start_embed (*this);
771
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
772
0
773
0
    out->featureParams.serialize_subset (c, featureParams, this, tag);
774
0
775
0
    auto it =
776
0
    + hb_iter (lookupIndex)
777
0
    | hb_filter (l->lookup_index_map)
778
0
    | hb_map (l->lookup_index_map)
779
0
    ;
780
0
781
0
    out->lookupIndex.serialize (c->serializer, l, it);
782
0
    // The decision to keep or drop this feature is already made before we get here
783
0
    // so always retain it.
784
0
    return_trace (true);
785
0
  }
786
787
  bool sanitize (hb_sanitize_context_t *c,
788
     const Record_sanitize_closure_t *closure = nullptr) const
789
325k
  {
790
325k
    TRACE_SANITIZE (this);
791
325k
    if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
792
2.76k
      return_trace (false);
793
794
    /* Some earlier versions of Adobe tools calculated the offset of the
795
     * FeatureParams subtable from the beginning of the FeatureList table!
796
     *
797
     * If sanitizing "failed" for the FeatureParams subtable, try it with the
798
     * alternative location.  We would know sanitize "failed" if old value
799
     * of the offset was non-zero, but it's zeroed now.
800
     *
801
     * Only do this for the 'size' feature, since at the time of the faulty
802
     * Adobe tools, only the 'size' feature had FeatureParams defined.
803
     */
804
805
323k
    if (likely (featureParams.is_null ()))
806
107k
      return_trace (true);
807
808
215k
    unsigned int orig_offset = featureParams;
809
215k
    if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
810
40
      return_trace (false);
811
812
215k
    if (featureParams == 0 && closure &&
813
215k
  closure->tag == HB_TAG ('s','i','z','e') &&
814
215k
  closure->list_base && closure->list_base < this)
815
0
    {
816
0
      unsigned int new_offset_int = orig_offset -
817
0
            (((char *) this) - ((char *) closure->list_base));
818
819
0
      Offset16To<FeatureParams> new_offset;
820
      /* Check that it would not overflow. */
821
0
      new_offset = new_offset_int;
822
0
      if (new_offset == new_offset_int &&
823
0
    c->try_set (&featureParams, new_offset_int) &&
824
0
    !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
825
0
  return_trace (false);
826
0
    }
827
828
215k
    return_trace (true);
829
215k
  }
830
831
  Offset16To<FeatureParams>
832
     featureParams; /* Offset to Feature Parameters table (if one
833
         * has been defined for the feature), relative
834
         * to the beginning of the Feature Table; = Null
835
         * if not required */
836
  IndexArray   lookupIndex; /* Array of LookupList indices */
837
  public:
838
  DEFINE_SIZE_ARRAY_SIZED (4, lookupIndex);
839
};
840
841
template <typename Type>
842
struct Record
843
{
844
56.1k
  int cmp (hb_tag_t a) const { return tag.cmp (a); }
OT::Record<OT::LangSys>::cmp(unsigned int) const
Line
Count
Source
844
2.08k
  int cmp (hb_tag_t a) const { return tag.cmp (a); }
OT::Record<OT::Script>::cmp(unsigned int) const
Line
Count
Source
844
54.0k
  int cmp (hb_tag_t a) const { return tag.cmp (a); }
Unexecuted instantiation: OT::Record<OT::Feature>::cmp(unsigned int) const
Unexecuted instantiation: OT::Record<OT::JstfLangSys>::cmp(unsigned int) const
Unexecuted instantiation: OT::Record<OT::JstfScript>::cmp(unsigned int) const
845
846
  bool subset (hb_subset_layout_context_t *c, const void *base, const void *f_sub = nullptr) const
847
0
  {
848
0
    TRACE_SUBSET (this);
849
0
    auto *out = c->subset_context->serializer->embed (this);
850
0
    if (unlikely (!out)) return_trace (false);
851
0
852
0
    if (!f_sub)
853
0
      return_trace (out->offset.serialize_subset (c->subset_context, offset, base, c, &tag));
854
0
855
0
    const Feature& f = *reinterpret_cast<const Feature *> (f_sub);
856
0
    auto *s = c->subset_context->serializer;
857
0
    s->push ();
858
0
859
0
    out->offset = 0;
860
0
    bool ret = f.subset (c->subset_context, c, &tag);
861
0
    if (ret)
862
0
      s->add_link (out->offset, s->pop_pack ());
863
0
    else
864
0
      s->pop_discard ();
865
0
866
0
    return_trace (ret);
867
0
  }
Unexecuted instantiation: OT::Record<OT::Feature>::subset(OT::hb_subset_layout_context_t*, void const*, void const*) const
Unexecuted instantiation: OT::Record<OT::LangSys>::subset(OT::hb_subset_layout_context_t*, void const*, void const*) const
Unexecuted instantiation: OT::Record<OT::Script>::subset(OT::hb_subset_layout_context_t*, void const*, void const*) const
868
869
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
870
49.6M
  {
871
49.6M
    TRACE_SANITIZE (this);
872
49.6M
    const Record_sanitize_closure_t closure = {tag, base};
873
49.6M
    return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
874
49.6M
  }
OT::Record<OT::LangSys>::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
870
47.6M
  {
871
47.6M
    TRACE_SANITIZE (this);
872
47.6M
    const Record_sanitize_closure_t closure = {tag, base};
873
47.6M
    return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
874
47.6M
  }
OT::Record<OT::Script>::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
870
1.41M
  {
871
1.41M
    TRACE_SANITIZE (this);
872
1.41M
    const Record_sanitize_closure_t closure = {tag, base};
873
1.41M
    return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
874
1.41M
  }
OT::Record<OT::Feature>::sanitize(hb_sanitize_context_t*, void const*) const
Line
Count
Source
870
599k
  {
871
599k
    TRACE_SANITIZE (this);
872
599k
    const Record_sanitize_closure_t closure = {tag, base};
873
599k
    return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
874
599k
  }
Unexecuted instantiation: OT::Record<OT::JstfLangSys>::sanitize(hb_sanitize_context_t*, void const*) const
Unexecuted instantiation: OT::Record<OT::JstfScript>::sanitize(hb_sanitize_context_t*, void const*) const
875
876
  Tag           tag;            /* 4-byte Tag identifier */
877
  Offset16To<Type>
878
                offset;         /* Offset from beginning of object holding
879
                                 * the Record */
880
  public:
881
  DEFINE_SIZE_STATIC (6);
882
};
883
884
template <typename Type>
885
struct RecordArrayOf : SortedArray16Of<Record<Type>>
886
{
887
  const Offset16To<Type>& get_offset (unsigned int i) const
888
1.58M
  { return (*this)[i].offset; }
OT::RecordArrayOf<OT::Script>::get_offset(unsigned int) const
Line
Count
Source
888
1.43M
  { return (*this)[i].offset; }
OT::RecordArrayOf<OT::Feature>::get_offset(unsigned int) const
Line
Count
Source
888
158k
  { return (*this)[i].offset; }
889
  Offset16To<Type>& get_offset (unsigned int i)
890
  { return (*this)[i].offset; }
891
  const Tag& get_tag (unsigned int i) const
892
5.23M
  { return (*this)[i].tag; }
Unexecuted instantiation: OT::RecordArrayOf<OT::LangSys>::get_tag(unsigned int) const
Unexecuted instantiation: OT::RecordArrayOf<OT::Script>::get_tag(unsigned int) const
OT::RecordArrayOf<OT::Feature>::get_tag(unsigned int) const
Line
Count
Source
892
5.23M
  { return (*this)[i].tag; }
Unexecuted instantiation: OT::RecordArrayOf<OT::JstfLangSys>::get_tag(unsigned int) const
Unexecuted instantiation: OT::RecordArrayOf<OT::JstfScript>::get_tag(unsigned int) const
893
  unsigned int get_tags (unsigned int start_offset,
894
                         unsigned int *record_count /* IN/OUT */,
895
                         hb_tag_t     *record_tags /* OUT */) const
896
0
  {
897
0
    if (record_count)
898
0
    {
899
0
      + this->as_array ().sub_array (start_offset, record_count)
900
0
      | hb_map (&Record<Type>::tag)
901
0
      | hb_sink (hb_array (record_tags, *record_count))
902
0
      ;
903
0
    }
904
0
    return this->len;
905
0
  }
Unexecuted instantiation: OT::RecordArrayOf<OT::LangSys>::get_tags(unsigned int, unsigned int*, unsigned int*) const
Unexecuted instantiation: OT::RecordArrayOf<OT::Script>::get_tags(unsigned int, unsigned int*, unsigned int*) const
Unexecuted instantiation: OT::RecordArrayOf<OT::Feature>::get_tags(unsigned int, unsigned int*, unsigned int*) const
Unexecuted instantiation: OT::RecordArrayOf<OT::JstfLangSys>::get_tags(unsigned int, unsigned int*, unsigned int*) const
Unexecuted instantiation: OT::RecordArrayOf<OT::JstfScript>::get_tags(unsigned int, unsigned int*, unsigned int*) const
906
  bool find_index (hb_tag_t tag, unsigned int *index) const
907
211k
  {
908
211k
    return this->bfind (tag, index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
909
211k
  }
OT::RecordArrayOf<OT::LangSys>::find_index(unsigned int, unsigned int*) const
Line
Count
Source
907
49.2k
  {
908
49.2k
    return this->bfind (tag, index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
909
49.2k
  }
OT::RecordArrayOf<OT::Script>::find_index(unsigned int, unsigned int*) const
Line
Count
Source
907
162k
  {
908
162k
    return this->bfind (tag, index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
909
162k
  }
Unexecuted instantiation: OT::RecordArrayOf<OT::Feature>::find_index(unsigned int, unsigned int*) const
Unexecuted instantiation: OT::RecordArrayOf<OT::JstfLangSys>::find_index(unsigned int, unsigned int*) const
Unexecuted instantiation: OT::RecordArrayOf<OT::JstfScript>::find_index(unsigned int, unsigned int*) const
910
};
911
912
template <typename Type>
913
struct RecordListOf : RecordArrayOf<Type>
914
{
915
  const Type& operator [] (unsigned int i) const
916
1.58M
  { return this+this->get_offset (i); }
OT::RecordListOf<OT::Script>::operator[](unsigned int) const
Line
Count
Source
916
1.43M
  { return this+this->get_offset (i); }
OT::RecordListOf<OT::Feature>::operator[](unsigned int) const
Line
Count
Source
916
158k
  { return this+this->get_offset (i); }
917
918
  bool subset (hb_subset_context_t *c,
919
               hb_subset_layout_context_t *l) const
920
  {
921
    TRACE_SUBSET (this);
922
    auto *out = c->serializer->start_embed (*this);
923
    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
924
925
    + this->iter ()
926
    | hb_apply (subset_record_array (l, out, this))
927
    ;
928
    return_trace (true);
929
  }
930
931
  bool sanitize (hb_sanitize_context_t *c) const
932
43.2k
  {
933
43.2k
    TRACE_SANITIZE (this);
934
43.2k
    return_trace (RecordArrayOf<Type>::sanitize (c, this));
935
43.2k
  }
OT::RecordListOf<OT::Script>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
932
22.1k
  {
933
22.1k
    TRACE_SANITIZE (this);
934
22.1k
    return_trace (RecordArrayOf<Type>::sanitize (c, this));
935
22.1k
  }
OT::RecordListOf<OT::Feature>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
932
21.1k
  {
933
21.1k
    TRACE_SANITIZE (this);
934
21.1k
    return_trace (RecordArrayOf<Type>::sanitize (c, this));
935
21.1k
  }
936
};
937
938
struct RecordListOfFeature : RecordListOf<Feature>
939
{
940
  bool subset (hb_subset_context_t *c,
941
         hb_subset_layout_context_t *l) const
942
0
  {
943
0
    TRACE_SUBSET (this);
944
0
    auto *out = c->serializer->start_embed (*this);
945
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
946
0
947
0
    + hb_enumerate (*this)
948
0
    | hb_filter (l->feature_index_map, hb_first)
949
0
    | hb_apply ([l, out, this] (const hb_pair_t<unsigned, const Record<Feature>&>& _)
950
0
                {
951
0
                  const Feature *f_sub = nullptr;
952
0
                  const Feature **f = nullptr;
953
0
                  if (l->feature_substitutes_map->has (_.first, &f))
954
0
                    f_sub = *f;
955
0
956
0
                  subset_record_array (l, out, this, f_sub) (_.second);
957
0
                })
958
0
    ;
959
0
960
0
    return_trace (true);
961
0
  }
962
};
963
964
typedef RecordListOf<Feature> FeatureList;
965
966
967
struct LangSys
968
{
969
  unsigned int get_feature_count () const
970
1.31M
  { return featureIndex.len; }
971
  hb_tag_t get_feature_index (unsigned int i) const
972
5.26M
  { return featureIndex[i]; }
973
  unsigned int get_feature_indexes (unsigned int start_offset,
974
            unsigned int *feature_count /* IN/OUT */,
975
            unsigned int *feature_indexes /* OUT */) const
976
19.7k
  { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
977
  void add_feature_indexes_to (hb_set_t *feature_indexes) const
978
0
  { featureIndex.add_indexes_to (feature_indexes); }
979
980
49.2k
  bool has_required_feature () const { return reqFeatureIndex != 0xFFFFu; }
981
  unsigned int get_required_feature_index () const
982
49.2k
  {
983
49.2k
    if (reqFeatureIndex == 0xFFFFu)
984
48.5k
      return Index::NOT_FOUND_INDEX;
985
660
   return reqFeatureIndex;
986
49.2k
  }
987
988
  LangSys* copy (hb_serialize_context_t *c) const
989
0
  {
990
0
    TRACE_SERIALIZE (this);
991
0
    return_trace (c->embed (*this));
992
0
  }
993
994
  bool compare (const LangSys& o, const hb_map_t *feature_index_map) const
995
0
  {
996
0
    if (reqFeatureIndex != o.reqFeatureIndex)
997
0
      return false;
998
0
999
0
    auto iter =
1000
0
    + hb_iter (featureIndex)
1001
0
    | hb_filter (feature_index_map)
1002
0
    | hb_map (feature_index_map)
1003
0
    ;
1004
0
1005
0
    auto o_iter =
1006
0
    + hb_iter (o.featureIndex)
1007
0
    | hb_filter (feature_index_map)
1008
0
    | hb_map (feature_index_map)
1009
0
    ;
1010
0
1011
0
    for (; iter && o_iter; iter++, o_iter++)
1012
0
    {
1013
0
      unsigned a = *iter;
1014
0
      unsigned b = *o_iter;
1015
0
      if (a != b) return false;
1016
0
    }
1017
0
1018
0
    if (iter || o_iter) return false;
1019
0
1020
0
    return true;
1021
0
  }
1022
1023
  void collect_features (hb_prune_langsys_context_t *c) const
1024
0
  {
1025
0
    if (!has_required_feature () && !get_feature_count ()) return;
1026
0
    if (has_required_feature () &&
1027
0
        c->duplicate_feature_map->has (reqFeatureIndex))
1028
0
      c->new_feature_indexes->add (get_required_feature_index ());
1029
0
1030
0
    + hb_iter (featureIndex)
1031
0
    | hb_filter (c->duplicate_feature_map)
1032
0
    | hb_sink (c->new_feature_indexes)
1033
0
    ;
1034
0
  }
1035
1036
  bool subset (hb_subset_context_t        *c,
1037
         hb_subset_layout_context_t *l,
1038
         const Tag                  *tag = nullptr) const
1039
0
  {
1040
0
    TRACE_SUBSET (this);
1041
0
    auto *out = c->serializer->start_embed (*this);
1042
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
1043
0
1044
0
    const uint32_t *v;
1045
0
    out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu;
1046
0
1047
0
    if (!l->visitFeatureIndex (featureIndex.len))
1048
0
      return_trace (false);
1049
0
1050
0
    auto it =
1051
0
    + hb_iter (featureIndex)
1052
0
    | hb_filter (l->feature_index_map)
1053
0
    | hb_map (l->feature_index_map)
1054
0
    ;
1055
0
1056
0
    bool ret = bool (it);
1057
0
    out->featureIndex.serialize (c->serializer, l, it);
1058
0
    return_trace (ret);
1059
0
  }
1060
1061
  bool sanitize (hb_sanitize_context_t *c,
1062
     const Record_sanitize_closure_t * = nullptr) const
1063
1.54M
  {
1064
1.54M
    TRACE_SANITIZE (this);
1065
1.54M
    return_trace (c->check_struct (this) && featureIndex.sanitize (c));
1066
1.54M
  }
1067
1068
  Offset16  lookupOrderZ; /* = Null (reserved for an offset to a
1069
         * reordering table) */
1070
  HBUINT16  reqFeatureIndex;/* Index of a feature required for this
1071
         * language system--if no required features
1072
         * = 0xFFFFu */
1073
  IndexArray  featureIndex; /* Array of indices into the FeatureList */
1074
  public:
1075
  DEFINE_SIZE_ARRAY_SIZED (6, featureIndex);
1076
};
1077
DECLARE_NULL_NAMESPACE_BYTES (OT, LangSys);
1078
1079
struct Script
1080
{
1081
  unsigned int get_lang_sys_count () const
1082
0
  { return langSys.len; }
1083
  const Tag& get_lang_sys_tag (unsigned int i) const
1084
0
  { return langSys.get_tag (i); }
1085
  unsigned int get_lang_sys_tags (unsigned int start_offset,
1086
          unsigned int *lang_sys_count /* IN/OUT */,
1087
          hb_tag_t     *lang_sys_tags /* OUT */) const
1088
0
  { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
1089
  const LangSys& get_lang_sys (unsigned int i) const
1090
1.38M
  {
1091
1.38M
    if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
1092
19.7k
    return this+langSys[i].offset;
1093
1.38M
  }
1094
  bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
1095
49.2k
  { return langSys.find_index (tag, index); }
1096
1097
0
  bool has_default_lang_sys () const           { return defaultLangSys != 0; }
1098
1.36M
  const LangSys& get_default_lang_sys () const { return this+defaultLangSys; }
1099
1100
  void prune_langsys (hb_prune_langsys_context_t *c,
1101
                      unsigned script_index) const
1102
0
  {
1103
0
    if (!has_default_lang_sys () && !get_lang_sys_count ()) return;
1104
0
    if (!c->visitScript ()) return;
1105
0
1106
0
    if (!c->script_langsys_map->has (script_index))
1107
0
    {
1108
0
      if (unlikely (!c->script_langsys_map->set (script_index, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
1109
0
  return;
1110
0
    }
1111
0
1112
0
    if (has_default_lang_sys ())
1113
0
    {
1114
0
      //only collect features from non-redundant langsys
1115
0
      const LangSys& d = get_default_lang_sys ();
1116
0
      if (c->visitLangsys (d.get_feature_count ())) {
1117
0
        d.collect_features (c);
1118
0
      }
1119
0
1120
0
      for (auto _ : + hb_enumerate (langSys))
1121
0
      {
1122
0
        const LangSys& l = this+_.second.offset;
1123
0
        if (!c->visitLangsys (l.get_feature_count ())) continue;
1124
0
        if (l.compare (d, c->duplicate_feature_map)) continue;
1125
0
1126
0
        l.collect_features (c);
1127
0
        c->script_langsys_map->get (script_index)->add (_.first);
1128
0
      }
1129
0
    }
1130
0
    else
1131
0
    {
1132
0
      for (auto _ : + hb_enumerate (langSys))
1133
0
      {
1134
0
        const LangSys& l = this+_.second.offset;
1135
0
        if (!c->visitLangsys (l.get_feature_count ())) continue;
1136
0
        l.collect_features (c);
1137
0
        c->script_langsys_map->get (script_index)->add (_.first);
1138
0
      }
1139
0
    }
1140
0
  }
1141
1142
  bool subset (hb_subset_context_t         *c,
1143
         hb_subset_layout_context_t  *l,
1144
         const Tag                   *tag) const
1145
0
  {
1146
0
    TRACE_SUBSET (this);
1147
0
    if (!l->visitScript ()) return_trace (false);
1148
0
    if (tag && !c->plan->layout_scripts.has (*tag))
1149
0
      return false;
1150
0
1151
0
    auto *out = c->serializer->start_embed (*this);
1152
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
1153
0
1154
0
    bool defaultLang = false;
1155
0
    if (has_default_lang_sys ())
1156
0
    {
1157
0
      c->serializer->push ();
1158
0
      const LangSys& ls = this+defaultLangSys;
1159
0
      bool ret = ls.subset (c, l);
1160
0
      if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T'))
1161
0
      {
1162
0
  c->serializer->pop_discard ();
1163
0
  out->defaultLangSys = 0;
1164
0
      }
1165
0
      else
1166
0
      {
1167
0
  c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ());
1168
0
  defaultLang = true;
1169
0
      }
1170
0
    }
1171
0
1172
0
    const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index);
1173
0
    if (active_langsys)
1174
0
    {
1175
0
      + hb_enumerate (langSys)
1176
0
      | hb_filter (active_langsys, hb_first)
1177
0
      | hb_map (hb_second)
1178
0
      | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); })
1179
0
      | hb_apply (subset_record_array (l, &(out->langSys), this))
1180
0
      ;
1181
0
    }
1182
0
1183
0
    return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB);
1184
0
  }
1185
1186
  bool sanitize (hb_sanitize_context_t *c,
1187
     const Record_sanitize_closure_t * = nullptr) const
1188
57.2k
  {
1189
57.2k
    TRACE_SANITIZE (this);
1190
57.2k
    return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
1191
57.2k
  }
1192
1193
  protected:
1194
  Offset16To<LangSys>
1195
    defaultLangSys; /* Offset to DefaultLangSys table--from
1196
         * beginning of Script table--may be Null */
1197
  RecordArrayOf<LangSys>
1198
    langSys;  /* Array of LangSysRecords--listed
1199
         * alphabetically by LangSysTag */
1200
  public:
1201
  DEFINE_SIZE_ARRAY_SIZED (4, langSys);
1202
};
1203
1204
struct RecordListOfScript : RecordListOf<Script>
1205
{
1206
  bool subset (hb_subset_context_t *c,
1207
               hb_subset_layout_context_t *l) const
1208
0
  {
1209
0
    TRACE_SUBSET (this);
1210
0
    auto *out = c->serializer->start_embed (*this);
1211
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
1212
0
1213
0
    for (auto _ : + hb_enumerate (*this))
1214
0
    {
1215
0
      auto snap = c->serializer->snapshot ();
1216
0
      l->cur_script_index = _.first;
1217
0
      bool ret = _.second.subset (l, this);
1218
0
      if (!ret) c->serializer->revert (snap);
1219
0
      else out->len++;
1220
0
    }
1221
0
1222
0
    return_trace (true);
1223
0
  }
1224
};
1225
1226
typedef RecordListOfScript ScriptList;
1227
1228
1229
1230
struct LookupFlag : HBUINT16
1231
{
1232
  enum Flags {
1233
    RightToLeft   = 0x0001u,
1234
    IgnoreBaseGlyphs  = 0x0002u,
1235
    IgnoreLigatures = 0x0004u,
1236
    IgnoreMarks   = 0x0008u,
1237
    IgnoreFlags   = 0x000Eu,
1238
    UseMarkFilteringSet = 0x0010u,
1239
    Reserved    = 0x00E0u,
1240
    MarkAttachmentType  = 0xFF00u
1241
  };
1242
  public:
1243
  DEFINE_SIZE_STATIC (2);
1244
};
1245
1246
} /* namespace OT */
1247
/* This has to be outside the namespace. */
1248
HB_MARK_AS_FLAG_T (OT::LookupFlag::Flags);
1249
namespace OT {
1250
1251
struct Lookup
1252
{
1253
275k
  unsigned int get_subtable_count () const { return subTable.len; }
1254
1255
  template <typename TSubTable>
1256
  const Array16OfOffset16To<TSubTable>& get_subtables () const
1257
895k
  { return reinterpret_cast<const Array16OfOffset16To<TSubTable> &> (subTable); }
OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > const& OT::Lookup::get_subtables<OT::Layout::GPOS_impl::PosLookupSubTable>() const
Line
Count
Source
1257
326k
  { return reinterpret_cast<const Array16OfOffset16To<TSubTable> &> (subTable); }
OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> > const& OT::Lookup::get_subtables<OT::Layout::GSUB_impl::SubstLookupSubTable>() const
Line
Count
Source
1257
568k
  { return reinterpret_cast<const Array16OfOffset16To<TSubTable> &> (subTable); }
1258
  template <typename TSubTable>
1259
  Array16OfOffset16To<TSubTable>& get_subtables ()
1260
380
  { return reinterpret_cast<Array16OfOffset16To<TSubTable> &> (subTable); }
Unexecuted instantiation: OT::ArrayOf<OT::OffsetTo<OT::Layout::GPOS_impl::PosLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >& OT::Lookup::get_subtables<OT::Layout::GPOS_impl::PosLookupSubTable>()
OT::ArrayOf<OT::OffsetTo<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::IntType<unsigned short, 2u>, true>, OT::IntType<unsigned short, 2u> >& OT::Lookup::get_subtables<OT::Layout::GSUB_impl::SubstLookupSubTable>()
Line
Count
Source
1260
380
  { return reinterpret_cast<Array16OfOffset16To<TSubTable> &> (subTable); }
1261
1262
  template <typename TSubTable>
1263
  const TSubTable& get_subtable (unsigned int i) const
1264
793k
  { return this+get_subtables<TSubTable> ()[i]; }
OT::Layout::GPOS_impl::PosLookupSubTable const& OT::Lookup::get_subtable<OT::Layout::GPOS_impl::PosLookupSubTable>(unsigned int) const
Line
Count
Source
1264
298k
  { return this+get_subtables<TSubTable> ()[i]; }
OT::Layout::GSUB_impl::SubstLookupSubTable const& OT::Lookup::get_subtable<OT::Layout::GSUB_impl::SubstLookupSubTable>(unsigned int) const
Line
Count
Source
1264
495k
  { return this+get_subtables<TSubTable> ()[i]; }
1265
  template <typename TSubTable>
1266
  TSubTable& get_subtable (unsigned int i)
1267
  { return this+get_subtables<TSubTable> ()[i]; }
1268
1269
  unsigned int get_size () const
1270
0
  {
1271
0
    const HBUINT16 &markFilteringSet = StructAfter<const HBUINT16> (subTable);
1272
0
    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
1273
0
      return (const char *) &StructAfter<const char> (markFilteringSet) - (const char *) this;
1274
0
    return (const char *) &markFilteringSet - (const char *) this;
1275
0
  }
1276
1277
304k
  unsigned int get_type () const { return lookupType; }
1278
1279
  /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
1280
   * higher 16-bit is mark-filtering-set if the lookup uses one.
1281
   * Not to be confused with glyph_props which is very similar. */
1282
  uint32_t get_props () const
1283
5.37M
  {
1284
5.37M
    unsigned int flag = lookupFlag;
1285
5.37M
    if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
1286
107k
    {
1287
107k
      const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
1288
107k
      flag += (markFilteringSet << 16);
1289
107k
    }
1290
5.37M
    return flag;
1291
5.37M
  }
1292
1293
  template <typename TSubTable, typename context_t, typename ...Ts>
1294
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
1295
86.7k
  {
1296
86.7k
    unsigned int lookup_type = get_type ();
1297
86.7k
    TRACE_DISPATCH (this, lookup_type);
1298
86.7k
    unsigned int count = get_subtable_count ();
1299
867k
    for (unsigned int i = 0; i < count; i++) {
1300
780k
      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...);
1301
780k
      if (c->stop_sublookup_iteration (r))
1302
0
  return_trace (r);
1303
780k
    }
1304
86.7k
    return_trace (c->default_return_value ());
1305
86.7k
  }
Unexecuted instantiation: OT::hb_ot_apply_context_t::return_t OT::Lookup::dispatch<OT::Layout::GPOS_impl::PosLookupSubTable, OT::hb_ot_apply_context_t>(OT::hb_ot_apply_context_t*) const
Unexecuted instantiation: OT::hb_intersects_context_t::return_t OT::Lookup::dispatch<OT::Layout::GPOS_impl::PosLookupSubTable, OT::hb_intersects_context_t>(OT::hb_intersects_context_t*) const
Unexecuted instantiation: OT::hb_collect_glyphs_context_t::return_t OT::Lookup::dispatch<OT::Layout::GPOS_impl::PosLookupSubTable, OT::hb_collect_glyphs_context_t>(OT::hb_collect_glyphs_context_t*) const
Unexecuted instantiation: OT::hb_closure_lookups_context_t::return_t OT::Lookup::dispatch<OT::Layout::GPOS_impl::PosLookupSubTable, OT::hb_closure_lookups_context_t>(OT::hb_closure_lookups_context_t*) const
Unexecuted instantiation: OT::hb_collect_variation_indices_context_t::return_t OT::Lookup::dispatch<OT::Layout::GPOS_impl::PosLookupSubTable, OT::hb_collect_variation_indices_context_t>(OT::hb_collect_variation_indices_context_t*) const
OT::hb_accelerate_subtables_context_t::return_t OT::Lookup::dispatch<OT::Layout::GPOS_impl::PosLookupSubTable, OT::hb_accelerate_subtables_context_t>(OT::hb_accelerate_subtables_context_t*) const
Line
Count
Source
1295
25.3k
  {
1296
25.3k
    unsigned int lookup_type = get_type ();
1297
25.3k
    TRACE_DISPATCH (this, lookup_type);
1298
25.3k
    unsigned int count = get_subtable_count ();
1299
321k
    for (unsigned int i = 0; i < count; i++) {
1300
296k
      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...);
1301
296k
      if (c->stop_sublookup_iteration (r))
1302
0
  return_trace (r);
1303
296k
    }
1304
25.3k
    return_trace (c->default_return_value ());
1305
25.3k
  }
Unexecuted instantiation: OT::hb_have_non_1to1_context_t::return_t OT::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, 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::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::hb_ot_apply_context_t>(OT::hb_ot_apply_context_t*) const
Unexecuted instantiation: OT::hb_intersects_context_t::return_t OT::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::hb_intersects_context_t>(OT::hb_intersects_context_t*) const
Unexecuted instantiation: OT::hb_closure_context_t::return_t OT::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::hb_closure_context_t>(OT::hb_closure_context_t*) const
Unexecuted instantiation: OT::hb_closure_lookups_context_t::return_t OT::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::hb_closure_lookups_context_t>(OT::hb_closure_lookups_context_t*) const
Unexecuted instantiation: OT::hb_collect_glyphs_context_t::return_t OT::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::hb_collect_glyphs_context_t>(OT::hb_collect_glyphs_context_t*) const
OT::hb_would_apply_context_t::return_t OT::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::hb_would_apply_context_t>(OT::hb_would_apply_context_t*) const
Line
Count
Source
1295
40
  {
1296
40
    unsigned int lookup_type = get_type ();
1297
40
    TRACE_DISPATCH (this, lookup_type);
1298
40
    unsigned int count = get_subtable_count ();
1299
100
    for (unsigned int i = 0; i < count; i++) {
1300
60
      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...);
1301
60
      if (c->stop_sublookup_iteration (r))
1302
0
  return_trace (r);
1303
60
    }
1304
40
    return_trace (c->default_return_value ());
1305
40
  }
OT::hb_accelerate_subtables_context_t::return_t OT::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, OT::hb_accelerate_subtables_context_t>(OT::hb_accelerate_subtables_context_t*) const
Line
Count
Source
1295
61.3k
  {
1296
61.3k
    unsigned int lookup_type = get_type ();
1297
61.3k
    TRACE_DISPATCH (this, lookup_type);
1298
61.3k
    unsigned int count = get_subtable_count ();
1299
545k
    for (unsigned int i = 0; i < count; i++) {
1300
484k
      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...);
1301
484k
      if (c->stop_sublookup_iteration (r))
1302
0
  return_trace (r);
1303
484k
    }
1304
61.3k
    return_trace (c->default_return_value ());
1305
61.3k
  }
Unexecuted instantiation: hb_get_glyph_alternates_dispatch_t::return_t OT::Lookup::dispatch<OT::Layout::GSUB_impl::SubstLookupSubTable, 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
Unexecuted instantiation: hb_position_single_dispatch_t::return_t OT::Lookup::dispatch<OT::Layout::GPOS_impl::PosLookupSubTable, hb_position_single_dispatch_t, hb_font_t*&, hb_direction_t&, unsigned int&, hb_glyph_position_t&>(hb_position_single_dispatch_t*, hb_font_t*&, hb_direction_t&, unsigned int&, hb_glyph_position_t&) const
1306
1307
  bool serialize (hb_serialize_context_t *c,
1308
      unsigned int lookup_type,
1309
      uint32_t lookup_props,
1310
      unsigned int num_subtables)
1311
400
  {
1312
400
    TRACE_SERIALIZE (this);
1313
400
    if (unlikely (!c->extend_min (this))) return_trace (false);
1314
380
    lookupType = lookup_type;
1315
380
    lookupFlag = lookup_props & 0xFFFFu;
1316
380
    if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
1317
380
    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
1318
0
    {
1319
0
      if (unlikely (!c->extend (this))) return_trace (false);
1320
0
      HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
1321
0
      markFilteringSet = lookup_props >> 16;
1322
0
    }
1323
380
    return_trace (true);
1324
380
  }
1325
1326
  template <typename TSubTable>
1327
  bool subset (hb_subset_context_t *c) const
1328
0
  {
1329
0
    TRACE_SUBSET (this);
1330
0
    auto *out = c->serializer->start_embed (*this);
1331
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
1332
0
    out->lookupType = lookupType;
1333
0
    out->lookupFlag = lookupFlag;
1334
0
1335
0
    const hb_set_t *glyphset = c->plan->glyphset_gsub ();
1336
0
    unsigned int lookup_type = get_type ();
1337
0
    + hb_iter (get_subtables <TSubTable> ())
1338
0
    | hb_filter ([this, glyphset, lookup_type] (const Offset16To<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); })
1339
0
    | hb_apply (subset_offset_array (c, out->get_subtables<TSubTable> (), this, lookup_type))
1340
0
    ;
1341
0
1342
0
    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
1343
0
    {
1344
0
      if (unlikely (!c->serializer->extend (out))) return_trace (false);
1345
0
      const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
1346
0
      HBUINT16 &outMarkFilteringSet = StructAfter<HBUINT16> (out->subTable);
1347
0
      outMarkFilteringSet = markFilteringSet;
1348
0
    }
1349
0
1350
0
    // Always keep the lookup even if it's empty. The rest of layout subsetting depends on lookup
1351
0
    // indices being consistent with those computed during planning. So if an empty lookup is
1352
0
    // discarded during the subset phase it will invalidate all subsequent lookup indices.
1353
0
    // Generally we shouldn't end up with an empty lookup as we pre-prune them during the planning
1354
0
    // phase, but it can happen in rare cases such as when during closure subtable is considered
1355
0
    // degenerate (see: https://github.com/harfbuzz/harfbuzz/issues/3853)
1356
0
    return_trace (true);
1357
0
  }
Unexecuted instantiation: bool OT::Lookup::subset<OT::Layout::GPOS_impl::PosLookupSubTable>(hb_subset_context_t*) const
Unexecuted instantiation: bool OT::Lookup::subset<OT::Layout::GSUB_impl::SubstLookupSubTable>(hb_subset_context_t*) const
1358
1359
  template <typename TSubTable>
1360
  bool sanitize (hb_sanitize_context_t *c) const
1361
104k
  {
1362
104k
    TRACE_SANITIZE (this);
1363
104k
    if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
1364
1365
102k
    unsigned subtables = get_subtable_count ();
1366
102k
    if (unlikely (!c->visit_subtables (subtables))) return_trace (false);
1367
1368
101k
    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
1369
2.52k
    {
1370
2.52k
      const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
1371
2.52k
      if (!markFilteringSet.sanitize (c)) return_trace (false);
1372
2.52k
    }
1373
1374
101k
    if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
1375
1.82k
      return_trace (false);
1376
1377
99.7k
    if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
1378
11.4k
    {
1379
      /* The spec says all subtables of an Extension lookup should
1380
       * have the same type, which shall not be the Extension type
1381
       * itself (but we already checked for that).
1382
       * This is specially important if one has a reverse type!
1383
       *
1384
       * We only do this if sanitizer edit_count is zero.  Otherwise,
1385
       * some of the subtables might have become insane after they
1386
       * were sanity-checked by the edits of subsequent subtables.
1387
       * https://bugs.chromium.org/p/chromium/issues/detail?id=960331
1388
       */
1389
11.4k
      unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
1390
12.8k
      for (unsigned int i = 1; i < subtables; i++)
1391
1.38k
  if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
1392
40
    return_trace (false);
1393
11.4k
    }
1394
99.7k
    return_trace (true);
1395
99.7k
  }
bool OT::Lookup::sanitize<OT::Layout::GPOS_impl::PosLookupSubTable>(hb_sanitize_context_t*) const
Line
Count
Source
1361
29.5k
  {
1362
29.5k
    TRACE_SANITIZE (this);
1363
29.5k
    if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
1364
1365
29.1k
    unsigned subtables = get_subtable_count ();
1366
29.1k
    if (unlikely (!c->visit_subtables (subtables))) return_trace (false);
1367
1368
28.5k
    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
1369
1.08k
    {
1370
1.08k
      const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
1371
1.08k
      if (!markFilteringSet.sanitize (c)) return_trace (false);
1372
1.08k
    }
1373
1374
28.5k
    if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
1375
680
      return_trace (false);
1376
1377
27.8k
    if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
1378
1.86k
    {
1379
      /* The spec says all subtables of an Extension lookup should
1380
       * have the same type, which shall not be the Extension type
1381
       * itself (but we already checked for that).
1382
       * This is specially important if one has a reverse type!
1383
       *
1384
       * We only do this if sanitizer edit_count is zero.  Otherwise,
1385
       * some of the subtables might have become insane after they
1386
       * were sanity-checked by the edits of subsequent subtables.
1387
       * https://bugs.chromium.org/p/chromium/issues/detail?id=960331
1388
       */
1389
1.86k
      unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
1390
2.02k
      for (unsigned int i = 1; i < subtables; i++)
1391
160
  if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
1392
0
    return_trace (false);
1393
1.86k
    }
1394
27.8k
    return_trace (true);
1395
27.8k
  }
bool OT::Lookup::sanitize<OT::Layout::GSUB_impl::SubstLookupSubTable>(hb_sanitize_context_t*) const
Line
Count
Source
1361
74.9k
  {
1362
74.9k
    TRACE_SANITIZE (this);
1363
74.9k
    if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
1364
1365
73.0k
    unsigned subtables = get_subtable_count ();
1366
73.0k
    if (unlikely (!c->visit_subtables (subtables))) return_trace (false);
1367
1368
73.0k
    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
1369
1.44k
    {
1370
1.44k
      const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
1371
1.44k
      if (!markFilteringSet.sanitize (c)) return_trace (false);
1372
1.44k
    }
1373
1374
73.0k
    if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
1375
1.14k
      return_trace (false);
1376
1377
71.9k
    if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
1378
9.60k
    {
1379
      /* The spec says all subtables of an Extension lookup should
1380
       * have the same type, which shall not be the Extension type
1381
       * itself (but we already checked for that).
1382
       * This is specially important if one has a reverse type!
1383
       *
1384
       * We only do this if sanitizer edit_count is zero.  Otherwise,
1385
       * some of the subtables might have become insane after they
1386
       * were sanity-checked by the edits of subsequent subtables.
1387
       * https://bugs.chromium.org/p/chromium/issues/detail?id=960331
1388
       */
1389
9.60k
      unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
1390
10.7k
      for (unsigned int i = 1; i < subtables; i++)
1391
1.22k
  if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
1392
40
    return_trace (false);
1393
9.60k
    }
1394
71.8k
    return_trace (true);
1395
71.9k
  }
1396
1397
  protected:
1398
  HBUINT16  lookupType;   /* Different enumerations for GSUB and GPOS */
1399
  HBUINT16  lookupFlag;   /* Lookup qualifiers */
1400
  Array16Of<Offset16>
1401
    subTable;   /* Array of SubTables */
1402
/*HBUINT16  markFilteringSetX[HB_VAR_ARRAY];*//* Index (base 0) into GDEF mark glyph sets
1403
           * structure. This field is only present if bit
1404
           * UseMarkFilteringSet of lookup flags is set. */
1405
  public:
1406
  DEFINE_SIZE_ARRAY (6, subTable);
1407
};
1408
1409
template <typename Types>
1410
using LookupList = List16OfOffsetTo<Lookup, typename Types::HBUINT>;
1411
1412
template <typename TLookup, typename OffsetType>
1413
struct LookupOffsetList : List16OfOffsetTo<TLookup, OffsetType>
1414
{
1415
  bool subset (hb_subset_context_t        *c,
1416
         hb_subset_layout_context_t *l) const
1417
0
  {
1418
0
    TRACE_SUBSET (this);
1419
0
    auto *out = c->serializer->start_embed (this);
1420
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
1421
0
1422
0
    + hb_enumerate (*this)
1423
0
    | hb_filter (l->lookup_index_map, hb_first)
1424
0
    | hb_map (hb_second)
1425
0
    | hb_apply (subset_offset_array (c, *out, this))
1426
0
    ;
1427
0
    return_trace (true);
1428
0
  }
Unexecuted instantiation: OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned short, 2u> >::subset(hb_subset_context_t*, OT::hb_subset_layout_context_t*) const
Unexecuted instantiation: OT::LookupOffsetList<OT::Layout::GPOS_impl::PosLookup, OT::IntType<unsigned int, 3u> >::subset(hb_subset_context_t*, OT::hb_subset_layout_context_t*) const
Unexecuted instantiation: OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned short, 2u> >::subset(hb_subset_context_t*, OT::hb_subset_layout_context_t*) const
Unexecuted instantiation: OT::LookupOffsetList<OT::Layout::GSUB_impl::SubstLookup, OT::IntType<unsigned int, 3u> >::subset(hb_subset_context_t*, OT::hb_subset_layout_context_t*) const
1429
1430
  bool sanitize (hb_sanitize_context_t *c) const
1431
  {
1432
    TRACE_SANITIZE (this);
1433
    return_trace (List16OfOffset16To<TLookup>::sanitize (c, this));
1434
  }
1435
};
1436
1437
1438
/*
1439
 * Coverage Table
1440
 */
1441
1442
1443
static bool ClassDef_remap_and_serialize (hb_serialize_context_t *c,
1444
            const hb_set_t &klasses,
1445
                                          bool use_class_zero,
1446
                                          hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
1447
            hb_map_t *klass_map /*IN/OUT*/)
1448
0
{
1449
0
  if (!klass_map)
1450
0
    return ClassDef_serialize (c, glyph_and_klass.iter ());
1451
0
1452
0
  /* any glyph not assigned a class value falls into Class zero (0),
1453
0
   * if any glyph assigned to class 0, remapping must start with 0->0*/
1454
0
  if (!use_class_zero)
1455
0
    klass_map->set (0, 0);
1456
0
1457
0
  unsigned idx = klass_map->has (0) ? 1 : 0;
1458
0
  for (const unsigned k: klasses)
1459
0
  {
1460
0
    if (klass_map->has (k)) continue;
1461
0
    klass_map->set (k, idx);
1462
0
    idx++;
1463
0
  }
1464
0
1465
0
1466
0
  for (unsigned i = 0; i < glyph_and_klass.length; i++)
1467
0
  {
1468
0
    hb_codepoint_t klass = glyph_and_klass[i].second;
1469
0
    glyph_and_klass[i].second = klass_map->get (klass);
1470
0
  }
1471
0
1472
0
  c->propagate_error (glyph_and_klass, klasses);
1473
0
  return ClassDef_serialize (c, glyph_and_klass.iter ());
1474
0
}
Unexecuted instantiation: hb-aat-layout.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-common.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-face.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-font.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-color.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-face.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-font.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-layout.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-math.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-metrics.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-var.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-cff1-table.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-cff2-table.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-shaper-arabic.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
Unexecuted instantiation: hb-ot-shape-fallback.cc:OT::ClassDef_remap_and_serialize(hb_serialize_context_t*, hb_set_t const&, bool, hb_vector_t<hb_pair_t<unsigned int, unsigned int>, true>&, hb_map_t*)
1475
1476
/*
1477
 * Class Definition Table
1478
 */
1479
1480
template <typename Types>
1481
struct ClassDefFormat1_3
1482
{
1483
  friend struct ClassDef;
1484
1485
  private:
1486
  unsigned int get_class (hb_codepoint_t glyph_id) const
1487
102k
  {
1488
102k
    return classValue[(unsigned int) (glyph_id - startGlyph)];
1489
102k
  }
OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::get_class(unsigned int) const
Line
Count
Source
1487
102k
  {
1488
102k
    return classValue[(unsigned int) (glyph_id - startGlyph)];
1489
102k
  }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::get_class(unsigned int) const
1490
1491
  unsigned get_population () const
1492
0
  {
1493
0
    return classValue.len;
1494
0
  }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::get_population() const
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::get_population() const
1495
1496
  template<typename Iterator,
1497
     hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
1498
  bool serialize (hb_serialize_context_t *c,
1499
      Iterator it)
1500
0
  {
1501
0
    TRACE_SERIALIZE (this);
1502
0
    if (unlikely (!c->extend_min (this))) return_trace (false);
1503
0
1504
0
    if (unlikely (!it))
1505
0
    {
1506
0
      classFormat = 1;
1507
0
      startGlyph = 0;
1508
0
      classValue.len = 0;
1509
0
      return_trace (true);
1510
0
    }
1511
0
1512
0
    hb_codepoint_t glyph_min = (*it).first;
1513
0
    hb_codepoint_t glyph_max = + it
1514
0
             | hb_map (hb_first)
1515
0
             | hb_reduce (hb_max, 0u);
1516
0
    unsigned glyph_count = glyph_max - glyph_min + 1;
1517
0
1518
0
    startGlyph = glyph_min;
1519
0
    if (unlikely (!classValue.serialize (c, glyph_count))) return_trace (false);
1520
0
    for (const hb_pair_t<hb_codepoint_t, uint32_t> gid_klass_pair : + it)
1521
0
    {
1522
0
      unsigned idx = gid_klass_pair.first - glyph_min;
1523
0
      classValue[idx] = gid_klass_pair.second;
1524
0
    }
1525
0
    return_trace (true);
1526
0
  }
Unexecuted instantiation: hb-aat-layout.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-aat-layout.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-common.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-common.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-face.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-face.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-font.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-font.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-color.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-color.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-face.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-face.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-font.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-font.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-layout.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-layout.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-math.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-math.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-metrics.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-metrics.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-var.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-var.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-cff1-table.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-cff1-table.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-cff2-table.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-cff2-table.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-shaper-arabic.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-shaper-arabic.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-shape-fallback.cc:bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-shape-fallback.cc:bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
1527
1528
  bool subset (hb_subset_context_t *c,
1529
         hb_map_t *klass_map = nullptr /*OUT*/,
1530
               bool keep_empty_table = true,
1531
               bool use_class_zero = true,
1532
               const Coverage* glyph_filter = nullptr) const
1533
0
  {
1534
0
    TRACE_SUBSET (this);
1535
0
    const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
1536
0
1537
0
    hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
1538
0
    hb_set_t orig_klasses;
1539
0
1540
0
    hb_codepoint_t start = startGlyph;
1541
0
    hb_codepoint_t end   = start + classValue.len;
1542
0
1543
0
    for (const hb_codepoint_t gid : + hb_range (start, end))
1544
0
    {
1545
0
      hb_codepoint_t new_gid = glyph_map[gid];
1546
0
      if (new_gid == HB_MAP_VALUE_INVALID) continue;
1547
0
      if (glyph_filter && !glyph_filter->has(gid)) continue;
1548
0
1549
0
      unsigned klass = classValue[gid - start];
1550
0
      if (!klass) continue;
1551
0
1552
0
      glyph_and_klass.push (hb_pair (new_gid, klass));
1553
0
      orig_klasses.add (klass);
1554
0
    }
1555
0
1556
0
    unsigned glyph_count = glyph_filter
1557
0
                           ? hb_len (hb_iter (glyph_map.keys()) | hb_filter (glyph_filter))
1558
0
                           : glyph_map.get_population ();
1559
0
    use_class_zero = use_class_zero && glyph_count <= glyph_and_klass.length;
1560
0
    if (!ClassDef_remap_and_serialize (c->serializer,
1561
0
                                       orig_klasses,
1562
0
                                       use_class_zero,
1563
0
                                       glyph_and_klass,
1564
0
                                       klass_map))
1565
0
      return_trace (false);
1566
0
    return_trace (keep_empty_table || (bool) glyph_and_klass);
1567
0
  }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::subset(hb_subset_context_t*, hb_map_t*, bool, bool, OT::Layout::Common::Coverage const*) const
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::subset(hb_subset_context_t*, hb_map_t*, bool, bool, OT::Layout::Common::Coverage const*) const
1568
1569
  bool sanitize (hb_sanitize_context_t *c) const
1570
7.66k
  {
1571
7.66k
    TRACE_SANITIZE (this);
1572
7.66k
    return_trace (c->check_struct (this) && classValue.sanitize (c));
1573
7.66k
  }
OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
1570
7.66k
  {
1571
7.66k
    TRACE_SANITIZE (this);
1572
7.66k
    return_trace (c->check_struct (this) && classValue.sanitize (c));
1573
7.66k
  }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::sanitize(hb_sanitize_context_t*) const
1574
1575
1.34k
  unsigned cost () const { return 1; }
OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::cost() const
Line
Count
Source
1575
1.34k
  unsigned cost () const { return 1; }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::cost() const
1576
1577
  template <typename set_t>
1578
  bool collect_coverage (set_t *glyphs) const
1579
0
  {
1580
0
    unsigned int start = 0;
1581
0
    unsigned int count = classValue.len;
1582
0
    for (unsigned int i = 0; i < count; i++)
1583
0
    {
1584
0
      if (classValue[i])
1585
0
  continue;
1586
1587
0
      if (start != i)
1588
0
  if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i)))
1589
0
    return false;
1590
1591
0
      start = i + 1;
1592
0
    }
1593
0
    if (start != count)
1594
0
      if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + count)))
1595
0
  return false;
1596
1597
0
    return true;
1598
0
  }
Unexecuted instantiation: bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::collect_coverage<hb_set_t>(hb_set_t*) const
Unexecuted instantiation: bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::collect_coverage<hb_set_t>(hb_set_t*) const
1599
1600
  template <typename set_t>
1601
  bool collect_class (set_t *glyphs, unsigned klass) const
1602
0
  {
1603
0
    unsigned int count = classValue.len;
1604
0
    for (unsigned int i = 0; i < count; i++)
1605
0
      if (classValue[i] == klass) glyphs->add (startGlyph + i);
1606
0
    return true;
1607
0
  }
Unexecuted instantiation: bool OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::collect_class<hb_set_t>(hb_set_t*, unsigned int) const
Unexecuted instantiation: bool OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::collect_class<hb_set_t>(hb_set_t*, unsigned int) const
1608
1609
  bool intersects (const hb_set_t *glyphs) const
1610
0
  {
1611
0
    hb_codepoint_t start = startGlyph;
1612
0
    hb_codepoint_t end = startGlyph + classValue.len;
1613
0
    for (hb_codepoint_t iter = startGlyph - 1;
1614
0
   glyphs->next (&iter) && iter < end;)
1615
0
      if (classValue[iter - start]) return true;
1616
0
    return false;
1617
0
  }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::intersects(hb_set_t const*) const
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::intersects(hb_set_t const*) const
1618
  bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const
1619
0
  {
1620
0
    unsigned int count = classValue.len;
1621
0
    if (klass == 0)
1622
0
    {
1623
      /* Match if there's any glyph that is not listed! */
1624
0
      hb_codepoint_t g = HB_SET_VALUE_INVALID;
1625
0
      if (!glyphs->next (&g)) return false;
1626
0
      if (g < startGlyph) return true;
1627
0
      g = startGlyph + count - 1;
1628
0
      if (glyphs->next (&g)) return true;
1629
      /* Fall through. */
1630
0
    }
1631
    /* TODO Speed up, using set overlap first? */
1632
    /* TODO(iter) Rewrite as dagger. */
1633
0
    const HBUINT16 *arr = classValue.arrayZ;
1634
0
    for (unsigned int i = 0; i < count; i++)
1635
0
      if (arr[i] == klass && glyphs->has (startGlyph + i))
1636
0
  return true;
1637
0
    return false;
1638
0
  }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::intersects_class(hb_set_t const*, unsigned short) const
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::intersects_class(hb_set_t const*, unsigned short) const
1639
1640
  void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const
1641
0
  {
1642
0
    unsigned count = classValue.len;
1643
0
    if (klass == 0)
1644
0
    {
1645
0
      unsigned start_glyph = startGlyph;
1646
0
      for (uint32_t g = HB_SET_VALUE_INVALID;
1647
0
     glyphs->next (&g) && g < start_glyph;)
1648
0
  intersect_glyphs->add (g);
1649
1650
0
      for (uint32_t g = startGlyph + count - 1;
1651
0
     glyphs-> next (&g);)
1652
0
  intersect_glyphs->add (g);
1653
1654
0
      return;
1655
0
    }
1656
1657
0
    for (unsigned i = 0; i < count; i++)
1658
0
      if (classValue[i] == klass && glyphs->has (startGlyph + i))
1659
0
  intersect_glyphs->add (startGlyph + i);
1660
1661
#if 0
1662
    /* The following implementation is faster asymptotically, but slower
1663
     * in practice. */
1664
    unsigned start_glyph = startGlyph;
1665
    unsigned end_glyph = start_glyph + count;
1666
    for (unsigned g = startGlyph - 1;
1667
   glyphs->next (&g) && g < end_glyph;)
1668
      if (classValue.arrayZ[g - start_glyph] == klass)
1669
        intersect_glyphs->add (g);
1670
#endif
1671
0
  }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::intersected_class_glyphs(hb_set_t const*, unsigned int, hb_set_t*) const
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::intersected_class_glyphs(hb_set_t const*, unsigned int, hb_set_t*) const
1672
1673
  void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
1674
0
  {
1675
0
    if (glyphs->is_empty ()) return;
1676
0
    hb_codepoint_t end_glyph = startGlyph + classValue.len - 1;
1677
0
    if (glyphs->get_min () < startGlyph ||
1678
0
        glyphs->get_max () > end_glyph)
1679
0
      intersect_classes->add (0);
1680
0
1681
0
    for (const auto& _ : + hb_enumerate (classValue))
1682
0
    {
1683
0
      hb_codepoint_t g = startGlyph + _.first;
1684
0
      if (glyphs->has (g))
1685
0
        intersect_classes->add (_.second);
1686
0
    }
1687
0
  }
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::SmallTypes>::intersected_classes(hb_set_t const*, hb_set_t*) const
Unexecuted instantiation: OT::ClassDefFormat1_3<OT::Layout::MediumTypes>::intersected_classes(hb_set_t const*, hb_set_t*) const
1688
1689
  protected:
1690
  HBUINT16  classFormat;  /* Format identifier--format = 1 */
1691
  typename Types::HBGlyphID
1692
     startGlyph;  /* First GlyphID of the classValueArray */
1693
  typename Types::template ArrayOf<HBUINT16>
1694
    classValue; /* Array of Class Values--one per GlyphID */
1695
  public:
1696
  DEFINE_SIZE_ARRAY (2 + 2 * Types::size, classValue);
1697
};
1698
1699
template <typename Types>
1700
struct ClassDefFormat2_4
1701
{
1702
  friend struct ClassDef;
1703
1704
  private:
1705
  unsigned int get_class (hb_codepoint_t glyph_id) const
1706
308k
  {
1707
308k
    return rangeRecord.bsearch (glyph_id).value;
1708
308k
  }
OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::get_class(unsigned int) const
Line
Count
Source
1706
306k
  {
1707
306k
    return rangeRecord.bsearch (glyph_id).value;
1708
306k
  }
OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::get_class(unsigned int) const
Line
Count
Source
1706
2.08k
  {
1707
2.08k
    return rangeRecord.bsearch (glyph_id).value;
1708
2.08k
  }
1709
1710
  unsigned get_population () const
1711
0
  {
1712
0
    typename Types::large_int ret = 0;
1713
0
    for (const auto &r : rangeRecord)
1714
0
      ret += r.get_population ();
1715
0
    return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
1716
0
  }
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::get_population() const
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::get_population() const
1717
1718
  template<typename Iterator,
1719
     hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
1720
  bool serialize (hb_serialize_context_t *c,
1721
      Iterator it)
1722
0
  {
1723
0
    TRACE_SERIALIZE (this);
1724
0
    if (unlikely (!c->extend_min (this))) return_trace (false);
1725
0
1726
0
    if (unlikely (!it))
1727
0
    {
1728
0
      classFormat = 2;
1729
0
      rangeRecord.len = 0;
1730
0
      return_trace (true);
1731
0
    }
1732
0
1733
0
    unsigned num_ranges = 1;
1734
0
    hb_codepoint_t prev_gid = (*it).first;
1735
0
    unsigned prev_klass = (*it).second;
1736
0
1737
0
    RangeRecord<Types> range_rec;
1738
0
    range_rec.first = prev_gid;
1739
0
    range_rec.last = prev_gid;
1740
0
    range_rec.value = prev_klass;
1741
0
1742
0
    auto *record = c->copy (range_rec);
1743
0
    if (unlikely (!record)) return_trace (false);
1744
0
1745
0
    for (const auto gid_klass_pair : + (++it))
1746
0
    {
1747
0
      hb_codepoint_t cur_gid = gid_klass_pair.first;
1748
0
      unsigned cur_klass = gid_klass_pair.second;
1749
0
1750
0
      if (cur_gid != prev_gid + 1 ||
1751
0
    cur_klass != prev_klass)
1752
0
      {
1753
0
  if (unlikely (!record)) break;
1754
0
  record->last = prev_gid;
1755
0
  num_ranges++;
1756
0
1757
0
  range_rec.first = cur_gid;
1758
0
  range_rec.last = cur_gid;
1759
0
  range_rec.value = cur_klass;
1760
0
1761
0
  record = c->copy (range_rec);
1762
0
      }
1763
0
1764
0
      prev_klass = cur_klass;
1765
0
      prev_gid = cur_gid;
1766
0
    }
1767
0
1768
0
    if (likely (record)) record->last = prev_gid;
1769
0
    rangeRecord.len = num_ranges;
1770
0
    return_trace (true);
1771
0
  }
Unexecuted instantiation: hb-aat-layout.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-aat-layout.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-common.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-common.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-face.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-face.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-font.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-font.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-color.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-color.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-face.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-face.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-font.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-font.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_31 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-layout.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-layout.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-math.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-math.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-metrics.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-metrics.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-var.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-var.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-cff1-table.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-cff1-table.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-cff2-table.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-cff2-table.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_32 const&, $_10 const&, (void*)0>)
Unexecuted instantiation: hb-ot-shaper-arabic.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-shaper-arabic.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-shape-fallback.cc:bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
Unexecuted instantiation: hb-ot-shape-fallback.cc:bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::serialize<hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_filter_iter_t<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>, $_6 const&, $_11 const&, (void*)0>)
1772
1773
  bool subset (hb_subset_context_t *c,
1774
         hb_map_t *klass_map = nullptr /*OUT*/,
1775
               bool keep_empty_table = true,
1776
               bool use_class_zero = true,
1777
               const Coverage* glyph_filter = nullptr) const
1778
0
  {
1779
0
    TRACE_SUBSET (this);
1780
0
    const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
1781
0
    const hb_set_t &glyph_set = *c->plan->glyphset_gsub ();
1782
0
1783
0
    hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
1784
0
    hb_set_t orig_klasses;
1785
0
1786
0
    if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2
1787
0
  < get_population ())
1788
0
    {
1789
0
      for (hb_codepoint_t g : glyph_set)
1790
0
      {
1791
0
  unsigned klass = get_class (g);
1792
0
  if (!klass) continue;
1793
0
  hb_codepoint_t new_gid = glyph_map[g];
1794
0
  if (new_gid == HB_MAP_VALUE_INVALID) continue;
1795
0
  if (glyph_filter && !glyph_filter->has (g)) continue;
1796
0
  glyph_and_klass.push (hb_pair (new_gid, klass));
1797
0
  orig_klasses.add (klass);
1798
0
      }
1799
0
    }
1800
0
    else
1801
0
    {
1802
0
      unsigned num_source_glyphs = c->plan->source->get_num_glyphs ();
1803
0
      for (auto &range : rangeRecord)
1804
0
      {
1805
0
  unsigned klass = range.value;
1806
0
  if (!klass) continue;
1807
0
  hb_codepoint_t start = range.first;
1808
0
  hb_codepoint_t end   = hb_min (range.last + 1, num_source_glyphs);
1809
0
  for (hb_codepoint_t g = start; g < end; g++)
1810
0
  {
1811
0
    hb_codepoint_t new_gid = glyph_map[g];
1812
0
    if (new_gid == HB_MAP_VALUE_INVALID) continue;
1813
0
    if (glyph_filter && !glyph_filter->has (g)) continue;
1814
0
1815
0
    glyph_and_klass.push (hb_pair (new_gid, klass));
1816
0
    orig_klasses.add (klass);
1817
0
  }
1818
0
      }
1819
0
    }
1820
0
1821
0
    const hb_set_t& glyphset = *c->plan->glyphset_gsub ();
1822
0
    unsigned glyph_count = glyph_filter
1823
0
                           ? hb_len (hb_iter (glyphset) | hb_filter (glyph_filter))
1824
0
                           : glyph_map.get_population ();
1825
0
    use_class_zero = use_class_zero && glyph_count <= glyph_and_klass.length;
1826
0
    if (!ClassDef_remap_and_serialize (c->serializer,
1827
0
                                       orig_klasses,
1828
0
                                       use_class_zero,
1829
0
                                       glyph_and_klass,
1830
0
                                       klass_map))
1831
0
      return_trace (false);
1832
0
    return_trace (keep_empty_table || (bool) glyph_and_klass);
1833
0
  }
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::subset(hb_subset_context_t*, hb_map_t*, bool, bool, OT::Layout::Common::Coverage const*) const
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::subset(hb_subset_context_t*, hb_map_t*, bool, bool, OT::Layout::Common::Coverage const*) const
1834
1835
  bool sanitize (hb_sanitize_context_t *c) const
1836
19.6k
  {
1837
19.6k
    TRACE_SANITIZE (this);
1838
19.6k
    return_trace (rangeRecord.sanitize (c));
1839
19.6k
  }
OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
1836
19.2k
  {
1837
19.2k
    TRACE_SANITIZE (this);
1838
19.2k
    return_trace (rangeRecord.sanitize (c));
1839
19.2k
  }
OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::sanitize(hb_sanitize_context_t*) const
Line
Count
Source
1836
400
  {
1837
400
    TRACE_SANITIZE (this);
1838
400
    return_trace (rangeRecord.sanitize (c));
1839
400
  }
1840
1841
4.52k
  unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ }
OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::cost() const
Line
Count
Source
1841
4.50k
  unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ }
OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::cost() const
Line
Count
Source
1841
20
  unsigned cost () const { return hb_bit_storage ((unsigned) rangeRecord.len); /* bsearch cost */ }
1842
1843
  template <typename set_t>
1844
  bool collect_coverage (set_t *glyphs) const
1845
0
  {
1846
0
    for (auto &range : rangeRecord)
1847
0
      if (range.value)
1848
0
  if (unlikely (!range.collect_coverage (glyphs)))
1849
0
    return false;
1850
0
    return true;
1851
0
  }
Unexecuted instantiation: bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::collect_coverage<hb_set_t>(hb_set_t*) const
Unexecuted instantiation: bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::collect_coverage<hb_set_t>(hb_set_t*) const
1852
1853
  template <typename set_t>
1854
  bool collect_class (set_t *glyphs, unsigned int klass) const
1855
0
  {
1856
0
    for (auto &range : rangeRecord)
1857
0
    {
1858
0
      if (range.value == klass)
1859
0
  if (unlikely (!range.collect_coverage (glyphs)))
1860
0
    return false;
1861
0
    }
1862
0
    return true;
1863
0
  }
Unexecuted instantiation: bool OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::collect_class<hb_set_t>(hb_set_t*, unsigned int) const
Unexecuted instantiation: bool OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::collect_class<hb_set_t>(hb_set_t*, unsigned int) const
1864
1865
  bool intersects (const hb_set_t *glyphs) const
1866
0
  {
1867
0
    if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
1868
0
    {
1869
0
      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
1870
0
        if (get_class (g))
1871
0
    return true;
1872
0
      return false;
1873
0
    }
1874
0
1875
0
    return hb_any (+ hb_iter (rangeRecord)
1876
0
                   | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs) && range.value; }));
1877
0
  }
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::intersects(hb_set_t const*) const
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::intersects(hb_set_t const*) const
1878
  bool intersects_class (const hb_set_t *glyphs, uint16_t klass) const
1879
0
  {
1880
0
    if (klass == 0)
1881
0
    {
1882
      /* Match if there's any glyph that is not listed! */
1883
0
      hb_codepoint_t g = HB_SET_VALUE_INVALID;
1884
0
      for (auto &range : rangeRecord)
1885
0
      {
1886
0
  if (!glyphs->next (&g))
1887
0
    break;
1888
0
  if (g < range.first)
1889
0
    return true;
1890
0
  g = range.last;
1891
0
      }
1892
0
      if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
1893
0
  return true;
1894
      /* Fall through. */
1895
0
    }
1896
0
    for (const auto &range : rangeRecord)
1897
0
      if (range.value == klass && range.intersects (*glyphs))
1898
0
  return true;
1899
0
    return false;
1900
0
  }
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::intersects_class(hb_set_t const*, unsigned short) const
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::intersects_class(hb_set_t const*, unsigned short) const
1901
1902
  void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const
1903
0
  {
1904
0
    if (klass == 0)
1905
0
    {
1906
0
      hb_codepoint_t g = HB_SET_VALUE_INVALID;
1907
0
      for (auto &range : rangeRecord)
1908
0
      {
1909
0
  if (!glyphs->next (&g))
1910
0
    goto done;
1911
0
  while (g < range.first)
1912
0
  {
1913
0
    intersect_glyphs->add (g);
1914
0
    if (!glyphs->next (&g))
1915
0
      goto done;
1916
0
        }
1917
0
        g = range.last;
1918
0
      }
1919
0
      while (glyphs->next (&g))
1920
0
  intersect_glyphs->add (g);
1921
0
      done:
1922
1923
0
      return;
1924
0
    }
1925
1926
0
    unsigned count = rangeRecord.len;
1927
0
    if (count > glyphs->get_population () * hb_bit_storage (count) * 8)
1928
0
    {
1929
0
      for (hb_codepoint_t g = HB_SET_VALUE_INVALID;
1930
0
     glyphs->next (&g);)
1931
0
      {
1932
0
        unsigned i;
1933
0
        if (rangeRecord.as_array ().bfind (g, &i) &&
1934
0
      rangeRecord.arrayZ[i].value == klass)
1935
0
    intersect_glyphs->add (g);
1936
0
      }
1937
0
      return;
1938
0
    }
1939
1940
0
    for (auto &range : rangeRecord)
1941
0
    {
1942
0
      if (range.value != klass) continue;
1943
1944
0
      unsigned end = range.last + 1;
1945
0
      for (hb_codepoint_t g = range.first - 1;
1946
0
     glyphs->next (&g) && g < end;)
1947
0
  intersect_glyphs->add (g);
1948
0
    }
1949
0
  }
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::intersected_class_glyphs(hb_set_t const*, unsigned int, hb_set_t*) const
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::intersected_class_glyphs(hb_set_t const*, unsigned int, hb_set_t*) const
1950
1951
  void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
1952
0
  {
1953
0
    if (glyphs->is_empty ()) return;
1954
0
1955
0
    hb_codepoint_t g = HB_SET_VALUE_INVALID;
1956
0
    for (auto &range : rangeRecord)
1957
0
    {
1958
0
      if (!glyphs->next (&g))
1959
0
        break;
1960
0
      if (g < range.first)
1961
0
      {
1962
0
        intersect_classes->add (0);
1963
0
        break;
1964
0
      }
1965
0
      g = range.last;
1966
0
    }
1967
0
    if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
1968
0
      intersect_classes->add (0);
1969
0
1970
0
    for (const auto& range : rangeRecord)
1971
0
      if (range.intersects (*glyphs))
1972
0
        intersect_classes->add (range.value);
1973
0
  }
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::SmallTypes>::intersected_classes(hb_set_t const*, hb_set_t*) const
Unexecuted instantiation: OT::ClassDefFormat2_4<OT::Layout::MediumTypes>::intersected_classes(hb_set_t const*, hb_set_t*) const
1974
1975
  protected:
1976
  HBUINT16  classFormat;  /* Format identifier--format = 2 */
1977
  typename Types::template SortedArrayOf<RangeRecord<Types>>
1978
    rangeRecord;  /* Array of glyph ranges--ordered by
1979
         * Start GlyphID */
1980
  public:
1981
  DEFINE_SIZE_ARRAY (2 + Types::size, rangeRecord);
1982
};
1983
1984
struct ClassDef
1985
{
1986
  /* Has interface. */
1987
0
  unsigned operator [] (hb_codepoint_t k) const { return get (k); }
1988
0
  bool has (hb_codepoint_t k) const { return (*this)[k]; }
1989
  /* Projection. */
1990
0
  hb_codepoint_t operator () (hb_codepoint_t k) const { return get (k); }
1991
1992
0
  unsigned int get (hb_codepoint_t k) const { return get_class (k); }
1993
  unsigned int get_class (hb_codepoint_t glyph_id) const
1994
1.27M
  {
1995
1.27M
    switch (u.format) {
1996
102k
    case 1: return u.format1.get_class (glyph_id);
1997
306k
    case 2: return u.format2.get_class (glyph_id);
1998
0
#ifndef HB_NO_BEYOND_64K
1999
0
    case 3: return u.format3.get_class (glyph_id);
2000
2.08k
    case 4: return u.format4.get_class (glyph_id);
2001
0
#endif
2002
865k
    default:return 0;
2003
1.27M
    }
2004
1.27M
  }
2005
2006
  unsigned get_population () const
2007
0
  {
2008
0
    switch (u.format) {
2009
0
    case 1: return u.format1.get_population ();
2010
0
    case 2: return u.format2.get_population ();
2011
0
#ifndef HB_NO_BEYOND_64K
2012
0
    case 3: return u.format3.get_population ();
2013
0
    case 4: return u.format4.get_population ();
2014
0
#endif
2015
0
    default:return NOT_COVERED;
2016
0
    }
2017
0
  }
2018
2019
  template<typename Iterator,
2020
     hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
2021
  bool serialize (hb_serialize_context_t *c, Iterator it_with_class_zero)
2022
0
  {
2023
0
    TRACE_SERIALIZE (this);
2024
0
    if (unlikely (!c->extend_min (this))) return_trace (false);
2025
0
2026
0
    auto it = + it_with_class_zero | hb_filter (hb_second);
2027
0
2028
0
    unsigned format = 2;
2029
0
    hb_codepoint_t glyph_max = 0;
2030
0
    if (likely (it))
2031
0
    {
2032
0
      hb_codepoint_t glyph_min = (*it).first;
2033
0
      glyph_max = glyph_min;
2034
0
2035
0
      unsigned num_glyphs = 0;
2036
0
      unsigned num_ranges = 1;
2037
0
      hb_codepoint_t prev_gid = glyph_min;
2038
0
      unsigned prev_klass = (*it).second;
2039
0
2040
0
      for (const auto gid_klass_pair : it)
2041
0
      {
2042
0
  hb_codepoint_t cur_gid = gid_klass_pair.first;
2043
0
  unsigned cur_klass = gid_klass_pair.second;
2044
0
        num_glyphs++;
2045
0
  if (cur_gid == glyph_min) continue;
2046
0
        if (cur_gid > glyph_max) glyph_max = cur_gid;
2047
0
  if (cur_gid != prev_gid + 1 ||
2048
0
      cur_klass != prev_klass)
2049
0
    num_ranges++;
2050
0
2051
0
  prev_gid = cur_gid;
2052
0
  prev_klass = cur_klass;
2053
0
      }
2054
0
2055
0
      if (num_glyphs && 1 + (glyph_max - glyph_min + 1) <= num_ranges * 3)
2056
0
  format = 1;
2057
0
    }
2058
0
2059
0
#ifndef HB_NO_BEYOND_64K
2060
0
    if (glyph_max > 0xFFFFu)
2061
0
      format += 2;
2062
0
#endif
2063
0
2064
0
    u.format = format;
2065
0
2066
0
    switch (u.format)
2067
0
    {
2068
0
    case 1: return_trace (u.format1.serialize (c, it));
2069
0
    case 2: return_trace (u.format2.serialize (c, it));
2070
0
#ifndef HB_NO_BEYOND_64K
2071
0
    case 3: return_trace (u.format3.serialize (c, it));
2072
0
    case 4: return_trace (u.format4.serialize (c, it));
2073
0
#endif
2074
0
    default:return_trace (false);
2075
0
    }
2076
0
  }
2077
2078
  bool subset (hb_subset_context_t *c,
2079
         hb_map_t *klass_map = nullptr /*OUT*/,
2080
               bool keep_empty_table = true,
2081
               bool use_class_zero = true,
2082
               const Coverage* glyph_filter = nullptr) const
2083
0
  {
2084
0
    TRACE_SUBSET (this);
2085
0
    switch (u.format) {
2086
0
    case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
2087
0
    case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
2088
0
#ifndef HB_NO_BEYOND_64K
2089
0
    case 3: return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
2090
0
    case 4: return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
2091
0
#endif
2092
0
    default:return_trace (false);
2093
0
    }
2094
0
  }
2095
2096
  bool sanitize (hb_sanitize_context_t *c) const
2097
31.6k
  {
2098
31.6k
    TRACE_SANITIZE (this);
2099
31.6k
    if (!u.format.sanitize (c)) return_trace (false);
2100
31.2k
    switch (u.format) {
2101
7.66k
    case 1: return_trace (u.format1.sanitize (c));
2102
19.2k
    case 2: return_trace (u.format2.sanitize (c));
2103
0
#ifndef HB_NO_BEYOND_64K
2104
0
    case 3: return_trace (u.format3.sanitize (c));
2105
400
    case 4: return_trace (u.format4.sanitize (c));
2106
0
#endif
2107
3.98k
    default:return_trace (true);
2108
31.2k
    }
2109
31.2k
  }
2110
2111
  unsigned cost () const
2112
6.60k
  {
2113
6.60k
    switch (u.format) {
2114
1.34k
    case 1: return u.format1.cost ();
2115
4.50k
    case 2: return u.format2.cost ();
2116
0
#ifndef HB_NO_BEYOND_64K
2117
0
    case 3: return u.format3.cost ();
2118
20
    case 4: return u.format4.cost ();
2119
0
#endif
2120
740
    default:return 0u;
2121
6.60k
    }
2122
6.60k
  }
2123
2124
  /* Might return false if array looks unsorted.
2125
   * Used for faster rejection of corrupt data. */
2126
  template <typename set_t>
2127
  bool collect_coverage (set_t *glyphs) const
2128
0
  {
2129
0
    switch (u.format) {
2130
0
    case 1: return u.format1.collect_coverage (glyphs);
2131
0
    case 2: return u.format2.collect_coverage (glyphs);
2132
0
#ifndef HB_NO_BEYOND_64K
2133
0
    case 3: return u.format3.collect_coverage (glyphs);
2134
0
    case 4: return u.format4.collect_coverage (glyphs);
2135
0
#endif
2136
0
    default:return false;
2137
0
    }
2138
0
  }
2139
2140
  /* Might return false if array looks unsorted.
2141
   * Used for faster rejection of corrupt data. */
2142
  template <typename set_t>
2143
  bool collect_class (set_t *glyphs, unsigned int klass) const
2144
0
  {
2145
0
    switch (u.format) {
2146
0
    case 1: return u.format1.collect_class (glyphs, klass);
2147
0
    case 2: return u.format2.collect_class (glyphs, klass);
2148
0
#ifndef HB_NO_BEYOND_64K
2149
0
    case 3: return u.format3.collect_class (glyphs, klass);
2150
0
    case 4: return u.format4.collect_class (glyphs, klass);
2151
0
#endif
2152
0
    default:return false;
2153
0
    }
2154
0
  }
2155
2156
  bool intersects (const hb_set_t *glyphs) const
2157
0
  {
2158
0
    switch (u.format) {
2159
0
    case 1: return u.format1.intersects (glyphs);
2160
0
    case 2: return u.format2.intersects (glyphs);
2161
0
#ifndef HB_NO_BEYOND_64K
2162
0
    case 3: return u.format3.intersects (glyphs);
2163
0
    case 4: return u.format4.intersects (glyphs);
2164
0
#endif
2165
0
    default:return false;
2166
0
    }
2167
0
  }
2168
  bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const
2169
0
  {
2170
0
    switch (u.format) {
2171
0
    case 1: return u.format1.intersects_class (glyphs, klass);
2172
0
    case 2: return u.format2.intersects_class (glyphs, klass);
2173
0
#ifndef HB_NO_BEYOND_64K
2174
0
    case 3: return u.format3.intersects_class (glyphs, klass);
2175
0
    case 4: return u.format4.intersects_class (glyphs, klass);
2176
0
#endif
2177
0
    default:return false;
2178
0
    }
2179
0
  }
2180
2181
  void intersected_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) const
2182
0
  {
2183
0
    switch (u.format) {
2184
0
    case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
2185
0
    case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
2186
0
#ifndef HB_NO_BEYOND_64K
2187
0
    case 3: return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
2188
0
    case 4: return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
2189
0
#endif
2190
0
    default:return;
2191
0
    }
2192
0
  }
2193
2194
  void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
2195
0
  {
2196
0
    switch (u.format) {
2197
0
    case 1: return u.format1.intersected_classes (glyphs, intersect_classes);
2198
0
    case 2: return u.format2.intersected_classes (glyphs, intersect_classes);
2199
0
#ifndef HB_NO_BEYOND_64K
2200
0
    case 3: return u.format3.intersected_classes (glyphs, intersect_classes);
2201
0
    case 4: return u.format4.intersected_classes (glyphs, intersect_classes);
2202
0
#endif
2203
0
    default:return;
2204
0
    }
2205
0
  }
2206
2207
2208
  protected:
2209
  union {
2210
  HBUINT16      format;   /* Format identifier */
2211
  ClassDefFormat1_3<SmallTypes> format1;
2212
  ClassDefFormat2_4<SmallTypes> format2;
2213
#ifndef HB_NO_BEYOND_64K
2214
  ClassDefFormat1_3<MediumTypes>format3;
2215
  ClassDefFormat2_4<MediumTypes>format4;
2216
#endif
2217
  } u;
2218
  public:
2219
  DEFINE_SIZE_UNION (2, format);
2220
};
2221
2222
template<typename Iterator>
2223
static inline bool ClassDef_serialize (hb_serialize_context_t *c,
2224
               Iterator it)
2225
0
{ return (c->start_embed<ClassDef> ()->serialize (c, it)); }
Unexecuted instantiation: hb-aat-layout.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-common.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-face.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-font.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-color.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-face.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-font.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-layout.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-math.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-metrics.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-var.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-cff1-table.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-cff2-table.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-shaper-arabic.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
Unexecuted instantiation: hb-ot-shape-fallback.cc:bool OT::ClassDef_serialize<hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const> >(hb_serialize_context_t*, hb_sorted_array_t<hb_pair_t<unsigned int, unsigned int> const>)
2226
2227
2228
/*
2229
 * Item Variation Store
2230
 */
2231
2232
struct VarRegionAxis
2233
{
2234
  float evaluate (int coord) const
2235
7.42k
  {
2236
7.42k
    int start = startCoord.to_int (), peak = peakCoord.to_int (), end = endCoord.to_int ();
2237
2238
    /* TODO Move these to sanitize(). */
2239
7.42k
    if (unlikely (start > peak || peak > end))
2240
0
      return 1.;
2241
7.42k
    if (unlikely (start < 0 && end > 0 && peak != 0))
2242
0
      return 1.;
2243
2244
7.42k
    if (peak == 0 || coord == peak)
2245
4.40k
      return 1.;
2246
2247
3.02k
    if (coord <= start || end <= coord)
2248
2.46k
      return 0.;
2249
2250
    /* Interpolate */
2251
560
    if (coord < peak)
2252
60
      return float (coord - start) / (peak - start);
2253
500
    else
2254
500
      return float (end - coord) / (end - peak);
2255
560
  }
2256
2257
  bool sanitize (hb_sanitize_context_t *c) const
2258
0
  {
2259
0
    TRACE_SANITIZE (this);
2260
0
    return_trace (c->check_struct (this));
2261
0
    /* TODO Handle invalid start/peak/end configs, so we don't
2262
0
     * have to do that at runtime. */
2263
0
  }
2264
2265
  public:
2266
  F2DOT14 startCoord;
2267
  F2DOT14 peakCoord;
2268
  F2DOT14 endCoord;
2269
  public:
2270
  DEFINE_SIZE_STATIC (6);
2271
};
2272
2273
6.42k
#define REGION_CACHE_ITEM_CACHE_INVALID 2.f
2274
2275
struct VarRegionList
2276
{
2277
  using cache_t = float;
2278
2279
  float evaluate (unsigned int region_index,
2280
      const int *coords, unsigned int coord_len,
2281
      cache_t *cache = nullptr) const
2282
2.84k
  {
2283
2.84k
    if (unlikely (region_index >= regionCount))
2284
0
      return 0.;
2285
2286
2.84k
    float *cached_value = nullptr;
2287
2.84k
    if (cache)
2288
0
    {
2289
0
      cached_value = &(cache[region_index]);
2290
0
      if (likely (*cached_value != REGION_CACHE_ITEM_CACHE_INVALID))
2291
0
  return *cached_value;
2292
0
    }
2293
2294
2.84k
    const VarRegionAxis *axes = axesZ.arrayZ + (region_index * axisCount);
2295
2296
2.84k
    float v = 1.;
2297
2.84k
    unsigned int count = axisCount;
2298
7.80k
    for (unsigned int i = 0; i < count; i++)
2299
7.42k
    {
2300
7.42k
      int coord = i < coord_len ? coords[i] : 0;
2301
7.42k
      float factor = axes[i].evaluate (coord);
2302
7.42k
      if (factor == 0.f)
2303
2.46k
      {
2304
2.46k
        if (cache)
2305
0
    *cached_value = 0.;
2306
2.46k
  return 0.;
2307
2.46k
      }
2308
4.96k
      v *= factor;
2309
4.96k
    }
2310
2311
380
    if (cache)
2312
0
      *cached_value = v;
2313
380
    return v;
2314
2.84k
  }
2315
2316
  bool sanitize (hb_sanitize_context_t *c) const
2317
2.92k
  {
2318
2.92k
    TRACE_SANITIZE (this);
2319
2.92k
    return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount));
2320
2.92k
  }
2321
2322
  bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_bimap_t &region_map)
2323
0
  {
2324
0
    TRACE_SERIALIZE (this);
2325
0
    if (unlikely (!c->extend_min (this))) return_trace (false);
2326
0
    axisCount = src->axisCount;
2327
0
    regionCount = region_map.get_population ();
2328
0
    if (unlikely (hb_unsigned_mul_overflows (axisCount * regionCount,
2329
0
               VarRegionAxis::static_size))) return_trace (false);
2330
0
    if (unlikely (!c->extend (this))) return_trace (false);
2331
0
    unsigned int region_count = src->regionCount;
2332
0
    for (unsigned int r = 0; r < regionCount; r++)
2333
0
    {
2334
0
      unsigned int backward = region_map.backward (r);
2335
0
      if (backward >= region_count) return_trace (false);
2336
0
      hb_memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * backward], VarRegionAxis::static_size * axisCount);
2337
0
    }
2338
0
2339
0
    return_trace (true);
2340
0
  }
2341
2342
0
  unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; }
2343
2344
  public:
2345
  HBUINT16  axisCount;
2346
  HBUINT15  regionCount;
2347
  protected:
2348
  UnsizedArrayOf<VarRegionAxis>
2349
    axesZ;
2350
  public:
2351
  DEFINE_SIZE_ARRAY (4, axesZ);
2352
};
2353
2354
struct VarData
2355
{
2356
  unsigned int get_item_count () const
2357
0
  { return itemCount; }
2358
2359
  unsigned int get_region_index_count () const
2360
360
  { return regionIndices.len; }
2361
2362
  unsigned int get_row_size () const
2363
5.52k
  { return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); }
2364
2365
  unsigned int get_size () const
2366
0
  { return min_size
2367
0
   - regionIndices.min_size + regionIndices.get_size ()
2368
0
   + itemCount * get_row_size ();
2369
0
  }
2370
2371
  float get_delta (unsigned int inner,
2372
       const int *coords, unsigned int coord_count,
2373
       const VarRegionList &regions,
2374
       VarRegionList::cache_t *cache = nullptr) const
2375
1.10k
  {
2376
1.10k
    if (unlikely (inner >= itemCount))
2377
0
      return 0.;
2378
2379
1.10k
   unsigned int count = regionIndices.len;
2380
1.10k
   bool is_long = longWords ();
2381
1.10k
   unsigned word_count = wordCount ();
2382
1.10k
   unsigned int scount = is_long ? count : word_count;
2383
1.10k
   unsigned int lcount = is_long ? word_count : 0;
2384
2385
1.10k
   const HBUINT8 *bytes = get_delta_bytes ();
2386
1.10k
   const HBUINT8 *row = bytes + inner * get_row_size ();
2387
2388
1.10k
   float delta = 0.;
2389
1.10k
   unsigned int i = 0;
2390
2391
1.10k
   const HBINT32 *lcursor = reinterpret_cast<const HBINT32 *> (row);
2392
1.10k
   for (; i < lcount; i++)
2393
0
   {
2394
0
     float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
2395
0
     delta += scalar * *lcursor++;
2396
0
   }
2397
1.10k
   const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (lcursor);
2398
1.30k
   for (; i < scount; i++)
2399
200
   {
2400
200
     float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
2401
200
     delta += scalar * *scursor++;
2402
200
   }
2403
1.10k
   const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor);
2404
3.74k
   for (; i < count; i++)
2405
2.64k
   {
2406
2.64k
     float scalar = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count, cache);
2407
2.64k
     delta += scalar * *bcursor++;
2408
2.64k
   }
2409
2410
1.10k
   return delta;
2411
1.10k
  }
2412
2413
  void get_region_scalars (const int *coords, unsigned int coord_count,
2414
         const VarRegionList &regions,
2415
         float *scalars /*OUT */,
2416
         unsigned int num_scalars) const
2417
0
  {
2418
0
    unsigned count = hb_min (num_scalars, regionIndices.len);
2419
0
    for (unsigned int i = 0; i < count; i++)
2420
0
      scalars[i] = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
2421
0
    for (unsigned int i = count; i < num_scalars; i++)
2422
0
      scalars[i] = 0.f;
2423
0
  }
2424
2425
  bool sanitize (hb_sanitize_context_t *c) const
2426
4.42k
  {
2427
4.42k
    TRACE_SANITIZE (this);
2428
4.42k
    return_trace (c->check_struct (this) &&
2429
4.42k
      regionIndices.sanitize (c) &&
2430
4.42k
      wordCount () <= regionIndices.len &&
2431
4.42k
      c->check_range (get_delta_bytes (),
2432
4.42k
          itemCount,
2433
4.42k
          get_row_size ()));
2434
4.42k
  }
2435
2436
  bool serialize (hb_serialize_context_t *c,
2437
      const VarData *src,
2438
      const hb_inc_bimap_t &inner_map,
2439
      const hb_bimap_t &region_map)
2440
0
  {
2441
0
    TRACE_SERIALIZE (this);
2442
0
    if (unlikely (!c->extend_min (this))) return_trace (false);
2443
0
    itemCount = inner_map.get_next_value ();
2444
0
2445
0
    /* Optimize word count */
2446
0
    unsigned ri_count = src->regionIndices.len;
2447
0
    enum delta_size_t { kZero=0, kNonWord, kWord };
2448
0
    hb_vector_t<delta_size_t> delta_sz;
2449
0
    hb_vector_t<unsigned int> ri_map; /* maps new index to old index */
2450
0
    delta_sz.resize (ri_count);
2451
0
    ri_map.resize (ri_count);
2452
0
    unsigned int new_word_count = 0;
2453
0
    unsigned int r;
2454
0
2455
0
    const HBUINT8 *src_delta_bytes = src->get_delta_bytes ();
2456
0
    unsigned src_row_size = src->get_row_size ();
2457
0
    unsigned src_word_count = src->wordCount ();
2458
0
    bool     src_long_words = src->longWords ();
2459
0
2460
0
    bool has_long = false;
2461
0
    if (src_long_words)
2462
0
    {
2463
0
      for (r = 0; r < src_word_count; r++)
2464
0
      {
2465
0
  for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
2466
0
  {
2467
0
    unsigned int old = inner_map.backward (i);
2468
0
    int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
2469
0
    if (delta < -65536 || 65535 < delta)
2470
0
    {
2471
0
      has_long = true;
2472
0
      break;
2473
0
    }
2474
0
        }
2475
0
      }
2476
0
    }
2477
0
2478
0
    signed min_threshold = has_long ? -65536 : -128;
2479
0
    signed max_threshold = has_long ? +65535 : +127;
2480
0
    for (r = 0; r < ri_count; r++)
2481
0
    {
2482
0
      bool short_circuit = src_long_words == has_long && src_word_count <= r;
2483
0
2484
0
      delta_sz[r] = kZero;
2485
0
      for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
2486
0
      {
2487
0
  unsigned int old = inner_map.backward (i);
2488
0
  int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
2489
0
  if (delta < min_threshold || max_threshold < delta)
2490
0
  {
2491
0
    delta_sz[r] = kWord;
2492
0
    new_word_count++;
2493
0
    break;
2494
0
  }
2495
0
  else if (delta != 0)
2496
0
  {
2497
0
    delta_sz[r] = kNonWord;
2498
0
    if (short_circuit)
2499
0
      break;
2500
0
  }
2501
0
      }
2502
0
    }
2503
0
2504
0
    unsigned int word_index = 0;
2505
0
    unsigned int non_word_index = new_word_count;
2506
0
    unsigned int new_ri_count = 0;
2507
0
    for (r = 0; r < ri_count; r++)
2508
0
      if (delta_sz[r])
2509
0
      {
2510
0
  unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
2511
0
  ri_map[new_r] = r;
2512
0
  new_ri_count++;
2513
0
      }
2514
0
2515
0
    wordSizeCount = new_word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0);
2516
0
2517
0
    regionIndices.len = new_ri_count;
2518
0
2519
0
    if (unlikely (!c->extend (this))) return_trace (false);
2520
0
2521
0
    for (r = 0; r < new_ri_count; r++)
2522
0
      regionIndices[r] = region_map[src->regionIndices[ri_map[r]]];
2523
0
2524
0
    HBUINT8 *delta_bytes = get_delta_bytes ();
2525
0
    unsigned row_size = get_row_size ();
2526
0
    unsigned count = itemCount;
2527
0
    for (unsigned int i = 0; i < count; i++)
2528
0
    {
2529
0
      unsigned int old = inner_map.backward (i);
2530
0
      for (unsigned int r = 0; r < new_ri_count; r++)
2531
0
  set_item_delta_fast (i, r,
2532
0
           src->get_item_delta_fast (old, ri_map[r],
2533
0
                   src_delta_bytes, src_row_size),
2534
0
           delta_bytes, row_size);
2535
0
    }
2536
0
2537
0
    return_trace (true);
2538
0
  }
2539
2540
  void collect_region_refs (hb_set_t &region_indices, const hb_inc_bimap_t &inner_map) const
2541
0
  {
2542
0
    const HBUINT8 *delta_bytes = get_delta_bytes ();
2543
0
    unsigned row_size = get_row_size ();
2544
0
2545
0
    for (unsigned int r = 0; r < regionIndices.len; r++)
2546
0
    {
2547
0
      unsigned int region = regionIndices.arrayZ[r];
2548
0
      if (region_indices.has (region)) continue;
2549
0
      for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
2550
0
  if (get_item_delta_fast (inner_map.backward (i), r, delta_bytes, row_size) != 0)
2551
0
  {
2552
0
    region_indices.add (region);
2553
0
    break;
2554
0
  }
2555
0
    }
2556
0
  }
2557
2558
  protected:
2559
  const HBUINT8 *get_delta_bytes () const
2560
5.52k
  { return &StructAfter<HBUINT8> (regionIndices); }
2561
2562
  HBUINT8 *get_delta_bytes ()
2563
0
  { return &StructAfter<HBUINT8> (regionIndices); }
2564
2565
  int32_t get_item_delta_fast (unsigned int item, unsigned int region,
2566
             const HBUINT8 *delta_bytes, unsigned row_size) const
2567
0
  {
2568
0
    if (unlikely (item >= itemCount || region >= regionIndices.len)) return 0;
2569
0
2570
0
    const HBINT8 *p = (const HBINT8 *) delta_bytes + item * row_size;
2571
0
    unsigned word_count = wordCount ();
2572
0
    bool is_long = longWords ();
2573
0
    if (is_long)
2574
0
    {
2575
0
      if (region < word_count)
2576
0
  return ((const HBINT32 *) p)[region];
2577
0
      else
2578
0
  return ((const HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count];
2579
0
    }
2580
0
    else
2581
0
    {
2582
0
      if (region < word_count)
2583
0
  return ((const HBINT16 *) p)[region];
2584
0
      else
2585
0
  return (p + HBINT16::static_size * word_count)[region - word_count];
2586
0
    }
2587
0
  }
2588
  int32_t get_item_delta (unsigned int item, unsigned int region) const
2589
0
  {
2590
0
     return get_item_delta_fast (item, region,
2591
0
         get_delta_bytes (),
2592
0
         get_row_size ());
2593
0
  }
2594
2595
  void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta,
2596
          HBUINT8 *delta_bytes, unsigned row_size)
2597
0
  {
2598
0
    HBINT8 *p = (HBINT8 *) delta_bytes + item * row_size;
2599
0
    unsigned word_count = wordCount ();
2600
0
    bool is_long = longWords ();
2601
0
    if (is_long)
2602
0
    {
2603
0
      if (region < word_count)
2604
0
  ((HBINT32 *) p)[region] = delta;
2605
0
      else
2606
0
  ((HBINT16 *)(p + HBINT32::static_size * word_count))[region - word_count] = delta;
2607
0
    }
2608
0
    else
2609
0
    {
2610
0
      if (region < word_count)
2611
0
  ((HBINT16 *) p)[region] = delta;
2612
0
      else
2613
0
  (p + HBINT16::static_size * word_count)[region - word_count] = delta;
2614
0
    }
2615
0
  }
2616
  void set_item_delta (unsigned int item, unsigned int region, int32_t delta)
2617
0
  {
2618
0
    set_item_delta_fast (item, region, delta,
2619
0
       get_delta_bytes (),
2620
0
       get_row_size ());
2621
0
  }
2622
2623
6.62k
  bool longWords () const { return wordSizeCount & 0x8000u /* LONG_WORDS */; }
2624
11.0k
  unsigned wordCount () const { return wordSizeCount & 0x7FFFu /* WORD_DELTA_COUNT_MASK */; }
2625
2626
  protected:
2627
  HBUINT16    itemCount;
2628
  HBUINT16    wordSizeCount;
2629
  Array16Of<HBUINT16> regionIndices;
2630
/*UnsizedArrayOf<HBUINT8>bytesX;*/
2631
  public:
2632
  DEFINE_SIZE_ARRAY (6, regionIndices);
2633
};
2634
2635
struct VariationStore
2636
{
2637
  using cache_t = VarRegionList::cache_t;
2638
2639
  cache_t *create_cache () const
2640
2.20k
  {
2641
#ifdef HB_NO_VAR
2642
    return nullptr;
2643
#endif
2644
2.20k
    auto &r = this+regions;
2645
2.20k
    unsigned count = r.regionCount;
2646
2647
2.20k
    float *cache = (float *) hb_malloc (sizeof (float) * count);
2648
2.20k
    if (unlikely (!cache)) return nullptr;
2649
2650
6.42k
    for (unsigned i = 0; i < count; i++)
2651
4.24k
      cache[i] = REGION_CACHE_ITEM_CACHE_INVALID;
2652
2653
2.18k
    return cache;
2654
2.20k
  }
2655
2656
983k
  static void destroy_cache (cache_t *cache) { hb_free (cache); }
2657
2658
  private:
2659
  float get_delta (unsigned int outer, unsigned int inner,
2660
       const int *coords, unsigned int coord_count,
2661
       VarRegionList::cache_t *cache = nullptr) const
2662
1.14k
  {
2663
#ifdef HB_NO_VAR
2664
    return 0.f;
2665
#endif
2666
2667
1.14k
    if (unlikely (outer >= dataSets.len))
2668
40
      return 0.f;
2669
2670
1.10k
    return (this+dataSets[outer]).get_delta (inner,
2671
1.10k
               coords, coord_count,
2672
1.10k
               this+regions,
2673
1.10k
               cache);
2674
1.14k
  }
2675
2676
  public:
2677
  float get_delta (unsigned int index,
2678
       const int *coords, unsigned int coord_count,
2679
       VarRegionList::cache_t *cache = nullptr) const
2680
1.14k
  {
2681
1.14k
    unsigned int outer = index >> 16;
2682
1.14k
    unsigned int inner = index & 0xFFFF;
2683
1.14k
    return get_delta (outer, inner, coords, coord_count, cache);
2684
1.14k
  }
2685
  float get_delta (unsigned int index,
2686
       hb_array_t<int> coords,
2687
       VarRegionList::cache_t *cache = nullptr) const
2688
0
  {
2689
0
    return get_delta (index,
2690
0
          coords.arrayZ, coords.length,
2691
0
          cache);
2692
0
  }
2693
2694
  bool sanitize (hb_sanitize_context_t *c) const
2695
3.26k
  {
2696
#ifdef HB_NO_VAR
2697
    return true;
2698
#endif
2699
2700
3.26k
    TRACE_SANITIZE (this);
2701
3.26k
    return_trace (c->check_struct (this) &&
2702
3.26k
      format == 1 &&
2703
3.26k
      regions.sanitize (c, this) &&
2704
3.26k
      dataSets.sanitize (c, this));
2705
3.26k
  }
2706
2707
  bool serialize (hb_serialize_context_t *c,
2708
      const VariationStore *src,
2709
      const hb_array_t <const hb_inc_bimap_t> &inner_maps)
2710
0
  {
2711
0
    TRACE_SERIALIZE (this);
2712
0
#ifdef HB_NO_VAR
2713
0
    return_trace (false);
2714
0
#endif
2715
0
2716
0
    if (unlikely (!c->extend_min (this))) return_trace (false);
2717
0
2718
0
    unsigned int set_count = 0;
2719
0
    for (unsigned int i = 0; i < inner_maps.length; i++)
2720
0
      if (inner_maps[i].get_population ())
2721
0
  set_count++;
2722
0
2723
0
    format = 1;
2724
0
2725
0
    const auto &src_regions = src+src->regions;
2726
0
2727
0
    hb_set_t region_indices;
2728
0
    for (unsigned int i = 0; i < inner_maps.length; i++)
2729
0
      (src+src->dataSets[i]).collect_region_refs (region_indices, inner_maps[i]);
2730
0
2731
0
    if (region_indices.in_error ())
2732
0
      return_trace (false);
2733
0
2734
0
    region_indices.del_range ((src_regions).regionCount, hb_set_t::INVALID);
2735
0
2736
0
    /* TODO use constructor when our data-structures support that. */
2737
0
    hb_inc_bimap_t region_map;
2738
0
    + hb_iter (region_indices)
2739
0
    | hb_apply ([&region_map] (unsigned _) { region_map.add(_); })
2740
0
    ;
2741
0
    if (region_map.in_error())
2742
0
      return_trace (false);
2743
0
2744
0
    if (unlikely (!regions.serialize_serialize (c, &src_regions, region_map)))
2745
0
      return_trace (false);
2746
0
2747
0
    dataSets.len = set_count;
2748
0
    if (unlikely (!c->extend (dataSets))) return_trace (false);
2749
0
2750
0
    /* TODO: The following code could be simplified when
2751
0
     * List16OfOffset16To::subset () can take a custom param to be passed to VarData::serialize () */
2752
0
    unsigned int set_index = 0;
2753
0
    for (unsigned int i = 0; i < inner_maps.length; i++)
2754
0
    {
2755
0
      if (!inner_maps[i].get_population ()) continue;
2756
0
      if (unlikely (!dataSets[set_index++]
2757
0
         .serialize_serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map)))
2758
0
  return_trace (false);
2759
0
    }
2760
0
2761
0
    return_trace (true);
2762
0
  }
2763
2764
  VariationStore *copy (hb_serialize_context_t *c) const
2765
0
  {
2766
0
    TRACE_SERIALIZE (this);
2767
0
    auto *out = c->start_embed (this);
2768
0
    if (unlikely (!out)) return_trace (nullptr);
2769
0
2770
0
    hb_vector_t <hb_inc_bimap_t> inner_maps;
2771
0
    unsigned count = dataSets.len;
2772
0
    for (unsigned i = 0; i < count; i++)
2773
0
    {
2774
0
      hb_inc_bimap_t *map = inner_maps.push ();
2775
0
      auto &data = this+dataSets[i];
2776
0
2777
0
      unsigned itemCount = data.get_item_count ();
2778
0
      for (unsigned j = 0; j < itemCount; j++)
2779
0
  map->add (j);
2780
0
    }
2781
0
2782
0
    if (unlikely (!out->serialize (c, this, inner_maps))) return_trace (nullptr);
2783
0
2784
0
    return_trace (out);
2785
0
  }
2786
2787
  bool subset (hb_subset_context_t *c, const hb_array_t<const hb_inc_bimap_t> &inner_maps) const
2788
0
  {
2789
0
    TRACE_SUBSET (this);
2790
0
#ifdef HB_NO_VAR
2791
0
    return_trace (false);
2792
0
#endif
2793
0
2794
0
    VariationStore *varstore_prime = c->serializer->start_embed<VariationStore> ();
2795
0
    if (unlikely (!varstore_prime)) return_trace (false);
2796
0
2797
0
    varstore_prime->serialize (c->serializer, this, inner_maps);
2798
0
2799
0
    return_trace (
2800
0
        !c->serializer->in_error()
2801
0
        && varstore_prime->dataSets);
2802
0
  }
2803
2804
  unsigned int get_region_index_count (unsigned int major) const
2805
360
  {
2806
#ifdef HB_NO_VAR
2807
    return 0;
2808
#endif
2809
360
    return (this+dataSets[major]).get_region_index_count ();
2810
360
  }
2811
2812
  void get_region_scalars (unsigned int major,
2813
         const int *coords, unsigned int coord_count,
2814
         float *scalars /*OUT*/,
2815
         unsigned int num_scalars) const
2816
0
  {
2817
#ifdef HB_NO_VAR
2818
    for (unsigned i = 0; i < num_scalars; i++)
2819
      scalars[i] = 0.f;
2820
    return;
2821
#endif
2822
2823
0
    (this+dataSets[major]).get_region_scalars (coords, coord_count,
2824
0
                 this+regions,
2825
0
                 &scalars[0], num_scalars);
2826
0
  }
2827
2828
  unsigned int get_sub_table_count () const
2829
0
   {
2830
0
#ifdef HB_NO_VAR
2831
0
     return 0;
2832
0
#endif
2833
0
     return dataSets.len;
2834
0
   }
2835
2836
  protected:
2837
  HBUINT16        format;
2838
  Offset32To<VarRegionList>   regions;
2839
  Array16OfOffset32To<VarData>    dataSets;
2840
  public:
2841
  DEFINE_SIZE_ARRAY_SIZED (8, dataSets);
2842
};
2843
2844
#undef REGION_CACHE_ITEM_CACHE_INVALID
2845
2846
/*
2847
 * Feature Variations
2848
 */
2849
enum Cond_with_Var_flag_t
2850
{
2851
  KEEP_COND_WITH_VAR = 0,
2852
  DROP_COND_WITH_VAR = 1,
2853
  DROP_RECORD_WITH_VAR = 2,
2854
  MEM_ERR_WITH_VAR = 3,
2855
};
2856
2857
struct ConditionFormat1
2858
{
2859
  friend struct Condition;
2860
2861
  bool subset (hb_subset_context_t *c) const
2862
0
  {
2863
0
    TRACE_SUBSET (this);
2864
0
    auto *out = c->serializer->embed (this);
2865
0
    if (unlikely (!out)) return_trace (false);
2866
0
2867
0
    const hb_map_t *index_map = &c->plan->axes_index_map;
2868
0
    if (index_map->is_empty ()) return_trace (true);
2869
0
2870
0
    if (!index_map->has (axisIndex))
2871
0
      return_trace (false);
2872
0
2873
0
    return_trace (c->serializer->check_assign (out->axisIndex, index_map->get (axisIndex),
2874
0
                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
2875
0
  }
2876
2877
  private:
2878
  Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
2879
                                             hb_map_t *condition_map /* OUT */) const
2880
0
  {
2881
0
    //invalid axis index, drop the entire record
2882
0
    if (!c->axes_index_tag_map->has (axisIndex))
2883
0
      return DROP_RECORD_WITH_VAR;
2884
0
2885
0
    hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex);
2886
0
2887
0
    //axis not pinned, keep the condition
2888
0
    if (!c->axes_location->has (axis_tag))
2889
0
    {
2890
0
      // add axisIndex->value into the hashmap so we can check if the record is
2891
0
      // unique with variations
2892
0
      int16_t min_val = filterRangeMinValue.to_int ();
2893
0
      int16_t max_val = filterRangeMaxValue.to_int ();
2894
0
      hb_codepoint_t val = (max_val << 16) + min_val;
2895
0
2896
0
      condition_map->set (axisIndex, val);
2897
0
      return KEEP_COND_WITH_VAR;
2898
0
    }
2899
0
2900
0
    //axis pinned, check if condition is met
2901
0
    //TODO: add check for axis Ranges
2902
0
    int v = c->axes_location->get (axis_tag);
2903
0
2904
0
    //condition not met, drop the entire record
2905
0
    if (v < filterRangeMinValue.to_int () || v > filterRangeMaxValue.to_int ())
2906
0
      return DROP_RECORD_WITH_VAR;
2907
0
2908
0
    //axis pinned and condition met, drop the condition
2909
0
    return DROP_COND_WITH_VAR;
2910
0
  }
2911
2912
  bool evaluate (const int *coords, unsigned int coord_len) const
2913
4.46k
  {
2914
4.46k
    int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
2915
4.46k
    return filterRangeMinValue.to_int () <= coord && coord <= filterRangeMaxValue.to_int ();
2916
4.46k
  }
2917
2918
  bool sanitize (hb_sanitize_context_t *c) const
2919
240
  {
2920
240
    TRACE_SANITIZE (this);
2921
240
    return_trace (c->check_struct (this));
2922
240
  }
2923
2924
  protected:
2925
  HBUINT16  format;   /* Format identifier--format = 1 */
2926
  HBUINT16  axisIndex;
2927
  F2DOT14 filterRangeMinValue;
2928
  F2DOT14 filterRangeMaxValue;
2929
  public:
2930
  DEFINE_SIZE_STATIC (8);
2931
};
2932
2933
struct Condition
2934
{
2935
  bool evaluate (const int *coords, unsigned int coord_len) const
2936
5.36k
  {
2937
5.36k
    switch (u.format) {
2938
4.46k
    case 1: return u.format1.evaluate (coords, coord_len);
2939
900
    default:return false;
2940
5.36k
    }
2941
5.36k
  }
2942
2943
  Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
2944
                                             hb_map_t *condition_map /* OUT */) const
2945
0
  {
2946
0
    switch (u.format) {
2947
0
    case 1: return u.format1.keep_with_variations (c, condition_map);
2948
0
    default:return KEEP_COND_WITH_VAR;
2949
0
    }
2950
0
  }
2951
2952
  template <typename context_t, typename ...Ts>
2953
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
2954
0
  {
2955
0
    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
2956
0
    TRACE_DISPATCH (this, u.format);
2957
0
    switch (u.format) {
2958
0
    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
2959
0
    default:return_trace (c->default_return_value ());
2960
0
    }
2961
0
  }
2962
2963
  bool sanitize (hb_sanitize_context_t *c) const
2964
660
  {
2965
660
    TRACE_SANITIZE (this);
2966
660
    if (!u.format.sanitize (c)) return_trace (false);
2967
580
    switch (u.format) {
2968
240
    case 1: return_trace (u.format1.sanitize (c));
2969
340
    default:return_trace (true);
2970
580
    }
2971
580
  }
2972
2973
  protected:
2974
  union {
2975
  HBUINT16    format;   /* Format identifier */
2976
  ConditionFormat1  format1;
2977
  } u;
2978
  public:
2979
  DEFINE_SIZE_UNION (2, format);
2980
};
2981
2982
struct ConditionSet
2983
{
2984
  bool evaluate (const int *coords, unsigned int coord_len) const
2985
5.92k
  {
2986
5.92k
    unsigned int count = conditions.len;
2987
8.62k
    for (unsigned int i = 0; i < count; i++)
2988
5.36k
      if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len))
2989
2.66k
  return false;
2990
3.26k
    return true;
2991
5.92k
  }
2992
2993
  Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
2994
0
  {
2995
0
    hb_map_t *condition_map = hb_map_create ();
2996
0
    if (unlikely (!condition_map)) return MEM_ERR_WITH_VAR;
2997
0
    hb::shared_ptr<hb_map_t> p {condition_map};
2998
0
2999
0
    hb_set_t *cond_set = hb_set_create ();
3000
0
    if (unlikely (!cond_set)) return MEM_ERR_WITH_VAR;
3001
0
    hb::shared_ptr<hb_set_t> s {cond_set};
3002
0
3003
0
    unsigned num_kept_cond = 0, cond_idx = 0;
3004
0
    for (const auto& offset : conditions)
3005
0
    {
3006
0
      Cond_with_Var_flag_t ret = (this+offset).keep_with_variations (c, condition_map);
3007
0
      // one condition is not met, drop the entire record
3008
0
      if (ret == DROP_RECORD_WITH_VAR)
3009
0
        return DROP_RECORD_WITH_VAR;
3010
0
3011
0
      // axis not pinned, keep this condition
3012
0
      if (ret == KEEP_COND_WITH_VAR)
3013
0
      {
3014
0
        cond_set->add (cond_idx);
3015
0
        num_kept_cond++;
3016
0
      }
3017
0
      cond_idx++;
3018
0
    }
3019
0
3020
0
    // all conditions met
3021
0
    if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
3022
0
3023
0
    //check if condition_set is unique with variations
3024
0
    if (c->conditionset_map->has (p))
3025
0
      //duplicate found, drop the entire record
3026
0
      return DROP_RECORD_WITH_VAR;
3027
0
3028
0
    c->conditionset_map->set (p, 1);
3029
0
    c->record_cond_idx_map->set (c->cur_record_idx, s);
3030
0
3031
0
    return KEEP_COND_WITH_VAR;
3032
0
  }
3033
3034
  bool subset (hb_subset_context_t *c,
3035
               hb_subset_layout_context_t *l) const
3036
0
  {
3037
0
    TRACE_SUBSET (this);
3038
0
    auto *out = c->serializer->start_embed (this);
3039
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
3040
0
3041
0
    hb_set_t *retained_cond_set = nullptr;
3042
0
    if (l->feature_record_cond_idx_map != nullptr)
3043
0
      retained_cond_set = l->feature_record_cond_idx_map->get (l->cur_feature_var_record_idx);
3044
0
3045
0
    unsigned int count = conditions.len;
3046
0
    for (unsigned int i = 0; i < count; i++)
3047
0
    {
3048
0
      if (retained_cond_set != nullptr && !retained_cond_set->has (i))
3049
0
        continue;
3050
0
      subset_offset_array (c, out->conditions, this) (conditions[i]);
3051
0
    }
3052
0
3053
0
    return_trace (bool (out->conditions));
3054
0
  }
3055
3056
  bool sanitize (hb_sanitize_context_t *c) const
3057
500
  {
3058
500
    TRACE_SANITIZE (this);
3059
500
    return_trace (conditions.sanitize (c, this));
3060
500
  }
3061
3062
  protected:
3063
  Array16OfOffset32To<Condition>  conditions;
3064
  public:
3065
  DEFINE_SIZE_ARRAY (2, conditions);
3066
};
3067
3068
struct FeatureTableSubstitutionRecord
3069
{
3070
  friend struct FeatureTableSubstitution;
3071
3072
  void collect_lookups (const void *base, hb_set_t *lookup_indexes /* OUT */) const
3073
0
  {
3074
0
    return (base+feature).add_lookup_indexes_to (lookup_indexes);
3075
0
  }
3076
3077
  void closure_features (const void *base,
3078
       const hb_map_t *lookup_indexes,
3079
       hb_set_t       *feature_indexes /* OUT */) const
3080
0
  {
3081
0
    if ((base+feature).intersects_lookup_indexes (lookup_indexes))
3082
0
      feature_indexes->add (featureIndex);
3083
0
  }
3084
3085
  void collect_feature_substitutes_with_variations (hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
3086
                                                    const hb_set_t *feature_indices,
3087
                                                    const void *base) const
3088
0
  {
3089
0
    if (feature_indices->has (featureIndex))
3090
0
      feature_substitutes_map->set (featureIndex, &(base+feature));
3091
0
  }
3092
3093
  bool subset (hb_subset_layout_context_t *c, const void *base) const
3094
0
  {
3095
0
    TRACE_SUBSET (this);
3096
0
    if (!c->feature_index_map->has (featureIndex) ||
3097
0
        c->feature_substitutes_map->has (featureIndex)) {
3098
0
      // Feature that is being substituted is not being retained, so we don't
3099
0
      // need this.
3100
0
      return_trace (false);
3101
0
    }
3102
0
3103
0
    auto *out = c->subset_context->serializer->embed (this);
3104
0
    if (unlikely (!out)) return_trace (false);
3105
0
3106
0
    out->featureIndex = c->feature_index_map->get (featureIndex);
3107
0
    bool ret = out->feature.serialize_subset (c->subset_context, feature, base, c);
3108
0
    return_trace (ret);
3109
0
  }
3110
3111
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
3112
820
  {
3113
820
    TRACE_SANITIZE (this);
3114
820
    return_trace (c->check_struct (this) && feature.sanitize (c, base));
3115
820
  }
3116
3117
  protected:
3118
  HBUINT16    featureIndex;
3119
  Offset32To<Feature> feature;
3120
  public:
3121
  DEFINE_SIZE_STATIC (6);
3122
};
3123
3124
struct FeatureTableSubstitution
3125
{
3126
  const Feature *find_substitute (unsigned int feature_index) const
3127
1.10k
  {
3128
1.10k
    unsigned int count = substitutions.len;
3129
1.60k
    for (unsigned int i = 0; i < count; i++)
3130
1.08k
    {
3131
1.08k
      const FeatureTableSubstitutionRecord &record = substitutions.arrayZ[i];
3132
1.08k
      if (record.featureIndex == feature_index)
3133
580
  return &(this+record.feature);
3134
1.08k
    }
3135
520
    return nullptr;
3136
1.10k
  }
3137
3138
  void collect_lookups (const hb_set_t *feature_indexes,
3139
      const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
3140
      hb_set_t       *lookup_indexes /* OUT */) const
3141
0
  {
3142
0
    + hb_iter (substitutions)
3143
0
    | hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex)
3144
0
    | hb_filter ([feature_substitutes_map] (const FeatureTableSubstitutionRecord& record)
3145
0
                 {
3146
0
                   if (feature_substitutes_map == nullptr) return true;
3147
0
                   return !feature_substitutes_map->has (record.featureIndex);
3148
0
                 })
3149
0
    | hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r)
3150
0
    { r.collect_lookups (this, lookup_indexes); })
3151
0
    ;
3152
0
  }
3153
3154
  void closure_features (const hb_map_t *lookup_indexes,
3155
       hb_set_t       *feature_indexes /* OUT */) const
3156
0
  {
3157
0
    for (const FeatureTableSubstitutionRecord& record : substitutions)
3158
0
      record.closure_features (this, lookup_indexes, feature_indexes);
3159
0
  }
3160
3161
  bool intersects_features (const hb_map_t *feature_index_map) const
3162
0
  {
3163
0
    for (const FeatureTableSubstitutionRecord& record : substitutions)
3164
0
    {
3165
0
      if (feature_index_map->has (record.featureIndex)) return true;
3166
0
    }
3167
0
    return false;
3168
0
  }
3169
3170
  void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
3171
0
  {
3172
0
    for (const FeatureTableSubstitutionRecord& record : substitutions)
3173
0
      record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, c->feature_indices, this);
3174
0
  }
3175
3176
  bool subset (hb_subset_context_t        *c,
3177
         hb_subset_layout_context_t *l) const
3178
0
  {
3179
0
    TRACE_SUBSET (this);
3180
0
    auto *out = c->serializer->start_embed (*this);
3181
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
3182
0
3183
0
    out->version.major = version.major;
3184
0
    out->version.minor = version.minor;
3185
0
3186
0
    + substitutions.iter ()
3187
0
    | hb_apply (subset_record_array (l, &(out->substitutions), this))
3188
0
    ;
3189
0
3190
0
    return_trace (bool (out->substitutions));
3191
0
  }
3192
3193
  bool sanitize (hb_sanitize_context_t *c) const
3194
600
  {
3195
600
    TRACE_SANITIZE (this);
3196
600
    return_trace (version.sanitize (c) &&
3197
600
      likely (version.major == 1) &&
3198
600
      substitutions.sanitize (c, this));
3199
600
  }
3200
3201
  protected:
3202
  FixedVersion<>  version;  /* Version--0x00010000u */
3203
  Array16Of<FeatureTableSubstitutionRecord>
3204
      substitutions;
3205
  public:
3206
  DEFINE_SIZE_ARRAY (6, substitutions);
3207
};
3208
3209
struct FeatureVariationRecord
3210
{
3211
  friend struct FeatureVariations;
3212
3213
  void collect_lookups (const void     *base,
3214
      const hb_set_t *feature_indexes,
3215
      const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
3216
      hb_set_t       *lookup_indexes /* OUT */) const
3217
0
  {
3218
0
    return (base+substitutions).collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes);
3219
0
  }
3220
3221
  void closure_features (const void     *base,
3222
       const hb_map_t *lookup_indexes,
3223
       hb_set_t       *feature_indexes /* OUT */) const
3224
0
  {
3225
0
    (base+substitutions).closure_features (lookup_indexes, feature_indexes);
3226
0
  }
3227
3228
  bool intersects_features (const void *base, const hb_map_t *feature_index_map) const
3229
0
  {
3230
0
    return (base+substitutions).intersects_features (feature_index_map);
3231
0
  }
3232
3233
  void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
3234
                                                    const void *base) const
3235
0
  {
3236
0
    // ret == 1, all conditions met
3237
0
    if ((base+conditions).keep_with_variations (c) == DROP_COND_WITH_VAR &&
3238
0
        c->apply)
3239
0
    {
3240
0
      (base+substitutions).collect_feature_substitutes_with_variations (c);
3241
0
      c->apply = false; // set variations only once
3242
0
    }
3243
0
  }
3244
3245
  bool subset (hb_subset_layout_context_t *c, const void *base) const
3246
0
  {
3247
0
    TRACE_SUBSET (this);
3248
0
    auto *out = c->subset_context->serializer->embed (this);
3249
0
    if (unlikely (!out)) return_trace (false);
3250
0
3251
0
    out->conditions.serialize_subset (c->subset_context, conditions, base, c);
3252
0
    out->substitutions.serialize_subset (c->subset_context, substitutions, base, c);
3253
0
3254
0
    return_trace (true);
3255
0
  }
3256
3257
  bool sanitize (hb_sanitize_context_t *c, const void *base) const
3258
800
  {
3259
800
    TRACE_SANITIZE (this);
3260
800
    return_trace (conditions.sanitize (c, base) &&
3261
800
      substitutions.sanitize (c, base));
3262
800
  }
3263
3264
  protected:
3265
  Offset32To<ConditionSet>
3266
      conditions;
3267
  Offset32To<FeatureTableSubstitution>
3268
      substitutions;
3269
  public:
3270
  DEFINE_SIZE_STATIC (8);
3271
};
3272
3273
struct FeatureVariations
3274
{
3275
  static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFFFFFu;
3276
3277
  bool find_index (const int *coords, unsigned int coord_len,
3278
       unsigned int *index) const
3279
826k
  {
3280
826k
    unsigned int count = varRecords.len;
3281
829k
    for (unsigned int i = 0; i < count; i++)
3282
5.92k
    {
3283
5.92k
      const FeatureVariationRecord &record = varRecords.arrayZ[i];
3284
5.92k
      if ((this+record.conditions).evaluate (coords, coord_len))
3285
3.26k
      {
3286
3.26k
  *index = i;
3287
3.26k
  return true;
3288
3.26k
      }
3289
5.92k
    }
3290
823k
    *index = NOT_FOUND_INDEX;
3291
823k
    return false;
3292
826k
  }
3293
3294
  const Feature *find_substitute (unsigned int variations_index,
3295
          unsigned int feature_index) const
3296
1.10k
  {
3297
1.10k
    const FeatureVariationRecord &record = varRecords[variations_index];
3298
1.10k
    return (this+record.substitutions).find_substitute (feature_index);
3299
1.10k
  }
3300
3301
  void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
3302
0
  {
3303
0
    unsigned int count = varRecords.len;
3304
0
    for (unsigned int i = 0; i < count; i++)
3305
0
    {
3306
0
      c->cur_record_idx = i;
3307
0
      varRecords[i].collect_feature_substitutes_with_variations (c, this);
3308
0
    }
3309
0
  }
3310
3311
  FeatureVariations* copy (hb_serialize_context_t *c) const
3312
0
  {
3313
0
    TRACE_SERIALIZE (this);
3314
0
    return_trace (c->embed (*this));
3315
0
  }
3316
3317
  void collect_lookups (const hb_set_t *feature_indexes,
3318
      const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
3319
      hb_set_t       *lookup_indexes /* OUT */) const
3320
0
  {
3321
0
    for (const FeatureVariationRecord& r : varRecords)
3322
0
      r.collect_lookups (this, feature_indexes, feature_substitutes_map, lookup_indexes);
3323
0
  }
3324
3325
  void closure_features (const hb_map_t *lookup_indexes,
3326
       const hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map,
3327
       hb_set_t       *feature_indexes /* OUT */) const
3328
0
  {
3329
0
    unsigned int count = varRecords.len;
3330
0
    for (unsigned int i = 0; i < count; i++)
3331
0
    {
3332
0
      if (feature_record_cond_idx_map != nullptr &&
3333
0
          !feature_record_cond_idx_map->has (i))
3334
0
        continue;
3335
0
      varRecords[i].closure_features (this, lookup_indexes, feature_indexes);
3336
0
    }
3337
0
  }
3338
3339
  bool subset (hb_subset_context_t *c,
3340
         hb_subset_layout_context_t *l) const
3341
0
  {
3342
0
    TRACE_SUBSET (this);
3343
0
    auto *out = c->serializer->start_embed (*this);
3344
0
    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
3345
0
3346
0
    out->version.major = version.major;
3347
0
    out->version.minor = version.minor;
3348
0
3349
0
    int keep_up_to = -1;
3350
0
    for (int i = varRecords.len - 1; i >= 0; i--) {
3351
0
      if (varRecords[i].intersects_features (this, l->feature_index_map)) {
3352
0
        keep_up_to = i;
3353
0
        break;
3354
0
      }
3355
0
    }
3356
0
3357
0
    unsigned count = (unsigned) (keep_up_to + 1);
3358
0
    for (unsigned i = 0; i < count; i++)
3359
0
    {
3360
0
      if (l->feature_record_cond_idx_map != nullptr &&
3361
0
          !l->feature_record_cond_idx_map->has (i))
3362
0
        continue;
3363
0
3364
0
      l->cur_feature_var_record_idx = i;
3365
0
      subset_record_array (l, &(out->varRecords), this) (varRecords[i]);
3366
0
    }
3367
0
    return_trace (bool (out->varRecords));
3368
0
  }
3369
3370
  bool sanitize (hb_sanitize_context_t *c) const
3371
540
  {
3372
540
    TRACE_SANITIZE (this);
3373
540
    return_trace (version.sanitize (c) &&
3374
540
      likely (version.major == 1) &&
3375
540
      varRecords.sanitize (c, this));
3376
540
  }
3377
3378
  protected:
3379
  FixedVersion<>  version;  /* Version--0x00010000u */
3380
  Array32Of<FeatureVariationRecord>
3381
      varRecords;
3382
  public:
3383
  DEFINE_SIZE_ARRAY_SIZED (8, varRecords);
3384
};
3385
3386
3387
/*
3388
 * Device Tables
3389
 */
3390
3391
struct HintingDevice
3392
{
3393
  friend struct Device;
3394
3395
  private:
3396
3397
  hb_position_t get_x_delta (hb_font_t *font) const
3398
0
  { return get_delta (font->x_ppem, font->x_scale); }
3399
3400
  hb_position_t get_y_delta (hb_font_t *font) const
3401
0
  { return get_delta (font->y_ppem, font->y_scale); }
3402
3403
  public:
3404
3405
  unsigned int get_size () const
3406
54.6k
  {
3407
54.6k
    unsigned int f = deltaFormat;
3408
54.6k
    if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * HBUINT16::static_size;
3409
37.3k
    return HBUINT16::static_size * (4 + ((endSize - startSize) >> (4 - f)));
3410
54.6k
  }
3411
3412
  bool sanitize (hb_sanitize_context_t *c) const
3413
54.6k
  {
3414
54.6k
    TRACE_SANITIZE (this);
3415
54.6k
    return_trace (c->check_struct (this) && c->check_range (this, this->get_size ()));
3416
54.6k
  }
3417
3418
  HintingDevice* copy (hb_serialize_context_t *c) const
3419
0
  {
3420
0
    TRACE_SERIALIZE (this);
3421
0
    return_trace (c->embed<HintingDevice> (this));
3422
0
  }
3423
3424
  private:
3425
3426
  int get_delta (unsigned int ppem, int scale) const
3427
0
  {
3428
0
    if (!ppem) return 0;
3429
3430
0
    int pixels = get_delta_pixels (ppem);
3431
3432
0
    if (!pixels) return 0;
3433
3434
0
    return (int) (pixels * (int64_t) scale / ppem);
3435
0
  }
3436
  int get_delta_pixels (unsigned int ppem_size) const
3437
0
  {
3438
0
    unsigned int f = deltaFormat;
3439
0
    if (unlikely (f < 1 || f > 3))
3440
0
      return 0;
3441
3442
0
    if (ppem_size < startSize || ppem_size > endSize)
3443
0
      return 0;
3444
3445
0
    unsigned int s = ppem_size - startSize;
3446
3447
0
    unsigned int byte = deltaValueZ[s >> (4 - f)];
3448
0
    unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
3449
0
    unsigned int mask = (0xFFFFu >> (16 - (1 << f)));
3450
3451
0
    int delta = bits & mask;
3452
3453
0
    if ((unsigned int) delta >= ((mask + 1) >> 1))
3454
0
      delta -= mask + 1;
3455
3456
0
    return delta;
3457
0
  }
3458
3459
  protected:
3460
  HBUINT16  startSize;    /* Smallest size to correct--in ppem */
3461
  HBUINT16  endSize;    /* Largest size to correct--in ppem */
3462
  HBUINT16  deltaFormat;    /* Format of DeltaValue array data: 1, 2, or 3
3463
           * 1  Signed 2-bit value, 8 values per uint16
3464
           * 2  Signed 4-bit value, 4 values per uint16
3465
           * 3  Signed 8-bit value, 2 values per uint16
3466
           */
3467
  UnsizedArrayOf<HBUINT16>
3468
    deltaValueZ;    /* Array of compressed data */
3469
  public:
3470
  DEFINE_SIZE_ARRAY (6, deltaValueZ);
3471
};
3472
3473
struct VariationDevice
3474
{
3475
  friend struct Device;
3476
3477
  private:
3478
3479
  hb_position_t get_x_delta (hb_font_t *font,
3480
           const VariationStore &store,
3481
           VariationStore::cache_t *store_cache = nullptr) const
3482
0
  { return font->em_scalef_x (get_delta (font, store, store_cache)); }
3483
3484
  hb_position_t get_y_delta (hb_font_t *font,
3485
           const VariationStore &store,
3486
           VariationStore::cache_t *store_cache = nullptr) const
3487
0
  { return font->em_scalef_y (get_delta (font, store, store_cache)); }
3488
3489
  VariationDevice* copy (hb_serialize_context_t *c,
3490
                         const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const
3491
0
  {
3492
0
    TRACE_SERIALIZE (this);
3493
0
    if (!layout_variation_idx_delta_map) return_trace (nullptr);
3494
0
3495
0
    hb_pair_t<unsigned, int> *v;
3496
0
    if (!layout_variation_idx_delta_map->has (varIdx, &v))
3497
0
      return_trace (nullptr);
3498
0
3499
0
    c->start_zerocopy (this->static_size);
3500
0
    auto *out = c->embed (this);
3501
0
    if (unlikely (!out)) return_trace (nullptr);
3502
0
3503
0
    unsigned new_idx = hb_first (*v);
3504
0
    out->varIdx = new_idx;
3505
0
    return_trace (out);
3506
0
  }
3507
3508
  void collect_variation_index (hb_collect_variation_indices_context_t *c) const
3509
0
  {
3510
0
    c->layout_variation_indices->add (varIdx);
3511
0
    int delta = 0;
3512
0
    if (c->font && c->var_store)
3513
0
      delta = roundf (get_delta (c->font, *c->var_store, c->store_cache));
3514
0
3515
0
    /* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap
3516
0
     * varidx later*/
3517
0
    c->varidx_delta_map->set (varIdx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta));
3518
0
  }
3519
3520
  bool sanitize (hb_sanitize_context_t *c) const
3521
184k
  {
3522
184k
    TRACE_SANITIZE (this);
3523
184k
    return_trace (c->check_struct (this));
3524
184k
  }
3525
3526
  private:
3527
3528
  float get_delta (hb_font_t *font,
3529
       const VariationStore &store,
3530
       VariationStore::cache_t *store_cache = nullptr) const
3531
0
  {
3532
0
    return store.get_delta (varIdx, font->coords, font->num_coords, (VariationStore::cache_t *) store_cache);
3533
0
  }
3534
3535
  protected:
3536
  VarIdx  varIdx;
3537
  HBUINT16  deltaFormat;  /* Format identifier for this table: 0x0x8000 */
3538
  public:
3539
  DEFINE_SIZE_STATIC (6);
3540
};
3541
3542
struct DeviceHeader
3543
{
3544
  protected:
3545
  HBUINT16    reserved1;
3546
  HBUINT16    reserved2;
3547
  public:
3548
  HBUINT16    format;   /* Format identifier */
3549
  public:
3550
  DEFINE_SIZE_STATIC (6);
3551
};
3552
3553
struct Device
3554
{
3555
  hb_position_t get_x_delta (hb_font_t *font,
3556
           const VariationStore &store=Null (VariationStore),
3557
           VariationStore::cache_t *store_cache = nullptr) const
3558
137k
  {
3559
137k
    switch (u.b.format)
3560
137k
    {
3561
0
#ifndef HB_NO_HINTING
3562
0
    case 1: case 2: case 3:
3563
0
      return u.hinting.get_x_delta (font);
3564
0
#endif
3565
0
#ifndef HB_NO_VAR
3566
0
    case 0x8000:
3567
0
      return u.variation.get_x_delta (font, store, store_cache);
3568
0
#endif
3569
137k
    default:
3570
137k
      return 0;
3571
137k
    }
3572
137k
  }
3573
  hb_position_t get_y_delta (hb_font_t *font,
3574
           const VariationStore &store=Null (VariationStore),
3575
           VariationStore::cache_t *store_cache = nullptr) const
3576
925k
  {
3577
925k
    switch (u.b.format)
3578
925k
    {
3579
0
    case 1: case 2: case 3:
3580
0
#ifndef HB_NO_HINTING
3581
0
      return u.hinting.get_y_delta (font);
3582
0
#endif
3583
0
#ifndef HB_NO_VAR
3584
0
    case 0x8000:
3585
0
      return u.variation.get_y_delta (font, store, store_cache);
3586
0
#endif
3587
925k
    default:
3588
925k
      return 0;
3589
925k
    }
3590
925k
  }
3591
3592
  bool sanitize (hb_sanitize_context_t *c) const
3593
1.38M
  {
3594
1.38M
    TRACE_SANITIZE (this);
3595
1.38M
    if (!u.b.format.sanitize (c)) return_trace (false);
3596
1.38M
    switch (u.b.format) {
3597
0
#ifndef HB_NO_HINTING
3598
54.6k
    case 1: case 2: case 3:
3599
54.6k
      return_trace (u.hinting.sanitize (c));
3600
0
#endif
3601
0
#ifndef HB_NO_VAR
3602
184k
    case 0x8000:
3603
184k
      return_trace (u.variation.sanitize (c));
3604
0
#endif
3605
1.14M
    default:
3606
1.14M
      return_trace (true);
3607
1.38M
    }
3608
1.38M
  }
3609
3610
  Device* copy (hb_serialize_context_t *c,
3611
                const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map=nullptr) const
3612
0
  {
3613
0
    TRACE_SERIALIZE (this);
3614
0
    switch (u.b.format) {
3615
0
#ifndef HB_NO_HINTING
3616
0
    case 1:
3617
0
    case 2:
3618
0
    case 3:
3619
0
      return_trace (reinterpret_cast<Device *> (u.hinting.copy (c)));
3620
0
#endif
3621
0
#ifndef HB_NO_VAR
3622
0
    case 0x8000:
3623
0
      return_trace (reinterpret_cast<Device *> (u.variation.copy (c, layout_variation_idx_delta_map)));
3624
0
#endif
3625
0
    default:
3626
0
      return_trace (nullptr);
3627
0
    }
3628
0
  }
3629
3630
  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
3631
0
  {
3632
0
    switch (u.b.format) {
3633
0
#ifndef HB_NO_HINTING
3634
0
    case 1:
3635
0
    case 2:
3636
0
    case 3:
3637
0
      return;
3638
0
#endif
3639
0
#ifndef HB_NO_VAR
3640
0
    case 0x8000:
3641
0
      u.variation.collect_variation_index (c);
3642
0
      return;
3643
0
#endif
3644
0
    default:
3645
0
      return;
3646
0
    }
3647
0
  }
3648
3649
  unsigned get_variation_index () const
3650
0
  {
3651
0
    switch (u.b.format) {
3652
0
#ifndef HB_NO_VAR
3653
0
    case 0x8000:
3654
0
      return u.variation.varIdx;
3655
0
#endif
3656
0
    default:
3657
0
      return HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
3658
0
    }
3659
0
  }
3660
3661
  protected:
3662
  union {
3663
  DeviceHeader    b;
3664
  HintingDevice   hinting;
3665
#ifndef HB_NO_VAR
3666
  VariationDevice variation;
3667
#endif
3668
  } u;
3669
  public:
3670
  DEFINE_SIZE_UNION (6, b);
3671
};
3672
3673
3674
} /* namespace OT */
3675
3676
3677
#endif /* HB_OT_LAYOUT_COMMON_HH */