• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 
get_anchorOT::Layout::GPOS_impl::AnchorMatrix33   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))>
collect_variation_indicesOT::Layout::GPOS_impl::AnchorMatrix47   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))>
subsetOT::Layout::GPOS_impl::AnchorMatrix56   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 */
86