Merge pull request #1291 from harfbuzz/use-reordering

[use] Fix reordering
diff --git a/.travis.yml b/.travis.yml
index eadfa76..c2db4ff 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,7 +11,7 @@
     - CONFIGURE_OPTS="--with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2"
     - NOCONFIGURE=1
     # COVERITY_SCAN_TOKEN
-    - secure: "MRJtVu/fQoWNwMAamvIJBCX/1SMvEuEUk/ljAif/y2/3syyWgxFGp17UGnDILdoZYyCqTM+jQciY2P0nVqbjjOAUlML4QOAalqw8kPp8iTsnHUe+KOMVrOVP6p6qAQxk1im1O41cCMkmVKvk+NXe/on5euz6LGF2laHZaOAMoes="
+    - secure: "k6l/18dpsoPAf0E5RQWCr+rgjbHns0H3k0WzSYovCoVg0B7RVlV8x8OjyEOBzEvXI4aaHRdH6MHCPDFnX4fa7ysImlT6LxxIG8YhDdLkJWyS0hHbcJiGxko9AhAGzOZcDl8fZi13d697wagMqqXpjN5v2T/AQm8t4X9z2otJosY="
 
 matrix:
   include:
@@ -28,7 +28,8 @@
         - make check || .ci/fail.sh
         - rm -rf freetype-2.9
       after_success:
-        - bash .ci/run-coveralls.sh # for coveralls.io code coverage tracking
+        - bash .ci/run-coveralls.sh # coveralls.io code coverage
+        - bash <(curl -s https://codecov.io/bash) # codecov.io code coverage
         - bash .ci/deploy-docs.sh
         - bash .ci/trigger-coverity.sh
 
diff --git a/README b/README
index 55775c8..e50f8f0 100644
--- a/README
+++ b/README
@@ -1,9 +1,10 @@
-[![Build Status](https://travis-ci.org/harfbuzz/harfbuzz.svg)](https://travis-ci.org/harfbuzz/harfbuzz)
-[![Build status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true)](https://ci.appveyor.com/project/harfbuzz/harfbuzz)
-[![CircleCI](https://circleci.com/gh/harfbuzz/harfbuzz.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz)
-[![Coverity](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz)
-[![Codacy Badge](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
-[![Coverage Status](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
+[![Travis Build Status](https://travis-ci.org/harfbuzz/harfbuzz.svg)](https://travis-ci.org/harfbuzz/harfbuzz)
+[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true)](https://ci.appveyor.com/project/harfbuzz/harfbuzz)
+[![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz)
+[![Coverity Code Health](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz)
+[![Codacy Code Health](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
+[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/master/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
+[![Coverals Code Coverage](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
 [ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
 
 This is HarfBuzz, a text shaping library.
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 63d5f6c..5f5dcef 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -161,6 +161,10 @@
 hb_ot_layout_table_find_script
 hb_ot_tag_from_language
 hb_ot_tags_from_script
+HB_OT_VAR_NO_AXIS_INDEX
+hb_ot_var_axis_t
+hb_ot_var_find_axis
+hb_ot_var_get_axes
 hb_set_invert
 hb_unicode_eastasian_width_func_t
 hb_unicode_eastasian_width
@@ -581,14 +585,12 @@
 HB_OT_TAG_VAR_AXIS_SLANT
 HB_OT_TAG_VAR_AXIS_WEIGHT
 HB_OT_TAG_VAR_AXIS_WIDTH
-HB_OT_VAR_NO_AXIS_INDEX
-hb_ot_var_axis_t
 hb_ot_var_has_data
-hb_ot_var_find_axis
-hb_ot_var_get_axis_count
-hb_ot_var_get_axes
 hb_ot_var_axis_flags_t
-hb_ot_var_axis_get_flags
+hb_ot_var_axis_info_t
+hb_ot_var_find_axis_info
+hb_ot_var_get_axis_count
+hb_ot_var_get_axis_infos
 hb_ot_var_get_named_instance_count
 hb_ot_var_named_instance_get_subfamily_name_id
 hb_ot_var_named_instance_get_postscript_name_id
diff --git a/src/gen-emoji-table.py b/src/gen-emoji-table.py
index 278e0b2..9afe747 100755
--- a/src/gen-emoji-table.py
+++ b/src/gen-emoji-table.py
@@ -12,7 +12,7 @@
 f = open(sys.argv[1])
 header = [f.readline () for _ in range(10)]
 
-sets = OrderedDict()
+ranges = OrderedDict()
 for line in f.readlines():
 	line = line.strip()
 	if not line or line[0] == '#':
@@ -25,9 +25,12 @@
 	else:
 		start = end = rang[0]
 
-	if typ not in sets:
-		sets[typ] = set()
-	sets[typ].add((start, end))
+	if typ not in ranges:
+		ranges[typ] = []
+	if ranges[typ] and ranges[typ][-1][1] == start - 1:
+		ranges[typ][-1] = (ranges[typ][-1][0], end)
+	else:
+		ranges[typ].append((start, end))
 
 
 
@@ -49,7 +52,7 @@
 print ('#include "hb-unicode.hh"')
 print ()
 
-for typ,s in sets.items():
+for typ,s in ranges.items():
 	if typ != "Extended_Pictographic": continue
 	print()
 	print("static const struct hb_unicode_range_t _hb_unicode_emoji_%s_table[] =" % typ)
diff --git a/src/gen-use-table.py b/src/gen-use-table.py
index a8a7a23..099f6a1 100755
--- a/src/gen-use-table.py
+++ b/src/gen-use-table.py
@@ -50,6 +50,8 @@
 # TODO https://github.com/roozbehp/unicode-data/issues/9
 data[0][0x11C44] = 'Consonant_Placeholder'
 data[0][0x11C45] = 'Consonant_Placeholder'
+# TODO https://github.com/harfbuzz/harfbuzz/pull/1399
+data[0][0x111C8] = 'Consonant_Placeholder'
 for u in range (0xFE00, 0xFE0F + 1):
 	data[0][u] = defaults[0]
 
@@ -168,7 +170,7 @@
 def is_BASE_IND(U, UISC, UGC):
 	#SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po)
 	return (UISC in [Consonant_Dead, Modifying_Letter] or
-		(UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or
+		(UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or
 		False # SPEC-DRAFT-OUTDATED! U == 0x002D
 		)
 def is_BASE_NUM(U, UISC, UGC):
@@ -354,6 +356,9 @@
 		# TODO: https://github.com/harfbuzz/harfbuzz/issues/1105
 		if U == 0x11134: UISC = Gemination_Mark
 
+		# TODO: https://github.com/harfbuzz/harfbuzz/pull/1399
+		if U == 0x111C9: UISC = Consonant_Final
+
 		values = [k for k,v in items if v(U,UISC,UGC)]
 		assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values)
 		USE = values[0]
diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index 6572b26..7340996 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -69,7 +69,7 @@
   UnsizedArrayOf<T>
 		arrayZ;		/* Array of lookup values, indexed by glyph index. */
   public:
-  DEFINE_SIZE_ARRAY (2, arrayZ);
+  DEFINE_SIZE_UNBOUNDED (2);
 };
 
 
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index f075a27..bb88d9d 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -812,6 +812,7 @@
   {
     TRACE_SANITIZE (this);
     if (!u.header.sanitize (c) ||
+	u.header.length <= u.header.static_size ||
 	!c->check_range (this, u.header.length))
       return_trace (false);
 
@@ -933,6 +934,7 @@
       st = &StructAfter<SubTable> (*st);
       c->set_lookup_index (c->lookup_index + 1);
     }
+    c->sanitizer.reset_object ();
 
     return ret;
   }
@@ -951,10 +953,12 @@
     unsigned int count = thiz()->tableCount;
     for (unsigned int i = 0; i < count; i++)
     {
+      c->set_object (*st);
       if (unlikely (!st->sanitize (c)))
 	return_trace (false);
       st = &StructAfter<SubTable> (*st);
     }
+    c->reset_object ();
 
     return_trace (true);
   }
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 4307327..7a39eea 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -915,7 +915,7 @@
   {
     TRACE_SANITIZE (this);
     if (!length.sanitize (c) ||
-	length < min_size ||
+	length <= min_size ||
 	!c->check_range (this, length))
       return_trace (false);
 
@@ -1041,6 +1041,7 @@
       subtable = &StructAfter<ChainSubtable<Types> > (*subtable);
       c->set_lookup_index (c->lookup_index + 1);
     }
+    c->sanitizer.reset_object ();
   }
 
   inline unsigned int get_size (void) const { return length; }
@@ -1060,10 +1061,12 @@
     unsigned int count = subtableCount;
     for (unsigned int i = 0; i < count; i++)
     {
+      c->set_object (*subtable);
       if (!subtable->sanitize (c))
 	return_trace (false);
       subtable = &StructAfter<ChainSubtable<Types> > (*subtable);
     }
+    c->reset_object ();
 
     return_trace (true);
   }
diff --git a/src/hb-blob.hh b/src/hb-blob.hh
index 802b1f0..4f9d8f0 100644
--- a/src/hb-blob.hh
+++ b/src/hb-blob.hh
@@ -60,7 +60,7 @@
   template <typename Type>
   inline const Type* as (void) const
   {
-    return length < Type::min_size ? &Null(Type) : reinterpret_cast<const Type *> (data);
+    return length < hb_null_size<Type>::value ? &Null(Type) : reinterpret_cast<const Type *> (data);
   }
   inline hb_bytes_t as_bytes (void) const
   {
diff --git a/src/hb-common.cc b/src/hb-common.cc
index 37be8a3..28b0c2b 100644
--- a/src/hb-common.cc
+++ b/src/hb-common.cc
@@ -276,7 +276,7 @@
 
 static hb_atomic_ptr_t <hb_language_item_t> langs;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void
 free_langs (void)
 {
@@ -323,7 +323,7 @@
     goto retry;
   }
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
   if (!first_lang)
     atexit (free_langs); /* First person registers atexit() callback. */
 #endif
@@ -780,7 +780,7 @@
 
 #ifdef USE_XLOCALE
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_C_locale (void);
 #endif
 
@@ -791,7 +791,7 @@
   {
     HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_C_locale);
 #endif
 
@@ -807,7 +807,7 @@
   }
 } static_C_locale;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_C_locale (void)
 {
diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h
index e39b79f..a74431f 100644
--- a/src/hb-deprecated.h
+++ b/src/hb-deprecated.h
@@ -241,6 +241,43 @@
 hb_ot_tag_from_language (hb_language_t language);
 
 
+typedef unsigned int hb_ot_name_id_t; /* Since is in hb-ot.h */
+
+/**
+ * HB_OT_VAR_NO_AXIS_INDEX:
+ *
+ * Since: 1.4.2
+ * Deprecated: REPLACEME
+ */
+#define HB_OT_VAR_NO_AXIS_INDEX		0xFFFFFFFFu
+
+/**
+ * hb_ot_var_axis_t:
+ *
+ * Since: 1.4.2
+ * Deprecated: REPLACEME
+ */
+typedef struct hb_ot_var_axis_t
+{
+  hb_tag_t tag;
+  hb_ot_name_id_t name_id;
+  float min_value;
+  float default_value;
+  float max_value;
+} hb_ot_var_axis_t;
+
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_get_axis_infos) unsigned int
+hb_ot_var_get_axes (hb_face_t        *face,
+		    unsigned int      start_offset,
+		    unsigned int     *axes_count /* IN/OUT */,
+		    hb_ot_var_axis_t *axes_array /* OUT */);
+
+HB_EXTERN HB_DEPRECATED_FOR (hb_ot_var_find_axis_info) hb_bool_t
+hb_ot_var_find_axis (hb_face_t        *face,
+		     hb_tag_t          axis_tag,
+		     unsigned int     *axis_index,
+		     hb_ot_var_axis_t *axis_info);
+
 #endif
 
 HB_END_DECLS
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 9b9d787..fff0e28 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -478,7 +478,7 @@
   return true;
 }
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_ft_funcs (void);
 #endif
 
@@ -504,7 +504,7 @@
 
     hb_font_funcs_make_immutable (funcs);
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_ft_funcs);
 #endif
 
@@ -512,7 +512,7 @@
   }
 } static_ft_funcs;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_ft_funcs (void)
 {
@@ -744,7 +744,7 @@
   return hb_ft_font_create (ft_face, _hb_ft_face_destroy);
 }
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_ft_library (void);
 #endif
 
@@ -757,7 +757,7 @@
     if (FT_Init_FreeType (&l))
       return nullptr;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_ft_library);
 #endif
 
@@ -773,7 +773,7 @@
   }
 } static_ft_library;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_ft_library (void)
 {
diff --git a/src/hb-glib.cc b/src/hb-glib.cc
index 23a0d89..cb7e709 100644
--- a/src/hb-glib.cc
+++ b/src/hb-glib.cc
@@ -336,7 +336,7 @@
 }
 
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_glib_funcs (void);
 #endif
 
@@ -355,7 +355,7 @@
 
     hb_unicode_funcs_make_immutable (funcs);
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_glib_funcs);
 #endif
 
@@ -363,7 +363,7 @@
   }
 } static_glib_funcs;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_glib_funcs (void)
 {
diff --git a/src/hb-icu.cc b/src/hb-icu.cc
index 1286467..4e51eb0 100644
--- a/src/hb-icu.cc
+++ b/src/hb-icu.cc
@@ -300,7 +300,7 @@
 }
 
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_icu_funcs (void);
 #endif
 
@@ -326,7 +326,7 @@
 
     hb_unicode_funcs_make_immutable (funcs);
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_icu_funcs);
 #endif
 
@@ -334,7 +334,7 @@
   }
 } static_icu_funcs;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_icu_funcs (void)
 {
diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh
index 3c11243..edef540 100644
--- a/src/hb-machinery.hh
+++ b/src/hb-machinery.hh
@@ -82,8 +82,7 @@
 /* Check _assertion in a method environment */
 #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
   inline void _instance_assertion_on_line_##_line (void) const \
-  { static_assert ((_assertion), ""); } \
-  static_assert (true, "") /* So we require semicolon here. */
+  { static_assert ((_assertion), ""); }
 # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
 # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
 
@@ -96,32 +95,36 @@
 
 
 #define DEFINE_SIZE_STATIC(size) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)) \
   inline unsigned int get_size (void) const { return (size); } \
-  enum { static_size = (size) }; \
-  enum { min_size = (size) }
+  enum { null_size = (size) }; \
+  enum { min_size = (size) }; \
+  enum { static_size = (size) }
 
 #define DEFINE_SIZE_UNION(size, _member) \
-  DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \
-  static const unsigned int min_size = (size)
+  DEFINE_COMPILES_ASSERTION ((void) this->u._member.static_size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof(this->u._member) == (size)) \
+  enum { null_size = (size) }; \
+  enum { min_size = (size) }
 
 #define DEFINE_SIZE_MIN(size) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
-  static const unsigned int min_size = (size)
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \
+  enum { null_size = (size) }; \
+  enum { min_size = (size) }
+
+#define DEFINE_SIZE_UNBOUNDED(size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)) \
+  enum { min_size = (size) }
 
 #define DEFINE_SIZE_ARRAY(size, array) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \
   DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \
+  enum { null_size = (size) }; \
   enum { min_size = (size) }
 
 #define DEFINE_SIZE_ARRAY_SIZED(size, array) \
-	inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \
-	DEFINE_SIZE_ARRAY(size, array)
-
-#define DEFINE_SIZE_ARRAY2(size, array1, array2) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
-  DEFINE_COMPILES_ASSERTION ((void) (array1)[0].static_size; (void) (array2)[0].static_size) \
-  static const unsigned int min_size = (size)
+  inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \
+  DEFINE_SIZE_ARRAY(size, array)
 
 
 /*
@@ -256,26 +259,34 @@
 
   inline void set_max_ops (int max_ops_) { max_ops = max_ops_; }
 
-  /* TODO
-   * This set_object() thing is to use sanitize at runtime lookup
-   * application time.  This is very distinct from the regular
-   * sanitizer operation, so, eventually, separate into another
-   * type and make hb_aat_apply_context_t use that one instead
-   * of abusing this one.
-   */
   template <typename T>
   inline void set_object (const T& obj)
   {
-    this->start = (const char *) &obj;
-    this->end = (const char *) &obj + obj.get_size ();
+    reset_object ();
+
+    const char *obj_start = (const char *) &obj;
+    const char *obj_end = (const char *) &obj + obj.get_size ();
+    assert (obj_start <= obj_end); /* Must not overflow. */
+
+    if (unlikely (obj_end < this->start || this->end < obj_start))
+      this->start = this->end = nullptr;
+    else
+    {
+      this->start = MAX (this->start, obj_start);
+      this->end   = MIN (this->end  , obj_end  );
+    }
+  }
+
+  inline void reset_object (void)
+  {
+    this->start = this->blob->data;
+    this->end = this->start + this->blob->length;
     assert (this->start <= this->end); /* Must not overflow. */
   }
 
   inline void start_processing (void)
   {
-    this->start = this->blob->data;
-    this->end = this->start + this->blob->length;
-    assert (this->start <= this->end); /* Must not overflow. */
+    reset_object ();
     this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
 			 (unsigned) HB_SANITIZE_MAX_OPS_MIN);
     this->edit_count = 0;
diff --git a/src/hb-null.hh b/src/hb-null.hh
index 25a24f0..58151d7 100644
--- a/src/hb-null.hh
+++ b/src/hb-null.hh
@@ -38,13 +38,32 @@
 
 #define HB_NULL_POOL_SIZE 1024
 
+/* Use SFINAE to sniff whether T has min_size; in which case return T::null_size,
+ * otherwise return sizeof(T). */
+
+/* The hard way...
+ * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol
+ */
+template<bool> struct _hb_bool_type {};
+
+template <typename T, typename B>
+struct _hb_null_size
+{ enum { value = sizeof (T) }; };
+template <typename T>
+struct _hb_null_size<T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
+{ enum { value = T::null_size }; };
+
+template <typename T>
+struct hb_null_size
+{ enum { value = _hb_null_size<T, _hb_bool_type<true> >::value }; };
+
 extern HB_INTERNAL
 hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
 
 /* Generic nul-content Null objects. */
 template <typename Type>
 static inline Type const & Null (void) {
-  static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
+  static_assert (hb_null_size<Type>::value <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
   return *reinterpret_cast<Type const *> (_hb_NullPool);
 }
 #define Null(Type) Null<typename hb_remove_const<typename hb_remove_reference<Type>::value>::value>()
@@ -52,7 +71,7 @@
 /* Specializations for arbitrary-content Null objects expressed in bytes. */
 #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \
 	} /* Close namespace. */ \
-	extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \
+	extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]; \
 	template <> \
 	/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \
 	  return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \
@@ -60,7 +79,7 @@
 	namespace Namespace { \
 	static_assert (true, "Just so we take semicolon after.")
 #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \
-	const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]
+	const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::null_size]
 
 /* Specializations for arbitrary-content Null objects expressed as struct initializer. */
 #define DECLARE_NULL_INSTANCE(Type) \
@@ -85,7 +104,7 @@
 /* CRAP pool: Common Region for Access Protection. */
 template <typename Type>
 static inline Type& Crap (void) {
-  static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
+  static_assert (hb_null_size<Type>::value <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
   Type *obj = reinterpret_cast<Type *> (_hb_CrapPool);
   memcpy (obj, &Null(Type), sizeof (*obj));
   return *obj;
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index b1fcd68..f4a9a5e 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -231,22 +231,31 @@
  * Use: (base+offset)
  */
 
-template <typename Type, bool has_null_> struct assert_has_min_size { static_assert (Type::min_size > 0, ""); };
-template <typename Type> struct assert_has_min_size<Type, false> {};
+template <typename Type, bool has_null>
+struct _hb_has_null
+{
+  static inline const Type *get_null (void) { return nullptr; }
+  static inline Type *get_crap (void) { return nullptr; }
+};
+template <typename Type>
+struct _hb_has_null<Type, true>
+{
+  static inline const Type *get_null (void) { return &Null(Type); }
+  static inline Type *get_crap (void) { return &Crap(Type); }
+};
 
 template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
 struct OffsetTo : Offset<OffsetType, has_null>
 {
-  static_assert (sizeof (assert_has_min_size<Type, has_null>) || true, "");
-
   inline const Type& operator () (const void *base) const
   {
-    if (unlikely (this->is_null ())) return Null (Type);
+    if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_null ();
     return StructAtOffset<const Type> (base, *this);
   }
   inline Type& operator () (void *base) const
   {
     if (unlikely (this->is_null ())) return Crap (Type);
+    if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_crap ();
     return StructAtOffset<Type> (base, *this);
   }
 
@@ -322,6 +331,7 @@
   DEFINE_SIZE_STATIC (sizeof (OffsetType));
 };
 template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {};
+
 template <typename Base, typename OffsetType, bool has_null, typename Type>
 static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
 template <typename Base, typename OffsetType, bool has_null, typename Type>
@@ -406,7 +416,7 @@
   public:
   Type		arrayZ[VAR];
   public:
-  DEFINE_SIZE_ARRAY (0, arrayZ);
+  DEFINE_SIZE_UNBOUNDED (0);
 };
 
 /* Unsized array of offset's */
diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index b7d1701..4297550 100644
--- a/src/hb-ot-cmap-table.hh
+++ b/src/hb-ot-cmap-table.hh
@@ -863,14 +863,6 @@
     hb_vector_t<CmapSubtableLongGroup> format12_groups;
   };
 
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-		  likely (version == 0) &&
-		  encodingRecord.sanitize (c, this));
-  }
-
   inline bool _create_plan (const hb_subset_plan_t *plan,
 			    subset_plan *cmap_plan) const
   {
@@ -1171,6 +1163,16 @@
     return &(this+encodingRecord[result].subtable);
   }
 
