SingleSubst.hh (3154B)
1 #ifndef OT_LAYOUT_GSUB_SINGLESUBST_HH 2 #define OT_LAYOUT_GSUB_SINGLESUBST_HH 3 4 #include "Common.hh" 5 #include "SingleSubstFormat1.hh" 6 #include "SingleSubstFormat2.hh" 7 8 namespace OT { 9 namespace Layout { 10 namespace GSUB_impl { 11 12 struct SingleSubst 13 { 14 protected: 15 union { 16 struct { HBUINT16 v; } format; /* Format identifier */ 17 SingleSubstFormat1_3<SmallTypes> format1; 18 SingleSubstFormat2_4<SmallTypes> format2; 19 #ifndef HB_NO_BEYOND_64K 20 SingleSubstFormat1_3<MediumTypes> format3; 21 SingleSubstFormat2_4<MediumTypes> format4; 22 #endif 23 } u; 24 25 public: 26 27 template <typename context_t, typename ...Ts> 28 typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const 29 { 30 if (unlikely (!c->may_dispatch (this, &u.format.v))) return c->no_dispatch_return_value (); 31 TRACE_DISPATCH (this, u.format.v); 32 switch (u.format.v) { 33 case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); 34 case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); 35 #ifndef HB_NO_BEYOND_64K 36 case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); 37 case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); 38 #endif 39 default:return_trace (c->default_return_value ()); 40 } 41 } 42 43 template<typename Iterator, 44 hb_requires (hb_is_sorted_source_of (Iterator, 45 const hb_codepoint_pair_t))> 46 bool serialize (hb_serialize_context_t *c, 47 Iterator glyphs) 48 { 49 TRACE_SERIALIZE (this); 50 if (unlikely (!c->extend_min (u.format.v))) return_trace (false); 51 unsigned format = 2; 52 unsigned delta = 0; 53 if (glyphs) 54 { 55 format = 1; 56 hb_codepoint_t mask = 0xFFFFu; 57 58 #ifndef HB_NO_BEYOND_64K 59 if (+ glyphs 60 | hb_map_retains_sorting (hb_second) 61 | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; })) 62 { 63 format += 2; 64 mask = 0xFFFFFFu; 65 } 66 #endif 67 68 auto get_delta = [=] (hb_codepoint_pair_t _) 69 { return (unsigned) (_.second - _.first) & mask; }; 70 delta = get_delta (*glyphs); 71 if (!hb_all (++(+glyphs), delta, get_delta)) format += 1; 72 } 73 74 u.format.v = format; 75 switch (u.format.v) { 76 case 1: return_trace (u.format1.serialize (c, 77 + glyphs 78 | hb_map_retains_sorting (hb_first), 79 delta)); 80 case 2: return_trace (u.format2.serialize (c, glyphs)); 81 #ifndef HB_NO_BEYOND_64K 82 case 3: return_trace (u.format3.serialize (c, 83 + glyphs 84 | hb_map_retains_sorting (hb_first), 85 delta)); 86 case 4: return_trace (u.format4.serialize (c, glyphs)); 87 #endif 88 default:return_trace (false); 89 } 90 } 91 }; 92 93 template<typename Iterator> 94 static void 95 SingleSubst_serialize (hb_serialize_context_t *c, 96 Iterator it) 97 { c->start_embed<SingleSubst> ()->serialize (c, it); } 98 99 } 100 } 101 } 102 103 #endif /* OT_LAYOUT_GSUB_SINGLESUBST_HH */