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

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Oct 11 00:11:28 UTC 2018


 src/hb-aat-layout-kerx-table.hh |  106 +++++++++++++++++++++++++++++++++-------
 src/hb-open-type.hh             |    3 +
 2 files changed, 91 insertions(+), 18 deletions(-)

New commits:
commit ab1f30bd059f1d2270793e9726b60666b328d2b8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 10 20:10:20 2018 -0400

    [kerx] Implement Format6
    
    Untested.  The only Apple font shipping with this format is San Francisco fonts
    that use this for their kerx variation tables, which we don't support.

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 31b650ad..3cff334a 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -136,7 +136,7 @@ struct KerxSubTableFormat2
     unsigned int offset = l + r;
     const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
     if (unlikely ((const char *) v < (const char *) &array ||
-		  (const char *) v + 2 - (const char *) this <= header.length))
+		  (const char *) v + v->static_size - (const char *) this <= header.length))
       return 0;
     return *v;
   }
@@ -230,6 +230,35 @@ struct KerxSubTableFormat6
 
   inline bool is_long (void) const { return flags & ValuesAreLong; }
 
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
+			  unsigned int num_glyphs) const
+  {
+    if (is_long ())
+    {
+      const U::Long &t = u.l;
+      unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs);
+      unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs);
+      unsigned int offset = l + r;
+      const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32));
+      if (unlikely ((const char *) v < (const char *) &t.array ||
+		    (const char *) v + v->static_size - (const char *) this <= header.length))
+	return 0;
+      return *v;
+    }
+    else
+    {
+      const U::Short &t = u.s;
+      unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs);
+      unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs);
+      unsigned int offset = l + r;
+      const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD));
+      if (unlikely ((const char *) v < (const char *) &t.array ||
+		    (const char *) v + v->static_size - (const char *) this <= header.length))
+	return 0;
+      return *v;
+    }
+  }
+
   inline bool apply (hb_aat_apply_context_t *c) const
   {
     TRACE_APPLY (this);
@@ -237,7 +266,10 @@ struct KerxSubTableFormat6
     if (!c->plan->requested_kerning)
       return false;
 
-    /* TODO */
+    accelerator_t accel (*this,
+			 c->face->get_num_glyphs ());
+    hb_kern_machine_t<accelerator_t> machine (accel);
+    machine.kern (c->font, c->buffer, c->plan->kern_mask);
 
     return_trace (true);
   }
@@ -250,33 +282,48 @@ struct KerxSubTableFormat6
 			  (
 			    u.l.rowIndexTable.sanitize (c, this) &&
 			    u.l.columnIndexTable.sanitize (c, this) &&
-			    u.l.kerningArray.sanitize (c, this)
+			    u.l.array.sanitize (c, this)
 			  ) : (
 			    u.s.rowIndexTable.sanitize (c, this) &&
 			    u.s.columnIndexTable.sanitize (c, this) &&
-			    u.s.kerningArray.sanitize (c, this)
+			    u.s.array.sanitize (c, this)
 			  )));
   }
 
+  struct accelerator_t
+  {
+    const KerxSubTableFormat6 &table;
+    unsigned int num_glyphs;
+
+    inline accelerator_t (const KerxSubTableFormat6 &table_,
+			  unsigned int num_glyphs_)
+			  : table (table_), num_glyphs (num_glyphs_) {}
+
+    inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+    {
+      return table.get_kerning (left, right, num_glyphs);
+    }
+  };
+
   protected:
   KerxSubTableHeader		header;
   HBUINT32			flags;
   HBUINT16			rowCount;
   HBUINT16			columnCount;
-  union
+  union U
   {
-    struct
-    {
-      LOffsetTo<Lookup<HBUINT16> >	rowIndexTable;
-      LOffsetTo<Lookup<HBUINT16> >	columnIndexTable;
-      LOffsetTo<FWORD>			kerningArray;
-    } s;
-    struct
+    struct Long
     {
       LOffsetTo<Lookup<HBUINT32> >	rowIndexTable;
       LOffsetTo<Lookup<HBUINT32> >	columnIndexTable;
-      LOffsetTo<FWORD32>		kerningArray;
+      LOffsetTo<FWORD32>		array;
     } l;
+    struct Short
+    {
+      LOffsetTo<Lookup<HBUINT16> >	rowIndexTable;
+      LOffsetTo<Lookup<HBUINT16> >	columnIndexTable;
+      LOffsetTo<FWORD>			array;
+    } s;
   } u;
   public:
   DEFINE_SIZE_STATIC (32);
commit c9a2ce9e05f91730a2150b9214dc6a49f31555c1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 10 20:00:44 2018 -0400

    [kerx] Move bounds-checking to subtable length itself

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 05b28f3c..31b650ad 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -129,14 +129,14 @@ struct KerxSubTableFormat1
 struct KerxSubTableFormat2
 {
   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
-			  const char *end, unsigned int num_glyphs) const
+			  unsigned int num_glyphs) const
   {
     unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs);
     unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs);
     unsigned int offset = l + r;
     const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
     if (unlikely ((const char *) v < (const char *) &array ||
-		  (const char *) v > (const char *) end - 2))
+		  (const char *) v + 2 - (const char *) this <= header.length))
       return 0;
     return *v;
   }
@@ -149,7 +149,6 @@ struct KerxSubTableFormat2
       return false;
 
     accelerator_t accel (*this,
-			 c->sanitizer.end,
 			 c->face->get_num_glyphs ());
     hb_kern_machine_t<accelerator_t> machine (accel);
     machine.kern (c->font, c->buffer, c->plan->kern_mask);
@@ -170,16 +169,15 @@ struct KerxSubTableFormat2
   struct accelerator_t
   {
     const KerxSubTableFormat2 &table;
-    const char *end;
     unsigned int num_glyphs;
 
     inline accelerator_t (const KerxSubTableFormat2 &table_,
-			  const char *end_, unsigned int num_glyphs_)
-			  : table (table_), end (end_), num_glyphs (num_glyphs_) {}
+			  unsigned int num_glyphs_)
+			  : table (table_), num_glyphs (num_glyphs_) {}
 
     inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
     {
-      return table.get_kerning (left, right, end, num_glyphs);
+      return table.get_kerning (left, right, num_glyphs);
     }
   };
 
commit 22955b23cdeb48e46cdffd0eb906a855a420c4d1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 10 19:58:20 2018 -0400

    [kerx] Start fleshing out Format6

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index cd8dc458..05b28f3c 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -225,6 +225,13 @@ struct KerxSubTableFormat4
 
 struct KerxSubTableFormat6
 {
+  enum Flags
+  {
+    ValuesAreLong	= 0x00000001,
+  };
+
+  inline bool is_long (void) const { return flags & ValuesAreLong; }
+
   inline bool apply (hb_aat_apply_context_t *c) const
   {
     TRACE_APPLY (this);
@@ -241,10 +248,16 @@ struct KerxSubTableFormat6
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-			  rowIndexTable.sanitize (c, this) &&
-			  columnIndexTable.sanitize (c, this) &&
-			  kerningArray.sanitize (c, this) &&
-			  kerningVector.sanitize (c, this)));
+			  is_long () ?
+			  (
+			    u.l.rowIndexTable.sanitize (c, this) &&
+			    u.l.columnIndexTable.sanitize (c, this) &&
+			    u.l.kerningArray.sanitize (c, this)
+			  ) : (
+			    u.s.rowIndexTable.sanitize (c, this) &&
+			    u.s.columnIndexTable.sanitize (c, this) &&
+			    u.s.kerningArray.sanitize (c, this)
+			  )));
   }
 
   protected:
@@ -252,12 +265,23 @@ struct KerxSubTableFormat6
   HBUINT32			flags;
   HBUINT16			rowCount;
   HBUINT16			columnCount;
-  LOffsetTo<Lookup<HBUINT16> >	rowIndexTable;
-  LOffsetTo<Lookup<HBUINT16> >	columnIndexTable;
-  LOffsetTo<Lookup<HBUINT16> >	kerningArray;
-  LOffsetTo<Lookup<HBUINT16> >	kerningVector;
+  union
+  {
+    struct
+    {
+      LOffsetTo<Lookup<HBUINT16> >	rowIndexTable;
+      LOffsetTo<Lookup<HBUINT16> >	columnIndexTable;
+      LOffsetTo<FWORD>			kerningArray;
+    } s;
+    struct
+    {
+      LOffsetTo<Lookup<HBUINT32> >	rowIndexTable;
+      LOffsetTo<Lookup<HBUINT32> >	columnIndexTable;
+      LOffsetTo<FWORD32>		kerningArray;
+    } l;
+  } u;
   public:
-  DEFINE_SIZE_STATIC (36);
+  DEFINE_SIZE_STATIC (32);
 };
 
 struct KerxTable
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index 9a087336..2eae09d5 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -92,6 +92,9 @@ typedef IntType<uint32_t, 3> HBUINT24;	/* 24-bit unsigned integer. */
 /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
 typedef HBINT16 FWORD;
 
+/* 32-bit signed integer (HBINT32) that describes a quantity in FUnits. */
+typedef HBINT32 FWORD32;
+
 /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
 typedef HBUINT16 UFWORD;
 
commit f6aaad9b4ffb42e6cd8398f6439fe420e393c8f6
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 10 19:20:06 2018 -0400

    [kerx] When rejecting variable kerning, also check for tupleCount

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index c683242f..cd8dc458 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -339,7 +339,8 @@ struct kerx
     {
       bool reverse;
 
-      if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation))
+      if (table->u.header.coverage & (KerxTable::CrossStream | KerxTable::Variation) ||
+	  table->u.header.tupleCount)
 	goto skip; /* We do NOT handle cross-stream or variation kerning. */
 
       if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=


More information about the HarfBuzz mailing list