| #ifndef OT_LAYOUT_GPOS_SINGLEPOS_HH | |
| #define OT_LAYOUT_GPOS_SINGLEPOS_HH | |
| #include "SinglePosFormat1.hh" | |
| #include "SinglePosFormat2.hh" | |
| namespace OT { | |
| namespace Layout { | |
| namespace GPOS_impl { | |
| struct SinglePos | |
| { | |
| protected: | |
| union { | |
| struct { HBUINT16 v; } format; /* Format identifier */ | |
| SinglePosFormat1_3<SmallTypes> format1; | |
| SinglePosFormat2_4<SmallTypes> format2; | |
| #ifndef HB_NO_BEYOND_64K | |
| SinglePosFormat1_3<MediumTypes> format3; | |
| SinglePosFormat2_4<MediumTypes> format4; | |
| #endif | |
| } u; | |
| public: | |
| template<typename Iterator, | |
| hb_requires (hb_is_iterator (Iterator))> | |
| unsigned get_format (Iterator glyph_val_iter_pairs) | |
| { | |
| hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs); | |
| for (const auto iter : glyph_val_iter_pairs) | |
| for (const auto _ : hb_zip (iter.second, first_val_iter)) | |
| if (_.first != _.second) | |
| return 2; | |
| return 1; | |
| } | |
| template<typename Iterator, | |
| hb_requires (hb_is_iterator (Iterator))> | |
| void serialize (hb_serialize_context_t *c, | |
| const ValueBase* src, | |
| ValueFormat src_format, | |
| Iterator glyph_val_iter_pairs, | |
| const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map, | |
| unsigned newFormat) | |
| { | |
| if (unlikely (!c->extend_min (u.format.v))) return; | |
| unsigned format = 2; | |
| ValueFormat new_format; | |
| new_format = newFormat; | |
| if (glyph_val_iter_pairs) | |
| format = get_format (glyph_val_iter_pairs); | |
| #ifndef HB_NO_BEYOND_64K | |
| if (+ glyph_val_iter_pairs | |
| | hb_map_retains_sorting (hb_first) | |
| | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; })) | |
| format += 2; | |
| #endif | |
| u.format.v = format; | |
| switch (u.format.v) { | |
| case 1: hb_barrier (); u.format1.serialize (c, | |
| src, src_format, | |
| glyph_val_iter_pairs, | |
| new_format, | |
| layout_variation_idx_delta_map); | |
| return; | |
| case 2: hb_barrier (); u.format2.serialize (c, | |
| src, src_format, | |
| glyph_val_iter_pairs, | |
| new_format, | |
| layout_variation_idx_delta_map); | |
| return; | |
| #ifndef HB_NO_BEYOND_64K | |
| case 3: u.format3.serialize (c, | |
| src, src_format, | |
| glyph_val_iter_pairs, | |
| new_format, | |
| layout_variation_idx_delta_map); | |
| return; | |
| case 4: u.format4.serialize (c, | |
| src, src_format, | |
| glyph_val_iter_pairs, | |
| new_format, | |
| layout_variation_idx_delta_map); | |
| return; | |
| #endif | |
| default:return; | |
| } | |
| } | |
| template <typename context_t, typename ...Ts> | |
| typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const | |
| { | |
| if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); | |
| TRACE_DISPATCH (this, u.format.v); | |
| switch (u.format.v) { | |
| case 1: hb_barrier (); return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); | |
| case 2: hb_barrier (); return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); | |
| #ifndef HB_NO_BEYOND_64K | |
| case 3: hb_barrier (); return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); | |
| case 4: hb_barrier (); return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); | |
| #endif | |
| default:return_trace (c->default_return_value ()); | |
| } | |
| } | |
| }; | |
| template<typename Iterator> | |
| static void | |
| SinglePos_serialize (hb_serialize_context_t *c, | |
| const ValueBase *src, | |
| ValueFormat src_format, | |
| Iterator it, | |
| const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map, | |
| unsigned new_format) | |
| { c->start_embed<SinglePos> ()->serialize (c, src, src_format, it, layout_variation_idx_delta_map, new_format); } | |
| } | |
| } | |
| } | |
| #endif /* OT_LAYOUT_GPOS_SINGLEPOS_HH */ |