[HarfBuzz] harfbuzz: Branch 'master' - 8 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Nov 2 18:48:39 UTC 2018


 src/hb-aat-layout-kerx-table.hh |   11 +
 src/hb-open-type.hh             |    3 
 src/hb-ot-face.hh               |    2 
 src/hb-ot-kern-table.hh         |  332 ++++++++++++++++++++++++++++++++--------
 src/hb-ot-layout.cc             |   28 ++-
 src/hb-ot-layout.hh             |    8 
 src/hb-ot-shape.cc              |    2 
 7 files changed, 305 insertions(+), 81 deletions(-)

New commits:
commit 8034d1dda091998d356e77f249d3c9f50501cc77
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Nov 2 14:47:42 2018 -0400

    [kern] Implement Format1
    
    Also, implement backwards kerning for Format1 in kern and kerx.
    
    Fixes https://github.com/harfbuzz/harfbuzz/issues/1350

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 94e0a9b6..b227af10 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -207,11 +207,18 @@ struct KerxSubTableFormat1
 	  int v = *actions++;
 	  if (idx < buffer->len && buffer->info[idx].mask & kern_mask)
 	  {
-	    /* XXX Non-forward direction... */
 	    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+	    {
 	      buffer->pos[idx].x_advance += c->font->em_scale_x (v);
+	      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+		buffer->pos[idx].x_offset += c->font->em_scale_x (v);
+	    }
 	    else
+	    {
 	      buffer->pos[idx].y_advance += c->font->em_scale_y (v);
+	      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+		buffer->pos[idx].y_offset += c->font->em_scale_y (v);
+	    }
 	  }
 	}
 	depth = 0;
@@ -255,7 +262,7 @@ struct KerxSubTableFormat1
 
   protected:
   KerxSubTableHeader				header;
-  StateTable<MorxTypes, EntryData>				machine;
+  StateTable<MorxTypes, EntryData>		machine;
   LOffsetTo<UnsizedArrayOf<FWORD>, false>	kernAction;
   public:
   DEFINE_SIZE_STATIC (32);
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index ec33d603..9f8a0115 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -192,6 +192,130 @@ struct KernSubTableFormat0
   DEFINE_SIZE_ARRAY (8, pairs);
 };
 
