[GX] Implement Feature Variations
Not hooked up to shaper yet.
This commit is contained in:
parent
85ec494434
commit
59055b5494
|
@ -507,7 +507,7 @@ struct Feature
|
|||
{ return this+featureParams; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c,
|
||||
const Record<Feature>::sanitize_closure_t *closure) const
|
||||
const Record<Feature>::sanitize_closure_t *closure = NULL) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
|
||||
|
@ -1333,6 +1333,172 @@ struct VariationStore
|
|||
DEFINE_SIZE_ARRAY (8, dataSets);
|
||||
};
|
||||
|
||||
/*
|
||||
* Feature Variations
|
||||
*/
|
||||
|
||||
struct ConditionFormat1
|
||||
{
|
||||
friend struct Condition;
|
||||
|
||||
private:
|
||||
inline bool evaluate (int *coords, unsigned int coord_len) const
|
||||
{
|
||||
int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
|
||||
return filterRangeMinValue <= coord && coord <= filterRangeMaxValue;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT format; /* Format identifier--format = 1 */
|
||||
USHORT axisIndex;
|
||||
F2DOT14 filterRangeMinValue;
|
||||
F2DOT14 filterRangeMaxValue;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
||||
struct Condition
|
||||
{
|
||||
inline bool evaluate (int *coords, unsigned int coord_len) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.evaluate (coords, coord_len);
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return_trace (false);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (u.format1.sanitize (c));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
ConditionFormat1 format1;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
struct ConditionSet
|
||||
{
|
||||
inline bool evaluate (int *coords, unsigned int coord_len) const
|
||||
{
|
||||
unsigned int count = conditions.len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!(this+conditions.array[i]).evaluate (coords, coord_len))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (conditions.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetArrayOf<Condition, ULONG> conditions;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, conditions);
|
||||
};
|
||||
|
||||
struct FeatureTableSubstitutionRecord
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && feature.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT featureIndex;
|
||||
OffsetTo<Feature, ULONG> feature;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
struct FeatureTableSubstitution
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (version.sanitize (c) &&
|
||||
likely (version.major == 1) &&
|
||||
substitutions.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<> version; /* Version--0x00010000u */
|
||||
OffsetArrayOf<FeatureTableSubstitutionRecord, ULONG>
|
||||
substitutions;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, substitutions);
|
||||
};
|
||||
|
||||
struct FeatureVariationRecord
|
||||
{
|
||||
friend struct FeatureVariations;
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (conditions.sanitize (c, base) &&
|
||||
substitutions.sanitize (c, base));
|
||||
}
|
||||
|
||||
protected:
|
||||
OffsetTo<ConditionSet, ULONG>
|
||||
conditions;
|
||||
OffsetTo<FeatureTableSubstitution, ULONG>
|
||||
substitutions;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
||||
struct FeatureVariations
|
||||
{
|
||||
inline const FeatureTableSubstitution &
|
||||
get_substitutions (int *coords, unsigned int coord_len) const
|
||||
{
|
||||
unsigned int count = varRecords.len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
const FeatureVariationRecord &record = varRecords.array[i];
|
||||
if ((this+record.conditions).evaluate (coords, coord_len))
|
||||
return (this+record.substitutions);
|
||||
}
|
||||
return Null(FeatureTableSubstitution);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (version.sanitize (c) &&
|
||||
likely (version.major == 1) &&
|
||||
varRecords.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<> version; /* Version--0x00010000u */
|
||||
ArrayOf<FeatureVariationRecord, ULONG>
|
||||
varRecords;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, varRecords);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Device Tables
|
||||
|
|
|
@ -397,7 +397,6 @@ struct GDEF
|
|||
(version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
|
||||
}
|
||||
|
||||
|
||||
/* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
|
||||
* glyph class and other bits, and high 8-bit gthe mark attachment type (if any).
|
||||
* Not to be confused with lookup_props which is very similar. */
|
||||
|
|
|
@ -1518,8 +1518,6 @@ struct GPOS : GSUBGPOS
|
|||
const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
|
||||
return_trace (list.sanitize (c, this));
|
||||
}
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1273,8 +1273,6 @@ struct GSUB : GSUBGPOS
|
|||
const OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
|
||||
return_trace (list.sanitize (c, this));
|
||||
}
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2271,6 +2271,11 @@ struct GSUBGPOS
|
|||
inline const Lookup& get_lookup (unsigned int i) const
|
||||
{ return (this+lookupList)[i]; }
|
||||
|
||||
inline const FeatureTableSubstitution &
|
||||
get_feature_substitutions (int *coords, unsigned int coord_len) const
|
||||
{ return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
|
||||
.get_substitutions (coords, coord_len); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -2278,7 +2283,8 @@ struct GSUBGPOS
|
|||
likely (version.major == 1) &&
|
||||
scriptList.sanitize (c, this) &&
|
||||
featureList.sanitize (c, this) &&
|
||||
lookupList.sanitize (c, this));
|
||||
lookupList.sanitize (c, this) &&
|
||||
(version.to_int () < 0x00010001u || featureVars.sanitize (c, this)));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -2290,8 +2296,13 @@ struct GSUBGPOS
|
|||
featureList; /* FeatureList table */
|
||||
OffsetTo<LookupList>
|
||||
lookupList; /* LookupList table */
|
||||
OffsetTo<FeatureVariations, ULONG>
|
||||
featureVars; /* Offset to Feature Variations
|
||||
table--from beginning of table
|
||||
* (may be NULL). Introduced
|
||||
* in version 0x00010001. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
DEFINE_SIZE_MIN (10);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue