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 <beh...@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 <beh...@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 <beh...@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@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 <beh...@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 <beh...@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 <beh...@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 <beh...@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);
_______________________________________________
HarfBuzz mailing list
HarfBuzz@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/harfbuzz

Reply via email to