+struct KernSubTableFormat1
+{
+  typedef void EntryData;
+
+  struct driver_context_t
+  {
+    static const bool in_place = true;
+    enum Flags
+    {
+      Push		= 0x8000,	/* If set, push this glyph on the kerning stack. */
+      DontAdvance	= 0x4000,	/* If set, don't advance to the next glyph
+					 * before going to the new state. */
+      Offset		= 0x3FFF,	/* Byte offset from beginning of subtable to the
+					 * value table for the glyphs on the kerning stack. */
+    };
+
+    inline driver_context_t (const KernSubTableFormat1 *table_,
+			     AAT::hb_aat_apply_context_t *c_) :
+	c (c_),
+	table (table_),
+	/* Apparently the offset kernAction is from the beginning of the state-machine,
+	 * similar to offsets in morx table, NOT from beginning of this table, like
+	 * other subtables in kerx.  Discovered via testing. */
+	kernAction (&table->machine + table->kernAction),
+	depth (0) {}
+
+    inline bool is_actionable (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver HB_UNUSED,
+			       const AAT::Entry<EntryData> *entry)
+    {
+      return entry->flags & Offset;
+    }
+    inline bool transition (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver,
+			    const AAT::Entry<EntryData> *entry)
+    {
+      hb_buffer_t *buffer = driver->buffer;
+      unsigned int flags = entry->flags;
+
+      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->flags & Offset)
+      {
+	unsigned int kernIndex = AAT::MortTypes::offsetToIndex (entry->flags & Offset, &table->machine, kernAction.arrayZ);
+	const FWORD *actions = &kernAction[kernIndex];
+	if (!c->sanitizer.check_array (actions, depth))
+	{
+	  depth = 0;
+	  return false;
+	}
+
+	hb_mask_t kern_mask = c->plan->kern_mask;
+	for (unsigned int i = 0; i < depth; i++)
+	{
+	  /* Apparently, when spec says "Each pops one glyph from the kerning stack
+	   * and applies the kerning value to it.", it doesn't mean it in that order.
+	   * The deepest item in the stack corresponds to the first item in the action
+	   * list.  Discovered by testing. */
+	  unsigned int idx = stack[i];
+	  int v = *actions++;
+	  if (idx < buffer->len && buffer->info[idx].mask & kern_mask)
+	  {
+	    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+	    {
+	      buffer->pos[idx].x_advance += c->font->em_scale_x (v);
+	      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+		buffer->pos[idx].x_offset += c->font->em_scale_x (v);
+	    }
+	    else
+	    {
+	      buffer->pos[idx].y_advance += c->font->em_scale_y (v);
+	      if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+		buffer->pos[idx].y_offset += c->font->em_scale_y (v);
+	    }
+	  }
+	}
+	depth = 0;
+      }
+
+      return true;
+    }
+
+    private:
+    AAT::hb_aat_apply_context_t *c;
+    const KernSubTableFormat1 *table;
+    const UnsizedArrayOf<FWORD> &kernAction;
+    unsigned int stack[8];
+    unsigned int depth;
+  };
+
+  inline bool apply (AAT::hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    if (!c->plan->requested_kerning)
+      return false;
+
+    driver_context_t dc (this, c);
+
+    AAT::StateTableDriver<AAT::MortTypes, EntryData> driver (machine, c->buffer, c->font->face);
+    driver.drive (&dc);
+
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    /* The rest of array sanitizations are done at run-time. */
+    return_trace (likely (c->check_struct (this) &&
+			  machine.sanitize (c)));
+  }
+
+  protected:
+  AAT::StateTable<AAT::MortTypes, EntryData>		machine;
+  OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false>	kernAction;
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
 struct KernClassTable
 {
   inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
@@ -361,6 +485,7 @@ struct KernSubTable
     /* TODO Switch to dispatch(). */
     switch (format) {
     case 0: u.format0.apply (c); return;
+    case 1: u.format1.apply (c); return;
     case 2: u.format2.apply (c); return;
     case 3: u.format3.apply (c); return;
     default:			 return;
@@ -372,6 +497,7 @@ struct KernSubTable
     TRACE_SANITIZE (this);
     switch (format) {
     case 0: return_trace (u.format0.sanitize (c));
+    case 1: return_trace (u.format1.sanitize (c));
     case 2: return_trace (u.format2.sanitize (c));
     case 3: return_trace (u.format3.sanitize (c));
     default:return_trace (true);
@@ -381,6 +507,7 @@ struct KernSubTable
   protected:
   union {
   KernSubTableFormat0	format0;
+  KernSubTableFormat1	format1;
   KernSubTableFormat2	format2;
   KernSubTableFormat3	format3;
   } u;
commit 46b3885c1a8ea3b85efbdd1704edcee385797c5d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Nov 2 14:43:38 2018 -0400

    [kern] Set subtable on sanitizer

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 3845da8e..ec33d603 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -474,6 +474,8 @@ struct KernTable
       if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index))
 	goto skip;
 
+      c->sanitizer.set_object (*st);
+
       st->apply (c);
 
       (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index);
commit 74c7a2c6c892446dcec574986e128967bd570e47
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Nov 2 14:26:04 2018 -0400

    [kern] Respect more flags

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 303e1bb3..3845da8e 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -395,8 +395,11 @@ struct KernSubTableWrapper
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
   inline const T* thiz (void) const { return static_cast<const T *> (this); }
 
+  inline bool is_supported (void) const
+  { return !(thiz()->coverage & T::CheckFlags); }
+
   inline bool is_horizontal (void) const
-  { return (thiz()->coverage & T::CheckFlags) == T::CheckHorizontal; }
+  { return (thiz()->coverage & T::Direction) == T::CheckHorizontal; }
 
   inline bool is_override (void) const
   { return bool (thiz()->coverage & T::Override); }
@@ -405,7 +408,7 @@ struct KernSubTableWrapper
   { return thiz()->subtable.get_kerning (left, right, thiz()->format); }
 
   inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-  { return is_horizontal () ? get_kerning (left, right) : 0; }
+  { return is_supported () && is_horizontal () ? get_kerning (left, right) : 0; }
 
   inline void apply (AAT::hb_aat_apply_context_t *c) const
   { thiz()->subtable.apply (c, thiz()->format); }
@@ -435,7 +438,7 @@ struct KernTable
     unsigned int count = thiz()->nTables;
     for (unsigned int i = 0; i < count; i++)
     {
-      if (st->is_override ())
+      if (st->is_supported () && st->is_override ())
         v = 0;
       v += st->get_h_kerning (left, right);
       st = &StructAfter<typename T::SubTableWrapper> (*st);
@@ -452,13 +455,19 @@ struct KernTable
     unsigned int last_override = 0;
     for (unsigned int i = 0; i < count; i++)
     {
-      if (st->is_override ())
+      if (st->is_supported () && st->is_override ())
         last_override = i;
       st = &StructAfter<typename T::SubTableWrapper> (*st);
     }
     st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
     for (unsigned int i = 0; i < count; i++)
     {
+      if (!st->is_supported ())
+        goto skip;
+
+      if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->is_horizontal ())
+	goto skip;
+
       if (i < last_override)
 	goto skip;
 
@@ -514,7 +523,7 @@ struct KernOT : KernTable<KernOT>
 
       Variation		= 0x00u, /* Not supported. */
 
-      CheckFlags	= 0x07u,
+      CheckFlags	= 0x06u,
       CheckHorizontal	= 0x01u
     };
 
@@ -555,7 +564,7 @@ struct KernAAT : KernTable<KernAAT>
 
       Override		= 0x00u, /* Not supported. */
 
-      CheckFlags	= 0xE0u,
+      CheckFlags	= 0x60u,
       CheckHorizontal	= 0x00u
     };
 
commit 9f880bad0d7291eaab10d814567c7a680e139c48
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Nov 2 13:57:41 2018 -0400

    [kern] Minor
    
    We like check_struct() more.

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 77dd7b36..303e1bb3 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -199,7 +199,8 @@ struct KernClassTable
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
+    return_trace (c->check_struct (this) &&
+		  classes.sanitize (c));
   }
 
   protected:
@@ -262,7 +263,7 @@ struct KernSubTableFormat2
   {
     TRACE_SANITIZE (this);
     return_trace (true); /* Disabled.  See above. */
-    return_trace (rowWidth.sanitize (c) &&
+    return_trace (c->check_struct (this) &&
 		  leftClassTable.sanitize (c, this) &&
 		  rightClassTable.sanitize (c, this) &&
 		  array.sanitize (c, this));
commit 04b82b181d06c229a98314c1620d3ae8a2825267
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Nov 2 13:47:33 2018 -0400

    Remove pointer cast operators from ArrayOf<>
    
    ArrayOf<>, unlike UnsizedArrayOf<>, has data before the array.
    This was confusing.  Remove.

diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index afd75be4..0f6efdc6 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -452,9 +452,6 @@ struct ArrayOf
     return arrayZ[i];
   }
 
-  template <typename T> inline operator T * (void) { return arrayZ; }
-  template <typename T> inline operator const T * (void) const { return arrayZ; }
-
   inline unsigned int get_size (void) const
   { return len.static_size + len * Type::static_size; }
 
commit f1df441bedaf5b2c7fadf9954ea39616af87702a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Nov 2 13:26:15 2018 -0400

    [kern] Comment

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 311d61d5..77dd7b36 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -217,8 +217,7 @@ struct KernSubTableFormat2
     /* This subtable is disabled.  It's not cleaer to me *exactly* where the offests are
      * based from.  I *think* they should be based from beginning of kern subtable wrapper,
      * *NOT* "this".  Since we know of no fonts that use this subtable, we are disabling
-     * it.  Someday fix it and re-enable.  Better yet, find fonts that use it... Meh,
-     * Windows doesn't implement it.  Maybe just remove... */
+     * it.  Someday fix it and re-enable. */
     return 0;
     unsigned int l = (this+leftClassTable).get_class (left);
     unsigned int r = (this+rightClassTable).get_class (right);
commit 095f5add0b1ca39dd09842594b80fae92f0796e4
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Nov 2 13:23:54 2018 -0400

    [kern] Push apply loop to each subtable

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 8c436f99..311d61d5 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -30,6 +30,8 @@
 #include "hb-open-type.hh"
 #include "hb-ot-shape.hh"
 #include "hb-ot-layout-gsubgpos.hh"
+#include "hb-aat-layout-ankr-table.hh" // Ugly but needed.
+#include "hb-aat-layout-common.hh"
 
 
 template <typename Driver>
@@ -165,6 +167,19 @@ struct KernSubTableFormat0
     return pairs[i].get_kerning ();
   }
 
