[mort] Implement / adjust Contextual substitution
This commit is contained in:
parent
11dbf0f129
commit
28b68cffe4
|
@ -213,10 +213,13 @@ struct ContextualSubtable
|
||||||
Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */
|
Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */
|
||||||
};
|
};
|
||||||
|
|
||||||
inline driver_context_t (const ContextualSubtable *table) :
|
inline driver_context_t (const ContextualSubtable *table_,
|
||||||
|
hb_aat_apply_context_t *c_) :
|
||||||
ret (false),
|
ret (false),
|
||||||
|
c (c_),
|
||||||
mark_set (false),
|
mark_set (false),
|
||||||
mark (0),
|
mark (0),
|
||||||
|
table (table_),
|
||||||
subs (table+table->substitutionTables) {}
|
subs (table+table->substitutionTables) {}
|
||||||
|
|
||||||
inline bool is_actionable (StateTableDriver<Types, EntryData> *driver,
|
inline bool is_actionable (StateTableDriver<Types, EntryData> *driver,
|
||||||
|
@ -239,30 +242,57 @@ struct ContextualSubtable
|
||||||
if (buffer->idx == buffer->len && !mark_set)
|
if (buffer->idx == buffer->len && !mark_set)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (entry->data.markIndex != 0xFFFF)
|
const GlyphID *replacement;
|
||||||
|
|
||||||
|
replacement = nullptr;
|
||||||
|
if (Types::extended)
|
||||||
{
|
{
|
||||||
const Lookup<GlyphID> &lookup = subs[entry->data.markIndex];
|
if (entry->data.markIndex != 0xFFFF)
|
||||||
hb_glyph_info_t *info = buffer->info;
|
|
||||||
const GlyphID *replacement = lookup.get_value (info[mark].codepoint, driver->num_glyphs);
|
|
||||||
if (replacement)
|
|
||||||
{
|
{
|
||||||
buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len));
|
const Lookup<GlyphID> &lookup = subs[entry->data.markIndex];
|
||||||
info[mark].codepoint = *replacement;
|
replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs);
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entry->data.currentIndex != 0xFFFF)
|
else
|
||||||
{
|
{
|
||||||
unsigned int idx = MIN (buffer->idx, buffer->len - 1);
|
unsigned int offset = 2 * (entry->data.markIndex + buffer->info[mark].codepoint);
|
||||||
const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex];
|
replacement = &StructAtOffset<GlyphID> (table, offset);
|
||||||
hb_glyph_info_t *info = buffer->info;
|
if ((const void *) replacement < (const void *) subs ||
|
||||||
const GlyphID *replacement = lookup.get_value (info[idx].codepoint, driver->num_glyphs);
|
!replacement->sanitize (&c->sanitizer) ||
|
||||||
if (replacement)
|
!*replacement)
|
||||||
|
replacement = nullptr;
|
||||||
|
}
|
||||||
|
if (replacement)
|
||||||
|
{
|
||||||
|
buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len));
|
||||||
|
buffer->info[mark].codepoint = *replacement;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
replacement = nullptr;
|
||||||
|
unsigned int idx = MIN (buffer->idx, buffer->len - 1);
|
||||||
|
if (Types::extended)
|
||||||
|
{
|
||||||
|
if (entry->data.currentIndex != 0xFFFF)
|
||||||
{
|
{
|
||||||
info[idx].codepoint = *replacement;
|
const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex];
|
||||||
ret = true;
|
replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int offset = 2 * (entry->data.currentIndex + buffer->info[idx].codepoint);
|
||||||
|
replacement = &StructAtOffset<GlyphID> (table, offset);
|
||||||
|
if ((const void *) replacement < (const void *) subs ||
|
||||||
|
!replacement->sanitize (&c->sanitizer) ||
|
||||||
|
!*replacement)
|
||||||
|
replacement = nullptr;
|
||||||
|
}
|
||||||
|
if (replacement)
|
||||||
|
{
|
||||||
|
buffer->info[idx].codepoint = *replacement;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (entry->flags & SetMark)
|
if (entry->flags & SetMark)
|
||||||
{
|
{
|
||||||
|
@ -276,8 +306,10 @@ struct ContextualSubtable
|
||||||
public:
|
public:
|
||||||
bool ret;
|
bool ret;
|
||||||
private:
|
private:
|
||||||
|
hb_aat_apply_context_t *c;
|
||||||
bool mark_set;
|
bool mark_set;
|
||||||
unsigned int mark;
|
unsigned int mark;
|
||||||
|
const ContextualSubtable *table;
|
||||||
const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false> &subs;
|
const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false> &subs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -285,7 +317,7 @@ struct ContextualSubtable
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
|
|
||||||
driver_context_t dc (this);
|
driver_context_t dc (this, c);
|
||||||
|
|
||||||
StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
|
StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
|
||||||
driver.drive (&dc);
|
driver.drive (&dc);
|
||||||
|
@ -300,6 +332,8 @@ struct ContextualSubtable
|
||||||
unsigned int num_entries = 0;
|
unsigned int num_entries = 0;
|
||||||
if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false);
|
if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false);
|
||||||
|
|
||||||
|
if (!Types::extended) return_trace (true);
|
||||||
|
|
||||||
unsigned int num_lookups = 0;
|
unsigned int num_lookups = 0;
|
||||||
|
|
||||||
const Entry<EntryData> *entries = machine.get_entries ();
|
const Entry<EntryData> *entries = machine.get_entries ();
|
||||||
|
|
|
@ -340,6 +340,9 @@ struct UnsizedArrayOf
|
||||||
inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
|
inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
|
||||||
inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
|
inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
|
||||||
|
|
||||||
|
template <typename T> inline operator T * (void) { return arrayZ; }
|
||||||
|
template <typename T> inline operator const T * (void) const { return arrayZ; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
|
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -450,6 +453,10 @@ struct ArrayOf
|
||||||
if (unlikely (i >= len)) return Crap(Type);
|
if (unlikely (i >= len)) return Crap(Type);
|
||||||
return arrayZ[i];
|
return arrayZ[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> inline operator T * (void) { return arrayZ; }
|
||||||
|
template <typename T> inline operator const T * (void) const { return arrayZ; }
|
||||||
|
|
||||||
inline unsigned int get_size (void) const
|
inline unsigned int get_size (void) const
|
||||||
{ return len.static_size + len * Type::static_size; }
|
{ return len.static_size + len * Type::static_size; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue