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