+  inline bool apply (AAT::hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    if (!c->plan->requested_kerning)
+      return false;
+
+    hb_kern_machine_t<KernSubTableFormat0> machine (*this);
+    machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -196,7 +211,8 @@ struct KernClassTable
 
 struct KernSubTableFormat2
 {
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
+			  AAT::hb_aat_apply_context_t *c) const
   {
     /* This subtable is disabled.  It's not cleaer to me *exactly* where the offests are
      * based from.  I *think* they should be based from beginning of kern subtable wrapper,
@@ -208,12 +224,41 @@ struct KernSubTableFormat2
     unsigned int r = (this+rightClassTable).get_class (right);
     unsigned int offset = l + r;
     const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
+#if 0
     if (unlikely ((const char *) v < (const char *) &array ||
 		  (const char *) v > (const char *) end - 2))
+#endif
       return 0;
     return *v;
   }
 
+  inline bool apply (AAT::hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    if (!c->plan->requested_kerning)
+      return false;
+
+    accelerator_t accel (*this, c);
+    hb_kern_machine_t<accelerator_t> machine (accel);
+    machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+    return_trace (true);
+  }
+
+  struct accelerator_t
+  {
+    const KernSubTableFormat2 &table;
+    AAT::hb_aat_apply_context_t *c;
+
+    inline accelerator_t (const KernSubTableFormat2 &table_,
+			  AAT::hb_aat_apply_context_t *c_) :
+			    table (table_), c (c_) {}
+
+    inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+    { return table.get_kerning (left, right, c); }
+  };
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -241,7 +286,7 @@ struct KernSubTableFormat2
 
 struct KernSubTableFormat3
 {
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
     hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
     hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (kernValue).as_array (glyphCount);
@@ -252,6 +297,19 @@ struct KernSubTableFormat3
     return kernValue[kernIndex[i]];
   }
 
+  inline bool apply (AAT::hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    if (!c->plan->requested_kerning)
+      return false;
+
+    hb_kern_machine_t<KernSubTableFormat3> machine (*this);
+    machine.kern (c->font, c->buffer, c->plan->kern_mask);
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -289,16 +347,26 @@ struct KernSubTableFormat3
 
 struct KernSubTable
 {
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int format) const
   {
     switch (format) {
+    /* This method hooks up to hb_font_t's get_h_kerning.  Only support Format0. */
     case 0: return u.format0.get_kerning (left, right);
-    case 2: return u.format2.get_kerning (left, right, end);
-    case 3: return u.format3.get_kerning (left, right, end);
     default:return 0;
     }
   }
 
