• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef OT_LAYOUT_GSUB_LIGATURESET_HH
2 #define OT_LAYOUT_GSUB_LIGATURESET_HH
3 
4 #include "Common.hh"
5 #include "Ligature.hh"
6 
7 namespace OT {
8 namespace Layout {
9 namespace GSUB_impl {
10 
11 template <typename Types>
12 struct LigatureSet
13 {
14   protected:
15   Array16OfOffset16To<Ligature<Types>>
16                 ligature;               /* Array LigatureSet tables
17                                          * ordered by preference */
18   public:
19   DEFINE_SIZE_ARRAY (2, ligature);
20 
sanitizeOT::Layout::GSUB_impl::LigatureSet21   bool sanitize (hb_sanitize_context_t *c) const
22   {
23     TRACE_SANITIZE (this);
24     return_trace (ligature.sanitize (c, this));
25   }
26 
intersectsOT::Layout::GSUB_impl::LigatureSet27   bool intersects (const hb_set_t *glyphs) const
28   {
29     return
30     + hb_iter (ligature)
31     | hb_map (hb_add (this))
32     | hb_map ([glyphs] (const Ligature<Types> &_) { return _.intersects (glyphs); })
33     | hb_any
34     ;
35   }
36 
closureOT::Layout::GSUB_impl::LigatureSet37   void closure (hb_closure_context_t *c) const
38   {
39     + hb_iter (ligature)
40     | hb_map (hb_add (this))
41     | hb_apply ([c] (const Ligature<Types> &_) { _.closure (c); })
42     ;
43   }
44 
collect_glyphsOT::Layout::GSUB_impl::LigatureSet45   void collect_glyphs (hb_collect_glyphs_context_t *c) const
46   {
47     + hb_iter (ligature)
48     | hb_map (hb_add (this))
49     | hb_apply ([c] (const Ligature<Types> &_) { _.collect_glyphs (c); })
50     ;
51   }
52 
would_applyOT::Layout::GSUB_impl::LigatureSet53   bool would_apply (hb_would_apply_context_t *c) const
54   {
55     return
56     + hb_iter (ligature)
57     | hb_map (hb_add (this))
58     | hb_map ([c] (const Ligature<Types> &_) { return _.would_apply (c); })
59     | hb_any
60     ;
61   }
62 
applyOT::Layout::GSUB_impl::LigatureSet63   bool apply (hb_ot_apply_context_t *c) const
64   {
65     TRACE_APPLY (this);
66     unsigned int num_ligs = ligature.len;
67     for (unsigned int i = 0; i < num_ligs; i++)
68     {
69       const auto &lig = this+ligature[i];
70       if (lig.apply (c)) return_trace (true);
71     }
72 
73     return_trace (false);
74   }
75 
serializeOT::Layout::GSUB_impl::LigatureSet76   bool serialize (hb_serialize_context_t *c,
77                   hb_array_t<const HBGlyphID16> ligatures,
78                   hb_array_t<const unsigned int> component_count_list,
79                   hb_array_t<const HBGlyphID16> &component_list /* Starting from second for each ligature */)
80   {
81     TRACE_SERIALIZE (this);
82     if (unlikely (!c->extend_min (this))) return_trace (false);
83     if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false);
84     for (unsigned int i = 0; i < ligatures.length; i++)
85     {
86       unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0);
87       if (unlikely (!ligature[i].serialize_serialize (c,
88                                                       ligatures[i],
89                                                       component_list.sub_array (0, component_count))))
90         return_trace (false);
91       component_list += component_count;
92     }
93     return_trace (true);
94   }
95 
subsetOT::Layout::GSUB_impl::LigatureSet96   bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
97   {
98     TRACE_SUBSET (this);
99     auto *out = c->serializer->start_embed (*this);
100     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
101 
102     + hb_iter (ligature)
103     | hb_filter (subset_offset_array (c, out->ligature, this, coverage_idx))
104     | hb_drain
105     ;
106 
107     if (bool (out->ligature))
108       // Ensure Coverage table is always packed after this.
109       c->serializer->add_virtual_link (coverage_idx);
110 
111     return_trace (bool (out->ligature));
112   }
113 };
114 
115 }
116 }
117 }
118 
119 #endif  /* OT_LAYOUT_GSUB_LIGATURESET_HH */
120