[HarfBuzz] harfbuzz: Branch 'master' - 2 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Jan 11 23:09:33 UTC 2018
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 <behdad at 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 <behdad at 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
More information about the HarfBuzz
mailing list