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

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Oct 11 05:23:32 UTC 2018


 src/hb-aat-layout-ankr-table.hh |   25 +++++-
 src/hb-aat-layout-common.hh     |   11 ++
 src/hb-aat-layout-kerx-table.hh |  154 ++++++++++++++++++++++++++++++++++++++--
 src/hb-aat-layout.cc            |   20 ++++-
 src/hb-ot-layout-gpos-table.hh  |    4 -
 5 files changed, 198 insertions(+), 16 deletions(-)

New commits:
commit fbbd926dba163d9a2a6a62f380951f03363c2b14
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 01:22:29 2018 -0400

    [kerx] Implement Format4 action_type=1 contour-point-based attachment
    
    Untested.
    
    This concludes kerx table support!

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index a54e2978..cd112912 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -354,7 +354,22 @@ struct KerxSubTableFormat4
 	      return false;
 	    HB_UNUSED unsigned int markControlPoint = *data++;
 	    HB_UNUSED unsigned int currControlPoint = *data++;
-	    /* TODO */
+	    hb_position_t markX = 0;
+	    hb_position_t markY = 0;
+	    hb_position_t currX = 0;
+	    hb_position_t currY = 0;
+	    if (!c->font->get_glyph_contour_point_for_origin (c->buffer->info[mark].codepoint,
+							      markControlPoint,
+							      HB_DIRECTION_LTR /*XXX*/,
+							      &markX, &markY) ||
+		!c->font->get_glyph_contour_point_for_origin (c->buffer->cur ().codepoint,
+							      currControlPoint,
+							      HB_DIRECTION_LTR /*XXX*/,
+							      &currX, &currY))
+	      return true; /* True, such that the machine continues. */
+
+	    o.x_offset = markX - currX;
+	    o.y_offset = markY - currY;
 	  }
 	  break;
 
commit b6bc0d4ff62e4509643db3b304306a72bbcb2c38
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 01:17:57 2018 -0400

    [kerx] Implement Format4 action_type=2 coordinate-based attachment
    
    Untested.

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 019efd57..a54e2978 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -343,6 +343,7 @@ struct KerxSubTableFormat4
 
       if (mark_set && entry->data.ankrActionIndex != 0xFFFF)
       {
+	hb_glyph_position_t &o = buffer->cur_pos();
 	switch (action_type)
 	{
 	  case 0: /* Control Point Actions.*/
@@ -373,12 +374,9 @@ struct KerxSubTableFormat4
 								currAnchorPoint,
 								c->face->get_num_glyphs (),
 								c->ankr_end);
-	    hb_glyph_position_t &o = buffer->cur_pos();
+
 	    o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate);
 	    o.y_offset = c->font->em_scale_y (markAnchor.yCoordinate) - c->font->em_scale_y (currAnchor.yCoordinate);
-	    o.attach_type() = ATTACH_TYPE_MARK;
-	    o.attach_chain() = (int) mark - (int) buffer->idx;
-	    buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
 	  }
 	  break;
 
@@ -387,14 +385,19 @@ struct KerxSubTableFormat4
 	    const FWORD *data = (const FWORD *) &ankrData[entry->data.ankrActionIndex];
 	    if (!c->sanitizer.check_array (data, 4))
 	      return false;
-	    HB_UNUSED int markX = *data++;
-	    HB_UNUSED int markY = *data++;
-	    HB_UNUSED int currX = *data++;
-	    HB_UNUSED int currY = *data++;
-	    /* TODO */
+	    int markX = *data++;
+	    int markY = *data++;
+	    int currX = *data++;
+	    int currY = *data++;
+
+	    o.x_offset = c->font->em_scale_x (markX) - c->font->em_scale_x (currX);
+	    o.y_offset = c->font->em_scale_y (markY) - c->font->em_scale_y (currY);
 	  }
 	  break;
 	}
+	o.attach_type() = ATTACH_TYPE_MARK;
+	o.attach_chain() = (int) mark - (int) buffer->idx;
+	buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
       }
 
       if (flags & Mark)
commit 1622ba5943d14b2d50d45dc17fb723f4c9ddb0bb
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 01:14:18 2018 -0400

    [kerx] Implement Format4 'ankr'-based mark attachment
    
    Tested with Kannada MN:
    
    $ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0CCD,0C95,0CD6
    [kn_ka.vattu=0+230|kn_ai_length_mark=1 at 326,0+607]

diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index dada9c7a..78de04fa 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -531,6 +531,7 @@ struct hb_aat_apply_context_t :
   hb_buffer_t *buffer;
   hb_sanitize_context_t sanitizer;
   const ankr &ankr_table;
+  const char *ankr_end;
 
   /* Unused. For debug tracing only. */
   unsigned int lookup_index;
@@ -540,9 +541,12 @@ struct hb_aat_apply_context_t :
 				 hb_font_t *font_,
 				 hb_buffer_t *buffer_,
 				 hb_blob_t *table,
-				 const ankr &ankr_table_ = Null(ankr)) :
+				 const ankr &ankr_table_ = Null(ankr),
+				 const char *ankr_end_ = nullptr) :
 		plan (plan_), font (font_), face (font->face), buffer (buffer_),
-		sanitizer (), ankr_table (ankr_table_), lookup_index (0), debug_depth (0)
+		sanitizer (),
+		ankr_table (ankr_table_), ankr_end (ankr_end_),
+		lookup_index (0), debug_depth (0)
   {
     sanitizer.init (table);
     sanitizer.set_num_glyphs (face->get_num_glyphs ());
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index c109d003..019efd57 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -30,6 +30,7 @@
 
 #include "hb-open-type.hh"
 #include "hb-aat-layout-common.hh"
+#include "hb-ot-layout-gpos-table.hh"
 #include "hb-ot-kern-table.hh"
 
 /*
@@ -362,9 +363,22 @@ struct KerxSubTableFormat4
 	    const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex];
 	    if (!c->sanitizer.check_array (data, 2))
 	      return false;
-	    HB_UNUSED unsigned int markAnchorPoint = *data++;
-	    HB_UNUSED unsigned int currAnchorPoint = *data++;
-	    /* TODO */
+	    unsigned int markAnchorPoint = *data++;
+	    unsigned int currAnchorPoint = *data++;
+	    const Anchor markAnchor = c->ankr_table.get_anchor (c->buffer->info[mark].codepoint,
+								markAnchorPoint,
+								c->face->get_num_glyphs (),
+								c->ankr_end);
+	    const Anchor currAnchor = c->ankr_table.get_anchor (c->buffer->cur ().codepoint,
+								currAnchorPoint,
+								c->face->get_num_glyphs (),
+								c->ankr_end);
+	    hb_glyph_position_t &o = buffer->cur_pos();
+	    o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate);
+	    o.y_offset = c->font->em_scale_y (markAnchor.yCoordinate) - c->font->em_scale_y (currAnchor.yCoordinate);
+	    o.attach_type() = ATTACH_TYPE_MARK;
+	    o.attach_chain() = (int) mark - (int) buffer->idx;
+	    buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
 	  }
 	  break;
 
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index 47462ad7..73ab06d3 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -69,10 +69,18 @@ _get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
   return kerx;
 }
 static inline const AAT::ankr&
-_get_ankr (hb_face_t *face)
+_get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr)
 {
-  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::ankr);
-  return *(hb_ot_face_data (face)->ankr.get ());
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
+  {
+    if (blob)
+      *blob = hb_blob_get_empty ();
+    return Null(AAT::ankr);
+  }
+  const AAT::ankr& ankr = *(hb_ot_face_data (face)->ankr.get ());
+  if (blob)
+    *blob = hb_ot_face_data (face)->ankr.get_blob ();
+  return ankr;
 }
 
 
@@ -109,6 +117,10 @@ hb_aat_layout_position (hb_ot_shape_plan_t *plan,
   hb_blob_t *blob;
   const AAT::kerx& kerx = _get_kerx (font->face, &blob);
 
-  AAT::hb_aat_apply_context_t c (plan, font, buffer, blob, _get_ankr (font->face));
+  hb_blob_t *ankr_blob;
+  const AAT::ankr& ankr = _get_ankr (font->face, &ankr_blob);
+
+  AAT::hb_aat_apply_context_t c (plan, font, buffer, blob,
+				 ankr, ankr_blob->data + ankr_blob->length);
   kerx.apply (&c);
 }
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 1a96609d..746c2462 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1755,10 +1755,6 @@ template <typename context_t>
 struct GPOS_accelerator_t : GPOS::accelerator_t {};
 
 
-#undef attach_chain
-#undef attach_type
-
-
 } /* namespace OT */
 
 
commit 7bb4da7d9538f3d4b1d28030d43e0c3d720d821b
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 00:52:07 2018 -0400

    [aat] Wire up 'ankr' table to apply context

diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index 37ab5353..dada9c7a 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -514,6 +514,7 @@ struct StateTableDriver
 };
 
 
+struct ankr;
 
 struct hb_aat_apply_context_t :
        hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
@@ -529,6 +530,7 @@ struct hb_aat_apply_context_t :
   hb_face_t *face;
   hb_buffer_t *buffer;
   hb_sanitize_context_t sanitizer;
+  const ankr &ankr_table;
 
   /* Unused. For debug tracing only. */
   unsigned int lookup_index;
@@ -537,9 +539,10 @@ struct hb_aat_apply_context_t :
   inline hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_,
 				 hb_font_t *font_,
 				 hb_buffer_t *buffer_,
-				 hb_blob_t *table) :
+				 hb_blob_t *table,
+				 const ankr &ankr_table_ = Null(ankr)) :
 		plan (plan_), font (font_), face (font->face), buffer (buffer_),
-		sanitizer (), lookup_index (0), debug_depth (0)
+		sanitizer (), ankr_table (ankr_table_), lookup_index (0), debug_depth (0)
   {
     sanitizer.init (table);
     sanitizer.set_num_glyphs (face->get_num_glyphs ());
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index 3fd4f9f8..47462ad7 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -68,6 +68,12 @@ _get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
     *blob = hb_ot_face_data (face)->kerx.get_blob ();
   return kerx;
 }
+static inline const AAT::ankr&
+_get_ankr (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::ankr);
+  return *(hb_ot_face_data (face)->ankr.get ());
+}
 
 
 hb_bool_t
@@ -103,6 +109,6 @@ hb_aat_layout_position (hb_ot_shape_plan_t *plan,
   hb_blob_t *blob;
   const AAT::kerx& kerx = _get_kerx (font->face, &blob);
 
-  AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+  AAT::hb_aat_apply_context_t c (plan, font, buffer, blob, _get_ankr (font->face));
   kerx.apply (&c);
 }
commit 28f0367aab648c486d6e8d0e13dbbb2af1b65dcc
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Oct 11 00:12:49 2018 -0400

    [kerx] Flesh out Format4
    
    Doesn't apply actions yet.

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index a96bad17..c109d003 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -293,11 +293,121 @@ struct KerxSubTableFormat2
 
 struct KerxSubTableFormat4
 {
+  struct EntryData
+  {
+    HBUINT16	ankrActionIndex;/* Either 0xFFFF (for no action) or the index of
+				 * the action to perform. */
+    public:
+    DEFINE_SIZE_STATIC (2);
+  };
+
+  struct driver_context_t
+  {
+    static const bool in_place = true;
+    enum Flags
+    {
+      Mark		= 0x8000,	/* If set, remember this glyph as the marked glyph. */
+      DontAdvance	= 0x4000,	/* If set, don't advance to the next glyph before
+					 * going to the new state. */
+      Reserved		= 0x3FFF,	/* Not used; set to 0. */
+    };
+
+    enum SubTableFlags
+    {
+      ActionType	= 0xC0000000,	/* A two-bit field containing the action type. */
+      Unused		= 0x3F000000,	/* Unused - must be zero. */
+      Offset		= 0x00FFFFFF,	/* Masks the offset in bytes from the beginning
+					 * of the subtable to the beginning of the control
+					 * point table. */
+    };
+
+    inline driver_context_t (const KerxSubTableFormat4 *table,
+			     hb_aat_apply_context_t *c_) :
+	c (c_),
+	action_type ((table->flags & ActionType) >> 30),
+	ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))),
+	mark_set (false),
+	mark (0) {}
+
+    inline bool is_actionable (StateTableDriver<EntryData> *driver,
+			       const Entry<EntryData> *entry)
+    {
+      return entry->data.ankrActionIndex != 0xFFFF;
+    }
+    inline bool transition (StateTableDriver<EntryData> *driver,
+			    const Entry<EntryData> *entry)
+    {
+      hb_buffer_t *buffer = driver->buffer;
+      unsigned int flags = entry->flags;
+
+      if (mark_set && entry->data.ankrActionIndex != 0xFFFF)
+      {
+	switch (action_type)
+	{
+	  case 0: /* Control Point Actions.*/
+	  {
+	    /* indexed into glyph outline. */
+	    const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex];
+	    if (!c->sanitizer.check_array (data, 2))
+	      return false;
+	    HB_UNUSED unsigned int markControlPoint = *data++;
+	    HB_UNUSED unsigned int currControlPoint = *data++;
+	    /* TODO */
+	  }
+	  break;
+
+	  case 1: /* Anchor Point Actions. */
+	  {
+	   /* Indexed into 'ankr' table. */
+	    const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex];
+	    if (!c->sanitizer.check_array (data, 2))
+	      return false;
+	    HB_UNUSED unsigned int markAnchorPoint = *data++;
+	    HB_UNUSED unsigned int currAnchorPoint = *data++;
+	    /* TODO */
+	  }
+	  break;
+
+	  case 2: /* Control Point Coordinate Actions. */
+	  {
+	    const FWORD *data = (const FWORD *) &ankrData[entry->data.ankrActionIndex];
+	    if (!c->sanitizer.check_array (data, 4))
+	      return false;
+	    HB_UNUSED int markX = *data++;
+	    HB_UNUSED int markY = *data++;
+	    HB_UNUSED int currX = *data++;
+	    HB_UNUSED int currY = *data++;
+	    /* TODO */
+	  }
+	  break;
+	}
+      }
+
+      if (flags & Mark)
+      {
+	mark_set = true;
+	mark = buffer->idx;
+      }
+
+      return true;
+    }
+
+    private:
+    hb_aat_apply_context_t *c;
+    unsigned int action_type;
+    const HBUINT16 *ankrData;
+    bool mark_set;
+    unsigned int mark;
+  };
+
   inline bool apply (hb_aat_apply_context_t *c) const
   {
     TRACE_APPLY (this);
 
-    /* TODO */
+    driver_context_t dc (this, c);
+
+    StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
+    driver.drive (&dc);
 
     return_trace (true);
   }
