1 | #ifndef OT_LAYOUT_GPOS_SINGLEPOS_HH |
2 | #define OT_LAYOUT_GPOS_SINGLEPOS_HH |
3 | |
4 | #include "SinglePosFormat1.hh" |
5 | #include "SinglePosFormat2.hh" |
6 | |
7 | namespace OT { |
8 | namespace Layout { |
9 | namespace GPOS_impl { |
10 | |
11 | struct SinglePos |
12 | { |
13 | protected: |
14 | union { |
15 | HBUINT16 format; /* Format identifier */ |
16 | SinglePosFormat1 format1; |
17 | SinglePosFormat2 format2; |
18 | } u; |
19 | |
20 | public: |
21 | template<typename Iterator, |
22 | hb_requires (hb_is_iterator (Iterator))> |
23 | unsigned get_format (Iterator glyph_val_iter_pairs) |
24 | { |
25 | hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs); |
26 | |
27 | for (const auto iter : glyph_val_iter_pairs) |
28 | for (const auto _ : hb_zip (iter.second, first_val_iter)) |
29 | if (_.first != _.second) |
30 | return 2; |
31 | |
32 | return 1; |
33 | } |
34 | |
35 | template<typename Iterator, |
36 | typename SrcLookup, |
37 | hb_requires (hb_is_iterator (Iterator))> |
38 | void serialize (hb_serialize_context_t *c, |
39 | const SrcLookup* src, |
40 | Iterator glyph_val_iter_pairs, |
41 | const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map, |
42 | bool all_axes_pinned) |
43 | { |
44 | if (unlikely (!c->extend_min (u.format))) return; |
45 | unsigned format = 2; |
46 | ValueFormat new_format = src->get_value_format (); |
47 | |
48 | if (all_axes_pinned) |
49 | new_format = new_format.drop_device_table_flags (); |
50 | |
51 | if (glyph_val_iter_pairs) |
52 | format = get_format (glyph_val_iter_pairs); |
53 | |
54 | u.format = format; |
55 | switch (u.format) { |
56 | case 1: u.format1.serialize (c, |
57 | src, |
58 | glyph_val_iter_pairs, |
59 | new_format, |
60 | layout_variation_idx_delta_map); |
61 | return; |
62 | case 2: u.format2.serialize (c, |
63 | src, |
64 | glyph_val_iter_pairs, |
65 | new_format, |
66 | layout_variation_idx_delta_map); |
67 | return; |
68 | default:return; |
69 | } |
70 | } |
71 | |
72 | template <typename context_t, typename ...Ts> |
73 | typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const |
74 | { |
75 | if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value (); |
76 | TRACE_DISPATCH (this, u.format); |
77 | switch (u.format) { |
78 | case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); |
79 | case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); |
80 | default:return_trace (c->default_return_value ()); |
81 | } |
82 | } |
83 | }; |
84 | |
85 | |
86 | template<typename Iterator, typename SrcLookup> |
87 | static void |
88 | SinglePos_serialize (hb_serialize_context_t *c, |
89 | const SrcLookup *src, |
90 | Iterator it, |
91 | const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map, |
92 | bool all_axes_pinned) |
93 | { c->start_embed<SinglePos> ()->serialize (c, src, it, layout_variation_idx_delta_map, all_axes_pinned); } |
94 | |
95 | |
96 | } |
97 | } |
98 | } |
99 | |
100 | #endif /* OT_LAYOUT_GPOS_SINGLEPOS_HH */ |
101 | |