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, AnchorMatrix>> 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 hb_barrier (); 22 if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false); 23 unsigned int count = rows * cols; 24 if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false); 25 26 if (c->lazy_some_gpos) 27 return_trace (true); 28 29 hb_barrier (); 30 for (unsigned int i = 0; i < count; i++) 31 if (!matrixZ[i].sanitize (c, this)) return_trace (false); 32 return_trace (true); 33 } 34 get_anchorOT::Layout::GPOS_impl::AnchorMatrix35 const Anchor& get_anchor (hb_ot_apply_context_t *c, 36 unsigned int row, unsigned int col, 37 unsigned int cols, bool *found) const 38 { 39 *found = false; 40 if (unlikely (row >= rows || col >= cols)) return Null (Anchor); 41 auto &offset = matrixZ[row * cols + col]; 42 if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor); 43 hb_barrier (); 44 *found = !offset.is_null (); 45 return this+offset; 46 } 47 48 template <typename Iterator, 49 hb_requires (hb_is_iterator (Iterator))> collect_variation_indicesOT::Layout::GPOS_impl::AnchorMatrix50 void collect_variation_indices (hb_collect_variation_indices_context_t *c, 51 Iterator index_iter) const 52 { 53 for (unsigned i : index_iter) 54 (this+matrixZ[i]).collect_variation_indices (c); 55 } 56 57 template <typename Iterator, 58 hb_requires (hb_is_iterator (Iterator))> subsetOT::Layout::GPOS_impl::AnchorMatrix59 bool subset (hb_subset_context_t *c, 60 unsigned num_rows, 61 Iterator index_iter) const 62 { 63 TRACE_SUBSET (this); 64 65 auto *out = c->serializer->start_embed (this); 66 67 if (!index_iter) return_trace (false); 68 if (unlikely (!c->serializer->extend_min (out))) return_trace (false); 69 70 out->rows = num_rows; 71 for (const unsigned i : index_iter) 72 { 73 auto *offset = c->serializer->embed (matrixZ[i]); 74 if (!offset) return_trace (false); 75 offset->serialize_subset (c, matrixZ[i], this); 76 } 77 78 return_trace (true); 79 } 80 }; 81 82 83 } 84 } 85 } 86 87 #endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */ 88