changeset 50956:25db2c8f3cf8

8199530: Upgrade to harfbuzz 1.7.6 Reviewed-by: srl, serb
author prr
date Wed, 30 May 2018 12:20:00 -0700
parents 9289c4214a35
children 204621ae8e7c
files src/java.desktop/share/native/libfontmanager/harfbuzz/hb-atomic-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.h src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-serialize.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.h src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.h src/java.desktop/share/native/libfontmanager/harfbuzz/hb-debug.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-dsalgs.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.h src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.h src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-file-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cbdt-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-cbdt-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-colr-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-cpal-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-glyf-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-head-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hhea-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hmtx-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-kern-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-base-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-common-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gdef-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gpos-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsub-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsubgpos-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.h src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-maxp-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-name-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-unicode-ranges.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-post-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-fallback.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-win1256.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hebrew.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-machine.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-table.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-khmer-machine.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-khmer-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-khmer.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar-machine.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-machine.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-table.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-fallback.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-tag.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-avar-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-fvar-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-hvar-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-mvar-table.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set-digest-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.cc src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.h src/java.desktop/share/native/libfontmanager/harfbuzz/hb-string-array.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset-glyf.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset-plan.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset.h src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode-private.hh src/java.desktop/share/native/libfontmanager/harfbuzz/hb-version.h
diffstat 85 files changed, 8181 insertions(+), 4041 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-atomic-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-atomic-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -70,6 +70,29 @@
 #define hb_atomic_ptr_impl_cmpexch(P,O,N)       (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
 
 
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
+
+typedef int hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V)           __sync_fetch_and_add (&(AI), (V))
+
+#define hb_atomic_ptr_impl_get(P)               (void *) (__sync_synchronize (), *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       __sync_bool_compare_and_swap ((P), (O), (N))
+
+
+#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
+
+#include <atomic.h>
+#include <mbarrier.h>
+
+typedef unsigned int hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V)           ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
+
+#define hb_atomic_ptr_impl_get(P)               ( ({__machine_rw_barrier ();}), (void *) *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
+
+
 #elif !defined(HB_NO_MT) && defined(__APPLE__)
 
 #include <libkern/OSAtomic.h>
@@ -96,29 +119,6 @@
 #endif
 
 
-#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
-
-typedef int hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
-#define hb_atomic_int_impl_add(AI, V)           __sync_fetch_and_add (&(AI), (V))
-
-#define hb_atomic_ptr_impl_get(P)               (void *) (__sync_synchronize (), *(P))
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)       __sync_bool_compare_and_swap ((P), (O), (N))
-
-
-#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
-
-#include <atomic.h>
-#include <mbarrier.h>
-
-typedef unsigned int hb_atomic_int_impl_t;
-#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
-#define hb_atomic_int_impl_add(AI, V)           ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
-
-#define hb_atomic_ptr_impl_get(P)               ( ({__machine_rw_barrier ();}), (void *) *(P))
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)       ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
-
-
 #elif !defined(HB_NO_MT) && defined(_AIX) && defined(__IBMCPP__)
 
 #include <builtins.h>
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.cc	Wed May 30 12:20:00 2018 -0700
@@ -26,7 +26,7 @@
 
 /* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
 #ifndef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 199309L
+#define _POSIX_C_SOURCE 200809L
 #endif
 
 #include "hb-private.hh"
@@ -171,6 +171,31 @@
 }
 
 /**
+ * hb_blob_copy_writable_or_fail:
+ * @blob: A blob.
+ *
+ * Makes a writable copy of @blob.
+ *
+ * Return value: New blob, or nullptr if allocation failed.
+ *
+ * Since: 1.8.0
+ **/
+hb_blob_t *
+hb_blob_copy_writable_or_fail (hb_blob_t *blob)
+{
+  blob = hb_blob_create (blob->data,
+                         blob->length,
+                         HB_MEMORY_MODE_DUPLICATE,
+                         nullptr,
+                         nullptr);
+
+  if (unlikely (blob == hb_blob_get_empty ()))
+    blob = nullptr;
+
+  return blob;
+}
+
+/**
  * hb_blob_get_empty:
  *
  * Returns the singleton empty blob.
@@ -222,7 +247,7 @@
  * hb_blob_destroy: (skip)
  * @blob: a blob.
  *
- * Descreases the reference count on @blob, and if it reaches zero, destroys
+ * Decreases the reference count on @blob, and if it reaches zero, destroys
  * @blob, freeing all memory, possibly calling the destroy-callback the blob
  * was created for if it has not been called already.
  *
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.h	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.h	Wed May 30 12:20:00 2018 -0700
@@ -44,7 +44,7 @@
  *   any such possibility, MODE_DUPLICATE should be used
  *   such that HarfBuzz makes a copy immediately,
  *
- * - Use MODE_READONLY otherse, unless you really really
+ * - Use MODE_READONLY otherwise, unless you really really
  *   really know what you are doing,
  *
  * - MODE_WRITABLE is appropriate if you really made a
@@ -83,6 +83,9 @@
                          unsigned int  length);
 
 HB_EXTERN hb_blob_t *
+hb_blob_copy_writable_or_fail (hb_blob_t *blob);
+
+HB_EXTERN hb_blob_t *
 hb_blob_get_empty (void);
 
 HB_EXTERN hb_blob_t *
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -35,8 +35,8 @@
 #include "hb-unicode-private.hh"
 
 
-#ifndef HB_BUFFER_MAX_EXPANSION_FACTOR
-#define HB_BUFFER_MAX_EXPANSION_FACTOR 32
+#ifndef HB_BUFFER_MAX_LEN_FACTOR
+#define HB_BUFFER_MAX_LEN_FACTOR 32
 #endif
 #ifndef HB_BUFFER_MAX_LEN_MIN
 #define HB_BUFFER_MAX_LEN_MIN 8192
@@ -45,6 +45,16 @@
 #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */
 #endif
 
+#ifndef HB_BUFFER_MAX_OPS_FACTOR
+#define HB_BUFFER_MAX_OPS_FACTOR 64
+#endif
+#ifndef HB_BUFFER_MAX_OPS_MIN
+#define HB_BUFFER_MAX_OPS_MIN 1024
+#endif
+#ifndef HB_BUFFER_MAX_OPS_DEFAULT
+#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */
+#endif
+
 static_assert ((sizeof (hb_glyph_info_t) == 20), "");
 static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), "");
 
@@ -59,6 +69,7 @@
   HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK             = 0x00000004u,
   HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT            = 0x00000008u,
   HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK            = 0x00000010u,
+  HB_BUFFER_SCRATCH_FLAG_HAS_CGJ                        = 0x00000020u,
 
   /* Reserved for complex shapers' internal use. */
   HB_BUFFER_SCRATCH_FLAG_COMPLEX0                       = 0x01000000u,
@@ -82,8 +93,9 @@
   hb_buffer_flags_t flags; /* BOT / EOT / etc. */
   hb_buffer_cluster_level_t cluster_level;
   hb_codepoint_t replacement; /* U+FFFD or something else. */
-  hb_buffer_scratch_flags_t scratch_flags; /* Have space-flallback, etc. */
+  hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
   unsigned int max_len; /* Maximum allowed len. */
+  int max_ops; /* Maximum allowed operations. */
 
   /* Buffer contents */
   hb_buffer_content_type_t content_type;
@@ -102,17 +114,6 @@
   hb_glyph_info_t     *out_info;
   hb_glyph_position_t *pos;
 
-  inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
-  inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
-
-  inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
-  inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
-
-  inline hb_glyph_info_t &prev (void) { return out_info[out_len ? out_len - 1 : 0]; }
-  inline hb_glyph_info_t prev (void) const { return out_info[out_len ? out_len - 1 : 0]; }
-
-  inline bool has_separate_output (void) const { return info != out_info; }
-
   unsigned int serial;
 
   /* Text before / after the main buffer contents.
@@ -132,6 +133,10 @@
 #ifndef HB_NDEBUG
   uint8_t allocated_var_bits;
 #endif
+
+
+  /* Methods */
+
   inline void allocate_var (unsigned int start, unsigned int count)
   {
 #ifndef HB_NDEBUG
@@ -168,8 +173,17 @@
 #endif
   }
 
+  inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; }
+  inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; }
 
-  /* Methods */
+  inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; }
+  inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; }
+
+  inline hb_glyph_info_t &prev (void) { return out_info[out_len ? out_len - 1 : 0]; }
+  inline hb_glyph_info_t prev (void) const { return out_info[out_len ? out_len - 1 : 0]; }
+
+  inline bool has_separate_output (void) const { return info != out_info; }
+
 
   HB_INTERNAL void reset (void);
   HB_INTERNAL void clear (void);
@@ -293,45 +307,44 @@
   HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
 
   static inline void
-  set_cluster (hb_glyph_info_t &info, unsigned int cluster, unsigned int mask = 0)
+  set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
   {
-    if (info.cluster != cluster)
+    if (inf.cluster != cluster)
     {
       if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
-        info.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+        inf.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
       else
-        info.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+        inf.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
     }
-    info.cluster = cluster;
+    inf.cluster = cluster;
   }
 
   inline int
-  _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *info,
+  _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos,
                                      unsigned int start, unsigned int end,
                                      unsigned int cluster) const
   {
     for (unsigned int i = start; i < end; i++)
-      cluster = MIN<unsigned int> (cluster, info[i].cluster);
+      cluster = MIN<unsigned int> (cluster, infos[i].cluster);
     return cluster;
   }
   inline void
-  _unsafe_to_break_set_mask (hb_glyph_info_t *info,
+  _unsafe_to_break_set_mask (hb_glyph_info_t *infos,
                              unsigned int start, unsigned int end,
                              unsigned int cluster)
   {
     for (unsigned int i = start; i < end; i++)
-      if (cluster != info[i].cluster)
+      if (cluster != infos[i].cluster)
       {
         scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK;
-        info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+        infos[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
       }
   }
 
   inline void
   unsafe_to_break_all (void)
   {
-    for (unsigned int i = 0; i < len; i++)
-      info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+    unsafe_to_break_impl (0, len);
   }
   inline void
   safe_to_break_all (void)
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-serialize.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-serialize.cc	Wed May 30 12:20:00 2018 -0700
@@ -109,6 +109,7 @@
                              nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
 
   *buf_consumed = 0;
+  hb_position_t x = 0, y = 0;
   for (unsigned int i = start; i < end; i++)
   {
     char b[1024];
@@ -146,9 +147,10 @@
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
     {
       p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
-                             pos[i].x_offset, pos[i].y_offset));
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
-                             pos[i].x_advance, pos[i].y_advance));
+                             x+pos[i].x_offset, y+pos[i].y_offset));
+      if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
+        p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
+                               pos[i].x_advance, pos[i].y_advance));
     }
 
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
@@ -179,6 +181,12 @@
       *buf = '\0';
     } else
       return i - start;
+
+    if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
+    {
+      x += pos[i].x_advance;
+      y += pos[i].y_advance;
+    }
   }
 
   return end - start;
@@ -199,6 +207,7 @@
                              nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
 
   *buf_consumed = 0;
+  hb_position_t x = 0, y = 0;
   for (unsigned int i = start; i < end; i++)
   {
     char b[1024];
@@ -223,13 +232,16 @@
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
     {
-      if (pos[i].x_offset || pos[i].y_offset)
-        p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset));
+      if (x+pos[i].x_offset || y+pos[i].y_offset)
+        p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
 
-      *p++ = '+';
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
-      if (pos[i].y_advance)
-        p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
+      if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
+      {
+        *p++ = '+';
+        p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
+        if (pos[i].y_advance)
+          p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
+      }
     }
 
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
@@ -255,6 +267,12 @@
       *buf = '\0';
     } else
       return i - start;
+
+    if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
+    {
+      x += pos[i].x_advance;
+      y += pos[i].y_advance;
+    }
   }
 
   return end - start;
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.cc	Wed May 30 12:20:00 2018 -0700
@@ -722,6 +722,7 @@
     return hb_buffer_get_empty ();
 
   buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
+  buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
 
   buffer->reset ();
 
@@ -749,6 +750,7 @@
     HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
     HB_BUFFER_SCRATCH_FLAG_DEFAULT,
     HB_BUFFER_MAX_LEN_DEFAULT,
+    HB_BUFFER_MAX_OPS_DEFAULT,
 
     HB_BUFFER_CONTENT_TYPE_INVALID,
     HB_SEGMENT_PROPERTIES_DEFAULT,
@@ -1931,7 +1933,7 @@
       result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH;
     if (buf_info->cluster != ref_info->cluster)
       result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH;
-    if ((buf_info->mask & HB_GLYPH_FLAG_DEFINED) != (ref_info->mask & HB_GLYPH_FLAG_DEFINED))
+    if ((buf_info->mask & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED))
       result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH;
     if (contains && ref_info->codepoint == dottedcircle_glyph)
       result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.h	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.h	Wed May 30 12:20:00 2018 -0700
@@ -71,6 +71,24 @@
   hb_var_int_t   var2;
 } hb_glyph_info_t;
 
+/**
+ * hb_glyph_flags_t:
+ * @HB_GLYPH_FLAG_UNSAFE_TO_BREAK: Indicates that if input text is broken at the
+ *                                 beginning of the cluster this glyph is part of,
+ *                                 then both sides need to be re-shaped, as the
+ *                                 result might be different.  On the flip side,
+ *                                 it means that when this flag is not present,
+ *                                 then it's safe to break the glyph-run at the
+ *                                 beginning of this cluster, and the two sides
+ *                                 represent the exact same result one would get
+ *                                 if breaking input text at the beginning of
+ *                                 this cluster and shaping the two sides
+ *                                 separately.  This can be used to optimize
+ *                                 paragraph layout, by avoiding re-shaping
+ *                                 of each line after line-breaking, or limiting
+ *                                 the reshaping to a small piece around the
+ *                                 breaking point only.
+ */
 typedef enum { /*< flags >*/
   HB_GLYPH_FLAG_UNSAFE_TO_BREAK         = 0x00000001,
 
@@ -247,13 +265,21 @@
  *                      of the text without the full context.
  * @HB_BUFFER_FLAG_EOT: flag indicating that special handling of the end of text
  *                      paragraph can be applied to this buffer, similar to
- *                      @HB_BUFFER_FLAG_EOT.
+ *                      @HB_BUFFER_FLAG_BOT.
  * @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES:
  *                      flag indication that character with Default_Ignorable
  *                      Unicode property should use the corresponding glyph
- *                      from the font, instead of hiding them (currently done
- *                      by replacing them with the space glyph and zeroing the
- *                      advance width.)
+ *                      from the font, instead of hiding them (done by
+ *                      replacing them with the space glyph and zeroing the
+ *                      advance width.)  This flag takes precedence over
+ *                      @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES.
+ * @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES:
+ *                      flag indication that character with Default_Ignorable
+ *                      Unicode property should be removed from glyph string
+ *                      instead of hiding them (done by replacing them with the
+ *                      space glyph and zeroing the advance width.)
+ *                      @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES takes
+ *                      precedence over this flag. Since: 1.8.0
  *
  * Since: 0.9.20
  */
@@ -261,7 +287,8 @@
   HB_BUFFER_FLAG_DEFAULT                        = 0x00000000u,
   HB_BUFFER_FLAG_BOT                            = 0x00000001u, /* Beginning-of-text */
   HB_BUFFER_FLAG_EOT                            = 0x00000002u, /* End-of-text */
-  HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES    = 0x00000004u
+  HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES    = 0x00000004u,
+  HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES      = 0x00000008u
 } hb_buffer_flags_t;
 
 HB_EXTERN void
@@ -412,6 +439,9 @@
  * @HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS: do not serialize glyph position information.
  * @HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES: do no serialize glyph name.
  * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents.
+ * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS: serialize glyph flags. Since: 1.5.0
+ * @HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES: do not serialize glyph advances,
+ *  glyph offsets will reflect absolute glyph positions. Since: 1.8.0
  *
  * Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs().
  *
@@ -423,7 +453,8 @@
   HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS         = 0x00000002u,
   HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES       = 0x00000004u,
   HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS        = 0x00000008u,
-  HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS          = 0x00000010u
+  HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS          = 0x00000010u,
+  HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES          = 0x00000020u
 } hb_buffer_serialize_flags_t;
 
 /**
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.cc	Wed May 30 12:20:00 2018 -0700
@@ -524,6 +524,7 @@
     case HB_SCRIPT_PSALTER_PAHLAVI:
 
     /* Unicode-8.0 additions */
+    case HB_SCRIPT_HATRAN:
     case HB_SCRIPT_OLD_HUNGARIAN:
 
     /* Unicode-9.0 additions */
@@ -784,9 +785,9 @@
     (*pp)++;
 
   /* CSS allows on/off as aliases 1/0. */
-  if (*pp - p == 2 || 0 == strncmp (p, "on", 2))
+  if (*pp - p == 2 && 0 == strncmp (p, "on", 2))
     *pv = 1;
-  else if (*pp - p == 3 || 0 == strncmp (p, "off", 2))
+  else if (*pp - p == 3 && 0 == strncmp (p, "off", 3))
     *pv = 0;
   else
     return false;
@@ -878,7 +879,7 @@
                    parse_bool (pp, end, &feature->value);
   /* CSS doesn't use equal-sign between tag and value.
    * If there was an equal-sign, then there *must* be a value.
-   * A value without an eqaul-sign is ok, but not required. */
+   * A value without an equal-sign is ok, but not required. */
   return !had_equal || had_value;
 }
 
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.cc	Wed May 30 12:20:00 2018 -0700
@@ -39,7 +39,7 @@
 #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
 
 static CGFloat
-coretext_font_size (float ptem)
+coretext_font_size_from_ptem (float ptem)
 {
   /* CoreText points are CSS pixels (96 per inch),
    * NOT typographic points (72 per inch).
@@ -49,6 +49,12 @@
   ptem *= 96.f / 72.f;
   return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem;
 }
+static float
+coretext_font_size_to_ptem (CGFloat size)
+{
+  size *= 72.f / 96.f;
+  return size <= 0.f ? 0 : size;
+}
 
 static void
 release_table_data (void *user_data)
@@ -68,7 +74,10 @@
   const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data));
   const size_t length = CFDataGetLength (cf_data);
   if (!data || !length)
+  {
+    CFRelease (cf_data);
     return nullptr;
+  }
 
   return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
                          reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)),
@@ -81,21 +90,12 @@
   CGFontRelease ((CGFontRef) data);
 }
 
-hb_face_t *
-hb_coretext_face_create (CGFontRef cg_font)
-{
-  return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
-}
 
 HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face)
 HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
-        fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size (font->ptem)) <= .5
+        fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5
 )
 
-/*
- * shaper face data
- */
-
 static CTFontDescriptorRef
 get_last_resort_font_desc (void)
 {
@@ -267,6 +267,12 @@
   CFRelease ((CGFontRef) data);
 }
 
+hb_face_t *
+hb_coretext_face_create (CGFontRef cg_font)
+{
+  return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
+}
+
 /*
  * Since: 0.9.10
  */
@@ -278,10 +284,6 @@
 }
 
 
-/*
- * shaper font data
- */
-
 hb_coretext_shaper_font_data_t *
 _hb_coretext_shaper_font_data_create (hb_font_t *font)
 {
@@ -289,7 +291,7 @@
   if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
   CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
 
-  CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size (font->ptem));
+  CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem));
 
   if (unlikely (!ct_font))
   {
@@ -306,6 +308,37 @@
   CFRelease ((CTFontRef) data);
 }
 
+/*
+ * Since: 1.7.2
+ */
+hb_font_t *
+hb_coretext_font_create (CTFontRef ct_font)
+{
+  CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr);
+  hb_face_t *face = hb_coretext_face_create (cg_font);
+  CFRelease (cg_font);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+
+  if (unlikely (hb_object_is_inert (font)))
+    return font;
+
+  hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
+
+  /* Let there be dragons here... */
+  HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font);
+
+  return font;
+}
+
+CTFontRef
+hb_coretext_font_get_ct_font (hb_font_t *font)
+{
+  if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr;
+  return (CTFontRef) HB_SHAPER_DATA_GET (font);
+}
+
+
 
 /*
  * shaper shape_plan data
@@ -328,13 +361,6 @@
 {
 }
 
-CTFontRef
-hb_coretext_font_get_ct_font (hb_font_t *font)
-{
-  if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr;
-  return (CTFontRef)HB_SHAPER_DATA_GET (font);
-}
-
 
 /*
  * shaper
@@ -854,7 +880,10 @@
                                                             kCFStringEncodingUTF8,
                                                             kCFAllocatorNull);
         if (unlikely (!lang))
+        {
+          CFRelease (attr_string);
           FAIL ("CFStringCreateWithCStringNoCopy failed");
+        }
         CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
                                         kCTLanguageAttributeName, lang);
         CFRelease (lang);
@@ -923,7 +952,10 @@
                                                     &kCFTypeDictionaryValueCallBacks);
       CFRelease (level_number);
       if (unlikely (!options))
+      {
+        CFRelease (attr_string);
         FAIL ("CFDictionaryCreate failed");
+      }
 
       CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options);
       CFRelease (options);
@@ -1000,7 +1032,7 @@
          * However, even that wouldn't work if we were passed in the CGFont to
          * construct a hb_face to begin with.
          *
-         * See: http://github.com/behdad/harfbuzz/pull/36
+         * See: http://github.com/harfbuzz/harfbuzz/pull/36
          *
          * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098
          */
@@ -1013,7 +1045,7 @@
           }
         if (!matched)
         {
-          CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
+          CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, nullptr);
           if (run_cg_font)
           {
             matched = CFEqual (run_cg_font, cg_font);
@@ -1186,7 +1218,7 @@
     }
 
     /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel,
-     * or if it does, it doesn't resepct it.  So we get runs with wrong
+     * or if it does, it doesn't respect it.  So we get runs with wrong
      * directions.  As such, disable the assert...  It wouldn't crash, but
      * cursoring will be off...
      *
@@ -1212,8 +1244,6 @@
         pos->x_offset = info->var1.i32;
         pos->y_offset = info->var2.i32;
 
-        info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
-
         info++, pos++;
       }
     else
@@ -1223,8 +1253,6 @@
         pos->x_offset = info->var1.i32;
         pos->y_offset = info->var2.i32;
 
-        info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
-
         info++, pos++;
       }
 
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.h	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.h	Wed May 30 12:20:00 2018 -0700
@@ -48,6 +48,9 @@
 HB_EXTERN hb_face_t *
 hb_coretext_face_create (CGFontRef cg_font);
 
+HB_EXTERN hb_font_t *
+hb_coretext_font_create (CTFontRef ct_font);
+
 
 HB_EXTERN CGFontRef
 hb_coretext_face_get_cg_font (hb_face_t *face);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-debug.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-debug.hh	Wed May 30 12:20:00 2018 -0700
@@ -93,7 +93,7 @@
   fprintf (stderr, "%-10s", what ? what : "");
 
   if (obj)
-    fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj);
+    fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj);
   else
     fprintf (stderr, " %*s  ", (unsigned int) (2 * sizeof (void *)), "");
 
@@ -220,13 +220,15 @@
 {}
 
 template <int max_level, typename ret_t>
-struct hb_auto_trace_t {
+struct hb_auto_trace_t
+{
   explicit inline hb_auto_trace_t (unsigned int *plevel_,
                                    const char *what_,
                                    const void *obj_,
                                    const char *func,
                                    const char *message,
-                                   ...) : plevel (plevel_), what (what_), obj (obj_), returned (false)
+                                   ...) HB_PRINTF_FUNC(6, 7)
+                                   : plevel (plevel_), what (what_), obj (obj_), returned (false)
   {
     if (plevel) ++*plevel;
 
@@ -267,10 +269,20 @@
   bool returned;
 };
 template <typename ret_t> /* Make sure we don't use hb_auto_trace_t when not tracing. */
-struct hb_auto_trace_t<0, ret_t>;
+struct hb_auto_trace_t<0, ret_t>
+{
+  explicit inline hb_auto_trace_t (unsigned int *plevel_,
+                                   const char *what_,
+                                   const void *obj_,
+                                   const char *func,
+                                   const char *message,
+                                   ...) HB_PRINTF_FUNC(6, 7) {}
+
+  inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
+};
 
 /* For disabled tracing; optimize out everything.
- * https://github.com/behdad/harfbuzz/pull/605 */
+ * https://github.com/harfbuzz/harfbuzz/pull/605 */
 template <typename ret_t>
 struct hb_no_trace_t {
   inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
@@ -343,7 +355,7 @@
 #define TRACE_CLOSURE(this) \
         hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
         (&c->debug_depth, c->get_name (), this, HB_FUNC, \
-         "")
+         " ")
 #else
 #define TRACE_CLOSURE(this) hb_no_trace_t<hb_void_t> trace HB_UNUSED
 #endif
@@ -355,7 +367,7 @@
 #define TRACE_COLLECT_GLYPHS(this) \
         hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \
         (&c->debug_depth, c->get_name (), this, HB_FUNC, \
-         "")
+         " ")
 #else
 #define TRACE_COLLECT_GLYPHS(this) hb_no_trace_t<hb_void_t> trace HB_UNUSED
 #endif
@@ -367,7 +379,7 @@
 #define TRACE_SANITIZE(this) \
         hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
         (&c->debug_depth, c->get_name (), this, HB_FUNC, \
-         "");
+         " ");
 #else
 #define TRACE_SANITIZE(this) hb_no_trace_t<bool> trace
 #endif
@@ -379,11 +391,23 @@
 #define TRACE_SERIALIZE(this) \
         hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
         (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
-         "");
+         " ");
 #else
 #define TRACE_SERIALIZE(this) hb_no_trace_t<bool> trace
 #endif
 
+#ifndef HB_DEBUG_SUBSET
+#define HB_DEBUG_SUBSET (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_SUBSET
+#define TRACE_SUBSET(this) \
+  hb_auto_trace_t<HB_DEBUG_SUBSET, bool> trace \
+  (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+   " ");
+#else
+#define TRACE_SUBSET(this) hb_no_trace_t<bool> trace
+#endif
+
 #ifndef HB_DEBUG_WOULD_APPLY
 #define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
 #endif
@@ -403,6 +427,7 @@
         HB_DEBUG_COLLECT_GLYPHS + \
         HB_DEBUG_SANITIZE + \
         HB_DEBUG_SERIALIZE + \
+  HB_DEBUG_SUBSET + \
         HB_DEBUG_WOULD_APPLY + \
         0)
 #endif
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-dsalgs.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-dsalgs.hh	Wed May 30 12:20:00 2018 -0700
@@ -76,12 +76,8 @@
 
 
 /* swap a, b iff a>b */
-#ifndef __SUNPRO_CC
 /* __restrict is same as restrict but better support on old machines */
 static int sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w,
-#else
-static int sort_r_cmpswap(char *a, char *b, size_t w,
-#endif
                           int (*compar)(const void *_a, const void *_b,
                                         void *_arg),
                           void *arg)
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.cc	Wed May 30 12:20:00 2018 -0700
@@ -170,7 +170,7 @@
   if (unlikely (!blob))
     blob = hb_blob_get_empty ();
 
-  hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
+  hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>().sanitize (hb_blob_reference (blob)), index);
 
   if (unlikely (!closure))
     return hb_face_get_empty ();
@@ -430,7 +430,7 @@
 void
 hb_face_t::load_upem (void) const
 {
-  hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head));
+  hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (reference_table (HB_OT_TAG_head));
   const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob);
   upem = head_table->get_upem ();
   hb_blob_destroy (head_blob);
@@ -474,7 +474,7 @@
 void
 hb_face_t::load_num_glyphs (void) const
 {
-  hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp));
+  hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (reference_table (HB_OT_TAG_maxp));
   const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
   num_glyphs = maxp_table->get_num_glyphs ();
   hb_blob_destroy (maxp_blob);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.h	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.h	Wed May 30 12:20:00 2018 -0700
@@ -71,7 +71,6 @@
                        hb_destroy_func_t   destroy,
                        hb_bool_t           replace);
 
-
 HB_EXTERN void *
 hb_face_get_user_data (hb_face_t          *face,
                        hb_user_data_key_t *key);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -128,6 +128,8 @@
   inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
   inline hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
   inline hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
+  inline float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
+  inline float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
   inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
   { return em_scale (v, dir_scale (direction)); }
 
@@ -541,7 +543,11 @@
   }
   inline hb_position_t em_scalef (float v, int scale)
   {
-    return (hb_position_t) (v * scale / face->get_upem ());
+    return (hb_position_t) round (v * scale / face->get_upem ());
+  }
+  inline float em_fscale (int16_t v, int scale)
+  {
+    return (float) v * scale / face->get_upem ();
   }
 };
 
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.h	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.h	Wed May 30 12:20:00 2018 -0700
@@ -456,7 +456,7 @@
 /* high-level funcs, with fallback */
 
 /* Calls either hb_font_get_nominal_glyph() if variation_selector is 0,
- * otherwise callse hb_font_get_variation_glyph(). */
+ * otherwise calls hb_font_get_variation_glyph(). */
 HB_EXTERN hb_bool_t
 hb_font_get_glyph (hb_font_t *font,
                    hb_codepoint_t unicode, hb_codepoint_t variation_selector,
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.cc	Wed May 30 12:20:00 2018 -0700
@@ -58,7 +58,7 @@
  *
  *   - In the future, we should add constructors to create fonts in font space?
  *
- *   - FT_Load_Glyph() is exteremely costly.  Do something about it?
+ *   - FT_Load_Glyph() is extremely costly.  Do something about it?
  */
 
 
@@ -635,15 +635,27 @@
     {
       if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, ft_coords))
       {
+        bool nonzero = false;
+
         for (unsigned int i = 0; i < mm_var->num_axis; ++i)
+         {
           coords[i] = ft_coords[i] >>= 2;
+          nonzero = nonzero || coords[i];
+         }
 
-        hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis);
+        if (nonzero)
+          hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis);
+        else
+          hb_font_set_var_coords_normalized (font, nullptr, 0);
       }
     }
     free (coords);
     free (ft_coords);
+#ifdef HAVE_FT_DONE_MM_VAR
+    FT_Done_MM_Var (ft_face->glyph->library, mm_var);
+#else
     free (mm_var);
+#endif
   }
 #endif
 }
@@ -747,6 +759,7 @@
     FT_Set_Transform (ft_face, &matrix, nullptr);
   }
 
+#ifdef HAVE_FT_SET_VAR_BLEND_COORDINATES
   unsigned int num_coords;
   const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
   if (num_coords)
@@ -760,6 +773,7 @@
       free (ft_coords);
     }
   }
+#endif
 
   ft_face->generic.data = blob;
   ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-file-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-file-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -30,6 +30,7 @@
 #define HB_OPEN_FILE_PRIVATE_HH
 
 #include "hb-open-type-private.hh"
+#include "hb-ot-head-table.hh"
 
 
 namespace OT {
@@ -54,7 +55,14 @@
 typedef struct TableRecord
 {
   int cmp (Tag t) const
-  { return t.cmp (tag); }
+  { return -t.cmp (tag); }
+
+  static int cmp (const void *pa, const void *pb)
+  {
+    const TableRecord *a = (const TableRecord *) pa;
+    const TableRecord *b = (const TableRecord *) pb;
+    return b->cmp (a->tag);
+  }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -64,9 +72,9 @@
 
   Tag           tag;            /* 4-byte identifier. */
   CheckSum      checkSum;       /* CheckSum for this table. */
-  ULONG         offset;         /* Offset from beginning of TrueType font
+  Offset32      offset;         /* Offset from beginning of TrueType font
                                  * file. */
-  ULONG         length;         /* Length of this table. */
+  HBUINT32      length;         /* Length of this table. */
   public:
   DEFINE_SIZE_STATIC (16);
 } OpenTypeTable;
@@ -81,7 +89,7 @@
   {
     return tables[i];
   }
-  inline unsigned int get_table_tags (unsigned int start_offset,
+  inline unsigned int get_table_tags (unsigned int  start_offset,
                                       unsigned int *table_count, /* IN/OUT */
                                       hb_tag_t     *table_tags /* OUT */) const
   {
@@ -118,6 +126,78 @@
   }
 
   public:
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         hb_tag_t sfnt_tag,
+                         Supplier<hb_tag_t> &tags,
+                         Supplier<hb_blob_t *> &blobs,
+                         unsigned int table_count)
+  {
+    TRACE_SERIALIZE (this);
+    /* Alloc 12 for the OTHeader. */
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    /* Write sfntVersion (bytes 0..3). */
+    sfnt_version.set (sfnt_tag);
+    /* Take space for numTables, searchRange, entrySelector, RangeShift
+     * and the TableRecords themselves.  */
+    if (unlikely (!tables.serialize (c, table_count))) return_trace (false);
+
+    const char *dir_end = (const char *) c->head;
+    HBUINT32 *checksum_adjustment = nullptr;
+
+    /* Write OffsetTables, alloc for and write actual table blobs. */
+    for (unsigned int i = 0; i < table_count; i++)
+    {
+      TableRecord &rec = tables.array[i];
+      hb_blob_t *blob = blobs[i];
+      rec.tag.set (tags[i]);
+      rec.length.set (hb_blob_get_length (blob));
+      rec.offset.serialize (c, this);
+
+      /* Allocate room for the table and copy it. */
+      char *start = (char *) c->allocate_size<void> (rec.length);
+      if (unlikely (!start)) {return false;}
+
+      memcpy (start, hb_blob_get_data (blob, nullptr), rec.length);
+
+      /* 4-byte allignment. */
+      if (rec.length % 4)
+        c->allocate_size<void> (4 - rec.length % 4);
+      const char *end = (const char *) c->head;
+
+      if (tags[i] == HB_OT_TAG_head && end - start >= head::static_size)
+      {
+        head *h = (head *) start;
+        checksum_adjustment = &h->checkSumAdjustment;
+        checksum_adjustment->set (0);
+      }
+
+      rec.checkSum.set_for_data (start, end - start);
+    }
+    tags += table_count;
+    blobs += table_count;
+
+    tables.qsort ();
+
+    if (checksum_adjustment)
+    {
+      CheckSum checksum;
+
+      /* The following line is a slower version of the following block. */
+      //checksum.set_for_data (this, (const char *) c->head - (const char *) this);
+      checksum.set_for_data (this, dir_end - (const char *) this);
+      for (unsigned int i = 0; i < table_count; i++)
+      {
+        TableRecord &rec = tables.array[i];
+        checksum.set (checksum + rec.checkSum);
+      }
+
+      checksum_adjustment->set (0xB1B0AFBAu - checksum);
+    }
+
+    return_trace (true);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -154,7 +234,7 @@
   Tag           ttcTag;         /* TrueType Collection ID string: 'ttcf' */
   FixedVersion<>version;        /* Version of the TTC Header (1.0),
                                  * 0x00010000u */
-  ArrayOf<LOffsetTo<OffsetTable>, ULONG>
+  ArrayOf<LOffsetTo<OffsetTable>, HBUINT32>
                 table;          /* Array of offsets to the OffsetTable for each font
                                  * from the beginning of the file */
   public:
@@ -249,6 +329,18 @@
     }
   }
 
+  inline bool serialize_single (hb_serialize_context_t *c,
+                                hb_tag_t sfnt_tag,
+                                Supplier<hb_tag_t> &tags,
+                                Supplier<hb_blob_t *> &blobs,
+                                unsigned int table_count)
+  {
+    TRACE_SERIALIZE (this);
+    assert (sfnt_tag != TTCTag);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    return_trace (u.fontFace.serialize (c, sfnt_tag, tags, blobs, table_count));
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -134,7 +134,17 @@
 
 #define HB_NULL_POOL_SIZE 264
 static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
-extern HB_INTERNAL const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)];
+
+#ifdef HB_NO_VISIBILITY
+static
+#else
+extern HB_INTERNAL
+#endif
+const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)]
+#ifdef HB_NO_VISIBILITY
+= {}
+#endif
+;
 
 /* Generic nul-content Null objects. */
 template <typename Type>
@@ -179,6 +189,12 @@
 #ifndef HB_SANITIZE_MAX_EDITS
 #define HB_SANITIZE_MAX_EDITS 32
 #endif
+#ifndef HB_SANITIZE_MAX_OPS_FACTOR
+#define HB_SANITIZE_MAX_OPS_FACTOR 8
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_MIN
+#define HB_SANITIZE_MAX_OPS_MIN 16384
+#endif
 
 struct hb_sanitize_context_t :
        hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
@@ -186,8 +202,9 @@
   inline hb_sanitize_context_t (void) :
         debug_depth (0),
         start (nullptr), end (nullptr),
-        writable (false), edit_count (0),
-        blob (nullptr) {}
+        writable (false), edit_count (0), max_ops (0),
+        blob (nullptr),
+        num_glyphs (0) {}
 
   inline const char *get_name (void) { return "SANITIZE"; }
   template <typename T, typename F>
@@ -210,6 +227,8 @@
     this->start = hb_blob_get_data (this->blob, nullptr);
     this->end = this->start + hb_blob_get_length (this->blob);
     assert (this->start <= this->end); /* Must not overflow. */
+    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;
     this->debug_depth = 0;
 
@@ -233,7 +252,10 @@
   inline bool check_range (const void *base, unsigned int len) const
   {
     const char *p = (const char *) base;
-    bool ok = this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len;
+    bool ok = this->max_ops-- > 0 &&
+              this->start <= p &&
+              p <= this->end &&
+              (unsigned int) (this->end - p) >= len;
 
     DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
        "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s",
@@ -297,7 +319,9 @@
   const char *start, *end;
   bool writable;
   unsigned int edit_count;
+  mutable int max_ops;
   hb_blob_t *blob;
+  unsigned int num_glyphs;
 };
 
 
@@ -306,8 +330,9 @@
 template <typename Type>
 struct Sanitizer
 {
-  static hb_blob_t *sanitize (hb_blob_t *blob) {
-    hb_sanitize_context_t c[1];
+  inline Sanitizer (void) {}
+
+  inline hb_blob_t *sanitize (hb_blob_t *blob) {
     bool sane;
 
     /* TODO is_sane() stuff */
@@ -370,6 +395,11 @@
     const char *base = hb_blob_get_data (blob, nullptr);
     return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
   }
+
+  inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; }
+
+  private:
+  hb_sanitize_context_t c[1];
 };
 
 
@@ -491,23 +521,25 @@
 template <typename Type>
 struct Supplier
 {
-  inline Supplier (const Type *array, unsigned int len_)
+  inline Supplier (const Type *array, unsigned int len_, unsigned int stride_=sizeof(Type))
   {
     head = array;
     len = len_;
+    stride = stride_;
   }
   inline const Type operator [] (unsigned int i) const
   {
     if (unlikely (i >= len)) return Type ();
-    return head[i];
+    return * (const Type *) (const void *) ((const char *) head + stride * i);
   }
 
-  inline void advance (unsigned int count)
+  inline Supplier<Type> & operator += (unsigned int count)
   {
     if (unlikely (count > len))
       count = len;
     len -= count;
-    head += count;
+    head = (const Type *) (const void *) ((const char *) head + stride * count);
+    return *this;
   }
 
   private:
@@ -515,12 +547,11 @@
   inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
 
   unsigned int len;
+  unsigned int stride;
   const Type *head;
 };
 
 
-
-
 /*
  *
  * The OpenType Font File: Data Types
@@ -635,23 +666,22 @@
   DEFINE_SIZE_STATIC (Size);
 };
 
-typedef IntType<int8_t,   1> CHAR;      /* 8-bit signed integer. */
-typedef IntType<uint8_t,  1> BYTE;      /* 8-bit unsigned integer. */
-typedef IntType<int8_t,   1> INT8;      /* 8-bit signed integer. */
-typedef IntType<uint16_t, 2> USHORT;    /* 16-bit unsigned integer. */
-typedef IntType<int16_t,  2> SHORT;     /* 16-bit signed integer. */
-typedef IntType<uint32_t, 4> ULONG;     /* 32-bit unsigned integer. */
-typedef IntType<int32_t,  4> LONG;      /* 32-bit signed integer. */
+typedef IntType<uint8_t,  1> HBUINT8;   /* 8-bit unsigned integer. */
+typedef IntType<int8_t,   1> HBINT8;    /* 8-bit signed integer. */
+typedef IntType<uint16_t, 2> HBUINT16;  /* 16-bit unsigned integer. */
+typedef IntType<int16_t,  2> HBINT16;   /* 16-bit signed integer. */
+typedef IntType<uint32_t, 4> HBUINT32;  /* 32-bit unsigned integer. */
+typedef IntType<int32_t,  4> HBINT32;   /* 32-bit signed integer. */
 typedef IntType<uint32_t, 3> UINT24;    /* 24-bit unsigned integer. */
 
-/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
-typedef SHORT FWORD;
+/* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
+typedef HBINT16 FWORD;
 
-/* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
-typedef USHORT UFWORD;
+/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
+typedef HBUINT16 UFWORD;
 
 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
-struct F2DOT14 : SHORT
+struct F2DOT14 : HBINT16
 {
   //inline float to_float (void) const { return ???; }
   //inline void set_float (float f) { v.set (f * ???); }
@@ -660,10 +690,10 @@
 };
 
 /* 32-bit signed fixed-point number (16.16). */
-struct Fixed: LONG
+struct Fixed: HBINT32
 {
-  //inline float to_float (void) const { return ???; }
-  //inline void set_float (float f) { v.set (f * ???); }
+  inline float to_float (void) const { return ((int32_t) v) / 65536.0; }
+  inline void set_float (float f) { v.set (round (f * 65536.0)); }
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -678,15 +708,15 @@
     return_trace (likely (c->check_struct (this)));
   }
   protected:
-  LONG major;
-  ULONG minor;
+  HBINT32 major;
+  HBUINT32 minor;
   public:
   DEFINE_SIZE_STATIC (8);
 };
 
 /* Array of four uint8s (length = 32 bits) used to identify a script, language
  * system, feature, or baseline */
-struct Tag : ULONG
+struct Tag : HBUINT32
 {
   /* What the char* converters return is NOT nul-terminated.  Print using "%.4s" */
   inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
@@ -697,32 +727,44 @@
 DEFINE_NULL_DATA (Tag, "    ");
 
 /* Glyph index number, same as uint16 (length = 16 bits) */
-typedef USHORT GlyphID;
+typedef HBUINT16 GlyphID;
 
 /* Script/language-system/feature index */
-struct Index : USHORT {
+struct Index : HBUINT16 {
   static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
 };
 DEFINE_NULL_DATA (Index, "\xff\xff");
 
 /* Offset, Null offset = 0 */
-template <typename Type=USHORT>
+template <typename Type>
 struct Offset : Type
 {
   inline bool is_null (void) const { return 0 == *this; }
+
+  inline void *serialize (hb_serialize_context_t *c, const void *base)
+  {
+    void *t = c->start_embed<void> ();
+    this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
+    return t;
+  }
+
   public:
   DEFINE_SIZE_STATIC (sizeof(Type));
 };
 
+typedef Offset<HBUINT16> Offset16;
+typedef Offset<HBUINT32> Offset32;
+
 
 /* CheckSum */
-struct CheckSum : ULONG
+struct CheckSum : HBUINT32
 {
   /* This is reference implementation from the spec. */
-  static inline uint32_t CalcTableChecksum (const ULONG *Table, uint32_t Length)
+  static inline uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length)
   {
     uint32_t Sum = 0L;
-    const ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size;
+    assert (0 == (Length & 3));
+    const HBUINT32 *EndPtr = Table + Length / HBUINT32::static_size;
 
     while (Table < EndPtr)
       Sum += *Table++;
@@ -731,7 +773,7 @@
 
   /* Note: data should be 4byte aligned and have 4byte padding at the end. */
   inline void set_for_data (const void *data, unsigned int length)
-  { set (CalcTableChecksum ((const ULONG *) data, length)); }
+  { set (CalcTableChecksum ((const HBUINT32 *) data, length)); }
 
   public:
   DEFINE_SIZE_STATIC (4);
@@ -742,7 +784,7 @@
  * Version Numbers
  */
 
-template <typename FixedType=USHORT>
+template <typename FixedType=HBUINT16>
 struct FixedVersion
 {
   inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; }
@@ -766,7 +808,7 @@
  * Use: (base+offset)
  */
 
-template <typename Type, typename OffsetType=USHORT>
+template <typename Type, typename OffsetType=HBUINT16>
 struct OffsetTo : Offset<OffsetType>
 {
   inline const Type& operator () (const void *base) const
@@ -778,9 +820,7 @@
 
   inline Type& serialize (hb_serialize_context_t *c, const void *base)
   {
-    Type *t = c->start_embed<Type> ();
-    this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
-    return *t;
+    return * (Type *) Offset<OffsetType>::serialize (c, base);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
@@ -811,7 +851,7 @@
   }
   DEFINE_SIZE_STATIC (sizeof(OffsetType));
 };
-template <typename Type> struct LOffsetTo : OffsetTo<Type, ULONG> {};
+template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {};
 template <typename Base, typename OffsetType, typename Type>
 static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
 template <typename Base, typename OffsetType, typename Type>
@@ -823,7 +863,7 @@
  */
 
 /* An array with a number of elements. */
-template <typename Type, typename LenType=USHORT>
+template <typename Type, typename LenType=HBUINT16>
 struct ArrayOf
 {
   const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
@@ -868,7 +908,7 @@
     if (unlikely (!serialize (c, items_len))) return_trace (false);
     for (unsigned int i = 0; i < items_len; i++)
       array[i] = items[i];
-    items.advance (items_len);
+    items += items_len;
     return_trace (true);
   }
 
@@ -920,6 +960,11 @@
     return -1;
   }
 
+  inline void qsort (void)
+  {
+    ::qsort (array, len, sizeof (Type), Type::cmp);
+  }
+
   private:
   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
   {
@@ -933,10 +978,10 @@
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), array);
 };
-template <typename Type> struct LArrayOf : ArrayOf<Type, ULONG> {};
+template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
 
 /* Array of Offset's */
-template <typename Type, typename OffsetType=USHORT>
+template <typename Type, typename OffsetType=HBUINT16>
 struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {};
 
 /* Array of offsets relative to the beginning of the array itself. */
@@ -964,7 +1009,7 @@
 
 
 /* An array starting at second element. */
-template <typename Type, typename LenType=USHORT>
+template <typename Type, typename LenType=HBUINT16>
 struct HeadlessArrayOf
 {
   inline const Type& operator [] (unsigned int i) const
@@ -986,7 +1031,7 @@
     if (unlikely (!c->extend (*this))) return_trace (false);
     for (unsigned int i = 0; i < items_len - 1; i++)
       array[i] = items[i];
-    items.advance (items_len - 1);
+    items += items_len - 1;
     return_trace (true);
   }
 
@@ -1026,19 +1071,19 @@
 /*
  * An array with sorted elements.  Supports binary searching.
  */
-template <typename Type, typename LenType=USHORT>
+template <typename Type, typename LenType=HBUINT16>
 struct SortedArrayOf : ArrayOf<Type, LenType>
 {
   template <typename SearchType>
   inline int bsearch (const SearchType &x) const
   {
     /* Hand-coded bsearch here since this is in the hot inner loop. */
-    const Type *array = this->array;
+    const Type *arr = this->array;
     int min = 0, max = (int) this->len - 1;
     while (min <= max)
     {
       int mid = (min + max) / 2;
-      int c = array[mid].cmp (x);
+      int c = arr[mid].cmp (x);
       if (c < 0)
         max = mid - 1;
       else if (c > 0)
@@ -1064,11 +1109,22 @@
     return_trace (c->check_struct (this));
   }
 
+  inline void set (unsigned int v)
+  {
+    len.set (v);
+    assert (len == v);
+    entrySelectorZ.set (MAX (1u, _hb_bit_storage (v)) - 1);
+    searchRangeZ.set (16 * (1u << entrySelectorZ));
+    rangeShiftZ.set (v * 16 > searchRangeZ
+                     ? 16 * v - searchRangeZ
+                     : 0);
+  }
+
   protected:
-  USHORT        len;
-  USHORT        searchRangeZ;
-  USHORT        entrySelectorZ;
-  USHORT        rangeShiftZ;
+  HBUINT16      len;
+  HBUINT16      searchRangeZ;
+  HBUINT16      entrySelectorZ;
+  HBUINT16      rangeShiftZ;
 
   public:
   DEFINE_SIZE_STATIC (8);
@@ -1137,8 +1193,8 @@
   inline void init (hb_face_t *face_)
   {
     face = face_;
+    blob = nullptr;
     instance = nullptr;
-    blob = nullptr;
   }
 
   inline void fini (void)
@@ -1152,7 +1208,7 @@
     T *p = (T *) hb_atomic_ptr_get (&instance);
     if (unlikely (!p))
     {
-      hb_blob_t *blob_ = OT::Sanitizer<T>::sanitize (face->reference_table (T::tableTag));
+      hb_blob_t *blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
       p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_));
       if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p))
       {
@@ -1169,10 +1225,10 @@
     return get();
   }
 
+  hb_face_t *face;
+  mutable hb_blob_t *blob;
   private:
-  hb_face_t *face;
-  T *instance;
-  mutable hb_blob_t *blob;
+  mutable T *instance;
 };
 
 
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cbdt-table.hh	Wed May 30 08:10:41 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,384 +0,0 @@
-/*
- * Copyright © 2016  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Seigo Nonaka
- */
-
-#ifndef HB_OT_CBDT_TABLE_HH
-#define HB_OT_CBDT_TABLE_HH
-
-#include "hb-open-type-private.hh"
-
-namespace OT {
-
-struct SmallGlyphMetrics
-{
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  inline void get_extents (hb_glyph_extents_t *extents) const
-  {
-    extents->x_bearing = bearingX;
-    extents->y_bearing = bearingY;
-    extents->width = width;
-    extents->height = -height;
-  }
-
-  BYTE height;
-  BYTE width;
-  CHAR bearingX;
-  CHAR bearingY;
-  BYTE advance;
-
-  DEFINE_SIZE_STATIC(5);
-};
-
-struct BigGlyphMetrics : SmallGlyphMetrics
-{
-  CHAR vertBearingX;
-  CHAR vertBearingY;
-  BYTE vertAdvance;
-
-  DEFINE_SIZE_STATIC(8);
-};
-
-struct SBitLineMetrics
-{
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  CHAR ascender;
-  CHAR decender;
-  BYTE widthMax;
-  CHAR caretSlopeNumerator;
-  CHAR caretSlopeDenominator;
-  CHAR caretOffset;
-  CHAR minOriginSB;
-  CHAR minAdvanceSB;
-  CHAR maxBeforeBL;
-  CHAR minAfterBL;
-  CHAR padding1;
-  CHAR padding2;
-
-  DEFINE_SIZE_STATIC(12);
-};
-
-
-/*
- * Index Subtables.
- */
-
-struct IndexSubtableHeader
-{
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this));
-  }
-
-  USHORT indexFormat;
-  USHORT imageFormat;
-  ULONG imageDataOffset;
-
-  DEFINE_SIZE_STATIC(8);
-};
-
-template <typename OffsetType>
-struct IndexSubtableFormat1Or3
-{
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1));
-  }
-
-  bool get_image_data (unsigned int idx,
-                       unsigned int *offset,
-                       unsigned int *length) const
-  {
-    if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
-      return false;
-
-    *offset = header.imageDataOffset + offsetArrayZ[idx];
-    *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
-    return true;
-  }
-
-  IndexSubtableHeader header;
-  Offset<OffsetType> offsetArrayZ[VAR];
-
-  DEFINE_SIZE_ARRAY(8, offsetArrayZ);
-};
-
-struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<ULONG> {};
-struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<USHORT> {};
-
-struct IndexSubtable
-{
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
-  {
-    TRACE_SANITIZE (this);
-    if (!u.header.sanitize (c)) return_trace (false);
-    switch (u.header.indexFormat) {
-    case 1: return_trace (u.format1.sanitize (c, glyph_count));
-    case 3: return_trace (u.format3.sanitize (c, glyph_count));
-    default:return_trace (true);
-    }
-  }
-
-  inline bool get_extents (hb_glyph_extents_t *extents) const
-  {
-    switch (u.header.indexFormat) {
-    case 2: case 5: /* TODO */
-    case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
-    default:return (false);
-    }
-  }
-
-  bool get_image_data (unsigned int idx,
-                       unsigned int *offset,
-                       unsigned int *length,
-                       unsigned int *format) const
-  {
-    *format = u.header.imageFormat;
-    switch (u.header.indexFormat) {
-    case 1: return u.format1.get_image_data (idx, offset, length);
-    case 3: return u.format3.get_image_data (idx, offset, length);
-    default: return false;
-    }
-  }
-
-  protected:
-  union {
-  IndexSubtableHeader   header;
-  IndexSubtableFormat1  format1;
-  IndexSubtableFormat3  format3;
-  /* TODO: Format 2, 4, 5. */
-  } u;
-  public:
-  DEFINE_SIZE_UNION (8, header);
-};
-
-struct IndexSubtableRecord
-{
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  firstGlyphIndex <= lastGlyphIndex &&
-                  offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1));
-  }
-
-  inline bool get_extents (hb_glyph_extents_t *extents) const
-  {
-    return (this+offsetToSubtable).get_extents (extents);
-  }
-
-  bool get_image_data (unsigned int gid,
-                       unsigned int *offset,
-                       unsigned int *length,
-                       unsigned int *format) const
-  {
-    if (gid < firstGlyphIndex || gid > lastGlyphIndex)
-    {
-      return false;
-    }
-    return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
-                                                   offset, length, format);
-  }
-
-  USHORT firstGlyphIndex;
-  USHORT lastGlyphIndex;
-  LOffsetTo<IndexSubtable> offsetToSubtable;
-
-  DEFINE_SIZE_STATIC(8);
-};
-
-struct IndexSubtableArray
-{
-  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count)))
-      return_trace (false);
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
-        return_trace (false);
-    return_trace (true);
-  }
-
-  public:
-  const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
-  {
-    for (unsigned int i = 0; i < numTables; ++i)
-    {
-      unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
-      unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
-      if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
-        return &indexSubtablesZ[i];
-      }
-    }
-    return nullptr;
-  }
-
-  protected:
-  IndexSubtableRecord indexSubtablesZ[VAR];
-
-  public:
-  DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
-};
-
-struct BitmapSizeTable
-{
-  friend struct CBLC;
-
-  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
-                  c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) &&
-                  horizontal.sanitize (c) &&
-                  vertical.sanitize (c));
-  }
-
-  const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const
-  {
-    return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
-  }
-
-  protected:
-  LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset;
-  ULONG indexTablesSize;
-  ULONG numberOfIndexSubtables;
-  ULONG colorRef;
-  SBitLineMetrics horizontal;
-  SBitLineMetrics vertical;
-  USHORT startGlyphIndex;
-  USHORT endGlyphIndex;
-  BYTE ppemX;
-  BYTE ppemY;
-  BYTE bitDepth;
-  CHAR flags;
-
-public:
-  DEFINE_SIZE_STATIC(48);
-};
-
-
-/*
- * Glyph Bitmap Data Formats.
- */
-
-struct GlyphBitmapDataFormat17
-{
-  SmallGlyphMetrics glyphMetrics;
-  ULONG dataLen;
-  BYTE dataZ[VAR];
-
-  DEFINE_SIZE_ARRAY(9, dataZ);
-};
-
-
-/*
- * CBLC -- Color Bitmap Location Table
- */
-
-#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
-
-struct CBLC
-{
-  static const hb_tag_t tableTag = HB_OT_TAG_CBLC;
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  likely (version.major == 2 || version.major == 3) &&
-                  sizeTables.sanitize (c, this));
-  }
-
-  public:
-  const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
-                                         unsigned int *x_ppem, unsigned int *y_ppem) const
-  {
-    /* TODO: Make it possible to select strike. */
-
-    unsigned int count = sizeTables.len;
-    for (uint32_t i = 0; i < count; ++i)
-    {
-      unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex;
-      unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex;
-      if (startGlyphIndex <= glyph && glyph <= endGlyphIndex)
-      {
-        *x_ppem = sizeTables[i].ppemX;
-        *y_ppem = sizeTables[i].ppemY;
-        return sizeTables[i].find_table (glyph, this);
-      }
-    }
-
-    return nullptr;
-  }
-
-  protected:
-  FixedVersion<>                version;
-  LArrayOf<BitmapSizeTable>     sizeTables;
-
-  public:
-  DEFINE_SIZE_ARRAY(8, sizeTables);
-};
-
-/*
- * CBDT -- Color Bitmap Data Table
- */
-#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
-
-struct CBDT
-{
-  static const hb_tag_t tableTag = HB_OT_TAG_CBDT;
-
-  inline bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  likely (version.major == 2 || version.major == 3));
-  }
-
-  protected:
-  FixedVersion<>version;
-  BYTE dataZ[VAR];
-
-  public:
-  DEFINE_SIZE_ARRAY(4, dataZ);
-};
-
-} /* namespace OT */
-
-#endif /* HB_OT_CBDT_TABLE_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -28,7 +28,7 @@
 #define HB_OT_CMAP_TABLE_HH
 
 #include "hb-open-type-private.hh"
-
+#include "hb-subset-plan.hh"
 
 namespace OT {
 
@@ -58,10 +58,10 @@
   }
 
   protected:
-  USHORT        format;         /* Format number is set to 0. */
-  USHORT        lengthZ;        /* Byte length of this subtable. */
-  USHORT        languageZ;      /* Ignore. */
-  BYTE          glyphIdArray[256];/* An array that maps character
+  HBUINT16      format;         /* Format number is set to 0. */
+  HBUINT16      lengthZ;        /* Byte length of this subtable. */
+  HBUINT16      languageZ;      /* Ignore. */
+  HBUINT8       glyphIdArray[256];/* An array that maps character
                                  * code to glyph index values. */
   public:
   DEFINE_SIZE_STATIC (6 + 256);
@@ -88,8 +88,8 @@
 
       /* Custom two-array bsearch. */
       int min = 0, max = (int) thiz->segCount - 1;
-      const USHORT *startCount = thiz->startCount;
-      const USHORT *endCount = thiz->endCount;
+      const HBUINT16 *startCount = thiz->startCount;
+      const HBUINT16 *endCount = thiz->endCount;
       unsigned int i;
       while (min <= max)
       {
@@ -127,11 +127,11 @@
       return true;
     }
 
-    const USHORT *endCount;
-    const USHORT *startCount;
-    const USHORT *idDelta;
-    const USHORT *idRangeOffset;
-    const USHORT *glyphIdArray;
+    const HBUINT16 *endCount;
+    const HBUINT16 *startCount;
+    const HBUINT16 *idDelta;
+    const HBUINT16 *idRangeOffset;
+    const HBUINT16 *glyphIdArray;
     unsigned int segCount;
     unsigned int glyphIdArrayLength;
   };
@@ -165,24 +165,24 @@
   }
 
   protected:
-  USHORT        format;         /* Format number is set to 4. */
-  USHORT        length;         /* This is the length in bytes of the
+  HBUINT16      format;         /* Format number is set to 4. */
+  HBUINT16      length;         /* This is the length in bytes of the
                                  * subtable. */
-  USHORT        languageZ;      /* Ignore. */
-  USHORT        segCountX2;     /* 2 x segCount. */
-  USHORT        searchRangeZ;   /* 2 * (2**floor(log2(segCount))) */
-  USHORT        entrySelectorZ; /* log2(searchRange/2) */
-  USHORT        rangeShiftZ;    /* 2 x segCount - searchRange */
+  HBUINT16      languageZ;      /* Ignore. */
+  HBUINT16      segCountX2;     /* 2 x segCount. */
+  HBUINT16      searchRangeZ;   /* 2 * (2**floor(log2(segCount))) */
+  HBUINT16      entrySelectorZ; /* log2(searchRange/2) */
+  HBUINT16      rangeShiftZ;    /* 2 x segCount - searchRange */
 
-  USHORT        values[VAR];
+  HBUINT16      values[VAR];
 #if 0
-  USHORT        endCount[segCount];     /* End characterCode for each segment,
+  HBUINT16      endCount[segCount];     /* End characterCode for each segment,
                                          * last=0xFFFFu. */
-  USHORT        reservedPad;            /* Set to 0. */
-  USHORT        startCount[segCount];   /* Start character code for each segment. */
-  SHORT         idDelta[segCount];      /* Delta for all character codes in segment. */
-  USHORT        idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
-  USHORT        glyphIdArray[VAR];      /* Glyph index array (arbitrary length) */
+  HBUINT16      reservedPad;            /* Set to 0. */
+  HBUINT16      startCount[segCount];   /* Start character code for each segment. */
+  HBINT16               idDelta[segCount];      /* Delta for all character codes in segment. */
+  HBUINT16      idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
+  HBUINT16      glyphIdArray[VAR];      /* Glyph index array (arbitrary length) */
 #endif
 
   public:
@@ -193,6 +193,7 @@
 {
   friend struct CmapSubtableFormat12;
   friend struct CmapSubtableFormat13;
+  friend struct cmap;
 
   int cmp (hb_codepoint_t codepoint) const
   {
@@ -208,9 +209,9 @@
   }
 
   private:
-  ULONG         startCharCode;  /* First character code in this group. */
-  ULONG         endCharCode;    /* Last character code in this group. */
-  ULONG         glyphID;        /* Glyph index; interpretation depends on
+  HBUINT32              startCharCode;  /* First character code in this group. */
+  HBUINT32              endCharCode;    /* Last character code in this group. */
+  HBUINT32              glyphID;        /* Glyph index; interpretation depends on
                                  * subtable format. */
   public:
   DEFINE_SIZE_STATIC (12);
@@ -247,12 +248,14 @@
   DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray);
 };
 
-struct CmapSubtableFormat6  : CmapSubtableTrimmed<USHORT> {};
-struct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {};
+struct CmapSubtableFormat6  : CmapSubtableTrimmed<HBUINT16> {};
+struct CmapSubtableFormat10 : CmapSubtableTrimmed<HBUINT32 > {};
 
 template <typename T>
 struct CmapSubtableLongSegmented
 {
+  friend struct cmap;
+
   inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
   {
     int i = groups.bsearch (codepoint);
@@ -268,12 +271,22 @@
     return_trace (c->check_struct (this) && groups.sanitize (c));
   }
 
+  inline bool serialize (hb_serialize_context_t *c,
+                         hb_prealloced_array_t<CmapSubtableLongGroup> &group_data)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    Supplier<CmapSubtableLongGroup> supplier (group_data.array, group_data.len);
+    if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false);
+    return true;
+  }
+
   protected:
-  USHORT        format;         /* Subtable format; set to 12. */
-  USHORT        reservedZ;      /* Reserved; set to 0. */
-  ULONG         lengthZ;        /* Byte length of this subtable. */
-  ULONG         languageZ;      /* Ignore. */
-  SortedArrayOf<CmapSubtableLongGroup, ULONG>
+  HBUINT16      format;         /* Subtable format; set to 12. */
+  HBUINT16      reservedZ;      /* Reserved; set to 0. */
+  HBUINT32              lengthZ;        /* Byte length of this subtable. */
+  HBUINT32              languageZ;      /* Ignore. */
+  SortedArrayOf<CmapSubtableLongGroup, HBUINT32>
                 groups;         /* Groupings. */
   public:
   DEFINE_SIZE_ARRAY (16, groups);
@@ -316,13 +329,13 @@
   }
 
   UINT24        startUnicodeValue;      /* First value in this range. */
-  BYTE          additionalCount;        /* Number of additional values in this
+  HBUINT8               additionalCount;        /* Number of additional values in this
                                          * range. */
   public:
   DEFINE_SIZE_STATIC (4);
 };
 
-typedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS;
+typedef SortedArrayOf<UnicodeValueRange, HBUINT32> DefaultUVS;
 
 struct UVSMapping
 {
@@ -343,7 +356,7 @@
   DEFINE_SIZE_STATIC (5);
 };
 
-typedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS;
+typedef SortedArrayOf<UVSMapping, HBUINT32> NonDefaultUVS;
 
 struct VariationSelectorRecord
 {
@@ -405,9 +418,9 @@
   }
 
   protected:
-  USHORT        format;         /* Format number is set to 14. */
-  ULONG         lengthZ;        /* Byte length of this subtable. */
-  SortedArrayOf<VariationSelectorRecord, ULONG>
+  HBUINT16      format;         /* Format number is set to 14. */
+  HBUINT32              lengthZ;        /* Byte length of this subtable. */
+  SortedArrayOf<VariationSelectorRecord, HBUINT32>
                 record;         /* Variation selector records; sorted
                                  * in increasing order of `varSelector'. */
   public:
@@ -422,12 +435,12 @@
                          hb_codepoint_t *glyph) const
   {
     switch (u.format) {
-    case  0: return u.format0 .get_glyph(codepoint, glyph);
-    case  4: return u.format4 .get_glyph(codepoint, glyph);
-    case  6: return u.format6 .get_glyph(codepoint, glyph);
-    case 10: return u.format10.get_glyph(codepoint, glyph);
-    case 12: return u.format12.get_glyph(codepoint, glyph);
-    case 13: return u.format13.get_glyph(codepoint, glyph);
+    case  0: return u.format0 .get_glyph (codepoint, glyph);
+    case  4: return u.format4 .get_glyph (codepoint, glyph);
+    case  6: return u.format6 .get_glyph (codepoint, glyph);
+    case 10: return u.format10.get_glyph (codepoint, glyph);
+    case 12: return u.format12.get_glyph (codepoint, glyph);
+    case 13: return u.format13.get_glyph (codepoint, glyph);
     case 14:
     default: return false;
     }
@@ -451,7 +464,7 @@
 
   public:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   CmapSubtableFormat0   format0;
   CmapSubtableFormat4   format4;
   CmapSubtableFormat6   format6;
@@ -484,8 +497,8 @@
                   subtable.sanitize (c, base));
   }
 
-  USHORT        platformID;     /* Platform ID. */
-  USHORT        encodingID;     /* Platform-specific encoding ID. */
+  HBUINT16      platformID;     /* Platform ID. */
+  HBUINT16      encodingID;     /* Platform-specific encoding ID. */
   LOffsetTo<CmapSubtable>
                 subtable;       /* Byte offset from beginning of table to the subtable for this encoding. */
   public:
@@ -496,6 +509,254 @@
 {
   static const hb_tag_t tableTag        = HB_OT_TAG_cmap;
 
+  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 populate_groups (hb_subset_plan_t *plan,
+                               hb_prealloced_array_t<CmapSubtableLongGroup> *groups) const
+  {
+    CmapSubtableLongGroup *group = nullptr;
+    for (unsigned int i = 0; i < plan->codepoints.len; i++) {
+
+      hb_codepoint_t cp = plan->codepoints[i];
+      if (!group || cp - 1 != group->endCharCode)
+      {
+        group = groups->push ();
+        group->startCharCode.set (cp);
+        group->endCharCode.set (cp);
+        hb_codepoint_t new_gid;
+        if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid)))
+        {
+          DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
+          return false;
+        }
+        group->glyphID.set (new_gid);
+      } else
+      {
+        group->endCharCode.set (cp);
+      }
+    }
+
+    DEBUG_MSG(SUBSET, nullptr, "cmap");
+    for (unsigned int i = 0; i < groups->len; i++) {
+      CmapSubtableLongGroup& group = (*groups)[i];
+      DEBUG_MSG(SUBSET, nullptr, "  %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode));
+    }
+
+    return true;
+  }
+
+  inline bool _subset (hb_prealloced_array_t<CmapSubtableLongGroup> &groups,
+                       size_t dest_sz,
+                       void *dest) const
+  {
+    hb_serialize_context_t c (dest, dest_sz);
+
+    OT::cmap *cmap = c.start_serialize<OT::cmap> ();
+    if (unlikely (!c.extend_min (*cmap)))
+    {
+      return false;
+    }
+
+    cmap->version.set (0);
+
+    if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 1))) return false;
+
+    EncodingRecord &rec = cmap->encodingRecord[0];
+    rec.platformID.set (3); // Windows
+    rec.encodingID.set (10); // Unicode UCS-4
+
+    /* capture offset to subtable */
+    CmapSubtable &subtable = rec.subtable.serialize (&c, cmap);
+
+    subtable.u.format.set (12);
+
+    CmapSubtableFormat12 &format12 = subtable.u.format12;
+    if (unlikely (!c.extend_min (format12))) return false;
+
+    format12.format.set (12);
+    format12.reservedZ.set (0);
+    format12.lengthZ.set (16 + 12 * groups.len);
+
+    if (unlikely (!format12.serialize (&c, groups))) return false;
+
+    c.end_serialize ();
+
+    return true;
+  }
+
+  inline bool subset (hb_subset_plan_t *plan) const
+  {
+    hb_auto_array_t<CmapSubtableLongGroup> groups;
+
+    if (unlikely (!populate_groups (plan, &groups))) return false;
+
+    // We now know how big our blob needs to be
+    // TODO use APIs from the structs to get size?
+    size_t dest_sz = 4 // header
+                   + 8 // 1 EncodingRecord
+                   + 16 // Format 12 header
+                   + 12 * groups.len; // SequentialMapGroup records
+    void *dest = malloc (dest_sz);
+    if (unlikely (!dest)) {
+      DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz);
+      return false;
+    }
+
+    if (unlikely (!_subset (groups, dest_sz, dest)))
+    {
+      free (dest);
+      return false;
+    }
+
+    // all done, write the blob into dest
+    hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest,
+                                            dest_sz,
+                                            HB_MEMORY_MODE_READONLY,
+                                            dest,
+                                            free);
+    bool result =  hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime);
+    hb_blob_destroy (cmap_prime);
+    return result;
+  }
+
+  struct accelerator_t
+  {
+    inline void init (hb_face_t *face)
+    {
+      this->blob = OT::Sanitizer<OT::cmap>().sanitize (face->reference_table (HB_OT_TAG_cmap));
+      const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
+      const OT::CmapSubtable *subtable = nullptr;
+      const OT::CmapSubtableFormat14 *subtable_uvs = nullptr;
+
+      bool symbol = false;
+      /* 32-bit subtables. */
+      if (!subtable) subtable = cmap->find_subtable (3, 10);
+      if (!subtable) subtable = cmap->find_subtable (0, 6);
+      if (!subtable) subtable = cmap->find_subtable (0, 4);
+      /* 16-bit subtables. */
+      if (!subtable) subtable = cmap->find_subtable (3, 1);
+      if (!subtable) subtable = cmap->find_subtable (0, 3);
+      if (!subtable) subtable = cmap->find_subtable (0, 2);
+      if (!subtable) subtable = cmap->find_subtable (0, 1);
+      if (!subtable) subtable = cmap->find_subtable (0, 0);
+      if (!subtable)
+      {
+        subtable = cmap->find_subtable (3, 0);
+        if (subtable) symbol = true;
+      }
+      /* Meh. */
+      if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
+
+      /* UVS subtable. */
+      if (!subtable_uvs)
+      {
+        const OT::CmapSubtable *st = cmap->find_subtable (0, 5);
+        if (st && st->u.format == 14)
+          subtable_uvs = &st->u.format14;
+      }
+      /* Meh. */
+      if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14);
+
+      this->uvs_table = subtable_uvs;
+
+      this->get_glyph_data = subtable;
+      if (unlikely (symbol))
+        this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
+      else
+        switch (subtable->u.format) {
+        /* Accelerate format 4 and format 12. */
+        default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;               break;
+        case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>;       break;
+        case  4:
+          {
+            this->format4_accel.init (&subtable->u.format4);
+            this->get_glyph_data = &this->format4_accel;
+            this->get_glyph_func = this->format4_accel.get_glyph_func;
+          }
+          break;
+        }
+    }
+
+    inline void fini (void)
+    {
+      hb_blob_destroy (this->blob);
+    }
+
+    inline bool get_nominal_glyph (hb_codepoint_t  unicode,
+                                   hb_codepoint_t *glyph) const
+    {
+      return this->get_glyph_func (this->get_glyph_data, unicode, glyph);
+    }
+
+    inline bool get_variation_glyph (hb_codepoint_t  unicode,
+                                     hb_codepoint_t  variation_selector,
+                                     hb_codepoint_t *glyph) const
+    {
+      switch (this->uvs_table->get_glyph_variant (unicode,
+                                                  variation_selector,
+                                                  glyph))
+      {
+        case OT::GLYPH_VARIANT_NOT_FOUND:               return false;
+        case OT::GLYPH_VARIANT_FOUND:           return true;
+        case OT::GLYPH_VARIANT_USE_DEFAULT:     break;
+      }
+
+      return get_nominal_glyph (unicode, glyph);
+    }
+
+    protected:
+    typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
+                                              hb_codepoint_t codepoint,
+                                              hb_codepoint_t *glyph);
+
+    template <typename Type>
+    static inline bool get_glyph_from (const void *obj,
+                                       hb_codepoint_t codepoint,
+                                       hb_codepoint_t *glyph)
+    {
+      const Type *typed_obj = (const Type *) obj;
+      return typed_obj->get_glyph (codepoint, glyph);
+    }
+
+    template <typename Type>
+    static inline bool get_glyph_from_symbol (const void *obj,
+                                              hb_codepoint_t codepoint,
+                                              hb_codepoint_t *glyph)
+    {
+      const Type *typed_obj = (const Type *) obj;
+      if (likely (typed_obj->get_glyph (codepoint, glyph)))
+        return true;
+
+      if (codepoint <= 0x00FFu)
+      {
+        /* For symbol-encoded OpenType fonts, we duplicate the
+         * U+F000..F0FF range at U+0000..U+00FF.  That's what
+         * Windows seems to do, and that's hinted about at:
+         * http://www.microsoft.com/typography/otspec/recom.htm
+         * under "Non-Standard (Symbol) Fonts". */
+        return typed_obj->get_glyph (0xF000u + codepoint, glyph);
+      }
+
+      return false;
+    }
+
+    private:
+    hb_cmap_get_glyph_func_t get_glyph_func;
+    const void *get_glyph_data;
+    OT::CmapSubtableFormat4::accelerator_t format4_accel;
+
+    const OT::CmapSubtableFormat14 *uvs_table;
+    hb_blob_t *blob;
+  };
+
+  protected:
+
   inline const CmapSubtable *find_subtable (unsigned int platform_id,
                                             unsigned int encoding_id) const
   {
@@ -513,15 +774,8 @@
     return &(this+encodingRecord[result].subtable);
   }
 
-  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));
-  }
-
-  USHORT                version;        /* Table version number (0). */
+  protected:
+  HBUINT16              version;        /* Table version number (0). */
   SortedArrayOf<EncodingRecord>
                         encodingRecord; /* Encoding tables. */
   public:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-cbdt-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -0,0 +1,471 @@
+/*
+ * Copyright © 2016  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Seigo Nonaka
+ */
+
+#ifndef HB_OT_COLOR_CBDT_TABLE_HH
+#define HB_OT_COLOR_CBDT_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+namespace OT {
+
+struct SmallGlyphMetrics
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  inline void get_extents (hb_glyph_extents_t *extents) const
+  {
+    extents->x_bearing = bearingX;
+    extents->y_bearing = bearingY;
+    extents->width = width;
+    extents->height = -height;
+  }
+
+  HBUINT8 height;
+  HBUINT8 width;
+  HBINT8 bearingX;
+  HBINT8 bearingY;
+  HBUINT8 advance;
+
+  DEFINE_SIZE_STATIC(5);
+};
+
+struct BigGlyphMetrics : SmallGlyphMetrics
+{
+  HBINT8 vertBearingX;
+  HBINT8 vertBearingY;
+  HBUINT8 vertAdvance;
+
+  DEFINE_SIZE_STATIC(8);
+};
+
+struct SBitLineMetrics
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBINT8 ascender;
+  HBINT8 decender;
+  HBUINT8 widthMax;
+  HBINT8 caretSlopeNumerator;
+  HBINT8 caretSlopeDenominator;
+  HBINT8 caretOffset;
+  HBINT8 minOriginSB;
+  HBINT8 minAdvanceSB;
+  HBINT8 maxBeforeBL;
+  HBINT8 minAfterBL;
+  HBINT8 padding1;
+  HBINT8 padding2;
+
+  DEFINE_SIZE_STATIC(12);
+};
+
+
+/*
+ * Index Subtables.
+ */
+
+struct IndexSubtableHeader
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBUINT16 indexFormat;
+  HBUINT16 imageFormat;
+  HBUINT32 imageDataOffset;
+
+  DEFINE_SIZE_STATIC(8);
+};
+
+template <typename OffsetType>
+struct IndexSubtableFormat1Or3
+{
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1));
+  }
+
+  bool get_image_data (unsigned int idx,
+                       unsigned int *offset,
+                       unsigned int *length) const
+  {
+    if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
+      return false;
+
+    *offset = header.imageDataOffset + offsetArrayZ[idx];
+    *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
+    return true;
+  }
+
+  IndexSubtableHeader header;
+  Offset<OffsetType> offsetArrayZ[VAR];
+
+  DEFINE_SIZE_ARRAY(8, offsetArrayZ);
+};
+
+struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {};
+struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<HBUINT16> {};
+
+struct IndexSubtable
+{
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.header.sanitize (c)) return_trace (false);
+    switch (u.header.indexFormat) {
+    case 1: return_trace (u.format1.sanitize (c, glyph_count));
+    case 3: return_trace (u.format3.sanitize (c, glyph_count));
+    default:return_trace (true);
+    }
+  }
+
+  inline bool get_extents (hb_glyph_extents_t *extents) const
+  {
+    switch (u.header.indexFormat) {
+    case 2: case 5: /* TODO */
+    case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
+    default:return (false);
+    }
+  }
+
+  bool get_image_data (unsigned int idx,
+                       unsigned int *offset,
+                       unsigned int *length,
+                       unsigned int *format) const
+  {
+    *format = u.header.imageFormat;
+    switch (u.header.indexFormat) {
+    case 1: return u.format1.get_image_data (idx, offset, length);
+    case 3: return u.format3.get_image_data (idx, offset, length);
+    default: return false;
+    }
+  }
+
+  protected:
+  union {
+  IndexSubtableHeader   header;
+  IndexSubtableFormat1  format1;
+  IndexSubtableFormat3  format3;
+  /* TODO: Format 2, 4, 5. */
+  } u;
+  public:
+  DEFINE_SIZE_UNION (8, header);
+};
+
+struct IndexSubtableRecord
+{
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  firstGlyphIndex <= lastGlyphIndex &&
+                  offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1));
+  }
+
+  inline bool get_extents (hb_glyph_extents_t *extents) const
+  {
+    return (this+offsetToSubtable).get_extents (extents);
+  }
+
+  bool get_image_data (unsigned int gid,
+                       unsigned int *offset,
+                       unsigned int *length,
+                       unsigned int *format) const
+  {
+    if (gid < firstGlyphIndex || gid > lastGlyphIndex)
+    {
+      return false;
+    }
+    return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
+                                                   offset, length, format);
+  }
+
+  HBUINT16 firstGlyphIndex;
+  HBUINT16 lastGlyphIndex;
+  LOffsetTo<IndexSubtable> offsetToSubtable;
+
+  DEFINE_SIZE_STATIC(8);
+};
+
+struct IndexSubtableArray
+{
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count)))
+      return_trace (false);
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
+        return_trace (false);
+    return_trace (true);
+  }
+
+  public:
+  const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
+  {
+    for (unsigned int i = 0; i < numTables; ++i)
+    {
+      unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
+      unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
+      if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
+        return &indexSubtablesZ[i];
+      }
+    }
+    return nullptr;
+  }
+
+  protected:
+  IndexSubtableRecord indexSubtablesZ[VAR];
+
+  public:
+  DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
+};
+
+struct BitmapSizeTable
+{
+  friend struct CBLC;
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
+                  c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) &&
+                  horizontal.sanitize (c) &&
+                  vertical.sanitize (c));
+  }
+
+  const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const
+  {
+    return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
+  }
+
+  protected:
+  LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset;
+  HBUINT32 indexTablesSize;
+  HBUINT32 numberOfIndexSubtables;
+  HBUINT32 colorRef;
+  SBitLineMetrics horizontal;
+  SBitLineMetrics vertical;
+  HBUINT16 startGlyphIndex;
+  HBUINT16 endGlyphIndex;
+  HBUINT8 ppemX;
+  HBUINT8 ppemY;
+  HBUINT8 bitDepth;
+  HBINT8 flags;
+
+  public:
+  DEFINE_SIZE_STATIC(48);
+};
+
+
+/*
+ * Glyph Bitmap Data Formats.
+ */
+
+struct GlyphBitmapDataFormat17
+{
+  SmallGlyphMetrics glyphMetrics;
+  HBUINT32 dataLen;
+  HBUINT8 dataZ[VAR];
+
+  DEFINE_SIZE_ARRAY(9, dataZ);
+};
+
+
+/*
+ * CBLC -- Color Bitmap Location Table
+ */
+
+#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
+
+struct CBLC
+{
+  friend struct CBDT;
+
+  static const hb_tag_t tableTag = HB_OT_TAG_CBLC;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  likely (version.major == 2 || version.major == 3) &&
+                  sizeTables.sanitize (c, this));
+  }
+
+  protected:
+  const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
+                                         unsigned int *x_ppem, unsigned int *y_ppem) const
+  {
+    /* TODO: Make it possible to select strike. */
+
+    unsigned int count = sizeTables.len;
+    for (uint32_t i = 0; i < count; ++i)
+    {
+      unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex;
+      unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex;
+      if (startGlyphIndex <= glyph && glyph <= endGlyphIndex)
+      {
+        *x_ppem = sizeTables[i].ppemX;
+        *y_ppem = sizeTables[i].ppemY;
+        return sizeTables[i].find_table (glyph, this);
+      }
+    }
+
+    return nullptr;
+  }
+
+  protected:
+  FixedVersion<>                version;
+  LArrayOf<BitmapSizeTable>     sizeTables;
+
+  public:
+  DEFINE_SIZE_ARRAY(8, sizeTables);
+};
+
+/*
+ * CBDT -- Color Bitmap Data Table
+ */
+#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
+
+struct CBDT
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_CBDT;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  likely (version.major == 2 || version.major == 3));
+  }
+
+  struct accelerator_t
+  {
+    inline void init (hb_face_t *face)
+    {
+      upem = hb_face_get_upem (face);
+
+      cblc_blob = Sanitizer<CBLC>().sanitize (face->reference_table (HB_OT_TAG_CBLC));
+      cbdt_blob = Sanitizer<CBDT>().sanitize (face->reference_table (HB_OT_TAG_CBDT));
+      cbdt_len = hb_blob_get_length (cbdt_blob);
+
+      if (hb_blob_get_length (cblc_blob) == 0) {
+        cblc = nullptr;
+        cbdt = nullptr;
+        return;  /* Not a bitmap font. */
+      }
+      cblc = Sanitizer<CBLC>::lock_instance (cblc_blob);
+      cbdt = Sanitizer<CBDT>::lock_instance (cbdt_blob);
+
+    }
+
+    inline void fini (void)
+    {
+      hb_blob_destroy (this->cblc_blob);
+      hb_blob_destroy (this->cbdt_blob);
+    }
+
+    inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+    {
+      unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */
+
+      if (!cblc)
+        return false;  // Not a color bitmap font.
+
+      const IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem);
+      if (!subtable_record || !x_ppem || !y_ppem)
+        return false;
+
+      if (subtable_record->get_extents (extents))
+        return true;
+
+      unsigned int image_offset = 0, image_length = 0, image_format = 0;
+      if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
+        return false;
+
+      {
+        if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+          return false;
+
+        switch (image_format)
+        {
+          case 17: {
+            if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
+              return false;
+
+            const GlyphBitmapDataFormat17& glyphFormat17 =
+                StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+            glyphFormat17.glyphMetrics.get_extents (extents);
+          }
+          break;
+          default:
+            // TODO: Support other image formats.
+            return false;
+        }
+      }
+
+      /* Convert to the font units. */
+      extents->x_bearing *= upem / (float) x_ppem;
+      extents->y_bearing *= upem / (float) y_ppem;
+      extents->width *= upem / (float) x_ppem;
+      extents->height *= upem / (float) y_ppem;
+
+      return true;
+    }
+
+    private:
+    hb_blob_t *cblc_blob;
+    hb_blob_t *cbdt_blob;
+    const CBLC *cblc;
+    const CBDT *cbdt;
+
+    unsigned int cbdt_len;
+    unsigned int upem;
+  };
+
+
+  protected:
+  FixedVersion<>version;
+  HBUINT8 dataZ[VAR];
+
+  public:
+  DEFINE_SIZE_ARRAY(4, dataZ);
+};
+
+} /* namespace OT */
+
+#endif /* HB_OT_COLOR_CBDT_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-colr-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_OT_COLOR_COLR_TABLE_HH
+#define HB_OT_COLOR_COLR_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+/*
+ * Color Palette
+ * http://www.microsoft.com/typography/otspec/colr.htm
+ */
+
+#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
+
+namespace OT {
+
+
+struct LayerRecord
+{
+  friend struct COLR;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  GlyphID gID;                  /* Glyph ID of layer glyph */
+  HBUINT16 paletteIndex;        /* Index value to use with a selected color palette */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct BaseGlyphRecord
+{
+  friend struct COLR;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  GlyphID gID;                  /* Glyph ID of reference glyph */
+  HBUINT16 firstLayerIndex;     /* Index to the layer record */
+  HBUINT16 numLayers;           /* Number of color layers associated with this glyph */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct COLR
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_COLR;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!(c->check_struct (this) &&
+        c->check_array ((const void*) &layerRecordsOffsetZ, sizeof (LayerRecord), numLayerRecords) &&
+        c->check_array ((const void*) &baseGlyphRecordsZ, sizeof (BaseGlyphRecord), numBaseGlyphRecords)))
+      return_trace (false);
+
+    const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this);
+    for (unsigned int i = 0; i < numBaseGlyphRecords; ++i)
+      if (base_glyph_records[i].firstLayerIndex +
+          base_glyph_records[i].numLayers > numLayerRecords)
+        return_trace (false);
+
+    return_trace (true);
+  }
+
+  inline bool get_base_glyph_record (
+    hb_codepoint_t glyph_id, unsigned int &first_layer, unsigned int &num_layers) const
+  {
+    const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this);
+    unsigned int min = 0, max = numBaseGlyphRecords - 1;
+    while (min <= max)
+    {
+      unsigned int mid = (min + max) / 2;
+      hb_codepoint_t gID = base_glyph_records[mid].gID;
+      if (gID > glyph_id)
+        max = mid - 1;
+      else if (gID < glyph_id)
+        min = mid + 1;
+      else
+      {
+        first_layer = base_glyph_records[mid].firstLayerIndex;
+        num_layers = base_glyph_records[mid].numLayers;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  inline void get_layer_record (int layer,
+    hb_codepoint_t &glyph_id, unsigned int &palette_index) const
+  {
+    const LayerRecord* records = &layerRecordsOffsetZ (this);
+    glyph_id = records[layer].gID;
+    palette_index = records[layer].paletteIndex;
+  }
+
+  protected:
+  HBUINT16      version;                /* Table version number */
+  HBUINT16      numBaseGlyphRecords;    /* Number of Base Glyph Records */
+  LOffsetTo<BaseGlyphRecord>
+                baseGlyphRecordsZ;      /* Offset to Base Glyph records. */
+  LOffsetTo<LayerRecord>
+                layerRecordsOffsetZ;    /* Offset to Layer Records */
+  HBUINT16      numLayerRecords;        /* Number of Layer Records */
+  public:
+  DEFINE_SIZE_STATIC (14);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_COLOR_COLR_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-cpal-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -0,0 +1,208 @@
+/*
+ * Copyright © 2016  Google, Inc.
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Sascha Brawer
+ */
+
+#ifndef HB_OT_COLOR_CPAL_TABLE_HH
+#define HB_OT_COLOR_CPAL_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+/*
+ * Following parts to be moved to a public header.
+ */
+
+/**
+ * hb_ot_color_t:
+ * ARGB data type for holding color values.
+ *
+ * Since: REPLACEME
+ */
+typedef uint32_t hb_ot_color_t;
+
+
+/**
+ * hb_ot_color_palette_flags_t:
+ * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special to note about a color palette.
+ * @HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND: flag indicating that the color palette is suitable for rendering text on light background.
+ * @HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND: flag indicating that the color palette is suitable for rendering text on dark background.
+ *
+ * Since: REPLACEME
+ */
+typedef enum { /*< flags >*/
+  HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u,
+  HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND = 0x00000001u,
+  HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u,
+} hb_ot_color_palette_flags_t;
+
+// HB_EXTERN unsigned int
+// hb_ot_color_get_palette_count (hb_face_t *face);
+
+// HB_EXTERN unsigned int
+// hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette);
+
+// HB_EXTERN hb_ot_color_palette_flags_t
+// hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette);
+
+// HB_EXTERN unsigned int
+// hb_ot_color_get_palette_colors (hb_face_t       *face,
+//                              unsigned int     palette, /* default=0 */
+//                              unsigned int     start_offset,
+//                              unsigned int    *color_count /* IN/OUT */,
+//                              hb_ot_color_t   *colors /* OUT */);
+
+
+
+
+
+/*
+ * Color Palette
+ * http://www.microsoft.com/typography/otspec/cpal.htm
+ */
+
+#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
+
+namespace OT {
+
+
+struct CPALV1Tail
+{
+  friend struct CPAL;
+
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int palettes) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (
+      c->check_struct (this) &&
+      c->check_array ((const void*) &paletteFlags, sizeof (HBUINT32), palettes) &&
+      c->check_array ((const void*) &paletteLabel, sizeof (HBUINT16), palettes) &&
+      c->check_array ((const void*) &paletteEntryLabel, sizeof (HBUINT16), palettes));
+  }
+
+  private:
+  inline hb_ot_color_palette_flags_t
+  get_palette_flags (const void *base, unsigned int palette) const
+  {
+    const HBUINT32* flags = &paletteFlags (base);
+    return (hb_ot_color_palette_flags_t) (uint32_t) flags[palette];
+  }
+
+  inline unsigned int
+  get_palette_name_id (const void *base, unsigned int palette) const
+  {
+    const HBUINT16* name_ids = &paletteLabel (base);
+    return name_ids[palette];
+  }
+
+  protected:
+  LOffsetTo<HBUINT32> paletteFlags;
+  LOffsetTo<HBUINT16> paletteLabel;
+  LOffsetTo<HBUINT16> paletteEntryLabel;
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+typedef HBUINT32 BGRAColor;
+
+struct CPAL
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_CPAL;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!(c->check_struct (this) && // This checks colorRecordIndicesX sanity also, see #get_size
+        c->check_array ((const void*) &colorRecordsZ, sizeof (BGRAColor), numColorRecords)))
+      return_trace (false);
+
+    // Check for indices sanity so no need for doing it runtime
+    for (unsigned int i = 0; i < numPalettes; ++i)
+      if (colorRecordIndicesX[i] + numPaletteEntries > numColorRecords)
+        return_trace (false);
+
+    // If version is zero, we are done here; otherwise we need to check tail also
+    if (version == 0)
+      return_trace (true);
+
+    const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this);
+    return_trace (v1.sanitize (c, numPalettes));
+  }
+
+  inline unsigned int get_size (void) const
+  {
+    return min_size + numPalettes * sizeof (HBUINT16);
+  }
+
+  inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const
+  {
+    if (version == 0 || palette >= numPalettes)
+      return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
+
+    const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
+    return cpal1.get_palette_flags (this, palette);
+  }
+
+  inline unsigned int get_palette_name_id (unsigned int palette) const
+  {
+    if (version == 0 || palette >= numPalettes)
+      return 0xFFFF;
+
+    const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this);
+    return cpal1.get_palette_name_id (this, palette);
+  }
+
+  inline unsigned int get_palette_count () const
+  {
+    return numPalettes;
+  }
+
+  inline hb_ot_color_t get_color_record_argb (unsigned int color_index, unsigned int palette) const
+  {
+    if (color_index >= numPaletteEntries || palette >= numPalettes)
+      return 0;
+
+    const BGRAColor* records = &colorRecordsZ(this);
+    // No need for more range check as it is already done on #sanitize
+    return records[colorRecordIndicesX[palette] + color_index];
+  }
+
+  protected:
+  HBUINT16      version;
+  /* Version 0 */
+  HBUINT16      numPaletteEntries;
+  HBUINT16      numPalettes;
+  HBUINT16      numColorRecords;
+  LOffsetTo<HBUINT32>   colorRecordsZ;
+  HBUINT16      colorRecordIndicesX[VAR];  // VAR=numPalettes
+/*CPALV1Tail    v1[VAR];*/
+  public:
+  DEFINE_SIZE_ARRAY (12, colorRecordIndicesX);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_COLOR_CPAL_TABLE_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.cc	Wed May 30 12:20:00 2018 -0700
@@ -31,468 +31,23 @@
 #include "hb-font-private.hh"
 
 #include "hb-ot-cmap-table.hh"
-#include "hb-ot-cbdt-table.hh"
 #include "hb-ot-glyf-table.hh"
-#include "hb-ot-head-table.hh"
-#include "hb-ot-hhea-table.hh"
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-kern-table.hh"
-#include "hb-ot-os2-table.hh"
 #include "hb-ot-post-table.hh"
-#include "hb-ot-var-hvar-table.hh"
 
+#include "hb-ot-color-cbdt-table.hh"
 
-struct hb_ot_face_metrics_accelerator_t
-{
-  unsigned int num_metrics;
-  unsigned int num_advances;
-  unsigned int default_advance;
-  unsigned short ascender;
-  unsigned short descender;
-  unsigned short line_gap;
-  bool has_font_extents;
-
-  const OT::hmtxvmtx *table;
-  hb_blob_t *blob;
-
-  const OT::HVARVVAR *var;
-  hb_blob_t *var_blob;
-
-  inline void init (hb_face_t *face,
-                    hb_tag_t _hea_tag,
-                    hb_tag_t _mtx_tag,
-                    hb_tag_t _var_tag,
-                    hb_tag_t os2_tag,
-                    unsigned int default_advance = 0)
-  {
-    this->default_advance = default_advance ? default_advance : face->get_upem ();
-
-    bool got_font_extents = false;
-    if (os2_tag)
-    {
-      hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>::sanitize (face->reference_table (os2_tag));
-      const OT::os2 *os2 = OT::Sanitizer<OT::os2>::lock_instance (os2_blob);
-#define USE_TYPO_METRICS (1u<<7)
-      if (0 != (os2->fsSelection & USE_TYPO_METRICS))
-      {
-        this->ascender = os2->sTypoAscender;
-        this->descender = os2->sTypoDescender;
-        this->line_gap = os2->sTypoLineGap;
-        got_font_extents = (this->ascender | this->descender) != 0;
-      }
-      hb_blob_destroy (os2_blob);
-    }
-
-    hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag));
-    const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob);
-    this->num_advances = _hea->numberOfLongMetrics;
-    if (!got_font_extents)
-    {
-      this->ascender = _hea->ascender;
-      this->descender = _hea->descender;
-      this->line_gap = _hea->lineGap;
-      got_font_extents = (this->ascender | this->descender) != 0;
-    }
-    hb_blob_destroy (_hea_blob);
-
-    this->has_font_extents = got_font_extents;
-
-    this->blob = OT::Sanitizer<OT::hmtxvmtx>::sanitize (face->reference_table (_mtx_tag));
-
-    /* Cap num_metrics() and num_advances() based on table length. */
-    unsigned int len = hb_blob_get_length (this->blob);
-    if (unlikely (this->num_advances * 4 > len))
-      this->num_advances = len / 4;
-    this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2;
-
-    /* We MUST set num_metrics to zero if num_advances is zero.
-     * Our get_advance() depends on that. */
-    if (unlikely (!this->num_advances))
-    {
-      this->num_metrics = this->num_advances = 0;
-      hb_blob_destroy (this->blob);
-      this->blob = hb_blob_get_empty ();
-    }
-    this->table = OT::Sanitizer<OT::hmtxvmtx>::lock_instance (this->blob);
-
-    this->var_blob = OT::Sanitizer<OT::HVARVVAR>::sanitize (face->reference_table (_var_tag));
-    this->var = OT::Sanitizer<OT::HVARVVAR>::lock_instance (this->var_blob);
-  }
-
-  inline void fini (void)
-  {
-    hb_blob_destroy (this->blob);
-    hb_blob_destroy (this->var_blob);
-  }
-
-  inline unsigned int get_advance (hb_codepoint_t  glyph,
-                                   hb_font_t      *font) const
-  {
-    if (unlikely (glyph >= this->num_metrics))
-    {
-      /* If this->num_metrics is zero, it means we don't have the metrics table
-       * for this direction: return default advance.  Otherwise, it means that the
-       * glyph index is out of bound: return zero. */
-      if (this->num_metrics)
-        return 0;
-      else
-        return this->default_advance;
-    }
-
-    return this->table->longMetric[MIN (glyph, (uint32_t) this->num_advances - 1)].advance
-         + this->var->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
-  }
-};
-
-struct hb_ot_face_glyf_accelerator_t
-{
-  bool short_offset;
-  unsigned int num_glyphs;
-  const OT::loca *loca;
-  const OT::glyf *glyf;
-  hb_blob_t *loca_blob;
-  hb_blob_t *glyf_blob;
-  unsigned int glyf_len;
-
-  inline void init (hb_face_t *face)
-  {
-    hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (face->reference_table (HB_OT_TAG_head));
-    const OT::head *head = OT::Sanitizer<OT::head>::lock_instance (head_blob);
-    if ((unsigned int) head->indexToLocFormat > 1 || head->glyphDataFormat != 0)
-    {
-      /* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
-      hb_blob_destroy (head_blob);
-      return;
-    }
-    this->short_offset = 0 == head->indexToLocFormat;
-    hb_blob_destroy (head_blob);
-
-    this->loca_blob = OT::Sanitizer<OT::loca>::sanitize (face->reference_table (HB_OT_TAG_loca));
-    this->loca = OT::Sanitizer<OT::loca>::lock_instance (this->loca_blob);
-    this->glyf_blob = OT::Sanitizer<OT::glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf));
-    this->glyf = OT::Sanitizer<OT::glyf>::lock_instance (this->glyf_blob);
-
-    this->num_glyphs = MAX (1u, hb_blob_get_length (this->loca_blob) / (this->short_offset ? 2 : 4)) - 1;
-    this->glyf_len = hb_blob_get_length (this->glyf_blob);
-  }
-
-  inline void fini (void)
-  {
-    hb_blob_destroy (this->loca_blob);
-    hb_blob_destroy (this->glyf_blob);
-  }
-
-  inline bool get_extents (hb_codepoint_t glyph,
-                           hb_glyph_extents_t *extents) const
-  {
-    if (unlikely (glyph >= this->num_glyphs))
-      return false;
-
-    unsigned int start_offset, end_offset;
-    if (this->short_offset)
-    {
-      start_offset = 2 * this->loca->u.shortsZ[glyph];
-      end_offset   = 2 * this->loca->u.shortsZ[glyph + 1];
-    }
-    else
-    {
-      start_offset = this->loca->u.longsZ[glyph];
-      end_offset   = this->loca->u.longsZ[glyph + 1];
-    }
-
-    if (start_offset > end_offset || end_offset > this->glyf_len)
-      return false;
-
-    if (end_offset - start_offset < OT::glyfGlyphHeader::static_size)
-      return true; /* Empty glyph; zero extents. */
-
-    const OT::glyfGlyphHeader &glyph_header = OT::StructAtOffset<OT::glyfGlyphHeader> (this->glyf, start_offset);
-
-    extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax);
-    extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax);
-    extents->width     = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
-    extents->height    = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
-
-    return true;
-  }
-};
-
-struct hb_ot_face_cbdt_accelerator_t
-{
-  hb_blob_t *cblc_blob;
-  hb_blob_t *cbdt_blob;
-  const OT::CBLC *cblc;
-  const OT::CBDT *cbdt;
-
-  unsigned int cbdt_len;
-  unsigned int upem;
-
-  inline void init (hb_face_t *face)
-  {
-    upem = face->get_upem();
-
-    cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC));
-    cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT));
-    cbdt_len = hb_blob_get_length (cbdt_blob);
-
-    if (hb_blob_get_length (cblc_blob) == 0) {
-      cblc = nullptr;
-      cbdt = nullptr;
-      return;  /* Not a bitmap font. */
-    }
-    cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob);
-    cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob);
-
-  }
-
-  inline void fini (void)
-  {
-    hb_blob_destroy (this->cblc_blob);
-    hb_blob_destroy (this->cbdt_blob);
-  }
-
-  inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
-  {
-    unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */
-
-    if (!cblc)
-      return false;  // Not a color bitmap font.
-
-    const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem);
-    if (!subtable_record || !x_ppem || !y_ppem)
-      return false;
-
-    if (subtable_record->get_extents (extents))
-      return true;
-
-    unsigned int image_offset = 0, image_length = 0, image_format = 0;
-    if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format))
-      return false;
-
-    {
-      /* TODO Move the following into CBDT struct when adding more formats. */
-
-      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
-        return false;
-
-      switch (image_format)
-      {
-        case 17: {
-          if (unlikely (image_length < OT::GlyphBitmapDataFormat17::min_size))
-            return false;
-
-          const OT::GlyphBitmapDataFormat17& glyphFormat17 =
-              OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image_offset);
-          glyphFormat17.glyphMetrics.get_extents (extents);
-        }
-        break;
-        default:
-          // TODO: Support other image formats.
-          return false;
-      }
-    }
-
-    /* Convert to the font units. */
-    extents->x_bearing *= upem / (float) x_ppem;
-    extents->y_bearing *= upem / (float) y_ppem;
-    extents->width *= upem / (float) x_ppem;
-    extents->height *= upem / (float) y_ppem;
-
-    return true;
-  }
-};
-
-struct hb_ot_face_post_accelerator_t
-{
-  hb_blob_t *post_blob;
-  OT::post::accelerator_t accel;
-
-  inline void init (hb_face_t *face)
-  {
-    hb_blob_t *blob = this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post));
-    accel.init (OT::Sanitizer<OT::post>::lock_instance (blob), hb_blob_get_length (blob));
-  }
-
-  inline void fini (void)
-  {
-    accel.fini ();
-    hb_blob_destroy (this->post_blob);
-  }
-
-  inline bool get_glyph_name (hb_codepoint_t glyph,
-                              char *name, unsigned int size) const
-  {
-    return this->accel.get_glyph_name (glyph, name, size);
-  }
-
-  inline bool get_glyph_from_name (const char *name, int len,
-                                   hb_codepoint_t *glyph) const
-  {
-    if (unlikely (!len))
-      return false;
-
-    return this->accel.get_glyph_from_name (name, len, glyph);
-  }
-};
-
-struct hb_ot_face_kern_accelerator_t
-{
-  hb_blob_t *kern_blob;
-  OT::kern::accelerator_t accel;
-
-  inline void init (hb_face_t *face)
-  {
-    hb_blob_t *blob = this->kern_blob = OT::Sanitizer<OT::kern>::sanitize (face->reference_table (HB_OT_TAG_kern));
-    accel.init (OT::Sanitizer<OT::kern>::lock_instance (blob), hb_blob_get_length (blob));
-  }
-
-  inline void fini (void)
-  {
-    accel.fini ();
-    hb_blob_destroy (this->kern_blob);
-  }
-
-  inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
-  { return accel.get_h_kerning (left, right); }
-};
-
-typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
-                                          hb_codepoint_t codepoint,
-                                          hb_codepoint_t *glyph);
-
-template <typename Type>
-static inline bool get_glyph_from (const void *obj,
-                                   hb_codepoint_t codepoint,
-                                   hb_codepoint_t *glyph)
-{
-  const Type *typed_obj = (const Type *) obj;
-  return typed_obj->get_glyph (codepoint, glyph);
-}
-
-template <typename Type>
-static inline bool get_glyph_from_symbol (const void *obj,
-                                          hb_codepoint_t codepoint,
-                                          hb_codepoint_t *glyph)
-{
-  const Type *typed_obj = (const Type *) obj;
-  if (likely (typed_obj->get_glyph (codepoint, glyph)))
-    return true;
-
-  if (codepoint <= 0x00FFu)
-  {
-    /* For symbol-encoded OpenType fonts, we duplicate the
-     * U+F000..F0FF range at U+0000..U+00FF.  That's what
-     * Windows seems to do, and that's hinted about at:
-     * http://www.microsoft.com/typography/otspec/recom.htm
-     * under "Non-Standard (Symbol) Fonts". */
-    return typed_obj->get_glyph (0xF000u + codepoint, glyph);
-  }
-
-  return false;
-}
-
-struct hb_ot_face_cmap_accelerator_t
-{
-  hb_cmap_get_glyph_func_t get_glyph_func;
-  const void *get_glyph_data;
-  OT::CmapSubtableFormat4::accelerator_t format4_accel;
-
-  const OT::CmapSubtableFormat14 *uvs_table;
-  hb_blob_t *blob;
-
-  inline void init (hb_face_t *face)
-  {
-    this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
-    const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
-    const OT::CmapSubtable *subtable = nullptr;
-    const OT::CmapSubtableFormat14 *subtable_uvs = nullptr;
-
-    bool symbol = false;
-    /* 32-bit subtables. */
-    if (!subtable) subtable = cmap->find_subtable (3, 10);
-    if (!subtable) subtable = cmap->find_subtable (0, 6);
-    if (!subtable) subtable = cmap->find_subtable (0, 4);
-    /* 16-bit subtables. */
-    if (!subtable) subtable = cmap->find_subtable (3, 1);
-    if (!subtable) subtable = cmap->find_subtable (0, 3);
-    if (!subtable) subtable = cmap->find_subtable (0, 2);
-    if (!subtable) subtable = cmap->find_subtable (0, 1);
-    if (!subtable) subtable = cmap->find_subtable (0, 0);
-    if (!subtable)
-    {
-      subtable = cmap->find_subtable (3, 0);
-      if (subtable) symbol = true;
-    }
-    /* Meh. */
-    if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
-
-    /* UVS subtable. */
-    if (!subtable_uvs)
-    {
-      const OT::CmapSubtable *st = cmap->find_subtable (0, 5);
-      if (st && st->u.format == 14)
-        subtable_uvs = &st->u.format14;
-    }
-    /* Meh. */
-    if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14);
-
-    this->uvs_table = subtable_uvs;
-
-    this->get_glyph_data = subtable;
-    if (unlikely (symbol))
-      this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
-    else
-      switch (subtable->u.format) {
-      /* Accelerate format 4 and format 12. */
-      default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;         break;
-      case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break;
-      case  4:
-        {
-          this->format4_accel.init (&subtable->u.format4);
-          this->get_glyph_data = &this->format4_accel;
-          this->get_glyph_func = this->format4_accel.get_glyph_func;
-        }
-        break;
-      }
-  }
-
-  inline void fini (void)
-  {
-    hb_blob_destroy (this->blob);
-  }
-
-  inline bool get_nominal_glyph (hb_codepoint_t  unicode,
-                                 hb_codepoint_t *glyph) const
-  {
-    return this->get_glyph_func (this->get_glyph_data, unicode, glyph);
-  }
-
-  inline bool get_variation_glyph (hb_codepoint_t  unicode,
-                                   hb_codepoint_t  variation_selector,
-                                   hb_codepoint_t *glyph) const
-  {
-    switch (this->uvs_table->get_glyph_variant (unicode,
-                                                variation_selector,
-                                                glyph))
-    {
-      case OT::GLYPH_VARIANT_NOT_FOUND:         return false;
-      case OT::GLYPH_VARIANT_FOUND:             return true;
-      case OT::GLYPH_VARIANT_USE_DEFAULT:       break;
-    }
-
-    return get_nominal_glyph (unicode, glyph);
-  }
-};
 
 struct hb_ot_font_t
 {
-  hb_ot_face_cmap_accelerator_t cmap;
-  hb_ot_face_metrics_accelerator_t h_metrics;
-  hb_ot_face_metrics_accelerator_t v_metrics;
-  OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
-  OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt;
-  OT::hb_lazy_loader_t<hb_ot_face_post_accelerator_t> post;
-  OT::hb_lazy_loader_t<hb_ot_face_kern_accelerator_t> kern;
+  OT::cmap::accelerator_t cmap;
+  OT::hmtx::accelerator_t h_metrics;
+  OT::vmtx::accelerator_t v_metrics;
+  OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf;
+  OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt;
+  OT::hb_lazy_loader_t<OT::post::accelerator_t> post;
+  OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern;
 };
 
 
@@ -505,9 +60,8 @@
     return nullptr;
 
   ot_font->cmap.init (face);
-  ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_HVAR, HB_OT_TAG_os2);
-  ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_OT_TAG_VVAR, HB_TAG_NONE,
-                           ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
+  ot_font->h_metrics.init (face);
+  ot_font->v_metrics.init (face, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
   ot_font->glyf.init (face);
   ot_font->cbdt.init (face);
   ot_font->post.init (face);
@@ -688,7 +242,7 @@
     hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr);
     //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr);
     hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
-    //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); TODO
+    //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
     hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
     hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
 
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-glyf-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-glyf-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -28,7 +28,10 @@
 #define HB_OT_GLYF_TABLE_HH
 
 #include "hb-open-type-private.hh"
-
+#include "hb-ot-head-table.hh"
+#include "hb-subset-glyf.hh"
+#include "hb-subset-plan.hh"
+#include "hb-subset-private.hh"
 
 namespace OT {
 
@@ -42,6 +45,8 @@
 
 struct loca
 {
+  friend struct glyf;
+
   static const hb_tag_t tableTag = HB_OT_TAG_loca;
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -50,12 +55,9 @@
     return_trace (true);
   }
 
-  public:
-  union {
-    USHORT      shortsZ[VAR];           /* Location offset divided by 2. */
-    ULONG       longsZ[VAR];            /* Location offset. */
-  } u;
-  DEFINE_SIZE_ARRAY (0, u.longsZ);
+  protected:
+  HBUINT8               dataX[VAR];             /* Location data. */
+  DEFINE_SIZE_ARRAY (0, dataX);
 };
 
 
@@ -78,26 +80,393 @@
     return_trace (true);
   }
 
-  public:
-  BYTE          dataX[VAR];             /* Glyphs data. */
+  inline bool subset (hb_subset_plan_t *plan) const
+  {
+    hb_blob_t *glyf_prime = nullptr;
+    hb_blob_t *loca_prime = nullptr;
+
+    bool success = true;
+    bool use_short_loca = false;
+    if (hb_subset_glyf_and_loca (plan, &use_short_loca, &glyf_prime, &loca_prime)) {
+      success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_glyf, glyf_prime);
+      success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_loca, loca_prime);
+      success = success && _add_head_and_set_loca_version (plan->source, use_short_loca, plan->dest);
+    } else {
+      success = false;
+    }
+    hb_blob_destroy (loca_prime);
+    hb_blob_destroy (glyf_prime);
+
+    return success;
+  }
+
+  static bool
+  _add_head_and_set_loca_version (hb_face_t *source, bool use_short_loca, hb_face_t *dest)
+  {
+    hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (source, HB_OT_TAG_head));
+    hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
+    hb_blob_destroy (head_blob);
+
+    if (unlikely (!head_prime_blob))
+      return false;
+
+    OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
+    head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1);
+    bool success = hb_subset_face_add_table (dest, HB_OT_TAG_head, head_prime_blob);
+
+    hb_blob_destroy (head_prime_blob);
+    return success;
+  }
+
+  struct GlyphHeader
+  {
+    HBINT16             numberOfContours;       /* If the number of contours is
+                                                 * greater than or equal to zero,
+                                                 * this is a simple glyph; if negative,
+                                                 * this is a composite glyph. */
+    FWORD               xMin;                   /* Minimum x for coordinate data. */
+    FWORD               yMin;                   /* Minimum y for coordinate data. */
+    FWORD               xMax;                   /* Maximum x for coordinate data. */
+    FWORD               yMax;                   /* Maximum y for coordinate data. */
+
+    DEFINE_SIZE_STATIC (10);
+  };
+
+  struct CompositeGlyphHeader
+  {
+    static const uint16_t ARG_1_AND_2_ARE_WORDS =      0x0001;
+    static const uint16_t ARGS_ARE_XY_VALUES =         0x0002;
+    static const uint16_t ROUND_XY_TO_GRID =           0x0004;
+    static const uint16_t WE_HAVE_A_SCALE =            0x0008;
+    static const uint16_t MORE_COMPONENTS =            0x0020;
+    static const uint16_t WE_HAVE_AN_X_AND_Y_SCALE =   0x0040;
+    static const uint16_t WE_HAVE_A_TWO_BY_TWO =       0x0080;
+    static const uint16_t WE_HAVE_INSTRUCTIONS =       0x0100;
+    static const uint16_t USE_MY_METRICS =             0x0200;
+    static const uint16_t OVERLAP_COMPOUND =           0x0400;
+    static const uint16_t SCALED_COMPONENT_OFFSET =    0x0800;
+    static const uint16_t UNSCALED_COMPONENT_OFFSET =  0x1000;
+
+    HBUINT16 flags;
+    HBUINT16 glyphIndex;
+
+    inline unsigned int get_size (void) const
+    {
+      unsigned int size = min_size;
+      if (flags & ARG_1_AND_2_ARE_WORDS) {
+        // arg1 and 2 are int16
+        size += 4;
+      } else {
+        // arg1 and 2 are int8
+        size += 2;
+      }
+      if (flags & WE_HAVE_A_SCALE) {
+        // One x 16 bit (scale)
+        size += 2;
+      } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
+        // Two x 16 bit (xscale, yscale)
+        size += 4;
+      } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
+        // Four x 16 bit (xscale, scale01, scale10, yscale)
+        size += 8;
+      }
+      return size;
+    }
+
+    struct Iterator
+    {
+      const char *glyph_start;
+      const char *glyph_end;
+      const CompositeGlyphHeader *current;
+
+      inline bool move_to_next ()
+      {
+        if (current->flags & CompositeGlyphHeader::MORE_COMPONENTS)
+        {
+          const CompositeGlyphHeader *possible =
+            &StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (*current);
+          if (!in_range (possible))
+            return false;
+          current = possible;
+          return true;
+        }
+        return false;
+      }
+
+      inline bool in_range (const CompositeGlyphHeader *composite) const
+      {
+        return (const char *) composite >= glyph_start
+          && ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
+          && ((const char *) composite + composite->get_size()) <= glyph_end;
+      }
+    };
+
+    static inline bool get_iterator (const char * glyph_data,
+                                     unsigned int length,
+                                     CompositeGlyphHeader::Iterator *iterator /* OUT */)
+    {
+      if (length < GlyphHeader::static_size)
+        return false; /* Empty glyph; zero extents. */
+
+      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0);
+      if (glyph_header.numberOfContours < 0)
+      {
+        const CompositeGlyphHeader *possible =
+          &StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
+
+        iterator->glyph_start = glyph_data;
+        iterator->glyph_end = (const char *) glyph_data + length;
+        if (!iterator->in_range (possible))
+          return false;
+        iterator->current = possible;
+        return true;
+      }
+
+      return false;
+    }
+
+    DEFINE_SIZE_MIN (4);
+  };
+
+  struct accelerator_t
+  {
+    inline void init (hb_face_t *face)
+    {
+      hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head));
+      const head *head_table = Sanitizer<head>::lock_instance (head_blob);
+      if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
+      {
+        /* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
+        hb_blob_destroy (head_blob);
+        return;
+      }
+      short_offset = 0 == head_table->indexToLocFormat;
+      hb_blob_destroy (head_blob);
+
+      loca_blob = Sanitizer<loca>().sanitize (face->reference_table (HB_OT_TAG_loca));
+      loca_table = Sanitizer<loca>::lock_instance (loca_blob);
+      glyf_blob = Sanitizer<glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf));
+      glyf_table = Sanitizer<glyf>::lock_instance (glyf_blob);
+
+      num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1;
+      glyf_len = hb_blob_get_length (glyf_blob);
+    }
+
+    inline void fini (void)
+    {
+      hb_blob_destroy (loca_blob);
+      hb_blob_destroy (glyf_blob);
+    }
+
+    /*
+     * Returns true if the referenced glyph is a valid glyph and a composite glyph.
+     * If true is returned a pointer to the composite glyph will be written into
+     * composite.
+     */
+    inline bool get_composite (hb_codepoint_t glyph,
+                               CompositeGlyphHeader::Iterator *composite /* OUT */) const
+    {
+      unsigned int start_offset, end_offset;
+      if (!get_offsets (glyph, &start_offset, &end_offset))
+        return false; /* glyph not found */
+
+      return CompositeGlyphHeader::get_iterator ((const char*) this->glyf_table + start_offset,
+                                                 end_offset - start_offset,
+                                                 composite);
+    }
+
+    /* based on FontTools _g_l_y_f.py::trim */
+    inline bool remove_padding(unsigned int start_offset,
+                               unsigned int *end_offset) const
+    {
+      static const int FLAG_X_SHORT = 0x02;
+      static const int FLAG_Y_SHORT = 0x04;
+      static const int FLAG_REPEAT = 0x08;
+      static const int FLAG_X_SAME = 0x10;
+      static const int FLAG_Y_SAME = 0x20;
+
+      if (*end_offset - start_offset < GlyphHeader::static_size)
+        return true;
+
+      const char *glyph = ((const char *) glyf_table) + start_offset;
+      const char * const glyph_end = glyph + (*end_offset - start_offset);
+      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph, 0);
+      int16_t num_contours = (int16_t) glyph_header.numberOfContours;
+
+      if (num_contours < 0)
+        /* Trimming for composites not implemented.
+         * If removing hints it falls out of that. */
+        return true;
+      else if (num_contours > 0)
+      {
+        /* simple glyph w/contours, possibly trimmable */
+        glyph += GlyphHeader::static_size + 2 * num_contours;
+
+        if (unlikely (glyph + 2 >= glyph_end)) return false;
+        uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16>(glyph - 2, 0) + 1;
+        uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16>(glyph, 0);
+
+        glyph += 2 + nInstructions;
+        if (unlikely (glyph + 2 >= glyph_end)) return false;
+
+        unsigned int coordBytes = 0;
+        unsigned int coordsWithFlags = 0;
+        while (glyph < glyph_end)
+        {
+          uint8_t flag = (uint8_t) *glyph;
+          glyph++;
+
+          unsigned int repeat = 1;
+          if (flag & FLAG_REPEAT)
+          {
+            if (glyph >= glyph_end)
+            {
+              DEBUG_MSG(SUBSET, nullptr, "Bad flag");
+              return false;
+            }
+            repeat = ((uint8_t) *glyph) + 1;
+            glyph++;
+          }
+
+          unsigned int xBytes, yBytes;
+          xBytes = yBytes = 0;
+          if (flag & FLAG_X_SHORT)
+            xBytes = 1;
+          else if ((flag & FLAG_X_SAME) == 0)
+            xBytes = 2;
+
+          if (flag & FLAG_Y_SHORT)
+            yBytes = 1;
+          else if ((flag & FLAG_Y_SAME) == 0)
+            yBytes = 2;
+
+          coordBytes += (xBytes + yBytes) * repeat;
+          coordsWithFlags += repeat;
+          if (coordsWithFlags >= nCoordinates)
+            break;
+        }
+
+        if (coordsWithFlags != nCoordinates)
+        {
+          DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags);
+          return false;
+        }
+        glyph += coordBytes;
+
+        if (glyph < glyph_end)
+          *end_offset -= glyph_end - glyph;
+      }
+      return true;
+    }
+
+    inline bool get_offsets (hb_codepoint_t  glyph,
+                             unsigned int   *start_offset /* OUT */,
+                             unsigned int   *end_offset   /* OUT */) const
+    {
+      if (unlikely (glyph >= num_glyphs))
+        return false;
+
+      if (short_offset)
+      {
+        const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataX;
+        *start_offset = 2 * offsets[glyph];
+        *end_offset   = 2 * offsets[glyph + 1];
+      }
+      else
+      {
+        const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX;
+
+        *start_offset = offsets[glyph];
+        *end_offset   = offsets[glyph + 1];
+      }
+
+      if (*start_offset > *end_offset || *end_offset > glyf_len)
+        return false;
+
+      return true;
+    }
+
+    inline bool get_instruction_offsets(unsigned int start_offset,
+                                        unsigned int end_offset,
+                                        unsigned int *instruction_start /* OUT */,
+                                        unsigned int *instruction_end /* OUT */) const
+    {
+      if (end_offset - start_offset < GlyphHeader::static_size)
+      {
+        *instruction_start = 0;
+        *instruction_end = 0;
+        return true; /* Empty glyph; no instructions. */
+      }
+      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
+      int16_t num_contours = (int16_t) glyph_header.numberOfContours;
+      if (num_contours < 0)
+      {
+        CompositeGlyphHeader::Iterator composite_it;
+        if (unlikely (!CompositeGlyphHeader::get_iterator (
+            (const char*) this->glyf_table + start_offset,
+             end_offset - start_offset, &composite_it))) return false;
+        const CompositeGlyphHeader *last;
+        do {
+          last = composite_it.current;
+        } while (composite_it.move_to_next());
+
+        if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
+          *instruction_start = ((char *) last - (char *) glyf_table->dataX) + last->get_size();
+        else
+          *instruction_start = end_offset;
+        *instruction_end = end_offset;
+        if (unlikely (*instruction_start > *instruction_end))
+        {
+          DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset);
+          return false;
+        }
+      }
+      else
+      {
+        unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
+        const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
+        *instruction_start = instruction_length_offset + 2;
+        *instruction_end = *instruction_start + (uint16_t) instruction_length;
+      }
+      return true;
+    }
+
+    inline bool get_extents (hb_codepoint_t glyph,
+                             hb_glyph_extents_t *extents) const
+    {
+      unsigned int start_offset, end_offset;
+      if (!get_offsets (glyph, &start_offset, &end_offset))
+        return false;
+
+      if (end_offset - start_offset < GlyphHeader::static_size)
+        return true; /* Empty glyph; zero extents. */
+
+      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
+
+      extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax);
+      extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax);
+      extents->width     = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
+      extents->height    = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
+
+      return true;
+    }
+
+    private:
+    bool short_offset;
+    unsigned int num_glyphs;
+    const loca *loca_table;
+    const glyf *glyf_table;
+    hb_blob_t *loca_blob;
+    hb_blob_t *glyf_blob;
+    unsigned int glyf_len;
+  };
+
+  protected:
+  HBUINT8               dataX[VAR];             /* Glyphs data. */
 
   DEFINE_SIZE_ARRAY (0, dataX);
 };
 
-struct glyfGlyphHeader
-{
-  SHORT         numberOfContours;       /* If the number of contours is
-                                         * greater than or equal to zero,
-                                         * this is a simple glyph; if negative,
-                                         * this is a composite glyph. */
-  FWORD         xMin;                   /* Minimum x for coordinate data. */
-  FWORD         yMin;                   /* Minimum y for coordinate data. */
-  FWORD         xMax;                   /* Maximum x for coordinate data. */
-  FWORD         yMax;                   /* Maximum y for coordinate data. */
-
-  DEFINE_SIZE_STATIC (10);
-};
-
 } /* namespace OT */
 
 
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-head-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-head-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -43,6 +43,8 @@
 
 struct head
 {
+  friend struct OffsetTable;
+
   static const hb_tag_t tableTag        = HB_OT_TAG_head;
 
   inline unsigned int get_upem (void) const
@@ -64,11 +66,11 @@
   FixedVersion<>version;                /* Version of the head table--currently
                                          * 0x00010000u for version 1.0. */
   FixedVersion<>fontRevision;           /* Set by font manufacturer. */
-  ULONG         checkSumAdjustment;     /* To compute: set it to 0, sum the
-                                         * entire font as ULONG, then store
+  HBUINT32      checkSumAdjustment;     /* To compute: set it to 0, sum the
+                                         * entire font as HBUINT32, then store
                                          * 0xB1B0AFBAu - sum. */
-  ULONG         magicNumber;            /* Set to 0x5F0F3CF5u. */
-  USHORT        flags;                  /* Bit 0: Baseline for font at y=0;
+  HBUINT32      magicNumber;            /* Set to 0x5F0F3CF5u. */
+  HBUINT16      flags;                  /* Bit 0: Baseline for font at y=0;
                                          * Bit 1: Left sidebearing point at x=0;
                                          * Bit 2: Instructions may depend on point size;
                                          * Bit 3: Force ppem to integer values for all
@@ -76,7 +78,6 @@
                                          *   ppem sizes if this bit is clear;
                                          * Bit 4: Instructions may alter advance width
                                          *   (the advance widths might not scale linearly);
-
                                          * Bits 5-10: These should be set according to
                                          *   Apple's specification. However, they are not
                                          *   implemented in OpenType.
@@ -96,7 +97,6 @@
                                          *   contains any strong right-to-left glyphs.
                                          * Bit 10: This bit should be set if the font
                                          *   contains Indic-style rearrangement effects.
-
                                          * Bit 11: Font data is 'lossless,' as a result
                                          *   of having been compressed and decompressed
                                          *   with the Agfa MicroType Express engine.
@@ -114,18 +114,18 @@
                                          * encoded in the cmap subtables represent proper
                                          * support for those code points.
                                          * Bit 15: Reserved, set to 0. */
-  USHORT        unitsPerEm;             /* Valid range is from 16 to 16384. This value
+  HBUINT16      unitsPerEm;             /* Valid range is from 16 to 16384. This value
                                          * should be a power of 2 for fonts that have
                                          * TrueType outlines. */
   LONGDATETIME  created;                /* Number of seconds since 12:00 midnight,
                                            January 1, 1904. 64-bit integer */
   LONGDATETIME  modified;               /* Number of seconds since 12:00 midnight,
                                            January 1, 1904. 64-bit integer */
-  SHORT         xMin;                   /* For all glyph bounding boxes. */
-  SHORT         yMin;                   /* For all glyph bounding boxes. */
-  SHORT         xMax;                   /* For all glyph bounding boxes. */
-  SHORT         yMax;                   /* For all glyph bounding boxes. */
-  USHORT        macStyle;               /* Bit 0: Bold (if set to 1);
+  HBINT16       xMin;                   /* For all glyph bounding boxes. */
+  HBINT16       yMin;                   /* For all glyph bounding boxes. */
+  HBINT16       xMax;                   /* For all glyph bounding boxes. */
+  HBINT16       yMax;                   /* For all glyph bounding boxes. */
+  HBUINT16      macStyle;               /* Bit 0: Bold (if set to 1);
                                          * Bit 1: Italic (if set to 1)
                                          * Bit 2: Underline (if set to 1)
                                          * Bit 3: Outline (if set to 1)
@@ -133,16 +133,16 @@
                                          * Bit 5: Condensed (if set to 1)
                                          * Bit 6: Extended (if set to 1)
                                          * Bits 7-15: Reserved (set to 0). */
-  USHORT        lowestRecPPEM;          /* Smallest readable size in pixels. */
-  SHORT         fontDirectionHint;      /* Deprecated (Set to 2).
+  HBUINT16      lowestRecPPEM;          /* Smallest readable size in pixels. */
+  HBINT16       fontDirectionHint;      /* Deprecated (Set to 2).
                                          * 0: Fully mixed directional glyphs;
                                          * 1: Only strongly left to right;
                                          * 2: Like 1 but also contains neutrals;
                                          * -1: Only strongly right to left;
                                          * -2: Like -1 but also contains neutrals. */
   public:
-  SHORT         indexToLocFormat;       /* 0 for short offsets, 1 for long. */
-  SHORT         glyphDataFormat;        /* 0 for current format. */
+  HBINT16       indexToLocFormat;       /* 0 for short offsets, 1 for long. */
+  HBINT16       glyphDataFormat;        /* 0 for current format. */
 
   DEFINE_SIZE_STATIC (54);
 };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hhea-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hhea-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -41,14 +41,9 @@
 #define HB_OT_TAG_hhea HB_TAG('h','h','e','a')
 #define HB_OT_TAG_vhea HB_TAG('v','h','e','a')
 
-
+template <typename T>
 struct _hea
 {
-  static const hb_tag_t tableTag = HB_TAG('_','h','e','a');
-
-  static const hb_tag_t hheaTag = HB_OT_TAG_hhea;
-  static const hb_tag_t vheaTag = HB_OT_TAG_vhea;
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -69,30 +64,30 @@
                                          * (xMax - xMin)) for horizontal. */
   FWORD         maxExtent;              /* horizontal: Max(lsb + (xMax - xMin)),
                                          * vertical: minLeadingBearing+(yMax-yMin). */
-  SHORT         caretSlopeRise;         /* Used to calculate the slope of the
+  HBINT16               caretSlopeRise;         /* Used to calculate the slope of the
                                          * cursor (rise/run); 1 for vertical caret,
                                          * 0 for horizontal.*/
-  SHORT         caretSlopeRun;          /* 0 for vertical caret, 1 for horizontal. */
-  SHORT         caretOffset;            /* The amount by which a slanted
+  HBINT16               caretSlopeRun;          /* 0 for vertical caret, 1 for horizontal. */
+  HBINT16               caretOffset;            /* The amount by which a slanted
                                          * highlight on a glyph needs
                                          * to be shifted to produce the
                                          * best appearance. Set to 0 for
                                          * non-slanted fonts. */
-  SHORT         reserved1;              /* Set to 0. */
-  SHORT         reserved2;              /* Set to 0. */
-  SHORT         reserved3;              /* Set to 0. */
-  SHORT         reserved4;              /* Set to 0. */
-  SHORT         metricDataFormat;       /* 0 for current format. */
-  USHORT        numberOfLongMetrics;    /* Number of LongMetric entries in metric
+  HBINT16               reserved1;              /* Set to 0. */
+  HBINT16               reserved2;              /* Set to 0. */
+  HBINT16               reserved3;              /* Set to 0. */
+  HBINT16               reserved4;              /* Set to 0. */
+  HBINT16               metricDataFormat;       /* 0 for current format. */
+  HBUINT16      numberOfLongMetrics;    /* Number of LongMetric entries in metric
                                          * table. */
   public:
   DEFINE_SIZE_STATIC (36);
 };
 
-struct hhea : _hea {
+struct hhea : _hea<hhea> {
   static const hb_tag_t tableTag        = HB_OT_TAG_hhea;
 };
-struct vhea : _hea {
+struct vhea : _hea<vhea> {
   static const hb_tag_t tableTag        = HB_OT_TAG_vhea;
 };
 
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hmtx-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hmtx-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -21,13 +21,16 @@
  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
- * Google Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Roderick Sheeter
  */
 
 #ifndef HB_OT_HMTX_TABLE_HH
 #define HB_OT_HMTX_TABLE_HH
 
 #include "hb-open-type-private.hh"
+#include "hb-ot-hhea-table.hh"
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-var-hvar-table.hh"
 
 
 namespace OT {
@@ -50,11 +53,9 @@
   DEFINE_SIZE_STATIC (4);
 };
 
+template <typename T, typename H>
 struct hmtxvmtx
 {
-  static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx;
-  static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx;
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -63,7 +64,228 @@
     return_trace (true);
   }
 
-  public:
+
+  inline bool subset_update_header (hb_subset_plan_t *plan,
+                                    unsigned int num_hmetrics) const
+  {
+    hb_blob_t *src_blob = OT::Sanitizer<H> ().sanitize (plan->source->reference_table (H::tableTag));
+    hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail(src_blob);
+    hb_blob_destroy (src_blob);
+
+    if (unlikely (!dest_blob)) {
+      return false;
+    }
+
+    unsigned int length;
+    H *table = (H *) hb_blob_get_data (dest_blob, &length);
+    table->numberOfLongMetrics.set (num_hmetrics);
+
+    bool result = hb_subset_plan_add_table (plan, H::tableTag, dest_blob);
+    hb_blob_destroy (dest_blob);
+
+    return result;
+  }
+
+  inline bool subset (hb_subset_plan_t *plan) const
+  {
+    typename T::accelerator_t _mtx;
+    _mtx.init (plan->source);
+
+    /* All the trailing glyphs with the same advance can use one LongMetric
+     * and just keep LSB */
+    hb_prealloced_array_t<hb_codepoint_t> &gids = plan->gids_to_retain_sorted;
+    unsigned int num_advances = gids.len;
+    unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]);
+    while (num_advances > 1
+        && last_advance == _mtx.get_advance (gids[num_advances - 2]))
+    {
+      num_advances--;
+    }
+
+    /* alloc the new table */
+    size_t dest_sz = num_advances * 4
+                  + (gids.len - num_advances) * 2;
+    void *dest = (void *) malloc (dest_sz);
+    if (unlikely (!dest))
+    {
+      return false;
+    }
+    DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in src has %d advances, %d lsbs", HB_UNTAG(T::tableTag), _mtx.num_advances, _mtx.num_metrics - _mtx.num_advances);
+    DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in dest has %d advances, %d lsbs, %u bytes", HB_UNTAG(T::tableTag), num_advances, gids.len - num_advances, (unsigned int) dest_sz);
+
+    const char *source_table = hb_blob_get_data (_mtx.blob, nullptr);
+    // Copy everything over
+    LongMetric * old_metrics = (LongMetric *) source_table;
+    FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances);
+    char * dest_pos = (char *) dest;
+    for (unsigned int i = 0; i < gids.len; i++)
+    {
+      /* the last metric or the one for gids[i] */
+      LongMetric *src_metric = old_metrics + MIN ((hb_codepoint_t) _mtx.num_advances - 1, gids[i]);
+      if (gids[i] < _mtx.num_advances)
+      {
+        /* src is a LongMetric */
+        if (i < num_advances)
+        {
+          /* dest is a LongMetric, copy it */
+          *((LongMetric *) dest_pos) = *src_metric;
+        }
+        else
+        {
+          /* dest just lsb */
+          *((FWORD *) dest_pos) = src_metric->lsb;
+        }
+      }
+      else
+      {
+        FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances);
+        if (i < num_advances)
+        {
+          /* dest needs a full LongMetric */
+          LongMetric *metric = (LongMetric *)dest_pos;
+          metric->advance = src_metric->advance;
+          metric->lsb = src_lsb;
+        }
+        else
+        {
+          /* dest just needs an lsb */
+          *((FWORD *) dest_pos) = src_lsb;
+        }
+      }
+      dest_pos += (i < num_advances ? 4 : 2);
+    }
+    _mtx.fini ();
+
+    // Amend header num hmetrics
+    if (unlikely (!subset_update_header (plan, num_advances)))
+    {
+      free (dest);
+      return false;
+    }
+
+    hb_blob_t *result = hb_blob_create ((const char *)dest,
+                                        dest_sz,
+                                        HB_MEMORY_MODE_READONLY,
+                                        dest,
+                                        free);
+    bool success = hb_subset_plan_add_table (plan, T::tableTag, result);
+    hb_blob_destroy (result);
+    return success;
+  }
+
+  struct accelerator_t
+  {
+    friend struct hmtxvmtx;
+
+    inline void init (hb_face_t *face,
+                      unsigned int default_advance_ = 0)
+    {
+      default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
+
+      bool got_font_extents = false;
+      if (T::os2Tag)
+      {
+        hb_blob_t *os2_blob = Sanitizer<os2> ().sanitize (face->reference_table (T::os2Tag));
+        const os2 *os2_table = Sanitizer<os2>::lock_instance (os2_blob);
+#define USE_TYPO_METRICS (1u<<7)
+        if (0 != (os2_table->fsSelection & USE_TYPO_METRICS))
+        {
+          ascender = os2_table->sTypoAscender;
+          descender = os2_table->sTypoDescender;
+          line_gap = os2_table->sTypoLineGap;
+          got_font_extents = (ascender | descender) != 0;
+        }
+        hb_blob_destroy (os2_blob);
+      }
+
+      hb_blob_t *_hea_blob = Sanitizer<H> ().sanitize (face->reference_table (H::tableTag));
+      const H *_hea_table = Sanitizer<H>::lock_instance (_hea_blob);
+      num_advances = _hea_table->numberOfLongMetrics;
+      if (!got_font_extents)
+      {
+        ascender = _hea_table->ascender;
+        descender = _hea_table->descender;
+        line_gap = _hea_table->lineGap;
+        got_font_extents = (ascender | descender) != 0;
+      }
+      hb_blob_destroy (_hea_blob);
+
+      has_font_extents = got_font_extents;
+
+      blob = Sanitizer<hmtxvmtx> ().sanitize (face->reference_table (T::tableTag));
+
+      /* Cap num_metrics() and num_advances() based on table length. */
+      unsigned int len = hb_blob_get_length (blob);
+      if (unlikely (num_advances * 4 > len))
+        num_advances = len / 4;
+      num_metrics = num_advances + (len - 4 * num_advances) / 2;
+
+      /* We MUST set num_metrics to zero if num_advances is zero.
+       * Our get_advance() depends on that. */
+      if (unlikely (!num_advances))
+      {
+        num_metrics = num_advances = 0;
+        hb_blob_destroy (blob);
+        blob = hb_blob_get_empty ();
+      }
+      table = Sanitizer<hmtxvmtx>::lock_instance (blob);
+
+      var_blob = Sanitizer<HVARVVAR> ().sanitize (face->reference_table (T::variationsTag));
+      var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob);
+    }
+
+    inline void fini (void)
+    {
+      hb_blob_destroy (blob);
+      hb_blob_destroy (var_blob);
+    }
+
+    inline unsigned int get_advance (hb_codepoint_t  glyph) const
+    {
+      if (unlikely (glyph >= num_metrics))
+      {
+        /* If num_metrics is zero, it means we don't have the metrics table
+         * for this direction: return default advance.  Otherwise, it means that the
+         * glyph index is out of bound: return zero. */
+        if (num_metrics)
+          return 0;
+        else
+          return default_advance;
+      }
+
+      return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance;
+    }
+
+    inline unsigned int get_advance (hb_codepoint_t  glyph,
+                                     hb_font_t      *font) const
+    {
+      unsigned int advance = get_advance (glyph);
+      if (likely(glyph < num_metrics))
+      {
+        advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
+      }
+      return advance;
+    }
+
+    public:
+    bool has_font_extents;
+    unsigned short ascender;
+    unsigned short descender;
+    unsigned short line_gap;
+
+    protected:
+    unsigned int num_metrics;
+    unsigned int num_advances;
+    unsigned int default_advance;
+
+    private:
+    const hmtxvmtx *table;
+    hb_blob_t *blob;
+    const HVARVVAR *var_table;
+    hb_blob_t *var_blob;
+  };
+
+  protected:
   LongMetric    longMetric[VAR];        /* Paired advance width and leading
                                          * bearing values for each glyph. The
                                          * value numOfHMetrics comes from
@@ -72,7 +294,7 @@
                                          * be in the array, but that entry is
                                          * required. The last entry applies to
                                          * all subsequent glyphs. */
-  FWORD         leadingBearingX[VAR];   /* Here the advance is assumed
+/*FWORD         leadingBearingX[VAR];*/ /* Here the advance is assumed
                                          * to be the same as the advance
                                          * for the last entry above. The
                                          * number of entries in this array is
@@ -86,14 +308,18 @@
                                          * font to vary the side bearing
                                          * values for each glyph. */
   public:
-  DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX);
+  DEFINE_SIZE_ARRAY (0, longMetric);
 };
 
-struct hmtx : hmtxvmtx {
+struct hmtx : hmtxvmtx<hmtx, hhea> {
   static const hb_tag_t tableTag        = HB_OT_TAG_hmtx;
+  static const hb_tag_t variationsTag   = HB_OT_TAG_HVAR;
+  static const hb_tag_t os2Tag          = HB_OT_TAG_os2;
 };
-struct vmtx : hmtxvmtx {
+struct vmtx : hmtxvmtx<vmtx, vhea> {
   static const hb_tag_t tableTag        = HB_OT_TAG_vmtx;
+  static const hb_tag_t variationsTag   = HB_OT_TAG_VVAR;
+  static const hb_tag_t os2Tag          = HB_TAG_NONE;
 };
 
 } /* namespace OT */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-kern-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-kern-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -104,8 +104,8 @@
   }
 
   protected:
-  USHORT                firstGlyph;     /* First glyph in class range. */
-  ArrayOf<USHORT>       classes;        /* Glyph classes. */
+  HBUINT16              firstGlyph;     /* First glyph in class range. */
+  ArrayOf<HBUINT16>     classes;        /* Glyph classes. */
   public:
   DEFINE_SIZE_ARRAY (4, classes);
 };
@@ -115,7 +115,7 @@
   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 r = (this+rightClassTable).get_class (right);
     unsigned int offset = l * rowWidth + r * sizeof (FWORD);
     const FWORD *arr = &(this+array);
     if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
@@ -136,7 +136,7 @@
   }
 
   protected:
-  USHORT        rowWidth;       /* The width, in bytes, of a row in the table. */
+  HBUINT16      rowWidth;       /* The width, in bytes, of a row in the table. */
   OffsetTo<KernClassTable>
                 leftClassTable; /* Offset from beginning of this subtable to
                                  * left-hand class table. */
@@ -275,19 +275,19 @@
     };
 
     protected:
-    USHORT      versionZ;       /* Unused. */
-    USHORT      length;         /* Length of the subtable (including this header). */
-    BYTE        format;         /* Subtable format. */
-    BYTE        coverage;       /* Coverage bits. */
+    HBUINT16    versionZ;       /* Unused. */
+    HBUINT16    length;         /* Length of the subtable (including this header). */
+    HBUINT8     format;         /* Subtable format. */
+    HBUINT8     coverage;       /* Coverage bits. */
     KernSubTable subtable;      /* Subtable data. */
     public:
     DEFINE_SIZE_MIN (6);
   };
 
   protected:
-  USHORT        version;        /* Version--0x0000u */
-  USHORT        nTables;        /* Number of subtables in the kerning table. */
-  BYTE          data[VAR];
+  HBUINT16      version;        /* Version--0x0000u */
+  HBUINT16      nTables;        /* Number of subtables in the kerning table. */
+  HBUINT8               data[VAR];
   public:
   DEFINE_SIZE_ARRAY (4, data);
 };
@@ -314,10 +314,10 @@
     };
 
     protected:
-    ULONG       length;         /* Length of the subtable (including this header). */
-    BYTE        coverage;       /* Coverage bits. */
-    BYTE        format;         /* Subtable format. */
-    USHORT      tupleIndex;     /* The tuple index (used for variations fonts).
+    HBUINT32    length;         /* Length of the subtable (including this header). */
+    HBUINT8     coverage;       /* Coverage bits. */
+    HBUINT8     format;         /* Subtable format. */
+    HBUINT16    tupleIndex;     /* The tuple index (used for variations fonts).
                                  * This value specifies which tuple this subtable covers. */
     KernSubTable subtable;      /* Subtable data. */
     public:
@@ -325,9 +325,9 @@
   };
 
   protected:
-  ULONG         version;        /* Version--0x00010000u */
-  ULONG         nTables;        /* Number of subtables in the kerning table. */
-  BYTE          data[VAR];
+  HBUINT32              version;        /* Version--0x00010000u */
+  HBUINT32              nTables;        /* Number of subtables in the kerning table. */
+  HBUINT8               data[VAR];
   public:
   DEFINE_SIZE_ARRAY (8, data);
 };
@@ -358,24 +358,29 @@
 
   struct accelerator_t
   {
-    inline void init (const kern *table_, unsigned int table_length_)
+    inline void init (hb_face_t *face)
     {
-      table = table_;
-      table_length = table_length_;
+      blob = Sanitizer<kern>().sanitize (face->reference_table (HB_OT_TAG_kern));
+      table = Sanitizer<kern>::lock_instance (blob);
+      table_length = hb_blob_get_length (blob);
     }
-    inline void fini (void) {}
+    inline void fini (void)
+    {
+      hb_blob_destroy (blob);
+    }
 
     inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
     { return table->get_h_kerning (left, right, table_length); }
 
     private:
+    hb_blob_t *blob;
     const kern *table;
     unsigned int table_length;
   };
 
   protected:
   union {
-  USHORT                major;
+  HBUINT16              major;
   KernOT                ot;
   KernAAT               aat;
   } u;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-base-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -0,0 +1,655 @@
+/*
+ * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_BASE_TABLE_HH
+#define HB_OT_LAYOUT_BASE_TABLE_HH
+
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-common-private.hh"
+
+namespace OT {
+
+#define NOT_INDEXED   ((unsigned int) -1)
+
+/*
+ * BASE -- The BASE Table
+ */
+
+struct BaseCoordFormat1
+{
+  inline int get_coord (void) const { return coordinate; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  HBUINT16      format;         /* Format identifier--format = 1 */
+  HBINT16       coordinate;     /* X or Y value, in design units */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct BaseCoordFormat2
+{
+  inline int get_coord (void) const
+  {
+    /* TODO */
+    return coordinate;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  HBUINT16      format;         /* Format identifier--format = 2 */
+  HBINT16       coordinate;     /* X or Y value, in design units */
+  GlyphID       referenceGlyph; /* Glyph ID of control glyph */
+  HBUINT16      coordPoint;     /* Index of contour point on the
+                                 * reference glyph */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct BaseCoordFormat3
+{
+  inline int get_coord (void) const
+  {
+    /* TODO */
+    return coordinate;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
+  }
+
+  protected:
+  HBUINT16              format;         /* Format identifier--format = 3 */
+  HBINT16               coordinate;     /* X or Y value, in design units */
+  OffsetTo<Device>      deviceTable;    /* Offset to Device table for X or
+                                         * Y value, from beginning of
+                                         * BaseCoord table (may be NULL). */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct BaseCoord
+{
+  inline int get_coord (void) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_coord ();
+    case 2: return u.format2.get_coord ();
+    case 3: return u.format3.get_coord ();
+    default:return 0;
+    }
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    switch (u.format) {
+    case 1: return_trace (u.format1.sanitize (c));
+    case 2: return_trace (u.format2.sanitize (c));
+    case 3: return_trace (u.format3.sanitize (c));
+    default:return_trace (false);
+    }
+  }
+
+  protected:
+  union {
+    HBUINT16            format;
+    BaseCoordFormat1    format1;
+    BaseCoordFormat2    format2;
+    BaseCoordFormat3    format3;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+struct FeatMinMaxRecord
+{
+  inline int get_min_value (void) const
+  { return (this+minCoord).get_coord(); }
+
+  inline int get_max_value (void) const
+  { return (this+maxCoord).get_coord(); }
+
+  inline const Tag &get_tag () const
+  { return tag; }
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  minCoord.sanitize (c, base) &&
+                  maxCoord.sanitize (c, base));
+  }
+
+  protected:
+  Tag                   tag;            /* 4-byte feature identification tag--must
+                                         * match feature tag in FeatureList */
+  OffsetTo<BaseCoord>   minCoord;       /* Offset to BaseCoord table that defines
+                                         * the minimum extent value, from beginning
+                                         * of MinMax table (may be NULL) */
+  OffsetTo<BaseCoord>   maxCoord;       /* Offset to BaseCoord table that defines
+                                         * the maximum extent value, from beginning
+                                         * of MinMax table (may be NULL) */
+  public:
+  DEFINE_SIZE_STATIC (8);
+
+};
+
+struct MinMax
+{
+  inline unsigned int get_feature_tag_index (Tag featureTableTag) const
+  {
+    /* TODO bsearch */
+    unsigned int count = featMinMaxRecords.len;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      Tag tag = featMinMaxRecords[i].get_tag();
+      int cmp = tag.cmp(featureTableTag);
+      if (cmp == 0) return i;
+      if (cmp > 0)  return NOT_INDEXED;
+    }
+    return NOT_INDEXED;
+  }
+
+  inline int get_min_value (unsigned int featureTableTagIndex) const
+  {
+    if (featureTableTagIndex == NOT_INDEXED)
+      return (this+minCoord).get_coord();
+    return featMinMaxRecords[featureTableTagIndex].get_min_value();
+  }
+
+  inline int get_max_value (unsigned int featureTableTagIndex) const
+  {
+    if (featureTableTagIndex == NOT_INDEXED)
+      return (this+maxCoord).get_coord();
+    return featMinMaxRecords[featureTableTagIndex].get_max_value();
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  minCoord.sanitize (c, this) &&
+                  maxCoord.sanitize (c, this) &&
+                  featMinMaxRecords.sanitize (c, this));
+  }
+
+  protected:
+  OffsetTo<BaseCoord>   minCoord;       /* Offset to BaseCoord table that defines
+                                         * minimum extent value, from the beginning
+                                         * of MinMax table (may be NULL) */
+  OffsetTo<BaseCoord>   maxCoord;       /* Offset to BaseCoord table that defines
+                                         * maximum extent value, from the beginning
+                                         * of MinMax table (may be NULL) */
+  ArrayOf<FeatMinMaxRecord>
+                featMinMaxRecords;      /* Array of FeatMinMaxRecords, in alphabetical
+                                         * order by featureTableTag */
+  public:
+  DEFINE_SIZE_ARRAY (6, featMinMaxRecords);
+};
+
+/* TODO... */
+struct BaseLangSysRecord
+{
+  inline const Tag& get_tag(void) const
+  { return baseLangSysTag; }
+
+  inline unsigned int get_feature_tag_index (Tag featureTableTag) const
+  { return (this+minMax).get_feature_tag_index(featureTableTag); }
+
+  inline int get_min_value (unsigned int featureTableTagIndex) const
+  { return (this+minMax).get_min_value(featureTableTagIndex); }
+
+  inline int get_max_value (unsigned int featureTableTagIndex) const
+  { return (this+minMax).get_max_value(featureTableTagIndex); }
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  minMax.sanitize (c, base));
+  }
+
+  protected:
+  Tag                   baseLangSysTag;
+  OffsetTo<MinMax>      minMax;
+  public:
+  DEFINE_SIZE_STATIC (6);
+
+};
+
+struct BaseValues
+{
+  inline unsigned int get_default_base_tag_index (void) const
+  { return defaultIndex; }
+
+  inline int get_base_coord (unsigned int baselineTagIndex) const
+  {
+    return (this+baseCoords[baselineTagIndex]).get_coord();
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+      defaultIndex <= baseCoordCount &&
+      baseCoords.sanitize (c, this));
+  }
+
+  protected:
+  Index                         defaultIndex;
+  HBUINT16                      baseCoordCount;
+  OffsetArrayOf<BaseCoord>      baseCoords;
+  public:
+  DEFINE_SIZE_ARRAY (6, baseCoords);
+
+};
+
+struct BaseScript {
+
+  inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const
+  {
+    Tag tag;
+    int cmp;
+    for (unsigned int i = 0; i < baseLangSysCount; i++) {
+      tag = baseLangSysRecords[i].get_tag();
+      // taking advantage of alphabetical order
+      cmp = tag.cmp(baseLangSysTag);
+      if (cmp == 0) return i;
+      if (cmp > 0)  return NOT_INDEXED;
+    }
+    return NOT_INDEXED;
+  }
+
+  inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
+  {
+    if (baseLangSysIndex == NOT_INDEXED) {
+      if (unlikely(defaultMinMax)) return NOT_INDEXED;
+      return (this+defaultMinMax).get_feature_tag_index(featureTableTag);
+    }
+    if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NOT_INDEXED;
+    return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index(featureTableTag);
+  }
+
+  inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    if (baseLangSysIndex == NOT_INDEXED)
+      return (this+defaultMinMax).get_min_value(featureTableTagIndex);
+    return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
+  }
+
+  inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    if (baseLangSysIndex == NOT_INDEXED)
+      return (this+defaultMinMax).get_min_value(featureTableTagIndex);
+    return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
+  }
+
+  inline unsigned int get_default_base_tag_index (void) const
+  { return (this+baseValues).get_default_base_tag_index(); }
+
+  inline int get_base_coord (unsigned int baselineTagIndex) const
+  { return (this+baseValues).get_base_coord(baselineTagIndex); }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+      baseValues.sanitize (c, this) &&
+      defaultMinMax.sanitize (c, this) &&
+      baseLangSysRecords.sanitize (c, this));
+  }
+
+  protected:
+  OffsetTo<BaseValues>        baseValues;
+  OffsetTo<MinMax>            defaultMinMax;
+  HBUINT16                      baseLangSysCount;
+  ArrayOf<BaseLangSysRecord>  baseLangSysRecords;
+
+  public:
+    DEFINE_SIZE_ARRAY (8, baseLangSysRecords);
+};
+
+
+struct BaseScriptRecord {
+
+  inline const Tag& get_tag (void) const
+  { return baseScriptTag; }
+
+  inline unsigned int get_default_base_tag_index(void) const
+  { return (this+baseScript).get_default_base_tag_index(); }
+
+  inline int get_base_coord(unsigned int baselineTagIndex) const
+  { return (this+baseScript).get_base_coord(baselineTagIndex); }
+
+  inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const
+  { return (this+baseScript).get_lang_tag_index(baseLangSysTag); }
+
+  inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
+  { return (this+baseScript).get_feature_tag_index(baseLangSysIndex, featureTableTag); }
+
+  inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  { return (this+baseScript).get_max_value(baseLangSysIndex, featureTableTagIndex); }
+
+  inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  { return (this+baseScript).get_min_value(baseLangSysIndex, featureTableTagIndex); }
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+      baseScript != Null(OffsetTo<BaseScript>) &&
+      baseScript.sanitize (c, base));
+  }
+
+  protected:
+  Tag                   baseScriptTag;
+  OffsetTo<BaseScript>  baseScript;
+
+  public:
+    DEFINE_SIZE_STATIC (6);
+};
+
+struct BaseScriptList {
+
+  inline unsigned int get_base_script_index (Tag baseScriptTag) const
+  {
+    for (unsigned int i = 0; i < baseScriptCount; i++)
+      if (baseScriptRecords[i].get_tag() == baseScriptTag)
+        return i;
+    return NOT_INDEXED;
+  }
+
+  inline unsigned int get_default_base_tag_index (unsigned int baseScriptIndex) const
+  {
+    if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
+    return baseScriptRecords[baseScriptIndex].get_default_base_tag_index();
+  }
+
+  inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+  {
+    return baseScriptRecords[baseScriptIndex].get_base_coord(baselineTagIndex);
+  }
+
+  inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
+  {
+    if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
+    return baseScriptRecords[baseScriptIndex].get_lang_tag_index(baseLangSysTag);
+  }
+
+  inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
+  {
+    if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
+    return baseScriptRecords[baseScriptIndex].get_feature_tag_index(baseLangSysIndex, featureTableTag);
+  }
+
+  inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    return baseScriptRecords[baseScriptIndex].get_max_value(baseLangSysIndex, featureTableTagIndex);
+  }
+
+  inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    return baseScriptRecords[baseScriptIndex].get_min_value(baseLangSysIndex, featureTableTagIndex);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+      baseScriptRecords.sanitize (c, this));
+  }
+
+  protected:
+  HBUINT16                    baseScriptCount;
+  ArrayOf<BaseScriptRecord> baseScriptRecords;
+
+  public:
+  DEFINE_SIZE_ARRAY (4, baseScriptRecords);
+
+};
+
+struct BaseTagList
+{
+
+  inline unsigned int get_tag_index(Tag baselineTag) const
+  {
+    for (unsigned int i = 0; i < baseTagCount; i++)
+      if (baselineTags[i] == baselineTag)
+        return i;
+    return NOT_INDEXED;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  HBUINT16        baseTagCount;
+  SortedArrayOf<Tag>  baselineTags;
+
+  public:
+  DEFINE_SIZE_ARRAY (4, baselineTags);
+};
+
+struct Axis
+{
+
+  inline unsigned int get_base_tag_index(Tag baselineTag) const
+  {
+    if (unlikely(baseTagList == Null(OffsetTo<BaseTagList>))) return NOT_INDEXED;
+    return (this+baseTagList).get_tag_index(baselineTag);
+  }
+
+  inline unsigned int get_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
+  {
+    if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
+    return (this+baseScriptList).get_default_base_tag_index(baseScriptIndex);
+  }
+
+  inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+  {
+    return (this+baseScriptList).get_base_coord(baseScriptIndex, baselineTagIndex);
+  }
+
+  inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
+  {
+    if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
+    return (this+baseScriptList).get_lang_tag_index(baseScriptIndex, baseLangSysTag);
+  }
+
+  inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
+  {
+    if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
+    return (this+baseScriptList).get_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag);
+  }
+
+  inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    return (this+baseScriptList).get_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+  }
+
+  inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    return (this+baseScriptList).get_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+      baseTagList.sanitize (c, this) &&
+      baseScriptList.sanitize (c, this));
+  }
+
+  protected:
+  OffsetTo<BaseTagList>     baseTagList;
+  OffsetTo<BaseScriptList>  baseScriptList;
+
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct BASE
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_BASE;
+
+  inline bool has_vert_axis(void)
+  { return vertAxis != Null(OffsetTo<Axis>); }
+
+  inline bool has_horiz_axis(void)
+  { return horizAxis != Null(OffsetTo<Axis>); }
+
+  // horizontal axis base coords:
+
+  inline unsigned int get_horiz_base_tag_index(Tag baselineTag) const
+  {
+    if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
+    return (this+horizAxis).get_base_tag_index(baselineTag);
+  }
+
+  inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
+  {
+    if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
+    return (this+horizAxis).get_default_base_tag_index_for_script_index(baseScriptIndex);
+  }
+
+  inline int get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+  {
+    return (this+horizAxis).get_base_coord(baseScriptIndex, baselineTagIndex);
+  }
+
+  // vertical axis base coords:
+
+  inline unsigned int get_vert_base_tag_index(Tag baselineTag) const
+  {
+    if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
+    return (this+vertAxis).get_base_tag_index(baselineTag);
+  }
+
+  inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
+  {
+    if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
+    return (this+vertAxis).get_default_base_tag_index_for_script_index(baseScriptIndex);
+  }
+
+  inline int get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+  {
+    return (this+vertAxis).get_base_coord(baseScriptIndex, baselineTagIndex);
+  }
+
+  // horizontal axis min/max coords:
+
+  inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
+  {
+    if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
+    return (this+horizAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag);
+  }
+
+  inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
+  {
+    if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
+    return (this+horizAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag);
+  }
+
+  inline int get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    return (this+horizAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+  }
+
+  inline int get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    return (this+horizAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+  }
+
+    // vertical axis min/max coords:
+
+  inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
+  {
+    if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
+    return (this+vertAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag);
+  }
+
+  inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
+  {
+    if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
+    return (this+vertAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag);
+  }
+
+  inline int get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    return (this+vertAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+  }
+
+  inline int get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+  {
+    return (this+vertAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  likely (version.major == 1) &&
+                  horizAxis.sanitize (c, this) &&
+                  vertAxis.sanitize (c, this) &&
+                  (version.to_int () < 0x00010001u || varStore.sanitize (c, this)));
+  }
+
+  protected:
+  FixedVersion<>  version;
+  OffsetTo<Axis>  horizAxis;
+  OffsetTo<Axis>  vertAxis;
+  LOffsetTo<VariationStore>
+                varStore;               /* Offset to the table of Item Variation
+                                         * Store--from beginning of BASE
+                                         * header (may be NULL).  Introduced
+                                         * in version 0x00010001. */
+  public:
+  DEFINE_SIZE_MIN (8);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_BASE_TABLE_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-common-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-common-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -155,13 +155,13 @@
   }
 
   template <typename set_t>
-  inline void add_coverage (set_t *glyphs) const {
-    glyphs->add_range (start, end);
+  inline bool add_coverage (set_t *glyphs) const {
+    return glyphs->add_range (start, end);
   }
 
   GlyphID       start;          /* First GlyphID in the range */
   GlyphID       end;            /* Last GlyphID in the range */
-  USHORT        value;          /* Value */
+  HBUINT16      value;          /* Value */
   public:
   DEFINE_SIZE_STATIC (6);
 };
@@ -175,7 +175,7 @@
                                    unsigned int *_indexes /* OUT */) const
   {
     if (_count) {
-      const USHORT *arr = this->sub_array (start_offset, _count);
+      const HBUINT16 *arr = this->sub_array (start_offset, _count);
       unsigned int count = *_count;
       for (unsigned int i = 0; i < count; i++)
         _indexes[i] = arr[i];
@@ -216,9 +216,9 @@
     return_trace (c->check_struct (this) && featureIndex.sanitize (c));
   }
 
-  Offset<>      lookupOrderZ;   /* = Null (reserved for an offset to a
+  Offset16      lookupOrderZ;   /* = Null (reserved for an offset to a
                                  * reordering table) */
-  USHORT        reqFeatureIndex;/* Index of a feature required for this
+  HBUINT16      reqFeatureIndex;/* Index of a feature required for this
                                  * language system--if no required features
                                  * = 0xFFFFu */
   IndexArray    featureIndex;   /* Array of indices into the FeatureList */
@@ -299,7 +299,7 @@
      * better.
      *
      * Assume that the offset to the size feature is according to specification,
-     * and make the following value checks. If it fails, assume the the size
+     * and make the following value checks. If it fails, assume the size
      * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it.
      * If this fails, reject the 'size' feature. The older makeOTF's calculated the
      * offset from the beginning of the FeatureList table, rather than from the
@@ -343,12 +343,12 @@
       return_trace (true);
   }
 
-  USHORT        designSize;     /* Represents the design size in 720/inch
+  HBUINT16      designSize;     /* Represents the design size in 720/inch
                                  * units (decipoints).  The design size entry
                                  * must be non-zero.  When there is a design
                                  * size but no recommended size range, the
                                  * rest of the array will consist of zeros. */
-  USHORT        subfamilyID;    /* Has no independent meaning, but serves
+  HBUINT16      subfamilyID;    /* Has no independent meaning, but serves
                                  * as an identifier that associates fonts
                                  * in a subfamily. All fonts which share a
                                  * Preferred or Font Family name and which
@@ -358,7 +358,7 @@
                                  * same subfamily value. If this value is
                                  * zero, the remaining fields in the array
                                  * will be ignored. */
-  USHORT        subfamilyNameID;/* If the preceding value is non-zero, this
+  HBUINT16      subfamilyNameID;/* If the preceding value is non-zero, this
                                  * value must be set in the range 256 - 32767
                                  * (inclusive). It records the value of a
                                  * field in the name table, which must
@@ -372,10 +372,10 @@
                                  * subfamily in a menu.  Applications will
                                  * choose the appropriate version based on
                                  * their selection criteria. */
-  USHORT        rangeStart;     /* Large end of the recommended usage range
+  HBUINT16      rangeStart;     /* Large end of the recommended usage range
                                  * (inclusive), stored in 720/inch units
                                  * (decipoints). */
-  USHORT        rangeEnd;       /* Small end of the recommended usage range
+  HBUINT16      rangeEnd;       /* Small end of the recommended usage range
                                    (exclusive), stored in 720/inch units
                                  * (decipoints). */
   public:
@@ -393,12 +393,12 @@
     return_trace (c->check_struct (this));
   }
 
-  USHORT        version;        /* (set to 0): This corresponds to a “minor”
+  HBUINT16      version;        /* (set to 0): This corresponds to a “minor”
                                  * version number. Additional data may be
                                  * added to the end of this Feature Parameters
                                  * table in the future. */
 
-  USHORT        uiNameID;       /* The 'name' table name ID that specifies a
+  HBUINT16      uiNameID;       /* The 'name' table name ID that specifies a
                                  * string (or strings, for multiple languages)
                                  * for a user-interface label for this
                                  * feature.  The values of uiLabelNameId and
@@ -426,25 +426,25 @@
                   characters.sanitize (c));
   }
 
-  USHORT        format;                 /* Format number is set to 0. */
-  USHORT        featUILableNameID;      /* The ‘name’ table name ID that
+  HBUINT16      format;                 /* Format number is set to 0. */
+  HBUINT16      featUILableNameID;      /* The ‘name’ table name ID that
                                          * specifies a string (or strings,
                                          * for multiple languages) for a
                                          * user-interface label for this
                                          * feature. (May be nullptr.) */
-  USHORT        featUITooltipTextNameID;/* The ‘name’ table name ID that
+  HBUINT16      featUITooltipTextNameID;/* The ‘name’ table name ID that
                                          * specifies a string (or strings,
                                          * for multiple languages) that an
                                          * application can use for tooltip
                                          * text for this feature. (May be
                                          * nullptr.) */
-  USHORT        sampleTextNameID;       /* The ‘name’ table name ID that
+  HBUINT16      sampleTextNameID;       /* The ‘name’ table name ID that
                                          * specifies sample text that
                                          * illustrates the effect of this
                                          * feature. (May be nullptr.) */
-  USHORT        numNamedParameters;     /* Number of named parameters. (May
+  HBUINT16      numNamedParameters;     /* Number of named parameters. (May
                                          * be zero.) */
-  USHORT        firstParamUILabelNameID;/* The first ‘name’ table name ID
+  HBUINT16      firstParamUILabelNameID;/* The first ‘name’ table name ID
                                          * used to specify strings for
                                          * user-interface labels for the
                                          * feature parameters. (Must be zero
@@ -562,7 +562,7 @@
 typedef RecordListOf<Feature> FeatureList;
 
 
-struct LookupFlag : USHORT
+struct LookupFlag : HBUINT16
 {
   enum Flags {
     RightToLeft         = 0x0001u,
@@ -608,7 +608,7 @@
     unsigned int flag = lookupFlag;
     if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
     {
-      const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+      const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
       flag += (markFilteringSet << 16);
     }
     return flag;
@@ -640,7 +640,7 @@
     if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
     {
-      USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+      HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
       markFilteringSet.set (lookup_props >> 16);
     }
     return_trace (true);
@@ -653,18 +653,18 @@
     if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
     {
-      const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+      const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
       if (!markFilteringSet.sanitize (c)) return_trace (false);
     }
     return_trace (true);
   }
 
   private:
-  USHORT        lookupType;             /* Different enumerations for GSUB and GPOS */
-  USHORT        lookupFlag;             /* Lookup qualifiers */
-  ArrayOf<Offset<> >
+  HBUINT16      lookupType;             /* Different enumerations for GSUB and GPOS */
+  HBUINT16      lookupFlag;             /* Lookup qualifiers */
+  ArrayOf<Offset16>
                 subTable;               /* Array of SubTables */
-  USHORT        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:
@@ -700,7 +700,7 @@
     if (unlikely (!c->extend (glyphArray))) return_trace (false);
     for (unsigned int i = 0; i < num_glyphs; i++)
       glyphArray[i] = glyphs[i];
-    glyphs.advance (num_glyphs);
+    glyphs += num_glyphs;
     return_trace (true);
   }
 
@@ -715,10 +715,8 @@
   }
 
   template <typename set_t>
-  inline void add_coverage (set_t *glyphs) const {
-    unsigned int count = glyphArray.len;
-    for (unsigned int i = 0; i < count; i++)
-      glyphs->add (glyphArray[i]);
+  inline bool add_coverage (set_t *glyphs) const {
+    return glyphs->add_sorted_array (glyphArray.array, glyphArray.len);
   }
 
   public:
@@ -737,7 +735,7 @@
   private:
 
   protected:
-  USHORT        coverageFormat; /* Format identifier--format = 1 */
+  HBUINT16      coverageFormat; /* Format identifier--format = 1 */
   SortedArrayOf<GlyphID>
                 glyphArray;     /* Array of GlyphIDs--in numerical order */
   public:
@@ -791,7 +789,7 @@
       } else {
         rangeRecord[range].end = glyphs[i];
       }
-    glyphs.advance (num_glyphs);
+    glyphs += num_glyphs;
     return_trace (true);
   }
 
@@ -817,10 +815,12 @@
   }
 
   template <typename set_t>
-  inline void add_coverage (set_t *glyphs) const {
+  inline bool add_coverage (set_t *glyphs) const {
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
-      rangeRecord[i].add_coverage (glyphs);
+      if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+        return false;
+    return true;
   }
 
   public:
@@ -860,7 +860,7 @@
   private:
 
   protected:
-  USHORT        coverageFormat; /* Format identifier--format = 2 */
+  HBUINT16      coverageFormat; /* Format identifier--format = 2 */
   SortedArrayOf<RangeRecord>
                 rangeRecord;    /* Array of glyph ranges--ordered by
                                  * Start GlyphID. rangeCount entries
@@ -874,8 +874,8 @@
   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
   {
     switch (u.format) {
-    case 1: return u.format1.get_coverage(glyph_id);
-    case 2: return u.format2.get_coverage(glyph_id);
+    case 1: return u.format1.get_coverage (glyph_id);
+    case 2: return u.format2.get_coverage (glyph_id);
     default:return NOT_COVERED;
     }
   }
@@ -927,12 +927,14 @@
     }
   }
 
+  /* Might return false if array looks unsorted.
+   * Used for faster rejection of corrupt data. */
   template <typename set_t>
-  inline void add_coverage (set_t *glyphs) const {
+  inline bool add_coverage (set_t *glyphs) const {
     switch (u.format) {
-    case 1: u.format1.add_coverage (glyphs); break;
-    case 2: u.format2.add_coverage (glyphs); break;
-    default:                                 break;
+    case 1: return u.format1.add_coverage (glyphs);
+    case 2: return u.format2.add_coverage (glyphs);
+    default:return false;
     }
   }
 
@@ -985,7 +987,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   CoverageFormat1       format1;
   CoverageFormat2       format2;
   } u;
@@ -1018,11 +1020,36 @@
   }
 
   template <typename set_t>
-  inline void add_class (set_t *glyphs, unsigned int klass) const {
+  inline bool add_coverage (set_t *glyphs) const {
+    unsigned int start = 0;
     unsigned int count = classValue.len;
     for (unsigned int i = 0; i < count; i++)
+    {
+      if (classValue[i])
+        continue;
+
+      if (start != i)
+        if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i)))
+          return false;
+
+      start = i + 1;
+    }
+    if (start != count)
+      if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + count)))
+        return false;
+
+    return true;
+  }
+
+  template <typename set_t>
+  inline bool add_class (set_t *glyphs, unsigned int klass) const {
+    unsigned int count = classValue.len;
+    for (unsigned int i = 0; i < count; i++)
+    {
       if (classValue[i] == klass)
         glyphs->add (startGlyph + i);
+    }
+    return true;
   }
 
   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
@@ -1030,7 +1057,7 @@
     if (klass == 0)
     {
       /* Match if there's any glyph that is not listed! */
-      hb_codepoint_t g = -1;
+      hb_codepoint_t g = HB_SET_VALUE_INVALID;
       if (!hb_set_next (glyphs, &g))
         return false;
       if (g < startGlyph)
@@ -1047,9 +1074,9 @@
   }
 
   protected:
-  USHORT        classFormat;            /* Format identifier--format = 1 */
+  HBUINT16      classFormat;            /* Format identifier--format = 1 */
   GlyphID       startGlyph;             /* First GlyphID of the classValueArray */
-  ArrayOf<USHORT>
+  ArrayOf<HBUINT16>
                 classValue;             /* Array of Class Values--one per GlyphID */
   public:
   DEFINE_SIZE_ARRAY (6, classValue);
@@ -1075,11 +1102,25 @@
   }
 
   template <typename set_t>
-  inline void add_class (set_t *glyphs, unsigned int klass) const {
+  inline bool add_coverage (set_t *glyphs) const {
     unsigned int count = rangeRecord.len;
     for (unsigned int i = 0; i < count; i++)
+      if (rangeRecord[i].value)
+        if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+          return false;
+    return true;
+  }
+
+  template <typename set_t>
+  inline bool add_class (set_t *glyphs, unsigned int klass) const {
+    unsigned int count = rangeRecord.len;
+    for (unsigned int i = 0; i < count; i++)
+    {
       if (rangeRecord[i].value == klass)
-        rangeRecord[i].add_coverage (glyphs);
+        if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
+          return false;
+    }
+    return true;
   }
 
   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
@@ -1087,7 +1128,7 @@
     if (klass == 0)
     {
       /* Match if there's any glyph that is not listed! */
-      hb_codepoint_t g = (hb_codepoint_t) -1;
+      hb_codepoint_t g = HB_SET_VALUE_INVALID;
       for (unsigned int i = 0; i < count; i++)
       {
         if (!hb_set_next (glyphs, &g))
@@ -1096,7 +1137,7 @@
           return true;
         g = rangeRecord[i].end;
       }
-      if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g))
+      if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
         return true;
       /* Fall through. */
     }
@@ -1107,7 +1148,7 @@
   }
 
   protected:
-  USHORT        classFormat;    /* Format identifier--format = 2 */
+  HBUINT16      classFormat;    /* Format identifier--format = 2 */
   SortedArrayOf<RangeRecord>
                 rangeRecord;    /* Array of glyph ranges--ordered by
                                  * Start GlyphID */
@@ -1120,8 +1161,8 @@
   inline unsigned int get_class (hb_codepoint_t glyph_id) const
   {
     switch (u.format) {
-    case 1: return u.format1.get_class(glyph_id);
-    case 2: return u.format2.get_class(glyph_id);
+    case 1: return u.format1.get_class (glyph_id);
+    case 2: return u.format2.get_class (glyph_id);
     default:return 0;
     }
   }
@@ -1137,11 +1178,25 @@
     }
   }
 
-  inline void add_class (hb_set_t *glyphs, unsigned int klass) const {
+  /* Might return false if array looks unsorted.
+   * Used for faster rejection of corrupt data. */
+  template <typename set_t>
+  inline bool add_coverage (set_t *glyphs) const {
     switch (u.format) {
-    case 1: u.format1.add_class (glyphs, klass); return;
-    case 2: u.format2.add_class (glyphs, klass); return;
-    default:return;
+    case 1: return u.format1.add_coverage (glyphs);
+    case 2: return u.format2.add_coverage (glyphs);
+    default:return false;
+    }
+  }
+
+  /* Might return false if array looks unsorted.
+   * Used for faster rejection of corrupt data. */
+  template <typename set_t>
+  inline bool add_class (set_t *glyphs, unsigned int klass) const {
+    switch (u.format) {
+    case 1: return u.format1.add_class (glyphs, klass);
+    case 2: return u.format2.add_class (glyphs, klass);
+    default:return false;
     }
   }
 
@@ -1155,7 +1210,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   ClassDefFormat1       format1;
   ClassDefFormat2       format2;
   } u;
@@ -1220,10 +1275,11 @@
     const VarRegionAxis *axes = axesZ + (region_index * axisCount);
 
     float v = 1.;
-    unsigned int count = MIN (coord_len, (unsigned int) axisCount);
+    unsigned int count = axisCount;
     for (unsigned int i = 0; i < count; i++)
     {
-      float factor = axes[i].evaluate (coords[i]);
+      int coord = i < coord_len ? coords[i] : 0;
+      float factor = axes[i].evaluate (coord);
       if (factor == 0.)
         return 0.;
       v *= factor;
@@ -1240,8 +1296,8 @@
   }
 
   protected:
-  USHORT        axisCount;
-  USHORT        regionCount;
+  HBUINT16      axisCount;
+  HBUINT16      regionCount;
   VarRegionAxis axesZ[VAR];
   public:
   DEFINE_SIZE_ARRAY (4, axesZ);
@@ -1265,19 +1321,19 @@
    unsigned int count = regionIndices.len;
    unsigned int scount = shortCount;
 
-   const BYTE *bytes = &StructAfter<BYTE> (regionIndices);
-   const BYTE *row = bytes + inner * (scount + count);
+   const HBUINT8 *bytes = &StructAfter<HBUINT8> (regionIndices);
+   const HBUINT8 *row = bytes + inner * (scount + count);
 
    float delta = 0.;
    unsigned int i = 0;
 
-   const SHORT *scursor = reinterpret_cast<const SHORT *> (row);
+   const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row);
    for (; i < scount; i++)
    {
      float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
      delta += scalar * *scursor++;
    }
-   const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor);
+   const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor);
    for (; i < count; i++)
    {
      float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
@@ -1293,15 +1349,15 @@
     return_trace (c->check_struct (this) &&
                   regionIndices.sanitize(c) &&
                   shortCount <= regionIndices.len &&
-                  c->check_array (&StructAfter<BYTE> (regionIndices),
+                  c->check_array (&StructAfter<HBUINT8> (regionIndices),
                                   get_row_size (), itemCount));
   }
 
   protected:
-  USHORT                itemCount;
-  USHORT                shortCount;
-  ArrayOf<USHORT>       regionIndices;
-  BYTE                  bytesX[VAR];
+  HBUINT16              itemCount;
+  HBUINT16              shortCount;
+  ArrayOf<HBUINT16>     regionIndices;
+  HBUINT8                       bytesX[VAR];
   public:
   DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
 };
@@ -1337,9 +1393,9 @@
   }
 
   protected:
-  USHORT                                format;
+  HBUINT16                              format;
   LOffsetTo<VarRegionList>              regions;
-  OffsetArrayOf<VarData, ULONG>         dataSets;
+  OffsetArrayOf<VarData, HBUINT32>      dataSets;
   public:
   DEFINE_SIZE_ARRAY (8, dataSets);
 };
@@ -1366,8 +1422,8 @@
   }
 
   protected:
-  USHORT        format;         /* Format identifier--format = 1 */
-  USHORT        axisIndex;
+  HBUINT16      format;         /* Format identifier--format = 1 */
+  HBUINT16      axisIndex;
   F2DOT14       filterRangeMinValue;
   F2DOT14       filterRangeMaxValue;
   public:
@@ -1396,7 +1452,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   ConditionFormat1      format1;
   } u;
   public:
@@ -1421,7 +1477,7 @@
   }
 
   protected:
-  OffsetArrayOf<Condition, ULONG> conditions;
+  OffsetArrayOf<Condition, HBUINT32> conditions;
   public:
   DEFINE_SIZE_ARRAY (2, conditions);
 };
@@ -1437,7 +1493,7 @@
   }
 
   protected:
-  USHORT                featureIndex;
+  HBUINT16              featureIndex;
   LOffsetTo<Feature>    feature;
   public:
   DEFINE_SIZE_STATIC (6);
@@ -1557,8 +1613,8 @@
   inline unsigned int get_size (void) const
   {
     unsigned int f = deltaFormat;
-    if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size;
-    return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f)));
+    if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * HBUINT16::static_size;
+    return HBUINT16::static_size * (4 + ((endSize - startSize) >> (4 - f)));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -1603,14 +1659,14 @@
   }
 
   protected:
-  USHORT        startSize;              /* Smallest size to correct--in ppem */
-  USHORT        endSize;                /* Largest size to correct--in ppem */
-  USHORT        deltaFormat;            /* Format of DeltaValue array data: 1, 2, or 3
+  HBUINT16      startSize;              /* Smallest size to correct--in ppem */
+  HBUINT16      endSize;                /* Largest size to correct--in ppem */
+  HBUINT16      deltaFormat;            /* Format of DeltaValue array data: 1, 2, or 3
                                          * 1    Signed 2-bit value, 8 values per uint16
                                          * 2    Signed 4-bit value, 4 values per uint16
                                          * 3    Signed 8-bit value, 2 values per uint16
                                          */
-  USHORT        deltaValue[VAR];        /* Array of compressed data */
+  HBUINT16      deltaValue[VAR];        /* Array of compressed data */
   public:
   DEFINE_SIZE_ARRAY (6, deltaValue);
 };
@@ -1641,9 +1697,9 @@
   }
 
   protected:
-  USHORT        outerIndex;
-  USHORT        innerIndex;
-  USHORT        deltaFormat;    /* Format identifier for this table: 0x0x8000 */
+  HBUINT16      outerIndex;
+  HBUINT16      innerIndex;
+  HBUINT16      deltaFormat;    /* Format identifier for this table: 0x0x8000 */
   public:
   DEFINE_SIZE_STATIC (6);
 };
@@ -1651,10 +1707,10 @@
 struct DeviceHeader
 {
   protected:
-  USHORT                reserved1;
-  USHORT                reserved2;
+  HBUINT16              reserved1;
+  HBUINT16              reserved2;
   public:
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   public:
   DEFINE_SIZE_STATIC (6);
 };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gdef-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gdef-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -41,7 +41,7 @@
  * Attachment List Table
  */
 
-typedef ArrayOf<USHORT> AttachPoint;    /* Array of contour point indices--in
+typedef ArrayOf<HBUINT16> AttachPoint;  /* Array of contour point indices--in
                                          * increasing numerical order */
 
 struct AttachList
@@ -62,7 +62,7 @@
     const AttachPoint &points = this+attachPoint[index];
 
     if (point_count) {
-      const USHORT *array = points.sub_array (start_offset, point_count);
+      const HBUINT16 *array = points.sub_array (start_offset, point_count);
       unsigned int count = *point_count;
       for (unsigned int i = 0; i < count; i++)
         point_array[i] = array[i];
@@ -109,8 +109,8 @@
   }
 
   protected:
-  USHORT        caretValueFormat;       /* Format identifier--format = 1 */
-  SHORT         coordinate;             /* X or Y value, in design units */
+  HBUINT16      caretValueFormat;       /* Format identifier--format = 1 */
+  FWORD         coordinate;             /* X or Y value, in design units */
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -136,8 +136,8 @@
   }
 
   protected:
-  USHORT        caretValueFormat;       /* Format identifier--format = 2 */
-  USHORT        caretValuePoint;        /* Contour point index on glyph */
+  HBUINT16      caretValueFormat;       /* Format identifier--format = 2 */
+  HBUINT16      caretValuePoint;        /* Contour point index on glyph */
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -160,8 +160,8 @@
   }
 
   protected:
-  USHORT        caretValueFormat;       /* Format identifier--format = 3 */
-  SHORT         coordinate;             /* X or Y value, in design units */
+  HBUINT16      caretValueFormat;       /* Format identifier--format = 3 */
+  FWORD         coordinate;             /* X or Y value, in design units */
   OffsetTo<Device>
                 deviceTable;            /* Offset to Device table for X or Y
                                          * value--from beginning of CaretValue
@@ -199,7 +199,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   CaretValueFormat1     format1;
   CaretValueFormat2     format2;
   CaretValueFormat3     format3;
@@ -294,7 +294,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   ArrayOf<LOffsetTo<Coverage> >
                 coverage;               /* Array of long offsets to mark set
                                          * coverage tables */
@@ -324,7 +324,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   MarkGlyphSetsFormat1  format1;
   } u;
   public:
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gpos-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gpos-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -51,11 +51,11 @@
 
 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
 
-typedef USHORT Value;
+typedef HBUINT16 Value;
 
 typedef Value ValueRecord[VAR];
 
-struct ValueFormat : USHORT
+struct ValueFormat : HBUINT16
 {
   enum Flags {
     xPlacement  = 0x0001u,      /* Includes horizontal adjustment for placement */
@@ -74,14 +74,14 @@
 
 /* All fields are options.  Only those available advance the value pointer. */
 #if 0
-  SHORT         xPlacement;             /* Horizontal adjustment for
+  HBINT16               xPlacement;             /* Horizontal adjustment for
                                          * placement--in design units */
-  SHORT         yPlacement;             /* Vertical adjustment for
+  HBINT16               yPlacement;             /* Vertical adjustment for
                                          * placement--in design units */
-  SHORT         xAdvance;               /* Horizontal adjustment for
+  HBINT16               xAdvance;               /* Horizontal adjustment for
                                          * advance--in design units (only used
                                          * for horizontal writing) */
-  SHORT         yAdvance;               /* Vertical adjustment for advance--in
+  HBINT16               yAdvance;               /* Vertical adjustment for advance--in
                                          * design units (only used for vertical
                                          * writing) */
   Offset        xPlaDevice;             /* Offset to Device table for
@@ -99,11 +99,11 @@
 #endif
 
   inline unsigned int get_len (void) const
-  { return _hb_popcount32 ((unsigned int) *this); }
+  { return _hb_popcount ((unsigned int) *this); }
   inline unsigned int get_size (void) const
   { return get_len () * Value::static_size; }
 
-  void apply_value (hb_apply_context_t   *c,
+  void apply_value (hb_ot_apply_context_t   *c,
                     const void           *base,
                     const Value          *values,
                     hb_glyph_position_t  &glyph_pos) const
@@ -178,8 +178,8 @@
   static inline const OffsetTo<Device>& get_device (const Value* value)
   { return *CastP<OffsetTo<Device> > (value); }
 
-  static inline const SHORT& get_short (const Value* value)
-  { return *CastP<SHORT> (value); }
+  static inline const HBINT16& get_short (const Value* value)
+  { return *CastP<HBINT16> (value); }
 
   public:
 
@@ -232,12 +232,12 @@
 
 struct AnchorFormat1
 {
-  inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
-                          hb_position_t *x, hb_position_t *y) const
+  inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
+                          float *x, float *y) const
   {
     hb_font_t *font = c->font;
-    *x = font->em_scale_x (xCoordinate);
-    *y = font->em_scale_y (yCoordinate);
+    *x = font->em_fscale_x (xCoordinate);
+    *y = font->em_fscale_y (yCoordinate);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -247,17 +247,17 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
-  SHORT         xCoordinate;            /* Horizontal value--in design units */
-  SHORT         yCoordinate;            /* Vertical value--in design units */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  FWORD         xCoordinate;            /* Horizontal value--in design units */
+  FWORD         yCoordinate;            /* Vertical value--in design units */
   public:
   DEFINE_SIZE_STATIC (6);
 };
 
 struct AnchorFormat2
 {
-  inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id,
-                          hb_position_t *x, hb_position_t *y) const
+  inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
+                          float *x, float *y) const
   {
     hb_font_t *font = c->font;
     unsigned int x_ppem = font->x_ppem;
@@ -267,8 +267,8 @@
 
     ret = (x_ppem || y_ppem) &&
            font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
-    *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate);
-    *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate);
+    *x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate);
+    *y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -278,22 +278,22 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 2 */
-  SHORT         xCoordinate;            /* Horizontal value--in design units */
-  SHORT         yCoordinate;            /* Vertical value--in design units */
-  USHORT        anchorPoint;            /* Index to glyph contour point */
+  HBUINT16      format;                 /* Format identifier--format = 2 */
+  FWORD         xCoordinate;            /* Horizontal value--in design units */
+  FWORD         yCoordinate;            /* Vertical value--in design units */
+  HBUINT16      anchorPoint;            /* Index to glyph contour point */
   public:
   DEFINE_SIZE_STATIC (8);
 };
 
 struct AnchorFormat3
 {
-  inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
-                          hb_position_t *x, hb_position_t *y) const
+  inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
+                          float *x, float *y) const
   {
     hb_font_t *font = c->font;
-    *x = font->em_scale_x (xCoordinate);
-    *y = font->em_scale_y (yCoordinate);
+    *x = font->em_fscale_x (xCoordinate);
+    *y = font->em_fscale_y (yCoordinate);
 
     if (font->x_ppem || font->num_coords)
       *x += (this+xDeviceTable).get_x_delta (font, c->var_store);
@@ -308,9 +308,9 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 3 */
-  SHORT         xCoordinate;            /* Horizontal value--in design units */
-  SHORT         yCoordinate;            /* Vertical value--in design units */
+  HBUINT16      format;                 /* Format identifier--format = 3 */
+  FWORD         xCoordinate;            /* Horizontal value--in design units */
+  FWORD         yCoordinate;            /* Vertical value--in design units */
   OffsetTo<Device>
                 xDeviceTable;           /* Offset to Device table for X
                                          * coordinate-- from beginning of
@@ -325,15 +325,15 @@
 
 struct Anchor
 {
-  inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id,
-                          hb_position_t *x, hb_position_t *y) const
+  inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
+                          float *x, float *y) const
   {
     *x = *y = 0;
     switch (u.format) {
     case 1: u.format1.get_anchor (c, glyph_id, x, y); return;
     case 2: u.format2.get_anchor (c, glyph_id, x, y); return;
     case 3: u.format3.get_anchor (c, glyph_id, x, y); return;
-    default:                                             return;
+    default:                                          return;
     }
   }
 
@@ -351,7 +351,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   AnchorFormat1         format1;
   AnchorFormat2         format2;
   AnchorFormat3         format3;
@@ -382,7 +382,7 @@
     return_trace (true);
   }
 
-  USHORT        rows;                   /* Number of rows */
+  HBUINT16      rows;                   /* Number of rows */
   protected:
   OffsetTo<Anchor>
                 matrixZ[VAR];           /* Matrix of offsets to Anchor tables--
@@ -403,7 +403,7 @@
   }
 
   protected:
-  USHORT        klass;                  /* Class defined for this mark */
+  HBUINT16      klass;                  /* Class defined for this mark */
   OffsetTo<Anchor>
                 markAnchor;             /* Offset to Anchor table--from
                                          * beginning of MarkArray table */
@@ -413,7 +413,7 @@
 
 struct MarkArray : ArrayOf<MarkRecord>  /* Array of MarkRecords--in Coverage order */
 {
-  inline bool apply (hb_apply_context_t *c,
+  inline bool apply (hb_ot_apply_context_t *c,
                      unsigned int mark_index, unsigned int glyph_index,
                      const AnchorMatrix &anchors, unsigned int class_count,
                      unsigned int glyph_pos) const
@@ -430,15 +430,15 @@
      * return false such that the subsequent subtables have a chance at it. */
     if (unlikely (!found)) return_trace (false);
 
-    hb_position_t mark_x, mark_y, base_x, base_y;
+    float mark_x, mark_y, base_x, base_y;
 
     buffer->unsafe_to_break (glyph_pos, buffer->idx);
     mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
     glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
 
     hb_glyph_position_t &o = buffer->cur_pos();
-    o.x_offset = base_x - mark_x;
-    o.y_offset = base_y - mark_y;
+    o.x_offset = round (base_x - mark_x);
+    o.y_offset = round (base_y - mark_y);
     o.attach_type() = ATTACH_TYPE_MARK;
     o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
     buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
@@ -462,7 +462,7 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+coverage).add_coverage (c->input);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
   }
 
   inline const Coverage &get_coverage (void) const
@@ -470,7 +470,7 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
@@ -492,7 +492,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of subtable */
@@ -510,7 +510,7 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+coverage).add_coverage (c->input);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
   }
 
   inline const Coverage &get_coverage (void) const
@@ -518,7 +518,7 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
@@ -544,13 +544,13 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 2 */
+  HBUINT16      format;                 /* Format identifier--format = 2 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of subtable */
   ValueFormat   valueFormat;            /* Defines the types of data in the
                                          * ValueRecord */
-  USHORT        valueCount;             /* Number of ValueRecords */
+  HBUINT16      valueCount;             /* Number of ValueRecords */
   ValueRecord   values;                 /* Array of ValueRecords--positioning
                                          * values applied to glyphs */
   public:
@@ -573,7 +573,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   SinglePosFormat1      format1;
   SinglePosFormat2      format2;
   } u;
@@ -604,18 +604,13 @@
     TRACE_COLLECT_GLYPHS (this);
     unsigned int len1 = valueFormats[0].get_len ();
     unsigned int len2 = valueFormats[1].get_len ();
-    unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
+    unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
 
     const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
-    unsigned int count = len;
-    for (unsigned int i = 0; i < count; i++)
-    {
-      c->input->add (record->secondGlyph);
-      record = &StructAtOffset<PairValueRecord> (record, record_size);
-    }
+    c->input->add_array (&record->secondGlyph, len, record_size);
   }
 
-  inline bool apply (hb_apply_context_t *c,
+  inline bool apply (hb_ot_apply_context_t *c,
                      const ValueFormat *valueFormats,
                      unsigned int pos) const
   {
@@ -623,7 +618,7 @@
     hb_buffer_t *buffer = c->buffer;
     unsigned int len1 = valueFormats[0].get_len ();
     unsigned int len2 = valueFormats[1].get_len ();
-    unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
+    unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
 
     const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
     unsigned int count = len;
@@ -668,7 +663,7 @@
   {
     TRACE_SANITIZE (this);
     if (!(c->check_struct (this)
-       && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return_trace (false);
+       && c->check_array (arrayZ, HBUINT16::static_size * closure->stride, len))) return_trace (false);
 
     unsigned int count = len;
     const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
@@ -677,8 +672,8 @@
   }
 
   protected:
-  USHORT        len;                    /* Number of PairValueRecords */
-  USHORT        arrayZ[VAR];            /* Array of PairValueRecords--ordered
+  HBUINT16      len;                    /* Number of PairValueRecords */
+  HBUINT16      arrayZ[VAR];            /* Array of PairValueRecords--ordered
                                          * by GlyphID of the second glyph */
   public:
   DEFINE_SIZE_ARRAY (2, arrayZ);
@@ -689,7 +684,7 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+coverage).add_coverage (c->input);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
     unsigned int count = pairSet.len;
     for (unsigned int i = 0; i < count; i++)
       (this+pairSet[i]).collect_glyphs (c, valueFormat);
@@ -700,14 +695,14 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
     unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
-    hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     if (!skippy_iter.next ()) return_trace (false);
 
@@ -733,7 +728,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of subtable */
@@ -755,17 +750,8 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+coverage).add_coverage (c->input);
-
-    unsigned int count1 = class1Count;
-    const ClassDef &klass1 = this+classDef1;
-    for (unsigned int i = 0; i < count1; i++)
-      klass1.add_class (c->input, i);
-
-    unsigned int count2 = class2Count;
-    const ClassDef &klass2 = this+classDef2;
-    for (unsigned int i = 0; i < count2; i++)
-      klass2.add_class (c->input, i);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+classDef2).add_coverage (c->input))) return;
   }
 
   inline const Coverage &get_coverage (void) const
@@ -773,14 +759,14 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
     unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
-    hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     if (!skippy_iter.next ()) return_trace (false);
 
@@ -823,7 +809,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 2 */
+  HBUINT16      format;                 /* Format identifier--format = 2 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of subtable */
@@ -841,9 +827,9 @@
                 classDef2;              /* Offset to ClassDef table--from
                                          * beginning of PairPos subtable--for
                                          * the second glyph of the pair */
-  USHORT        class1Count;            /* Number of classes in ClassDef1
+  HBUINT16      class1Count;            /* Number of classes in ClassDef1
                                          * table--includes Class0 */
-  USHORT        class2Count;            /* Number of classes in ClassDef2
+  HBUINT16      class2Count;            /* Number of classes in ClassDef2
                                          * table--includes Class0 */
   ValueRecord   values;                 /* Matrix of value pairs:
                                          * class1-major, class2-minor,
@@ -868,7 +854,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   PairPosFormat1        format1;
   PairPosFormat2        format2;
   } u;
@@ -906,7 +892,7 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+coverage).add_coverage (c->input);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
   }
 
   inline const Coverage &get_coverage (void) const
@@ -914,7 +900,7 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
@@ -922,7 +908,7 @@
     const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage  (buffer->cur().codepoint)];
     if (!this_record.exitAnchor) return_trace (false);
 
-    hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     if (!skippy_iter.next ()) return_trace (false);
 
@@ -933,7 +919,7 @@
     unsigned int j = skippy_iter.idx;
 
     buffer->unsafe_to_break (i, j);
-    hb_position_t entry_x, entry_y, exit_x, exit_y;
+    float entry_x, entry_y, exit_x, exit_y;
     (this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
     (this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
 
@@ -943,32 +929,32 @@
     /* Main-direction adjustment */
     switch (c->direction) {
       case HB_DIRECTION_LTR:
-        pos[i].x_advance  =  exit_x + pos[i].x_offset;
+        pos[i].x_advance  = round (exit_x) + pos[i].x_offset;
 
-        d = entry_x + pos[j].x_offset;
+        d = round (entry_x) + pos[j].x_offset;
         pos[j].x_advance -= d;
         pos[j].x_offset  -= d;
         break;
       case HB_DIRECTION_RTL:
-        d = exit_x + pos[i].x_offset;
+        d = round (exit_x) + pos[i].x_offset;
         pos[i].x_advance -= d;
         pos[i].x_offset  -= d;
 
-        pos[j].x_advance  =  entry_x + pos[j].x_offset;
+        pos[j].x_advance  = round (entry_x) + pos[j].x_offset;
         break;
       case HB_DIRECTION_TTB:
-        pos[i].y_advance  =  exit_y + pos[i].y_offset;
+        pos[i].y_advance  = round (exit_y) + pos[i].y_offset;
 
-        d = entry_y + pos[j].y_offset;
+        d = round (entry_y) + pos[j].y_offset;
         pos[j].y_advance -= d;
         pos[j].y_offset  -= d;
         break;
       case HB_DIRECTION_BTT:
-        d = exit_y + pos[i].y_offset;
+        d = round (exit_y) + pos[i].y_offset;
         pos[i].y_advance -= d;
         pos[i].y_offset  -= d;
 
-        pos[j].y_advance  =  entry_y;
+        pos[j].y_advance  = round (entry_y);
         break;
       case HB_DIRECTION_INVALID:
       default:
@@ -1022,7 +1008,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of subtable */
@@ -1048,7 +1034,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   CursivePosFormat1     format1;
   } u;
 };
@@ -1064,8 +1050,8 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+markCoverage).add_coverage (c->input);
-    (this+baseCoverage).add_coverage (c->input);
+    if (unlikely (!(this+markCoverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+baseCoverage).add_coverage (c->input))) return;
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1073,7 +1059,7 @@
     return this+markCoverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
@@ -1081,14 +1067,22 @@
     if (likely (mark_index == NOT_COVERED)) return_trace (false);
 
     /* Now we search backwards for a non-mark glyph */
-    hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
     do {
       if (!skippy_iter.prev ()) return_trace (false);
-      /* We only want to attach to the first of a MultipleSubst sequence.  Reject others. */
+      /* We only want to attach to the first of a MultipleSubst sequence.
+       * https://github.com/harfbuzz/harfbuzz/issues/740
+       * Reject others. */
       if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) ||
-          0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]))
+          0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) ||
+          (skippy_iter.idx == 0 ||
+           _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) !=
+           _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) ||
+           _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) !=
+           _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx - 1]) + 1
+           ))
         break;
       skippy_iter.reject ();
     } while (1);
@@ -1113,14 +1107,14 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 markCoverage;           /* Offset to MarkCoverage table--from
                                          * beginning of MarkBasePos subtable */
   OffsetTo<Coverage>
                 baseCoverage;           /* Offset to BaseCoverage table--from
                                          * beginning of MarkBasePos subtable */
-  USHORT        classCount;             /* Number of classes defined for marks */
+  HBUINT16      classCount;             /* Number of classes defined for marks */
   OffsetTo<MarkArray>
                 markArray;              /* Offset to MarkArray table--from
                                          * beginning of MarkBasePos subtable */
@@ -1146,7 +1140,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   MarkBasePosFormat1    format1;
   } u;
 };
@@ -1167,8 +1161,8 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+markCoverage).add_coverage (c->input);
-    (this+ligatureCoverage).add_coverage (c->input);
+    if (unlikely (!(this+markCoverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+ligatureCoverage).add_coverage (c->input))) return;
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1176,7 +1170,7 @@
     return this+markCoverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
@@ -1184,7 +1178,7 @@
     if (likely (mark_index == NOT_COVERED)) return_trace (false);
 
     /* Now we search backwards for a non-mark glyph */
-    hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
     if (!skippy_iter.prev ()) return_trace (false);
@@ -1230,7 +1224,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 markCoverage;           /* Offset to Mark Coverage table--from
                                          * beginning of MarkLigPos subtable */
@@ -1238,7 +1232,7 @@
                 ligatureCoverage;       /* Offset to Ligature Coverage
                                          * table--from beginning of MarkLigPos
                                          * subtable */
-  USHORT        classCount;             /* Number of defined mark classes */
+  HBUINT16      classCount;             /* Number of defined mark classes */
   OffsetTo<MarkArray>
                 markArray;              /* Offset to MarkArray table--from
                                          * beginning of MarkLigPos subtable */
@@ -1264,7 +1258,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   MarkLigPosFormat1     format1;
   } u;
 };
@@ -1280,8 +1274,8 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+mark1Coverage).add_coverage (c->input);
-    (this+mark2Coverage).add_coverage (c->input);
+    if (unlikely (!(this+mark1Coverage).add_coverage (c->input))) return;
+    if (unlikely (!(this+mark2Coverage).add_coverage (c->input))) return;
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1289,7 +1283,7 @@
     return this+mark1Coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_buffer_t *buffer = c->buffer;
@@ -1297,7 +1291,7 @@
     if (likely (mark1_index == NOT_COVERED)) return_trace (false);
 
     /* now we search backwards for a suitable mark glyph until a non-mark glyph */
-    hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
     skippy_iter.reset (buffer->idx, 1);
     skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
     if (!skippy_iter.prev ()) return_trace (false);
@@ -1344,7 +1338,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 mark1Coverage;          /* Offset to Combining Mark1 Coverage
                                          * table--from beginning of MarkMarkPos
@@ -1353,7 +1347,7 @@
                 mark2Coverage;          /* Offset to Combining Mark2 Coverage
                                          * table--from beginning of MarkMarkPos
                                          * subtable */
-  USHORT        classCount;             /* Number of defined mark classes */
+  HBUINT16      classCount;             /* Number of defined mark classes */
   OffsetTo<MarkArray>
                 mark1Array;             /* Offset to Mark1Array table--from
                                          * beginning of MarkMarkPos subtable */
@@ -1379,7 +1373,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   MarkMarkPosFormat1    format1;
   } u;
 };
@@ -1438,7 +1432,7 @@
 
   protected:
   union {
-  USHORT                sub_format;
+  HBUINT16              sub_format;
   SinglePos             single;
   PairPos               pair;
   CursivePos            cursive;
@@ -1464,7 +1458,7 @@
     return false;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     return_trace (dispatch (c));
@@ -1483,7 +1477,7 @@
     dispatch (&c);
   }
 
-  static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+  static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
 
   template <typename context_t>
   static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
@@ -1635,7 +1629,7 @@
   return l.dispatch (c);
 }
 
-/*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
+/*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
 {
   const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
   const PosLookup &l = gpos.get_lookup (lookup_index);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsub-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsub-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -44,7 +44,7 @@
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       /* TODO Switch to range-based API to work around malicious fonts.
-       * https://github.com/behdad/harfbuzz/issues/363 */
+       * https://github.com/harfbuzz/harfbuzz/issues/363 */
       hb_codepoint_t glyph_id = iter.get_glyph ();
       if (c->glyphs->has (glyph_id))
         c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
@@ -54,13 +54,13 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
     Coverage::Iter iter;
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       /* TODO Switch to range-based API to work around malicious fonts.
-       * https://github.com/behdad/harfbuzz/issues/363 */
+       * https://github.com/harfbuzz/harfbuzz/issues/363 */
       hb_codepoint_t glyph_id = iter.get_glyph ();
-      c->input->add (glyph_id);
       c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
     }
   }
@@ -76,7 +76,7 @@
     return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@@ -110,11 +110,11 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of Substitution table */
-  SHORT         deltaGlyphID;           /* Add to original GlyphID to get
+  HBINT16       deltaGlyphID;           /* Add to original GlyphID to get
                                          * substitute GlyphID */
   public:
   DEFINE_SIZE_STATIC (6);
@@ -130,7 +130,7 @@
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
         c->glyphs->add (substitute[iter.get_coverage ()]);
     }
@@ -139,13 +139,13 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
     Coverage::Iter iter;
     unsigned int count = substitute.len;
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
-      c->input->add (iter.get_glyph ());
+        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       c->output->add (substitute[iter.get_coverage ()]);
     }
   }
@@ -161,7 +161,7 @@
     return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@@ -195,7 +195,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 2 */
+  HBUINT16      format;                 /* Format identifier--format = 2 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of Substitution table */
@@ -249,7 +249,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   SingleSubstFormat1    format1;
   SingleSubstFormat2    format2;
   } u;
@@ -269,12 +269,10 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    unsigned int count = substitute.len;
-    for (unsigned int i = 0; i < count; i++)
-      c->output->add (substitute[i]);
+    c->output->add_array (substitute.array, substitute.len);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     unsigned int count = substitute.len;
@@ -287,7 +285,7 @@
       return_trace (true);
     }
     /* Spec disallows this, but Uniscribe allows it.
-     * https://github.com/behdad/harfbuzz/issues/253 */
+     * https://github.com/harfbuzz/harfbuzz/issues/253 */
     else if (unlikely (count == 0))
     {
       c->buffer->delete_glyph ();
@@ -339,7 +337,7 @@
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
         (this+sequence[iter.get_coverage ()]).closure (c);
     }
@@ -348,7 +346,7 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    (this+coverage).add_coverage (c->input);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
     unsigned int count = sequence.len;
     for (unsigned int i = 0; i < count; i++)
         (this+sequence[i]).collect_glyphs (c);
@@ -365,7 +363,7 @@
     return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
 
@@ -388,7 +386,7 @@
       if (unlikely (!sequence[i].serialize (c, this).serialize (c,
                                                                 substitute_glyphs_list,
                                                                 substitute_len_list[i]))) return_trace (false);
-    substitute_len_list.advance (num_glyphs);
+    substitute_len_list += num_glyphs;
     if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
     return_trace (true);
   }
@@ -400,7 +398,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of Substitution table */
@@ -442,7 +440,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   MultipleSubstFormat1  format1;
   } u;
 };
@@ -461,7 +459,7 @@
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ())) {
         const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
         unsigned int count = alt_set.len;
@@ -474,17 +472,15 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
     Coverage::Iter iter;
     unsigned int count = alternateSet.len;
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
-      c->input->add (iter.get_glyph ());
+        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
-      unsigned int count = alt_set.len;
-      for (unsigned int i = 0; i < count; i++)
-        c->output->add (alt_set[i]);
+      c->output->add_array (alt_set.array, alt_set.len);
     }
   }
 
@@ -499,7 +495,7 @@
     return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@@ -540,7 +536,7 @@
       if (unlikely (!alternateSet[i].serialize (c, this).serialize (c,
                                                                     alternate_glyphs_list,
                                                                     alternate_len_list[i]))) return_trace (false);
-    alternate_len_list.advance (num_glyphs);
+    alternate_len_list += num_glyphs;
     if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
     return_trace (true);
   }
@@ -552,7 +548,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of Substitution table */
@@ -594,7 +590,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   AlternateSubstFormat1 format1;
   } u;
 };
@@ -615,9 +611,7 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    unsigned int count = component.len;
-    for (unsigned int i = 1; i < count; i++)
-      c->input->add (component[i]);
+    c->input->add_array (component.array, component.len ? component.len - 1 : 0);
     c->output->add (ligGlyph);
   }
 
@@ -634,7 +628,7 @@
     return_trace (true);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     unsigned int count = component.len;
@@ -736,7 +730,7 @@
     return_trace (false);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     unsigned int num_ligs = ligature.len;
@@ -763,8 +757,8 @@
                                                                 ligatures[i],
                                                                 component_list,
                                                                 component_count_list[i]))) return_trace (false);
-    ligatures.advance (num_ligatures);
-    component_count_list.advance (num_ligatures);
+    ligatures += num_ligatures;
+    component_count_list += num_ligatures;
     return_trace (true);
   }
 
@@ -792,7 +786,7 @@
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
         (this+ligatureSet[iter.get_coverage ()]).closure (c);
     }
@@ -801,13 +795,13 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
     Coverage::Iter iter;
     unsigned int count = ligatureSet.len;
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
-      c->input->add (iter.get_glyph ());
+        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
     }
   }
@@ -827,7 +821,7 @@
     return_trace (lig_set.would_apply (c));
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@@ -856,7 +850,7 @@
                                                                    component_count_list,
                                                                    ligature_per_first_glyph_count_list[i],
                                                                    component_list))) return_trace (false);
-    ligature_per_first_glyph_count_list.advance (num_first_glyphs);
+    ligature_per_first_glyph_count_list += num_first_glyphs;
     if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return_trace (false);
     return_trace (true);
   }
@@ -868,7 +862,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of Substitution table */
@@ -918,7 +912,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   LigatureSubstFormat1  format1;
   } u;
 };
@@ -961,7 +955,7 @@
     for (iter.init (this+coverage); iter.more (); iter.next ())
     {
       if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */
+        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
       if (c->glyphs->has (iter.get_glyph ()))
         c->glyphs->add (substitute[iter.get_coverage ()]);
     }
@@ -970,25 +964,22 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     TRACE_COLLECT_GLYPHS (this);
-
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    if (unlikely (!(this+coverage).add_coverage (c->input))) return;
 
     unsigned int count;
 
-    (this+coverage).add_coverage (c->input);
-
     count = backtrack.len;
     for (unsigned int i = 0; i < count; i++)
-      (this+backtrack[i]).add_coverage (c->before);
+      if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return;
 
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
     count = lookahead.len;
     for (unsigned int i = 0; i < count; i++)
-      (this+lookahead[i]).add_coverage (c->after);
+      if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
 
     const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
     count = substitute.len;
-    for (unsigned int i = 0; i < count; i++)
-      c->output->add (substitute[i]);
+    c->output->add_array (substitute.array, substitute.len);
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1002,7 +993,7 @@
     return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
@@ -1016,11 +1007,11 @@
 
   unsigned int start_index = 0, end_index = 0;
     if (match_backtrack (c,
-                         backtrack.len, (USHORT *) backtrack.array,
+                         backtrack.len, (HBUINT16 *) backtrack.array,
                          match_coverage, this,
                          &start_index) &&
         match_lookahead (c,
-                         lookahead.len, (USHORT *) lookahead.array,
+                         lookahead.len, (HBUINT16 *) lookahead.array,
                          match_coverage, this,
                          1, &end_index))
     {
@@ -1048,7 +1039,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of table */
@@ -1082,7 +1073,7 @@
 
   protected:
   union {
-  USHORT                                format;         /* Format identifier */
+  HBUINT16                              format;         /* Format identifier */
   ReverseChainSingleSubstFormat1        format1;
   } u;
 };
@@ -1128,7 +1119,7 @@
 
   protected:
   union {
-  USHORT                        sub_format;
+  HBUINT16                      sub_format;
   SingleSubst                   single;
   MultipleSubst                 multiple;
   AlternateSubst                alternate;
@@ -1159,7 +1150,7 @@
     return lookup_type_is_reverse (type);
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     return_trace (dispatch (c));
@@ -1195,7 +1186,7 @@
       return_trace (dispatch (c));
   }
 
-  static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+  static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
 
   inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
                                                   unsigned int i)
@@ -1280,8 +1271,9 @@
     if (unlikely (get_type () == SubstLookupSubTable::Extension))
     {
       /* The spec says all subtables of an Extension lookup should
-       * have the same type.  This is specially important if one has
-       * a reverse type! */
+       * have the same type, which shall not be the Extension type
+       * itself (but we already checked for that).
+       * This is specially important if one has a reverse type! */
       unsigned int type = get_subtable (0).u.extension.get_type ();
       unsigned int count = get_subtable_count ();
       for (unsigned int i = 1; i < count; i++)
@@ -1351,7 +1343,7 @@
   return l.dispatch (c);
 }
 
-/*static*/ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
+/*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
 {
   const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
   const SubstLookup &l = gsub.get_lookup (lookup_index);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsubgpos-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsubgpos-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -218,8 +218,8 @@
 };
 
 
-struct hb_apply_context_t :
-       hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY>
+struct hb_ot_apply_context_t :
+       hb_dispatch_context_t<hb_ot_apply_context_t, bool, HB_DEBUG_APPLY>
 {
   struct matcher_t
   {
@@ -234,7 +234,7 @@
              match_func (nullptr),
              match_data (nullptr) {};
 
-    typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
+    typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
 
     inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
     inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
@@ -252,7 +252,7 @@
     };
 
     inline may_match_t may_match (const hb_glyph_info_t &info,
-                                  const USHORT          *glyph_data) const
+                                  const HBUINT16          *glyph_data) const
     {
       if (!(info.mask & mask) ||
           (syllable && syllable != info.syllable ()))
@@ -271,7 +271,7 @@
     };
 
     inline may_skip_t
-    may_skip (const hb_apply_context_t *c,
+    may_skip (const hb_ot_apply_context_t *c,
               const hb_glyph_info_t    &info) const
     {
       if (!c->check_glyph_property (&info, lookup_props))
@@ -297,7 +297,7 @@
 
   struct skipping_iterator_t
   {
-    inline void init (hb_apply_context_t *c_, bool context_match = false)
+    inline void init (hb_ot_apply_context_t *c_, bool context_match = false)
     {
       c = c_;
       match_glyph_data = nullptr;
@@ -315,7 +315,7 @@
     }
     inline void set_match_func (matcher_t::match_func_t match_func_,
                                 const void *match_data_,
-                                const USHORT glyph_data[])
+                                const HBUINT16 glyph_data[])
     {
       matcher.set_match_func (match_func_, match_data_);
       match_glyph_data = glyph_data;
@@ -333,8 +333,7 @@
     inline void reject (void) { num_items++; match_glyph_data--; }
 
     inline matcher_t::may_skip_t
-    may_skip (const hb_apply_context_t *c,
-              const hb_glyph_info_t    &info) const
+    may_skip (const hb_glyph_info_t    &info) const
     {
       return matcher.may_skip (c, info);
     }
@@ -396,9 +395,9 @@
 
     unsigned int idx;
     protected:
-    hb_apply_context_t *c;
+    hb_ot_apply_context_t *c;
     matcher_t matcher;
-    const USHORT *match_glyph_data;
+    const HBUINT16 *match_glyph_data;
 
     unsigned int num_items;
     unsigned int end;
@@ -406,18 +405,18 @@
 
 
   inline const char *get_name (void) { return "APPLY"; }
-  typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
+  typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index);
   template <typename T>
   inline return_t dispatch (const T &obj) { return obj.apply (this); }
   static return_t default_return_value (void) { return false; }
   bool stop_sublookup_iteration (return_t r) const { return r; }
-  return_t recurse (unsigned int lookup_index)
+  return_t recurse (unsigned int sub_lookup_index)
   {
-    if (unlikely (nesting_level_left == 0 || !recurse_func))
+    if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0))
       return default_return_value ();
 
     nesting_level_left--;
-    bool ret = recurse_func (this, lookup_index);
+    bool ret = recurse_func (this, sub_lookup_index);
     nesting_level_left++;
     return ret;
   }
@@ -444,7 +443,7 @@
   bool has_glyph_classes;
 
 
-  hb_apply_context_t (unsigned int table_index_,
+  hb_ot_apply_context_t (unsigned int table_index_,
                       hb_font_t *font_,
                       hb_buffer_t *buffer_) :
                         iter_input (), iter_context (),
@@ -568,9 +567,9 @@
 
 
 
-typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
-typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
-typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
+typedef bool (*intersects_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
+typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
+typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
 
 struct ContextClosureFuncs
 {
@@ -586,16 +585,16 @@
 };
 
 
-static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+static inline bool intersects_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED)
 {
   return glyphs->has (value);
 }
-static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data)
+static inline bool intersects_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
 {
   const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
   return class_def.intersects_class (glyphs, value);
 }
-static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data)
+static inline bool intersects_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
 {
   const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
   return (data+coverage).intersects (glyphs);
@@ -603,7 +602,7 @@
 
 static inline bool intersects_array (hb_closure_context_t *c,
                                      unsigned int count,
-                                     const USHORT values[],
+                                     const HBUINT16 values[],
                                      intersects_func_t intersects_func,
                                      const void *intersects_data)
 {
@@ -614,16 +613,16 @@
 }
 
 
-static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+static inline void collect_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED)
 {
   glyphs->add (value);
 }
-static inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data)
+static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
 {
   const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
   class_def.add_class (glyphs, value);
 }
-static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data)
+static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
 {
   const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
   (data+coverage).add_coverage (glyphs);
@@ -631,7 +630,7 @@
 static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
                                   hb_set_t *glyphs,
                                   unsigned int count,
-                                  const USHORT values[],
+                                  const HBUINT16 values[],
                                   collect_glyphs_func_t collect_func,
                                   const void *collect_data)
 {
@@ -640,16 +639,16 @@
 }
 
 
-static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED)
+static inline bool match_glyph (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data HB_UNUSED)
 {
   return glyph_id == value;
 }
-static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
+static inline bool match_class (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data)
 {
   const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
   return class_def.get_class (glyph_id) == value;
 }
-static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
+static inline bool match_coverage (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data)
 {
   const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
   return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
@@ -657,7 +656,7 @@
 
 static inline bool would_match_input (hb_would_apply_context_t *c,
                                       unsigned int count, /* Including the first glyph (not matched) */
-                                      const USHORT input[], /* Array of input values--start with second glyph */
+                                      const HBUINT16 input[], /* Array of input values--start with second glyph */
                                       match_func_t match_func,
                                       const void *match_data)
 {
@@ -670,9 +669,9 @@
 
   return true;
 }
-static inline bool match_input (hb_apply_context_t *c,
+static inline bool match_input (hb_ot_apply_context_t *c,
                                 unsigned int count, /* Including the first glyph (not matched) */
-                                const USHORT input[], /* Array of input values--start with second glyph */
+                                const HBUINT16 input[], /* Array of input values--start with second glyph */
                                 match_func_t match_func,
                                 const void *match_data,
                                 unsigned int *end_offset,
@@ -686,7 +685,7 @@
 
   hb_buffer_t *buffer = c->buffer;
 
-  hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+  hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
   skippy_iter.reset (buffer->idx, count - 1);
   skippy_iter.set_match_func (match_func, match_data, input);
 
@@ -711,7 +710,7 @@
    *   o If two marks want to ligate and they belong to different components of the
    *     same ligature glyph, and said ligature glyph is to be ignored according to
    *     mark-filtering rules, then allow.
-   *     https://github.com/behdad/harfbuzz/issues/545
+   *     https://github.com/harfbuzz/harfbuzz/issues/545
    */
 
   bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
@@ -763,7 +762,7 @@
             j--;
           }
 
-          if (found && skippy_iter.may_skip (c, out[j]) == hb_apply_context_t::matcher_t::SKIP_YES)
+          if (found && skippy_iter.may_skip (out[j]) == hb_ot_apply_context_t::matcher_t::SKIP_YES)
             ligbase = LIGBASE_MAY_SKIP;
           else
             ligbase = LIGBASE_MAY_NOT_SKIP;
@@ -796,7 +795,7 @@
 
   return_trace (true);
 }
-static inline bool ligate_input (hb_apply_context_t *c,
+static inline bool ligate_input (hb_ot_apply_context_t *c,
                                  unsigned int count, /* Including the first glyph */
                                  unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
                                  unsigned int match_length,
@@ -894,16 +893,16 @@
   return_trace (true);
 }
 
-static inline bool match_backtrack (hb_apply_context_t *c,
+static inline bool match_backtrack (hb_ot_apply_context_t *c,
                                     unsigned int count,
-                                    const USHORT backtrack[],
+                                    const HBUINT16 backtrack[],
                                     match_func_t match_func,
                                     const void *match_data,
                                     unsigned int *match_start)
 {
   TRACE_APPLY (nullptr);
 
-  hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
+  hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
   skippy_iter.reset (c->buffer->backtrack_len (), count);
   skippy_iter.set_match_func (match_func, match_data, backtrack);
 
@@ -916,9 +915,9 @@
   return_trace (true);
 }
 
-static inline bool match_lookahead (hb_apply_context_t *c,
+static inline bool match_lookahead (hb_ot_apply_context_t *c,
                                     unsigned int count,
-                                    const USHORT lookahead[],
+                                    const HBUINT16 lookahead[],
                                     match_func_t match_func,
                                     const void *match_data,
                                     unsigned int offset,
@@ -926,7 +925,7 @@
 {
   TRACE_APPLY (nullptr);
 
-  hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
+  hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
   skippy_iter.reset (c->buffer->idx + offset - 1, count);
   skippy_iter.set_match_func (match_func, match_data, lookahead);
 
@@ -949,9 +948,9 @@
     return_trace (c->check_struct (this));
   }
 
-  USHORT        sequenceIndex;          /* Index into current glyph
+  HBUINT16      sequenceIndex;          /* Index into current glyph
                                          * sequence--first glyph = 0 */
-  USHORT        lookupListIndex;        /* Lookup to apply to that
+  HBUINT16      lookupListIndex;        /* Lookup to apply to that
                                          * position--zero--based */
   public:
   DEFINE_SIZE_STATIC (4);
@@ -967,7 +966,7 @@
     c->recurse (lookupRecord[i].lookupListIndex);
 }
 
-static inline bool apply_lookup (hb_apply_context_t *c,
+static inline bool apply_lookup (hb_ot_apply_context_t *c,
                                  unsigned int count, /* Including the first glyph */
                                  unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
                                  unsigned int lookupCount,
@@ -1002,7 +1001,11 @@
     if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index)
       continue;
 
-    buffer->move_to (match_positions[idx]);
+    if (unlikely (!buffer->move_to (match_positions[idx])))
+      break;
+
+    if (unlikely (buffer->max_ops <= 0))
+      break;
 
     unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
     if (!c->recurse (lookupRecord[i].lookupListIndex))
@@ -1108,7 +1111,7 @@
 
 static inline void context_closure_lookup (hb_closure_context_t *c,
                                            unsigned int inputCount, /* Including the first glyph (not matched) */
-                                           const USHORT input[], /* Array of input values--start with second glyph */
+                                           const HBUINT16 input[], /* Array of input values--start with second glyph */
                                            unsigned int lookupCount,
                                            const LookupRecord lookupRecord[],
                                            ContextClosureLookupContext &lookup_context)
@@ -1122,7 +1125,7 @@
 
 static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
                                                   unsigned int inputCount, /* Including the first glyph (not matched) */
-                                                  const USHORT input[], /* Array of input values--start with second glyph */
+                                                  const HBUINT16 input[], /* Array of input values--start with second glyph */
                                                   unsigned int lookupCount,
                                                   const LookupRecord lookupRecord[],
                                                   ContextCollectGlyphsLookupContext &lookup_context)
@@ -1136,7 +1139,7 @@
 
 static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
                                                unsigned int inputCount, /* Including the first glyph (not matched) */
-                                               const USHORT input[], /* Array of input values--start with second glyph */
+                                               const HBUINT16 input[], /* Array of input values--start with second glyph */
                                                unsigned int lookupCount HB_UNUSED,
                                                const LookupRecord lookupRecord[] HB_UNUSED,
                                                ContextApplyLookupContext &lookup_context)
@@ -1145,9 +1148,9 @@
                             inputCount, input,
                             lookup_context.funcs.match, lookup_context.match_data);
 }
-static inline bool context_apply_lookup (hb_apply_context_t *c,
+static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
                                          unsigned int inputCount, /* Including the first glyph (not matched) */
-                                         const USHORT input[], /* Array of input values--start with second glyph */
+                                         const HBUINT16 input[], /* Array of input values--start with second glyph */
                                          unsigned int lookupCount,
                                          const LookupRecord lookupRecord[],
                                          ContextApplyLookupContext &lookup_context)
@@ -1194,7 +1197,7 @@
     return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
   }
 
-  inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+  inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
     const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
@@ -1209,20 +1212,20 @@
                   lookupCount.sanitize (c) &&
                   c->check_range (inputZ,
                                   inputZ[0].static_size * inputCount +
-                                  lookupRecordX[0].static_size * lookupCount));
+                                  LookupRecord::static_size * lookupCount));
   }
 
   protected:
-  USHORT        inputCount;             /* Total number of glyphs in input
+  HBUINT16      inputCount;             /* Total number of glyphs in input
                                          * glyph sequence--includes the first
                                          * glyph */
-  USHORT        lookupCount;            /* Number of LookupRecords */
-  USHORT        inputZ[VAR];            /* Array of match inputs--start with
+  HBUINT16      lookupCount;            /* Number of LookupRecords */
+  HBUINT16      inputZ[VAR];            /* Array of match inputs--start with
                                          * second glyph */
-  LookupRecord  lookupRecordX[VAR];     /* Array of LookupRecords--in
+/*LookupRecord  lookupRecordX[VAR];*/   /* Array of LookupRecords--in
                                          * design order */
   public:
-  DEFINE_SIZE_ARRAY2 (4, inputZ, lookupRecordX);
+  DEFINE_SIZE_ARRAY (4, inputZ);
 };
 
 struct RuleSet
@@ -1255,7 +1258,7 @@
     return_trace (false);
   }
 
-  inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+  inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
     unsigned int num_rules = rule.len;
@@ -1335,7 +1338,7 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -1357,7 +1360,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of table */
@@ -1427,7 +1430,7 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -1450,7 +1453,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 2 */
+  HBUINT16      format;                 /* Format identifier--format = 2 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of table */
@@ -1479,7 +1482,7 @@
       this
     };
     context_closure_lookup (c,
-                            glyphCount, (const USHORT *) (coverageZ + 1),
+                            glyphCount, (const HBUINT16 *) (coverageZ + 1),
                             lookupCount, lookupRecord,
                             lookup_context);
   }
@@ -1496,7 +1499,7 @@
     };
 
     context_collect_glyphs_lookup (c,
-                                   glyphCount, (const USHORT *) (coverageZ + 1),
+                                   glyphCount, (const HBUINT16 *) (coverageZ + 1),
                                    lookupCount, lookupRecord,
                                    lookup_context);
   }
@@ -1510,7 +1513,7 @@
       {match_coverage},
       this
     };
-    return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+    return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
   }
 
   inline const Coverage &get_coverage (void) const
@@ -1518,7 +1521,7 @@
     return this+coverageZ[0];
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
@@ -1529,7 +1532,7 @@
       {match_coverage},
       this
     };
-    return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+    return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
@@ -1546,17 +1549,17 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 3 */
-  USHORT        glyphCount;             /* Number of glyphs in the input glyph
+  HBUINT16      format;                 /* Format identifier--format = 3 */
+  HBUINT16      glyphCount;             /* Number of glyphs in the input glyph
                                          * sequence */
-  USHORT        lookupCount;            /* Number of LookupRecords */
+  HBUINT16      lookupCount;            /* Number of LookupRecords */
   OffsetTo<Coverage>
                 coverageZ[VAR];         /* Array of offsets to Coverage
                                          * table in glyph sequence order */
-  LookupRecord  lookupRecordX[VAR];     /* Array of LookupRecords--in
+/*LookupRecord  lookupRecordX[VAR];*/   /* Array of LookupRecords--in
                                          * design order */
   public:
-  DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX);
+  DEFINE_SIZE_ARRAY (6, coverageZ);
 };
 
 struct Context
@@ -1576,7 +1579,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   ContextFormat1        format1;
   ContextFormat2        format2;
   ContextFormat3        format3;
@@ -1606,11 +1609,11 @@
 
 static inline void chain_context_closure_lookup (hb_closure_context_t *c,
                                                  unsigned int backtrackCount,
-                                                 const USHORT backtrack[],
+                                                 const HBUINT16 backtrack[],
                                                  unsigned int inputCount, /* Including the first glyph (not matched) */
-                                                 const USHORT input[], /* Array of input values--start with second glyph */
+                                                 const HBUINT16 input[], /* Array of input values--start with second glyph */
                                                  unsigned int lookaheadCount,
-                                                 const USHORT lookahead[],
+                                                 const HBUINT16 lookahead[],
                                                  unsigned int lookupCount,
                                                  const LookupRecord lookupRecord[],
                                                  ChainContextClosureLookupContext &lookup_context)
@@ -1630,11 +1633,11 @@
 
 static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
                                                         unsigned int backtrackCount,
-                                                        const USHORT backtrack[],
+                                                        const HBUINT16 backtrack[],
                                                         unsigned int inputCount, /* Including the first glyph (not matched) */
-                                                        const USHORT input[], /* Array of input values--start with second glyph */
+                                                        const HBUINT16 input[], /* Array of input values--start with second glyph */
                                                         unsigned int lookaheadCount,
-                                                        const USHORT lookahead[],
+                                                        const HBUINT16 lookahead[],
                                                         unsigned int lookupCount,
                                                         const LookupRecord lookupRecord[],
                                                         ChainContextCollectGlyphsLookupContext &lookup_context)
@@ -1654,11 +1657,11 @@
 
 static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c,
                                                      unsigned int backtrackCount,
-                                                     const USHORT backtrack[] HB_UNUSED,
+                                                     const HBUINT16 backtrack[] HB_UNUSED,
                                                      unsigned int inputCount, /* Including the first glyph (not matched) */
-                                                     const USHORT input[], /* Array of input values--start with second glyph */
+                                                     const HBUINT16 input[], /* Array of input values--start with second glyph */
                                                      unsigned int lookaheadCount,
-                                                     const USHORT lookahead[] HB_UNUSED,
+                                                     const HBUINT16 lookahead[] HB_UNUSED,
                                                      unsigned int lookupCount HB_UNUSED,
                                                      const LookupRecord lookupRecord[] HB_UNUSED,
                                                      ChainContextApplyLookupContext &lookup_context)
@@ -1669,13 +1672,13 @@
                             lookup_context.funcs.match, lookup_context.match_data[1]);
 }
 
-static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
+static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
                                                unsigned int backtrackCount,
-                                               const USHORT backtrack[],
+                                               const HBUINT16 backtrack[],
                                                unsigned int inputCount, /* Including the first glyph (not matched) */
-                                               const USHORT input[], /* Array of input values--start with second glyph */
+                                               const HBUINT16 input[], /* Array of input values--start with second glyph */
                                                unsigned int lookaheadCount,
-                                               const USHORT lookahead[],
+                                               const HBUINT16 lookahead[],
                                                unsigned int lookupCount,
                                                const LookupRecord lookupRecord[],
                                                ChainContextApplyLookupContext &lookup_context)
@@ -1706,8 +1709,8 @@
   inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
   {
     TRACE_CLOSURE (this);
-    const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
-    const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     chain_context_closure_lookup (c,
                                   backtrack.len, backtrack.array,
@@ -1720,8 +1723,8 @@
   inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
   {
     TRACE_COLLECT_GLYPHS (this);
-    const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
-    const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     chain_context_collect_glyphs_lookup (c,
                                          backtrack.len, backtrack.array,
@@ -1734,8 +1737,8 @@
   inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_WOULD_APPLY (this);
-    const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
-    const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     return_trace (chain_context_would_apply_lookup (c,
                                                     backtrack.len, backtrack.array,
@@ -1744,11 +1747,11 @@
                                                     lookup.array, lookup_context));
   }
 
-  inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+  inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
-    const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     return_trace (chain_context_apply_lookup (c,
                                               backtrack.len, backtrack.array,
@@ -1761,23 +1764,23 @@
   {
     TRACE_SANITIZE (this);
     if (!backtrack.sanitize (c)) return_trace (false);
-    const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
     if (!input.sanitize (c)) return_trace (false);
-    const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
     if (!lookahead.sanitize (c)) return_trace (false);
     const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
     return_trace (lookup.sanitize (c));
   }
 
   protected:
-  ArrayOf<USHORT>
+  ArrayOf<HBUINT16>
                 backtrack;              /* Array of backtracking values
                                          * (to be matched before the input
                                          * sequence) */
-  HeadlessArrayOf<USHORT>
+  HeadlessArrayOf<HBUINT16>
                 inputX;                 /* Array of input values (start with
                                          * second glyph) */
-  ArrayOf<USHORT>
+  ArrayOf<HBUINT16>
                 lookaheadX;             /* Array of lookahead values's (to be
                                          * matched after the input sequence) */
   ArrayOf<LookupRecord>
@@ -1816,7 +1819,7 @@
     return_trace (false);
   }
 
-  inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+  inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
     unsigned int num_rules = rule.len;
@@ -1893,7 +1896,7 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -1914,7 +1917,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 1 */
+  HBUINT16      format;                 /* Format identifier--format = 1 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of table */
@@ -1997,7 +2000,7 @@
     return this+coverage;
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -2029,7 +2032,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 2 */
+  HBUINT16      format;                 /* Format identifier--format = 2 */
   OffsetTo<Coverage>
                 coverage;               /* Offset to Coverage table--from
                                          * beginning of table */
@@ -2069,9 +2072,9 @@
       {this, this, this}
     };
     chain_context_closure_lookup (c,
-                                  backtrack.len, (const USHORT *) backtrack.array,
-                                  input.len, (const USHORT *) input.array + 1,
-                                  lookahead.len, (const USHORT *) lookahead.array,
+                                  backtrack.len, (const HBUINT16 *) backtrack.array,
+                                  input.len, (const HBUINT16 *) input.array + 1,
+                                  lookahead.len, (const HBUINT16 *) lookahead.array,
                                   lookup.len, lookup.array,
                                   lookup_context);
   }
@@ -2090,9 +2093,9 @@
       {this, this, this}
     };
     chain_context_collect_glyphs_lookup (c,
-                                         backtrack.len, (const USHORT *) backtrack.array,
-                                         input.len, (const USHORT *) input.array + 1,
-                                         lookahead.len, (const USHORT *) lookahead.array,
+                                         backtrack.len, (const HBUINT16 *) backtrack.array,
+                                         input.len, (const HBUINT16 *) input.array + 1,
+                                         lookahead.len, (const HBUINT16 *) lookahead.array,
                                          lookup.len, lookup.array,
                                          lookup_context);
   }
@@ -2109,9 +2112,9 @@
       {this, this, this}
     };
     return_trace (chain_context_would_apply_lookup (c,
-                                                    backtrack.len, (const USHORT *) backtrack.array,
-                                                    input.len, (const USHORT *) input.array + 1,
-                                                    lookahead.len, (const USHORT *) lookahead.array,
+                                                    backtrack.len, (const HBUINT16 *) backtrack.array,
+                                                    input.len, (const HBUINT16 *) input.array + 1,
+                                                    lookahead.len, (const HBUINT16 *) lookahead.array,
                                                     lookup.len, lookup.array, lookup_context));
   }
 
@@ -2121,7 +2124,7 @@
     return this+input[0];
   }
 
-  inline bool apply (hb_apply_context_t *c) const
+  inline bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
     const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
@@ -2136,9 +2139,9 @@
       {this, this, this}
     };
     return_trace (chain_context_apply_lookup (c,
-                                              backtrack.len, (const USHORT *) backtrack.array,
-                                              input.len, (const USHORT *) input.array + 1,
-                                              lookahead.len, (const USHORT *) lookahead.array,
+                                              backtrack.len, (const HBUINT16 *) backtrack.array,
+                                              input.len, (const HBUINT16 *) input.array + 1,
+                                              lookahead.len, (const HBUINT16 *) lookahead.array,
                                               lookup.len, lookup.array, lookup_context));
   }
 
@@ -2156,7 +2159,7 @@
   }
 
   protected:
-  USHORT        format;                 /* Format identifier--format = 3 */
+  HBUINT16      format;                 /* Format identifier--format = 3 */
   OffsetArrayOf<Coverage>
                 backtrack;              /* Array of coverage tables
                                          * in backtracking sequence, in  glyph
@@ -2193,7 +2196,7 @@
 
   protected:
   union {
-  USHORT                format; /* Format identifier */
+  HBUINT16              format; /* Format identifier */
   ChainContextFormat1   format1;
   ChainContextFormat2   format2;
   ChainContextFormat3   format3;
@@ -2226,15 +2229,17 @@
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && extensionOffset != 0);
+    return_trace (c->check_struct (this) &&
+                  extensionOffset != 0 &&
+                  extensionLookupType != T::LookupSubTable::Extension);
   }
 
   protected:
-  USHORT        format;                 /* Format identifier. Set to 1. */
-  USHORT        extensionLookupType;    /* Lookup type of subtable referenced
+  HBUINT16      format;                 /* Format identifier. Set to 1. */
+  HBUINT16      extensionLookupType;    /* Lookup type of subtable referenced
                                          * by ExtensionOffset (i.e. the
                                          * extension subtable). */
-  ULONG         extensionOffset;        /* Offset to the extension subtable,
+  HBUINT32      extensionOffset;        /* Offset to the extension subtable,
                                          * of lookup type subtable. */
   public:
   DEFINE_SIZE_STATIC (8);
@@ -2272,7 +2277,7 @@
 
   protected:
   union {
-  USHORT                format;         /* Format identifier */
+  HBUINT16              format;         /* Format identifier */
   ExtensionFormat1<T>   format1;
   } u;
 };
@@ -2284,9 +2289,6 @@
 
 struct GSUBGPOS
 {
-  static const hb_tag_t GSUBTag = HB_OT_TAG_GSUB;
-  static const hb_tag_t GPOSTag = HB_OT_TAG_GPOS;
-
   inline unsigned int get_script_count (void) const
   { return (this+scriptList).len; }
   inline const Tag& get_script_tag (unsigned int i) const
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -90,12 +90,12 @@
 struct hb_ot_layout_lookup_accelerator_t;
 
 namespace OT {
-  struct hb_apply_context_t;
+  struct hb_ot_apply_context_t;
   struct SubstLookup;
 }
 
 HB_INTERNAL void
-hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
                                 const OT::SubstLookup &lookup,
                                 const hb_ot_layout_lookup_accelerator_t &accel);
 
@@ -122,6 +122,9 @@
  */
 
 namespace OT {
+  struct BASE;
+  struct COLR;
+  struct CPAL;
   struct GDEF;
   struct GSUB;
   struct GPOS;
@@ -130,6 +133,13 @@
   struct avar;
 }
 
+namespace AAT {
+  struct ankr;
+  struct kerx;
+  struct morx;
+  struct trak;
+}
+
 struct hb_ot_layout_lookup_accelerator_t
 {
   template <typename TLookup>
@@ -162,9 +172,16 @@
   const struct OT::GPOS *gpos;
 
   /* TODO Move the following out of this struct. */
+  OT::hb_lazy_table_loader_t<struct OT::BASE> base;
+  OT::hb_lazy_table_loader_t<struct OT::COLR> colr;
+  OT::hb_lazy_table_loader_t<struct OT::CPAL> cpal;
   OT::hb_lazy_table_loader_t<struct OT::MATH> math;
   OT::hb_lazy_table_loader_t<struct OT::fvar> fvar;
   OT::hb_lazy_table_loader_t<struct OT::avar> avar;
+  OT::hb_lazy_table_loader_t<struct AAT::ankr> ankr;
+  OT::hb_lazy_table_loader_t<struct AAT::kerx> kerx;
+  OT::hb_lazy_table_loader_t<struct AAT::morx> morx;
+  OT::hb_lazy_table_loader_t<struct AAT::trak> trak;
 
   unsigned int gsub_lookup_count;
   unsigned int gpos_lookup_count;
@@ -273,14 +290,18 @@
        * what we do for joiners in Indic-like shapers, but since the
        * FVSes are GC=Mn, we have use a separate bit to remember them.
        * Fixes:
-       * https://github.com/behdad/harfbuzz/issues/234 */
+       * https://github.com/harfbuzz/harfbuzz/issues/234 */
       else if (unlikely (hb_in_range (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_HIDDEN;
       /* TAG characters need similar treatment. Fixes:
-       * https://github.com/behdad/harfbuzz/issues/463 */
+       * https://github.com/harfbuzz/harfbuzz/issues/463 */
       else if (unlikely (hb_in_range (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN;
       /* COMBINING GRAPHEME JOINER should not be skipped; at least some times.
-       * https://github.com/behdad/harfbuzz/issues/554 */
-      else if (unlikely (u == 0x034Fu)) props |= UPROPS_MASK_HIDDEN;
+       * https://github.com/harfbuzz/harfbuzz/issues/554 */
+      else if (unlikely (u == 0x034Fu))
+      {
+        buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CGJ;
+        props |= UPROPS_MASK_HIDDEN;
+      }
     }
     else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat)))
     {
@@ -305,7 +326,7 @@
       /* Recategorize emoji skin-tone modifiers as Unicode mark, so they
        * behave correctly in non-native directionality.  They originally
        * are MODIFIER_SYMBOL.  Fixes:
-       * https://github.com/behdad/harfbuzz/issues/169
+       * https://github.com/harfbuzz/harfbuzz/issues/169
        */
       if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu)))
       {
@@ -350,6 +371,28 @@
   return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0;
 }
 
+
+/* Loop over grapheme. Based on foreach_cluster(). */
+#define foreach_grapheme(buffer, start, end) \
+  for (unsigned int \
+       _count = buffer->len, \
+       start = 0, end = _count ? _next_grapheme (buffer, 0) : 0; \
+       start < _count; \
+       start = end, end = _next_grapheme (buffer, start))
+
+static inline unsigned int
+_next_grapheme (hb_buffer_t *buffer, unsigned int start)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+
+  while (++start < count && _hb_glyph_info_is_unicode_mark (&info[start]))
+    ;
+
+  return start;
+}
+
+
 #define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info)))
 
 static inline bool
@@ -388,6 +431,11 @@
           == UPROPS_MASK_IGNORABLE) &&
          !_hb_glyph_info_ligated (info);
 }
+static inline void
+_hb_glyph_info_unhide (hb_glyph_info_t *info)
+{
+  info->unicode_props() &= ~ UPROPS_MASK_HIDDEN;
+}
 
 static inline bool
 _hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.cc	Wed May 30 12:20:00 2018 -0700
@@ -31,16 +31,21 @@
 #include "hb-open-type-private.hh"
 #include "hb-ot-layout-private.hh"
 
+#include "hb-ot-layout-base-table.hh"
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
 #include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-ot-name-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-ot-color-colr-table.hh"
+#include "hb-ot-color-cpal-table.hh"
 
 #include "hb-ot-map-private.hh"
 
 
+#ifndef HB_NO_VISIBILITY
 const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
+#endif
 
 
 hb_ot_layout_t *
@@ -50,18 +55,25 @@
   if (unlikely (!layout))
     return nullptr;
 
-  layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF));
+  layout->gdef_blob = OT::Sanitizer<OT::GDEF>().sanitize (face->reference_table (HB_OT_TAG_GDEF));
   layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob);
 
-  layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB));
+  layout->gsub_blob = OT::Sanitizer<OT::GSUB>().sanitize (face->reference_table (HB_OT_TAG_GSUB));
   layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob);
 
-  layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS));
+  layout->gpos_blob = OT::Sanitizer<OT::GPOS>().sanitize (face->reference_table (HB_OT_TAG_GPOS));
   layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
 
+  layout->base.init (face);
+  layout->colr.init (face);
+  layout->cpal.init (face);
   layout->math.init (face);
   layout->fvar.init (face);
   layout->avar.init (face);
+  layout->ankr.init (face);
+  layout->kerx.init (face);
+  layout->morx.init (face);
+  layout->trak.init (face);
 
   {
     /*
@@ -194,10 +206,12 @@
 void
 _hb_ot_layout_destroy (hb_ot_layout_t *layout)
 {
-  for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
-    layout->gsub_accels[i].fini ();
-  for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
-    layout->gpos_accels[i].fini ();
+  if (layout->gsub_accels)
+    for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
+      layout->gsub_accels[i].fini ();
+  if (layout->gpos_accels)
+    for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
+      layout->gpos_accels[i].fini ();
 
   free (layout->gsub_accels);
   free (layout->gpos_accels);
@@ -206,13 +220,28 @@
   hb_blob_destroy (layout->gsub_blob);
   hb_blob_destroy (layout->gpos_blob);
 
+  layout->base.fini ();
+  layout->colr.fini ();
+  layout->cpal.fini ();
   layout->math.fini ();
   layout->fvar.fini ();
   layout->avar.fini ();
+  layout->ankr.fini ();
+  layout->kerx.fini ();
+  layout->morx.fini ();
+  layout->trak.fini ();
 
   free (layout);
 }
 
+// static inline const OT::BASE&
+// _get_base (hb_face_t *face)
+// {
+//   if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE);
+//   hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
+//   return *(layout->base.get ());
+// }
+
 static inline const OT::GDEF&
 _get_gdef (hb_face_t *face)
 {
@@ -601,6 +630,7 @@
 hb_ot_layout_table_get_lookup_count (hb_face_t    *face,
                                      hb_tag_t      table_tag)
 {
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return 0;
   switch (table_tag)
   {
     case HB_OT_TAG_GSUB:
@@ -1054,13 +1084,13 @@
        OT::hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
 {
   template <typename Type>
-  static inline bool apply_to (const void *obj, OT::hb_apply_context_t *c)
+  static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
   {
     const Type *typed_obj = (const Type *) obj;
     return typed_obj->apply (c);
   }
 
-  typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_apply_context_t *c);
+  typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
 
   struct hb_applicable_t
   {
@@ -1070,7 +1100,7 @@
       apply_func = apply_func_;
     }
 
-    inline bool apply (OT::hb_apply_context_t *c) const { return apply_func (obj, c); }
+    inline bool apply (OT::hb_ot_apply_context_t *c) const { return apply_func (obj, c); }
 
     private:
     const void *obj;
@@ -1101,7 +1131,7 @@
 };
 
 static inline bool
-apply_forward (OT::hb_apply_context_t *c,
+apply_forward (OT::hb_ot_apply_context_t *c,
                const hb_ot_layout_lookup_accelerator_t &accel,
                const hb_get_subtables_context_t::array_t &subtables)
 {
@@ -1131,7 +1161,7 @@
 }
 
 static inline bool
-apply_backward (OT::hb_apply_context_t *c,
+apply_backward (OT::hb_ot_apply_context_t *c,
                const hb_ot_layout_lookup_accelerator_t &accel,
                const hb_get_subtables_context_t::array_t &subtables)
 {
@@ -1160,7 +1190,7 @@
 
 template <typename Proxy>
 static inline void
-apply_string (OT::hb_apply_context_t *c,
+apply_string (OT::hb_ot_apply_context_t *c,
               const typename Proxy::Lookup &lookup,
               const hb_ot_layout_lookup_accelerator_t &accel)
 {
@@ -1211,7 +1241,7 @@
 {
   const unsigned int table_index = proxy.table_index;
   unsigned int i = 0;
-  OT::hb_apply_context_t c (table_index, font, buffer);
+  OT::hb_ot_apply_context_t c (table_index, font, buffer);
   c.set_recurse_func (Proxy::Lookup::apply_recurse_func);
 
   for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) {
@@ -1250,10 +1280,34 @@
   apply (proxy, plan, font, buffer);
 }
 
-HB_INTERNAL void
-hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+void
+hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
                                 const OT::SubstLookup &lookup,
                                 const hb_ot_layout_lookup_accelerator_t &accel)
 {
   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) != &OT::Null(OT::BASE);
+// }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.h	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.h	Wed May 30 12:20:00 2018 -0700
@@ -38,6 +38,7 @@
 HB_BEGIN_DECLS
 
 
+#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
 #define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
 #define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
 #define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
@@ -316,6 +317,22 @@
                               unsigned int *range_end          /* OUT.  May be NULL */);
 
 
+/*
+ * BASE
+ */
+#if 0
+
+#define HB_OT_TAG_BASE_HANG HB_TAG('h','a','n','g')
+#define HB_OT_TAG_BASE_ICFB HB_TAG('i','c','f','b')
+#define HB_OT_TAG_BASE_ICFT HB_TAG('i','c','f','t')
+#define HB_OT_TAG_BASE_IDEO HB_TAG('i','d','e','o')
+#define HB_OT_TAG_BASE_IDTB HB_TAG('i','d','t','b')
+#define HB_OT_TAG_BASE_MATH HB_TAG('m','a','t','h')
+#define HB_OT_TAG_BASE_ROMN HB_TAG('r','o','m','n')
+
+#endif
+
+
 HB_END_DECLS
 
 #endif /* HB_OT_LAYOUT_H */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map-private.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map-private.hh	Wed May 30 12:20:00 2018 -0700
@@ -84,28 +84,28 @@
   inline hb_mask_t get_global_mask (void) const { return global_mask; }
 
   inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = nullptr) const {
-    const feature_map_t *map = features.bsearch (&feature_tag);
+    const feature_map_t *map = features.bsearch (feature_tag);
     if (shift) *shift = map ? map->shift : 0;
     return map ? map->mask : 0;
   }
 
   inline bool needs_fallback (hb_tag_t feature_tag) const {
-    const feature_map_t *map = features.bsearch (&feature_tag);
+    const feature_map_t *map = features.bsearch (feature_tag);
     return map ? map->needs_fallback : false;
   }
 
   inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
-    const feature_map_t *map = features.bsearch (&feature_tag);
+    const feature_map_t *map = features.bsearch (feature_tag);
     return map ? map->_1_mask : 0;
   }
 
   inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
-    const feature_map_t *map = features.bsearch (&feature_tag);
+    const feature_map_t *map = features.bsearch (feature_tag);
     return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
   }
 
   inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const {
-    const feature_map_t *map = features.bsearch (&feature_tag);
+    const feature_map_t *map = features.bsearch (feature_tag);
     return map ? map->stage[table_index] : (unsigned int) -1;
   }
 
@@ -198,7 +198,6 @@
   private:
 
   HB_INTERNAL void add_lookups (hb_ot_map_t  &m,
-                                hb_face_t    *face,
                                 unsigned int  table_index,
                                 unsigned int  feature_index,
                                 unsigned int  variations_index,
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map.cc	Wed May 30 12:20:00 2018 -0700
@@ -80,7 +80,6 @@
 
 void
 hb_ot_map_builder_t::add_lookups (hb_ot_map_t  &m,
-                                  hb_face_t    *face,
                                   unsigned int  table_index,
                                   unsigned int  feature_index,
                                   unsigned int  variations_index,
@@ -140,7 +139,7 @@
 {
   static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
   unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1;
-  unsigned int global_bit_shift = _hb_popcount32 (HB_GLYPH_FLAG_DEFINED);
+  unsigned int global_bit_shift = _hb_popcount (HB_GLYPH_FLAG_DEFINED);
 
   m.global_mask = global_bit_mask;
 
@@ -289,14 +288,14 @@
     {
       if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX &&
           required_feature_stage[table_index] == stage)
-        add_lookups (m, face, table_index,
+        add_lookups (m, table_index,
                      required_feature_index[table_index],
                      variations_index,
                      global_bit_mask);
 
       for (unsigned i = 0; i < m.features.len; i++)
         if (m.features[i].stage[table_index] == stage)
-          add_lookups (m, face, table_index,
+          add_lookups (m, table_index,
                        m.features[i].index[table_index],
                        variations_index,
                        m.features[i].mask,
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-maxp-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-maxp-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -28,7 +28,7 @@
 #define HB_OT_MAXP_TABLE_HH
 
 #include "hb-open-type-private.hh"
-
+#include "hb-subset-plan.hh"
 
 namespace OT {
 
@@ -39,28 +39,104 @@
 
 #define HB_OT_TAG_maxp HB_TAG('m','a','x','p')
 
+struct maxpV1Tail
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBUINT16 maxPoints;             /* Maximum points in a non-composite glyph. */
+  HBUINT16 maxContours;           /* Maximum contours in a non-composite glyph. */
+  HBUINT16 maxCompositePoints;    /* Maximum points in a composite glyph. */
+  HBUINT16 maxCompositeContours;  /* Maximum contours in a composite glyph. */
+  HBUINT16 maxZones;              /* 1 if instructions do not use the twilight zone (Z0),
+                                   * or 2 if instructions do use Z0; should be set to 2 in
+                                   * most cases. */
+  HBUINT16 maxTwilightPoints;     /* Maximum points used in Z0. */
+  HBUINT16 maxStorage;            /* Number of Storage Area locations. */
+  HBUINT16 maxFunctionDefs;       /* Number of FDEFs, equal to the highest function number + 1. */
+  HBUINT16 maxInstructionDefs;    /* Number of IDEFs. */
+  HBUINT16 maxStackElements;      /* Maximum stack depth. (This includes Font and CVT
+                                   * Programs, as well as the instructions for each glyph.) */
+  HBUINT16 maxSizeOfInstructions; /* Maximum byte count for glyph instructions. */
+  HBUINT16 maxComponentElements;  /* Maximum number of components referenced at
+                                   * "top level" for any composite glyph. */
+  HBUINT16 maxComponentDepth;     /* Maximum levels of recursion; 1 for simple components. */
+ public:
+  DEFINE_SIZE_STATIC (26);
+};
+
+
 struct maxp
 {
-  static const hb_tag_t tableTag        = HB_OT_TAG_maxp;
+  static const hb_tag_t tableTag = HB_OT_TAG_maxp;
 
   inline unsigned int get_num_glyphs (void) const
   {
     return numGlyphs;
   }
 
+  inline void set_num_glyphs (unsigned int count)
+  {
+    numGlyphs.set (count);
+  }
+
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) &&
-                  likely (version.major == 1 ||
-                          (version.major == 0 && version.minor == 0x5000u)));
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    if (version.major == 1)
+    {
+      const maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*this);
+      return v1.sanitize (c);
+    }
+    return_trace (likely (version.major == 0 && version.minor == 0x5000u));
   }
 
-  /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
+  inline bool subset (hb_subset_plan_t *plan) const
+  {
+    hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_maxp));
+    hb_blob_t *maxp_prime_blob = hb_blob_copy_writable_or_fail (maxp_blob);
+    hb_blob_destroy (maxp_blob);
+
+    if (unlikely (!maxp_prime_blob)) {
+      return false;
+    }
+    OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr);
+
+    maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len);
+    if (plan->drop_hints)
+      drop_hint_fields (plan, maxp_prime);
+
+    bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_maxp, maxp_prime_blob);
+    hb_blob_destroy (maxp_prime_blob);
+    return result;
+  }
+
+  static inline void drop_hint_fields (hb_subset_plan_t *plan, OT::maxp *maxp_prime)
+  {
+    if (maxp_prime->version.major == 1)
+    {
+      maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*maxp_prime);
+      v1.maxZones.set (1);
+      v1.maxTwilightPoints.set (0);
+      v1.maxStorage.set (0);
+      v1.maxFunctionDefs.set (0);
+      v1.maxInstructionDefs.set (0);
+      v1.maxStackElements.set (0);
+      v1.maxSizeOfInstructions.set (0);
+    }
+  }
+
   protected:
   FixedVersion<>version;                /* Version of the maxp table (0.5 or 1.0),
                                          * 0x00005000u or 0x00010000u. */
-  USHORT        numGlyphs;              /* The number of glyphs in the font. */
+  HBUINT16      numGlyphs;              /* The number of glyphs in the font. */
+/*maxpV1Tail v1Tail[VAR]; */
   public:
   DEFINE_SIZE_STATIC (6);
 };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-name-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-name-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -65,12 +65,12 @@
     return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
   }
 
-  USHORT        platformID;     /* Platform ID. */
-  USHORT        encodingID;     /* Platform-specific encoding ID. */
-  USHORT        languageID;     /* Language ID. */
-  USHORT        nameID;         /* Name ID. */
-  USHORT        length;         /* String length (in bytes). */
-  USHORT        offset;         /* String offset from start of storage area (in bytes). */
+  HBUINT16      platformID;     /* Platform ID. */
+  HBUINT16      encodingID;     /* Platform-specific encoding ID. */
+  HBUINT16      languageID;     /* Language ID. */
+  HBUINT16      nameID;         /* Name ID. */
+  HBUINT16      length;         /* String length (in bytes). */
+  HBUINT16      offset;         /* String offset from start of storage area (in bytes). */
   public:
   DEFINE_SIZE_STATIC (12);
 };
@@ -123,9 +123,9 @@
   }
 
   /* We only implement format 0 for now. */
-  USHORT        format;                 /* Format selector (=0/1). */
-  USHORT        count;                  /* Number of name records. */
-  Offset<>      stringOffset;           /* Offset to start of string storage (from start of table). */
+  HBUINT16      format;                 /* Format selector (=0/1). */
+  HBUINT16      count;                  /* Number of name records. */
+  Offset16      stringOffset;           /* Offset to start of string storage (from start of table). */
   NameRecord    nameRecord[VAR];        /* The name records where count is the number of records. */
   public:
   DEFINE_SIZE_ARRAY (6, nameRecord);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -28,7 +28,7 @@
 #define HB_OT_OS2_TABLE_HH
 
 #include "hb-open-type-private.hh"
-
+#include "hb-ot-os2-unicode-ranges.hh"
 
 namespace OT {
 
@@ -49,51 +49,127 @@
     return_trace (c->check_struct (this));
   }
 
+  inline bool subset (hb_subset_plan_t *plan) const
+  {
+    hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_os2));
+    hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1);
+    // TODO(grieger): move to hb_blob_copy_writable_or_fail
+    hb_blob_destroy (os2_blob);
+
+    OT::os2 *os2_prime = (OT::os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr);
+    if (unlikely (!os2_prime)) {
+      hb_blob_destroy (os2_prime_blob);
+      return false;
+    }
+
+    uint16_t min_cp, max_cp;
+    find_min_and_max_codepoint (plan->codepoints, &min_cp, &max_cp);
+    os2_prime->usFirstCharIndex.set (min_cp);
+    os2_prime->usLastCharIndex.set (max_cp);
+
+    _update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange);
+    bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob);
+
+    hb_blob_destroy (os2_prime_blob);
+    return result;
+  }
+
+  inline void _update_unicode_ranges (const hb_prealloced_array_t<hb_codepoint_t> &codepoints,
+                                      HBUINT32 ulUnicodeRange[4]) const
+  {
+    for (unsigned int i = 0; i < 4; i++)
+      ulUnicodeRange[i].set (0);
+
+    for (unsigned int i = 0; i < codepoints.len; i++)
+    {
+      hb_codepoint_t cp = codepoints[i];
+      unsigned int bit = hb_get_unicode_range_bit (cp);
+      if (bit < 128)
+      {
+        unsigned int block = bit / 32;
+        unsigned int bit_in_block = bit % 32;
+        unsigned int mask = 1 << bit_in_block;
+        ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
+      }
+      if (cp >= 0x10000 && cp <= 0x110000)
+      {
+        /* the spec says that bit 57 ("Non Plane 0") implies that there's
+           at least one codepoint beyond the BMP; so I also include all
+           the non-BMP codepoints here */
+        ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
+      }
+    }
+  }
+
+  static inline void find_min_and_max_codepoint (const hb_prealloced_array_t<hb_codepoint_t> &codepoints,
+                                                 uint16_t *min_cp, /* OUT */
+                                                 uint16_t *max_cp  /* OUT */)
+  {
+    hb_codepoint_t min = -1, max = 0;
+
+    for (unsigned int i = 0; i < codepoints.len; i++)
+    {
+      hb_codepoint_t cp = codepoints[i];
+      if (cp < min)
+        min = cp;
+      if (cp > max)
+        max = cp;
+    }
+
+    if (min > 0xFFFF)
+      min = 0xFFFF;
+    if (max > 0xFFFF)
+      max = 0xFFFF;
+
+    *min_cp = min;
+    *max_cp = max;
+  }
+
   public:
-  USHORT        version;
+  HBUINT16      version;
 
   /* Version 0 */
-  SHORT         xAvgCharWidth;
-  USHORT        usWeightClass;
-  USHORT        usWidthClass;
-  USHORT        fsType;
-  SHORT         ySubscriptXSize;
-  SHORT         ySubscriptYSize;
-  SHORT         ySubscriptXOffset;
-  SHORT         ySubscriptYOffset;
-  SHORT         ySuperscriptXSize;
-  SHORT         ySuperscriptYSize;
-  SHORT         ySuperscriptXOffset;
-  SHORT         ySuperscriptYOffset;
-  SHORT         yStrikeoutSize;
-  SHORT         yStrikeoutPosition;
-  SHORT         sFamilyClass;
-  BYTE          panose[10];
-  ULONG         ulUnicodeRange[4];
+  HBINT16       xAvgCharWidth;
+  HBUINT16      usWeightClass;
+  HBUINT16      usWidthClass;
+  HBUINT16      fsType;
+  HBINT16       ySubscriptXSize;
+  HBINT16       ySubscriptYSize;
+  HBINT16       ySubscriptXOffset;
+  HBINT16       ySubscriptYOffset;
+  HBINT16       ySuperscriptXSize;
+  HBINT16       ySuperscriptYSize;
+  HBINT16       ySuperscriptXOffset;
+  HBINT16       ySuperscriptYOffset;
+  HBINT16       yStrikeoutSize;
+  HBINT16       yStrikeoutPosition;
+  HBINT16       sFamilyClass;
+  HBUINT8       panose[10];
+  HBUINT32      ulUnicodeRange[4];
   Tag           achVendID;
-  USHORT        fsSelection;
-  USHORT        usFirstCharIndex;
-  USHORT        usLastCharIndex;
-  SHORT         sTypoAscender;
-  SHORT         sTypoDescender;
-  SHORT         sTypoLineGap;
-  USHORT        usWinAscent;
-  USHORT        usWinDescent;
+  HBUINT16      fsSelection;
+  HBUINT16      usFirstCharIndex;
+  HBUINT16      usLastCharIndex;
+  HBINT16       sTypoAscender;
+  HBINT16       sTypoDescender;
+  HBINT16       sTypoLineGap;
+  HBUINT16      usWinAscent;
+  HBUINT16      usWinDescent;
 
   /* Version 1 */
-  //ULONG ulCodePageRange1;
-  //ULONG ulCodePageRange2;
+  //HBUINT32    ulCodePageRange1;
+  //HBUINT32    ulCodePageRange2;
 
   /* Version 2 */
-  //SHORT sxHeight;
-  //SHORT sCapHeight;
-  //USHORT  usDefaultChar;
-  //USHORT  usBreakChar;
-  //USHORT  usMaxContext;
+  //HBINT16     sxHeight;
+  //HBINT16     sCapHeight;
+  //HBUINT16    usDefaultChar;
+  //HBUINT16    usBreakChar;
+  //HBUINT16    usMaxContext;
 
   /* Version 5 */
-  //USHORT  usLowerOpticalPointSize;
-  //USHORT  usUpperOpticalPointSize;
+  //HBUINT16    usLowerOpticalPointSize;
+  //HBUINT16    usUpperOpticalPointSize;
 
   public:
   DEFINE_SIZE_STATIC (78);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-unicode-ranges.hh	Wed May 30 12:20:00 2018 -0700
@@ -0,0 +1,247 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#ifndef HB_OT_OS2_UNICODE_RANGES_HH
+#define HB_OT_OS2_UNICODE_RANGES_HH
+
+#include "hb-private.hh"
+#include "hb-dsalgs.hh"
+
+namespace OT {
+
+struct Range {
+  hb_codepoint_t start;
+  hb_codepoint_t end;
+  unsigned int bit;
+};
+
+/* Note: The contents of this array was generated using src/gen-unicode-ranges.py. */
+static Range os2UnicodeRangesSorted[] =
+{
+  {     0x0,     0x7F,   0}, // Basic Latin
+  {    0x80,     0xFF,   1}, // Latin-1 Supplement
+  {   0x100,    0x17F,   2}, // Latin Extended-A
+  {   0x180,    0x24F,   3}, // Latin Extended-B
+  {   0x250,    0x2AF,   4}, // IPA Extensions
+  {   0x2B0,    0x2FF,   5}, // Spacing Modifier Letters
+  {   0x300,    0x36F,   6}, // Combining Diacritical Marks
+  {   0x370,    0x3FF,   7}, // Greek and Coptic
+  {   0x400,    0x4FF,   9}, // Cyrillic
+  {   0x500,    0x52F,   9}, // Cyrillic Supplement
+  {   0x530,    0x58F,  10}, // Armenian
+  {   0x590,    0x5FF,  11}, // Hebrew
+  {   0x600,    0x6FF,  13}, // Arabic
+  {   0x700,    0x74F,  71}, // Syriac
+  {   0x750,    0x77F,  13}, // Arabic Supplement
+  {   0x780,    0x7BF,  72}, // Thaana
+  {   0x7C0,    0x7FF,  14}, // NKo
+  {   0x900,    0x97F,  15}, // Devanagari
+  {   0x980,    0x9FF,  16}, // Bengali
+  {   0xA00,    0xA7F,  17}, // Gurmukhi
+  {   0xA80,    0xAFF,  18}, // Gujarati
+  {   0xB00,    0xB7F,  19}, // Oriya
+  {   0xB80,    0xBFF,  20}, // Tamil
+  {   0xC00,    0xC7F,  21}, // Telugu
+  {   0xC80,    0xCFF,  22}, // Kannada
+  {   0xD00,    0xD7F,  23}, // Malayalam
+  {   0xD80,    0xDFF,  73}, // Sinhala
+  {   0xE00,    0xE7F,  24}, // Thai
+  {   0xE80,    0xEFF,  25}, // Lao
+  {   0xF00,    0xFFF,  70}, // Tibetan
+  {  0x1000,   0x109F,  74}, // Myanmar
+  {  0x10A0,   0x10FF,  26}, // Georgian
+  {  0x1100,   0x11FF,  28}, // Hangul Jamo
+  {  0x1200,   0x137F,  75}, // Ethiopic
+  {  0x1380,   0x139F,  75}, // Ethiopic Supplement
+  {  0x13A0,   0x13FF,  76}, // Cherokee
+  {  0x1400,   0x167F,  77}, // Unified Canadian Aboriginal Syllabics
+  {  0x1680,   0x169F,  78}, // Ogham
+  {  0x16A0,   0x16FF,  79}, // Runic
+  {  0x1700,   0x171F,  84}, // Tagalog
+  {  0x1720,   0x173F,  84}, // Hanunoo
+  {  0x1740,   0x175F,  84}, // Buhid
+  {  0x1760,   0x177F,  84}, // Tagbanwa
+  {  0x1780,   0x17FF,  80}, // Khmer
+  {  0x1800,   0x18AF,  81}, // Mongolian
+  {  0x1900,   0x194F,  93}, // Limbu
+  {  0x1950,   0x197F,  94}, // Tai Le
+  {  0x1980,   0x19DF,  95}, // New Tai Lue
+  {  0x19E0,   0x19FF,  80}, // Khmer Symbols
+  {  0x1A00,   0x1A1F,  96}, // Buginese
+  {  0x1B00,   0x1B7F,  27}, // Balinese
+  {  0x1B80,   0x1BBF, 112}, // Sundanese
+  {  0x1C00,   0x1C4F, 113}, // Lepcha
+  {  0x1C50,   0x1C7F, 114}, // Ol Chiki
+  {  0x1D00,   0x1D7F,   4}, // Phonetic Extensions
+  {  0x1D80,   0x1DBF,   4}, // Phonetic Extensions Supplement
+  {  0x1DC0,   0x1DFF,   6}, // Combining Diacritical Marks Supplement
+  {  0x1E00,   0x1EFF,  29}, // Latin Extended Additional
+  {  0x1F00,   0x1FFF,  30}, // Greek Extended
+  {  0x2000,   0x206F,  31}, // General Punctuation
+  {  0x2070,   0x209F,  32}, // Superscripts And Subscripts
+  {  0x20A0,   0x20CF,  33}, // Currency Symbols
+  {  0x20D0,   0x20FF,  34}, // Combining Diacritical Marks For Symbols
+  {  0x2100,   0x214F,  35}, // Letterlike Symbols
+  {  0x2150,   0x218F,  36}, // Number Forms
+  {  0x2190,   0x21FF,  37}, // Arrows
+  {  0x2200,   0x22FF,  38}, // Mathematical Operators
+  {  0x2300,   0x23FF,  39}, // Miscellaneous Technical
+  {  0x2400,   0x243F,  40}, // Control Pictures
+  {  0x2440,   0x245F,  41}, // Optical Character Recognition
+  {  0x2460,   0x24FF,  42}, // Enclosed Alphanumerics
+  {  0x2500,   0x257F,  43}, // Box Drawing
+  {  0x2580,   0x259F,  44}, // Block Elements
+  {  0x25A0,   0x25FF,  45}, // Geometric Shapes
+  {  0x2600,   0x26FF,  46}, // Miscellaneous Symbols
+  {  0x2700,   0x27BF,  47}, // Dingbats
+  {  0x27C0,   0x27EF,  38}, // Miscellaneous Mathematical Symbols-A
+  {  0x27F0,   0x27FF,  37}, // Supplemental Arrows-A
+  {  0x2800,   0x28FF,  82}, // Braille Patterns
+  {  0x2900,   0x297F,  37}, // Supplemental Arrows-B
+  {  0x2980,   0x29FF,  38}, // Miscellaneous Mathematical Symbols-B
+  {  0x2A00,   0x2AFF,  38}, // Supplemental Mathematical Operators
+  {  0x2B00,   0x2BFF,  37}, // Miscellaneous Symbols and Arrows
+  {  0x2C00,   0x2C5F,  97}, // Glagolitic
+  {  0x2C60,   0x2C7F,  29}, // Latin Extended-C
+  {  0x2C80,   0x2CFF,   8}, // Coptic
+  {  0x2D00,   0x2D2F,  26}, // Georgian Supplement
+  {  0x2D30,   0x2D7F,  98}, // Tifinagh
+  {  0x2D80,   0x2DDF,  75}, // Ethiopic Extended
+  {  0x2DE0,   0x2DFF,   9}, // Cyrillic Extended-A
+  {  0x2E00,   0x2E7F,  31}, // Supplemental Punctuation
+  {  0x2E80,   0x2EFF,  59}, // CJK Radicals Supplement
+  {  0x2F00,   0x2FDF,  59}, // Kangxi Radicals
+  {  0x2FF0,   0x2FFF,  59}, // Ideographic Description Characters
+  {  0x3000,   0x303F,  48}, // CJK Symbols And Punctuation
+  {  0x3040,   0x309F,  49}, // Hiragana
+  {  0x30A0,   0x30FF,  50}, // Katakana
+  {  0x3100,   0x312F,  51}, // Bopomofo
+  {  0x3130,   0x318F,  52}, // Hangul Compatibility Jamo
+  {  0x3190,   0x319F,  59}, // Kanbun
+  {  0x31A0,   0x31BF,  51}, // Bopomofo Extended
+  {  0x31C0,   0x31EF,  61}, // CJK Strokes
+  {  0x31F0,   0x31FF,  50}, // Katakana Phonetic Extensions
+  {  0x3200,   0x32FF,  54}, // Enclosed CJK Letters And Months
+  {  0x3300,   0x33FF,  55}, // CJK Compatibility
+  {  0x3400,   0x4DBF,  59}, // CJK Unified Ideographs Extension A
+  {  0x4DC0,   0x4DFF,  99}, // Yijing Hexagram Symbols
+  {  0x4E00,   0x9FFF,  59}, // CJK Unified Ideographs
+  {  0xA000,   0xA48F,  83}, // Yi Syllables
+  {  0xA490,   0xA4CF,  83}, // Yi Radicals
+  {  0xA500,   0xA63F,  12}, // Vai
+  {  0xA640,   0xA69F,   9}, // Cyrillic Extended-B
+  {  0xA700,   0xA71F,   5}, // Modifier Tone Letters
+  {  0xA720,   0xA7FF,  29}, // Latin Extended-D
+  {  0xA800,   0xA82F, 100}, // Syloti Nagri
+  {  0xA840,   0xA87F,  53}, // Phags-pa
+  {  0xA880,   0xA8DF, 115}, // Saurashtra
+  {  0xA900,   0xA92F, 116}, // Kayah Li
+  {  0xA930,   0xA95F, 117}, // Rejang
+  {  0xAA00,   0xAA5F, 118}, // Cham
+  {  0xAC00,   0xD7AF,  56}, // Hangul Syllables
+  {  0xD800,   0xDFFF,  57}, // Non-Plane 0 *
+  {  0xE000,   0xF8FF,  60}, // Private Use Area (plane 0)
+  {  0xF900,   0xFAFF,  61}, // CJK Compatibility Ideographs
+  {  0xFB00,   0xFB4F,  62}, // Alphabetic Presentation Forms
+  {  0xFB50,   0xFDFF,  63}, // Arabic Presentation Forms-A
+  {  0xFE00,   0xFE0F,  91}, // Variation Selectors
+  {  0xFE10,   0xFE1F,  65}, // Vertical Forms
+  {  0xFE20,   0xFE2F,  64}, // Combining Half Marks
+  {  0xFE30,   0xFE4F,  65}, // CJK Compatibility Forms
+  {  0xFE50,   0xFE6F,  66}, // Small Form Variants
+  {  0xFE70,   0xFEFF,  67}, // Arabic Presentation Forms-B
+  {  0xFF00,   0xFFEF,  68}, // Halfwidth And Fullwidth Forms
+  {  0xFFF0,   0xFFFF,  69}, // Specials
+  { 0x10000,  0x1007F, 101}, // Linear B Syllabary
+  { 0x10080,  0x100FF, 101}, // Linear B Ideograms
+  { 0x10100,  0x1013F, 101}, // Aegean Numbers
+  { 0x10140,  0x1018F, 102}, // Ancient Greek Numbers
+  { 0x10190,  0x101CF, 119}, // Ancient Symbols
+  { 0x101D0,  0x101FF, 120}, // Phaistos Disc
+  { 0x10280,  0x1029F, 121}, // Lycian
+  { 0x102A0,  0x102DF, 121}, // Carian
+  { 0x10300,  0x1032F,  85}, // Old Italic
+  { 0x10330,  0x1034F,  86}, // Gothic
+  { 0x10380,  0x1039F, 103}, // Ugaritic
+  { 0x103A0,  0x103DF, 104}, // Old Persian
+  { 0x10400,  0x1044F,  87}, // Deseret
+  { 0x10450,  0x1047F, 105}, // Shavian
+  { 0x10480,  0x104AF, 106}, // Osmanya
+  { 0x10800,  0x1083F, 107}, // Cypriot Syllabary
+  { 0x10900,  0x1091F,  58}, // Phoenician
+  { 0x10920,  0x1093F, 121}, // Lydian
+  { 0x10A00,  0x10A5F, 108}, // Kharoshthi
+  { 0x12000,  0x123FF, 110}, // Cuneiform
+  { 0x12400,  0x1247F, 110}, // Cuneiform Numbers and Punctuation
+  { 0x1D000,  0x1D0FF,  88}, // Byzantine Musical Symbols
+  { 0x1D100,  0x1D1FF,  88}, // Musical Symbols
+  { 0x1D200,  0x1D24F,  88}, // Ancient Greek Musical Notation
+  { 0x1D300,  0x1D35F, 109}, // Tai Xuan Jing Symbols
+  { 0x1D360,  0x1D37F, 111}, // Counting Rod Numerals
+  { 0x1D400,  0x1D7FF,  89}, // Mathematical Alphanumeric Symbols
+  { 0x1F000,  0x1F02F, 122}, // Mahjong Tiles
+  { 0x1F030,  0x1F09F, 122}, // Domino Tiles
+  { 0x20000,  0x2A6DF,  59}, // CJK Unified Ideographs Extension B
+  { 0x2F800,  0x2FA1F,  61}, // CJK Compatibility Ideographs Supplement
+  { 0xE0000,  0xE007F,  92}, // Tags
+  { 0xE0100,  0xE01EF,  91}, // Variation Selectors Supplement
+  { 0xF0000,  0xFFFFD,  90}, // Private Use (plane 15)
+  {0x100000, 0x10FFFD,  90}, // Private Use (plane 16)
+};
+
+static int
+_compare_range (const void *_key, const void *_item, void *_arg)
+{
+  hb_codepoint_t cp = *((hb_codepoint_t *) _key);
+  const Range *range = (Range *) _item;
+
+  if (cp < range->start)
+    return -1;
+  else if (cp <= range->end)
+    return 0;
+  else
+    return 1;
+}
+
+/**
+ * hb_get_unicode_range_bit:
+ * Returns the bit to be set in os/2 ulUnicodeRange for a given codepoint.
+ **/
+static unsigned int
+hb_get_unicode_range_bit (hb_codepoint_t cp)
+{
+  Range *range = (Range*) hb_bsearch_r (&cp, os2UnicodeRangesSorted,
+                                        sizeof (os2UnicodeRangesSorted) / sizeof(Range),
+                                        sizeof(Range),
+                                        _compare_range, nullptr);
+  if (range != NULL)
+    return range->bit;
+  return -1;
+}
+
+} /* namespace OT */
+
+#endif /* HB_OT_OS2_UNICODE_RANGES_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-post-table.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-post-table.hh	Wed May 30 12:20:00 2018 -0700
@@ -56,10 +56,10 @@
     return_trace (glyphNameIndex.sanitize (c));
   }
 
