[GSUB] Implement Alternate subtables
This commit is contained in:
parent
4f27ce7e02
commit
52886ca56b
|
@ -221,10 +221,12 @@ struct MultipleSubstFormat1 {
|
||||||
glyph_id = IN_CURGLYPH ();
|
glyph_id = IN_CURGLYPH ();
|
||||||
|
|
||||||
index = get_glyph_coverage (glyph_id);
|
index = get_glyph_coverage (glyph_id);
|
||||||
if (index >= sequenceCount)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const Sequence &seq = (*this)[index];
|
const Sequence &seq = (*this)[index];
|
||||||
|
|
||||||
|
if (HB_UNLIKELY (!seq.get_len ()))
|
||||||
|
return false;
|
||||||
|
|
||||||
_hb_buffer_add_output_glyph_ids (buffer, 1,
|
_hb_buffer_add_output_glyph_ids (buffer, 1,
|
||||||
seq.glyphCount, seq.substitute,
|
seq.glyphCount, seq.substitute,
|
||||||
0xFFFF, 0xFFFF);
|
0xFFFF, 0xFFFF);
|
||||||
|
@ -285,7 +287,9 @@ DEFINE_NULL (MultipleSubst, 2);
|
||||||
|
|
||||||
|
|
||||||
struct AlternateSet {
|
struct AlternateSet {
|
||||||
/* TODO */
|
|
||||||
|
/* GlyphIDs, in no particular order */
|
||||||
|
DEFINE_ARRAY_TYPE (GlyphID, alternate, glyphCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT glyphCount; /* Number of GlyphIDs in the Alternate
|
USHORT glyphCount; /* Number of GlyphIDs in the Alternate
|
||||||
|
@ -296,7 +300,62 @@ struct AlternateSet {
|
||||||
DEFINE_NULL_ASSERT_SIZE (AlternateSet, 2);
|
DEFINE_NULL_ASSERT_SIZE (AlternateSet, 2);
|
||||||
|
|
||||||
struct AlternateSubstFormat1 {
|
struct AlternateSubstFormat1 {
|
||||||
/* TODO */
|
|
||||||
|
friend struct AlternateSubst;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* AlternateSet tables, in Coverage Index order */
|
||||||
|
DEFINE_OFFSET_ARRAY_TYPE (AlternateSet, alternateSet, alternateSetCount);
|
||||||
|
DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
|
||||||
|
DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
|
||||||
|
|
||||||
|
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
|
||||||
|
|
||||||
|
hb_codepoint_t glyph_id;
|
||||||
|
unsigned int index;
|
||||||
|
unsigned int property;
|
||||||
|
|
||||||
|
HB_UNUSED (nesting_level_left);
|
||||||
|
|
||||||
|
if (HB_UNLIKELY (context_length < 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
glyph_id = IN_CURGLYPH ();
|
||||||
|
|
||||||
|
index = get_glyph_coverage (glyph_id);
|
||||||
|
|
||||||
|
const AlternateSet &alt_set = (*this)[index];
|
||||||
|
|
||||||
|
if (HB_UNLIKELY (!alt_set.get_len ()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned int alt_index = 0;
|
||||||
|
|
||||||
|
/* XXX callback to user to choose alternate
|
||||||
|
if ( gsub->altfunc )
|
||||||
|
alt_index = (gsub->altfunc)( buffer->out_pos, glyph_id,
|
||||||
|
aset.GlyphCount, aset.Alternate,
|
||||||
|
gsub->data );
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (HB_UNLIKELY (alt_index >= alt_set.get_len ()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
glyph_id = alt_set[alt_index];
|
||||||
|
|
||||||
|
_hb_buffer_replace_output_glyph (buffer, glyph_id, context_length == NO_CONTEXT);
|
||||||
|
|
||||||
|
if ( _hb_ot_layout_has_new_glyph_classes (layout) )
|
||||||
|
{
|
||||||
|
/* we inherit the old glyph class to the substituted glyph */
|
||||||
|
_hb_ot_layout_set_glyph_property (layout, glyph_id, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT substFormat; /* Format identifier--format = 1 */
|
USHORT substFormat; /* Format identifier--format = 1 */
|
||||||
|
@ -310,6 +369,34 @@ struct AlternateSubstFormat1 {
|
||||||
};
|
};
|
||||||
ASSERT_SIZE (AlternateSubstFormat1, 6);
|
ASSERT_SIZE (AlternateSubstFormat1, 6);
|
||||||
|
|
||||||
|
struct AlternateSubst {
|
||||||
|
|
||||||
|
friend struct SubstLookupSubTable;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
unsigned int get_size (void) const {
|
||||||
|
switch (u.substFormat) {
|
||||||
|
case 1: return sizeof (u.format1);
|
||||||
|
default:return sizeof (u.substFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
|
||||||
|
switch (u.substFormat) {
|
||||||
|
case 1: return u.format1.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
||||||
|
default:return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
union {
|
||||||
|
USHORT substFormat; /* Format identifier */
|
||||||
|
AlternateSubstFormat1 format1;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
DEFINE_NULL (AlternateSubst, 2);
|
||||||
|
|
||||||
|
|
||||||
struct Ligature {
|
struct Ligature {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
@ -716,9 +803,9 @@ struct SubstLookupSubTable {
|
||||||
unsigned int get_size (unsigned int lookup_type) const {
|
unsigned int get_size (unsigned int lookup_type) const {
|
||||||
switch (lookup_type) {
|
switch (lookup_type) {
|
||||||
case GSUB_Single: return u.single.get_size ();
|
case GSUB_Single: return u.single.get_size ();
|
||||||
case GSUB_Multiple: return u.multiple.get_size ();
|
case GSUB_Multiple: return u.multiple.get_size ();
|
||||||
/*
|
case GSUB_Alternate: return u.alternate.get_size ();
|
||||||
case GSUB_Alternate:
|
/*
|
||||||
case GSUB_Ligature:
|
case GSUB_Ligature:
|
||||||
case GSUB_Context:
|
case GSUB_Context:
|
||||||
case GSUB_ChainingContext:
|
case GSUB_ChainingContext:
|
||||||
|
@ -736,8 +823,8 @@ struct SubstLookupSubTable {
|
||||||
switch (lookup_type) {
|
switch (lookup_type) {
|
||||||
case GSUB_Single: return u.single.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
case GSUB_Single: return u.single.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
||||||
case GSUB_Multiple: return u.multiple.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
case GSUB_Multiple: return u.multiple.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
||||||
|
case GSUB_Alternate: return u.alternate.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
||||||
/*
|
/*
|
||||||
case GSUB_Alternate:
|
|
||||||
case GSUB_Ligature:
|
case GSUB_Ligature:
|
||||||
case GSUB_Context:
|
case GSUB_Context:
|
||||||
case GSUB_ChainingContext:
|
case GSUB_ChainingContext:
|
||||||
|
@ -755,6 +842,7 @@ struct SubstLookupSubTable {
|
||||||
USHORT substFormat;
|
USHORT substFormat;
|
||||||
SingleSubst single;
|
SingleSubst single;
|
||||||
MultipleSubst multiple;
|
MultipleSubst multiple;
|
||||||
|
AlternateSubst alternate;
|
||||||
|
|
||||||
ExtensionSubst extension;
|
ExtensionSubst extension;
|
||||||
} u;
|
} u;
|
||||||
|
|
|
@ -822,7 +822,7 @@ struct ClassDefFormat1 {
|
||||||
friend struct ClassDef;
|
friend struct ClassDef;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* GlyphIDs, in sorted numerical order */
|
/* Class Values, in sorted numerical order */
|
||||||
DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount);
|
DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount);
|
||||||
|
|
||||||
inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
|
inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
|
||||||
|
|
Loading…
Reference in New Issue