From 84967537966a76297c89460d95e7336f1bfc332d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 10 Oct 2018 21:18:37 -0400 Subject: [PATCH] [kerx] Implement Format1 Untested. --- src/hb-aat-layout-kerx-table.hh | 62 +++++++++++++++++++++++++++------ src/hb-aat-layout-morx-table.hh | 2 +- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index edc17a398..552bb0657 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -101,9 +101,9 @@ struct KerxSubTableFormat1 { struct EntryData { - HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry - * for processing this group, if indicated - * by the flags. */ + HBUINT16 kernActionIndex;/* Index into the kerning value array. If + * this index is 0xFFFF, then no kerning + * is to be performed. */ public: DEFINE_SIZE_STATIC (2); }; @@ -120,25 +120,65 @@ struct KerxSubTableFormat1 Reserved = 0x1FFF, /* Not used; set to 0. */ }; - inline driver_context_t (const KerxSubTableFormat1 *table) - {} + inline driver_context_t (const KerxSubTableFormat1 *table, + hb_aat_apply_context_t *c_) : + c (c_), + kernAction (table+table->kernAction), + depth (0) {} inline bool is_actionable (StateTableDriver *driver, const Entry *entry) { - return false; // XXX return (entry->flags & Verb) && start < end; + return entry->data.kernActionIndex != 0xFFFF; } inline bool transition (StateTableDriver *driver, const Entry *entry) { - //hb_buffer_t *buffer = driver->buffer; - //unsigned int flags = entry->flags; + hb_buffer_t *buffer = driver->buffer; + unsigned int flags = entry->flags; + + if (flags & Reset) + { + depth = 0; + } + + if (flags & Push) + { + if (likely (depth < ARRAY_LENGTH (stack))) + stack[depth++] = buffer->idx; + else + depth = 0; /* Probably not what CoreText does, but better? */ + } + + if (entry->data.kernActionIndex != 0xFFFF) + { + const FWORD *actions = &kernAction[entry->data.kernActionIndex]; + if (!c->sanitizer.check_array (actions, depth)) + { + depth = 0; + return false; + } + + for (; depth; depth--) + { + unsigned int idx = stack[depth - 1]; + int v = *actions++; + /* XXX Non-forward direction... */ + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + buffer->pos[idx].x_advance += v; + else + buffer->pos[idx].y_advance += v; + } + } return true; } - public: private: + hb_aat_apply_context_t *c; + const UnsizedArrayOf &kernAction; + unsigned int stack[8]; + unsigned int depth; }; inline bool apply (hb_aat_apply_context_t *c) const @@ -148,7 +188,7 @@ struct KerxSubTableFormat1 if (!c->plan->requested_kerning) return false; - driver_context_t dc (this); + driver_context_t dc (this, c); StateTableDriver driver (machine, c->buffer, c->font->face); driver.drive (&dc); @@ -165,7 +205,7 @@ struct KerxSubTableFormat1 protected: KerxSubTableHeader header; StateTable machine; - LOffsetTo, false> values; + LOffsetTo, false> kernAction; public: DEFINE_SIZE_STATIC (32); }; diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 5de851266..b902fd79b 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -365,7 +365,7 @@ struct LigatureSubtable inline bool is_actionable (StateTableDriver *driver, const Entry *entry) { - return !!(entry->flags & PerformAction); + return entry->flags & PerformAction; } inline bool transition (StateTableDriver *driver, const Entry *entry)