xref: /aosp_15_r20/external/harfbuzz_ng/src/OT/Layout/GSUB/SingleSubst.hh (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
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   HBUINT16				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>
dispatchOT::Layout::GSUB_impl::SingleSubst28   typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
29   {
30     if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
31     TRACE_DISPATCH (this, u.format);
32     switch (u.format) {
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))>
serializeOT::Layout::GSUB_impl::SingleSubst46   bool serialize (hb_serialize_context_t *c,
47                   Iterator glyphs)
48   {
49     TRACE_SERIALIZE (this);
50     if (unlikely (!c->extend_min (u.format))) 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 = format;
75     switch (u.format) {
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
SingleSubst_serialize(hb_serialize_context_t * c,Iterator it)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 */
104