mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-13 08:42:59 +00:00
commit
00541f1952
7 changed files with 83 additions and 43 deletions
|
@ -386,11 +386,22 @@ struct Glyph
|
|||
|
||||
#ifndef HB_NO_VAR
|
||||
if (coords)
|
||||
glyf_accelerator.gvar->apply_deltas_to_points (gid,
|
||||
coords,
|
||||
points.as_array ().sub_array (old_length),
|
||||
scratch,
|
||||
phantom_only && type == SIMPLE);
|
||||
{
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
if (glyf_accelerator.GVAR->has_data ())
|
||||
glyf_accelerator.GVAR->apply_deltas_to_points (gid,
|
||||
coords,
|
||||
points.as_array ().sub_array (old_length),
|
||||
scratch,
|
||||
phantom_only && type == SIMPLE);
|
||||
else
|
||||
#endif
|
||||
glyf_accelerator.gvar->apply_deltas_to_points (gid,
|
||||
coords,
|
||||
points.as_array ().sub_array (old_length),
|
||||
scratch,
|
||||
phantom_only && type == SIMPLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
// mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
|
||||
|
|
|
@ -172,6 +172,9 @@ struct glyf_accelerator_t
|
|||
glyf_table = nullptr;
|
||||
#ifndef HB_NO_VAR
|
||||
gvar = nullptr;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
GVAR = nullptr;
|
||||
#endif
|
||||
#endif
|
||||
hmtx = nullptr;
|
||||
#ifndef HB_NO_VERTICAL
|
||||
|
@ -187,6 +190,9 @@ struct glyf_accelerator_t
|
|||
glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
|
||||
#ifndef HB_NO_VAR
|
||||
gvar = face->table.gvar;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
GVAR = face->table.GVAR;
|
||||
#endif
|
||||
#endif
|
||||
hmtx = face->table.hmtx;
|
||||
#ifndef HB_NO_VERTICAL
|
||||
|
@ -512,6 +518,9 @@ struct glyf_accelerator_t
|
|||
|
||||
#ifndef HB_NO_VAR
|
||||
const gvar_accelerator_t *gvar;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
const GVAR_accelerator_t *GVAR;
|
||||
#endif
|
||||
#endif
|
||||
const hmtx_accelerator_t *hmtx;
|
||||
#ifndef HB_NO_VERTICAL
|
||||
|
|
|
@ -95,6 +95,9 @@ HB_OT_CORE_TABLE (OT, fvar)
|
|||
HB_OT_CORE_TABLE (OT, avar)
|
||||
HB_OT_CORE_TABLE (OT, cvar)
|
||||
HB_OT_ACCELERATOR (OT, gvar)
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
HB_OT_ACCELERATOR (OT, GVAR)
|
||||
#endif
|
||||
HB_OT_CORE_TABLE (OT, MVAR)
|
||||
#ifndef HB_NO_VAR_COMPOSITES
|
||||
HB_OT_ACCELERATOR (OT, VARC)
|
||||
|
|
|
@ -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>*;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
* https://docs.microsoft.com/en-us/typography/opentype/spec/gvar
|
||||
*/
|
||||
#define HB_OT_TAG_gvar HB_TAG('g','v','a','r')
|
||||
#define HB_OT_TAG_GVAR HB_TAG('G','V','A','R')
|
||||
|
||||
struct hb_glyf_scratch_t
|
||||
{
|
||||
|
@ -58,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;
|
||||
|
@ -105,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;
|
||||
|
@ -279,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)
|
||||
{
|
||||
|
@ -293,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)
|
||||
|
@ -316,9 +318,14 @@ struct glyph_variations_t
|
|||
}
|
||||
};
|
||||
|
||||
struct gvar
|
||||
template <typename GidOffsetType, unsigned TableTag>
|
||||
struct gvar_GVAR
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar;
|
||||
static constexpr hb_tag_t tableTag = TableTag;
|
||||
|
||||
using GlyphVariationData = TupleVariationData<GidOffsetType>;
|
||||
|
||||
bool has_data () const { return version.to_int () != 0; }
|
||||
|
||||
bool sanitize_shallow (hb_sanitize_context_t *c) const
|
||||
{
|
||||
|
@ -337,7 +344,7 @@ struct 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);
|
||||
|
@ -364,14 +371,14 @@ struct 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,
|
||||
bool force_long_offsets) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
gvar *out = c->allocate_min<gvar> ();
|
||||
gvar_GVAR *out = c->allocate_min<gvar_GVAR> ();
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
out->version.major = 1;
|
||||
|
@ -413,7 +420,7 @@ struct 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);
|
||||
|
||||
|
@ -443,7 +450,7 @@ struct gvar
|
|||
|
||||
unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0;
|
||||
|
||||
gvar *out = c->serializer->allocate_min<gvar> ();
|
||||
gvar_GVAR *out = c->serializer->allocate_min<gvar_GVAR> ();
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
out->version.major = 1;
|
||||
|
@ -577,9 +584,11 @@ struct gvar
|
|||
public:
|
||||
struct accelerator_t
|
||||
{
|
||||
bool has_data () const { return table->has_data (); }
|
||||
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
table = hb_sanitize_context_t ().reference_table<gvar> (face);
|
||||
table = hb_sanitize_context_t ().reference_table<gvar_GVAR> (face);
|
||||
/* If sanitize failed, set glyphCount to 0. */
|
||||
glyphCount = table->version.to_int () ? face->get_num_glyphs () : 0;
|
||||
|
||||
|
@ -658,7 +667,7 @@ struct 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))
|
||||
|
@ -875,7 +884,7 @@ struct gvar
|
|||
unsigned int get_axis_count () const { return table->axisCount; }
|
||||
|
||||
private:
|
||||
hb_blob_ptr_t<gvar> table;
|
||||
hb_blob_ptr_t<gvar_GVAR> table;
|
||||
unsigned glyphCount;
|
||||
hb_vector_t<hb_pair_t<int, int>> shared_tuple_active_idx;
|
||||
};
|
||||
|
@ -893,7 +902,7 @@ struct gvar
|
|||
NNOffset32To<UnsizedArrayOf<F2DOT14>>
|
||||
sharedTuples; /* Offset from the start of this table to the shared tuple records.
|
||||
* Array of tuple records shared across all glyph variation data tables. */
|
||||
HBUINT16 glyphCountX; /* The number of glyphs in this font. This must match the number of
|
||||
GidOffsetType glyphCountX; /* The number of glyphs in this font. This must match the number of
|
||||
* glyphs stored elsewhere in the font. */
|
||||
HBUINT16 flags; /* Bit-field that gives the format of the offset array that follows.
|
||||
* If bit 0 is clear, the offsets are uint16; if bit 0 is set, the
|
||||
|
@ -908,9 +917,15 @@ struct gvar
|
|||
DEFINE_SIZE_ARRAY (20, offsetZ);
|
||||
};
|
||||
|
||||
using gvar = gvar_GVAR<HBUINT16, HB_OT_TAG_gvar>;
|
||||
using GVAR = gvar_GVAR<HBUINT24, HB_OT_TAG_GVAR>;
|
||||
|
||||
struct gvar_accelerator_t : gvar::accelerator_t {
|
||||
gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {}
|
||||
};
|
||||
struct GVAR_accelerator_t : GVAR::accelerator_t {
|
||||
GVAR_accelerator_t (hb_face_t *face) : GVAR::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue