2022-06-25 00:36:14 +02:00
|
|
|
#ifndef OT_LAYOUT_GPOS_ANCHORMATRIX_HH
|
|
|
|
#define OT_LAYOUT_GPOS_ANCHORMATRIX_HH
|
|
|
|
|
|
|
|
namespace OT {
|
|
|
|
namespace Layout {
|
2022-06-29 01:26:49 +02:00
|
|
|
namespace GPOS_impl {
|
2022-06-25 00:36:14 +02:00
|
|
|
|
|
|
|
struct AnchorMatrix
|
|
|
|
{
|
|
|
|
HBUINT16 rows; /* Number of rows */
|
|
|
|
UnsizedArrayOf<Offset16To<Anchor>>
|
|
|
|
matrixZ; /* Matrix of offsets to Anchor tables--
|
|
|
|
* from beginning of AnchorMatrix table */
|
|
|
|
public:
|
|
|
|
DEFINE_SIZE_ARRAY (2, matrixZ);
|
|
|
|
|
|
|
|
bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
|
|
|
|
{
|
|
|
|
TRACE_SANITIZE (this);
|
|
|
|
if (!c->check_struct (this)) return_trace (false);
|
|
|
|
if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
|
|
|
|
unsigned int count = rows * cols;
|
|
|
|
if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
|
|
|
|
for (unsigned int i = 0; i < count; i++)
|
|
|
|
if (!matrixZ[i].sanitize (c, this)) return_trace (false);
|
|
|
|
return_trace (true);
|
|
|
|
}
|
|
|
|
|
|
|
|
const Anchor& get_anchor (unsigned int row, unsigned int col,
|
|
|
|
unsigned int cols, bool *found) const
|
|
|
|
{
|
|
|
|
*found = false;
|
|
|
|
if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
|
|
|
|
*found = !matrixZ[row * cols + col].is_null ();
|
|
|
|
return this+matrixZ[row * cols + col];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Iterator,
|
|
|
|
hb_requires (hb_is_iterator (Iterator))>
|
|
|
|
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
|
|
|
Iterator index_iter) const
|
|
|
|
{
|
|
|
|
for (unsigned i : index_iter)
|
|
|
|
(this+matrixZ[i]).collect_variation_indices (c);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Iterator,
|
|
|
|
hb_requires (hb_is_iterator (Iterator))>
|
|
|
|
bool subset (hb_subset_context_t *c,
|
|
|
|
unsigned num_rows,
|
|
|
|
Iterator index_iter) const
|
|
|
|
{
|
|
|
|
TRACE_SUBSET (this);
|
|
|
|
|
|
|
|
auto *out = c->serializer->start_embed (this);
|
|
|
|
|
|
|
|
if (!index_iter) return_trace (false);
|
|
|
|
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
|
|
|
|
|
|
|
out->rows = num_rows;
|
|
|
|
for (const unsigned i : index_iter)
|
|
|
|
{
|
|
|
|
auto *offset = c->serializer->embed (matrixZ[i]);
|
|
|
|
if (!offset) return_trace (false);
|
|
|
|
offset->serialize_subset (c, matrixZ[i], this);
|
|
|
|
}
|
|
|
|
|
|
|
|
return_trace (true);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */
|