[aat] Implement ContextualSubtable
Tested with Zapfino and text "2nd". Sascha will create tests later.
This commit is contained in:
parent
335a9c1fe4
commit
f9be673814
|
@ -200,8 +200,70 @@ struct ContextualSubtable
|
||||||
inline bool apply (hb_apply_context_t *c) const
|
inline bool apply (hb_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
/* TODO */
|
|
||||||
return_trace (false);
|
bool ret = false;
|
||||||
|
unsigned int num_glyphs = c->face->get_num_glyphs ();
|
||||||
|
|
||||||
|
const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT> &subs = this+substitutionTables;
|
||||||
|
|
||||||
|
unsigned int state = 0;
|
||||||
|
unsigned int last_zero = 0;
|
||||||
|
unsigned int last_zero_before_mark = 0;
|
||||||
|
unsigned int mark = 0;
|
||||||
|
|
||||||
|
hb_glyph_info_t *info = c->buffer->info;
|
||||||
|
unsigned int count = c->buffer->len;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i <= count; i++)
|
||||||
|
{
|
||||||
|
if (!state)
|
||||||
|
last_zero = i;
|
||||||
|
|
||||||
|
unsigned int klass = i < count ?
|
||||||
|
machine.get_class (info[i].codepoint, num_glyphs) :
|
||||||
|
0 /* End of text */;
|
||||||
|
const Entry<EntryData> *entry = machine.get_entry (state, klass);
|
||||||
|
if (unlikely (!entry))
|
||||||
|
break;
|
||||||
|
|
||||||
|
unsigned int flags = entry->flags;
|
||||||
|
|
||||||
|
if (flags & SetMark)
|
||||||
|
{
|
||||||
|
mark = i;
|
||||||
|
last_zero_before_mark = last_zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->data.markIndex != 0xFFFF)
|
||||||
|
{
|
||||||
|
const Lookup<GlyphID> &lookup = subs[entry->data.markIndex]; // XXX bounds
|
||||||
|
const GlyphID *replacement = lookup.get_value (info[mark].codepoint, num_glyphs);
|
||||||
|
if (replacement)
|
||||||
|
{
|
||||||
|
c->buffer->unsafe_to_break (last_zero_before_mark, MIN (i + 1, count));
|
||||||
|
info[mark].codepoint = *replacement;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entry->data.currentIndex != 0xFFFF)
|
||||||
|
{
|
||||||
|
const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex]; // XXX bounds
|
||||||
|
const GlyphID *replacement = lookup.get_value (info[i].codepoint, num_glyphs);
|
||||||
|
if (replacement)
|
||||||
|
{
|
||||||
|
c->buffer->unsafe_to_break (last_zero, MIN (i + 1, count));
|
||||||
|
info[i].codepoint = *replacement;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false/* XXX */ && flags & DontAdvance)
|
||||||
|
i--; /* XXX Detect infinite loop. */
|
||||||
|
|
||||||
|
state = entry->newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return_trace (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
@ -233,7 +295,7 @@ struct LigatureSubtable
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
return_trace (false);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -288,7 +350,7 @@ struct InsertionSubtable
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
/* TODO */
|
/* TODO */
|
||||||
return_trace (false);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue