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

Reply via email to