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

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue Oct 23 09:21:51 UTC 2018


 src/Makefile.sources                                                          |    1 
 src/hb-aat-layout-morx-table.hh                                               |   10 
 src/hb-ot-face.hh                                                             |    1 
 src/hb-ot-font.cc                                                             |   11 
 src/hb-ot-vorg-table.hh                                                       |  182 ++++++++++
 test/shaping/data/in-house/fonts/4cbbc461be066fccc611dcc634af6e8cb2705537.ttf |binary
 test/shaping/data/in-house/tests/vertical.tests                               |    1 
 7 files changed, 204 insertions(+), 2 deletions(-)

New commits:
commit 48ed598a356983f4623029dd5e87254fb59e3691
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 23 02:19:32 2018 -0700

    [VORG] Hook up to hb-ot-font's v_origin
    
    Fixes https://github.com/harfbuzz/harfbuzz/issues/544
    
    Test added with NotoSansCJK, eg. with U+FF38.

diff --git a/src/hb-ot-face.cc b/src/hb-ot-face.cc
index 202619c3..1bc68d36 100644
--- a/src/hb-ot-face.cc
+++ b/src/hb-ot-face.cc
@@ -31,7 +31,6 @@
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-kern-table.hh"
 #include "hb-ot-post-table.hh"
-#include "hb-ot-vorg-table.hh"
 #include "hb-ot-color-cbdt-table.hh"
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index e6df038d..f0b62089 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -37,6 +37,7 @@
 #include "hb-ot-kern-table.hh"
 #include "hb-ot-post-table.hh"
 #include "hb-ot-glyf-table.hh"
+#include "hb-ot-vorg-table.hh"
 #include "hb-ot-color-cbdt-table.hh"
 
 
@@ -138,9 +139,15 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
 
   *x = font->get_glyph_h_advance (glyph) / 2;
 
+  const OT::VORG &VORG = *ot_face->VORG.get ();
+  if (VORG.has_data ())
+  {
+    *y = font->em_scale_y (VORG.get_y_origin (glyph));
+    return true;
+  }
+
   hb_glyph_extents_t extents = {0};
