[GSUB] Implement ReverseChainSingleSubst

GSUB is done!
This commit is contained in:
Behdad Esfahbod 2009-05-18 05:47:47 -04:00
parent 4acaffd786
commit 969afd706e
2 changed files with 54 additions and 44 deletions

View File

@ -540,29 +540,56 @@ ASSERT_SIZE (ExtensionSubst, 2);
struct ReverseChainSingleSubstFormat1 { struct ReverseChainSingleSubstFormat1 {
/* TODO */
friend struct ReverseChainSingleSubst;
private:
inline bool substitute (LOOKUP_ARGS_DEF) const { inline bool substitute (LOOKUP_ARGS_DEF) const {
if (HB_UNLIKELY (context_length != NO_CONTEXT))
return false; /* No chaining to this type */
unsigned int index = (this+coverage) (IN_CURGLYPH ());
if (HB_LIKELY (index == NOT_COVERED))
return false;
const OffsetArrayOf<Coverage> &lookahead = * (const OffsetArrayOf<Coverage> *)
((const char *) &backtrack + backtrack.get_size ());
const ArrayOf<GlyphID> &substitute = * (const ArrayOf<GlyphID> *)
((const char *) &lookahead + lookahead.get_size ());
if (match_backtrack (LOOKUP_ARGS,
backtrack.len, (USHORT *) backtrack.array,
match_coverage, (char *) this) &&
match_lookahead (LOOKUP_ARGS,
lookahead.len, (USHORT *) lookahead.array,
match_coverage, (char *) this,
1))
{
IN_CURGLYPH() = substitute[index];
buffer->in_pos--; /* Reverse! */
return true;
}
return false; return false;
} }
private: private:
USHORT format; /* Format identifier--format = 1 */ USHORT format; /* Format identifier--format = 1 */
Offset coverage; /* Offset to Coverage table -- from OffsetTo<Coverage>
* beginning of Substitution table */ coverage; /* Offset to Coverage table--from
USHORT backtrackGlyphCount; /* Number of glyphs in the backtracking * beginning of table */
* sequence */ OffsetArrayOf<Coverage>
Offset backtrackCoverage[]; /* Array of offsets to coverage tables backtrack; /* Array of coverage tables
* in backtracking sequence, in glyph * in backtracking sequence, in glyph
* sequence order */ * sequence order */
USHORT lookaheadGlyphCount; /* Number of glyphs in lookahead OffsetArrayOf<Coverage>
* sequence */ lookaheadX; /* Array of coverage tables
Offset lookaheadCoverage[]; /* Array of offsets to coverage tables * in lookahead sequence, in glyph
* in lookahead sequence, in glyph
* sequence order */ * sequence order */
USHORT glyphCount; /* Number of GlyphIDs in the Substitute ArrayOf<GlyphID>
* array */ substituteX; /* Array of substitute
GlyphID substituteGlyphs[]; /* Array of substitute * GlyphIDs--ordered by Coverage Index */
* GlyphIDs--ordered by Coverage Index */
}; };
ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10); ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10);

View File

@ -221,11 +221,6 @@ static inline bool context_lookup (LOOKUP_ARGS_DEF,
const LookupRecord lookupRecord[], const LookupRecord lookupRecord[],
ContextLookupContext &context) ContextLookupContext &context)
{ {
/* First guess */
if (HB_UNLIKELY (buffer->in_pos + inputCount > buffer->in_length ||
inputCount > context_length))
return false;
return match_input (LOOKUP_ARGS, return match_input (LOOKUP_ARGS,
inputCount, input, inputCount, input,
context.funcs.match, context.match_data, context.funcs.match, context.match_data,
@ -246,10 +241,8 @@ struct Rule {
((const char *) input + ((const char *) input +
sizeof (input[0]) * (inputCount ? inputCount - 1 : 0)); sizeof (input[0]) * (inputCount ? inputCount - 1 : 0));
return context_lookup (LOOKUP_ARGS, return context_lookup (LOOKUP_ARGS,
inputCount, inputCount, input,
input, lookupCount, lookupRecord,
lookupCount,
lookupRecord,
context); context);
} }
@ -374,10 +367,8 @@ struct ContextFormat3 {
(char *) this (char *) this
}; };
return context_lookup (LOOKUP_ARGS, return context_lookup (LOOKUP_ARGS,
glyphCount, glyphCount, (const USHORT *) (coverage + 1),
(const USHORT *) (coverage + 1), lookupCount, lookupRecord,
lookupCount,
lookupRecord,
context); context);
} }
@ -473,14 +464,10 @@ struct ChainRule {
const ArrayOf<LookupRecord> &lookup = * (const ArrayOf<LookupRecord> *) const ArrayOf<LookupRecord> &lookup = * (const ArrayOf<LookupRecord> *)
((const char *) &lookahead + lookahead.get_size ()); ((const char *) &lookahead + lookahead.get_size ());
return chain_context_lookup (LOOKUP_ARGS, return chain_context_lookup (LOOKUP_ARGS,
backtrack.len, backtrack.len, backtrack.array,
backtrack.array, input.len, input.array + 1,
input.len, lookahead.len, lookahead.array,
input.array + 1, lookup.len, lookup.array,
lookahead.len,
lookahead.array,
lookup.len,
lookup.array,
context); context);
return false; return false;
} }
@ -623,7 +610,7 @@ struct ChainContextFormat3 {
return false; return false;
const OffsetArrayOf<Coverage> &lookahead = * (const OffsetArrayOf<Coverage> *) const OffsetArrayOf<Coverage> &lookahead = * (const OffsetArrayOf<Coverage> *)
((const char *) &input + input.get_size ()); ((const char *) &input + input.get_size ());
const ArrayOf<LookupRecord> &lookup = * (const ArrayOf<LookupRecord> *) const ArrayOf<LookupRecord> &lookup = * (const ArrayOf<LookupRecord> *)
((const char *) &lookahead + lookahead.get_size ()); ((const char *) &lookahead + lookahead.get_size ());
struct ChainContextLookupContext context = { struct ChainContextLookupContext context = {
@ -631,14 +618,10 @@ struct ChainContextFormat3 {
{(char *) this, (char *) this, (char *) this} {(char *) this, (char *) this, (char *) this}
}; };
return chain_context_lookup (LOOKUP_ARGS, return chain_context_lookup (LOOKUP_ARGS,
backtrack.len, backtrack.len, (USHORT *) backtrack.array,
(USHORT *) backtrack.array, input.len, (USHORT *) input.array,
input.len, lookahead.len, (USHORT *) lookahead.array,
(USHORT *) input.array, lookup.len, lookup.array,
lookahead.len,
(USHORT *) lookahead.array,
lookup.len,
lookup.array,
context); context);
return false; return false;
} }