diff options
author | Behdad Esfahbod <behdad@behdad.org> | 2016-03-12 23:49:09 -0800 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2016-12-16 19:06:26 -0600 |
commit | 71b06fd392680b6fcfece60d8a83ba6c56eada09 (patch) | |
tree | a74b2f4dff8fb1f02ee949ab2eedea08b167ea6f /src | |
parent | 976eeb8e025e2b7601a91e661d6e9a88bf8afbd2 (diff) |
[GX] Add VariationAlternates, to allow conditional lookups in GSUB/GPOS
Not hooked up to runtime yet.
Diffstat (limited to 'src')
-rw-r--r-- | src/hb-open-type-private.hh | 1 | ||||
-rw-r--r-- | src/hb-ot-layout-common-private.hh | 99 |
2 files changed, 98 insertions, 2 deletions
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 66f1c08d..865429da 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -630,6 +630,7 @@ struct IntType inline operator Type(void) const { return v; } inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; } inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); } + inline unsigned int get_size (void) const { return Size; } static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); } inline int cmp (Type a) const { diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index 3154cfe7..328472fb 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -575,6 +575,7 @@ struct LookupFlag : USHORT IgnoreMarks = 0x0008u, IgnoreFlags = 0x000Eu, UseMarkFilteringSet = 0x0010u, + UseVariationAlternates= 0x0020u, Reserved = 0x00E0u, MarkAttachmentType = 0xFF00u }; @@ -587,6 +588,88 @@ struct LookupFlag : USHORT HB_MARK_AS_FLAG_T (OT::LookupFlag::Flags); namespace OT { +struct VariationGridAxis +{ + inline int locate (int *coords, unsigned int coord_len) const + { + int coord = axisIndex < coord_len ? coords[axisIndex] : 0; + + unsigned int count = axisCoords.len; + unsigned int i = 0; + while (i + 1 < count && coord < axisCoords[i + 1]) + i++; + + return axisCoords[i] <= coord ? i : -1; + } + + inline unsigned int get_len (void) const + { + return axisCoords.len - 1; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && axisCoords.sanitize (c)); + } + + Index axisIndex; + SortedArrayOf<F2DOT14> axisCoords; + public: + DEFINE_SIZE_ARRAY (4, axisCoords); +}; + +struct VariationGrid +{ + inline int locate (int *coords, unsigned int coord_len) const + { + int location = 0; + unsigned int count = axes.len; + for (unsigned int i = 0; i < count; i++) + { + const VariationGridAxis &axis = (this+axes[i]); + int axisLoc = axis.locate (coords, coord_len); + if (axisLoc == -1) + return -1; + location = location * (axis.get_len () - 1) + axisLoc; /* XXX Check for overflow?. */ + } + return location; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (axes.sanitize (c, this)); + } + + OffsetArrayOf<VariationGridAxis> + axes; + public: + DEFINE_SIZE_ARRAY (2, axes); +}; + +struct VariationAlternates +{ + inline unsigned int get_lookup_index (int *coords, unsigned int coord_len) const + { + int location = (this+grid).locate (coords, coord_len); + if (location == -1) + return 0xFFFE; /* TODO: give it a name. */ + return lookupIndex[location]; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (grid.sanitize (c, this) && lookupIndex.sanitize (c)); + } + + OffsetTo<VariationGrid> grid; + IndexArray lookupIndex; + public: + DEFINE_SIZE_ARRAY (4, lookupIndex); +}; + struct Lookup { inline unsigned int get_subtable_count (void) const { return subTable.len; } @@ -655,10 +738,17 @@ struct Lookup TRACE_SANITIZE (this); /* Real sanitize of the subtables is done by GSUB/GPOS/... */ if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); + const void *cursor = &StructAfter<char> (subTable); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { - const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); + const USHORT &markFilteringSet = CastR<USHORT> (cursor); if (!markFilteringSet.sanitize (c)) return_trace (false); + cursor = &StructAfter<char> (markFilteringSet); + } + if (lookupFlag & LookupFlag::UseVariationAlternates) + { + const OffsetTo<VariationAlternates,ULONG> &varAlts = CastR<const OffsetTo<VariationAlternates,ULONG> > (cursor); + if (!varAlts.sanitize (c, this)) return_trace (false); } return_trace (true); } @@ -671,8 +761,13 @@ struct Lookup USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets * structure. This field is only present if bit * UseMarkFilteringSet of lookup flags is set. */ + OffsetTo<VariationAlternates,ULONG> + variationAlternatesZ[VAR]; + /* Index (base 0) into GDEF mark glyph sets + * structure. This field is only present if bit + * UseMarkFilteringSet of lookup flags is set. */ public: - DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); + DEFINE_SIZE_MIN (6); }; typedef OffsetListOf<Lookup> LookupList; |