Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / src / OT / Layout / GPOS / AnchorMatrix.hh
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
17   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
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
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))>
47   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))>
56   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 */