[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