/src/skia/third_party/externals/harfbuzz/src/hb-ot-var-hvar-table.hh
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright © 2017 Google, Inc. |
3 | | * |
4 | | * This is part of HarfBuzz, a text shaping library. |
5 | | * |
6 | | * Permission is hereby granted, without written agreement and without |
7 | | * license or royalty fees, to use, copy, modify, and distribute this |
8 | | * software and its documentation for any purpose, provided that the |
9 | | * above copyright notice and the following two paragraphs appear in |
10 | | * all copies of this software. |
11 | | * |
12 | | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
13 | | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
14 | | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
15 | | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
16 | | * DAMAGE. |
17 | | * |
18 | | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
19 | | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
20 | | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
21 | | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
22 | | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
23 | | * |
24 | | * Google Author(s): Behdad Esfahbod |
25 | | */ |
26 | | |
27 | | #ifndef HB_OT_VAR_HVAR_TABLE_HH |
28 | | #define HB_OT_VAR_HVAR_TABLE_HH |
29 | | |
30 | | #include "hb-ot-layout-common.hh" |
31 | | |
32 | | |
33 | | namespace OT { |
34 | | |
35 | | |
36 | | struct DeltaSetIndexMap |
37 | | { |
38 | | bool sanitize (hb_sanitize_context_t *c) const |
39 | 0 | { |
40 | 0 | TRACE_SANITIZE (this); |
41 | 0 | return_trace (c->check_struct (this) && |
42 | 0 | c->check_range (mapDataZ.arrayZ, |
43 | 0 | mapCount, |
44 | 0 | get_width ())); |
45 | 0 | } |
46 | | |
47 | | template <typename T> |
48 | | bool serialize (hb_serialize_context_t *c, const T &plan) |
49 | 0 | { |
50 | 0 | unsigned int width = plan.get_width (); |
51 | 0 | unsigned int inner_bit_count = plan.get_inner_bit_count (); |
52 | 0 | const hb_array_t<const uint32_t> output_map = plan.get_output_map (); |
53 | |
|
54 | 0 | TRACE_SERIALIZE (this); |
55 | 0 | if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0)))) |
56 | 0 | return_trace (false); |
57 | 0 | if (unlikely (!c->extend_min (this))) return_trace (false); |
58 | |
|
59 | 0 | format = ((width-1)<<4)|(inner_bit_count-1); |
60 | 0 | mapCount = output_map.length; |
61 | 0 | HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length); |
62 | 0 | if (unlikely (!p)) return_trace (false); |
63 | 0 | for (unsigned int i = 0; i < output_map.length; i++) |
64 | 0 | { |
65 | 0 | unsigned int v = output_map[i]; |
66 | 0 | unsigned int outer = v >> 16; |
67 | 0 | unsigned int inner = v & 0xFFFF; |
68 | 0 | unsigned int u = (outer << inner_bit_count) | inner; |
69 | 0 | for (unsigned int w = width; w > 0;) |
70 | 0 | { |
71 | 0 | p[--w] = u; |
72 | 0 | u >>= 8; |
73 | 0 | } |
74 | 0 | p += width; |
75 | 0 | } |
76 | 0 | return_trace (true); |
77 | 0 | } Unexecuted instantiation: bool OT::DeltaSetIndexMap::serialize<OT::index_map_subset_plan_t>(hb_serialize_context_t*, OT::index_map_subset_plan_t const&) Unexecuted instantiation: bool OT::DeltaSetIndexMap::serialize<OT::index_map_subset_plan_t>(hb_serialize_context_t*, OT::index_map_subset_plan_t const&) |
78 | | |
79 | | uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */ |
80 | 0 | { |
81 | | /* If count is zero, pass value unchanged. This takes |
82 | | * care of direct mapping for advance map. */ |
83 | 0 | if (!mapCount) |
84 | 0 | return v; |
85 | | |
86 | 0 | if (v >= mapCount) |
87 | 0 | v = mapCount - 1; |
88 | |
|
89 | 0 | unsigned int u = 0; |
90 | 0 | { /* Fetch it. */ |
91 | 0 | unsigned int w = get_width (); |
92 | 0 | const HBUINT8 *p = mapDataZ.arrayZ + w * v; |
93 | 0 | for (; w; w--) |
94 | 0 | u = (u << 8) + *p++; |
95 | 0 | } |
96 | |
|
97 | 0 | { /* Repack it. */ |
98 | 0 | unsigned int n = get_inner_bit_count (); |
99 | 0 | unsigned int outer = u >> n; |
100 | 0 | unsigned int inner = u & ((1 << n) - 1); |
101 | 0 | u = (outer<<16) | inner; |
102 | 0 | } |
103 | |
|
104 | 0 | return u; |
105 | 0 | } |
106 | | |
107 | 0 | unsigned int get_map_count () const { return mapCount; } |
108 | 0 | unsigned int get_width () const { return ((format >> 4) & 3) + 1; } |
109 | 0 | unsigned int get_inner_bit_count () const { return (format & 0xF) + 1; } |
110 | | |
111 | | protected: |
112 | | HBUINT16 format; /* A packed field that describes the compressed |
113 | | * representation of delta-set indices. */ |
114 | | HBUINT16 mapCount; /* The number of mapping entries. */ |
115 | | UnsizedArrayOf<HBUINT8> |
116 | | mapDataZ; /* The delta-set index mapping data. */ |
117 | | |
118 | | public: |
119 | | DEFINE_SIZE_ARRAY (4, mapDataZ); |
120 | | }; |
121 | | |
122 | | struct index_map_subset_plan_t |
123 | | { |
124 | | enum index_map_index_t { |
125 | | ADV_INDEX, |
126 | | LSB_INDEX, /* dual as TSB */ |
127 | | RSB_INDEX, /* dual as BSB */ |
128 | | VORG_INDEX |
129 | | }; |
130 | | |
131 | | void init (const DeltaSetIndexMap &index_map, |
132 | | hb_inc_bimap_t &outer_map, |
133 | | hb_vector_t<hb_set_t *> &inner_sets, |
134 | | const hb_subset_plan_t *plan) |
135 | 0 | { |
136 | 0 | map_count = 0; |
137 | 0 | outer_bit_count = 0; |
138 | 0 | inner_bit_count = 1; |
139 | 0 | max_inners.init (); |
140 | 0 | output_map.init (); |
141 | |
|
142 | 0 | if (&index_map == &Null (DeltaSetIndexMap)) return; |
143 | | |
144 | 0 | unsigned int last_val = (unsigned int)-1; |
145 | 0 | hb_codepoint_t last_gid = (hb_codepoint_t)-1; |
146 | 0 | hb_codepoint_t gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ()); |
147 | |
|
148 | 0 | outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count (); |
149 | 0 | max_inners.resize (inner_sets.length); |
150 | 0 | for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0; |
151 | | |
152 | | /* Search backwards for a map value different from the last map value */ |
153 | 0 | for (; gid > 0; gid--) |
154 | 0 | { |
155 | 0 | hb_codepoint_t old_gid; |
156 | 0 | if (!plan->old_gid_for_new_gid (gid - 1, &old_gid)) |
157 | 0 | { |
158 | 0 | if (last_gid == (hb_codepoint_t) -1) |
159 | 0 | continue; |
160 | 0 | else |
161 | 0 | break; |
162 | 0 | } |
163 | | |
164 | 0 | unsigned int v = index_map.map (old_gid); |
165 | 0 | if (last_gid == (hb_codepoint_t) -1) |
166 | 0 | { |
167 | 0 | last_val = v; |
168 | 0 | last_gid = gid; |
169 | 0 | continue; |
170 | 0 | } |
171 | 0 | if (v != last_val) break; |
172 | | |
173 | 0 | last_gid = gid; |
174 | 0 | } |
175 | |
|
176 | 0 | if (unlikely (last_gid == (hb_codepoint_t)-1)) return; |
177 | 0 | map_count = last_gid; |
178 | 0 | for (gid = 0; gid < map_count; gid++) |
179 | 0 | { |
180 | 0 | hb_codepoint_t old_gid; |
181 | 0 | if (plan->old_gid_for_new_gid (gid, &old_gid)) |
182 | 0 | { |
183 | 0 | unsigned int v = index_map.map (old_gid); |
184 | 0 | unsigned int outer = v >> 16; |
185 | 0 | unsigned int inner = v & 0xFFFF; |
186 | 0 | outer_map.add (outer); |
187 | 0 | if (inner > max_inners[outer]) max_inners[outer] = inner; |
188 | 0 | if (outer >= inner_sets.length) return; |
189 | 0 | inner_sets[outer]->add (inner); |
190 | 0 | } |
191 | 0 | } |
192 | 0 | } Unexecuted instantiation: OT::index_map_subset_plan_t::init(OT::DeltaSetIndexMap const&, hb_inc_bimap_t&, hb_vector_t<hb_set_t*>&, hb_subset_plan_t const*) Unexecuted instantiation: OT::index_map_subset_plan_t::init(OT::DeltaSetIndexMap const&, hb_inc_bimap_t&, hb_vector_t<hb_set_t*>&, hb_subset_plan_t const*) |
193 | | |
194 | | void fini () |
195 | 0 | { |
196 | 0 | max_inners.fini (); |
197 | 0 | output_map.fini (); |
198 | 0 | } |
199 | | |
200 | | void remap (const DeltaSetIndexMap *input_map, |
201 | | const hb_inc_bimap_t &outer_map, |
202 | | const hb_vector_t<hb_inc_bimap_t> &inner_maps, |
203 | | const hb_subset_plan_t *plan) |
204 | 0 | { |
205 | 0 | if (input_map == &Null (DeltaSetIndexMap)) return; |
206 | | |
207 | 0 | for (unsigned int i = 0; i < max_inners.length; i++) |
208 | 0 | { |
209 | 0 | if (inner_maps[i].get_population () == 0) continue; |
210 | 0 | unsigned int bit_count = (max_inners[i]==0)? 1: hb_bit_storage (inner_maps[i][max_inners[i]]); |
211 | 0 | if (bit_count > inner_bit_count) inner_bit_count = bit_count; |
212 | 0 | } |
213 | |
|
214 | 0 | output_map.resize (map_count); |
215 | 0 | for (hb_codepoint_t gid = 0; gid < output_map.length; gid++) |
216 | 0 | { |
217 | 0 | hb_codepoint_t old_gid; |
218 | 0 | if (plan->old_gid_for_new_gid (gid, &old_gid)) |
219 | 0 | { |
220 | 0 | uint32_t v = input_map->map (old_gid); |
221 | 0 | unsigned int outer = v >> 16; |
222 | 0 | output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]); |
223 | 0 | } |
224 | 0 | else |
225 | 0 | output_map[gid] = 0; /* Map unused glyph to outer/inner=0/0 */ |
226 | 0 | } |
227 | 0 | } Unexecuted instantiation: OT::index_map_subset_plan_t::remap(OT::DeltaSetIndexMap const*, hb_inc_bimap_t const&, hb_vector_t<hb_inc_bimap_t> const&, hb_subset_plan_t const*) Unexecuted instantiation: OT::index_map_subset_plan_t::remap(OT::DeltaSetIndexMap const*, hb_inc_bimap_t const&, hb_vector_t<hb_inc_bimap_t> const&, hb_subset_plan_t const*) |
228 | | |
229 | 0 | unsigned int get_inner_bit_count () const { return inner_bit_count; } |
230 | 0 | unsigned int get_width () const { return ((outer_bit_count + inner_bit_count + 7) / 8); } |
231 | 0 | unsigned int get_map_count () const { return map_count; } |
232 | | |
233 | | unsigned int get_size () const |
234 | 0 | { return (map_count? (DeltaSetIndexMap::min_size + get_width () * map_count): 0); } |
235 | | |
236 | 0 | bool is_identity () const { return get_output_map ().length == 0; } |
237 | 0 | hb_array_t<const uint32_t> get_output_map () const { return output_map.as_array (); } |
238 | | |
239 | | protected: |
240 | | unsigned int map_count; |
241 | | hb_vector_t<unsigned int> max_inners; |
242 | | unsigned int outer_bit_count; |
243 | | unsigned int inner_bit_count; |
244 | | hb_vector_t<uint32_t> output_map; |
245 | | }; |
246 | | |
247 | | struct hvarvvar_subset_plan_t |
248 | | { |
249 | 0 | hvarvvar_subset_plan_t() : inner_maps (), index_map_plans () {} |
250 | 0 | ~hvarvvar_subset_plan_t() { fini (); } |
251 | | |
252 | | void init (const hb_array_t<const DeltaSetIndexMap *> &index_maps, |
253 | | const VariationStore &_var_store, |
254 | | const hb_subset_plan_t *plan) |
255 | 0 | { |
256 | 0 | index_map_plans.resize (index_maps.length); |
257 | |
|
258 | 0 | var_store = &_var_store; |
259 | 0 | inner_sets.resize (var_store->get_sub_table_count ()); |
260 | 0 | for (unsigned int i = 0; i < inner_sets.length; i++) |
261 | 0 | inner_sets[i] = hb_set_create (); |
262 | 0 | adv_set = hb_set_create (); |
263 | |
|
264 | 0 | inner_maps.resize (var_store->get_sub_table_count ()); |
265 | |
|
266 | 0 | for (unsigned int i = 0; i < inner_maps.length; i++) |
267 | 0 | inner_maps[i].init (); |
268 | |
|
269 | 0 | if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return; |
270 | | |
271 | 0 | bool retain_adv_map = false; |
272 | 0 | index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan); |
273 | 0 | if (index_maps[0] == &Null (DeltaSetIndexMap)) |
274 | 0 | { |
275 | 0 | retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS; |
276 | 0 | outer_map.add (0); |
277 | 0 | for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) |
278 | 0 | { |
279 | 0 | hb_codepoint_t old_gid; |
280 | 0 | if (plan->old_gid_for_new_gid (gid, &old_gid)) |
281 | 0 | inner_sets[0]->add (old_gid); |
282 | 0 | } |
283 | 0 | hb_set_union (adv_set, inner_sets[0]); |
284 | 0 | } |
285 | |
|
286 | 0 | for (unsigned int i = 1; i < index_maps.length; i++) |
287 | 0 | index_map_plans[i].init (*index_maps[i], outer_map, inner_sets, plan); |
288 | |
|
289 | 0 | outer_map.sort (); |
290 | |
|
291 | 0 | if (retain_adv_map) |
292 | 0 | { |
293 | 0 | for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++) |
294 | 0 | if (inner_sets[0]->has (gid)) |
295 | 0 | inner_maps[0].add (gid); |
296 | 0 | else |
297 | 0 | inner_maps[0].skip (); |
298 | 0 | } |
299 | 0 | else |
300 | 0 | { |
301 | 0 | inner_maps[0].add_set (adv_set); |
302 | 0 | hb_set_subtract (inner_sets[0], adv_set); |
303 | 0 | inner_maps[0].add_set (inner_sets[0]); |
304 | 0 | } |
305 | |
|
306 | 0 | for (unsigned int i = 1; i < inner_maps.length; i++) |
307 | 0 | inner_maps[i].add_set (inner_sets[i]); |
308 | |
|
309 | 0 | for (unsigned int i = 0; i < index_maps.length; i++) |
310 | 0 | index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan); |
311 | 0 | } Unexecuted instantiation: OT::hvarvvar_subset_plan_t::init(hb_array_t<OT::DeltaSetIndexMap const*> const&, OT::VariationStore const&, hb_subset_plan_t const*) Unexecuted instantiation: OT::hvarvvar_subset_plan_t::init(hb_array_t<OT::DeltaSetIndexMap const*> const&, OT::VariationStore const&, hb_subset_plan_t const*) |
312 | | |
313 | | void fini () |
314 | 0 | { |
315 | 0 | for (unsigned int i = 0; i < inner_sets.length; i++) |
316 | 0 | hb_set_destroy (inner_sets[i]); |
317 | 0 | hb_set_destroy (adv_set); |
318 | 0 | inner_maps.fini_deep (); |
319 | 0 | index_map_plans.fini_deep (); |
320 | 0 | } |
321 | | |
322 | | hb_inc_bimap_t outer_map; |
323 | | hb_vector_t<hb_inc_bimap_t> inner_maps; |
324 | | hb_vector_t<index_map_subset_plan_t> index_map_plans; |
325 | | const VariationStore *var_store; |
326 | | |
327 | | protected: |
328 | | hb_vector_t<hb_set_t *> inner_sets; |
329 | | hb_set_t *adv_set; |
330 | | }; |
331 | | |
332 | | /* |
333 | | * HVAR -- Horizontal Metrics Variations |
334 | | * https://docs.microsoft.com/en-us/typography/opentype/spec/hvar |
335 | | * VVAR -- Vertical Metrics Variations |
336 | | * https://docs.microsoft.com/en-us/typography/opentype/spec/vvar |
337 | | */ |
338 | 0 | #define HB_OT_TAG_HVAR HB_TAG('H','V','A','R') |
339 | 0 | #define HB_OT_TAG_VVAR HB_TAG('V','V','A','R') |
340 | | |
341 | | struct HVARVVAR |
342 | | { |
343 | | static constexpr hb_tag_t HVARTag = HB_OT_TAG_HVAR; |
344 | | static constexpr hb_tag_t VVARTag = HB_OT_TAG_VVAR; |
345 | | |
346 | | bool sanitize (hb_sanitize_context_t *c) const |
347 | 0 | { |
348 | 0 | TRACE_SANITIZE (this); |
349 | 0 | return_trace (version.sanitize (c) && |
350 | 0 | likely (version.major == 1) && |
351 | 0 | varStore.sanitize (c, this) && |
352 | 0 | advMap.sanitize (c, this) && |
353 | 0 | lsbMap.sanitize (c, this) && |
354 | 0 | rsbMap.sanitize (c, this)); |
355 | 0 | } |
356 | | |
357 | | void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const |
358 | 0 | { |
359 | 0 | index_maps.push (&(this+advMap)); |
360 | 0 | index_maps.push (&(this+lsbMap)); |
361 | 0 | index_maps.push (&(this+rsbMap)); |
362 | 0 | } |
363 | | |
364 | | bool serialize_index_maps (hb_serialize_context_t *c, |
365 | | const hb_array_t<index_map_subset_plan_t> &im_plans) |
366 | 0 | { |
367 | 0 | TRACE_SERIALIZE (this); |
368 | 0 | if (im_plans[index_map_subset_plan_t::ADV_INDEX].is_identity ()) |
369 | 0 | advMap = 0; |
370 | 0 | else if (unlikely (!advMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::ADV_INDEX]))) |
371 | 0 | return_trace (false); |
372 | 0 | if (im_plans[index_map_subset_plan_t::LSB_INDEX].is_identity ()) |
373 | 0 | lsbMap = 0; |
374 | 0 | else if (unlikely (!lsbMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::LSB_INDEX]))) |
375 | 0 | return_trace (false); |
376 | 0 | if (im_plans[index_map_subset_plan_t::RSB_INDEX].is_identity ()) |
377 | 0 | rsbMap = 0; |
378 | 0 | else if (unlikely (!rsbMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::RSB_INDEX]))) |
379 | 0 | return_trace (false); |
380 | |
|
381 | 0 | return_trace (true); |
382 | 0 | } Unexecuted instantiation: OT::HVARVVAR::serialize_index_maps(hb_serialize_context_t*, hb_array_t<OT::index_map_subset_plan_t> const&) Unexecuted instantiation: OT::HVARVVAR::serialize_index_maps(hb_serialize_context_t*, hb_array_t<OT::index_map_subset_plan_t> const&) |
383 | | |
384 | | template <typename T> |
385 | | bool _subset (hb_subset_context_t *c) const |
386 | 0 | { |
387 | 0 | TRACE_SUBSET (this); |
388 | 0 | hvarvvar_subset_plan_t hvar_plan; |
389 | 0 | hb_vector_t<const DeltaSetIndexMap *> |
390 | 0 | index_maps; |
391 | |
|
392 | 0 | ((T*)this)->listup_index_maps (index_maps); |
393 | 0 | hvar_plan.init (index_maps.as_array (), this+varStore, c->plan); |
394 | |
|
395 | 0 | T *out = c->serializer->allocate_min<T> (); |
396 | 0 | if (unlikely (!out)) return_trace (false); |
397 | |
|
398 | 0 | out->version.major = 1; |
399 | 0 | out->version.minor = 0; |
400 | |
|
401 | 0 | if (unlikely (!out->varStore |
402 | 0 | .serialize_serialize (c->serializer, |
403 | 0 | hvar_plan.var_store, |
404 | 0 | hvar_plan.inner_maps.as_array ()))) |
405 | 0 | return_trace (false); |
406 | |
|
407 | 0 | return_trace (out->T::serialize_index_maps (c->serializer, |
408 | 0 | hvar_plan.index_map_plans.as_array ())); |
409 | 0 | } Unexecuted instantiation: bool OT::HVARVVAR::_subset<OT::HVAR>(hb_subset_context_t*) const Unexecuted instantiation: bool OT::HVARVVAR::_subset<OT::VVAR>(hb_subset_context_t*) const Unexecuted instantiation: bool OT::HVARVVAR::_subset<OT::HVAR>(hb_subset_context_t*) const Unexecuted instantiation: bool OT::HVARVVAR::_subset<OT::VVAR>(hb_subset_context_t*) const |
410 | | |
411 | | float get_advance_var (hb_codepoint_t glyph, hb_font_t *font) const |
412 | 0 | { |
413 | 0 | uint32_t varidx = (this+advMap).map (glyph); |
414 | 0 | return (this+varStore).get_delta (varidx, font->coords, font->num_coords); |
415 | 0 | } |
416 | | |
417 | | float get_side_bearing_var (hb_codepoint_t glyph, |
418 | | const int *coords, unsigned int coord_count) const |
419 | 0 | { |
420 | 0 | if (!has_side_bearing_deltas ()) return 0.f; |
421 | 0 | uint32_t varidx = (this+lsbMap).map (glyph); |
422 | 0 | return (this+varStore).get_delta (varidx, coords, coord_count); |
423 | 0 | } |
424 | | |
425 | 0 | bool has_side_bearing_deltas () const { return lsbMap && rsbMap; } |
426 | | |
427 | | protected: |
428 | | FixedVersion<>version; /* Version of the metrics variation table |
429 | | * initially set to 0x00010000u */ |
430 | | Offset32To<VariationStore> |
431 | | varStore; /* Offset to item variation store table. */ |
432 | | Offset32To<DeltaSetIndexMap> |
433 | | advMap; /* Offset to advance var-idx mapping. */ |
434 | | Offset32To<DeltaSetIndexMap> |
435 | | lsbMap; /* Offset to lsb/tsb var-idx mapping. */ |
436 | | Offset32To<DeltaSetIndexMap> |
437 | | rsbMap; /* Offset to rsb/bsb var-idx mapping. */ |
438 | | |
439 | | public: |
440 | | DEFINE_SIZE_STATIC (20); |
441 | | }; |
442 | | |
443 | | struct HVAR : HVARVVAR { |
444 | | static constexpr hb_tag_t tableTag = HB_OT_TAG_HVAR; |
445 | 0 | bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<HVAR> (c); } |
446 | | }; |
447 | | struct VVAR : HVARVVAR { |
448 | | static constexpr hb_tag_t tableTag = HB_OT_TAG_VVAR; |
449 | | |
450 | | bool sanitize (hb_sanitize_context_t *c) const |
451 | 0 | { |
452 | 0 | TRACE_SANITIZE (this); |
453 | 0 | return_trace (static_cast<const HVARVVAR *> (this)->sanitize (c) && |
454 | 0 | vorgMap.sanitize (c, this)); |
455 | 0 | } Unexecuted instantiation: OT::VVAR::sanitize(hb_sanitize_context_t*) const Unexecuted instantiation: OT::VVAR::sanitize(hb_sanitize_context_t*) const |
456 | | |
457 | | void listup_index_maps (hb_vector_t<const DeltaSetIndexMap *> &index_maps) const |
458 | 0 | { |
459 | 0 | HVARVVAR::listup_index_maps (index_maps); |
460 | 0 | index_maps.push (&(this+vorgMap)); |
461 | 0 | } |
462 | | |
463 | | bool serialize_index_maps (hb_serialize_context_t *c, |
464 | | const hb_array_t<index_map_subset_plan_t> &im_plans) |
465 | 0 | { |
466 | 0 | TRACE_SERIALIZE (this); |
467 | 0 | if (unlikely (!HVARVVAR::serialize_index_maps (c, im_plans))) |
468 | 0 | return_trace (false); |
469 | 0 | if (!im_plans[index_map_subset_plan_t::VORG_INDEX].get_map_count ()) |
470 | 0 | vorgMap = 0; |
471 | 0 | else if (unlikely (!vorgMap.serialize_serialize (c, im_plans[index_map_subset_plan_t::VORG_INDEX]))) |
472 | 0 | return_trace (false); |
473 | |
|
474 | 0 | return_trace (true); |
475 | 0 | } Unexecuted instantiation: OT::VVAR::serialize_index_maps(hb_serialize_context_t*, hb_array_t<OT::index_map_subset_plan_t> const&) Unexecuted instantiation: OT::VVAR::serialize_index_maps(hb_serialize_context_t*, hb_array_t<OT::index_map_subset_plan_t> const&) |
476 | | |
477 | 0 | bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<VVAR> (c); } |
478 | | |
479 | | protected: |
480 | | Offset32To<DeltaSetIndexMap> |
481 | | vorgMap; /* Offset to vertical-origin var-idx mapping. */ |
482 | | |
483 | | public: |
484 | | DEFINE_SIZE_STATIC (24); |
485 | | }; |
486 | | |
487 | | } /* namespace OT */ |
488 | | |
489 | | |
490 | | #endif /* HB_OT_VAR_HVAR_TABLE_HH */ |