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 for (unsigned int i = 0; i < count; i++) 25 if (!matrixZ[i].sanitize (c, this)) return_trace (false); 26 return_trace (true); 27 } 28 get_anchorOT::Layout::GPOS_impl::AnchorMatrix29 const Anchor& get_anchor (unsigned int row, unsigned int col, 30 unsigned int cols, bool *found) const 31 { 32 *found = false; 33 if (unlikely (row >= rows || col >= cols)) return Null (Anchor); 34 *found = !matrixZ[row * cols + col].is_null (); 35 return this+matrixZ[row * cols + col]; 36 } 37 38 template <typename Iterator, 39 hb_requires (hb_is_iterator (Iterator))> collect_variation_indicesOT::Layout::GPOS_impl::AnchorMatrix40 void collect_variation_indices (hb_collect_variation_indices_context_t *c, 41 Iterator index_iter) const 42 { 43 for (unsigned i : index_iter) 44 (this+matrixZ[i]).collect_variation_indices (c); 45 } 46 47 template <typename Iterator, 48 hb_requires (hb_is_iterator (Iterator))> subsetOT::Layout::GPOS_impl::AnchorMatrix49 bool subset (hb_subset_context_t *c, 50 unsigned num_rows, 51 Iterator index_iter) const 52 { 53 TRACE_SUBSET (this); 54 55 auto *out = c->serializer->start_embed (this); 56 57 if (!index_iter) return_trace (false); 58 if (unlikely (!c->serializer->extend_min (out))) return_trace (false); 59 60 out->rows = num_rows; 61 for (const unsigned i : index_iter) 62 { 63 auto *offset = c->serializer->embed (matrixZ[i]); 64 if (!offset) return_trace (false); 65 offset->serialize_subset (c, matrixZ[i], this); 66 } 67 68 return_trace (true); 69 } 70 }; 71 72 73 } 74 } 75 } 76 77 #endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */ 78