[GVAR] Change offsetToData size to 24bit

As per https://github.com/harfbuzz/boring-expansion-spec/issues/162
This commit is contained in:
Behdad Esfahbod 2025-02-26 13:40:18 -07:00
parent 894fee6db3
commit ffe955b9f9
4 changed files with 36 additions and 31 deletions

View file

@ -841,6 +841,7 @@ struct tuple_delta_t
{ return (i >= end) ? start : (i + 1); }
};
template <typename OffType = HBUINT16>
struct TupleVariationData
{
bool sanitize (hb_sanitize_context_t *c) const
@ -1521,15 +1522,16 @@ struct TupleVariationData
* low 12 bits are the number of tuple variation tables
* for this glyph. The number of tuple variation tables
* can be any number between 1 and 4095. */
Offset16To<HBUINT8>
OffsetTo<HBUINT8, OffType>
data; /* Offset from the start of the base table
* to the serialized data. */
/* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */
public:
DEFINE_SIZE_MIN (4);
DEFINE_SIZE_MIN (2 + OffType::static_size);
};
using tuple_variations_t = TupleVariationData::tuple_variations_t;
// TODO: Move tuple_variations_t to outside of TupleVariationData
using tuple_variations_t = TupleVariationData<HBUINT16>::tuple_variations_t;
struct item_variations_t
{
using region_t = const hb_hashmap_t<hb_tag_t, Triple>*;

View file

@ -50,7 +50,7 @@ struct cvar
tupleVariationData.sanitize (c));
}
const TupleVariationData* get_tuple_var_data (void) const
const TupleVariationData<>* get_tuple_var_data (void) const
{ return &tupleVariationData; }
bool decompile_tuple_variations (unsigned axis_count,
@ -58,12 +58,12 @@ struct cvar
hb_blob_t *blob,
bool is_gvar,
const hb_map_t *axes_old_index_tag_map,
TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const
TupleVariationData<>::tuple_variations_t& tuple_variations /* OUT */) const
{
hb_vector_t<unsigned> shared_indices;
TupleVariationData::tuple_iterator_t iterator;
TupleVariationData<>::tuple_iterator_t iterator;
hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4);
if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this,
if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, this,
shared_indices, &iterator))
return false;
@ -77,16 +77,16 @@ struct cvar
static bool calculate_cvt_deltas (unsigned axis_count,
hb_array_t<int> coords,
unsigned num_cvt_item,
const TupleVariationData *tuple_var_data,
const TupleVariationData<> *tuple_var_data,
const void *base,
hb_vector_t<float>& cvt_deltas /* OUT */)
{
if (!coords) return true;
hb_vector_t<unsigned> shared_indices;
TupleVariationData::tuple_iterator_t iterator;
TupleVariationData<>::tuple_iterator_t iterator;
unsigned var_data_length = tuple_var_data->get_size (axis_count);
hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast<const char*> (tuple_var_data), var_data_length);
if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, base,
if (!TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, base,
shared_indices, &iterator))
return true; /* isn't applied at all */
@ -107,14 +107,14 @@ struct cvar
bool has_private_points = iterator.current_tuple->has_private_points ();
if (has_private_points &&
!TupleVariationData::decompile_points (p, private_indices, end))
!TupleVariationData<>::decompile_points (p, private_indices, end))
return false;
const hb_vector_t<unsigned int> &indices = has_private_points ? private_indices : shared_indices;
bool apply_to_all = (indices.length == 0);
unsigned num_deltas = apply_to_all ? num_cvt_item : indices.length;
if (unlikely (!unpacked_deltas.resize (num_deltas, false))) return false;
if (unlikely (!TupleVariationData::decompile_deltas (p, unpacked_deltas, end))) return false;
if (unlikely (!TupleVariationData<>::decompile_deltas (p, unpacked_deltas, end))) return false;
for (unsigned int i = 0; i < num_deltas; i++)
{
@ -129,7 +129,7 @@ struct cvar
}
bool serialize (hb_serialize_context_t *c,
TupleVariationData::tuple_variations_t& tuple_variations) const
TupleVariationData<>::tuple_variations_t& tuple_variations) const
{
TRACE_SERIALIZE (this);
if (!tuple_variations) return_trace (false);
@ -144,7 +144,7 @@ struct cvar
if (c->plan->all_axes_pinned)
return_trace (false);
OT::TupleVariationData::tuple_variations_t tuple_variations;
OT::TupleVariationData<>::tuple_variations_t tuple_variations;
unsigned axis_count = c->plan->axes_old_index_tag_map.get_population ();
const hb_tag_t cvt = HB_TAG('c','v','t',' ');
@ -169,7 +169,7 @@ struct cvar
}
static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan,
const TupleVariationData *tuple_var_data,
const TupleVariationData<> *tuple_var_data,
const void *base)
{
const hb_tag_t cvt = HB_TAG('c','v','t',' ');
@ -209,7 +209,7 @@ struct cvar
protected:
FixedVersion<>version; /* Version of the CVT variation table
* initially set to 0x00010000u */
TupleVariationData tupleVariationData; /* TupleVariationDate for cvar table */
TupleVariationData<> tupleVariationData; /* TupleVariationDate for cvar table */
public:
DEFINE_SIZE_MIN (8);
};