+  inline void apply (AAT::hb_aat_apply_context_t *c, unsigned int format) const
+  {
+    /* TODO Switch to dispatch(). */
+    switch (format) {
+    case 0: u.format0.apply (c); return;
+    case 2: u.format2.apply (c); return;
+    case 3: u.format3.apply (c); return;
+    default:			 return;
+    }
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
   {
     TRACE_SANITIZE (this);
@@ -333,11 +401,14 @@ struct KernSubTableWrapper
   inline bool is_override (void) const
   { return bool (thiz()->coverage & T::Override); }
 
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
-  { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+  { return thiz()->subtable.get_kerning (left, right, thiz()->format); }
 
-  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
-  { return is_horizontal () ? get_kerning (left, right, end) : 0; }
+  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+  { return is_horizontal () ? get_kerning (left, right) : 0; }
+
+  inline void apply (AAT::hb_aat_apply_context_t *c) const
+  { thiz()->subtable.apply (c, thiz()->format); }
 
   inline unsigned int get_size (void) const { return thiz()->length; }
 
@@ -366,12 +437,43 @@ struct KernTable
     {
       if (st->is_override ())
         v = 0;
-      v += st->get_h_kerning (left, right, st->length + (const char *) st);
+      v += st->get_h_kerning (left, right);
       st = &StructAfter<typename T::SubTableWrapper> (*st);
     }
     return v;
   }
 
+  inline void apply (AAT::hb_aat_apply_context_t *c) const
+  {
+    c->set_lookup_index (0);
+    const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
+    unsigned int count = thiz()->nTables;
+    /* If there's an override subtable, skip subtables before that. */
+    unsigned int last_override = 0;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (st->is_override ())
+        last_override = i;
+      st = &StructAfter<typename T::SubTableWrapper> (*st);
+    }
+    st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (i < last_override)
+	goto skip;
+
+      if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index))
+	goto skip;
+
+      st->apply (c);
+
+      (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index);
+
+    skip:
+      st = &StructAfter<typename T::SubTableWrapper> (*st);
+    }
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -492,6 +594,16 @@ struct kern
     }
   }
 
+  inline void apply (AAT::hb_aat_apply_context_t *c) const
+  {
+    /* TODO Switch to dispatch(). */
+    switch (u.major) {
+    case 0: u.ot.apply (c);  return;
+    case 1: u.aat.apply (c); return;
+    default:		     return;
+    }
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -503,27 +615,6 @@ struct kern
     }
   }
 
-  inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
-  { return get_h_kerning (first, second); }
-
-  inline void apply (hb_font_t *font,
-		     hb_buffer_t  *buffer,
-		     hb_mask_t kern_mask) const
-  {
-    /* We only apply horizontal kerning in this table. */
-    if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
-      return;
-
-    hb_kern_machine_t<kern> machine (*this);
-
-    if (!buffer->message (font, "start kern table"))
-      return;
-
-    machine.kern (font, buffer, kern_mask);
-
-    (void) buffer->message (font, "end kern table");
-  }
-
   protected:
   union {
   HBUINT32		version32;
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index f4ae840b..b81aabd2 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -55,10 +55,19 @@
  **/
 
 
-static const OT::kern& _get_kern (hb_face_t *face)
+static inline const OT::kern&
+_get_kern (hb_face_t *face, hb_blob_t **blob = nullptr)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern);
-  return *hb_ot_face_data (face)->kern;
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
+  {
+    if (blob)
+      *blob = hb_blob_get_empty ();
+    return Null(OT::kern);
+  }
+  const OT::kern& kern = *(hb_ot_face_data (face)->kern.get ());
+  if (blob)
+    *blob = hb_ot_face_data (face)->kern.get_blob ();
+  return kern;
 }
 const OT::GDEF& _get_gdef (hb_face_t *face)
 {
@@ -106,11 +115,16 @@ hb_ot_layout_has_kerning (hb_face_t *face)
 }
 
 void
-hb_ot_layout_kern (hb_font_t *font,
-		   hb_buffer_t  *buffer,
-		   hb_mask_t kern_mask)
+hb_ot_layout_kern (hb_ot_shape_plan_t *plan,
+		   hb_font_t *font,
+		   hb_buffer_t  *buffer)
 {
-  _get_kern (font->face).apply (font, buffer, kern_mask);
+  hb_blob_t *blob;
+  const AAT::kern& kern = _get_kern (font->face, &blob);
+
+  AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+
+  kern.apply (&c);
 }
 
 
diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh
index 64b3d748..b29f87c5 100644
--- a/src/hb-ot-layout.hh
+++ b/src/hb-ot-layout.hh
@@ -34,6 +34,7 @@
 #include "hb-font.hh"
 #include "hb-buffer.hh"
 #include "hb-open-type.hh"
+#include "hb-ot-shape.hh"
 #include "hb-set-digest.hh"
 
 
@@ -48,6 +49,7 @@ HB_INTERNAL const OT::GDEF& _get_gdef (hb_face_t *face);
 HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face);
 HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face);
 