-  bool ret = ot_face->glyf->get_extents (glyph, &extents);
-  if (ret)
+  if (ot_face->glyf->get_extents (glyph, &extents))
   {
     const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get ();
     hb_position_t tsb = vmtx.get_side_bearing (glyph);
diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh
index 0baaf2e0..b6494b51 100644
--- a/src/hb-ot-vorg-table.hh
+++ b/src/hb-ot-vorg-table.hh
@@ -39,7 +39,7 @@ namespace OT {
 
 struct VertOriginMetric
 {
-  inline int cmp (hb_codepoint_t g) const { return -glyph.cmp (g); }
+  inline int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -63,7 +63,9 @@ struct VORG
 
   inline int get_y_origin (hb_codepoint_t glyph) const
   {
-    vertYOrigins.bsearch (glyph);
+    int i = vertYOrigins.bsearch (glyph);
+    if (i != -1)
+      return vertYOrigins[i].vertOriginY;
 
     return defaultVertOriginY;
   }
diff --git a/test/shaping/data/in-house/fonts/4cbbc461be066fccc611dcc634af6e8cb2705537.ttf b/test/shaping/data/in-house/fonts/4cbbc461be066fccc611dcc634af6e8cb2705537.ttf
new file mode 100644
index 00000000..03166b0c
Binary files /dev/null and b/test/shaping/data/in-house/fonts/4cbbc461be066fccc611dcc634af6e8cb2705537.ttf differ
diff --git a/test/shaping/data/in-house/tests/vertical.tests b/test/shaping/data/in-house/tests/vertical.tests
index b1811922..39588133 100644
--- a/test/shaping/data/in-house/tests/vertical.tests
+++ b/test/shaping/data/in-house/tests/vertical.tests
@@ -1,3 +1,4 @@
 ../fonts/191826b9643e3f124d865d617ae609db6a2ce203.ttf:--direction=t --font-funcs=ft:U+300C:[uni300C.vert=0 at -512,-578+0,-1024]
 ../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ft:U+0041,U+0042:[gid1=0 at -654,-2128+0,-2789|gid2=1 at -665,-2125+0,-2789]
 ../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ot:U+0041,U+0042:[gid1=0 at -654,-1468+0,-2048|gid2=1 at -665,-1462+0,-2048]
+../fonts/4cbbc461be066fccc611dcc634af6e8cb2705537.ttf:--direction=t --font-funcs=ot:U+FF38:[gid2=0 at -500,-867+0,-1000]
commit 097ecfd4a991d4fa306bab7330d9952966e94d1f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 23 02:09:42 2018 -0700

    [VORG] Add get_y_origin()
    
    Unhooked.

diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh
index 3b7bf4c0..0baaf2e0 100644
--- a/src/hb-ot-vorg-table.hh
+++ b/src/hb-ot-vorg-table.hh
@@ -39,6 +39,8 @@ namespace OT {
 
 struct VertOriginMetric
 {
+  inline int cmp (hb_codepoint_t g) const { return -glyph.cmp (g); }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -57,6 +59,15 @@ struct VORG
 {
   static const hb_tag_t tableTag = HB_OT_TAG_VORG;
 
+  inline bool has_data (void) const { return version.to_int (); }
+
+  inline int get_y_origin (hb_codepoint_t glyph) const
+  {
+    vertYOrigins.bsearch (glyph);
+
+    return defaultVertOriginY;
+  }
+
   inline bool _subset (const hb_subset_plan_t *plan,
                        const VORG *vorg_table,
                        const hb_vector_t<VertOriginMetric> &subset_metrics,
@@ -157,8 +168,9 @@ struct VORG
 
   protected:
   FixedVersion<>	version;		/* Version of VORG table. Set to 0x00010000u. */
-  FWORD			defaultVertOriginY;	/* The default vertical origin */
-  ArrayOf<VertOriginMetric>vertYOrigins;	/* The array of vertical origins */
+  FWORD			defaultVertOriginY;	/* The default vertical origin. */
+  SortedArrayOf<VertOriginMetric>
+			vertYOrigins;		/* The array of vertical origins. */
 
   public:
   DEFINE_SIZE_ARRAY(8, vertYOrigins);
commit 6fb24d5e3e0cf61c0ed3574e5bcf4598a13d6b69
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 23 01:58:59 2018 -0700

    [VORG] Add VORG table
    
    Cherry-picked from cff-subset branch.

diff --git a/src/Makefile.sources b/src/Makefile.sources
index 93965ac0..eed245bc 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -153,6 +153,7 @@ HB_OT_sources = \
 	hb-ot-var-fvar-table.hh \
 	hb-ot-var-hvar-table.hh \
 	hb-ot-var-mvar-table.hh \
+	hb-ot-vorg-table.hh \
 	$(NULL)
 
 HB_OT_RAGEL_GENERATED_sources = \
diff --git a/src/hb-ot-face.cc b/src/hb-ot-face.cc
index 1bc68d36..202619c3 100644
--- a/src/hb-ot-face.cc
+++ b/src/hb-ot-face.cc
@@ -31,6 +31,7 @@
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-kern-table.hh"
 #include "hb-ot-post-table.hh"
+#include "hb-ot-vorg-table.hh"
 #include "hb-ot-color-cbdt-table.hh"
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh
index 5ea7bf0e..a45a4936 100644
--- a/src/hb-ot-face.hh
+++ b/src/hb-ot-face.hh
@@ -68,6 +68,7 @@
     HB_OT_ACCELERATOR(OT, post) \
     HB_OT_ACCELERATOR(OT, kern) \
     HB_OT_ACCELERATOR(OT, glyf) \
+    HB_OT_TABLE(OT, VORG) \
     /* OpenType color fonts. */ \
     HB_OT_TABLE(OT, COLR) \
     HB_OT_TABLE(OT, CPAL) \
diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh
new file mode 100644
index 00000000..3b7bf4c0
--- /dev/null
+++ b/src/hb-ot-vorg-table.hh
@@ -0,0 +1,168 @@
+/*
+ * Copyright © 2018 Adobe Systems Incorporated.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Adobe Author(s): Michiharu Ariza
+ */
+
+#ifndef HB_OT_VORG_TABLE_HH
+#define HB_OT_VORG_TABLE_HH
+
+#include "hb-open-type.hh"
+
+/*
+ * VORG -- Vertical Origin Table
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/vorg
+ */
+#define HB_OT_TAG_VORG HB_TAG('V','O','R','G')
+
+namespace OT {
+
+struct VertOriginMetric
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  GlyphID	glyph;
+  FWORD		vertOriginY;
+
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct VORG
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_VORG;
+
+  inline bool _subset (const hb_subset_plan_t *plan,
+                       const VORG *vorg_table,
+                       const hb_vector_t<VertOriginMetric> &subset_metrics,
+                       unsigned int dest_sz,
+                       void *dest) const
+  {
+    hb_serialize_context_t c (dest, dest_sz);
+
+    VORG *subset_table = c.start_serialize<VORG> ();
+    if (unlikely (!c.extend_min (*subset_table)))
+      return false;
+
+    subset_table->version.major.set (1);
+    subset_table->version.minor.set (0);
+
+    subset_table->defaultVertOriginY.set (vorg_table->defaultVertOriginY);
+    subset_table->vertYOrigins.len.set (subset_metrics.len);
+
+    bool success = true;
+    if (subset_metrics.len > 0)
+    {
+      unsigned int  size = VertOriginMetric::static_size * subset_metrics.len;
+      VertOriginMetric  *metrics = c.allocate_size<VertOriginMetric> (size);
+      if (likely (metrics != nullptr))
+        memcpy (metrics, &subset_metrics[0], size);
+      else
+        success = false;
+    }
+    c.end_serialize ();
+
+    return success;
+  }
+
+  inline bool subset (hb_subset_plan_t *plan) const
+  {
+    hb_blob_t *vorg_blob = hb_sanitize_context_t().reference_table<VORG> (plan->source);
+    const VORG *vorg_table = vorg_blob->as<VORG> ();
+
+    /* count the number of glyphs to be included in the subset table */
+    hb_vector_t<VertOriginMetric> subset_metrics;
+    subset_metrics.init ();
+    unsigned int glyph = 0;
+    unsigned int i = 0;
+    while ((glyph < plan->glyphs.len) && (i < vertYOrigins.len))
+    {
+      if (plan->glyphs[glyph] > vertYOrigins[i].glyph)
+        i++;
+      else if (plan->glyphs[glyph] < vertYOrigins[i].glyph)
+        glyph++;
+      else
+      {
+        VertOriginMetric *metrics = subset_metrics.push ();
+        metrics->glyph.set (glyph);
+        metrics->vertOriginY.set (vertYOrigins[i].vertOriginY);
+        glyph++;
+        i++;
+      }
+    }
+
+    /* alloc the new table */
+    unsigned int dest_sz = VORG::min_size + VertOriginMetric::static_size * subset_metrics.len;
+    void *dest = (void *) malloc (dest_sz);
+    if (unlikely (!dest))
+    {
+      subset_metrics.fini ();
+      hb_blob_destroy (vorg_blob);
+      return false;
+    }
+
+    /* serialize the new table */
+    if (!_subset (plan, vorg_table, subset_metrics, dest_sz, dest))
+    {
+      subset_metrics.fini ();
+      free (dest);
+      hb_blob_destroy (vorg_blob);
+      return false;
+    }
+
+    hb_blob_t *result = hb_blob_create ((const char *)dest,
+                                        dest_sz,
+                                        HB_MEMORY_MODE_READONLY,
+                                        dest,
+                                        free);
+    bool success = plan->add_table (HB_OT_TAG_VORG, result);
+    hb_blob_destroy (result);
+    subset_metrics.fini ();
+    hb_blob_destroy (vorg_blob);
+    return success;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  version.major == 1 &&
+                  vertYOrigins.sanitize (c));
+  }
+
+  protected:
+  FixedVersion<>	version;		/* Version of VORG table. Set to 0x00010000u. */
+  FWORD			defaultVertOriginY;	/* The default vertical origin */
+  ArrayOf<VertOriginMetric>vertYOrigins;	/* The array of vertical origins */
+
+  public:
+  DEFINE_SIZE_ARRAY(8, vertYOrigins);
+};
+} /* namespace OT */
+
+#endif /* HB_OT_VORG_TABLE_HH */
commit 531f9822b2e8a60f03c43d6f86ef9ed32c951f0e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 23 01:32:08 2018 -0700

    [morx] Add a few debug messages to Ligature chain

diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 3f5f29d1..5577efe8 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -373,6 +373,7 @@ struct LigatureSubtable
       hb_buffer_t *buffer = driver->buffer;
       unsigned int flags = entry->flags;
 
+      DEBUG_MSG (APPLY, nullptr, "Ligature transition at %d", buffer->idx);
       if (flags & SetComponent)
       {
         if (unlikely (match_length >= ARRAY_LENGTH (match_positions)))
@@ -383,10 +384,12 @@ struct LigatureSubtable
 	  match_length--;
 
 	match_positions[match_length++] = buffer->out_len;
+	DEBUG_MSG (APPLY, nullptr, "Set component at %d", buffer->out_len);
       }
 
       if (flags & PerformAction)
       {
+	DEBUG_MSG (APPLY, nullptr, "Perform action with %d", match_length);
 	unsigned int end = buffer->out_len;
 	unsigned int action_idx = entry->data.ligActionIndex;
 	unsigned int action;
@@ -404,10 +407,12 @@ struct LigatureSubtable
 	  if (unlikely (!cursor))
 	  {
 	    /* Stack underflow.  Clear the stack. */
+	    DEBUG_MSG (APPLY, nullptr, "Stack underflow");
 	    match_length = 0;
 	    break;
 	  }
 
+	  DEBUG_MSG (APPLY, nullptr, "Moving to stack position %d", cursor - 1);
 	  buffer->move_to (match_positions[--cursor]);
 
 	  const HBUINT32 &actionData = ligAction[action_idx];
@@ -426,17 +431,22 @@ struct LigatureSubtable
 	  if (unlikely (!componentData.sanitize (&c->sanitizer))) return false;
 	  ligature_idx += componentData;
 
+	  DEBUG_MSG (APPLY, nullptr, "Action store %d last %d",
+		     bool (action & LigActionStore),
+		     bool (action & LigActionLast));
 	  if (action & (LigActionStore | LigActionLast))
 	  {
 	    const GlyphID &ligatureData = ligature[ligature_idx];
 	    if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false;
 	    hb_codepoint_t lig = ligatureData;
 
+	    DEBUG_MSG (APPLY, nullptr, "Produced ligature %d", lig);
 	    buffer->replace_glyph (lig);
 
 	    /* Now go and delete all subsequent components. */
 	    while (match_length - 1 > cursor)
 	    {
+	      DEBUG_MSG (APPLY, nullptr, "Skipping ligature component");
 	      buffer->move_to (match_positions[--match_length]);
 	      buffer->skip_glyph ();
 	      end--;


More information about the HarfBuzz mailing list