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