@@ -306,14 +416,18 @@ struct KerxSubTableFormat4
   {
     TRACE_SANITIZE (this);
 
-    /* TODO */
-    return_trace (likely (c->check_struct (this)));
+    /* The rest of array sanitizations are done at run-time. */
+    return_trace (c->check_struct (this) &&
+		  machine.sanitize (c) &&
+		  flags.sanitize (c));
   }
 
   protected:
   KerxSubTableHeader	header;
+  StateTable<EntryData>	machine;
+  HBUINT32		flags;
   public:
-  DEFINE_SIZE_STATIC (12);
+  DEFINE_SIZE_STATIC (32);
 };
 
 struct KerxSubTableFormat6
commit 947962a287d9aca2cb509c11f44cb5150aa6daf1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 10 23:07:03 2018 -0400

    [ankr] Implement table access

diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh
index cc92ee29..3eac473a 100644
--- a/src/hb-aat-layout-ankr-table.hh
+++ b/src/hb-aat-layout-ankr-table.hh
@@ -45,16 +45,32 @@ struct Anchor
     return_trace (c->check_struct (this));
   }
 
+  public:
   FWORD		xCoordinate;
   FWORD		yCoordinate;
   public:
   DEFINE_SIZE_STATIC (4);
 };
 
+typedef LArrayOf<Anchor> GlyphAnchors;
+
 struct ankr
 {
   static const hb_tag_t tableTag = HB_AAT_TAG_ankr;
 
+  inline const Anchor &get_anchor (hb_codepoint_t glyph_id,
+				   unsigned int i,
+				   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);
+    /* TODO Use sanitizer; to avoid overflows and more. */
+    if (unlikely ((const char *) &anchors + anchors.get_size () > end))
+      return Null(Anchor);
+    return anchors[i];
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
commit 7281cb3eeb00091c6e6085895afd4a38a0516f35
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Oct 10 22:56:52 2018 -0400

    [ankr] Start fixing

diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh
index a197cec8..cc92ee29 100644
--- a/src/hb-aat-layout-ankr-table.hh
+++ b/src/hb-aat-layout-ankr-table.hh
@@ -60,17 +60,16 @@ struct ankr
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
 			  version == 0 &&
-			  lookupTable.sanitize (c, this) &&
-			  anchors.sanitize (c, this)));
+			  lookupTable.sanitize (c, this)));
   }
 
   protected:
   HBUINT16	version; 	/* Version number (set to zero) */
   HBUINT16	flags;		/* Flags (currently unused; set to zero) */
-  LOffsetTo<Lookup<HBUINT16> >
+  LOffsetTo<Lookup<Offset<HBUINT16, false> > >
 		lookupTable;	/* Offset to the table's lookup table */
-  LOffsetTo<LArrayOf<Anchor> >
-		anchors;	/* Offset to the glyph data table */
+  LOffsetTo<HBUINT8>
+		anchorData;	/* Offset to the glyph data table */
 
   public:
   DEFINE_SIZE_STATIC (12);


More information about the HarfBuzz mailing list