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

Behdad Esfahbod behdad at kemper.freedesktop.org
Tue Oct 9 04:26:25 UTC 2018


 docs/harfbuzz-sections.txt                                 |   28 +-
 src/hb-aat-layout-common.hh                                |  111 ---------
 src/hb-aat-layout-kerx-table.hh                            |  128 ++++------
 src/hb-common.h                                            |    9 
 src/hb-deprecated.h                                        |  158 ++++++++++++-
 src/hb-font.cc                                             |    3 
 src/hb-font.h                                              |   51 ----
 src/hb-font.hh                                             |    2 
 src/hb-open-type.hh                                        |  116 +++++++++
 src/hb-ot-kern-table.hh                                    |  135 +++++++++--
 src/hb-ot-layout.cc                                        |   57 ++--
 src/hb-ot-layout.hh                                        |   13 +
 src/hb-ot-shape-fallback.cc                                |   81 +-----
 src/hb-ot-shape-fallback.hh                                |   12 
 src/hb-ot-shape-normalize.hh                               |    2 
 src/hb-ot-shape.cc                                         |   47 ++-
 src/hb-ot-shape.hh                                         |    5 
 src/hb-unicode.h                                           |   75 ------
 test/shaping/data/text-rendering-tests/DISABLED            |    3 
 test/shaping/data/text-rendering-tests/Makefile.sources    |    2 
 test/shaping/data/text-rendering-tests/tests/MORX-35.tests |    4 
 21 files changed, 566 insertions(+), 476 deletions(-)

New commits:
commit 977c8a8e5c811995f47b0eb721199d0dc3689e48
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 9 00:22:08 2018 -0400

    [kern] Minor

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 0af188e7..0ab9322f 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -68,11 +68,17 @@ struct hb_kern_machine_t
 
       unsigned int i = idx;
       unsigned int j = skippy_iter.idx;
+      hb_position_t kern1, kern2;
+
       hb_position_t kern = driver.get_kerning (info[i].codepoint,
 					       info[j].codepoint);
 
-      hb_position_t kern1 = kern >> 1;
-      hb_position_t kern2 = kern - kern1;
+
+      if (likely (!kern))
+        goto skip;
+
+      kern1 = kern >> 1;
+      kern2 = kern - kern1;
 
       if (horizontal)
       {
@@ -89,6 +95,7 @@ struct hb_kern_machine_t
 
       buffer->unsafe_to_break (i, j + 1);
 
+    skip:
       idx = skippy_iter.idx;
     }
   }
commit ed5cfa42c7fb8d5ff2d74bdb452a0590174f4e19
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 9 00:20:35 2018 -0400

    [kern] Minor

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index db6bba4a..6a793a3e 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -324,6 +324,7 @@ struct kerx
       if (reverse)
         c->buffer->reverse ();
 
+      /* XXX Reverse-kern is not working yet... */
       table->dispatch (c);
 
       if (reverse)
commit d219f899f4b2fb4b39ebc1dff9fb648fc5d6d112
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Tue Oct 9 00:01:09 2018 -0400

    Deprecate font kern API

diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 452e8900..2ee14a96 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -163,6 +163,14 @@ HB_UNICODE_MAX_DECOMPOSITION_LEN
 hb_unicode_decompose_compatibility_func_t
 hb_unicode_decompose_compatibility
 hb_unicode_funcs_set_decompose_compatibility_func
+hb_font_funcs_set_glyph_h_kerning_func
+hb_font_funcs_set_glyph_v_kerning_func
+hb_font_get_glyph_h_kerning
+hb_font_get_glyph_h_kerning_func_t
+hb_font_get_glyph_kerning_for_direction
+hb_font_get_glyph_kerning_func_t
+hb_font_get_glyph_v_kerning
+hb_font_get_glyph_v_kerning_func_t
 </SECTION>
 
 <SECTION>
@@ -223,12 +231,10 @@ hb_font_funcs_set_glyph_extents_func
 hb_font_funcs_set_glyph_from_name_func
 hb_font_funcs_set_glyph_h_advance_func
 hb_font_funcs_set_glyph_h_advances_func
-hb_font_funcs_set_glyph_h_kerning_func
 hb_font_funcs_set_glyph_h_origin_func
 hb_font_funcs_set_glyph_name_func
 hb_font_funcs_set_glyph_v_advance_func
 hb_font_funcs_set_glyph_v_advances_func
-hb_font_funcs_set_glyph_v_kerning_func
 hb_font_funcs_set_glyph_v_origin_func
 hb_font_funcs_set_nominal_glyph_func
 hb_font_funcs_set_user_data
@@ -253,12 +259,8 @@ hb_font_get_glyph_h_advance
 hb_font_get_glyph_h_advance_func_t
 hb_font_get_glyph_h_advances
 hb_font_get_glyph_h_advances_func_t
-hb_font_get_glyph_h_kerning
-hb_font_get_glyph_h_kerning_func_t
 hb_font_get_glyph_h_origin
 hb_font_get_glyph_h_origin_func_t
-hb_font_get_glyph_kerning_for_direction
-hb_font_get_glyph_kerning_func_t
 hb_font_get_glyph_name
 hb_font_get_glyph_name_func_t
 hb_font_get_glyph_origin_for_direction
@@ -267,8 +269,6 @@ hb_font_get_glyph_v_advance
 hb_font_get_glyph_v_advance_func_t
 hb_font_get_glyph_v_advances
 hb_font_get_glyph_v_advances_func_t
-hb_font_get_glyph_v_kerning
-hb_font_get_glyph_v_kerning_func_t
 hb_font_get_glyph_v_origin
 hb_font_get_glyph_v_origin_func_t
 hb_font_get_nominal_glyph
diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h
index 8a161798..2deb249a 100644
--- a/src/hb-deprecated.h
+++ b/src/hb-deprecated.h
@@ -158,6 +158,60 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
 				    hb_codepoint_t     *decomposed);
 
 
+typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
+							   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+							   void *user_data);
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
+
+/**
+ * hb_font_funcs_set_glyph_h_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ * 
+ *
+ * Since: 0.9.2
+ * Deprecated: REPLACEME
+ **/
+HB_EXTERN void
+hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_h_kerning_func_t func,
+					void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ * 
+ *
+ * Since: 0.9.2
+ * Deprecated: REPLACEME
+ **/
+HB_EXTERN void
+hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
+					hb_font_get_glyph_v_kerning_func_t func,
+					void *user_data, hb_destroy_func_t destroy);
+
+HB_EXTERN hb_position_t
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
+HB_EXTERN hb_position_t
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
+
+HB_EXTERN void
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+					 hb_direction_t direction,
+					 hb_position_t *x, hb_position_t *y);
+
+
 #endif
 
 HB_END_DECLS
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 5c259dca..f4f2df7c 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -887,6 +887,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
  * Return value: 
  *
  * Since: 0.9.2
+ * Deprecated: REPLACEME
  **/
 hb_position_t
 hb_font_get_glyph_h_kerning (hb_font_t *font,
@@ -906,6 +907,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
  * Return value: 
  *
  * Since: 0.9.2
+ * Deprecated: REPLACEME
  **/
 hb_position_t
 hb_font_get_glyph_v_kerning (hb_font_t *font,
@@ -1134,6 +1136,7 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
  * 
  *
  * Since: 0.9.2
+ * Deprecated: REPLACEME
  **/
 void
 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
diff --git a/src/hb-font.h b/src/hb-font.h
index 6cd48697..e13b0916 100644
--- a/src/hb-font.h
+++ b/src/hb-font.h
@@ -149,12 +149,6 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon
 typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
 typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
 
-typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
-							   hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-							   void *user_data);
-typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
-typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
-
 
 typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
 						       hb_codepoint_t glyph,
@@ -339,38 +333,6 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
 				       void *user_data, hb_destroy_func_t destroy);
 
 /**
- * hb_font_funcs_set_glyph_h_kerning_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
-					hb_font_get_glyph_h_kerning_func_t func,
-					void *user_data, hb_destroy_func_t destroy);
-
-/**
- * hb_font_funcs_set_glyph_v_kerning_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
-					hb_font_get_glyph_v_kerning_func_t func,
-					void *user_data, hb_destroy_func_t destroy);
-
-/**
  * hb_font_funcs_set_glyph_extents_func:
  * @ffuncs: font functions.
  * @func: (closure user_data) (destroy destroy) (scope notified):
@@ -483,13 +445,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
 			    hb_codepoint_t glyph,
 			    hb_position_t *x, hb_position_t *y);
 
-HB_EXTERN hb_position_t
-hb_font_get_glyph_h_kerning (hb_font_t *font,
-			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
-HB_EXTERN hb_position_t
-hb_font_get_glyph_v_kerning (hb_font_t *font,
-			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
-
 HB_EXTERN hb_bool_t
 hb_font_get_glyph_extents (hb_font_t *font,
 			   hb_codepoint_t glyph,
@@ -552,12 +507,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
 					     hb_direction_t direction,
 					     hb_position_t *x, hb_position_t *y);
 
-HB_EXTERN void
-hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
-					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-					 hb_direction_t direction,
-					 hb_position_t *x, hb_position_t *y);
-
 HB_EXTERN hb_bool_t
 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
 				      hb_codepoint_t glyph,
commit a51958819fcf51ade3f8eb38001e680a419ebbba
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 23:57:45 2018 -0400

    Apply TrueType/OpenType kern table when GPOS kern feature is not available
    
    Fixes https://github.com/harfbuzz/harfbuzz/issues/250

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 6033bcce..0af188e7 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -37,14 +37,11 @@ struct hb_kern_machine_t
 {
   hb_kern_machine_t (const Driver &driver_) : driver (driver_) {}
 
-  inline void kern (const hb_ot_shape_plan_t *plan,
-		    hb_font_t *font,
-		    hb_buffer_t  *buffer) const
+  inline void kern (hb_font_t *font,
+		    hb_buffer_t  *buffer,
+		    hb_mask_t kern_mask) const
   {
-    if (!plan->kerning_requested) return;
-
     OT::hb_ot_apply_context_t c (1, font, buffer);
-    hb_mask_t kern_mask = plan->kern_mask;
     c.set_lookup_mask (kern_mask);
     c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
     OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
@@ -411,6 +408,9 @@ struct kern
 {
   static const hb_tag_t tableTag = HB_OT_TAG_kern;
 
+  inline bool has_data (void) const
+  { return u.version32 != 0; }
+
   inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
   {
     switch (u.major) {
@@ -444,22 +444,25 @@ struct kern
       hb_blob_destroy (blob);
     }
 
+    inline bool has_data (void) const
+    { return table->has_data (); }
+
     inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
     { return table->get_h_kerning (left, right, table_length); }
 
     inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
     { return get_h_kerning (first, second); }
 
-    inline void apply (hb_ot_shape_plan_t *plan,
-		       hb_font_t *font,
-		       hb_buffer_t  *buffer) const
+    inline void apply (hb_font_t *font,
+		       hb_buffer_t  *buffer,
+		       hb_mask_t kern_mask) const
     {
       if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
         return;
 
       hb_kern_machine_t<accelerator_t> machine (*this);
 
-      machine.kern (plan, font, buffer);
+      machine.kern (font, buffer, kern_mask);
     }
 
     private:
@@ -471,6 +474,7 @@ struct kern
   protected:
   union {
   HBUINT16		major;
+  HBUINT32		version32;
   KernOT		ot;
   KernAAT		aat;
   } u;
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 51c11985..975b7f8d 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -45,17 +45,15 @@
 #include "hb-ot-color-cpal-table.hh"
 #include "hb-ot-color-sbix-table.hh"
 #include "hb-ot-color-svg-table.hh"
+#include "hb-ot-kern-table.hh"
 #include "hb-ot-name-table.hh"
 
 
-// static inline const OT::BASE&
-// _get_base (hb_face_t *face)
-// {
-//   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE);
-//   hb_ot_face_data_t *data = hb_ot_face_data (face);
-//   return *(data->base.get ());
-// }
-
+static const OT::kern::accelerator_t& _get_kern (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t);
+  return *hb_ot_face_data (face)->kern;
+}
 const OT::GDEF& _get_gdef (hb_face_t *face)
 {
   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF);
@@ -92,6 +90,25 @@ const OT::GPOS& _get_gpos_relaxed (hb_face_t *face)
 
 
 /*
+ * kern
+ */
+
+hb_bool_t
+hb_ot_layout_has_kerning (hb_face_t *face)
+{
+  return _get_kern (face).has_data ();
+}
+
+void
+hb_ot_layout_kern (hb_font_t *font,
+		   hb_buffer_t  *buffer,
+		   hb_mask_t kern_mask)
+{
+  _get_kern (font->face).apply (font, buffer, kern_mask);
+}
+
+
+/*
  * GDEF
  */
 
@@ -1306,27 +1323,3 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
 {
   apply_string<GSUBProxy> (c, lookup, accel);
 }
-
-
-
-
-/*
- * OT::BASE
- */
-
-// /**
-//  * hb_ot_base_has_data:
-//  * @face: #hb_face_t to test
-//  *
-//  * This function allows to verify the presence of an OpenType BASE table on the
-//  * face.
-//  *
-//  * Return value: true if face has a BASE table, false otherwise
-//  *
-//  * Since: XXX
-//  **/
-// hb_bool_t
-// hb_ot_base_has_data (hb_face_t *face)
-// {
-//   return _get_base (face).has_data ();
-// }
diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh
index ac55459b..f5ffe311 100644
--- a/src/hb-ot-layout.hh
+++ b/src/hb-ot-layout.hh
@@ -49,6 +49,19 @@ HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face);
 HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face);
 
 
+/*
+ * kern
+ */
+
+HB_INTERNAL hb_bool_t
+hb_ot_layout_has_kerning (hb_face_t *face);
+
+HB_INTERNAL void
+hb_ot_layout_kern (hb_font_t *font,
+		   hb_buffer_t  *buffer,
+		   hb_mask_t kern_mask);
+
+
 /* Private API corresponding to hb-ot-layout.h: */
 
 HB_INTERNAL hb_bool_t
diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index e1dd603a..bf1fc8fb 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -439,7 +439,7 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
 void
 _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
 			    hb_font_t *font,
-			    hb_buffer_t  *buffer)
+			    hb_buffer_t *buffer)
 {
   struct driver_t
   {
@@ -462,7 +462,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
 
   hb_kern_machine_t<driver_t> machine (driver);
 
-  machine.kern (plan, font, buffer);
+  machine.kern (font, buffer, plan->kern_mask);
 }
 
 
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index b8136b4b..a9c0844e 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -69,8 +69,8 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
   bool disable_gpos = plan.shaper->gpos_tag &&
 		      plan.shaper->gpos_tag != plan.map.chosen_script[1];
   plan.apply_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
-
-  plan.fallback_kerning = !plan.apply_gpos;
+  plan.apply_kern = !plan.apply_gpos && hb_ot_layout_has_kerning (face);
+  plan.fallback_kerning = !plan.apply_gpos && !plan.apply_kern;
   plan.fallback_mark_positioning = !plan.apply_gpos;
   plan.fallback_glyph_classes = !hb_ot_layout_has_glyph_classes (face);
 }
@@ -835,7 +835,11 @@ hb_ot_position (const hb_ot_shape_context_t *c)
 
   /* Visual fallback goes here. */
 
-  if (c->plan->fallback_kerning)
+  if (!c->plan->kerning_requested)
+    ;
+  else if (c->plan->apply_kern)
+    hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask);
+  else if (c->plan->fallback_kerning)
     _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
 
   _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh
index 7a1e3854..43852d8f 100644
--- a/src/hb-ot-shape.hh
+++ b/src/hb-ot-shape.hh
@@ -51,6 +51,7 @@ struct hb_ot_shape_plan_t
   bool fallback_mark_positioning : 1;
 
   bool apply_morx : 1;
+  bool apply_kern : 1;
   bool apply_gpos : 1;
 
 
commit 09ad2613c8d8a60dac69a878c2d568adfea054c8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 23:30:24 2018 -0400

    Separate fallback kern vs mark positioning

diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index fb7db1d5..e1dd603a 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -162,9 +162,9 @@ recategorize_combining_class (hb_codepoint_t u,
 }
 
 void
-_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
-						   hb_font_t *font HB_UNUSED,
-						   hb_buffer_t  *buffer)
+_hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
+						        hb_font_t *font HB_UNUSED,
+						        hb_buffer_t  *buffer)
 {
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
@@ -417,9 +417,9 @@ position_cluster (const hb_ot_shape_plan_t *plan,
 }
 
 void
-_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
-				hb_font_t *font,
-				hb_buffer_t  *buffer)
+_hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
+				     hb_font_t *font,
+				     hb_buffer_t  *buffer)
 {
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
diff --git a/src/hb-ot-shape-fallback.hh b/src/hb-ot-shape-fallback.hh
index 730e7f28..12f18ed1 100644
--- a/src/hb-ot-shape-fallback.hh
+++ b/src/hb-ot-shape-fallback.hh
@@ -32,13 +32,13 @@
 #include "hb-ot-shape.hh"
 
 
-HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
-						 hb_font_t *font,
-						 hb_buffer_t  *buffer);
+HB_INTERNAL void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
+						      hb_font_t *font,
+						      hb_buffer_t  *buffer);
 
-HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
-								    hb_font_t *font,
-								    hb_buffer_t  *buffer);
+HB_INTERNAL void _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
+									 hb_font_t *font,
+									 hb_buffer_t  *buffer);
 
 
 HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index d3cf7e12..b8136b4b 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -70,7 +70,8 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
 		      plan.shaper->gpos_tag != plan.map.chosen_script[1];
   plan.apply_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
 
-  plan.fallback_positioning = !plan.apply_gpos;
+  plan.fallback_kerning = !plan.apply_gpos;
+  plan.fallback_mark_positioning = !plan.apply_gpos;
   plan.fallback_glyph_classes = !hb_ot_layout_has_glyph_classes (face);
 }
 
@@ -648,8 +649,8 @@ hb_ot_substitute_default (const hb_ot_shape_context_t *c)
   hb_ot_shape_setup_masks (c);
 
   /* This is unfortunate to go here, but necessary... */
-  if (c->plan->fallback_positioning)
-    _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
+  if (c->plan->fallback_mark_positioning)
+    _hb_ot_shape_fallback_mark_position_recategorize_marks (c->plan, c->font, buffer);
 
   hb_ot_map_glyphs_fast (buffer);
 
@@ -762,7 +763,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
    * If fallback positinoing happens or GPOS is present, we don't
    * care.
    */
-  bool adjust_offsets_when_zeroing = c->plan->fallback_positioning &&
+  bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning &&
 				     !c->plan->shaper->fallback_position &&
 				     HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
 
@@ -826,15 +827,15 @@ hb_ot_position (const hb_ot_shape_context_t *c)
 
   hb_ot_position_complex (c);
 
-  if (c->plan->fallback_positioning && c->plan->shaper->fallback_position)
-    _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
+  if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
+    _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
 
   if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
     hb_buffer_reverse (c->buffer);
 
   /* Visual fallback goes here. */
 
-  if (c->plan->fallback_positioning)
+  if (c->plan->fallback_kerning)
     _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
 
   _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh
index 23c385aa..7a1e3854 100644
--- a/src/hb-ot-shape.hh
+++ b/src/hb-ot-shape.hh
@@ -46,11 +46,11 @@ struct hb_ot_shape_plan_t
   bool has_frac : 1;
   bool kerning_requested : 1;
   bool has_gpos_mark : 1;
-  bool fallback_positioning : 1;
   bool fallback_glyph_classes : 1;
+  bool fallback_kerning : 1;
+  bool fallback_mark_positioning : 1;
 
   bool apply_morx : 1;
-
   bool apply_gpos : 1;
 
 
commit 3c23ff9b7c4241ec23054a95f1fdfbdef2c51f40
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 23:26:26 2018 -0400

    [kern] Add kerning driver to TT kern table

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index f7c2ed38..6033bcce 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -35,7 +35,7 @@
 template <typename Driver>
 struct hb_kern_machine_t
 {
-  hb_kern_machine_t (Driver &driver_) : driver (driver_) {}
+  hb_kern_machine_t (const Driver &driver_) : driver (driver_) {}
 
   inline void kern (const hb_ot_shape_plan_t *plan,
 		    hb_font_t *font,
@@ -96,7 +96,7 @@ struct hb_kern_machine_t
     }
   }
 
-  Driver &driver;
+  const Driver &driver;
 };
 
 
@@ -447,6 +447,21 @@ struct kern
     inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
     { return table->get_h_kerning (left, right, table_length); }
 
+    inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
+    { return get_h_kerning (first, second); }
+
+    inline void apply (hb_ot_shape_plan_t *plan,
+		       hb_font_t *font,
+		       hb_buffer_t  *buffer) const
+    {
+      if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+        return;
+
+      hb_kern_machine_t<accelerator_t> machine (*this);
+
+      machine.kern (plan, font, buffer);
+    }
+
     private:
     hb_blob_t *blob;
     const kern *table;
diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index 920ef22c..fb7db1d5 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -447,7 +447,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
 	      hb_buffer_t *buffer) :
       font (font_), direction (buffer->props.direction) {}
 
-    hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second)
+    hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
     {
       hb_position_t kern = 0;
       font->get_glyph_kerning_for_direction (first, second,
commit 683c3a95330928129cfbb1488650f708414d68ba
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 23:09:48 2018 -0400

    [kern] Abstract away kerning machine

diff --git a/src/hb-font.hh b/src/hb-font.hh
index 4c8d0aee..8b19dd71 100644
--- a/src/hb-font.hh
+++ b/src/hb-font.hh
@@ -502,8 +502,8 @@ struct hb_font_t
 					       hb_position_t *x, hb_position_t *y)
   {
     if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
-      *x = get_glyph_h_kerning (first_glyph, second_glyph);
       *y = 0;
+      *x = get_glyph_h_kerning (first_glyph, second_glyph);
     } else {
       *x = 0;
       *y = get_glyph_v_kerning (first_glyph, second_glyph);
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index e33b1739..f7c2ed38 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -28,6 +28,77 @@
 #define HB_OT_KERN_TABLE_HH
 
 #include "hb-open-type.hh"
+#include "hb-ot-shape.hh"
+#include "hb-ot-layout-gsubgpos.hh"
+
+
+template <typename Driver>
+struct hb_kern_machine_t
+{
+  hb_kern_machine_t (Driver &driver_) : driver (driver_) {}
+
+  inline void kern (const hb_ot_shape_plan_t *plan,
+		    hb_font_t *font,
+		    hb_buffer_t  *buffer) const
+  {
+    if (!plan->kerning_requested) return;
+
+    OT::hb_ot_apply_context_t c (1, font, buffer);
+    hb_mask_t kern_mask = plan->kern_mask;
+    c.set_lookup_mask (kern_mask);
+    c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
+    OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
+    skippy_iter.init (&c);
+
+    bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction);
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    hb_glyph_position_t *pos = buffer->pos;
+    for (unsigned int idx = 0; idx < count;)
+    {
+      if (!(info[idx].mask & kern_mask))
+      {
+	idx++;
+	continue;
+      }
+
+      skippy_iter.reset (idx, 1);
+      if (!skippy_iter.next ())
+      {
+	idx++;
+	continue;
+      }
+
+      unsigned int i = idx;
+      unsigned int j = skippy_iter.idx;
+      hb_position_t kern = driver.get_kerning (info[i].codepoint,
+					       info[j].codepoint);
+
+      hb_position_t kern1 = kern >> 1;
+      hb_position_t kern2 = kern - kern1;
+
+      if (horizontal)
+      {
+	pos[i].x_advance += kern1;
+	pos[j].x_advance += kern2;
+	pos[j].x_offset += kern2;
+      }
+      else
+      {
+	pos[i].y_advance += kern1;
+	pos[j].y_advance += kern2;
+	pos[j].y_offset += kern2;
+      }
+
+      buffer->unsafe_to_break (i, j + 1);
+
+      idx = skippy_iter.idx;
+    }
+  }
+
+  Driver &driver;
+};
+
 
 /*
  * kern -- Kerning
diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index 6673abd1..920ef22c 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -25,7 +25,7 @@
  */
 
 #include "hb-ot-shape-fallback.hh"
-#include "hb-ot-layout-gsubgpos.hh"
+#include "hb-ot-kern-table.hh"
 
 static unsigned int
 recategorize_combining_class (hb_codepoint_t u,
@@ -435,67 +435,34 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
 }
 
 
-/* Performs old-style TrueType kerning. */
+/* Performs font-assisted kerning. */
 void
 _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
 			    hb_font_t *font,
 			    hb_buffer_t  *buffer)
 {
-  if (!plan->kerning_requested) return;
-
-  OT::hb_ot_apply_context_t c (1, font, buffer);
-  hb_mask_t kern_mask = plan->kern_mask;
-  c.set_lookup_mask (kern_mask);
-  c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
-  OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
-  skippy_iter.init (&c);
-
-  unsigned int count = buffer->len;
-  hb_glyph_info_t *info = buffer->info;
-  hb_glyph_position_t *pos = buffer->pos;
-  for (unsigned int idx = 0; idx < count;)
+  struct driver_t
   {
-    if (!(info[idx].mask & kern_mask))
-    {
-      idx++;
-      continue;
-    }
+    driver_t (hb_font_t   *font_,
+	      hb_buffer_t *buffer) :
+      font (font_), direction (buffer->props.direction) {}
 
-    skippy_iter.reset (idx, 1);
-    if (!skippy_iter.next ())
+    hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second)
     {
-      idx++;
-      continue;
+      hb_position_t kern = 0;
+      font->get_glyph_kerning_for_direction (first, second,
+					     direction,
+					     &kern, &kern);
+      return kern;
     }
 
-    hb_position_t x_kern, y_kern;
-    font->get_glyph_kerning_for_direction (info[idx].codepoint,
-					   info[skippy_iter.idx].codepoint,
-					   buffer->props.direction,
-					   &x_kern, &y_kern);
+    hb_font_t *font;
+    hb_direction_t direction;
+  } driver (font, buffer);
 
-    if (x_kern)
-    {
-      hb_position_t kern1 = x_kern >> 1;
-      hb_position_t kern2 = x_kern - kern1;
-      pos[idx].x_advance += kern1;
-      pos[skippy_iter.idx].x_advance += kern2;
-      pos[skippy_iter.idx].x_offset += kern2;
-      buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
-    }
-
-    if (y_kern)
-    {
-      hb_position_t kern1 = y_kern >> 1;
-      hb_position_t kern2 = y_kern - kern1;
-      pos[idx].y_advance += kern1;
-      pos[skippy_iter.idx].y_advance += kern2;
-      pos[skippy_iter.idx].y_offset += kern2;
-      buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
-    }
+  hb_kern_machine_t<driver_t> machine (driver);
 
-    idx = skippy_iter.idx;
-  }
+  machine.kern (plan, font, buffer);
 }
 
 
commit fb4f43838154a77912a9fc3437110c81e9d34aac
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 22:44:16 2018 -0400

    Add HB_DEPRECATED
    
    Fixes https://github.com/harfbuzz/harfbuzz/issues/1232

diff --git a/src/hb-common.h b/src/hb-common.h
index 6101d72f..4f91a176 100644
--- a/src/hb-common.h
+++ b/src/hb-common.h
@@ -63,6 +63,15 @@ typedef unsigned __int64 uint64_t;
 #  include <stdint.h>
 #endif
 
+#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+#define HB_DEPRECATED __attribute__((__deprecated__))
+#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+#define HB_DEPRECATED __declspec(deprecated)
+#else
+#define HB_DEPRECATED
+#endif
+
+
 HB_BEGIN_DECLS
 
 
diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h
index 826cd978..8a161798 100644
--- a/src/hb-deprecated.h
+++ b/src/hb-deprecated.h
@@ -50,12 +50,12 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
 					       hb_codepoint_t *glyph,
 					       void *user_data);
 
-HB_EXTERN void
+HB_EXTERN HB_DEPRECATED void
 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
 			      hb_font_get_glyph_func_t func,
 			      void *user_data, hb_destroy_func_t destroy);
 
-HB_EXTERN void
+HB_EXTERN HB_DEPRECATED void
 hb_set_invert (hb_set_t *set);
 
 /**
@@ -79,7 +79,7 @@ typedef unsigned int			(*hb_unicode_eastasian_width_func_t)	(hb_unicode_funcs_t
  * Since: 0.9.2
  * Deprecated: REPLACEME
  **/
-HB_EXTERN void
+HB_EXTERN HB_DEPRECATED void
 hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
 					   hb_unicode_eastasian_width_func_t func,
 					   void *user_data, hb_destroy_func_t destroy);
@@ -90,7 +90,7 @@ hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
  * Since: 0.9.2
  * Deprecated: REPLACEME
  **/
-HB_EXTERN unsigned int
+HB_EXTERN HB_DEPRECATED unsigned int
 hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
 			    hb_codepoint_t unicode);
 
@@ -141,7 +141,7 @@ typedef unsigned int			(*hb_unicode_decompose_compatibility_func_t)	(hb_unicode_
  * Since: 0.9.2
  * Deprecated: REPLACEME
  **/
-HB_EXTERN void
+HB_EXTERN HB_DEPRECATED void
 hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
 						   hb_unicode_decompose_compatibility_func_t func,
 						   void *user_data, hb_destroy_func_t destroy);
@@ -152,7 +152,7 @@ hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
  *
  * Deprecated: REPLACEME
  **/
-HB_EXTERN unsigned int
+HB_EXTERN HB_DEPRECATED unsigned int
 hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
 				    hb_codepoint_t      u,
 				    hb_codepoint_t     *decomposed);
commit 80e3102b8a216f9a751d073f9a2f7900ca758086
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 22:41:08 2018 -0400

    [kerx] Process coverage flags

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 9693af32..db6bba4a 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -212,6 +212,8 @@ struct KerxSubTableFormat6
 
 struct KerxTable
 {
+  friend kerx;
+
   inline unsigned int get_size (void) const { return length; }
   inline unsigned int get_type (void) const { return coverage & SubtableType; }
 
@@ -304,7 +306,32 @@ struct kerx
     unsigned int count = tableCount;
     for (unsigned int i = 0; i < count; i++)
     {
+      bool reverse;
+
+      if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
+	  bool (table->coverage & KerxTable::Vertical))
+        goto skip;
+
+      if (table->coverage & KerxTable::CrossStream)
+        goto skip; /* We do NOT handle cross-stream kerning. */
+
+      reverse = bool (table->coverage & KerxTable::ProcessDirection) !=
+		HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
+
+      if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
+        goto skip;
+
+      if (reverse)
+        c->buffer->reverse ();
+
       table->dispatch (c);
+
+      if (reverse)
+        c->buffer->reverse ();
+
+      (void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index);
+
+    skip:
       table = &StructAfter<KerxTable> (*table);
     }
   }
commit 26d7305da7a7e2cf765b068f565836442872ffe7
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 22:31:35 2018 -0400

    Deprecate decompose_compatibility stuff

diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 884f3d07..452e8900 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -159,6 +159,10 @@ hb_set_invert
 hb_unicode_eastasian_width_func_t
 hb_unicode_eastasian_width
 hb_unicode_funcs_set_eastasian_width_func
+HB_UNICODE_MAX_DECOMPOSITION_LEN
+hb_unicode_decompose_compatibility_func_t
+hb_unicode_decompose_compatibility
+hb_unicode_funcs_set_decompose_compatibility_func
 </SECTION>
 
 <SECTION>
@@ -616,14 +620,12 @@ hb_shape_plan_t
 <SECTION>
 <FILE>hb-unicode</FILE>
 HB_UNICODE_MAX
-HB_UNICODE_MAX_DECOMPOSITION_LEN
 hb_unicode_combining_class
 hb_unicode_combining_class_func_t
 hb_unicode_combining_class_t
 hb_unicode_compose
 hb_unicode_compose_func_t
 hb_unicode_decompose
-hb_unicode_decompose_compatibility
 hb_unicode_decompose_func_t
 hb_unicode_funcs_create
 hb_unicode_funcs_destroy
@@ -636,7 +638,6 @@ hb_unicode_funcs_make_immutable
 hb_unicode_funcs_reference
 hb_unicode_funcs_set_combining_class_func
 hb_unicode_funcs_set_compose_func
-hb_unicode_funcs_set_decompose_compatibility_func
 hb_unicode_funcs_set_decompose_func
 hb_unicode_funcs_set_general_category_func
 hb_unicode_funcs_set_mirroring_func
diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h
index 519a57e6..826cd978 100644
--- a/src/hb-deprecated.h
+++ b/src/hb-deprecated.h
@@ -95,6 +95,69 @@ hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
 			    hb_codepoint_t unicode);
 
 
+/**
+ * hb_unicode_decompose_compatibility_func_t:
+ * @ufuncs: a Unicode function structure
+ * @u: codepoint to decompose
+ * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
+ * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
+ *
+ * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
+ * The complete length of the decomposition will be returned.
+ *
+ * If @u has no compatibility decomposition, zero should be returned.
+ *
+ * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
+ * compatibility decomposition plus an terminating value of 0.  Consequently, @decompose must be allocated by the caller to be at least this length.  Implementations
+ * of this function type must ensure that they do not write past the provided array.
+ *
+ * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
+ *
+ * Deprecated: REPLACEME
+ */
+typedef unsigned int			(*hb_unicode_decompose_compatibility_func_t)	(hb_unicode_funcs_t *ufuncs,
+											 hb_codepoint_t      u,
+											 hb_codepoint_t     *decomposed,
+											 void               *user_data);
+
+/**
+ * HB_UNICODE_MAX_DECOMPOSITION_LEN:
+ *
+ * See Unicode 6.1 for details on the maximum decomposition length.
+ *
+ * Deprecated: REPLACEME
+ */
+#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
+
+/**
+ * hb_unicode_funcs_set_decompose_compatibility_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ * 
+ *
+ * Since: 0.9.2
+ * Deprecated: REPLACEME
+ **/
+HB_EXTERN void
+hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
+						   hb_unicode_decompose_compatibility_func_t func,
+						   void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_decompose_compatibility:
+ * 
+ *
+ * Deprecated: REPLACEME
+ **/
+HB_EXTERN unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+				    hb_codepoint_t      u,
+				    hb_codepoint_t     *decomposed);
+
+
 #endif
 
 HB_END_DECLS
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index 604c207a..62b58803 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -251,32 +251,6 @@ typedef hb_bool_t			(*hb_unicode_decompose_func_t)		(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t     *b,
 										 void               *user_data);
 
-/**
- * hb_unicode_decompose_compatibility_func_t:
- * @ufuncs: a Unicode function structure
- * @u: codepoint to decompose
- * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
- * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
- *
- * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
- * The complete length of the decomposition will be returned.
- *
- * If @u has no compatibility decomposition, zero should be returned.
- *
- * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
- * compatibility decomposition plus an terminating value of 0.  Consequently, @decompose must be allocated by the caller to be at least this length.  Implementations
- * of this function type must ensure that they do not write past the provided array.
- *
- * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
- */
-typedef unsigned int			(*hb_unicode_decompose_compatibility_func_t)	(hb_unicode_funcs_t *ufuncs,
-											 hb_codepoint_t      u,
-											 hb_codepoint_t     *decomposed,
-											 void               *user_data);
-
-/* See Unicode 6.1 for details on the maximum decomposition length. */
-#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
-
 /* setters */
 
 /**
@@ -375,22 +349,6 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
 				     hb_unicode_decompose_func_t func,
 				     void *user_data, hb_destroy_func_t destroy);
 
-/**
- * hb_unicode_funcs_set_decompose_compatibility_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- **/
-HB_EXTERN void
-hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
-						   hb_unicode_decompose_compatibility_func_t func,
-						   void *user_data, hb_destroy_func_t destroy);
-
 /* accessors */
 
 /**
@@ -441,11 +399,6 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
 		      hb_codepoint_t     *a,
 		      hb_codepoint_t     *b);
 
-HB_EXTERN unsigned int
-hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
-				    hb_codepoint_t      u,
-				    hb_codepoint_t     *decomposed);
-
 HB_END_DECLS
 
 #endif /* HB_UNICODE_H */
commit 42b51eee54f143854b7c6c3be5d84bfbbd895100
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 22:26:39 2018 -0400

    Deprecate eastasian_width stuff

diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 455e4f50..884f3d07 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -156,6 +156,9 @@ HB_SCRIPT_CANADIAN_ABORIGINAL
 hb_font_funcs_set_glyph_func
 hb_font_get_glyph_func_t
 hb_set_invert
+hb_unicode_eastasian_width_func_t
+hb_unicode_eastasian_width
+hb_unicode_funcs_set_eastasian_width_func
 </SECTION>
 
 <SECTION>
@@ -622,7 +625,6 @@ hb_unicode_compose_func_t
 hb_unicode_decompose
 hb_unicode_decompose_compatibility
 hb_unicode_decompose_func_t
-hb_unicode_eastasian_width
 hb_unicode_funcs_create
 hb_unicode_funcs_destroy
 hb_unicode_funcs_get_default
@@ -636,7 +638,6 @@ hb_unicode_funcs_set_combining_class_func
 hb_unicode_funcs_set_compose_func
 hb_unicode_funcs_set_decompose_compatibility_func
 hb_unicode_funcs_set_decompose_func
-hb_unicode_funcs_set_eastasian_width_func
 hb_unicode_funcs_set_general_category_func
 hb_unicode_funcs_set_mirroring_func
 hb_unicode_funcs_set_script_func
diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h
index eac7efb4..519a57e6 100644
--- a/src/hb-deprecated.h
+++ b/src/hb-deprecated.h
@@ -58,6 +58,43 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
 HB_EXTERN void
 hb_set_invert (hb_set_t *set);
 
+/**
+ * hb_unicode_eastasian_width_func_t:
+ *
+ * Deprecated: REPLACEME
+ */
+typedef unsigned int			(*hb_unicode_eastasian_width_func_t)	(hb_unicode_funcs_t *ufuncs,
+										 hb_codepoint_t      unicode,
+										 void               *user_data);
+
+/**
+ * hb_unicode_funcs_set_eastasian_width_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ * 
+ *
+ * Since: 0.9.2
+ * Deprecated: REPLACEME
+ **/
+HB_EXTERN void
+hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
+					   hb_unicode_eastasian_width_func_t func,
+					   void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_eastasian_width:
+ *
+ * Since: 0.9.2
+ * Deprecated: REPLACEME
+ **/
+HB_EXTERN unsigned int
+hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
+			    hb_codepoint_t unicode);
+
+
 #endif
 
 HB_END_DECLS
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index c8d87e4d..604c207a 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -230,9 +230,6 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
 typedef hb_unicode_combining_class_t	(*hb_unicode_combining_class_func_t)	(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
-typedef unsigned int			(*hb_unicode_eastasian_width_func_t)	(hb_unicode_funcs_t *ufuncs,
-										 hb_codepoint_t      unicode,
-										 void               *user_data);
 typedef hb_unicode_general_category_t	(*hb_unicode_general_category_func_t)	(hb_unicode_funcs_t *ufuncs,
 										 hb_codepoint_t      unicode,
 										 void               *user_data);
@@ -299,22 +296,6 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
 					   void *user_data, hb_destroy_func_t destroy);
 
 /**
- * hb_unicode_funcs_set_eastasian_width_func:
- * @ufuncs: a Unicode function structure
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- **/
-HB_EXTERN void
-hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
-					   hb_unicode_eastasian_width_func_t func,
-					   void *user_data, hb_destroy_func_t destroy);
-
-/**
  * hb_unicode_funcs_set_general_category_func:
  * @ufuncs: a Unicode function structure
  * @func: (closure user_data) (destroy destroy) (scope notified):
@@ -422,15 +403,6 @@ hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
 			    hb_codepoint_t unicode);
 
 /**
- * hb_unicode_eastasian_width:
- *
- * Since: 0.9.2
- **/
-HB_EXTERN unsigned int
-hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
-			    hb_codepoint_t unicode);
-
-/**
  * hb_unicode_general_category:
  *
  * Since: 0.9.2
commit 286a45641fc6732bb7cab02f06c90396834541b1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 16:41:08 2018 -0400

    Minor

diff --git a/src/hb-ot-shape-normalize.hh b/src/hb-ot-shape-normalize.hh
index 80755f77..04f1a800 100644
--- a/src/hb-ot-shape-normalize.hh
+++ b/src/hb-ot-shape-normalize.hh
@@ -41,7 +41,7 @@ enum hb_ot_shape_normalization_mode_t {
   HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* Never composes base-to-base */
   HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */
 
-  HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* Choose decomposed if GPOS mark feature available, compose otherwise. */
+  HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* See hb-ot-shape-normalize.cc for logic. */
   HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_AUTO
 };
 
commit c0d3bf1bafe7b6d2e8f2798c1f55aaec71350d90
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 16:32:44 2018 -0400

    Minor

diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 4e5bd4e9..d3cf7e12 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -404,7 +404,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
 /* Substitute */
 
 static inline void
-hb_ot_mirror_chars (hb_ot_shape_context_t *c)
+hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
 {
   if (HB_DIRECTION_IS_FORWARD (c->target_direction))
     return;
@@ -425,7 +425,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
+hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
 {
   if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
       !c->plan->has_frac)
@@ -475,7 +475,7 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
+hb_ot_shape_initialize_masks (const hb_ot_shape_context_t *c)
 {
   hb_ot_map_t *map = &c->plan->map;
   hb_buffer_t *buffer = c->buffer;
@@ -485,7 +485,7 @@ hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
+hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c)
 {
   hb_ot_map_t *map = &c->plan->map;
   hb_buffer_t *buffer = c->buffer;
@@ -507,7 +507,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
 }
 
 static void
-hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
+hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c)
 {
   hb_buffer_t *buffer = c->buffer;
 
@@ -526,7 +526,7 @@ hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
 }
 
 static void
-hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
+hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c)
 {
   hb_buffer_t *buffer = c->buffer;
 
@@ -609,7 +609,7 @@ hb_ot_map_glyphs_fast (hb_buffer_t  *buffer)
 }
 
 static inline void
-hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
+hb_synthesize_glyph_classes (const hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
   hb_glyph_info_t *info = c->buffer->info;
@@ -635,7 +635,7 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_substitute_default (hb_ot_shape_context_t *c)
+hb_ot_substitute_default (const hb_ot_shape_context_t *c)
 {
   hb_buffer_t *buffer = c->buffer;
 
@@ -657,7 +657,7 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_substitute_complex (hb_ot_shape_context_t *c)
+hb_ot_substitute_complex (const hb_ot_shape_context_t *c)
 {
   hb_buffer_t *buffer = c->buffer;
 
@@ -673,7 +673,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_substitute (hb_ot_shape_context_t *c)
+hb_ot_substitute (const hb_ot_shape_context_t *c)
 {
   hb_ot_substitute_default (c);
 
@@ -713,7 +713,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
 }
 
 static inline void
-hb_ot_position_default (hb_ot_shape_context_t *c)
+hb_ot_position_default (const hb_ot_shape_context_t *c)
 {
   hb_direction_t direction = c->buffer->props.direction;
   unsigned int count = c->buffer->len;
@@ -747,7 +747,7 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_position_complex (hb_ot_shape_context_t *c)
+hb_ot_position_complex (const hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
   hb_glyph_info_t *info = c->buffer->info;
@@ -818,7 +818,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
 }
 
 static inline void
-hb_ot_position (hb_ot_shape_context_t *c)
+hb_ot_position (const hb_ot_shape_context_t *c)
 {
   c->buffer->clear_positions ();
 
commit 9c1bb81f5c5ca64ad1c665edd16947e4bc6f6c46
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Mon Oct 8 16:10:54 2018 -0400

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

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 \
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 616b2f9b..a0331852 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|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]
+../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A|B at 639,0|C at 1265,0|E at 1861,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]
commit 1a5a3325a26f4989ab8c4bb91515d4898ffa4631
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 23:08:39 2018 -0400

    [kerx] Minor

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 9df3242a..9693af32 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -104,9 +104,9 @@ struct KerxSubTableFormat1
 
 struct KerxSubTableFormat2
 {
-  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
+			  const char *end, unsigned int num_glyphs) const
   {
-    unsigned int num_glyphs = 0; /* XXX */
     unsigned int l = *(this+leftClassTable).get_value (left, num_glyphs);
     unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs);
     unsigned int offset = l + r;
commit d62b4011cc600ade2b130f81a077dd08d4e4464f
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 22:58:06 2018 -0400

    [kern] Shout less

diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index d26f402c..e33b1739 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -190,10 +190,10 @@ struct KernSubTableWrapper
   inline const T* thiz (void) const { return static_cast<const T *> (this); }
 
   inline bool is_horizontal (void) const
-  { return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; }
+  { return (thiz()->coverage & T::CheckFlags) == T::CheckHorizontal; }
 
   inline bool is_override (void) const
-  { return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); }
+  { return bool (thiz()->coverage & T::Override); }
 
   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
   { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
@@ -264,16 +264,17 @@ struct KernOT : KernTable<KernOT>
   {
     friend struct KernSubTableWrapper<SubTableWrapper>;
 
-    enum coverage_flags_t {
-      COVERAGE_DIRECTION_FLAG	= 0x01u,
-      COVERAGE_MINIMUM_FLAG	= 0x02u,
-      COVERAGE_CROSSSTREAM_FLAG	= 0x04u,
-      COVERAGE_OVERRIDE_FLAG	= 0x08u,
+    enum Coverage
+    {
+      Direction		= 0x01u,
+      Minimum		= 0x02u,
+      CrossStream	= 0x04u,
+      Override		= 0x08u,
 
-      COVERAGE_VARIATION_FLAG	= 0x00u, /* Not supported. */
+      Variation		= 0x00u, /* Not supported. */
 
-      COVERAGE_CHECK_FLAGS	= 0x07u,
-      COVERAGE_CHECK_HORIZONTAL	= 0x01u
+      CheckFlags	= 0x07u,
+      CheckHorizontal	= 0x01u
     };
 
     protected:
@@ -304,15 +305,16 @@ struct KernAAT : KernTable<KernAAT>
   {
     friend struct KernSubTableWrapper<SubTableWrapper>;
 
-    enum coverage_flags_t {
-      COVERAGE_DIRECTION_FLAG	= 0x80u,
-      COVERAGE_CROSSSTREAM_FLAG	= 0x40u,
-      COVERAGE_VARIATION_FLAG	= 0x20u,
+    enum Coverage
+    {
+      Direction		= 0x80u,
+      CrossStream	= 0x40u,
+      Variation		= 0x20u,
 
-      COVERAGE_OVERRIDE_FLAG	= 0x00u, /* Not supported. */
+      Override		= 0x00u, /* Not supported. */
 
-      COVERAGE_CHECK_FLAGS	= 0xE0u,
-      COVERAGE_CHECK_HORIZONTAL	= 0x00u
+      CheckFlags	= 0xE0u,
+      CheckHorizontal	= 0x00u
     };
 
     protected:
commit c6bb3a588f493630b40d8823532b482f407bacbf
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 22:52:53 2018 -0400

    [kerx] Clean up Format2

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index c2eed5d4..9df3242a 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -102,31 +102,13 @@ struct KerxSubTableFormat1
   DEFINE_SIZE_STATIC (20);
 };
 
-// TODO(ebraminio): Maybe this can be replaced with Lookup<HBUINT16>?
-struct KerxClassTable
-{
-  inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely (firstGlyph.sanitize (c) &&
-			  classes.sanitize (c)));
-  }
-
-  protected:
-  HBUINT16		firstGlyph;	/* First glyph in class range. */
-  ArrayOf<HBUINT16>	classes;	/* Glyph classes. */
-  public:
-  DEFINE_SIZE_ARRAY (4, classes);
-};
-
 struct KerxSubTableFormat2
 {
   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
   {
-    unsigned int l = (this+leftClassTable).get_class (left);
-    unsigned int r = (this+leftClassTable).get_class (left);
+    unsigned int num_glyphs = 0; /* XXX */
+    unsigned int l = *(this+leftClassTable).get_value (left, num_glyphs);
+    unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs);
     unsigned int offset = l + r;
     const FWORD *arr = &(this+array);
     if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
@@ -158,10 +140,10 @@ struct KerxSubTableFormat2
 
   protected:
   HBUINT32	rowWidth;	/* The width, in bytes, of a row in the table. */
-  LOffsetTo<KerxClassTable>
+  LOffsetTo<Lookup<HBUINT16> >
 		leftClassTable;	/* Offset from beginning of this subtable to
 				 * left-hand class table. */
-  LOffsetTo<KerxClassTable>
+  LOffsetTo<Lookup<HBUINT16> >
 		rightClassTable;/* Offset from beginning of this subtable to
 				 * right-hand class table. */
   LOffsetTo<FWORD>
@@ -185,26 +167,14 @@ struct KerxSubTableFormat4
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  rowWidth.sanitize (c) &&
-			  leftClassTable.sanitize (c, this) &&
-			  rightClassTable.sanitize (c, this) &&
-			  array.sanitize (c, this)));
+
+    /* TODO */
+    return_trace (likely (c->check_struct (this)));
   }
 
   protected:
-  HBUINT32	rowWidth;	/* The width, in bytes, of a row in the table. */
-  LOffsetTo<KerxClassTable>
-		leftClassTable;	/* Offset from beginning of this subtable to
-				 * left-hand class table. */
-  LOffsetTo<KerxClassTable>
-		rightClassTable;/* Offset from beginning of this subtable to
-				 * right-hand class table. */
-  LOffsetTo<FWORD>
-		array;		/* Offset from beginning of this subtable to
-				 * the start of the kerning array. */
   public:
-  DEFINE_SIZE_STATIC (16);
+  DEFINE_SIZE_STATIC (1);
 };
 
 struct KerxSubTableFormat6
commit 8aa83d97f9e7f63e2fcb4ae965b75a39961c7d87
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 22:43:59 2018 -0400

    [kern/kerx] Fix Format2 offsetting
    
    "The values in the right class table are stored pre-multiplied by the
    number of bytes in a single kerning value, and the values in the left
    class table are stored pre-multiplied by the number of bytes in one
    row. This eliminates needing to multiply the row and column values
    together to determine the location of the kerning value. The array can
    be indexed by doing the right- and left-hand class mappings, adding the
    class values to the address of the array, and fetching the kerning
    value to which the new address points."

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index ee05a045..c2eed5d4 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -127,7 +127,7 @@ struct KerxSubTableFormat2
   {
     unsigned int l = (this+leftClassTable).get_class (left);
     unsigned int r = (this+leftClassTable).get_class (left);
-    unsigned int offset = l * rowWidth + r * sizeof (FWORD);
+    unsigned int offset = l + r;
     const FWORD *arr = &(this+array);
     if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
       return 0;
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 8ed6298f..d26f402c 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -118,7 +118,7 @@ struct KernSubTableFormat2
   {
     unsigned int l = (this+leftClassTable).get_class (left);
     unsigned int r = (this+rightClassTable).get_class (right);
-    unsigned int offset = l * rowWidth + r * sizeof (FWORD);
+    unsigned int offset = l + r;
     const FWORD *arr = &(this+array);
     if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
       return 0;
commit ed2a404272bc99234c6f71f22b5a642834e59e6c
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 22:33:41 2018 -0400

    [kerx] Clean up Format0

diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 21fd26b4..ee05a045 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-kern-table.hh"
 
 /*
  * kerx -- Extended Kerning
@@ -43,33 +44,17 @@ namespace AAT {
 using namespace OT;
 
 
-struct KerxFormat0Records
+struct KerxSubTableFormat0
 {
-  inline bool sanitize (hb_sanitize_context_t *c) const
+  inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
-    TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this)));
+    hb_glyph_pair_t pair = {left, right};
+    int i = pairs.bsearch (pair);
+    if (i == -1)
+      return 0;
+    return pairs[i].get_kerning ();
   }
 
-  protected:
-  GlyphID	left;
-  GlyphID	right;
-  FWORD		value;
-  public:
-  DEFINE_SIZE_STATIC (6);
-};
-
-struct KerxSubTableFormat0
-{
-  // TODO(ebraminio) Enable when we got suitable BinSearchArrayOf
-  // inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-  // {
-  //   hb_glyph_pair_t pair = {left, right};
-  //   int i = pairs.bsearch (pair);
-  //   if (i == -1)
-  //     return 0;
-  //   return pairs[i].get_kerning ();
-  // }
   inline bool apply (hb_aat_apply_context_t *c) const
   {
     TRACE_APPLY (this);
@@ -82,23 +67,14 @@ struct KerxSubTableFormat0
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-			  recordsZ.sanitize (c, nPairs)));
+    return_trace (likely (pairs.sanitize (c)));
   }
 
   protected:
-  // TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is
-  // needed here to use HBUINT32 instead
-  HBUINT32	nPairs;		/* The number of kerning pairs in this subtable */
-  HBUINT32	searchRange;	/* The largest power of two less than or equal to the value of nPairs,
-				 * multiplied by the size in bytes of an entry in the subtable. */
-  HBUINT32	entrySelector;	/* This is calculated as log2 of the largest power of two less
-				 * than or equal to the value of nPairs. */
-  HBUINT32	rangeShift;	/* The value of nPairs minus the largest power of two less than or equal to nPairs. */
-  UnsizedArrayOf<KerxFormat0Records>
-		recordsZ;	/* VAR=nPairs */
+  BinSearchArrayOf<KernPair, HBUINT32>
+		pairs;	/* Sorted kern records. */
   public:
-  DEFINE_SIZE_ARRAY (16, recordsZ);
+  DEFINE_SIZE_ARRAY (16, pairs);
 };
 
 struct KerxSubTableFormat1
commit 4c3b19d52ec7a1fa46f8d0971e377a7d29b87e27
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 22:30:42 2018 -0400

    Support HBUINT32 BinSearchArrayOf

diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index cd3e773f..9a087336 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -706,6 +706,7 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
  * Binary-search arrays
  */
 
+template <typename LenType=HBUINT16>
 struct BinSearchHeader
 {
   inline operator uint32_t (void) const { return len; }
@@ -728,17 +729,17 @@ struct BinSearchHeader
   }
 
   protected:
-  HBUINT16	len;
-  HBUINT16	searchRange;
-  HBUINT16	entrySelector;
-  HBUINT16	rangeShift;
+  LenType	len;
+  LenType	searchRange;
+  LenType	entrySelector;
+  LenType	rangeShift;
 
   public:
   DEFINE_SIZE_STATIC (8);
 };
 
-template <typename Type>
-struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
+template <typename Type, typename LenType=HBUINT16>
+struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader<LenType> > {};
 
 struct VarSizedBinSearchHeader
 {
commit 456a68c506238e9c6b019244237d4443bd3589af
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 22:28:45 2018 -0400

    Move code

diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index fd842c2e..d6e597a4 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -36,111 +36,6 @@ using namespace OT;
 
 
 /*
- * Binary Searching Tables
- */
-
-struct VarSizedBinSearchHeader
-{
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  HBUINT16	unitSize;	/* Size of a lookup unit for this search in bytes. */
-  HBUINT16	nUnits;		/* Number of units of the preceding size to be searched. */
-  HBUINT16	searchRange;	/* The value of unitSize times the largest power of 2
-				 * that is less than or equal to the value of nUnits. */
-  HBUINT16	entrySelector;	/* The log base 2 of the largest power of 2 less than
-				 * or equal to the value of nUnits. */
-  HBUINT16	rangeShift;	/* The value of unitSize times the difference of the
-				 * value of nUnits minus the largest power of 2 less
-				 * than or equal to the value of nUnits. */
-  public:
-  DEFINE_SIZE_STATIC (10);
-};
-
-template <typename Type>
-struct VarSizedBinSearchArrayOf
-{
-  inline const Type& operator [] (unsigned int i) const
-  {
-    if (unlikely (i >= header.nUnits)) return Null(Type);
-    return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
-  }
-  inline Type& operator [] (unsigned int i)
-  {
-    return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
-  }
-  inline unsigned int get_size (void) const
-  { return header.static_size + header.nUnits * header.unitSize; }
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && StructAtOffset<Type> (&bytesZ, 0).sanitize (c));
-
-    return_trace (true);
-  }
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    unsigned int count = header.nUnits;
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(*this)[i].sanitize (c, base)))
-        return_trace (false);
-    return_trace (true);
-  }
-
-  template <typename T>
-  inline const Type *bsearch (const T &key) const
-  {
-    unsigned int size = header.unitSize;
-    int min = 0, max = (int) header.nUnits - 1;
-    while (min <= max)
-    {
-      int mid = (min + max) / 2;
-      const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
-      int c = p->cmp (key);
-      if (c < 0)
-	max = mid - 1;
-      else if (c > 0)
-	min = mid + 1;
-      else
-	return p;
-    }
-    return nullptr;
-  }
-
-  private:
-  inline bool sanitize_shallow (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (header.sanitize (c) &&
-		  Type::static_size >= header.unitSize &&
-		  c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize));
-  }
-
-  protected:
-  VarSizedBinSearchHeader	header;
-  UnsizedArrayOf<HBUINT8>	bytesZ;
-  public:
-  DEFINE_SIZE_ARRAY (10, bytesZ);
-};
-
-
-/*
  * Lookup Table
  */
 
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index ae7cdfaf..cd3e773f 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -702,7 +702,10 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
   }
 };
 
-/* Binary-search arrays */
+/*
+ * Binary-search arrays
+ */
+
 struct BinSearchHeader
 {
   inline operator uint32_t (void) const { return len; }
@@ -737,6 +740,106 @@ struct BinSearchHeader
 template <typename Type>
 struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
 
+struct VarSizedBinSearchHeader
+{
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBUINT16	unitSize;	/* Size of a lookup unit for this search in bytes. */
+  HBUINT16	nUnits;		/* Number of units of the preceding size to be searched. */
+  HBUINT16	searchRange;	/* The value of unitSize times the largest power of 2
+				 * that is less than or equal to the value of nUnits. */
+  HBUINT16	entrySelector;	/* The log base 2 of the largest power of 2 less than
+				 * or equal to the value of nUnits. */
+  HBUINT16	rangeShift;	/* The value of unitSize times the difference of the
+				 * value of nUnits minus the largest power of 2 less
+				 * than or equal to the value of nUnits. */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+template <typename Type>
+struct VarSizedBinSearchArrayOf
+{
+  inline const Type& operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= header.nUnits)) return Null(Type);
+    return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
+  }
+  inline Type& operator [] (unsigned int i)
+  {
+    return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
+  }
+  inline unsigned int get_size (void) const
+  { return header.static_size + header.nUnits * header.unitSize; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+
+    /* Note: for structs that do not reference other structs,
+     * we do not need to call their sanitize() as we already did
+     * a bound check on the aggregate array size.  We just include
+     * a small unreachable expression to make sure the structs
+     * pointed to do have a simple sanitize(), ie. they do not
+     * reference other structs via offsets.
+     */
+    (void) (false && StructAtOffset<Type> (&bytesZ, 0).sanitize (c));
+
+    return_trace (true);
+  }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    unsigned int count = header.nUnits;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!(*this)[i].sanitize (c, base)))
+        return_trace (false);
+    return_trace (true);
+  }
+
+  template <typename T>
+  inline const Type *bsearch (const T &key) const
+  {
+    unsigned int size = header.unitSize;
+    int min = 0, max = (int) header.nUnits - 1;
+    while (min <= max)
+    {
+      int mid = (min + max) / 2;
+      const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
+      int c = p->cmp (key);
+      if (c < 0)
+	max = mid - 1;
+      else if (c > 0)
+	min = mid + 1;
+      else
+	return p;
+    }
+    return nullptr;
+  }
+
+  private:
+  inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (header.sanitize (c) &&
+		  Type::static_size >= header.unitSize &&
+		  c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize));
+  }
+
+  protected:
+  VarSizedBinSearchHeader	header;
+  UnsizedArrayOf<HBUINT8>	bytesZ;
+  public:
+  DEFINE_SIZE_ARRAY (10, bytesZ);
+};
+
 
 } /* namespace OT */
 
commit 3515c8b187e2316dcf3abaefc84917b09449d485
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sun Oct 7 22:27:00 2018 -0400

    [aat] Rename

diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index 97866919..fd842c2e 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -39,7 +39,7 @@ using namespace OT;
  * Binary Searching Tables
  */
 
-struct BinSearchHeader
+struct VarSizedBinSearchHeader
 {
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -62,7 +62,7 @@ struct BinSearchHeader
 };
 
 template <typename Type>
-struct BinSearchArrayOf
+struct VarSizedBinSearchArrayOf
 {
   inline const Type& operator [] (unsigned int i) const
   {
@@ -133,7 +133,7 @@ struct BinSearchArrayOf
   }
 
   protected:
-  BinSearchHeader		header;
+  VarSizedBinSearchHeader	header;
   UnsizedArrayOf<HBUINT8>	bytesZ;
   public:
   DEFINE_SIZE_ARRAY (10, bytesZ);
@@ -213,7 +213,7 @@ struct LookupFormat2
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 2 */
-  BinSearchArrayOf<LookupSegmentSingle<T> >
+  VarSizedBinSearchArrayOf<LookupSegmentSingle<T> >
 		segments;	/* The actual segments. These must already be sorted,
 				 * according to the first word in each one (the last
 				 * glyph in each segment). */
@@ -270,7 +270,7 @@ struct LookupFormat4
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 2 */
-  BinSearchArrayOf<LookupSegmentArray<T> >
+  VarSizedBinSearchArrayOf<LookupSegmentArray<T> >
 		segments;	/* The actual segments. These must already be sorted,
 				 * according to the first word in each one (the last
 				 * glyph in each segment). */
@@ -315,7 +315,7 @@ struct LookupFormat6
 
   protected:
   HBUINT16	format;		/* Format identifier--format = 6 */
-  BinSearchArrayOf<LookupSingle<T> >
+  VarSizedBinSearchArrayOf<LookupSingle<T> >
 		entries;	/* The actual entries, sorted by glyph index. */
   public:
   DEFINE_SIZE_ARRAY (8, entries);


More information about the HarfBuzz mailing list