[GSUB] Implement Extension subtables
This commit is contained in:
parent
83e61ff470
commit
4f27ce7e02
|
@ -40,18 +40,18 @@
|
||||||
return c.get_coverage (glyph); \
|
return c.get_coverage (glyph); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SUBTABLE_SUBSTITUTE \
|
#define SUBTABLE_SUBSTITUTE_ARGS_DEF \
|
||||||
bool substitute (hb_ot_layout_t *layout, \
|
hb_ot_layout_t *layout, \
|
||||||
hb_buffer_t *buffer, \
|
hb_buffer_t *buffer, \
|
||||||
unsigned int context_length, \
|
unsigned int context_length, \
|
||||||
unsigned int nesting_level_left, \
|
unsigned int nesting_level_left, \
|
||||||
unsigned int lookup_flag) const
|
unsigned int lookup_flag
|
||||||
#define SUBTABLE_SUBSTITUTE_CHAIN(obj) \
|
#define SUBTABLE_SUBSTITUTE_ARGS \
|
||||||
obj.substitute (layout, \
|
layout, \
|
||||||
buffer, \
|
buffer, \
|
||||||
context_length, \
|
context_length, \
|
||||||
nesting_level_left, \
|
nesting_level_left, \
|
||||||
lookup_flag)
|
lookup_flag
|
||||||
|
|
||||||
struct SingleSubstFormat1 {
|
struct SingleSubstFormat1 {
|
||||||
|
|
||||||
|
@ -74,17 +74,6 @@ struct SingleSubstFormat1 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
if ( index >= ss->ssf.ssf2.GlyphCount )
|
|
||||||
return ERR(HB_Err_Invalid_SubTable);
|
|
||||||
value = ss->ssf.ssf2.Substitute[index];
|
|
||||||
if ( REPLACE_Glyph( buffer, value, nesting_level ) )
|
|
||||||
return error;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT substFormat; /* Format identifier--format = 1 */
|
USHORT substFormat; /* Format identifier--format = 1 */
|
||||||
Offset coverage; /* Offset to Coverage table--from
|
Offset coverage; /* Offset to Coverage table--from
|
||||||
|
@ -130,6 +119,8 @@ struct SingleSubst {
|
||||||
|
|
||||||
friend struct SubstLookupSubTable;
|
friend struct SubstLookupSubTable;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
unsigned int get_size (void) const {
|
unsigned int get_size (void) const {
|
||||||
switch (u.substFormat) {
|
switch (u.substFormat) {
|
||||||
case 1: return sizeof (u.format1);
|
case 1: return sizeof (u.format1);
|
||||||
|
@ -138,8 +129,7 @@ struct SingleSubst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
|
||||||
inline SUBTABLE_SUBSTITUTE {
|
|
||||||
|
|
||||||
hb_codepoint_t glyph_id;
|
hb_codepoint_t glyph_id;
|
||||||
unsigned int property;
|
unsigned int property;
|
||||||
|
@ -214,7 +204,7 @@ struct MultipleSubstFormat1 {
|
||||||
DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
|
DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
|
||||||
DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
|
DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
|
||||||
|
|
||||||
inline SUBTABLE_SUBSTITUTE {
|
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
|
||||||
|
|
||||||
hb_codepoint_t glyph_id;
|
hb_codepoint_t glyph_id;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
@ -267,6 +257,10 @@ ASSERT_SIZE (MultipleSubstFormat1, 6);
|
||||||
|
|
||||||
struct MultipleSubst {
|
struct MultipleSubst {
|
||||||
|
|
||||||
|
friend struct SubstLookupSubTable;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
unsigned int get_size (void) const {
|
unsigned int get_size (void) const {
|
||||||
switch (u.substFormat) {
|
switch (u.substFormat) {
|
||||||
case 1: return sizeof (u.format1);
|
case 1: return sizeof (u.format1);
|
||||||
|
@ -274,10 +268,9 @@ struct MultipleSubst {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
|
||||||
inline SUBTABLE_SUBSTITUTE {
|
|
||||||
switch (u.substFormat) {
|
switch (u.substFormat) {
|
||||||
case 1: return SUBTABLE_SUBSTITUTE_CHAIN(u.format1);
|
case 1: return u.format1.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,8 +612,14 @@ struct ChainContextSubstFormat3 {
|
||||||
};
|
};
|
||||||
ASSERT_SIZE (ChainContextSubstFormat3, 10);
|
ASSERT_SIZE (ChainContextSubstFormat3, 10);
|
||||||
|
|
||||||
|
|
||||||
struct ExtensionSubstFormat1 {
|
struct ExtensionSubstFormat1 {
|
||||||
/* TODO */
|
|
||||||
|
friend struct ExtensionSubst;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline unsigned int get_type (void) const { return extensionLookupType; }
|
||||||
|
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
USHORT substFormat; /* Format identifier. Set to 1. */
|
USHORT substFormat; /* Format identifier. Set to 1. */
|
||||||
|
@ -632,6 +631,44 @@ struct ExtensionSubstFormat1 {
|
||||||
};
|
};
|
||||||
ASSERT_SIZE (ExtensionSubstFormat1, 8);
|
ASSERT_SIZE (ExtensionSubstFormat1, 8);
|
||||||
|
|
||||||
|
struct ExtensionSubst {
|
||||||
|
|
||||||
|
friend struct SubstLookup;
|
||||||
|
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 unsigned int get_type (void) const {
|
||||||
|
switch (u.substFormat) {
|
||||||
|
case 1: return u.format1.get_type ();
|
||||||
|
default:return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
|
ExtensionSubstFormat1 format1;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
DEFINE_NULL (ExtensionSubst, 2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ReverseChainSingleSubstFormat1 {
|
struct ReverseChainSingleSubstFormat1 {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
|
||||||
|
@ -678,37 +715,35 @@ 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 1: return u.format1.get_size ();
|
case GSUB_Single: return u.single.get_size ();
|
||||||
// case 2: return u.format2.get_size ();
|
case GSUB_Multiple: return u.multiple.get_size ();
|
||||||
/*
|
/*
|
||||||
case GSUB_Single:
|
|
||||||
case GSUB_Multiple:
|
|
||||||
case GSUB_Alternate:
|
case GSUB_Alternate:
|
||||||
case GSUB_Ligature:
|
case GSUB_Ligature:
|
||||||
case GSUB_Context:
|
case GSUB_Context:
|
||||||
case GSUB_ChainingContext:
|
case GSUB_ChainingContext:
|
||||||
case GSUB_Extension:
|
*/
|
||||||
|
case GSUB_Extension: return u.extension.get_size ();
|
||||||
|
/*
|
||||||
case GSUB_ReverseChainingContextSingle:
|
case GSUB_ReverseChainingContextSingle:
|
||||||
*/
|
*/
|
||||||
default:return sizeof (LookupSubTable);
|
default:return sizeof (LookupSubTable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool substitute (hb_ot_layout_t *layout,
|
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF,
|
||||||
hb_buffer_t *buffer,
|
unsigned int lookup_type) const {
|
||||||
unsigned int context_length,
|
|
||||||
unsigned int nesting_level_left,
|
|
||||||
unsigned int lookup_type,
|
|
||||||
unsigned int lookup_flag) const {
|
|
||||||
switch (lookup_type) {
|
switch (lookup_type) {
|
||||||
case GSUB_Single: return SUBTABLE_SUBSTITUTE_CHAIN (u.singleSubst);
|
case GSUB_Single: return u.single.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
||||||
|
case GSUB_Multiple: return u.multiple.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
||||||
/*
|
/*
|
||||||
case GSUB_Multiple:
|
|
||||||
case GSUB_Alternate:
|
case GSUB_Alternate:
|
||||||
case GSUB_Ligature:
|
case GSUB_Ligature:
|
||||||
case GSUB_Context:
|
case GSUB_Context:
|
||||||
case GSUB_ChainingContext:
|
case GSUB_ChainingContext:
|
||||||
case GSUB_Extension:
|
*/
|
||||||
|
case GSUB_Extension: return u.extension.substitute (SUBTABLE_SUBSTITUTE_ARGS);
|
||||||
|
/*
|
||||||
case GSUB_ReverseChainingContextSingle:
|
case GSUB_ReverseChainingContextSingle:
|
||||||
*/
|
*/
|
||||||
default:return false;
|
default:return false;
|
||||||
|
@ -718,10 +753,23 @@ struct SubstLookupSubTable {
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
USHORT substFormat;
|
USHORT substFormat;
|
||||||
SingleSubst singleSubst;
|
SingleSubst single;
|
||||||
|
MultipleSubst multiple;
|
||||||
|
|
||||||
|
ExtensionSubst extension;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Out-of-class implementation for methods chaining */
|
||||||
|
|
||||||
|
inline bool ExtensionSubstFormat1::substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
|
||||||
|
return (*(SubstLookupSubTable *)(((char *) this) + extensionOffset)).substitute (SUBTABLE_SUBSTITUTE_ARGS,
|
||||||
|
get_type ());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct SubstLookup : Lookup {
|
struct SubstLookup : Lookup {
|
||||||
|
|
||||||
DEFINE_NON_INSTANTIABLE(SubstLookup);
|
DEFINE_NON_INSTANTIABLE(SubstLookup);
|
||||||
|
@ -739,7 +787,7 @@ struct SubstLookup : Lookup {
|
||||||
/* Return lookup type of first extension subtable.
|
/* Return lookup type of first extension subtable.
|
||||||
* The spec says all of them should have the same type.
|
* The spec says all of them should have the same type.
|
||||||
* XXX check for that somehow */
|
* XXX check for that somehow */
|
||||||
//XXX type = get_subtable(0).v.extension.get_type ();
|
type = get_subtable(0).u.extension.get_type ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
|
@ -752,7 +800,7 @@ struct SubstLookup : Lookup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool substitute_once (hb_ot_layout_t *layout,
|
bool substitute_once (hb_ot_layout_t *layout,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
unsigned int context_length,
|
unsigned int context_length,
|
||||||
unsigned int nesting_level_left) const {
|
unsigned int nesting_level_left) const {
|
||||||
|
@ -765,15 +813,14 @@ struct SubstLookup : Lookup {
|
||||||
nesting_level_left--;
|
nesting_level_left--;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < get_subtable_count (); i++)
|
for (unsigned int i = 0; i < get_subtable_count (); i++)
|
||||||
if (get_subtable (i).substitute (layout, buffer,
|
if (get_subtable (i).substitute (SUBTABLE_SUBSTITUTE_ARGS,
|
||||||
context_length, nesting_level_left,
|
lookup_type))
|
||||||
lookup_type, lookup_flag))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool substitute_string (hb_ot_layout_t *layout,
|
bool substitute_string (hb_ot_layout_t *layout,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
hb_ot_layout_feature_mask_t mask) const {
|
hb_ot_layout_feature_mask_t mask) const {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue