From d5c88af4a23bffc09840c43e6b1403b64a9f74d5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 7 Nov 2018 11:20:14 -0500 Subject: [PATCH] [kerx] More towards sharing Format1 --- src/hb-aat-layout-kerx-table.hh | 35 +++++++++++++++++++++++++++++---- src/hb-aat-layout-morx-table.hh | 10 ++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index e72378233..2a12a0b56 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -180,6 +180,12 @@ struct Format1Entry public: DEFINE_SIZE_STATIC (2); }; + + static inline bool performAction (const Entry *entry) + { return entry->data.kernActionIndex != 0xFFFF; } + + static inline unsigned int kernActionIndex (const Entry *entry) + { return entry->data.kernActionIndex; } }; template <> struct Format1Entry @@ -196,6 +202,12 @@ struct Format1Entry }; typedef void EntryData; + + static inline bool performAction (const Entry *entry) + { return entry->flags & Offset; } + + static inline unsigned int kernActionIndex (const Entry *entry) + { return entry->flags & Offset; } }; template @@ -215,9 +227,10 @@ struct KerxSubTableFormat1 DontAdvance = Format1EntryT::DontAdvance, }; - inline driver_context_t (const KerxSubTableFormat1 *table, + inline driver_context_t (const KerxSubTableFormat1 *table_, hb_aat_apply_context_t *c_) : c (c_), + table (table_), /* 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 * other subtables in kerx. Discovered via testing. */ @@ -226,10 +239,21 @@ struct KerxSubTableFormat1 crossStream (table->header.coverage & table->header.CrossStream), 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 *driver HB_UNUSED, const Entry *entry) { - return entry->data.kernActionIndex != 0xFFFF; + return Format1EntryT::performAction (entry); } inline bool transition (StateTableDriver *driver, const Entry *entry) @@ -248,9 +272,11 @@ struct KerxSubTableFormat1 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)) { depth = 0; @@ -334,6 +360,7 @@ struct KerxSubTableFormat1 private: hb_aat_apply_context_t *c; + const KerxSubTableFormat1 *table; const UnsizedArrayOf &kernAction; unsigned int stack[8]; unsigned int depth; diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 784b36cf4..51f14682c 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -410,7 +410,7 @@ struct LigatureEntry { return entry->flags & Offset; } static inline unsigned int ligActionIndex (const Entry *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); 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)) return true; @@ -490,8 +487,13 @@ struct LigatureSubtable return false; // TODO Work on previous instead? unsigned int cursor = match_length; + + unsigned int action_idx = LigatureEntryT::ligActionIndex (entry); action_idx = Types::offsetToIndex (action_idx, table, ligAction.arrayZ); const HBUINT32 *actionData = &ligAction[action_idx]; + + unsigned int ligature_idx = 0; + unsigned int action; do { if (unlikely (!cursor))