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

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Mar 1 23:16:25 UTC 2018


 src/hb-aat-layout-kerx-table.hh |  298 ++++++++++++++++------------------------
 src/hb-ot-colr-table.hh         |   27 ++-
 src/hb-ot-cpal-table.hh         |   14 -
 3 files changed, 148 insertions(+), 191 deletions(-)

New commits:
commit b73a5a1c240478616827529c94f0133018f9f790
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Fri Mar 2 00:07:26 2018 +0330

    [aat/kerx] Make parsing of the table actually work (#850)

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 505e5084..b3c6a11d 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -1,6 +1,6 @@
 /*
- * Copyright © 2018  Google, Inc.
  * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2018  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -28,35 +28,19 @@
 #ifndef HB_AAT_LAYOUT_KERX_TABLE_HH
 #define HB_AAT_LAYOUT_KERX_TABLE_HH
 
+#include "hb-open-type-private.hh"
 #include "hb-aat-layout-common-private.hh"
 
-namespace AAT {
+#define HB_AAT_TAG_KERX HB_TAG('k','e','r','x')
 
 
-/*
- * kerx -- Kerning
- */
+namespace AAT {
 
-#define HB_AAT_TAG_kerx HB_TAG('k','e','r','x')
+using namespace OT;
 
-struct hb_glyph_pair_t
-{
-  hb_codepoint_t left;
-  hb_codepoint_t right;
-};
 
-struct KerxPair
+struct KerxFormat0Records
 {
-  inline int get_kerning (void) const
-  { return value; }
-
-  inline int cmp (const hb_glyph_pair_t &o) const
-  {
-    int ret = left.cmp (o.left);
-    if (ret) return ret;
-    return right.cmp (o.right);
-  }
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -67,59 +51,60 @@ struct KerxPair
   GlyphID	left;
   GlyphID	right;
   FWORD		value;
-  HBUINT16 pad;
   public:
-  DEFINE_SIZE_STATIC (8);
+  DEFINE_SIZE_STATIC (6);
 };
 
 struct KerxSubTableFormat0
 {
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-  {
-    //hb_glyph_pair_t pair = {left, right};
-    //int i = pairs.bsearch (pair);
-    //if (i == -1)
-      return 0;
-    //return pairs[i].get_kerning ();
-  }
+  // TODO(ebraminio) Enable when we got suitable BinSearchArrayOf
+  // inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+  // {
+  //   hb_glyph_pair_t pair = {left, right};
+  //   int i = pairs.bsearch (pair);
+  //   if (i == -1)
+  //     return 0;
+  //   return pairs[i].get_kerning ();
+  // }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (pairs.sanitize (c));
+    return_trace (c->check_struct (this) &&
+      c->check_array (records, records[0].static_size, nPairs));
   }
 
   protected:
-  BinSearchArrayOf<KerxPair> pairs;	/* Array of kerning pairs. */
-  //FIXME: BinSearchArrayOf and its BinSearchHeader should be
-  //modified in a way to accept uint32s
+  // TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is
+  // needed here to use HBUINT32 instead
+  HBUINT32 nPairs;	/* The number of kerning pairs in this subtable */
+  HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs,
+                         * multiplied by the size in bytes of an entry in the subtable. */
+  HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less
+                           * than or equal to the value of nPairs. */
+  HBUINT32 rangeShift;	/* The value of nPairs minus the largest power of two less than or equal to nPairs. */
+  KerxFormat0Records records[VAR]; /* VAR=nPairs */
   public:
-  //DEFINE_SIZE_ARRAY (16, pairs);
-};
-
-struct KerxAction
-{
-  HBUINT16 index;
+  DEFINE_SIZE_ARRAY (16, records);
 };
 
 struct KerxSubTableFormat1
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
-    //TRACE_SANITIZE (this);
-    //return_trace (stateHeader.sanitize (c));
-    return false;
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+      stateHeader.sanitize (c));
   }
 
   protected:
-  StateTable<KerxAction> stateHeader;
-  OffsetTo<ArrayOf<HBUINT16>, HBUINT32> valueTable;
-
+  StateTable<HBUINT16>		stateHeader;
+  LOffsetTo<ArrayOf<HBUINT16> >	valueTable;
   public:
-  //DEFINE_SIZE_MIN (4);
+  DEFINE_SIZE_STATIC (20);
 };
 
-//FIXME: Maybe this can be replaced with Lookup<HBUINT16>?
+// TODO(ebraminio): Maybe this can be replaced with Lookup<HBUINT16>?
 struct KerxClassTable
 {
   inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
@@ -156,7 +141,8 @@ struct KerxSubTableFormat2
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (rowWidth.sanitize (c) &&
+    return_trace (c->check_struct (this) &&
+      rowWidth.sanitize (c) &&
 		  leftClassTable.sanitize (c, this) &&
 		  rightClassTable.sanitize (c, this) &&
 		  array.sanitize (c, this));
@@ -174,7 +160,7 @@ struct KerxSubTableFormat2
 		array;		/* Offset from beginning of this subtable to
 				 * the start of the kerning array. */
   public:
-  DEFINE_SIZE_MIN (16);
+  DEFINE_SIZE_STATIC (16);
 };
 
 struct KerxSubTableFormat4
@@ -182,7 +168,8 @@ struct KerxSubTableFormat4
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (rowWidth.sanitize (c) &&
+    return_trace (c->check_struct (this) &&
+      rowWidth.sanitize (c) &&
 		  leftClassTable.sanitize (c, this) &&
 		  rightClassTable.sanitize (c, this) &&
 		  array.sanitize (c, this));
@@ -200,182 +187,145 @@ struct KerxSubTableFormat4
 		array;		/* Offset from beginning of this subtable to
 				 * the start of the kerning array. */
   public:
-  DEFINE_SIZE_MIN (16);
+  DEFINE_SIZE_STATIC (16);
 };
 
 struct KerxSubTableFormat6
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
-    //TRACE_SANITIZE (this);
-    //return_trace ;
-    return false;
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
   }
 
   protected:
-  HBUINT32 flags;
-  HBUINT16 rowCount;
-  HBUINT16 columnCount;
-  HBUINT32 rowIndexTableOffset;
-  HBUINT32 columnIndexTableOffset;
-  HBUINT32 kerningArrayOffset;
-  HBUINT32 kerningVectorOffset;
-
+  HBUINT32	flags;
+  HBUINT16	rowCount;
+  HBUINT16	columnCount;
+  HBUINT32	rowIndexTableOffset;
+  HBUINT32	columnIndexTableOffset;
+  HBUINT32	kerningArrayOffset;
+  HBUINT32	kerningVectorOffset;
   public:
-  DEFINE_SIZE_MIN (24);
+  DEFINE_SIZE_STATIC (24);
 };
 
-struct KerxSubTable
+enum coverage_flags_t
 {
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const
+  COVERAGE_VERTICAL_FLAG	= 0x80u,
+  COVERAGE_CROSSSTREAM_FLAG	= 0x40u,
+  COVERAGE_VARIATION_FLAG	= 0x20u,
+  COVERAGE_PROCESS_DIRECTION	= 0x10u,
+};
+
+struct KerxTable
+{
+  inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const
   {
-    switch (format) {
-    case 0: return u.format0.get_kerning (left, right);
-    case 2: return u.format2.get_kerning (left, right, end);
-    default:return 0;
-    }
+    TRACE_APPLY (this);
+    /* TODO */
+    return_trace (false);
   }
 
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
+  inline unsigned int get_size (void) const { return length; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
+    if (!c->check_struct (this))
+      return_trace (false);
+
     switch (format) {
-    case 0: return_trace (u.format0.sanitize (c));
-    case 2: return_trace (u.format2.sanitize (c));
-    default:return_trace (true);
+    case 0: return u.format0.sanitize (c);
+    case 1: return u.format1.sanitize (c);
+    case 2: return u.format2.sanitize (c);
+    case 4: return u.format4.sanitize (c);
+    case 6: return u.format6.sanitize (c);
+    default:return_trace (false);
     }
   }
 
-  protected:
+protected:
+  HBUINT32	length;
+  HBUINT8	coverage;
+  HBUINT16	unused;
+  HBUINT8	format;
+  HBUINT32	tupleIndex;
   union {
   KerxSubTableFormat0	format0;
+  KerxSubTableFormat1	format1;
   KerxSubTableFormat2	format2;
   KerxSubTableFormat4	format4;
   KerxSubTableFormat6	format6;
   } u;
-  public:
-  DEFINE_SIZE_MIN (0);
+public:
+  DEFINE_SIZE_MIN (12);
 };
 
+struct SubtableGlyphCoverageArray
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
 
+  protected:
+  HBUINT32	length;
+  HBUINT32	coverage;
+  HBUINT32	tupleCount;
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
 
 struct kerx
 {
-  static const hb_tag_t tableTag = HB_AAT_TAG_kerx;
+  static const hb_tag_t tableTag = HB_AAT_TAG_KERX;
 
   inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const
   {
     TRACE_APPLY (this);
-    /* TODO */
-    return_trace (false);
+    const KerxTable &table = StructAfter<KerxTable> (*this);
+    return_trace (table.apply (c, ankr));
   }
 
-  struct SubTableWrapper
+  inline bool sanitize (hb_sanitize_context_t *c) const
   {
-    enum coverage_flags_t {
-      COVERAGE_VERTICAL_FLAG	= 0x8000u,
-      COVERAGE_CROSSSTREAM_FLAG	= 0x4000u,
-      COVERAGE_VARIATION_FLAG	= 0x2000u,
-
-      COVERAGE_OVERRIDE_FLAG	= 0x0000u, /* Not supported. */
-
-      COVERAGE_CHECK_FLAGS	= 0x0700u, //FIXME: Where these two come from?
-      COVERAGE_CHECK_HORIZONTAL	= 0x0100u
-    };
-
-    protected:
-    HBUINT32	length;		/* Length of the subtable (including this header). */
-    HBUINT16	coverage;	/* Coverage bits. */
-    HBUINT16	format;		/* Subtable format. */
-    HBUINT32	tupleIndex;	/* The tuple index (used for variations fonts).
-				 * This value specifies which tuple this subtable covers. */
-    KerxSubTable subtable;	/* Subtable data. */
-    public:
-    inline bool is_horizontal (void) const
-    { return (coverage & COVERAGE_CHECK_FLAGS) == COVERAGE_CHECK_HORIZONTAL; }
-
-    inline bool is_override (void) const
-    { return bool (coverage & COVERAGE_OVERRIDE_FLAG); }
-
-    inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
-    { return subtable.get_kerning (left, right, end, 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; }
+    TRACE_SANITIZE (this);
+    if (!(c->check_struct (this)))
+     return_trace (false);
 
-    inline unsigned int get_size (void) const { return length; }
+    const KerxTable *table = &StructAfter<KerxTable> (*this);
+    if (!(table->sanitize (c)))
+      return_trace (false);
 
-    inline bool sanitize (hb_sanitize_context_t *c) const
+    for (unsigned int i = 0; i < nTables - 1; ++i)
     {
-      TRACE_SANITIZE (this);
-      return_trace (c->check_struct (this) &&
-        length >= min_size &&
-        c->check_array (this, 1, length) &&
-        subtable.sanitize (c, format));
+      table = &StructAfter<KerxTable> (*table);
+      if (!(table->sanitize (c)))
+        return_trace (false);
     }
-    DEFINE_SIZE_MIN (12);
-  };
 
-  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
-  {
-    int v = 0;
-    const SubTableWrapper *st = (SubTableWrapper *) data;
-    unsigned int count = nTables;
-    for (unsigned int i = 0; i < count; i++)
-    {
-      if (st->is_override ())
-        v = 0;
-      v += st->get_h_kerning (left, right, table_length + (const char *) this);
-      st = (SubTableWrapper *) st;
-    }
-    return v;
-  }
+    // If version is less than 3, we are done here; otherwise better to check footer also
+    if (version < 3)
+      return_trace (true);
 
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    const SubTableWrapper *st = (SubTableWrapper *) data;
-    unsigned int count = nTables;
-    for (unsigned int i = 0; i < count; i++)
-    {
-      if (unlikely (!st->sanitize (c)))
-	return_trace (false);
-      st = (SubTableWrapper *) st;
-    }
+    // TODO: Investigate why this just work on some fonts no matter of version
+    // const SubtableGlyphCoverageArray &footer =
+    //   StructAfter<SubtableGlyphCoverageArray> (*table);
+    // return_trace (footer.sanitize (c));
 
     return_trace (true);
   }
 
-  struct accelerator_t
-  {
-    inline void init (hb_face_t *face)
-    {
-      blob = Sanitizer<kerx>().sanitize (face->reference_table (HB_AAT_TAG_kerx));
-      table = Sanitizer<kerx>::lock_instance (blob);
-      table_length = hb_blob_get_length (blob);
-    }
-    inline void fini (void)
-    {
-      hb_blob_destroy (blob);
-    }
-
-    inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-    { return table->get_h_kerning (left, right, table_length); }
-
-    private:
-    hb_blob_t *blob;
-    const kerx *table;
-    unsigned int table_length;
-  };
-
   protected:
   HBUINT16		version;
   HBUINT16		padding;
-  HBUINT32		nTables;	/* Number of subtables in the kerning table. */
-  HBUINT8		data[VAR];
-  //ArrayOf<GlyphCoverageArray> subtableGlyphCoverageArray;
+  HBUINT32		nTables;
+/*KerxTable tables[VAR];*/
+/*SubtableGlyphCoverageArray coverage_array;*/
   public:
-  DEFINE_SIZE_ARRAY (8, data);
+  DEFINE_SIZE_STATIC (8);
 };
 
 } /* namespace AAT */
commit a570edcde2f89e59b5ccd4867a8c0eed084bf35d
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Fri Mar 2 00:06:03 2018 +0330

    [COLR] Sanitize BaseGlyphRecord (#854)

diff --git a/src/hb-ot-colr-table.hh b/src/hb-ot-colr-table.hh
index c5bc2ccb..08a39a99 100644
--- a/src/hb-ot-colr-table.hh
+++ b/src/hb-ot-colr-table.hh
@@ -42,10 +42,10 @@ struct LayerRecord
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (true);
+    return_trace (c->check_struct (this));
   }
 
-  HBUINT16 gID;			/* Glyph ID of layer glyph */
+  GlyphID gID;			/* Glyph ID of layer glyph */
   HBUINT16 paletteIndex;	/* Index value to use with a selected color palette */
   public:
   DEFINE_SIZE_STATIC (4);
@@ -53,13 +53,15 @@ struct LayerRecord
 
 struct BaseGlyphRecord
 {
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int palettes) const
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
+    return_trace (c->check_struct (this) &&
+      firstLayerIndex.sanitize (c, base) &&
+      c->check_array ((const void*) &firstLayerIndex, sizeof (LayerRecord), numLayers));
   }
 
-  HBUINT16 gID;			/* Glyph ID of reference glyph */
+  GlyphID gID;			/* Glyph ID of reference glyph */
   OffsetTo<LayerRecord>
   	firstLayerIndex;	/* Index to the layer record */
   HBUINT16 numLayers;		/* Number of color layers associated with this glyph */
@@ -74,9 +76,17 @@ struct COLR
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-        c->check_array ((const void*) &baseGlyphRecords, sizeof (BaseGlyphRecord), numBaseGlyphRecords) &&
-        c->check_array ((const void*) &layerRecordsOffset, sizeof (LayerRecord), numLayerRecords));
+    if (!(c->check_struct (this) &&
+      c->check_array ((const void*) &baseGlyphRecords, sizeof (BaseGlyphRecord), numBaseGlyphRecords) &&
+      c->check_array ((const void*) &layerRecordsOffset, sizeof (LayerRecord), numLayerRecords)))
+      return_trace (false);
+
+    const BaseGlyphRecord *base_glyph_records = &baseGlyphRecords (this);
+    for (unsigned int i = 0; i < numBaseGlyphRecords; ++i)
+      if (!(base_glyph_records[i].sanitize (c, this)))
+        return_trace (false);
+
+    return_trace (true);
   }
 
   protected:
@@ -87,7 +97,6 @@ struct COLR
   LOffsetTo<LayerRecord>
 		layerRecordsOffset;	/* Offset to Layer Records */
   HBUINT16	numLayerRecords;	/* Number of Layer Records */
-
   public:
   DEFINE_SIZE_STATIC (14);
 };
commit 7e958646a4a825bfe3aac56ddb96100d68c5592c
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date:   Thu Mar 1 10:27:18 2018 +0330

    [CPAL] Fix version checking logic on sanitizer (#851)

diff --git a/src/hb-ot-cpal-table.hh b/src/hb-ot-cpal-table.hh
index aade0e73..740a94b3 100644
--- a/src/hb-ot-cpal-table.hh
+++ b/src/hb-ot-cpal-table.hh
@@ -89,7 +89,6 @@ struct CPALV1Tail
   LOffsetTo<HBUINT32> paletteFlags;
   LOffsetTo<HBUINT16> paletteLabel;
   LOffsetTo<HBUINT16> paletteEntryLabel;
-
   public:
   DEFINE_SIZE_STATIC (12);
 };
@@ -113,13 +112,12 @@ struct CPAL
       if (colorRecordIndices[i] + numPaletteEntries > colorRecords.get_size ())
         return_trace (false);
 
-    if (version > 1)
-    {
-      const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this);
-      return_trace (v1.sanitize (c, palettes));
-    }
-    else
+    // If version is zero, we are done here; otherwise we need to check tail also
+    if (version == 0)
       return_trace (true);
+
+    const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this);
+    return_trace (v1.sanitize (c, palettes));
   }
 
   inline unsigned int get_size (void) const
@@ -158,7 +156,7 @@ struct CPAL
   HBUINT16	numPalettes;
   ArrayOf<ColorRecord>	colorRecords;
   HBUINT16	colorRecordIndices[VAR];  // VAR=numPalettes
-
+/*CPALV1Tail	v1[VAR];*/
   public:
   DEFINE_SIZE_ARRAY (12, colorRecordIndices);
 };


More information about the HarfBuzz mailing list