+  public:
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  likely (version == 0) &&
+		  encodingRecord.sanitize (c, this));
+  }
+
   protected:
   HBUINT16		version;	/* Table version number (0). */
   SortedArrayOf<EncodingRecord>
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index b19b25a..7c91362 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -243,7 +243,7 @@
   return vmtx.has_font_extents;
 }
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_ot_funcs (void);
 #endif
 
@@ -269,7 +269,7 @@
 
     hb_font_funcs_make_immutable (funcs);
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_ot_funcs);
 #endif
 
@@ -277,7 +277,7 @@
   }
 } static_ot_funcs;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_ot_funcs (void)
 {
diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh
index 5d9e7a2..c88f433 100644
--- a/src/hb-ot-glyf-table.hh
+++ b/src/hb-ot-glyf-table.hh
@@ -56,7 +56,9 @@
   protected:
   UnsizedArrayOf<HBUINT8>	dataZ;		/* Location data. */
   public:
-  DEFINE_SIZE_ARRAY (0, dataZ);
+  DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
+			* check the size externally, allow Null() object of it by
+			* defining it MIN() instead. */
 };
 
 
@@ -465,7 +467,9 @@
   protected:
   UnsizedArrayOf<HBUINT8>	dataZ;		/* Glyphs data. */
   public:
-  DEFINE_SIZE_ARRAY (0, dataZ);
+  DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
+			* check the size externally, allow Null() object of it by
+			* defining it MIN() instead. */
 };
 
 struct glyf_accelerator_t : glyf::accelerator_t {};
diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh
index 14e0656..b2d5714 100644
--- a/src/hb-ot-kern-table.hh
+++ b/src/hb-ot-kern-table.hh
@@ -154,7 +154,7 @@
   KernSubTableFormat3<KernSubTableHeader>	format3;
   } u;
   public:
-  DEFINE_SIZE_MIN (0);
+  DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
 };
 
 
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index 55b05b5..46c2f18 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -802,11 +802,11 @@
   HBUINT16	lookupFlag;		/* Lookup qualifiers */
   ArrayOf<Offset16>
 		subTable;		/* Array of SubTables */
-  HBUINT16	markFilteringSetX[VAR];	/* Index (base 0) into GDEF mark glyph sets
+/*HBUINT16	markFilteringSetX[VAR];*//* Index (base 0) into GDEF mark glyph sets
 					 * structure. This field is only present if bit
 					 * UseMarkFilteringSet of lookup flags is set. */
   public:
-  DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX);
+  DEFINE_SIZE_ARRAY (6, subTable);
 };
 
 typedef OffsetListOf<Lookup> LookupList;
@@ -1568,9 +1568,9 @@
   HBUINT16		itemCount;
   HBUINT16		shortCount;
   ArrayOf<HBUINT16>	regionIndices;
-  UnsizedArrayOf<HBUINT8>bytesX;
+/*UnsizedArrayOf<HBUINT8>bytesX;*/
   public:
-  DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
+  DEFINE_SIZE_ARRAY (6, regionIndices);
 };
 
 struct VariationStore
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 715317b..501f230 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1449,7 +1449,10 @@
 
     hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index);
 
-    c->flush ();
+    /* While in theory we should flush here, it will cause timeouts because a recursive
+     * lookup can keep growing the glyph set.  Skip, and outer loop will retry up to
+     * HB_CLOSURE_MAX_STAGES time, which should be enough for every realistic font. */
+    //c->flush ();
 
     return ret;
   }
diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index f80303c..98df3e7 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -61,12 +61,12 @@
   ArrayOf<HBUINT16>	glyphNameIndex;	/* This is not an offset, but is the
 					 * ordinal number of the glyph in 'post'
 					 * string tables. */
