[kerx] More towards sharing Format1

This commit is contained in:
Behdad Esfahbod 2018-11-07 11:20:14 -05:00
parent b693fd0dc6
commit d5c88af4a2
2 changed files with 37 additions and 8 deletions

View File

@ -180,6 +180,12 @@ struct Format1Entry<true>
public: public:
DEFINE_SIZE_STATIC (2); DEFINE_SIZE_STATIC (2);
}; };
static inline bool performAction (const Entry<EntryData> *entry)
{ return entry->data.kernActionIndex != 0xFFFF; }
static inline unsigned int kernActionIndex (const Entry<EntryData> *entry)
{ return entry->data.kernActionIndex; }
}; };
template <> template <>
struct Format1Entry<false> struct Format1Entry<false>
@ -196,6 +202,12 @@ struct Format1Entry<false>
}; };
typedef void EntryData; typedef void EntryData;
static inline bool performAction (const Entry<EntryData> *entry)
{ return entry->flags & Offset; }
static inline unsigned int kernActionIndex (const Entry<EntryData> *entry)
{ return entry->flags & Offset; }
}; };
template <typename KernSubTableHeader> template <typename KernSubTableHeader>
@ -215,9 +227,10 @@ struct KerxSubTableFormat1
DontAdvance = Format1EntryT::DontAdvance, DontAdvance = Format1EntryT::DontAdvance,
}; };
inline driver_context_t (const KerxSubTableFormat1 *table, inline driver_context_t (const KerxSubTableFormat1 *table_,
hb_aat_apply_context_t *c_) : hb_aat_apply_context_t *c_) :
c (c_), c (c_),
table (table_),
/* Apparently the offset kernAction is from the beginning of the state-machine, /* Apparently the offset kernAction is from the beginning of the state-machine,
* similar to offsets in morx table, NOT from beginning of this table, like * similar to offsets in morx table, NOT from beginning of this table, like
* other subtables in kerx. Discovered via testing. */ * other subtables in kerx. Discovered via testing. */
@ -226,10 +239,21 @@ struct KerxSubTableFormat1
crossStream (table->header.coverage & table->header.CrossStream), crossStream (table->header.coverage & table->header.CrossStream),
crossOffset (0) {} crossOffset (0) {}
/* TODO
* 'kern' table has this pecularity, we don't currently implement.
*
* "Because the stateTableOffset in the state table header is (strictly
* speaking) redundant, some 'kern' tables use it to record an initial
* state where that should not be StartOfText. To determine if this is
* done, calculate what the stateTableOffset should be. If it's different
* from the actual stateTableOffset, use it as the initial state."
*/
inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED, inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry) const Entry<EntryData> *entry)
{ {
return entry->data.kernActionIndex != 0xFFFF; return Format1EntryT::performAction (entry);
} }
inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver, inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
const Entry<EntryData> *entry) const Entry<EntryData> *entry)
@ -248,9 +272,11 @@ struct KerxSubTableFormat1
depth = 0; /* Probably not what CoreText does, but better? */ depth = 0; /* Probably not what CoreText does, but better? */
} }
if (entry->data.kernActionIndex != 0xFFFF) if (Format1EntryT::performAction (entry))
{ {
const FWORD *actions = &kernAction[entry->data.kernActionIndex]; unsigned int kern_idx = Format1EntryT::kernActionIndex (entry);
kern_idx = Types::offsetToIndex (kern_idx, &table->machine, kernAction.arrayZ);
const FWORD *actions = &kernAction[kern_idx];
if (!c->sanitizer.check_array (actions, depth)) if (!c->sanitizer.check_array (actions, depth))
{ {
depth = 0; depth = 0;
@ -334,6 +360,7 @@ struct KerxSubTableFormat1
private: private:
hb_aat_apply_context_t *c; hb_aat_apply_context_t *c;
const KerxSubTableFormat1 *table;
const UnsizedArrayOf<FWORD> &kernAction; const UnsizedArrayOf<FWORD> &kernAction;
unsigned int stack[8]; unsigned int stack[8];
unsigned int depth; unsigned int depth;

View File

@ -410,7 +410,7 @@ struct LigatureEntry<false>
{ return entry->flags & Offset; } { return entry->flags & Offset; }
static inline unsigned int ligActionIndex (const Entry<EntryData> *entry) static inline unsigned int ligActionIndex (const Entry<EntryData> *entry)
{ return entry->flags & 0x3FFF; } { return entry->flags & Offset; }
}; };
@ -479,9 +479,6 @@ struct LigatureSubtable
{ {
DEBUG_MSG (APPLY, nullptr, "Perform action with %d", match_length); DEBUG_MSG (APPLY, nullptr, "Perform action with %d", match_length);
unsigned int end = buffer->out_len; unsigned int end = buffer->out_len;
unsigned int action_idx = LigatureEntryT::ligActionIndex (entry);
unsigned int action;
unsigned int ligature_idx = 0;
if (unlikely (!match_length)) if (unlikely (!match_length))
return true; return true;
@ -490,8 +487,13 @@ struct LigatureSubtable
return false; // TODO Work on previous instead? return false; // TODO Work on previous instead?
unsigned int cursor = match_length; unsigned int cursor = match_length;
unsigned int action_idx = LigatureEntryT::ligActionIndex (entry);
action_idx = Types::offsetToIndex (action_idx, table, ligAction.arrayZ); action_idx = Types::offsetToIndex (action_idx, table, ligAction.arrayZ);
const HBUINT32 *actionData = &ligAction[action_idx]; const HBUINT32 *actionData = &ligAction[action_idx];
unsigned int ligature_idx = 0;
unsigned int action;
do do
{ {
if (unlikely (!cursor)) if (unlikely (!cursor))