xref: /aosp_15_r20/external/harfbuzz_ng/src/OT/Layout/GPOS/AnchorMatrix.hh (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
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