View file

@ -59,12 +59,13 @@ struct hb_glyf_scratch_t
namespace OT {
struct GlyphVariationData : TupleVariationData
{};
template <typename OffsetType>
struct glyph_variations_t
{
using tuple_variations_t = TupleVariationData::tuple_variations_t;
// TODO: Move tuple_variations_t to outside of TupleVariationData
using tuple_variations_t = typename TupleVariationData<OffsetType>::tuple_variations_t;
using GlyphVariationData = TupleVariationData<OffsetType>;
hb_vector_t<tuple_variations_t> glyph_variations;
hb_vector_t<char> compiled_shared_tuples;
@ -106,7 +107,7 @@ struct glyph_variations_t
hb_bytes_t var_data = new_gid_var_data_map.get (new_gid);
const GlyphVariationData* p = reinterpret_cast<const GlyphVariationData*> (var_data.arrayZ);
GlyphVariationData::tuple_iterator_t iterator;
typename GlyphVariationData::tuple_iterator_t iterator;
tuple_variations_t tuple_vars;
hb_vector_t<unsigned> shared_indices;
@ -280,7 +281,7 @@ struct glyph_variations_t
hb_codepoint_t last_gid = 0;
unsigned idx = 0;
TupleVariationData* cur_glyph = c->start_embed<TupleVariationData> ();
GlyphVariationData* cur_glyph = c->start_embed<GlyphVariationData> ();
if (!cur_glyph) return_trace (false);
for (auto &_ : it)
{
@ -294,7 +295,7 @@ struct glyph_variations_t
if (idx >= glyph_variations.length) return_trace (false);
if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false);
TupleVariationData* next_glyph = c->start_embed<TupleVariationData> ();
GlyphVariationData* next_glyph = c->start_embed<GlyphVariationData> ();
glyph_offset += (char *) next_glyph - (char *) cur_glyph;
if (long_offset)
@ -322,6 +323,8 @@ struct gvar_GVAR
{
static constexpr hb_tag_t tableTag = TableTag;
using GlyphVariationData = TupleVariationData<GidOffsetType>;
bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -339,7 +342,7 @@ struct gvar_GVAR
{ return sanitize_shallow (c); }
bool decompile_glyph_variations (hb_subset_context_t *c,
glyph_variations_t& glyph_vars /* OUT */) const
glyph_variations_t<GidOffsetType>& glyph_vars /* OUT */) const
{
hb_hashmap_t<hb_codepoint_t, hb_bytes_t> new_gid_var_data_map;
auto it = hb_iter (c->plan->new_to_old_gid_list);
@ -366,7 +369,7 @@ struct gvar_GVAR
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
bool serialize (hb_serialize_context_t *c,
const glyph_variations_t& glyph_vars,
const glyph_variations_t<GidOffsetType>& glyph_vars,
Iterator it,
unsigned axis_count,
unsigned num_glyphs,
@ -415,7 +418,7 @@ struct gvar_GVAR
bool instantiate (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
glyph_variations_t glyph_vars;
glyph_variations_t<GidOffsetType> glyph_vars;
if (!decompile_glyph_variations (c, glyph_vars))
return_trace (false);
@ -660,7 +663,7 @@ struct gvar_GVAR
auto &shared_indices = scratch.shared_indices;
shared_indices.clear ();
GlyphVariationData::tuple_iterator_t iterator;
typename GlyphVariationData::tuple_iterator_t iterator;
if (!GlyphVariationData::get_tuple_iterator (var_data_bytes, table->axisCount,
var_data_bytes.arrayZ,
shared_indices, &iterator))

View file

@ -38,15 +38,15 @@ test_decompile_cvar ()
hb_map_t axis_idx_tag_map;
axis_idx_tag_map.set (0, axis_tag);
OT::TupleVariationData::tuple_variations_t tuple_variations;
OT::TupleVariationData<>::tuple_variations_t tuple_variations;
hb_vector_t<unsigned> shared_indices;
OT::TupleVariationData::tuple_iterator_t iterator;
OT::TupleVariationData<>::tuple_iterator_t iterator;
const OT::TupleVariationData* tuple_var_data = reinterpret_cast<const OT::TupleVariationData*> (cvar_data + 4);
const OT::TupleVariationData<>* tuple_var_data = reinterpret_cast<const OT::TupleVariationData<>*> (cvar_data + 4);
unsigned len = sizeof (cvar_data);
hb_bytes_t var_data_bytes{(const char* ) cvar_data + 4, len - 4};
bool result = OT::TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, cvar_table,
bool result = OT::TupleVariationData<>::get_tuple_iterator (var_data_bytes, axis_count, cvar_table,
shared_indices, &iterator);
assert (result);