+struct hb_ot_shape_plan_t;
 
 /*
  * kern
@@ -57,9 +59,9 @@ HB_INTERNAL hb_bool_t
 hb_ot_layout_has_kerning (hb_face_t *face);
 
 HB_INTERNAL void
-hb_ot_layout_kern (hb_font_t *font,
-		   hb_buffer_t  *buffer,
-		   hb_mask_t kern_mask);
+hb_ot_layout_kern (hb_ot_shape_plan_t *plan,
+		   hb_font_t *font,
+		   hb_buffer_t  *buffer);
 
 
 /* Private API corresponding to hb-ot-layout.h: */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index c55d8dcb..b687996f 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -918,7 +918,7 @@ hb_ot_position (const hb_ot_shape_context_t *c)
   /* Visual fallback goes here. */
 
   if (c->plan->apply_kern)
-    hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask);
+    hb_ot_layout_kern (c->plan, c->font, c->buffer);
   else if (c->plan->fallback_kerning)
     _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
 
commit 949dad89a81ff5b6ef92e8737962b667249a3f2b
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Nov 2 12:47:55 2018 -0400

    [kern] Remove accelerator
    
    It wasn't doing anything.

diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh
index 6e629eb4..caa1d97e 100644
--- a/src/hb-ot-face.hh
+++ b/src/hb-ot-face.hh
@@ -67,7 +67,7 @@
     HB_OT_ACCELERATOR(OT, hmtx) \
     HB_OT_ACCELERATOR(OT, vmtx) \
     HB_OT_ACCELERATOR(OT, post) \
-    HB_OT_ACCELERATOR(OT, kern) \
+    HB_OT_TABLE(OT, kern) \
     HB_OT_ACCELERATOR(OT, glyf) \
     HB_OT_TABLE(OT, VORG) \
     HB_OT_ACCELERATOR(OT, name) \
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 4f196789..8c436f99 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -503,49 +503,26 @@ struct kern
     }
   }
 
-  struct accelerator_t
-  {
-    inline void init (hb_face_t *face)
-    {
-      blob = hb_sanitize_context_t().reference_table<kern> (face);
-      table = blob->as<kern> ();
-    }
-    inline void fini (void)
-    {
-      hb_blob_destroy (blob);
-    }
-
-    inline bool has_data (void) const
-    { return table->has_data (); }
-
-    inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-    { return table->get_h_kerning (left, right); }
-
-    inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
-    { return get_h_kerning (first, second); }
+  inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
+  { return get_h_kerning (first, second); }
 
-    inline void apply (hb_font_t *font,
-		       hb_buffer_t  *buffer,
-		       hb_mask_t kern_mask) const
-    {
-      /* We only apply horizontal kerning in this table. */
-      if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
-        return;
-
-      hb_kern_machine_t<accelerator_t> machine (*this);
+  inline void apply (hb_font_t *font,
+		     hb_buffer_t  *buffer,
+		     hb_mask_t kern_mask) const
+  {
+    /* We only apply horizontal kerning in this table. */
+    if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+      return;
 
-      if (!buffer->message (font, "start kern table"))
-        return;
+    hb_kern_machine_t<kern> machine (*this);
 
-      machine.kern (font, buffer, kern_mask);
+    if (!buffer->message (font, "start kern table"))
+      return;
 
-      (void) buffer->message (font, "end kern table");
-    }
+    machine.kern (font, buffer, kern_mask);
 
-    private:
-    hb_blob_t *blob;
-    const kern *table;
-  };
+    (void) buffer->message (font, "end kern table");
+  }
 
   protected:
   union {
@@ -558,8 +535,6 @@ struct kern
   DEFINE_SIZE_UNION (4, version32);
 };
 
-struct kern_accelerator_t : kern::accelerator_t {};
-
 } /* namespace OT */
 
 
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index e1b6b2e3..f4ae840b 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -55,9 +55,9 @@
  **/
 
 
-static const OT::kern::accelerator_t& _get_kern (hb_face_t *face)
+static const OT::kern& _get_kern (hb_face_t *face)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t);
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern);
   return *hb_ot_face_data (face)->kern;
 }
 const OT::GDEF& _get_gdef (hb_face_t *face)


More information about the HarfBuzz mailing list