1 #ifndef OT_LAYOUT_GPOS_ANCHORMATRIX_HH 2 #define OT_LAYOUT_GPOS_ANCHORMATRIX_HH 3 4 namespace OT { 5 namespace Layout { 6 namespace GPOS_impl { 7 8 struct AnchorMatrix 9 { 10 HBUINT16 rows; /* Number of rows */ 11 UnsizedArrayOf<Offset16To<Anchor>> 12 matrixZ; /* Matrix of offsets to Anchor tables-- 13 * from beginning of AnchorMatrix table */ 14 public: 15 DEFINE_SIZE_ARRAY (2, matrixZ); 16 sanitizeOT::Layout::GPOS_impl::AnchorMatrix17 bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const 18 { 19 TRACE_SANITIZE (this); 20 if (!c->check_struct (this)) return_trace (false); 21 if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false); 22 unsigned int count = rows * cols; 23 if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false); 24 25 if (c->lazy_some_gpos) 26 return_trace (true); 27 28 for (unsigned int i = 0; i < count; i++) 29 if (!matrixZ[i].sanitize (c, this)) return_trace (false); 30 return_trace (true); 31 } 32 get_anchorOT::Layout::GPOS_impl::AnchorMatrix33 const Anchor& get_anchor (hb_ot_apply_context_t *c, 34 unsigned int row, unsigned int col, 35 unsigned int cols, bool *found) const 36 { 37 *found = false; 38 if (unlikely (row >= rows || col >= cols)) return Null (Anchor); 39 auto &offset = matrixZ[row * cols + col]; 40 if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor); 41 *found = !offset.is_null (); 42 return this+offset; 43 } 44 45 template <typename Iterator, 46 hb_requires (hb_is_iterator (Iterator))> collect_variation_indicesOT::Layout::GPOS_impl::AnchorMatrix47 void collect_variation_indices (hb_collect_variation_indices_context_t *c, 48 Iterator index_iter) const 49 { 50 for (unsigned i : index_iter) 51 (this+matrixZ[i]).collect_variation_indices (c); 52 } 53 54 template <typename Iterator, 55 hb_requires (hb_is_iterator (Iterator))> subsetOT::Layout::GPOS_impl::AnchorMatrix56 bool subset (hb_subset_context_t *c, 57 unsigned num_rows, 58 Iterator index_iter) const 59 { 60 TRACE_SUBSET (this); 61 62 auto *out = c->serializer->start_embed (this); 63 64 if (!index_iter) return_trace (false); 65 if (unlikely (!c->serializer->extend_min (out))) return_trace (false); 66 67 out->rows = num_rows; 68 bool ret = false; 69 for (const unsigned i : index_iter) 70 { 71 auto *offset = c->serializer->embed (matrixZ[i]); 72 if (!offset) return_trace (false); 73 ret |= offset->serialize_subset (c, matrixZ[i], this); 74 } 75 76 return_trace (ret); 77 } 78 }; 79 80 81 } 82 } 83 } 84 85 #endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */ 86