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