src/hb-aat-layout-common-private.hh | 51 +++++++++ src/hb-aat-layout-morx-table.hh | 188 +++++++++++++++++------------------- 2 files changed, 141 insertions(+), 98 deletions(-)
New commits: commit c70d58f97da7dcbdd7ea72a44f39130a75a279f7 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 12 00:08:22 2018 +0100 [aat] Port RearrangementSubtable to StateTableDriver diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index bfe239e4..cedab1b1 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -40,57 +40,40 @@ using namespace OT; struct RearrangementSubtable { - enum Flags { - MarkFirst = 0x8000, /* If set, make the current glyph the first - * glyph to be rearranged. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph - * before going to the new state. This means - * that the glyph index doesn't change, even - * if the glyph at that index has changed. */ - MarkLast = 0x2000, /* If set, make the current glyph the last - * glyph to be rearranged. */ - Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ - Verb = 0x000F, /* The type of rearrangement specified. */ - }; - - inline bool apply (hb_apply_context_t *c) const + struct driver_context_t { - TRACE_APPLY (this); - - bool ret = false; - unsigned int num_glyphs = c->face->get_num_glyphs (); - - unsigned int state = 0; - unsigned int last_zero = 0; - unsigned int last_zero_before_start = 0; - unsigned int start = 0; - unsigned int end = 0; + enum Flags { + MarkFirst = 0x8000, /* If set, make the current glyph the first + * glyph to be rearranged. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph + * before going to the new state. This means + * that the glyph index doesn't change, even + * if the glyph at that index has changed. */ + MarkLast = 0x2000, /* If set, make the current glyph the last + * glyph to be rearranged. */ + Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ + Verb = 0x000F, /* The type of rearrangement specified. */ + }; - hb_glyph_info_t *info = c->buffer->info; - unsigned int count = c->buffer->len; + inline driver_context_t (const RearrangementSubtable *table) : + ret (false), + start (0), end (0), + last_zero_before_start (0) {} - for (unsigned int i = 0; i <= count; i++) + inline void transition (StateTableDriver<void> *driver, + const Entry<void> *entry) { - if (!state) - last_zero = i; - - unsigned int klass = i < count ? - machine.get_class (info[i].codepoint, num_glyphs) : - 0 /* End of text */; - const Entry<void> *entry = machine.get_entryZ (state, klass); - if (unlikely (!entry)) - break; - + hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry->flags; if (flags & MarkFirst) { - start = i; - last_zero_before_start = last_zero; + start = buffer->idx; + last_zero_before_start = driver->last_zero; } if (flags & MarkLast) - end = MIN (i + 1, count); + end = MIN (buffer->idx + 1, buffer->len); if ((flags & Verb) && start < end) { @@ -126,10 +109,12 @@ struct RearrangementSubtable if (end - start >= l + r) { - c->buffer->unsafe_to_break (last_zero_before_start, MIN (i + 1, count)); - c->buffer->merge_clusters (start, end); + buffer->unsafe_to_break (last_zero_before_start, MIN (buffer->idx + 1, buffer->len)); + buffer->merge_clusters (start, end); + hb_glyph_info_t *info = buffer->info; hb_glyph_info_t buf[4]; + memcpy (buf, info + start, l * sizeof (buf[0])); memcpy (buf + 2, info + end - r, r * sizeof (buf[0])); @@ -152,14 +137,26 @@ struct RearrangementSubtable } } } + } - if (flags & DontAdvance) - i--; /* TODO Detect infinite loop. */ + public: + bool ret; + private: + unsigned int start = 0; + unsigned int end = 0; + unsigned int last_zero_before_start = 0; + }; - state = entry->newState; - } + inline bool apply (hb_apply_context_t *c) const + { + TRACE_APPLY (this); - return_trace (ret); + driver_context_t dc (this); + + StateTableDriver<void> driver (machine, c->buffer, c->face); + driver.drive (&dc); + + return_trace (dc.ret); } inline bool sanitize (hb_sanitize_context_t *c) const commit 117cfe7bb7cef682eb151b94f1eb12363ba3af67 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Jan 12 00:01:36 2018 +0100 [aat] Add StateTableDriver and convert ContextualSubtable to it diff --git a/src/hb-aat-layout-common-private.hh b/src/hb-aat-layout-common-private.hh index 2462701c..04007db3 100644 --- a/src/hb-aat-layout-common-private.hh +++ b/src/hb-aat-layout-common-private.hh @@ -605,6 +605,57 @@ struct StateTable DEFINE_SIZE_UNION (2, format); }; +template <typename EntryData> +struct StateTableDriver +{ + inline StateTableDriver (const StateTable<EntryData> &machine_, + hb_buffer_t *buffer_, + hb_face_t *face_) : + machine (machine_), + buffer (buffer_), + num_glyphs (face_->get_num_glyphs ()), + state (0), + last_zero (0) {} + + template <typename context_t> + inline void drive (context_t *c) + { + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + for (buffer->idx = 0; buffer->idx <= count; buffer->idx++) + { + if (!state) + last_zero = buffer->idx; + + unsigned int klass = buffer->idx < count ? + machine.get_class (info[buffer->idx].codepoint, num_glyphs) : + 0 /* End of text */; + const Entry<EntryData> *entry = machine.get_entryZ (state, klass); + if (unlikely (!entry)) + break; + + c->transition (this, entry); + + if (entry->flags & context_t::Flags::DontAdvance) + buffer->idx--; /* TODO Detect infinite loop. */ + + state = entry->newState; + } + + /* XXX finish if not in-place */ + } + + public: + const StateTable<EntryData> &machine; + hb_buffer_t *buffer; + + unsigned int num_glyphs; + + unsigned int state; + unsigned int last_zero; +}; + } /* namespace AAT */ diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 95f4245d..bfe239e4 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -176,14 +176,6 @@ struct RearrangementSubtable struct ContextualSubtable { - enum Flags { - SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph before - * going to the new state. */ - Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ - }; - - /* XXX the following is different in mort: it's directly index to sublookups. */ struct EntryData { HBUINT16 markIndex; /* Index of the substitution table for the @@ -194,50 +186,40 @@ struct ContextualSubtable DEFINE_SIZE_STATIC (4); }; - inline bool apply (hb_apply_context_t *c) const + struct driver_context_t { - TRACE_APPLY (this); - - bool ret = false; - unsigned int num_glyphs = c->face->get_num_glyphs (); - - const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> &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++) + enum Flags { + SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. */ + Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ + }; + + inline driver_context_t (const ContextualSubtable *table) : + ret (false), + mark (0), + last_zero_before_mark (0), + subs (table+table->substitutionTables) {} + + inline void transition (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) { - 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_entryZ (state, klass); - if (unlikely (!entry)) - break; + hb_buffer_t *buffer = driver->buffer; - unsigned int flags = entry->flags; - - if (flags & SetMark) + if (entry->flags & SetMark) { - mark = i; - last_zero_before_mark = last_zero; + mark = buffer->idx; + last_zero_before_mark = driver->last_zero; } if (entry->data.markIndex != 0xFFFF) { const Lookup<GlyphID> &lookup = subs[entry->data.markIndex]; - const GlyphID *replacement = lookup.get_value (info[mark].codepoint, num_glyphs); + hb_glyph_info_t *info = buffer->info; + const GlyphID *replacement = lookup.get_value (info[mark].codepoint, driver->num_glyphs); if (replacement) { - c->buffer->unsafe_to_break (last_zero_before_mark, MIN (i + 1, count)); + buffer->unsafe_to_break (last_zero_before_mark, MIN (buffer->idx + 1, buffer->len)); info[mark].codepoint = *replacement; ret = true; } @@ -245,22 +227,35 @@ struct ContextualSubtable if (entry->data.currentIndex != 0xFFFF) { const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex]; - const GlyphID *replacement = lookup.get_value (info[i].codepoint, num_glyphs); + hb_glyph_info_t *info = buffer->info; + const GlyphID *replacement = lookup.get_value (info[buffer->idx].codepoint, driver->num_glyphs); if (replacement) { - c->buffer->unsafe_to_break (last_zero, MIN (i + 1, count)); - info[i].codepoint = *replacement; + buffer->unsafe_to_break (driver->last_zero, MIN (buffer->idx + 1, buffer->len)); + info[buffer->idx].codepoint = *replacement; ret = true; } } + } - if (flags & DontAdvance) - i--; /* TODO Detect infinite loop. */ + public: + bool ret; + private: + unsigned int mark; + unsigned int last_zero_before_mark; + const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> &subs; + }; - state = entry->newState; - } + inline bool apply (hb_apply_context_t *c) const + { + TRACE_APPLY (this); - return_trace (ret); + driver_context_t dc (this); + + StateTableDriver<EntryData> driver (machine, c->buffer, c->face); + driver.drive (&dc); + + return_trace (dc.ret); } inline bool sanitize (hb_sanitize_context_t *c) const _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz