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

Behdad Esfahbod behdad at kemper.freedesktop.org
Mon Oct 8 00:38:28 UTC 2018


 src/hb-aat-layout-kerx-table.hh                                      |  169 ++++++----
 src/hb-aat-layout-morx-table.hh                                      |    4 
 src/hb-buffer.cc                                                     |   16 
 src/hb-ot-shape.cc                                                   |   16 
 test/shaping/data/text-rendering-tests/Makefile.sources              |    6 
 test/shaping/data/text-rendering-tests/fonts/TestMORXForty.ttf       |binary
 test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyeight.ttf |binary
 test/shaping/data/text-rendering-tests/fonts/TestMORXThirtynine.ttf  |binary
 test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyseven.ttf |binary
 test/shaping/data/text-rendering-tests/tests/MORX-35.tests           |    4 
 test/shaping/data/text-rendering-tests/tests/MORX-37.tests           |    4 
 test/shaping/data/text-rendering-tests/tests/MORX-38.tests           |    4 
 test/shaping/data/text-rendering-tests/tests/MORX-39.tests           |    4 
 test/shaping/data/text-rendering-tests/tests/MORX-40.tests           |    4 
 14 files changed, 154 insertions(+), 77 deletions(-)

New commits:
commit 2a5cb37fdb43230217e055f3d7c770a35cfd5c21
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 20:36:46 2018 -0400

    Revert "[morx] Fix MORX-35"
    
    This reverts commit f62f6e90ad1f1a83f77771ad65ee1ffb79470a8a.

diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index b9dddb2a..cf08d796 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -661,17 +661,13 @@ struct InsertionSubtable
 	 * current glyph, the next glyph processed would in fact be the first
 	 * one inserted."
 	 *
-	 * So, if DontAdvance *is* set, we move to "end", such that newly
-	 * inserted glyphs are visible.
+	 * This suggests that if DontAdvance is NOT set, we should move to
+	 * end+count.  If it *was*, then move to end, such that newly inserted
+	 * glyphs are now visible.
 	 *
-	 * If DontAdvance is *not* set, if inserted before, move past them,
-	 * such that original current glyph will be skipped over by the driver.
-	 * Otherwise, again, just move to "end" such that current glyph will
-	 * be skipped over by driver.
-	 *
-	 * https://github.com/harfbuzz/harfbuzz/issues/1224
+	 * https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417
 	 */
-	buffer->move_to ((flags & DontAdvance) || !before ? end : end + count);
+	buffer->move_to ((flags & DontAdvance) ? end : end + count);
       }
 
       if (flags & SetMark)
diff --git a/test/shaping/data/text-rendering-tests/DISABLED b/test/shaping/data/text-rendering-tests/DISABLED
index 8539c0ee..4e8b1cf2 100644
--- a/test/shaping/data/text-rendering-tests/DISABLED
+++ b/test/shaping/data/text-rendering-tests/DISABLED
@@ -1,3 +1,6 @@
+# https://github.com/harfbuzz/harfbuzz/issues/1224
+tests/MORX-35.tests
+
 # Non-Unicode cmap
 tests/CMAP-3.tests
 
diff --git a/test/shaping/data/text-rendering-tests/Makefile.sources b/test/shaping/data/text-rendering-tests/Makefile.sources
index c7f48760..5a3d20a6 100644
--- a/test/shaping/data/text-rendering-tests/Makefile.sources
+++ b/test/shaping/data/text-rendering-tests/Makefile.sources
@@ -55,7 +55,6 @@ TESTS = \
 	tests/MORX-32.tests \
 	tests/MORX-33.tests \
 	tests/MORX-34.tests \
-	tests/MORX-35.tests \
 	tests/MORX-36.tests \
 	tests/MORX-37.tests \
 	tests/MORX-38.tests \
@@ -74,6 +73,7 @@ TESTS = \
 
 DISBALED_TESTS = \
 	tests/CMAP-3.tests \
+	tests/MORX-35.tests \
 	tests/SHARAN-1.tests \
 	tests/SHBALI-1.tests \
 	tests/SHBALI-2.tests \
commit 14ebf8af0c04efcae6ca788ac85601bfe462f28d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 20:35:06 2018 -0400

    [buffer] Improve shift_forward()
    
    "Improve" is a strong word in this case though, I understand.

diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 0b8593f8..2b7b8864 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -182,7 +182,11 @@ hb_buffer_t::shift_forward (unsigned int count)
   if (idx + count > len)
   {
     /* Under memory failure we might expose this area.  At least
-     * clean it up.  Oh well... */
+     * clean it up.  Oh well...
+     *
+     * Ideally, we should at least set Default_Ignorable bits on
+     * these, as well as consistent cluster values.  But the former
+     * is layering violation... */
     memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
   }
   len += count;
@@ -399,8 +403,14 @@ hb_buffer_t::move_to (unsigned int i)
     unsigned int count = out_len - i;
 
     /* This will blow in our face if memory allocation fails later
-     * in this same lookup... */
-    if (unlikely (idx < count && !shift_forward (count + 32))) return false;
+     * in this same lookup...
+     *
+     * We used to shift with extra 32 items, instead of the 0 below.
+     * But that would leave empty slots in the buffer in case of allocation
+     * failures.  Setting to zero for now to avoid other problems (see
+     * comments in shift_forward().  This can cause O(N^2) behavior more
+     * severely than adding 32 empty slots can... */
+    if (unlikely (idx < count && !shift_forward (count + 0))) return false;
 
     assert (idx >= count);
 
commit f62f6e90ad1f1a83f77771ad65ee1ffb79470a8a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 18:06:53 2018 -0400

    [morx] Fix MORX-35
    
    Fixes https://github.com/harfbuzz/harfbuzz/issues/1224

diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 63b937ba..b9dddb2a 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -661,11 +661,17 @@ struct InsertionSubtable
 	 * current glyph, the next glyph processed would in fact be the first
 	 * one inserted."
 	 *
-	 * This suggests that if DontAdvance is NOT set, we should move to
-	 * end+count.  If it *was*, then move to end, such that newly inserted
-	 * glyphs are now visible.
+	 * So, if DontAdvance *is* set, we move to "end", such that newly
+	 * inserted glyphs are visible.
+	 *
+	 * If DontAdvance is *not* set, if inserted before, move past them,
+	 * such that original current glyph will be skipped over by the driver.
+	 * Otherwise, again, just move to "end" such that current glyph will
+	 * be skipped over by driver.
+	 *
+	 * https://github.com/harfbuzz/harfbuzz/issues/1224
 	 */
-	buffer->move_to ((flags & DontAdvance) ? end : end + count);
+	buffer->move_to ((flags & DontAdvance) || !before ? end : end + count);
       }
 
       if (flags & SetMark)
diff --git a/test/shaping/data/text-rendering-tests/DISABLED b/test/shaping/data/text-rendering-tests/DISABLED
index 4e8b1cf2..8539c0ee 100644
--- a/test/shaping/data/text-rendering-tests/DISABLED
+++ b/test/shaping/data/text-rendering-tests/DISABLED
@@ -1,6 +1,3 @@
-# https://github.com/harfbuzz/harfbuzz/issues/1224
-tests/MORX-35.tests
-
 # Non-Unicode cmap
 tests/CMAP-3.tests
 
diff --git a/test/shaping/data/text-rendering-tests/Makefile.sources b/test/shaping/data/text-rendering-tests/Makefile.sources
index 5a3d20a6..c7f48760 100644
--- a/test/shaping/data/text-rendering-tests/Makefile.sources
+++ b/test/shaping/data/text-rendering-tests/Makefile.sources
@@ -55,6 +55,7 @@ TESTS = \
 	tests/MORX-32.tests \
 	tests/MORX-33.tests \
 	tests/MORX-34.tests \
+	tests/MORX-35.tests \
 	tests/MORX-36.tests \
 	tests/MORX-37.tests \
 	tests/MORX-38.tests \
@@ -73,7 +74,6 @@ TESTS = \
 
 DISBALED_TESTS = \
 	tests/CMAP-3.tests \
-	tests/MORX-35.tests \
 	tests/SHARAN-1.tests \
 	tests/SHBALI-1.tests \
 	tests/SHBALI-2.tests \
commit 94368855c6bd7201d562cab3d2107685589e69c8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 18:52:12 2018 -0400

    Remove some code
    
    We use scratch-flags to short-circuit this function.  No need for previous
    early loop.

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 3b79ef46..4e5bd4e9 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -537,23 +537,13 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   hb_glyph_position_t *pos = buffer->pos;
-  unsigned int i = 0;
-  for (i = 0; i < count; i++)
-  {
-    if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i])))
-      break;
-  }
-
-  /* No default-ignorables found; return. */
-  if (i == count)
-    return;
 
   hb_codepoint_t invisible = c->buffer->invisible;
   if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) &&
       (invisible || c->font->get_nominal_glyph (' ', &invisible)))
   {
     /* Replace default-ignorables with a zero-advance invisible glyph. */
-    for (/*continue*/; i < count; i++)
+    for (unsigned int i = 0; i < count; i++)
     {
       if (_hb_glyph_info_is_default_ignorable (&info[i]))
 	info[i].codepoint = invisible;
@@ -563,8 +553,8 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
   {
     /* Merge clusters and delete default-ignorables.
      * NOTE! We can't use out-buffer as we have positioning data. */
-    unsigned int j = i;
-    for (; i < count; i++)
+    unsigned int j = 0;
+    for (unsigned int i = 0; i < count; i++)
     {
       if (_hb_glyph_info_is_default_ignorable (&info[i]))
       {
commit c07b91b812dc66b38b11329cd6a93258a3769f9e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 18:00:14 2018 -0400

    [test/text-rendering-tests] Update from upstream

diff --git a/test/shaping/data/text-rendering-tests/Makefile.sources b/test/shaping/data/text-rendering-tests/Makefile.sources
index 29d064b7..5a3d20a6 100644
--- a/test/shaping/data/text-rendering-tests/Makefile.sources
+++ b/test/shaping/data/text-rendering-tests/Makefile.sources
@@ -56,7 +56,11 @@ TESTS = \
 	tests/MORX-33.tests \
 	tests/MORX-34.tests \
 	tests/MORX-36.tests \
+	tests/MORX-37.tests \
+	tests/MORX-38.tests \
+	tests/MORX-39.tests \
 	tests/MORX-3.tests \
+	tests/MORX-40.tests \
 	tests/MORX-4.tests \
 	tests/MORX-5.tests \
 	tests/MORX-6.tests \
@@ -68,8 +72,8 @@ TESTS = \
 	$(NULL)
 
 DISBALED_TESTS = \
-	tests/MORX-35.tests \
 	tests/CMAP-3.tests \
+	tests/MORX-35.tests \
 	tests/SHARAN-1.tests \
 	tests/SHBALI-1.tests \
 	tests/SHBALI-2.tests \
diff --git a/test/shaping/data/text-rendering-tests/fonts/TestMORXForty.ttf b/test/shaping/data/text-rendering-tests/fonts/TestMORXForty.ttf
new file mode 100644
index 00000000..37d0b637
Binary files /dev/null and b/test/shaping/data/text-rendering-tests/fonts/TestMORXForty.ttf differ
diff --git a/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyeight.ttf b/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyeight.ttf
new file mode 100644
index 00000000..29a41d0a
Binary files /dev/null and b/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyeight.ttf differ
diff --git a/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtynine.ttf b/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtynine.ttf
new file mode 100644
index 00000000..c106ae94
Binary files /dev/null and b/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtynine.ttf differ
diff --git a/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyseven.ttf b/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyseven.ttf
new file mode 100644
index 00000000..22057f18
Binary files /dev/null and b/test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyseven.ttf differ
diff --git a/test/shaping/data/text-rendering-tests/tests/MORX-35.tests b/test/shaping/data/text-rendering-tests/tests/MORX-35.tests
index 1061034d..616b2f9b 100644
--- a/test/shaping/data/text-rendering-tests/tests/MORX-35.tests
+++ b/test/shaping/data/text-rendering-tests/tests/MORX-35.tests
@@ -1,2 +1,2 @@
-../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A|B at 639,0|C at 1265,0]
-../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[X|A at 586,0|B at 1225,0|C at 1851,0|E at 2447,0|Y at 3003,0]
+../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A|B at 639,0|E at 1265,0|C at 1821,0|E at 2417,0]
+../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[X|A at 586,0|B at 1225,0|E at 1851,0|C at 2407,0|E at 3003,0|Y at 3559,0]
diff --git a/test/shaping/data/text-rendering-tests/tests/MORX-37.tests b/test/shaping/data/text-rendering-tests/tests/MORX-37.tests
new file mode 100644
index 00000000..f28c5e2a
--- /dev/null
+++ b/test/shaping/data/text-rendering-tests/tests/MORX-37.tests
@@ -0,0 +1,4 @@
+../fonts/TestMORXThirtyseven.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041,U+0042:[A.alt|B.alt at 1000,0]
+../fonts/TestMORXThirtyseven.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0042,U+0041:[B|A at 650,0]
+../fonts/TestMORXThirtyseven.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+05D0,U+05D1:[uni05D1|uni05D0 at 542,0]
+../fonts/TestMORXThirtyseven.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+05D1,U+05D0:[uni05D0.alt|uni05D1.alt at 1000,0]
diff --git a/test/shaping/data/text-rendering-tests/tests/MORX-38.tests b/test/shaping/data/text-rendering-tests/tests/MORX-38.tests
new file mode 100644
index 00000000..abefe29b
--- /dev/null
+++ b/test/shaping/data/text-rendering-tests/tests/MORX-38.tests
@@ -0,0 +1,4 @@
+../fonts/TestMORXThirtyeight.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041,U+0042:[A.alt|B.alt at 1000,0]
+../fonts/TestMORXThirtyeight.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0042,U+0041:[B|A at 650,0]
+../fonts/TestMORXThirtyeight.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+05D0,U+05D1:[uni05D1.alt|uni05D0.alt at 1000,0]
+../fonts/TestMORXThirtyeight.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+05D1,U+05D0:[uni05D0|uni05D1 at 606,0]
diff --git a/test/shaping/data/text-rendering-tests/tests/MORX-39.tests b/test/shaping/data/text-rendering-tests/tests/MORX-39.tests
new file mode 100644
index 00000000..83bfa52b
--- /dev/null
+++ b/test/shaping/data/text-rendering-tests/tests/MORX-39.tests
@@ -0,0 +1,4 @@
+../fonts/TestMORXThirtynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041,U+0042:[A|B at 639,0]
+../fonts/TestMORXThirtynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0042,U+0041:[B.alt|A.alt at 1000,0]
+../fonts/TestMORXThirtynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+05D0,U+05D1:[uni05D1.alt|uni05D0.alt at 1000,0]
+../fonts/TestMORXThirtynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+05D1,U+05D0:[uni05D0|uni05D1 at 606,0]
diff --git a/test/shaping/data/text-rendering-tests/tests/MORX-40.tests b/test/shaping/data/text-rendering-tests/tests/MORX-40.tests
new file mode 100644
index 00000000..c99155e2
--- /dev/null
+++ b/test/shaping/data/text-rendering-tests/tests/MORX-40.tests
@@ -0,0 +1,4 @@
+../fonts/TestMORXForty.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041,U+0042:[A|B at 639,0]
+../fonts/TestMORXForty.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0042,U+0041:[B.alt|A.alt at 1000,0]
+../fonts/TestMORXForty.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+05D0,U+05D1:[uni05D1|uni05D0 at 542,0]
+../fonts/TestMORXForty.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+05D1,U+05D0:[uni05D0.alt|uni05D1.alt at 1000,0]
commit fdce1e15434f14b7f4802edd67f7af737cf2b075
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 14:01:33 2018 -0400

    [kerx] Clean up kerx and KerxTable structures

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 615a8f8d..21fd26b4 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -30,7 +30,6 @@
 
 #include "hb-open-type.hh"
 #include "hb-aat-layout-common.hh"
-#include "hb-aat-layout-ankr-table.hh"
 
 /*
  * kerx -- Extended Kerning
@@ -71,6 +70,14 @@ struct KerxSubTableFormat0
   //     return 0;
   //   return pairs[i].get_kerning ();
   // }
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    /* TODO */
+
+    return_trace (true);
+  }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -96,6 +103,15 @@ struct KerxSubTableFormat0
 
 struct KerxSubTableFormat1
 {
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    /* TODO */
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -145,6 +161,15 @@ struct KerxSubTableFormat2
     return *v;
   }
 
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    /* TODO */
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -172,6 +197,15 @@ struct KerxSubTableFormat2
 
 struct KerxSubTableFormat4
 {
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    /* TODO */
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -199,6 +233,15 @@ struct KerxSubTableFormat4
 
 struct KerxSubTableFormat6
 {
+  inline bool apply (hb_aat_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    /* TODO */
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -221,47 +264,55 @@ struct KerxSubTableFormat6
   DEFINE_SIZE_STATIC (24);
 };
 
-enum coverage_flags_t
-{
-  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
+  inline unsigned int get_size (void) const { return length; }
+  inline unsigned int get_type (void) const { return coverage & SubtableType; }
+
+  enum Coverage
   {
-    TRACE_APPLY (this);
-    /* TODO */
-    return_trace (false);
+    Vertical		= 0x80000000,	/* Set if table has vertical kerning values. */
+    CrossStream		= 0x40000000,	/* Set if table has cross-stream kerning values. */
+    Variation		= 0x20000000,	/* Set if table has variation kerning values. */
+    ProcessDirection	= 0x10000000,	/* If clear, process the glyphs forwards, that
+					 * is, from first to last in the glyph stream.
+					 * If we, process them from last to first.
+					 * This flag only applies to state-table based
+					 * 'kerx' subtables (types 1 and 4). */
+    Reserved		= 0x0FFFFF00,	/* Reserved, set to zero. */
+    SubtableType	= 0x000000FF,	/* Subtable type. */
+  };
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    unsigned int subtable_type = get_type ();
+    TRACE_DISPATCH (this, subtable_type);
+    switch (subtable_type) {
+    case 0	:		return_trace (c->dispatch (u.format0));
+    case 1	:		return_trace (c->dispatch (u.format1));
+    case 2	:		return_trace (c->dispatch (u.format2));
+    case 4	:		return_trace (c->dispatch (u.format4));
+    case 6	:		return_trace (c->dispatch (u.format6));
+    default:			return_trace (c->default_return_value ());
+    }
   }
 
-  inline unsigned int get_size (void) const { return length; }
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!c->check_struct (this)))
+    if (!length.sanitize (c) ||
+	length < min_size ||
+	!c->check_range (this, length))
       return_trace (false);
 
-    switch (format) {
-    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);
-    }
+    return_trace (dispatch (c));
   }
 
 protected:
   HBUINT32	length;
-  HBUINT8	coverage;
-  HBUINT16	unused;
-  HBUINT8	format;
-  HBUINT32	tupleIndex;
+  HBUINT32	coverage;
+  HBUINT32	tupleCount;
   union {
   KerxSubTableFormat0	format0;
   KerxSubTableFormat1	format1;
@@ -273,7 +324,7 @@ public:
   DEFINE_SIZE_MIN (12);
 };
 
-struct SubtableGlyphCoverageArray
+struct SubtableXXX
 {
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -289,55 +340,59 @@ struct SubtableGlyphCoverageArray
   DEFINE_SIZE_STATIC (12);
 };
 
+
+/*
+ * The 'kerx' Table
+ */
+
 struct 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
+  inline bool has_data (void) const { return version != 0; }
+
+  inline void apply (hb_aat_apply_context_t *c) const
   {
-    TRACE_APPLY (this);
-    const KerxTable &table = StructAfter<KerxTable> (*this);
-    return_trace (table.apply (c, ankr));
+    c->set_lookup_index (0);
+    const KerxTable *table = &firstTable;
+    unsigned int count = tableCount;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      table->dispatch (c);
+      table = &StructAfter<KerxTable> (*table);
+    }
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (!(c->check_struct (this))))
-     return_trace (false);
-
-    /* TODO: Something like `morx`s ChainSubtable should be done here instead */
-    const KerxTable *table = &StructAfter<KerxTable> (*this);
-    if (unlikely (!(table->sanitize (c))))
+    if (!version.sanitize (c) || version < 2 ||
+	!tableCount.sanitize (c))
       return_trace (false);
 
-    for (unsigned int i = 0; i < nTables - 1; ++i)
+    const KerxTable *table = &firstTable;
+    unsigned int count = tableCount;
+    for (unsigned int i = 0; i < count; i++)
     {
+      if (!table->sanitize (c))
+	return_trace (false);
       table = &StructAfter<KerxTable> (*table);
-      if (unlikely (!(table->sanitize (c))))
-        return_trace (false);
     }
 
-    // If version is less than 3, we are done here; otherwise better to check footer also
-    if (version < 3)
-      return_trace (true);
-
-    // 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);
   }
 
   protected:
-  HBUINT16		version;
-  HBUINT16		padding;
-  HBUINT32		nTables;
-/*KerxTable tablesZ[VAR]; XXX ArrayOf??? */
-/*SubtableGlyphCoverageArray coverage_array;*/
+  HBUINT16	version;	/* The version number of the extended kerning table
+				 * (currently 2, 3, or 4). */
+  HBUINT16	unused;		/* Set to 0. */
+  HBUINT32	tableCount;	/* The number of subtables included in the extended kerning
+				 * table. */
+  KerxTable	firstTable;	/* Subtables. */
+/*subtableGlyphCoverageArray*/	/* Only if version >= 3. We don't use. */
+
   public:
-  DEFINE_SIZE_STATIC (8);
+  DEFINE_SIZE_MIN (8);
 };
 
 } /* namespace AAT */
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index e9869036..63b937ba 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -940,7 +940,7 @@ struct Chain
 
 
 /*
- * The 'mort'/'morx' Tables
+ * The 'morx' Table
  */
 
 struct morx


More information about the HarfBuzz mailing list