1 #ifndef OT_LAYOUT_GPOS_ANCHORMATRIX_HH
2 #define OT_LAYOUT_GPOS_ANCHORMATRIX_HH
10 HBUINT16 rows; /* Number of rows */
11 UnsizedArrayOf<Offset16To<Anchor>>
12 matrixZ; /* Matrix of offsets to Anchor tables--
13 * from beginning of AnchorMatrix table */
15 DEFINE_SIZE_ARRAY (2, matrixZ);
17 bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
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);
25 if (c->lazy_some_gpos)
28 for (unsigned int i = 0; i < count; i++)
29 if (!matrixZ[i].sanitize (c, this)) return_trace (false);
33 const Anchor& get_anchor (hb_ot_apply_context_t *c,
34 unsigned int row, unsigned int col,
35 unsigned int cols, bool *found) const
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 ();
45 template <typename Iterator,
46 hb_requires (hb_is_iterator (Iterator))>
47 void collect_variation_indices (hb_collect_variation_indices_context_t *c,
48 Iterator index_iter) const
50 for (unsigned i : index_iter)
51 (this+matrixZ[i]).collect_variation_indices (c);
54 template <typename Iterator,
55 hb_requires (hb_is_iterator (Iterator))>
56 bool subset (hb_subset_context_t *c,
58 Iterator index_iter) const
62 auto *out = c->serializer->start_embed (this);
64 if (!index_iter) return_trace (false);
65 if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
69 for (const unsigned i : index_iter)
71 auto *offset = c->serializer->embed (matrixZ[i]);
72 if (!offset) return_trace (false);
73 ret |= offset->serialize_subset (c, matrixZ[i], this);
85 #endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */