LigatureArray.hh (2277B)
1 #ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH 2 #define OT_LAYOUT_GPOS_LIGATUREARRAY_HH 3 4 namespace OT { 5 namespace Layout { 6 namespace GPOS_impl { 7 8 9 typedef AnchorMatrix LigatureAttach; /* component-major-- 10 * in order of writing direction--, 11 * mark-minor-- 12 * ordered by class--zero-based. */ 13 14 /* Array of LigatureAttach tables ordered by LigatureCoverage Index */ 15 struct LigatureArray : List16OfOffset16To<LigatureAttach> 16 { 17 template <typename Iterator, 18 hb_requires (hb_is_iterator (Iterator))> 19 bool subset (hb_subset_context_t *c, 20 Iterator coverage, 21 unsigned class_count, 22 const hb_map_t *klass_mapping, 23 hb_sorted_vector_t<hb_codepoint_t> &new_coverage /* OUT */) const 24 { 25 TRACE_SUBSET (this); 26 const hb_map_t &glyph_map = c->plan->glyph_map_gsub; 27 28 auto *out = c->serializer->start_embed (this); 29 if (unlikely (!c->serializer->extend_min (out))) return_trace (false); 30 31 bool ret = false; 32 for (const auto _ : + hb_zip (coverage, *this) 33 | hb_filter (glyph_map, hb_first)) 34 { 35 const LigatureAttach& src = (this + _.second); 36 bool non_empty = + hb_range (src.rows * class_count) 37 | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) 38 | hb_map ([&] (const unsigned index) { return !src.offset_is_null (index / class_count, index % class_count, class_count); }) 39 | hb_any; 40 41 if (!non_empty) continue; 42 43 auto *matrix = out->serialize_append (c->serializer); 44 if (unlikely (!matrix)) return_trace (false); 45 46 auto indexes = 47 + hb_range (src.rows * class_count) 48 | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); }) 49 ; 50 ret |= matrix->serialize_subset (c, 51 _.second, 52 this, 53 src.rows, 54 indexes); 55 56 hb_codepoint_t new_gid = glyph_map.get (_.first); 57 new_coverage.push (new_gid); 58 } 59 return_trace (ret); 60 } 61 }; 62 63 64 } 65 } 66 } 67 68 #endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */