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

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Oct 19 23:07:57 UTC 2018


 src/hb-aat-layout-ankr-table.hh |    6 ++--
 src/hb-aat-layout-common.hh     |   55 +++++++++++++++++++++++++++++++++++++---
 src/hb-aat-layout-kerx-table.hh |   37 +++++++++++++++++++++-----
 src/hb-machinery.hh             |    4 ++
 src/hb-open-type.hh             |    3 ++
 5 files changed, 92 insertions(+), 13 deletions(-)

New commits:
commit 29d877518fc2c29083cd7b955b422087966235f7
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 19 16:06:54 2018 -0700

    [kerx] Implement variation-kerning tables (without the variation part)
    
    SFSNDisplay uses these.  We just apply the default kern without
    variations right now.  But at least makes the default kern work.

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 9727e396..64257809 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -45,6 +45,21 @@ namespace AAT {
 using namespace OT;
 
 
+static inline int
+kerxTupleKern (int value,
+	       unsigned int tupleCount,
+	       const void *base,
+	       hb_aat_apply_context_t *c)
+{
+  if (likely (!tupleCount)) return value;
+
+  unsigned int offset = value;
+  const FWORD *pv = &StructAtOffset<FWORD> (base, offset);
+  if (unlikely (!pv->sanitize (&c->sanitizer))) return 0;
+  return *pv;
+}
+
+
 struct KerxSubTableHeader
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -65,6 +80,7 @@ struct KerxSubTableFormat0
 {
   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
+    if (header.tupleCount) return 0; /* TODO kerxTupleKern */
     hb_glyph_pair_t pair = {left, right};
     int i = pairs.bsearch (pair);
     return i == -1 ? 0 : pairs[i].get_kerning ();
@@ -201,6 +217,9 @@ struct KerxSubTableFormat1
     if (!c->plan->requested_kerning)
       return false;
 
+    if (header.tupleCount)
+      return_trace (false); /* TODO kerxTupleKern */
+
     driver_context_t dc (this, c);
 
     StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
@@ -236,7 +255,7 @@ struct KerxSubTableFormat2
     unsigned int offset = l + r;
     const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
     if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
-    return *v;
+    return kerxTupleKern (*v, header.tupleCount, this, c);
   }
 
   inline bool apply (hb_aat_apply_context_t *c) const
@@ -482,7 +501,7 @@ struct KerxSubTableFormat6
       if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0;
       const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32));
       if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
-      return *v;
+      return kerxTupleKern (*v, header.tupleCount, &(this+vector), c);
     }
     else
     {
@@ -492,7 +511,7 @@ struct KerxSubTableFormat6
       unsigned int offset = l + r;
       const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD));
       if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
-      return *v;
+      return kerxTupleKern (*v, header.tupleCount, &(this+vector), c);
     }
   }
 
@@ -523,7 +542,9 @@ struct KerxSubTableFormat6
 			     u.s.rowIndexTable.sanitize (c, this) &&
 			     u.s.columnIndexTable.sanitize (c, this) &&
 			     c->check_range (this, u.s.array)
-			   ))));
+			   )) &&
+			  (header.tupleCount == 0 ||
+			   c->check_range (this, vector))));
   }
 
   struct accelerator_t
@@ -559,8 +580,9 @@ struct KerxSubTableFormat6
       LOffsetTo<UnsizedArrayOf<FWORD>, false>	array;
     } s;
   } u;
+  LOffsetTo<UnsizedArrayOf<FWORD>, false>	vector;
   public:
-  DEFINE_SIZE_STATIC (32);
+  DEFINE_SIZE_STATIC (36);
 };
 
 struct KerxTable
@@ -642,9 +664,8 @@ struct kerx
     {
       bool reverse;
 
-      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 (table->u.header.coverage & (KerxTable::CrossStream))
+	goto skip; /* We do NOT handle cross-stream. */
 
       if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
 	  bool (table->u.header.coverage & KerxTable::Vertical))
commit f7c0b4319c6f82f1e0020a0029469d8953a7a161
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Oct 19 15:23:49 2018 -0700

    [aat] Implement LookupFormat10

diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh
index 2e3ed275..5f7656d2 100644
--- a/src/hb-aat-layout-ankr-table.hh
+++ b/src/hb-aat-layout-ankr-table.hh
@@ -63,8 +63,10 @@ struct ankr
 				   unsigned int num_glyphs,
 				   const char *end) const
   {
-    unsigned int offset = (this+lookupTable).get_value_or_null (glyph_id, num_glyphs);
-    const GlyphAnchors &anchors = StructAtOffset<GlyphAnchors> (&(this+anchorData), offset);
+    const Offset<HBUINT16, false> *offset = (this+lookupTable).get_value (glyph_id, num_glyphs);
+    if (!offset)
+      return Null(Anchor);
+    const GlyphAnchors &anchors = StructAtOffset<GlyphAnchors> (&(this+anchorData), *offset);
     /* TODO Use sanitizer; to avoid overflows and more. */
     if (unlikely ((const char *) &anchors + anchors.get_size () > end))
       return Null(Anchor);
diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index 89ed91f2..60724c18 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -247,6 +247,48 @@ struct LookupFormat8
 };
 
 template <typename T>
+struct LookupFormat10
+{
+  friend struct Lookup<T>;
+
+  private:
+  inline const typename T::type get_value_or_null (hb_codepoint_t glyph_id) const
+  {
+    if (!(firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount))
+      return Null(T);
+
+    const HBUINT8 *p = &valueArrayZ[(glyph_id - firstGlyph) * valueSize];
+
+    unsigned int v = 0;
+    unsigned int count = valueSize;
+    for (unsigned int i = 0; i < count; i++)
+      v = (v << 8) | *p++;
+
+    return v;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  valueSize <= 4 &&
+		  valueArrayZ.sanitize (c, glyphCount * valueSize));
+  }
+
+  protected:
+  HBUINT16	format;		/* Format identifier--format = 8 */
+  HBUINT16	valueSize;	/* Byte size of each value. */
+  GlyphID	firstGlyph;	/* First glyph index included in the trimmed array. */
+  HBUINT16	glyphCount;	/* Total number of glyphs (equivalent to the last
+				 * glyph minus the value of firstGlyph plus 1). */
+  UnsizedArrayOf<HBUINT8>
+		valueArrayZ;	/* The lookup values (indexed by the glyph index
+				 * minus the value of firstGlyph). */
+  public:
+  DEFINE_SIZE_ARRAY (6, valueArrayZ);
+};
+
+template <typename T>
 struct Lookup
 {
   inline const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
@@ -261,10 +303,15 @@ struct Lookup
     }
   }
 
-  inline const T& get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
+  inline const typename T::type get_value_or_null (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
   {
-    const T *v = get_value (glyph_id, num_glyphs);
-    return v ? *v : Null(T);
+    switch (u.format) {
+      /* Format 10 cannot return a pointer. */
+      case 10: return u.format10.get_value_or_null (glyph_id);
+      default:
+      const T *v = get_value (glyph_id, num_glyphs);
+      return v ? *v : Null(T);
+    }
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -277,6 +324,7 @@ struct Lookup
     case 4: return_trace (u.format4.sanitize (c));
     case 6: return_trace (u.format6.sanitize (c));
     case 8: return_trace (u.format8.sanitize (c));
+    case 10: return_trace (u.format10.sanitize (c));
     default:return_trace (true);
     }
   }
@@ -289,6 +337,7 @@ struct Lookup
   LookupFormat4<T>	format4;
   LookupFormat6<T>	format6;
   LookupFormat8<T>	format8;
+  LookupFormat10<T>	format10;
   } u;
   public:
   DEFINE_SIZE_UNION (2, format);
diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh
index 717abea9..ae34c92f 100644
--- a/src/hb-machinery.hh
+++ b/src/hb-machinery.hh
@@ -652,6 +652,7 @@ template <typename Type>
 struct BEInt<Type, 1>
 {
   public:
+  typedef Type type;
   inline void set (Type V)
   {
     v = V;
@@ -666,6 +667,7 @@ template <typename Type>
 struct BEInt<Type, 2>
 {
   public:
+  typedef Type type;
   inline void set (Type V)
   {
     v[0] = (V >>  8) & 0xFF;
@@ -682,6 +684,7 @@ template <typename Type>
 struct BEInt<Type, 3>
 {
   public:
+  typedef Type type;
   inline void set (Type V)
   {
     v[0] = (V >> 16) & 0xFF;
@@ -700,6 +703,7 @@ template <typename Type>
 struct BEInt<Type, 4>
 {
   public:
+  typedef Type type;
   inline void set (Type V)
   {
     v[0] = (V >> 24) & 0xFF;
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index 9d2e1fa7..08e72064 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -56,6 +56,7 @@ namespace OT {
 template <typename Type, unsigned int Size>
 struct IntType
 {
+  typedef Type type;
   inline void set (Type i) { v.set (i); }
   inline operator Type(void) const { return v; }
   inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
@@ -161,6 +162,8 @@ DECLARE_NULL_NAMESPACE_BYTES (OT, Index);
 template <typename Type, bool has_null=true>
 struct Offset : Type
 {
+  typedef Type type;
+
   inline bool is_null (void) const { return has_null && 0 == *this; }
 
   inline void *serialize (hb_serialize_context_t *c, const void *base)


More information about the HarfBuzz mailing list