-  ArrayOf<USHORT>glyphNameIndex;        /* This is not an offset, but is the
+  ArrayOf<HBUINT16>glyphNameIndex;      /* This is not an offset, but is the
                                          * ordinal number of the glyph in 'post'
                                          * string tables. */
-  BYTE          namesX[VAR];            /* Glyph names with length bytes [variable]
+  HBUINT8               namesX[VAR];            /* Glyph names with length bytes [variable]
                                          * (a Pascal string). */
 
   DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
@@ -84,8 +84,12 @@
 
   struct accelerator_t
   {
-    inline void init (const post *table, unsigned int post_len)
+    inline void init (hb_face_t *face)
     {
+      blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post));
+      const post *table = Sanitizer<post>::lock_instance (blob);
+      unsigned int table_length = hb_blob_get_length (blob);
+
       version = table->version.to_int ();
       index_to_offset.init ();
       if (version != 0x00020000)
@@ -96,7 +100,7 @@
       glyphNameIndex = &v2.glyphNameIndex;
       pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
 
-      const uint8_t *end = (uint8_t *) table + post_len;
+      const uint8_t *end = (uint8_t *) table + table_length;
       for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data)
       {
         uint32_t *offset = index_to_offset.push ();
@@ -227,8 +231,10 @@
       return hb_string_t ((const char *) data, name_length);
     }
 
+    private:
+    hb_blob_t *blob;
     uint32_t version;
-    const ArrayOf<USHORT> *glyphNameIndex;
+    const ArrayOf<HBUINT16> *glyphNameIndex;
     hb_prealloced_array_t<uint32_t, 1> index_to_offset;
     const uint8_t *pool;
     mutable uint16_t *gids_sorted_by_name;
@@ -255,16 +261,16 @@
                                          * from the value of this field. */
   FWORD         underlineThickness;     /* Suggested values for the underline
                                            thickness. */
-  ULONG         isFixedPitch;           /* Set to 0 if the font is proportionally
+  HBUINT32      isFixedPitch;           /* Set to 0 if the font is proportionally
                                          * spaced, non-zero if the font is not
                                          * proportionally spaced (i.e. monospaced). */
-  ULONG         minMemType42;           /* Minimum memory usage when an OpenType font
+  HBUINT32      minMemType42;           /* Minimum memory usage when an OpenType font
                                          * is downloaded. */
-  ULONG         maxMemType42;           /* Maximum memory usage when an OpenType font
+  HBUINT32      maxMemType42;           /* Maximum memory usage when an OpenType font
                                          * is downloaded. */
-  ULONG         minMemType1;            /* Minimum memory usage when an OpenType font
+  HBUINT32      minMemType1;            /* Minimum memory usage when an OpenType font
                                          * is downloaded as a Type 1 font. */
-  ULONG         maxMemType1;            /* Maximum memory usage when an OpenType font
+  HBUINT32      maxMemType1;            /* Maximum memory usage when an OpenType font
                                          * is downloaded as a Type 1 font. */
 /*postV2Tail    v2[VAR];*/
   DEFINE_SIZE_STATIC (32);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-fallback.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-fallback.hh	Wed May 30 12:20:00 2018 -0700
@@ -77,13 +77,7 @@
 
   /* Bubble-sort or something equally good!
    * May not be good-enough for presidential candidate interviews, but good-enough for us... */
-
-#if defined(_AIX)
-  /* Workaround AIX xlC 12 compilation problems caused by the overloaded versions of 'cmp' in IntType */
   hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]);
-#else
-  hb_stable_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
-#endif
 
   OT::Supplier<OT::GlyphID> glyphs_supplier      (glyphs, num_glyphs);
   OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
@@ -132,13 +126,7 @@
     first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
     num_first_glyphs++;
   }
-
-#if defined(_AIX)
-  /* Workaround AIX xlC 12 compilation problems caused by the overloaded versions of 'cmp' in IntType */
-  hb_stable_sort (&first_glyphs[0], num_first_glyphs, (int(*)(const OT::GlyphID *, const OT::GlyphID *)) OT::GlyphID::cmp, &first_glyphs_indirection[0]);
-#else
-  hb_stable_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]);
-#endif
+  hb_stable_sort (&first_glyphs[0], num_first_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &first_glyphs_indirection[0]);
 
   /* Now that the first-glyphs are sorted, walk again, populate ligatures. */
   for (unsigned int i = 0; i < num_first_glyphs; i++)
@@ -352,7 +340,7 @@
                             hb_font_t *font,
                             hb_buffer_t *buffer)
 {
-  OT::hb_apply_context_t c (0, font, buffer);
+  OT::hb_ot_apply_context_t c (0, font, buffer);
   for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
     if (fallback_plan->lookup_array[i]) {
       c.set_lookup_mask (fallback_plan->mask_array[i]);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-win1256.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-win1256.hh	Wed May 30 12:20:00 2018 -0700
@@ -43,16 +43,16 @@
 #define OT_TABLE_END                    }
 #define OT_LABEL_START(Name)            unsigned char Name[
 #define OT_LABEL_END                    ];
-#define OT_BYTE(u8)                     +1/*byte*/
-#define OT_USHORT(u16)                  +2/*bytes*/
+#define OT_UINT8(u8)                    +1/*byte*/
+#define OT_UINT16(u16)                  +2/*bytes*/
 #else
 #undef  OT_MEASURE
 #define OT_TABLE_START                  TABLE_NAME = {
 #define OT_TABLE_END                    };
 #define OT_LABEL_START(Name)            {
 #define OT_LABEL_END                    },
-#define OT_BYTE(u8)                     (u8),
-#define OT_USHORT(u16)                  (unsigned char)((u16)>>8), (unsigned char)((u16)&0xFFu),
+#define OT_UINT8(u8)                    (u8),
+#define OT_UINT16(u16)                  (unsigned char)((u16)>>8), (unsigned char)((u16)&0xFFu),
 #define OT_COUNT(Name, ItemSize)        ((unsigned int) sizeof(((struct TABLE_NAME*)0)->Name) \
                                          / (unsigned int)(ItemSize) \
                                          /* OT_ASSERT it's divisible (and positive). */)
@@ -80,24 +80,24 @@
  */
 
 #define OT_TAG(a,b,c,d) \
-        OT_BYTE(a) OT_BYTE(b) OT_BYTE(c) OT_BYTE(d)
+        OT_UINT8(a) OT_UINT8(b) OT_UINT8(c) OT_UINT8(d)
 
 #define OT_OFFSET(From, To) /* Offset from From to To in bytes */ \
-        OT_USHORT(OT_DISTANCE(From, To))
+        OT_UINT16(OT_DISTANCE(From, To))
 
 #define OT_GLYPHID /* GlyphID */ \
-        OT_USHORT
+        OT_UINT16
 
 #define OT_UARRAY(Name, Items) \
         OT_LABEL_START(Name) \
-        OT_USHORT(OT_COUNT(Name##Data, 2)) \
+        OT_UINT16(OT_COUNT(Name##Data, 2)) \
         OT_LABEL(Name##Data) \
         Items \
         OT_LABEL_END
 
 #define OT_UHEADLESSARRAY(Name, Items) \
         OT_LABEL_START(Name) \
-        OT_USHORT(OT_COUNT(Name##Data, 2) + 1) \
+        OT_UINT16(OT_COUNT(Name##Data, 2) + 1) \
         OT_LABEL(Name##Data) \
         Items \
         OT_LABEL_END
@@ -111,19 +111,19 @@
 
 #define OT_LOOKUP(Name, LookupType, LookupFlag, SubLookupOffsets) \
         OT_LABEL_START(Name) \
-        OT_USHORT(LookupType) \
-        OT_USHORT(LookupFlag) \
+        OT_UINT16(LookupType) \
+        OT_UINT16(LookupFlag) \
         OT_LABEL_END \
         OT_UARRAY(Name##SubLookupOffsetsArray, OT_LIST(SubLookupOffsets))
 
 #define OT_SUBLOOKUP(Name, SubFormat, Items) \
         OT_LABEL_START(Name) \
-        OT_USHORT(SubFormat) \
+        OT_UINT16(SubFormat) \
         Items
 
 #define OT_COVERAGE1(Name, Items) \
         OT_LABEL_START(Name) \
-        OT_USHORT(1) \
+        OT_UINT16(1) \
         OT_LABEL_END \
         OT_UARRAY(Name##Glyphs, OT_LIST(Items))
 
@@ -174,7 +174,7 @@
 /* Table manifest. */
 #define MANIFEST(Items) \
         OT_LABEL_START(manifest) \
-        OT_USHORT(OT_COUNT(manifestData, 6)) \
+        OT_UINT16(OT_COUNT(manifestData, 6)) \
         OT_LABEL(manifestData) \
         Items \
         OT_LABEL_END
@@ -304,8 +304,8 @@
 #undef OT_TABLE_END
 #undef OT_LABEL_START
 #undef OT_LABEL_END
-#undef OT_BYTE
-#undef OT_USHORT
+#undef OT_UINT8
+#undef OT_UINT16
 #undef OT_DISTANCE
 #undef OT_COUNT
 
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic.cc	Wed May 30 12:20:00 2018 -0700
@@ -36,7 +36,7 @@
 #define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0
 
 /* See:
- * https://github.com/behdad/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
+ * https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
 #define HB_ARABIC_GENERAL_CATEGORY_IS_WORD(gen_cat) \
         (FLAG_UNSAFE (gen_cat) & \
          (FLAG (HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) | \
@@ -198,7 +198,7 @@
    * pause for Arabic, not other scripts.
    *
    * A pause after calt is required to make KFGQPC Uthmanic Script HAFS
-   * work correctly.  See https://github.com/behdad/harfbuzz/issues/505
+   * work correctly.  See https://github.com/harfbuzz/harfbuzz/issues/505
    */
 
   map->add_gsub_pause (nuke_joiners);
@@ -644,13 +644,15 @@
 {
   hb_glyph_info_t *info = buffer->info;
 
+  DEBUG_MSG (ARABIC, buffer, "Reordering marks from %d to %d", start, end);
+
   unsigned int i = start;
   for (unsigned int cc = 220; cc <= 230; cc += 10)
   {
-    DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d\n", cc, i);
+    DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d", cc, i);
     while (i < end && info_cc(info[i]) < cc)
       i++;
-    DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d\n", cc, i);
+    DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d", cc, i);
 
     if (i == end)
       break;
@@ -658,20 +660,17 @@
     if (info_cc(info[i]) > cc)
       continue;
 
-    /* Technically we should also check "info_cc(info[j]) == cc"
-     * in the following loop.  But not doing it is safe; we might
-     * end up moving all the 220 MCMs and 230 MCMs together in one
-     * move and be done. */
     unsigned int j = i;
-    while (j < end && info_is_mcm (info[j]))
+    while (j < end && info_cc(info[j]) == cc && info_is_mcm (info[j]))
       j++;
-    DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d\n", cc, i, j);
 
     if (i == j)
       continue;
 
+    DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d", cc, i, j);
+
     /* Shift it! */
-    DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d\n", cc, i, j);
+    DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d", cc, i, j);
     hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS];
     assert (j - i <= ARRAY_LENGTH (temp));
     buffer->merge_clusters (start, j);
@@ -679,7 +678,25 @@
     memmove (&info[start + j - i], &info[start], (i - start) * sizeof (hb_glyph_info_t));
     memmove (&info[start], temp, (j - i) * sizeof (hb_glyph_info_t));
 
-    start += j - i;
+    /* Renumber CC such that the reordered sequence is still sorted.
+     * 22 and 26 are chosen because they are smaller than all Arabic categories,
+     * and are folded back to 220/230 respectively during fallback mark positioning.
+     *
+     * We do this because the CGJ-handling logic in the normalizer relies on
+     * mark sequences having an increasing order even after this reordering.
+     * https://github.com/harfbuzz/harfbuzz/issues/554
+     * This, however, does break some obscure sequences, where the normalizer
+     * might compose a sequence that it should not.  For example, in the seequence
+     * ALEF, HAMZAH, MADDAH, we should NOT try to compose ALEF+MADDAH, but with this
+     * renumbering, we will.
+     */
+    unsigned int new_start = start + j - i;
+    unsigned int new_cc = cc == 220 ? HB_MODIFIED_COMBINING_CLASS_CCC22 : HB_MODIFIED_COMBINING_CLASS_CCC26;
+    while (start < new_start)
+    {
+      _hb_glyph_info_set_modified_combining_class (&info[start], new_cc);
+      start++;
+    }
 
     i = j;
   }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hebrew.cc	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hebrew.cc	Wed May 30 12:20:00 2018 -0700
@@ -161,7 +161,7 @@
    * script.  This matches Uniscribe better, and makes fonts like
    * Arial that have GSUB/GPOS/GDEF but no data for Hebrew work.
    * See:
-   * https://github.com/behdad/harfbuzz/issues/347#issuecomment-267838368
+   * https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368
    */
   return plan->map.chosen_script[1] != HB_TAG ('h','e','b','r');
 }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-machine.hh	Wed May 30 08:10:41 2018 -0700
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-machine.hh	Wed May 30 12:20:00 2018 -0700
@@ -34,1106 +34,889 @@
 
 #line 36 "hb-ot-shape-complex-indic-machine.hh"
 static const unsigned char _indic_syllable_machine_trans_keys[] = {
-        8u, 8u, 1u, 16u, 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u,
-        7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u,
-        6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u,
-        4u, 8u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
-        4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, 8u, 13u,
-        5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u,
-        7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u,
-        6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u,
-        4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
-        4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u,
-        5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u,
-        7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u,
-        6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u,
-        4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u,
-        8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u,
+        8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u,
         5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u,
         4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u,
-        16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
-        4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 5u, 8u, 4u, 14u, 4u, 14u, 5u, 8u,
-        5u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u,
-        5u, 7u, 7u, 7u, 8u, 8u, 1u, 16u, 8u, 13u, 4u, 8u, 6u, 6u, 16u, 16u,
+        16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u,
+        4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u,
+        5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u,
         4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u,
-        16u, 16u, 8u, 8u, 1u, 19u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u,
+        16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u,
+        4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 8u,
+        5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u,
+        5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u,
+        16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u,
+        4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u,
+        8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u,
+        5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u,
+        4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u,
+        16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u,
+        4u, 13u, 4u, 8u, 4u, 13u, 4u, 13u, 5u, 8u, 5u, 8u, 5u, 7u, 5u, 8u,
+        5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u,
+        8u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u,
+        6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 8u, 8u, 1u, 19u, 3u, 17u,
         3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u,
-        3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u,
-        5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u,
-        3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u,
-        3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u,
-        5u, 14u, 3u, 14u, 1u, 16u, 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u,
-        1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u,
+        3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u,
+        3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u,
+        5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u,
+        3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u,
+        3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u,
+        1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u,
         1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
-        1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
         3u, 17u, 3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u,
         4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u,
-        4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u, 5u, 10u,
-        9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u,
-        5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u,
-        4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u,
-        3u, 14u, 1u, 16u, 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u,
-        1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
-        1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
-        3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 1u, 16u,
+        4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u,
+        10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u,
+        3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u,
+        5u, 10u, 3u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u,
+        3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u,
         3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u,
+        3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u,
+        5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u,
+        4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u,
+        3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u,
+        3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 13u, 3u, 17u, 4u, 8u,
         3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u,
-        3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u, 5u, 10u, 9u, 10u, 9u, 9u,
-        9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u,
-        3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u,
-        3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 1u, 16u,
-        4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
-        3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u,
-        3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u,
-        1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 3u, 17u, 4u, 14u,
         3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u,
-        3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u,
-        3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u, 5u, 10u, 9u, 10u, 9u, 9u,
-        9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u,
-        3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u,
-        3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 1u, 16u,
-        4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
-        3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u,
-        3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u,
-        1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u,
-        1u, 17u, 4u, 14u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u,
-        5u, 10u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 3u, 17u, 3u, 17u, 1u, 16u,
-        3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u,
-        5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u,
-        3u, 13u, 1u, 16u, 3u, 10u, 5u, 10u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u,
-        9u, 10u, 9u, 9u, 5u, 10u, 1u, 16u, 0
+        3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u,
+        10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u,
+        5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u,
+        4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u,
+        3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u,
+        10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u,
+        4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u,
+        3u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u,
+        0
 };
 
 static const char _indic_syllable_machine_key_spans[] = {
-        1, 16, 6, 4, 3, 1, 4, 3,
-        1, 4, 3, 1, 4, 3, 1, 5,
-        1, 1, 5, 1, 1, 5, 1, 1,
-        5, 1, 1, 11, 11, 11, 11, 11,
-        11, 11, 11, 11, 11, 1, 16, 6,
-        4, 3, 1, 4, 3, 1, 4, 3,
-        1, 4, 3, 1, 5, 1, 1, 5,
-        1, 1, 5, 1, 1, 5, 1, 1,
-        11, 11, 11, 11, 11, 11, 11, 11,
-        11, 11, 1, 16, 6, 4, 3, 1,
-        4, 3, 1, 4, 3, 1, 4, 3,
-        1, 5, 1, 1, 5, 1, 1, 5,
-        1, 1, 5, 1, 1, 11, 11, 11,
-        11, 11, 11, 11, 11, 11, 1, 16,
-        6, 4, 3, 1, 4, 3, 1, 4,
+        1, 4, 3, 1, 4, 3, 1, 4,
         3, 1, 4, 3, 1, 5, 1, 1,
         5, 1, 1, 5, 1, 1, 5, 1,
-        1, 11, 11, 11, 11, 11, 11, 11,
-        11, 11, 11, 11, 4, 11, 11, 4,
-        3, 4, 3, 1, 4, 3, 1, 4,
-        3, 1, 1, 16, 6, 5, 1, 1,
+        1, 5, 10, 5, 10, 5, 10, 5,
+        10, 5, 10, 1, 4, 3, 1, 4,
+        3, 1, 4, 3, 1, 4, 3, 1,
         5, 1, 1, 5, 1, 1, 5, 1,
-        1, 1, 19, 15, 15, 14, 16, 15,
+        1, 5, 1, 1, 5, 10, 5, 10,
+        5, 10, 5, 10, 5, 10, 1, 4,
+        3, 1, 4, 3, 1, 4, 3, 1,
+        4, 3, 1, 5, 1, 1, 5, 1,
+        1, 5, 1, 1, 5, 1, 1, 5,
+        10, 5, 10, 5, 10, 5, 10, 5,
+        1, 4, 3, 1, 4, 3, 1, 4,
+        3, 1, 4, 3, 1, 5, 1, 1,
+        5, 1, 1, 5, 1, 1, 5, 1,
+        1, 5, 10, 5, 10, 5, 10, 5,
+        10, 5, 10, 10, 4, 4, 3, 4,
+        3, 1, 4, 3, 1, 4, 3, 1,
+        1, 5, 1, 1, 5, 1, 1, 5,
+        1, 1, 5, 1, 1, 1, 19, 15,
         15, 14, 16, 15, 15, 14, 16, 15,
-        15, 14, 16, 15, 15, 14, 10, 10,
-        6, 2, 1, 2, 2, 1, 6, 11,
-        8, 6, 8, 11, 12, 12, 11, 10,
-        12, 11, 10, 12, 11, 10, 12, 11,
-        10, 12, 16, 11, 15, 15, 16, 16,
-        16, 16, 16, 15, 15, 16, 16, 16,
+        15, 14, 16, 15, 15, 14, 16, 15,
+        15, 14, 6, 6, 6, 1, 1, 1,
+        6, 8, 8, 7, 6, 8, 7, 6,
+        8, 7, 6, 8, 7, 6, 8, 7,
+        15, 15, 16, 16, 16, 16, 15, 15,
+        16, 16, 16, 16, 15, 15, 16, 16,
         16, 16, 15, 15, 16, 16, 16, 16,
-        16, 15, 15, 16, 16, 16, 16, 16,
         15, 15, 15, 15, 14, 16, 15, 15,
         14, 16, 15, 15, 14, 16, 15, 15,
-        14, 16, 15, 15, 14, 10, 10, 6,
-        2, 1, 2, 2, 1, 6, 11, 8,
-        6, 8, 11, 12, 12, 11, 10, 12,
-        11, 10, 12, 11, 10, 12, 11, 10,
-        12, 16, 11, 15, 15, 16, 16, 16,
-        16, 16, 15, 15, 16, 16, 16, 16,
-        16, 15, 15, 16, 16, 16, 16, 16,
-        15, 15, 16, 16, 16, 16, 11, 16,
+        14, 16, 15, 15, 14, 6, 6, 6,
+        1, 1, 1, 6, 8, 8, 7, 6,
+        8, 7, 6, 8, 7, 6, 8, 7,
+        6, 8, 7, 15, 15, 16, 16, 16,
+        16, 15, 15, 16, 16, 16, 16, 15,
+        15, 16, 16, 16, 16, 15, 15, 16,
+        16, 16, 16, 5, 15, 15, 14, 16,
         15, 15, 14, 16, 15, 15, 14, 16,
+        15, 15, 14, 16, 15, 15, 14, 6,
+        6, 6, 1, 1, 1, 6, 8, 8,
+        7, 6, 8, 7, 6, 8, 7, 6,
+        8, 7, 6, 8, 7, 15, 15, 16,
+        16, 16, 16, 15, 15, 16, 16, 16,
+        16, 15, 15, 16, 16, 16, 16, 15,
+        15, 16, 16, 16, 16, 10, 15, 5,
         15, 15, 14, 16, 15, 15, 14, 16,
-        15, 15, 14, 10, 10, 6, 2, 1,
-        2, 2, 1, 6, 11, 8, 6, 8,
-        11, 12, 12, 11, 10, 12, 11, 10,
-        12, 11, 10, 12, 11, 10, 12, 16,
-        11, 15, 15, 16, 16, 16, 16, 16,
-        15, 15, 16, 16, 16, 16, 16, 15,
-        15, 16, 16, 16, 16, 16, 15, 15,
-        16, 16, 16, 16, 16, 11, 15, 11,
         15, 15, 14, 16, 15, 15, 14, 16,
-        15, 15, 14, 16, 15, 15, 14, 16,
-        15, 15, 14, 10, 10, 6, 2, 1,
-        2, 2, 1, 6, 11, 8, 6, 8,
-        11, 12, 12, 11, 10, 12, 11, 10,
-        12, 11, 10, 12, 11, 10, 12, 16,
-        11, 15, 15, 16, 16, 16, 16, 16,
-        15, 15, 16, 16, 16, 16, 16, 15,
-        15, 16, 16, 16, 16, 16, 15, 15,
-        16, 16, 16, 16, 16, 15, 17, 15,
-        17, 11, 6, 2, 1, 2, 2, 1,
-        6, 16, 15, 15, 14, 15, 15, 16,
-        12, 11, 10, 12, 11, 10, 12, 11,
-        10, 12, 11, 10, 11, 8, 6, 8,
-        11, 16, 8, 6, 6, 2, 1, 2,
-        2, 1, 6, 16
+        15, 15, 14, 6, 6, 6, 1, 1,
+        1, 6, 8, 8, 7, 6, 8, 7,
+        6, 8, 7, 6, 8, 7, 6, 8,
+        7, 15, 15, 16, 16, 16, 16, 15,
+        15, 16, 16, 16, 16, 15, 15, 16,
+        16, 16, 16, 15, 15, 16, 16, 16,
+        16, 15, 17, 15, 17, 10, 6, 1,
+        1, 1, 6, 16, 8, 7, 6, 8,
+        7, 6, 8, 7, 6, 8, 7, 6,
+        8, 6, 6, 1, 1, 1, 6, 16
 };
 
 static const short _indic_syllable_machine_index_offsets[] = {
-        0, 2, 19, 26, 31, 35, 37, 42,
-        46, 48, 53, 57, 59, 64, 68, 70,
-        76, 78, 80, 86, 88, 90, 96, 98,
-        100, 106, 108, 110, 122, 134, 146, 158,
-        170, 182, 194, 206, 218, 230, 232, 249,
-        256, 261, 265, 267, 272, 276, 278, 283,
-        287, 289, 294, 298, 300, 306, 308, 310,
-        316, 318, 320, 326, 328, 330, 336, 338,
-        340, 352, 364, 376, 388, 400, 412, 424,
-        436, 448, 460, 462, 479, 486, 491, 495,
-        497, 502, 506, 508, 513, 517, 519, 524,
-        528, 530, 536, 538, 540, 546, 548, 550,
-        556, 558, 560, 566, 568, 570, 582, 594,
-        606, 618, 630, 642, 654, 666, 678, 680,
-        697, 704, 709, 713, 715, 720, 724, 726,
-        731, 735, 737, 742, 746, 748, 754, 756,
-        758, 764, 766, 768, 774, 776, 778, 784,
-        786, 788, 800, 812, 824, 836, 848, 860,
-        872, 884, 896, 908, 920, 925, 937, 949,
-        954, 958, 963, 967, 969, 974, 978, 980,
-        985, 989, 991, 993, 1010, 1017, 1023, 1025,
-        1027, 1033, 1035, 1037, 1043, 1045, 1047, 1053,
-        1055, 1057, 1059, 1079, 1095, 1111, 1126, 1143,
-        1159, 1175, 1190, 1207, 1223, 1239, 1254, 1271,
-        1287, 1303, 1318, 1335, 1351, 1367, 1382, 1393,
-        1404, 1411, 1414, 1416, 1419, 1422, 1424, 1431,
-        1443, 1452, 1459, 1468, 1480, 1493, 1506, 1518,
-        1529, 1542, 1554, 1565, 1578, 1590, 1601, 1614,
-        1626, 1637, 1650, 1667, 1679, 1695, 1711, 1728,
-        1745, 1762, 1779, 1796, 1812, 1828, 1845, 1862,
-        1879, 1896, 1913, 1929, 1945, 1962, 1979, 1996,
-        2013, 2030, 2046, 2062, 2079, 2096, 2113, 2130,
-        2147, 2163, 2179, 2195, 2211, 2226, 2243, 2259,
-        2275, 2290, 2307, 2323, 2339, 2354, 2371, 2387,
-        2403, 2418, 2435, 2451, 2467, 2482, 2493, 2504,
-        2511, 2514, 2516, 2519, 2522, 2524, 2531, 2543,
-        2552, 2559, 2568, 2580, 2593, 2606, 2618, 2629,
-        2642, 2654, 2665, 2678, 2690, 2701, 2714, 2726,
-        2737, 2750, 2767, 2779, 2795, 2811, 2828, 2845,
-        2862, 2879, 2896, 2912, 2928, 2945, 2962, 2979,
-        2996, 3013, 3029, 3045, 3062, 3079, 3096, 3113,
-        3130, 3146, 3162, 3179, 3196, 3213, 3230, 3242,
-        3259, 3275, 3291, 3306, 3323, 3339, 3355, 3370,
-        3387, 3403, 3419, 3434, 3451, 3467, 3483, 3498,
-        3515, 3531, 3547, 3562, 3573, 3584, 3591, 3594,
-        3596, 3599, 3602, 3604, 3611, 3623, 3632, 3639,
-        3648, 3660, 3673, 3686, 3698, 3709, 3722, 3734,
-        3745, 3758, 3770, 3781, 3794, 3806, 3817, 3830,
-        3847, 3859, 3875, 3891, 3908, 3925, 3942, 3959,
-        3976, 3992, 4008, 4025, 4042, 4059, 4076, 4093,
-        4109, 4125, 4142, 4159, 4176, 4193, 4210, 4226,
-        4242, 4259, 4276, 4293, 4310, 4327, 4339, 4355,
-        4367, 4383, 4399, 4414, 4431, 4447, 4463, 4478,
-        4495, 4511, 4527, 4542, 4559, 4575, 4591, 4606,
-        4623, 4639, 4655, 4670, 4681, 4692, 4699, 4702,
-        4704, 4707, 4710, 4712, 4719, 4731, 4740, 4747,
-        4756, 4768, 4781, 4794, 4806, 4817, 4830, 4842,
-        4853, 4866, 4878, 4889, 4902, 4914, 4925, 4938,
-        4955, 4967, 4983, 4999, 5016, 5033, 5050, 5067,
-        5084, 5100, 5116, 5133, 5150, 5167, 5184, 5201,
-        5217, 5233, 5250, 5267, 5284, 5301, 5318, 5334,
-        5350, 5367, 5384, 5401, 5418, 5435, 5451, 5469,
-        5485, 5503, 5515, 5522, 5525, 5527, 5530, 5533,
-        5535, 5542, 5559, 5575, 5591, 5606, 5622, 5638,
-        5655, 5668, 5680, 5691, 5704, 5716, 5727, 5740,
-        5752, 5763, 5776, 5788, 5799, 5811, 5820, 5827,
-        5836, 5848, 5865, 5874, 5881, 5888, 5891, 5893,
-        5896, 5899, 5901, 5908
+        0, 2, 7, 11, 13, 18, 22, 24,
+        29, 33, 35, 40, 44, 46, 52, 54,
+        56, 62, 64, 66, 72, 74, 76, 82,
+        84, 86, 92, 103, 109, 120, 126, 137,
+        143, 154, 160, 171, 173, 178, 182, 184,
+        189, 193, 195, 200, 204, 206, 211, 215,
+        217, 223, 225, 227, 233, 235, 237, 243,
+        245, 247, 253, 255, 257, 263, 274, 280,
+        291, 297, 308, 314, 325, 331, 342, 344,
+        349, 353, 355, 360, 364, 366, 371, 375,
+        377, 382, 386, 388, 394, 396, 398, 404,
+        406, 408, 414, 416, 418, 424, 426, 428,
+        434, 445, 451, 462, 468, 479, 485, 496,
+        502, 504, 509, 513, 515, 520, 524, 526,
+        531, 535, 537, 542, 546, 548, 554, 556,
+        558, 564, 566, 568, 574, 576, 578, 584,
+        586, 588, 594, 605, 611, 622, 628, 639,
+        645, 656, 662, 673, 684, 689, 694, 698,
+        703, 707, 709, 714, 718, 720, 725, 729,
+        731, 733, 739, 741, 743, 749, 751, 753,
+        759, 761, 763, 769, 771, 773, 775, 795,
+        811, 827, 842, 859, 875, 891, 906, 923,
+        939, 955, 970, 987, 1003, 1019, 1034, 1051,
+        1067, 1083, 1098, 1105, 1112, 1119, 1121, 1123,
+        1125, 1132, 1141, 1150, 1158, 1165, 1174, 1182,
+        1189, 1198, 1206, 1213, 1222, 1230, 1237, 1246,
+        1254, 1270, 1286, 1303, 1320, 1337, 1354, 1370,
+        1386, 1403, 1420, 1437, 1454, 1470, 1486, 1503,
+        1520, 1537, 1554, 1570, 1586, 1603, 1620, 1637,
+        1654, 1670, 1686, 1702, 1718, 1733, 1750, 1766,
+        1782, 1797, 1814, 1830, 1846, 1861, 1878, 1894,
+        1910, 1925, 1942, 1958, 1974, 1989, 1996, 2003,
+        2010, 2012, 2014, 2016, 2023, 2032, 2041, 2049,
+        2056, 2065, 2073, 2080, 2089, 2097, 2104, 2113,
+        2121, 2128, 2137, 2145, 2161, 2177, 2194, 2211,
+        2228, 2245, 2261, 2277, 2294, 2311, 2328, 2345,
+        2361, 2377, 2394, 2411, 2428, 2445, 2461, 2477,
+        2494, 2511, 2528, 2545, 2551, 2567, 2583, 2598,
+        2615, 2631, 2647, 2662, 2679, 2695, 2711, 2726,
+        2743, 2759, 2775, 2790, 2807, 2823, 2839, 2854,
+        2861, 2868, 2875, 2877, 2879, 2881, 2888, 2897,
+        2906, 2914, 2921, 2930, 2938, 2945, 2954, 2962,
+        2969, 2978, 2986, 2993, 3002, 3010, 3026, 3042,
+        3059, 3076, 3093, 3110, 3126, 3142, 3159, 3176,
+        3193, 3210, 3226, 3242, 3259, 3276, 3293, 3310,
+        3326, 3342, 3359, 3376, 3393, 3410, 3421, 3437,
+        3443, 3459, 3475, 3490, 3507, 3523, 3539, 3554,
+        3571, 3587, 3603, 3618, 3635, 3651, 3667, 3682,
+        3699, 3715, 3731, 3746, 3753, 3760, 3767, 3769,
+        3771, 3773, 3780, 3789, 3798, 3806, 3813, 3822,
+        3830, 3837, 3846, 3854, 3861, 3870, 3878, 3885,
+        3894, 3902, 3918, 3934, 3951, 3968, 3985, 4002,
+        4018, 4034, 4051, 4068, 4085, 4102, 4118, 4134,
+        4151, 4168, 4185, 4202, 4218, 4234, 4251, 4268,
+        4285, 4302, 4318, 4336, 4352, 4370, 4381, 4388,
+        4390, 4392, 4394, 4401, 4418, 4427, 4435, 4442,
+        4451, 4459, 4466, 4475, 4483, 4490, 4499, 4507,
+        4514, 4523, 4530, 4537, 4539, 4541, 4543, 4550
 };
 
 static const short _indic_syllable_machine_indicies[] = {
-        1, 0, 2, 3, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0,
-        0, 2, 0, 1, 0, 0, 0, 0,
-        4, 0, 5, 5, 6, 1, 0, 7,
-        7, 6, 0, 6, 0, 8, 8, 9,
-        1, 0, 10, 10, 9, 0, 9, 0,
-        11, 11, 12, 1, 0, 13, 13, 12,
-        0, 12, 0, 14, 14, 15, 1, 0,
-        16, 16, 15, 0, 15, 0, 17, 0,
-        0, 0, 1, 0, 18, 0, 19, 0,
-        20, 14, 14, 15, 1, 0, 21, 0,
-        22, 0, 23, 11, 11, 12, 1, 0,
-        24, 0, 25, 0, 26, 8, 8, 9,
-        1, 0, 27, 0, 28, 0, 29, 5,
-        5, 6, 1, 0, 0, 0, 0, 0,
-        29, 0, 29, 5, 5, 6, 1, 0,
-        0, 0, 0, 30, 29, 0, 31, 5,
-        5, 6, 1, 0, 0, 0, 0, 0,
-        31, 0, 31, 5, 5, 6, 1, 0,
-        0, 0, 0, 32, 31, 0, 33, 5,
-        5, 6, 1, 0, 0, 0, 0, 0,
-        33, 0, 33, 5, 5, 6, 1, 0,
-        0, 0, 0, 34, 33, 0, 35, 5,
-        5, 6, 1, 0, 0, 0, 0, 0,
-        35, 0, 35, 5, 5, 6, 1, 0,
-        0, 0, 0, 36, 35, 0, 37, 5,
-        5, 6, 1, 0, 0, 0, 0, 0,
-        37, 0, 37, 5, 5, 6, 1, 0,
-        0, 0, 0, 38, 37, 0, 40, 39,
-        41, 42, 39, 39, 39, 39, 39, 39,
-        39, 39, 39, 39, 39, 39, 39, 41,
-        39, 40, 39, 39, 39, 39, 43, 39,
-        44, 44, 45, 40, 39, 46, 46, 45,
-        39, 45, 39, 47, 47, 48, 40, 39,
-        49, 49, 48, 39, 48, 39, 50, 50,
-        51, 40, 39, 52, 52, 51, 39, 51,
-        39, 53, 53, 54, 40, 39, 55, 55,
-        54, 39, 54, 39, 56, 39, 39, 39,