-  UnsizedArrayOf<HBUINT8>
-			namesX;		/* Glyph names with length bytes [variable]
+/*UnsizedArrayOf<HBUINT8>
+			namesX;*/	/* Glyph names with length bytes [variable]
 					 * (a Pascal string). */
 
   public:
-  DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
+  DEFINE_SIZE_ARRAY (2, glyphNameIndex);
 };
 
 struct post
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index ca7b5a9..8fdf2f4 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -391,27 +391,6 @@
 };
 
 
-/* Uniscribe seems to have a shaper for 'mymr' that is like the
- * generic shaper, except that it zeros mark advances GDEF_LATE. */
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
-{
-  nullptr, /* collect_features */
-  nullptr, /* override_features */
-  nullptr, /* data_create */
-  nullptr, /* data_destroy */
-  nullptr, /* preprocess_text */
-  nullptr, /* postprocess_glyphs */
-  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
-  nullptr, /* decompose */
-  nullptr, /* compose */
-  nullptr, /* setup_masks */
-  HB_TAG_NONE, /* gpos_tag */
-  nullptr, /* reorder_marks */
-  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
-  true, /* fallback_position */
-};
-
-
 /* Ugly Zawgyi encoding.
  * Disable all auto processing.
  * https://github.com/harfbuzz/harfbuzz/issues/1162 */
diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc
index bfc92d3..2f3eb70 100644
--- a/src/hb-ot-shape-complex-use-table.cc
+++ b/src/hb-ot-shape-complex-use-table.cc
@@ -544,7 +544,7 @@
   /* 11190 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111B0 */     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,
-  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,     O,    FM, CMBlw,  VAbv,  VBlw,     O,     O,     O,
+  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,    GB,  FBlw, CMBlw,  VAbv,  VBlw,     O,     O,     O,
   /* 111D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
   /* Sinhala Archaic Numbers */
diff --git a/src/hb-ot-shape-complex.hh b/src/hb-ot-shape-complex.hh
index 2944d74..a2499de 100644
--- a/src/hb-ot-shape-complex.hh
+++ b/src/hb-ot-shape-complex.hh
@@ -57,7 +57,6 @@
   HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
   HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \
   HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
-  HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \
   HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \
   HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
   HB_COMPLEX_SHAPER_IMPLEMENT (use) \
@@ -269,12 +268,25 @@
 	return &_hb_ot_complex_shaper_khmer;
 
     case HB_SCRIPT_MYANMAR:
-      if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
-	return &_hb_ot_complex_shaper_myanmar;
-      else if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','r'))
-	return &_hb_ot_complex_shaper_myanmar_old;
-      else
+      /* If the designer designed the font for the 'DFLT' script,
+       * (or we ended up arbitrarily pick 'latn'), use the default shaper.
+       * Otherwise, use the specific shaper.
+       *
+       * If designer designed for 'mymr' tag, also send to default
+       * shaper.  That's tag used from before Myanmar shaping spec
+       * was developed.  The shaping spec uses 'mym2' tag. */
+      if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
+	  planner->map.chosen_script[0] == HB_TAG ('l','a','t','n') ||
+	  planner->map.chosen_script[0] == HB_TAG ('m','y','m','r'))
 	return &_hb_ot_complex_shaper_default;
+      else
+	return &_hb_ot_complex_shaper_myanmar;
+
+
+    /* https://github.com/harfbuzz/harfbuzz/issues/1162 */
+    case HB_SCRIPT_MYANMAR_ZAWGYI:
+
+      return &_hb_ot_complex_shaper_myanmar_zawgyi;
 
 
     /* Unicode-2.0 additions */
@@ -375,10 +387,6 @@
 	return &_hb_ot_complex_shaper_default;
       else
 	return &_hb_ot_complex_shaper_use;
-
-    /* https://github.com/harfbuzz/harfbuzz/issues/1162 */
-    case HB_SCRIPT_MYANMAR_ZAWGYI:
-      return &_hb_ot_complex_shaper_myanmar_zawgyi;
   }
 }
 
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index ccee8d3..8d84480 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -76,10 +76,16 @@
 						props (*props),
 						map (face, props),
 						aat_map (face, props),
-						apply_morx (_hb_apply_morx (face)),
-						shaper (apply_morx ?
-						        &_hb_ot_complex_shaper_default :
-							hb_ot_shape_complex_categorize (this)) {}
+						apply_morx (_hb_apply_morx (face))
+{
+  shaper = hb_ot_shape_complex_categorize (this);
+
+  script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
+  script_fallback_mark_positioning = shaper->fallback_position;
+
+  if (apply_morx)
+    shaper = &_hb_ot_complex_shaper_default;
+}
 
 void
 hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t           &plan,
@@ -140,10 +146,15 @@
       plan.apply_kern = true;
   }
 
-  bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face);
-  plan.zero_marks = !plan.apply_morx && !plan.apply_kerx && !has_kern_mark;
+  plan.zero_marks = script_zero_marks && !plan.apply_kerx;
   plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
-  plan.fallback_mark_positioning = !plan.apply_gpos && plan.zero_marks;
+
+  plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos &&
+					      !plan.apply_kerx &&
+					      (!plan.apply_kern || !hb_ot_layout_has_cross_kerning (face));
+
+  plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing &&
+				   script_fallback_mark_positioning;
 
   /* Currently we always apply trak. */
   plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
@@ -158,6 +169,7 @@
 
   hb_ot_shape_planner_t planner (face,
 				 &key->props);
+
   hb_ot_shape_collect_features (&planner,
 				key->user_features,
 				key->num_user_features);
@@ -811,17 +823,16 @@
   hb_glyph_info_t *info = c->buffer->info;
   hb_glyph_position_t *pos = c->buffer->pos;
 
-  /* If the font has no GPOS, AND, no fallback positioning will
-   * happen, AND, direction is forward, then when zeroing mark
-   * widths, we shift the mark with it, such that the mark
-   * is positioned hanging over the previous glyph.  When
+  /* If the font has no GPOS and direction is forward, then when
+   * zeroing mark widths, we shift the mark with it, such that the
+   * mark is positioned hanging over the previous glyph.  When
    * direction is backward we don't shift and it will end up
    * hanging over the next glyph after the final reordering.
-   * If fallback positinoing happens or GPOS is present, we don't
-   * care.
+   *
+   * Note: If fallback positinoing happens, we don't care about
+   * this as it will be overriden.
    */
-  bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning &&
-				     !c->plan->shaper->fallback_position &&
+  bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing &&
 				     HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
 
   /* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
@@ -877,7 +888,7 @@
 					&pos[i].x_offset,
 					&pos[i].y_offset);
 
-  if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
+  if (c->plan->fallback_mark_positioning)
     _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
 }
 
diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh
index 397634c..6e1478d 100644
--- a/src/hb-ot-shape.hh
+++ b/src/hb-ot-shape.hh
@@ -77,6 +77,7 @@
   bool zero_marks : 1;
   bool fallback_glyph_classes : 1;
   bool fallback_mark_positioning : 1;
+  bool adjust_mark_positioning_when_zeroing : 1;
 
   bool apply_gpos : 1;
   bool apply_kerx : 1;
@@ -113,6 +114,8 @@
   hb_ot_map_builder_t map;
   hb_aat_map_builder_t aat_map;
   bool apply_morx : 1;
+  bool script_zero_marks : 1;
+  bool script_fallback_mark_positioning : 1;
   const struct hb_ot_complex_shaper_t *shaper;
 
   HB_INTERNAL hb_ot_shape_planner_t (hb_face_t                     *face,
diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh
index f61296d..fed334e 100644
--- a/src/hb-ot-var-fvar-table.hh
+++ b/src/hb-ot-var-fvar-table.hh
@@ -65,7 +65,7 @@
   //				  * instance. */
 
   public:
-  DEFINE_SIZE_ARRAY (4, coordinatesZ);
+  DEFINE_SIZE_UNBOUNDED (4);
 };
 
 struct AxisRecord
@@ -109,40 +109,46 @@
 		  axisSize == 20 && /* Assumed in our code. */
 		  instanceSize >= axisCount * 4 + 4 &&
 		  get_axes ().sanitize (c) &&
-		  c->check_range (&get_instance (0), instanceCount, instanceSize));
+		  c->check_range (get_instance (0), instanceCount, instanceSize));
   }
 
   inline unsigned int get_axis_count (void) const
   { return axisCount; }
 
-  inline bool get_axis (unsigned int index, hb_ot_var_axis_t *info) const
+  inline void get_axis_deprecated (unsigned int axis_index,
+				   hb_ot_var_axis_t *info) const
   {
-    if (info)
-    {
-      const AxisRecord &axis = get_axes ()[index];
-      info->tag = axis.axisTag;
-      info->name_id =  axis.axisNameID;
-      info->default_value = axis.defaultValue / 65536.;
-      /* Ensure order, to simplify client math. */
-      info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
-      info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
-    }
-
-    return true;
+    const AxisRecord &axis = get_axes ()[axis_index];
+    info->tag = axis.axisTag;
+    info->name_id =  axis.axisNameID;
+    info->default_value = axis.defaultValue / 65536.;
+    /* Ensure order, to simplify client math. */
+    info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
+    info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
   }
 
-  inline hb_ot_var_axis_flags_t get_axis_flags (unsigned int index) const
+  inline void get_axis_info (unsigned int axis_index,
+			     hb_ot_var_axis_info_t *info) const
   {
-    const AxisRecord &axis = get_axes ()[index];
-    return (hb_ot_var_axis_flags_t) (unsigned int) axis.flags;
+    const AxisRecord &axis = get_axes ()[axis_index];
+    info->axis_index = axis_index;
+    info->tag = axis.axisTag;
+    info->name_id =  axis.axisNameID;
+    info->flags = (hb_ot_var_axis_flags_t) (unsigned int) axis.flags;
+    info->default_value = axis.defaultValue / 65536.;
+    /* Ensure order, to simplify client math. */
+    info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
+    info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
+    info->reserved = 0;
   }
 
-  inline unsigned int get_axis_infos (unsigned int      start_offset,
-				      unsigned int     *axes_count /* IN/OUT */,
-				      hb_ot_var_axis_t *axes_array /* OUT */) const
+  inline unsigned int get_axes_deprecated (unsigned int      start_offset,
+					   unsigned int     *axes_count /* IN/OUT */,
+					   hb_ot_var_axis_t *axes_array /* OUT */) const
   {
     if (axes_count)
     {
+      /* TODO Rewrite as hb_array_t<>::sub-array() */
       unsigned int count = axisCount;
       start_offset = MIN (start_offset, count);
 
@@ -153,32 +159,70 @@
       *axes_count = count;
 
       for (unsigned int i = 0; i < count; i++)
-	get_axis (start_offset + i, axes_array + i);
+	get_axis_deprecated (start_offset + i, axes_array + i);
     }
     return axisCount;
   }
 
-  inline bool find_axis (hb_tag_t tag, unsigned int *index, hb_ot_var_axis_t *info) const
+  inline unsigned int get_axis_infos (unsigned int           start_offset,
+				      unsigned int          *axes_count /* IN/OUT */,
+				      hb_ot_var_axis_info_t *axes_array /* OUT */) const
+  {
+    if (axes_count)
+    {
+      /* TODO Rewrite as hb_array_t<>::sub-array() */
+      unsigned int count = axisCount;
+      start_offset = MIN (start_offset, count);
+
+      count -= start_offset;
+      axes_array += start_offset;
+
+      count = MIN (count, *axes_count);
+      *axes_count = count;
+
+      for (unsigned int i = 0; i < count; i++)
+	get_axis_info (start_offset + i, axes_array + i);
+    }
+    return axisCount;
+  }
+
+  inline bool find_axis_deprecated (hb_tag_t tag,
+				    unsigned int *axis_index,
+				    hb_ot_var_axis_t *info) const
   {
     const AxisRecord *axes = get_axes ();
     unsigned int count = get_axis_count ();
     for (unsigned int i = 0; i < count; i++)
       if (axes[i].axisTag == tag)
       {
-        if (index)
-	  *index = i;
-	return get_axis (i, info);
+        if (axis_index)
+	  *axis_index = i;
+	get_axis_deprecated (i, info);
+	return true;
       }
-    if (index)
-      *index = HB_OT_VAR_NO_AXIS_INDEX;
+    if (axis_index)
+      *axis_index = HB_OT_VAR_NO_AXIS_INDEX;
+    return false;
+  }
+
+  inline bool find_axis_info (hb_tag_t tag,
+			      hb_ot_var_axis_info_t *info) const
+  {
+    const AxisRecord *axes = get_axes ();
+    unsigned int count = get_axis_count ();
+    for (unsigned int i = 0; i < count; i++)
+      if (axes[i].axisTag == tag)
+      {
+	get_axis_info (i, info);
+	return true;
+      }
     return false;
   }
 
   inline int normalize_axis_value (unsigned int axis_index, float v) const
   {
-    hb_ot_var_axis_t axis;
-    if (!get_axis (axis_index, &axis))
-      return 0;
+    hb_ot_var_axis_info_t axis;
+    get_axis_info (axis_index, &axis);
 
     v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */
 
@@ -194,25 +238,28 @@
   inline unsigned int get_instance_count (void) const
   { return instanceCount; }
 
-  inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int index) const
+  inline hb_ot_name_id_t get_instance_subfamily_name_id (unsigned int instance_index) const
   {
-    const InstanceRecord &instance = get_instance (index);
-    return instance.subfamilyNameID;
+    const InstanceRecord *instance = get_instance (instance_index);
+    if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID;
+    return instance->subfamilyNameID;
   }
 
-  inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int index) const
+  inline hb_ot_name_id_t get_instance_postscript_name_id (unsigned int instance_index) const
   {
-    const InstanceRecord &instance = get_instance (index);
+    const InstanceRecord *instance = get_instance (instance_index);
+    if (unlikely (!instance)) return HB_OT_NAME_ID_INVALID;
     if (instanceSize >= axisCount * 4 + 6)
-      return StructAfter<NameID> (instance.get_coordinates (axisCount));
+      return StructAfter<NameID> (instance->get_coordinates (axisCount));
     return HB_OT_NAME_ID_INVALID;
   }
 
-  inline unsigned int get_instance_coords (unsigned int  index,
+  inline unsigned int get_instance_coords (unsigned int  instance_index,
 					   unsigned int *coords_length, /* IN/OUT */
-					   int          *coords         /* OUT */) const
+					   float        *coords         /* OUT */) const
   {
-    if (unlikely (index >= instanceCount))
+    const InstanceRecord *instance = get_instance (instance_index);
+    if (unlikely (!instance))
     {
       if (coords_length)
         *coords_length = 0;
@@ -221,9 +268,8 @@
 
     if (coords_length && *coords_length)
     {
-      const InstanceRecord &instance = get_instance (index);
-      hb_array_t<const Fixed> instanceCoords = instance.get_coordinates (axisCount)
-						       .sub_array (0, *coords_length);
+      hb_array_t<const Fixed> instanceCoords = instance->get_coordinates (axisCount)
+							 .sub_array (0, *coords_length);
       for (unsigned int i = 0; i < instanceCoords.len; i++)
         coords[i] = instanceCoords.arrayZ[i].to_float ();
     }
@@ -234,12 +280,11 @@
   inline hb_array_t<const AxisRecord> get_axes (void) const
   { return hb_array (&(this+firstAxis), axisCount); }
 
-  inline const InstanceRecord &get_instance (unsigned int i) const
+  inline const InstanceRecord *get_instance (unsigned int i) const
   {
-    if (unlikely (i >= instanceCount)) return Null (InstanceRecord);
-
-   return StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (get_axes ()),
-					  i * instanceSize);
+    if (unlikely (i >= instanceCount)) return nullptr;
+   return &StructAtOffset<InstanceRecord> (&StructAfter<InstanceRecord> (get_axes ()),
+					   i * instanceSize);
   }
 
   protected:
diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc
index bb8d264..56d2481 100644
--- a/src/hb-ot-var.cc
+++ b/src/hb-ot-var.cc
@@ -53,7 +53,6 @@
  * @face: #hb_face_t to test
  *
  * This function allows to verify the presence of OpenType variation data on the face.
- * Alternatively, use hb_ot_var_get_axis_count().
  *
  * Return value: true if face has a `fvar' table and false otherwise
  *
@@ -80,6 +79,7 @@
  * hb_ot_var_get_axes:
  *
  * Since: 1.4.2
+ * Deprecated: REPLACEME
  **/
 unsigned int
 hb_ot_var_get_axes (hb_face_t        *face,
@@ -87,13 +87,14 @@
 		    unsigned int     *axes_count /* IN/OUT */,
 		    hb_ot_var_axis_t *axes_array /* OUT */)
 {
-  return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array);
+  return face->table.fvar->get_axes_deprecated (start_offset, axes_count, axes_array);
 }
 
 /**
  * hb_ot_var_find_axis:
  *
  * Since: 1.4.2
+ * Deprecated: REPLACEME
  **/
 hb_bool_t
 hb_ot_var_find_axis (hb_face_t        *face,
@@ -101,21 +102,37 @@
 		     unsigned int     *axis_index,
 		     hb_ot_var_axis_t *axis_info)
 {
-  return face->table.fvar->find_axis (axis_tag, axis_index, axis_info);
+  return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info);
 }
 
 /**
- * hb_ot_var_axis_get_flags:
+ * hb_ot_var_get_axis_infos:
  *
  * Since: REPLACEME
  **/
-hb_ot_var_axis_flags_t
-hb_ot_var_axis_get_flags (hb_face_t    *face,
-			  unsigned int  axis_index)
+HB_EXTERN unsigned int
+hb_ot_var_get_axis_infos (hb_face_t             *face,
+			  unsigned int           start_offset,
+			  unsigned int          *axes_count /* IN/OUT */,
+			  hb_ot_var_axis_info_t *axes_array /* OUT */)
 {
-  return face->table.fvar->get_axis_flags (axis_index);
+  return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array);
 }
 
+/**
+ * hb_ot_var_find_axis_info:
+ *
+ * Since: REPLACEME
+ **/
+HB_EXTERN hb_bool_t
+hb_ot_var_find_axis_info (hb_face_t             *face,
+			  hb_tag_t               axis_tag,
+			  hb_ot_var_axis_info_t *axis_info)
+{
+  return face->table.fvar->find_axis_info (axis_tag, axis_info);
+}
+
+
 /*
  * Named instances.
  */
@@ -144,7 +161,7 @@
 hb_ot_var_named_instance_get_design_coords (hb_face_t    *face,
 					    unsigned int  instance_index,
 					    unsigned int *coords_length, /* IN/OUT */
-					    int          *coords         /* OUT */)
+					    float        *coords         /* OUT */)
 {
   return face->table.fvar->get_instance_coords (instance_index, coords_length, coords);
 }
@@ -168,10 +185,10 @@
   const OT::fvar &fvar = *face->table.fvar;
   for (unsigned int i = 0; i < variations_length; i++)
   {
-    unsigned int axis_index;
-    if (hb_ot_var_find_axis (face, variations[i].tag, &axis_index, nullptr) &&
-	axis_index < coords_length)
-      coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value);
+    hb_ot_var_axis_info_t info;
+    if (hb_ot_var_find_axis_info (face, variations[i].tag, &info) &&
+	info.axis_index < coords_length)
+      coords[info.axis_index] = fvar.normalize_axis_value (info.axis_index, variations[i].value);
   }
 
   face->table.avar->map_coords (coords, coords_length);
diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h
index e0ac5c4..779be10 100644
--- a/src/hb-ot-var.h
+++ b/src/hb-ot-var.h
@@ -47,19 +47,6 @@
  * fvar / avar
  */
 
-/**
- * hb_ot_var_axis_t:
- *
- * Since: 1.4.2
- */
-typedef struct hb_ot_var_axis_t {
-  hb_tag_t tag;
-  hb_ot_name_id_t name_id;
-  float min_value;
-  float default_value;
-  float max_value;
-} hb_ot_var_axis_t;
-
 HB_EXTERN hb_bool_t
 hb_ot_var_has_data (hb_face_t *face);
 
@@ -68,28 +55,10 @@
  * Variation axes.
  */
 
-/**
- * HB_OT_VAR_NO_AXIS_INDEX:
- *
- * Since: 1.4.2
- */
-#define HB_OT_VAR_NO_AXIS_INDEX		0xFFFFFFFFu
 
 HB_EXTERN unsigned int
 hb_ot_var_get_axis_count (hb_face_t *face);
 
-HB_EXTERN unsigned int
-hb_ot_var_get_axes (hb_face_t        *face,
-		    unsigned int      start_offset,
-		    unsigned int     *axes_count /* IN/OUT */,
-		    hb_ot_var_axis_t *axes_array /* OUT */);
-
-HB_EXTERN hb_bool_t
-hb_ot_var_find_axis (hb_face_t        *face,
-		     hb_tag_t          axis_tag,
-		     unsigned int     *axis_index,
-		     hb_ot_var_axis_t *axis_info);
-
 /**
  * hb_ot_var_axis_flags_t:
  * @HB_OT_VAR_AXIS_FLAG_HIDDEN: The axis should not be exposed directly in user interfaces.
@@ -97,12 +66,39 @@
  * Since: REPLACEME
  */
 typedef enum { /*< flags >*/
-  HB_OT_VAR_AXIS_FLAG_HIDDEN	= 0x0001u,
+  HB_OT_VAR_AXIS_FLAG_HIDDEN	= 0x00000001u,
+
+  _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
 } hb_ot_var_axis_flags_t;
 
-HB_EXTERN hb_ot_var_axis_flags_t
-hb_ot_var_axis_get_flags (hb_face_t    *face,
-			  unsigned int  axis_index);
+/**
+ * hb_ot_var_axis_info_t:
+ *
+ * Since: REPLACEME
+ */
+typedef struct hb_ot_var_axis_info_t
+{
+  unsigned int			axis_index;
+  hb_tag_t			tag;
+  hb_ot_name_id_t		name_id;
+  hb_ot_var_axis_flags_t	flags;
+  float				min_value;
+  float				default_value;
+  float				max_value;
+  /*< private >*/
+  unsigned int			reserved;
+} hb_ot_var_axis_info_t;
+
+HB_EXTERN unsigned int
+hb_ot_var_get_axis_infos (hb_face_t             *face,
+			  unsigned int           start_offset,
+			  unsigned int          *axes_count /* IN/OUT */,
+			  hb_ot_var_axis_info_t *axes_array /* OUT */);
+
+HB_EXTERN hb_bool_t
+hb_ot_var_find_axis_info (hb_face_t             *face,
+			  hb_tag_t               axis_tag,
+			  hb_ot_var_axis_info_t *axis_info);
 
 
 /*
@@ -124,7 +120,7 @@
 hb_ot_var_named_instance_get_design_coords (hb_face_t    *face,
 					    unsigned int  instance_index,
 					    unsigned int *coords_length, /* IN/OUT */
-					    int          *coords         /* OUT */);
+					    float        *coords         /* OUT */);
 
 
 /*
diff --git a/src/hb-set.hh b/src/hb-set.hh
index bc26ed3..cc061a7 100644
--- a/src/hb-set.hh
+++ b/src/hb-set.hh
@@ -341,11 +341,11 @@
   {
     /* TODO perform op even if !successful. */
     if (unlikely (!successful)) return;
-    page_t *p = page_for (g);
-    if (!p)
+    page_t *page = page_for (g);
+    if (!page)
       return;
     dirty ();
-    p->del (g);
+    page->del (g);
   }
   inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
   {
@@ -357,10 +357,10 @@
   }
   inline bool has (hb_codepoint_t g) const
   {
-    const page_t *p = page_for (g);
-    if (!p)
+    const page_t *page = page_for (g);
+    if (!page)
       return false;
-    return p->has (g);
+    return page->has (g);
   }
   inline bool intersects (hb_codepoint_t first,
 			  hb_codepoint_t last) const
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 270da3d..45f3a69 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -48,7 +48,7 @@
  **/
 
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_shaper_list (void);
 #endif
 
@@ -69,7 +69,7 @@
       shaper_list[i] = shapers[i].name;
     shaper_list[i] = nullptr;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_shaper_list);
 #endif
 
@@ -85,7 +85,7 @@
   }
 } static_shaper_list;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_shaper_list (void)
 {
diff --git a/src/hb-shaper.cc b/src/hb-shaper.cc
index abea544..b10927e 100644
--- a/src/hb-shaper.cc
+++ b/src/hb-shaper.cc
@@ -35,7 +35,7 @@
 #undef HB_SHAPER_IMPLEMENT
 };
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_shapers (void);
 #endif
 
@@ -80,7 +80,7 @@
 	p = end + 1;
     }
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_shapers);
 #endif
 
@@ -96,7 +96,7 @@
   }
 } static_shapers;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_shapers (void)
 {
diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc
index 3179683..10608af 100644
--- a/src/hb-ucdn.cc
+++ b/src/hb-ucdn.cc
@@ -222,7 +222,7 @@
 }
 
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static void free_static_ucdn_funcs (void);
 #endif
 
@@ -241,7 +241,7 @@
 
     hb_unicode_funcs_make_immutable (funcs);
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_ucdn_funcs);
 #endif
 
@@ -249,7 +249,7 @@
   }
 } static_ucdn_funcs;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_ucdn_funcs (void)
 {
diff --git a/src/hb-unicode-emoji-table.hh b/src/hb-unicode-emoji-table.hh
index 41199de..1dd0b32 100644
--- a/src/hb-unicode-emoji-table.hh
+++ b/src/hb-unicode-emoji-table.hh
@@ -47,38 +47,9 @@
   {0x25FB, 0x25FE},
   {0x2600, 0x2605},
   {0x2607, 0x2612},
-  {0x2614, 0x2615},
-  {0x2616, 0x2617},
-  {0x2618, 0x2618},
-  {0x2619, 0x2619},
-  {0x261A, 0x266F},
-  {0x2670, 0x2671},
-  {0x2672, 0x267D},
-  {0x267E, 0x267F},
-  {0x2680, 0x2685},
-  {0x2690, 0x2691},
-  {0x2692, 0x269C},
-  {0x269D, 0x269D},
-  {0x269E, 0x269F},
-  {0x26A0, 0x26A1},
-  {0x26A2, 0x26B1},
-  {0x26B2, 0x26B2},
-  {0x26B3, 0x26BC},
-  {0x26BD, 0x26BF},
-  {0x26C0, 0x26C3},
-  {0x26C4, 0x26CD},
-  {0x26CE, 0x26CE},
-  {0x26CF, 0x26E1},
-  {0x26E2, 0x26E2},
-  {0x26E3, 0x26E3},
-  {0x26E4, 0x26E7},
-  {0x26E8, 0x26FF},
-  {0x2700, 0x2700},
-  {0x2701, 0x2704},
-  {0x2705, 0x2705},
-  {0x2708, 0x2709},
-  {0x270A, 0x270B},
-  {0x270C, 0x2712},
+  {0x2614, 0x2685},
+  {0x2690, 0x2705},
+  {0x2708, 0x2712},
   {0x2714, 0x2714},
   {0x2716, 0x2716},
   {0x271D, 0x271D},
@@ -105,163 +76,33 @@
   {0x303D, 0x303D},
   {0x3297, 0x3297},
   {0x3299, 0x3299},
-  {0x1F000, 0x1F02B},
-  {0x1F02C, 0x1F02F},
-  {0x1F030, 0x1F093},
-  {0x1F094, 0x1F09F},
-  {0x1F0A0, 0x1F0AE},
-  {0x1F0AF, 0x1F0B0},
-  {0x1F0B1, 0x1F0BE},
-  {0x1F0BF, 0x1F0BF},
-  {0x1F0C0, 0x1F0C0},
-  {0x1F0C1, 0x1F0CF},
-  {0x1F0D0, 0x1F0D0},
-  {0x1F0D1, 0x1F0DF},
-  {0x1F0E0, 0x1F0F5},
-  {0x1F0F6, 0x1F0FF},
+  {0x1F000, 0x1F0FF},
   {0x1F10D, 0x1F10F},
   {0x1F12F, 0x1F12F},
-  {0x1F16C, 0x1F16F},
-  {0x1F170, 0x1F171},
-  {0x1F17E, 0x1F17E},
-  {0x1F17F, 0x1F17F},
+  {0x1F16C, 0x1F171},
+  {0x1F17E, 0x1F17F},
   {0x1F18E, 0x1F18E},
   {0x1F191, 0x1F19A},
   {0x1F1AD, 0x1F1E5},
-  {0x1F201, 0x1F202},
-  {0x1F203, 0x1F20F},
+  {0x1F201, 0x1F20F},
   {0x1F21A, 0x1F21A},
   {0x1F22F, 0x1F22F},
   {0x1F232, 0x1F23A},
   {0x1F23C, 0x1F23F},
-  {0x1F249, 0x1F24F},
-  {0x1F250, 0x1F251},
-  {0x1F252, 0x1F25F},
-  {0x1F260, 0x1F265},
-  {0x1F266, 0x1F2FF},
-  {0x1F300, 0x1F320},
-  {0x1F321, 0x1F32C},
-  {0x1F32D, 0x1F32F},
-  {0x1F330, 0x1F335},
-  {0x1F336, 0x1F336},
-  {0x1F337, 0x1F37C},
-  {0x1F37D, 0x1F37D},
-  {0x1F37E, 0x1F37F},
-  {0x1F380, 0x1F393},
-  {0x1F394, 0x1F39F},
-  {0x1F3A0, 0x1F3C4},
-  {0x1F3C5, 0x1F3C5},
-  {0x1F3C6, 0x1F3CA},
-  {0x1F3CB, 0x1F3CE},
-  {0x1F3CF, 0x1F3D3},
-  {0x1F3D4, 0x1F3DF},
-  {0x1F3E0, 0x1F3F0},
-  {0x1F3F1, 0x1F3F7},
-  {0x1F3F8, 0x1F3FA},
-  {0x1F400, 0x1F43E},
-  {0x1F43F, 0x1F43F},
-  {0x1F440, 0x1F440},
-  {0x1F441, 0x1F441},
-  {0x1F442, 0x1F4F7},
-  {0x1F4F8, 0x1F4F8},
-  {0x1F4F9, 0x1F4FC},
-  {0x1F4FD, 0x1F4FE},
-  {0x1F4FF, 0x1F4FF},
-  {0x1F500, 0x1F53D},
-  {0x1F546, 0x1F54A},
-  {0x1F54B, 0x1F54F},
-  {0x1F550, 0x1F567},
-  {0x1F568, 0x1F579},
-  {0x1F57A, 0x1F57A},
-  {0x1F57B, 0x1F5A3},
-  {0x1F5A4, 0x1F5A4},
-  {0x1F5A5, 0x1F5FA},
-  {0x1F5FB, 0x1F5FF},
-  {0x1F600, 0x1F600},
-  {0x1F601, 0x1F610},
-  {0x1F611, 0x1F611},
-  {0x1F612, 0x1F614},
-  {0x1F615, 0x1F615},
-  {0x1F616, 0x1F616},
-  {0x1F617, 0x1F617},
-  {0x1F618, 0x1F618},
-  {0x1F619, 0x1F619},
-  {0x1F61A, 0x1F61A},
-  {0x1F61B, 0x1F61B},
-  {0x1F61C, 0x1F61E},
-  {0x1F61F, 0x1F61F},
-  {0x1F620, 0x1F625},
-  {0x1F626, 0x1F627},
-  {0x1F628, 0x1F62B},
-  {0x1F62C, 0x1F62C},
-  {0x1F62D, 0x1F62D},
-  {0x1F62E, 0x1F62F},
-  {0x1F630, 0x1F633},
-  {0x1F634, 0x1F634},
-  {0x1F635, 0x1F640},
-  {0x1F641, 0x1F642},
-  {0x1F643, 0x1F644},
-  {0x1F645, 0x1F64F},
-  {0x1F680, 0x1F6C5},
-  {0x1F6C6, 0x1F6CF},
-  {0x1F6D0, 0x1F6D0},
-  {0x1F6D1, 0x1F6D2},
-  {0x1F6D3, 0x1F6D4},
-  {0x1F6D5, 0x1F6DF},
-  {0x1F6E0, 0x1F6EC},
-  {0x1F6ED, 0x1F6EF},
-  {0x1F6F0, 0x1F6F3},
-  {0x1F6F4, 0x1F6F6},
-  {0x1F6F7, 0x1F6F8},
-  {0x1F6F9, 0x1F6F9},
-  {0x1F6FA, 0x1F6FF},
+  {0x1F249, 0x1F3FA},
+  {0x1F400, 0x1F53D},
+  {0x1F546, 0x1F64F},
+  {0x1F680, 0x1F6FF},
   {0x1F774, 0x1F77F},
-  {0x1F7D5, 0x1F7D8},
-  {0x1F7D9, 0x1F7FF},
+  {0x1F7D5, 0x1F7FF},
   {0x1F80C, 0x1F80F},
   {0x1F848, 0x1F84F},
   {0x1F85A, 0x1F85F},
   {0x1F888, 0x1F88F},
   {0x1F8AE, 0x1F8FF},
-  {0x1F90C, 0x1F90F},
-  {0x1F910, 0x1F918},
-  {0x1F919, 0x1F91E},
-  {0x1F91F, 0x1F91F},
-  {0x1F920, 0x1F927},
-  {0x1F928, 0x1F92F},
-  {0x1F930, 0x1F930},
-  {0x1F931, 0x1F932},
-  {0x1F933, 0x1F93A},
-  {0x1F93C, 0x1F93E},
-  {0x1F93F, 0x1F93F},
-  {0x1F940, 0x1F945},
-  {0x1F947, 0x1F94B},
-  {0x1F94C, 0x1F94C},
-  {0x1F94D, 0x1F94F},
-  {0x1F950, 0x1F95E},
-  {0x1F95F, 0x1F96B},
-  {0x1F96C, 0x1F970},
-  {0x1F971, 0x1F972},
-  {0x1F973, 0x1F976},
-  {0x1F977, 0x1F979},
-  {0x1F97A, 0x1F97A},
-  {0x1F97B, 0x1F97B},
-  {0x1F97C, 0x1F97F},
-  {0x1F980, 0x1F984},
-  {0x1F985, 0x1F991},
-  {0x1F992, 0x1F997},
-  {0x1F998, 0x1F9A2},
-  {0x1F9A3, 0x1F9AF},
-  {0x1F9B0, 0x1F9B9},
-  {0x1F9BA, 0x1F9BF},
-  {0x1F9C0, 0x1F9C0},
-  {0x1F9C1, 0x1F9C2},
-  {0x1F9C3, 0x1F9CF},
-  {0x1F9D0, 0x1F9E6},
-  {0x1F9E7, 0x1F9FF},
-  {0x1FA00, 0x1FA5F},
-  {0x1FA60, 0x1FA6D},
-  {0x1FA6E, 0x1FFFD},
+  {0x1F90C, 0x1F93A},
+  {0x1F93C, 0x1F945},
+  {0x1F947, 0x1FFFD},
 };
 
 #endif /* HB_UNICODE_EMOJI_TABLE_HH */
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index 1331704..1fae643 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -245,7 +245,7 @@
 
     funcs->init ();
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
     atexit (free_static_uniscribe_shaper_funcs);
 #endif
 
@@ -261,7 +261,7 @@
   }
 } static_uniscribe_shaper_funcs;
 
-#ifdef HB_USE_ATEXIT
+#if HB_USE_ATEXIT
 static
 void free_static_uniscribe_shaper_funcs (void)
 {
diff --git a/src/hb.hh b/src/hb.hh
index ba857ed..a40e6f2 100644
--- a/src/hb.hh
+++ b/src/hb.hh
@@ -281,7 +281,7 @@
 #  endif
 #endif
 
-#if HAVE_ATEXIT
+#if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT)
 /* atexit() is only safe to be called from shared libraries on certain
  * platforms.  Whitelist.
  * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
@@ -313,6 +313,9 @@
 #ifdef HB_NO_ATEXIT
 #  undef HB_USE_ATEXIT
 #endif
+#ifndef HB_USE_ATEXIT
+#  define HB_USE_ATEXIT 0
+#endif
 
 #define HB_STMT_START do
 #define HB_STMT_END   while (0)
diff --git a/src/test-name-table.cc b/src/test-name-table.cc
index 3330527..58c98f0 100644
--- a/src/test-name-table.cc
+++ b/src/test-name-table.cc
@@ -48,7 +48,7 @@
 
   for (unsigned int i = 0; i < count; i++)
   {
-    printf ("%d	%s	",
+    printf ("%u	%s	",
 	    entries[i].name_id,
 	    hb_language_to_string (entries[i].language));
 
diff --git a/src/test-ot-color.cc b/src/test-ot-color.cc
index 4b10e01..4050a66 100644
--- a/src/test-ot-color.cc
+++ b/src/test-ot-color.cc
@@ -54,7 +54,7 @@
     const char *data = hb_blob_get_data (blob, &length);
 
     char output_path[255];
-    sprintf (output_path, "out/svg-%d-%d.svg%s",
+    sprintf (output_path, "out/svg-%u-%u.svg%s",
 	     glyph_id,
 	     face_index,
 	     // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
@@ -108,7 +108,7 @@
 	const char *data = hb_blob_get_data (blob, &length);
 
 	char output_path[255];
-	sprintf (output_path, "out/png-%d-%d-%d.png", glyph_id, strike, face_index);
+	sprintf (output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index);
 
 	FILE *f = fopen (output_path, "wb");
 	fwrite (data, 1, length, f);
@@ -167,9 +167,8 @@
 
       // Render
       unsigned int palette_count = hb_ot_color_palette_get_count (face);
-      for (unsigned int palette = 0; palette < palette_count; palette++) {
-	char output_path[255];
-
+      for (unsigned int palette = 0; palette < palette_count; palette++)
+      {
 	unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, NULL, NULL);
 	if (!num_colors)
 	  continue;
@@ -178,7 +177,8 @@
 	hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors);
 	if (num_colors)
 	{
-	  sprintf (output_path, "out/colr-%d-%d-%d.svg", gid, palette, face_index);
+	  char output_path[255];
+	  sprintf (output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index);
 
 	  cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
 	  cairo_t *cr = cairo_create (surface);
@@ -245,7 +245,7 @@
     // Render
     {
       char output_path[255];
-      sprintf (output_path, "out/%d-%d.svg", face_index, i);
+      sprintf (output_path, "out/%u-%u.svg", face_index, i);
       cairo_surface_t *surface = cairo_svg_surface_create (output_path, extents.width, extents.height);
       cairo_t *cr = cairo_create (surface);
       cairo_set_font_face (cr, cairo_face);
diff --git a/test/api/test-buffer.c b/test/api/test-buffer.c
index 5fba3b2..64ab3db 100644
--- a/test/api/test-buffer.c
+++ b/test/api/test-buffer.c
@@ -379,14 +379,15 @@
 test_buffer_utf8_conversion (void)
 {
   hb_buffer_t *b;
-  hb_glyph_info_t *glyphs;
-  unsigned int bytes, chars, i, j, len;
+  unsigned int chars, i, j, len;
 
   b = hb_buffer_create ();
   hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
 
   for (i = 0; i < G_N_ELEMENTS (utf8_conversion_tests); i++)
   {
+    unsigned int bytes;
+    hb_glyph_info_t *glyphs;
     const utf8_conversion_test_t *test = &utf8_conversion_tests[i];
     char *escaped;
 
diff --git a/test/api/test-object.c b/test/api/test-object.c
index 02b9760..093615e 100644
--- a/test/api/test-object.c
+++ b/test/api/test-object.c
@@ -235,7 +235,7 @@
 
     {
       unsigned int j;
-      data_t data[2] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
+      data_t data[1000] = {{MAGIC0, FALSE}, {MAGIC1, FALSE}};
       deadlock_test_t deadlock_test;
 
       g_test_message ("Testing object %s", o->name);
diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c
index d6eefba..757bc1f 100644
--- a/test/api/test-ot-face.c
+++ b/test/api/test-ot-face.c
@@ -93,7 +93,7 @@
   hb_ot_name_get_utf32 (face, cp, NULL, NULL, NULL);
 
   hb_ot_var_get_axis_count (face);
-  hb_ot_var_get_axes (face, 0, NULL, NULL);
+  hb_ot_var_get_axis_infos (face, 0, NULL, NULL);
   hb_ot_var_normalize_variations (face, NULL, 0, NULL, 0);
   hb_ot_var_normalize_coords (face, 0, NULL, NULL);
 
diff --git a/test/api/test-ot-name.c b/test/api/test-ot-name.c
index 71a8727..9e88015 100644
--- a/test/api/test-ot-name.c
+++ b/test/api/test-ot-name.c
@@ -81,7 +81,7 @@
   hb_ot_name_id_t name_id = entries[3].name_id;
   g_assert_cmpuint (3, ==, name_id);
   hb_language_t lang = entries[3].language;
-  g_assert_cmpstr ("en", ==, hb_language_to_string (lang));
+  g_assert_cmpstr (hb_language_to_string (lang), ==, "en");
   char text[10];
   unsigned int text_size = 10;
   g_assert_cmpuint (27, ==, hb_ot_name_get_utf8 (face, name_id, lang, &text_size, text));
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832
new file mode 100644
index 0000000..df1556b
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5722888989048832
Binary files differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904
new file mode 100644
index 0000000..9f57f7b
--- /dev/null
+++ b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5067936541179904
Binary files differ
diff --git a/test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf b/test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf
new file mode 100644
index 0000000..5a47a39
--- /dev/null
+++ b/test/shaping/data/in-house/fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf
Binary files differ
diff --git a/test/shaping/data/in-house/tests/use-syllable.tests b/test/shaping/data/in-house/tests/use-syllable.tests
index d8f1dff..6a247ed 100644
--- a/test/shaping/data/in-house/tests/use-syllable.tests
+++ b/test/shaping/data/in-house/tests/use-syllable.tests
@@ -9,3 +9,4 @@
 ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+11042,U+11046:[brm_KA=0+754|brm_vowelEE=0@-383,0+0|brm_virama=0@-524,0+0]
 ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+11044,U+11046:[brm_KA=0+754|brm_vowelOO=0@-647,0+0|brm_virama=0@-524,0+0]
 ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+1103C:[brm_KA=0+754|brm_vowelU=0@-403,0+0]
+../fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf::U+111C8,U+111C9,U+111C9:[u111C8=0+500|u111C9=0@-500,0+0|u111C9=0@-500,0+0]