8143177: Integrate harfbuzz opentype layout engine per JEP 258
authorprr
Mon, 23 Nov 2015 09:58:44 -0800
changeset 34414 e496a8d8fc8a
parent 34413 bbed9966db6e
child 34415 098d54b4051d
8143177: Integrate harfbuzz opentype layout engine per JEP 258 Reviewed-by: srl, vadim, serb
jdk/make/lib/Awt2dLibraries.gmk
jdk/make/mapfiles/libfontmanager/mapfile-vers
jdk/make/mapfiles/libfontmanager/mapfile-vers.openjdk
jdk/src/java.desktop/macosx/classes/sun/font/CFont.java
jdk/src/java.desktop/share/classes/sun/font/Font2D.java
jdk/src/java.desktop/share/classes/sun/font/GlyphLayout.java
jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java
jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java
jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-atomic-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-deserialize-json.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-deserialize-text.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-serialize.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-cache-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-deprecated.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-fallback-shape.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-mutex-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-object-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-file-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-glyf-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-head-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hhea-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hmtx-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-common-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gdef-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gpos-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsub-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsubgpos-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-jstf-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-maxp-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-name-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-fallback.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-table.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-win1256.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-default.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hangul.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hebrew.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-machine.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-table.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar-machine.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-thai.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-tibetan.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-machine.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-table.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-fallback-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-fallback.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-tag.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-tag.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape-plan-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape-plan.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape-plan.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shaper-impl-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shaper-list.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shaper-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shaper.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ucdn.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ucdn/ucdn.c
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ucdn/ucdn.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ucdn/unicodedata_db.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-utf-private.hh
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-version.h
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-warning.cc
jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb.h
jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc
jdk/src/java.desktop/share/native/libfontmanager/hb-jdk.h
jdk/src/java.desktop/share/native/libfontmanager/scriptMapping.c
jdk/src/java.desktop/share/native/libfontmanager/scriptMapping.h
jdk/test/java/awt/font/TextLayout/TestLayoutVsICU.java
jdk/test/java/awt/font/TextLayout/TestLayoutVsICU_jdkbase.xml
--- a/jdk/make/lib/Awt2dLibraries.gmk	Mon Nov 23 14:44:41 2015 +0300
+++ b/jdk/make/lib/Awt2dLibraries.gmk	Mon Nov 23 09:58:44 2015 -0800
@@ -602,6 +602,34 @@
     $(LIBJAVA_HEADER_FLAGS) \
     #
 
+#### Begin harfbuzz configuration
+
+HARFBUZZ_CFLAGS := -DHAVE_OT -DHAVE_FALLBACK -DHAVE_UCDN
+
+ifneq ($(OPENJDK_TARGET_OS), windows)
+  HARFBUZZ_CFLAGS += -DGETPAGESIZE -DHAVE_MPROTECT -DHAVE_PTHREAD \
+                      -DHAVE_SYSCONF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H
+endif
+ifneq (, $(findstring $(OPENJDK_TARGET_OS), linux macosx))
+  HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES
+endif
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+  HARFBUZZ_CFLAGS += -DHAVE_SOLARIS_ATOMIC_OPS
+endif
+ifeq ($(OPENJDK_TARGET_OS), macosx)
+  HARFBUZZ_CFLAGS += -DHAVE_CORETEXT
+endif
+ifneq ($(OPENJDK_TARGET_OS), macosx)
+  LIBFONTMANAGER_EXCLUDE_FILES += harfbuzz/hb-coretext.cc
+endif
+ifndef OPENJDK
+  LIBFONTMANAGER_EXCLUDE_FILES += harfbuzz/hb-ft.cc
+endif
+
+LIBFONTMANAGER_CFLAGS += $(HARFBUZZ_CFLAGS)
+
+#### End harfbuzz configuration
+
 ifndef OPENJDK
   LIBFONTMANAGER_CFLAGS += -I$(JDK_TOPDIR)/src/closed/java.desktop/share/native/libt2k
   BUILD_LIBFONTMANAGER_MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libfontmanager/mapfile-vers
@@ -648,11 +676,11 @@
     OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \
     CFLAGS_windows = -DCC_NOEX, \
     DISABLED_WARNINGS_gcc := sign-compare int-to-pointer-cast reorder \
-        delete-non-virtual-dtor type-limits, \
+        delete-non-virtual-dtor type-limits missing-field-initializers, \
     DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \
         tautological-constant-out-of-range-compare int-to-pointer-cast, \
     DISABLED_WARNINGS_solstudio := truncwarn, \
-    DISABLED_WARNINGS_microsoft := 4267 4244 4018 4090 4996 4146, \
+    DISABLED_WARNINGS_microsoft := 4267 4244 4018 4090 4996 4146 4334, \
     WARNINGS_AS_ERRORS_gcc := false, \
     WARNINGS_AS_ERRORS_solstudio := false, \
     MAPFILE := $(BUILD_LIBFONTMANAGER_MAPFILE), \
--- a/jdk/make/mapfiles/libfontmanager/mapfile-vers	Mon Nov 23 14:44:41 2015 +0300
+++ b/jdk/make/mapfiles/libfontmanager/mapfile-vers	Mon Nov 23 09:58:44 2015 -0800
@@ -41,6 +41,7 @@
                 Java_sun_font_StrikeCache_freeLongMemory;
                 Java_sun_font_SunLayoutEngine_initGVIDs;
                 Java_sun_font_SunLayoutEngine_nativeLayout;
+                Java_sun_font_SunLayoutEngine_shape;
                 Java_sun_font_X11TextRenderer_doDrawGlyphList;
 		Java_sun_java2d_loops_DrawGlyphListAA_DrawGlyphListAA;
 		Java_sun_java2d_loops_DrawGlyphListLCD_DrawGlyphListLCD;
--- a/jdk/make/mapfiles/libfontmanager/mapfile-vers.openjdk	Mon Nov 23 14:44:41 2015 +0300
+++ b/jdk/make/mapfiles/libfontmanager/mapfile-vers.openjdk	Mon Nov 23 09:58:44 2015 -0800
@@ -43,6 +43,7 @@
                 Java_sun_font_StrikeCache_freeLongMemory;
                 Java_sun_font_SunLayoutEngine_initGVIDs;
                 Java_sun_font_SunLayoutEngine_nativeLayout;
+                Java_sun_font_SunLayoutEngine_shape;
                 Java_sun_font_X11TextRenderer_doDrawGlyphList;
 		Java_sun_java2d_loops_DrawGlyphListAA_DrawGlyphListAA;
 		Java_sun_java2d_loops_DrawGlyphListLCD_DrawGlyphListLCD;
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CFont.java	Mon Nov 23 14:44:41 2015 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFont.java	Mon Nov 23 09:58:44 2015 -0800
@@ -198,6 +198,13 @@
         return nativeFontPtr;
     }
 
+    private native long getCGFontPtrNative(long ptr);
+
+    // This digs the CGFont out of the AWTFont.
+    protected synchronized long getPlatformNativeFontPtr() {
+        return getCGFontPtrNative(getNativeFontPtr());
+    }
+
     static native void getCascadeList(long nativeFontPtr, ArrayList<String> listOfString);
 
     private CompositeFont createCompositeFont() {
--- a/jdk/src/java.desktop/share/classes/sun/font/Font2D.java	Mon Nov 23 14:44:41 2015 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/font/Font2D.java	Mon Nov 23 09:58:44 2015 -0800
@@ -472,6 +472,12 @@
         return 0L;
     }
 
+    /* Used only on OS X.
+     */
+    protected long getPlatformNativeFontPtr() {
+        return 0L;
+    }
+
     /* for layout code */
     protected long getUnitsPerEm() {
         return 2048;
--- a/jdk/src/java.desktop/share/classes/sun/font/GlyphLayout.java	Mon Nov 23 14:44:41 2015 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/font/GlyphLayout.java	Mon Nov 23 09:58:44 2015 -0800
@@ -96,6 +96,7 @@
     private Point2D.Float _pt;
     private FontStrikeDesc _sd;
     private float[] _mat;
+    private float ptSize;
     private int _typo_flags;
     private int _offset;
 
@@ -172,7 +173,7 @@
          * If the GVData does not have room for the glyphs, throws an IndexOutOfBoundsException and
          * leave pt and the gvdata unchanged.
          */
-        public void layout(FontStrikeDesc sd, float[] mat, int gmask,
+        public void layout(FontStrikeDesc sd, float[] mat, float ptSize, int gmask,
                            int baseIndex, TextRecord text, int typo_flags, Point2D.Float pt, GVData data);
     }
 
@@ -386,6 +387,7 @@
         _mat[2] = (float)txinfo.gtx.getShearX();
         _mat[3] = (float)txinfo.gtx.getScaleY();
         _pt.setLocation(txinfo.delta);
+        ptSize = font.getSize2D();
 
         int lim = offset + count;
 
@@ -682,7 +684,7 @@
         void layout() {
             _textRecord.start = start;
             _textRecord.limit = limit;
-            engine.layout(_sd, _mat, gmask, start - _offset, _textRecord,
+            engine.layout(_sd, _mat, ptSize, gmask, start - _offset, _textRecord,
                           _typo_flags | eflags, _pt, _gvdata);
         }
     }
--- a/jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java	Mon Nov 23 14:44:41 2015 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java	Mon Nov 23 09:58:44 2015 -0800
@@ -103,9 +103,20 @@
  * */
 public final class SunLayoutEngine implements LayoutEngine, LayoutEngineFactory {
     private static native void initGVIDs();
+    private static final boolean useICU;
     static {
         FontManagerNativeLibrary.load();
         initGVIDs();
+        String le = java.security.AccessController.doPrivileged(
+            new sun.security.action.
+                GetPropertyAction("sun.font.layoutengine", ""));
+        useICU = le.equals("icu");
+        String verbose = java.security.AccessController.doPrivileged(
+            new sun.security.action.
+                GetPropertyAction("sun.font.layoutengine.verbose", ""));
+        if ("true".equalsIgnoreCase(verbose)) {
+            System.out.println("Using " + (useICU ? "icu." : "harfbuzz."));
+        }
     }
 
     private LayoutEngineKey key;
@@ -150,21 +161,57 @@
         this.key = key;
     }
 
-    public void layout(FontStrikeDesc desc, float[] mat, int gmask,
+    private boolean isAAT(Font2D font) {
+       if (font instanceof TrueTypeFont) {
+           TrueTypeFont ttf = (TrueTypeFont)font;
+           return ttf.getDirectoryEntry(TrueTypeFont.morxTag) != null ||
+                  ttf.getDirectoryEntry(TrueTypeFont.mortTag) != null;
+       } else if (font instanceof PhysicalFont) {
+           PhysicalFont pf = (PhysicalFont)font;
+           return pf.getTableBytes(TrueTypeFont.morxTag) != null ||
+                  pf.getTableBytes(TrueTypeFont.mortTag) != null;
+       }
+       return false;
+    }
+
+    public void layout(FontStrikeDesc desc, float[] mat, float ptSize, int gmask,
                        int baseIndex, TextRecord tr, int typo_flags,
                        Point2D.Float pt, GVData data) {
         Font2D font = key.font();
         FontStrike strike = font.getStrike(desc);
         long layoutTables = font.getLayoutTableCache();
+        if (useICU) {
         nativeLayout(font, strike, mat, gmask, baseIndex,
              tr.text, tr.start, tr.limit, tr.min, tr.max,
              key.script(), key.lang(), typo_flags, pt, data,
              font.getUnitsPerEm(), layoutTables);
+        } else {
+            long pNativeFont = font.getPlatformNativeFontPtr(); // used on OSX
+            // pScaler probably not needed long term.
+            long pScaler = 0L;
+            if (font instanceof FileFont) {
+                pScaler = ((FileFont)font).getScaler().nativeScaler;
+            }
+            shape(font, strike, ptSize, mat, pScaler, pNativeFont, isAAT(font),
+                  tr.text, data, key.script(),
+                  tr.start, tr.limit, baseIndex, pt,
+                  typo_flags, gmask);
+         }
     }
 
+    /* Native method to invoke ICU layout engine */
     private static native void
         nativeLayout(Font2D font, FontStrike strike, float[] mat, int gmask,
              int baseIndex, char[] chars, int offset, int limit,
              int min, int max, int script, int lang, int typo_flags,
              Point2D.Float pt, GVData data, long upem, long layoutTables);
+
+
+    /* Native method to invoke harfbuzz layout engine */
+    private static native boolean
+        shape(Font2D font, FontStrike strike, float ptSize, float[] mat,
+              long pscaler, long pNativeFont, boolean aat,
+              char[] chars, GVData data,
+              int script, int offset, int limit,
+              int baseIndex, Point2D.Float pt, int typo_flags, int slot);
 }
--- a/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java	Mon Nov 23 14:44:41 2015 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/font/TrueTypeFont.java	Mon Nov 23 09:58:44 2015 -0800
@@ -83,6 +83,7 @@
     public static final int GPOSTag = 0x47504F53; // 'GPOS'
     public static final int GSUBTag = 0x47535542; // 'GSUB'
     public static final int mortTag = 0x6D6F7274; // 'mort'
+    public static final int morxTag = 0x6D6F7278; // 'morx'
 
     /* -- Tags for non-standard tables */
     public static final int fdscTag = 0x66647363; // 'fdsc' - gxFont descriptor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni_util.h>
+#include <stdlib.h>
+#include "hb.h"
+#include "hb-jdk.h"
+#include "hb-ot.h"
+#ifdef MACOSX
+#include "hb-coretext.h"
+#endif
+#include "scriptMapping.h"
+
+static jclass gvdClass = 0;
+static const char* gvdClassName = "sun/font/GlyphLayout$GVData";
+static jfieldID gvdCountFID = 0;
+static jfieldID gvdFlagsFID = 0;
+static jfieldID gvdGlyphsFID = 0;
+static jfieldID gvdPositionsFID = 0;
+static jfieldID gvdIndicesFID = 0;
+static int jniInited = 0;
+
+static void getFloat(JNIEnv* env, jobject pt, jfloat *x, jfloat *y) {
+    *x = (*env)->GetFloatField(env, pt, sunFontIDs.xFID);
+    *y = (*env)->GetFloatField(env, pt, sunFontIDs.yFID);
+}
+
+static void putFloat(JNIEnv* env, jobject pt, jfloat x, jfloat y) {
+    (*env)->SetFloatField(env, pt, sunFontIDs.xFID, x);
+    (*env)->SetFloatField(env, pt, sunFontIDs.yFID, y);
+}
+
+static int init_JNI_IDs(JNIEnv *env) {
+    if (jniInited) {
+        return jniInited;
+    }
+    CHECK_NULL_RETURN(gvdClass = (*env)->FindClass(env, gvdClassName), 0);
+    CHECK_NULL_RETURN(gvdClass = (jclass)(*env)->NewGlobalRef(env, gvdClass), 0);
+    CHECK_NULL_RETURN(gvdCountFID = (*env)->GetFieldID(env, gvdClass, "_count", "I"), 0);
+    CHECK_NULL_RETURN(gvdFlagsFID = (*env)->GetFieldID(env, gvdClass, "_flags", "I"), 0);
+    CHECK_NULL_RETURN(gvdGlyphsFID = (*env)->GetFieldID(env, gvdClass, "_glyphs", "[I"), 0);
+    CHECK_NULL_RETURN(gvdPositionsFID = (*env)->GetFieldID(env, gvdClass, "_positions", "[F"), 0);
+    CHECK_NULL_RETURN(gvdIndicesFID = (*env)->GetFieldID(env, gvdClass, "_indices", "[I"), 0);
+    jniInited = 1;
+    return jniInited;
+}
+
+// gmask is the composite font slot mask
+// baseindex is to be added to the character (code point) index.
+int storeGVData(JNIEnv* env,
+               jobject gvdata, jint slot, jint baseIndex, jobject startPt,
+               int glyphCount, hb_glyph_info_t *glyphInfo,
+               hb_glyph_position_t *glyphPos, hb_direction_t direction) {
+
+    int i;
+    float x=0, y=0;
+    float startX, startY;
+    float scale = 1.0f/64.0f;
+    unsigned int* glyphs;
+    float* positions;
+
+    if (!init_JNI_IDs(env)) {
+        return 0;
+    }
+
+    int initialCount = (*env)->GetIntField(env, gvdata, gvdCountFID);
+    jarray glyphArray =
+       (jarray)(*env)->GetObjectField(env, gvdata, gvdGlyphsFID);
+    jarray posArray =
+        (jarray)(*env)->GetObjectField(env, gvdata, gvdPositionsFID);
+
+    if (glyphArray == NULL || posArray == NULL)
+    {
+        JNU_ThrowArrayIndexOutOfBoundsException(env, "");
+        return 0;
+    }
+
+    // The Java code catches the IIOBE and expands the storage
+    // and re-invokes layout. I suppose this is expected to be rare
+    // because at least in a single threaded case there should be
+    // re-use of the same container, but it is a little wasteful/distateful.
+    int glyphArrayLen = (*env)->GetArrayLength(env, glyphArray);
+    int posArrayLen = (*env)->GetArrayLength(env, posArray);
+    int maxGlyphs = glyphCount + initialCount;
+    if ((maxGlyphs >  glyphArrayLen) ||
+        (maxGlyphs * 2 + 2 >  posArrayLen))
+    {
+        JNU_ThrowArrayIndexOutOfBoundsException(env, "");
+        return 0;
+    }
+
+    getFloat(env, startPt, &startX, &startY);
+
+    glyphs =
+        (unsigned int*)(*env)->GetPrimitiveArrayCritical(env, glyphArray, NULL);
+    positions = (jfloat*)(*env)->GetPrimitiveArrayCritical(env, posArray, NULL);
+    for (i = 0; i < glyphCount; i++) {
+        int storei = i + initialCount;
+        int index = glyphInfo[i].codepoint | slot;
+        if (i<glyphCount)glyphs[storei] = (unsigned int)index;
+        positions[(storei*2)] = startX + x + glyphPos[i].x_offset * scale;
+        positions[(storei*2)+1] = startY + y - glyphPos[i].y_offset * scale;
+        x += glyphPos[i].x_advance * scale;
+        y += glyphPos[i].y_advance * scale;
+    }
+    int storeadv = initialCount+glyphCount;
+    // The final slot in the positions array is important
+    // because when the GlyphVector is created from this
+    // data it determines the overall advance of the glyphvector
+    // and this is used in positioning the next glyphvector
+    // during rendering where text is broken into runs.
+    // We also need to report it back into "pt", so layout can
+    // pass it back down for that next run in this code.
+    positions[(storeadv*2)] = startX + x;
+    positions[(storeadv*2)+1] = startY + y;
+    (*env)->ReleasePrimitiveArrayCritical(env, glyphArray, glyphs, 0);
+    (*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, 0);
+    putFloat(env, startPt,positions[(storeadv*2)],positions[(storeadv*2)+1] );
+    jarray inxArray =
+        (jarray)(*env)->GetObjectField(env, gvdata, gvdIndicesFID);
+    unsigned int* indices =
+        (unsigned int*)(*env)->GetPrimitiveArrayCritical(env, inxArray, NULL);
+    int prevCluster = -1;
+    for (i = 0; i < glyphCount; i++) {
+        int cluster = glyphInfo[i].cluster;
+        if (direction == HB_DIRECTION_LTR) {
+            // I need to understand what hb does when processing a substring
+            // I expected the cluster index to be from the start of the text
+            // to process.
+            // Instead it appears to be from the start of the whole thing.
+            indices[i+initialCount] = cluster;
+        } else {
+            indices[i+initialCount] = baseIndex + glyphCount -1 -i;
+        }
+    }
+    (*env)->ReleasePrimitiveArrayCritical(env, inxArray, indices, 0);
+    (*env)->SetIntField(env, gvdata, gvdCountFID, initialCount+glyphCount);
+    return initialCount+glyphCount;
+}
+
+static float euclidianDistance(float a, float b)
+{
+    float root;
+    if (a < 0) {
+        a = -a;
+    }
+
+    if (b < 0) {
+        b = -b;
+    }
+
+    if (a == 0) {
+        return b;
+    }
+
+    if (b == 0) {
+        return a;
+    }
+
+    /* Do an initial approximation, in root */
+    root = a > b ? a + (b / 2) : b + (a / 2);
+
+    /* An unrolled Newton-Raphson iteration sequence */
+    root = (root + (a * (a / root)) + (b * (b / root)) + 1) / 2;
+    root = (root + (a * (a / root)) + (b * (b / root)) + 1) / 2;
+    root = (root + (a * (a / root)) + (b * (b / root)) + 1) / 2;
+
+    return root;
+}
+
+JDKFontInfo*
+     createJDKFontInfo(JNIEnv *env,
+                       jobject font2D,
+                       jobject fontStrike,
+                       jfloat ptSize,
+                       jlong pScaler,
+                       jlong pNativeFont,
+                       jfloatArray matrix,
+                       jboolean aat) {
+
+
+    JDKFontInfo *fi = (JDKFontInfo*)malloc(sizeof(JDKFontInfo));
+    if (!fi) {
+       return NULL;
+    }
+    fi->env = env; // this is valid only for the life of this JNI call.
+    fi->font2D = font2D;
+    fi->fontStrike = fontStrike;
+    fi->nativeFont = pNativeFont;
+    fi->aat = aat;
+    (*env)->GetFloatArrayRegion(env, matrix, 0, 4, fi->matrix);
+    fi->ptSize = ptSize;
+    fi->xPtSize = euclidianDistance(fi->matrix[0], fi->matrix[1]);
+    fi->yPtSize = euclidianDistance(fi->matrix[2], fi->matrix[3]);
+
+    return fi;
+}
+
+
+#define TYPO_RTL 0x80000000
+
+JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
+    (JNIEnv *env, jclass cls,
+     jobject font2D,
+     jobject fontStrike,
+     jfloat ptSize,
+     jfloatArray matrix,
+     jlong pScaler,
+     jlong pNativeFont,
+     jboolean aat,
+     jcharArray text,
+     jobject gvdata,
+     jint script,
+     jint offset,
+     jint limit,
+     jint baseIndex,
+     jobject startPt,
+     jint flags,
+     jint slot) {
+
+     hb_buffer_t *buffer;
+     hb_font_t* hbfont;
+     jchar  *chars;
+     jsize len;
+     int glyphCount;
+     hb_glyph_info_t *glyphInfo;
+     hb_glyph_position_t *glyphPos;
+     hb_direction_t direction = HB_DIRECTION_LTR;
+     hb_feature_t *features =  NULL;
+     int featureCount = 0;
+
+     int i;
+     unsigned int buflen;
+
+     JDKFontInfo *jdkFontInfo =
+         createJDKFontInfo(env, font2D, fontStrike, ptSize,
+                           pScaler, pNativeFont, matrix, aat);
+     if (!jdkFontInfo) {
+        return JNI_FALSE;
+     }
+     jdkFontInfo->env = env; // this is valid only for the life of this JNI call.
+     jdkFontInfo->font2D = font2D;
+     jdkFontInfo->fontStrike = fontStrike;
+
+     hbfont = hb_jdk_font_create(jdkFontInfo, NULL);
+
+     buffer = hb_buffer_create();
+     hb_buffer_set_script(buffer, getHBScriptCode(script));
+     hb_buffer_set_language(buffer,
+                            hb_ot_tag_to_language(HB_OT_TAG_DEFAULT_LANGUAGE));
+     if ((flags & TYPO_RTL) != 0) {
+         direction = HB_DIRECTION_RTL;
+     }
+     hb_buffer_set_direction(buffer, direction);
+
+     chars = (*env)->GetCharArrayElements(env, text, NULL);
+     len = (*env)->GetArrayLength(env, text);
+
+     hb_buffer_add_utf16(buffer, chars, len, offset, limit-offset);
+
+     hb_shape_full(hbfont, buffer, features, featureCount, 0);
+     glyphCount = hb_buffer_get_length(buffer);
+     glyphInfo = hb_buffer_get_glyph_infos(buffer, 0);
+     glyphPos = hb_buffer_get_glyph_positions(buffer, &buflen);
+     for (i = 0; i < glyphCount; i++) {
+         int index = glyphInfo[i].codepoint;
+         int xadv = (glyphPos[i].x_advance);
+         int yadv = (glyphPos[i].y_advance);
+     }
+     // On "input" HB assigns a cluster index to each character in UTF-16.
+     // On output where a sequence of characters have been mapped to
+     // a glyph they are all mapped to the cluster index of the first character.
+     // The next cluster index will be that of the first character in the
+     // next cluster. So cluster indexes may 'skip' on output.
+     // This can also happen if there are supplementary code-points
+     // such that two UTF-16 characters are needed to make one codepoint.
+     // In RTL text you need to count down.
+     // So the following code tries to build the reverse map as expected
+     // by calling code.
+
+     storeGVData(env, gvdata, slot, baseIndex, startPt,
+                 glyphCount, glyphInfo, glyphPos, direction);
+
+     hb_buffer_destroy (buffer);
+     hb_font_destroy(hbfont);
+     free((void*)jdkFontInfo);
+     if (features != NULL) free(features);
+
+     return JNI_TRUE;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-atomic-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,164 @@
+/*
+ * Copyright © 2007  Chris Wilson
+ * Copyright © 2009,2010  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Contributor(s):
+ *      Chris Wilson <chris@chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_ATOMIC_PRIVATE_HH
+#define HB_ATOMIC_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* atomic_int */
+
+/* We need external help for these */
+
+#if defined(hb_atomic_int_impl_add) \
+ && defined(hb_atomic_ptr_impl_get) \
+ && defined(hb_atomic_ptr_impl_cmpexch)
+
+/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */
+
+
+#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
+
+#include <windows.h>
+
+/* MinGW has a convoluted history of supporting MemoryBarrier
+ * properly.  As such, define a function to wrap the whole
+ * thing. */
+static inline void _HBMemoryBarrier (void) {
+#if !defined(MemoryBarrier)
+  long dummy = 0;
+  InterlockedExchange (&dummy, 1);
+#else
+  MemoryBarrier ();
+#endif
+}
+
+typedef LONG hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V)           InterlockedExchangeAdd (&(AI), (V))
+
+#define hb_atomic_ptr_impl_get(P)               (_HBMemoryBarrier (), (void *) *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
+
+
+#elif !defined(HB_NO_MT) && defined(__APPLE__)
+
+#include <libkern/OSAtomic.h>
+#ifdef __MAC_OS_X_MIN_REQUIRED
+#include <AvailabilityMacros.h>
+#elif defined(__IPHONE_OS_MIN_REQUIRED)
+#include <Availability.h>
+#endif
+
+
+typedef int32_t hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V)           (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
+
+#define hb_atomic_ptr_impl_get(P)               (OSMemoryBarrier (), (void *) *(P))
+#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
+#else
+#if __ppc64__ || __x86_64__ || __aarch64__
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
+#else
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
+#endif
+#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)
+
+#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
+
+typedef volatile int hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
+#define hb_atomic_int_impl_add(AI, V)           (((AI) += (V)) - (V))
+
+#define hb_atomic_ptr_impl_get(P)               ((void *) *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
+
+
+#else /* HB_NO_MT */
+
+typedef int hb_atomic_int_impl_t;
+#define HB_ATOMIC_INT_IMPL_INIT(V)              (V)
+#define hb_atomic_int_impl_add(AI, V)           (((AI) += (V)) - (V))
+
+#define hb_atomic_ptr_impl_get(P)               ((void *) *(P))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)       (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
+
+
+#endif
+
+
+#define HB_ATOMIC_INT_INIT(V)           {HB_ATOMIC_INT_IMPL_INIT(V)}
+
+struct hb_atomic_int_t
+{
+  hb_atomic_int_impl_t v;
+
+  inline void set_unsafe (int v_) { v = v_; }
+  inline int get_unsafe (void) const { return v; }
+  inline int inc (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v),  1); }
+  inline int dec (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), -1); }
+};
+
+
+#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P)
+#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N))
+
+
+#endif /* HB_ATOMIC_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,479 @@
+/*
+ * Copyright © 2009  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 199309L
+#endif
+
+#include "hb-private.hh"
+
+#include "hb-object-private.hh"
+
+#ifdef HAVE_SYS_MMAN_H
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <sys/mman.h>
+#endif /* HAVE_SYS_MMAN_H */
+
+#include <stdio.h>
+#include <errno.h>
+
+
+
+#ifndef HB_DEBUG_BLOB
+#define HB_DEBUG_BLOB (HB_DEBUG+0)
+#endif
+
+
+struct hb_blob_t {
+  hb_object_header_t header;
+  ASSERT_POD ();
+
+  bool immutable;
+
+  const char *data;
+  unsigned int length;
+  hb_memory_mode_t mode;
+
+  void *user_data;
+  hb_destroy_func_t destroy;
+};
+
+
+static bool _try_writable (hb_blob_t *blob);
+
+static void
+_hb_blob_destroy_user_data (hb_blob_t *blob)
+{
+  if (blob->destroy) {
+    blob->destroy (blob->user_data);
+    blob->user_data = NULL;
+    blob->destroy = NULL;
+  }
+}
+
+/**
+ * hb_blob_create: (skip)
+ * @data: Pointer to blob data.
+ * @length: Length of @data in bytes.
+ * @mode: Memory mode for @data.
+ * @user_data: Data parameter to pass to @destroy.
+ * @destroy: Callback to call when @data is not needed anymore.
+ *
+ * Creates a new "blob" object wrapping @data.  The @mode parameter is used
+ * to negotiate ownership and lifecycle of @data.
+ *
+ * Return value: New blob, or the empty blob if something failed or if @length is
+ * zero.  Destroy with hb_blob_destroy().
+ *
+ * Since: 0.9.2
+ **/
+hb_blob_t *
+hb_blob_create (const char        *data,
+                unsigned int       length,
+                hb_memory_mode_t   mode,
+                void              *user_data,
+                hb_destroy_func_t  destroy)
+{
+  hb_blob_t *blob;
+
+  if (!length ||
+      length >= 1u << 31 ||
+      data + length < data /* overflows */ ||
+      !(blob = hb_object_create<hb_blob_t> ())) {
+    if (destroy)
+      destroy (user_data);
+    return hb_blob_get_empty ();
+  }
+
+  blob->data = data;
+  blob->length = length;
+  blob->mode = mode;
+
+  blob->user_data = user_data;
+  blob->destroy = destroy;
+
+  if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
+    blob->mode = HB_MEMORY_MODE_READONLY;
+    if (!_try_writable (blob)) {
+      hb_blob_destroy (blob);
+      return hb_blob_get_empty ();
+    }
+  }
+
+  return blob;
+}
+
+/**
+ * hb_blob_create_sub_blob:
+ * @parent: Parent blob.
+ * @offset: Start offset of sub-blob within @parent, in bytes.
+ * @length: Length of sub-blob.
+ *
+ * Returns a blob that represents a range of bytes in @parent.  The new
+ * blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it
+ * will never modify data in the parent blob.  The parent data is not
+ * expected to be modified, and will result in undefined behavior if it
+ * is.
+ *
+ * Makes @parent immutable.
+ *
+ * Return value: New blob, or the empty blob if something failed or if
+ * @length is zero or @offset is beyond the end of @parent's data.  Destroy
+ * with hb_blob_destroy().
+ *
+ * Since: 0.9.2
+ **/
+hb_blob_t *
+hb_blob_create_sub_blob (hb_blob_t    *parent,
+                         unsigned int  offset,
+                         unsigned int  length)
+{
+  hb_blob_t *blob;
+
+  if (!length || offset >= parent->length)
+    return hb_blob_get_empty ();
+
+  hb_blob_make_immutable (parent);
+
+  blob = hb_blob_create (parent->data + offset,
+                         MIN (length, parent->length - offset),
+                         HB_MEMORY_MODE_READONLY,
+                         hb_blob_reference (parent),
+                         (hb_destroy_func_t) hb_blob_destroy);
+
+  return blob;
+}
+
+/**
+ * hb_blob_get_empty:
+ *
+ * Returns the singleton empty blob.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Return value: (transfer full): the empty blob.
+ *
+ * Since: 0.9.2
+ **/
+hb_blob_t *
+hb_blob_get_empty (void)
+{
+  static const hb_blob_t _hb_blob_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    true, /* immutable */
+
+    NULL, /* data */
+    0, /* length */
+    HB_MEMORY_MODE_READONLY, /* mode */
+
+    NULL, /* user_data */
+    NULL  /* destroy */
+  };
+
+  return const_cast<hb_blob_t *> (&_hb_blob_nil);
+}
+
+/**
+ * hb_blob_reference: (skip)
+ * @blob: a blob.
+ *
+ * Increases the reference count on @blob.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Return value: @blob.
+ *
+ * Since: 0.9.2
+ **/
+hb_blob_t *
+hb_blob_reference (hb_blob_t *blob)
+{
+  return hb_object_reference (blob);
+}
+
+/**
+ * hb_blob_destroy: (skip)
+ * @blob: a blob.
+ *
+ * Descreases 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.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_blob_destroy (hb_blob_t *blob)
+{
+  if (!hb_object_destroy (blob)) return;
+
+  _hb_blob_destroy_user_data (blob);
+
+  free (blob);
+}
+
+/**
+ * hb_blob_set_user_data: (skip)
+ * @blob: a blob.
+ * @key: key for data to set.
+ * @data: data to set.
+ * @destroy: callback to call when @data is not needed anymore.
+ * @replace: whether to replace an existing data with the same key.
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_blob_set_user_data (hb_blob_t          *blob,
+                       hb_user_data_key_t *key,
+                       void *              data,
+                       hb_destroy_func_t   destroy,
+                       hb_bool_t           replace)
+{
+  return hb_object_set_user_data (blob, key, data, destroy, replace);
+}
+
+/**
+ * hb_blob_get_user_data: (skip)
+ * @blob: a blob.
+ * @key: key for data to get.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+void *
+hb_blob_get_user_data (hb_blob_t          *blob,
+                       hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (blob, key);
+}
+
+
+/**
+ * hb_blob_make_immutable:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_blob_make_immutable (hb_blob_t *blob)
+{
+  if (hb_object_is_inert (blob))
+    return;
+
+  blob->immutable = true;
+}
+
+/**
+ * hb_blob_is_immutable:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Return value: TODO
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_blob_is_immutable (hb_blob_t *blob)
+{
+  return blob->immutable;
+}
+
+
+/**
+ * hb_blob_get_length:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Return value: the length of blob data in bytes.
+ *
+ * Since: 0.9.2
+ **/
+unsigned int
+hb_blob_get_length (hb_blob_t *blob)
+{
+  return blob->length;
+}
+
+/**
+ * hb_blob_get_data:
+ * @blob: a blob.
+ * @length: (out):
+ *
+ *
+ *
+ * Returns: (transfer none) (array length=length):
+ *
+ * Since: 0.9.2
+ **/
+const char *
+hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
+{
+  if (length)
+    *length = blob->length;
+
+  return blob->data;
+}
+
+/**
+ * hb_blob_get_data_writable:
+ * @blob: a blob.
+ * @length: (out): output length of the writable data.
+ *
+ * Tries to make blob data writable (possibly copying it) and
+ * return pointer to data.
+ *
+ * Fails if blob has been made immutable, or if memory allocation
+ * fails.
+ *
+ * Returns: (transfer none) (array length=length): Writable blob data,
+ * or %NULL if failed.
+ *
+ * Since: 0.9.2
+ **/
+char *
+hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
+{
+  if (!_try_writable (blob)) {
+    if (length)
+      *length = 0;
+
+    return NULL;
+  }
+
+  if (length)
+    *length = blob->length;
+
+  return const_cast<char *> (blob->data);
+}
+
+
+static hb_bool_t
+_try_make_writable_inplace_unix (hb_blob_t *blob)
+{
+#if defined(HAVE_SYS_MMAN_H) && defined(HAVE_MPROTECT)
+  uintptr_t pagesize = -1, mask, length;
+  const char *addr;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
+  pagesize = (uintptr_t) sysconf (_SC_PAGE_SIZE);
+#elif defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+  pagesize = (uintptr_t) sysconf (_SC_PAGESIZE);
+#elif defined(HAVE_GETPAGESIZE)
+  pagesize = (uintptr_t) getpagesize ();
+#endif
+
+  if ((uintptr_t) -1L == pagesize) {
+    DEBUG_MSG_FUNC (BLOB, blob, "failed to get pagesize: %s", strerror (errno));
+    return false;
+  }
+  DEBUG_MSG_FUNC (BLOB, blob, "pagesize is %lu", (unsigned long) pagesize);
+
+  mask = ~(pagesize-1);
+  addr = (const char *) (((uintptr_t) blob->data) & mask);
+  length = (const char *) (((uintptr_t) blob->data + blob->length + pagesize-1) & mask)  - addr;
+  DEBUG_MSG_FUNC (BLOB, blob,
+                  "calling mprotect on [%p..%p] (%lu bytes)",
+                  addr, addr+length, (unsigned long) length);
+  if (-1 == mprotect ((void *) addr, length, PROT_READ | PROT_WRITE)) {
+    DEBUG_MSG_FUNC (BLOB, blob, "mprotect failed: %s", strerror (errno));
+    return false;
+  }
+
+  blob->mode = HB_MEMORY_MODE_WRITABLE;
+
+  DEBUG_MSG_FUNC (BLOB, blob,
+                  "successfully made [%p..%p] (%lu bytes) writable\n",
+                  addr, addr+length, (unsigned long) length);
+  return true;
+#else
+  return false;
+#endif
+}
+
+static bool
+_try_writable_inplace (hb_blob_t *blob)
+{
+  DEBUG_MSG_FUNC (BLOB, blob, "making writable inplace\n");
+
+  if (_try_make_writable_inplace_unix (blob))
+    return true;
+
+  DEBUG_MSG_FUNC (BLOB, blob, "making writable -> FAILED\n");
+
+  /* Failed to make writable inplace, mark that */
+  blob->mode = HB_MEMORY_MODE_READONLY;
+  return false;
+}
+
+static bool
+_try_writable (hb_blob_t *blob)
+{
+  if (blob->immutable)
+    return false;
+
+  if (blob->mode == HB_MEMORY_MODE_WRITABLE)
+    return true;
+
+  if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE && _try_writable_inplace (blob))
+    return true;
+
+  if (blob->mode == HB_MEMORY_MODE_WRITABLE)
+    return true;
+
+
+  DEBUG_MSG_FUNC (BLOB, blob, "current data is -> %p\n", blob->data);
+
+  char *new_data;
+
+  new_data = (char *) malloc (blob->length);
+  if (unlikely (!new_data))
+    return false;
+
+  DEBUG_MSG_FUNC (BLOB, blob, "dupped successfully -> %p\n", blob->data);
+
+  memcpy (new_data, blob->data, blob->length);
+  _hb_blob_destroy_user_data (blob);
+  blob->mode = HB_MEMORY_MODE_WRITABLE;
+  blob->data = new_data;
+  blob->user_data = new_data;
+  blob->destroy = free;
+
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2009  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_BLOB_H
+#define HB_BLOB_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * Note re various memory-modes:
+ *
+ * - In no case shall the HarfBuzz client modify memory
+ *   that is passed to HarfBuzz in a blob.  If there is
+ *   any such possibility, MODE_DUPLICATE should be used
+ *   such that HarfBuzz makes a copy immediately,
+ *
+ * - Use MODE_READONLY otherse, unless you really really
+ *   really know what you are doing,
+ *
+ * - MODE_WRITABLE is appropriate if you really made a
+ *   copy of data solely for the purpose of passing to
+ *   HarfBuzz and doing that just once (no reuse!),
+ *
+ * - If the font is mmap()ed, it's ok to use
+ *   READONLY_MAY_MAKE_WRITABLE, however, using that mode
+ *   correctly is very tricky.  Use MODE_READONLY instead.
+ */
+typedef enum {
+  HB_MEMORY_MODE_DUPLICATE,
+  HB_MEMORY_MODE_READONLY,
+  HB_MEMORY_MODE_WRITABLE,
+  HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
+} hb_memory_mode_t;
+
+typedef struct hb_blob_t hb_blob_t;
+
+hb_blob_t *
+hb_blob_create (const char        *data,
+                unsigned int       length,
+                hb_memory_mode_t   mode,
+                void              *user_data,
+                hb_destroy_func_t  destroy);
+
+/* Always creates with MEMORY_MODE_READONLY.
+ * Even if the parent blob is writable, we don't
+ * want the user of the sub-blob to be able to
+ * modify the parent data as that data may be
+ * shared among multiple sub-blobs.
+ */
+hb_blob_t *
+hb_blob_create_sub_blob (hb_blob_t    *parent,
+                         unsigned int  offset,
+                         unsigned int  length);
+
+hb_blob_t *
+hb_blob_get_empty (void);
+
+hb_blob_t *
+hb_blob_reference (hb_blob_t *blob);
+
+void
+hb_blob_destroy (hb_blob_t *blob);
+
+hb_bool_t
+hb_blob_set_user_data (hb_blob_t          *blob,
+                       hb_user_data_key_t *key,
+                       void *              data,
+                       hb_destroy_func_t   destroy,
+                       hb_bool_t           replace);
+
+
+void *
+hb_blob_get_user_data (hb_blob_t          *blob,
+                       hb_user_data_key_t *key);
+
+
+void
+hb_blob_make_immutable (hb_blob_t *blob);
+
+hb_bool_t
+hb_blob_is_immutable (hb_blob_t *blob);
+
+
+unsigned int
+hb_blob_get_length (hb_blob_t *blob);
+
+const char *
+hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
+
+char *
+hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
+
+
+HB_END_DECLS
+
+#endif /* HB_BLOB_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-deserialize-json.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,643 @@
+
+#line 1 "hb-buffer-deserialize-json.rl"
+/*
+ * Copyright © 2013  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_BUFFER_DESERIALIZE_JSON_HH
+#define HB_BUFFER_DESERIALIZE_JSON_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-buffer-deserialize-json.hh"
+static const unsigned char _deserialize_json_trans_keys[] = {
+        0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
+        48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
+        9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u,
+        120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u,
+        9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
+        65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0
+};
+
+static const char _deserialize_json_key_spans[] = {
+        0, 115, 26, 7, 2, 1, 50, 49,
+        10, 117, 117, 117, 1, 50, 49, 10,
+        117, 117, 1, 1, 50, 49, 117, 117,
+        2, 1, 50, 49, 10, 117, 117, 1,
+        50, 49, 10, 117, 117, 1, 50, 49,
+        58, 89, 117, 117, 85, 115, 0
+};
+
+static const short _deserialize_json_index_offsets[] = {
+        0, 0, 116, 143, 151, 154, 156, 207,
+        257, 268, 386, 504, 622, 624, 675, 725,
+        736, 854, 972, 974, 976, 1027, 1077, 1195,
+        1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666,
+        1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069,
+        2119, 2178, 2268, 2386, 2504, 2590, 2706
+};
+
+static const char _deserialize_json_indicies[] = {
+        0, 0, 0, 0, 0, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        0, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 2, 1, 3, 3, 3,
+        3, 3, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 3, 1, 4, 1,
+        5, 1, 6, 7, 1, 1, 8, 1,
+        9, 10, 1, 11, 1, 11, 11, 11,
+        11, 11, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 11, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 12, 1,
+        12, 12, 12, 12, 12, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 12,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 13, 1, 1, 14,
+        15, 15, 15, 15, 15, 15, 15, 15,
+        15, 1, 16, 17, 17, 17, 17, 17,
+        17, 17, 17, 17, 1, 18, 18, 18,
+        18, 18, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 18, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        19, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 20, 1, 21, 21, 21, 21, 21,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 21, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 3, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 22,
+        1, 18, 18, 18, 18, 18, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        18, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 19, 1, 1, 1,
+        17, 17, 17, 17, 17, 17, 17, 17,
+        17, 17, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 20, 1, 23,
+        1, 23, 23, 23, 23, 23, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        23, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 24, 1, 24, 24, 24, 24,
+        24, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 24, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        25, 1, 1, 26, 27, 27, 27, 27,
+        27, 27, 27, 27, 27, 1, 28, 29,
+        29, 29, 29, 29, 29, 29, 29, 29,
+        1, 30, 30, 30, 30, 30, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        30, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 31, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 32, 1, 30,
+        30, 30, 30, 30, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 30, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 31, 1, 1, 1, 29, 29,
+        29, 29, 29, 29, 29, 29, 29, 29,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 32, 1, 33, 1, 34,
+        1, 34, 34, 34, 34, 34, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        34, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 35, 1, 35, 35, 35, 35,
+        35, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 35, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 36, 37, 37, 37, 37,
+        37, 37, 37, 37, 37, 1, 38, 38,
+        38, 38, 38, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 38, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 39, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 40, 1, 38, 38, 38, 38,
+        38, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 38, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 39,
+        1, 1, 1, 41, 41, 41, 41, 41,
+        41, 41, 41, 41, 41, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        40, 1, 42, 43, 1, 44, 1, 44,
+        44, 44, 44, 44, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 44, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        45, 1, 45, 45, 45, 45, 45, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 45, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 46, 1,
+        1, 47, 48, 48, 48, 48, 48, 48,
+        48, 48, 48, 1, 49, 50, 50, 50,
+        50, 50, 50, 50, 50, 50, 1, 51,
+        51, 51, 51, 51, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 51, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 52, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 53, 1, 51, 51, 51,
+        51, 51, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 51, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        52, 1, 1, 1, 50, 50, 50, 50,
+        50, 50, 50, 50, 50, 50, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 53, 1, 54, 1, 54, 54, 54,
+        54, 54, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 54, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 55, 1,
+        55, 55, 55, 55, 55, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 55,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 56, 1, 1, 57,
+        58, 58, 58, 58, 58, 58, 58, 58,
+        58, 1, 59, 60, 60, 60, 60, 60,
+        60, 60, 60, 60, 1, 61, 61, 61,
+        61, 61, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 61, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        62, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 63, 1, 61, 61, 61, 61, 61,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 61, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 62, 1,
+        1, 1, 60, 60, 60, 60, 60, 60,
+        60, 60, 60, 60, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 63,
+        1, 64, 1, 64, 64, 64, 64, 64,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 64, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 65, 1, 65, 65,
+        65, 65, 65, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 65, 1, 66,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 67, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 1,
+        69, 69, 69, 69, 69, 69, 69, 69,
+        69, 69, 69, 69, 69, 69, 69, 69,
+        69, 69, 69, 69, 69, 69, 69, 69,
+        69, 69, 1, 1, 1, 1, 1, 1,
+        69, 69, 69, 69, 69, 69, 69, 69,
+        69, 69, 69, 69, 69, 69, 69, 69,
+        69, 69, 69, 69, 69, 69, 69, 69,
+        69, 69, 1, 70, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 71, 71,
+        1, 71, 71, 71, 71, 71, 71, 71,
+        71, 71, 71, 1, 1, 1, 1, 1,
+        1, 1, 71, 71, 71, 71, 71, 71,
+        71, 71, 71, 71, 71, 71, 71, 71,
+        71, 71, 71, 71, 71, 71, 71, 71,
+        71, 71, 71, 71, 1, 1, 1, 1,
+        71, 1, 71, 71, 71, 71, 71, 71,
+        71, 71, 71, 71, 71, 71, 71, 71,
+        71, 71, 71, 71, 71, 71, 71, 71,
+        71, 71, 71, 71, 1, 72, 72, 72,
+        72, 72, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 72, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        73, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 74, 1, 72, 72, 72, 72, 72,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 72, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 73, 1,
+        1, 1, 75, 75, 75, 75, 75, 75,
+        75, 75, 75, 75, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 74,
+        1, 76, 76, 76, 76, 76, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        76, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 77, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 78, 1, 0,
+        0, 0, 0, 0, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 0, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 2, 1, 1, 0
+};
+
+static const char _deserialize_json_trans_targs[] = {
+        1, 0, 2, 2, 3, 4, 18, 24,
+        37, 5, 12, 6, 7, 8, 9, 11,
+        9, 11, 10, 2, 44, 10, 44, 13,
+        14, 15, 16, 17, 16, 17, 10, 2,
+        44, 19, 20, 21, 22, 23, 10, 2,
+        44, 23, 25, 31, 26, 27, 28, 29,
+        30, 29, 30, 10, 2, 44, 32, 33,
+        34, 35, 36, 35, 36, 10, 2, 44,
+        38, 39, 40, 42, 43, 41, 10, 41,
+        10, 2, 44, 43, 44, 45, 46
+};
+
+static const char _deserialize_json_trans_actions[] = {
+        0, 0, 1, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 2, 2, 2,
+        0, 0, 3, 3, 4, 0, 5, 0,
+        0, 2, 2, 2, 0, 0, 6, 6,
+        7, 0, 0, 0, 2, 2, 8, 8,
+        9, 0, 0, 0, 0, 0, 2, 2,
+        2, 0, 0, 10, 10, 11, 0, 0,
+        2, 2, 2, 0, 0, 12, 12, 13,
+        0, 0, 0, 2, 2, 2, 14, 0,
+        15, 15, 16, 0, 0, 0, 0
+};
+
+static const int deserialize_json_start = 1;
+static const int deserialize_json_first_final = 44;
+static const int deserialize_json_error = 0;
+
+static const int deserialize_json_en_main = 1;
+
+
+#line 97 "hb-buffer-deserialize-json.rl"
+
+
+static hb_bool_t
+_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
+                                    const char *buf,
+                                    unsigned int buf_len,
+                                    const char **end_ptr,
+                                    hb_font_t *font)
+{
+  const char *p = buf, *pe = buf + buf_len;
+
+  /* Ensure we have positions. */
+  (void) hb_buffer_get_glyph_positions (buffer, NULL);
+
+  while (p < pe && ISSPACE (*p))
+    p++;
+  if (p < pe && *p == (buffer->len ? ',' : '['))
+  {
+    *end_ptr = ++p;
+  }
+
+  const char *tok = NULL;
+  int cs;
+  hb_glyph_info_t info = {0};
+  hb_glyph_position_t pos = {0};
+
+#line 466 "hb-buffer-deserialize-json.hh"
+        {
+        cs = deserialize_json_start;
+        }
+
+#line 471 "hb-buffer-deserialize-json.hh"
+        {
+        int _slen;
+        int _trans;
+        const unsigned char *_keys;
+        const char *_inds;
+        if ( p == pe )
+                goto _test_eof;
+        if ( cs == 0 )
+                goto _out;
+_resume:
+        _keys = _deserialize_json_trans_keys + (cs<<1);
+        _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs];
+
+        _slen = _deserialize_json_key_spans[cs];
+        _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
+                (*p) <= _keys[1] ?
+                (*p) - _keys[0] : _slen ];
+
+        cs = _deserialize_json_trans_targs[_trans];
+
+        if ( _deserialize_json_trans_actions[_trans] == 0 )
+                goto _again;
+
+        switch ( _deserialize_json_trans_actions[_trans] ) {
+        case 1:
+#line 38 "hb-buffer-deserialize-json.rl"
+        {
+        memset (&info, 0, sizeof (info));
+        memset (&pos , 0, sizeof (pos ));
+}
+        break;
+        case 5:
+#line 43 "hb-buffer-deserialize-json.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 2:
+#line 51 "hb-buffer-deserialize-json.rl"
+        {
+        tok = p;
+}
+        break;
+        case 14:
+#line 55 "hb-buffer-deserialize-json.rl"
+        {
+        if (!hb_font_glyph_from_string (font,
+                                        tok, p - tok,
+                                        &info.codepoint))
+          return false;
+}
+        break;
+        case 15:
+#line 62 "hb-buffer-deserialize-json.rl"
+        { if (!parse_uint (tok, p, &info.codepoint)) return false; }
+        break;
+        case 8:
+#line 63 "hb-buffer-deserialize-json.rl"
+        { if (!parse_uint (tok, p, &info.cluster )) return false; }
+        break;
+        case 10:
+#line 64 "hb-buffer-deserialize-json.rl"
+        { if (!parse_int  (tok, p, &pos.x_offset )) return false; }
+        break;
+        case 12:
+#line 65 "hb-buffer-deserialize-json.rl"
+        { if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+        break;
+        case 3:
+#line 66 "hb-buffer-deserialize-json.rl"
+        { if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+        break;
+        case 6:
+#line 67 "hb-buffer-deserialize-json.rl"
+        { if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+        break;
+        case 16:
+#line 62 "hb-buffer-deserialize-json.rl"
+        { if (!parse_uint (tok, p, &info.codepoint)) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 9:
+#line 63 "hb-buffer-deserialize-json.rl"
+        { if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 11:
+#line 64 "hb-buffer-deserialize-json.rl"
+        { if (!parse_int  (tok, p, &pos.x_offset )) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 13:
+#line 65 "hb-buffer-deserialize-json.rl"
+        { if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 4:
+#line 66 "hb-buffer-deserialize-json.rl"
+        { if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 7:
+#line 67 "hb-buffer-deserialize-json.rl"
+        { if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-json.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+#line 624 "hb-buffer-deserialize-json.hh"
+        }
+
+_again:
+        if ( cs == 0 )
+                goto _out;
+        if ( ++p != pe )
+                goto _resume;
+        _test_eof: {}
+        _out: {}
+        }
+
+#line 125 "hb-buffer-deserialize-json.rl"
+
+
+  *end_ptr = p;
+
+  return p == pe && *(p-1) != ']';
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-deserialize-text.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,571 @@
+
+#line 1 "hb-buffer-deserialize-text.rl"
+/*
+ * Copyright © 2013  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_BUFFER_DESERIALIZE_TEXT_HH
+#define HB_BUFFER_DESERIALIZE_TEXT_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-buffer-deserialize-text.hh"
+static const unsigned char _deserialize_text_trans_keys[] = {
+        0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
+        48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
+        9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u,
+        9u, 124u, 9u, 124u, 9u, 124u, 0
+};
+
+static const char _deserialize_text_key_spans[] = {
+        0, 114, 13, 10, 13, 10, 10, 13,
+        10, 1, 13, 10, 14, 116, 116, 0,
+        114, 116, 116, 116, 116, 116, 116, 116,
+        116, 116, 116
+};
+
+static const short _deserialize_text_index_offsets[] = {
+        0, 0, 115, 129, 140, 154, 165, 176,
+        190, 201, 203, 217, 228, 243, 360, 477,
+        478, 593, 710, 827, 944, 1061, 1178, 1295,
+        1412, 1529, 1646
+};
+
+static const char _deserialize_text_indicies[] = {
+        0, 0, 0, 0, 0, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        0, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        2, 3, 3, 3, 3, 3, 3, 3,
+        3, 3, 1, 1, 1, 1, 1, 1,
+        1, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 1, 1, 1, 1, 1,
+        1, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 1, 5, 1, 1, 6,
+        7, 7, 7, 7, 7, 7, 7, 7,
+        7, 1, 8, 9, 9, 9, 9, 9,
+        9, 9, 9, 9, 1, 10, 1, 1,
+        11, 12, 12, 12, 12, 12, 12, 12,
+        12, 12, 1, 13, 14, 14, 14, 14,
+        14, 14, 14, 14, 14, 1, 15, 16,
+        16, 16, 16, 16, 16, 16, 16, 16,
+        1, 17, 1, 1, 18, 19, 19, 19,
+        19, 19, 19, 19, 19, 19, 1, 20,
+        21, 21, 21, 21, 21, 21, 21, 21,
+        21, 1, 22, 1, 23, 1, 1, 24,
+        25, 25, 25, 25, 25, 25, 25, 25,
+        25, 1, 26, 27, 27, 27, 27, 27,
+        27, 27, 27, 27, 1, 22, 1, 1,
+        1, 21, 21, 21, 21, 21, 21, 21,
+        21, 21, 21, 1, 28, 28, 28, 28,
+        28, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 28, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 29, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        30, 1, 1, 31, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        32, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 33,
+        1, 34, 34, 34, 34, 34, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        34, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 35, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 36, 1, 1, 0,
+        0, 0, 0, 0, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 0, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 2, 3,
+        3, 3, 3, 3, 3, 3, 3, 3,
+        1, 1, 1, 1, 1, 1, 1, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 1, 1, 1, 1, 1, 1, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 4, 4, 4, 4, 4, 4, 4,
+        4, 1, 28, 28, 28, 28, 28, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 28, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 29, 1, 1, 1,
+        1, 37, 37, 37, 37, 37, 37, 37,
+        37, 37, 37, 1, 1, 1, 30, 1,
+        1, 31, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 32, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 33, 1, 38,
+        38, 38, 38, 38, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 38, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 39, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 40, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 41, 1, 42, 42, 42, 42,
+        42, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 42, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        43, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 44,
+        1, 42, 42, 42, 42, 42, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        42, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        14, 14, 14, 14, 14, 14, 14, 14,
+        14, 14, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 43, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 44, 1, 38, 38,
+        38, 38, 38, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 38, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 39, 1, 1, 1, 9, 9, 9,
+        9, 9, 9, 9, 9, 9, 9, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 40, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 41, 1, 45, 45, 45, 45, 45,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 45, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 46, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 47, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 48,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 49, 1,
+        50, 50, 50, 50, 50, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 50,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 51, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 52, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 53, 1, 50, 50, 50,
+        50, 50, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 50, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 51,
+        1, 1, 1, 1, 27, 27, 27, 27,
+        27, 27, 27, 27, 27, 27, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 52, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        53, 1, 45, 45, 45, 45, 45, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 45, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 46, 1, 1, 1,
+        1, 54, 54, 54, 54, 54, 54, 54,
+        54, 54, 54, 1, 1, 1, 1, 1,
+        1, 47, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 48, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 49, 1, 28,
+        28, 28, 28, 28, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 28, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 29, 1, 55, 55, 1, 55, 55,
+        55, 55, 55, 55, 55, 55, 55, 55,
+        1, 1, 1, 30, 1, 1, 31, 55,
+        55, 55, 55, 55, 55, 55, 55, 55,
+        55, 55, 55, 55, 55, 55, 55, 55,
+        55, 55, 55, 55, 55, 55, 55, 55,
+        55, 1, 1, 32, 1, 55, 1, 55,
+        55, 55, 55, 55, 55, 55, 55, 55,
+        55, 55, 55, 55, 55, 55, 55, 55,
+        55, 55, 55, 55, 55, 55, 55, 55,
+        55, 1, 33, 1, 0
+};
+
+static const char _deserialize_text_trans_targs[] = {
+        1, 0, 13, 17, 26, 3, 18, 21,
+        18, 21, 5, 19, 20, 19, 20, 22,
+        25, 8, 9, 12, 9, 12, 10, 11,
+        23, 24, 23, 24, 14, 2, 6, 7,
+        15, 16, 14, 15, 16, 17, 14, 4,
+        15, 16, 14, 15, 16, 14, 2, 7,
+        15, 16, 14, 2, 15, 16, 25, 26
+};
+
+static const char _deserialize_text_trans_actions[] = {
+        0, 0, 1, 1, 1, 2, 2, 2,
+        0, 0, 2, 2, 2, 0, 0, 2,
+        2, 2, 2, 2, 0, 0, 3, 2,
+        2, 2, 0, 0, 4, 5, 5, 5,
+        4, 4, 0, 0, 0, 0, 6, 7,
+        6, 6, 8, 8, 8, 9, 10, 10,
+        9, 9, 11, 12, 11, 11, 0, 0
+};
+
+static const char _deserialize_text_eof_actions[] = {
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 4, 0, 0,
+        0, 4, 6, 8, 8, 6, 9, 11,
+        11, 9, 4
+};
+
+static const int deserialize_text_start = 1;
+static const int deserialize_text_first_final = 13;
+static const int deserialize_text_error = 0;
+
+static const int deserialize_text_en_main = 1;
+
+
+#line 91 "hb-buffer-deserialize-text.rl"
+
+
+static hb_bool_t
+_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
+                                    const char *buf,
+                                    unsigned int buf_len,
+                                    const char **end_ptr,
+                                    hb_font_t *font)
+{
+  const char *p = buf, *pe = buf + buf_len;
+
+  /* Ensure we have positions. */
+  (void) hb_buffer_get_glyph_positions (buffer, NULL);
+
+  while (p < pe && ISSPACE (*p))
+    p++;
+  if (p < pe && *p == (buffer->len ? '|' : '['))
+  {
+    *end_ptr = ++p;
+  }
+
+  const char *eof = pe, *tok = NULL;
+  int cs;
+  hb_glyph_info_t info = {0};
+  hb_glyph_position_t pos = {0};
+
+#line 343 "hb-buffer-deserialize-text.hh"
+        {
+        cs = deserialize_text_start;
+        }
+
+#line 348 "hb-buffer-deserialize-text.hh"
+        {
+        int _slen;
+        int _trans;
+        const unsigned char *_keys;
+        const char *_inds;
+        if ( p == pe )
+                goto _test_eof;
+        if ( cs == 0 )
+                goto _out;
+_resume:
+        _keys = _deserialize_text_trans_keys + (cs<<1);
+        _inds = _deserialize_text_indicies + _deserialize_text_index_offsets[cs];
+
+        _slen = _deserialize_text_key_spans[cs];
+        _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
+                (*p) <= _keys[1] ?
+                (*p) - _keys[0] : _slen ];
+
+        cs = _deserialize_text_trans_targs[_trans];
+
+        if ( _deserialize_text_trans_actions[_trans] == 0 )
+                goto _again;
+
+        switch ( _deserialize_text_trans_actions[_trans] ) {
+        case 2:
+#line 51 "hb-buffer-deserialize-text.rl"
+        {
+        tok = p;
+}
+        break;
+        case 5:
+#line 55 "hb-buffer-deserialize-text.rl"
+        {
+        if (!hb_font_glyph_from_string (font,
+                                        tok, p - tok,
+                                        &info.codepoint))
+          return false;
+}
+        break;
+        case 10:
+#line 62 "hb-buffer-deserialize-text.rl"
+        { if (!parse_uint (tok, p, &info.cluster )) return false; }
+        break;
+        case 3:
+#line 63 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.x_offset )) return false; }
+        break;
+        case 12:
+#line 64 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+        break;
+        case 7:
+#line 65 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+        break;
+        case 1:
+#line 38 "hb-buffer-deserialize-text.rl"
+        {
+        memset (&info, 0, sizeof (info));
+        memset (&pos , 0, sizeof (pos ));
+}
+#line 51 "hb-buffer-deserialize-text.rl"
+        {
+        tok = p;
+}
+        break;
+        case 4:
+#line 55 "hb-buffer-deserialize-text.rl"
+        {
+        if (!hb_font_glyph_from_string (font,
+                                        tok, p - tok,
+                                        &info.codepoint))
+          return false;
+}
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 9:
+#line 62 "hb-buffer-deserialize-text.rl"
+        { if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 11:
+#line 64 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 6:
+#line 65 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 8:
+#line 66 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+#line 480 "hb-buffer-deserialize-text.hh"
+        }
+
+_again:
+        if ( cs == 0 )
+                goto _out;
+        if ( ++p != pe )
+                goto _resume;
+        _test_eof: {}
+        if ( p == eof )
+        {
+        switch ( _deserialize_text_eof_actions[cs] ) {
+        case 4:
+#line 55 "hb-buffer-deserialize-text.rl"
+        {
+        if (!hb_font_glyph_from_string (font,
+                                        tok, p - tok,
+                                        &info.codepoint))
+          return false;
+}
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 9:
+#line 62 "hb-buffer-deserialize-text.rl"
+        { if (!parse_uint (tok, p, &info.cluster )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 11:
+#line 64 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 6:
+#line 65 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+        case 8:
+#line 66 "hb-buffer-deserialize-text.rl"
+        { if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+#line 43 "hb-buffer-deserialize-text.rl"
+        {
+        buffer->add_info (info);
+        if (buffer->in_error)
+          return false;
+        buffer->pos[buffer->len - 1] = pos;
+        *end_ptr = p;
+}
+        break;
+#line 557 "hb-buffer-deserialize-text.hh"
+        }
+        }
+
+        _out: {}
+        }
+
+#line 119 "hb-buffer-deserialize-text.rl"
+
+
+  *end_ptr = p;
+
+  return p == pe && *(p-1) != ']';
+}
+
+#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,220 @@
+/*
+ * Copyright © 1998-2004  David Turner and Werner Lemberg
+ * Copyright © 2004,2007,2009,2010  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_BUFFER_PRIVATE_HH
+#define HB_BUFFER_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-object-private.hh"
+#include "hb-unicode-private.hh"
+
+
+ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
+ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
+
+
+/*
+ * hb_buffer_t
+ */
+
+struct hb_buffer_t {
+  hb_object_header_t header;
+  ASSERT_POD ();
+
+  /* Information about how the text in the buffer should be treated */
+  hb_unicode_funcs_t *unicode; /* Unicode functions */
+  hb_buffer_flags_t flags; /* BOT / EOT / etc. */
+  hb_buffer_cluster_level_t cluster_level;
+  hb_codepoint_t replacement; /* U+FFFD or something else. */
+
+  /* Buffer contents */
+  hb_buffer_content_type_t content_type;
+  hb_segment_properties_t props; /* Script, language, direction */
+
+  bool in_error; /* Allocation failed */
+  bool have_output; /* Whether we have an output buffer going on */
+  bool have_positions; /* Whether we have positions */
+
+  unsigned int idx; /* Cursor into ->info and ->pos arrays */
+  unsigned int len; /* Length of ->info and ->pos arrays */
+  unsigned int out_len; /* Length of ->out array if have_output */
+
+  unsigned int allocated; /* Length of allocated arrays */
+  hb_glyph_info_t     *info;
+  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 - 1]; }
+  inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; }
+
+  inline bool has_separate_output (void) const { return info != out_info; }
+
+  unsigned int serial;
+
+  /* These reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
+  uint8_t allocated_var_bytes[8];
+  const char *allocated_var_owner[8];
+
+  /* Text before / after the main buffer contents.
+   * Always in Unicode, and ordered outward.
+   * Index 0 is for "pre-context", 1 for "post-context". */
+  static const unsigned int CONTEXT_LENGTH = 5;
+  hb_codepoint_t context[2][CONTEXT_LENGTH];
+  unsigned int context_len[2];
+
+
+  /* Methods */
+
+  HB_INTERNAL void reset (void);
+  HB_INTERNAL void clear (void);
+
+  inline unsigned int backtrack_len (void) const
+  { return have_output? out_len : idx; }
+  inline unsigned int lookahead_len (void) const
+  { return len - idx; }
+  inline unsigned int next_serial (void) { return serial++; }
+
+  HB_INTERNAL void allocate_var (unsigned int byte_i, unsigned int count, const char *owner);
+  HB_INTERNAL void deallocate_var (unsigned int byte_i, unsigned int count, const char *owner);
+  HB_INTERNAL void assert_var (unsigned int byte_i, unsigned int count, const char *owner);
+  HB_INTERNAL void deallocate_var_all (void);
+
+  HB_INTERNAL void add (hb_codepoint_t  codepoint,
+                        unsigned int    cluster);
+  HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
+
+  HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
+  HB_INTERNAL void reverse (void);
+  HB_INTERNAL void reverse_clusters (void);
+  HB_INTERNAL void guess_segment_properties (void);
+
+  HB_INTERNAL void swap_buffers (void);
+  HB_INTERNAL void remove_output (void);
+  HB_INTERNAL void clear_output (void);
+  HB_INTERNAL void clear_positions (void);
+
+  HB_INTERNAL void replace_glyphs (unsigned int num_in,
+                                   unsigned int num_out,
+                                   const hb_codepoint_t *glyph_data);
+
+  HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
+  /* Makes a copy of the glyph at idx to output and replace glyph_index */
+  HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
+  HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
+  /* Copies glyph at idx to output but doesn't advance idx */
+  HB_INTERNAL void copy_glyph (void);
+  HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
+  /* Copies glyph at idx to output and advance idx.
+   * If there's no output, just advance idx. */
+  inline void
+  next_glyph (void)
+  {
+    if (have_output)
+    {
+      if (unlikely (out_info != info || out_len != idx)) {
+        if (unlikely (!make_room_for (1, 1))) return;
+        out_info[out_len] = info[idx];
+      }
+      out_len++;
+    }
+
+    idx++;
+  }
+
+  /* Advance idx without copying to output. */
+  inline void skip_glyph (void) { idx++; }
+
+  inline void reset_masks (hb_mask_t mask)
+  {
+    for (unsigned int j = 0; j < len; j++)
+      info[j].mask = mask;
+  }
+  inline void add_masks (hb_mask_t mask)
+  {
+    for (unsigned int j = 0; j < len; j++)
+      info[j].mask |= mask;
+  }
+  HB_INTERNAL void set_masks (hb_mask_t value,
+                              hb_mask_t mask,
+                              unsigned int cluster_start,
+                              unsigned int cluster_end);
+
+  HB_INTERNAL void merge_clusters (unsigned int start,
+                                   unsigned int end)
+  {
+    if (end - start < 2)
+      return;
+    merge_clusters_impl (start, end);
+  }
+  HB_INTERNAL void merge_clusters_impl (unsigned int start,
+                                        unsigned int end);
+  HB_INTERNAL void merge_out_clusters (unsigned int start,
+                                       unsigned int end);
+  /* Merge clusters for deleting current glyph, and skip it. */
+  HB_INTERNAL void delete_glyph (void);
+
+  /* Internal methods */
+  HB_INTERNAL bool enlarge (unsigned int size);
+
+  inline bool ensure (unsigned int size)
+  { return likely (!size || size < allocated) ? true : enlarge (size); }
+
+  inline bool ensure_inplace (unsigned int size)
+  { return likely (!size || size < allocated); }
+
+  HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
+  HB_INTERNAL bool shift_forward (unsigned int count);
+
+  typedef long scratch_buffer_t;
+  HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
+
+  inline void clear_context (unsigned int side) { context_len[side] = 0; }
+
+  HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
+};
+
+
+#define HB_BUFFER_XALLOCATE_VAR(b, func, var, owner) \
+  b->func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \
+           sizeof (b->info[0].var), owner)
+#define HB_BUFFER_ALLOCATE_VAR(b, var) \
+        HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var (), #var)
+#define HB_BUFFER_DEALLOCATE_VAR(b, var) \
+        HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var (), #var)
+#define HB_BUFFER_ASSERT_VAR(b, var) \
+        HB_BUFFER_XALLOCATE_VAR (b, assert_var, var (), #var)
+
+
+#endif /* HB_BUFFER_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-serialize.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,418 @@
+/*
+ * Copyright © 2012,2013  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
+ */
+
+#include "hb-buffer-private.hh"
+
+
+static const char *serialize_formats[] = {
+  "text",
+  "json",
+  NULL
+};
+
+/**
+ * hb_buffer_serialize_list_formats:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+const char **
+hb_buffer_serialize_list_formats (void)
+{
+  return serialize_formats;
+}
+
+/**
+ * hb_buffer_serialize_format_from_string:
+ * @str:
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_buffer_serialize_format_t
+hb_buffer_serialize_format_from_string (const char *str, int len)
+{
+  /* Upper-case it. */
+  return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020u);
+}
+
+/**
+ * hb_buffer_serialize_format_to_string:
+ * @format:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+const char *
+hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
+{
+  switch (format)
+  {
+    case HB_BUFFER_SERIALIZE_FORMAT_TEXT:       return serialize_formats[0];
+    case HB_BUFFER_SERIALIZE_FORMAT_JSON:       return serialize_formats[1];
+    default:
+    case HB_BUFFER_SERIALIZE_FORMAT_INVALID:    return NULL;
+  }
+}
+
+static unsigned int
+_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
+                                  unsigned int start,
+                                  unsigned int end,
+                                  char *buf,
+                                  unsigned int buf_size,
+                                  unsigned int *buf_consumed,
+                                  hb_font_t *font,
+                                  hb_buffer_serialize_flags_t flags)
+{
+  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
+  hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
+                             NULL : hb_buffer_get_glyph_positions (buffer, NULL);
+
+  *buf_consumed = 0;
+  for (unsigned int i = start; i < end; i++)
+  {
+    char b[1024];
+    char *p = b;
+
+    /* In the following code, we know b is large enough that no overflow can happen. */
+
+#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END
+
+    if (i)
+      *p++ = ',';
+
+    *p++ = '{';
+
+    APPEND ("\"g\":");
+    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
+    {
+      char g[128];
+      hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
+      *p++ = '"';
+      for (char *q = g; *q; q++) {
+        if (*q == '"')
+          *p++ = '\\';
+        *p++ = *q;
+      }
+      *p++ = '"';
+    }
+    else
+      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+
+    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
+      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
+    }
+
+    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
+    {
+      p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
+                     pos[i].x_offset, pos[i].y_offset);
+      p += 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_EXTENTS)
+    {
+      hb_glyph_extents_t extents;
+      hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
+      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
+        extents.x_bearing, extents.y_bearing));
+      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
+        extents.width, extents.height));
+    }
+
+    *p++ = '}';
+
+    unsigned int l = p - b;
+    if (buf_size > l)
+    {
+      memcpy (buf, b, l);
+      buf += l;
+      buf_size -= l;
+      *buf_consumed += l;
+      *buf = '\0';
+    } else
+      return i - start;
+  }
+
+  return end - start;
+}
+
+static unsigned int
+_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
+                                  unsigned int start,
+                                  unsigned int end,
+                                  char *buf,
+                                  unsigned int buf_size,
+                                  unsigned int *buf_consumed,
+                                  hb_font_t *font,
+                                  hb_buffer_serialize_flags_t flags)
+{
+  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
+  hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ?
+                             NULL : hb_buffer_get_glyph_positions (buffer, NULL);
+
+  *buf_consumed = 0;
+  for (unsigned int i = start; i < end; i++)
+  {
+    char b[1024];
+    char *p = b;
+
+    /* In the following code, we know b is large enough that no overflow can happen. */
+
+    if (i)
+      *p++ = '|';
+
+    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
+    {
+      hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
+      p += strlen (p);
+    }
+    else
+      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+
+    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
+      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
+    }
+
+    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));
+
+      *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_EXTENTS)
+    {
+      hb_glyph_extents_t extents;
+      hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
+      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
+    }
+
+    unsigned int l = p - b;
+    if (buf_size > l)
+    {
+      memcpy (buf, b, l);
+      buf += l;
+      buf_size -= l;
+      *buf_consumed += l;
+      *buf = '\0';
+    } else
+      return i - start;
+  }
+
+  return end - start;
+}
+
+/* Returns number of items, starting at start, that were serialized. */
+/**
+ * hb_buffer_serialize_glyphs:
+ * @buffer: a buffer.
+ * @start:
+ * @end:
+ * @buf: (array length=buf_size):
+ * @buf_size:
+ * @buf_consumed: (out):
+ * @font:
+ * @format:
+ * @flags:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+unsigned int
+hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
+                            unsigned int start,
+                            unsigned int end,
+                            char *buf,
+                            unsigned int buf_size,
+                            unsigned int *buf_consumed, /* May be NULL */
+                            hb_font_t *font, /* May be NULL */
+                            hb_buffer_serialize_format_t format,
+                            hb_buffer_serialize_flags_t flags)
+{
+  assert (start <= end && end <= buffer->len);
+
+  unsigned int sconsumed;
+  if (!buf_consumed)
+    buf_consumed = &sconsumed;
+  *buf_consumed = 0;
+
+  assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
+          buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+  if (unlikely (start == end))
+    return 0;
+
+  if (!font)
+    font = hb_font_get_empty ();
+
+  switch (format)
+  {
+    case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
+      return _hb_buffer_serialize_glyphs_text (buffer, start, end,
+                                               buf, buf_size, buf_consumed,
+                                               font, flags);
+
+    case HB_BUFFER_SERIALIZE_FORMAT_JSON:
+      return _hb_buffer_serialize_glyphs_json (buffer, start, end,
+                                               buf, buf_size, buf_consumed,
+                                               font, flags);
+
+    default:
+    case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
+      return 0;
+
+  }
+}
+
+
+static hb_bool_t
+parse_uint (const char *pp, const char *end, uint32_t *pv)
+{
+  char buf[32];
+  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
+  strncpy (buf, pp, len);
+  buf[len] = '\0';
+
+  char *p = buf;
+  char *pend = p;
+  uint32_t v;
+
+  errno = 0;
+  v = strtol (p, &pend, 10);
+  if (errno || p == pend || pend - p != end - pp)
+    return false;
+
+  *pv = v;
+  return true;
+}
+
+static hb_bool_t
+parse_int (const char *pp, const char *end, int32_t *pv)
+{
+  char buf[32];
+  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
+  strncpy (buf, pp, len);
+  buf[len] = '\0';
+
+  char *p = buf;
+  char *pend = p;
+  int32_t v;
+
+  errno = 0;
+  v = strtol (p, &pend, 10);
+  if (errno || p == pend || pend - p != end - pp)
+    return false;
+
+  *pv = v;
+  return true;
+}
+
+#include "hb-buffer-deserialize-json.hh"
+#include "hb-buffer-deserialize-text.hh"
+
+/**
+ * hb_buffer_deserialize_glyphs:
+ * @buffer: a buffer.
+ * @buf: (array length=buf_len):
+ * @buf_len:
+ * @end_ptr: (out):
+ * @font:
+ * @format:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
+                              const char *buf,
+                              int buf_len, /* -1 means nul-terminated */
+                              const char **end_ptr, /* May be NULL */
+                              hb_font_t *font, /* May be NULL */
+                              hb_buffer_serialize_format_t format)
+{
+  const char *end;
+  if (!end_ptr)
+    end_ptr = &end;
+  *end_ptr = buf;
+
+  assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
+          buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+  if (buf_len == -1)
+    buf_len = strlen (buf);
+
+  if (!buf_len)
+  {
+    *end_ptr = buf;
+    return false;
+  }
+
+  hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+  if (!font)
+    font = hb_font_get_empty ();
+
+  switch (format)
+  {
+    case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
+      return _hb_buffer_deserialize_glyphs_text (buffer,
+                                                 buf, buf_len, end_ptr,
+                                                 font);
+
+    case HB_BUFFER_SERIALIZE_FORMAT_JSON:
+      return _hb_buffer_deserialize_glyphs_json (buffer,
+                                                 buf, buf_len, end_ptr,
+                                                 font);
+
+    default:
+    case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
+      return false;
+
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1701 @@
+/*
+ * Copyright © 1998-2004  David Turner and Werner Lemberg
+ * Copyright © 2004,2007,2009,2010  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-buffer-private.hh"
+#include "hb-utf-private.hh"
+
+
+#ifndef HB_DEBUG_BUFFER
+#define HB_DEBUG_BUFFER (HB_DEBUG+0)
+#endif
+
+
+/**
+ * Since: 0.9.7
+ **/
+hb_bool_t
+hb_segment_properties_equal (const hb_segment_properties_t *a,
+                             const hb_segment_properties_t *b)
+{
+  return a->direction == b->direction &&
+         a->script    == b->script    &&
+         a->language  == b->language  &&
+         a->reserved1 == b->reserved1 &&
+         a->reserved2 == b->reserved2;
+
+}
+
+/**
+ * Since: 0.9.7
+ **/
+unsigned int
+hb_segment_properties_hash (const hb_segment_properties_t *p)
+{
+  return (unsigned int) p->direction ^
+         (unsigned int) p->script ^
+         (intptr_t) (p->language);
+}
+
+
+
+/* Here is how the buffer works internally:
+ *
+ * There are two info pointers: info and out_info.  They always have
+ * the same allocated size, but different lengths.
+ *
+ * As an optimization, both info and out_info may point to the
+ * same piece of memory, which is owned by info.  This remains the
+ * case as long as out_len doesn't exceed i at any time.
+ * In that case, swap_buffers() is no-op and the glyph operations operate
+ * mostly in-place.
+ *
+ * As soon as out_info gets longer than info, out_info is moved over
+ * to an alternate buffer (which we reuse the pos buffer for!), and its
+ * current contents (out_len entries) are copied to the new place.
+ * This should all remain transparent to the user.  swap_buffers() then
+ * switches info and out_info.
+ */
+
+
+
+/* Internal API */
+
+bool
+hb_buffer_t::enlarge (unsigned int size)
+{
+  if (unlikely (in_error))
+    return false;
+
+  unsigned int new_allocated = allocated;
+  hb_glyph_position_t *new_pos = NULL;
+  hb_glyph_info_t *new_info = NULL;
+  bool separate_out = out_info != info;
+
+  if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0]))))
+    goto done;
+
+  while (size >= new_allocated)
+    new_allocated += (new_allocated >> 1) + 32;
+
+  ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0]));
+  if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0]))))
+    goto done;
+
+  new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0]));
+  new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));
+
+done:
+  if (unlikely (!new_pos || !new_info))
+    in_error = true;
+
+  if (likely (new_pos))
+    pos = new_pos;
+
+  if (likely (new_info))
+    info = new_info;
+
+  out_info = separate_out ? (hb_glyph_info_t *) pos : info;
+  if (likely (!in_error))
+    allocated = new_allocated;
+
+  return likely (!in_error);
+}
+
+bool
+hb_buffer_t::make_room_for (unsigned int num_in,
+                            unsigned int num_out)
+{
+  if (unlikely (!ensure (out_len + num_out))) return false;
+
+  if (out_info == info &&
+      out_len + num_out > idx + num_in)
+  {
+    assert (have_output);
+
+    out_info = (hb_glyph_info_t *) pos;
+    memcpy (out_info, info, out_len * sizeof (out_info[0]));
+  }
+
+  return true;
+}
+
+bool
+hb_buffer_t::shift_forward (unsigned int count)
+{
+  assert (have_output);
+  if (unlikely (!ensure (len + count))) return false;
+
+  memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0]));
+  len += count;
+  idx += count;
+
+  return true;
+}
+
+hb_buffer_t::scratch_buffer_t *
+hb_buffer_t::get_scratch_buffer (unsigned int *size)
+{
+  have_output = false;
+  have_positions = false;
+
+  out_len = 0;
+  out_info = info;
+
+  assert ((uintptr_t) pos % sizeof (scratch_buffer_t) == 0);
+  *size = allocated * sizeof (pos[0]) / sizeof (scratch_buffer_t);
+  return (scratch_buffer_t *) (void *) pos;
+}
+
+
+
+/* HarfBuzz-Internal API */
+
+void
+hb_buffer_t::reset (void)
+{
+  if (unlikely (hb_object_is_inert (this)))
+    return;
+
+  hb_unicode_funcs_destroy (unicode);
+  unicode = hb_unicode_funcs_get_default ();
+  flags = HB_BUFFER_FLAG_DEFAULT;
+  replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+
+  clear ();
+}
+
+void
+hb_buffer_t::clear (void)
+{
+  if (unlikely (hb_object_is_inert (this)))
+    return;
+
+  hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
+  props = default_props;
+
+  content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
+  in_error = false;
+  have_output = false;
+  have_positions = false;
+
+  idx = 0;
+  len = 0;
+  out_len = 0;
+  out_info = info;
+
+  serial = 0;
+  memset (allocated_var_bytes, 0, sizeof allocated_var_bytes);
+  memset (allocated_var_owner, 0, sizeof allocated_var_owner);
+
+  memset (context, 0, sizeof context);
+  memset (context_len, 0, sizeof context_len);
+}
+
+void
+hb_buffer_t::add (hb_codepoint_t  codepoint,
+                  unsigned int    cluster)
+{
+  hb_glyph_info_t *glyph;
+
+  if (unlikely (!ensure (len + 1))) return;
+
+  glyph = &info[len];
+
+  memset (glyph, 0, sizeof (*glyph));
+  glyph->codepoint = codepoint;
+  glyph->mask = 1;
+  glyph->cluster = cluster;
+
+  len++;
+}
+
+void
+hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info)
+{
+  if (unlikely (!ensure (len + 1))) return;
+
+  info[len] = glyph_info;
+
+  len++;
+}
+
+
+void
+hb_buffer_t::remove_output (void)
+{
+  if (unlikely (hb_object_is_inert (this)))
+    return;
+
+  have_output = false;
+  have_positions = false;
+
+  out_len = 0;
+  out_info = info;
+}
+
+void
+hb_buffer_t::clear_output (void)
+{
+  if (unlikely (hb_object_is_inert (this)))
+    return;
+
+  have_output = true;
+  have_positions = false;
+
+  out_len = 0;
+  out_info = info;
+}
+
+void
+hb_buffer_t::clear_positions (void)
+{
+  if (unlikely (hb_object_is_inert (this)))
+    return;
+
+  have_output = false;
+  have_positions = true;
+
+  out_len = 0;
+  out_info = info;
+
+  memset (pos, 0, sizeof (pos[0]) * len);
+}
+
+void
+hb_buffer_t::swap_buffers (void)
+{
+  if (unlikely (in_error)) return;
+
+  assert (have_output);
+  have_output = false;
+
+  if (out_info != info)
+  {
+    hb_glyph_info_t *tmp_string;
+    tmp_string = info;
+    info = out_info;
+    out_info = tmp_string;
+    pos = (hb_glyph_position_t *) out_info;
+  }
+
+  unsigned int tmp;
+  tmp = len;
+  len = out_len;
+  out_len = tmp;
+
+  idx = 0;
+}
+
+
+void
+hb_buffer_t::replace_glyphs (unsigned int num_in,
+                             unsigned int num_out,
+                             const uint32_t *glyph_data)
+{
+  if (unlikely (!make_room_for (num_in, num_out))) return;
+
+  merge_clusters (idx, idx + num_in);
+
+  hb_glyph_info_t orig_info = info[idx];
+  hb_glyph_info_t *pinfo = &out_info[out_len];
+  for (unsigned int i = 0; i < num_out; i++)
+  {
+    *pinfo = orig_info;
+    pinfo->codepoint = glyph_data[i];
+    pinfo++;
+  }
+
+  idx  += num_in;
+  out_len += num_out;
+}
+
+void
+hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
+{
+  if (unlikely (!make_room_for (0, 1))) return;
+
+  out_info[out_len] = info[idx];
+  out_info[out_len].codepoint = glyph_index;
+
+  out_len++;
+}
+
+void
+hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info)
+{
+  if (unlikely (!make_room_for (0, 1))) return;
+
+  out_info[out_len] = glyph_info;
+
+  out_len++;
+}
+
+void
+hb_buffer_t::copy_glyph (void)
+{
+  if (unlikely (!make_room_for (0, 1))) return;
+
+  out_info[out_len] = info[idx];
+
+  out_len++;
+}
+
+bool
+hb_buffer_t::move_to (unsigned int i)
+{
+  if (!have_output)
+  {
+    assert (i <= len);
+    idx = i;
+    return true;
+  }
+
+  assert (i <= out_len + (len - idx));
+
+  if (out_len < i)
+  {
+    unsigned int count = i - out_len;
+    if (unlikely (!make_room_for (count, count))) return false;
+
+    memmove (out_info + out_len, info + idx, count * sizeof (out_info[0]));
+    idx += count;
+    out_len += count;
+  }
+  else if (out_len > i)
+  {
+    /* Tricky part: rewinding... */
+    unsigned int count = out_len - i;
+
+    if (unlikely (idx < count && !shift_forward (count + 32))) return false;
+
+    assert (idx >= count);
+
+    idx -= count;
+    out_len -= count;
+    memmove (info + idx, out_info + out_len, count * sizeof (out_info[0]));
+  }
+
+  return true;
+}
+
+void
+hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
+{
+  if (unlikely (out_info != info || out_len != idx)) {
+    if (unlikely (!make_room_for (1, 1))) return;
+    out_info[out_len] = info[idx];
+  }
+  out_info[out_len].codepoint = glyph_index;
+
+  idx++;
+  out_len++;
+}
+
+
+void
+hb_buffer_t::set_masks (hb_mask_t    value,
+                        hb_mask_t    mask,
+                        unsigned int cluster_start,
+                        unsigned int cluster_end)
+{
+  hb_mask_t not_mask = ~mask;
+  value &= mask;
+
+  if (!mask)
+    return;
+
+  if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
+    unsigned int count = len;
+    for (unsigned int i = 0; i < count; i++)
+      info[i].mask = (info[i].mask & not_mask) | value;
+    return;
+  }
+
+  unsigned int count = len;
+  for (unsigned int i = 0; i < count; i++)
+    if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
+      info[i].mask = (info[i].mask & not_mask) | value;
+}
+
+void
+hb_buffer_t::reverse_range (unsigned int start,
+                            unsigned int end)
+{
+  unsigned int i, j;
+
+  if (end - start < 2)
+    return;
+
+  for (i = start, j = end - 1; i < j; i++, j--) {
+    hb_glyph_info_t t;
+
+    t = info[i];
+    info[i] = info[j];
+    info[j] = t;
+  }
+
+  if (have_positions) {
+    for (i = start, j = end - 1; i < j; i++, j--) {
+      hb_glyph_position_t t;
+
+      t = pos[i];
+      pos[i] = pos[j];
+      pos[j] = t;
+    }
+  }
+}
+
+void
+hb_buffer_t::reverse (void)
+{
+  if (unlikely (!len))
+    return;
+
+  reverse_range (0, len);
+}
+
+void
+hb_buffer_t::reverse_clusters (void)
+{
+  unsigned int i, start, count, last_cluster;
+
+  if (unlikely (!len))
+    return;
+
+  reverse ();
+
+  count = len;
+  start = 0;
+  last_cluster = info[0].cluster;
+  for (i = 1; i < count; i++) {
+    if (last_cluster != info[i].cluster) {
+      reverse_range (start, i);
+      start = i;
+      last_cluster = info[i].cluster;
+    }
+  }
+  reverse_range (start, i);
+}
+
+void
+hb_buffer_t::merge_clusters_impl (unsigned int start,
+                                  unsigned int end)
+{
+  if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
+    return;
+
+  unsigned int cluster = info[start].cluster;
+
+  for (unsigned int i = start + 1; i < end; i++)
+    cluster = MIN (cluster, info[i].cluster);
+
+  /* Extend end */
+  while (end < len && info[end - 1].cluster == info[end].cluster)
+    end++;
+
+  /* Extend start */
+  while (idx < start && info[start - 1].cluster == info[start].cluster)
+    start--;
+
+  /* If we hit the start of buffer, continue in out-buffer. */
+  if (idx == start)
+    for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
+      out_info[i - 1].cluster = cluster;
+
+  for (unsigned int i = start; i < end; i++)
+    info[i].cluster = cluster;
+}
+void
+hb_buffer_t::merge_out_clusters (unsigned int start,
+                                 unsigned int end)
+{
+  if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
+    return;
+
+  if (unlikely (end - start < 2))
+    return;
+
+  unsigned int cluster = out_info[start].cluster;
+
+  for (unsigned int i = start + 1; i < end; i++)
+    cluster = MIN (cluster, out_info[i].cluster);
+
+  /* Extend start */
+  while (start && out_info[start - 1].cluster == out_info[start].cluster)
+    start--;
+
+  /* Extend end */
+  while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
+    end++;
+
+  /* If we hit the end of out-buffer, continue in buffer. */
+  if (end == out_len)
+    for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
+      info[i].cluster = cluster;
+
+  for (unsigned int i = start; i < end; i++)
+    out_info[i].cluster = cluster;
+}
+void
+hb_buffer_t::delete_glyph ()
+{
+  unsigned int cluster = info[idx].cluster;
+  if (idx + 1 < len && cluster == info[idx + 1].cluster)
+  {
+    /* Cluster survives; do nothing. */
+    goto done;
+  }
+
+  if (out_len)
+  {
+    /* Merge cluster backward. */
+    if (cluster < out_info[out_len - 1].cluster)
+    {
+      unsigned int old_cluster = out_info[out_len - 1].cluster;
+      for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--)
+        out_info[i - 1].cluster = cluster;
+    }
+    goto done;
+  }
+
+  if (idx + 1 < len)
+  {
+    /* Merge cluster forward. */
+    merge_clusters (idx, idx + 2);
+    goto done;
+  }
+
+done:
+  skip_glyph ();
+}
+
+void
+hb_buffer_t::guess_segment_properties (void)
+{
+  assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+          (!len && content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+
+  /* If script is set to INVALID, guess from buffer contents */
+  if (props.script == HB_SCRIPT_INVALID) {
+    for (unsigned int i = 0; i < len; i++) {
+      hb_script_t script = unicode->script (info[i].codepoint);
+      if (likely (script != HB_SCRIPT_COMMON &&
+                  script != HB_SCRIPT_INHERITED &&
+                  script != HB_SCRIPT_UNKNOWN)) {
+        props.script = script;
+        break;
+      }
+    }
+  }
+
+  /* If direction is set to INVALID, guess from script */
+  if (props.direction == HB_DIRECTION_INVALID) {
+    props.direction = hb_script_get_horizontal_direction (props.script);
+  }
+
+  /* If language is not set, use default language from locale */
+  if (props.language == HB_LANGUAGE_INVALID) {
+    /* TODO get_default_for_script? using $LANGUAGE */
+    props.language = hb_language_get_default ();
+  }
+}
+
+
+static inline void
+dump_var_allocation (const hb_buffer_t *buffer)
+{
+  char buf[80];
+  for (unsigned int i = 0; i < 8; i++)
+    buf[i] = '0' + buffer->allocated_var_bytes[7 - i];
+  buf[8] = '\0';
+  DEBUG_MSG (BUFFER, buffer,
+             "Current var allocation: %s",
+             buf);
+}
+
+void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+  assert (byte_i < 8 && byte_i + count <= 8);
+
+  if (DEBUG_ENABLED (BUFFER))
+    dump_var_allocation (this);
+  DEBUG_MSG (BUFFER, this,
+             "Allocating var bytes %d..%d for %s",
+             byte_i, byte_i + count - 1, owner);
+
+  for (unsigned int i = byte_i; i < byte_i + count; i++) {
+    assert (!allocated_var_bytes[i]);
+    allocated_var_bytes[i]++;
+    allocated_var_owner[i] = owner;
+  }
+}
+
+void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+  if (DEBUG_ENABLED (BUFFER))
+    dump_var_allocation (this);
+
+  DEBUG_MSG (BUFFER, this,
+             "Deallocating var bytes %d..%d for %s",
+             byte_i, byte_i + count - 1, owner);
+
+  assert (byte_i < 8 && byte_i + count <= 8);
+  for (unsigned int i = byte_i; i < byte_i + count; i++) {
+    assert (allocated_var_bytes[i]);
+    assert (0 == strcmp (allocated_var_owner[i], owner));
+    allocated_var_bytes[i]--;
+  }
+}
+
+void hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner)
+{
+  if (DEBUG_ENABLED (BUFFER))
+    dump_var_allocation (this);
+
+  DEBUG_MSG (BUFFER, this,
+             "Asserting var bytes %d..%d for %s",
+             byte_i, byte_i + count - 1, owner);
+
+  assert (byte_i < 8 && byte_i + count <= 8);
+  for (unsigned int i = byte_i; i < byte_i + count; i++) {
+    assert (allocated_var_bytes[i]);
+    assert (0 == strcmp (allocated_var_owner[i], owner));
+  }
+}
+
+void hb_buffer_t::deallocate_var_all (void)
+{
+  memset (allocated_var_bytes, 0, sizeof (allocated_var_bytes));
+  memset (allocated_var_owner, 0, sizeof (allocated_var_owner));
+}
+
+/* Public API */
+
+/**
+ * hb_buffer_create: (Xconstructor)
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 0.9.2
+ **/
+hb_buffer_t *
+hb_buffer_create (void)
+{
+  hb_buffer_t *buffer;
+
+  if (!(buffer = hb_object_create<hb_buffer_t> ()))
+    return hb_buffer_get_empty ();
+
+  buffer->reset ();
+
+  return buffer;
+}
+
+/**
+ * hb_buffer_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_buffer_t *
+hb_buffer_get_empty (void)
+{
+  static const hb_buffer_t _hb_buffer_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
+    HB_BUFFER_FLAG_DEFAULT,
+    HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
+    HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
+
+    HB_BUFFER_CONTENT_TYPE_INVALID,
+    HB_SEGMENT_PROPERTIES_DEFAULT,
+    true, /* in_error */
+    true, /* have_output */
+    true  /* have_positions */
+
+    /* Zero is good enough for everything else. */
+  };
+
+  return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
+}
+
+/**
+ * hb_buffer_reference: (skip)
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_buffer_t *
+hb_buffer_reference (hb_buffer_t *buffer)
+{
+  return hb_object_reference (buffer);
+}
+
+/**
+ * hb_buffer_destroy: (skip)
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_destroy (hb_buffer_t *buffer)
+{
+  if (!hb_object_destroy (buffer)) return;
+
+  hb_unicode_funcs_destroy (buffer->unicode);
+
+  free (buffer->info);
+  free (buffer->pos);
+
+  free (buffer);
+}
+
+/**
+ * hb_buffer_set_user_data: (skip)
+ * @buffer: a buffer.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_buffer_set_user_data (hb_buffer_t        *buffer,
+                         hb_user_data_key_t *key,
+                         void *              data,
+                         hb_destroy_func_t   destroy,
+                         hb_bool_t           replace)
+{
+  return hb_object_set_user_data (buffer, key, data, destroy, replace);
+}
+
+/**
+ * hb_buffer_get_user_data: (skip)
+ * @buffer: a buffer.
+ * @key:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+void *
+hb_buffer_get_user_data (hb_buffer_t        *buffer,
+                         hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (buffer, key);
+}
+
+
+/**
+ * hb_buffer_set_content_type:
+ * @buffer: a buffer.
+ * @content_type:
+ *
+ *
+ *
+ * Since: 0.9.5
+ **/
+void
+hb_buffer_set_content_type (hb_buffer_t              *buffer,
+                            hb_buffer_content_type_t  content_type)
+{
+  buffer->content_type = content_type;
+}
+
+/**
+ * hb_buffer_get_content_type:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.5
+ **/
+hb_buffer_content_type_t
+hb_buffer_get_content_type (hb_buffer_t *buffer)
+{
+  return buffer->content_type;
+}
+
+
+/**
+ * hb_buffer_set_unicode_funcs:
+ * @buffer: a buffer.
+ * @unicode_funcs:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
+                             hb_unicode_funcs_t *unicode_funcs)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  if (!unicode_funcs)
+    unicode_funcs = hb_unicode_funcs_get_default ();
+
+
+  hb_unicode_funcs_reference (unicode_funcs);
+  hb_unicode_funcs_destroy (buffer->unicode);
+  buffer->unicode = unicode_funcs;
+}
+
+/**
+ * hb_buffer_get_unicode_funcs:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_unicode_funcs_t *
+hb_buffer_get_unicode_funcs (hb_buffer_t        *buffer)
+{
+  return buffer->unicode;
+}
+
+/**
+ * hb_buffer_set_direction:
+ * @buffer: a buffer.
+ * @direction:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_set_direction (hb_buffer_t    *buffer,
+                         hb_direction_t  direction)
+
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->props.direction = direction;
+}
+
+/**
+ * hb_buffer_get_direction:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_direction_t
+hb_buffer_get_direction (hb_buffer_t    *buffer)
+{
+  return buffer->props.direction;
+}
+
+/**
+ * hb_buffer_set_script:
+ * @buffer: a buffer.
+ * @script:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_set_script (hb_buffer_t *buffer,
+                      hb_script_t  script)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->props.script = script;
+}
+
+/**
+ * hb_buffer_get_script:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_script_t
+hb_buffer_get_script (hb_buffer_t *buffer)
+{
+  return buffer->props.script;
+}
+
+/**
+ * hb_buffer_set_language:
+ * @buffer: a buffer.
+ * @language:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_set_language (hb_buffer_t   *buffer,
+                        hb_language_t  language)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->props.language = language;
+}
+
+/**
+ * hb_buffer_get_language:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+hb_language_t
+hb_buffer_get_language (hb_buffer_t *buffer)
+{
+  return buffer->props.language;
+}
+
+/**
+ * hb_buffer_set_segment_properties:
+ * @buffer: a buffer.
+ * @props:
+ *
+ *
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_buffer_set_segment_properties (hb_buffer_t *buffer,
+                                  const hb_segment_properties_t *props)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->props = *props;
+}
+
+/**
+ * hb_buffer_get_segment_properties:
+ * @buffer: a buffer.
+ * @props: (out):
+ *
+ *
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_buffer_get_segment_properties (hb_buffer_t *buffer,
+                                  hb_segment_properties_t *props)
+{
+  *props = buffer->props;
+}
+
+
+/**
+ * hb_buffer_set_flags:
+ * @buffer: a buffer.
+ * @flags:
+ *
+ *
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_buffer_set_flags (hb_buffer_t       *buffer,
+                     hb_buffer_flags_t  flags)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->flags = flags;
+}
+
+/**
+ * hb_buffer_get_flags:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.7
+ **/
+hb_buffer_flags_t
+hb_buffer_get_flags (hb_buffer_t *buffer)
+{
+  return buffer->flags;
+}
+
+/**
+ * hb_buffer_set_cluster_level:
+ * @buffer: a buffer.
+ * @cluster_level:
+ *
+ *
+ *
+ * Since: 0.9.42
+ **/
+void
+hb_buffer_set_cluster_level (hb_buffer_t       *buffer,
+                     hb_buffer_cluster_level_t  cluster_level)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->cluster_level = cluster_level;
+}
+
+/**
+ * hb_buffer_get_cluster_level:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.42
+ **/
+hb_buffer_cluster_level_t
+hb_buffer_get_cluster_level (hb_buffer_t *buffer)
+{
+  return buffer->cluster_level;
+}
+
+
+/**
+ * hb_buffer_set_replacement_codepoint:
+ * @buffer: a buffer.
+ * @replacement:
+ *
+ *
+ *
+ * Since: 0.9.31
+ **/
+void
+hb_buffer_set_replacement_codepoint (hb_buffer_t    *buffer,
+                                     hb_codepoint_t  replacement)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->replacement = replacement;
+}
+
+/**
+ * hb_buffer_get_replacement_codepoint:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.31
+ **/
+hb_codepoint_t
+hb_buffer_get_replacement_codepoint (hb_buffer_t    *buffer)
+{
+  return buffer->replacement;
+}
+
+
+/**
+ * hb_buffer_reset:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_reset (hb_buffer_t *buffer)
+{
+  buffer->reset ();
+}
+
+/**
+ * hb_buffer_clear_contents:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 0.9.11
+ **/
+void
+hb_buffer_clear_contents (hb_buffer_t *buffer)
+{
+  buffer->clear ();
+}
+
+/**
+ * hb_buffer_pre_allocate:
+ * @buffer: a buffer.
+ * @size:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
+{
+  return buffer->ensure (size);
+}
+
+/**
+ * hb_buffer_allocation_successful:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_buffer_allocation_successful (hb_buffer_t  *buffer)
+{
+  return !buffer->in_error;
+}
+
+/**
+ * hb_buffer_add:
+ * @buffer: a buffer.
+ * @codepoint:
+ * @cluster:
+ *
+ *
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_buffer_add (hb_buffer_t    *buffer,
+               hb_codepoint_t  codepoint,
+               unsigned int    cluster)
+{
+  buffer->add (codepoint, cluster);
+  buffer->clear_context (1);
+}
+
+/**
+ * hb_buffer_set_length:
+ * @buffer: a buffer.
+ * @length:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_buffer_set_length (hb_buffer_t  *buffer,
+                      unsigned int  length)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return length == 0;
+
+  if (!buffer->ensure (length))
+    return false;
+
+  /* Wipe the new space */
+  if (length > buffer->len) {
+    memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
+    if (buffer->have_positions)
+      memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
+  }
+
+  buffer->len = length;
+
+  if (!length)
+  {
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
+    buffer->clear_context (0);
+  }
+  buffer->clear_context (1);
+
+  return true;
+}
+
+/**
+ * hb_buffer_get_length:
+ * @buffer: a buffer.
+ *
+ * Returns the number of items in the buffer.
+ *
+ * Return value: buffer length.
+ *
+ * Since: 0.9.2
+ **/
+unsigned int
+hb_buffer_get_length (hb_buffer_t *buffer)
+{
+  return buffer->len;
+}
+
+/**
+ * hb_buffer_get_glyph_infos:
+ * @buffer: a buffer.
+ * @length: (out): output array length.
+ *
+ * Returns buffer glyph information array.  Returned pointer
+ * is valid as long as buffer contents are not modified.
+ *
+ * Return value: (transfer none) (array length=length): buffer glyph information array.
+ *
+ * Since: 0.9.2
+ **/
+hb_glyph_info_t *
+hb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
+                           unsigned int *length)
+{
+  if (length)
+    *length = buffer->len;
+
+  return (hb_glyph_info_t *) buffer->info;
+}
+
+/**
+ * hb_buffer_get_glyph_positions:
+ * @buffer: a buffer.
+ * @length: (out): output length.
+ *
+ * Returns buffer glyph position array.  Returned pointer
+ * is valid as long as buffer contents are not modified.
+ *
+ * Return value: (transfer none) (array length=length): buffer glyph position array.
+ *
+ * Since: 0.9.2
+ **/
+hb_glyph_position_t *
+hb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
+                               unsigned int *length)
+{
+  if (!buffer->have_positions)
+    buffer->clear_positions ();
+
+  if (length)
+    *length = buffer->len;
+
+  return (hb_glyph_position_t *) buffer->pos;
+}
+
+/**
+ * hb_buffer_reverse:
+ * @buffer: a buffer.
+ *
+ * Reverses buffer contents.
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_reverse (hb_buffer_t *buffer)
+{
+  buffer->reverse ();
+}
+
+/**
+ * hb_buffer_reverse_range:
+ * @buffer: a buffer.
+ * @start: start index.
+ * @end: end index.
+ *
+ * Reverses buffer contents between start to end.
+ *
+ * Since: 0.9.41
+ **/
+void
+hb_buffer_reverse_range (hb_buffer_t *buffer,
+                         unsigned int start, unsigned int end)
+{
+  buffer->reverse_range (start, end);
+}
+
+/**
+ * hb_buffer_reverse_clusters:
+ * @buffer: a buffer.
+ *
+ * Reverses buffer clusters.  That is, the buffer contents are
+ * reversed, then each cluster (consecutive items having the
+ * same cluster number) are reversed again.
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_reverse_clusters (hb_buffer_t *buffer)
+{
+  buffer->reverse_clusters ();
+}
+
+/**
+ * hb_buffer_guess_segment_properties:
+ * @buffer: a buffer.
+ *
+ * Sets unset buffer segment properties based on buffer Unicode
+ * contents.  If buffer is not empty, it must have content type
+ * %HB_BUFFER_CONTENT_TYPE_UNICODE.
+ *
+ * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it
+ * will be set to the Unicode script of the first character in
+ * the buffer that has a script other than %HB_SCRIPT_COMMON,
+ * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN.
+ *
+ * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
+ * it will be set to the natural horizontal direction of the
+ * buffer script as returned by hb_script_get_horizontal_direction().
+ *
+ * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
+ * it will be set to the process's default language as returned by
+ * hb_language_get_default().  This may change in the future by
+ * taking buffer script into consideration when choosing a language.
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
+{
+  buffer->guess_segment_properties ();
+}
+
+template <typename utf_t>
+static inline void
+hb_buffer_add_utf (hb_buffer_t  *buffer,
+                   const typename utf_t::codepoint_t *text,
+                   int           text_length,
+                   unsigned int  item_offset,
+                   int           item_length)
+{
+  typedef typename utf_t::codepoint_t T;
+  const hb_codepoint_t replacement = buffer->replacement;
+
+  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+          (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  if (text_length == -1)
+    text_length = utf_t::strlen (text);
+
+  if (item_length == -1)
+    item_length = text_length - item_offset;
+
+  buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
+
+  /* If buffer is empty and pre-context provided, install it.
+   * This check is written this way, to make sure people can
+   * provide pre-context in one add_utf() call, then provide
+   * text in a follow-up call.  See:
+   *
+   * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13
+   */
+  if (!buffer->len && item_offset > 0)
+  {
+    /* Add pre-context */
+    buffer->clear_context (0);
+    const T *prev = text + item_offset;
+    const T *start = text;
+    while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
+    {
+      hb_codepoint_t u;
+      prev = utf_t::prev (prev, start, &u, replacement);
+      buffer->context[0][buffer->context_len[0]++] = u;
+    }
+  }
+
+  const T *next = text + item_offset;
+  const T *end = next + item_length;
+  while (next < end)
+  {
+    hb_codepoint_t u;
+    const T *old_next = next;
+    next = utf_t::next (next, end, &u, replacement);
+    buffer->add (u, old_next - (const T *) text);
+  }
+
+  /* Add post-context */
+  buffer->clear_context (1);
+  end = text + text_length;
+  while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
+  {
+    hb_codepoint_t u;
+    next = utf_t::next (next, end, &u, replacement);
+    buffer->context[1][buffer->context_len[1]++] = u;
+  }
+
+  buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
+}
+
+/**
+ * hb_buffer_add_utf8:
+ * @buffer: a buffer.
+ * @text: (array length=text_length) (element-type uint8_t):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_add_utf8 (hb_buffer_t  *buffer,
+                    const char   *text,
+                    int           text_length,
+                    unsigned int  item_offset,
+                    int           item_length)
+{
+  hb_buffer_add_utf<hb_utf8_t> (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
+}
+
+/**
+ * hb_buffer_add_utf16:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_add_utf16 (hb_buffer_t    *buffer,
+                     const uint16_t *text,
+                     int             text_length,
+                     unsigned int    item_offset,
+                     int             item_length)
+{
+  hb_buffer_add_utf<hb_utf16_t> (buffer, text, text_length, item_offset, item_length);
+}
+
+/**
+ * hb_buffer_add_utf32:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_add_utf32 (hb_buffer_t    *buffer,
+                     const uint32_t *text,
+                     int             text_length,
+                     unsigned int    item_offset,
+                     int             item_length)
+{
+  hb_buffer_add_utf<hb_utf32_t<> > (buffer, text, text_length, item_offset, item_length);
+}
+
+/**
+ * hb_buffer_add_latin1:
+ * @buffer: a buffer.
+ * @text: (array length=text_length) (element-type uint8_t):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 0.9.39
+ **/
+void
+hb_buffer_add_latin1 (hb_buffer_t   *buffer,
+                      const uint8_t *text,
+                      int            text_length,
+                      unsigned int   item_offset,
+                      int            item_length)
+{
+  hb_buffer_add_utf<hb_latin1_t> (buffer, text, text_length, item_offset, item_length);
+}
+
+/**
+ * hb_buffer_add_codepoints:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 0.9.31
+ **/
+void
+hb_buffer_add_codepoints (hb_buffer_t          *buffer,
+                          const hb_codepoint_t *text,
+                          int                   text_length,
+                          unsigned int          item_offset,
+                          int                   item_length)
+{
+  hb_buffer_add_utf<hb_utf32_t<false> > (buffer, text, text_length, item_offset, item_length);
+}
+
+
+static int
+compare_info_codepoint (const hb_glyph_info_t *pa,
+                        const hb_glyph_info_t *pb)
+{
+  return (int) pb->codepoint - (int) pa->codepoint;
+}
+
+static inline void
+normalize_glyphs_cluster (hb_buffer_t *buffer,
+                          unsigned int start,
+                          unsigned int end,
+                          bool backward)
+{
+  hb_glyph_position_t *pos = buffer->pos;
+
+  /* Total cluster advance */
+  hb_position_t total_x_advance = 0, total_y_advance = 0;
+  for (unsigned int i = start; i < end; i++)
+  {
+    total_x_advance += pos[i].x_advance;
+    total_y_advance += pos[i].y_advance;
+  }
+
+  hb_position_t x_advance = 0, y_advance = 0;
+  for (unsigned int i = start; i < end; i++)
+  {
+    pos[i].x_offset += x_advance;
+    pos[i].y_offset += y_advance;
+
+    x_advance += pos[i].x_advance;
+    y_advance += pos[i].y_advance;
+
+    pos[i].x_advance = 0;
+    pos[i].y_advance = 0;
+  }
+
+  if (backward)
+  {
+    /* Transfer all cluster advance to the last glyph. */
+    pos[end - 1].x_advance = total_x_advance;
+    pos[end - 1].y_advance = total_y_advance;
+
+    hb_stable_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
+  } else {
+    /* Transfer all cluster advance to the first glyph. */
+    pos[start].x_advance += total_x_advance;
+    pos[start].y_advance += total_y_advance;
+    for (unsigned int i = start + 1; i < end; i++) {
+      pos[i].x_offset -= total_x_advance;
+      pos[i].y_offset -= total_y_advance;
+    }
+    hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
+  }
+}
+
+/**
+ * hb_buffer_normalize_glyphs:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
+{
+  assert (buffer->have_positions);
+  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+  bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+
+  unsigned int count = buffer->len;
+  if (unlikely (!count)) return;
+  hb_glyph_info_t *info = buffer->info;
+
+  unsigned int start = 0;
+  unsigned int end;
+  for (end = start + 1; end < count; end++)
+    if (info[start].cluster != info[end].cluster) {
+      normalize_glyphs_cluster (buffer, start, end, backward);
+      start = end;
+    }
+  normalize_glyphs_cluster (buffer, start, end, backward);
+}
+
+void
+hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *))
+{
+  assert (!have_positions);
+  for (unsigned int i = start + 1; i < end; i++)
+  {
+    unsigned int j = i;
+    while (j > start && compar (&info[j - 1], &info[i]) > 0)
+      j--;
+    if (i == j)
+      continue;
+    /* Move item i to occupy place for item j, shift what's in between. */
+    merge_clusters (j, i + 1);
+    {
+      hb_glyph_info_t t = info[i];
+      memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t));
+      info[j] = t;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,378 @@
+/*
+ * Copyright © 1998-2004  David Turner and Werner Lemberg
+ * Copyright © 2004,2007,2009  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_BUFFER_H
+#define HB_BUFFER_H
+
+#include "hb-common.h"
+#include "hb-unicode.h"
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+
+typedef struct hb_glyph_info_t {
+  hb_codepoint_t codepoint;
+  hb_mask_t      mask;
+  uint32_t       cluster;
+
+  /*< private >*/
+  hb_var_int_t   var1;
+  hb_var_int_t   var2;
+} hb_glyph_info_t;
+
+typedef struct hb_glyph_position_t {
+  hb_position_t  x_advance;
+  hb_position_t  y_advance;
+  hb_position_t  x_offset;
+  hb_position_t  y_offset;
+
+  /*< private >*/
+  hb_var_int_t   var;
+} hb_glyph_position_t;
+
+
+typedef struct hb_segment_properties_t {
+  hb_direction_t  direction;
+  hb_script_t     script;
+  hb_language_t   language;
+  /*< private >*/
+  void           *reserved1;
+  void           *reserved2;
+} hb_segment_properties_t;
+
+#define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \
+                                       HB_SCRIPT_INVALID, \
+                                       HB_LANGUAGE_INVALID, \
+                                       NULL, \
+                                       NULL}
+
+hb_bool_t
+hb_segment_properties_equal (const hb_segment_properties_t *a,
+                             const hb_segment_properties_t *b);
+
+unsigned int
+hb_segment_properties_hash (const hb_segment_properties_t *p);
+
+
+
+/*
+ * hb_buffer_t
+ */
+
+typedef struct hb_buffer_t hb_buffer_t;
+
+hb_buffer_t *
+hb_buffer_create (void);
+
+hb_buffer_t *
+hb_buffer_get_empty (void);
+
+hb_buffer_t *
+hb_buffer_reference (hb_buffer_t *buffer);
+
+void
+hb_buffer_destroy (hb_buffer_t *buffer);
+
+hb_bool_t
+hb_buffer_set_user_data (hb_buffer_t        *buffer,
+                         hb_user_data_key_t *key,
+                         void *              data,
+                         hb_destroy_func_t   destroy,
+                         hb_bool_t           replace);
+
+void *
+hb_buffer_get_user_data (hb_buffer_t        *buffer,
+                         hb_user_data_key_t *key);
+
+
+typedef enum {
+  HB_BUFFER_CONTENT_TYPE_INVALID = 0,
+  HB_BUFFER_CONTENT_TYPE_UNICODE,
+  HB_BUFFER_CONTENT_TYPE_GLYPHS
+} hb_buffer_content_type_t;
+
+void
+hb_buffer_set_content_type (hb_buffer_t              *buffer,
+                            hb_buffer_content_type_t  content_type);
+
+hb_buffer_content_type_t
+hb_buffer_get_content_type (hb_buffer_t *buffer);
+
+
+void
+hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
+                             hb_unicode_funcs_t *unicode_funcs);
+
+hb_unicode_funcs_t *
+hb_buffer_get_unicode_funcs (hb_buffer_t        *buffer);
+
+void
+hb_buffer_set_direction (hb_buffer_t    *buffer,
+                         hb_direction_t  direction);
+
+hb_direction_t
+hb_buffer_get_direction (hb_buffer_t *buffer);
+
+void
+hb_buffer_set_script (hb_buffer_t *buffer,
+                      hb_script_t  script);
+
+hb_script_t
+hb_buffer_get_script (hb_buffer_t *buffer);
+
+void
+hb_buffer_set_language (hb_buffer_t   *buffer,
+                        hb_language_t  language);
+
+
+hb_language_t
+hb_buffer_get_language (hb_buffer_t *buffer);
+
+void
+hb_buffer_set_segment_properties (hb_buffer_t *buffer,
+                                  const hb_segment_properties_t *props);
+
+void
+hb_buffer_get_segment_properties (hb_buffer_t *buffer,
+                                  hb_segment_properties_t *props);
+
+void
+hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
+
+
+/*
+ * Since: 0.9.20
+ */
+typedef enum { /*< flags >*/
+  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_flags_t;
+
+void
+hb_buffer_set_flags (hb_buffer_t       *buffer,
+                     hb_buffer_flags_t  flags);
+
+hb_buffer_flags_t
+hb_buffer_get_flags (hb_buffer_t *buffer);
+
+/*
+ * Since: 0.9.42
+ */
+typedef enum {
+  HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES    = 0,
+  HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS   = 1,
+  HB_BUFFER_CLUSTER_LEVEL_CHARACTERS            = 2,
+  HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES
+} hb_buffer_cluster_level_t;
+
+void
+hb_buffer_set_cluster_level (hb_buffer_t               *buffer,
+                             hb_buffer_cluster_level_t  cluster_level);
+
+hb_buffer_cluster_level_t
+hb_buffer_get_cluster_level (hb_buffer_t *buffer);
+
+#define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu
+
+/* Sets codepoint used to replace invalid UTF-8/16/32 entries.
+ * Default is 0xFFFDu. */
+void
+hb_buffer_set_replacement_codepoint (hb_buffer_t    *buffer,
+                                     hb_codepoint_t  replacement);
+
+hb_codepoint_t
+hb_buffer_get_replacement_codepoint (hb_buffer_t    *buffer);
+
+
+/* Resets the buffer.  Afterwards it's as if it was just created,
+ * except that it has a larger buffer allocated perhaps... */
+void
+hb_buffer_reset (hb_buffer_t *buffer);
+
+/* Like reset, but does NOT clear unicode_funcs and replacement_codepoint. */
+void
+hb_buffer_clear_contents (hb_buffer_t *buffer);
+
+/* Returns false if allocation failed */
+hb_bool_t
+hb_buffer_pre_allocate (hb_buffer_t  *buffer,
+                        unsigned int  size);
+
+
+/* Returns false if allocation has failed before */
+hb_bool_t
+hb_buffer_allocation_successful (hb_buffer_t  *buffer);
+
+void
+hb_buffer_reverse (hb_buffer_t *buffer);
+
+void
+hb_buffer_reverse_range (hb_buffer_t *buffer,
+                         unsigned int start, unsigned int end);
+
+void
+hb_buffer_reverse_clusters (hb_buffer_t *buffer);
+
+
+/* Filling the buffer in */
+
+void
+hb_buffer_add (hb_buffer_t    *buffer,
+               hb_codepoint_t  codepoint,
+               unsigned int    cluster);
+
+void
+hb_buffer_add_utf8 (hb_buffer_t  *buffer,
+                    const char   *text,
+                    int           text_length,
+                    unsigned int  item_offset,
+                    int           item_length);
+
+void
+hb_buffer_add_utf16 (hb_buffer_t    *buffer,
+                     const uint16_t *text,
+                     int             text_length,
+                     unsigned int    item_offset,
+                     int             item_length);
+
+void
+hb_buffer_add_utf32 (hb_buffer_t    *buffer,
+                     const uint32_t *text,
+                     int             text_length,
+                     unsigned int    item_offset,
+                     int             item_length);
+
+/* Allows only access to first 256 Unicode codepoints. */
+void
+hb_buffer_add_latin1 (hb_buffer_t   *buffer,
+                      const uint8_t *text,
+                      int            text_length,
+                      unsigned int   item_offset,
+                      int            item_length);
+
+/* Like add_utf32 but does NOT check for invalid Unicode codepoints. */
+void
+hb_buffer_add_codepoints (hb_buffer_t          *buffer,
+                          const hb_codepoint_t *text,
+                          int                   text_length,
+                          unsigned int          item_offset,
+                          int                   item_length);
+
+
+/* Clears any new items added at the end */
+hb_bool_t
+hb_buffer_set_length (hb_buffer_t  *buffer,
+                      unsigned int  length);
+
+/* Return value valid as long as buffer not modified */
+unsigned int
+hb_buffer_get_length (hb_buffer_t *buffer);
+
+/* Getting glyphs out of the buffer */
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_info_t *
+hb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
+                           unsigned int *length);
+
+/* Return value valid as long as buffer not modified */
+hb_glyph_position_t *
+hb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
+                               unsigned int *length);
+
+
+/* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
+ * The resulting clusters should behave identical to pre-reordering clusters.
+ * NOTE: This has nothing to do with Unicode normalization. */
+void
+hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
+
+
+/*
+ * Serialize
+ */
+
+/*
+ * Since: 0.9.20
+ */
+typedef enum { /*< flags >*/
+  HB_BUFFER_SERIALIZE_FLAG_DEFAULT              = 0x00000000u,
+  HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS          = 0x00000001u,
+  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_flags_t;
+
+typedef enum {
+  HB_BUFFER_SERIALIZE_FORMAT_TEXT       = HB_TAG('T','E','X','T'),
+  HB_BUFFER_SERIALIZE_FORMAT_JSON       = HB_TAG('J','S','O','N'),
+  HB_BUFFER_SERIALIZE_FORMAT_INVALID    = HB_TAG_NONE
+} hb_buffer_serialize_format_t;
+
+/* len=-1 means str is NUL-terminated. */
+hb_buffer_serialize_format_t
+hb_buffer_serialize_format_from_string (const char *str, int len);
+
+const char *
+hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format);
+
+const char **
+hb_buffer_serialize_list_formats (void);
+
+/* Returns number of items, starting at start, that were serialized. */
+unsigned int
+hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
+                            unsigned int start,
+                            unsigned int end,
+                            char *buf,
+                            unsigned int buf_size,
+                            unsigned int *buf_consumed, /* May be NULL */
+                            hb_font_t *font, /* May be NULL */
+                            hb_buffer_serialize_format_t format,
+                            hb_buffer_serialize_flags_t flags);
+
+hb_bool_t
+hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
+                              const char *buf,
+                              int buf_len, /* -1 means nul-terminated */
+                              const char **end_ptr, /* May be NULL */
+                              hb_font_t *font, /* May be NULL */
+                              hb_buffer_serialize_format_t format);
+
+
+HB_END_DECLS
+
+#endif /* HB_BUFFER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-cache-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2012  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_CACHE_PRIVATE_HH
+#define HB_CACHE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* Implements a lock-free cache for int->int functions. */
+
+template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
+struct hb_cache_t
+{
+  ASSERT_STATIC (key_bits >= cache_bits);
+  ASSERT_STATIC (key_bits + value_bits - cache_bits < 8 * sizeof (unsigned int));
+
+  inline void clear (void)
+  {
+    memset (values, 255, sizeof (values));
+  }
+
+  inline bool get (unsigned int key, unsigned int *value)
+  {
+    unsigned int k = key & ((1<<cache_bits)-1);
+    unsigned int v = values[k];
+    if ((v >> value_bits) != (key >> cache_bits))
+      return false;
+    *value = v & ((1<<value_bits)-1);
+    return true;
+  }
+
+  inline bool set (unsigned int key, unsigned int value)
+  {
+    if (unlikely ((key >> key_bits) || (value >> value_bits)))
+      return false; /* Overflows */
+    unsigned int k = key & ((1<<cache_bits)-1);
+    unsigned int v = ((key>>cache_bits)<<value_bits) | value;
+    values[k] = v;
+    return true;
+  }
+
+  private:
+  unsigned int values[1<<cache_bits];
+};
+
+typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t;
+typedef hb_cache_t<16, 24, 8> hb_advance_cache_t;
+
+
+#endif /* HB_CACHE_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,593 @@
+/*
+ * Copyright © 2009,2010  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-mutex-private.hh"
+#include "hb-object-private.hh"
+
+#include <locale.h>
+
+
+/* hb_options_t */
+
+hb_options_union_t _hb_options;
+
+void
+_hb_options_init (void)
+{
+  hb_options_union_t u;
+  u.i = 0;
+  u.opts.initialized = 1;
+
+  char *c = getenv ("HB_OPTIONS");
+  u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
+
+  /* This is idempotent and threadsafe. */
+  _hb_options = u;
+}
+
+
+/* hb_tag_t */
+
+/**
+ * hb_tag_from_string:
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_tag_t
+hb_tag_from_string (const char *str, int len)
+{
+  char tag[4];
+  unsigned int i;
+
+  if (!str || !len || !*str)
+    return HB_TAG_NONE;
+
+  if (len < 0 || len > 4)
+    len = 4;
+  for (i = 0; i < (unsigned) len && str[i]; i++)
+    tag[i] = str[i];
+  for (; i < 4; i++)
+    tag[i] = ' ';
+
+  return HB_TAG_CHAR4 (tag);
+}
+
+/**
+ * hb_tag_to_string:
+ * @tag:
+ * @buf: (array fixed-size=4):
+ *
+ *
+ *
+ * Since: 0.9.5
+ **/
+void
+hb_tag_to_string (hb_tag_t tag, char *buf)
+{
+  buf[0] = (char) (uint8_t) (tag >> 24);
+  buf[1] = (char) (uint8_t) (tag >> 16);
+  buf[2] = (char) (uint8_t) (tag >>  8);
+  buf[3] = (char) (uint8_t) (tag >>  0);
+}
+
+
+/* hb_direction_t */
+
+const char direction_strings[][4] = {
+  "ltr",
+  "rtl",
+  "ttb",
+  "btt"
+};
+
+/**
+ * hb_direction_from_string:
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_direction_t
+hb_direction_from_string (const char *str, int len)
+{
+  if (unlikely (!str || !len || !*str))
+    return HB_DIRECTION_INVALID;
+
+  /* Lets match loosely: just match the first letter, such that
+   * all of "ltr", "left-to-right", etc work!
+   */
+  char c = TOLOWER (str[0]);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (direction_strings); i++)
+    if (c == direction_strings[i][0])
+      return (hb_direction_t) (HB_DIRECTION_LTR + i);
+
+  return HB_DIRECTION_INVALID;
+}
+
+/**
+ * hb_direction_to_string:
+ * @direction:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+const char *
+hb_direction_to_string (hb_direction_t direction)
+{
+  if (likely ((unsigned int) (direction - HB_DIRECTION_LTR)
+              < ARRAY_LENGTH (direction_strings)))
+    return direction_strings[direction - HB_DIRECTION_LTR];
+
+  return "invalid";
+}
+
+
+/* hb_language_t */
+
+struct hb_language_impl_t {
+  const char s[1];
+};
+
+static const char canon_map[256] = {
+   0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,  '-',  0,   0,
+  '0', '1', '2', '3', '4', '5', '6', '7',  '8', '9',  0,   0,   0,   0,   0,   0,
+  '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g',  'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+  'p', 'q', 'r', 's', 't', 'u', 'v', 'w',  'x', 'y', 'z',  0,   0,   0,   0,  '-',
+   0,  'a', 'b', 'c', 'd', 'e', 'f', 'g',  'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+  'p', 'q', 'r', 's', 't', 'u', 'v', 'w',  'x', 'y', 'z',  0,   0,   0,   0,   0
+};
+
+static bool
+lang_equal (hb_language_t  v1,
+            const void    *v2)
+{
+  const unsigned char *p1 = (const unsigned char *) v1;
+  const unsigned char *p2 = (const unsigned char *) v2;
+
+  while (*p1 && *p1 == canon_map[*p2])
+    p1++, p2++;
+
+  return *p1 == canon_map[*p2];
+}
+
+#if 0
+static unsigned int
+lang_hash (const void *key)
+{
+  const unsigned char *p = key;
+  unsigned int h = 0;
+  while (canon_map[*p])
+    {
+      h = (h << 5) - h + canon_map[*p];
+      p++;
+    }
+
+  return h;
+}
+#endif
+
+
+struct hb_language_item_t {
+
+  struct hb_language_item_t *next;
+  hb_language_t lang;
+
+  inline bool operator == (const char *s) const {
+    return lang_equal (lang, s);
+  }
+
+  inline hb_language_item_t & operator = (const char *s) {
+    lang = (hb_language_t) strdup (s);
+    for (unsigned char *p = (unsigned char *) lang; *p; p++)
+      *p = canon_map[*p];
+
+    return *this;
+  }
+
+  void finish (void) { free ((void *) lang); }
+};
+
+
+/* Thread-safe lock-free language list */
+
+static hb_language_item_t *langs;
+
+#ifdef HB_USE_ATEXIT
+static
+void free_langs (void)
+{
+  while (langs) {
+    hb_language_item_t *next = langs->next;
+    langs->finish ();
+    free (langs);
+    langs = next;
+  }
+}
+#endif
+
+static hb_language_item_t *
+lang_find_or_insert (const char *key)
+{
+retry:
+  hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
+
+  for (hb_language_item_t *lang = first_lang; lang; lang = lang->next)
+    if (*lang == key)
+      return lang;
+
+  /* Not found; allocate one. */
+  hb_language_item_t *lang = (hb_language_item_t *) calloc (1, sizeof (hb_language_item_t));
+  if (unlikely (!lang))
+    return NULL;
+  lang->next = first_lang;
+  *lang = key;
+
+  if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
+    lang->finish ();
+    free (lang);
+    goto retry;
+  }
+
+#ifdef HB_USE_ATEXIT
+  if (!first_lang)
+    atexit (free_langs); /* First person registers atexit() callback. */
+#endif
+
+  return lang;
+}
+
+
+/**
+ * hb_language_from_string:
+ * @str: (array length=len) (element-type uint8_t):
+ * @len:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+hb_language_t
+hb_language_from_string (const char *str, int len)
+{
+  if (!str || !len || !*str)
+    return HB_LANGUAGE_INVALID;
+
+  hb_language_item_t *item = NULL;
+  if (len >= 0)
+  {
+    /* NUL-terminate it. */
+    char strbuf[64];
+    len = MIN (len, (int) sizeof (strbuf) - 1);
+    memcpy (strbuf, str, len);
+    strbuf[len] = '\0';
+    item = lang_find_or_insert (strbuf);
+  }
+  else
+    item = lang_find_or_insert (str);
+
+  return likely (item) ? item->lang : HB_LANGUAGE_INVALID;
+}
+
+/**
+ * hb_language_to_string:
+ * @language:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+const char *
+hb_language_to_string (hb_language_t language)
+{
+  /* This is actually NULL-safe! */
+  return language->s;
+}
+
+/**
+ * hb_language_get_default:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+hb_language_t
+hb_language_get_default (void)
+{
+  static hb_language_t default_language = HB_LANGUAGE_INVALID;
+
+  hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language);
+  if (unlikely (language == HB_LANGUAGE_INVALID)) {
+    language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1);
+    (void) hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
+  }
+
+  return default_language;
+}
+
+
+/* hb_script_t */
+
+/**
+ * hb_script_from_iso15924_tag:
+ * @tag:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_script_t
+hb_script_from_iso15924_tag (hb_tag_t tag)
+{
+  if (unlikely (tag == HB_TAG_NONE))
+    return HB_SCRIPT_INVALID;
+
+  /* Be lenient, adjust case (one capital letter followed by three small letters) */
+  tag = (tag & 0xDFDFDFDFu) | 0x00202020u;
+
+  switch (tag) {
+
+    /* These graduated from the 'Q' private-area codes, but
+     * the old code is still aliased by Unicode, and the Qaai
+     * one in use by ICU. */
+    case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED;
+    case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
+
+    /* Script variants from http://unicode.org/iso15924/ */
+    case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC;
+    case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN;
+    case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN;
+    case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC;
+    case HB_TAG('S','y','r','j'): return HB_SCRIPT_SYRIAC;
+    case HB_TAG('S','y','r','n'): return HB_SCRIPT_SYRIAC;
+  }
+
+  /* If it looks right, just use the tag as a script */
+  if (((uint32_t) tag & 0xE0E0E0E0u) == 0x40606060u)
+    return (hb_script_t) tag;
+
+  /* Otherwise, return unknown */
+  return HB_SCRIPT_UNKNOWN;
+}
+
+/**
+ * hb_script_from_string:
+ * @s: (array length=len) (element-type uint8_t):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_script_t
+hb_script_from_string (const char *s, int len)
+{
+  return hb_script_from_iso15924_tag (hb_tag_from_string (s, len));
+}
+
+/**
+ * hb_script_to_iso15924_tag:
+ * @script:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_tag_t
+hb_script_to_iso15924_tag (hb_script_t script)
+{
+  return (hb_tag_t) script;
+}
+
+/**
+ * hb_script_get_horizontal_direction:
+ * @script:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_direction_t
+hb_script_get_horizontal_direction (hb_script_t script)
+{
+  /* http://goo.gl/x9ilM */
+  switch ((hb_tag_t) script)
+  {
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_ARABIC:
+    case HB_SCRIPT_HEBREW:
+
+    /* Unicode-3.0 additions */
+    case HB_SCRIPT_SYRIAC:
+    case HB_SCRIPT_THAANA:
+
+    /* Unicode-4.0 additions */
+    case HB_SCRIPT_CYPRIOT:
+
+    /* Unicode-4.1 additions */
+    case HB_SCRIPT_KHAROSHTHI:
+
+    /* Unicode-5.0 additions */
+    case HB_SCRIPT_PHOENICIAN:
+    case HB_SCRIPT_NKO:
+
+    /* Unicode-5.1 additions */
+    case HB_SCRIPT_LYDIAN:
+
+    /* Unicode-5.2 additions */
+    case HB_SCRIPT_AVESTAN:
+    case HB_SCRIPT_IMPERIAL_ARAMAIC:
+    case HB_SCRIPT_INSCRIPTIONAL_PAHLAVI:
+    case HB_SCRIPT_INSCRIPTIONAL_PARTHIAN:
+    case HB_SCRIPT_OLD_SOUTH_ARABIAN:
+    case HB_SCRIPT_OLD_TURKIC:
+    case HB_SCRIPT_SAMARITAN:
+
+    /* Unicode-6.0 additions */
+    case HB_SCRIPT_MANDAIC:
+
+    /* Unicode-6.1 additions */
+    case HB_SCRIPT_MEROITIC_CURSIVE:
+    case HB_SCRIPT_MEROITIC_HIEROGLYPHS:
+
+    /* Unicode-7.0 additions */
+    case HB_SCRIPT_MANICHAEAN:
+    case HB_SCRIPT_MENDE_KIKAKUI:
+    case HB_SCRIPT_NABATAEAN:
+    case HB_SCRIPT_OLD_NORTH_ARABIAN:
+    case HB_SCRIPT_PALMYRENE:
+    case HB_SCRIPT_PSALTER_PAHLAVI:
+
+    /* Unicode-8.0 additions */
+    case HB_SCRIPT_OLD_HUNGARIAN:
+
+      return HB_DIRECTION_RTL;
+  }
+
+  return HB_DIRECTION_LTR;
+}
+
+
+/* hb_user_data_array_t */
+
+bool
+hb_user_data_array_t::set (hb_user_data_key_t *key,
+                           void *              data,
+                           hb_destroy_func_t   destroy,
+                           hb_bool_t           replace)
+{
+  if (!key)
+    return false;
+
+  if (replace) {
+    if (!data && !destroy) {
+      items.remove (key, lock);
+      return true;
+    }
+  }
+  hb_user_data_item_t item = {key, data, destroy};
+  bool ret = !!items.replace_or_insert (item, lock, replace);
+
+  return ret;
+}
+
+void *
+hb_user_data_array_t::get (hb_user_data_key_t *key)
+{
+  hb_user_data_item_t item = {NULL };
+
+  return items.find (key, &item, lock) ? item.data : NULL;
+}
+
+
+/* hb_version */
+
+/**
+ * hb_version:
+ * @major: (out): Library major version component.
+ * @minor: (out): Library minor version component.
+ * @micro: (out): Library micro version component.
+ *
+ * Returns library version as three integer components.
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_version (unsigned int *major,
+            unsigned int *minor,
+            unsigned int *micro)
+{
+  *major = HB_VERSION_MAJOR;
+  *minor = HB_VERSION_MINOR;
+  *micro = HB_VERSION_MICRO;
+}
+
+/**
+ * hb_version_string:
+ *
+ * Returns library version as a string with three components.
+ *
+ * Return value: library version string.
+ *
+ * Since: 0.9.2
+ **/
+const char *
+hb_version_string (void)
+{
+  return HB_VERSION_STRING;
+}
+
+/**
+ * hb_version_atleast:
+ * @major:
+ * @minor:
+ * @micro:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.30
+ **/
+hb_bool_t
+hb_version_atleast (unsigned int major,
+                    unsigned int minor,
+                    unsigned int micro)
+{
+  return HB_VERSION_ATLEAST (major, minor, micro);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,354 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_COMMON_H
+#define HB_COMMON_H
+
+#ifndef HB_BEGIN_DECLS
+# ifdef __cplusplus
+#  define HB_BEGIN_DECLS        extern "C" {
+#  define HB_END_DECLS          }
+# else /* !__cplusplus */
+#  define HB_BEGIN_DECLS
+#  define HB_END_DECLS
+# endif /* !__cplusplus */
+#endif
+
+#if !defined (HB_DONT_DEFINE_STDINT)
+
+#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
+    defined (_sgi) || defined (__sun) || defined (sun) || \
+    defined (__digital__) || defined (__HP_cc)
+#  include <inttypes.h>
+#elif defined (_AIX)
+#  include <sys/inttypes.h>
+/* VS 2010 (_MSC_VER 1600) has stdint.h */
+#elif defined (_MSC_VER) && _MSC_VER < 1600
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#  include <stdint.h>
+#endif
+
+#endif
+
+HB_BEGIN_DECLS
+
+
+typedef int hb_bool_t;
+
+typedef uint32_t hb_codepoint_t;
+typedef int32_t hb_position_t;
+typedef uint32_t hb_mask_t;
+
+typedef union _hb_var_int_t {
+  uint32_t u32;
+  int32_t i32;
+  uint16_t u16[2];
+  int16_t i16[2];
+  uint8_t u8[4];
+  int8_t i8[4];
+} hb_var_int_t;
+
+
+/* hb_tag_t */
+
+typedef uint32_t hb_tag_t;
+
+#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
+#define HB_UNTAG(tag)   ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
+
+#define HB_TAG_NONE HB_TAG(0,0,0,0)
+#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
+#define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff)
+
+/* len=-1 means str is NUL-terminated. */
+hb_tag_t
+hb_tag_from_string (const char *str, int len);
+
+/* buf should have 4 bytes. */
+void
+hb_tag_to_string (hb_tag_t tag, char *buf);
+
+
+/* hb_direction_t */
+
+typedef enum {
+  HB_DIRECTION_INVALID = 0,
+  HB_DIRECTION_LTR = 4,
+  HB_DIRECTION_RTL,
+  HB_DIRECTION_TTB,
+  HB_DIRECTION_BTT
+} hb_direction_t;
+
+/* len=-1 means str is NUL-terminated */
+hb_direction_t
+hb_direction_from_string (const char *str, int len);
+
+const char *
+hb_direction_to_string (hb_direction_t direction);
+
+#define HB_DIRECTION_IS_VALID(dir)      ((((unsigned int) (dir)) & ~3U) == 4)
+/* Direction must be valid for the following */
+#define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4)
+#define HB_DIRECTION_IS_VERTICAL(dir)   ((((unsigned int) (dir)) & ~1U) == 6)
+#define HB_DIRECTION_IS_FORWARD(dir)    ((((unsigned int) (dir)) & ~2U) == 4)
+#define HB_DIRECTION_IS_BACKWARD(dir)   ((((unsigned int) (dir)) & ~2U) == 5)
+#define HB_DIRECTION_REVERSE(dir)       ((hb_direction_t) (((unsigned int) (dir)) ^ 1))
+
+
+/* hb_language_t */
+
+typedef const struct hb_language_impl_t *hb_language_t;
+
+/* len=-1 means str is NUL-terminated */
+hb_language_t
+hb_language_from_string (const char *str, int len);
+
+const char *
+hb_language_to_string (hb_language_t language);
+
+#define HB_LANGUAGE_INVALID ((hb_language_t) NULL)
+
+hb_language_t
+hb_language_get_default (void);
+
+
+/* hb_script_t */
+
+/* http://unicode.org/iso15924/ */
+/* http://goo.gl/x9ilM */
+/* Unicode Character Database property: Script (sc) */
+typedef enum
+{
+  /*1.1*/ HB_SCRIPT_COMMON                      = HB_TAG ('Z','y','y','y'),
+  /*1.1*/ HB_SCRIPT_INHERITED                   = HB_TAG ('Z','i','n','h'),
+  /*5.0*/ HB_SCRIPT_UNKNOWN                     = HB_TAG ('Z','z','z','z'),
+
+  /*1.1*/ HB_SCRIPT_ARABIC                      = HB_TAG ('A','r','a','b'),
+  /*1.1*/ HB_SCRIPT_ARMENIAN                    = HB_TAG ('A','r','m','n'),
+  /*1.1*/ HB_SCRIPT_BENGALI                     = HB_TAG ('B','e','n','g'),
+  /*1.1*/ HB_SCRIPT_CYRILLIC                    = HB_TAG ('C','y','r','l'),
+  /*1.1*/ HB_SCRIPT_DEVANAGARI                  = HB_TAG ('D','e','v','a'),
+  /*1.1*/ HB_SCRIPT_GEORGIAN                    = HB_TAG ('G','e','o','r'),
+  /*1.1*/ HB_SCRIPT_GREEK                       = HB_TAG ('G','r','e','k'),
+  /*1.1*/ HB_SCRIPT_GUJARATI                    = HB_TAG ('G','u','j','r'),
+  /*1.1*/ HB_SCRIPT_GURMUKHI                    = HB_TAG ('G','u','r','u'),
+  /*1.1*/ HB_SCRIPT_HANGUL                      = HB_TAG ('H','a','n','g'),
+  /*1.1*/ HB_SCRIPT_HAN                         = HB_TAG ('H','a','n','i'),
+  /*1.1*/ HB_SCRIPT_HEBREW                      = HB_TAG ('H','e','b','r'),
+  /*1.1*/ HB_SCRIPT_HIRAGANA                    = HB_TAG ('H','i','r','a'),
+  /*1.1*/ HB_SCRIPT_KANNADA                     = HB_TAG ('K','n','d','a'),
+  /*1.1*/ HB_SCRIPT_KATAKANA                    = HB_TAG ('K','a','n','a'),
+  /*1.1*/ HB_SCRIPT_LAO                         = HB_TAG ('L','a','o','o'),
+  /*1.1*/ HB_SCRIPT_LATIN                       = HB_TAG ('L','a','t','n'),
+  /*1.1*/ HB_SCRIPT_MALAYALAM                   = HB_TAG ('M','l','y','m'),
+  /*1.1*/ HB_SCRIPT_ORIYA                       = HB_TAG ('O','r','y','a'),
+  /*1.1*/ HB_SCRIPT_TAMIL                       = HB_TAG ('T','a','m','l'),
+  /*1.1*/ HB_SCRIPT_TELUGU                      = HB_TAG ('T','e','l','u'),
+  /*1.1*/ HB_SCRIPT_THAI                        = HB_TAG ('T','h','a','i'),
+
+  /*2.0*/ HB_SCRIPT_TIBETAN                     = HB_TAG ('T','i','b','t'),
+
+  /*3.0*/ HB_SCRIPT_BOPOMOFO                    = HB_TAG ('B','o','p','o'),
+  /*3.0*/ HB_SCRIPT_BRAILLE                     = HB_TAG ('B','r','a','i'),
+  /*3.0*/ HB_SCRIPT_CANADIAN_SYLLABICS          = HB_TAG ('C','a','n','s'),
+  /*3.0*/ HB_SCRIPT_CHEROKEE                    = HB_TAG ('C','h','e','r'),
+  /*3.0*/ HB_SCRIPT_ETHIOPIC                    = HB_TAG ('E','t','h','i'),
+  /*3.0*/ HB_SCRIPT_KHMER                       = HB_TAG ('K','h','m','r'),
+  /*3.0*/ HB_SCRIPT_MONGOLIAN                   = HB_TAG ('M','o','n','g'),
+  /*3.0*/ HB_SCRIPT_MYANMAR                     = HB_TAG ('M','y','m','r'),
+  /*3.0*/ HB_SCRIPT_OGHAM                       = HB_TAG ('O','g','a','m'),
+  /*3.0*/ HB_SCRIPT_RUNIC                       = HB_TAG ('R','u','n','r'),
+  /*3.0*/ HB_SCRIPT_SINHALA                     = HB_TAG ('S','i','n','h'),
+  /*3.0*/ HB_SCRIPT_SYRIAC                      = HB_TAG ('S','y','r','c'),
+  /*3.0*/ HB_SCRIPT_THAANA                      = HB_TAG ('T','h','a','a'),
+  /*3.0*/ HB_SCRIPT_YI                          = HB_TAG ('Y','i','i','i'),
+
+  /*3.1*/ HB_SCRIPT_DESERET                     = HB_TAG ('D','s','r','t'),
+  /*3.1*/ HB_SCRIPT_GOTHIC                      = HB_TAG ('G','o','t','h'),
+  /*3.1*/ HB_SCRIPT_OLD_ITALIC                  = HB_TAG ('I','t','a','l'),
+
+  /*3.2*/ HB_SCRIPT_BUHID                       = HB_TAG ('B','u','h','d'),
+  /*3.2*/ HB_SCRIPT_HANUNOO                     = HB_TAG ('H','a','n','o'),
+  /*3.2*/ HB_SCRIPT_TAGALOG                     = HB_TAG ('T','g','l','g'),
+  /*3.2*/ HB_SCRIPT_TAGBANWA                    = HB_TAG ('T','a','g','b'),
+
+  /*4.0*/ HB_SCRIPT_CYPRIOT                     = HB_TAG ('C','p','r','t'),
+  /*4.0*/ HB_SCRIPT_LIMBU                       = HB_TAG ('L','i','m','b'),
+  /*4.0*/ HB_SCRIPT_LINEAR_B                    = HB_TAG ('L','i','n','b'),
+  /*4.0*/ HB_SCRIPT_OSMANYA                     = HB_TAG ('O','s','m','a'),
+  /*4.0*/ HB_SCRIPT_SHAVIAN                     = HB_TAG ('S','h','a','w'),
+  /*4.0*/ HB_SCRIPT_TAI_LE                      = HB_TAG ('T','a','l','e'),
+  /*4.0*/ HB_SCRIPT_UGARITIC                    = HB_TAG ('U','g','a','r'),
+
+  /*4.1*/ HB_SCRIPT_BUGINESE                    = HB_TAG ('B','u','g','i'),
+  /*4.1*/ HB_SCRIPT_COPTIC                      = HB_TAG ('C','o','p','t'),
+  /*4.1*/ HB_SCRIPT_GLAGOLITIC                  = HB_TAG ('G','l','a','g'),
+  /*4.1*/ HB_SCRIPT_KHAROSHTHI                  = HB_TAG ('K','h','a','r'),
+  /*4.1*/ HB_SCRIPT_NEW_TAI_LUE                 = HB_TAG ('T','a','l','u'),
+  /*4.1*/ HB_SCRIPT_OLD_PERSIAN                 = HB_TAG ('X','p','e','o'),
+  /*4.1*/ HB_SCRIPT_SYLOTI_NAGRI                = HB_TAG ('S','y','l','o'),
+  /*4.1*/ HB_SCRIPT_TIFINAGH                    = HB_TAG ('T','f','n','g'),
+
+  /*5.0*/ HB_SCRIPT_BALINESE                    = HB_TAG ('B','a','l','i'),
+  /*5.0*/ HB_SCRIPT_CUNEIFORM                   = HB_TAG ('X','s','u','x'),
+  /*5.0*/ HB_SCRIPT_NKO                         = HB_TAG ('N','k','o','o'),
+  /*5.0*/ HB_SCRIPT_PHAGS_PA                    = HB_TAG ('P','h','a','g'),
+  /*5.0*/ HB_SCRIPT_PHOENICIAN                  = HB_TAG ('P','h','n','x'),
+
+  /*5.1*/ HB_SCRIPT_CARIAN                      = HB_TAG ('C','a','r','i'),
+  /*5.1*/ HB_SCRIPT_CHAM                        = HB_TAG ('C','h','a','m'),
+  /*5.1*/ HB_SCRIPT_KAYAH_LI                    = HB_TAG ('K','a','l','i'),
+  /*5.1*/ HB_SCRIPT_LEPCHA                      = HB_TAG ('L','e','p','c'),
+  /*5.1*/ HB_SCRIPT_LYCIAN                      = HB_TAG ('L','y','c','i'),
+  /*5.1*/ HB_SCRIPT_LYDIAN                      = HB_TAG ('L','y','d','i'),
+  /*5.1*/ HB_SCRIPT_OL_CHIKI                    = HB_TAG ('O','l','c','k'),
+  /*5.1*/ HB_SCRIPT_REJANG                      = HB_TAG ('R','j','n','g'),
+  /*5.1*/ HB_SCRIPT_SAURASHTRA                  = HB_TAG ('S','a','u','r'),
+  /*5.1*/ HB_SCRIPT_SUNDANESE                   = HB_TAG ('S','u','n','d'),
+  /*5.1*/ HB_SCRIPT_VAI                         = HB_TAG ('V','a','i','i'),
+
+  /*5.2*/ HB_SCRIPT_AVESTAN                     = HB_TAG ('A','v','s','t'),
+  /*5.2*/ HB_SCRIPT_BAMUM                       = HB_TAG ('B','a','m','u'),
+  /*5.2*/ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS        = HB_TAG ('E','g','y','p'),
+  /*5.2*/ HB_SCRIPT_IMPERIAL_ARAMAIC            = HB_TAG ('A','r','m','i'),
+  /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI       = HB_TAG ('P','h','l','i'),
+  /*5.2*/ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN      = HB_TAG ('P','r','t','i'),
+  /*5.2*/ HB_SCRIPT_JAVANESE                    = HB_TAG ('J','a','v','a'),
+  /*5.2*/ HB_SCRIPT_KAITHI                      = HB_TAG ('K','t','h','i'),
+  /*5.2*/ HB_SCRIPT_LISU                        = HB_TAG ('L','i','s','u'),
+  /*5.2*/ HB_SCRIPT_MEETEI_MAYEK                = HB_TAG ('M','t','e','i'),
+  /*5.2*/ HB_SCRIPT_OLD_SOUTH_ARABIAN           = HB_TAG ('S','a','r','b'),
+  /*5.2*/ HB_SCRIPT_OLD_TURKIC                  = HB_TAG ('O','r','k','h'),
+  /*5.2*/ HB_SCRIPT_SAMARITAN                   = HB_TAG ('S','a','m','r'),
+  /*5.2*/ HB_SCRIPT_TAI_THAM                    = HB_TAG ('L','a','n','a'),
+  /*5.2*/ HB_SCRIPT_TAI_VIET                    = HB_TAG ('T','a','v','t'),
+
+  /*6.0*/ HB_SCRIPT_BATAK                       = HB_TAG ('B','a','t','k'),
+  /*6.0*/ HB_SCRIPT_BRAHMI                      = HB_TAG ('B','r','a','h'),
+  /*6.0*/ HB_SCRIPT_MANDAIC                     = HB_TAG ('M','a','n','d'),
+
+  /*6.1*/ HB_SCRIPT_CHAKMA                      = HB_TAG ('C','a','k','m'),
+  /*6.1*/ HB_SCRIPT_MEROITIC_CURSIVE            = HB_TAG ('M','e','r','c'),
+  /*6.1*/ HB_SCRIPT_MEROITIC_HIEROGLYPHS        = HB_TAG ('M','e','r','o'),
+  /*6.1*/ HB_SCRIPT_MIAO                        = HB_TAG ('P','l','r','d'),
+  /*6.1*/ HB_SCRIPT_SHARADA                     = HB_TAG ('S','h','r','d'),
+  /*6.1*/ HB_SCRIPT_SORA_SOMPENG                = HB_TAG ('S','o','r','a'),
+  /*6.1*/ HB_SCRIPT_TAKRI                       = HB_TAG ('T','a','k','r'),
+
+  /*
+   * Since: 0.9.30
+   */
+  /*7.0*/ HB_SCRIPT_BASSA_VAH                   = HB_TAG ('B','a','s','s'),
+  /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN          = HB_TAG ('A','g','h','b'),
+  /*7.0*/ HB_SCRIPT_DUPLOYAN                    = HB_TAG ('D','u','p','l'),
+  /*7.0*/ HB_SCRIPT_ELBASAN                     = HB_TAG ('E','l','b','a'),
+  /*7.0*/ HB_SCRIPT_GRANTHA                     = HB_TAG ('G','r','a','n'),
+  /*7.0*/ HB_SCRIPT_KHOJKI                      = HB_TAG ('K','h','o','j'),
+  /*7.0*/ HB_SCRIPT_KHUDAWADI                   = HB_TAG ('S','i','n','d'),
+  /*7.0*/ HB_SCRIPT_LINEAR_A                    = HB_TAG ('L','i','n','a'),
+  /*7.0*/ HB_SCRIPT_MAHAJANI                    = HB_TAG ('M','a','h','j'),
+  /*7.0*/ HB_SCRIPT_MANICHAEAN                  = HB_TAG ('M','a','n','i'),
+  /*7.0*/ HB_SCRIPT_MENDE_KIKAKUI               = HB_TAG ('M','e','n','d'),
+  /*7.0*/ HB_SCRIPT_MODI                        = HB_TAG ('M','o','d','i'),
+  /*7.0*/ HB_SCRIPT_MRO                         = HB_TAG ('M','r','o','o'),
+  /*7.0*/ HB_SCRIPT_NABATAEAN                   = HB_TAG ('N','b','a','t'),
+  /*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN           = HB_TAG ('N','a','r','b'),
+  /*7.0*/ HB_SCRIPT_OLD_PERMIC                  = HB_TAG ('P','e','r','m'),
+  /*7.0*/ HB_SCRIPT_PAHAWH_HMONG                = HB_TAG ('H','m','n','g'),
+  /*7.0*/ HB_SCRIPT_PALMYRENE                   = HB_TAG ('P','a','l','m'),
+  /*7.0*/ HB_SCRIPT_PAU_CIN_HAU                 = HB_TAG ('P','a','u','c'),
+  /*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI             = HB_TAG ('P','h','l','p'),
+  /*7.0*/ HB_SCRIPT_SIDDHAM                     = HB_TAG ('S','i','d','d'),
+  /*7.0*/ HB_SCRIPT_TIRHUTA                     = HB_TAG ('T','i','r','h'),
+  /*7.0*/ HB_SCRIPT_WARANG_CITI                 = HB_TAG ('W','a','r','a'),
+
+  /*8.0*/ HB_SCRIPT_AHOM                        = HB_TAG ('A','h','o','m'),
+  /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS       = HB_TAG ('H','l','u','w'),
+  /*8.0*/ HB_SCRIPT_HATRAN                      = HB_TAG ('H','a','t','r'),
+  /*8.0*/ HB_SCRIPT_MULTANI                     = HB_TAG ('M','u','l','t'),
+  /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN               = HB_TAG ('H','u','n','g'),
+  /*8.0*/ HB_SCRIPT_SIGNWRITING                 = HB_TAG ('S','g','n','w'),
+
+  /* No script set. */
+  HB_SCRIPT_INVALID                             = HB_TAG_NONE,
+
+  /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
+   * without risking undefined behavior.  Include both a signed and unsigned max,
+   * since technically enums are int, and indeed, hb_script_t ends up being signed.
+   * See this thread for technicalities:
+   *
+   *   http://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
+   */
+  _HB_SCRIPT_MAX_VALUE                          = HB_TAG_MAX, /*< skip >*/
+  _HB_SCRIPT_MAX_VALUE_SIGNED                   = HB_TAG_MAX_SIGNED /*< skip >*/
+
+} hb_script_t;
+
+
+/* Script functions */
+
+hb_script_t
+hb_script_from_iso15924_tag (hb_tag_t tag);
+
+/* sugar for tag_from_string() then script_from_iso15924_tag */
+/* len=-1 means s is NUL-terminated */
+hb_script_t
+hb_script_from_string (const char *s, int len);
+
+hb_tag_t
+hb_script_to_iso15924_tag (hb_script_t script);
+
+hb_direction_t
+hb_script_get_horizontal_direction (hb_script_t script);
+
+
+/* User data */
+
+typedef struct hb_user_data_key_t {
+  /*< private >*/
+  char unused;
+} hb_user_data_key_t;
+
+typedef void (*hb_destroy_func_t) (void *user_data);
+
+
+HB_END_DECLS
+
+#endif /* HB_COMMON_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1219 @@
+/*
+ * Copyright © 2012,2013  Mozilla Foundation.
+ * Copyright © 2012,2013  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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#define HB_SHAPER coretext
+#define hb_coretext_shaper_face_data_t CGFont
+#include "hb-shaper-impl-private.hh"
+
+#include "hb-coretext.h"
+
+
+#ifndef HB_DEBUG_CORETEXT
+#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
+#endif
+
+
+static void
+release_table_data (void *user_data)
+{
+  CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data);
+  CFRelease(cf_data);
+}
+
+static hb_blob_t *
+reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+  CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
+  CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
+  if (unlikely (!cf_data))
+    return NULL;
+
+  const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data));
+  const size_t length = CFDataGetLength (cf_data);
+  if (!data || !length)
+    return NULL;
+
+  return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
+                         reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)),
+                         release_table_data);
+}
+
+hb_face_t *
+hb_coretext_face_create (CGFontRef cg_font)
+{
+  return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), (hb_destroy_func_t) CGFontRelease);
+}
+
+
+HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
+HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
+
+
+/*
+ * shaper face data
+ */
+
+static void
+release_data (void *info, const void *data, size_t size)
+{
+  assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
+          hb_blob_get_data ((hb_blob_t *) info, NULL) == data);
+
+  hb_blob_destroy ((hb_blob_t *) info);
+}
+
+hb_coretext_shaper_face_data_t *
+_hb_coretext_shaper_face_data_create (hb_face_t *face)
+{
+  hb_coretext_shaper_face_data_t *data = NULL;
+
+  if (face->destroy == (hb_destroy_func_t) CGFontRelease)
+  {
+    data = CGFontRetain ((CGFontRef) face->user_data);
+  }
+  else
+  {
+    hb_blob_t *blob = hb_face_reference_blob (face);
+    unsigned int blob_length;
+    const char *blob_data = hb_blob_get_data (blob, &blob_length);
+    if (unlikely (!blob_length))
+      DEBUG_MSG (CORETEXT, face, "Face has empty blob");
+
+    CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
+    if (likely (provider))
+    {
+      data = CGFontCreateWithDataProvider (provider);
+      CGDataProviderRelease (provider);
+    }
+  }
+
+  if (unlikely (!data)) {
+    DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
+  }
+
+  return data;
+}
+
+void
+_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
+{
+  CFRelease (data);
+}
+
+/*
+ * Since: 0.9.10
+ */
+CGFontRef
+hb_coretext_face_get_cg_font (hb_face_t *face)
+{
+  if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
+  hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+  return face_data;
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_coretext_shaper_font_data_t {
+  CTFontRef ct_font;
+  CGFloat x_mult, y_mult; /* From CT space to HB space. */
+};
+
+hb_coretext_shaper_font_data_t *
+_hb_coretext_shaper_font_data_create (hb_font_t *font)
+{
+  if (unlikely (!hb_coretext_shaper_face_data_ensure (font->face))) return NULL;
+
+  hb_coretext_shaper_font_data_t *data = (hb_coretext_shaper_font_data_t *) calloc (1, sizeof (hb_coretext_shaper_font_data_t));
+  if (unlikely (!data))
+    return NULL;
+
+  hb_face_t *face = font->face;
+  hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+
+  /* Choose a CoreText font size and calculate multipliers to convert to HarfBuzz space. */
+  /* TODO: use upem instead of 36? */
+  CGFloat font_size = 36.; /* Default... */
+  /* No idea if the following is even a good idea. */
+  if (font->y_ppem)
+    font_size = font->y_ppem;
+
+  if (font_size < 0)
+    font_size = -font_size;
+  data->x_mult = (CGFloat) font->x_scale / font_size;
+  data->y_mult = (CGFloat) font->y_scale / font_size;
+  data->ct_font = CTFontCreateWithGraphicsFont (face_data, font_size, NULL, NULL);
+  if (unlikely (!data->ct_font)) {
+    DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
+    free (data);
+    return NULL;
+  }
+
+  return data;
+}
+
+void
+_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
+{
+  CFRelease (data->ct_font);
+  free (data);
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_coretext_shaper_shape_plan_data_t {};
+
+hb_coretext_shaper_shape_plan_data_t *
+_hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
+                                             const hb_feature_t *user_features HB_UNUSED,
+                                             unsigned int        num_user_features HB_UNUSED)
+{
+  return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED)
+{
+}
+
+CTFontRef
+hb_coretext_font_get_ct_font (hb_font_t *font)
+{
+  if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL;
+  hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+  return font_data->ct_font;
+}
+
+
+/*
+ * shaper
+ */
+
+struct feature_record_t {
+  unsigned int feature;
+  unsigned int setting;
+};
+
+struct active_feature_t {
+  feature_record_t rec;
+  unsigned int order;
+
+  static int cmp (const active_feature_t *a, const active_feature_t *b) {
+    return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
+           a->order < b->order ? -1 : a->order > b->order ? 1 :
+           a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
+           0;
+  }
+  bool operator== (const active_feature_t *f) {
+    return cmp (this, f) == 0;
+  }
+};
+
+struct feature_event_t {
+  unsigned int index;
+  bool start;
+  active_feature_t feature;
+
+  static int cmp (const feature_event_t *a, const feature_event_t *b) {
+    return a->index < b->index ? -1 : a->index > b->index ? 1 :
+           a->start < b->start ? -1 : a->start > b->start ? 1 :
+           active_feature_t::cmp (&a->feature, &b->feature);
+  }
+};
+
+struct range_record_t {
+  CTFontRef font;
+  unsigned int index_first; /* == start */
+  unsigned int index_last;  /* == end - 1 */
+};
+
+
+/* The following enum members are added in OS X 10.8. */
+#define kAltHalfWidthTextSelector               6
+#define kAltProportionalTextSelector            5
+#define kAlternateHorizKanaOffSelector          1
+#define kAlternateHorizKanaOnSelector           0
+#define kAlternateKanaType                      34
+#define kAlternateVertKanaOffSelector           3
+#define kAlternateVertKanaOnSelector            2
+#define kCaseSensitiveLayoutOffSelector         1
+#define kCaseSensitiveLayoutOnSelector          0
+#define kCaseSensitiveLayoutType                33
+#define kCaseSensitiveSpacingOffSelector        3
+#define kCaseSensitiveSpacingOnSelector         2
+#define kContextualAlternatesOffSelector        1
+#define kContextualAlternatesOnSelector         0
+#define kContextualAlternatesType               36
+#define kContextualLigaturesOffSelector         19
+#define kContextualLigaturesOnSelector          18
+#define kContextualSwashAlternatesOffSelector   5
+#define kContextualSwashAlternatesOnSelector    4
+#define kDefaultLowerCaseSelector               0
+#define kDefaultUpperCaseSelector               0
+#define kHistoricalLigaturesOffSelector         21
+#define kHistoricalLigaturesOnSelector          20
+#define kHojoCharactersSelector                 12
+#define kJIS2004CharactersSelector              11
+#define kLowerCasePetiteCapsSelector            2
+#define kLowerCaseSmallCapsSelector             1
+#define kLowerCaseType                          37
+#define kMathematicalGreekOffSelector           11
+#define kMathematicalGreekOnSelector            10
+#define kNLCCharactersSelector                  13
+#define kQuarterWidthTextSelector               4
+#define kScientificInferiorsSelector            4
+#define kStylisticAltEightOffSelector           17
+#define kStylisticAltEightOnSelector            16
+#define kStylisticAltEighteenOffSelector        37
+#define kStylisticAltEighteenOnSelector         36
+#define kStylisticAltElevenOffSelector          23
+#define kStylisticAltElevenOnSelector           22
+#define kStylisticAltFifteenOffSelector         31
+#define kStylisticAltFifteenOnSelector          30
+#define kStylisticAltFiveOffSelector            11
+#define kStylisticAltFiveOnSelector             10
+#define kStylisticAltFourOffSelector            9
+#define kStylisticAltFourOnSelector             8
+#define kStylisticAltFourteenOffSelector        29
+#define kStylisticAltFourteenOnSelector         28
+#define kStylisticAltNineOffSelector            19
+#define kStylisticAltNineOnSelector             18
+#define kStylisticAltNineteenOffSelector        39
+#define kStylisticAltNineteenOnSelector         38
+#define kStylisticAltOneOffSelector             3
+#define kStylisticAltOneOnSelector              2
+#define kStylisticAltSevenOffSelector           15
+#define kStylisticAltSevenOnSelector            14
+#define kStylisticAltSeventeenOffSelector       35
+#define kStylisticAltSeventeenOnSelector        34
+#define kStylisticAltSixOffSelector             13
+#define kStylisticAltSixOnSelector              12
+#define kStylisticAltSixteenOffSelector         33
+#define kStylisticAltSixteenOnSelector          32
+#define kStylisticAltTenOffSelector             21
+#define kStylisticAltTenOnSelector              20
+#define kStylisticAltThirteenOffSelector        27
+#define kStylisticAltThirteenOnSelector         26
+#define kStylisticAltThreeOffSelector           7
+#define kStylisticAltThreeOnSelector            6
+#define kStylisticAltTwelveOffSelector          25
+#define kStylisticAltTwelveOnSelector           24
+#define kStylisticAltTwentyOffSelector          41
+#define kStylisticAltTwentyOnSelector           40
+#define kStylisticAltTwoOffSelector             5
+#define kStylisticAltTwoOnSelector              4
+#define kStylisticAlternativesType              35
+#define kSwashAlternatesOffSelector             3
+#define kSwashAlternatesOnSelector              2
+#define kThirdWidthTextSelector                 3
+#define kTraditionalNamesCharactersSelector     14
+#define kUpperCasePetiteCapsSelector            2
+#define kUpperCaseSmallCapsSelector             1
+#define kUpperCaseType                          38
+
+/* Table data courtesy of Apple. */
+static const struct feature_mapping_t {
+    FourCharCode otFeatureTag;
+    uint16_t aatFeatureType;
+    uint16_t selectorToEnable;
+    uint16_t selectorToDisable;
+} feature_mappings[] = {
+    { 'c2pc',   kUpperCaseType,             kUpperCasePetiteCapsSelector,           kDefaultUpperCaseSelector },
+    { 'c2sc',   kUpperCaseType,             kUpperCaseSmallCapsSelector,            kDefaultUpperCaseSelector },
+    { 'calt',   kContextualAlternatesType,  kContextualAlternatesOnSelector,        kContextualAlternatesOffSelector },
+    { 'case',   kCaseSensitiveLayoutType,   kCaseSensitiveLayoutOnSelector,         kCaseSensitiveLayoutOffSelector },
+    { 'clig',   kLigaturesType,             kContextualLigaturesOnSelector,         kContextualLigaturesOffSelector },
+    { 'cpsp',   kCaseSensitiveLayoutType,   kCaseSensitiveSpacingOnSelector,        kCaseSensitiveSpacingOffSelector },
+    { 'cswh',   kContextualAlternatesType,  kContextualSwashAlternatesOnSelector,   kContextualSwashAlternatesOffSelector },
+    { 'dlig',   kLigaturesType,             kRareLigaturesOnSelector,               kRareLigaturesOffSelector },
+    { 'expt',   kCharacterShapeType,        kExpertCharactersSelector,              16 },
+    { 'frac',   kFractionsType,             kDiagonalFractionsSelector,             kNoFractionsSelector },
+    { 'fwid',   kTextSpacingType,           kMonospacedTextSelector,                7 },
+    { 'halt',   kTextSpacingType,           kAltHalfWidthTextSelector,              7 },
+    { 'hist',   kLigaturesType,             kHistoricalLigaturesOnSelector,         kHistoricalLigaturesOffSelector },
+    { 'hkna',   kAlternateKanaType,         kAlternateHorizKanaOnSelector,          kAlternateHorizKanaOffSelector, },
+    { 'hlig',   kLigaturesType,             kHistoricalLigaturesOnSelector,         kHistoricalLigaturesOffSelector },
+    { 'hngl',   kTransliterationType,       kHanjaToHangulSelector,                 kNoTransliterationSelector },
+    { 'hojo',   kCharacterShapeType,        kHojoCharactersSelector,                16 },
+    { 'hwid',   kTextSpacingType,           kHalfWidthTextSelector,                 7 },
+    { 'ital',   kItalicCJKRomanType,        kCJKItalicRomanOnSelector,              kCJKItalicRomanOffSelector },
+    { 'jp04',   kCharacterShapeType,        kJIS2004CharactersSelector,             16 },
+    { 'jp78',   kCharacterShapeType,        kJIS1978CharactersSelector,             16 },
+    { 'jp83',   kCharacterShapeType,        kJIS1983CharactersSelector,             16 },
+    { 'jp90',   kCharacterShapeType,        kJIS1990CharactersSelector,             16 },
+    { 'liga',   kLigaturesType,             kCommonLigaturesOnSelector,             kCommonLigaturesOffSelector },
+    { 'lnum',   kNumberCaseType,            kUpperCaseNumbersSelector,              2 },
+    { 'mgrk',   kMathematicalExtrasType,    kMathematicalGreekOnSelector,           kMathematicalGreekOffSelector },
+    { 'nlck',   kCharacterShapeType,        kNLCCharactersSelector,                 16 },
+    { 'onum',   kNumberCaseType,            kLowerCaseNumbersSelector,              2 },
+    { 'ordn',   kVerticalPositionType,      kOrdinalsSelector,                      kNormalPositionSelector },
+    { 'palt',   kTextSpacingType,           kAltProportionalTextSelector,           7 },
+    { 'pcap',   kLowerCaseType,             kLowerCasePetiteCapsSelector,           kDefaultLowerCaseSelector },
+    { 'pkna',   kTextSpacingType,           kProportionalTextSelector,              7 },
+    { 'pnum',   kNumberSpacingType,         kProportionalNumbersSelector,           4 },
+    { 'pwid',   kTextSpacingType,           kProportionalTextSelector,              7 },
+    { 'qwid',   kTextSpacingType,           kQuarterWidthTextSelector,              7 },
+    { 'ruby',   kRubyKanaType,              kRubyKanaOnSelector,                    kRubyKanaOffSelector },
+    { 'sinf',   kVerticalPositionType,      kScientificInferiorsSelector,           kNormalPositionSelector },
+    { 'smcp',   kLowerCaseType,             kLowerCaseSmallCapsSelector,            kDefaultLowerCaseSelector },
+    { 'smpl',   kCharacterShapeType,        kSimplifiedCharactersSelector,          16 },
+    { 'ss01',   kStylisticAlternativesType, kStylisticAltOneOnSelector,             kStylisticAltOneOffSelector },
+    { 'ss02',   kStylisticAlternativesType, kStylisticAltTwoOnSelector,             kStylisticAltTwoOffSelector },
+    { 'ss03',   kStylisticAlternativesType, kStylisticAltThreeOnSelector,           kStylisticAltThreeOffSelector },
+    { 'ss04',   kStylisticAlternativesType, kStylisticAltFourOnSelector,            kStylisticAltFourOffSelector },
+    { 'ss05',   kStylisticAlternativesType, kStylisticAltFiveOnSelector,            kStylisticAltFiveOffSelector },
+    { 'ss06',   kStylisticAlternativesType, kStylisticAltSixOnSelector,             kStylisticAltSixOffSelector },
+    { 'ss07',   kStylisticAlternativesType, kStylisticAltSevenOnSelector,           kStylisticAltSevenOffSelector },
+    { 'ss08',   kStylisticAlternativesType, kStylisticAltEightOnSelector,           kStylisticAltEightOffSelector },
+    { 'ss09',   kStylisticAlternativesType, kStylisticAltNineOnSelector,            kStylisticAltNineOffSelector },
+    { 'ss10',   kStylisticAlternativesType, kStylisticAltTenOnSelector,             kStylisticAltTenOffSelector },
+    { 'ss11',   kStylisticAlternativesType, kStylisticAltElevenOnSelector,          kStylisticAltElevenOffSelector },
+    { 'ss12',   kStylisticAlternativesType, kStylisticAltTwelveOnSelector,          kStylisticAltTwelveOffSelector },
+    { 'ss13',   kStylisticAlternativesType, kStylisticAltThirteenOnSelector,        kStylisticAltThirteenOffSelector },
+    { 'ss14',   kStylisticAlternativesType, kStylisticAltFourteenOnSelector,        kStylisticAltFourteenOffSelector },
+    { 'ss15',   kStylisticAlternativesType, kStylisticAltFifteenOnSelector,         kStylisticAltFifteenOffSelector },
+    { 'ss16',   kStylisticAlternativesType, kStylisticAltSixteenOnSelector,         kStylisticAltSixteenOffSelector },
+    { 'ss17',   kStylisticAlternativesType, kStylisticAltSeventeenOnSelector,       kStylisticAltSeventeenOffSelector },
+    { 'ss18',   kStylisticAlternativesType, kStylisticAltEighteenOnSelector,        kStylisticAltEighteenOffSelector },
+    { 'ss19',   kStylisticAlternativesType, kStylisticAltNineteenOnSelector,        kStylisticAltNineteenOffSelector },
+    { 'ss20',   kStylisticAlternativesType, kStylisticAltTwentyOnSelector,          kStylisticAltTwentyOffSelector },
+    { 'subs',   kVerticalPositionType,      kInferiorsSelector,                     kNormalPositionSelector },
+    { 'sups',   kVerticalPositionType,      kSuperiorsSelector,                     kNormalPositionSelector },
+    { 'swsh',   kContextualAlternatesType,  kSwashAlternatesOnSelector,             kSwashAlternatesOffSelector },
+    { 'titl',   kStyleOptionsType,          kTitlingCapsSelector,                   kNoStyleOptionsSelector },
+    { 'tnam',   kCharacterShapeType,        kTraditionalNamesCharactersSelector,    16 },
+    { 'tnum',   kNumberSpacingType,         kMonospacedNumbersSelector,             4 },
+    { 'trad',   kCharacterShapeType,        kTraditionalCharactersSelector,         16 },
+    { 'twid',   kTextSpacingType,           kThirdWidthTextSelector,                7 },
+    { 'unic',   kLetterCaseType,            14,                                     15 },
+    { 'valt',   kTextSpacingType,           kAltProportionalTextSelector,           7 },
+    { 'vert',   kVerticalSubstitutionType,  kSubstituteVerticalFormsOnSelector,     kSubstituteVerticalFormsOffSelector },
+    { 'vhal',   kTextSpacingType,           kAltHalfWidthTextSelector,              7 },
+    { 'vkna',   kAlternateKanaType,         kAlternateVertKanaOnSelector,           kAlternateVertKanaOffSelector },
+    { 'vpal',   kTextSpacingType,           kAltProportionalTextSelector,           7 },
+    { 'vrt2',   kVerticalSubstitutionType,  kSubstituteVerticalFormsOnSelector,     kSubstituteVerticalFormsOffSelector },
+    { 'zero',   kTypographicExtrasType,     kSlashedZeroOnSelector,                 kSlashedZeroOffSelector },
+};
+
+static int
+_hb_feature_mapping_cmp (const void *key_, const void *entry_)
+{
+  unsigned int key = * (unsigned int *) key_;
+  const feature_mapping_t * entry = (const feature_mapping_t *) entry_;
+  return key < entry->otFeatureTag ? -1 :
+         key > entry->otFeatureTag ? 1 :
+         0;
+}
+
+hb_bool_t
+_hb_coretext_shape (hb_shape_plan_t    *shape_plan,
+                    hb_font_t          *font,
+                    hb_buffer_t        *buffer,
+                    const hb_feature_t *features,
+                    unsigned int        num_features)
+{
+  hb_face_t *face = font->face;
+  hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+  hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+
+  /* Attach marks to their bases, to match the 'ot' shaper.
+   * Adapted from hb-ot-shape:hb_form_clusters().
+   * Note that this only makes us be closer to the 'ot' shaper,
+   * but by no means the same.  For example, if there's
+   * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will
+   * continue pointing to B2 even though B2 was merged into B1's
+   * cluster... */
+  {
+    hb_unicode_funcs_t *unicode = buffer->unicode;
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    for (unsigned int i = 1; i < count; i++)
+      if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i].codepoint)))
+        buffer->merge_clusters (i - 1, i + 1);
+  }
+
+  hb_auto_array_t<feature_record_t> feature_records;
+  hb_auto_array_t<range_record_t> range_records;
+
+  /*
+   * Set up features.
+   * (copied + modified from code from hb-uniscribe.cc)
+   */
+  if (num_features)
+  {
+    /* Sort features by start/end events. */
+    hb_auto_array_t<feature_event_t> feature_events;
+    for (unsigned int i = 0; i < num_features; i++)
+    {
+      const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag,
+                                                                               feature_mappings,
+                                                                               ARRAY_LENGTH (feature_mappings),
+                                                                               sizeof (feature_mappings[0]),
+                                                                               _hb_feature_mapping_cmp);
+      if (!mapping)
+        continue;
+
+      active_feature_t feature;
+      feature.rec.feature = mapping->aatFeatureType;
+      feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable;
+      feature.order = i;
+
+      feature_event_t *event;
+
+      event = feature_events.push ();
+      if (unlikely (!event))
+        goto fail_features;
+      event->index = features[i].start;
+      event->start = true;
+      event->feature = feature;
+
+      event = feature_events.push ();
+      if (unlikely (!event))
+        goto fail_features;
+      event->index = features[i].end;
+      event->start = false;
+      event->feature = feature;
+    }
+    feature_events.qsort ();
+    /* Add a strategic final event. */
+    {
+      active_feature_t feature;
+      feature.rec.feature = HB_TAG_NONE;
+      feature.rec.setting = 0;
+      feature.order = num_features + 1;
+
+      feature_event_t *event = feature_events.push ();
+      if (unlikely (!event))
+        goto fail_features;
+      event->index = 0; /* This value does magic. */
+      event->start = false;
+      event->feature = feature;
+    }
+
+    /* Scan events and save features for each range. */
+    hb_auto_array_t<active_feature_t> active_features;
+    unsigned int last_index = 0;
+    for (unsigned int i = 0; i < feature_events.len; i++)
+    {
+      feature_event_t *event = &feature_events[i];
+
+      if (event->index != last_index)
+      {
+        /* Save a snapshot of active features and the range. */
+        range_record_t *range = range_records.push ();
+        if (unlikely (!range))
+          goto fail_features;
+
+        if (active_features.len)
+        {
+          CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+          /* TODO sort and resolve conflicting features? */
+          /* active_features.qsort (); */
+          for (unsigned int j = 0; j < active_features.len; j++)
+          {
+            CFStringRef keys[2] = {
+              kCTFontFeatureTypeIdentifierKey,
+              kCTFontFeatureSelectorIdentifierKey
+            };
+            CFNumberRef values[2] = {
+              CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature),
+              CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
+            };
+            CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault,
+                                                       (const void **) keys,
+                                                       (const void **) values,
+                                                       2,
+                                                       &kCFTypeDictionaryKeyCallBacks,
+                                                       &kCFTypeDictionaryValueCallBacks);
+            CFRelease (values[0]);
+            CFRelease (values[1]);
+
+            CFArrayAppendValue (features_array, dict);
+            CFRelease (dict);
+
+          }
+
+          CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
+                                                           (const void **) &kCTFontFeatureSettingsAttribute,
+                                                           (const void **) &features_array,
+                                                           1,
+                                                           &kCFTypeDictionaryKeyCallBacks,
+                                                           &kCFTypeDictionaryValueCallBacks);
+          CFRelease (features_array);
+
+          CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
+          CFRelease (attributes);
+
+          range->font = CTFontCreateCopyWithAttributes (font_data->ct_font, 0.0, NULL, font_desc);
+          CFRelease (font_desc);
+        }
+        else
+        {
+          range->font = NULL;
+        }
+
+        range->index_first = last_index;
+        range->index_last  = event->index - 1;
+
+        last_index = event->index;
+      }
+
+      if (event->start) {
+        active_feature_t *feature = active_features.push ();
+        if (unlikely (!feature))
+          goto fail_features;
+        *feature = event->feature;
+      } else {
+        active_feature_t *feature = active_features.find (&event->feature);
+        if (feature)
+          active_features.remove (feature - active_features.array);
+      }
+    }
+
+    if (!range_records.len) /* No active feature found. */
+      goto fail_features;
+  }
+  else
+  {
+  fail_features:
+    num_features = 0;
+  }
+
+  unsigned int scratch_size;
+  hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
+
+#define ALLOCATE_ARRAY(Type, name, len, on_no_room) \
+  Type *name = (Type *) scratch; \
+  { \
+    unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
+    if (unlikely (_consumed > scratch_size)) \
+    { \
+      on_no_room; \
+      assert (0); \
+    } \
+    scratch += _consumed; \
+    scratch_size -= _consumed; \
+  }
+
+  ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/);
+  unsigned int chars_len = 0;
+  for (unsigned int i = 0; i < buffer->len; i++) {
+    hb_codepoint_t c = buffer->info[i].codepoint;
+    if (likely (c <= 0xFFFFu))
+      pchars[chars_len++] = c;
+    else if (unlikely (c > 0x10FFFFu))
+      pchars[chars_len++] = 0xFFFDu;
+    else {
+      pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
+      pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1));
+    }
+  }
+
+  ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, /*nothing*/);
+  chars_len = 0;
+  for (unsigned int i = 0; i < buffer->len; i++)
+  {
+    hb_codepoint_t c = buffer->info[i].codepoint;
+    unsigned int cluster = buffer->info[i].cluster;
+    log_clusters[chars_len++] = cluster;
+    if (hb_in_range (c, 0x10000u, 0x10FFFFu))
+      log_clusters[chars_len++] = cluster; /* Surrogates. */
+  }
+
+#define FAIL(...) \
+  HB_STMT_START { \
+    DEBUG_MSG (CORETEXT, NULL, __VA_ARGS__); \
+    ret = false; \
+    goto fail; \
+  } HB_STMT_END;
+
+  bool ret = true;
+  CFStringRef string_ref = NULL;
+  CTLineRef line = NULL;
+
+  if (0)
+  {
+resize_and_retry:
+    DEBUG_MSG (CORETEXT, buffer, "Buffer resize");
+    /* string_ref uses the scratch-buffer for backing store, and line references
+     * string_ref (via attr_string).  We must release those before resizing buffer. */
+    assert (string_ref);
+    assert (line);
+    CFRelease (string_ref);
+    CFRelease (line);
+    string_ref = NULL;
+    line = NULL;
+
+    /* Get previous start-of-scratch-area, that we use later for readjusting
+     * our existing scratch arrays. */
+    unsigned int old_scratch_used;
+    hb_buffer_t::scratch_buffer_t *old_scratch;
+    old_scratch = buffer->get_scratch_buffer (&old_scratch_used);
+    old_scratch_used = scratch - old_scratch;
+
+    if (unlikely (!buffer->ensure (buffer->allocated * 2)))
+      FAIL ("Buffer resize failed");
+
+    /* Adjust scratch, pchars, and log_cluster arrays.  This is ugly, but really the
+     * cleanest way to do without completely restructuring the rest of this shaper. */
+    scratch = buffer->get_scratch_buffer (&scratch_size);
+    pchars = reinterpret_cast<UniChar *> (((char *) scratch + ((char *) pchars - (char *) old_scratch)));
+    log_clusters = reinterpret_cast<unsigned int *> (((char *) scratch + ((char *) log_clusters - (char *) old_scratch)));
+    scratch += old_scratch_used;
+    scratch_size -= old_scratch_used;
+  }
+retry:
+  {
+    string_ref = CFStringCreateWithCharactersNoCopy (NULL,
+                                                     pchars, chars_len,
+                                                     kCFAllocatorNull);
+    if (unlikely (!string_ref))
+      FAIL ("CFStringCreateWithCharactersNoCopy failed");
+
+    /* Create an attributed string, populate it, and create a line from it, then release attributed string. */
+    {
+      CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (kCFAllocatorDefault,
+                                                                                  chars_len);
+      if (unlikely (!attr_string))
+        FAIL ("CFAttributedStringCreateMutable failed");
+      CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref);
+      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
+      {
+        CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
+                                        kCTVerticalFormsAttributeName, kCFBooleanTrue);
+      }
+
+      if (buffer->props.language)
+      {
+/* What's the iOS equivalent of this check?
+ * The symbols was introduced in iOS 7.0.
+ * At any rate, our fallback is safe and works fine. */
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
+#  define kCTLanguageAttributeName CFSTR ("NSLanguage")
+#endif
+        CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
+                                                            hb_language_to_string (buffer->props.language),
+                                                            kCFStringEncodingUTF8,
+                                                            kCFAllocatorNull);
+        if (unlikely (!lang))
+          FAIL ("CFStringCreateWithCStringNoCopy failed");
+        CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
+                                        kCTLanguageAttributeName, lang);
+        CFRelease (lang);
+      }
+      CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
+                                      kCTFontAttributeName, font_data->ct_font);
+
+      if (num_features)
+      {
+        unsigned int start = 0;
+        range_record_t *last_range = &range_records[0];
+        for (unsigned int k = 0; k < chars_len; k++)
+        {
+          range_record_t *range = last_range;
+          while (log_clusters[k] < range->index_first)
+            range--;
+          while (log_clusters[k] > range->index_last)
+            range++;
+          if (range != last_range)
+          {
+            if (last_range->font)
+              CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, k - start),
+                                              kCTFontAttributeName, last_range->font);
+
+            start = k;
+          }
+
+          last_range = range;
+        }
+        if (start != chars_len && last_range->font)
+          CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, chars_len - start),
+                                          kCTFontAttributeName, last_range->font);
+      }
+
+      int level = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
+      CFNumberRef level_number = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &level);
+      CFDictionaryRef options = CFDictionaryCreate (kCFAllocatorDefault,
+                                                    (const void **) &kCTTypesetterOptionForcedEmbeddingLevel,
+                                                    (const void **) &level_number,
+                                                    1,
+                                                    &kCFTypeDictionaryKeyCallBacks,
+                                                    &kCFTypeDictionaryValueCallBacks);
+      if (unlikely (!options))
+        FAIL ("CFDictionaryCreate failed");
+
+      CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options);
+      CFRelease (options);
+      CFRelease (attr_string);
+      if (unlikely (!typesetter))
+        FAIL ("CTTypesetterCreateWithAttributedStringAndOptions failed");
+
+      line = CTTypesetterCreateLine (typesetter, CFRangeMake(0, 0));
+      CFRelease (typesetter);
+      if (unlikely (!line))
+        FAIL ("CTTypesetterCreateLine failed");
+    }
+
+    CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
+    unsigned int num_runs = CFArrayGetCount (glyph_runs);
+    DEBUG_MSG (CORETEXT, NULL, "Num runs: %d", num_runs);
+
+    buffer->len = 0;
+    uint32_t status_and = ~0, status_or = 0;
+    double advances_so_far = 0;
+    /* For right-to-left runs, CoreText returns the glyphs positioned such that
+     * any trailing whitespace is to the left of (0,0).  Adjust coordinate system
+     * to fix for that.  Test with any RTL string with trailing spaces.
+     * https://code.google.com/p/chromium/issues/detail?id=469028
+     */
+    if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+    {
+      advances_so_far -= CTLineGetTrailingWhitespaceWidth (line);
+      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
+          advances_so_far = -advances_so_far;
+    }
+
+    const CFRange range_all = CFRangeMake (0, 0);
+
+    for (unsigned int i = 0; i < num_runs; i++)
+    {
+      CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i));
+      CTRunStatus run_status = CTRunGetStatus (run);
+      status_or  |= run_status;
+      status_and &= run_status;
+      DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
+      double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL);
+      if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
+          run_advance = -run_advance;
+      DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
+
+      /* CoreText does automatic font fallback (AKA "cascading") for  characters
+       * not supported by the requested font, and provides no way to turn it off,
+       * so we must detect if the returned run uses a font other than the requested
+       * one and fill in the buffer with .notdef glyphs instead of random glyph
+       * indices from a different font.
+       */
+      CFDictionaryRef attributes = CTRunGetAttributes (run);
+      CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
+      if (!CFEqual (run_ct_font, font_data->ct_font))
+      {
+        /* The run doesn't use our main font instance.  We have to figure out
+         * whether font fallback happened, or this is just CoreText giving us
+         * another CTFont using the same underlying CGFont.  CoreText seems
+         * to do that in a variety of situations, one of which being vertical
+         * text, but also perhaps for caching reasons.
+         *
+         * First, see if it uses any of our subfonts created to set font features...
+         *
+         * Next, compare the CGFont to the one we used to create our fonts.
+         * Even this doesn't work all the time.
+         *
+         * Finally, we compare PS names, which I don't think are unique...
+         *
+         * Looks like if we really want to be sure here we have to modify the
+         * font to change the name table, similar to what we do in the uniscribe
+         * backend.
+         *
+         * However, even that wouldn't work if we were passed in the CGFont to
+         * begin with.
+         *
+         * Webkit uses a slightly different approach: it installs LastResort
+         * as fallback chain, and then checks PS name of used font against
+         * LastResort.  That one is safe for any font except for LastResort,
+         * as opposed to ours, which can fail if we are using any uninstalled
+         * font that has the same name as an installed font.
+         *
+         * See: http://github.com/behdad/harfbuzz/pull/36
+         */
+        bool matched = false;
+        for (unsigned int i = 0; i < range_records.len; i++)
+          if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font))
+          {
+            matched = true;
+            break;
+          }
+        if (!matched)
+        {
+          CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
+          if (run_cg_font)
+          {
+            matched = CFEqual (run_cg_font, face_data);
+            CFRelease (run_cg_font);
+          }
+        }
+        if (!matched)
+        {
+          CFStringRef font_ps_name = CTFontCopyName (font_data->ct_font, kCTFontPostScriptNameKey);
+          CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey);
+          CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0);
+          CFRelease (run_ps_name);
+          CFRelease (font_ps_name);
+          if (result == kCFCompareEqualTo)
+            matched = true;
+        }
+        if (!matched)
+        {
+          CFRange range = CTRunGetStringRange (run);
+          DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
+                     range.location, range.location + range.length);
+          if (!buffer->ensure_inplace (buffer->len + range.length))
+            goto resize_and_retry;
+          hb_glyph_info_t *info = buffer->info + buffer->len;
+
+          hb_codepoint_t notdef = 0;
+          hb_direction_t dir = buffer->props.direction;
+          hb_position_t x_advance, y_advance, x_offset, y_offset;
+          hb_font_get_glyph_advance_for_direction (font, notdef, dir, &x_advance, &y_advance);
+          hb_font_get_glyph_origin_for_direction (font, notdef, dir, &x_offset, &y_offset);
+          hb_position_t advance = x_advance + y_advance;
+          x_offset = -x_offset;
+          y_offset = -y_offset;
+
+          unsigned int old_len = buffer->len;
+          for (CFIndex j = range.location; j < range.location + range.length; j++)
+          {
+              UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
+              if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j)
+              {
+                ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
+                if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu))
+                  /* This is the second of a surrogate pair.  Don't need .notdef
+                   * for this one. */
+                  continue;
+              }
+              if (buffer->unicode->is_default_ignorable (ch))
+                continue;
+
+              info->codepoint = notdef;
+              info->cluster = log_clusters[j];
+
+              info->mask = advance;
+              info->var1.i32 = x_offset;
+              info->var2.i32 = y_offset;
+
+              info++;
+              buffer->len++;
+          }
+          if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
+            buffer->reverse_range (old_len, buffer->len);
+          advances_so_far += run_advance;
+          continue;
+        }
+      }
+
+      unsigned int num_glyphs = CTRunGetGlyphCount (run);
+      if (num_glyphs == 0)
+        continue;
+
+      if (!buffer->ensure_inplace (buffer->len + num_glyphs))
+        goto resize_and_retry;
+
+      hb_glyph_info_t *run_info = buffer->info + buffer->len;
+
+      /* Testing used to indicate that CTRunGetGlyphsPtr, etc (almost?) always
+       * succeed, and so copying data to our own buffer will be rare.  Reports
+       * have it that this changed in OS X 10.10 Yosemite, and NULL is returned
+       * frequently.  At any rate, we can test that codepath by setting USE_PTR
+       * to false. */
+
+#define USE_PTR true
+
+#define SCRATCH_SAVE() \
+  unsigned int scratch_size_saved = scratch_size; \
+  hb_buffer_t::scratch_buffer_t *scratch_saved = scratch
+
+#define SCRATCH_RESTORE() \
+  scratch_size = scratch_size_saved; \
+  scratch = scratch_saved;
+
+      { /* Setup glyphs */
+        SCRATCH_SAVE();
+        const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL;
+        if (!glyphs) {
+          ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry);
+          CTRunGetGlyphs (run, range_all, glyph_buf);
+          glyphs = glyph_buf;
+        }
+        const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : NULL;
+        if (!string_indices) {
+          ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs, goto resize_and_retry);
+          CTRunGetStringIndices (run, range_all, index_buf);
+          string_indices = index_buf;
+        }
+        hb_glyph_info_t *info = run_info;
+        for (unsigned int j = 0; j < num_glyphs; j++)
+        {
+          info->codepoint = glyphs[j];
+          info->cluster = log_clusters[string_indices[j]];
+          info++;
+        }
+        SCRATCH_RESTORE();
+      }
+      {
+        /* Setup positions.
+         * Note that CoreText does not return advances for glyphs.  As such,
+         * for all but last glyph, we use the delta position to next glyph as
+         * advance (in the advance direction only), and for last glyph we set
+         * whatever is needed to make the whole run's advance add up. */
+        SCRATCH_SAVE();
+        const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL;
+        if (!positions) {
+          ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry);
+          CTRunGetPositions (run, range_all, position_buf);
+          positions = position_buf;
+        }
+        hb_glyph_info_t *info = run_info;
+        CGFloat x_mult = font_data->x_mult, y_mult = font_data->y_mult;
+        if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+        {
+          hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult;
+          for (unsigned int j = 0; j < num_glyphs; j++)
+          {
+            double advance;
+            if (likely (j + 1 < num_glyphs))
+              advance = positions[j + 1].x - positions[j].x;
+            else /* last glyph */
+              advance = run_advance - (positions[j].x - positions[0].x);
+            info->mask = advance * x_mult;
+            info->var1.i32 = x_offset;
+            info->var2.i32 = positions[j].y * y_mult;
+            info++;
+          }
+        }
+        else
+        {
+          hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult;
+          for (unsigned int j = 0; j < num_glyphs; j++)
+          {
+            double advance;
+            if (likely (j + 1 < num_glyphs))
+              advance = positions[j + 1].y - positions[j].y;
+            else /* last glyph */
+              advance = run_advance - (positions[j].y - positions[0].y);
+            info->mask = advance * y_mult;
+            info->var1.i32 = positions[j].x * x_mult;
+            info->var2.i32 = y_offset;
+            info++;
+          }
+        }
+        SCRATCH_RESTORE();
+        advances_so_far += run_advance;
+      }
+#undef SCRATCH_RESTORE
+#undef SCRATCH_SAVE
+#undef USE_PTR
+#undef ALLOCATE_ARRAY
+
+      buffer->len += num_glyphs;
+    }
+
+    /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel,
+     * or if it does, it doesn't resepct it.  So we get runs with wrong
+     * directions.  As such, disable the assert...  It wouldn't crash, but
+     * cursoring will be off...
+     *
+     * http://crbug.com/419769
+     */
+    if (0)
+    {
+      /* Make sure all runs had the expected direction. */
+      bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+      assert (bool (status_and & kCTRunStatusRightToLeft) == backward);
+      assert (bool (status_or  & kCTRunStatusRightToLeft) == backward);
+    }
+
+    buffer->clear_positions ();
+
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    hb_glyph_position_t *pos = buffer->pos;
+    if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
+      for (unsigned int i = 0; i < count; i++)
+      {
+        pos->x_advance = info->mask;
+        pos->x_offset = info->var1.i32;
+        pos->y_offset = info->var2.i32;
+        info++, pos++;
+      }
+    else
+      for (unsigned int i = 0; i < count; i++)
+      {
+        pos->y_advance = info->mask;
+        pos->x_offset = info->var1.i32;
+        pos->y_offset = info->var2.i32;
+        info++, pos++;
+      }
+
+    /* Fix up clusters so that we never return out-of-order indices;
+     * if core text has reordered glyphs, we'll merge them to the
+     * beginning of the reordered cluster.  CoreText is nice enough
+     * to tell us whenever it has produced nonmonotonic results...
+     * Note that we assume the input clusters were nonmonotonic to
+     * begin with.
+     *
+     * This does *not* mean we'll form the same clusters as Uniscribe
+     * or the native OT backend, only that the cluster indices will be
+     * monotonic in the output buffer. */
+    if (count > 1 && (status_or & kCTRunStatusNonMonotonic))
+    {
+      hb_glyph_info_t *info = buffer->info;
+      if (HB_DIRECTION_IS_FORWARD (buffer->props.direction))
+      {
+        unsigned int cluster = info[count - 1].cluster;
+        for (unsigned int i = count - 1; i > 0; i--)
+        {
+          cluster = MIN (cluster, info[i - 1].cluster);
+          info[i - 1].cluster = cluster;
+        }
+      }
+      else
+      {
+        unsigned int cluster = info[0].cluster;
+        for (unsigned int i = 1; i < count; i++)
+        {
+          cluster = MIN (cluster, info[i].cluster);
+          info[i].cluster = cluster;
+        }
+      }
+    }
+  }
+
+#undef FAIL
+
+fail:
+  if (string_ref)
+    CFRelease (string_ref);
+  if (line)
+    CFRelease (line);
+
+  for (unsigned int i = 0; i < range_records.len; i++)
+    if (range_records[i].font)
+      CFRelease (range_records[i].font);
+
+  return ret;
+}
+
+
+/*
+ * AAT shaper
+ */
+
+HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face)
+HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font)
+
+
+/*
+ * shaper face data
+ */
+
+struct hb_coretext_aat_shaper_face_data_t {};
+
+hb_coretext_aat_shaper_face_data_t *
+_hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
+{
+  hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT);
+  /* Umm, we just reference the table to check whether it exists.
+   * Maybe add better API for this? */
+  if (!hb_blob_get_length (mort_blob))
+  {
+    hb_blob_destroy (mort_blob);
+    mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
+    if (!hb_blob_get_length (mort_blob))
+    {
+      hb_blob_destroy (mort_blob);
+      return NULL;
+    }
+  }
+  hb_blob_destroy (mort_blob);
+
+  return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
+}
+
+void
+_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_coretext_aat_shaper_font_data_t {};
+
+hb_coretext_aat_shaper_font_data_t *
+_hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
+{
+  return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
+}
+
+void
+_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_coretext_aat_shaper_shape_plan_data_t {};
+
+hb_coretext_aat_shaper_shape_plan_data_t *
+_hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
+                                             const hb_feature_t *user_features HB_UNUSED,
+                                             unsigned int        num_user_features HB_UNUSED)
+{
+  return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper
+ */
+
+hb_bool_t
+_hb_coretext_aat_shape (hb_shape_plan_t    *shape_plan,
+                        hb_font_t          *font,
+                        hb_buffer_t        *buffer,
+                        const hb_feature_t *features,
+                        unsigned int        num_features)
+{
+  return _hb_coretext_shape (shape_plan, font, buffer, features, num_features);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2012  Mozilla Foundation.
+ *
+ *  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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ */
+
+#ifndef HB_CORETEXT_H
+#define HB_CORETEXT_H
+
+#include "hb.h"
+
+#include <TargetConditionals.h>
+#if TARGET_OS_IPHONE
+#  include <CoreText/CoreText.h>
+#  include <CoreGraphics/CoreGraphics.h>
+#else
+#  include <ApplicationServices/ApplicationServices.h>
+#endif
+
+HB_BEGIN_DECLS
+
+
+#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
+#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
+
+
+hb_face_t *
+hb_coretext_face_create (CGFontRef cg_font);
+
+
+CGFontRef
+hb_coretext_face_get_cg_font (hb_face_t *face);
+
+CTFontRef
+hb_coretext_font_get_ct_font (hb_font_t *font);
+
+
+HB_END_DECLS
+
+#endif /* HB_CORETEXT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-deprecated.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2013  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_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_DEPRECATED_H
+#define HB_DEPRECATED_H
+
+#include "hb-common.h"
+#include "hb-unicode.h"
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+#ifndef HB_DISABLE_DEPRECATED
+
+#define HB_SCRIPT_CANADIAN_ABORIGINAL           HB_SCRIPT_CANADIAN_SYLLABICS
+
+#define HB_BUFFER_FLAGS_DEFAULT                 HB_BUFFER_FLAG_DEFAULT
+#define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT       HB_BUFFER_SERIALIZE_FLAG_DEFAULT
+
+#endif
+
+HB_END_DECLS
+
+#endif /* HB_DEPRECATED_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2011  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_FACE_PRIVATE_HH
+#define HB_FACE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-object-private.hh"
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+
+
+/*
+ * hb_face_t
+ */
+
+struct hb_face_t {
+  hb_object_header_t header;
+  ASSERT_POD ();
+
+  hb_bool_t immutable;
+
+  hb_reference_table_func_t  reference_table_func;
+  void                      *user_data;
+  hb_destroy_func_t          destroy;
+
+  unsigned int index;
+  mutable unsigned int upem;
+  mutable unsigned int num_glyphs;
+
+  struct hb_shaper_data_t shaper_data;
+
+  struct plan_node_t {
+    hb_shape_plan_t *shape_plan;
+    plan_node_t *next;
+  } *shape_plans;
+
+
+  inline hb_blob_t *reference_table (hb_tag_t tag) const
+  {
+    hb_blob_t *blob;
+
+    if (unlikely (!reference_table_func))
+      return hb_blob_get_empty ();
+
+    blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data);
+    if (unlikely (!blob))
+      return hb_blob_get_empty ();
+
+    return blob;
+  }
+
+  inline HB_PURE_FUNC unsigned int get_upem (void) const
+  {
+    if (unlikely (!upem))
+      load_upem ();
+    return upem;
+  }
+
+  inline unsigned int get_num_glyphs (void) const
+  {
+    if (unlikely (num_glyphs == (unsigned int) -1))
+      load_num_glyphs ();
+    return num_glyphs;
+  }
+
+  private:
+  HB_INTERNAL void load_upem (void) const;
+  HB_INTERNAL void load_num_glyphs (void) const;
+};
+
+extern HB_INTERNAL const hb_face_t _hb_face_nil;
+
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+
+
+#endif /* HB_FACE_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,481 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-ot-layout-private.hh"
+
+#include "hb-font-private.hh"
+#include "hb-open-file-private.hh"
+#include "hb-ot-head-table.hh"
+#include "hb-ot-maxp-table.hh"
+
+#include "hb-cache-private.hh"
+
+#include <string.h>
+
+
+/*
+ * hb_face_t
+ */
+
+const hb_face_t _hb_face_nil = {
+  HB_OBJECT_HEADER_STATIC,
+
+  true, /* immutable */
+
+  NULL, /* reference_table_func */
+  NULL, /* user_data */
+  NULL, /* destroy */
+
+  0,    /* index */
+  1000, /* upem */
+  0,    /* num_glyphs */
+
+  {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+  },
+
+  NULL, /* shape_plans */
+};
+
+
+/**
+ * hb_face_create_for_tables:
+ * @reference_table_func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 0.9.2
+ **/
+hb_face_t *
+hb_face_create_for_tables (hb_reference_table_func_t  reference_table_func,
+                           void                      *user_data,
+                           hb_destroy_func_t          destroy)
+{
+  hb_face_t *face;
+
+  if (!reference_table_func || !(face = hb_object_create<hb_face_t> ())) {
+    if (destroy)
+      destroy (user_data);
+    return hb_face_get_empty ();
+  }
+
+  face->reference_table_func = reference_table_func;
+  face->user_data = user_data;
+  face->destroy = destroy;
+
+  face->upem = 0;
+  face->num_glyphs = (unsigned int) -1;
+
+  return face;
+}
+
+
+typedef struct hb_face_for_data_closure_t {
+  hb_blob_t *blob;
+  unsigned int  index;
+} hb_face_for_data_closure_t;
+
+static hb_face_for_data_closure_t *
+_hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
+{
+  hb_face_for_data_closure_t *closure;
+
+  closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t));
+  if (unlikely (!closure))
+    return NULL;
+
+  closure->blob = blob;
+  closure->index = index;
+
+  return closure;
+}
+
+static void
+_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
+{
+  hb_blob_destroy (closure->blob);
+  free (closure);
+}
+
+static hb_blob_t *
+_hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+  hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
+
+  if (tag == HB_TAG_NONE)
+    return hb_blob_reference (data->blob);
+
+  const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
+  const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
+
+  const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag);
+
+  hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
+
+  return blob;
+}
+
+/**
+ * hb_face_create: (Xconstructor)
+ * @blob:
+ * @index:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_face_t *
+hb_face_create (hb_blob_t    *blob,
+                unsigned int  index)
+{
+  hb_face_t *face;
+
+  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);
+
+  if (unlikely (!closure))
+    return hb_face_get_empty ();
+
+  face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
+                                    closure,
+                                    (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
+
+  hb_face_set_index (face, index);
+
+  return face;
+}
+
+/**
+ * hb_face_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 0.9.2
+ **/
+hb_face_t *
+hb_face_get_empty (void)
+{
+  return const_cast<hb_face_t *> (&_hb_face_nil);
+}
+
+
+/**
+ * hb_face_reference: (skip)
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_face_t *
+hb_face_reference (hb_face_t *face)
+{
+  return hb_object_reference (face);
+}
+
+/**
+ * hb_face_destroy: (skip)
+ * @face: a face.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_face_destroy (hb_face_t *face)
+{
+  if (!hb_object_destroy (face)) return;
+
+  for (hb_face_t::plan_node_t *node = face->shape_plans; node; )
+  {
+    hb_face_t::plan_node_t *next = node->next;
+    hb_shape_plan_destroy (node->shape_plan);
+    free (node);
+    node = next;
+  }
+
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+  if (face->destroy)
+    face->destroy (face->user_data);
+
+  free (face);
+}
+
+/**
+ * hb_face_set_user_data: (skip)
+ * @face: a face.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_face_set_user_data (hb_face_t          *face,
+                       hb_user_data_key_t *key,
+                       void *              data,
+                       hb_destroy_func_t   destroy,
+                       hb_bool_t           replace)
+{
+  return hb_object_set_user_data (face, key, data, destroy, replace);
+}
+
+/**
+ * hb_face_get_user_data: (skip)
+ * @face: a face.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+void *
+hb_face_get_user_data (hb_face_t          *face,
+                       hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (face, key);
+}
+
+/**
+ * hb_face_make_immutable:
+ * @face: a face.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_face_make_immutable (hb_face_t *face)
+{
+  if (unlikely (hb_object_is_inert (face)))
+    return;
+
+  face->immutable = true;
+}
+
+/**
+ * hb_face_is_immutable:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_face_is_immutable (hb_face_t *face)
+{
+  return face->immutable;
+}
+
+
+/**
+ * hb_face_reference_table:
+ * @face: a face.
+ * @tag:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_blob_t *
+hb_face_reference_table (hb_face_t *face,
+                         hb_tag_t   tag)
+{
+  return face->reference_table (tag);
+}
+
+/**
+ * hb_face_reference_blob:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_blob_t *
+hb_face_reference_blob (hb_face_t *face)
+{
+  return face->reference_table (HB_TAG_NONE);
+}
+
+/**
+ * hb_face_set_index:
+ * @face: a face.
+ * @index:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_face_set_index (hb_face_t    *face,
+                   unsigned int  index)
+{
+  if (face->immutable)
+    return;
+
+  face->index = index;
+}
+
+/**
+ * hb_face_get_index:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+unsigned int
+hb_face_get_index (hb_face_t    *face)
+{
+  return face->index;
+}
+
+/**
+ * hb_face_set_upem:
+ * @face: a face.
+ * @upem:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_face_set_upem (hb_face_t    *face,
+                  unsigned int  upem)
+{
+  if (face->immutable)
+    return;
+
+  face->upem = upem;
+}
+
+/**
+ * hb_face_get_upem:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+unsigned int
+hb_face_get_upem (hb_face_t *face)
+{
+  return face->get_upem ();
+}
+
+void
+hb_face_t::load_upem (void) const
+{
+  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);
+}
+
+/**
+ * hb_face_set_glyph_count:
+ * @face: a face.
+ * @glyph_count:
+ *
+ *
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_face_set_glyph_count (hb_face_t    *face,
+                         unsigned int  glyph_count)
+{
+  if (face->immutable)
+    return;
+
+  face->num_glyphs = glyph_count;
+}
+
+/**
+ * hb_face_get_glyph_count:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.7
+ **/
+unsigned int
+hb_face_get_glyph_count (hb_face_t *face)
+{
+  return face->get_num_glyphs ();
+}
+
+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));
+  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);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2009  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_FACE_H
+#define HB_FACE_H
+
+#include "hb-common.h"
+#include "hb-blob.h"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * hb_face_t
+ */
+
+typedef struct hb_face_t hb_face_t;
+
+hb_face_t *
+hb_face_create (hb_blob_t    *blob,
+                unsigned int  index);
+
+typedef hb_blob_t * (*hb_reference_table_func_t)  (hb_face_t *face, hb_tag_t tag, void *user_data);
+
+/* calls destroy() when not needing user_data anymore */
+hb_face_t *
+hb_face_create_for_tables (hb_reference_table_func_t  reference_table_func,
+                           void                      *user_data,
+                           hb_destroy_func_t          destroy);
+
+hb_face_t *
+hb_face_get_empty (void);
+
+hb_face_t *
+hb_face_reference (hb_face_t *face);
+
+void
+hb_face_destroy (hb_face_t *face);
+
+hb_bool_t
+hb_face_set_user_data (hb_face_t          *face,
+                       hb_user_data_key_t *key,
+                       void *              data,
+                       hb_destroy_func_t   destroy,
+                       hb_bool_t           replace);
+
+
+void *
+hb_face_get_user_data (hb_face_t          *face,
+                       hb_user_data_key_t *key);
+
+void
+hb_face_make_immutable (hb_face_t *face);
+
+hb_bool_t
+hb_face_is_immutable (hb_face_t *face);
+
+
+hb_blob_t *
+hb_face_reference_table (hb_face_t *face,
+                         hb_tag_t   tag);
+
+hb_blob_t *
+hb_face_reference_blob (hb_face_t *face);
+
+void
+hb_face_set_index (hb_face_t    *face,
+                   unsigned int  index);
+
+unsigned int
+hb_face_get_index (hb_face_t    *face);
+
+void
+hb_face_set_upem (hb_face_t    *face,
+                  unsigned int  upem);
+
+unsigned int
+hb_face_get_upem (hb_face_t *face);
+
+void
+hb_face_set_glyph_count (hb_face_t    *face,
+                         unsigned int  glyph_count);
+
+unsigned int
+hb_face_get_glyph_count (hb_face_t *face);
+
+
+HB_END_DECLS
+
+#endif /* HB_FACE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-fallback-shape.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2011  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
+ */
+
+#define HB_SHAPER fallback
+#include "hb-shaper-impl-private.hh"
+
+
+/*
+ * shaper face data
+ */
+
+struct hb_fallback_shaper_face_data_t {};
+
+hb_fallback_shaper_face_data_t *
+_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
+{
+  return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_fallback_shaper_font_data_t {};
+
+hb_fallback_shaper_font_data_t *
+_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
+{
+  return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_fallback_shaper_shape_plan_data_t {};
+
+hb_fallback_shaper_shape_plan_data_t *
+_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan HB_UNUSED,
+                                            const hb_feature_t *user_features HB_UNUSED,
+                                            unsigned int        num_user_features HB_UNUSED)
+{
+  return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
+{
+}
+
+
+/*
+ * shaper
+ */
+
+hb_bool_t
+_hb_fallback_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
+                    hb_font_t          *font,
+                    hb_buffer_t        *buffer,
+                    const hb_feature_t *features HB_UNUSED,
+                    unsigned int        num_features HB_UNUSED)
+{
+  /* TODO
+   *
+   * - Apply fallback kern.
+   * - Handle Variation Selectors?
+   * - Apply normalization?
+   *
+   * This will make the fallback shaper into a dumb "TrueType"
+   * shaper which many people unfortunately still request.
+   */
+
+  hb_codepoint_t space;
+  bool has_space = font->get_glyph (' ', 0, &space);
+
+  buffer->clear_positions ();
+
+  hb_direction_t direction = buffer->props.direction;
+  hb_unicode_funcs_t *unicode = buffer->unicode;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  hb_glyph_position_t *pos = buffer->pos;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    if (has_space && unicode->is_default_ignorable (info[i].codepoint)) {
+      info[i].codepoint = space;
+      pos[i].x_advance = 0;
+      pos[i].y_advance = 0;
+      continue;
+    }
+    font->get_glyph (info[i].codepoint, 0, &info[i].codepoint);
+    font->get_glyph_advance_for_direction (info[i].codepoint,
+                                           direction,
+                                           &pos[i].x_advance,
+                                           &pos[i].y_advance);
+    font->subtract_glyph_origin_for_direction (info[i].codepoint,
+                                               direction,
+                                               &pos[i].x_offset,
+                                               &pos[i].y_offset);
+  }
+
+  if (HB_DIRECTION_IS_BACKWARD (direction))
+    hb_buffer_reverse (buffer);
+
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,415 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2011  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_FONT_PRIVATE_HH
+#define HB_FONT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-object-private.hh"
+#include "hb-face-private.hh"
+#include "hb-shaper-private.hh"
+
+
+
+/*
+ * hb_font_funcs_t
+ */
+
+#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
+  HB_FONT_FUNC_IMPLEMENT (glyph) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_name) \
+  HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
+  /* ^--- Add new callbacks here */
+
+struct hb_font_funcs_t {
+  hb_object_header_t header;
+  ASSERT_POD ();
+
+  hb_bool_t immutable;
+
+  /* Don't access these directly.  Call hb_font_get_*() instead. */
+
+  struct {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
+    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+  } get;
+
+  struct {
+#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
+    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+  } user_data;
+
+  struct {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
+    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+  } destroy;
+};
+
+
+
+/*
+ * hb_font_t
+ */
+
+struct hb_font_t {
+  hb_object_header_t header;
+  ASSERT_POD ();
+
+  hb_bool_t immutable;
+
+  hb_font_t *parent;
+  hb_face_t *face;
+
+  int x_scale;
+  int y_scale;
+
+  unsigned int x_ppem;
+  unsigned int y_ppem;
+
+  hb_font_funcs_t   *klass;
+  void              *user_data;
+  hb_destroy_func_t  destroy;
+
+  struct hb_shaper_data_t shaper_data;
+
+
+  /* Convert from font-space to user-space */
+  inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
+  inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); }
+
+  /* Convert from parent-font user-space to our user-space */
+  inline hb_position_t parent_scale_x_distance (hb_position_t v) {
+    if (unlikely (parent && parent->x_scale != x_scale))
+      return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
+    return v;
+  }
+  inline hb_position_t parent_scale_y_distance (hb_position_t v) {
+    if (unlikely (parent && parent->y_scale != y_scale))
+      return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
+    return v;
+  }
+  inline hb_position_t parent_scale_x_position (hb_position_t v) {
+    return parent_scale_x_distance (v);
+  }
+  inline hb_position_t parent_scale_y_position (hb_position_t v) {
+    return parent_scale_y_distance (v);
+  }
+
+  inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
+    *x = parent_scale_x_distance (*x);
+    *y = parent_scale_y_distance (*y);
+  }
+  inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
+    *x = parent_scale_x_position (*x);
+    *y = parent_scale_y_position (*y);
+  }
+
+
+  /* Public getters */
+
+  inline hb_bool_t has_glyph (hb_codepoint_t unicode)
+  {
+    hb_codepoint_t glyph;
+    return get_glyph (unicode, 0, &glyph);
+  }
+
+  inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+                              hb_codepoint_t *glyph)
+  {
+    *glyph = 0;
+    return klass->get.glyph (this, user_data,
+                             unicode, variation_selector, glyph,
+                             klass->user_data.glyph);
+  }
+
+  inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
+  {
+    return klass->get.glyph_h_advance (this, user_data,
+                                       glyph,
+                                       klass->user_data.glyph_h_advance);
+  }
+
+  inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
+  {
+    return klass->get.glyph_v_advance (this, user_data,
+                                       glyph,
+                                       klass->user_data.glyph_v_advance);
+  }
+
+  inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
+                                       hb_position_t *x, hb_position_t *y)
+  {
+    *x = *y = 0;
+    return klass->get.glyph_h_origin (this, user_data,
+                                      glyph, x, y,
+                                      klass->user_data.glyph_h_origin);
+  }
+
+  inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
+                                       hb_position_t *x, hb_position_t *y)
+  {
+    *x = *y = 0;
+    return klass->get.glyph_v_origin (this, user_data,
+                                      glyph, x, y,
+                                      klass->user_data.glyph_v_origin);
+  }
+
+  inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+  {
+    return klass->get.glyph_h_kerning (this, user_data,
+                                       left_glyph, right_glyph,
+                                       klass->user_data.glyph_h_kerning);
+  }
+
+  inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
+  {
+    return klass->get.glyph_v_kerning (this, user_data,
+                                       top_glyph, bottom_glyph,
+                                       klass->user_data.glyph_v_kerning);
+  }
+
+  inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
+                                      hb_glyph_extents_t *extents)
+  {
+    memset (extents, 0, sizeof (*extents));
+    return klass->get.glyph_extents (this, user_data,
+                                     glyph,
+                                     extents,
+                                     klass->user_data.glyph_extents);
+  }
+
+  inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
+                                            hb_position_t *x, hb_position_t *y)
+  {
+    *x = *y = 0;
+    return klass->get.glyph_contour_point (this, user_data,
+                                           glyph, point_index,
+                                           x, y,
+                                           klass->user_data.glyph_contour_point);
+  }
+
+  inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
+                                   char *name, unsigned int size)
+  {
+    if (size) *name = '\0';
+    return klass->get.glyph_name (this, user_data,
+                                  glyph,
+                                  name, size,
+                                  klass->user_data.glyph_name);
+  }
+
+  inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
+                                        hb_codepoint_t *glyph)
+  {
+    *glyph = 0;
+    if (len == -1) len = strlen (name);
+    return klass->get.glyph_from_name (this, user_data,
+                                       name, len,
+                                       glyph,
+                                       klass->user_data.glyph_from_name);
+  }
+
+
+  /* A bit higher-level, and with fallback */
+
+  inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
+                                               hb_direction_t direction,
+                                               hb_position_t *x, hb_position_t *y)
+  {
+    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+      *x = get_glyph_h_advance (glyph);
+      *y = 0;
+    } else {
+      *x = 0;
+      *y = get_glyph_v_advance (glyph);
+    }
+  }
+
+  /* Internal only */
+  inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
+                                             hb_position_t *x, hb_position_t *y)
+  {
+    *x = get_glyph_h_advance (glyph) / 2;
+
+    /* TODO use font_metrics.ascent */
+    *y = y_scale;
+  }
+
+  inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
+                                              hb_direction_t direction,
+                                              hb_position_t *x, hb_position_t *y)
+  {
+    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
+    {
+      if (!get_glyph_h_origin (glyph, x, y) &&
+           get_glyph_v_origin (glyph, x, y))
+      {
+        hb_position_t dx, dy;
+        guess_v_origin_minus_h_origin (glyph, &dx, &dy);
+        *x -= dx; *y -= dy;
+      }
+    }
+    else
+    {
+      if (!get_glyph_v_origin (glyph, x, y) &&
+           get_glyph_h_origin (glyph, x, y))
+      {
+        hb_position_t dx, dy;
+        guess_v_origin_minus_h_origin (glyph, &dx, &dy);
+        *x += dx; *y += dy;
+      }
+    }
+  }
+
+  inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
+                                              hb_direction_t direction,
+                                              hb_position_t *x, hb_position_t *y)
+  {
+    hb_position_t origin_x, origin_y;
+
+    get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
+
+    *x += origin_x;
+    *y += origin_y;
+  }
+
+  inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
+                                                   hb_direction_t direction,
+                                                   hb_position_t *x, hb_position_t *y)
+  {
+    hb_position_t origin_x, origin_y;
+
+    get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
+
+    *x -= origin_x;
+    *y -= origin_y;
+  }
+
+  inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+                                               hb_direction_t direction,
+                                               hb_position_t *x, hb_position_t *y)
+  {
+    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
+      *x = get_glyph_h_kerning (first_glyph, second_glyph);
+      *y = 0;
+    } else {
+      *x = 0;
+      *y = get_glyph_v_kerning (first_glyph, second_glyph);
+    }
+  }
+
+  inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
+                                                 hb_direction_t direction,
+                                                 hb_glyph_extents_t *extents)
+  {
+    hb_bool_t ret = get_glyph_extents (glyph, extents);
+
+    if (ret)
+      subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
+
+    return ret;
+  }
+
+  inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
+                                                       hb_direction_t direction,
+                                                       hb_position_t *x, hb_position_t *y)
+  {
+    hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
+
+    if (ret)
+      subtract_glyph_origin_for_direction (glyph, direction, x, y);
+
+    return ret;
+  }
+
+  /* Generates gidDDD if glyph has no name. */
+  inline void
+  glyph_to_string (hb_codepoint_t glyph,
+                   char *s, unsigned int size)
+  {
+    if (get_glyph_name (glyph, s, size)) return;
+
+    if (size && snprintf (s, size, "gid%u", glyph) < 0)
+      *s = '\0';
+  }
+
+  /* Parses gidDDD and uniUUUU strings automatically. */
+  inline hb_bool_t
+  glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
+                     hb_codepoint_t *glyph)
+  {
+    if (get_glyph_from_name (s, len, glyph)) return true;
+
+    if (len == -1) len = strlen (s);
+
+    /* Straight glyph index. */
+    if (hb_codepoint_parse (s, len, 10, glyph))
+      return true;
+
+    if (len > 3)
+    {
+      /* gidDDD syntax for glyph indices. */
+      if (0 == strncmp (s, "gid", 3) &&
+          hb_codepoint_parse (s + 3, len - 3, 10, glyph))
+        return true;
+
+      /* uniUUUU and other Unicode character indices. */
+      hb_codepoint_t unichar;
+      if (0 == strncmp (s, "uni", 3) &&
+          hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
+          get_glyph (unichar, 0, glyph))
+        return true;
+    }
+
+    return false;
+  }
+
+  private:
+  inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); }
+};
+
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+
+
+#endif /* HB_FONT_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1266 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-ot-layout-private.hh"
+
+#include "hb-font-private.hh"
+#include "hb-open-file-private.hh"
+#include "hb-ot-head-table.hh"
+#include "hb-ot-maxp-table.hh"
+
+#include "hb-cache-private.hh"
+
+#include <string.h>
+
+
+/*
+ * hb_font_funcs_t
+ */
+
+static hb_bool_t
+hb_font_get_glyph_nil (hb_font_t *font,
+                       void *font_data HB_UNUSED,
+                       hb_codepoint_t unicode,
+                       hb_codepoint_t variation_selector,
+                       hb_codepoint_t *glyph,
+                       void *user_data HB_UNUSED)
+{
+  if (font->parent)
+    return font->parent->get_glyph (unicode, variation_selector, glyph);
+
+  *glyph = 0;
+  return false;
+}
+
+static hb_position_t
+hb_font_get_glyph_h_advance_nil (hb_font_t *font,
+                                 void *font_data HB_UNUSED,
+                                 hb_codepoint_t glyph,
+                                 void *user_data HB_UNUSED)
+{
+  if (font->parent)
+    return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
+
+  return font->x_scale;
+}
+
+static hb_position_t
+hb_font_get_glyph_v_advance_nil (hb_font_t *font,
+                                 void *font_data HB_UNUSED,
+                                 hb_codepoint_t glyph,
+                                 void *user_data HB_UNUSED)
+{
+  if (font->parent)
+    return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
+
+  return font->y_scale;
+}
+
+static hb_bool_t
+hb_font_get_glyph_h_origin_nil (hb_font_t *font,
+                                void *font_data HB_UNUSED,
+                                hb_codepoint_t glyph,
+                                hb_position_t *x,
+                                hb_position_t *y,
+                                void *user_data HB_UNUSED)
+{
+  if (font->parent) {
+    hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
+    if (ret)
+      font->parent_scale_position (x, y);
+    return ret;
+  }
+
+  *x = *y = 0;
+  return false;
+}
+
+static hb_bool_t
+hb_font_get_glyph_v_origin_nil (hb_font_t *font,
+                                void *font_data HB_UNUSED,
+                                hb_codepoint_t glyph,
+                                hb_position_t *x,
+                                hb_position_t *y,
+                                void *user_data HB_UNUSED)
+{
+  if (font->parent) {
+    hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
+    if (ret)
+      font->parent_scale_position (x, y);
+    return ret;
+  }
+
+  *x = *y = 0;
+  return false;
+}
+
+static hb_position_t
+hb_font_get_glyph_h_kerning_nil (hb_font_t *font,
+                                 void *font_data HB_UNUSED,
+                                 hb_codepoint_t left_glyph,
+                                 hb_codepoint_t right_glyph,
+                                 void *user_data HB_UNUSED)
+{
+  if (font->parent)
+    return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
+
+  return 0;
+}
+
+static hb_position_t
+hb_font_get_glyph_v_kerning_nil (hb_font_t *font,
+                                 void *font_data HB_UNUSED,
+                                 hb_codepoint_t top_glyph,
+                                 hb_codepoint_t bottom_glyph,
+                                 void *user_data HB_UNUSED)
+{
+  if (font->parent)
+    return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
+
+  return 0;
+}
+
+static hb_bool_t
+hb_font_get_glyph_extents_nil (hb_font_t *font,
+                               void *font_data HB_UNUSED,
+                               hb_codepoint_t glyph,
+                               hb_glyph_extents_t *extents,
+                               void *user_data HB_UNUSED)
+{
+  if (font->parent) {
+    hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
+    if (ret) {
+      font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
+      font->parent_scale_distance (&extents->width, &extents->height);
+    }
+    return ret;
+  }
+
+  memset (extents, 0, sizeof (*extents));
+  return false;
+}
+
+static hb_bool_t
+hb_font_get_glyph_contour_point_nil (hb_font_t *font,
+                                     void *font_data HB_UNUSED,
+                                     hb_codepoint_t glyph,
+                                     unsigned int point_index,
+                                     hb_position_t *x,
+                                     hb_position_t *y,
+                                     void *user_data HB_UNUSED)
+{
+  if (font->parent) {
+    hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
+    if (ret)
+      font->parent_scale_position (x, y);
+    return ret;
+  }
+
+  *x = *y = 0;
+  return false;
+}
+
+static hb_bool_t
+hb_font_get_glyph_name_nil (hb_font_t *font,
+                            void *font_data HB_UNUSED,
+                            hb_codepoint_t glyph,
+                            char *name, unsigned int size,
+                            void *user_data HB_UNUSED)
+{
+  if (font->parent)
+    return font->parent->get_glyph_name (glyph, name, size);
+
+  if (size) *name = '\0';
+  return false;
+}
+
+static hb_bool_t
+hb_font_get_glyph_from_name_nil (hb_font_t *font,
+                                 void *font_data HB_UNUSED,
+                                 const char *name, int len, /* -1 means nul-terminated */
+                                 hb_codepoint_t *glyph,
+                                 void *user_data HB_UNUSED)
+{
+  if (font->parent)
+    return font->parent->get_glyph_from_name (name, len, glyph);
+
+  *glyph = 0;
+  return false;
+}
+
+
+static const hb_font_funcs_t _hb_font_funcs_nil = {
+  HB_OBJECT_HEADER_STATIC,
+
+  true, /* immutable */
+
+  {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
+    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+  }
+};
+
+
+/**
+ * hb_font_funcs_create: (Xconstructor)
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_font_funcs_t *
+hb_font_funcs_create (void)
+{
+  hb_font_funcs_t *ffuncs;
+
+  if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
+    return hb_font_funcs_get_empty ();
+
+  ffuncs->get = _hb_font_funcs_nil.get;
+
+  return ffuncs;
+}
+
+/**
+ * hb_font_funcs_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_font_funcs_t *
+hb_font_funcs_get_empty (void)
+{
+  return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
+}
+
+/**
+ * hb_font_funcs_reference: (skip)
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_font_funcs_t *
+hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
+{
+  return hb_object_reference (ffuncs);
+}
+
+/**
+ * hb_font_funcs_destroy: (skip)
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
+{
+  if (!hb_object_destroy (ffuncs)) return;
+
+#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
+  ffuncs->destroy.name (ffuncs->user_data.name);
+  HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+
+  free (ffuncs);
+}
+
+/**
+ * hb_font_funcs_set_user_data: (skip)
+ * @ffuncs: font functions.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
+                             hb_user_data_key_t *key,
+                             void *              data,
+                             hb_destroy_func_t   destroy,
+                             hb_bool_t           replace)
+{
+  return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
+}
+
+/**
+ * hb_font_funcs_get_user_data: (skip)
+ * @ffuncs: font functions.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+void *
+hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
+                             hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (ffuncs, key);
+}
+
+
+/**
+ * hb_font_funcs_make_immutable:
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
+{
+  if (unlikely (hb_object_is_inert (ffuncs)))
+    return;
+
+  ffuncs->immutable = true;
+}
+
+/**
+ * hb_font_funcs_is_immutable:
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
+{
+  return ffuncs->immutable;
+}
+
+
+#define HB_FONT_FUNC_IMPLEMENT(name) \
+                                                                         \
+void                                                                     \
+hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
+                                 hb_font_get_##name##_func_t  func,      \
+                                 void                        *user_data, \
+                                 hb_destroy_func_t            destroy)   \
+{                                                                        \
+  if (ffuncs->immutable) {                                               \
+    if (destroy)                                                         \
+      destroy (user_data);                                               \
+    return;                                                              \
+  }                                                                      \
+                                                                         \
+  if (ffuncs->destroy.name)                                              \
+    ffuncs->destroy.name (ffuncs->user_data.name);                       \
+                                                                         \
+  if (func) {                                                            \
+    ffuncs->get.name = func;                                             \
+    ffuncs->user_data.name = user_data;                                  \
+    ffuncs->destroy.name = destroy;                                      \
+  } else {                                                               \
+    ffuncs->get.name = hb_font_get_##name##_nil;                         \
+    ffuncs->user_data.name = NULL;                                       \
+    ffuncs->destroy.name = NULL;                                         \
+  }                                                                      \
+}
+
+HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+
+
+/* Public getters */
+
+/**
+ * hb_font_get_glyph:
+ * @font: a font.
+ * @unicode:
+ * @variation_selector:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph (hb_font_t *font,
+                   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+                   hb_codepoint_t *glyph)
+{
+  return font->get_glyph (unicode, variation_selector, glyph);
+}
+
+/**
+ * hb_font_get_glyph_h_advance:
+ * @font: a font.
+ * @glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_position_t
+hb_font_get_glyph_h_advance (hb_font_t *font,
+                             hb_codepoint_t glyph)
+{
+  return font->get_glyph_h_advance (glyph);
+}
+
+/**
+ * hb_font_get_glyph_v_advance:
+ * @font: a font.
+ * @glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_position_t
+hb_font_get_glyph_v_advance (hb_font_t *font,
+                             hb_codepoint_t glyph)
+{
+  return font->get_glyph_v_advance (glyph);
+}
+
+/**
+ * hb_font_get_glyph_h_origin:
+ * @font: a font.
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph_h_origin (hb_font_t *font,
+                            hb_codepoint_t glyph,
+                            hb_position_t *x, hb_position_t *y)
+{
+  return font->get_glyph_h_origin (glyph, x, y);
+}
+
+/**
+ * hb_font_get_glyph_v_origin:
+ * @font: a font.
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph_v_origin (hb_font_t *font,
+                            hb_codepoint_t glyph,
+                            hb_position_t *x, hb_position_t *y)
+{
+  return font->get_glyph_v_origin (glyph, x, y);
+}
+
+/**
+ * hb_font_get_glyph_h_kerning:
+ * @font: a font.
+ * @left_glyph:
+ * @right_glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_position_t
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+                             hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+{
+  return font->get_glyph_h_kerning (left_glyph, right_glyph);
+}
+
+/**
+ * hb_font_get_glyph_v_kerning:
+ * @font: a font.
+ * @top_glyph:
+ * @bottom_glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_position_t
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+                             hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
+{
+  return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
+}
+
+/**
+ * hb_font_get_glyph_extents:
+ * @font: a font.
+ * @glyph:
+ * @extents: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph_extents (hb_font_t *font,
+                           hb_codepoint_t glyph,
+                           hb_glyph_extents_t *extents)
+{
+  return font->get_glyph_extents (glyph, extents);
+}
+
+/**
+ * hb_font_get_glyph_contour_point:
+ * @font: a font.
+ * @glyph:
+ * @point_index:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph_contour_point (hb_font_t *font,
+                                 hb_codepoint_t glyph, unsigned int point_index,
+                                 hb_position_t *x, hb_position_t *y)
+{
+  return font->get_glyph_contour_point (glyph, point_index, x, y);
+}
+
+/**
+ * hb_font_get_glyph_name:
+ * @font: a font.
+ * @glyph:
+ * @name: (array length=size):
+ * @size:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph_name (hb_font_t *font,
+                        hb_codepoint_t glyph,
+                        char *name, unsigned int size)
+{
+  return font->get_glyph_name (glyph, name, size);
+}
+
+/**
+ * hb_font_get_glyph_from_name:
+ * @font: a font.
+ * @name: (array length=len):
+ * @len:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph_from_name (hb_font_t *font,
+                             const char *name, int len, /* -1 means nul-terminated */
+                             hb_codepoint_t *glyph)
+{
+  return font->get_glyph_from_name (name, len, glyph);
+}
+
+
+/* A bit higher-level, and with fallback */
+
+/**
+ * hb_font_get_glyph_advance_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_get_glyph_advance_for_direction (hb_font_t *font,
+                                         hb_codepoint_t glyph,
+                                         hb_direction_t direction,
+                                         hb_position_t *x, hb_position_t *y)
+{
+  return font->get_glyph_advance_for_direction (glyph, direction, x, y);
+}
+
+/**
+ * hb_font_get_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_get_glyph_origin_for_direction (hb_font_t *font,
+                                        hb_codepoint_t glyph,
+                                        hb_direction_t direction,
+                                        hb_position_t *x, hb_position_t *y)
+{
+  return font->get_glyph_origin_for_direction (glyph, direction, x, y);
+}
+
+/**
+ * hb_font_add_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_add_glyph_origin_for_direction (hb_font_t *font,
+                                        hb_codepoint_t glyph,
+                                        hb_direction_t direction,
+                                        hb_position_t *x, hb_position_t *y)
+{
+  return font->add_glyph_origin_for_direction (glyph, direction, x, y);
+}
+
+/**
+ * hb_font_subtract_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
+                                             hb_codepoint_t glyph,
+                                             hb_direction_t direction,
+                                             hb_position_t *x, hb_position_t *y)
+{
+  return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
+}
+
+/**
+ * hb_font_get_glyph_kerning_for_direction:
+ * @font: a font.
+ * @first_glyph:
+ * @second_glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+                                         hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+                                         hb_direction_t direction,
+                                         hb_position_t *x, hb_position_t *y)
+{
+  return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
+}
+
+/**
+ * hb_font_get_glyph_extents_for_origin:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @extents: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph_extents_for_origin (hb_font_t *font,
+                                      hb_codepoint_t glyph,
+                                      hb_direction_t direction,
+                                      hb_glyph_extents_t *extents)
+{
+  return font->get_glyph_extents_for_origin (glyph, direction, extents);
+}
+
+/**
+ * hb_font_get_glyph_contour_point_for_origin:
+ * @font: a font.
+ * @glyph:
+ * @point_index:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
+                                            hb_codepoint_t glyph, unsigned int point_index,
+                                            hb_direction_t direction,
+                                            hb_position_t *x, hb_position_t *y)
+{
+  return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
+}
+
+/* Generates gidDDD if glyph has no name. */
+/**
+ * hb_font_glyph_to_string:
+ * @font: a font.
+ * @glyph:
+ * @s: (array length=size):
+ * @size:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_glyph_to_string (hb_font_t *font,
+                         hb_codepoint_t glyph,
+                         char *s, unsigned int size)
+{
+  font->glyph_to_string (glyph, s, size);
+}
+
+/* Parses gidDDD and uniUUUU strings automatically. */
+/**
+ * hb_font_glyph_from_string:
+ * @font: a font.
+ * @s: (array length=len) (element-type uint8_t):
+ * @len:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_glyph_from_string (hb_font_t *font,
+                           const char *s, int len, /* -1 means nul-terminated */
+                           hb_codepoint_t *glyph)
+{
+  return font->glyph_from_string (s, len, glyph);
+}
+
+
+/*
+ * hb_font_t
+ */
+
+/**
+ * hb_font_create: (Xconstructor)
+ * @face: a face.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_font_t *
+hb_font_create (hb_face_t *face)
+{
+  hb_font_t *font;
+
+  if (unlikely (!face))
+    face = hb_face_get_empty ();
+  if (!(font = hb_object_create<hb_font_t> ()))
+    return hb_font_get_empty ();
+
+  hb_face_make_immutable (face);
+  font->face = hb_face_reference (face);
+  font->klass = hb_font_funcs_get_empty ();
+
+  font->x_scale = font->y_scale = hb_face_get_upem (face);
+
+  return font;
+}
+
+/**
+ * hb_font_create_sub_font:
+ * @parent: parent font.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_font_t *
+hb_font_create_sub_font (hb_font_t *parent)
+{
+  if (unlikely (!parent))
+    parent = hb_font_get_empty ();
+
+  hb_font_t *font = hb_font_create (parent->face);
+
+  if (unlikely (hb_object_is_inert (font)))
+    return font;
+
+  font->parent = hb_font_reference (parent);
+
+  font->x_scale = parent->x_scale;
+  font->y_scale = parent->y_scale;
+  font->x_ppem = parent->x_ppem;
+  font->y_ppem = parent->y_ppem;
+
+  return font;
+}
+
+/**
+ * hb_font_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 0.9.2
+ **/
+hb_font_t *
+hb_font_get_empty (void)
+{
+  static const hb_font_t _hb_font_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    true, /* immutable */
+
+    NULL, /* parent */
+    const_cast<hb_face_t *> (&_hb_face_nil),
+
+    0, /* x_scale */
+    0, /* y_scale */
+
+    0, /* x_ppem */
+    0, /* y_ppem */
+
+    const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
+    NULL, /* user_data */
+    NULL, /* destroy */
+
+    {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_font_t *> (&_hb_font_nil);
+}
+
+/**
+ * hb_font_reference: (skip)
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_font_t *
+hb_font_reference (hb_font_t *font)
+{
+  return hb_object_reference (font);
+}
+
+/**
+ * hb_font_destroy: (skip)
+ * @font: a font.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_destroy (hb_font_t *font)
+{
+  if (!hb_object_destroy (font)) return;
+
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+  if (font->destroy)
+    font->destroy (font->user_data);
+
+  hb_font_destroy (font->parent);
+  hb_face_destroy (font->face);
+  hb_font_funcs_destroy (font->klass);
+
+  free (font);
+}
+
+/**
+ * hb_font_set_user_data: (skip)
+ * @font: a font.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_set_user_data (hb_font_t          *font,
+                       hb_user_data_key_t *key,
+                       void *              data,
+                       hb_destroy_func_t   destroy,
+                       hb_bool_t           replace)
+{
+  return hb_object_set_user_data (font, key, data, destroy, replace);
+}
+
+/**
+ * hb_font_get_user_data: (skip)
+ * @font: a font.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+void *
+hb_font_get_user_data (hb_font_t          *font,
+                       hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (font, key);
+}
+
+/**
+ * hb_font_make_immutable:
+ * @font: a font.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_make_immutable (hb_font_t *font)
+{
+  if (unlikely (hb_object_is_inert (font)))
+    return;
+
+  if (font->parent)
+    hb_font_make_immutable (font->parent);
+
+  font->immutable = true;
+}
+
+/**
+ * hb_font_is_immutable:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_font_is_immutable (hb_font_t *font)
+{
+  return font->immutable;
+}
+
+/**
+ * hb_font_set_parent:
+ * @font: a font.
+ * @parent: new parent.
+ *
+ * Sets parent font of @font.
+ *
+ * Since: 1.0.5
+ **/
+void
+hb_font_set_parent (hb_font_t *font,
+                    hb_font_t *parent)
+{
+  if (font->immutable)
+    return;
+
+  if (!parent)
+    parent = hb_font_get_empty ();
+
+  hb_font_t *old = font->parent;
+
+  font->parent = hb_font_reference (parent);
+
+  hb_font_destroy (old);
+}
+
+/**
+ * hb_font_get_parent:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+hb_font_t *
+hb_font_get_parent (hb_font_t *font)
+{
+  return font->parent;
+}
+
+/**
+ * hb_font_get_face:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+hb_face_t *
+hb_font_get_face (hb_font_t *font)
+{
+  return font->face;
+}
+
+
+/**
+ * hb_font_set_funcs:
+ * @font: a font.
+ * @klass: (closure font_data) (destroy destroy) (scope notified):
+ * @font_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_set_funcs (hb_font_t         *font,
+                   hb_font_funcs_t   *klass,
+                   void              *font_data,
+                   hb_destroy_func_t  destroy)
+{
+  if (font->immutable) {
+    if (destroy)
+      destroy (font_data);
+    return;
+  }
+
+  if (font->destroy)
+    font->destroy (font->user_data);
+
+  if (!klass)
+    klass = hb_font_funcs_get_empty ();
+
+  hb_font_funcs_reference (klass);
+  hb_font_funcs_destroy (font->klass);
+  font->klass = klass;
+  font->user_data = font_data;
+  font->destroy = destroy;
+}
+
+/**
+ * hb_font_set_funcs_data:
+ * @font: a font.
+ * @font_data: (destroy destroy) (scope notified):
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_set_funcs_data (hb_font_t         *font,
+                        void              *font_data,
+                        hb_destroy_func_t  destroy)
+{
+  /* Destroy user_data? */
+  if (font->immutable) {
+    if (destroy)
+      destroy (font_data);
+    return;
+  }
+
+  if (font->destroy)
+    font->destroy (font->user_data);
+
+  font->user_data = font_data;
+  font->destroy = destroy;
+}
+
+
+/**
+ * hb_font_set_scale:
+ * @font: a font.
+ * @x_scale:
+ * @y_scale:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_set_scale (hb_font_t *font,
+                   int x_scale,
+                   int y_scale)
+{
+  if (font->immutable)
+    return;
+
+  font->x_scale = x_scale;
+  font->y_scale = y_scale;
+}
+
+/**
+ * hb_font_get_scale:
+ * @font: a font.
+ * @x_scale: (out):
+ * @y_scale: (out):
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_get_scale (hb_font_t *font,
+                   int *x_scale,
+                   int *y_scale)
+{
+  if (x_scale) *x_scale = font->x_scale;
+  if (y_scale) *y_scale = font->y_scale;
+}
+
+/**
+ * hb_font_set_ppem:
+ * @font: a font.
+ * @x_ppem:
+ * @y_ppem:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_set_ppem (hb_font_t *font,
+                  unsigned int x_ppem,
+                  unsigned int y_ppem)
+{
+  if (font->immutable)
+    return;
+
+  font->x_ppem = x_ppem;
+  font->y_ppem = y_ppem;
+}
+
+/**
+ * hb_font_get_ppem:
+ * @font: a font.
+ * @x_ppem: (out):
+ * @y_ppem: (out):
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_get_ppem (hb_font_t *font,
+                  unsigned int *x_ppem,
+                  unsigned int *y_ppem)
+{
+  if (x_ppem) *x_ppem = font->x_ppem;
+  if (y_ppem) *y_ppem = font->y_ppem;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,512 @@
+/*
+ * Copyright © 2009  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_FONT_H
+#define HB_FONT_H
+
+#include "hb-common.h"
+#include "hb-face.h"
+
+HB_BEGIN_DECLS
+
+
+typedef struct hb_font_t hb_font_t;
+
+
+/*
+ * hb_font_funcs_t
+ */
+
+typedef struct hb_font_funcs_t hb_font_funcs_t;
+
+hb_font_funcs_t *
+hb_font_funcs_create (void);
+
+hb_font_funcs_t *
+hb_font_funcs_get_empty (void);
+
+hb_font_funcs_t *
+hb_font_funcs_reference (hb_font_funcs_t *ffuncs);
+
+void
+hb_font_funcs_destroy (hb_font_funcs_t *ffuncs);
+
+hb_bool_t
+hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
+                             hb_user_data_key_t *key,
+                             void *              data,
+                             hb_destroy_func_t   destroy,
+                             hb_bool_t           replace);
+
+
+void *
+hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
+                             hb_user_data_key_t *key);
+
+
+void
+hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs);
+
+hb_bool_t
+hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
+
+
+/* glyph extents */
+
+/* Note that height is negative in coordinate systems that grow up. */
+typedef struct hb_glyph_extents_t
+{
+  hb_position_t x_bearing; /* left side of glyph from origin. */
+  hb_position_t y_bearing; /* top side of glyph from origin. */
+  hb_position_t width; /* distance from left to right side. */
+  hb_position_t height; /* distance from top to bottom side. */
+} hb_glyph_extents_t;
+
+
+/* func types */
+
+typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
+                                               hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+                                               hb_codepoint_t *glyph,
+                                               void *user_data);
+
+
+typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
+                                                           hb_codepoint_t glyph,
+                                                           void *user_data);
+typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
+typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
+
+typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data,
+                                                      hb_codepoint_t glyph,
+                                                      hb_position_t *x, hb_position_t *y,
+                                                      void *user_data);
+typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
+typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
+
+typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
+                                                           hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+                                                           void *user_data);
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
+
+
+typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
+                                                       hb_codepoint_t glyph,
+                                                       hb_glyph_extents_t *extents,
+                                                       void *user_data);
+typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data,
+                                                             hb_codepoint_t glyph, unsigned int point_index,
+                                                             hb_position_t *x, hb_position_t *y,
+                                                             void *user_data);
+
+
+typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data,
+                                                    hb_codepoint_t glyph,
+                                                    char *name, unsigned int size,
+                                                    void *user_data);
+typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data,
+                                                         const char *name, int len, /* -1 means nul-terminated */
+                                                         hb_codepoint_t *glyph,
+                                                         void *user_data);
+
+
+/* func setters */
+
+/**
+ * hb_font_funcs_set_glyph_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
+                              hb_font_get_glyph_func_t func,
+                              void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_h_advance_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
+                                        hb_font_get_glyph_h_advance_func_t func,
+                                        void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_advance_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
+                                        hb_font_get_glyph_v_advance_func_t func,
+                                        void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_h_origin_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
+                                       hb_font_get_glyph_h_origin_func_t func,
+                                       void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_origin_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
+                                       hb_font_get_glyph_v_origin_func_t func,
+                                       void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_h_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
+                                        hb_font_get_glyph_h_kerning_func_t func,
+                                        void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
+                                        hb_font_get_glyph_v_kerning_func_t func,
+                                        void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_extents_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
+                                      hb_font_get_glyph_extents_func_t func,
+                                      void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_contour_point_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
+                                            hb_font_get_glyph_contour_point_func_t func,
+                                            void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_name_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
+                                   hb_font_get_glyph_name_func_t func,
+                                   void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_from_name_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
+                                        hb_font_get_glyph_from_name_func_t func,
+                                        void *user_data, hb_destroy_func_t destroy);
+
+
+/* func dispatch */
+
+hb_bool_t
+hb_font_get_glyph (hb_font_t *font,
+                   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
+                   hb_codepoint_t *glyph);
+
+hb_position_t
+hb_font_get_glyph_h_advance (hb_font_t *font,
+                             hb_codepoint_t glyph);
+hb_position_t
+hb_font_get_glyph_v_advance (hb_font_t *font,
+                             hb_codepoint_t glyph);
+
+hb_bool_t
+hb_font_get_glyph_h_origin (hb_font_t *font,
+                            hb_codepoint_t glyph,
+                            hb_position_t *x, hb_position_t *y);
+hb_bool_t
+hb_font_get_glyph_v_origin (hb_font_t *font,
+                            hb_codepoint_t glyph,
+                            hb_position_t *x, hb_position_t *y);
+
+hb_position_t
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+                             hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
+hb_position_t
+hb_font_get_glyph_v_kerning (hb_font_t *font,
+                             hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
+
+hb_bool_t
+hb_font_get_glyph_extents (hb_font_t *font,
+                           hb_codepoint_t glyph,
+                           hb_glyph_extents_t *extents);
+
+hb_bool_t
+hb_font_get_glyph_contour_point (hb_font_t *font,
+                                 hb_codepoint_t glyph, unsigned int point_index,
+                                 hb_position_t *x, hb_position_t *y);
+
+hb_bool_t
+hb_font_get_glyph_name (hb_font_t *font,
+                        hb_codepoint_t glyph,
+                        char *name, unsigned int size);
+hb_bool_t
+hb_font_get_glyph_from_name (hb_font_t *font,
+                             const char *name, int len, /* -1 means nul-terminated */
+                             hb_codepoint_t *glyph);
+
+
+/* high-level funcs, with fallback */
+
+void
+hb_font_get_glyph_advance_for_direction (hb_font_t *font,
+                                         hb_codepoint_t glyph,
+                                         hb_direction_t direction,
+                                         hb_position_t *x, hb_position_t *y);
+void
+hb_font_get_glyph_origin_for_direction (hb_font_t *font,
+                                        hb_codepoint_t glyph,
+                                        hb_direction_t direction,
+                                        hb_position_t *x, hb_position_t *y);
+void
+hb_font_add_glyph_origin_for_direction (hb_font_t *font,
+                                        hb_codepoint_t glyph,
+                                        hb_direction_t direction,
+                                        hb_position_t *x, hb_position_t *y);
+void
+hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
+                                             hb_codepoint_t glyph,
+                                             hb_direction_t direction,
+                                             hb_position_t *x, hb_position_t *y);
+
+void
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+                                         hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+                                         hb_direction_t direction,
+                                         hb_position_t *x, hb_position_t *y);
+
+hb_bool_t
+hb_font_get_glyph_extents_for_origin (hb_font_t *font,
+                                      hb_codepoint_t glyph,
+                                      hb_direction_t direction,
+                                      hb_glyph_extents_t *extents);
+
+hb_bool_t
+hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
+                                            hb_codepoint_t glyph, unsigned int point_index,
+                                            hb_direction_t direction,
+                                            hb_position_t *x, hb_position_t *y);
+
+/* Generates gidDDD if glyph has no name. */
+void
+hb_font_glyph_to_string (hb_font_t *font,
+                         hb_codepoint_t glyph,
+                         char *s, unsigned int size);
+/* Parses gidDDD and uniUUUU strings automatically. */
+hb_bool_t
+hb_font_glyph_from_string (hb_font_t *font,
+                           const char *s, int len, /* -1 means nul-terminated */
+                           hb_codepoint_t *glyph);
+
+
+/*
+ * hb_font_t
+ */
+
+/* Fonts are very light-weight objects */
+
+hb_font_t *
+hb_font_create (hb_face_t *face);
+
+hb_font_t *
+hb_font_create_sub_font (hb_font_t *parent);
+
+hb_font_t *
+hb_font_get_empty (void);
+
+hb_font_t *
+hb_font_reference (hb_font_t *font);
+
+void
+hb_font_destroy (hb_font_t *font);
+
+hb_bool_t
+hb_font_set_user_data (hb_font_t          *font,
+                       hb_user_data_key_t *key,
+                       void *              data,
+                       hb_destroy_func_t   destroy,
+                       hb_bool_t           replace);
+
+
+void *
+hb_font_get_user_data (hb_font_t          *font,
+                       hb_user_data_key_t *key);
+
+void
+hb_font_make_immutable (hb_font_t *font);
+
+hb_bool_t
+hb_font_is_immutable (hb_font_t *font);
+
+void
+hb_font_set_parent (hb_font_t *font,
+                    hb_font_t *parent);
+
+hb_font_t *
+hb_font_get_parent (hb_font_t *font);
+
+hb_face_t *
+hb_font_get_face (hb_font_t *font);
+
+
+void
+hb_font_set_funcs (hb_font_t         *font,
+                   hb_font_funcs_t   *klass,
+                   void              *font_data,
+                   hb_destroy_func_t  destroy);
+
+/* Be *very* careful with this function! */
+void
+hb_font_set_funcs_data (hb_font_t         *font,
+                        void              *font_data,
+                        hb_destroy_func_t  destroy);
+
+
+void
+hb_font_set_scale (hb_font_t *font,
+                   int x_scale,
+                   int y_scale);
+
+void
+hb_font_get_scale (hb_font_t *font,
+                   int *x_scale,
+                   int *y_scale);
+
+/*
+ * A zero value means "no hinting in that direction"
+ */
+void
+hb_font_set_ppem (hb_font_t *font,
+                  unsigned int x_ppem,
+                  unsigned int y_ppem);
+
+void
+hb_font_get_ppem (hb_font_t *font,
+                  unsigned int *x_ppem,
+                  unsigned int *y_ppem);
+
+
+HB_END_DECLS
+
+#endif /* HB_FONT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,650 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2009  Keith Stribley
+ * Copyright © 2015  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-ft.h"
+
+#include "hb-font-private.hh"
+
+#include FT_ADVANCES_H
+#include FT_TRUETYPE_TABLES_H
+
+
+
+#ifndef HB_DEBUG_FT
+#define HB_DEBUG_FT (HB_DEBUG+0)
+#endif
+
+
+/* TODO:
+ *
+ * In general, this file does a fine job of what it's supposed to do.
+ * There are, however, things that need more work:
+ *
+ *   - I remember seeing FT_Get_Advance() without the NO_HINTING flag to be buggy.
+ *     Have not investigated.
+ *
+ *   - FreeType works in 26.6 mode.  Clients can decide to use that mode, and everything
+ *     would work fine.  However, we also abuse this API for performing in font-space,
+ *     but don't pass the correct flags to FreeType.  We just abuse the no-hinting mode
+ *     for that, such that no rounding etc happens.  As such, we don't set ppem, and
+ *     pass NO_HINTING as load_flags.  Would be much better to use NO_SCALE, and scale
+ *     ourselves, like we do in uniscribe, etc.
+ *
+ *   - We don't handle / allow for emboldening / obliqueing.
+ *
+ *   - In the future, we should add constructors to create fonts in font space?
+ *
+ *   - FT_Load_Glyph() is exteremely costly.  Do something about it?
+ */
+
+
+struct hb_ft_font_t
+{
+  FT_Face ft_face;
+  int load_flags;
+  bool unref; /* Whether to destroy ft_face when done. */
+};
+
+static hb_ft_font_t *
+_hb_ft_font_create (FT_Face ft_face, bool unref)
+{
+  hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t));
+
+  if (unlikely (!ft_font))
+    return NULL;
+
+  ft_font->ft_face = ft_face;
+  ft_font->unref = unref;
+
+  ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
+
+  return ft_font;
+}
+
+static void
+_hb_ft_font_destroy (hb_ft_font_t *ft_font)
+{
+  if (ft_font->unref)
+    FT_Done_Face (ft_font->ft_face);
+
+  free (ft_font);
+}
+
+/**
+ * hb_ft_font_set_load_flags:
+ * @font:
+ * @load_flags:
+ *
+ *
+ *
+ * Since: 1.0.5
+ **/
+void
+hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
+{
+  if (font->immutable)
+    return;
+
+  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+    return;
+
+  hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
+
+  ft_font->load_flags = load_flags;
+}
+
+/**
+ * hb_ft_font_get_load_flags:
+ * @font:
+ *
+ *
+ *
+ * Return value:
+ * Since: 1.0.5
+ **/
+int
+hb_ft_font_get_load_flags (hb_font_t *font)
+{
+  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+    return 0;
+
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
+
+  return ft_font->load_flags;
+}
+
+FT_Face
+hb_ft_font_get_face (hb_font_t *font)
+{
+  if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
+    return NULL;
+
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
+
+  return ft_font->ft_face;
+}
+
+
+
+static hb_bool_t
+hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
+                 void *font_data,
+                 hb_codepoint_t unicode,
+                 hb_codepoint_t variation_selector,
+                 hb_codepoint_t *glyph,
+                 void *user_data HB_UNUSED)
+
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  unsigned int g;
+
+  if (likely (!variation_selector))
+    g = FT_Get_Char_Index (ft_font->ft_face, unicode);
+  else
+    g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
+
+  if (unlikely (!g))
+    return false;
+
+  *glyph = g;
+  return true;
+}
+
+static hb_position_t
+hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
+                           void *font_data,
+                           hb_codepoint_t glyph,
+                           void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Fixed v;
+
+  if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags, &v)))
+    return 0;
+
+  if (font->x_scale < 0)
+    v = -v;
+
+  return (v + (1<<9)) >> 10;
+}
+
+static hb_position_t
+hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
+                           void *font_data,
+                           hb_codepoint_t glyph,
+                           void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Fixed v;
+
+  if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v)))
+    return 0;
+
+  if (font->y_scale < 0)
+    v = -v;
+
+  /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
+   * have a Y growing upward.  Hence the extra negation. */
+  return (-v + (1<<9)) >> 10;
+}
+
+static hb_bool_t
+hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
+                          void *font_data HB_UNUSED,
+                          hb_codepoint_t glyph HB_UNUSED,
+                          hb_position_t *x HB_UNUSED,
+                          hb_position_t *y HB_UNUSED,
+                          void *user_data HB_UNUSED)
+{
+  /* We always work in the horizontal coordinates. */
+  return true;
+}
+
+static hb_bool_t
+hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
+                          void *font_data,
+                          hb_codepoint_t glyph,
+                          hb_position_t *x,
+                          hb_position_t *y,
+                          void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Face ft_face = ft_font->ft_face;
+
+  if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
+    return false;
+
+  /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
+   * have a Y growing upward.  Hence the extra negation. */
+  *x = ft_face->glyph->metrics.horiBearingX -   ft_face->glyph->metrics.vertBearingX;
+  *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
+
+  if (font->x_scale < 0)
+    *x = -*x;
+  if (font->y_scale < 0)
+    *y = -*y;
+
+  return true;
+}
+
+static hb_position_t
+hb_ft_get_glyph_h_kerning (hb_font_t *font,
+                           void *font_data,
+                           hb_codepoint_t left_glyph,
+                           hb_codepoint_t right_glyph,
+                           void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Vector kerningv;
+
+  FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
+  if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
+    return 0;
+
+  return kerningv.x;
+}
+
+static hb_position_t
+hb_ft_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
+                           void *font_data HB_UNUSED,
+                           hb_codepoint_t top_glyph HB_UNUSED,
+                           hb_codepoint_t bottom_glyph HB_UNUSED,
+                           void *user_data HB_UNUSED)
+{
+  /* FreeType API doesn't support vertical kerning */
+  return 0;
+}
+
+static hb_bool_t
+hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
+                         void *font_data,
+                         hb_codepoint_t glyph,
+                         hb_glyph_extents_t *extents,
+                         void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Face ft_face = ft_font->ft_face;
+
+  if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
+    return false;
+
+  extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
+  extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
+  extents->width = ft_face->glyph->metrics.width;
+  extents->height = -ft_face->glyph->metrics.height;
+  return true;
+}
+
+static hb_bool_t
+hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
+                               void *font_data,
+                               hb_codepoint_t glyph,
+                               unsigned int point_index,
+                               hb_position_t *x,
+                               hb_position_t *y,
+                               void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Face ft_face = ft_font->ft_face;
+
+  if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
+      return false;
+
+  if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
+      return false;
+
+  if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
+      return false;
+
+  *x = ft_face->glyph->outline.points[point_index].x;
+  *y = ft_face->glyph->outline.points[point_index].y;
+
+  return true;
+}
+
+static hb_bool_t
+hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED,
+                      void *font_data,
+                      hb_codepoint_t glyph,
+                      char *name, unsigned int size,
+                      void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+
+  hb_bool_t ret = !FT_Get_Glyph_Name (ft_font->ft_face, glyph, name, size);
+  if (ret && (size && !*name))
+    ret = false;
+
+  return ret;
+}
+
+static hb_bool_t
+hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
+                           void *font_data,
+                           const char *name, int len, /* -1 means nul-terminated */
+                           hb_codepoint_t *glyph,
+                           void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Face ft_face = ft_font->ft_face;
+
+  if (len < 0)
+    *glyph = FT_Get_Name_Index (ft_face, (FT_String *) name);
+  else {
+    /* Make a nul-terminated version. */
+    char buf[128];
+    len = MIN (len, (int) sizeof (buf) - 1);
+    strncpy (buf, name, len);
+    buf[len] = '\0';
+    *glyph = FT_Get_Name_Index (ft_face, buf);
+  }
+
+  if (*glyph == 0)
+  {
+    /* Check whether the given name was actually the name of glyph 0. */
+    char buf[128];
+    if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) &&
+        len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len))
+      return true;
+  }
+
+  return *glyph != 0;
+}
+
+
+static void
+_hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
+{
+  static const hb_font_funcs_t ft_ffuncs = {
+    HB_OBJECT_HEADER_STATIC,
+
+    true, /* immutable */
+
+    {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_ft_get_##name,
+      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+    }
+  };
+
+  hb_font_set_funcs (font,
+                     const_cast<hb_font_funcs_t *> (&ft_ffuncs),
+                     _hb_ft_font_create (ft_face, unref),
+                     (hb_destroy_func_t) _hb_ft_font_destroy);
+}
+
+
+static hb_blob_t *
+reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+  FT_Face ft_face = (FT_Face) user_data;
+  FT_Byte *buffer;
+  FT_ULong  length = 0;
+  FT_Error error;
+
+  /* Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob */
+
+  error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
+  if (error)
+    return NULL;
+
+  buffer = (FT_Byte *) malloc (length);
+  if (buffer == NULL)
+    return NULL;
+
+  error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
+  if (error)
+    return NULL;
+
+  return hb_blob_create ((const char *) buffer, length,
+                         HB_MEMORY_MODE_WRITABLE,
+                         buffer, free);
+}
+
+/**
+ * hb_ft_face_create:
+ * @ft_face: (destroy destroy) (scope notified):
+ * @destroy:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ * Since: 0.9.2
+ **/
+hb_face_t *
+hb_ft_face_create (FT_Face           ft_face,
+                   hb_destroy_func_t destroy)
+{
+  hb_face_t *face;
+
+  if (ft_face->stream->read == NULL) {
+    hb_blob_t *blob;
+
+    blob = hb_blob_create ((const char *) ft_face->stream->base,
+                           (unsigned int) ft_face->stream->size,
+                           HB_MEMORY_MODE_READONLY,
+                           ft_face, destroy);
+    face = hb_face_create (blob, ft_face->face_index);
+    hb_blob_destroy (blob);
+  } else {
+    face = hb_face_create_for_tables (reference_table, ft_face, destroy);
+  }
+
+  hb_face_set_index (face, ft_face->face_index);
+  hb_face_set_upem (face, ft_face->units_per_EM);
+
+  return face;
+}
+
+/**
+ * hb_ft_face_create_referenced:
+ * @ft_face:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ * Since: 0.9.38
+ **/
+hb_face_t *
+hb_ft_face_create_referenced (FT_Face ft_face)
+{
+  FT_Reference_Face (ft_face);
+  return hb_ft_face_create (ft_face, (hb_destroy_func_t) FT_Done_Face);
+}
+
+static void
+hb_ft_face_finalize (FT_Face ft_face)
+{
+  hb_face_destroy ((hb_face_t *) ft_face->generic.data);
+}
+
+/**
+ * hb_ft_face_create_cached:
+ * @ft_face:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ * Since: 0.9.2
+ **/
+hb_face_t *
+hb_ft_face_create_cached (FT_Face ft_face)
+{
+  if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize))
+  {
+    if (ft_face->generic.finalizer)
+      ft_face->generic.finalizer (ft_face);
+
+    ft_face->generic.data = hb_ft_face_create (ft_face, NULL);
+    ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize;
+  }
+
+  return hb_face_reference ((hb_face_t *) ft_face->generic.data);
+}
+
+
+/**
+ * hb_ft_font_create:
+ * @ft_face: (destroy destroy) (scope notified):
+ * @destroy:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ * Since: 0.9.2
+ **/
+hb_font_t *
+hb_ft_font_create (FT_Face           ft_face,
+                   hb_destroy_func_t destroy)
+{
+  hb_font_t *font;
+  hb_face_t *face;
+
+  face = hb_ft_face_create (ft_face, destroy);
+  font = hb_font_create (face);
+  hb_face_destroy (face);
+  _hb_ft_font_set_funcs (font, ft_face, false);
+  hb_font_set_scale (font,
+                     (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16),
+                     (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16));
+#if 0 /* hb-ft works in no-hinting model */
+  hb_font_set_ppem (font,
+                    ft_face->size->metrics.x_ppem,
+                    ft_face->size->metrics.y_ppem);
+#endif
+
+  return font;
+}
+
+/**
+ * hb_ft_font_create_referenced:
+ * @ft_face:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ * Since: 0.9.38
+ **/
+hb_font_t *
+hb_ft_font_create_referenced (FT_Face ft_face)
+{
+  FT_Reference_Face (ft_face);
+  return hb_ft_font_create (ft_face, (hb_destroy_func_t) FT_Done_Face);
+}
+
+
+/* Thread-safe, lock-free, FT_Library */
+
+static FT_Library ft_library;
+
+#ifdef HB_USE_ATEXIT
+static
+void free_ft_library (void)
+{
+  FT_Done_FreeType (ft_library);
+}
+#endif
+
+static FT_Library
+get_ft_library (void)
+{
+retry:
+  FT_Library library = (FT_Library) hb_atomic_ptr_get (&ft_library);
+
+  if (unlikely (!library))
+  {
+    /* Not found; allocate one. */
+    if (FT_Init_FreeType (&library))
+      return NULL;
+
+    if (!hb_atomic_ptr_cmpexch (&ft_library, NULL, library)) {
+      FT_Done_FreeType (library);
+      goto retry;
+    }
+
+#ifdef HB_USE_ATEXIT
+    atexit (free_ft_library); /* First person registers atexit() callback. */
+#endif
+  }
+
+  return library;
+}
+
+static void
+_release_blob (FT_Face ft_face)
+{
+  hb_blob_destroy ((hb_blob_t *) ft_face->generic.data);
+}
+
+void
+hb_ft_font_set_funcs (hb_font_t *font)
+{
+  hb_blob_t *blob = hb_face_reference_blob (font->face);
+  unsigned int blob_length;
+  const char *blob_data = hb_blob_get_data (blob, &blob_length);
+  if (unlikely (!blob_length))
+    DEBUG_MSG (FT, font, "Font face has empty blob");
+
+  FT_Face ft_face = NULL;
+  FT_Error err = FT_New_Memory_Face (get_ft_library (),
+                                     (const FT_Byte *) blob_data,
+                                     blob_length,
+                                     hb_face_get_index (font->face),
+                                     &ft_face);
+
+  if (unlikely (err)) {
+    hb_blob_destroy (blob);
+    DEBUG_MSG (FT, font, "Font face FT_New_Memory_Face() failed");
+    return;
+  }
+
+  FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
+
+  FT_Set_Char_Size (ft_face,
+                    abs (font->x_scale), abs (font->y_scale),
+                    0, 0);
+#if 0
+                    font->x_ppem * 72 * 64 / font->x_scale,
+                    font->y_ppem * 72 * 64 / font->y_scale);
+#endif
+  if (font->x_scale < 0 || font->y_scale < 0)
+  {
+    FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0,
+                          0, font->y_scale < 0 ? -1 : +1};
+    FT_Set_Transform (ft_face, &matrix, NULL);
+  }
+
+  ft_face->generic.data = blob;
+  ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
+
+  _hb_ft_font_set_funcs (font, ft_face, true);
+  hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2015  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_FT_H
+#define HB_FT_H
+
+#include "hb.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+HB_BEGIN_DECLS
+
+/*
+ * Note: FreeType is not thread-safe.
+ * Hence, these functions are not either.
+ */
+
+/*
+ * hb-face from ft-face.
+ */
+
+/* This one creates a new hb-face for given ft-face.
+ * When the returned hb-face is destroyed, the destroy
+ * callback is called (if not NULL), with the ft-face passed
+ * to it.
+ *
+ * The client is responsible to make sure that ft-face is
+ * destroyed after hb-face is destroyed.
+ *
+ * Most often you don't want this function.  You should use either
+ * hb_ft_face_create_cached(), or hb_ft_face_create_referenced().
+ * In particular, if you are going to pass NULL as destroy, you
+ * probably should use (the more recent) hb_ft_face_create_referenced()
+ * instead.
+ */
+hb_face_t *
+hb_ft_face_create (FT_Face           ft_face,
+                   hb_destroy_func_t destroy);
+
+/* This version is like hb_ft_face_create(), except that it caches
+ * the hb-face using the generic pointer of the ft-face.  This means
+ * that subsequent calls to this function with the same ft-face will
+ * return the same hb-face (correctly referenced).
+ *
+ * Client is still responsible for making sure that ft-face is destroyed
+ * after hb-face is.
+ */
+hb_face_t *
+hb_ft_face_create_cached (FT_Face ft_face);
+
+/* This version is like hb_ft_face_create(), except that it calls
+ * FT_Reference_Face() on ft-face, as such keeping ft-face alive
+ * as long as the hb-face is.
+ *
+ * This is the most convenient version to use.  Use it unless you have
+ * very good reasons not to.
+ */
+hb_face_t *
+hb_ft_face_create_referenced (FT_Face ft_face);
+
+
+/*
+ * hb-font from ft-face.
+ */
+
+/*
+ * Note:
+ *
+ * Set face size on ft-face before creating hb-font from it.
+ * Otherwise hb-ft would NOT pick up the font size correctly.
+ */
+
+/* See notes on hb_ft_face_create().  Same issues re lifecycle-management
+ * apply here.  Use hb_ft_font_create_referenced() if you can. */
+hb_font_t *
+hb_ft_font_create (FT_Face           ft_face,
+                   hb_destroy_func_t destroy);
+
+/* See notes on hb_ft_face_create_referenced() re lifecycle-management
+ * issues. */
+hb_font_t *
+hb_ft_font_create_referenced (FT_Face ft_face);
+
+FT_Face
+hb_ft_font_get_face (hb_font_t *font);
+
+void
+hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
+
+int
+hb_ft_font_get_load_flags (hb_font_t *font);
+
+/* Makes an hb_font_t use FreeType internally to implement font functions. */
+void
+hb_ft_font_set_funcs (hb_font_t *font);
+
+
+HB_END_DECLS
+
+#endif /* HB_FT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-mutex-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2007  Chris Wilson
+ * Copyright © 2009,2010  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Contributor(s):
+ *      Chris Wilson <chris@chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_MUTEX_PRIVATE_HH
+#define HB_MUTEX_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* mutex */
+
+/* We need external help for these */
+
+#if defined(HB_MUTEX_IMPL_INIT) \
+ && defined(hb_mutex_impl_init) \
+ && defined(hb_mutex_impl_lock) \
+ && defined(hb_mutex_impl_unlock) \
+ && defined(hb_mutex_impl_finish)
+
+/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */
+
+
+#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
+
+#include <windows.h>
+typedef CRITICAL_SECTION hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT      {0}
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+#define hb_mutex_impl_init(M)   InitializeCriticalSectionEx (M, 0, 0)
+#else
+#define hb_mutex_impl_init(M)   InitializeCriticalSection (M)
+#endif
+#define hb_mutex_impl_lock(M)   EnterCriticalSection (M)
+#define hb_mutex_impl_unlock(M) LeaveCriticalSection (M)
+#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
+
+
+#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
+
+#include <pthread.h>
+typedef pthread_mutex_t hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT      PTHREAD_MUTEX_INITIALIZER
+#define hb_mutex_impl_init(M)   pthread_mutex_init (M, NULL)
+#define hb_mutex_impl_lock(M)   pthread_mutex_lock (M)
+#define hb_mutex_impl_unlock(M) pthread_mutex_unlock (M)
+#define hb_mutex_impl_finish(M) pthread_mutex_destroy (M)
+
+
+#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
+
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+# define HB_SCHED_YIELD() sched_yield ()
+#else
+# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
+#endif
+
+/* This actually is not a totally awful implementation. */
+typedef volatile int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT      0
+#define hb_mutex_impl_init(M)   *(M) = 0
+#define hb_mutex_impl_lock(M)   HB_STMT_START { while (__sync_lock_test_and_set((M), 1)) HB_SCHED_YIELD (); } HB_STMT_END
+#define hb_mutex_impl_unlock(M) __sync_lock_release (M)
+#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
+
+
+#elif !defined(HB_NO_MT)
+
+#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
+# include <sched.h>
+# define HB_SCHED_YIELD() sched_yield ()
+#else
+# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
+#endif
+
+#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
+typedef volatile int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT      0
+#define hb_mutex_impl_init(M)   *(M) = 0
+#define hb_mutex_impl_lock(M)   HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
+#define hb_mutex_impl_unlock(M) (*(M))--;
+#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
+
+
+#else /* HB_NO_MT */
+
+typedef int hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT      0
+#define hb_mutex_impl_init(M)   HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_lock(M)   HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END
+#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
+
+
+#endif
+
+
+#define HB_MUTEX_INIT           {HB_MUTEX_IMPL_INIT}
+
+struct hb_mutex_t
+{
+  /* TODO Add tracing. */
+
+  hb_mutex_impl_t m;
+
+  inline void init   (void) { hb_mutex_impl_init   (&m); }
+  inline void lock   (void) { hb_mutex_impl_lock   (&m); }
+  inline void unlock (void) { hb_mutex_impl_unlock (&m); }
+  inline void finish (void) { hb_mutex_impl_finish (&m); }
+};
+
+
+#endif /* HB_MUTEX_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-object-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,202 @@
+/*
+ * Copyright © 2007  Chris Wilson
+ * Copyright © 2009,2010  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Contributor(s):
+ *      Chris Wilson <chris@chris-wilson.co.uk>
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OBJECT_PRIVATE_HH
+#define HB_OBJECT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-atomic-private.hh"
+#include "hb-mutex-private.hh"
+
+
+/* Debug */
+
+#ifndef HB_DEBUG_OBJECT
+#define HB_DEBUG_OBJECT (HB_DEBUG+0)
+#endif
+
+
+/* reference_count */
+
+#define HB_REFERENCE_COUNT_INERT_VALUE -1
+#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD
+#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)}
+
+struct hb_reference_count_t
+{
+  hb_atomic_int_t ref_count;
+
+  inline void init (int v) { ref_count.set_unsafe (v); }
+  inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
+  inline int inc (void) { return ref_count.inc (); }
+  inline int dec (void) { return ref_count.dec (); }
+  inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
+
+  inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
+  inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; }
+};
+
+
+/* user_data */
+
+#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
+struct hb_user_data_array_t
+{
+  struct hb_user_data_item_t {
+    hb_user_data_key_t *key;
+    void *data;
+    hb_destroy_func_t destroy;
+
+    inline bool operator == (hb_user_data_key_t *other_key) const { return key == other_key; }
+    inline bool operator == (hb_user_data_item_t &other) const { return key == other.key; }
+
+    void finish (void) { if (destroy) destroy (data); }
+  };
+
+  hb_mutex_t lock;
+  hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
+
+  inline void init (void) { lock.init (); items.init (); }
+
+  HB_INTERNAL bool set (hb_user_data_key_t *key,
+                        void *              data,
+                        hb_destroy_func_t   destroy,
+                        hb_bool_t           replace);
+
+  HB_INTERNAL void *get (hb_user_data_key_t *key);
+
+  inline void finish (void) { items.finish (lock); lock.finish (); }
+};
+
+
+/* object_header */
+
+struct hb_object_header_t
+{
+  hb_reference_count_t ref_count;
+  hb_user_data_array_t user_data;
+
+#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT}
+
+  private:
+  ASSERT_POD ();
+};
+
+
+/* object */
+
+template <typename Type>
+static inline void hb_object_trace (const Type *obj, const char *function)
+{
+  DEBUG_MSG (OBJECT, (void *) obj,
+             "%s refcount=%d",
+             function,
+             obj ? obj->header.ref_count.get_unsafe () : 0);
+}
+
+template <typename Type>
+static inline Type *hb_object_create (void)
+{
+  Type *obj = (Type *) calloc (1, sizeof (Type));
+
+  if (unlikely (!obj))
+    return obj;
+
+  hb_object_init (obj);
+  hb_object_trace (obj, HB_FUNC);
+  return obj;
+}
+template <typename Type>
+static inline void hb_object_init (Type *obj)
+{
+  obj->header.ref_count.init (1);
+  obj->header.user_data.init ();
+}
+template <typename Type>
+static inline bool hb_object_is_inert (const Type *obj)
+{
+  return unlikely (obj->header.ref_count.is_inert ());
+}
+template <typename Type>
+static inline bool hb_object_is_valid (const Type *obj)
+{
+  return likely (obj->header.ref_count.is_valid ());
+}
+template <typename Type>
+static inline Type *hb_object_reference (Type *obj)
+{
+  hb_object_trace (obj, HB_FUNC);
+  if (unlikely (!obj || hb_object_is_inert (obj)))
+    return obj;
+  assert (hb_object_is_valid (obj));
+  obj->header.ref_count.inc ();
+  return obj;
+}
+template <typename Type>
+static inline bool hb_object_destroy (Type *obj)
+{
+  hb_object_trace (obj, HB_FUNC);
+  if (unlikely (!obj || hb_object_is_inert (obj)))
+    return false;
+  assert (hb_object_is_valid (obj));
+  if (obj->header.ref_count.dec () != 1)
+    return false;
+
+  obj->header.ref_count.finish (); /* Do this before user_data */
+  obj->header.user_data.finish ();
+  return true;
+}
+template <typename Type>
+static inline bool hb_object_set_user_data (Type               *obj,
+                                            hb_user_data_key_t *key,
+                                            void *              data,
+                                            hb_destroy_func_t   destroy,
+                                            hb_bool_t           replace)
+{
+  if (unlikely (!obj || hb_object_is_inert (obj)))
+    return false;
+  assert (hb_object_is_valid (obj));
+  return obj->header.user_data.set (key, data, destroy, replace);
+}
+
+template <typename Type>
+static inline void *hb_object_get_user_data (Type               *obj,
+                                             hb_user_data_key_t *key)
+{
+  if (unlikely (!obj || hb_object_is_inert (obj)))
+    return NULL;
+  assert (hb_object_is_valid (obj));
+  return obj->header.user_data.get (key);
+}
+
+
+#endif /* HB_OBJECT_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-file-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,268 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OPEN_FILE_PRIVATE_HH
+#define HB_OPEN_FILE_PRIVATE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ *
+ * The OpenType Font File
+ *
+ */
+
+
+/*
+ * Organization of an OpenType Font
+ */
+
+struct OpenTypeFontFile;
+struct OffsetTable;
+struct TTCHeader;
+
+
+typedef struct TableRecord
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  Tag           tag;            /* 4-byte identifier. */
+  CheckSum      checkSum;       /* CheckSum for this table. */
+  ULONG         offset;         /* Offset from beginning of TrueType font
+                                 * file. */
+  ULONG         length;         /* Length of this table. */
+  public:
+  DEFINE_SIZE_STATIC (16);
+} OpenTypeTable;
+
+typedef struct OffsetTable
+{
+  friend struct OpenTypeFontFile;
+
+  inline unsigned int get_table_count (void) const
+  { return numTables; }
+  inline const TableRecord& get_table (unsigned int i) const
+  {
+    if (unlikely (i >= numTables)) return Null(TableRecord);
+    return tables[i];
+  }
+  inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
+  {
+    Tag t;
+    t.set (tag);
+    unsigned int count = numTables;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (t == tables[i].tag)
+      {
+        if (table_index) *table_index = i;
+        return true;
+      }
+    }
+    if (table_index) *table_index = Index::NOT_FOUND_INDEX;
+    return false;
+  }
+  inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
+  {
+    unsigned int table_index;
+    find_table_index (tag, &table_index);
+    return get_table (table_index);
+  }
+
+  public:
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
+  }
+
+  protected:
+  Tag           sfnt_version;   /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
+  USHORT        numTables;      /* Number of tables. */
+  USHORT        searchRangeZ;   /* (Maximum power of 2 <= numTables) x 16 */
+  USHORT        entrySelectorZ; /* Log2(maximum power of 2 <= numTables). */
+  USHORT        rangeShiftZ;    /* NumTables x 16-searchRange. */
+  TableRecord   tables[VAR];    /* TableRecord entries. numTables items */
+  public:
+  DEFINE_SIZE_ARRAY (12, tables);
+} OpenTypeFontFace;
+
+
+/*
+ * TrueType Collections
+ */
+
+struct TTCHeaderVersion1
+{
+  friend struct TTCHeader;
+
+  inline unsigned int get_face_count (void) const { return table.len; }
+  inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (table.sanitize (c, this));
+  }
+
+  protected:
+  Tag           ttcTag;         /* TrueType Collection ID string: 'ttcf' */
+  FixedVersion  version;        /* Version of the TTC Header (1.0),
+                                 * 0x00010000u */
+  ArrayOf<OffsetTo<OffsetTable, ULONG>, ULONG>
+                table;          /* Array of offsets to the OffsetTable for each font
+                                 * from the beginning of the file */
+  public:
+  DEFINE_SIZE_ARRAY (12, table);
+};
+
+struct TTCHeader
+{
+  friend struct OpenTypeFontFile;
+
+  private:
+
+  inline unsigned int get_face_count (void) const
+  {
+    switch (u.header.version.major) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return u.version1.get_face_count ();
+    default:return 0;
+    }
+  }
+  inline const OpenTypeFontFace& get_face (unsigned int i) const
+  {
+    switch (u.header.version.major) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return u.version1.get_face (i);
+    default:return Null(OpenTypeFontFace);
+    }
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!u.header.version.sanitize (c))) return_trace (false);
+    switch (u.header.version.major) {
+    case 2: /* version 2 is compatible with version 1 */
+    case 1: return_trace (u.version1.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  union {
+  struct {
+  Tag           ttcTag;         /* TrueType Collection ID string: 'ttcf' */
+  FixedVersion  version;        /* Version of the TTC Header (1.0 or 2.0),
+                                 * 0x00010000u or 0x00020000u */
+  }                     header;
+  TTCHeaderVersion1     version1;
+  } u;
+};
+
+
+/*
+ * OpenType Font File
+ */
+
+struct OpenTypeFontFile
+{
+  static const hb_tag_t tableTag        = HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */
+
+  static const hb_tag_t CFFTag          = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
+  static const hb_tag_t TrueTypeTag     = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
+  static const hb_tag_t TTCTag          = HB_TAG ('t','t','c','f'); /* TrueType Collection */
+  static const hb_tag_t TrueTag         = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
+  static const hb_tag_t Typ1Tag         = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
+
+  inline hb_tag_t get_tag (void) const { return u.tag; }
+
+  inline unsigned int get_face_count (void) const
+  {
+    switch (u.tag) {
+    case CFFTag:        /* All the non-collection tags */
+    case TrueTag:
+    case Typ1Tag:
+    case TrueTypeTag:   return 1;
+    case TTCTag:        return u.ttcHeader.get_face_count ();
+    default:            return 0;
+    }
+  }
+  inline const OpenTypeFontFace& get_face (unsigned int i) const
+  {
+    switch (u.tag) {
+    /* Note: for non-collection SFNT data we ignore index.  This is because
+     * Apple dfont container is a container of SFNT's.  So each SFNT is a
+     * non-TTC, but the index is more than zero. */
+    case CFFTag:        /* All the non-collection tags */
+    case TrueTag:
+    case Typ1Tag:
+    case TrueTypeTag:   return u.fontFace;
+    case TTCTag:        return u.ttcHeader.get_face (i);
+    default:            return Null(OpenTypeFontFace);
+    }
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!u.tag.sanitize (c))) return_trace (false);
+    switch (u.tag) {
+    case CFFTag:        /* All the non-collection tags */
+    case TrueTag:
+    case Typ1Tag:
+    case TrueTypeTag:   return_trace (u.fontFace.sanitize (c));
+    case TTCTag:        return_trace (u.ttcHeader.sanitize (c));
+    default:            return_trace (true);
+    }
+  }
+
+  protected:
+  union {
+  Tag                   tag;            /* 4-byte identifier. */
+  OpenTypeFontFace      fontFace;
+  TTCHeader             ttcHeader;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (4, tag);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OPEN_FILE_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1046 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OPEN_TYPE_PRIVATE_HH
+#define HB_OPEN_TYPE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+namespace OT {
+
+
+
+/*
+ * Casts
+ */
+
+/* Cast to struct T, reference to reference */
+template<typename Type, typename TObject>
+static inline const Type& CastR(const TObject &X)
+{ return reinterpret_cast<const Type&> (X); }
+template<typename Type, typename TObject>
+static inline Type& CastR(TObject &X)
+{ return reinterpret_cast<Type&> (X); }
+
+/* Cast to struct T, pointer to pointer */
+template<typename Type, typename TObject>
+static inline const Type* CastP(const TObject *X)
+{ return reinterpret_cast<const Type*> (X); }
+template<typename Type, typename TObject>
+static inline Type* CastP(TObject *X)
+{ return reinterpret_cast<Type*> (X); }
+
+/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
+ * location pointed to by P plus Ofs bytes. */
+template<typename Type>
+static inline const Type& StructAtOffset(const void *P, unsigned int offset)
+{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
+template<typename Type>
+static inline Type& StructAtOffset(void *P, unsigned int offset)
+{ return * reinterpret_cast<Type*> ((char *) P + offset); }
+
+/* StructAfter<T>(X) returns the struct T& that is placed after X.
+ * Works with X of variable size also.  X must implement get_size() */
+template<typename Type, typename TObject>
+static inline const Type& StructAfter(const TObject &X)
+{ return StructAtOffset<Type>(&X, X.get_size()); }
+template<typename Type, typename TObject>
+static inline Type& StructAfter(TObject &X)
+{ return StructAtOffset<Type>(&X, X.get_size()); }
+
+
+
+/*
+ * Size checking
+ */
+
+/* Check _assertion in a method environment */
+#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
+  inline void _instance_assertion_on_line_##_line (void) const \
+  { \
+    ASSERT_STATIC (_assertion); \
+    ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
+  }
+# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
+# define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
+
+/* Check that _code compiles in a method environment */
+#define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
+  inline void _compiles_assertion_on_line_##_line (void) const \
+  { _code; }
+# define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
+# define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
+
+
+#define DEFINE_SIZE_STATIC(size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
+  static const unsigned int static_size = (size); \
+  static const unsigned int min_size = (size)
+
+/* Size signifying variable-sized array */
+#define VAR 1
+
+#define DEFINE_SIZE_UNION(size, _member) \
+  DEFINE_INSTANCE_ASSERTION (this->u._member.static_size == (size)); \
+  static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_MIN(size) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
+  static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_ARRAY(size, array) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
+  DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
+  static const unsigned int min_size = (size)
+
+#define DEFINE_SIZE_ARRAY2(size, array1, array2) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
+  DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
+  static const unsigned int min_size = (size)
+
+
+
+/*
+ * Null objects
+ */
+
+/* Global nul-content Null pool.  Enlarge as necessary. */
+/* TODO This really should be a extern HB_INTERNAL and defined somewhere... */
+static const void *_NullPool[(256+8) / sizeof (void *)];
+
+/* Generic nul-content Null objects. */
+template <typename Type>
+static inline const Type& Null (void) {
+  ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool));
+  return *CastP<Type> (_NullPool);
+}
+
+/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
+#define DEFINE_NULL_DATA(Type, data) \
+static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
+template <> \
+/*static*/ inline const Type& Null<Type> (void) { \
+  return *CastP<Type> (_Null##Type); \
+} /* The following line really exists such that we end in a place needing semicolon */ \
+ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
+
+/* Accessor macro. */
+#define Null(Type) Null<Type>()
+
+
+/*
+ * Dispatch
+ */
+
+template <typename Context, typename Return, unsigned int MaxDebugDepth>
+struct hb_dispatch_context_t
+{
+  static const unsigned int max_debug_depth = MaxDebugDepth;
+  typedef Return return_t;
+  template <typename T, typename F>
+  inline bool may_dispatch (const T *obj, const F *format) { return true; }
+  static return_t no_dispatch_return_value (void) { return Context::default_return_value (); }
+};
+
+
+/*
+ * Sanitize
+ */
+
+#ifndef HB_DEBUG_SANITIZE
+#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
+#endif
+
+
+#define TRACE_SANITIZE(this) \
+        hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
+        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+         "");
+
+/* This limits sanitizing time on really broken fonts. */
+#ifndef HB_SANITIZE_MAX_EDITS
+#define HB_SANITIZE_MAX_EDITS 100
+#endif
+
+struct hb_sanitize_context_t :
+       hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
+{
+  inline hb_sanitize_context_t (void) :
+        debug_depth (0),
+        start (NULL), end (NULL),
+        writable (false), edit_count (0),
+        blob (NULL) {}
+
+  inline const char *get_name (void) { return "SANITIZE"; }
+  template <typename T, typename F>
+  inline bool may_dispatch (const T *obj, const F *format)
+  { return format->sanitize (this); }
+  template <typename T>
+  inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
+  static return_t default_return_value (void) { return true; }
+  static return_t no_dispatch_return_value (void) { return false; }
+  bool stop_sublookup_iteration (const return_t r) const { return !r; }
+
+  inline void init (hb_blob_t *b)
+  {
+    this->blob = hb_blob_reference (b);
+    this->writable = false;
+  }
+
+  inline void start_processing (void)
+  {
+    this->start = hb_blob_get_data (this->blob, NULL);
+    this->end = this->start + hb_blob_get_length (this->blob);
+    assert (this->start <= this->end); /* Must not overflow. */
+    this->edit_count = 0;
+    this->debug_depth = 0;
+
+    DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
+                     "start [%p..%p] (%lu bytes)",
+                     this->start, this->end,
+                     (unsigned long) (this->end - this->start));
+  }
+
+  inline void end_processing (void)
+  {
+    DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
+                     "end [%p..%p] %u edit requests",
+                     this->start, this->end, this->edit_count);
+
+    hb_blob_destroy (this->blob);
+    this->blob = NULL;
+    this->start = this->end = NULL;
+  }
+
+  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;
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+       "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s",
+       p, p + len, len,
+       this->start, this->end,
+       ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
+
+  inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const
+  {
+    const char *p = (const char *) base;
+    bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
+    unsigned int array_size = record_size * len;
+    bool ok = !overflows && this->check_range (base, array_size);
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+       "check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s",
+       p, p + (record_size * len), record_size, len, (unsigned int) array_size,
+       this->start, this->end,
+       overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
+
+  template <typename Type>
+  inline bool check_struct (const Type *obj) const
+  {
+    return likely (this->check_range (obj, obj->min_size));
+  }
+
+  inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED)
+  {
+    if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
+      return false;
+
+    const char *p = (const char *) base;
+    this->edit_count++;
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+       "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
+       this->edit_count,
+       p, p + len, len,
+       this->start, this->end,
+       this->writable ? "GRANTED" : "DENIED");
+
+    return this->writable;
+  }
+
+  template <typename Type, typename ValueType>
+  inline bool try_set (const Type *obj, const ValueType &v) {
+    if (this->may_edit (obj, obj->static_size)) {
+      const_cast<Type *> (obj)->set (v);
+      return true;
+    }
+    return false;
+  }
+
+  mutable unsigned int debug_depth;
+  const char *start, *end;
+  bool writable;
+  unsigned int edit_count;
+  hb_blob_t *blob;
+};
+
+
+
+/* Template to sanitize an object. */
+template <typename Type>
+struct Sanitizer
+{
+  static hb_blob_t *sanitize (hb_blob_t *blob) {
+    hb_sanitize_context_t c[1];
+    bool sane;
+
+    /* TODO is_sane() stuff */
+
+    c->init (blob);
+
+  retry:
+    DEBUG_MSG_FUNC (SANITIZE, c->start, "start");
+
+    c->start_processing ();
+
+    if (unlikely (!c->start)) {
+      c->end_processing ();
+      return blob;
+    }
+
+    Type *t = CastP<Type> (const_cast<char *> (c->start));
+
+    sane = t->sanitize (c);
+    if (sane) {
+      if (c->edit_count) {
+        DEBUG_MSG_FUNC (SANITIZE, c->start, "passed first round with %d edits; going for second round", c->edit_count);
+
+        /* sanitize again to ensure no toe-stepping */
+        c->edit_count = 0;
+        sane = t->sanitize (c);
+        if (c->edit_count) {
+          DEBUG_MSG_FUNC (SANITIZE, c->start, "requested %d edits in second round; FAILLING", c->edit_count);
+          sane = false;
+        }
+      }
+    } else {
+      unsigned int edit_count = c->edit_count;
+      if (edit_count && !c->writable) {
+        c->start = hb_blob_get_data_writable (blob, NULL);
+        c->end = c->start + hb_blob_get_length (blob);
+
+        if (c->start) {
+          c->writable = true;
+          /* ok, we made it writable by relocating.  try again */
+          DEBUG_MSG_FUNC (SANITIZE, c->start, "retry");
+          goto retry;
+        }
+      }
+    }
+
+    c->end_processing ();
+
+    DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED");
+    if (sane)
+      return blob;
+    else {
+      hb_blob_destroy (blob);
+      return hb_blob_get_empty ();
+    }
+  }
+
+  static const Type* lock_instance (hb_blob_t *blob) {
+    hb_blob_make_immutable (blob);
+    const char *base = hb_blob_get_data (blob, NULL);
+    return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
+  }
+};
+
+
+
+/*
+ * Serialize
+ */
+
+#ifndef HB_DEBUG_SERIALIZE
+#define HB_DEBUG_SERIALIZE (HB_DEBUG+0)
+#endif
+
+
+#define TRACE_SERIALIZE(this) \
+        hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
+        (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
+         "");
+
+
+struct hb_serialize_context_t
+{
+  inline hb_serialize_context_t (void *start, unsigned int size)
+  {
+    this->start = (char *) start;
+    this->end = this->start + size;
+
+    this->ran_out_of_room = false;
+    this->head = this->start;
+    this->debug_depth = 0;
+  }
+
+  template <typename Type>
+  inline Type *start_serialize (void)
+  {
+    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
+                     "start [%p..%p] (%lu bytes)",
+                     this->start, this->end,
+                     (unsigned long) (this->end - this->start));
+
+    return start_embed<Type> ();
+  }
+
+  inline void end_serialize (void)
+  {
+    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
+                     "end [%p..%p] serialized %d bytes; %s",
+                     this->start, this->end,
+                     (int) (this->head - this->start),
+                     this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
+
+  }
+
+  template <typename Type>
+  inline Type *copy (void)
+  {
+    assert (!this->ran_out_of_room);
+    unsigned int len = this->head - this->start;
+    void *p = malloc (len);
+    if (p)
+      memcpy (p, this->start, len);
+    return reinterpret_cast<Type *> (p);
+  }
+
+  template <typename Type>
+  inline Type *allocate_size (unsigned int size)
+  {
+    if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
+      this->ran_out_of_room = true;
+      return NULL;
+    }
+    memset (this->head, 0, size);
+    char *ret = this->head;
+    this->head += size;
+    return reinterpret_cast<Type *> (ret);
+  }
+
+  template <typename Type>
+  inline Type *allocate_min (void)
+  {
+    return this->allocate_size<Type> (Type::min_size);
+  }
+
+  template <typename Type>
+  inline Type *start_embed (void)
+  {
+    Type *ret = reinterpret_cast<Type *> (this->head);
+    return ret;
+  }
+
+  template <typename Type>
+  inline Type *embed (const Type &obj)
+  {
+    unsigned int size = obj.get_size ();
+    Type *ret = this->allocate_size<Type> (size);
+    if (unlikely (!ret)) return NULL;
+    memcpy (ret, obj, size);
+    return ret;
+  }
+
+  template <typename Type>
+  inline Type *extend_min (Type &obj)
+  {
+    unsigned int size = obj.min_size;
+    assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
+    if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
+    return reinterpret_cast<Type *> (&obj);
+  }
+
+  template <typename Type>
+  inline Type *extend (Type &obj)
+  {
+    unsigned int size = obj.get_size ();
+    assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
+    if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
+    return reinterpret_cast<Type *> (&obj);
+  }
+
+  inline void truncate (void *head)
+  {
+    assert (this->start < head && head <= this->head);
+    this->head = (char *) head;
+  }
+
+  unsigned int debug_depth;
+  char *start, *end, *head;
+  bool ran_out_of_room;
+};
+
+template <typename Type>
+struct Supplier
+{
+  inline Supplier (const Type *array, unsigned int len_)
+  {
+    head = array;
+    len = len_;
+  }
+  inline const Type operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= len)) return Type ();
+    return head[i];
+  }
+
+  inline void advance (unsigned int count)
+  {
+    if (unlikely (count > len))
+      count = len;
+    len -= count;
+    head += count;
+  }
+
+  private:
+  inline Supplier (const Supplier<Type> &); /* Disallow copy */
+  inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
+
+  unsigned int len;
+  const Type *head;
+};
+
+
+
+
+/*
+ *
+ * The OpenType Font File: Data Types
+ */
+
+
+/* "The following data types are used in the OpenType font file.
+ *  All OpenType fonts use Motorola-style byte ordering (Big Endian):" */
+
+/*
+ * Int types
+ */
+
+
+template <typename Type, int Bytes> struct BEInt;
+
+template <typename Type>
+struct BEInt<Type, 1>
+{
+  public:
+  inline void set (Type V)
+  {
+    v = V;
+  }
+  inline operator Type (void) const
+  {
+    return v;
+  }
+  private: uint8_t v;
+};
+template <typename Type>
+struct BEInt<Type, 2>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[0] = (V >>  8) & 0xFF;
+    v[1] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[0] <<  8)
+         + (v[1]      );
+  }
+  private: uint8_t v[2];
+};
+template <typename Type>
+struct BEInt<Type, 3>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[0] = (V >> 16) & 0xFF;
+    v[1] = (V >>  8) & 0xFF;
+    v[2] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[0] << 16)
+         + (v[1] <<  8)
+         + (v[2]      );
+  }
+  private: uint8_t v[3];
+};
+template <typename Type>
+struct BEInt<Type, 4>
+{
+  public:
+  inline void set (Type V)
+  {
+    v[0] = (V >> 24) & 0xFF;
+    v[1] = (V >> 16) & 0xFF;
+    v[2] = (V >>  8) & 0xFF;
+    v[3] = (V      ) & 0xFF;
+  }
+  inline operator Type (void) const
+  {
+    return (v[0] << 24)
+         + (v[1] << 16)
+         + (v[2] <<  8)
+         + (v[3]      );
+  }
+  private: uint8_t v[4];
+};
+
+/* Integer types in big-endian order and no alignment requirement */
+template <typename Type, unsigned int Size>
+struct IntType
+{
+  inline void set (Type i) { v.set (i); }
+  inline operator Type(void) const { return v; }
+  inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
+  inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
+  static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
+  inline int cmp (Type a) const
+  {
+    Type b = v;
+    if (sizeof (Type) < sizeof (int))
+      return (int) a - (int) b;
+    else
+      return a < b ? -1 : a == b ? 0 : +1;
+  }
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+  protected:
+  BEInt<Type, Size> v;
+  public:
+  DEFINE_SIZE_STATIC (Size);
+};
+
+typedef IntType<uint8_t , 1> BYTE;      /* 8-bit unsigned 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<uint32_t, 3> UINT24;    /* 24-bit unsigned integer. */
+
+/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
+typedef SHORT FWORD;
+
+/* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
+typedef USHORT UFWORD;
+
+/* Date represented in number of seconds since 12:00 midnight, January 1,
+ * 1904. The value is represented as a signed 64-bit integer. */
+struct LONGDATETIME
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+  protected:
+  LONG major;
+  ULONG 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
+{
+  /* 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); }
+  inline operator char* (void) { return reinterpret_cast<char *> (&this->v); }
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+DEFINE_NULL_DATA (Tag, "    ");
+
+/* Glyph index number, same as uint16 (length = 16 bits) */
+struct GlyphID : USHORT {
+  static inline int cmp (const GlyphID *a, const GlyphID *b) { return b->USHORT::cmp (*a); }
+  inline int cmp (hb_codepoint_t a) const { return (int) a - (int) *this; }
+};
+
+/* Script/language-system/feature index */
+struct Index : USHORT {
+  static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
+};
+DEFINE_NULL_DATA (Index, "\xff\xff");
+
+/* Offset, Null offset = 0 */
+template <typename Type=USHORT>
+struct Offset : Type
+{
+  inline bool is_null (void) const { return 0 == *this; }
+  public:
+  DEFINE_SIZE_STATIC (sizeof(Type));
+};
+
+
+/* CheckSum */
+struct CheckSum : ULONG
+{
+  /* This is reference implementation from the spec. */
+  static inline uint32_t CalcTableChecksum (const ULONG *Table, uint32_t Length)
+  {
+    uint32_t Sum = 0L;
+    const ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size;
+
+    while (Table < EndPtr)
+      Sum += *Table++;
+    return Sum;
+  }
+
+  /* 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)); }
+
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+
+/*
+ * Version Numbers
+ */
+
+struct FixedVersion
+{
+  inline uint32_t to_int (void) const { return (major << 16) + minor; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  USHORT major;
+  USHORT minor;
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+
+
+/*
+ * Template subclasses of Offset that do the dereferencing.
+ * Use: (base+offset)
+ */
+
+template <typename Type, typename OffsetType=USHORT>
+struct OffsetTo : Offset<OffsetType>
+{
+  inline const Type& operator () (const void *base) const
+  {
+    unsigned int offset = *this;
+    if (unlikely (!offset)) return Null(Type);
+    return StructAtOffset<Type> (base, offset);
+  }
+
+  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;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this))) return_trace (false);
+    unsigned int offset = *this;
+    if (unlikely (!offset)) return_trace (true);
+    const Type &obj = StructAtOffset<Type> (base, offset);
+    return_trace (likely (obj.sanitize (c)) || neuter (c));
+  }
+  template <typename T>
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this))) return_trace (false);
+    unsigned int offset = *this;
+    if (unlikely (!offset)) return_trace (true);
+    const Type &obj = StructAtOffset<Type> (base, offset);
+    return_trace (likely (obj.sanitize (c, user_data)) || neuter (c));
+  }
+
+  /* Set the offset to Null */
+  inline bool neuter (hb_sanitize_context_t *c) const {
+    return c->try_set (this, 0);
+  }
+  DEFINE_SIZE_STATIC (sizeof(OffsetType));
+};
+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>
+static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); }
+
+
+/*
+ * Array Types
+ */
+
+/* An array with a number of elements. */
+template <typename Type, typename LenType=USHORT>
+struct ArrayOf
+{
+  const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
+  {
+    unsigned int count = len;
+    if (unlikely (start_offset > count))
+      count = 0;
+    else
+      count -= start_offset;
+    count = MIN (count, *pcount);
+    *pcount = count;
+    return array + start_offset;
+  }
+
+  inline const Type& operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= len)) return Null(Type);
+    return array[i];
+  }
+  inline Type& operator [] (unsigned int i)
+  {
+    return array[i];
+  }
+  inline unsigned int get_size (void) const
+  { return len.static_size + len * Type::static_size; }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         unsigned int items_len)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    len.set (items_len); /* TODO(serialize) Overflow? */
+    if (unlikely (!c->extend (*this))) return_trace (false);
+    return_trace (true);
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<Type> &items,
+                         unsigned int items_len)
+  {
+    TRACE_SERIALIZE (this);
+    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);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+
+    /* Note: for structs that do not reference other structs,
+     * we do not need to call their sanitize() as we already did
+     * a bound check on the aggregate array size.  We just include
+     * a small unreachable expression to make sure the structs
+     * pointed to do have a simple sanitize(), ie. they do not
+     * reference other structs via offsets.
+     */
+    (void) (false && array[0].sanitize (c));
+
+    return_trace (true);
+  }
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    unsigned int count = len;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!array[i].sanitize (c, base)))
+        return_trace (false);
+    return_trace (true);
+  }
+  template <typename T>
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    unsigned int count = len;
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!array[i].sanitize (c, base, user_data)))
+        return_trace (false);
+    return_trace (true);
+  }
+
+  template <typename SearchType>
+  inline int lsearch (const SearchType &x) const
+  {
+    unsigned int count = len;
+    for (unsigned int i = 0; i < count; i++)
+      if (!this->array[i].cmp (x))
+        return i;
+    return -1;
+  }
+
+  private:
+  inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len));
+  }
+
+  public:
+  LenType len;
+  Type array[VAR];
+  public:
+  DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+};
+
+/* Array of Offset's */
+template <typename Type>
+struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {};
+
+/* Array of offsets relative to the beginning of the array itself. */
+template <typename Type>
+struct OffsetListOf : OffsetArrayOf<Type>
+{
+  inline const Type& operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= this->len)) return Null(Type);
+    return this+this->array[i];
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (OffsetArrayOf<Type>::sanitize (c, this));
+  }
+  template <typename T>
+  inline bool sanitize (hb_sanitize_context_t *c, T user_data) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data));
+  }
+};
+
+
+/* An array starting at second element. */
+template <typename Type, typename LenType=USHORT>
+struct HeadlessArrayOf
+{
+  inline const Type& operator [] (unsigned int i) const
+  {
+    if (unlikely (i >= len || !i)) return Null(Type);
+    return array[i-1];
+  }
+  inline unsigned int get_size (void) const
+  { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<Type> &items,
+                         unsigned int items_len)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    len.set (items_len); /* TODO(serialize) Overflow? */
+    if (unlikely (!items_len)) return_trace (true);
+    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);
+    return_trace (true);
+  }
+
+  inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+  {
+    return c->check_struct (this)
+        && c->check_array (this, Type::static_size, len);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!sanitize_shallow (c))) return_trace (false);
+
+    /* Note: for structs that do not reference other structs,
+     * we do not need to call their sanitize() as we already did
+     * a bound check on the aggregate array size.  We just include
+     * a small unreachable expression to make sure the structs
+     * pointed to do have a simple sanitize(), ie. they do not
+     * reference other structs via offsets.
+     */
+    (void) (false && array[0].sanitize (c));
+
+    return_trace (true);
+  }
+
+  LenType len;
+  Type array[VAR];
+  public:
+  DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+};
+
+
+/* An array with sorted elements.  Supports binary searching. */
+template <typename Type, typename LenType=USHORT>
+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. */
+    int min = 0, max = (int) this->len - 1;
+    while (min <= max)
+    {
+      int mid = (min + max) / 2;
+      int c = this->array[mid].cmp (x);
+      if (c < 0)
+        max = mid - 1;
+      else if (c > 0)
+        min = mid + 1;
+      else
+        return mid;
+    }
+    return -1;
+  }
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OPEN_TYPE_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,528 @@
+/*
+ * Copyright © 2014  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_CMAP_TABLE_HH
+#define HB_OT_CMAP_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * cmap -- Character To Glyph Index Mapping Table
+ */
+
+#define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
+
+
+struct CmapSubtableFormat0
+{
+  inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+  {
+    hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0;
+    if (!gid)
+      return false;
+    *glyph = gid;
+    return true;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  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
+                                 * code to glyph index values. */
+  public:
+  DEFINE_SIZE_STATIC (6 + 256);
+};
+
+struct CmapSubtableFormat4
+{
+  inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+  {
+    unsigned int segCount;
+    const USHORT *endCount;
+    const USHORT *startCount;
+    const USHORT *idDelta;
+    const USHORT *idRangeOffset;
+    const USHORT *glyphIdArray;
+    unsigned int glyphIdArrayLength;
+
+    segCount = this->segCountX2 / 2;
+    endCount = this->values;
+    startCount = endCount + segCount + 1;
+    idDelta = startCount + segCount;
+    idRangeOffset = idDelta + segCount;
+    glyphIdArray = idRangeOffset + segCount;
+    glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2;
+
+    /* Custom two-array bsearch. */
+    int min = 0, max = (int) segCount - 1;
+    unsigned int i;
+    while (min <= max)
+    {
+      int mid = (min + max) / 2;
+      if (codepoint < startCount[mid])
+        max = mid - 1;
+      else if (codepoint > endCount[mid])
+        min = mid + 1;
+      else
+      {
+        i = mid;
+        goto found;
+      }
+    }
+    return false;
+
+  found:
+    hb_codepoint_t gid;
+    unsigned int rangeOffset = idRangeOffset[i];
+    if (rangeOffset == 0)
+      gid = codepoint + idDelta[i];
+    else
+    {
+      /* Somebody has been smoking... */
+      unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount;
+      if (unlikely (index >= glyphIdArrayLength))
+        return false;
+      gid = glyphIdArray[index];
+      if (unlikely (!gid))
+        return false;
+      gid += idDelta[i];
+    }
+
+    *glyph = gid & 0xFFFFu;
+    return true;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    if (unlikely (!c->check_range (this, length)))
+    {
+      /* Some broken fonts have too long of a "length" value.
+       * If that is the case, just change the value to truncate
+       * the subtable at the end of the blob. */
+      uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535,
+                                            (uintptr_t) (c->end -
+                                                         (char *) this));
+      if (!c->try_set (&length, new_length))
+        return_trace (false);
+    }
+
+    return_trace (16 + 4 * (unsigned int) segCountX2 <= length);
+  }
+
+  protected:
+  USHORT        format;         /* Format number is set to 4. */
+  USHORT        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 */
+
+  USHORT        values[VAR];
+#if 0
+  USHORT        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) */
+#endif
+
+  public:
+  DEFINE_SIZE_ARRAY (14, values);
+};
+
+struct CmapSubtableLongGroup
+{
+  friend struct CmapSubtableFormat12;
+  friend struct CmapSubtableFormat13;
+
+  int cmp (hb_codepoint_t codepoint) const
+  {
+    if (codepoint < startCharCode) return -1;
+    if (codepoint > endCharCode)   return +1;
+    return 0;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  private:
+  ULONG         startCharCode;  /* First character code in this group. */
+  ULONG         endCharCode;    /* Last character code in this group. */
+  ULONG         glyphID;        /* Glyph index; interpretation depends on
+                                 * subtable format. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+template <typename UINT>
+struct CmapSubtableTrimmed
+{
+  inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+  {
+    /* Rely on our implicit array bound-checking. */
+    hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode];
+    if (!gid)
+      return false;
+    *glyph = gid;
+    return true;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && glyphIdArray.sanitize (c));
+  }
+
+  protected:
+  UINT          formatReserved; /* Subtable format and (maybe) padding. */
+  UINT          lengthZ;        /* Byte length of this subtable. */
+  UINT          languageZ;      /* Ignore. */
+  UINT          startCharCode;  /* First character code covered. */
+  ArrayOf<GlyphID, UINT>
+                glyphIdArray;   /* Array of glyph index values for character
+                                 * codes in the range. */
+  public:
+  DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray);
+};
+
+struct CmapSubtableFormat6  : CmapSubtableTrimmed<USHORT> {};
+struct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {};
+
+template <typename T>
+struct CmapSubtableLongSegmented
+{
+  inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+  {
+    int i = groups.bsearch (codepoint);
+    if (i == -1)
+      return false;
+    *glyph = T::group_get_glyph (groups[i], codepoint);
+    return true;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && groups.sanitize (c));
+  }
+
+  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>
+                groups;         /* Groupings. */
+  public:
+  DEFINE_SIZE_ARRAY (16, groups);
+};
+
+struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
+{
+  static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
+                                                hb_codepoint_t u)
+  { return group.glyphID + (u - group.startCharCode); }
+};
+
+struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
+{
+  static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
+                                                hb_codepoint_t u HB_UNUSED)
+  { return group.glyphID; }
+};
+
+typedef enum
+{
+  GLYPH_VARIANT_NOT_FOUND = 0,
+  GLYPH_VARIANT_FOUND = 1,
+  GLYPH_VARIANT_USE_DEFAULT = 2
+} glyph_variant_t;
+
+struct UnicodeValueRange
+{
+  inline int cmp (const hb_codepoint_t &codepoint) const
+  {
+    if (codepoint < startUnicodeValue) return -1;
+    if (codepoint > startUnicodeValue + additionalCount) return +1;
+    return 0;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  UINT24        startUnicodeValue;      /* First value in this range. */
+  BYTE          additionalCount;        /* Number of additional values in this
+                                         * range. */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+typedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS;
+
+struct UVSMapping
+{
+  inline int cmp (const hb_codepoint_t &codepoint) const
+  {
+    return unicodeValue.cmp (codepoint);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  UINT24        unicodeValue;   /* Base Unicode value of the UVS */
+  GlyphID       glyphID;        /* Glyph ID of the UVS */
+  public:
+  DEFINE_SIZE_STATIC (5);
+};
+
+typedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS;
+
+struct VariationSelectorRecord
+{
+  inline glyph_variant_t get_glyph (hb_codepoint_t codepoint,
+                                    hb_codepoint_t *glyph,
+                                    const void *base) const
+  {
+    int i;
+    const DefaultUVS &defaults = base+defaultUVS;
+    i = defaults.bsearch (codepoint);
+    if (i != -1)
+      return GLYPH_VARIANT_USE_DEFAULT;
+    const NonDefaultUVS &nonDefaults = base+nonDefaultUVS;
+    i = nonDefaults.bsearch (codepoint);
+    if (i != -1)
+    {
+      *glyph = nonDefaults[i].glyphID;
+       return GLYPH_VARIANT_FOUND;
+    }
+    return GLYPH_VARIANT_NOT_FOUND;
+  }
+
+  inline int cmp (const hb_codepoint_t &variation_selector) const
+  {
+    return varSelector.cmp (variation_selector);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  defaultUVS.sanitize (c, base) &&
+                  nonDefaultUVS.sanitize (c, base));
+  }
+
+  UINT24        varSelector;    /* Variation selector. */
+  OffsetTo<DefaultUVS, ULONG>
+                defaultUVS;     /* Offset to Default UVS Table. May be 0. */
+  OffsetTo<NonDefaultUVS, ULONG>
+                nonDefaultUVS;  /* Offset to Non-Default UVS Table. May be 0. */
+  public:
+  DEFINE_SIZE_STATIC (11);
+};
+
+struct CmapSubtableFormat14
+{
+  inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
+                                            hb_codepoint_t variation_selector,
+                                            hb_codepoint_t *glyph) const
+  {
+    return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  record.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;         /* Format number is set to 0. */
+  ULONG         lengthZ;        /* Byte length of this subtable. */
+  SortedArrayOf<VariationSelectorRecord, ULONG>
+                record;         /* Variation selector records; sorted
+                                 * in increasing order of `varSelector'. */
+  public:
+  DEFINE_SIZE_ARRAY (10, record);
+};
+
+struct CmapSubtable
+{
+  /* Note: We intentionally do NOT implement subtable formats 2 and 8. */
+
+  inline bool get_glyph (hb_codepoint_t codepoint,
+                         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 14:
+    default: return false;
+    }
+  }
+
+  inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
+                                            hb_codepoint_t variation_selector,
+                                            hb_codepoint_t *glyph) const
+  {
+    switch (u.format) {
+    case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph);
+    default: return GLYPH_VARIANT_NOT_FOUND;
+    }
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    switch (u.format) {
+    case  0: return_trace (u.format0 .sanitize (c));
+    case  4: return_trace (u.format4 .sanitize (c));
+    case  6: return_trace (u.format6 .sanitize (c));
+    case 10: return_trace (u.format10.sanitize (c));
+    case 12: return_trace (u.format12.sanitize (c));
+    case 13: return_trace (u.format13.sanitize (c));
+    case 14: return_trace (u.format14.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  CmapSubtableFormat0   format0;
+  CmapSubtableFormat4   format4;
+  CmapSubtableFormat6   format6;
+  CmapSubtableFormat10  format10;
+  CmapSubtableFormat12  format12;
+  CmapSubtableFormat13  format13;
+  CmapSubtableFormat14  format14;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+
+struct EncodingRecord
+{
+  inline int cmp (const EncodingRecord &other) const
+  {
+    int ret;
+    ret = platformID.cmp (other.platformID);
+    if (ret) return ret;
+    ret = encodingID.cmp (other.encodingID);
+    if (ret) return ret;
+    return 0;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  subtable.sanitize (c, base));
+  }
+
+  USHORT        platformID;     /* Platform ID. */
+  USHORT        encodingID;     /* Platform-specific encoding ID. */
+  OffsetTo<CmapSubtable, ULONG>
+                subtable;       /* Byte offset from beginning of table to the subtable for this encoding. */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct cmap
+{
+  static const hb_tag_t tableTag        = HB_OT_TAG_cmap;
+
+  inline const CmapSubtable *find_subtable (unsigned int platform_id,
+                                            unsigned int encoding_id) const
+  {
+    EncodingRecord key;
+    key.platformID.set (platform_id);
+    key.encodingID.set (encoding_id);
+
+    /* Note: We can use bsearch, but since it has no performance
+     * implications, we use lsearch and as such accept fonts with
+     * unsorted subtable list. */
+    int result = encodingRecord./*bsearch*/lsearch (key);
+    if (result == -1 || !encodingRecord[result].subtable)
+      return NULL;
+
+    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). */
+  SortedArrayOf<EncodingRecord>
+                        encodingRecord; /* Encoding tables. */
+  public:
+  DEFINE_SIZE_ARRAY (4, encodingRecord);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_CMAP_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,434 @@
+/*
+ * Copyright © 2011,2014  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, Roozbeh Pournader
+ */
+
+#include "hb-private.hh"
+
+#include "hb-ot.h"
+
+#include "hb-font-private.hh"
+
+#include "hb-ot-cmap-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"
+
+
+struct hb_ot_face_metrics_accelerator_t
+{
+  unsigned int num_metrics;
+  unsigned int num_advances;
+  unsigned int default_advance;
+  const OT::_mtx *table;
+  hb_blob_t *blob;
+
+  inline void init (hb_face_t *face,
+                    hb_tag_t _hea_tag, hb_tag_t _mtx_tag,
+                    unsigned int default_advance_)
+  {
+    this->default_advance = default_advance_;
+    this->num_metrics = face->get_num_glyphs ();
+
+    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;
+    hb_blob_destroy (_hea_blob);
+
+    this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag));
+    if (unlikely (!this->num_advances ||
+                  2 * (this->num_advances + this->num_metrics) > hb_blob_get_length (this->blob)))
+    {
+      this->num_metrics = this->num_advances = 0;
+      hb_blob_destroy (this->blob);
+      this->blob = hb_blob_get_empty ();
+    }
+    this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob);
+  }
+
+  inline void fini (void)
+  {
+    hb_blob_destroy (this->blob);
+  }
+
+  inline unsigned int get_advance (hb_codepoint_t glyph) 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;
+    }
+
+    if (glyph >= this->num_advances)
+      glyph = this->num_advances - 1;
+
+    return this->table->longMetric[glyph].advance;
+  }
+};
+
+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_cmap_accelerator_t
+{
+  const OT::CmapSubtable *table;
+  const OT::CmapSubtable *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 = NULL;
+    const OT::CmapSubtable *subtable_uvs = NULL;
+
+    /* 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);
+    /* Meh. */
+    if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
+
+    /* UVS subtable. */
+    if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5);
+    /* Meh. */
+    if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
+
+    this->table = subtable;
+    this->uvs_table = subtable_uvs;
+  }
+
+  inline void fini (void)
+  {
+    hb_blob_destroy (this->blob);
+  }
+
+  inline bool get_glyph (hb_codepoint_t  unicode,
+                         hb_codepoint_t  variation_selector,
+                         hb_codepoint_t *glyph) const
+  {
+    if (unlikely (variation_selector))
+    {
+      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 this->table->get_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;
+  hb_ot_face_glyf_accelerator_t glyf;
+};
+
+
+static hb_ot_font_t *
+_hb_ot_font_create (hb_face_t *face)
+{
+  hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
+
+  if (unlikely (!ot_font))
+    return NULL;
+
+  unsigned int upem = face->get_upem ();
+
+  ot_font->cmap.init (face);
+  ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1);
+  ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */
+  ot_font->glyf.init (face);
+
+  return ot_font;
+}
+
+static void
+_hb_ot_font_destroy (hb_ot_font_t *ot_font)
+{
+  ot_font->cmap.fini ();
+  ot_font->h_metrics.fini ();
+  ot_font->v_metrics.fini ();
+  ot_font->glyf.fini ();
+
+  free (ot_font);
+}
+
+
+static hb_bool_t
+hb_ot_get_glyph (hb_font_t *font HB_UNUSED,
+                 void *font_data,
+                 hb_codepoint_t unicode,
+                 hb_codepoint_t variation_selector,
+                 hb_codepoint_t *glyph,
+                 void *user_data HB_UNUSED)
+
+{
+  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+  return ot_font->cmap.get_glyph (unicode, variation_selector, glyph);
+}
+
+static hb_position_t
+hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
+                           void *font_data,
+                           hb_codepoint_t glyph,
+                           void *user_data HB_UNUSED)
+{
+  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+  return font->em_scale_x (ot_font->h_metrics.get_advance (glyph));
+}
+
+static hb_position_t
+hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
+                           void *font_data,
+                           hb_codepoint_t glyph,
+                           void *user_data HB_UNUSED)
+{
+  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+  return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph));
+}
+
+static hb_bool_t
+hb_ot_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
+                          void *font_data HB_UNUSED,
+                          hb_codepoint_t glyph HB_UNUSED,
+                          hb_position_t *x HB_UNUSED,
+                          hb_position_t *y HB_UNUSED,
+                          void *user_data HB_UNUSED)
+{
+  /* We always work in the horizontal coordinates. */
+  return true;
+}
+
+static hb_bool_t
+hb_ot_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
+                          void *font_data,
+                          hb_codepoint_t glyph,
+                          hb_position_t *x,
+                          hb_position_t *y,
+                          void *user_data HB_UNUSED)
+{
+  /* TODO */
+  return false;
+}
+
+static hb_position_t
+hb_ot_get_glyph_h_kerning (hb_font_t *font,
+                           void *font_data,
+                           hb_codepoint_t left_glyph,
+                           hb_codepoint_t right_glyph,
+                           void *user_data HB_UNUSED)
+{
+  /* TODO */
+  return 0;
+}
+
+static hb_position_t
+hb_ot_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
+                           void *font_data HB_UNUSED,
+                           hb_codepoint_t top_glyph HB_UNUSED,
+                           hb_codepoint_t bottom_glyph HB_UNUSED,
+                           void *user_data HB_UNUSED)
+{
+  /* OpenType doesn't have vertical-kerning other than GPOS. */
+  return 0;
+}
+
+static hb_bool_t
+hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
+                         void *font_data,
+                         hb_codepoint_t glyph,
+                         hb_glyph_extents_t *extents,
+                         void *user_data HB_UNUSED)
+{
+  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
+  bool ret = ot_font->glyf.get_extents (glyph, extents);
+  extents->x_bearing = font->em_scale_x (extents->x_bearing);
+  extents->y_bearing = font->em_scale_y (extents->y_bearing);
+  extents->width     = font->em_scale_x (extents->width);
+  extents->height    = font->em_scale_y (extents->height);
+  return ret;
+}
+
+static hb_bool_t
+hb_ot_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
+                               void *font_data,
+                               hb_codepoint_t glyph,
+                               unsigned int point_index,
+                               hb_position_t *x,
+                               hb_position_t *y,
+                               void *user_data HB_UNUSED)
+{
+  /* TODO */
+  return false;
+}
+
+static hb_bool_t
+hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
+                      void *font_data,
+                      hb_codepoint_t glyph,
+                      char *name, unsigned int size,
+                      void *user_data HB_UNUSED)
+{
+  /* TODO */
+  return false;
+}
+
+static hb_bool_t
+hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
+                           void *font_data,
+                           const char *name, int len, /* -1 means nul-terminated */
+                           hb_codepoint_t *glyph,
+                           void *user_data HB_UNUSED)
+{
+  /* TODO */
+  return false;
+}
+
+
+static hb_font_funcs_t *
+_hb_ot_get_font_funcs (void)
+{
+  static const hb_font_funcs_t ot_ffuncs = {
+    HB_OBJECT_HEADER_STATIC,
+
+    true, /* immutable */
+
+    {
+#define HB_FONT_FUNC_IMPLEMENT(name) hb_ot_get_##name,
+      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_FONT_FUNC_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_font_funcs_t *> (&ot_ffuncs);
+}
+
+
+/**
+ * Since: 0.9.28
+ **/
+void
+hb_ot_font_set_funcs (hb_font_t *font)
+{
+  hb_ot_font_t *ot_font = _hb_ot_font_create (font->face);
+  if (unlikely (!ot_font))
+    return;
+
+  hb_font_set_funcs (font,
+                     _hb_ot_get_font_funcs (),
+                     ot_font,
+                     (hb_destroy_func_t) _hb_ot_font_destroy);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2014  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, Roozbeh Pournader
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_FONT_H
+#define HB_OT_FONT_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+
+void
+hb_ot_font_set_funcs (hb_font_t *font);
+
+
+HB_END_DECLS
+
+#endif /* HB_OT_FONT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-glyf-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2015  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_GLYF_TABLE_HH
+#define HB_OT_GLYF_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * loca -- Index to Location
+ */
+
+#define HB_OT_TAG_loca HB_TAG('l','o','c','a')
+
+
+struct loca
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_loca;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    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);
+};
+
+
+/*
+ * glyf -- TrueType Glyph Data
+ */
+
+#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
+
+
+struct glyf
+{
+  static const hb_tag_t tableTag = HB_OT_TAG_glyf;
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    /* We don't check for anything specific here.  The users of the
+     * struct do all the hard work... */
+    return_trace (true);
+  }
+
+  public:
+  BYTE          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. */
+  SHORT         xMin;                   /* Minimum x for coordinate data. */
+  SHORT         yMin;                   /* Minimum y for coordinate data. */
+  SHORT         xMax;                   /* Maximum x for coordinate data. */
+  SHORT         yMax;                   /* Maximum y for coordinate data. */
+
+  DEFINE_SIZE_STATIC (10);
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_GLYF_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-head-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,152 @@
+/*
+ * Copyright © 2010  Red Hat, Inc.
+ * Copyright © 2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_HEAD_TABLE_HH
+#define HB_OT_HEAD_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * head -- Font Header
+ */
+
+#define HB_OT_TAG_head HB_TAG('h','e','a','d')
+
+struct head
+{
+  static const hb_tag_t tableTag        = HB_OT_TAG_head;
+
+  inline unsigned int get_upem (void) const
+  {
+    unsigned int upem = unitsPerEm;
+    /* If no valid head table found, assume 1000, which matches typical Type1 usage. */
+    return 16 <= upem && upem <= 16384 ? upem : 1000;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && likely (version.major == 1));
+  }
+
+  protected:
+  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
+                                         * 0xB1B0AFBAu - sum. */
+  ULONG         magicNumber;            /* Set to 0x5F0F3CF5u. */
+  USHORT        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
+                                         *   internal scaler math; may use fractional
+                                         *   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.
+                                         * Bit 5: This bit should be set in fonts that are
+                                         *   intended to e laid out vertically, and in
+                                         *   which the glyphs have been drawn such that an
+                                         *   x-coordinate of 0 corresponds to the desired
+                                         *   vertical baseline.
+                                         * Bit 6: This bit must be set to zero.
+                                         * Bit 7: This bit should be set if the font
+                                         *   requires layout for correct linguistic
+                                         *   rendering (e.g. Arabic fonts).
+                                         * Bit 8: This bit should be set for a GX font
+                                         *   which has one or more metamorphosis effects
+                                         *   designated as happening by default.
+                                         * Bit 9: This bit should be set if the font
+                                         *   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.
+                                         * Bit 12: Font converted (produce compatible metrics)
+                                         * Bit 13: Font optimized for ClearType™.
+                                         *   Note, fonts that rely on embedded bitmaps (EBDT)
+                                         *   for rendering should not be considered optimized
+                                         *   for ClearType, and therefore should keep this bit
+                                         *   cleared.
+                                         * Bit 14: Last Resort font. If set, indicates that
+                                         * the glyphs encoded in the cmap subtables are simply
+                                         * generic symbolic representations of code point
+                                         * ranges and don’t truly represent support for those
+                                         * code points. If unset, indicates that the glyphs
+                                         * 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
+                                         * 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);
+                                         * Bit 1: Italic (if set to 1)
+                                         * Bit 2: Underline (if set to 1)
+                                         * Bit 3: Outline (if set to 1)
+                                         * Bit 4: Shadow (if set to 1)
+                                         * 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).
+                                         * 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. */
+
+  DEFINE_SIZE_STATIC (54);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_HEAD_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hhea-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2011,2012  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_HHEA_TABLE_HH
+#define HB_OT_HHEA_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * hhea -- The Horizontal Header Table
+ * vhea -- The Vertical Header Table
+ */
+
+#define HB_OT_TAG_hhea HB_TAG('h','h','e','a')
+#define HB_OT_TAG_vhea HB_TAG('v','h','e','a')
+
+
+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);
+    return_trace (c->check_struct (this) && likely (version.major == 1));
+  }
+
+  public:
+  FixedVersion  version;                /* 0x00010000u for version 1.0. */
+  FWORD         ascender;               /* Typographic ascent. */
+  FWORD         descender;              /* Typographic descent. */
+  FWORD         lineGap;                /* Typographic line gap. */
+  UFWORD        advanceMax;             /* Maximum advance width/height value in
+                                         * metrics table. */
+  FWORD         minLeadingBearing;      /* Minimum left/top sidebearing value in
+                                         * metrics table. */
+  FWORD         minTrailingBearing;     /* Minimum right/bottom sidebearing value;
+                                         * calculated as Min(aw - lsb -
+                                         * (xMax - xMin)) for horizontal. */
+  FWORD         maxExtent;              /* horizontal: Max(lsb + (xMax - xMin)),
+                                         * vertical: minLeadingBearing+(yMax-yMin). */
+  SHORT         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
+                                         * 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
+                                         * table. */
+  public:
+  DEFINE_SIZE_STATIC (36);
+};
+
+struct hhea : _hea {
+  static const hb_tag_t tableTag        = HB_OT_TAG_hhea;
+};
+struct vhea : _hea {
+  static const hb_tag_t tableTag        = HB_OT_TAG_vhea;
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_HHEA_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hmtx-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2011,2012  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_HMTX_TABLE_HH
+#define HB_OT_HMTX_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * hmtx -- The Horizontal Metrics Table
+ * vmtx -- The Vertical Metrics Table
+ */
+
+#define HB_OT_TAG_hmtx HB_TAG('h','m','t','x')
+#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')
+
+
+struct LongMetric
+{
+  USHORT        advance; /* Advance width/height. */
+  SHORT         lsb; /* Leading (left/top) side bearing. */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct _mtx
+{
+  static const hb_tag_t tableTag = HB_TAG('_','m','t','x');
+
+  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);
+    /* We don't check for anything specific here.  The users of the
+     * struct do all the hard work... */
+    return_trace (true);
+  }
+
+  public:
+  LongMetric    longMetric[VAR];        /* Paired advance width and leading
+                                         * bearing values for each glyph. The
+                                         * value numOfHMetrics comes from
+                                         * the 'hhea' table. If the font is
+                                         * monospaced, only one entry need
+                                         * be in the array, but that entry is
+                                         * required. The last entry applies to
+                                         * all subsequent glyphs. */
+  SHORT         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
+                                         * derived from numGlyphs (from 'maxp'
+                                         * table) minus numberOfLongMetrics.
+                                         * This generally is used with a run
+                                         * of monospaced glyphs (e.g., Kanji
+                                         * fonts or Courier fonts). Only one
+                                         * run is allowed and it must be at
+                                         * the end. This allows a monospaced
+                                         * font to vary the side bearing
+                                         * values for each glyph. */
+  public:
+  DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX);
+};
+
+struct hmtx : _mtx {
+  static const hb_tag_t tableTag        = HB_OT_TAG_hmtx;
+};
+struct vmtx : _mtx {
+  static const hb_tag_t tableTag        = HB_OT_TAG_vmtx;
+};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_HMTX_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-common-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1224 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2010,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_COMMON_PRIVATE_HH
+#define HB_OT_LAYOUT_COMMON_PRIVATE_HH
+
+#include "hb-ot-layout-private.hh"
+#include "hb-open-type-private.hh"
+#include "hb-set-private.hh"
+
+
+namespace OT {
+
+
+#define TRACE_DISPATCH(this, format) \
+        hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
+        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+         "format %d", (int) format);
+
+
+#define NOT_COVERED             ((unsigned int) -1)
+#define MAX_NESTING_LEVEL       6
+#define MAX_CONTEXT_LENGTH      64
+
+
+
+/*
+ *
+ * OpenType Layout Common Table Formats
+ *
+ */
+
+
+/*
+ * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
+ */
+
+template <typename Type>
+struct Record
+{
+  inline int cmp (hb_tag_t a) const {
+    return tag.cmp (a);
+  }
+
+  struct sanitize_closure_t {
+    hb_tag_t tag;
+    const void *list_base;
+  };
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    const sanitize_closure_t closure = {tag, base};
+    return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
+  }
+
+  Tag           tag;            /* 4-byte Tag identifier */
+  OffsetTo<Type>
+                offset;         /* Offset from beginning of object holding
+                                 * the Record */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+template <typename Type>
+struct RecordArrayOf : SortedArrayOf<Record<Type> > {
+  inline const Tag& get_tag (unsigned int i) const
+  {
+    /* We cheat slightly and don't define separate Null objects
+     * for Record types.  Instead, we return the correct Null(Tag)
+     * here. */
+    if (unlikely (i >= this->len)) return Null(Tag);
+    return (*this)[i].tag;
+  }
+  inline unsigned int get_tags (unsigned int start_offset,
+                                unsigned int *record_count /* IN/OUT */,
+                                hb_tag_t     *record_tags /* OUT */) const
+  {
+    if (record_count) {
+      const Record<Type> *arr = this->sub_array (start_offset, record_count);
+      unsigned int count = *record_count;
+      for (unsigned int i = 0; i < count; i++)
+        record_tags[i] = arr[i].tag;
+    }
+    return this->len;
+  }
+  inline bool find_index (hb_tag_t tag, unsigned int *index) const
+  {
+    /* If we want to allow non-sorted data, we can lsearch(). */
+    int i = this->/*lsearch*/bsearch (tag);
+    if (i != -1) {
+        if (index) *index = i;
+        return true;
+    } else {
+      if (index) *index = Index::NOT_FOUND_INDEX;
+      return false;
+    }
+  }
+};
+
+template <typename Type>
+struct RecordListOf : RecordArrayOf<Type>
+{
+  inline const Type& operator [] (unsigned int i) const
+  { return this+RecordArrayOf<Type>::operator [](i).offset; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (RecordArrayOf<Type>::sanitize (c, this));
+  }
+};
+
+
+struct RangeRecord
+{
+  inline int cmp (hb_codepoint_t g) const {
+    return g < start ? -1 : g <= end ? 0 : +1 ;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  inline bool intersects (const hb_set_t *glyphs) const {
+    return glyphs->intersects (start, end);
+  }
+
+  template <typename set_t>
+  inline void add_coverage (set_t *glyphs) const {
+    glyphs->add_range (start, end);
+  }
+
+  GlyphID       start;          /* First GlyphID in the range */
+  GlyphID       end;            /* Last GlyphID in the range */
+  USHORT        value;          /* Value */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+DEFINE_NULL_DATA (RangeRecord, "\000\001");
+
+
+struct IndexArray : ArrayOf<Index>
+{
+  inline unsigned int get_indexes (unsigned int start_offset,
+                                   unsigned int *_count /* IN/OUT */,
+                                   unsigned int *_indexes /* OUT */) const
+  {
+    if (_count) {
+      const USHORT *arr = this->sub_array (start_offset, _count);
+      unsigned int count = *_count;
+      for (unsigned int i = 0; i < count; i++)
+        _indexes[i] = arr[i];
+    }
+    return this->len;
+  }
+};
+
+
+struct Script;
+struct LangSys;
+struct Feature;
+
+
+struct LangSys
+{
+  inline unsigned int get_feature_count (void) const
+  { return featureIndex.len; }
+  inline hb_tag_t get_feature_index (unsigned int i) const
+  { return featureIndex[i]; }
+  inline unsigned int get_feature_indexes (unsigned int start_offset,
+                                           unsigned int *feature_count /* IN/OUT */,
+                                           unsigned int *feature_indexes /* OUT */) const
+  { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
+
+  inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; }
+  inline unsigned int get_required_feature_index (void) const
+  {
+    if (reqFeatureIndex == 0xFFFFu)
+      return Index::NOT_FOUND_INDEX;
+   return reqFeatureIndex;;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c,
+                        const Record<LangSys>::sanitize_closure_t * = NULL) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && featureIndex.sanitize (c));
+  }
+
+  Offset<>      lookupOrderZ;   /* = Null (reserved for an offset to a
+                                 * reordering table) */
+  USHORT        reqFeatureIndex;/* Index of a feature required for this
+                                 * language system--if no required features
+                                 * = 0xFFFFu */
+  IndexArray    featureIndex;   /* Array of indices into the FeatureList */
+  public:
+  DEFINE_SIZE_ARRAY (6, featureIndex);
+};
+DEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF");
+
+
+struct Script
+{
+  inline unsigned int get_lang_sys_count (void) const
+  { return langSys.len; }
+  inline const Tag& get_lang_sys_tag (unsigned int i) const
+  { return langSys.get_tag (i); }
+  inline unsigned int get_lang_sys_tags (unsigned int start_offset,
+                                         unsigned int *lang_sys_count /* IN/OUT */,
+                                         hb_tag_t     *lang_sys_tags /* OUT */) const
+  { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
+  inline const LangSys& get_lang_sys (unsigned int i) const
+  {
+    if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
+    return this+langSys[i].offset;
+  }
+  inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
+  { return langSys.find_index (tag, index); }
+
+  inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
+  inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
+
+  inline bool sanitize (hb_sanitize_context_t *c,
+                        const Record<Script>::sanitize_closure_t * = NULL) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
+  }
+
+  protected:
+  OffsetTo<LangSys>
+                defaultLangSys; /* Offset to DefaultLangSys table--from
+                                 * beginning of Script table--may be Null */
+  RecordArrayOf<LangSys>
+                langSys;        /* Array of LangSysRecords--listed
+                                 * alphabetically by LangSysTag */
+  public:
+  DEFINE_SIZE_ARRAY (4, langSys);
+};
+
+typedef RecordListOf<Script> ScriptList;
+
+
+/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+struct FeatureParamsSize
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this))) return_trace (false);
+
+    /* This subtable has some "history", if you will.  Some earlier versions of
+     * Adobe tools calculated the offset of the FeatureParams sutable from the
+     * beginning of the FeatureList table!  Now, that is dealt with in the
+     * Feature implementation.  But we still need to be able to tell junk from
+     * real data.  Note: We don't check that the nameID actually exists.
+     *
+     * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk :
+     *
+     * Yes, it is correct that a new version of the AFDKO (version 2.0) will be
+     * coming out soon, and that the makeotf program will build a font with a
+     * 'size' feature that is correct by the specification.
+     *
+     * The specification for this feature tag is in the "OpenType Layout Tag
+     * Registry". You can see a copy of this at:
+     * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size
+     *
+     * Here is one set of rules to determine if the 'size' feature is built
+     * correctly, or as by the older versions of MakeOTF. You may be able to do
+     * 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
+     * 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
+     * beginning of the 'size' Feature table.
+     *
+     * If "design size" == 0:
+     *     fails check
+     *
+     * Else if ("subfamily identifier" == 0 and
+     *     "range start" == 0 and
+     *     "range end" == 0 and
+     *     "range start" == 0 and
+     *     "menu name ID" == 0)
+     *     passes check: this is the format used when there is a design size
+     * specified, but there is no recommended size range.
+     *
+     * Else if ("design size" <  "range start" or
+     *     "design size" >   "range end" or
+     *     "range end" <= "range start" or
+     *     "menu name ID"  < 256 or
+     *     "menu name ID"  > 32767 or
+     *     menu name ID is not a name ID which is actually in the name table)
+     *     fails test
+     * Else
+     *     passes test.
+     */
+
+    if (!designSize)
+      return_trace (false);
+    else if (subfamilyID == 0 &&
+             subfamilyNameID == 0 &&
+             rangeStart == 0 &&
+             rangeEnd == 0)
+      return_trace (true);
+    else if (designSize < rangeStart ||
+             designSize > rangeEnd ||
+             subfamilyNameID < 256 ||
+             subfamilyNameID > 32767)
+      return_trace (false);
+    else
+      return_trace (true);
+  }
+
+  USHORT        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
+                                 * as an identifier that associates fonts
+                                 * in a subfamily. All fonts which share a
+                                 * Preferred or Font Family name and which
+                                 * differ only by size range shall have the
+                                 * same subfamily value, and no fonts which
+                                 * differ in weight or style shall have the
+                                 * 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
+                                 * value must be set in the range 256 - 32767
+                                 * (inclusive). It records the value of a
+                                 * field in the name table, which must
+                                 * contain English-language strings encoded
+                                 * in Windows Unicode and Macintosh Roman,
+                                 * and may contain additional strings
+                                 * localized to other scripts and languages.
+                                 * Each of these strings is the name an
+                                 * application should use, in combination
+                                 * with the family name, to represent the
+                                 * subfamily in a menu.  Applications will
+                                 * choose the appropriate version based on
+                                 * their selection criteria. */
+  USHORT        rangeStart;     /* Large end of the recommended usage range
+                                 * (inclusive), stored in 720/inch units
+                                 * (decipoints). */
+  USHORT        rangeEnd;       /* Small end of the recommended usage range
+                                   (exclusive), stored in 720/inch units
+                                 * (decipoints). */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */
+struct FeatureParamsStylisticSet
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    /* Right now minorVersion is at zero.  Which means, any table supports
+     * the uiNameID field. */
+    return_trace (c->check_struct (this));
+  }
+
+  USHORT        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
+                                 * string (or strings, for multiple languages)
+                                 * for a user-interface label for this
+                                 * feature.  The values of uiLabelNameId and
+                                 * sampleTextNameId are expected to be in the
+                                 * font-specific name ID range (256-32767),
+                                 * though that is not a requirement in this
+                                 * Feature Parameters specification. The
+                                 * user-interface label for the feature can
+                                 * be provided in multiple languages. An
+                                 * English string should be included as a
+                                 * fallback. The string should be kept to a
+                                 * minimal length to fit comfortably with
+                                 * different application interfaces. */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
+struct FeatureParamsCharacterVariants
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  characters.sanitize (c));
+  }
+
+  USHORT        format;                 /* Format number is set to 0. */
+  USHORT        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 NULL.) */
+  USHORT        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
+                                         * NULL.) */
+  USHORT        sampleTextNameID;       /* The ‘name’ table name ID that
+                                         * specifies sample text that
+                                         * illustrates the effect of this
+                                         * feature. (May be NULL.) */
+  USHORT        numNamedParameters;     /* Number of named parameters. (May
+                                         * be zero.) */
+  USHORT        firstParamUILabelNameID;/* The first ‘name’ table name ID
+                                         * used to specify strings for
+                                         * user-interface labels for the
+                                         * feature parameters. (Must be zero
+                                         * if numParameters is zero.) */
+  ArrayOf<UINT24>
+                characters;             /* Array of the Unicode Scalar Value
+                                         * of the characters for which this
+                                         * feature provides glyph variants.
+                                         * (May be zero.) */
+  public:
+  DEFINE_SIZE_ARRAY (14, characters);
+};
+
+struct FeatureParams
+{
+  inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const
+  {
+    TRACE_SANITIZE (this);
+    if (tag == HB_TAG ('s','i','z','e'))
+      return_trace (u.size.sanitize (c));
+    if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
+      return_trace (u.stylisticSet.sanitize (c));
+    if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
+      return_trace (u.characterVariants.sanitize (c));
+    return_trace (true);
+  }
+
+  inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const
+  {
+    if (tag == HB_TAG ('s','i','z','e'))
+      return u.size;
+    return Null(FeatureParamsSize);
+  }
+
+  private:
+  union {
+  FeatureParamsSize                     size;
+  FeatureParamsStylisticSet             stylisticSet;
+  FeatureParamsCharacterVariants        characterVariants;
+  } u;
+  DEFINE_SIZE_STATIC (17);
+};
+
+struct Feature
+{
+  inline unsigned int get_lookup_count (void) const
+  { return lookupIndex.len; }
+  inline hb_tag_t get_lookup_index (unsigned int i) const
+  { return lookupIndex[i]; }
+  inline unsigned int get_lookup_indexes (unsigned int start_index,
+                                          unsigned int *lookup_count /* IN/OUT */,
+                                          unsigned int *lookup_tags /* OUT */) const
+  { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
+
+  inline const FeatureParams &get_feature_params (void) const
+  { return this+featureParams; }
+
+  inline bool sanitize (hb_sanitize_context_t *c,
+                        const Record<Feature>::sanitize_closure_t *closure) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
+      return_trace (false);
+
+    /* Some earlier versions of Adobe tools calculated the offset of the
+     * FeatureParams subtable from the beginning of the FeatureList table!
+     *
+     * If sanitizing "failed" for the FeatureParams subtable, try it with the
+     * alternative location.  We would know sanitize "failed" if old value
+     * of the offset was non-zero, but it's zeroed now.
+     *
+     * Only do this for the 'size' feature, since at the time of the faulty
+     * Adobe tools, only the 'size' feature had FeatureParams defined.
+     */
+
+    OffsetTo<FeatureParams> orig_offset = featureParams;
+    if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
+      return_trace (false);
+
+    if (likely (orig_offset.is_null ()))
+      return_trace (true);
+
+    if (featureParams == 0 && closure &&
+        closure->tag == HB_TAG ('s','i','z','e') &&
+        closure->list_base && closure->list_base < this)
+    {
+      unsigned int new_offset_int = (unsigned int) orig_offset -
+                                    (((char *) this) - ((char *) closure->list_base));
+
+      OffsetTo<FeatureParams> new_offset;
+      /* Check that it did not overflow. */
+      new_offset.set (new_offset_int);
+      if (new_offset == new_offset_int &&
+          c->try_set (&featureParams, new_offset) &&
+          !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
+        return_trace (false);
+    }
+
+    return_trace (true);
+  }
+
+  OffsetTo<FeatureParams>
+                 featureParams; /* Offset to Feature Parameters table (if one
+                                 * has been defined for the feature), relative
+                                 * to the beginning of the Feature Table; = Null
+                                 * if not required */
+  IndexArray     lookupIndex;   /* Array of LookupList indices */
+  public:
+  DEFINE_SIZE_ARRAY (4, lookupIndex);
+};
+
+typedef RecordListOf<Feature> FeatureList;
+
+
+struct LookupFlag : USHORT
+{
+  enum Flags {
+    RightToLeft         = 0x0001u,
+    IgnoreBaseGlyphs    = 0x0002u,
+    IgnoreLigatures     = 0x0004u,
+    IgnoreMarks         = 0x0008u,
+    IgnoreFlags         = 0x000Eu,
+    UseMarkFilteringSet = 0x0010u,
+    Reserved            = 0x00E0u,
+    MarkAttachmentType  = 0xFF00u
+  };
+  public:
+  DEFINE_SIZE_STATIC (2);
+};
+
+struct Lookup
+{
+  inline unsigned int get_subtable_count (void) const { return subTable.len; }
+
+  template <typename SubTableType>
+  inline const SubTableType& get_subtable (unsigned int i) const
+  { return this+CastR<OffsetArrayOf<SubTableType> > (subTable)[i]; }
+
+  template <typename SubTableType>
+  inline const OffsetArrayOf<SubTableType>& get_subtables (void) const
+  { return CastR<OffsetArrayOf<SubTableType> > (subTable); }
+  template <typename SubTableType>
+  inline OffsetArrayOf<SubTableType>& get_subtables (void)
+  { return CastR<OffsetArrayOf<SubTableType> > (subTable); }
+
+  inline unsigned int get_type (void) const { return lookupType; }
+
+  /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
+   * higher 16-bit is mark-filtering-set if the lookup uses one.
+   * Not to be confused with glyph_props which is very similar. */
+  inline uint32_t get_props (void) const
+  {
+    unsigned int flag = lookupFlag;
+    if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
+    {
+      const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+      flag += (markFilteringSet << 16);
+    }
+    return flag;
+  }
+
+  template <typename SubTableType, typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    unsigned int lookup_type = get_type ();
+    TRACE_DISPATCH (this, lookup_type);
+    unsigned int count = get_subtable_count ();
+    for (unsigned int i = 0; i < count; i++) {
+      typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (c, lookup_type);
+      if (c->stop_sublookup_iteration (r))
+        return_trace (r);
+    }
+    return_trace (c->default_return_value ());
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         unsigned int lookup_type,
+                         uint32_t lookup_props,
+                         unsigned int num_subtables)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    lookupType.set (lookup_type);
+    lookupFlag.set (lookup_props & 0xFFFFu);
+    if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
+    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
+    {
+      USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
+      markFilteringSet.set (lookup_props >> 16);
+    }
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    /* Real sanitize of the subtables is done by GSUB/GPOS/... */
+    if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
+    if (lookupFlag & LookupFlag::UseMarkFilteringSet)
+    {
+      const USHORT &markFilteringSet = StructAfter<USHORT> (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<> >
+                subTable;               /* Array of SubTables */
+  USHORT        markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
+                                         * structure. This field is only present if bit
+                                         * UseMarkFilteringSet of lookup flags is set. */
+  public:
+  DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX);
+};
+
+typedef OffsetListOf<Lookup> LookupList;
+
+
+/*
+ * Coverage Table
+ */
+
+struct CoverageFormat1
+{
+  friend struct Coverage;
+
+  private:
+  inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
+  {
+    int i = glyphArray.bsearch (glyph_id);
+    ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED);
+    return i;
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         unsigned int num_glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    glyphArray.len.set (num_glyphs);
+    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);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (glyphArray.sanitize (c));
+  }
+
+  inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+    return glyphs->has (glyphArray[index]);
+  }
+
+  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]);
+  }
+
+  public:
+  /* Older compilers need this to be public. */
+  struct Iter {
+    inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
+    inline bool more (void) { return i < c->glyphArray.len; }
+    inline void next (void) { i++; }
+    inline uint16_t get_glyph (void) { return c->glyphArray[i]; }
+    inline uint16_t get_coverage (void) { return i; }
+
+    private:
+    const struct CoverageFormat1 *c;
+    unsigned int i;
+  };
+  private:
+
+  protected:
+  USHORT        coverageFormat; /* Format identifier--format = 1 */
+  SortedArrayOf<GlyphID>
+                glyphArray;     /* Array of GlyphIDs--in numerical order */
+  public:
+  DEFINE_SIZE_ARRAY (4, glyphArray);
+};
+
+struct CoverageFormat2
+{
+  friend struct Coverage;
+
+  private:
+  inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
+  {
+    int i = rangeRecord.bsearch (glyph_id);
+    if (i != -1) {
+      const RangeRecord &range = rangeRecord[i];
+      return (unsigned int) range.value + (glyph_id - range.start);
+    }
+    return NOT_COVERED;
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         unsigned int num_glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+
+    if (unlikely (!num_glyphs)) return_trace (true);
+
+    unsigned int num_ranges = 1;
+    for (unsigned int i = 1; i < num_glyphs; i++)
+      if (glyphs[i - 1] + 1 != glyphs[i])
+        num_ranges++;
+    rangeRecord.len.set (num_ranges);
+    if (unlikely (!c->extend (rangeRecord))) return_trace (false);
+
+    unsigned int range = 0;
+    rangeRecord[range].start = glyphs[0];
+    rangeRecord[range].value.set (0);
+    for (unsigned int i = 1; i < num_glyphs; i++)
+      if (glyphs[i - 1] + 1 != glyphs[i]) {
+        range++;
+        rangeRecord[range].start = glyphs[i];
+        rangeRecord[range].value.set (i);
+        rangeRecord[range].end = glyphs[i];
+      } else {
+        rangeRecord[range].end = glyphs[i];
+      }
+    glyphs.advance (num_glyphs);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (rangeRecord.sanitize (c));
+  }
+
+  inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+    unsigned int i;
+    unsigned int count = rangeRecord.len;
+    for (i = 0; i < count; i++) {
+      const RangeRecord &range = rangeRecord[i];
+      if (range.value <= index &&
+          index < (unsigned int) range.value + (range.end - range.start) &&
+          range.intersects (glyphs))
+        return true;
+      else if (index < range.value)
+        return false;
+    }
+    return false;
+  }
+
+  template <typename set_t>
+  inline void add_coverage (set_t *glyphs) const {
+    unsigned int count = rangeRecord.len;
+    for (unsigned int i = 0; i < count; i++)
+      rangeRecord[i].add_coverage (glyphs);
+  }
+
+  public:
+  /* Older compilers need this to be public. */
+  struct Iter {
+    inline void init (const CoverageFormat2 &c_) {
+      c = &c_;
+      coverage = 0;
+      i = 0;
+      j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0;
+    }
+    inline bool more (void) { return i < c->rangeRecord.len; }
+    inline void next (void) {
+      coverage++;
+      if (j == c->rangeRecord[i].end) {
+        i++;
+        if (more ())
+          j = c->rangeRecord[i].start;
+        return;
+      }
+      j++;
+    }
+    inline uint16_t get_glyph (void) { return j; }
+    inline uint16_t get_coverage (void) { return coverage; }
+
+    private:
+    const struct CoverageFormat2 *c;
+    unsigned int i, j, coverage;
+  };
+  private:
+
+  protected:
+  USHORT        coverageFormat; /* Format identifier--format = 2 */
+  SortedArrayOf<RangeRecord>
+                rangeRecord;    /* Array of glyph ranges--ordered by
+                                 * Start GlyphID. rangeCount entries
+                                 * long */
+  public:
+  DEFINE_SIZE_ARRAY (4, rangeRecord);
+};
+
+struct Coverage
+{
+  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);
+    default:return NOT_COVERED;
+    }
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         unsigned int num_glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    unsigned int num_ranges = 1;
+    for (unsigned int i = 1; i < num_glyphs; i++)
+      if (glyphs[i - 1] + 1 != glyphs[i])
+        num_ranges++;
+    u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2);
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs));
+    case 2: return_trace (u.format2.serialize (c, glyphs, num_glyphs));
+    default:return_trace (false);
+    }
+  }
+
+  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));
+    default:return_trace (true);
+    }
+  }
+
+  inline bool intersects (const hb_set_t *glyphs) const {
+    /* TODO speed this up */
+    Coverage::Iter iter;
+    for (iter.init (*this); iter.more (); iter.next ()) {
+      if (glyphs->has (iter.get_glyph ()))
+        return true;
+    }
+    return false;
+  }
+
+  inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
+    switch (u.format) {
+    case 1: return u.format1.intersects_coverage (glyphs, index);
+    case 2: return u.format2.intersects_coverage (glyphs, index);
+    default:return false;
+    }
+  }
+
+  template <typename set_t>
+  inline void 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;
+    }
+  }
+
+  struct Iter {
+    Iter (void) : format (0) {};
+    inline void init (const Coverage &c_) {
+      format = c_.u.format;
+      switch (format) {
+      case 1: u.format1.init (c_.u.format1); return;
+      case 2: u.format2.init (c_.u.format2); return;
+      default:                               return;
+      }
+    }
+    inline bool more (void) {
+      switch (format) {
+      case 1: return u.format1.more ();
+      case 2: return u.format2.more ();
+      default:return false;
+      }
+    }
+    inline void next (void) {
+      switch (format) {
+      case 1: u.format1.next (); break;
+      case 2: u.format2.next (); break;
+      default:                   break;
+      }
+    }
+    inline uint16_t get_glyph (void) {
+      switch (format) {
+      case 1: return u.format1.get_glyph ();
+      case 2: return u.format2.get_glyph ();
+      default:return 0;
+      }
+    }
+    inline uint16_t get_coverage (void) {
+      switch (format) {
+      case 1: return u.format1.get_coverage ();
+      case 2: return u.format2.get_coverage ();
+      default:return -1;
+      }
+    }
+
+    private:
+    unsigned int format;
+    union {
+    CoverageFormat1::Iter       format1;
+    CoverageFormat2::Iter       format2;
+    } u;
+  };
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  CoverageFormat1       format1;
+  CoverageFormat2       format2;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * Class Definition Table
+ */
+
+struct ClassDefFormat1
+{
+  friend struct ClassDef;
+
+  private:
+  inline unsigned int get_class (hb_codepoint_t glyph_id) const
+  {
+    unsigned int i = (unsigned int) (glyph_id - startGlyph);
+    if (unlikely (i < classValue.len))
+      return classValue[i];
+    return 0;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && classValue.sanitize (c));
+  }
+
+  template <typename set_t>
+  inline void 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);
+  }
+
+  inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
+    unsigned int count = classValue.len;
+    if (klass == 0)
+    {
+      /* Match if there's any glyph that is not listed! */
+      hb_codepoint_t g = -1;
+      if (!hb_set_next (glyphs, &g))
+        return false;
+      if (g < startGlyph)
+        return true;
+      g = startGlyph + count - 1;
+      if (hb_set_next (glyphs, &g))
+        return true;
+      /* Fall through. */
+    }
+    for (unsigned int i = 0; i < count; i++)
+      if (classValue[i] == klass && glyphs->has (startGlyph + i))
+        return true;
+    return false;
+  }
+
+  protected:
+  USHORT        classFormat;            /* Format identifier--format = 1 */
+  GlyphID       startGlyph;             /* First GlyphID of the classValueArray */
+  ArrayOf<USHORT>
+                classValue;             /* Array of Class Values--one per GlyphID */
+  public:
+  DEFINE_SIZE_ARRAY (6, classValue);
+};
+
+struct ClassDefFormat2
+{
+  friend struct ClassDef;
+
+  private:
+  inline unsigned int get_class (hb_codepoint_t glyph_id) const
+  {
+    int i = rangeRecord.bsearch (glyph_id);
+    if (unlikely (i != -1))
+      return rangeRecord[i].value;
+    return 0;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (rangeRecord.sanitize (c));
+  }
+
+  template <typename set_t>
+  inline void 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);
+  }
+
+  inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
+    unsigned int count = rangeRecord.len;
+    if (klass == 0)
+    {
+      /* Match if there's any glyph that is not listed! */
+      hb_codepoint_t g = (hb_codepoint_t) -1;
+      for (unsigned int i = 0; i < count; i++)
+      {
+        if (!hb_set_next (glyphs, &g))
+          break;
+        if (g < rangeRecord[i].start)
+          return true;
+        g = rangeRecord[i].end;
+      }
+      if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g))
+        return true;
+      /* Fall through. */
+    }
+    for (unsigned int i = 0; i < count; i++)
+      if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
+        return true;
+    return false;
+  }
+
+  protected:
+  USHORT        classFormat;    /* Format identifier--format = 2 */
+  SortedArrayOf<RangeRecord>
+                rangeRecord;    /* Array of glyph ranges--ordered by
+                                 * Start GlyphID */
+  public:
+  DEFINE_SIZE_ARRAY (4, rangeRecord);
+};
+
+struct ClassDef
+{
+  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);
+    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));
+    default:return_trace (true);
+    }
+  }
+
+  inline void add_class (hb_set_t *glyphs, unsigned int klass) const {
+    switch (u.format) {
+    case 1: u.format1.add_class (glyphs, klass); return;
+    case 2: u.format2.add_class (glyphs, klass); return;
+    default:return;
+    }
+  }
+
+  inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
+    switch (u.format) {
+    case 1: return u.format1.intersects_class (glyphs, klass);
+    case 2: return u.format2.intersects_class (glyphs, klass);
+    default:return false;
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  ClassDefFormat1       format1;
+  ClassDefFormat2       format2;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * Device Tables
+ */
+
+struct Device
+{
+
+  inline hb_position_t get_x_delta (hb_font_t *font) const
+  { return get_delta (font->x_ppem, font->x_scale); }
+
+  inline hb_position_t get_y_delta (hb_font_t *font) const
+  { return get_delta (font->y_ppem, font->y_scale); }
+
+  inline int get_delta (unsigned int ppem, int scale) const
+  {
+    if (!ppem) return 0;
+
+    int pixels = get_delta_pixels (ppem);
+
+    if (!pixels) return 0;
+
+    return (int) (pixels * (int64_t) scale / ppem);
+  }
+
+
+  inline int get_delta_pixels (unsigned int ppem_size) const
+  {
+    unsigned int f = deltaFormat;
+    if (unlikely (f < 1 || f > 3))
+      return 0;
+
+    if (ppem_size < startSize || ppem_size > endSize)
+      return 0;
+
+    unsigned int s = ppem_size - startSize;
+
+    unsigned int byte = deltaValue[s >> (4 - f)];
+    unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
+    unsigned int mask = (0xFFFFu >> (16 - (1 << f)));
+
+    int delta = bits & mask;
+
+    if ((unsigned int) delta >= ((mask + 1) >> 1))
+      delta -= mask + 1;
+
+    return delta;
+  }
+
+  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)));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && c->check_range (this, this->get_size ()));
+  }
+
+  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
+                                         * 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 */
+  public:
+  DEFINE_SIZE_ARRAY (6, deltaValue);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gdef-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,443 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2010,2011,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GDEF_TABLE_HH
+#define HB_OT_LAYOUT_GDEF_TABLE_HH
+
+#include "hb-ot-layout-common-private.hh"
+
+#include "hb-font-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * Attachment List Table
+ */
+
+typedef ArrayOf<USHORT> AttachPoint;    /* Array of contour point indices--in
+                                         * increasing numerical order */
+
+struct AttachList
+{
+  inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
+                                         unsigned int start_offset,
+                                         unsigned int *point_count /* IN/OUT */,
+                                         unsigned int *point_array /* OUT */) const
+  {
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (index == NOT_COVERED)
+    {
+      if (point_count)
+        *point_count = 0;
+      return 0;
+    }
+
+    const AttachPoint &points = this+attachPoint[index];
+
+    if (point_count) {
+      const USHORT *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];
+    }
+
+    return points.len;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
+  }
+
+  protected:
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table -- from
+                                         * beginning of AttachList table */
+  OffsetArrayOf<AttachPoint>
+                attachPoint;            /* Array of AttachPoint tables
+                                         * in Coverage Index order */
+  public:
+  DEFINE_SIZE_ARRAY (4, attachPoint);
+};
+
+/*
+ * Ligature Caret Table
+ */
+
+struct CaretValueFormat1
+{
+  friend struct CaretValue;
+
+  private:
+  inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const
+  {
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  USHORT        caretValueFormat;       /* Format identifier--format = 1 */
+  SHORT         coordinate;             /* X or Y value, in design units */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat2
+{
+  friend struct CaretValue;
+
+  private:
+  inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+  {
+    hb_position_t x, y;
+    if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y))
+      return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
+    else
+      return 0;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  USHORT        caretValueFormat;       /* Format identifier--format = 2 */
+  USHORT        caretValuePoint;        /* Contour point index on glyph */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat3
+{
+  friend struct CaretValue;
+
+  inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const
+  {
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ?
+           font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font) :
+           font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        caretValueFormat;       /* Format identifier--format = 3 */
+  SHORT         coordinate;             /* X or Y value, in design units */
+  OffsetTo<Device>
+                deviceTable;            /* Offset to Device table for X or Y
+                                         * value--from beginning of CaretValue
+                                         * table */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct CaretValue
+{
+  inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_caret_value (font, direction, glyph_id);
+    case 2: return u.format2.get_caret_value (font, direction, glyph_id);
+    case 3: return u.format3.get_caret_value (font, direction, glyph_id);
+    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 (true);
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  CaretValueFormat1     format1;
+  CaretValueFormat2     format2;
+  CaretValueFormat3     format3;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+struct LigGlyph
+{
+  inline unsigned int get_lig_carets (hb_font_t *font,
+                                      hb_direction_t direction,
+                                      hb_codepoint_t glyph_id,
+                                      unsigned int start_offset,
+                                      unsigned int *caret_count /* IN/OUT */,
+                                      hb_position_t *caret_array /* OUT */) const
+  {
+    if (caret_count) {
+      const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count);
+      unsigned int count = *caret_count;
+      for (unsigned int i = 0; i < count; i++)
+        caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id);
+    }
+
+    return carets.len;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (carets.sanitize (c, this));
+  }
+
+  protected:
+  OffsetArrayOf<CaretValue>
+                carets;                 /* Offset array of CaretValue tables
+                                         * --from beginning of LigGlyph table
+                                         * --in increasing coordinate order */
+  public:
+  DEFINE_SIZE_ARRAY (2, carets);
+};
+
+struct LigCaretList
+{
+  inline unsigned int get_lig_carets (hb_font_t *font,
+                                      hb_direction_t direction,
+                                      hb_codepoint_t glyph_id,
+                                      unsigned int start_offset,
+                                      unsigned int *caret_count /* IN/OUT */,
+                                      hb_position_t *caret_array /* OUT */) const
+  {
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (index == NOT_COVERED)
+    {
+      if (caret_count)
+        *caret_count = 0;
+      return 0;
+    }
+    const LigGlyph &lig_glyph = this+ligGlyph[index];
+    return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
+  }
+
+  protected:
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of LigCaretList table */
+  OffsetArrayOf<LigGlyph>
+                ligGlyph;               /* Array of LigGlyph tables
+                                         * in Coverage Index order */
+  public:
+  DEFINE_SIZE_ARRAY (4, ligGlyph);
+};
+
+
+struct MarkGlyphSetsFormat1
+{
+  inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  ArrayOf<OffsetTo<Coverage, ULONG> >
+                coverage;               /* Array of long offsets to mark set
+                                         * coverage tables */
+  public:
+  DEFINE_SIZE_ARRAY (4, coverage);
+};
+
+struct MarkGlyphSets
+{
+  inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.covers (set_index, glyph_id);
+    default:return false;
+    }
+  }
+
+  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));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  MarkGlyphSetsFormat1  format1;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * GDEF -- The Glyph Definition Table
+ */
+
+struct GDEF
+{
+  static const hb_tag_t tableTag        = HB_OT_TAG_GDEF;
+
+  enum GlyphClasses {
+    UnclassifiedGlyph   = 0,
+    BaseGlyph           = 1,
+    LigatureGlyph       = 2,
+    MarkGlyph           = 3,
+    ComponentGlyph      = 4
+  };
+
+  inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
+  inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
+  { return (this+glyphClassDef).get_class (glyph); }
+  inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
+  { (this+glyphClassDef).add_class (glyphs, klass); }
+
+  inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
+  inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
+  { return (this+markAttachClassDef).get_class (glyph); }
+
+  inline bool has_attach_points (void) const { return attachList != 0; }
+  inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
+                                         unsigned int start_offset,
+                                         unsigned int *point_count /* IN/OUT */,
+                                         unsigned int *point_array /* OUT */) const
+  { return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); }
+
+  inline bool has_lig_carets (void) const { return ligCaretList != 0; }
+  inline unsigned int get_lig_carets (hb_font_t *font,
+                                      hb_direction_t direction,
+                                      hb_codepoint_t glyph_id,
+                                      unsigned int start_offset,
+                                      unsigned int *caret_count /* IN/OUT */,
+                                      hb_position_t *caret_array /* OUT */) const
+  { return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); }
+
+  inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef[0] != 0; }
+  inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (version.sanitize (c) &&
+                  likely (version.major == 1) &&
+                  glyphClassDef.sanitize (c, this) &&
+                  attachList.sanitize (c, this) &&
+                  ligCaretList.sanitize (c, this) &&
+                  markAttachClassDef.sanitize (c, this) &&
+                  (version.to_int () < 0x00010002u || markGlyphSetsDef[0].sanitize (c, this)));
+  }
+
+
+  /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
+   * glyph class and other bits, and high 8-bit gthe mark attachment type (if any).
+   * Not to be confused with lookup_props which is very similar. */
+  inline unsigned int get_glyph_props (hb_codepoint_t glyph) const
+  {
+    unsigned int klass = get_glyph_class (glyph);
+
+    ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs);
+    ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures);
+    ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks);
+
+    switch (klass) {
+    default:                    return 0;
+    case BaseGlyph:             return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+    case LigatureGlyph:         return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+    case MarkGlyph:
+          klass = get_mark_attachment_type (glyph);
+          return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
+    }
+  }
+
+
+  protected:
+  FixedVersion  version;                /* Version of the GDEF table--currently
+                                         * 0x00010002u */
+  OffsetTo<ClassDef>
+                glyphClassDef;          /* Offset to class definition table
+                                         * for glyph type--from beginning of
+                                         * GDEF header (may be Null) */
+  OffsetTo<AttachList>
+                attachList;             /* Offset to list of glyphs with
+                                         * attachment points--from beginning
+                                         * of GDEF header (may be Null) */
+  OffsetTo<LigCaretList>
+                ligCaretList;           /* Offset to list of positioning points
+                                         * for ligature carets--from beginning
+                                         * of GDEF header (may be Null) */
+  OffsetTo<ClassDef>
+                markAttachClassDef;     /* Offset to class definition table for
+                                         * mark attachment type--from beginning
+                                         * of GDEF header (may be Null) */
+  OffsetTo<MarkGlyphSets>
+                markGlyphSetsDef[VAR];  /* Offset to the table of mark set
+                                         * definitions--from beginning of GDEF
+                                         * header (may be NULL).  Introduced
+                                         * in version 00010002. */
+  public:
+  DEFINE_SIZE_ARRAY (12, markGlyphSetsDef);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gpos-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1643 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2010,2012,2013  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GPOS_TABLE_HH
+#define HB_OT_LAYOUT_GPOS_TABLE_HH
+
+#include "hb-ot-layout-gsubgpos-private.hh"
+
+
+namespace OT {
+
+
+/* buffer **position** var allocations */
+#define attach_lookback() var.u16[0] /* number of glyphs to go back to attach this glyph to its base */
+#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */
+
+
+/* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
+
+typedef USHORT Value;
+
+typedef Value ValueRecord[VAR];
+
+struct ValueFormat : USHORT
+{
+  enum Flags {
+    xPlacement  = 0x0001u,      /* Includes horizontal adjustment for placement */
+    yPlacement  = 0x0002u,      /* Includes vertical adjustment for placement */
+    xAdvance    = 0x0004u,      /* Includes horizontal adjustment for advance */
+    yAdvance    = 0x0008u,      /* Includes vertical adjustment for advance */
+    xPlaDevice  = 0x0010u,      /* Includes horizontal Device table for placement */
+    yPlaDevice  = 0x0020u,      /* Includes vertical Device table for placement */
+    xAdvDevice  = 0x0040u,      /* Includes horizontal Device table for advance */
+    yAdvDevice  = 0x0080u,      /* Includes vertical Device table for advance */
+    ignored     = 0x0F00u,      /* Was used in TrueType Open for MM fonts */
+    reserved    = 0xF000u,      /* For future use */
+
+    devices     = 0x00F0u       /* Mask for having any Device table */
+  };
+
+/* All fields are options.  Only those available advance the value pointer. */
+#if 0
+  SHORT         xPlacement;             /* Horizontal adjustment for
+                                         * placement--in design units */
+  SHORT         yPlacement;             /* Vertical adjustment for
+                                         * placement--in design units */
+  SHORT         xAdvance;               /* Horizontal adjustment for
+                                         * advance--in design units (only used
+                                         * for horizontal writing) */
+  SHORT         yAdvance;               /* Vertical adjustment for advance--in
+                                         * design units (only used for vertical
+                                         * writing) */
+  Offset        xPlaDevice;             /* Offset to Device table for
+                                         * horizontal placement--measured from
+                                         * beginning of PosTable (may be NULL) */
+  Offset        yPlaDevice;             /* Offset to Device table for vertical
+                                         * placement--measured from beginning
+                                         * of PosTable (may be NULL) */
+  Offset        xAdvDevice;             /* Offset to Device table for
+                                         * horizontal advance--measured from
+                                         * beginning of PosTable (may be NULL) */
+  Offset        yAdvDevice;             /* Offset to Device table for vertical
+                                         * advance--measured from beginning of
+                                         * PosTable (may be NULL) */
+#endif
+
+  inline unsigned int get_len (void) const
+  { return _hb_popcount32 ((unsigned int) *this); }
+  inline unsigned int get_size (void) const
+  { return get_len () * Value::static_size; }
+
+  void apply_value (hb_font_t            *font,
+                    hb_direction_t        direction,
+                    const void           *base,
+                    const Value          *values,
+                    hb_glyph_position_t  &glyph_pos) const
+  {
+    unsigned int x_ppem, y_ppem;
+    unsigned int format = *this;
+    hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction);
+
+    if (!format) return;
+
+    if (format & xPlacement) glyph_pos.x_offset  += font->em_scale_x (get_short (values++));
+    if (format & yPlacement) glyph_pos.y_offset  += font->em_scale_y (get_short (values++));
+    if (format & xAdvance) {
+      if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values));
+      values++;
+    }
+    /* y_advance values grow downward but font-space grows upward, hence negation */
+    if (format & yAdvance) {
+      if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values));
+      values++;
+    }
+
+    if (!has_device ()) return;
+
+    x_ppem = font->x_ppem;
+    y_ppem = font->y_ppem;
+
+    if (!x_ppem && !y_ppem) return;
+
+    /* pixel -> fractional pixel */
+    if (format & xPlaDevice) {
+      if (x_ppem) glyph_pos.x_offset  += (base + get_device (values)).get_x_delta (font);
+      values++;
+    }
+    if (format & yPlaDevice) {
+      if (y_ppem) glyph_pos.y_offset  += (base + get_device (values)).get_y_delta (font);
+      values++;
+    }
+    if (format & xAdvDevice) {
+      if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font);
+      values++;
+    }
+    if (format & yAdvDevice) {
+      /* y_advance values grow downward but font-space grows upward, hence negation */
+      if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font);
+      values++;
+    }
+  }
+
+  private:
+  inline bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
+  {
+    unsigned int format = *this;
+
+    if (format & xPlacement) values++;
+    if (format & yPlacement) values++;
+    if (format & xAdvance)   values++;
+    if (format & yAdvance)   values++;
+
+    if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
+    if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
+    if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
+    if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
+
+    return true;
+  }
+
+  static inline OffsetTo<Device>& get_device (Value* value)
+  { return *CastP<OffsetTo<Device> > (value); }
+  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); }
+
+  public:
+
+  inline bool has_device (void) const {
+    unsigned int format = *this;
+    return (format & devices) != 0;
+  }
+
+  inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
+  }
+
+  inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
+  {
+    TRACE_SANITIZE (this);
+    unsigned int len = get_len ();
+
+    if (!c->check_array (values, get_size (), count)) return_trace (false);
+
+    if (!has_device ()) return_trace (true);
+
+    for (unsigned int i = 0; i < count; i++) {
+      if (!sanitize_value_devices (c, base, values))
+        return_trace (false);
+      values += len;
+    }
+
+    return_trace (true);
+  }
+
+  /* Just sanitize referenced Device tables.  Doesn't check the values themselves. */
+  inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const
+  {
+    TRACE_SANITIZE (this);
+
+    if (!has_device ()) return_trace (true);
+
+    for (unsigned int i = 0; i < count; i++) {
+      if (!sanitize_value_devices (c, base, values))
+        return_trace (false);
+      values += stride;
+    }
+
+    return_trace (true);
+  }
+};
+
+
+struct AnchorFormat1
+{
+  inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
+                          hb_position_t *x, hb_position_t *y) const
+  {
+      *x = font->em_scale_x (xCoordinate);
+      *y = font->em_scale_y (yCoordinate);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  SHORT         xCoordinate;            /* Horizontal value--in design units */
+  SHORT         yCoordinate;            /* Vertical value--in design units */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct AnchorFormat2
+{
+  inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
+                          hb_position_t *x, hb_position_t *y) const
+  {
+      unsigned int x_ppem = font->x_ppem;
+      unsigned int y_ppem = font->y_ppem;
+      hb_position_t cx, cy;
+      hb_bool_t ret;
+
+      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);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  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 */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct AnchorFormat3
+{
+  inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
+                          hb_position_t *x, hb_position_t *y) const
+  {
+      *x = font->em_scale_x (xCoordinate);
+      *y = font->em_scale_y (yCoordinate);
+
+      if (font->x_ppem)
+        *x += (this+xDeviceTable).get_x_delta (font);
+      if (font->y_ppem)
+        *y += (this+yDeviceTable).get_x_delta (font);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 3 */
+  SHORT         xCoordinate;            /* Horizontal value--in design units */
+  SHORT         yCoordinate;            /* Vertical value--in design units */
+  OffsetTo<Device>
+                xDeviceTable;           /* Offset to Device table for X
+                                         * coordinate-- from beginning of
+                                         * Anchor table (may be NULL) */
+  OffsetTo<Device>
+                yDeviceTable;           /* Offset to Device table for Y
+                                         * coordinate-- from beginning of
+                                         * Anchor table (may be NULL) */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+struct Anchor
+{
+  inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
+                          hb_position_t *x, hb_position_t *y) const
+  {
+    *x = *y = 0;
+    switch (u.format) {
+    case 1: u.format1.get_anchor (font, glyph_id, x, y); return;
+    case 2: u.format2.get_anchor (font, glyph_id, x, y); return;
+    case 3: u.format3.get_anchor (font, glyph_id, x, y); return;
+    default:                                             return;
+    }
+  }
+
+  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 (true);
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  AnchorFormat1         format1;
+  AnchorFormat2         format2;
+  AnchorFormat3         format3;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+
+struct AnchorMatrix
+{
+  inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols, bool *found) const {
+    *found = false;
+    if (unlikely (row >= rows || col >= cols)) return Null(Anchor);
+    *found = !matrixZ[row * cols + col].is_null ();
+    return this+matrixZ[row * cols + col];
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
+  {
+    TRACE_SANITIZE (this);
+    if (!c->check_struct (this)) return_trace (false);
+    if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return_trace (false);
+    unsigned int count = rows * cols;
+    if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false);
+    for (unsigned int i = 0; i < count; i++)
+      if (!matrixZ[i].sanitize (c, this)) return_trace (false);
+    return_trace (true);
+  }
+
+  USHORT        rows;                   /* Number of rows */
+  protected:
+  OffsetTo<Anchor>
+                matrixZ[VAR];           /* Matrix of offsets to Anchor tables--
+                                         * from beginning of AnchorMatrix table */
+  public:
+  DEFINE_SIZE_ARRAY (2, matrixZ);
+};
+
+
+struct MarkRecord
+{
+  friend struct MarkArray;
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
+  }
+
+  protected:
+  USHORT        klass;                  /* Class defined for this mark */
+  OffsetTo<Anchor>
+                markAnchor;             /* Offset to Anchor table--from
+                                         * beginning of MarkArray table */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct MarkArray : ArrayOf<MarkRecord>  /* Array of MarkRecords--in Coverage order */
+{
+  inline bool apply (hb_apply_context_t *c,
+                     unsigned int mark_index, unsigned int glyph_index,
+                     const AnchorMatrix &anchors, unsigned int class_count,
+                     unsigned int glyph_pos) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+    const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
+    unsigned int mark_class = record.klass;
+
+    const Anchor& mark_anchor = this + record.markAnchor;
+    bool found;
+    const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
+    /* If this subtable doesn't have an anchor for this base and this class,
+     * 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;
+
+    mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y);
+    glyph_anchor.get_anchor (c->font, 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.attach_lookback() = buffer->idx - glyph_pos;
+
+    buffer->idx++;
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (ArrayOf<MarkRecord>::sanitize (c, this));
+  }
+};
+
+
+/* Lookups */
+
+struct SinglePosFormat1
+{
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_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);
+
+    valueFormat.apply_value (c->font, c->direction, this,
+                             values, buffer->cur_pos());
+
+    buffer->idx++;
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  coverage.sanitize (c, this) &&
+                  valueFormat.sanitize_value (c, this, values));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of subtable */
+  ValueFormat   valueFormat;            /* Defines the types of data in the
+                                         * ValueRecord */
+  ValueRecord   values;                 /* Defines positioning
+                                         * value(s)--applied to all glyphs in
+                                         * the Coverage table */
+  public:
+  DEFINE_SIZE_ARRAY (6, values);
+};
+
+struct SinglePosFormat2
+{
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_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);
+
+    if (likely (index >= valueCount)) return_trace (false);
+
+    valueFormat.apply_value (c->font, c->direction, this,
+                             &values[index * valueFormat.get_len ()],
+                             buffer->cur_pos());
+
+    buffer->idx++;
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  coverage.sanitize (c, this) &&
+                  valueFormat.sanitize_values (c, this, values, valueCount));
+  }
+
+  protected:
+  USHORT        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 */
+  ValueRecord   values;                 /* Array of ValueRecords--positioning
+                                         * values applied to glyphs */
+  public:
+  DEFINE_SIZE_ARRAY (8, values);
+};
+
+struct SinglePos
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    case 2: return_trace (c->dispatch (u.format2));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  SinglePosFormat1      format1;
+  SinglePosFormat2      format2;
+  } u;
+};
+
+
+struct PairValueRecord
+{
+  friend struct PairSet;
+
+  protected:
+  GlyphID       secondGlyph;            /* GlyphID of second glyph in the
+                                         * pair--first glyph is listed in the
+                                         * Coverage table */
+  ValueRecord   values;                 /* Positioning data for the first glyph
+                                         * followed by for second glyph */
+  public:
+  DEFINE_SIZE_ARRAY (2, values);
+};
+
+struct PairSet
+{
+  friend struct PairPosFormat1;
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c,
+                              const ValueFormat *valueFormats) const
+  {
+    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);
+
+    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);
+    }
+  }
+
+  inline bool apply (hb_apply_context_t *c,
+                     const ValueFormat *valueFormats,
+                     unsigned int pos) const
+  {
+    TRACE_APPLY (this);
+    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);
+
+    const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
+    unsigned int count = len;
+
+    /* Hand-coded bsearch. */
+    if (unlikely (!count))
+      return_trace (false);
+    hb_codepoint_t x = buffer->info[pos].codepoint;
+    int min = 0, max = (int) count - 1;
+    while (min <= max)
+    {
+      int mid = (min + max) / 2;
+      const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_array, record_size * mid);
+      hb_codepoint_t mid_x = record->secondGlyph;
+      if (x < mid_x)
+        max = mid - 1;
+      else if (x > mid_x)
+        min = mid + 1;
+      else
+      {
+        valueFormats[0].apply_value (c->font, c->direction, this,
+                                     &record->values[0], buffer->cur_pos());
+        valueFormats[1].apply_value (c->font, c->direction, this,
+                                     &record->values[len1], buffer->pos[pos]);
+        if (len2)
+          pos++;
+        buffer->idx = pos;
+        return_trace (true);
+      }
+    }
+
+    return_trace (false);
+  }
+
+  struct sanitize_closure_t {
+    const void *base;
+    const ValueFormat *valueFormats;
+    unsigned int len1; /* valueFormats[0].get_len() */
+    unsigned int stride; /* 1 + len1 + len2 */
+  };
+
+  inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
+  {
+    TRACE_SANITIZE (this);
+    if (!(c->check_struct (this)
+       && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return_trace (false);
+
+    unsigned int count = len;
+    const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
+    return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) &&
+                  closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride));
+  }
+
+  protected:
+  USHORT        len;                    /* Number of PairValueRecords */
+  USHORT        arrayZ[VAR];            /* Array of PairValueRecords--ordered
+                                         * by GlyphID of the second glyph */
+  public:
+  DEFINE_SIZE_ARRAY (2, arrayZ);
+};
+
+struct PairPosFormat1
+{
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+    unsigned int count = pairSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      (this+pairSet[i]).collect_glyphs (c, &valueFormat1);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_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;
+    skippy_iter.reset (buffer->idx, 1);
+    if (!skippy_iter.next ()) return_trace (false);
+
+    return_trace ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+
+    if (!c->check_struct (this)) return_trace (false);
+
+    unsigned int len1 = valueFormat1.get_len ();
+    unsigned int len2 = valueFormat2.get_len ();
+    PairSet::sanitize_closure_t closure = {
+      this,
+      &valueFormat1,
+      len1,
+      1 + len1 + len2
+    };
+
+    return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of subtable */
+  ValueFormat   valueFormat1;           /* Defines the types of data in
+                                         * ValueRecord1--for the first glyph
+                                         * in the pair--may be zero (0) */
+  ValueFormat   valueFormat2;           /* Defines the types of data in
+                                         * ValueRecord2--for the second glyph
+                                         * in the pair--may be zero (0) */
+  OffsetArrayOf<PairSet>
+                pairSet;                /* Array of PairSet tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (10, pairSet);
+};
+
+struct PairPosFormat2
+{
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    /* (this+coverage).add_coverage (c->input); // Don't need this. */
+
+    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);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_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;
+    skippy_iter.reset (buffer->idx, 1);
+    if (!skippy_iter.next ()) return_trace (false);
+
+    unsigned int len1 = valueFormat1.get_len ();
+    unsigned int len2 = valueFormat2.get_len ();
+    unsigned int record_len = len1 + len2;
+
+    unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
+    unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
+    if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
+
+    const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
+    valueFormat1.apply_value (c->font, c->direction, this,
+                              v, buffer->cur_pos());
+    valueFormat2.apply_value (c->font, c->direction, this,
+                              v + len1, buffer->pos[skippy_iter.idx]);
+
+    buffer->idx = skippy_iter.idx;
+    if (len2)
+      buffer->idx++;
+
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!(c->check_struct (this)
+       && coverage.sanitize (c, this)
+       && classDef1.sanitize (c, this)
+       && classDef2.sanitize (c, this))) return_trace (false);
+
+    unsigned int len1 = valueFormat1.get_len ();
+    unsigned int len2 = valueFormat2.get_len ();
+    unsigned int stride = len1 + len2;
+    unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
+    unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
+    return_trace (c->check_array (values, record_size, count) &&
+                  valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
+                  valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 2 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of subtable */
+  ValueFormat   valueFormat1;           /* ValueRecord definition--for the
+                                         * first glyph of the pair--may be zero
+                                         * (0) */
+  ValueFormat   valueFormat2;           /* ValueRecord definition--for the
+                                         * second glyph of the pair--may be
+                                         * zero (0) */
+  OffsetTo<ClassDef>
+                classDef1;              /* Offset to ClassDef table--from
+                                         * beginning of PairPos subtable--for
+                                         * the first glyph of the pair */
+  OffsetTo<ClassDef>
+                classDef2;              /* Offset to ClassDef table--from
+                                         * beginning of PairPos subtable--for
+                                         * the second glyph of the pair */
+  USHORT        class1Count;            /* Number of classes in ClassDef1
+                                         * table--includes Class0 */
+  USHORT        class2Count;            /* Number of classes in ClassDef2
+                                         * table--includes Class0 */
+  ValueRecord   values;                 /* Matrix of value pairs:
+                                         * class1-major, class2-minor,
+                                         * Each entry has value1 and value2 */
+  public:
+  DEFINE_SIZE_ARRAY (16, values);
+};
+
+struct PairPos
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    case 2: return_trace (c->dispatch (u.format2));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  PairPosFormat1        format1;
+  PairPosFormat2        format2;
+  } u;
+};
+
+
+struct EntryExitRecord
+{
+  friend struct CursivePosFormat1;
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
+  }
+
+  protected:
+  OffsetTo<Anchor>
+                entryAnchor;            /* Offset to EntryAnchor table--from
+                                         * beginning of CursivePos
+                                         * subtable--may be NULL */
+  OffsetTo<Anchor>
+                exitAnchor;             /* Offset to ExitAnchor table--from
+                                         * beginning of CursivePos
+                                         * subtable--may be NULL */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+static void
+reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent);
+
+struct CursivePosFormat1
+{
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+
+    /* We don't handle mark glyphs here. */
+    if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return_trace (false);
+
+    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;
+    skippy_iter.reset (buffer->idx, 1);
+    if (!skippy_iter.next ()) return_trace (false);
+
+    const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint)];
+    if (!next_record.entryAnchor) return_trace (false);
+
+    unsigned int i = buffer->idx;
+    unsigned int j = skippy_iter.idx;
+
+    hb_position_t entry_x, entry_y, exit_x, exit_y;
+    (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint, &exit_x, &exit_y);
+    (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoint, &entry_x, &entry_y);
+
+    hb_glyph_position_t *pos = buffer->pos;
+
+    hb_position_t d;
+    /* Main-direction adjustment */
+    switch (c->direction) {
+      case HB_DIRECTION_LTR:
+        pos[i].x_advance  =  exit_x + pos[i].x_offset;
+
+        d = 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;
+        pos[i].x_advance -= d;
+        pos[i].x_offset  -= d;
+
+        pos[j].x_advance  =  entry_x + pos[j].x_offset;
+        break;
+      case HB_DIRECTION_TTB:
+        pos[i].y_advance  =  exit_y + pos[i].y_offset;
+
+        d = 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;
+        pos[i].y_advance -= d;
+        pos[i].y_offset  -= d;
+
+        pos[j].y_advance  =  entry_y;
+        break;
+      case HB_DIRECTION_INVALID:
+      default:
+        break;
+    }
+
+    /* Cross-direction adjustment */
+
+    /* We attach child to parent (think graph theory and rooted trees whereas
+     * the root stays on baseline and each node aligns itself against its
+     * parent.
+     *
+     * Optimize things for the case of RightToLeft, as that's most common in
+     * Arabinc. */
+    unsigned int child  = i;
+    unsigned int parent = j;
+    hb_position_t x_offset = entry_x - exit_x;
+    hb_position_t y_offset = entry_y - exit_y;
+    if  (!(c->lookup_props & LookupFlag::RightToLeft))
+    {
+      unsigned int k = child;
+      child = parent;
+      parent = k;
+      x_offset = -x_offset;
+      y_offset = -y_offset;
+    }
+
+    /* If child was already connected to someone else, walk through its old
+     * chain and reverse the link direction, such that the whole tree of its
+     * previous connection now attaches to new parent.  Watch out for case
+     * where new parent is on the path from old chain...
+     */
+    reverse_cursive_minor_offset (pos, child, c->direction, parent);
+
+    pos[child].cursive_chain() = parent - child;
+    if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+      pos[child].y_offset = y_offset;
+    else
+      pos[child].x_offset = x_offset;
+
+    buffer->idx = j;
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of subtable */
+  ArrayOf<EntryExitRecord>
+                entryExitRecord;        /* Array of EntryExit records--in
+                                         * Coverage Index order */
+  public:
+  DEFINE_SIZE_ARRAY (6, entryExitRecord);
+};
+
+struct CursivePos
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  CursivePosFormat1     format1;
+  } u;
+};
+
+
+typedef AnchorMatrix BaseArray;         /* base-major--
+                                         * in order of BaseCoverage Index--,
+                                         * mark-minor--
+                                         * ordered by class--zero-based. */
+
+struct MarkBasePosFormat1
+{
+  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);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+markCoverage;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark_index = (this+markCoverage).get_coverage  (buffer->cur().codepoint);
+    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;
+    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. */
+      if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break;
+      skippy_iter.reject ();
+    } while (1);
+
+    /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
+    if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ }
+
+    unsigned int base_index = (this+baseCoverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint);
+    if (base_index == NOT_COVERED) return_trace (false);
+
+    return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  markCoverage.sanitize (c, this) &&
+                  baseCoverage.sanitize (c, this) &&
+                  markArray.sanitize (c, this) &&
+                  baseArray.sanitize (c, this, (unsigned int) classCount));
+  }
+
+  protected:
+  USHORT        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 */
+  OffsetTo<MarkArray>
+                markArray;              /* Offset to MarkArray table--from
+                                         * beginning of MarkBasePos subtable */
+  OffsetTo<BaseArray>
+                baseArray;              /* Offset to BaseArray table--from
+                                         * beginning of MarkBasePos subtable */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkBasePos
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  MarkBasePosFormat1    format1;
+  } u;
+};
+
+
+typedef AnchorMatrix LigatureAttach;    /* component-major--
+                                         * in order of writing direction--,
+                                         * mark-minor--
+                                         * ordered by class--zero-based. */
+
+typedef OffsetListOf<LigatureAttach> LigatureArray;
+                                        /* Array of LigatureAttach
+                                         * tables ordered by
+                                         * LigatureCoverage Index */
+
+struct MarkLigPosFormat1
+{
+  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);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+markCoverage;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark_index = (this+markCoverage).get_coverage  (buffer->cur().codepoint);
+    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;
+    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
+    if (!skippy_iter.prev ()) return_trace (false);
+
+    /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
+    if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ }
+
+    unsigned int j = skippy_iter.idx;
+    unsigned int lig_index = (this+ligatureCoverage).get_coverage  (buffer->info[j].codepoint);
+    if (lig_index == NOT_COVERED) return_trace (false);
+
+    const LigatureArray& lig_array = this+ligatureArray;
+    const LigatureAttach& lig_attach = lig_array[lig_index];
+
+    /* Find component to attach to */
+    unsigned int comp_count = lig_attach.rows;
+    if (unlikely (!comp_count)) return_trace (false);
+
+    /* We must now check whether the ligature ID of the current mark glyph
+     * is identical to the ligature ID of the found ligature.  If yes, we
+     * can directly use the component index.  If not, we attach the mark
+     * glyph to the last component of the ligature. */
+    unsigned int comp_index;
+    unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+    unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+    unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+    if (lig_id && lig_id == mark_id && mark_comp > 0)
+      comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
+    else
+      comp_index = comp_count - 1;
+
+    return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  markCoverage.sanitize (c, this) &&
+                  ligatureCoverage.sanitize (c, this) &&
+                  markArray.sanitize (c, this) &&
+                  ligatureArray.sanitize (c, this, (unsigned int) classCount));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                markCoverage;           /* Offset to Mark Coverage table--from
+                                         * beginning of MarkLigPos subtable */
+  OffsetTo<Coverage>
+                ligatureCoverage;       /* Offset to Ligature Coverage
+                                         * table--from beginning of MarkLigPos
+                                         * subtable */
+  USHORT        classCount;             /* Number of defined mark classes */
+  OffsetTo<MarkArray>
+                markArray;              /* Offset to MarkArray table--from
+                                         * beginning of MarkLigPos subtable */
+  OffsetTo<LigatureArray>
+                ligatureArray;          /* Offset to LigatureArray table--from
+                                         * beginning of MarkLigPos subtable */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkLigPos
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  MarkLigPosFormat1     format1;
+  } u;
+};
+
+
+typedef AnchorMatrix Mark2Array;        /* mark2-major--
+                                         * in order of Mark2Coverage Index--,
+                                         * mark1-minor--
+                                         * ordered by class--zero-based. */
+
+struct MarkMarkPosFormat1
+{
+  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);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+mark1Coverage;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark1_index = (this+mark1Coverage).get_coverage  (buffer->cur().codepoint);
+    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;
+    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
+    if (!skippy_iter.prev ()) return_trace (false);
+
+    if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); }
+
+    unsigned int j = skippy_iter.idx;
+
+    unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
+    unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+    unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
+    unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
+
+    if (likely (id1 == id2)) {
+      if (id1 == 0) /* Marks belonging to the same base. */
+        goto good;
+      else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
+        goto good;
+    } else {
+      /* If ligature ids don't match, it may be the case that one of the marks
+       * itself is a ligature.  In which case match. */
+      if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
+        goto good;
+    }
+
+    /* Didn't match. */
+    return_trace (false);
+
+    good:
+    unsigned int mark2_index = (this+mark2Coverage).get_coverage  (buffer->info[j].codepoint);
+    if (mark2_index == NOT_COVERED) return_trace (false);
+
+    return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  mark1Coverage.sanitize (c, this) &&
+                  mark2Coverage.sanitize (c, this) &&
+                  mark1Array.sanitize (c, this) &&
+                  mark2Array.sanitize (c, this, (unsigned int) classCount));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                mark1Coverage;          /* Offset to Combining Mark1 Coverage
+                                         * table--from beginning of MarkMarkPos
+                                         * subtable */
+  OffsetTo<Coverage>
+                mark2Coverage;          /* Offset to Combining Mark2 Coverage
+                                         * table--from beginning of MarkMarkPos
+                                         * subtable */
+  USHORT        classCount;             /* Number of defined mark classes */
+  OffsetTo<MarkArray>
+                mark1Array;             /* Offset to Mark1Array table--from
+                                         * beginning of MarkMarkPos subtable */
+  OffsetTo<Mark2Array>
+                mark2Array;             /* Offset to Mark2Array table--from
+                                         * beginning of MarkMarkPos subtable */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct MarkMarkPos
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  MarkMarkPosFormat1    format1;
+  } u;
+};
+
+
+struct ContextPos : Context {};
+
+struct ChainContextPos : ChainContext {};
+
+struct ExtensionPos : Extension<ExtensionPos>
+{
+  typedef struct PosLookupSubTable LookupSubTable;
+};
+
+
+
+/*
+ * PosLookup
+ */
+
+
+struct PosLookupSubTable
+{
+  friend struct PosLookup;
+
+  enum Type {
+    Single              = 1,
+    Pair                = 2,
+    Cursive             = 3,
+    MarkBase            = 4,
+    MarkLig             = 5,
+    MarkMark            = 6,
+    Context             = 7,
+    ChainContext        = 8,
+    Extension           = 9
+  };
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+  {
+    TRACE_DISPATCH (this, lookup_type);
+    if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ());
+    switch (lookup_type) {
+    case Single:                return_trace (u.single.dispatch (c));
+    case Pair:                  return_trace (u.pair.dispatch (c));
+    case Cursive:               return_trace (u.cursive.dispatch (c));
+    case MarkBase:              return_trace (u.markBase.dispatch (c));
+    case MarkLig:               return_trace (u.markLig.dispatch (c));
+    case MarkMark:              return_trace (u.markMark.dispatch (c));
+    case Context:               return_trace (u.context.dispatch (c));
+    case ChainContext:          return_trace (u.chainContext.dispatch (c));
+    case Extension:             return_trace (u.extension.dispatch (c));
+    default:                    return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                sub_format;
+  SinglePos             single;
+  PairPos               pair;
+  CursivePos            cursive;
+  MarkBasePos           markBase;
+  MarkLigPos            markLig;
+  MarkMarkPos           markMark;
+  ContextPos            context;
+  ChainContextPos       chainContext;
+  ExtensionPos          extension;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, sub_format);
+};
+
+
+struct PosLookup : Lookup
+{
+  inline const PosLookupSubTable& get_subtable (unsigned int i) const
+  { return Lookup::get_subtable<PosLookupSubTable> (i); }
+
+  inline bool is_reverse (void) const
+  {
+    return false;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    return_trace (dispatch (c));
+  }
+
+  inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    return_trace (dispatch (c));
+  }
+
+  template <typename set_t>
+  inline void add_coverage (set_t *glyphs) const
+  {
+    hb_add_coverage_context_t<set_t> c (glyphs);
+    dispatch (&c);
+  }
+
+  static bool apply_recurse_func (hb_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);
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  { return Lookup::dispatch<PosLookupSubTable> (c); }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!Lookup::sanitize (c))) return_trace (false);
+    return_trace (dispatch (c));
+  }
+};
+
+typedef OffsetListOf<PosLookup> PosLookupList;
+
+/*
+ * GPOS -- The Glyph Positioning Table
+ */
+
+struct GPOS : GSUBGPOS
+{
+  static const hb_tag_t tableTag        = HB_OT_TAG_GPOS;
+
+  inline const PosLookup& get_lookup (unsigned int i) const
+  { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
+
+  static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
+  static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer);
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false);
+    const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
+    return_trace (list.sanitize (c, this));
+  }
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+
+static void
+reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent)
+{
+  unsigned int j = pos[i].cursive_chain();
+  if (likely (!j))
+    return;
+
+  j += i;
+
+  pos[i].cursive_chain() = 0;
+
+  /* Stop if we see new parent in the chain. */
+  if (j == new_parent)
+    return;
+
+  reverse_cursive_minor_offset (pos, j, direction, new_parent);
+
+  if (HB_DIRECTION_IS_HORIZONTAL (direction))
+    pos[j].y_offset = -pos[i].y_offset;
+  else
+    pos[j].x_offset = -pos[i].x_offset;
+
+  pos[j].cursive_chain() = i - j;
+}
+static void
+fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
+{
+  unsigned int j = pos[i].cursive_chain();
+  if (likely (!j))
+    return;
+
+  j += i;
+
+  pos[i].cursive_chain() = 0;
+
+  fix_cursive_minor_offset (pos, j, direction);
+
+  if (HB_DIRECTION_IS_HORIZONTAL (direction))
+    pos[i].y_offset += pos[j].y_offset;
+  else
+    pos[i].x_offset += pos[j].x_offset;
+}
+
+static void
+fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
+{
+  if (likely (!(pos[i].attach_lookback())))
+    return;
+
+  unsigned int j = i - pos[i].attach_lookback();
+
+  pos[i].x_offset += pos[j].x_offset;
+  pos[i].y_offset += pos[j].y_offset;
+
+  if (HB_DIRECTION_IS_FORWARD (direction))
+    for (unsigned int k = j; k < i; k++) {
+      pos[i].x_offset -= pos[k].x_advance;
+      pos[i].y_offset -= pos[k].y_advance;
+    }
+  else
+    for (unsigned int k = j + 1; k < i + 1; k++) {
+      pos[i].x_offset += pos[k].x_advance;
+      pos[i].y_offset += pos[k].y_advance;
+    }
+}
+
+void
+GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+{
+  buffer->clear_positions ();
+
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0;
+}
+
+void
+GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+{
+  _hb_buffer_assert_gsubgpos_vars (buffer);
+
+  unsigned int len;
+  hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
+  hb_direction_t direction = buffer->props.direction;
+
+  /* Handle cursive connections */
+  for (unsigned int i = 0; i < len; i++)
+    fix_cursive_minor_offset (pos, i, direction);
+
+  /* Handle attachments */
+  for (unsigned int i = 0; i < len; i++)
+    fix_mark_attachment (pos, i, direction);
+}
+
+
+/* Out-of-class implementation for methods recursing */
+
+template <typename context_t>
+/*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (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);
+  return l.dispatch (c);
+}
+
+/*static*/ inline bool PosLookup::apply_recurse_func (hb_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);
+  unsigned int saved_lookup_props = c->lookup_props;
+  unsigned int saved_lookup_index = c->lookup_index;
+  c->set_lookup_index (lookup_index);
+  c->set_lookup_props (l.get_props ());
+  bool ret = l.dispatch (c);
+  c->set_lookup_index (saved_lookup_index);
+  c->set_lookup_props (saved_lookup_props);
+  return ret;
+}
+
+
+#undef attach_lookback
+#undef cursive_chain
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsub-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1342 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2010,2012,2013  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GSUB_TABLE_HH
+#define HB_OT_LAYOUT_GSUB_TABLE_HH
+
+#include "hb-ot-layout-gsubgpos-private.hh"
+
+
+namespace OT {
+
+
+struct SingleSubstFormat1
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      hb_codepoint_t glyph_id = iter.get_glyph ();
+      if (c->glyphs->has (glyph_id))
+        c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
+    }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      hb_codepoint_t glyph_id = iter.get_glyph ();
+      c->input->add (glyph_id);
+      c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
+    }
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    /* According to the Adobe Annotated OpenType Suite, result is always
+     * limited to 16bit. */
+    glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu;
+    c->replace_glyph (glyph_id);
+
+    return_trace (true);
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         unsigned int num_glyphs,
+                         int delta)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+    deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
+  }
+
+  protected:
+  USHORT        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
+                                         * substitute GlyphID */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct SingleSubstFormat2
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      if (c->glyphs->has (iter.get_glyph ()))
+        c->glyphs->add (substitute[iter.get_coverage ()]);
+    }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      c->input->add (iter.get_glyph ());
+      c->output->add (substitute[iter.get_coverage ()]);
+    }
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    if (unlikely (index >= substitute.len)) return_trace (false);
+
+    glyph_id = substitute[index];
+    c->replace_glyph (glyph_id);
+
+    return_trace (true);
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         Supplier<GlyphID> &substitutes,
+                         unsigned int num_glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return_trace (false);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && substitute.sanitize (c));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 2 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  ArrayOf<GlyphID>
+                substitute;             /* Array of substitute
+                                         * GlyphIDs--ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, substitute);
+};
+
+struct SingleSubst
+{
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         Supplier<GlyphID> &substitutes,
+                         unsigned int num_glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    unsigned int format = 2;
+    int delta = 0;
+    if (num_glyphs) {
+      format = 1;
+      /* TODO(serialize) check for wrap-around */
+      delta = substitutes[0] - glyphs[0];
+      for (unsigned int i = 1; i < num_glyphs; i++)
+        if (delta != substitutes[i] - glyphs[i]) {
+          format = 2;
+          break;
+        }
+    }
+    u.format.set (format);
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs, delta));
+    case 2: return_trace (u.format2.serialize (c, glyphs, substitutes, num_glyphs));
+    default:return_trace (false);
+    }
+  }
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    case 2: return_trace (c->dispatch (u.format2));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  SingleSubstFormat1    format1;
+  SingleSubstFormat2    format2;
+  } u;
+};
+
+
+struct Sequence
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    unsigned int count = substitute.len;
+    for (unsigned int i = 0; i < count; i++)
+      c->glyphs->add (substitute[i]);
+  }
+
+  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]);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int count = substitute.len;
+
+    /* TODO:
+     * Testing shows that Uniscribe actually allows zero-len susbstitute,
+     * which essentially deletes a glyph.  We don't allow for now.  It
+     * can be confusing to the client since the cluster from the deleted
+     * glyph won't be merged with any output cluster...  Also, currently
+     * buffer->move_to() makes assumptions about this too.  Perhaps fix
+     * in the future after figuring out what to do with the clusters.
+     */
+    if (unlikely (!count)) return_trace (false);
+
+    /* Special-case to make it in-place and not consider this
+     * as a "multiplied" substitution. */
+    if (unlikely (count == 1))
+    {
+      c->replace_glyph (substitute.array[0]);
+      return_trace (true);
+    }
+
+    unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
+                         HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
+
+    for (unsigned int i = 0; i < count; i++) {
+      _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
+      c->output_glyph_for_component (substitute.array[i], klass);
+    }
+    c->buffer->skip_glyph ();
+
+    return_trace (true);
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         unsigned int num_glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return_trace (false);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (substitute.sanitize (c));
+  }
+
+  protected:
+  ArrayOf<GlyphID>
+                substitute;             /* String of GlyphIDs to substitute */
+  public:
+  DEFINE_SIZE_ARRAY (2, substitute);
+};
+
+struct MultipleSubstFormat1
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      if (c->glyphs->has (iter.get_glyph ()))
+        (this+sequence[iter.get_coverage ()]).closure (c);
+    }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+    unsigned int count = sequence.len;
+    for (unsigned int i = 0; i < count; i++)
+        (this+sequence[i]).collect_glyphs (c);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    return_trace ((this+sequence[index]).apply (c));
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         Supplier<unsigned int> &substitute_len_list,
+                         unsigned int num_glyphs,
+                         Supplier<GlyphID> &substitute_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!sequence.serialize (c, num_glyphs))) return_trace (false);
+    for (unsigned int i = 0; i < num_glyphs; i++)
+      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);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && sequence.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  OffsetArrayOf<Sequence>
+                sequence;               /* Array of Sequence tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, sequence);
+};
+
+struct MultipleSubst
+{
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         Supplier<unsigned int> &substitute_len_list,
+                         unsigned int num_glyphs,
+                         Supplier<GlyphID> &substitute_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    unsigned int format = 1;
+    u.format.set (format);
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list));
+    default:return_trace (false);
+    }
+  }
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  MultipleSubstFormat1  format1;
+  } u;
+};
+
+
+typedef ArrayOf<GlyphID> AlternateSet;  /* Array of alternate GlyphIDs--in
+                                         * arbitrary order */
+
+struct AlternateSubstFormat1
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      if (c->glyphs->has (iter.get_glyph ())) {
+        const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
+        unsigned int count = alt_set.len;
+        for (unsigned int i = 0; i < count; i++)
+          c->glyphs->add (alt_set[i]);
+      }
+    }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      c->input->add (iter.get_glyph ());
+      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]);
+    }
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const AlternateSet &alt_set = this+alternateSet[index];
+
+    if (unlikely (!alt_set.len)) return_trace (false);
+
+    hb_mask_t glyph_mask = c->buffer->cur().mask;
+    hb_mask_t lookup_mask = c->lookup_mask;
+
+    /* Note: This breaks badly if two features enabled this lookup together. */
+    unsigned int shift = _hb_ctz (lookup_mask);
+    unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
+
+    if (unlikely (alt_index > alt_set.len || alt_index == 0)) return_trace (false);
+
+    glyph_id = alt_set[alt_index - 1];
+
+    c->replace_glyph (glyph_id);
+
+    return_trace (true);
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         Supplier<unsigned int> &alternate_len_list,
+                         unsigned int num_glyphs,
+                         Supplier<GlyphID> &alternate_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!alternateSet.serialize (c, num_glyphs))) return_trace (false);
+    for (unsigned int i = 0; i < num_glyphs; i++)
+      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);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  OffsetArrayOf<AlternateSet>
+                alternateSet;           /* Array of AlternateSet tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, alternateSet);
+};
+
+struct AlternateSubst
+{
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &glyphs,
+                         Supplier<unsigned int> &alternate_len_list,
+                         unsigned int num_glyphs,
+                         Supplier<GlyphID> &alternate_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    unsigned int format = 1;
+    u.format.set (format);
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list));
+    default:return_trace (false);
+    }
+  }
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  AlternateSubstFormat1 format1;
+  } u;
+};
+
+
+struct Ligature
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    unsigned int count = component.len;
+    for (unsigned int i = 1; i < count; i++)
+      if (!c->glyphs->has (component[i]))
+        return;
+    c->glyphs->add (ligGlyph);
+  }
+
+  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->output->add (ligGlyph);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+    if (c->len != component.len)
+      return_trace (false);
+
+    for (unsigned int i = 1; i < c->len; i++)
+      if (likely (c->glyphs[i] != component[i]))
+        return_trace (false);
+
+    return_trace (true);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int count = component.len;
+
+    if (unlikely (!count)) return_trace (false);
+
+    /* Special-case to make it in-place and not consider this
+     * as a "ligated" substitution. */
+    if (unlikely (count == 1))
+    {
+      c->replace_glyph (ligGlyph);
+      return_trace (true);
+    }
+
+    bool is_mark_ligature = false;
+    unsigned int total_component_count = 0;
+
+    unsigned int match_length = 0;
+    unsigned int match_positions[MAX_CONTEXT_LENGTH];
+
+    if (likely (!match_input (c, count,
+                              &component[1],
+                              match_glyph,
+                              NULL,
+                              &match_length,
+                              match_positions,
+                              &is_mark_ligature,
+                              &total_component_count)))
+      return_trace (false);
+
+    ligate_input (c,
+                  count,
+                  match_positions,
+                  match_length,
+                  ligGlyph,
+                  is_mark_ligature,
+                  total_component_count);
+
+    return_trace (true);
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         GlyphID ligature,
+                         Supplier<GlyphID> &components, /* Starting from second */
+                         unsigned int num_components /* Including first component */)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    ligGlyph = ligature;
+    if (unlikely (!component.serialize (c, components, num_components))) return_trace (false);
+    return_trace (true);
+  }
+
+  public:
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (ligGlyph.sanitize (c) && component.sanitize (c));
+  }
+
+  protected:
+  GlyphID       ligGlyph;               /* GlyphID of ligature to substitute */
+  HeadlessArrayOf<GlyphID>
+                component;              /* Array of component GlyphIDs--start
+                                         * with the second  component--ordered
+                                         * in writing direction */
+  public:
+  DEFINE_SIZE_ARRAY (4, component);
+};
+
+struct LigatureSet
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    unsigned int num_ligs = ligature.len;
+    for (unsigned int i = 0; i < num_ligs; i++)
+      (this+ligature[i]).closure (c);
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    unsigned int num_ligs = ligature.len;
+    for (unsigned int i = 0; i < num_ligs; i++)
+      (this+ligature[i]).collect_glyphs (c);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+    unsigned int num_ligs = ligature.len;
+    for (unsigned int i = 0; i < num_ligs; i++)
+    {
+      const Ligature &lig = this+ligature[i];
+      if (lig.would_apply (c))
+        return_trace (true);
+    }
+    return_trace (false);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int num_ligs = ligature.len;
+    for (unsigned int i = 0; i < num_ligs; i++)
+    {
+      const Ligature &lig = this+ligature[i];
+      if (lig.apply (c)) return_trace (true);
+    }
+
+    return_trace (false);
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &ligatures,
+                         Supplier<unsigned int> &component_count_list,
+                         unsigned int num_ligatures,
+                         Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!ligature.serialize (c, num_ligatures))) return_trace (false);
+    for (unsigned int i = 0; i < num_ligatures; i++)
+      if (unlikely (!ligature[i].serialize (c, this).serialize (c,
+                                                                ligatures[i],
+                                                                component_list,
+                                                                component_count_list[i]))) return_trace (false);
+    ligatures.advance (num_ligatures);
+    component_count_list.advance (num_ligatures);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (ligature.sanitize (c, this));
+  }
+
+  protected:
+  OffsetArrayOf<Ligature>
+                ligature;               /* Array LigatureSet tables
+                                         * ordered by preference */
+  public:
+  DEFINE_SIZE_ARRAY (2, ligature);
+};
+
+struct LigatureSubstFormat1
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      if (c->glyphs->has (iter.get_glyph ()))
+        (this+ligatureSet[iter.get_coverage ()]).closure (c);
+    }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      c->input->add (iter.get_glyph ());
+      (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
+    }
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+    unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const LigatureSet &lig_set = this+ligatureSet[index];
+    return_trace (lig_set.would_apply (c));
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
+
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const LigatureSet &lig_set = this+ligatureSet[index];
+    return_trace (lig_set.apply (c));
+  }
+
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &first_glyphs,
+                         Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+                         unsigned int num_first_glyphs,
+                         Supplier<GlyphID> &ligatures_list,
+                         Supplier<unsigned int> &component_count_list,
+                         Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return_trace (false);
+    for (unsigned int i = 0; i < num_first_glyphs; i++)
+      if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c,
+                                                                   ligatures_list,
+                                                                   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);
+    if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return_trace (false);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of Substitution table */
+  OffsetArrayOf<LigatureSet>
+                ligatureSet;            /* Array LigatureSet tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, ligatureSet);
+};
+
+struct LigatureSubst
+{
+  inline bool serialize (hb_serialize_context_t *c,
+                         Supplier<GlyphID> &first_glyphs,
+                         Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+                         unsigned int num_first_glyphs,
+                         Supplier<GlyphID> &ligatures_list,
+                         Supplier<unsigned int> &component_count_list,
+                         Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (u.format))) return_trace (false);
+    unsigned int format = 1;
+    u.format.set (format);
+    switch (u.format) {
+    case 1: return_trace (u.format1.serialize (c,
+                                               first_glyphs,
+                                               ligature_per_first_glyph_count_list,
+                                               num_first_glyphs,
+                                               ligatures_list,
+                                               component_count_list,
+                                               component_list));
+    default:return_trace (false);
+    }
+  }
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  LigatureSubstFormat1  format1;
+  } u;
+};
+
+
+struct ContextSubst : Context {};
+
+struct ChainContextSubst : ChainContext {};
+
+struct ExtensionSubst : Extension<ExtensionSubst>
+{
+  typedef struct SubstLookupSubTable LookupSubTable;
+
+  inline bool is_reverse (void) const;
+};
+
+
+struct ReverseChainSingleSubstFormat1
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+    unsigned int count;
+
+    count = backtrack.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (!(this+backtrack[i]).intersects (c->glyphs))
+        return;
+
+    count = lookahead.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (!(this+lookahead[i]).intersects (c->glyphs))
+        return;
+
+    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    Coverage::Iter iter;
+    for (iter.init (this+coverage); iter.more (); iter.next ()) {
+      if (c->glyphs->has (iter.get_glyph ()))
+        c->glyphs->add (substitute[iter.get_coverage ()]);
+    }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+    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);
+
+    count = lookahead.len;
+    for (unsigned int i = 0; i < count; i++)
+      (this+lookahead[i]).add_coverage (c->after);
+
+    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    count = substitute.len;
+    for (unsigned int i = 0; i < count; i++)
+      c->output->add (substitute[i]);
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    if (unlikely (c->nesting_level_left != MAX_NESTING_LEVEL))
+      return_trace (false); /* No chaining to this type */
+
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+
+    if (match_backtrack (c,
+                         backtrack.len, (USHORT *) backtrack.array,
+                         match_coverage, this) &&
+        match_lookahead (c,
+                         lookahead.len, (USHORT *) lookahead.array,
+                         match_coverage, this,
+                         1))
+    {
+      c->replace_glyph_inplace (substitute[index]);
+      /* Note: We DON'T decrease buffer->idx.  The main loop does it
+       * for us.  This is useful for preventing surprises if someone
+       * calls us through a Context lookup. */
+      return_trace (true);
+    }
+
+    return_trace (false);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
+      return_trace (false);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    if (!lookahead.sanitize (c, this))
+      return_trace (false);
+    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    return_trace (substitute.sanitize (c));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of table */
+  OffsetArrayOf<Coverage>
+                backtrack;              /* Array of coverage tables
+                                         * in backtracking sequence, in  glyph
+                                         * sequence order */
+  OffsetArrayOf<Coverage>
+                lookaheadX;             /* Array of coverage tables
+                                         * in lookahead sequence, in glyph
+                                         * sequence order */
+  ArrayOf<GlyphID>
+                substituteX;            /* Array of substitute
+                                         * GlyphIDs--ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_MIN (10);
+};
+
+struct ReverseChainSingleSubst
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                                format;         /* Format identifier */
+  ReverseChainSingleSubstFormat1        format1;
+  } u;
+};
+
+
+
+/*
+ * SubstLookup
+ */
+
+struct SubstLookupSubTable
+{
+  friend struct SubstLookup;
+
+  enum Type {
+    Single              = 1,
+    Multiple            = 2,
+    Alternate           = 3,
+    Ligature            = 4,
+    Context             = 5,
+    ChainContext        = 6,
+    Extension           = 7,
+    ReverseChainSingle  = 8
+  };
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+  {
+    TRACE_DISPATCH (this, lookup_type);
+    if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ());
+    switch (lookup_type) {
+    case Single:                return_trace (u.single.dispatch (c));
+    case Multiple:              return_trace (u.multiple.dispatch (c));
+    case Alternate:             return_trace (u.alternate.dispatch (c));
+    case Ligature:              return_trace (u.ligature.dispatch (c));
+    case Context:               return_trace (u.context.dispatch (c));
+    case ChainContext:          return_trace (u.chainContext.dispatch (c));
+    case Extension:             return_trace (u.extension.dispatch (c));
+    case ReverseChainSingle:    return_trace (u.reverseChainContextSingle.dispatch (c));
+    default:                    return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                        sub_format;
+  SingleSubst                   single;
+  MultipleSubst                 multiple;
+  AlternateSubst                alternate;
+  LigatureSubst                 ligature;
+  ContextSubst                  context;
+  ChainContextSubst             chainContext;
+  ExtensionSubst                extension;
+  ReverseChainSingleSubst       reverseChainContextSingle;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, sub_format);
+};
+
+
+struct SubstLookup : Lookup
+{
+  inline const SubstLookupSubTable& get_subtable (unsigned int i) const
+  { return Lookup::get_subtable<SubstLookupSubTable> (i); }
+
+  inline static bool lookup_type_is_reverse (unsigned int lookup_type)
+  { return lookup_type == SubstLookupSubTable::ReverseChainSingle; }
+
+  inline bool is_reverse (void) const
+  {
+    unsigned int type = get_type ();
+    if (unlikely (type == SubstLookupSubTable::Extension))
+      return CastR<ExtensionSubst> (get_subtable(0)).is_reverse ();
+    return lookup_type_is_reverse (type);
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    return_trace (dispatch (c));
+  }
+
+  inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>);
+    return_trace (dispatch (c));
+  }
+
+  inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>);
+    return_trace (dispatch (c));
+  }
+
+  template <typename set_t>
+  inline void add_coverage (set_t *glyphs) const
+  {
+    hb_add_coverage_context_t<set_t> c (glyphs);
+    dispatch (&c);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c,
+                           const hb_ot_layout_lookup_accelerator_t *accel) const
+  {
+    TRACE_WOULD_APPLY (this);
+    if (unlikely (!c->len))  return_trace (false);
+    if (!accel->may_have (c->glyphs[0]))  return_trace (false);
+      return_trace (dispatch (c));
+  }
+
+  static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+
+  inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
+                                                  unsigned int i)
+  { return get_subtables<SubstLookupSubTable> ()[i].serialize (c, this); }
+
+  inline bool serialize_single (hb_serialize_context_t *c,
+                                uint32_t lookup_props,
+                                Supplier<GlyphID> &glyphs,
+                                Supplier<GlyphID> &substitutes,
+                                unsigned int num_glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return_trace (false);
+    return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs));
+  }
+
+  inline bool serialize_multiple (hb_serialize_context_t *c,
+                                  uint32_t lookup_props,
+                                  Supplier<GlyphID> &glyphs,
+                                  Supplier<unsigned int> &substitute_len_list,
+                                  unsigned int num_glyphs,
+                                  Supplier<GlyphID> &substitute_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return_trace (false);
+    return_trace (serialize_subtable (c, 0).u.multiple.serialize (c,
+                                                                  glyphs,
+                                                                  substitute_len_list,
+                                                                  num_glyphs,
+                                                                  substitute_glyphs_list));
+  }
+
+  inline bool serialize_alternate (hb_serialize_context_t *c,
+                                   uint32_t lookup_props,
+                                   Supplier<GlyphID> &glyphs,
+                                   Supplier<unsigned int> &alternate_len_list,
+                                   unsigned int num_glyphs,
+                                   Supplier<GlyphID> &alternate_glyphs_list)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return_trace (false);
+    return_trace (serialize_subtable (c, 0).u.alternate.serialize (c,
+                                                                   glyphs,
+                                                                   alternate_len_list,
+                                                                   num_glyphs,
+                                                                   alternate_glyphs_list));
+  }
+
+  inline bool serialize_ligature (hb_serialize_context_t *c,
+                                  uint32_t lookup_props,
+                                  Supplier<GlyphID> &first_glyphs,
+                                  Supplier<unsigned int> &ligature_per_first_glyph_count_list,
+                                  unsigned int num_first_glyphs,
+                                  Supplier<GlyphID> &ligatures_list,
+                                  Supplier<unsigned int> &component_count_list,
+                                  Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return_trace (false);
+    return_trace (serialize_subtable (c, 0).u.ligature.serialize (c,
+                                                                  first_glyphs,
+                                                                  ligature_per_first_glyph_count_list,
+                                                                  num_first_glyphs,
+                                                                  ligatures_list,
+                                                                  component_count_list,
+                                                                  component_list));
+  }
+
+  template <typename context_t>
+  static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  { return Lookup::dispatch<SubstLookupSubTable> (c); }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!Lookup::sanitize (c))) return_trace (false);
+    if (unlikely (!dispatch (c))) return_trace (false);
+
+    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! */
+      unsigned int type = get_subtable (0).u.extension.get_type ();
+      unsigned int count = get_subtable_count ();
+      for (unsigned int i = 1; i < count; i++)
+        if (get_subtable (i).u.extension.get_type () != type)
+          return_trace (false);
+    }
+    return_trace (true);
+  }
+};
+
+typedef OffsetListOf<SubstLookup> SubstLookupList;
+
+/*
+ * GSUB -- The Glyph Substitution Table
+ */
+
+struct GSUB : GSUBGPOS
+{
+  static const hb_tag_t tableTag        = HB_OT_TAG_GSUB;
+
+  inline const SubstLookup& get_lookup (unsigned int i) const
+  { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
+
+  static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer);
+  static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer);
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false);
+    const OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
+    return_trace (list.sanitize (c, this));
+  }
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+
+void
+GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
+{
+  _hb_buffer_assert_gsubgpos_vars (buffer);
+
+  const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
+    _hb_glyph_info_clear_lig_props (&buffer->info[i]);
+    buffer->info[i].syllable() = 0;
+  }
+}
+
+void
+GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
+{
+}
+
+
+/* Out-of-class implementation for methods recursing */
+
+/*static*/ inline bool ExtensionSubst::is_reverse (void) const
+{
+  unsigned int type = get_type ();
+  if (unlikely (type == SubstLookupSubTable::Extension))
+    return CastR<ExtensionSubst> (get_subtable<LookupSubTable>()).is_reverse ();
+  return SubstLookup::lookup_type_is_reverse (type);
+}
+
+template <typename context_t>
+/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (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);
+  return l.dispatch (c);
+}
+
+/*static*/ inline bool SubstLookup::apply_recurse_func (hb_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);
+  unsigned int saved_lookup_props = c->lookup_props;
+  unsigned int saved_lookup_index = c->lookup_index;
+  c->set_lookup_index (lookup_index);
+  c->set_lookup_props (l.get_props ());
+  bool ret = l.dispatch (c);
+  c->set_lookup_index (saved_lookup_index);
+  c->set_lookup_props (saved_lookup_props);
+  return ret;
+}
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GSUB_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsubgpos-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,2286 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2010,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
+#define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
+
+#include "hb-buffer-private.hh"
+#include "hb-ot-layout-gdef-table.hh"
+#include "hb-set-private.hh"
+
+
+namespace OT {
+
+
+#ifndef HB_DEBUG_CLOSURE
+#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
+#endif
+
+#define TRACE_CLOSURE(this) \
+        hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
+        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+         "");
+
+struct hb_closure_context_t :
+       hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE>
+{
+  inline const char *get_name (void) { return "CLOSURE"; }
+  typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
+  template <typename T>
+  inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
+  static return_t default_return_value (void) { return HB_VOID; }
+  bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
+  return_t recurse (unsigned int lookup_index)
+  {
+    if (unlikely (nesting_level_left == 0 || !recurse_func))
+      return default_return_value ();
+
+    nesting_level_left--;
+    recurse_func (this, lookup_index);
+    nesting_level_left++;
+    return HB_VOID;
+  }
+
+  hb_face_t *face;
+  hb_set_t *glyphs;
+  recurse_func_t recurse_func;
+  unsigned int nesting_level_left;
+  unsigned int debug_depth;
+
+  hb_closure_context_t (hb_face_t *face_,
+                        hb_set_t *glyphs_,
+                        unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
+                          face (face_),
+                          glyphs (glyphs_),
+                          recurse_func (NULL),
+                          nesting_level_left (nesting_level_left_),
+                          debug_depth (0) {}
+
+  void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+};
+
+
+
+#ifndef HB_DEBUG_WOULD_APPLY
+#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
+#endif
+
+#define TRACE_WOULD_APPLY(this) \
+        hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
+        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+         "%d glyphs", c->len);
+
+struct hb_would_apply_context_t :
+       hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY>
+{
+  inline const char *get_name (void) { return "WOULD_APPLY"; }
+  template <typename T>
+  inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
+  static return_t default_return_value (void) { return false; }
+  bool stop_sublookup_iteration (return_t r) const { return r; }
+
+  hb_face_t *face;
+  const hb_codepoint_t *glyphs;
+  unsigned int len;
+  bool zero_context;
+  unsigned int debug_depth;
+
+  hb_would_apply_context_t (hb_face_t *face_,
+                            const hb_codepoint_t *glyphs_,
+                            unsigned int len_,
+                            bool zero_context_) :
+                              face (face_),
+                              glyphs (glyphs_),
+                              len (len_),
+                              zero_context (zero_context_),
+                              debug_depth (0) {}
+};
+
+
+
+#ifndef HB_DEBUG_COLLECT_GLYPHS
+#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0)
+#endif
+
+#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, \
+         "");
+
+struct hb_collect_glyphs_context_t :
+       hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS>
+{
+  inline const char *get_name (void) { return "COLLECT_GLYPHS"; }
+  typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
+  template <typename T>
+  inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
+  static return_t default_return_value (void) { return HB_VOID; }
+  bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
+  return_t recurse (unsigned int lookup_index)
+  {
+    if (unlikely (nesting_level_left == 0 || !recurse_func))
+      return default_return_value ();
+
+    /* Note that GPOS sets recurse_func to NULL already, so it doesn't get
+     * past the previous check.  For GSUB, we only want to collect the output
+     * glyphs in the recursion.  If output is not requested, we can go home now.
+     *
+     * Note further, that the above is not exactly correct.  A recursed lookup
+     * is allowed to match input that is not matched in the context, but that's
+     * not how most fonts are built.  It's possible to relax that and recurse
+     * with all sets here if it proves to be an issue.
+     */
+
+    if (output == hb_set_get_empty ())
+      return HB_VOID;
+
+    /* Return if new lookup was recursed to before. */
+    if (recursed_lookups.has (lookup_index))
+      return HB_VOID;
+
+    hb_set_t *old_before = before;
+    hb_set_t *old_input  = input;
+    hb_set_t *old_after  = after;
+    before = input = after = hb_set_get_empty ();
+
+    nesting_level_left--;
+    recurse_func (this, lookup_index);
+    nesting_level_left++;
+
+    before = old_before;
+    input  = old_input;
+    after  = old_after;
+
+    recursed_lookups.add (lookup_index);
+
+    return HB_VOID;
+  }
+
+  hb_face_t *face;
+  hb_set_t *before;
+  hb_set_t *input;
+  hb_set_t *after;
+  hb_set_t *output;
+  recurse_func_t recurse_func;
+  hb_set_t recursed_lookups;
+  unsigned int nesting_level_left;
+  unsigned int debug_depth;
+
+  hb_collect_glyphs_context_t (hb_face_t *face_,
+                               hb_set_t  *glyphs_before, /* OUT. May be NULL */
+                               hb_set_t  *glyphs_input,  /* OUT. May be NULL */
+                               hb_set_t  *glyphs_after,  /* OUT. May be NULL */
+                               hb_set_t  *glyphs_output, /* OUT. May be NULL */
+                               unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
+                              face (face_),
+                              before (glyphs_before ? glyphs_before : hb_set_get_empty ()),
+                              input  (glyphs_input  ? glyphs_input  : hb_set_get_empty ()),
+                              after  (glyphs_after  ? glyphs_after  : hb_set_get_empty ()),
+                              output (glyphs_output ? glyphs_output : hb_set_get_empty ()),
+                              recurse_func (NULL),
+                              recursed_lookups (),
+                              nesting_level_left (nesting_level_left_),
+                              debug_depth (0)
+  {
+    recursed_lookups.init ();
+  }
+  ~hb_collect_glyphs_context_t (void)
+  {
+    recursed_lookups.fini ();
+  }
+
+  void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+};
+
+
+
+#ifndef HB_DEBUG_GET_COVERAGE
+#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
+#endif
+
+/* XXX Can we remove this? */
+
+template <typename set_t>
+struct hb_add_coverage_context_t :
+       hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE>
+{
+  inline const char *get_name (void) { return "GET_COVERAGE"; }
+  typedef const Coverage &return_t;
+  template <typename T>
+  inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
+  static return_t default_return_value (void) { return Null(Coverage); }
+  bool stop_sublookup_iteration (return_t r) const
+  {
+    r.add_coverage (set);
+    return false;
+  }
+
+  hb_add_coverage_context_t (set_t *set_) :
+                            set (set_),
+                            debug_depth (0) {}
+
+  set_t *set;
+  unsigned int debug_depth;
+};
+
+
+
+#ifndef HB_DEBUG_APPLY
+#define HB_DEBUG_APPLY (HB_DEBUG+0)
+#endif
+
+#define TRACE_APPLY(this) \
+        hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
+        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+         "idx %d gid %u lookup %d", \
+         c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index);
+
+struct hb_apply_context_t :
+       hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY>
+{
+  struct matcher_t
+  {
+    inline matcher_t (void) :
+             lookup_props (0),
+             ignore_zwnj (false),
+             ignore_zwj (false),
+             mask (-1),
+#define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
+             syllable arg1(0),
+#undef arg1
+             match_func (NULL),
+             match_data (NULL) {};
+
+    typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &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_; }
+    inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
+    inline void set_mask (hb_mask_t mask_) { mask = mask_; }
+    inline void set_syllable (uint8_t syllable_)  { syllable = syllable_; }
+    inline void set_match_func (match_func_t match_func_,
+                                const void *match_data_)
+    { match_func = match_func_; match_data = match_data_; }
+
+    enum may_match_t {
+      MATCH_NO,
+      MATCH_YES,
+      MATCH_MAYBE
+    };
+
+    inline may_match_t may_match (const hb_glyph_info_t &info,
+                                  const USHORT          *glyph_data) const
+    {
+      if (!(info.mask & mask) ||
+          (syllable && syllable != info.syllable ()))
+        return MATCH_NO;
+
+      if (match_func)
+        return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
+
+      return MATCH_MAYBE;
+    }
+
+    enum may_skip_t {
+      SKIP_NO,
+      SKIP_YES,
+      SKIP_MAYBE
+    };
+
+    inline may_skip_t
+    may_skip (const hb_apply_context_t *c,
+              const hb_glyph_info_t    &info) const
+    {
+      if (!c->check_glyph_property (&info, lookup_props))
+        return SKIP_YES;
+
+      if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
+                    (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
+                    (ignore_zwj || !_hb_glyph_info_is_zwj (&info))))
+        return SKIP_MAYBE;
+
+      return SKIP_NO;
+    }
+
+    protected:
+    unsigned int lookup_props;
+    bool ignore_zwnj;
+    bool ignore_zwj;
+    hb_mask_t mask;
+    uint8_t syllable;
+    match_func_t match_func;
+    const void *match_data;
+  };
+
+  struct skipping_iterator_t
+  {
+    inline void init (hb_apply_context_t *c_, bool context_match = false)
+    {
+      c = c_;
+      match_glyph_data = NULL,
+      matcher.set_match_func (NULL, NULL);
+      matcher.set_lookup_props (c->lookup_props);
+      /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
+      matcher.set_ignore_zwnj (context_match || c->table_index == 1);
+      /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
+      matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
+      matcher.set_mask (context_match ? -1 : c->lookup_mask);
+    }
+    inline void set_lookup_props (unsigned int lookup_props)
+    {
+      matcher.set_lookup_props (lookup_props);
+    }
+    inline void set_match_func (matcher_t::match_func_t match_func,
+                                const void *match_data,
+                                const USHORT glyph_data[])
+    {
+      matcher.set_match_func (match_func, match_data);
+      match_glyph_data = glyph_data;
+    }
+
+    inline void reset (unsigned int start_index_,
+                       unsigned int num_items_)
+    {
+      idx = start_index_;
+      num_items = num_items_;
+      end = c->buffer->len;
+      matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
+    }
+
+    inline void reject (void) { num_items++; match_glyph_data--; }
+
+    inline bool next (void)
+    {
+      assert (num_items > 0);
+      while (idx + num_items < end)
+      {
+        idx++;
+        const hb_glyph_info_t &info = c->buffer->info[idx];
+
+        matcher_t::may_skip_t skip = matcher.may_skip (c, info);
+        if (unlikely (skip == matcher_t::SKIP_YES))
+          continue;
+
+        matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data);
+        if (match == matcher_t::MATCH_YES ||
+            (match == matcher_t::MATCH_MAYBE &&
+             skip == matcher_t::SKIP_NO))
+        {
+          num_items--;
+          match_glyph_data++;
+          return true;
+        }
+
+        if (skip == matcher_t::SKIP_NO)
+          return false;
+      }
+      return false;
+    }
+    inline bool prev (void)
+    {
+      assert (num_items > 0);
+      while (idx >= num_items)
+      {
+        idx--;
+        const hb_glyph_info_t &info = c->buffer->out_info[idx];
+
+        matcher_t::may_skip_t skip = matcher.may_skip (c, info);
+        if (unlikely (skip == matcher_t::SKIP_YES))
+          continue;
+
+        matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data);
+        if (match == matcher_t::MATCH_YES ||
+            (match == matcher_t::MATCH_MAYBE &&
+             skip == matcher_t::SKIP_NO))
+        {
+          num_items--;
+          match_glyph_data++;
+          return true;
+        }
+
+        if (skip == matcher_t::SKIP_NO)
+          return false;
+      }
+      return false;
+    }
+
+    unsigned int idx;
+    protected:
+    hb_apply_context_t *c;
+    matcher_t matcher;
+    const USHORT *match_glyph_data;
+
+    unsigned int num_items;
+    unsigned int end;
+  };
+
+
+  inline const char *get_name (void) { return "APPLY"; }
+  typedef return_t (*recurse_func_t) (hb_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)
+  {
+    if (unlikely (nesting_level_left == 0 || !recurse_func))
+      return default_return_value ();
+
+    nesting_level_left--;
+    bool ret = recurse_func (this, lookup_index);
+    nesting_level_left++;
+    return ret;
+  }
+
+  unsigned int table_index; /* GSUB/GPOS */
+  hb_font_t *font;
+  hb_face_t *face;
+  hb_buffer_t *buffer;
+  hb_direction_t direction;
+  hb_mask_t lookup_mask;
+  bool auto_zwj;
+  recurse_func_t recurse_func;
+  unsigned int nesting_level_left;
+  unsigned int lookup_props;
+  const GDEF &gdef;
+  bool has_glyph_classes;
+  skipping_iterator_t iter_input, iter_context;
+  unsigned int lookup_index;
+  unsigned int debug_depth;
+
+
+  hb_apply_context_t (unsigned int table_index_,
+                      hb_font_t *font_,
+                      hb_buffer_t *buffer_) :
+                        table_index (table_index_),
+                        font (font_), face (font->face), buffer (buffer_),
+                        direction (buffer_->props.direction),
+                        lookup_mask (1),
+                        auto_zwj (true),
+                        recurse_func (NULL),
+                        nesting_level_left (MAX_NESTING_LEVEL),
+                        lookup_props (0),
+                        gdef (*hb_ot_layout_from_face (face)->gdef),
+                        has_glyph_classes (gdef.has_glyph_classes ()),
+                        iter_input (),
+                        iter_context (),
+                        lookup_index ((unsigned int) -1),
+                        debug_depth (0) {}
+
+  inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
+  inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
+  inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+  inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
+  inline void set_lookup_props (unsigned int lookup_props_)
+  {
+    lookup_props = lookup_props_;
+    iter_input.init (this, false);
+    iter_context.init (this, true);
+  }
+
+  inline bool
+  match_properties_mark (hb_codepoint_t  glyph,
+                         unsigned int    glyph_props,
+                         unsigned int    match_props) const
+  {
+    /* If using mark filtering sets, the high short of
+     * match_props has the set index.
+     */
+    if (match_props & LookupFlag::UseMarkFilteringSet)
+      return gdef.mark_set_covers (match_props >> 16, glyph);
+
+    /* The second byte of match_props has the meaning
+     * "ignore marks of attachment type different than
+     * the attachment type specified."
+     */
+    if (match_props & LookupFlag::MarkAttachmentType)
+      return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
+
+    return true;
+  }
+
+  inline bool
+  check_glyph_property (const hb_glyph_info_t *info,
+                        unsigned int  match_props) const
+  {
+    hb_codepoint_t glyph = info->codepoint;
+    unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
+
+    /* Not covered, if, for example, glyph class is ligature and
+     * match_props includes LookupFlags::IgnoreLigatures
+     */
+    if (glyph_props & match_props & LookupFlag::IgnoreFlags)
+      return false;
+
+    if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
+      return match_properties_mark (glyph, glyph_props, match_props);
+
+    return true;
+  }
+
+  inline void _set_glyph_props (hb_codepoint_t glyph_index,
+                          unsigned int class_guess = 0,
+                          bool ligature = false,
+                          bool component = false) const
+  {
+    unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
+                          HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+    add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+    if (ligature)
+    {
+      add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
+      /* In the only place that the MULTIPLIED bit is used, Uniscribe
+       * seems to only care about the "last" transformation between
+       * Ligature and Multiple substitions.  Ie. if you ligate, expand,
+       * and ligate again, it forgives the multiplication and acts as
+       * if only ligation happened.  As such, clear MULTIPLIED bit.
+       */
+      add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+    }
+    if (component)
+      add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+    if (likely (has_glyph_classes))
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
+    else if (class_guess)
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
+  }
+
+  inline void replace_glyph (hb_codepoint_t glyph_index) const
+  {
+    _set_glyph_props (glyph_index);
+    buffer->replace_glyph (glyph_index);
+  }
+  inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const
+  {
+    _set_glyph_props (glyph_index);
+    buffer->cur().codepoint = glyph_index;
+  }
+  inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
+                                           unsigned int class_guess) const
+  {
+    _set_glyph_props (glyph_index, class_guess, true);
+    buffer->replace_glyph (glyph_index);
+  }
+  inline void output_glyph_for_component (hb_codepoint_t glyph_index,
+                                          unsigned int class_guess) const
+  {
+    _set_glyph_props (glyph_index, class_guess, false, true);
+    buffer->output_glyph (glyph_index);
+  }
+};
+
+
+
+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);
+
+struct ContextClosureFuncs
+{
+  intersects_func_t intersects;
+};
+struct ContextCollectGlyphsFuncs
+{
+  collect_glyphs_func_t collect;
+};
+struct ContextApplyFuncs
+{
+  match_func_t match;
+};
+
+
+static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &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)
+{
+  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)
+{
+  const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+  return (data+coverage).intersects (glyphs);
+}
+
+static inline bool intersects_array (hb_closure_context_t *c,
+                                     unsigned int count,
+                                     const USHORT values[],
+                                     intersects_func_t intersects_func,
+                                     const void *intersects_data)
+{
+  for (unsigned int i = 0; i < count; i++)
+    if (likely (!intersects_func (c->glyphs, values[i], intersects_data)))
+      return false;
+  return true;
+}
+
+
+static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+{
+  glyphs->add (value);
+}
+static inline void collect_class (hb_set_t *glyphs, const USHORT &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)
+{
+  const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+  (data+coverage).add_coverage (glyphs);
+}
+static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
+                                  hb_set_t *glyphs,
+                                  unsigned int count,
+                                  const USHORT values[],
+                                  collect_glyphs_func_t collect_func,
+                                  const void *collect_data)
+{
+  for (unsigned int i = 0; i < count; i++)
+    collect_func (glyphs, values[i], collect_data);
+}
+
+
+static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &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)
+{
+  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)
+{
+  const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+  return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
+}
+
+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 */
+                                      match_func_t match_func,
+                                      const void *match_data)
+{
+  if (count != c->len)
+    return false;
+
+  for (unsigned int i = 1; i < count; i++)
+    if (likely (!match_func (c->glyphs[i], input[i - 1], match_data)))
+      return false;
+
+  return true;
+}
+static inline bool match_input (hb_apply_context_t *c,
+                                unsigned int count, /* Including the first glyph (not matched) */
+                                const USHORT input[], /* Array of input values--start with second glyph */
+                                match_func_t match_func,
+                                const void *match_data,
+                                unsigned int *end_offset,
+                                unsigned int match_positions[MAX_CONTEXT_LENGTH],
+                                bool *p_is_mark_ligature = NULL,
+                                unsigned int *p_total_component_count = NULL)
+{
+  TRACE_APPLY (NULL);
+
+  if (unlikely (count > MAX_CONTEXT_LENGTH)) return_trace (false);
+
+  hb_buffer_t *buffer = c->buffer;
+
+  hb_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);
+
+  /*
+   * This is perhaps the trickiest part of OpenType...  Remarks:
+   *
+   * - If all components of the ligature were marks, we call this a mark ligature.
+   *
+   * - If there is no GDEF, and the ligature is NOT a mark ligature, we categorize
+   *   it as a ligature glyph.
+   *
+   * - Ligatures cannot be formed across glyphs attached to different components
+   *   of previous ligatures.  Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and
+   *   LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother.
+   *   However, it would be wrong to ligate that SHADDA,FATHA sequence.o
+   *   There is an exception to this: If a ligature tries ligating with marks that
+   *   belong to it itself, go ahead, assuming that the font designer knows what
+   *   they are doing (otherwise it can break Indic stuff when a matra wants to
+   *   ligate with a conjunct...)
+   */
+
+  bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
+
+  unsigned int total_component_count = 0;
+  total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
+
+  unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+  unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+
+  match_positions[0] = buffer->idx;
+  for (unsigned int i = 1; i < count; i++)
+  {
+    if (!skippy_iter.next ()) return_trace (false);
+
+    match_positions[i] = skippy_iter.idx;
+
+    unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
+    unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
+
+    if (first_lig_id && first_lig_comp) {
+      /* If first component was attached to a previous ligature component,
+       * all subsequent components should be attached to the same ligature
+       * component, otherwise we shouldn't ligate them. */
+      if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
+        return_trace (false);
+    } else {
+      /* If first component was NOT attached to a previous ligature component,
+       * all subsequent components should also NOT be attached to any ligature
+       * component, unless they are attached to the first component itself! */
+      if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id))
+        return_trace (false);
+    }
+
+    is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
+    total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
+  }
+
+  *end_offset = skippy_iter.idx - buffer->idx + 1;
+
+  if (p_is_mark_ligature)
+    *p_is_mark_ligature = is_mark_ligature;
+
+  if (p_total_component_count)
+    *p_total_component_count = total_component_count;
+
+  return_trace (true);
+}
+static inline bool ligate_input (hb_apply_context_t *c,
+                                 unsigned int count, /* Including the first glyph */
+                                 unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
+                                 unsigned int match_length,
+                                 hb_codepoint_t lig_glyph,
+                                 bool is_mark_ligature,
+                                 unsigned int total_component_count)
+{
+  TRACE_APPLY (NULL);
+
+  hb_buffer_t *buffer = c->buffer;
+
+  buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
+
+  /*
+   * - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
+   *   the ligature to keep its old ligature id.  This will allow it to attach to
+   *   a base ligature in GPOS.  Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HEH,
+   *   and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a
+   *   ligature id and component value of 2.  Then if SHADDA,FATHA form a ligature
+   *   later, we don't want them to lose their ligature id/component, otherwise
+   *   GPOS will fail to correctly position the mark ligature on top of the
+   *   LAM,LAM,HEH ligature.  See:
+   *     https://bugzilla.gnome.org/show_bug.cgi?id=676343
+   *
+   * - If a ligature is formed of components that some of which are also ligatures
+   *   themselves, and those ligature components had marks attached to *their*
+   *   components, we have to attach the marks to the new ligature component
+   *   positions!  Now *that*'s tricky!  And these marks may be following the
+   *   last component of the whole sequence, so we should loop forward looking
+   *   for them and update them.
+   *
+   *   Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a
+   *   'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature
+   *   id and component == 1.  Now, during 'liga', the LAM and the LAM-HEH ligature
+   *   form a LAM-LAM-HEH ligature.  We need to reassign the SHADDA and FATHA to
+   *   the new ligature with a component value of 2.
+   *
+   *   This in fact happened to a font...  See:
+   *   https://bugzilla.gnome.org/show_bug.cgi?id=437633
+   */
+
+  unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+  unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer);
+  unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+  unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
+  unsigned int components_so_far = last_num_components;
+
+  if (!is_mark_ligature)
+  {
+    _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
+    if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+    {
+      _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+      _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0);
+    }
+  }
+  c->replace_glyph_with_ligature (lig_glyph, klass);
+
+  for (unsigned int i = 1; i < count; i++)
+  {
+    while (buffer->idx < match_positions[i])
+    {
+      if (!is_mark_ligature) {
+        unsigned int new_lig_comp = components_so_far - last_num_components +
+                                    MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components);
+        _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
+      }
+      buffer->next_glyph ();
+    }
+
+    last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+    last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
+    components_so_far += last_num_components;
+
+    /* Skip the base glyph */
+    buffer->idx++;
+  }
+
+  if (!is_mark_ligature && last_lig_id) {
+    /* Re-adjust components for any marks following. */
+    for (unsigned int i = buffer->idx; i < buffer->len; i++) {
+      if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
+        unsigned int new_lig_comp = components_so_far - last_num_components +
+                                    MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components);
+        _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
+      } else
+        break;
+    }
+  }
+  return_trace (true);
+}
+
+static inline bool match_backtrack (hb_apply_context_t *c,
+                                    unsigned int count,
+                                    const USHORT backtrack[],
+                                    match_func_t match_func,
+                                    const void *match_data)
+{
+  TRACE_APPLY (NULL);
+
+  hb_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);
+
+  for (unsigned int i = 0; i < count; i++)
+    if (!skippy_iter.prev ())
+      return_trace (false);
+
+  return_trace (true);
+}
+
+static inline bool match_lookahead (hb_apply_context_t *c,
+                                    unsigned int count,
+                                    const USHORT lookahead[],
+                                    match_func_t match_func,
+                                    const void *match_data,
+                                    unsigned int offset)
+{
+  TRACE_APPLY (NULL);
+
+  hb_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);
+
+  for (unsigned int i = 0; i < count; i++)
+    if (!skippy_iter.next ())
+      return_trace (false);
+
+  return_trace (true);
+}
+
+
+
+struct LookupRecord
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  USHORT        sequenceIndex;          /* Index into current glyph
+                                         * sequence--first glyph = 0 */
+  USHORT        lookupListIndex;        /* Lookup to apply to that
+                                         * position--zero--based */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+
+template <typename context_t>
+static inline void recurse_lookups (context_t *c,
+                                    unsigned int lookupCount,
+                                    const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
+{
+  for (unsigned int i = 0; i < lookupCount; i++)
+    c->recurse (lookupRecord[i].lookupListIndex);
+}
+
+static inline bool apply_lookup (hb_apply_context_t *c,
+                                 unsigned int count, /* Including the first glyph */
+                                 unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
+                                 unsigned int lookupCount,
+                                 const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
+                                 unsigned int match_length)
+{
+  TRACE_APPLY (NULL);
+
+  hb_buffer_t *buffer = c->buffer;
+  unsigned int end;
+
+  /* All positions are distance from beginning of *output* buffer.
+   * Adjust. */
+  {
+    unsigned int bl = buffer->backtrack_len ();
+    end = bl + match_length;
+
+    int delta = bl - buffer->idx;
+    /* Convert positions to new indexing. */
+    for (unsigned int j = 0; j < count; j++)
+      match_positions[j] += delta;
+  }
+
+  for (unsigned int i = 0; i < lookupCount; i++)
+  {
+    unsigned int idx = lookupRecord[i].sequenceIndex;
+    if (idx >= count)
+      continue;
+
+    buffer->move_to (match_positions[idx]);
+
+    unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
+    if (!c->recurse (lookupRecord[i].lookupListIndex))
+      continue;
+
+    unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len ();
+    int delta = new_len - orig_len;
+
+    if (!delta)
+        continue;
+
+    /* Recursed lookup changed buffer len.  Adjust. */
+
+    /* end can't go back past the current match position.
+     * Note: this is only true because we do NOT allow MultipleSubst
+     * with zero sequence len. */
+    end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
+
+    unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
+
+    if (delta > 0)
+    {
+      if (unlikely (delta + count > MAX_CONTEXT_LENGTH))
+        break;
+    }
+    else
+    {
+      /* NOTE: delta is negative. */
+      delta = MAX (delta, (int) next - (int) count);
+      next -= delta;
+    }
+
+    /* Shift! */
+    memmove (match_positions + next + delta, match_positions + next,
+             (count - next) * sizeof (match_positions[0]));
+    next += delta;
+    count += delta;
+
+    /* Fill in new entries. */
+    for (unsigned int j = idx + 1; j < next; j++)
+      match_positions[j] = match_positions[j - 1] + 1;
+
+    /* And fixup the rest. */
+    for (; next < count; next++)
+      match_positions[next] += delta;
+  }
+
+  buffer->move_to (end);
+
+  return_trace (true);
+}
+
+
+
+/* Contextual lookups */
+
+struct ContextClosureLookupContext
+{
+  ContextClosureFuncs funcs;
+  const void *intersects_data;
+};
+
+struct ContextCollectGlyphsLookupContext
+{
+  ContextCollectGlyphsFuncs funcs;
+  const void *collect_data;
+};
+
+struct ContextApplyLookupContext
+{
+  ContextApplyFuncs funcs;
+  const void *match_data;
+};
+
+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 */
+                                           unsigned int lookupCount,
+                                           const LookupRecord lookupRecord[],
+                                           ContextClosureLookupContext &lookup_context)
+{
+  if (intersects_array (c,
+                        inputCount ? inputCount - 1 : 0, input,
+                        lookup_context.funcs.intersects, lookup_context.intersects_data))
+    recurse_lookups (c,
+                     lookupCount, lookupRecord);
+}
+
+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 */
+                                                  unsigned int lookupCount,
+                                                  const LookupRecord lookupRecord[],
+                                                  ContextCollectGlyphsLookupContext &lookup_context)
+{
+  collect_array (c, c->input,
+                 inputCount ? inputCount - 1 : 0, input,
+                 lookup_context.funcs.collect, lookup_context.collect_data);
+  recurse_lookups (c,
+                   lookupCount, lookupRecord);
+}
+
+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 */
+                                               unsigned int lookupCount HB_UNUSED,
+                                               const LookupRecord lookupRecord[] HB_UNUSED,
+                                               ContextApplyLookupContext &lookup_context)
+{
+  return would_match_input (c,
+                            inputCount, input,
+                            lookup_context.funcs.match, lookup_context.match_data);
+}
+static inline bool context_apply_lookup (hb_apply_context_t *c,
+                                         unsigned int inputCount, /* Including the first glyph (not matched) */
+                                         const USHORT input[], /* Array of input values--start with second glyph */
+                                         unsigned int lookupCount,
+                                         const LookupRecord lookupRecord[],
+                                         ContextApplyLookupContext &lookup_context)
+{
+  unsigned int match_length = 0;
+  unsigned int match_positions[MAX_CONTEXT_LENGTH];
+  return match_input (c,
+                      inputCount, input,
+                      lookup_context.funcs.match, lookup_context.match_data,
+                      &match_length, match_positions)
+      && apply_lookup (c,
+                       inputCount, match_positions,
+                       lookupCount, lookupRecord,
+                       match_length);
+}
+
+struct Rule
+{
+  inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+  {
+    TRACE_CLOSURE (this);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+    context_closure_lookup (c,
+                            inputCount, inputZ,
+                            lookupCount, lookupRecord,
+                            lookup_context);
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+    context_collect_glyphs_lookup (c,
+                                   inputCount, inputZ,
+                                   lookupCount, lookupRecord,
+                                   lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+  {
+    TRACE_WOULD_APPLY (this);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+    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
+  {
+    TRACE_APPLY (this);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
+    return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
+  }
+
+  public:
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return inputCount.sanitize (c)
+        && lookupCount.sanitize (c)
+        && c->check_range (inputZ,
+                           inputZ[0].static_size * inputCount
+                           + lookupRecordX[0].static_size * lookupCount);
+  }
+
+  protected:
+  USHORT        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
+                                         * second glyph */
+  LookupRecord  lookupRecordX[VAR];     /* Array of LookupRecords--in
+                                         * design order */
+  public:
+  DEFINE_SIZE_ARRAY2 (4, inputZ, lookupRecordX);
+};
+
+struct RuleSet
+{
+  inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+  {
+    TRACE_CLOSURE (this);
+    unsigned int num_rules = rule.len;
+    for (unsigned int i = 0; i < num_rules; i++)
+      (this+rule[i]).closure (c, lookup_context);
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    unsigned int num_rules = rule.len;
+    for (unsigned int i = 0; i < num_rules; i++)
+      (this+rule[i]).collect_glyphs (c, lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+  {
+    TRACE_WOULD_APPLY (this);
+    unsigned int num_rules = rule.len;
+    for (unsigned int i = 0; i < num_rules; i++)
+    {
+      if ((this+rule[i]).would_apply (c, lookup_context))
+        return_trace (true);
+    }
+    return_trace (false);
+  }
+
+  inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
+  {
+    TRACE_APPLY (this);
+    unsigned int num_rules = rule.len;
+    for (unsigned int i = 0; i < num_rules; i++)
+    {
+      if ((this+rule[i]).apply (c, lookup_context))
+        return_trace (true);
+    }
+    return_trace (false);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (rule.sanitize (c, this));
+  }
+
+  protected:
+  OffsetArrayOf<Rule>
+                rule;                   /* Array of Rule tables
+                                         * ordered by preference */
+  public:
+  DEFINE_SIZE_ARRAY (2, rule);
+};
+
+
+struct ContextFormat1
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+
+    const Coverage &cov = (this+coverage);
+
+    struct ContextClosureLookupContext lookup_context = {
+      {intersects_glyph},
+      NULL
+    };
+
+    unsigned int count = ruleSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (cov.intersects_coverage (c->glyphs, i)) {
+        const RuleSet &rule_set = this+ruleSet[i];
+        rule_set.closure (c, lookup_context);
+      }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+
+    struct ContextCollectGlyphsLookupContext lookup_context = {
+      {collect_glyph},
+      NULL
+    };
+
+    unsigned int count = ruleSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+
+    const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
+    struct ContextApplyLookupContext lookup_context = {
+      {match_glyph},
+      NULL
+    };
+    return_trace (rule_set.would_apply (c, lookup_context));
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED))
+      return_trace (false);
+
+    const RuleSet &rule_set = this+ruleSet[index];
+    struct ContextApplyLookupContext lookup_context = {
+      {match_glyph},
+      NULL
+    };
+    return_trace (rule_set.apply (c, lookup_context));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of table */
+  OffsetArrayOf<RuleSet>
+                ruleSet;                /* Array of RuleSet tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, ruleSet);
+};
+
+
+struct ContextFormat2
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    if (!(this+coverage).intersects (c->glyphs))
+      return;
+
+    const ClassDef &class_def = this+classDef;
+
+    struct ContextClosureLookupContext lookup_context = {
+      {intersects_class},
+      &class_def
+    };
+
+    unsigned int count = ruleSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (class_def.intersects_class (c->glyphs, i)) {
+        const RuleSet &rule_set = this+ruleSet[i];
+        rule_set.closure (c, lookup_context);
+      }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+
+    const ClassDef &class_def = this+classDef;
+    struct ContextCollectGlyphsLookupContext lookup_context = {
+      {collect_class},
+      &class_def
+    };
+
+    unsigned int count = ruleSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+
+    const ClassDef &class_def = this+classDef;
+    unsigned int index = class_def.get_class (c->glyphs[0]);
+    const RuleSet &rule_set = this+ruleSet[index];
+    struct ContextApplyLookupContext lookup_context = {
+      {match_class},
+      &class_def
+    };
+    return_trace (rule_set.would_apply (c, lookup_context));
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const ClassDef &class_def = this+classDef;
+    index = class_def.get_class (c->buffer->cur().codepoint);
+    const RuleSet &rule_set = this+ruleSet[index];
+    struct ContextApplyLookupContext lookup_context = {
+      {match_class},
+      &class_def
+    };
+    return_trace (rule_set.apply (c, lookup_context));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 2 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of table */
+  OffsetTo<ClassDef>
+                classDef;               /* Offset to glyph ClassDef table--from
+                                         * beginning of table */
+  OffsetArrayOf<RuleSet>
+                ruleSet;                /* Array of RuleSet tables
+                                         * ordered by class */
+  public:
+  DEFINE_SIZE_ARRAY (8, ruleSet);
+};
+
+
+struct ContextFormat3
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    if (!(this+coverageZ[0]).intersects (c->glyphs))
+      return;
+
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+    struct ContextClosureLookupContext lookup_context = {
+      {intersects_coverage},
+      this
+    };
+    context_closure_lookup (c,
+                            glyphCount, (const USHORT *) (coverageZ + 1),
+                            lookupCount, lookupRecord,
+                            lookup_context);
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverageZ[0]).add_coverage (c->input);
+
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+    struct ContextCollectGlyphsLookupContext lookup_context = {
+      {collect_coverage},
+      this
+    };
+
+    context_collect_glyphs_lookup (c,
+                                   glyphCount, (const USHORT *) (coverageZ + 1),
+                                   lookupCount, lookupRecord,
+                                   lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+    struct ContextApplyLookupContext lookup_context = {
+      {match_coverage},
+      this
+    };
+    return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverageZ[0];
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
+    struct ContextApplyLookupContext lookup_context = {
+      {match_coverage},
+      this
+    };
+    return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!c->check_struct (this)) return_trace (false);
+    unsigned int count = glyphCount;
+    if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */
+    if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false);
+    for (unsigned int i = 0; i < count; i++)
+      if (!coverageZ[i].sanitize (c, this)) return_trace (false);
+    const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count);
+    return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 3 */
+  USHORT        glyphCount;             /* Number of glyphs in the input glyph
+                                         * sequence */
+  USHORT        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
+                                         * design order */
+  public:
+  DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX);
+};
+
+struct Context
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    case 2: return_trace (c->dispatch (u.format2));
+    case 3: return_trace (c->dispatch (u.format3));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  ContextFormat1        format1;
+  ContextFormat2        format2;
+  ContextFormat3        format3;
+  } u;
+};
+
+
+/* Chaining Contextual lookups */
+
+struct ChainContextClosureLookupContext
+{
+  ContextClosureFuncs funcs;
+  const void *intersects_data[3];
+};
+
+struct ChainContextCollectGlyphsLookupContext
+{
+  ContextCollectGlyphsFuncs funcs;
+  const void *collect_data[3];
+};
+
+struct ChainContextApplyLookupContext
+{
+  ContextApplyFuncs funcs;
+  const void *match_data[3];
+};
+
+static inline void chain_context_closure_lookup (hb_closure_context_t *c,
+                                                 unsigned int backtrackCount,
+                                                 const USHORT backtrack[],
+                                                 unsigned int inputCount, /* Including the first glyph (not matched) */
+                                                 const USHORT input[], /* Array of input values--start with second glyph */
+                                                 unsigned int lookaheadCount,
+                                                 const USHORT lookahead[],
+                                                 unsigned int lookupCount,
+                                                 const LookupRecord lookupRecord[],
+                                                 ChainContextClosureLookupContext &lookup_context)
+{
+  if (intersects_array (c,
+                        backtrackCount, backtrack,
+                        lookup_context.funcs.intersects, lookup_context.intersects_data[0])
+   && intersects_array (c,
+                        inputCount ? inputCount - 1 : 0, input,
+                        lookup_context.funcs.intersects, lookup_context.intersects_data[1])
+   && intersects_array (c,
+                       lookaheadCount, lookahead,
+                       lookup_context.funcs.intersects, lookup_context.intersects_data[2]))
+    recurse_lookups (c,
+                     lookupCount, lookupRecord);
+}
+
+static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
+                                                        unsigned int backtrackCount,
+                                                        const USHORT backtrack[],
+                                                        unsigned int inputCount, /* Including the first glyph (not matched) */
+                                                        const USHORT input[], /* Array of input values--start with second glyph */
+                                                        unsigned int lookaheadCount,
+                                                        const USHORT lookahead[],
+                                                        unsigned int lookupCount,
+                                                        const LookupRecord lookupRecord[],
+                                                        ChainContextCollectGlyphsLookupContext &lookup_context)
+{
+  collect_array (c, c->before,
+                 backtrackCount, backtrack,
+                 lookup_context.funcs.collect, lookup_context.collect_data[0]);
+  collect_array (c, c->input,
+                 inputCount ? inputCount - 1 : 0, input,
+                 lookup_context.funcs.collect, lookup_context.collect_data[1]);
+  collect_array (c, c->after,
+                 lookaheadCount, lookahead,
+                 lookup_context.funcs.collect, lookup_context.collect_data[2]);
+  recurse_lookups (c,
+                   lookupCount, lookupRecord);
+}
+
+static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c,
+                                                     unsigned int backtrackCount,
+                                                     const USHORT backtrack[] HB_UNUSED,
+                                                     unsigned int inputCount, /* Including the first glyph (not matched) */
+                                                     const USHORT input[], /* Array of input values--start with second glyph */
+                                                     unsigned int lookaheadCount,
+                                                     const USHORT lookahead[] HB_UNUSED,
+                                                     unsigned int lookupCount HB_UNUSED,
+                                                     const LookupRecord lookupRecord[] HB_UNUSED,
+                                                     ChainContextApplyLookupContext &lookup_context)
+{
+  return (c->zero_context ? !backtrackCount && !lookaheadCount : true)
+      && would_match_input (c,
+                            inputCount, input,
+                            lookup_context.funcs.match, lookup_context.match_data[1]);
+}
+
+static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
+                                               unsigned int backtrackCount,
+                                               const USHORT backtrack[],
+                                               unsigned int inputCount, /* Including the first glyph (not matched) */
+                                               const USHORT input[], /* Array of input values--start with second glyph */
+                                               unsigned int lookaheadCount,
+                                               const USHORT lookahead[],
+                                               unsigned int lookupCount,
+                                               const LookupRecord lookupRecord[],
+                                               ChainContextApplyLookupContext &lookup_context)
+{
+  unsigned int match_length = 0;
+  unsigned int match_positions[MAX_CONTEXT_LENGTH];
+  return match_input (c,
+                      inputCount, input,
+                      lookup_context.funcs.match, lookup_context.match_data[1],
+                      &match_length, match_positions)
+      && match_backtrack (c,
+                          backtrackCount, backtrack,
+                          lookup_context.funcs.match, lookup_context.match_data[0])
+      && match_lookahead (c,
+                          lookaheadCount, lookahead,
+                          lookup_context.funcs.match, lookup_context.match_data[2],
+                          match_length)
+      && apply_lookup (c,
+                       inputCount, match_positions,
+                       lookupCount, lookupRecord,
+                       match_length);
+}
+
+struct ChainRule
+{
+  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 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    chain_context_closure_lookup (c,
+                                  backtrack.len, backtrack.array,
+                                  input.len, input.array,
+                                  lookahead.len, lookahead.array,
+                                  lookup.len, lookup.array,
+                                  lookup_context);
+  }
+
+  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 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    chain_context_collect_glyphs_lookup (c,
+                                         backtrack.len, backtrack.array,
+                                         input.len, input.array,
+                                         lookahead.len, lookahead.array,
+                                         lookup.len, lookup.array,
+                                         lookup_context);
+  }
+
+  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 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    return_trace (chain_context_would_apply_lookup (c,
+                                                    backtrack.len, backtrack.array,
+                                                    input.len, input.array,
+                                                    lookahead.len, lookahead.array, lookup.len,
+                                                    lookup.array, lookup_context));
+  }
+
+  inline bool apply (hb_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 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    return_trace (chain_context_apply_lookup (c,
+                                              backtrack.len, backtrack.array,
+                                              input.len, input.array,
+                                              lookahead.len, lookahead.array, lookup.len,
+                                              lookup.array, lookup_context));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!backtrack.sanitize (c)) return_trace (false);
+    const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+    if (!input.sanitize (c)) return_trace (false);
+    const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+    if (!lookahead.sanitize (c)) return_trace (false);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    return_trace (lookup.sanitize (c));
+  }
+
+  protected:
+  ArrayOf<USHORT>
+                backtrack;              /* Array of backtracking values
+                                         * (to be matched before the input
+                                         * sequence) */
+  HeadlessArrayOf<USHORT>
+                inputX;                 /* Array of input values (start with
+                                         * second glyph) */
+  ArrayOf<USHORT>
+                lookaheadX;             /* Array of lookahead values's (to be
+                                         * matched after the input sequence) */
+  ArrayOf<LookupRecord>
+                lookupX;                /* Array of LookupRecords--in
+                                         * design order) */
+  public:
+  DEFINE_SIZE_MIN (8);
+};
+
+struct ChainRuleSet
+{
+  inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+  {
+    TRACE_CLOSURE (this);
+    unsigned int num_rules = rule.len;
+    for (unsigned int i = 0; i < num_rules; i++)
+      (this+rule[i]).closure (c, lookup_context);
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    unsigned int num_rules = rule.len;
+    for (unsigned int i = 0; i < num_rules; i++)
+      (this+rule[i]).collect_glyphs (c, lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+  {
+    TRACE_WOULD_APPLY (this);
+    unsigned int num_rules = rule.len;
+    for (unsigned int i = 0; i < num_rules; i++)
+      if ((this+rule[i]).would_apply (c, lookup_context))
+        return_trace (true);
+
+    return_trace (false);
+  }
+
+  inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
+  {
+    TRACE_APPLY (this);
+    unsigned int num_rules = rule.len;
+    for (unsigned int i = 0; i < num_rules; i++)
+      if ((this+rule[i]).apply (c, lookup_context))
+        return_trace (true);
+
+    return_trace (false);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (rule.sanitize (c, this));
+  }
+
+  protected:
+  OffsetArrayOf<ChainRule>
+                rule;                   /* Array of ChainRule tables
+                                         * ordered by preference */
+  public:
+  DEFINE_SIZE_ARRAY (2, rule);
+};
+
+struct ChainContextFormat1
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    const Coverage &cov = (this+coverage);
+
+    struct ChainContextClosureLookupContext lookup_context = {
+      {intersects_glyph},
+      {NULL, NULL, NULL}
+    };
+
+    unsigned int count = ruleSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (cov.intersects_coverage (c->glyphs, i)) {
+        const ChainRuleSet &rule_set = this+ruleSet[i];
+        rule_set.closure (c, lookup_context);
+      }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+
+    struct ChainContextCollectGlyphsLookupContext lookup_context = {
+      {collect_glyph},
+      {NULL, NULL, NULL}
+    };
+
+    unsigned int count = ruleSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+
+    const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
+    struct ChainContextApplyLookupContext lookup_context = {
+      {match_glyph},
+      {NULL, NULL, NULL}
+    };
+    return_trace (rule_set.would_apply (c, lookup_context));
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const ChainRuleSet &rule_set = this+ruleSet[index];
+    struct ChainContextApplyLookupContext lookup_context = {
+      {match_glyph},
+      {NULL, NULL, NULL}
+    };
+    return_trace (rule_set.apply (c, lookup_context));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 1 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of table */
+  OffsetArrayOf<ChainRuleSet>
+                ruleSet;                /* Array of ChainRuleSet tables
+                                         * ordered by Coverage Index */
+  public:
+  DEFINE_SIZE_ARRAY (6, ruleSet);
+};
+
+struct ChainContextFormat2
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    if (!(this+coverage).intersects (c->glyphs))
+      return;
+
+    const ClassDef &backtrack_class_def = this+backtrackClassDef;
+    const ClassDef &input_class_def = this+inputClassDef;
+    const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+    struct ChainContextClosureLookupContext lookup_context = {
+      {intersects_class},
+      {&backtrack_class_def,
+       &input_class_def,
+       &lookahead_class_def}
+    };
+
+    unsigned int count = ruleSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      if (input_class_def.intersects_class (c->glyphs, i)) {
+        const ChainRuleSet &rule_set = this+ruleSet[i];
+        rule_set.closure (c, lookup_context);
+      }
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    (this+coverage).add_coverage (c->input);
+
+    const ClassDef &backtrack_class_def = this+backtrackClassDef;
+    const ClassDef &input_class_def = this+inputClassDef;
+    const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+    struct ChainContextCollectGlyphsLookupContext lookup_context = {
+      {collect_class},
+      {&backtrack_class_def,
+       &input_class_def,
+       &lookahead_class_def}
+    };
+
+    unsigned int count = ruleSet.len;
+    for (unsigned int i = 0; i < count; i++)
+      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+
+    const ClassDef &backtrack_class_def = this+backtrackClassDef;
+    const ClassDef &input_class_def = this+inputClassDef;
+    const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+    unsigned int index = input_class_def.get_class (c->glyphs[0]);
+    const ChainRuleSet &rule_set = this+ruleSet[index];
+    struct ChainContextApplyLookupContext lookup_context = {
+      {match_class},
+      {&backtrack_class_def,
+       &input_class_def,
+       &lookahead_class_def}
+    };
+    return_trace (rule_set.would_apply (c, lookup_context));
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    return this+coverage;
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const ClassDef &backtrack_class_def = this+backtrackClassDef;
+    const ClassDef &input_class_def = this+inputClassDef;
+    const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+    index = input_class_def.get_class (c->buffer->cur().codepoint);
+    const ChainRuleSet &rule_set = this+ruleSet[index];
+    struct ChainContextApplyLookupContext lookup_context = {
+      {match_class},
+      {&backtrack_class_def,
+       &input_class_def,
+       &lookahead_class_def}
+    };
+    return_trace (rule_set.apply (c, lookup_context));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) &&
+                  backtrackClassDef.sanitize (c, this) &&
+                  inputClassDef.sanitize (c, this) &&
+                  lookaheadClassDef.sanitize (c, this) &&
+                  ruleSet.sanitize (c, this));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 2 */
+  OffsetTo<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of table */
+  OffsetTo<ClassDef>
+                backtrackClassDef;      /* Offset to glyph ClassDef table
+                                         * containing backtrack sequence
+                                         * data--from beginning of table */
+  OffsetTo<ClassDef>
+                inputClassDef;          /* Offset to glyph ClassDef
+                                         * table containing input sequence
+                                         * data--from beginning of table */
+  OffsetTo<ClassDef>
+                lookaheadClassDef;      /* Offset to glyph ClassDef table
+                                         * containing lookahead sequence
+                                         * data--from beginning of table */
+  OffsetArrayOf<ChainRuleSet>
+                ruleSet;                /* Array of ChainRuleSet tables
+                                         * ordered by class */
+  public:
+  DEFINE_SIZE_ARRAY (12, ruleSet);
+};
+
+struct ChainContextFormat3
+{
+  inline void closure (hb_closure_context_t *c) const
+  {
+    TRACE_CLOSURE (this);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+    if (!(this+input[0]).intersects (c->glyphs))
+      return;
+
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    struct ChainContextClosureLookupContext lookup_context = {
+      {intersects_coverage},
+      {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,
+                                  lookup.len, lookup.array,
+                                  lookup_context);
+  }
+
+  inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    TRACE_COLLECT_GLYPHS (this);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+    (this+input[0]).add_coverage (c->input);
+
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    struct ChainContextCollectGlyphsLookupContext lookup_context = {
+      {collect_coverage},
+      {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,
+                                         lookup.len, lookup.array,
+                                         lookup_context);
+  }
+
+  inline bool would_apply (hb_would_apply_context_t *c) const
+  {
+    TRACE_WOULD_APPLY (this);
+
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    struct ChainContextApplyLookupContext lookup_context = {
+      {match_coverage},
+      {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,
+                                                    lookup.len, lookup.array, lookup_context));
+  }
+
+  inline const Coverage &get_coverage (void) const
+  {
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    return this+input[0];
+  }
+
+  inline bool apply (hb_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+    unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
+    if (likely (index == NOT_COVERED)) return_trace (false);
+
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    struct ChainContextApplyLookupContext lookup_context = {
+      {match_coverage},
+      {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,
+                                              lookup.len, lookup.array, lookup_context));
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!backtrack.sanitize (c, this)) return_trace (false);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    if (!input.sanitize (c, this)) return_trace (false);
+    if (!input.len) return_trace (false); /* To be consistent with Context. */
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    if (!lookahead.sanitize (c, this)) return_trace (false);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    return_trace (lookup.sanitize (c));
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier--format = 3 */
+  OffsetArrayOf<Coverage>
+                backtrack;              /* Array of coverage tables
+                                         * in backtracking sequence, in  glyph
+                                         * sequence order */
+  OffsetArrayOf<Coverage>
+                inputX          ;       /* Array of coverage
+                                         * tables in input sequence, in glyph
+                                         * sequence order */
+  OffsetArrayOf<Coverage>
+                lookaheadX;             /* Array of coverage tables
+                                         * in lookahead sequence, in glyph
+                                         * sequence order */
+  ArrayOf<LookupRecord>
+                lookupX;                /* Array of LookupRecords--in
+                                         * design order) */
+  public:
+  DEFINE_SIZE_MIN (10);
+};
+
+struct ChainContext
+{
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1));
+    case 2: return_trace (c->dispatch (u.format2));
+    case 3: return_trace (c->dispatch (u.format3));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format; /* Format identifier */
+  ChainContextFormat1   format1;
+  ChainContextFormat2   format2;
+  ChainContextFormat3   format3;
+  } u;
+};
+
+
+template <typename T>
+struct ExtensionFormat1
+{
+  inline unsigned int get_type (void) const { return extensionLookupType; }
+
+  template <typename X>
+  inline const X& get_subtable (void) const
+  {
+    unsigned int offset = extensionOffset;
+    if (unlikely (!offset)) return Null(typename T::LookupSubTable);
+    return StructAtOffset<typename T::LookupSubTable> (this, offset);
+  }
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, format);
+    if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ());
+    return_trace (get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()));
+  }
+
+  /* This is called from may_dispatch() above with hb_sanitize_context_t. */
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && extensionOffset != 0);
+  }
+
+  protected:
+  USHORT        format;                 /* Format identifier. Set to 1. */
+  USHORT        extensionLookupType;    /* Lookup type of subtable referenced
+                                         * by ExtensionOffset (i.e. the
+                                         * extension subtable). */
+  ULONG         extensionOffset;        /* Offset to the extension subtable,
+                                         * of lookup type subtable. */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+template <typename T>
+struct Extension
+{
+  inline unsigned int get_type (void) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_type ();
+    default:return 0;
+    }
+  }
+  template <typename X>
+  inline const X& get_subtable (void) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.template get_subtable<typename T::LookupSubTable> ();
+    default:return Null(typename T::LookupSubTable);
+    }
+  }
+
+  template <typename context_t>
+  inline typename context_t::return_t dispatch (context_t *c) const
+  {
+    TRACE_DISPATCH (this, u.format);
+    if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
+    switch (u.format) {
+    case 1: return_trace (u.format1.dispatch (c));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  USHORT                format;         /* Format identifier */
+  ExtensionFormat1<T>   format1;
+  } u;
+};
+
+
+/*
+ * GSUB/GPOS Common
+ */
+
+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
+  { return (this+scriptList).get_tag (i); }
+  inline unsigned int get_script_tags (unsigned int start_offset,
+                                       unsigned int *script_count /* IN/OUT */,
+                                       hb_tag_t     *script_tags /* OUT */) const
+  { return (this+scriptList).get_tags (start_offset, script_count, script_tags); }
+  inline const Script& get_script (unsigned int i) const
+  { return (this+scriptList)[i]; }
+  inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
+  { return (this+scriptList).find_index (tag, index); }
+
+  inline unsigned int get_feature_count (void) const
+  { return (this+featureList).len; }
+  inline hb_tag_t get_feature_tag (unsigned int i) const
+  { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); }
+  inline unsigned int get_feature_tags (unsigned int start_offset,
+                                        unsigned int *feature_count /* IN/OUT */,
+                                        hb_tag_t     *feature_tags /* OUT */) const
+  { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); }
+  inline const Feature& get_feature (unsigned int i) const
+  { return (this+featureList)[i]; }
+  inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const
+  { return (this+featureList).find_index (tag, index); }
+
+  inline unsigned int get_lookup_count (void) const
+  { return (this+lookupList).len; }
+  inline const Lookup& get_lookup (unsigned int i) const
+  { return (this+lookupList)[i]; }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (version.sanitize (c) &&
+                  likely (version.major == 1) &&
+                  scriptList.sanitize (c, this) &&
+                  featureList.sanitize (c, this) &&
+                  lookupList.sanitize (c, this));
+  }
+
+  protected:
+  FixedVersion  version;        /* Version of the GSUB/GPOS table--initially set
+                                 * to 0x00010000u */
+  OffsetTo<ScriptList>
+                scriptList;     /* ScriptList table */
+  OffsetTo<FeatureList>
+                featureList;    /* FeatureList table */
+  OffsetTo<LookupList>
+                lookupList;     /* LookupList table */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-jstf-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,234 @@
+/*
+ * Copyright © 2013  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_JSTF_TABLE_HH
+#define HB_OT_LAYOUT_JSTF_TABLE_HH
+
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-gpos-table.hh"
+
+
+namespace OT {
+
+
+/*
+ * JstfModList -- Justification Modification List Tables
+ */
+
+typedef IndexArray JstfModList;
+
+
+/*
+ * JstfMax -- Justification Maximum Table
+ */
+
+typedef OffsetListOf<PosLookup> JstfMax;
+
+
+/*
+ * JstfPriority -- Justification Priority Table
+ */
+
+struct JstfPriority
+{
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  shrinkageEnableGSUB.sanitize (c, this) &&
+                  shrinkageDisableGSUB.sanitize (c, this) &&
+                  shrinkageEnableGPOS.sanitize (c, this) &&
+                  shrinkageDisableGPOS.sanitize (c, this) &&
+                  shrinkageJstfMax.sanitize (c, this) &&
+                  extensionEnableGSUB.sanitize (c, this) &&
+                  extensionDisableGSUB.sanitize (c, this) &&
+                  extensionEnableGPOS.sanitize (c, this) &&
+                  extensionDisableGPOS.sanitize (c, this) &&
+                  extensionJstfMax.sanitize (c, this));
+  }
+
+  protected:
+  OffsetTo<JstfModList>
+                shrinkageEnableGSUB;    /* Offset to Shrinkage Enable GSUB
+                                         * JstfModList table--from beginning of
+                                         * JstfPriority table--may be NULL */
+  OffsetTo<JstfModList>
+                shrinkageDisableGSUB;   /* Offset to Shrinkage Disable GSUB
+                                         * JstfModList table--from beginning of
+                                         * JstfPriority table--may be NULL */
+  OffsetTo<JstfModList>
+                shrinkageEnableGPOS;    /* Offset to Shrinkage Enable GPOS
+                                         * JstfModList table--from beginning of
+                                         * JstfPriority table--may be NULL */
+  OffsetTo<JstfModList>
+                shrinkageDisableGPOS;   /* Offset to Shrinkage Disable GPOS
+                                         * JstfModList table--from beginning of
+                                         * JstfPriority table--may be NULL */
+  OffsetTo<JstfMax>
+                shrinkageJstfMax;       /* Offset to Shrinkage JstfMax table--
+                                         * from beginning of JstfPriority table
+                                         * --may be NULL */
+  OffsetTo<JstfModList>
+                extensionEnableGSUB;    /* Offset to Extension Enable GSUB
+                                         * JstfModList table--from beginning of
+                                         * JstfPriority table--may be NULL */
+  OffsetTo<JstfModList>
+                extensionDisableGSUB;   /* Offset to Extension Disable GSUB
+                                         * JstfModList table--from beginning of
+                                         * JstfPriority table--may be NULL */
+  OffsetTo<JstfModList>
+                extensionEnableGPOS;    /* Offset to Extension Enable GPOS
+                                         * JstfModList table--from beginning of
+                                         * JstfPriority table--may be NULL */
+  OffsetTo<JstfModList>
+                extensionDisableGPOS;   /* Offset to Extension Disable GPOS
+                                         * JstfModList table--from beginning of
+                                         * JstfPriority table--may be NULL */
+  OffsetTo<JstfMax>
+                extensionJstfMax;       /* Offset to Extension JstfMax table--
+                                         * from beginning of JstfPriority table
+                                         * --may be NULL */
+
+  public:
+  DEFINE_SIZE_STATIC (20);
+};
+
+
+/*
+ * JstfLangSys -- Justification Language System Table
+ */
+
+struct JstfLangSys : OffsetListOf<JstfPriority>
+{
+  inline bool sanitize (hb_sanitize_context_t *c,
+                        const Record<JstfLangSys>::sanitize_closure_t * = NULL) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (OffsetListOf<JstfPriority>::sanitize (c));
+  }
+};
+
+
+/*
+ * ExtenderGlyphs -- Extender Glyph Table
+ */
+
+typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
+
+
+/*
+ * JstfScript -- The Justification Table
+ */
+
+struct JstfScript
+{
+  inline unsigned int get_lang_sys_count (void) const
+  { return langSys.len; }
+  inline const Tag& get_lang_sys_tag (unsigned int i) const
+  { return langSys.get_tag (i); }
+  inline unsigned int get_lang_sys_tags (unsigned int start_offset,
+                                         unsigned int *lang_sys_count /* IN/OUT */,
+                                         hb_tag_t     *lang_sys_tags /* OUT */) const
+  { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
+  inline const JstfLangSys& get_lang_sys (unsigned int i) const
+  {
+    if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
+    return this+langSys[i].offset;
+  }
+  inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
+  { return langSys.find_index (tag, index); }
+
+  inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
+  inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
+
+  inline bool sanitize (hb_sanitize_context_t *c,
+                        const Record<JstfScript>::sanitize_closure_t * = NULL) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (extenderGlyphs.sanitize (c, this) &&
+                  defaultLangSys.sanitize (c, this) &&
+                  langSys.sanitize (c, this));
+  }
+
+  protected:
+  OffsetTo<ExtenderGlyphs>
+                extenderGlyphs; /* Offset to ExtenderGlyph table--from beginning
+                                 * of JstfScript table-may be NULL */
+  OffsetTo<JstfLangSys>
+                defaultLangSys; /* Offset to DefaultJstfLangSys table--from
+                                 * beginning of JstfScript table--may be Null */
+  RecordArrayOf<JstfLangSys>
+                langSys;        /* Array of JstfLangSysRecords--listed
+                                 * alphabetically by LangSysTag */
+  public:
+  DEFINE_SIZE_ARRAY (6, langSys);
+};
+
+
+/*
+ * JSTF -- The Justification Table
+ */
+
+struct JSTF
+{
+  static const hb_tag_t tableTag        = HB_OT_TAG_JSTF;
+
+  inline unsigned int get_script_count (void) const
+  { return scriptList.len; }
+  inline const Tag& get_script_tag (unsigned int i) const
+  { return scriptList.get_tag (i); }
+  inline unsigned int get_script_tags (unsigned int start_offset,
+                                       unsigned int *script_count /* IN/OUT */,
+                                       hb_tag_t     *script_tags /* OUT */) const
+  { return scriptList.get_tags (start_offset, script_count, script_tags); }
+  inline const JstfScript& get_script (unsigned int i) const
+  { return this+scriptList[i].offset; }
+  inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
+  { return scriptList.find_index (tag, index); }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (version.sanitize (c) &&
+                  likely (version.major == 1) &&
+                  scriptList.sanitize (c, this));
+  }
+
+  protected:
+  FixedVersion  version;        /* Version of the JSTF table--initially set
+                                 * to 0x00010000u */
+  RecordArrayOf<JstfScript>
+                scriptList;     /* Array of JstfScripts--listed
+                                 * alphabetically by ScriptTag */
+  public:
+  DEFINE_SIZE_ARRAY (6, scriptList);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_JSTF_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,507 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2012,2013  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_PRIVATE_HH
+#define HB_OT_LAYOUT_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
+#include "hb-set-private.hh"
+
+
+/* Private API corresponding to hb-ot-layout.h: */
+
+HB_INTERNAL hb_bool_t
+hb_ot_layout_table_find_feature (hb_face_t    *face,
+                                 hb_tag_t      table_tag,
+                                 hb_tag_t      feature_tag,
+                                 unsigned int *feature_index);
+
+
+/*
+ * GDEF
+ */
+
+typedef enum
+{
+  /* The following three match LookupFlags::Ignore* numbers. */
+  HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH   = 0x02u,
+  HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE     = 0x04u,
+  HB_OT_LAYOUT_GLYPH_PROPS_MARK         = 0x08u,
+
+  /* The following are used internally; not derived from GDEF. */
+  HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED  = 0x10u,
+  HB_OT_LAYOUT_GLYPH_PROPS_LIGATED      = 0x20u,
+  HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED   = 0x40u,
+
+  HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE     = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
+                                          HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
+                                          HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED
+} hb_ot_layout_glyph_class_mask_t;
+
+
+/*
+ * GSUB/GPOS
+ */
+
+HB_INTERNAL hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t            *face,
+                                           unsigned int          lookup_index,
+                                           const hb_codepoint_t *glyphs,
+                                           unsigned int          glyphs_length,
+                                           hb_bool_t             zero_context);
+
+
+/* Should be called before all the substitute_lookup's are done. */
+HB_INTERNAL void
+hb_ot_layout_substitute_start (hb_font_t    *font,
+                               hb_buffer_t  *buffer);
+
+
+struct hb_ot_layout_lookup_accelerator_t;
+
+namespace OT {
+  struct hb_apply_context_t;
+  struct SubstLookup;
+}
+
+HB_INTERNAL void
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+                                const OT::SubstLookup &lookup,
+                                const hb_ot_layout_lookup_accelerator_t &accel);
+
+
+/* Should be called after all the substitute_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_substitute_finish (hb_font_t    *font,
+                                hb_buffer_t  *buffer);
+
+
+/* Should be called before all the position_lookup's are done.  Resets positions to zero. */
+HB_INTERNAL void
+hb_ot_layout_position_start (hb_font_t    *font,
+                             hb_buffer_t  *buffer);
+
+/* Should be called after all the position_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_position_finish (hb_font_t    *font,
+                              hb_buffer_t  *buffer);
+
+
+
+/*
+ * hb_ot_layout_t
+ */
+
+namespace OT {
+  struct GDEF;
+  struct GSUB;
+  struct GPOS;
+}
+
+struct hb_ot_layout_lookup_accelerator_t
+{
+  template <typename TLookup>
+  inline void init (const TLookup &lookup)
+  {
+    digest.init ();
+    lookup.add_coverage (&digest);
+  }
+
+  inline void fini (void)
+  {
+  }
+
+  inline bool may_have (hb_codepoint_t g) const {
+    return digest.may_have (g);
+  }
+
+  private:
+  hb_set_digest_t digest;
+};
+
+struct hb_ot_layout_t
+{
+  hb_blob_t *gdef_blob;
+  hb_blob_t *gsub_blob;
+  hb_blob_t *gpos_blob;
+
+  const struct OT::GDEF *gdef;
+  const struct OT::GSUB *gsub;
+  const struct OT::GPOS *gpos;
+
+  unsigned int gsub_lookup_count;
+  unsigned int gpos_lookup_count;
+
+  hb_ot_layout_lookup_accelerator_t *gsub_accels;
+  hb_ot_layout_lookup_accelerator_t *gpos_accels;
+};
+
+
+HB_INTERNAL hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face);
+
+HB_INTERNAL void
+_hb_ot_layout_destroy (hb_ot_layout_t *layout);
+
+
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
+
+
+/*
+ * Buffer var routines.
+ */
+
+/* buffer var allocations, used during the entire shaping process */
+#define unicode_props0()        var2.u8[0]
+#define unicode_props1()        var2.u8[1]
+
+/* buffer var allocations, used during the GSUB/GPOS processing */
+#define glyph_props()           var1.u16[0] /* GDEF glyph properties */
+#define lig_props()             var1.u8[2] /* GSUB/GPOS ligature tracking */
+#define syllable()              var1.u8[3] /* GSUB/GPOS shaping boundaries */
+
+
+/* loop over syllables */
+
+#define foreach_syllable(buffer, start, end) \
+  for (unsigned int \
+       _count = buffer->len, \
+       start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \
+       start < _count; \
+       start = end, end = _next_syllable (buffer, start))
+
+static inline unsigned int
+_next_syllable (hb_buffer_t *buffer, unsigned int start)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+
+  unsigned int syllable = info[start].syllable();
+  while (++start < count && syllable == info[start].syllable())
+    ;
+
+  return start;
+}
+
+
+/* unicode_props */
+
+enum {
+  MASK0_ZWJ       = 0x20u,
+  MASK0_ZWNJ      = 0x40u,
+  MASK0_IGNORABLE = 0x80u,
+  MASK0_GEN_CAT   = 0x1Fu
+};
+
+static inline void
+_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
+{
+  /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */
+  info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
+                           (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
+                           (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) |
+                           (info->codepoint == 0x200Du ? MASK0_ZWJ : 0);
+  info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
+}
+
+static inline void
+_hb_glyph_info_set_general_category (hb_glyph_info_t *info,
+                                     hb_unicode_general_category_t gen_cat)
+{
+  info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
+}
+
+static inline hb_unicode_general_category_t
+_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
+{
+  return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT);
+}
+
+static inline void
+_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
+                                             unsigned int modified_class)
+{
+  info->unicode_props1() = modified_class;
+}
+
+static inline unsigned int
+_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
+{
+  return info->unicode_props1();
+}
+
+static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info);
+
+static inline hb_bool_t
+_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
+{
+  return (info->unicode_props0() & MASK0_IGNORABLE) && !_hb_glyph_info_ligated (info);
+}
+
+static inline hb_bool_t
+_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
+{
+  return !!(info->unicode_props0() & MASK0_ZWNJ);
+}
+
+static inline hb_bool_t
+_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
+{
+  return !!(info->unicode_props0() & MASK0_ZWJ);
+}
+
+static inline void
+_hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
+{
+  info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
+}
+
+/* lig_props: aka lig_id / lig_comp
+ *
+ * When a ligature is formed:
+ *
+ *   - The ligature glyph and any marks in between all the same newly allocated
+ *     lig_id,
+ *   - The ligature glyph will get lig_num_comps set to the number of components
+ *   - The marks get lig_comp > 0, reflecting which component of the ligature
+ *     they were applied to.
+ *   - This is used in GPOS to attach marks to the right component of a ligature
+ *     in MarkLigPos,
+ *   - Note that when marks are ligated together, much of the above is skipped
+ *     and the current lig_id reused.
+ *
+ * When a multiple-substitution is done:
+ *
+ *   - All resulting glyphs will have lig_id = 0,
+ *   - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
+ *   - This is used in GPOS to attach marks to the first component of a
+ *     multiple substitution in MarkBasePos.
+ *
+ * The numbers are also used in GPOS to do mark-to-mark positioning only
+ * to marks that belong to the same component of the same ligature.
+ */
+
+static inline void
+_hb_glyph_info_clear_lig_props (hb_glyph_info_t *info)
+{
+  info->lig_props() = 0;
+}
+
+#define IS_LIG_BASE 0x10
+
+static inline void
+_hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info,
+                                           unsigned int lig_id,
+                                           unsigned int lig_num_comps)
+{
+  info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
+}
+
+static inline void
+_hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
+                                       unsigned int lig_id,
+                                       unsigned int lig_comp)
+{
+  info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
+}
+
+static inline void
+_hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
+{
+  _hb_glyph_info_set_lig_props_for_mark (info, 0, comp);
+}
+
+static inline unsigned int
+_hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
+{
+  return info->lig_props() >> 5;
+}
+
+static inline bool
+_hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
+{
+  return !!(info->lig_props() & IS_LIG_BASE);
+}
+
+static inline unsigned int
+_hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
+{
+  if (_hb_glyph_info_ligated_internal (info))
+    return 0;
+  else
+    return info->lig_props() & 0x0F;
+}
+
+static inline unsigned int
+_hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
+{
+  if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) &&
+      _hb_glyph_info_ligated_internal (info))
+    return info->lig_props() & 0x0F;
+  else
+    return 1;
+}
+
+static inline uint8_t
+_hb_allocate_lig_id (hb_buffer_t *buffer) {
+  uint8_t lig_id = buffer->next_serial () & 0x07;
+  if (unlikely (!lig_id))
+    lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
+  return lig_id;
+}
+
+/* glyph_props: */
+
+static inline void
+_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
+{
+  info->glyph_props() = props;
+}
+
+static inline unsigned int
+_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
+{
+  return info->glyph_props();
+}
+
+static inline bool
+_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
+}
+
+static inline bool
+_hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
+}
+
+static inline bool
+_hb_glyph_info_is_mark (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+}
+
+static inline bool
+_hb_glyph_info_substituted (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
+}
+
+static inline bool
+_hb_glyph_info_ligated (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
+}
+
+static inline bool
+_hb_glyph_info_multiplied (const hb_glyph_info_t *info)
+{
+  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
+}
+
+static inline bool
+_hb_glyph_info_ligated_and_didnt_multiply (const hb_glyph_info_t *info)
+{
+  return _hb_glyph_info_ligated (info) && !_hb_glyph_info_multiplied (info);
+}
+
+static inline void
+_hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info)
+{
+  info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
+                           HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
+}
+
+static inline void
+_hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *info)
+{
+  info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
+                           HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
+                           HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
+}
+
+
+/* Allocation / deallocation. */
+
+static inline void
+_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
+  HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
+}
+
+static inline void
+_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
+}
+
+static inline void
+_hb_buffer_assert_unicode_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_ASSERT_VAR (buffer, unicode_props0);
+  HB_BUFFER_ASSERT_VAR (buffer, unicode_props1);
+}
+
+static inline void
+_hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
+  HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
+  HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+}
+
+static inline void
+_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
+}
+
+static inline void
+_hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
+{
+  HB_BUFFER_ASSERT_VAR (buffer, glyph_props);
+  HB_BUFFER_ASSERT_VAR (buffer, lig_props);
+  HB_BUFFER_ASSERT_VAR (buffer, syllable);
+}
+
+/* Make sure no one directly touches our props... */
+#undef unicode_props0
+#undef unicode_props1
+#undef lig_props
+#undef glyph_props
+
+
+#endif /* HB_OT_LAYOUT_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1058 @@
+/*
+ * Copyright © 1998-2004  David Turner and Werner Lemberg
+ * Copyright © 2006  Behdad Esfahbod
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2012,2013  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-private.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"
+
+#include "hb-ot-map-private.hh"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
+
+hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face)
+{
+  hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
+  if (unlikely (!layout))
+    return NULL;
+
+  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 = 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 = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
+
+  layout->gsub_lookup_count = layout->gsub->get_lookup_count ();
+  layout->gpos_lookup_count = layout->gpos->get_lookup_count ();
+
+  layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t));
+  layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t));
+
+  if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) ||
+                (layout->gpos_lookup_count && !layout->gpos_accels)))
+  {
+    _hb_ot_layout_destroy (layout);
+    return NULL;
+  }
+
+  for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
+    layout->gsub_accels[i].init (layout->gsub->get_lookup (i));
+  for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
+    layout->gpos_accels[i].init (layout->gpos->get_lookup (i));
+
+  return layout;
+}
+
+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 ();
+
+  free (layout->gsub_accels);
+  free (layout->gpos_accels);
+
+  hb_blob_destroy (layout->gdef_blob);
+  hb_blob_destroy (layout->gsub_blob);
+  hb_blob_destroy (layout->gpos_blob);
+
+  free (layout);
+}
+
+static inline const OT::GDEF&
+_get_gdef (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GDEF);
+  return *hb_ot_layout_from_face (face)->gdef;
+}
+static inline const OT::GSUB&
+_get_gsub (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GSUB);
+  return *hb_ot_layout_from_face (face)->gsub;
+}
+static inline const OT::GPOS&
+_get_gpos (hb_face_t *face)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::GPOS);
+  return *hb_ot_layout_from_face (face)->gpos;
+}
+
+
+/*
+ * GDEF
+ */
+
+hb_bool_t
+hb_ot_layout_has_glyph_classes (hb_face_t *face)
+{
+  return _get_gdef (face).has_glyph_classes ();
+}
+
+/**
+ * Since: 0.9.7
+ **/
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class (hb_face_t      *face,
+                              hb_codepoint_t  glyph)
+{
+  return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph);
+}
+
+/**
+ * Since: 0.9.7
+ **/
+void
+hb_ot_layout_get_glyphs_in_class (hb_face_t                  *face,
+                                  hb_ot_layout_glyph_class_t  klass,
+                                  hb_set_t                   *glyphs /* OUT */)
+{
+  return _get_gdef (face).get_glyphs_in_class (klass, glyphs);
+}
+
+unsigned int
+hb_ot_layout_get_attach_points (hb_face_t      *face,
+                                hb_codepoint_t  glyph,
+                                unsigned int    start_offset,
+                                unsigned int   *point_count /* IN/OUT */,
+                                unsigned int   *point_array /* OUT */)
+{
+  return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array);
+}
+
+unsigned int
+hb_ot_layout_get_ligature_carets (hb_font_t      *font,
+                                  hb_direction_t  direction,
+                                  hb_codepoint_t  glyph,
+                                  unsigned int    start_offset,
+                                  unsigned int   *caret_count /* IN/OUT */,
+                                  int            *caret_array /* OUT */)
+{
+  return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
+}
+
+
+/*
+ * GSUB/GPOS
+ */
+
+static const OT::GSUBGPOS&
+get_gsubgpos_table (hb_face_t *face,
+                    hb_tag_t   table_tag)
+{
+  switch (table_tag) {
+    case HB_OT_TAG_GSUB: return _get_gsub (face);
+    case HB_OT_TAG_GPOS: return _get_gpos (face);
+    default:             return OT::Null(OT::GSUBGPOS);
+  }
+}
+
+
+unsigned int
+hb_ot_layout_table_get_script_tags (hb_face_t    *face,
+                                    hb_tag_t      table_tag,
+                                    unsigned int  start_offset,
+                                    unsigned int *script_count /* IN/OUT */,
+                                    hb_tag_t     *script_tags /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+  return g.get_script_tags (start_offset, script_count, script_tags);
+}
+
+#define HB_OT_TAG_LATIN_SCRIPT          HB_TAG ('l', 'a', 't', 'n')
+
+hb_bool_t
+hb_ot_layout_table_find_script (hb_face_t    *face,
+                                hb_tag_t      table_tag,
+                                hb_tag_t      script_tag,
+                                unsigned int *script_index)
+{
+  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+  if (g.find_script_index (script_tag, script_index))
+    return true;
+
+  /* try finding 'DFLT' */
+  if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index))
+    return false;
+
+  /* try with 'dflt'; MS site has had typos and many fonts use it now :(.
+   * including many versions of DejaVu Sans Mono! */
+  if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index))
+    return false;
+
+  /* try with 'latn'; some old fonts put their features there even though
+     they're really trying to support Thai, for example :( */
+  if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index))
+    return false;
+
+  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+  return false;
+}
+
+hb_bool_t
+hb_ot_layout_table_choose_script (hb_face_t      *face,
+                                  hb_tag_t        table_tag,
+                                  const hb_tag_t *script_tags,
+                                  unsigned int   *script_index,
+                                  hb_tag_t       *chosen_script)
+{
+  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+  while (*script_tags)
+  {
+    if (g.find_script_index (*script_tags, script_index)) {
+      if (chosen_script)
+        *chosen_script = *script_tags;
+      return true;
+    }
+    script_tags++;
+  }
+
+  /* try finding 'DFLT' */
+  if (g.find_script_index (HB_OT_TAG_DEFAULT_SCRIPT, script_index)) {
+    if (chosen_script)
+      *chosen_script = HB_OT_TAG_DEFAULT_SCRIPT;
+    return false;
+  }
+
+  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
+  if (g.find_script_index (HB_OT_TAG_DEFAULT_LANGUAGE, script_index)) {
+    if (chosen_script)
+      *chosen_script = HB_OT_TAG_DEFAULT_LANGUAGE;
+    return false;
+  }
+
+  /* try with 'latn'; some old fonts put their features there even though
+     they're really trying to support Thai, for example :( */
+  if (g.find_script_index (HB_OT_TAG_LATIN_SCRIPT, script_index)) {
+    if (chosen_script)
+      *chosen_script = HB_OT_TAG_LATIN_SCRIPT;
+    return false;
+  }
+
+  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+  if (chosen_script)
+    *chosen_script = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+  return false;
+}
+
+unsigned int
+hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
+                                     hb_tag_t      table_tag,
+                                     unsigned int  start_offset,
+                                     unsigned int *feature_count /* IN/OUT */,
+                                     hb_tag_t     *feature_tags /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+  return g.get_feature_tags (start_offset, feature_count, feature_tags);
+}
+
+hb_bool_t
+hb_ot_layout_table_find_feature (hb_face_t    *face,
+                                 hb_tag_t      table_tag,
+                                 hb_tag_t      feature_tag,
+                                 unsigned int *feature_index)
+{
+  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+
+  unsigned int num_features = g.get_feature_count ();
+  for (unsigned int i = 0; i < num_features; i++)
+  {
+    if (feature_tag == g.get_feature_tag (i)) {
+      if (feature_index) *feature_index = i;
+      return true;
+    }
+  }
+
+  if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
+  return false;
+}
+
+
+unsigned int
+hb_ot_layout_script_get_language_tags (hb_face_t    *face,
+                                       hb_tag_t      table_tag,
+                                       unsigned int  script_index,
+                                       unsigned int  start_offset,
+                                       unsigned int *language_count /* IN/OUT */,
+                                       hb_tag_t     *language_tags /* OUT */)
+{
+  const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
+
+  return s.get_lang_sys_tags (start_offset, language_count, language_tags);
+}
+
+hb_bool_t
+hb_ot_layout_script_find_language (hb_face_t    *face,
+                                   hb_tag_t      table_tag,
+                                   unsigned int  script_index,
+                                   hb_tag_t      language_tag,
+                                   unsigned int *language_index)
+{
+  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
+  const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
+
+  if (s.find_lang_sys_index (language_tag, language_index))
+    return true;
+
+  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
+  if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
+    return false;
+
+  if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
+  return false;
+}
+
+hb_bool_t
+hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
+                                                  hb_tag_t      table_tag,
+                                                  unsigned int  script_index,
+                                                  unsigned int  language_index,
+                                                  unsigned int *feature_index)
+{
+  return hb_ot_layout_language_get_required_feature (face,
+                                                     table_tag,
+                                                     script_index,
+                                                     language_index,
+                                                     feature_index,
+                                                     NULL);
+}
+
+/**
+ * Since: 0.9.30
+ **/
+hb_bool_t
+hb_ot_layout_language_get_required_feature (hb_face_t    *face,
+                                            hb_tag_t      table_tag,
+                                            unsigned int  script_index,
+                                            unsigned int  language_index,
+                                            unsigned int *feature_index,
+                                            hb_tag_t     *feature_tag)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+  unsigned int index = l.get_required_feature_index ();
+  if (feature_index) *feature_index = index;
+  if (feature_tag) *feature_tag = g.get_feature_tag (index);
+
+  return l.has_required_feature ();
+}
+
+unsigned int
+hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
+                                           hb_tag_t      table_tag,
+                                           unsigned int  script_index,
+                                           unsigned int  language_index,
+                                           unsigned int  start_offset,
+                                           unsigned int *feature_count /* IN/OUT */,
+                                           unsigned int *feature_indexes /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+  return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
+}
+
+unsigned int
+hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
+                                        hb_tag_t      table_tag,
+                                        unsigned int  script_index,
+                                        unsigned int  language_index,
+                                        unsigned int  start_offset,
+                                        unsigned int *feature_count /* IN/OUT */,
+                                        hb_tag_t     *feature_tags /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+  ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
+  unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);
+
+  if (feature_tags) {
+    unsigned int count = *feature_count;
+    for (unsigned int i = 0; i < count; i++)
+      feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]);
+  }
+
+  return ret;
+}
+
+
+hb_bool_t
+hb_ot_layout_language_find_feature (hb_face_t    *face,
+                                    hb_tag_t      table_tag,
+                                    unsigned int  script_index,
+                                    unsigned int  language_index,
+                                    hb_tag_t      feature_tag,
+                                    unsigned int *feature_index)
+{
+  ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+  unsigned int num_features = l.get_feature_count ();
+  for (unsigned int i = 0; i < num_features; i++) {
+    unsigned int f_index = l.get_feature_index (i);
+
+    if (feature_tag == g.get_feature_tag (f_index)) {
+      if (feature_index) *feature_index = f_index;
+      return true;
+    }
+  }
+
+  if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
+  return false;
+}
+
+/**
+ * Since: 0.9.7
+ **/
+unsigned int
+hb_ot_layout_feature_get_lookups (hb_face_t    *face,
+                                  hb_tag_t      table_tag,
+                                  unsigned int  feature_index,
+                                  unsigned int  start_offset,
+                                  unsigned int *lookup_count /* IN/OUT */,
+                                  unsigned int *lookup_indexes /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  const OT::Feature &f = g.get_feature (feature_index);
+
+  return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
+}
+
+/**
+ * Since: 0.9.22
+ **/
+unsigned int
+hb_ot_layout_table_get_lookup_count (hb_face_t    *face,
+                                     hb_tag_t      table_tag)
+{
+  switch (table_tag)
+  {
+    case HB_OT_TAG_GSUB:
+    {
+      return hb_ot_layout_from_face (face)->gsub_lookup_count;
+    }
+    case HB_OT_TAG_GPOS:
+    {
+      return hb_ot_layout_from_face (face)->gpos_lookup_count;
+    }
+  }
+  return 0;
+}
+
+static void
+_hb_ot_layout_collect_lookups_lookups (hb_face_t      *face,
+                                       hb_tag_t        table_tag,
+                                       unsigned int    feature_index,
+                                       hb_set_t       *lookup_indexes /* OUT */)
+{
+  unsigned int lookup_indices[32];
+  unsigned int offset, len;
+
+  offset = 0;
+  do {
+    len = ARRAY_LENGTH (lookup_indices);
+    hb_ot_layout_feature_get_lookups (face,
+                                      table_tag,
+                                      feature_index,
+                                      offset, &len,
+                                      lookup_indices);
+
+    for (unsigned int i = 0; i < len; i++)
+      lookup_indexes->add (lookup_indices[i]);
+
+    offset += len;
+  } while (len == ARRAY_LENGTH (lookup_indices));
+}
+
+static void
+_hb_ot_layout_collect_lookups_features (hb_face_t      *face,
+                                        hb_tag_t        table_tag,
+                                        unsigned int    script_index,
+                                        unsigned int    language_index,
+                                        const hb_tag_t *features,
+                                        hb_set_t       *lookup_indexes /* OUT */)
+{
+  if (!features)
+  {
+    unsigned int required_feature_index;
+    if (hb_ot_layout_language_get_required_feature (face,
+                                                    table_tag,
+                                                    script_index,
+                                                    language_index,
+                                                    &required_feature_index,
+                                                    NULL))
+      _hb_ot_layout_collect_lookups_lookups (face,
+                                             table_tag,
+                                             required_feature_index,
+                                             lookup_indexes);
+
+    /* All features */
+    unsigned int feature_indices[32];
+    unsigned int offset, len;
+
+    offset = 0;
+    do {
+      len = ARRAY_LENGTH (feature_indices);
+      hb_ot_layout_language_get_feature_indexes (face,
+                                                 table_tag,
+                                                 script_index,
+                                                 language_index,
+                                                 offset, &len,
+                                                 feature_indices);
+
+      for (unsigned int i = 0; i < len; i++)
+        _hb_ot_layout_collect_lookups_lookups (face,
+                                               table_tag,
+                                               feature_indices[i],
+                                               lookup_indexes);
+
+      offset += len;
+    } while (len == ARRAY_LENGTH (feature_indices));
+  }
+  else
+  {
+    for (; *features; features++)
+    {
+      unsigned int feature_index;
+      if (hb_ot_layout_language_find_feature (face,
+                                              table_tag,
+                                              script_index,
+                                              language_index,
+                                              *features,
+                                              &feature_index))
+        _hb_ot_layout_collect_lookups_lookups (face,
+                                               table_tag,
+                                               feature_index,
+                                               lookup_indexes);
+    }
+  }
+}
+
+static void
+_hb_ot_layout_collect_lookups_languages (hb_face_t      *face,
+                                         hb_tag_t        table_tag,
+                                         unsigned int    script_index,
+                                         const hb_tag_t *languages,
+                                         const hb_tag_t *features,
+                                         hb_set_t       *lookup_indexes /* OUT */)
+{
+  _hb_ot_layout_collect_lookups_features (face,
+                                          table_tag,
+                                          script_index,
+                                          HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
+                                          features,
+                                          lookup_indexes);
+
+  if (!languages)
+  {
+    /* All languages */
+    unsigned int count = hb_ot_layout_script_get_language_tags (face,
+                                                                table_tag,
+                                                                script_index,
+                                                                0, NULL, NULL);
+    for (unsigned int language_index = 0; language_index < count; language_index++)
+      _hb_ot_layout_collect_lookups_features (face,
+                                              table_tag,
+                                              script_index,
+                                              language_index,
+                                              features,
+                                              lookup_indexes);
+  }
+  else
+  {
+    for (; *languages; languages++)
+    {
+      unsigned int language_index;
+      if (hb_ot_layout_script_find_language (face,
+                                             table_tag,
+                                             script_index,
+                                             *languages,
+                                             &language_index))
+        _hb_ot_layout_collect_lookups_features (face,
+                                                table_tag,
+                                                script_index,
+                                                language_index,
+                                                features,
+                                                lookup_indexes);
+    }
+  }
+}
+
+/**
+ * Since: 0.9.8
+ **/
+void
+hb_ot_layout_collect_lookups (hb_face_t      *face,
+                              hb_tag_t        table_tag,
+                              const hb_tag_t *scripts,
+                              const hb_tag_t *languages,
+                              const hb_tag_t *features,
+                              hb_set_t       *lookup_indexes /* OUT */)
+{
+  if (!scripts)
+  {
+    /* All scripts */
+    unsigned int count = hb_ot_layout_table_get_script_tags (face,
+                                                             table_tag,
+                                                             0, NULL, NULL);
+    for (unsigned int script_index = 0; script_index < count; script_index++)
+      _hb_ot_layout_collect_lookups_languages (face,
+                                               table_tag,
+                                               script_index,
+                                               languages,
+                                               features,
+                                               lookup_indexes);
+  }
+  else
+  {
+    for (; *scripts; scripts++)
+    {
+      unsigned int script_index;
+      if (hb_ot_layout_table_find_script (face,
+                                          table_tag,
+                                          *scripts,
+                                          &script_index))
+        _hb_ot_layout_collect_lookups_languages (face,
+                                                 table_tag,
+                                                 script_index,
+                                                 languages,
+                                                 features,
+                                                 lookup_indexes);
+    }
+  }
+}
+
+/**
+ * Since: 0.9.7
+ **/
+void
+hb_ot_layout_lookup_collect_glyphs (hb_face_t    *face,
+                                    hb_tag_t      table_tag,
+                                    unsigned int  lookup_index,
+                                    hb_set_t     *glyphs_before, /* OUT. May be NULL */
+                                    hb_set_t     *glyphs_input,  /* OUT. May be NULL */
+                                    hb_set_t     *glyphs_after,  /* OUT. May be NULL */
+                                    hb_set_t     *glyphs_output  /* OUT. May be NULL */)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
+
+  OT::hb_collect_glyphs_context_t c (face,
+                                     glyphs_before,
+                                     glyphs_input,
+                                     glyphs_after,
+                                     glyphs_output);
+
+  switch (table_tag)
+  {
+    case HB_OT_TAG_GSUB:
+    {
+      const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
+      l.collect_glyphs (&c);
+      return;
+    }
+    case HB_OT_TAG_GPOS:
+    {
+      const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index);
+      l.collect_glyphs (&c);
+      return;
+    }
+  }
+}
+
+
+/*
+ * OT::GSUB
+ */
+
+hb_bool_t
+hb_ot_layout_has_substitution (hb_face_t *face)
+{
+  return &_get_gsub (face) != &OT::Null(OT::GSUB);
+}
+
+/**
+ * Since: 0.9.7
+ **/
+hb_bool_t
+hb_ot_layout_lookup_would_substitute (hb_face_t            *face,
+                                      unsigned int          lookup_index,
+                                      const hb_codepoint_t *glyphs,
+                                      unsigned int          glyphs_length,
+                                      hb_bool_t             zero_context)
+{
+  if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
+  return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
+}
+
+hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t            *face,
+                                           unsigned int          lookup_index,
+                                           const hb_codepoint_t *glyphs,
+                                           unsigned int          glyphs_length,
+                                           hb_bool_t             zero_context)
+{
+  if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false;
+  OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context);
+
+  const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
+
+  return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index]);
+}
+
+void
+hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer)
+{
+  OT::GSUB::substitute_start (font, buffer);
+}
+
+void
+hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer)
+{
+  OT::GSUB::substitute_finish (font, buffer);
+}
+
+/**
+ * Since: 0.9.7
+ **/
+void
+hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
+                                        unsigned int  lookup_index,
+                                        hb_set_t     *glyphs)
+{
+  OT::hb_closure_context_t c (face, glyphs);
+
+  const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index);
+
+  l.closure (&c);
+}
+
+/*
+ * OT::GPOS
+ */
+
+hb_bool_t
+hb_ot_layout_has_positioning (hb_face_t *face)
+{
+  return &_get_gpos (face) != &OT::Null(OT::GPOS);
+}
+
+void
+hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
+{
+  OT::GPOS::position_start (font, buffer);
+}
+
+void
+hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer)
+{
+  OT::GPOS::position_finish (font, buffer);
+}
+
+/**
+ * Since: 0.9.10
+ **/
+hb_bool_t
+hb_ot_layout_get_size_params (hb_face_t    *face,
+                              unsigned int *design_size,       /* OUT.  May be NULL */
+                              unsigned int *subfamily_id,      /* OUT.  May be NULL */
+                              unsigned int *subfamily_name_id, /* OUT.  May be NULL */
+                              unsigned int *range_start,       /* OUT.  May be NULL */
+                              unsigned int *range_end          /* OUT.  May be NULL */)
+{
+  const OT::GPOS &gpos = _get_gpos (face);
+  const hb_tag_t tag = HB_TAG ('s','i','z','e');
+
+  unsigned int num_features = gpos.get_feature_count ();
+  for (unsigned int i = 0; i < num_features; i++)
+  {
+    if (tag == gpos.get_feature_tag (i))
+    {
+      const OT::Feature &f = gpos.get_feature (i);
+      const OT::FeatureParamsSize &params = f.get_feature_params ().get_size_params (tag);
+
+      if (params.designSize)
+      {
+#define PARAM(a, A) if (a) *a = params.A
+        PARAM (design_size, designSize);
+        PARAM (subfamily_id, subfamilyID);
+        PARAM (subfamily_name_id, subfamilyNameID);
+        PARAM (range_start, rangeStart);
+        PARAM (range_end, rangeEnd);
+#undef PARAM
+
+        return true;
+      }
+    }
+  }
+
+#define PARAM(a, A) if (a) *a = 0
+  PARAM (design_size, designSize);
+  PARAM (subfamily_id, subfamilyID);
+  PARAM (subfamily_name_id, subfamilyNameID);
+  PARAM (range_start, rangeStart);
+  PARAM (range_end, rangeEnd);
+#undef PARAM
+
+  return false;
+}
+
+
+/*
+ * Parts of different types are implemented here such that they have direct
+ * access to GSUB/GPOS lookups.
+ */
+
+
+struct GSUBProxy
+{
+  static const unsigned int table_index = 0;
+  static const bool inplace = false;
+  typedef OT::SubstLookup Lookup;
+
+  GSUBProxy (hb_face_t *face) :
+    table (*hb_ot_layout_from_face (face)->gsub),
+    accels (hb_ot_layout_from_face (face)->gsub_accels) {}
+
+  const OT::GSUB &table;
+  const hb_ot_layout_lookup_accelerator_t *accels;
+};
+
+struct GPOSProxy
+{
+  static const unsigned int table_index = 1;
+  static const bool inplace = true;
+  typedef OT::PosLookup Lookup;
+
+  GPOSProxy (hb_face_t *face) :
+    table (*hb_ot_layout_from_face (face)->gpos),
+    accels (hb_ot_layout_from_face (face)->gpos_accels) {}
+
+  const OT::GPOS &table;
+  const hb_ot_layout_lookup_accelerator_t *accels;
+};
+
+
+template <typename Obj>
+static inline bool
+apply_forward (OT::hb_apply_context_t *c,
+               const Obj &obj,
+               const hb_ot_layout_lookup_accelerator_t &accel)
+{
+  bool ret = false;
+  hb_buffer_t *buffer = c->buffer;
+  while (buffer->idx < buffer->len)
+  {
+    if (accel.may_have (buffer->cur().codepoint) &&
+        (buffer->cur().mask & c->lookup_mask) &&
+        c->check_glyph_property (&buffer->cur(), c->lookup_props) &&
+        obj.apply (c))
+      ret = true;
+    else
+      buffer->next_glyph ();
+  }
+  return ret;
+}
+
+template <typename Obj>
+static inline bool
+apply_backward (OT::hb_apply_context_t *c,
+                const Obj &obj,
+                const hb_ot_layout_lookup_accelerator_t &accel)
+{
+  bool ret = false;
+  hb_buffer_t *buffer = c->buffer;
+  do
+  {
+    if (accel.may_have (buffer->cur().codepoint) &&
+        (buffer->cur().mask & c->lookup_mask) &&
+        c->check_glyph_property (&buffer->cur(), c->lookup_props) &&
+        obj.apply (c))
+      ret = true;
+    /* The reverse lookup doesn't "advance" cursor (for good reason). */
+    buffer->idx--;
+
+  }
+  while ((int) buffer->idx >= 0);
+  return ret;
+}
+
+struct hb_apply_forward_context_t :
+       OT::hb_dispatch_context_t<hb_apply_forward_context_t, bool, HB_DEBUG_APPLY>
+{
+  inline const char *get_name (void) { return "APPLY_FWD"; }
+  template <typename T>
+  inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel); }
+  static return_t default_return_value (void) { return false; }
+  bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return true; }
+
+  hb_apply_forward_context_t (OT::hb_apply_context_t *c_,
+                              const hb_ot_layout_lookup_accelerator_t &accel_) :
+                                c (c_),
+                                accel (accel_),
+                                debug_depth (0) {}
+
+  OT::hb_apply_context_t *c;
+  const hb_ot_layout_lookup_accelerator_t &accel;
+  unsigned int debug_depth;
+};
+
+template <typename Proxy>
+static inline void
+apply_string (OT::hb_apply_context_t *c,
+              const typename Proxy::Lookup &lookup,
+              const hb_ot_layout_lookup_accelerator_t &accel)
+{
+  hb_buffer_t *buffer = c->buffer;
+
+  if (unlikely (!buffer->len || !c->lookup_mask))
+    return;
+
+  c->set_lookup_props (lookup.get_props ());
+
+  if (likely (!lookup.is_reverse ()))
+  {
+    /* in/out forward substitution/positioning */
+    if (Proxy::table_index == 0)
+      buffer->clear_output ();
+    buffer->idx = 0;
+
+    bool ret;
+    if (lookup.get_subtable_count () == 1)
+    {
+      hb_apply_forward_context_t c_forward (c, accel);
+      ret = lookup.dispatch (&c_forward);
+    }
+    else
+      ret = apply_forward (c, lookup, accel);
+    if (ret)
+    {
+      if (!Proxy::inplace)
+        buffer->swap_buffers ();
+      else
+        assert (!buffer->has_separate_output ());
+    }
+  }
+  else
+  {
+    /* in-place backward substitution/positioning */
+    if (Proxy::table_index == 0)
+      buffer->remove_output ();
+    buffer->idx = buffer->len - 1;
+
+    apply_backward (c, lookup, accel);
+  }
+}
+
+template <typename Proxy>
+inline void hb_ot_map_t::apply (const Proxy &proxy,
+                                const hb_ot_shape_plan_t *plan,
+                                hb_font_t *font,
+                                hb_buffer_t *buffer) const
+{
+  const unsigned int table_index = proxy.table_index;
+  unsigned int i = 0;
+  OT::hb_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++) {
+    const stage_map_t *stage = &stages[table_index][stage_index];
+    for (; i < stage->last_lookup; i++)
+    {
+#if 0
+      char buf[4096];
+      hb_buffer_serialize_glyphs (buffer, 0, buffer->len,
+                                  buf, sizeof (buf), NULL,
+                                  font,
+                                  HB_BUFFER_SERIALIZE_FORMAT_TEXT,
+                                  Proxy::table_index == 0 ?
+                                  HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS :
+                                  HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
+      printf ("buf: [%s]\n", buf);
+#endif
+
+      unsigned int lookup_index = lookups[table_index][i].index;
+      c.set_lookup_index (lookup_index);
+      c.set_lookup_mask (lookups[table_index][i].mask);
+      c.set_auto_zwj (lookups[table_index][i].auto_zwj);
+      apply_string<Proxy> (&c,
+                           proxy.table.get_lookup (lookup_index),
+                           proxy.accels[lookup_index]);
+    }
+
+    if (stage->pause_func)
+    {
+      buffer->clear_output ();
+      stage->pause_func (plan, font, buffer);
+    }
+  }
+}
+
+void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
+{
+  GSUBProxy proxy (font->face);
+  apply (proxy, plan, font, buffer);
+}
+
+void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
+{
+  GPOSProxy proxy (font->face);
+  apply (proxy, plan, font, buffer);
+}
+
+HB_INTERNAL void
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+                                const OT::SubstLookup &lookup,
+                                const hb_ot_layout_lookup_accelerator_t &accel)
+{
+  apply_string<GSUBProxy> (c, lookup, accel);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,302 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_LAYOUT_H
+#define HB_OT_LAYOUT_H
+
+#include "hb.h"
+
+#include "hb-ot-tag.h"
+
+HB_BEGIN_DECLS
+
+
+#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')
+#define HB_OT_TAG_JSTF HB_TAG('J','S','T','F')
+
+
+/*
+ * GDEF
+ */
+
+hb_bool_t
+hb_ot_layout_has_glyph_classes (hb_face_t *face);
+
+typedef enum {
+  HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0,
+  HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH   = 1,
+  HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE     = 2,
+  HB_OT_LAYOUT_GLYPH_CLASS_MARK         = 3,
+  HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT    = 4
+} hb_ot_layout_glyph_class_t;
+
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class (hb_face_t      *face,
+                              hb_codepoint_t  glyph);
+
+void
+hb_ot_layout_get_glyphs_in_class (hb_face_t                  *face,
+                                  hb_ot_layout_glyph_class_t  klass,
+                                  hb_set_t                   *glyphs /* OUT */);
+
+
+/* Not that useful.  Provides list of attach points for a glyph that a
+ * client may want to cache */
+unsigned int
+hb_ot_layout_get_attach_points (hb_face_t      *face,
+                                hb_codepoint_t  glyph,
+                                unsigned int    start_offset,
+                                unsigned int   *point_count /* IN/OUT */,
+                                unsigned int   *point_array /* OUT */);
+
+/* Ligature caret positions */
+unsigned int
+hb_ot_layout_get_ligature_carets (hb_font_t      *font,
+                                  hb_direction_t  direction,
+                                  hb_codepoint_t  glyph,
+                                  unsigned int    start_offset,
+                                  unsigned int   *caret_count /* IN/OUT */,
+                                  hb_position_t  *caret_array /* OUT */);
+
+
+/*
+ * GSUB/GPOS feature query and enumeration interface
+ */
+
+#define HB_OT_LAYOUT_NO_SCRIPT_INDEX            0xFFFFu
+#define HB_OT_LAYOUT_NO_FEATURE_INDEX           0xFFFFu
+#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX     0xFFFFu
+
+unsigned int
+hb_ot_layout_table_get_script_tags (hb_face_t    *face,
+                                    hb_tag_t      table_tag,
+                                    unsigned int  start_offset,
+                                    unsigned int *script_count /* IN/OUT */,
+                                    hb_tag_t     *script_tags /* OUT */);
+
+hb_bool_t
+hb_ot_layout_table_find_script (hb_face_t    *face,
+                                hb_tag_t      table_tag,
+                                hb_tag_t      script_tag,
+                                unsigned int *script_index);
+
+/* Like find_script, but takes zero-terminated array of scripts to test */
+hb_bool_t
+hb_ot_layout_table_choose_script (hb_face_t      *face,
+                                  hb_tag_t        table_tag,
+                                  const hb_tag_t *script_tags,
+                                  unsigned int   *script_index,
+                                  hb_tag_t       *chosen_script);
+
+unsigned int
+hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
+                                     hb_tag_t      table_tag,
+                                     unsigned int  start_offset,
+                                     unsigned int *feature_count /* IN/OUT */,
+                                     hb_tag_t     *feature_tags /* OUT */);
+
+unsigned int
+hb_ot_layout_script_get_language_tags (hb_face_t    *face,
+                                       hb_tag_t      table_tag,
+                                       unsigned int  script_index,
+                                       unsigned int  start_offset,
+                                       unsigned int *language_count /* IN/OUT */,
+                                       hb_tag_t     *language_tags /* OUT */);
+
+hb_bool_t
+hb_ot_layout_script_find_language (hb_face_t    *face,
+                                   hb_tag_t      table_tag,
+                                   unsigned int  script_index,
+                                   hb_tag_t      language_tag,
+                                   unsigned int *language_index);
+
+hb_bool_t
+hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
+                                                  hb_tag_t      table_tag,
+                                                  unsigned int  script_index,
+                                                  unsigned int  language_index,
+                                                  unsigned int *feature_index);
+
+hb_bool_t
+hb_ot_layout_language_get_required_feature (hb_face_t    *face,
+                                            hb_tag_t      table_tag,
+                                            unsigned int  script_index,
+                                            unsigned int  language_index,
+                                            unsigned int *feature_index,
+                                            hb_tag_t     *feature_tag);
+
+unsigned int
+hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
+                                           hb_tag_t      table_tag,
+                                           unsigned int  script_index,
+                                           unsigned int  language_index,
+                                           unsigned int  start_offset,
+                                           unsigned int *feature_count /* IN/OUT */,
+                                           unsigned int *feature_indexes /* OUT */);
+
+unsigned int
+hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
+                                        hb_tag_t      table_tag,
+                                        unsigned int  script_index,
+                                        unsigned int  language_index,
+                                        unsigned int  start_offset,
+                                        unsigned int *feature_count /* IN/OUT */,
+                                        hb_tag_t     *feature_tags /* OUT */);
+
+hb_bool_t
+hb_ot_layout_language_find_feature (hb_face_t    *face,
+                                    hb_tag_t      table_tag,
+                                    unsigned int  script_index,
+                                    unsigned int  language_index,
+                                    hb_tag_t      feature_tag,
+                                    unsigned int *feature_index);
+
+unsigned int
+hb_ot_layout_feature_get_lookups (hb_face_t    *face,
+                                  hb_tag_t      table_tag,
+                                  unsigned int  feature_index,
+                                  unsigned int  start_offset,
+                                  unsigned int *lookup_count /* IN/OUT */,
+                                  unsigned int *lookup_indexes /* OUT */);
+
+unsigned int
+hb_ot_layout_table_get_lookup_count (hb_face_t    *face,
+                                     hb_tag_t      table_tag);
+
+
+void
+hb_ot_layout_collect_lookups (hb_face_t      *face,
+                              hb_tag_t        table_tag,
+                              const hb_tag_t *scripts,
+                              const hb_tag_t *languages,
+                              const hb_tag_t *features,
+                              hb_set_t       *lookup_indexes /* OUT */);
+
+void
+hb_ot_layout_lookup_collect_glyphs (hb_face_t    *face,
+                                    hb_tag_t      table_tag,
+                                    unsigned int  lookup_index,
+                                    hb_set_t     *glyphs_before, /* OUT. May be NULL */
+                                    hb_set_t     *glyphs_input,  /* OUT. May be NULL */
+                                    hb_set_t     *glyphs_after,  /* OUT. May be NULL */
+                                    hb_set_t     *glyphs_output  /* OUT. May be NULL */);
+
+#ifdef HB_NOT_IMPLEMENTED
+typedef struct
+{
+  const hb_codepoint_t *before,
+  unsigned int          before_length,
+  const hb_codepoint_t *input,
+  unsigned int          input_length,
+  const hb_codepoint_t *after,
+  unsigned int          after_length,
+} hb_ot_layout_glyph_sequence_t;
+
+typedef hb_bool_t
+(*hb_ot_layout_glyph_sequence_func_t) (hb_font_t    *font,
+                                       hb_tag_t      table_tag,
+                                       unsigned int  lookup_index,
+                                       const hb_ot_layout_glyph_sequence_t *sequence,
+                                       void         *user_data);
+
+void
+Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t    *face,
+                                         hb_tag_t      table_tag,
+                                         unsigned int  lookup_index,
+                                         hb_ot_layout_glyph_sequence_func_t callback,
+                                         void         *user_data);
+#endif
+
+
+/*
+ * GSUB
+ */
+
+hb_bool_t
+hb_ot_layout_has_substitution (hb_face_t *face);
+
+hb_bool_t
+hb_ot_layout_lookup_would_substitute (hb_face_t            *face,
+                                      unsigned int          lookup_index,
+                                      const hb_codepoint_t *glyphs,
+                                      unsigned int          glyphs_length,
+                                      hb_bool_t             zero_context);
+
+void
+hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
+                                        unsigned int  lookup_index,
+                                        hb_set_t     *glyphs
+                                        /*TODO , hb_bool_t  inclusive */);
+
+#ifdef HB_NOT_IMPLEMENTED
+/* Note: You better have GDEF when using this API, or marks won't do much. */
+hb_bool_t
+Xhb_ot_layout_lookup_substitute (hb_font_t            *font,
+                                unsigned int          lookup_index,
+                                const hb_ot_layout_glyph_sequence_t *sequence,
+                                unsigned int          out_size,
+                                hb_codepoint_t       *glyphs_out,   /* OUT */
+                                unsigned int         *clusters_out, /* OUT */
+                                unsigned int         *out_length    /* OUT */);
+#endif
+
+
+/*
+ * GPOS
+ */
+
+hb_bool_t
+hb_ot_layout_has_positioning (hb_face_t *face);
+
+#ifdef HB_NOT_IMPLEMENTED
+/* Note: You better have GDEF when using this API, or marks won't do much. */
+hb_bool_t
+Xhb_ot_layout_lookup_position (hb_font_t            *font,
+                              unsigned int          lookup_index,
+                              const hb_ot_layout_glyph_sequence_t *sequence,
+                              hb_glyph_position_t  *positions /* IN / OUT */);
+#endif
+
+/* Optical 'size' feature info.  Returns true if found.
+ * http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+hb_bool_t
+hb_ot_layout_get_size_params (hb_face_t    *face,
+                              unsigned int *design_size,       /* OUT.  May be NULL */
+                              unsigned int *subfamily_id,      /* OUT.  May be NULL */
+                              unsigned int *subfamily_name_id, /* OUT.  May be NULL */
+                              unsigned int *range_start,       /* OUT.  May be NULL */
+                              unsigned int *range_end          /* OUT.  May be NULL */);
+
+
+HB_END_DECLS
+
+#endif /* HB_OT_LAYOUT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,248 @@
+/*
+ * Copyright © 2009,2010  Red Hat, Inc.
+ * Copyright © 2010,2011,2012,2013  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_MAP_PRIVATE_HH
+#define HB_OT_MAP_PRIVATE_HH
+
+#include "hb-buffer-private.hh"
+
+
+struct hb_ot_shape_plan_t;
+
+static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
+
+struct hb_ot_map_t
+{
+  friend struct hb_ot_map_builder_t;
+
+  public:
+
+  struct feature_map_t {
+    hb_tag_t tag; /* should be first for our bsearch to work */
+    unsigned int index[2]; /* GSUB/GPOS */
+    unsigned int stage[2]; /* GSUB/GPOS */
+    unsigned int shift;
+    hb_mask_t mask;
+    hb_mask_t _1_mask; /* mask for value=1, for quick access */
+    unsigned int needs_fallback : 1;
+    unsigned int auto_zwj : 1;
+
+    static int cmp (const feature_map_t *a, const feature_map_t *b)
+    { return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
+  };
+
+  struct lookup_map_t {
+    unsigned short index;
+    unsigned short auto_zwj : 1;
+    hb_mask_t mask;
+
+    static int cmp (const lookup_map_t *a, const lookup_map_t *b)
+    { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
+  };
+
+  typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
+
+  struct stage_map_t {
+    unsigned int last_lookup; /* Cumulative */
+    pause_func_t pause_func;
+  };
+
+
+  hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
+
+  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 = NULL) const {
+    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);
+    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);
+    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);
+    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);
+    return map ? map->stage[table_index] : (unsigned int) -1;
+  }
+
+  inline void get_stage_lookups (unsigned int table_index, unsigned int stage,
+                                 const struct lookup_map_t **plookups, unsigned int *lookup_count) const {
+    if (unlikely (stage == (unsigned int) -1)) {
+      *plookups = NULL;
+      *lookup_count = 0;
+      return;
+    }
+    assert (stage <= stages[table_index].len);
+    unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0;
+    unsigned int end   = stage < stages[table_index].len ? stages[table_index][stage].last_lookup : lookups[table_index].len;
+    *plookups = &lookups[table_index][start];
+    *lookup_count = end - start;
+  }
+
+  HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
+  template <typename Proxy>
+  HB_INTERNAL inline void apply (const Proxy &proxy,
+                                 const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+  HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+  HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+
+  inline void finish (void) {
+    features.finish ();
+    for (unsigned int table_index = 0; table_index < 2; table_index++)
+    {
+      lookups[table_index].finish ();
+      stages[table_index].finish ();
+    }
+  }
+
+  public:
+  hb_tag_t chosen_script[2];
+  bool found_script[2];
+
+  private:
+
+  HB_INTERNAL void add_lookups (hb_face_t    *face,
+                                unsigned int  table_index,
+                                unsigned int  feature_index,
+                                hb_mask_t     mask,
+                                bool          auto_zwj);
+
+  hb_mask_t global_mask;
+
+  hb_prealloced_array_t<feature_map_t, 8> features;
+  hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
+  hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
+};
+
+enum hb_ot_map_feature_flags_t {
+  F_NONE                = 0x0000u,
+  F_GLOBAL              = 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */
+  F_HAS_FALLBACK        = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */
+  F_MANUAL_ZWJ          = 0x0004u, /* Don't skip over ZWJ when matching. */
+  F_GLOBAL_SEARCH       = 0x0008u  /* If feature not found in LangSys, look for it in global feature list and pick one. */
+};
+/* Macro version for where const is desired. */
+#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
+static inline hb_ot_map_feature_flags_t
+operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); }
+static inline hb_ot_map_feature_flags_t
+operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); }
+static inline hb_ot_map_feature_flags_t
+operator ~ (hb_ot_map_feature_flags_t r)
+{ return hb_ot_map_feature_flags_t (~(unsigned int) r); }
+static inline hb_ot_map_feature_flags_t&
+operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r)
+{ l = l | r; return l; }
+static inline hb_ot_map_feature_flags_t&
+operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r)
+{ l = l & r; return l; }
+
+
+struct hb_ot_map_builder_t
+{
+  public:
+
+  HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
+                                   const hb_segment_properties_t *props_);
+
+  HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
+                                hb_ot_map_feature_flags_t flags);
+
+  inline void add_global_bool_feature (hb_tag_t tag)
+  { add_feature (tag, 1, F_GLOBAL); }
+
+  inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
+  { add_pause (0, pause_func); }
+  inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
+  { add_pause (1, pause_func); }
+
+  HB_INTERNAL void compile (struct hb_ot_map_t &m);
+
+  inline void finish (void) {
+    feature_infos.finish ();
+    for (unsigned int table_index = 0; table_index < 2; table_index++)
+    {
+      stages[table_index].finish ();
+    }
+  }
+
+  private:
+
+  struct feature_info_t {
+    hb_tag_t tag;
+    unsigned int seq; /* sequence#, used for stable sorting only */
+    unsigned int max_value;
+    hb_ot_map_feature_flags_t flags;
+    unsigned int default_value; /* for non-global features, what should the unset glyphs take */
+    unsigned int stage[2]; /* GSUB/GPOS */
+
+    static int cmp (const feature_info_t *a, const feature_info_t *b)
+    { return (a->tag != b->tag) ?  (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); }
+  };
+
+  struct stage_info_t {
+    unsigned int index;
+    hb_ot_map_t::pause_func_t pause_func;
+  };
+
+  HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func);
+
+  public:
+
+  hb_face_t *face;
+  hb_segment_properties_t props;
+
+  hb_tag_t chosen_script[2];
+  bool found_script[2];
+  unsigned int script_index[2], language_index[2];
+
+  private:
+
+  unsigned int current_stage[2]; /* GSUB/GPOS */
+  hb_prealloced_array_t<feature_info_t, 32> feature_infos;
+  hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */
+};
+
+
+
+#endif /* HB_OT_MAP_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,315 @@
+/*
+ * Copyright © 2009,2010  Red Hat, Inc.
+ * Copyright © 2010,2011,2013  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-map-private.hh"
+
+#include "hb-ot-layout-private.hh"
+
+
+void
+hb_ot_map_t::add_lookups (hb_face_t    *face,
+                          unsigned int  table_index,
+                          unsigned int  feature_index,
+                          hb_mask_t     mask,
+                          bool          auto_zwj)
+{
+  unsigned int lookup_indices[32];
+  unsigned int offset, len;
+  unsigned int table_lookup_count;
+
+  table_lookup_count = hb_ot_layout_table_get_lookup_count (face, table_tags[table_index]);
+
+  offset = 0;
+  do {
+    len = ARRAY_LENGTH (lookup_indices);
+    hb_ot_layout_feature_get_lookups (face,
+                                      table_tags[table_index],
+                                      feature_index,
+                                      offset, &len,
+                                      lookup_indices);
+
+    for (unsigned int i = 0; i < len; i++)
+    {
+      if (lookup_indices[i] >= table_lookup_count)
+        continue;
+      hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push ();
+      if (unlikely (!lookup))
+        return;
+      lookup->mask = mask;
+      lookup->index = lookup_indices[i];
+      lookup->auto_zwj = auto_zwj;
+    }
+
+    offset += len;
+  } while (len == ARRAY_LENGTH (lookup_indices));
+}
+
+hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
+                                          const hb_segment_properties_t *props_)
+{
+  memset (this, 0, sizeof (*this));
+
+  face = face_;
+  props = *props_;
+
+
+  /* Fetch script/language indices for GSUB/GPOS.  We need these later to skip
+   * features not available in either table and not waste precious bits for them. */
+
+  hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE};
+  hb_tag_t language_tag;
+
+  hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]);
+  language_tag = hb_ot_tag_from_language (props.language);
+
+  for (unsigned int table_index = 0; table_index < 2; table_index++) {
+    hb_tag_t table_tag = table_tags[table_index];
+    found_script[table_index] = hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]);
+    hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
+  }
+}
+
+void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
+                                       hb_ot_map_feature_flags_t flags)
+{
+  feature_info_t *info = feature_infos.push();
+  if (unlikely (!info)) return;
+  if (unlikely (!tag)) return;
+  info->tag = tag;
+  info->seq = feature_infos.len;
+  info->max_value = value;
+  info->flags = flags;
+  info->default_value = (flags & F_GLOBAL) ? value : 0;
+  info->stage[0] = current_stage[0];
+  info->stage[1] = current_stage[1];
+}
+
+
+void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
+{
+  for (unsigned int i = 0; i < lookups[table_index].len; i++)
+    hb_set_add (lookups_out, lookups[table_index][i].index);
+}
+
+void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func)
+{
+  stage_info_t *s = stages[table_index].push ();
+  if (likely (s)) {
+    s->index = current_stage[table_index];
+    s->pause_func = pause_func;
+  }
+
+  current_stage[table_index]++;
+}
+
+void
+hb_ot_map_builder_t::compile (hb_ot_map_t &m)
+{
+  m.global_mask = 1;
+
+  unsigned int required_feature_index[2];
+  hb_tag_t required_feature_tag[2];
+  /* We default to applying required feature in stage 0.  If the required
+   * feature has a tag that is known to the shaper, we apply required feature
+   * in the stage for that tag.
+   */
+  unsigned int required_feature_stage[2] = {0, 0};
+
+  for (unsigned int table_index = 0; table_index < 2; table_index++)
+  {
+    m.chosen_script[table_index] = chosen_script[table_index];
+    m.found_script[table_index] = found_script[table_index];
+
+    hb_ot_layout_language_get_required_feature (face,
+                                                table_tags[table_index],
+                                                script_index[table_index],
+                                                language_index[table_index],
+                                                &required_feature_index[table_index],
+                                                &required_feature_tag[table_index]);
+  }
+
+  if (!feature_infos.len)
+    return;
+
+  /* Sort features and merge duplicates */
+  {
+    feature_infos.qsort ();
+    unsigned int j = 0;
+    for (unsigned int i = 1; i < feature_infos.len; i++)
+      if (feature_infos[i].tag != feature_infos[j].tag)
+        feature_infos[++j] = feature_infos[i];
+      else {
+        if (feature_infos[i].flags & F_GLOBAL) {
+          feature_infos[j].flags |= F_GLOBAL;
+          feature_infos[j].max_value = feature_infos[i].max_value;
+          feature_infos[j].default_value = feature_infos[i].default_value;
+        } else {
+          feature_infos[j].flags &= ~F_GLOBAL;
+          feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
+          /* Inherit default_value from j */
+        }
+        feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
+        feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
+        feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
+      }
+    feature_infos.shrink (j + 1);
+  }
+
+
+  /* Allocate bits now */
+  unsigned int next_bit = 1;
+  for (unsigned int i = 0; i < feature_infos.len; i++)
+  {
+    const feature_info_t *info = &feature_infos[i];
+
+    unsigned int bits_needed;
+
+    if ((info->flags & F_GLOBAL) && info->max_value == 1)
+      /* Uses the global bit */
+      bits_needed = 0;
+    else
+      bits_needed = _hb_bit_storage (info->max_value);
+
+    if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
+      continue; /* Feature disabled, or not enough bits. */
+
+
+    hb_bool_t found = false;
+    unsigned int feature_index[2];
+    for (unsigned int table_index = 0; table_index < 2; table_index++)
+    {
+      if (required_feature_tag[table_index] == info->tag)
+      {
+        required_feature_stage[table_index] = info->stage[table_index];
+        found = true;
+        continue;
+      }
+      found |= hb_ot_layout_language_find_feature (face,
+                                                   table_tags[table_index],
+                                                   script_index[table_index],
+                                                   language_index[table_index],
+                                                   info->tag,
+                                                   &feature_index[table_index]);
+    }
+    if (!found && (info->flags & F_GLOBAL_SEARCH))
+    {
+      for (unsigned int table_index = 0; table_index < 2; table_index++)
+      {
+        found |= hb_ot_layout_table_find_feature (face,
+                                                  table_tags[table_index],
+                                                  info->tag,
+                                                  &feature_index[table_index]);
+      }
+    }
+    if (!found && !(info->flags & F_HAS_FALLBACK))
+      continue;
+
+
+    hb_ot_map_t::feature_map_t *map = m.features.push ();
+    if (unlikely (!map))
+      break;
+
+    map->tag = info->tag;
+    map->index[0] = feature_index[0];
+    map->index[1] = feature_index[1];
+    map->stage[0] = info->stage[0];
+    map->stage[1] = info->stage[1];
+    map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
+    if ((info->flags & F_GLOBAL) && info->max_value == 1) {
+      /* Uses the global bit */
+      map->shift = 0;
+      map->mask = 1;
+    } else {
+      map->shift = next_bit;
+      map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit);
+      next_bit += bits_needed;
+      m.global_mask |= (info->default_value << map->shift) & map->mask;
+    }
+    map->_1_mask = (1 << map->shift) & map->mask;
+    map->needs_fallback = !found;
+
+  }
+  feature_infos.shrink (0); /* Done with these */
+
+
+  add_gsub_pause (NULL);
+  add_gpos_pause (NULL);
+
+  for (unsigned int table_index = 0; table_index < 2; table_index++)
+  {
+    /* Collect lookup indices for features */
+
+    unsigned int stage_index = 0;
+    unsigned int last_num_lookups = 0;
+    for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
+    {
+      if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX &&
+          required_feature_stage[table_index] == stage)
+        m.add_lookups (face, table_index,
+                       required_feature_index[table_index],
+                       1 /* mask */,
+                       true /* auto_zwj */);
+
+      for (unsigned i = 0; i < m.features.len; i++)
+        if (m.features[i].stage[table_index] == stage)
+          m.add_lookups (face, table_index,
+                         m.features[i].index[table_index],
+                         m.features[i].mask,
+                         m.features[i].auto_zwj);
+
+      /* Sort lookups and merge duplicates */
+      if (last_num_lookups < m.lookups[table_index].len)
+      {
+        m.lookups[table_index].qsort (last_num_lookups, m.lookups[table_index].len);
+
+        unsigned int j = last_num_lookups;
+        for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++)
+          if (m.lookups[table_index][i].index != m.lookups[table_index][j].index)
+            m.lookups[table_index][++j] = m.lookups[table_index][i];
+          else
+          {
+            m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask;
+            m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj;
+          }
+        m.lookups[table_index].shrink (j + 1);
+      }
+
+      last_num_lookups = m.lookups[table_index].len;
+
+      if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) {
+        hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push ();
+        if (likely (stage_map)) {
+          stage_map->last_lookup = last_num_lookups;
+          stage_map->pause_func = stages[table_index][stage_index].pause_func;
+        }
+
+        stage_index++;
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-maxp-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2011,2012  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_MAXP_TABLE_HH
+#define HB_OT_MAXP_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * maxp -- The Maximum Profile Table
+ */
+
+#define HB_OT_TAG_maxp HB_TAG('m','a','x','p')
+
+struct maxp
+{
+  static const hb_tag_t tableTag        = HB_OT_TAG_maxp;
+
+  inline unsigned int get_num_glyphs (void) const
+  {
+    return numGlyphs;
+  }
+
+  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)));
+  }
+
+  /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
+  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. */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_MAXP_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-name-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2011,2012  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_NAME_TABLE_HH
+#define HB_OT_NAME_TABLE_HH
+
+#include "hb-open-type-private.hh"
+
+
+namespace OT {
+
+
+/*
+ * name -- The Naming Table
+ */
+
+#define HB_OT_TAG_name HB_TAG('n','a','m','e')
+
+
+struct NameRecord
+{
+  static int cmp (const NameRecord *a, const NameRecord *b)
+  {
+    int ret;
+    ret = b->platformID.cmp (a->platformID);
+    if (ret) return ret;
+    ret = b->encodingID.cmp (a->encodingID);
+    if (ret) return ret;
+    ret = b->languageID.cmp (a->languageID);
+    if (ret) return ret;
+    ret = b->nameID.cmp (a->nameID);
+    if (ret) return ret;
+    return 0;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    /* We can check from base all the way up to the end of string... */
+    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). */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct name
+{
+  static const hb_tag_t tableTag        = HB_OT_TAG_name;
+
+  inline unsigned int get_name (unsigned int platform_id,
+                                unsigned int encoding_id,
+                                unsigned int language_id,
+                                unsigned int name_id,
+                                void *buffer,
+                                unsigned int buffer_length) const
+  {
+    NameRecord key;
+    key.platformID.set (platform_id);
+    key.encodingID.set (encoding_id);
+    key.languageID.set (language_id);
+    key.nameID.set (name_id);
+    NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp);
+
+    if (!match)
+      return 0;
+
+    unsigned int length = MIN (buffer_length, (unsigned int) match->length);
+    memcpy (buffer, (char *) this + stringOffset + match->offset, length);
+    return length;
+  }
+
+  inline unsigned int get_size (void) const
+  { return min_size + count * nameRecord[0].min_size; }
+
+  inline bool sanitize_records (hb_sanitize_context_t *c) const {
+    TRACE_SANITIZE (this);
+    char *string_pool = (char *) this + stringOffset;
+    unsigned int _count = count;
+    for (unsigned int i = 0; i < _count; i++)
+      if (!nameRecord[i].sanitize (c, string_pool)) return_trace (false);
+    return_trace (true);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  likely (format == 0 || format == 1) &&
+                  c->check_array (nameRecord, nameRecord[0].static_size, count) &&
+                  sanitize_records (c));
+  }
+
+  /* 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). */
+  NameRecord    nameRecord[VAR];        /* The name records where count is the number of records. */
+  public:
+  DEFINE_SIZE_ARRAY (6, nameRecord);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_NAME_TABLE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-fallback.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,354 @@
+/*
+ * Copyright © 2012  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_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-shape-private.hh"
+#include "hb-ot-layout-gsub-table.hh"
+
+
+/* Features ordered the same as the entries in shaping_table rows,
+ * followed by rlig.  Don't change. */
+static const hb_tag_t arabic_fallback_features[] =
+{
+  HB_TAG('i','n','i','t'),
+  HB_TAG('m','e','d','i'),
+  HB_TAG('f','i','n','a'),
+  HB_TAG('i','s','o','l'),
+  HB_TAG('r','l','i','g'),
+};
+
+static OT::SubstLookup *
+arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                                          hb_font_t *font,
+                                          unsigned int feature_index)
+{
+  OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+  OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+  unsigned int num_glyphs = 0;
+
+  /* Populate arrays */
+  for (hb_codepoint_t u = SHAPING_TABLE_FIRST; u < SHAPING_TABLE_LAST + 1; u++)
+  {
+    hb_codepoint_t s = shaping_table[u - SHAPING_TABLE_FIRST][feature_index];
+    hb_codepoint_t u_glyph, s_glyph;
+
+    if (!s ||
+        !hb_font_get_glyph (font, u, 0, &u_glyph) ||
+        !hb_font_get_glyph (font, s, 0, &s_glyph) ||
+        u_glyph == s_glyph ||
+        u_glyph > 0xFFFFu || s_glyph > 0xFFFFu)
+      continue;
+
+    glyphs[num_glyphs].set (u_glyph);
+    substitutes[num_glyphs].set (s_glyph);
+
+    num_glyphs++;
+  }
+
+  if (!num_glyphs)
+    return NULL;
+
+  /* Bubble-sort or something equally good!
+   * May not be good-enough for presidential candidate interviews, but good-enough for us... */
+  hb_stable_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
+
+  OT::Supplier<OT::GlyphID> glyphs_supplier      (glyphs, num_glyphs);
+  OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
+
+  /* Each glyph takes four bytes max, and there's some overhead. */
+  char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
+  OT::hb_serialize_context_t c (buf, sizeof (buf));
+  OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
+  bool ret = lookup->serialize_single (&c,
+                                       OT::LookupFlag::IgnoreMarks,
+                                       glyphs_supplier,
+                                       substitutes_supplier,
+                                       num_glyphs);
+  c.end_serialize ();
+  /* TODO sanitize the results? */
+
+  return ret ? c.copy<OT::SubstLookup> () : NULL;
+}
+
+static OT::SubstLookup *
+arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                                            hb_font_t *font)
+{
+  OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
+  unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
+  unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
+  unsigned int num_first_glyphs = 0;
+
+  /* We know that all our ligatures are 2-component */
+  OT::GlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
+  unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
+  OT::GlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
+  unsigned int num_ligatures = 0;
+
+  /* Populate arrays */
+
+  /* Sort out the first-glyphs */
+  for (unsigned int first_glyph_idx = 0; first_glyph_idx < ARRAY_LENGTH (first_glyphs); first_glyph_idx++)
+  {
+    hb_codepoint_t first_u = ligature_table[first_glyph_idx].first;
+    hb_codepoint_t first_glyph;
+    if (!hb_font_get_glyph (font, first_u, 0, &first_glyph))
+      continue;
+    first_glyphs[num_first_glyphs].set (first_glyph);
+    ligature_per_first_glyph_count_list[num_first_glyphs] = 0;
+    first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
+    num_first_glyphs++;
+  }
+  hb_stable_sort (&first_glyphs[0], num_first_glyphs, 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++)
+  {
+    unsigned int first_glyph_idx = first_glyphs_indirection[i];
+
+    for (unsigned int second_glyph_idx = 0; second_glyph_idx < ARRAY_LENGTH (ligature_table[0].ligatures); second_glyph_idx++)
+    {
+      hb_codepoint_t second_u   = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].second;
+      hb_codepoint_t ligature_u = ligature_table[first_glyph_idx].ligatures[second_glyph_idx].ligature;
+      hb_codepoint_t second_glyph, ligature_glyph;
+      if (!second_u ||
+          !hb_font_get_glyph (font, second_u,   0, &second_glyph) ||
+          !hb_font_get_glyph (font, ligature_u, 0, &ligature_glyph))
+        continue;
+
+      ligature_per_first_glyph_count_list[i]++;
+
+      ligature_list[num_ligatures].set (ligature_glyph);
+      component_count_list[num_ligatures] = 2;
+      component_list[num_ligatures].set (second_glyph);
+      num_ligatures++;
+    }
+  }
+
+  if (!num_ligatures)
+    return NULL;
+
+  OT::Supplier<OT::GlyphID>   first_glyphs_supplier                      (first_glyphs, num_first_glyphs);
+  OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier    (ligature_per_first_glyph_count_list, num_first_glyphs);
+  OT::Supplier<OT::GlyphID>   ligatures_supplier                         (ligature_list, num_ligatures);
+  OT::Supplier<unsigned int > component_count_supplier                   (component_count_list, num_ligatures);
+  OT::Supplier<OT::GlyphID>   component_supplier                         (component_list, num_ligatures);
+
+  /* 16 bytes per ligature ought to be enough... */
+  char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
+  OT::hb_serialize_context_t c (buf, sizeof (buf));
+  OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
+  bool ret = lookup->serialize_ligature (&c,
+                                         OT::LookupFlag::IgnoreMarks,
+                                         first_glyphs_supplier,
+                                         ligature_per_first_glyph_count_supplier,
+                                         num_first_glyphs,
+                                         ligatures_supplier,
+                                         component_count_supplier,
+                                         component_supplier);
+
+  c.end_serialize ();
+  /* TODO sanitize the results? */
+
+  return ret ? c.copy<OT::SubstLookup> () : NULL;
+}
+
+static OT::SubstLookup *
+arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan,
+                                   hb_font_t *font,
+                                   unsigned int feature_index)
+{
+  if (feature_index < 4)
+    return arabic_fallback_synthesize_lookup_single (plan, font, feature_index);
+  else
+    return arabic_fallback_synthesize_lookup_ligature (plan, font);
+}
+
+#define ARABIC_FALLBACK_MAX_LOOKUPS 5
+
+struct arabic_fallback_plan_t
+{
+  ASSERT_POD ();
+
+  unsigned int num_lookups;
+  bool free_lookups;
+
+  hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
+  OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
+  hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
+};
+
+static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
+
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256)
+#define HB_WITH_WIN1256
+#endif
+
+#ifdef HB_WITH_WIN1256
+#include "hb-ot-shape-complex-arabic-win1256.hh"
+#endif
+
+struct ManifestLookup {
+  OT::Tag tag;
+  OT::OffsetTo<OT::SubstLookup> lookupOffset;
+};
+typedef OT::ArrayOf<ManifestLookup> Manifest;
+
+static bool
+arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan,
+                                   const hb_ot_shape_plan_t *plan,
+                                   hb_font_t *font)
+{
+#ifdef HB_WITH_WIN1256
+  /* Does this font look like it's Windows-1256-encoded? */
+  hb_codepoint_t g;
+  if (!(hb_font_get_glyph (font, 0x0627u, 0, &g) && g == 199 /* ALEF */ &&
+        hb_font_get_glyph (font, 0x0644u, 0, &g) && g == 225 /* LAM */ &&
+        hb_font_get_glyph (font, 0x0649u, 0, &g) && g == 236 /* ALEF MAKSURA */ &&
+        hb_font_get_glyph (font, 0x064Au, 0, &g) && g == 237 /* YEH */ &&
+        hb_font_get_glyph (font, 0x0652u, 0, &g) && g == 250 /* SUKUN */))
+    return false;
+
+  const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
+  ASSERT_STATIC (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
+                 <= ARABIC_FALLBACK_MAX_LOOKUPS);
+  /* TODO sanitize the table? */
+
+  unsigned j = 0;
+  unsigned int count = manifest.len;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    fallback_plan->mask_array[j] = plan->map.get_1_mask (manifest[i].tag);
+    if (fallback_plan->mask_array[j])
+    {
+      fallback_plan->lookup_array[j] = const_cast<OT::SubstLookup*> (&(&manifest+manifest[i].lookupOffset));
+      if (fallback_plan->lookup_array[j])
+      {
+        fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
+        j++;
+      }
+    }
+  }
+
+  fallback_plan->num_lookups = j;
+  fallback_plan->free_lookups = false;
+
+  return j > 0;
+#else
+  return false;
+#endif
+}
+
+static bool
+arabic_fallback_plan_init_unicode (arabic_fallback_plan_t *fallback_plan,
+                                   const hb_ot_shape_plan_t *plan,
+                                   hb_font_t *font)
+{
+  ASSERT_STATIC (ARRAY_LENGTH_CONST(arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS);
+  unsigned int j = 0;
+  for (unsigned int i = 0; i < ARRAY_LENGTH(arabic_fallback_features) ; i++)
+  {
+    fallback_plan->mask_array[j] = plan->map.get_1_mask (arabic_fallback_features[i]);
+    if (fallback_plan->mask_array[j])
+    {
+      fallback_plan->lookup_array[j] = arabic_fallback_synthesize_lookup (plan, font, i);
+      if (fallback_plan->lookup_array[j])
+      {
+        fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
+        j++;
+      }
+    }
+  }
+
+  fallback_plan->num_lookups = j;
+  fallback_plan->free_lookups = true;
+
+  return j > 0;
+}
+
+static arabic_fallback_plan_t *
+arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
+                             hb_font_t *font)
+{
+  arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t));
+  if (unlikely (!fallback_plan))
+    return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
+
+  fallback_plan->num_lookups = 0;
+  fallback_plan->free_lookups = false;
+
+  /* Try synthesizing GSUB table using Unicode Arabic Presentation Forms,
+   * in case the font has cmap entries for the presentation-forms characters. */
+  if (arabic_fallback_plan_init_unicode (fallback_plan, plan, font))
+    return fallback_plan;
+
+  /* See if this looks like a Windows-1256-encoded font.  If it does, use a
+   * hand-coded GSUB table. */
+  if (arabic_fallback_plan_init_win1256 (fallback_plan, plan, font))
+    return fallback_plan;
+
+  free (fallback_plan);
+  return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
+}
+
+static void
+arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
+{
+  if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
+    return;
+
+  for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
+    if (fallback_plan->lookup_array[i])
+    {
+      fallback_plan->accel_array[i].fini ();
+      if (fallback_plan->free_lookups)
+        free (fallback_plan->lookup_array[i]);
+    }
+
+  free (fallback_plan);
+}
+
+static void
+arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
+                            hb_font_t *font,
+                            hb_buffer_t *buffer)
+{
+  OT::hb_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]);
+      hb_ot_layout_substitute_lookup (&c,
+                                      *fallback_plan->lookup_array[i],
+                                      fallback_plan->accel_array[i]);
+    }
+}
+
+
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_FALLBACK_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2015  Mozilla Foundation.
+ * Copyright © 2015  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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+struct arabic_shape_plan_t;
+
+HB_INTERNAL void *
+data_create_arabic (const hb_ot_shape_plan_t *plan);
+
+HB_INTERNAL void
+data_destroy_arabic (void *data);
+
+HB_INTERNAL void
+setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan,
+                         hb_buffer_t               *buffer,
+                         hb_script_t                script);
+
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-table.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,383 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ *   ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
+ *
+ * on files with these headers:
+ *
+ * # ArabicShaping-8.0.0.txt
+ * # Date: 2015-02-17, 23:33:00 GMT [RP]
+ * # Blocks-8.0.0.txt
+ * # Date: 2014-11-10, 23:04:00 GMT [KW]
+ * UnicodeData.txt does not have a header.
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH
+
+
+#define X       JOINING_TYPE_X
+#define R       JOINING_TYPE_R
+#define U       JOINING_TYPE_U
+#define A       JOINING_GROUP_ALAPH
+#define DR      JOINING_GROUP_DALATH_RISH
+#define L       JOINING_TYPE_L
+#define C       JOINING_TYPE_C
+#define D       JOINING_TYPE_D
+
+static const uint8_t joining_table[] =
+{
+
+#define joining_offset_0x0600u 0
+
+  /* Arabic */
+
+  /* 0600 */ U,U,U,U,U,U,X,X,U,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+  /* 0620 */ D,U,R,R,R,R,D,R,D,R,D,D,D,D,D,R,R,R,R,D,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* 0640 */ C,D,D,D,D,D,D,D,R,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+  /* 0660 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,D,D,X,R,R,R,U,R,R,R,D,D,D,D,D,D,D,D,
+  /* 0680 */ D,D,D,D,D,D,D,D,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,R,D,D,D,D,D,D,
+  /* 06A0 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* 06C0 */ R,D,D,R,R,R,R,R,R,R,R,R,D,R,D,R,D,D,R,R,X,R,X,X,X,X,X,X,X,U,X,X,
+  /* 06E0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,R,R,X,X,X,X,X,X,X,X,X,X,D,D,D,X,X,D,
+
+  /* Syriac */
+
+  /* 0700 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,A,X,D,D,D,DR,DR,R,R,R,D,D,D,D,R,D,
+  /* 0720 */ D,D,D,D,D,D,D,D,R,D,DR,D,R,D,D,DR,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+  /* 0740 */ X,X,X,X,X,X,X,X,X,X,X,X,X,R,D,D,
+
+  /* Arabic Supplement */
+
+  /* 0740 */                                 D,D,D,D,D,D,D,D,D,R,R,R,D,D,D,D,
+  /* 0760 */ D,D,D,D,D,D,D,D,D,D,D,R,R,D,D,D,D,R,D,R,R,D,D,D,R,R,D,D,D,D,D,D,
+
+  /* FILLER */
+
+  /* 0780 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+  /* 07A0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+
+  /* NKo */
+
+  /* 07C0 */ X,X,X,X,X,X,X,X,X,X,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* 07E0 */ D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,C,X,X,X,X,X,
+
+  /* FILLER */
+
+  /* 0800 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+  /* 0820 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+
+  /* Mandaic */
+
+  /* 0840 */ R,D,D,D,D,D,R,R,D,R,D,D,D,D,D,D,D,D,D,D,R,D,U,U,U,X,X,X,X,X,X,X,
+  /* 0860 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+  /* 0880 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+
+  /* Arabic Extended-A */
+
+  /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,
+
+#define joining_offset_0x1806u 693
+
+  /* Mongolian */
+
+  /* 1800 */             U,D,X,X,C,X,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+  /* 1820 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* 1840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* 1860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X,
+  /* 1880 */ U,U,U,U,U,U,U,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* 18A0 */ D,D,D,D,D,D,D,D,D,X,D,
+
+#define joining_offset_0x200cu 858
+
+  /* General Punctuation */
+
+  /* 2000 */                         U,C,
+
+#define joining_offset_0x2066u 860
+
+  /* General Punctuation */
+
+  /* 2060 */             U,U,U,U,
+
+#define joining_offset_0xa840u 864
+
+  /* Phags-pa */
+
+  /* A840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,
+  /* A860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,L,U,
+
+#define joining_offset_0x10ac0u 916
+
+  /* Manichaean */
+
+  /* 10AC0 */ D,D,D,D,D,R,U,R,U,R,R,U,U,L,R,R,R,R,R,D,D,D,D,L,D,D,D,D,D,R,D,D,
+  /* 10AE0 */ D,R,U,U,R,X,X,X,X,X,X,D,D,D,D,R,
+
+#define joining_offset_0x10b80u 964
+
+  /* Psalter Pahlavi */
+
+  /* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X,
+  /* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U,
+
+}; /* Table items: 1012; occupancy: 57% */
+
+
+static unsigned int
+joining_type (hb_codepoint_t u)
+{
+  switch (u >> 12)
+  {
+    case 0x0u:
+      if (hb_in_range (u, 0x0600u, 0x08B4u)) return joining_table[u - 0x0600u + joining_offset_0x0600u];
+      break;
+
+    case 0x1u:
+      if (hb_in_range (u, 0x1806u, 0x18AAu)) return joining_table[u - 0x1806u + joining_offset_0x1806u];
+      break;
+
+    case 0x2u:
+      if (hb_in_range (u, 0x200Cu, 0x200Du)) return joining_table[u - 0x200Cu + joining_offset_0x200cu];
+      if (hb_in_range (u, 0x2066u, 0x2069u)) return joining_table[u - 0x2066u + joining_offset_0x2066u];
+      break;
+
+    case 0xAu:
+      if (hb_in_range (u, 0xA840u, 0xA873u)) return joining_table[u - 0xA840u + joining_offset_0xa840u];
+      break;
+
+    case 0x10u:
+      if (hb_in_range (u, 0x10AC0u, 0x10AEFu)) return joining_table[u - 0x10AC0u + joining_offset_0x10ac0u];
+      if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u];
+      break;
+
+    default:
+      break;
+  }
+  return X;
+}
+
+#undef X
+#undef R
+#undef U
+#undef A
+#undef DR
+#undef L
+#undef C
+#undef D
+
+
+static const uint16_t shaping_table[][4] =
+{
+  {0x0000u, 0x0000u, 0x0000u, 0xFE80u}, /* U+0621 ARABIC LETTER HAMZA ISOLATED FORM */
+  {0x0000u, 0x0000u, 0xFE82u, 0xFE81u}, /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
+  {0x0000u, 0x0000u, 0xFE84u, 0xFE83u}, /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
+  {0x0000u, 0x0000u, 0xFE86u, 0xFE85u}, /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
+  {0x0000u, 0x0000u, 0xFE88u, 0xFE87u}, /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
+  {0xFE8Bu, 0xFE8Cu, 0xFE8Au, 0xFE89u}, /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
+  {0x0000u, 0x0000u, 0xFE8Eu, 0xFE8Du}, /* U+0627 ARABIC LETTER ALEF */
+  {0xFE91u, 0xFE92u, 0xFE90u, 0xFE8Fu}, /* U+0628 ARABIC LETTER BEH */
+  {0x0000u, 0x0000u, 0xFE94u, 0xFE93u}, /* U+0629 ARABIC LETTER TEH MARBUTA */
+  {0xFE97u, 0xFE98u, 0xFE96u, 0xFE95u}, /* U+062A ARABIC LETTER TEH */
+  {0xFE9Bu, 0xFE9Cu, 0xFE9Au, 0xFE99u}, /* U+062B ARABIC LETTER THEH */
+  {0xFE9Fu, 0xFEA0u, 0xFE9Eu, 0xFE9Du}, /* U+062C ARABIC LETTER JEEM */
+  {0xFEA3u, 0xFEA4u, 0xFEA2u, 0xFEA1u}, /* U+062D ARABIC LETTER HAH */
+  {0xFEA7u, 0xFEA8u, 0xFEA6u, 0xFEA5u}, /* U+062E ARABIC LETTER KHAH */
+  {0x0000u, 0x0000u, 0xFEAAu, 0xFEA9u}, /* U+062F ARABIC LETTER DAL */
+  {0x0000u, 0x0000u, 0xFEACu, 0xFEABu}, /* U+0630 ARABIC LETTER THAL */
+  {0x0000u, 0x0000u, 0xFEAEu, 0xFEADu}, /* U+0631 ARABIC LETTER REH */
+  {0x0000u, 0x0000u, 0xFEB0u, 0xFEAFu}, /* U+0632 ARABIC LETTER ZAIN */
+  {0xFEB3u, 0xFEB4u, 0xFEB2u, 0xFEB1u}, /* U+0633 ARABIC LETTER SEEN */
+  {0xFEB7u, 0xFEB8u, 0xFEB6u, 0xFEB5u}, /* U+0634 ARABIC LETTER SHEEN */
+  {0xFEBBu, 0xFEBCu, 0xFEBAu, 0xFEB9u}, /* U+0635 ARABIC LETTER SAD */
+  {0xFEBFu, 0xFEC0u, 0xFEBEu, 0xFEBDu}, /* U+0636 ARABIC LETTER DAD */
+  {0xFEC3u, 0xFEC4u, 0xFEC2u, 0xFEC1u}, /* U+0637 ARABIC LETTER TAH */
+  {0xFEC7u, 0xFEC8u, 0xFEC6u, 0xFEC5u}, /* U+0638 ARABIC LETTER ZAH */
+  {0xFECBu, 0xFECCu, 0xFECAu, 0xFEC9u}, /* U+0639 ARABIC LETTER AIN */
+  {0xFECFu, 0xFED0u, 0xFECEu, 0xFECDu}, /* U+063A ARABIC LETTER GHAIN */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063B  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063C  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063D  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063E  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+063F  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0640  */
+  {0xFED3u, 0xFED4u, 0xFED2u, 0xFED1u}, /* U+0641 ARABIC LETTER FEH */
+  {0xFED7u, 0xFED8u, 0xFED6u, 0xFED5u}, /* U+0642 ARABIC LETTER QAF */
+  {0xFEDBu, 0xFEDCu, 0xFEDAu, 0xFED9u}, /* U+0643 ARABIC LETTER KAF */
+  {0xFEDFu, 0xFEE0u, 0xFEDEu, 0xFEDDu}, /* U+0644 ARABIC LETTER LAM */
+  {0xFEE3u, 0xFEE4u, 0xFEE2u, 0xFEE1u}, /* U+0645 ARABIC LETTER MEEM */
+  {0xFEE7u, 0xFEE8u, 0xFEE6u, 0xFEE5u}, /* U+0646 ARABIC LETTER NOON */
+  {0xFEEBu, 0xFEECu, 0xFEEAu, 0xFEE9u}, /* U+0647 ARABIC LETTER HEH */
+  {0x0000u, 0x0000u, 0xFEEEu, 0xFEEDu}, /* U+0648 ARABIC LETTER WAW */
+  {0xFBE8u, 0xFBE9u, 0xFEF0u, 0xFEEFu}, /* U+0649 ARABIC LETTER */
+  {0xFEF3u, 0xFEF4u, 0xFEF2u, 0xFEF1u}, /* U+064A ARABIC LETTER YEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064B  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064C  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064D  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064E  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+064F  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0650  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0651  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0652  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0653  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0654  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0655  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0656  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0657  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0658  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0659  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065A  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065B  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065C  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065D  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065E  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+065F  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0660  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0661  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0662  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0663  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0664  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0665  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0666  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0667  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0668  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0669  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066A  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066B  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066C  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066D  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066E  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+066F  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0670  */
+  {0x0000u, 0x0000u, 0xFB51u, 0xFB50u}, /* U+0671 ARABIC LETTER ALEF WASLA */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0672  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0673  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0674  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0675  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0676  */
+  {0x0000u, 0x0000u, 0x0000u, 0xFBDDu}, /* U+0677 ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0678  */
+  {0xFB68u, 0xFB69u, 0xFB67u, 0xFB66u}, /* U+0679 ARABIC LETTER TTEH */
+  {0xFB60u, 0xFB61u, 0xFB5Fu, 0xFB5Eu}, /* U+067A ARABIC LETTER TTEHEH */
+  {0xFB54u, 0xFB55u, 0xFB53u, 0xFB52u}, /* U+067B ARABIC LETTER BEEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+067C  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+067D  */
+  {0xFB58u, 0xFB59u, 0xFB57u, 0xFB56u}, /* U+067E ARABIC LETTER PEH */
+  {0xFB64u, 0xFB65u, 0xFB63u, 0xFB62u}, /* U+067F ARABIC LETTER TEHEH */
+  {0xFB5Cu, 0xFB5Du, 0xFB5Bu, 0xFB5Au}, /* U+0680 ARABIC LETTER BEHEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0681  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0682  */
+  {0xFB78u, 0xFB79u, 0xFB77u, 0xFB76u}, /* U+0683 ARABIC LETTER NYEH */
+  {0xFB74u, 0xFB75u, 0xFB73u, 0xFB72u}, /* U+0684 ARABIC LETTER DYEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0685  */
+  {0xFB7Cu, 0xFB7Du, 0xFB7Bu, 0xFB7Au}, /* U+0686 ARABIC LETTER TCHEH */
+  {0xFB80u, 0xFB81u, 0xFB7Fu, 0xFB7Eu}, /* U+0687 ARABIC LETTER TCHEHEH */
+  {0x0000u, 0x0000u, 0xFB89u, 0xFB88u}, /* U+0688 ARABIC LETTER DDAL */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0689  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+068A  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+068B  */
+  {0x0000u, 0x0000u, 0xFB85u, 0xFB84u}, /* U+068C ARABIC LETTER DAHAL */
+  {0x0000u, 0x0000u, 0xFB83u, 0xFB82u}, /* U+068D ARABIC LETTER DDAHAL */
+  {0x0000u, 0x0000u, 0xFB87u, 0xFB86u}, /* U+068E ARABIC LETTER DUL */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+068F  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0690  */
+  {0x0000u, 0x0000u, 0xFB8Du, 0xFB8Cu}, /* U+0691 ARABIC LETTER RREH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0692  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0693  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0694  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0695  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0696  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0697  */
+  {0x0000u, 0x0000u, 0xFB8Bu, 0xFB8Au}, /* U+0698 ARABIC LETTER JEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+0699  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069A  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069B  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069C  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069D  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069E  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+069F  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A0  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A1  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A2  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A3  */
+  {0xFB6Cu, 0xFB6Du, 0xFB6Bu, 0xFB6Au}, /* U+06A4 ARABIC LETTER VEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A5  */
+  {0xFB70u, 0xFB71u, 0xFB6Fu, 0xFB6Eu}, /* U+06A6 ARABIC LETTER PEHEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A7  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06A8  */
+  {0xFB90u, 0xFB91u, 0xFB8Fu, 0xFB8Eu}, /* U+06A9 ARABIC LETTER KEHEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06AA  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06AB  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06AC  */
+  {0xFBD5u, 0xFBD6u, 0xFBD4u, 0xFBD3u}, /* U+06AD ARABIC LETTER NG */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06AE  */
+  {0xFB94u, 0xFB95u, 0xFB93u, 0xFB92u}, /* U+06AF ARABIC LETTER GAF */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B0  */
+  {0xFB9Cu, 0xFB9Du, 0xFB9Bu, 0xFB9Au}, /* U+06B1 ARABIC LETTER NGOEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B2  */
+  {0xFB98u, 0xFB99u, 0xFB97u, 0xFB96u}, /* U+06B3 ARABIC LETTER GUEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B4  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B5  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B6  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B7  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B8  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06B9  */
+  {0x0000u, 0x0000u, 0xFB9Fu, 0xFB9Eu}, /* U+06BA ARABIC LETTER NOON GHUNNA */
+  {0xFBA2u, 0xFBA3u, 0xFBA1u, 0xFBA0u}, /* U+06BB ARABIC LETTER RNOON */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06BC  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06BD  */
+  {0xFBACu, 0xFBADu, 0xFBABu, 0xFBAAu}, /* U+06BE ARABIC LETTER HEH DOACHASHMEE */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06BF  */
+  {0x0000u, 0x0000u, 0xFBA5u, 0xFBA4u}, /* U+06C0 ARABIC LETTER HEH WITH YEH ABOVE */
+  {0xFBA8u, 0xFBA9u, 0xFBA7u, 0xFBA6u}, /* U+06C1 ARABIC LETTER HEH GOAL */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06C2  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06C3  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06C4  */
+  {0x0000u, 0x0000u, 0xFBE1u, 0xFBE0u}, /* U+06C5 ARABIC LETTER KIRGHIZ OE */
+  {0x0000u, 0x0000u, 0xFBDAu, 0xFBD9u}, /* U+06C6 ARABIC LETTER OE */
+  {0x0000u, 0x0000u, 0xFBD8u, 0xFBD7u}, /* U+06C7 ARABIC LETTER U */
+  {0x0000u, 0x0000u, 0xFBDCu, 0xFBDBu}, /* U+06C8 ARABIC LETTER YU */
+  {0x0000u, 0x0000u, 0xFBE3u, 0xFBE2u}, /* U+06C9 ARABIC LETTER KIRGHIZ YU */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06CA  */
+  {0x0000u, 0x0000u, 0xFBDFu, 0xFBDEu}, /* U+06CB ARABIC LETTER VE */
+  {0xFBFEu, 0xFBFFu, 0xFBFDu, 0xFBFCu}, /* U+06CC ARABIC LETTER FARSI YEH */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06CD  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06CE  */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06CF  */
+  {0xFBE6u, 0xFBE7u, 0xFBE5u, 0xFBE4u}, /* U+06D0 ARABIC LETTER E */
+  {0x0000u, 0x0000u, 0x0000u, 0x0000u}, /* U+06D1  */
+  {0x0000u, 0x0000u, 0xFBAFu, 0xFBAEu}, /* U+06D2 ARABIC LETTER YEH BARREE */
+  {0x0000u, 0x0000u, 0xFBB1u, 0xFBB0u}, /* U+06D3 ARABIC LETTER YEH BARREE WITH HAMZA ABOVE */
+};
+
+#define SHAPING_TABLE_FIRST     0x0621u
+#define SHAPING_TABLE_LAST      0x06D3u
+
+
+static const struct ligature_set_t {
+ uint16_t first;
+ struct ligature_pairs_t {
+   uint16_t second;
+   uint16_t ligature;
+ } ligatures[4];
+} ligature_table[] =
+{
+  { 0xFEDFu, {
+    { 0xFE88u, 0xFEF9u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
+    { 0xFE82u, 0xFEF5u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
+    { 0xFE8Eu, 0xFEFBu }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
+    { 0xFE84u, 0xFEF7u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
+  }},
+  { 0xFEE0u, {
+    { 0xFE88u, 0xFEFAu }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
+    { 0xFE82u, 0xFEF6u }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
+    { 0xFE8Eu, 0xFEFCu }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+    { 0xFE84u, 0xFEF8u }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
+  }},
+};
+
+
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */
+
+/* == End of generated table == */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-win1256.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,323 @@
+/*
+ * Copyright © 2014  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_SHAPE_COMPLEX_ARABIC_WIN1256_HH
+
+
+/*
+ * The macros in the first part of this file are generic macros that can
+ * be used to define the bytes for OpenType table data in code in a
+ * readable manner.  We can move the macros to reside with their respective
+ * struct types, but since we only use these to define one data table, the
+ * Windows-1256 Arabic shaping table in this file, we keep them here.
+ */
+
+
+/* First we measure, then we cut. */
+#ifndef OT_MEASURE
+#define OT_MEASURE
+#define OT_TABLE_START                  static const struct TABLE_NAME {
+#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*/
+#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_COUNT(Name, ItemSize)        ((unsigned int) sizeof(((struct TABLE_NAME*)0)->Name) \
+                                         / (unsigned int)(ItemSize) \
+                                         /* OT_ASSERT it's divisible (and positive). */)
+#define OT_DISTANCE(From,To)            ((unsigned int) \
+                                         ((char*)(&((struct TABLE_NAME*)0)->To) - \
+                                          (char*)(&((struct TABLE_NAME*)0)->From)) \
+                                         /* OT_ASSERT it's positive. */)
+#endif
+
+
+#define OT_LABEL(Name) \
+        OT_LABEL_END \
+        OT_LABEL_START(Name)
+
+/* Whenever we receive an argument that is a list, it will expand to
+ * contain commas.  That cannot be passed to another macro because the
+ * commas will throw off the preprocessor.  The solution is to wrap
+ * the passed-in argument in OT_LIST() before passing to the next macro.
+ * Unfortunately this trick requires vararg macros. */
+#define OT_LIST(...) __VA_ARGS__
+
+
+/*
+ * Basic Types
+ */
+
+#define OT_TAG(a,b,c,d) \
+        OT_BYTE(a) OT_BYTE(b) OT_BYTE(c) OT_BYTE(d)
+
+#define OT_OFFSET(From, To) /* Offset from From to To in bytes */ \
+        OT_USHORT(OT_DISTANCE(From, To))
+
+#define OT_GLYPHID /* GlyphID */ \
+        OT_USHORT
+
+#define OT_UARRAY(Name, Items) \
+        OT_LABEL_START(Name) \
+        OT_USHORT(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_LABEL(Name##Data) \
+        Items \
+        OT_LABEL_END
+
+
+/*
+ * Common Types
+ */
+
+#define OT_LOOKUP_FLAG_IGNORE_MARKS     0x08u
+
+#define OT_LOOKUP(Name, LookupType, LookupFlag, SubLookupOffsets) \
+        OT_LABEL_START(Name) \
+        OT_USHORT(LookupType) \
+        OT_USHORT(LookupFlag) \
+        OT_LABEL_END \
+        OT_UARRAY(Name##SubLookupOffsetsArray, OT_LIST(SubLookupOffsets))
+
+#define OT_SUBLOOKUP(Name, SubFormat, Items) \
+        OT_LABEL_START(Name) \
+        OT_USHORT(SubFormat) \
+        Items
+
+#define OT_COVERAGE1(Name, Items) \
+        OT_LABEL_START(Name) \
+        OT_USHORT(1) \
+        OT_LABEL_END \
+        OT_UARRAY(Name##Glyphs, OT_LIST(Items))
+
+
+/*
+ * GSUB
+ */
+
+#define OT_LOOKUP_TYPE_SUBST_SINGLE     1u
+#define OT_LOOKUP_TYPE_SUBST_LIGATURE   4u
+
+#define OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(Name, FromGlyphs, ToGlyphs) \
+        OT_SUBLOOKUP(Name, 2, \
+                OT_OFFSET(Name, Name##Coverage) \
+                OT_LABEL_END \
+                OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \
+        ) \
+        OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \
+        /* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */
+
+#define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \
+        OT_SUBLOOKUP(Name, 1, \
+                OT_OFFSET(Name, Name##Coverage) \
+                OT_LABEL_END \
+                OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \
+        ) \
+        OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \
+        /* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */
+
+#define OT_LIGATURE_SET(Name, LigatureSetOffsets) \
+        OT_UARRAY(Name, OT_LIST(LigatureSetOffsets))
+
+#define OT_LIGATURE(Name, Components, LigGlyph) \
+        OT_LABEL_START(Name) \
+        LigGlyph \
+        OT_LABEL_END \
+        OT_UHEADLESSARRAY(Name##ComponentsArray, OT_LIST(Components))
+
+/*
+ *
+ * Start of Windows-1256 shaping table.
+ *
+ */
+
+/* Table name. */
+#define TABLE_NAME arabic_win1256_gsub_lookups
+
+/* Table manifest. */
+#define MANIFEST(Items) \
+        OT_LABEL_START(manifest) \
+        OT_USHORT(OT_COUNT(manifestData, 6)) \
+        OT_LABEL(manifestData) \
+        Items \
+        OT_LABEL_END
+
+#define MANIFEST_LOOKUP(Tag, Name) \
+        Tag \
+        OT_OFFSET(manifest, Name)
+
+/* Shorthand. */
+#define G       OT_GLYPHID
+
+/*
+ * Table Start
+ */
+OT_TABLE_START
+
+
+/*
+ * Manifest
+ */
+MANIFEST(
+        MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligLookup)
+        MANIFEST_LOOKUP(OT_TAG('i','n','i','t'), initLookup)
+        MANIFEST_LOOKUP(OT_TAG('m','e','d','i'), mediLookup)
+        MANIFEST_LOOKUP(OT_TAG('f','i','n','a'), finaLookup)
+        MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligMarksLookup)
+)
+
+/*
+ * Lookups
+ */
+OT_LOOKUP(initLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
+        OT_OFFSET(initLookup, initmediSubLookup)
+        OT_OFFSET(initLookup, initSubLookup)
+)
+OT_LOOKUP(mediLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
+        OT_OFFSET(mediLookup, initmediSubLookup)
+        OT_OFFSET(mediLookup, mediSubLookup)
+        OT_OFFSET(mediLookup, medifinaLamAlefSubLookup)
+)
+OT_LOOKUP(finaLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
+        OT_OFFSET(finaLookup, finaSubLookup)
+        /* We don't need this one currently as the sequence inherits masks
+         * from the first item.  Just in case we change that in the future
+         * to be smart about Arabic masks when ligating... */
+        OT_OFFSET(finaLookup, medifinaLamAlefSubLookup)
+)
+OT_LOOKUP(rligLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, OT_LOOKUP_FLAG_IGNORE_MARKS,
+        OT_OFFSET(rligLookup, lamAlefLigaturesSubLookup)
+)
+OT_LOOKUP(rligMarksLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, 0,
+        OT_OFFSET(rligMarksLookup, shaddaLigaturesSubLookup)
+)
+
+/*
+ * init/medi/fina forms
+ */
+OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initmediSubLookup,
+        G(198)  G(200)  G(201)  G(202)  G(203)  G(204)  G(205)  G(206)  G(211)
+        G(212)  G(213)  G(214)  G(223)  G(225)  G(227)  G(228)  G(236)  G(237),
+        G(162)  G(4)    G(5)    G(5)    G(6)    G(7)    G(9)    G(11)   G(13)
+        G(14)   G(15)   G(26)   G(140)  G(141)  G(142)  G(143)  G(154)  G(154)
+)
+OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initSubLookup,
+        G(218)  G(219)  G(221)  G(222)  G(229),
+        G(27)   G(30)   G(128)  G(131)  G(144)
+)
+OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(mediSubLookup,
+        G(218)  G(219)  G(221)  G(222)  G(229),
+        G(28)   G(31)   G(129)  G(138)  G(149)
+)
+OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(finaSubLookup,
+        G(194)  G(195)  G(197)  G(198)  G(199)  G(201)  G(204)  G(205)  G(206)
+        G(218)  G(219)  G(229)  G(236)  G(237),
+        G(2)    G(1)    G(3)    G(181)  G(0)    G(159)  G(8)    G(10)   G(12)
+        G(29)   G(127)  G(152) G(160)   G(156)
+)
+OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(medifinaLamAlefSubLookup,
+        G(165)  G(178)  G(180)  G(252),
+        G(170)  G(179)  G(185)  G(255)
+)
+
+/*
+ * Lam+Alef ligatures
+ */
+OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(lamAlefLigaturesSubLookup,
+        G(225),
+        OT_OFFSET(lamAlefLigaturesSubLookup, lamLigatureSet)
+)
+OT_LIGATURE_SET(lamLigatureSet,
+        OT_OFFSET(lamLigatureSet, lamInitLigature1)
+        OT_OFFSET(lamLigatureSet, lamInitLigature2)
+        OT_OFFSET(lamLigatureSet, lamInitLigature3)
+        OT_OFFSET(lamLigatureSet, lamInitLigature4)
+)
+OT_LIGATURE(lamInitLigature1, G(199), G(165))
+OT_LIGATURE(lamInitLigature2, G(195), G(178))
+OT_LIGATURE(lamInitLigature3, G(194), G(180))
+OT_LIGATURE(lamInitLigature4, G(197), G(252))
+
+/*
+ * Shadda ligatures
+ */
+OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(shaddaLigaturesSubLookup,
+        G(248),
+        OT_OFFSET(shaddaLigaturesSubLookup, shaddaLigatureSet)
+)
+OT_LIGATURE_SET(shaddaLigatureSet,
+        OT_OFFSET(shaddaLigatureSet, shaddaLigature1)
+        OT_OFFSET(shaddaLigatureSet, shaddaLigature2)
+        OT_OFFSET(shaddaLigatureSet, shaddaLigature3)
+)
+OT_LIGATURE(shaddaLigature1, G(243), G(172))
+OT_LIGATURE(shaddaLigature2, G(245), G(173))
+OT_LIGATURE(shaddaLigature3, G(246), G(175))
+
+/*
+ * Table end
+ */
+OT_TABLE_END
+
+
+/*
+ * Clean up
+ */
+#undef OT_TABLE_START
+#undef OT_TABLE_END
+#undef OT_LABEL_START
+#undef OT_LABEL_END
+#undef OT_BYTE
+#undef OT_USHORT
+#undef OT_DISTANCE
+#undef OT_COUNT
+
+/*
+ * Include a second time to get the table data...
+ */
+#if 0
+#include "hb-private.hh" /* Make check-includes.sh happy. */
+#endif
+#ifdef OT_MEASURE
+#include "hb-ot-shape-complex-arabic-win1256.hh"
+#endif
+
+#define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,389 @@
+/*
+ * Copyright © 2010,2012  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
+ */
+
+#include "hb-ot-shape-complex-arabic-private.hh"
+#include "hb-ot-shape-private.hh"
+
+
+/* buffer var allocations */
+#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
+
+
+/*
+ * Joining types:
+ */
+
+/*
+ * Bits used in the joining tables
+ */
+enum hb_arabic_joining_type_t {
+  JOINING_TYPE_U                = 0,
+  JOINING_TYPE_L                = 1,
+  JOINING_TYPE_R                = 2,
+  JOINING_TYPE_D                = 3,
+  JOINING_TYPE_C                = JOINING_TYPE_D,
+  JOINING_GROUP_ALAPH           = 4,
+  JOINING_GROUP_DALATH_RISH     = 5,
+  NUM_STATE_MACHINE_COLS        = 6,
+
+  JOINING_TYPE_T = 7,
+  JOINING_TYPE_X = 8  /* means: use general-category to choose between U or T. */
+};
+
+#include "hb-ot-shape-complex-arabic-table.hh"
+
+static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
+{
+  unsigned int j_type = joining_type(u);
+  if (likely (j_type != JOINING_TYPE_X))
+    return j_type;
+
+  return (FLAG_SAFE(gen_cat) &
+          (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
+           FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
+           FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))
+         ) ?  JOINING_TYPE_T : JOINING_TYPE_U;
+}
+
+#define FEATURE_IS_SYRIAC(tag) hb_in_range<unsigned char> ((unsigned char) (tag), '2', '3')
+
+static const hb_tag_t arabic_features[] =
+{
+  HB_TAG('i','s','o','l'),
+  HB_TAG('f','i','n','a'),
+  HB_TAG('f','i','n','2'),
+  HB_TAG('f','i','n','3'),
+  HB_TAG('m','e','d','i'),
+  HB_TAG('m','e','d','2'),
+  HB_TAG('i','n','i','t'),
+  HB_TAG_NONE
+};
+
+
+/* Same order as the feature array */
+enum {
+  ISOL,
+  FINA,
+  FIN2,
+  FIN3,
+  MEDI,
+  MED2,
+  INIT,
+
+  NONE,
+
+  ARABIC_NUM_FEATURES = NONE
+};
+
+static const struct arabic_state_table_entry {
+        uint8_t prev_action;
+        uint8_t curr_action;
+        uint16_t next_state;
+} arabic_state_table[][NUM_STATE_MACHINE_COLS] =
+{
+  /*   jt_U,          jt_L,          jt_R,          jt_D,          jg_ALAPH,      jg_DALATH_RISH */
+
+  /* State 0: prev was U, not willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
+
+  /* State 1: prev was R or ISOL/ALAPH, not willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
+
+  /* State 2: prev was D/L in ISOL form, willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
+
+  /* State 3: prev was D in FINA form, willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
+
+  /* State 4: prev was FINA ALAPH, not willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
+
+  /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
+
+  /* State 6: prev was DALATH/RISH, not willing to join. */
+  { {NONE,NONE,0}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
+};
+
+
+static void
+nuke_joiners (const hb_ot_shape_plan_t *plan,
+              hb_font_t *font,
+              hb_buffer_t *buffer);
+
+static void
+arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
+                       hb_font_t *font,
+                       hb_buffer_t *buffer);
+
+static void
+collect_features_arabic (hb_ot_shape_planner_t *plan)
+{
+  hb_ot_map_builder_t *map = &plan->map;
+
+  /* We apply features according to the Arabic spec, with pauses
+   * in between most.
+   *
+   * The pause between init/medi/... and rlig is required.  See eg:
+   * https://bugzilla.mozilla.org/show_bug.cgi?id=644184
+   *
+   * The pauses between init/medi/... themselves are not necessarily
+   * needed as only one of those features is applied to any character.
+   * The only difference it makes is when fonts have contextual
+   * substitutions.  We now follow the order of the spec, which makes
+   * for better experience if that's what Uniscribe is doing.
+   *
+   * At least for Arabic, looks like Uniscribe has a pause between
+   * rlig and calt.  Otherwise the IranNastaliq's ALLAH ligature won't
+   * work.  However, testing shows that rlig and calt are applied
+   * together for Mongolian in Uniscribe.  As such, we only add a
+   * pause for Arabic, not other scripts.
+   */
+
+  map->add_gsub_pause (nuke_joiners);
+
+  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+
+  map->add_gsub_pause (NULL);
+
+  for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
+  {
+    bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
+    map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
+    map->add_gsub_pause (NULL);
+  }
+
+  map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
+  if (plan->props.script == HB_SCRIPT_ARABIC)
+    map->add_gsub_pause (arabic_fallback_shape);
+
+  map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+  map->add_gsub_pause (NULL);
+
+  /* The spec includes 'cswh'.  Earlier versions of Windows
+   * used to enable this by default, but testing suggests
+   * that Windows 8 and later do not enable it by default,
+   * and spec now says 'Off by default'.
+   * We disabled this in ae23c24c32.
+   * Note that IranNastaliq uses this feature extensively
+   * to fixup broken glyph sequences.  Oh well...
+   * Test case: U+0643,U+0640,U+0631. */
+  //map->add_global_bool_feature (HB_TAG('c','s','w','h'));
+  map->add_global_bool_feature (HB_TAG('m','s','e','t'));
+}
+
+#include "hb-ot-shape-complex-arabic-fallback.hh"
+
+struct arabic_shape_plan_t
+{
+  ASSERT_POD ();
+
+  /* The "+ 1" in the next array is to accommodate for the "NONE" command,
+   * which is not an OpenType feature, but this simplifies the code by not
+   * having to do a "if (... < NONE) ..." and just rely on the fact that
+   * mask_array[NONE] == 0. */
+  hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
+
+  bool do_fallback;
+  arabic_fallback_plan_t *fallback_plan;
+};
+
+void *
+data_create_arabic (const hb_ot_shape_plan_t *plan)
+{
+  arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t));
+  if (unlikely (!arabic_plan))
+    return NULL;
+
+  arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
+  for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
+    arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
+    arabic_plan->do_fallback = arabic_plan->do_fallback &&
+                               (FEATURE_IS_SYRIAC (arabic_features[i]) ||
+                                plan->map.needs_fallback (arabic_features[i]));
+  }
+
+  return arabic_plan;
+}
+
+void
+data_destroy_arabic (void *data)
+{
+  arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) data;
+
+  arabic_fallback_plan_destroy (arabic_plan->fallback_plan);
+
+  free (data);
+}
+
+static void
+arabic_joining (hb_buffer_t *buffer)
+{
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int prev = (unsigned int) -1, state = 0;
+
+  /* Check pre-context */
+  for (unsigned int i = 0; i < buffer->context_len[0]; i++)
+  {
+    unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
+
+    if (unlikely (this_type == JOINING_TYPE_T))
+      continue;
+
+    const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+    state = entry->next_state;
+    break;
+  }
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    unsigned int this_type = get_joining_type (info[i].codepoint, _hb_glyph_info_get_general_category (&info[i]));
+
+    if (unlikely (this_type == JOINING_TYPE_T)) {
+      info[i].arabic_shaping_action() = NONE;
+      continue;
+    }
+
+    const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+
+    if (entry->prev_action != NONE && prev != (unsigned int) -1)
+      info[prev].arabic_shaping_action() = entry->prev_action;
+
+    info[i].arabic_shaping_action() = entry->curr_action;
+
+    prev = i;
+    state = entry->next_state;
+  }
+
+  for (unsigned int i = 0; i < buffer->context_len[1]; i++)
+  {
+    unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[1][i]));
+
+    if (unlikely (this_type == JOINING_TYPE_T))
+      continue;
+
+    const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+    if (entry->prev_action != NONE && prev != (unsigned int) -1)
+      info[prev].arabic_shaping_action() = entry->prev_action;
+    break;
+  }
+}
+
+static void
+mongolian_variation_selectors (hb_buffer_t *buffer)
+{
+  /* Copy arabic_shaping_action() from base to Mongolian variation selectors. */
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 1; i < count; i++)
+    if (unlikely (hb_in_range (info[i].codepoint, 0x180Bu, 0x180Du)))
+      info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action();
+}
+
+void
+setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan,
+                         hb_buffer_t               *buffer,
+                         hb_script_t                script)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
+
+  arabic_joining (buffer);
+  if (script == HB_SCRIPT_MONGOLIAN)
+    mongolian_variation_selectors (buffer);
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()];
+
+  HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
+}
+
+static void
+setup_masks_arabic (const hb_ot_shape_plan_t *plan,
+                    hb_buffer_t              *buffer,
+                    hb_font_t                *font HB_UNUSED)
+{
+  const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
+  setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
+}
+
+
+static void
+nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
+              hb_font_t *font HB_UNUSED,
+              hb_buffer_t *buffer)
+{
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    if (_hb_glyph_info_is_zwj (&info[i]))
+      _hb_glyph_info_flip_joiners (&info[i]);
+}
+
+static void
+arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
+                       hb_font_t *font,
+                       hb_buffer_t *buffer)
+{
+  const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
+
+  if (!arabic_plan->do_fallback)
+    return;
+
+retry:
+  arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) hb_atomic_ptr_get (&arabic_plan->fallback_plan);
+  if (unlikely (!fallback_plan))
+  {
+    /* This sucks.  We need a font to build the fallback plan... */
+    fallback_plan = arabic_fallback_plan_create (plan, font);
+    if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (arabic_plan))->fallback_plan, NULL, fallback_plan))) {
+      arabic_fallback_plan_destroy (fallback_plan);
+      goto retry;
+    }
+  }
+
+  arabic_fallback_plan_shape (fallback_plan, font, buffer);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
+{
+  "arabic",
+  collect_features_arabic,
+  NULL, /* override_features */
+  data_create_arabic,
+  data_destroy_arabic,
+  NULL, /* preprocess_text_arabic */
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+  NULL, /* decompose */
+  NULL, /* compose */
+  setup_masks_arabic,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
+  true, /* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-default.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2010,2012  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
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
+{
+  "default",
+  NULL, /* collect_features */
+  NULL, /* override_features */
+  NULL, /* data_create */
+  NULL, /* data_destroy */
+  NULL, /* preprocess_text */
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+  NULL, /* decompose */
+  NULL, /* compose */
+  NULL, /* setup_masks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
+  true, /* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hangul.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,423 @@
+/*
+ * Copyright © 2013  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
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+/* Hangul shaper */
+
+
+/* Same order as the feature array below */
+enum {
+  NONE,
+
+  LJMO,
+  VJMO,
+  TJMO,
+
+  FIRST_HANGUL_FEATURE = LJMO,
+  HANGUL_FEATURE_COUNT = TJMO + 1
+};
+
+static const hb_tag_t hangul_features[HANGUL_FEATURE_COUNT] =
+{
+  HB_TAG_NONE,
+  HB_TAG('l','j','m','o'),
+  HB_TAG('v','j','m','o'),
+  HB_TAG('t','j','m','o')
+};
+
+static void
+collect_features_hangul (hb_ot_shape_planner_t *plan)
+{
+  hb_ot_map_builder_t *map = &plan->map;
+
+  for (unsigned int i = FIRST_HANGUL_FEATURE; i < HANGUL_FEATURE_COUNT; i++)
+    map->add_feature (hangul_features[i], 1, F_NONE);
+}
+
+static void
+override_features_hangul (hb_ot_shape_planner_t *plan)
+{
+  /* Uniscribe does not apply 'calt' for Hangul, and certain fonts
+   * (Noto Sans CJK, Source Sans Han, etc) apply all of jamo lookups
+   * in calt, which is not desirable. */
+  plan->map.add_feature (HB_TAG('c','a','l','t'), 0, F_GLOBAL);
+}
+
+struct hangul_shape_plan_t
+{
+  ASSERT_POD ();
+
+  hb_mask_t mask_array[HANGUL_FEATURE_COUNT];
+};
+
+static void *
+data_create_hangul (const hb_ot_shape_plan_t *plan)
+{
+  hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t));
+  if (unlikely (!hangul_plan))
+    return NULL;
+
+  for (unsigned int i = 0; i < HANGUL_FEATURE_COUNT; i++)
+    hangul_plan->mask_array[i] = plan->map.get_1_mask (hangul_features[i]);
+
+  return hangul_plan;
+}
+
+static void
+data_destroy_hangul (void *data)
+{
+  free (data);
+}
+
+/* Constants for algorithmic hangul syllable [de]composition. */
+#define LBase 0x1100u
+#define VBase 0x1161u
+#define TBase 0x11A7u
+#define LCount 19u
+#define VCount 21u
+#define TCount 28u
+#define SBase 0xAC00u
+#define NCount (VCount * TCount)
+#define SCount (LCount * NCount)
+
+#define isCombiningL(u) (hb_in_range ((u), LBase, LBase+LCount-1))
+#define isCombiningV(u) (hb_in_range ((u), VBase, VBase+VCount-1))
+#define isCombiningT(u) (hb_in_range ((u), TBase+1, TBase+TCount-1))
+#define isCombinedS(u) (hb_in_range ((u), SBase, SBase+SCount-1))
+
+#define isL(u) (hb_in_ranges ((u), 0x1100u, 0x115Fu, 0xA960u, 0xA97Cu))
+#define isV(u) (hb_in_ranges ((u), 0x1160u, 0x11A7u, 0xD7B0u, 0xD7C6u))
+#define isT(u) (hb_in_ranges ((u), 0x11A8u, 0x11FFu, 0xD7CBu, 0xD7FBu))
+
+#define isHangulTone(u) (hb_in_range ((u), 0x302Eu, 0x302Fu))
+
+/* buffer var allocations */
+#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
+
+static bool
+is_zero_width_char (hb_font_t *font,
+                    hb_codepoint_t unicode)
+{
+  hb_codepoint_t glyph;
+  return hb_font_get_glyph (font, unicode, 0, &glyph) && hb_font_get_glyph_h_advance (font, glyph) == 0;
+}
+
+static void
+preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
+                        hb_buffer_t              *buffer,
+                        hb_font_t                *font)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, hangul_shaping_feature);
+
+  /* Hangul syllables come in two shapes: LV, and LVT.  Of those:
+   *
+   *   - LV can be precomposed, or decomposed.  Lets call those
+   *     <LV> and <L,V>,
+   *   - LVT can be fully precomposed, partically precomposed, or
+   *     fully decomposed.  Ie. <LVT>, <LV,T>, or <L,V,T>.
+   *
+   * The composition / decomposition is mechanical.  However, not
+   * all <L,V> sequences compose, and not all <LV,T> sequences
+   * compose.
+   *
+   * Here are the specifics:
+   *
+   *   - <L>: U+1100..115F, U+A960..A97F
+   *   - <V>: U+1160..11A7, U+D7B0..D7C7
+   *   - <T>: U+11A8..11FF, U+D7CB..D7FB
+   *
+   *   - Only the <L,V> sequences for the 11xx ranges combine.
+   *   - Only <LV,T> sequences for T in U+11A8..11C3 combine.
+   *
+   * Here is what we want to accomplish in this shaper:
+   *
+   *   - If the whole syllable can be precomposed, do that,
+   *   - Otherwise, fully decompose and apply ljmo/vjmo/tjmo features.
+   *   - If a valid syllable is followed by a Hangul tone mark, reorder the tone
+   *     mark to precede the whole syllable - unless it is a zero-width glyph, in
+   *     which case we leave it untouched, assuming it's designed to overstrike.
+   *
+   * That is, of the different possible syllables:
+   *
+   *   <L>
+   *   <L,V>
+   *   <L,V,T>
+   *   <LV>
+   *   <LVT>
+   *   <LV, T>
+   *
+   * - <L> needs no work.
+   *
+   * - <LV> and <LVT> can stay the way they are if the font supports them, otherwise we
+   *   should fully decompose them if font supports.
+   *
+   * - <L,V> and <L,V,T> we should compose if the whole thing can be composed.
+   *
+   * - <LV,T> we should compose if the whole thing can be composed, otherwise we should
+   *   decompose.
+   */
+
+  buffer->clear_output ();
+  unsigned int start = 0, end = 0; /* Extent of most recently seen syllable;
+                                    * valid only if start < end
+                                    */
+  unsigned int count = buffer->len;
+
+  for (buffer->idx = 0; buffer->idx < count;)
+  {
+    hb_codepoint_t u = buffer->cur().codepoint;
+
+    if (isHangulTone (u))
+    {
+      /*
+       * We could cache the width of the tone marks and the existence of dotted-circle,
+       * but the use of the Hangul tone mark characters seems to be rare enough that
+       * I didn't bother for now.
+       */
+      if (start < end && end == buffer->out_len)
+      {
+        /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
+        buffer->next_glyph ();
+        if (!is_zero_width_char (font, u))
+        {
+          buffer->merge_out_clusters (start, end + 1);
+          hb_glyph_info_t *info = buffer->out_info;
+          hb_glyph_info_t tone = info[end];
+          memmove (&info[start + 1], &info[start], (end - start) * sizeof (hb_glyph_info_t));
+          info[start] = tone;
+        }
+      }
+      else
+      {
+        /* No valid syllable as base for tone mark; try to insert dotted circle. */
+        if (font->has_glyph (0x25CCu))
+        {
+          hb_codepoint_t chars[2];
+          if (!is_zero_width_char (font, u)) {
+            chars[0] = u;
+            chars[1] = 0x25CCu;
+          } else {
+            chars[0] = 0x25CCu;
+            chars[1] = u;
+          }
+          buffer->replace_glyphs (1, 2, chars);
+        }
+        else
+        {
+          /* No dotted circle available in the font; just leave tone mark untouched. */
+          buffer->next_glyph ();
+        }
+      }
+      start = end = buffer->out_len;
+      continue;
+    }
+
+    start = buffer->out_len; /* Remember current position as a potential syllable start;
+                              * will only be used if we set end to a later position.
+                              */
+
+    if (isL (u) && buffer->idx + 1 < count)
+    {
+      hb_codepoint_t l = u;
+      hb_codepoint_t v = buffer->cur(+1).codepoint;
+      if (isV (v))
+      {
+        /* Have <L,V> or <L,V,T>. */
+        hb_codepoint_t t = 0;
+        unsigned int tindex = 0;
+        if (buffer->idx + 2 < count)
+        {
+          t = buffer->cur(+2).codepoint;
+          if (isT (t))
+            tindex = t - TBase; /* Only used if isCombiningT (t); otherwise invalid. */
+          else
+            t = 0; /* The next character was not a trailing jamo. */
+        }
+
+        /* We've got a syllable <L,V,T?>; see if it can potentially be composed. */
+        if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t)))
+        {
+          /* Try to compose; if this succeeds, end is set to start+1. */
+          hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex;
+          if (font->has_glyph (s))
+          {
+            buffer->replace_glyphs (t ? 3 : 2, 1, &s);
+            if (unlikely (buffer->in_error))
+              return;
+            end = start + 1;
+            continue;
+          }
+        }
+
+        /* We didn't compose, either because it's an Old Hangul syllable without a
+         * precomposed character in Unicode, or because the font didn't support the
+         * necessary precomposed glyph.
+         * Set jamo features on the individual glyphs, and advance past them.
+         */
+        buffer->cur().hangul_shaping_feature() = LJMO;
+        buffer->next_glyph ();
+        buffer->cur().hangul_shaping_feature() = VJMO;
+        buffer->next_glyph ();
+        if (t)
+        {
+          buffer->cur().hangul_shaping_feature() = TJMO;
+          buffer->next_glyph ();
+          end = start + 3;
+        }
+        else
+          end = start + 2;
+        if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
+          buffer->merge_out_clusters (start, end);
+        continue;
+      }
+    }
+
+    else if (isCombinedS (u))
+    {
+      /* Have <LV>, <LVT>, or <LV,T> */
+      hb_codepoint_t s = u;
+      bool has_glyph = font->has_glyph (s);
+      unsigned int lindex = (s - SBase) / NCount;
+      unsigned int nindex = (s - SBase) % NCount;
+      unsigned int vindex = nindex / TCount;
+      unsigned int tindex = nindex % TCount;
+
+      if (!tindex &&
+          buffer->idx + 1 < count &&
+          isCombiningT (buffer->cur(+1).codepoint))
+      {
+        /* <LV,T>, try to combine. */
+        unsigned int new_tindex = buffer->cur(+1).codepoint - TBase;
+        hb_codepoint_t new_s = s + new_tindex;
+        if (font->has_glyph (new_s))
+        {
+          buffer->replace_glyphs (2, 1, &new_s);
+          if (unlikely (buffer->in_error))
+            return;
+          end = start + 1;
+          continue;
+        }
+      }
+
+      /* Otherwise, decompose if font doesn't support <LV> or <LVT>,
+       * or if having non-combining <LV,T>.  Note that we already handled
+       * combining <LV,T> above. */
+      if (!has_glyph ||
+          (!tindex &&
+           buffer->idx + 1 < count &&
+           isT (buffer->cur(+1).codepoint)))
+      {
+        hb_codepoint_t decomposed[3] = {LBase + lindex,
+                                        VBase + vindex,
+                                        TBase + tindex};
+        if (font->has_glyph (decomposed[0]) &&
+            font->has_glyph (decomposed[1]) &&
+            (!tindex || font->has_glyph (decomposed[2])))
+        {
+          unsigned int s_len = tindex ? 3 : 2;
+          buffer->replace_glyphs (1, s_len, decomposed);
+          if (unlikely (buffer->in_error))
+            return;
+
+          /* We decomposed S: apply jamo features to the individual glyphs
+           * that are now in buffer->out_info.
+           */
+          hb_glyph_info_t *info = buffer->out_info;
+
+          /* If we decomposed an LV because of a non-combining T following,
+           * we want to include this T in the syllable.
+           */
+          if (has_glyph && !tindex)
+          {
+            buffer->next_glyph ();
+            s_len++;
+          }
+          end = start + s_len;
+
+          unsigned int i = start;
+          info[i++].hangul_shaping_feature() = LJMO;
+          info[i++].hangul_shaping_feature() = VJMO;
+          if (i < end)
+            info[i++].hangul_shaping_feature() = TJMO;
+          if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
+            buffer->merge_out_clusters (start, end);
+          continue;
+        }
+      }
+
+      if (has_glyph)
+      {
+        /* We didn't decompose the S, so just advance past it. */
+        end = start + 1;
+        buffer->next_glyph ();
+        continue;
+      }
+    }
+
+    /* Didn't find a recognizable syllable, so we leave end <= start;
+     * this will prevent tone-mark reordering happening.
+     */
+    buffer->next_glyph ();
+  }
+  buffer->swap_buffers ();
+}
+
+static void
+setup_masks_hangul (const hb_ot_shape_plan_t *plan,
+                    hb_buffer_t              *buffer,
+                    hb_font_t                *font HB_UNUSED)
+{
+  const hangul_shape_plan_t *hangul_plan = (const hangul_shape_plan_t *) plan->data;
+
+  if (likely (hangul_plan))
+  {
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    for (unsigned int i = 0; i < count; i++, info++)
+      info->mask |= hangul_plan->mask_array[info->hangul_shaping_feature()];
+  }
+
+  HB_BUFFER_DEALLOCATE_VAR (buffer, hangul_shaping_feature);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
+{
+  "hangul",
+  collect_features_hangul,
+  override_features_hangul,
+  data_create_hangul, /* data_create */
+  data_destroy_hangul, /* data_destroy */
+  preprocess_text_hangul,
+  HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
+  NULL, /* decompose */
+  NULL, /* compose */
+  setup_masks_hangul, /* setup_masks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+  false, /* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hebrew.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2010,2012  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
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+static bool
+compose_hebrew (const hb_ot_shape_normalize_context_t *c,
+                hb_codepoint_t  a,
+                hb_codepoint_t  b,
+                hb_codepoint_t *ab)
+{
+  /* Hebrew presentation-form shaping.
+   * https://bugzilla.mozilla.org/show_bug.cgi?id=728866
+   * Hebrew presentation forms with dagesh, for characters U+05D0..05EA;
+   * Note that some letters do not have a dagesh presForm encoded.
+   */
+  static const hb_codepoint_t sDageshForms[0x05EAu - 0x05D0u + 1] = {
+    0xFB30u, /* ALEF */
+    0xFB31u, /* BET */
+    0xFB32u, /* GIMEL */
+    0xFB33u, /* DALET */
+    0xFB34u, /* HE */
+    0xFB35u, /* VAV */
+    0xFB36u, /* ZAYIN */
+    0x0000u, /* HET */
+    0xFB38u, /* TET */
+    0xFB39u, /* YOD */
+    0xFB3Au, /* FINAL KAF */
+    0xFB3Bu, /* KAF */
+    0xFB3Cu, /* LAMED */
+    0x0000u, /* FINAL MEM */
+    0xFB3Eu, /* MEM */
+    0x0000u, /* FINAL NUN */
+    0xFB40u, /* NUN */
+    0xFB41u, /* SAMEKH */
+    0x0000u, /* AYIN */
+    0xFB43u, /* FINAL PE */
+    0xFB44u, /* PE */
+    0x0000u, /* FINAL TSADI */
+    0xFB46u, /* TSADI */
+    0xFB47u, /* QOF */
+    0xFB48u, /* RESH */
+    0xFB49u, /* SHIN */
+    0xFB4Au /* TAV */
+  };
+
+  bool found = c->unicode->compose (a, b, ab);
+
+  if (!found && !c->plan->has_mark)
+  {
+      /* Special-case Hebrew presentation forms that are excluded from
+       * standard normalization, but wanted for old fonts. */
+      switch (b) {
+      case 0x05B4u: /* HIRIQ */
+          if (a == 0x05D9u) { /* YOD */
+              *ab = 0xFB1Du;
+              found = true;
+          }
+          break;
+      case 0x05B7u: /* patah */
+          if (a == 0x05F2u) { /* YIDDISH YOD YOD */
+              *ab = 0xFB1Fu;
+              found = true;
+          } else if (a == 0x05D0u) { /* ALEF */
+              *ab = 0xFB2Eu;
+              found = true;
+          }
+          break;
+      case 0x05B8u: /* QAMATS */
+          if (a == 0x05D0u) { /* ALEF */
+              *ab = 0xFB2Fu;
+              found = true;
+          }
+          break;
+      case 0x05B9u: /* HOLAM */
+          if (a == 0x05D5u) { /* VAV */
+              *ab = 0xFB4Bu;
+              found = true;
+          }
+          break;
+      case 0x05BCu: /* DAGESH */
+          if (a >= 0x05D0u && a <= 0x05EAu) {
+              *ab = sDageshForms[a - 0x05D0u];
+              found = (*ab != 0);
+          } else if (a == 0xFB2Au) { /* SHIN WITH SHIN DOT */
+              *ab = 0xFB2Cu;
+              found = true;
+          } else if (a == 0xFB2Bu) { /* SHIN WITH SIN DOT */
+              *ab = 0xFB2Du;
+              found = true;
+          }
+          break;
+      case 0x05BFu: /* RAFE */
+          switch (a) {
+          case 0x05D1u: /* BET */
+              *ab = 0xFB4Cu;
+              found = true;
+              break;
+          case 0x05DBu: /* KAF */
+              *ab = 0xFB4Du;
+              found = true;
+              break;
+          case 0x05E4u: /* PE */
+              *ab = 0xFB4Eu;
+              found = true;
+              break;
+          }
+          break;
+      case 0x05C1u: /* SHIN DOT */
+          if (a == 0x05E9u) { /* SHIN */
+              *ab = 0xFB2Au;
+              found = true;
+          } else if (a == 0xFB49u) { /* SHIN WITH DAGESH */
+              *ab = 0xFB2Cu;
+              found = true;
+          }
+          break;
+      case 0x05C2u: /* SIN DOT */
+          if (a == 0x05E9u) { /* SHIN */
+              *ab = 0xFB2Bu;
+              found = true;
+          } else if (a == 0xFB49u) { /* SHIN WITH DAGESH */
+              *ab = 0xFB2Du;
+              found = true;
+          }
+          break;
+      }
+  }
+
+  return found;
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
+{
+  "hebrew",
+  NULL, /* collect_features */
+  NULL, /* override_features */
+  NULL, /* data_create */
+  NULL, /* data_destroy */
+  NULL, /* preprocess_text */
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+  NULL, /* decompose */
+  compose_hebrew,
+  NULL, /* setup_masks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
+  true, /* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-machine.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1762 @@
+
+#line 1 "hb-ot-shape-complex-indic-machine.rl"
+/*
+ * Copyright © 2011,2012  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_SHAPE_COMPLEX_INDIC_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#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,
+        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,
+        4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u,
+        16u, 16u, 8u, 8u, 1u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u,
+        3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u,
+        3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 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, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 3u, 31u, 3u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u,
+        3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u,
+        3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 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, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+        4u, 14u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u,
+        4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u,
+        4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 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, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+        4u, 14u, 3u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u,
+        3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u,
+        3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 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, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u,
+        1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+        1u, 16u, 3u, 31u, 1u, 31u, 3u, 31u, 1u, 31u, 4u, 14u, 5u, 10u, 9u, 10u,
+        9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 1u, 16u, 3u, 31u, 3u, 31u,
+        4u, 31u, 3u, 31u, 3u, 31u, 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, 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,
+        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,
+        5, 1, 1, 5, 1, 1, 5, 1,
+        1, 1, 31, 29, 29, 28, 16, 29,
+        29, 28, 16, 29, 29, 28, 16, 29,
+        29, 28, 16, 29, 29, 28, 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, 28, 11, 29, 29, 16,
+        16, 16, 16, 16, 29, 29, 16, 16,
+        16, 16, 16, 29, 29, 16, 16, 16,
+        16, 16, 29, 29, 16, 16, 16, 16,
+        16, 29, 29, 29, 29, 28, 16, 29,
+        29, 28, 16, 29, 29, 28, 16, 29,
+        29, 28, 16, 29, 29, 28, 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, 28, 11, 29, 29, 16,
+        16, 16, 16, 16, 29, 29, 16, 16,
+        16, 16, 16, 29, 29, 16, 16, 16,
+        16, 16, 29, 29, 16, 16, 16, 16,
+        11, 16, 29, 29, 28, 16, 29, 29,
+        28, 16, 29, 29, 28, 16, 29, 29,
+        28, 16, 29, 29, 28, 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, 28, 11, 29, 29, 16, 16,
+        16, 16, 16, 29, 29, 16, 16, 16,
+        16, 16, 29, 29, 16, 16, 16, 16,
+        16, 29, 29, 16, 16, 16, 16, 16,
+        11, 29, 11, 29, 29, 28, 16, 29,
+        29, 28, 16, 29, 29, 28, 16, 29,
+        29, 28, 16, 29, 29, 28, 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, 28, 11, 29, 29, 16,
+        16, 16, 16, 16, 29, 29, 16, 16,
+        16, 16, 16, 29, 29, 16, 16, 16,
+        16, 16, 29, 29, 16, 16, 16, 16,
+        16, 29, 31, 29, 31, 11, 6, 2,
+        1, 2, 2, 1, 6, 16, 29, 29,
+        28, 29, 29, 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
+};
+
+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, 1091, 1121, 1151, 1180, 1197,
+        1227, 1257, 1286, 1303, 1333, 1363, 1392, 1409,
+        1439, 1469, 1498, 1515, 1545, 1575, 1604, 1615,
+        1626, 1633, 1636, 1638, 1641, 1644, 1646, 1653,
+        1665, 1674, 1681, 1690, 1702, 1715, 1728, 1740,
+        1751, 1764, 1776, 1787, 1800, 1812, 1823, 1836,
+        1848, 1859, 1872, 1889, 1918, 1930, 1960, 1990,
+        2007, 2024, 2041, 2058, 2075, 2105, 2135, 2152,
+        2169, 2186, 2203, 2220, 2250, 2280, 2297, 2314,
+        2331, 2348, 2365, 2395, 2425, 2442, 2459, 2476,
+        2493, 2510, 2540, 2570, 2600, 2630, 2659, 2676,
+        2706, 2736, 2765, 2782, 2812, 2842, 2871, 2888,
+        2918, 2948, 2977, 2994, 3024, 3054, 3083, 3094,
+        3105, 3112, 3115, 3117, 3120, 3123, 3125, 3132,
+        3144, 3153, 3160, 3169, 3181, 3194, 3207, 3219,
+        3230, 3243, 3255, 3266, 3279, 3291, 3302, 3315,
+        3327, 3338, 3351, 3368, 3397, 3409, 3439, 3469,
+        3486, 3503, 3520, 3537, 3554, 3584, 3614, 3631,
+        3648, 3665, 3682, 3699, 3729, 3759, 3776, 3793,
+        3810, 3827, 3844, 3874, 3904, 3921, 3938, 3955,
+        3972, 3984, 4001, 4031, 4061, 4090, 4107, 4137,
+        4167, 4196, 4213, 4243, 4273, 4302, 4319, 4349,
+        4379, 4408, 4425, 4455, 4485, 4514, 4525, 4536,
+        4543, 4546, 4548, 4551, 4554, 4556, 4563, 4575,
+        4584, 4591, 4600, 4612, 4625, 4638, 4650, 4661,
+        4674, 4686, 4697, 4710, 4722, 4733, 4746, 4758,
+        4769, 4782, 4799, 4828, 4840, 4870, 4900, 4917,
+        4934, 4951, 4968, 4985, 5015, 5045, 5062, 5079,
+        5096, 5113, 5130, 5160, 5190, 5207, 5224, 5241,
+        5258, 5275, 5305, 5335, 5352, 5369, 5386, 5403,
+        5420, 5432, 5462, 5474, 5504, 5534, 5563, 5580,
+        5610, 5640, 5669, 5686, 5716, 5746, 5775, 5792,
+        5822, 5852, 5881, 5898, 5928, 5958, 5987, 5998,
+        6009, 6016, 6019, 6021, 6024, 6027, 6029, 6036,
+        6048, 6057, 6064, 6073, 6085, 6098, 6111, 6123,
+        6134, 6147, 6159, 6170, 6183, 6195, 6206, 6219,
+        6231, 6242, 6255, 6272, 6301, 6313, 6343, 6373,
+        6390, 6407, 6424, 6441, 6458, 6488, 6518, 6535,
+        6552, 6569, 6586, 6603, 6633, 6663, 6680, 6697,
+        6714, 6731, 6748, 6778, 6808, 6825, 6842, 6859,
+        6876, 6893, 6923, 6955, 6985, 7017, 7029, 7036,
+        7039, 7041, 7044, 7047, 7049, 7056, 7073, 7103,
+        7133, 7162, 7192, 7222, 7239, 7252, 7264, 7275,
+        7288, 7300, 7311, 7324, 7336, 7347, 7360, 7372,
+        7383, 7395, 7404, 7411, 7420, 7432, 7449, 7458,
+        7465, 7472, 7475, 7477, 7480, 7483, 7485
+};
+
+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,
+        40, 39, 57, 39, 58, 39, 59, 53,
+        53, 54, 40, 39, 60, 39, 61, 39,
+        62, 50, 50, 51, 40, 39, 63, 39,
+        64, 39, 65, 47, 47, 48, 40, 39,
+        66, 39, 67, 39, 68, 44, 44, 45,
+        40, 39, 39, 39, 39, 39, 68, 39,
+        68, 44, 44, 45, 40, 39, 39, 39,
+        39, 69, 68, 39, 70, 44, 44, 45,
+        40, 39, 39, 39, 39, 39, 70, 39,
+        70, 44, 44, 45, 40, 39, 39, 39,
+        39, 71, 70, 39, 72, 44, 44, 45,
+        40, 39, 39, 39, 39, 39, 72, 39,
+        72, 44, 44, 45, 40, 39, 39, 39,
+        39, 73, 72, 39, 74, 44, 44, 45,
+        40, 39, 39, 39, 39, 39, 74, 39,
+        74, 44, 44, 45, 40, 39, 39, 39,
+        39, 75, 74, 39, 76, 44, 44, 45,
+        40, 39, 39, 39, 39, 39, 76, 39,
+        76, 44, 44, 45, 40, 39, 39, 39,
+        39, 77, 76, 39, 79, 78, 80, 81,
+        78, 78, 78, 78, 78, 78, 78, 78,
+        78, 78, 78, 78, 78, 80, 78, 79,
+        78, 78, 78, 78, 82, 78, 83, 83,
+        84, 79, 78, 86, 86, 84, 85, 84,
+        85, 87, 87, 88, 79, 78, 89, 89,
+        88, 78, 88, 78, 90, 90, 91, 79,
+        78, 92, 92, 91, 78, 91, 78, 93,
+        93, 94, 79, 78, 95, 95, 94, 78,
+        94, 78, 96, 78, 78, 78, 79, 78,
+        97, 78, 98, 78, 99, 93, 93, 94,
+        79, 78, 100, 78, 101, 78, 102, 90,
+        90, 91, 79, 78, 103, 78, 104, 78,
+        105, 87, 87, 88, 79, 78, 106, 78,
+        107, 78, 108, 83, 83, 84, 79, 78,
+        78, 78, 78, 78, 108, 78, 108, 83,
+        83, 84, 79, 78, 78, 78, 78, 109,
+        108, 78, 110, 83, 83, 84, 79, 78,
+        78, 78, 78, 78, 110, 78, 110, 83,
+        83, 84, 79, 78, 78, 78, 78, 111,
+        110, 78, 112, 83, 83, 84, 79, 78,
+        78, 78, 78, 78, 112, 78, 112, 83,
+        83, 84, 79, 78, 78, 78, 78, 113,
+        112, 78, 114, 83, 83, 84, 79, 78,
+        78, 78, 78, 78, 114, 78, 114, 83,
+        83, 84, 79, 78, 78, 78, 78, 115,
+        114, 78, 116, 83, 83, 84, 79, 78,
+        78, 78, 78, 78, 116, 78, 118, 117,
+        119, 120, 117, 117, 117, 117, 117, 117,
+        117, 117, 117, 117, 117, 117, 117, 119,
+        117, 118, 117, 117, 117, 117, 121, 117,
+        122, 122, 123, 118, 117, 124, 124, 123,
+        117, 123, 117, 125, 125, 126, 118, 117,
+        127, 127, 126, 117, 126, 117, 128, 128,
+        129, 118, 117, 130, 130, 129, 117, 129,
+        117, 131, 131, 132, 118, 117, 133, 133,
+        132, 117, 132, 117, 134, 117, 117, 117,
+        118, 117, 135, 117, 136, 117, 137, 131,
+        131, 132, 118, 117, 138, 117, 139, 117,
+        140, 128, 128, 129, 118, 117, 141, 117,
+        142, 117, 143, 125, 125, 126, 118, 117,
+        144, 117, 145, 117, 146, 122, 122, 123,
+        118, 117, 117, 117, 117, 117, 146, 117,
+        146, 122, 122, 123, 118, 117, 117, 117,
+        117, 147, 146, 117, 148, 122, 122, 123,
+        118, 117, 117, 117, 117, 117, 148, 117,
+        148, 122, 122, 123, 118, 117, 117, 117,
+        117, 149, 148, 117, 150, 122, 122, 123,
+        118, 117, 117, 117, 117, 117, 150, 117,
+        150, 122, 122, 123, 118, 117, 117, 117,
+        117, 151, 150, 117, 152, 122, 122, 123,
+        118, 117, 117, 117, 117, 117, 152, 117,
+        152, 122, 122, 123, 118, 117, 117, 117,
+        117, 153, 152, 117, 154, 122, 122, 123,
+        118, 117, 117, 117, 117, 117, 154, 117,
+        154, 122, 122, 123, 118, 117, 117, 117,
+        117, 155, 154, 117, 116, 83, 83, 84,
+        79, 78, 78, 78, 78, 156, 116, 78,
+        86, 86, 84, 1, 0, 114, 83, 83,
+        84, 157, 0, 0, 0, 0, 0, 114,
+        0, 114, 83, 83, 84, 157, 0, 0,
+        0, 0, 158, 114, 0, 159, 159, 160,
+        1, 0, 7, 7, 160, 0, 161, 161,
+        162, 157, 0, 163, 163, 162, 0, 162,
+        0, 164, 164, 165, 157, 0, 166, 166,
+        165, 0, 165, 0, 167, 167, 168, 157,
+        0, 169, 169, 168, 0, 168, 0, 157,
+        0, 170, 171, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        170, 0, 157, 0, 0, 0, 0, 172,
+        0, 173, 0, 0, 0, 157, 0, 174,
+        0, 175, 0, 176, 167, 167, 168, 157,
+        0, 177, 0, 178, 0, 179, 164, 164,
+        165, 157, 0, 180, 0, 181, 0, 182,
+        161, 161, 162, 157, 0, 183, 0, 184,
+        0, 186, 185, 188, 189, 190, 191, 192,
+        193, 84, 79, 194, 195, 196, 196, 156,
+        197, 198, 199, 200, 201, 187, 187, 187,
+        187, 187, 187, 187, 187, 187, 187, 187,
+        187, 202, 187, 204, 205, 206, 207, 6,
+        1, 208, 209, 203, 203, 38, 210, 203,
+        203, 211, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 212,
+        203, 213, 205, 214, 214, 6, 1, 208,
+        209, 203, 203, 203, 210, 203, 203, 211,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 212, 203, 205,
+        214, 214, 6, 1, 208, 209, 203, 203,
+        203, 210, 203, 203, 211, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 212, 203, 215, 203, 203, 203,
+        19, 216, 203, 1, 208, 209, 203, 203,
+        203, 217, 203, 215, 203, 218, 219, 220,
+        221, 6, 1, 208, 209, 203, 203, 36,
+        222, 203, 203, 211, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 212, 203, 223, 219, 224, 224, 6,
+        1, 208, 209, 203, 203, 203, 222, 203,
+        203, 211, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 212,
+        203, 219, 224, 224, 6, 1, 208, 209,
+        203, 203, 203, 222, 203, 203, 211, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 212, 203, 225, 203,
+        203, 203, 19, 226, 203, 1, 208, 209,
+        203, 203, 203, 217, 203, 225, 203, 227,
+        228, 229, 230, 6, 1, 208, 209, 203,
+        203, 34, 231, 203, 203, 211, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 212, 203, 232, 228, 233,
+        233, 6, 1, 208, 209, 203, 203, 203,
+        231, 203, 203, 211, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 212, 203, 228, 233, 233, 6, 1,
+        208, 209, 203, 203, 203, 231, 203, 203,
+        211, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 212, 203,
+        234, 203, 203, 203, 19, 235, 203, 1,
+        208, 209, 203, 203, 203, 217, 203, 234,
+        203, 236, 237, 238, 239, 6, 1, 208,
+        209, 203, 203, 32, 240, 203, 203, 211,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 212, 203, 241,
+        237, 242, 242, 6, 1, 208, 209, 203,
+        203, 203, 240, 203, 203, 211, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 212, 203, 237, 242, 242,
+        6, 1, 208, 209, 203, 203, 203, 240,
+        203, 203, 211, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        212, 203, 243, 203, 203, 203, 19, 244,
+        203, 1, 208, 209, 203, 203, 203, 217,
+        203, 243, 203, 245, 246, 247, 248, 6,
+        1, 208, 209, 203, 203, 30, 249, 203,
+        203, 211, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 212,
+        203, 250, 246, 251, 251, 6, 1, 208,
+        209, 203, 203, 203, 249, 203, 203, 211,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 212, 203, 246,
+        251, 251, 6, 1, 208, 209, 203, 203,
+        203, 249, 203, 203, 211, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 212, 203, 19, 252, 203, 1,
+        208, 209, 203, 203, 203, 217, 203, 253,
+        253, 203, 1, 208, 209, 203, 203, 203,
+        217, 203, 254, 203, 203, 255, 208, 209,
+        203, 208, 209, 203, 256, 203, 208, 257,
+        203, 208, 258, 203, 208, 203, 254, 203,
+        203, 203, 208, 209, 203, 259, 203, 260,
+        261, 203, 1, 208, 209, 203, 203, 4,
+        203, 3, 203, 253, 253, 203, 1, 208,
+        209, 203, 253, 253, 203, 1, 208, 209,
+        203, 259, 203, 253, 253, 203, 1, 208,
+        209, 203, 259, 203, 260, 253, 203, 1,
+        208, 209, 203, 203, 4, 203, 19, 203,
+        262, 262, 6, 1, 208, 209, 203, 203,
+        203, 217, 203, 263, 28, 264, 265, 9,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        28, 264, 265, 9, 1, 208, 209, 203,
+        203, 203, 217, 203, 264, 264, 9, 1,
+        208, 209, 203, 203, 203, 217, 203, 266,
+        25, 267, 268, 12, 1, 208, 209, 203,
+        203, 203, 217, 203, 25, 267, 268, 12,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        267, 267, 12, 1, 208, 209, 203, 203,
+        203, 217, 203, 269, 22, 270, 271, 15,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        22, 270, 271, 15, 1, 208, 209, 203,
+        203, 203, 217, 203, 270, 270, 15, 1,
+        208, 209, 203, 203, 203, 217, 203, 272,
+        19, 253, 273, 203, 1, 208, 209, 203,
+        203, 203, 217, 203, 19, 253, 273, 203,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        253, 274, 203, 1, 208, 209, 203, 203,
+        203, 217, 203, 19, 203, 253, 253, 203,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        2, 3, 203, 203, 19, 252, 203, 1,
+        208, 209, 203, 203, 203, 217, 203, 2,
+        203, 246, 251, 251, 6, 1, 208, 209,
+        203, 203, 203, 249, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 212, 203, 246, 251,
+        251, 6, 1, 208, 209, 203, 203, 203,
+        249, 203, 245, 246, 251, 251, 6, 1,
+        208, 209, 203, 203, 203, 249, 203, 203,
+        211, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 212, 203,
+        245, 246, 247, 251, 6, 1, 208, 209,
+        203, 203, 30, 249, 203, 203, 211, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 212, 203, 243, 203,
+        275, 203, 262, 262, 6, 1, 208, 209,
+        203, 203, 203, 217, 203, 243, 203, 243,
+        203, 203, 203, 253, 253, 203, 1, 208,
+        209, 203, 203, 203, 217, 203, 243, 203,
+        243, 203, 203, 203, 253, 276, 203, 1,
+        208, 209, 203, 203, 203, 217, 203, 243,
+        203, 243, 203, 275, 203, 253, 253, 203,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        243, 203, 243, 3, 203, 203, 19, 244,
+        203, 1, 208, 209, 203, 203, 203, 217,
+        203, 243, 203, 236, 237, 242, 242, 6,
+        1, 208, 209, 203, 203, 203, 240, 203,
+        203, 211, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 212,
+        203, 236, 237, 238, 242, 6, 1, 208,
+        209, 203, 203, 32, 240, 203, 203, 211,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 212, 203, 234,
+        203, 277, 203, 262, 262, 6, 1, 208,
+        209, 203, 203, 203, 217, 203, 234, 203,
+        234, 203, 203, 203, 253, 253, 203, 1,
+        208, 209, 203, 203, 203, 217, 203, 234,
+        203, 234, 203, 203, 203, 253, 278, 203,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        234, 203, 234, 203, 277, 203, 253, 253,
+        203, 1, 208, 209, 203, 203, 203, 217,
+        203, 234, 203, 234, 3, 203, 203, 19,
+        235, 203, 1, 208, 209, 203, 203, 203,
+        217, 203, 234, 203, 227, 228, 233, 233,
+        6, 1, 208, 209, 203, 203, 203, 231,
+        203, 203, 211, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        212, 203, 227, 228, 229, 233, 6, 1,
+        208, 209, 203, 203, 34, 231, 203, 203,
+        211, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 212, 203,
+        225, 203, 279, 203, 262, 262, 6, 1,
+        208, 209, 203, 203, 203, 217, 203, 225,
+        203, 225, 203, 203, 203, 253, 253, 203,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        225, 203, 225, 203, 203, 203, 253, 280,
+        203, 1, 208, 209, 203, 203, 203, 217,
+        203, 225, 203, 225, 203, 279, 203, 253,
+        253, 203, 1, 208, 209, 203, 203, 203,
+        217, 203, 225, 203, 225, 3, 203, 203,
+        19, 226, 203, 1, 208, 209, 203, 203,
+        203, 217, 203, 225, 203, 218, 219, 224,
+        224, 6, 1, 208, 209, 203, 203, 203,
+        222, 203, 203, 211, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 212, 203, 218, 219, 220, 224, 6,
+        1, 208, 209, 203, 203, 36, 222, 203,
+        203, 211, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 212,
+        203, 215, 203, 281, 203, 262, 262, 6,
+        1, 208, 209, 203, 203, 203, 217, 203,
+        215, 203, 215, 203, 203, 203, 253, 253,
+        203, 1, 208, 209, 203, 203, 203, 217,
+        203, 215, 203, 215, 203, 203, 203, 253,
+        282, 203, 1, 208, 209, 203, 203, 203,
+        217, 203, 215, 203, 215, 203, 281, 203,
+        253, 253, 203, 1, 208, 209, 203, 203,
+        203, 217, 203, 215, 203, 215, 3, 203,
+        203, 19, 216, 203, 1, 208, 209, 203,
+        203, 203, 217, 203, 215, 203, 204, 205,
+        214, 214, 6, 1, 208, 209, 203, 203,
+        203, 210, 203, 203, 211, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 212, 203, 204, 205, 206, 214,
+        6, 1, 208, 209, 203, 203, 38, 210,
+        203, 203, 211, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        212, 203, 284, 285, 286, 287, 45, 40,
+        288, 289, 283, 283, 77, 290, 283, 283,
+        291, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 292, 283,
+        293, 285, 294, 287, 45, 40, 288, 289,
+        283, 283, 283, 290, 283, 283, 291, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 292, 283, 285, 294,
+        287, 45, 40, 288, 289, 283, 283, 283,
+        290, 283, 283, 291, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 292, 283, 295, 283, 283, 283, 58,
+        296, 283, 40, 288, 289, 283, 283, 283,
+        297, 283, 295, 283, 298, 299, 300, 301,
+        45, 40, 288, 289, 283, 283, 75, 302,
+        283, 283, 291, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        292, 283, 303, 299, 304, 304, 45, 40,
+        288, 289, 283, 283, 283, 302, 283, 283,
+        291, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 292, 283,
+        299, 304, 304, 45, 40, 288, 289, 283,
+        283, 283, 302, 283, 283, 291, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 292, 283, 305, 283, 283,
+        283, 58, 306, 283, 40, 288, 289, 283,
+        283, 283, 297, 283, 305, 283, 307, 308,
+        309, 310, 45, 40, 288, 289, 283, 283,
+        73, 311, 283, 283, 291, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 292, 283, 312, 308, 313, 313,
+        45, 40, 288, 289, 283, 283, 283, 311,
+        283, 283, 291, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        292, 283, 308, 313, 313, 45, 40, 288,
+        289, 283, 283, 283, 311, 283, 283, 291,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 292, 283, 314,
+        283, 283, 283, 58, 315, 283, 40, 288,
+        289, 283, 283, 283, 297, 283, 314, 283,
+        316, 317, 318, 319, 45, 40, 288, 289,
+        283, 283, 71, 320, 283, 283, 291, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 292, 283, 321, 317,
+        322, 322, 45, 40, 288, 289, 283, 283,
+        283, 320, 283, 283, 291, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 292, 283, 317, 322, 322, 45,
+        40, 288, 289, 283, 283, 283, 320, 283,
+        283, 291, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 292,
+        283, 323, 283, 283, 283, 58, 324, 283,
+        40, 288, 289, 283, 283, 283, 297, 283,
+        323, 283, 325, 326, 327, 328, 45, 40,
+        288, 289, 283, 283, 69, 329, 283, 283,
+        291, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 292, 283,
+        330, 326, 331, 331, 45, 40, 288, 289,
+        283, 283, 283, 329, 283, 283, 291, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 292, 283, 326, 331,
+        331, 45, 40, 288, 289, 283, 283, 283,
+        329, 283, 283, 291, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 292, 283, 58, 332, 283, 40, 288,
+        289, 283, 283, 283, 297, 283, 333, 333,
+        283, 40, 288, 289, 283, 283, 283, 297,
+        283, 334, 283, 283, 335, 288, 289, 283,
+        288, 289, 283, 336, 283, 288, 337, 283,
+        288, 338, 283, 288, 283, 334, 283, 283,
+        283, 288, 289, 283, 339, 283, 340, 341,
+        283, 40, 288, 289, 283, 283, 43, 283,
+        42, 283, 333, 333, 283, 40, 288, 289,
+        283, 333, 333, 283, 40, 288, 289, 283,
+        339, 283, 333, 333, 283, 40, 288, 289,
+        283, 339, 283, 340, 333, 283, 40, 288,
+        289, 283, 283, 43, 283, 58, 283, 342,
+        342, 45, 40, 288, 289, 283, 283, 283,
+        297, 283, 343, 67, 344, 345, 48, 40,
+        288, 289, 283, 283, 283, 297, 283, 67,
+        344, 345, 48, 40, 288, 289, 283, 283,
+        283, 297, 283, 344, 344, 48, 40, 288,
+        289, 283, 283, 283, 297, 283, 346, 64,
+        347, 348, 51, 40, 288, 289, 283, 283,
+        283, 297, 283, 64, 347, 348, 51, 40,
+        288, 289, 283, 283, 283, 297, 283, 347,
+        347, 51, 40, 288, 289, 283, 283, 283,
+        297, 283, 349, 61, 350, 351, 54, 40,
+        288, 289, 283, 283, 283, 297, 283, 61,
+        350, 351, 54, 40, 288, 289, 283, 283,
+        283, 297, 283, 350, 350, 54, 40, 288,
+        289, 283, 283, 283, 297, 283, 352, 58,
+        333, 353, 283, 40, 288, 289, 283, 283,
+        283, 297, 283, 58, 333, 353, 283, 40,
+        288, 289, 283, 283, 283, 297, 283, 333,
+        354, 283, 40, 288, 289, 283, 283, 283,
+        297, 283, 58, 283, 333, 333, 283, 40,
+        288, 289, 283, 283, 283, 297, 283, 41,
+        42, 283, 283, 58, 332, 283, 40, 288,
+        289, 283, 283, 283, 297, 283, 41, 283,
+        326, 331, 331, 45, 40, 288, 289, 283,
+        283, 283, 329, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 292, 283, 326, 331, 331,
+        45, 40, 288, 289, 283, 283, 283, 329,
+        283, 325, 326, 331, 331, 45, 40, 288,
+        289, 283, 283, 283, 329, 283, 283, 291,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 292, 283, 325,
+        326, 327, 331, 45, 40, 288, 289, 283,
+        283, 69, 329, 283, 283, 291, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 292, 283, 323, 283, 355,
+        283, 342, 342, 45, 40, 288, 289, 283,
+        283, 283, 297, 283, 323, 283, 323, 283,
+        283, 283, 333, 333, 283, 40, 288, 289,
+        283, 283, 283, 297, 283, 323, 283, 323,
+        283, 283, 283, 333, 356, 283, 40, 288,
+        289, 283, 283, 283, 297, 283, 323, 283,
+        323, 283, 355, 283, 333, 333, 283, 40,
+        288, 289, 283, 283, 283, 297, 283, 323,
+        283, 323, 42, 283, 283, 58, 324, 283,
+        40, 288, 289, 283, 283, 283, 297, 283,
+        323, 283, 316, 317, 322, 322, 45, 40,
+        288, 289, 283, 283, 283, 320, 283, 283,
+        291, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 292, 283,
+        316, 317, 318, 322, 45, 40, 288, 289,
+        283, 283, 71, 320, 283, 283, 291, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 292, 283, 314, 283,
+        357, 283, 342, 342, 45, 40, 288, 289,
+        283, 283, 283, 297, 283, 314, 283, 314,
+        283, 283, 283, 333, 333, 283, 40, 288,
+        289, 283, 283, 283, 297, 283, 314, 283,
+        314, 283, 283, 283, 333, 358, 283, 40,
+        288, 289, 283, 283, 283, 297, 283, 314,
+        283, 314, 283, 357, 283, 333, 333, 283,
+        40, 288, 289, 283, 283, 283, 297, 283,
+        314, 283, 314, 42, 283, 283, 58, 315,
+        283, 40, 288, 289, 283, 283, 283, 297,
+        283, 314, 283, 307, 308, 313, 313, 45,
+        40, 288, 289, 283, 283, 283, 311, 283,
+        283, 291, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 292,
+        283, 307, 308, 309, 313, 45, 40, 288,
+        289, 283, 283, 73, 311, 283, 283, 291,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 292, 283, 305,
+        283, 359, 283, 342, 342, 45, 40, 288,
+        289, 283, 283, 283, 297, 283, 305, 283,
+        305, 283, 283, 283, 333, 333, 283, 40,
+        288, 289, 283, 283, 283, 297, 283, 305,
+        283, 305, 283, 283, 283, 333, 360, 283,
+        40, 288, 289, 283, 283, 283, 297, 283,
+        305, 283, 305, 283, 359, 283, 333, 333,
+        283, 40, 288, 289, 283, 283, 283, 297,
+        283, 305, 283, 305, 42, 283, 283, 58,
+        306, 283, 40, 288, 289, 283, 283, 283,
+        297, 283, 305, 283, 298, 299, 304, 304,
+        45, 40, 288, 289, 283, 283, 283, 302,
+        283, 283, 291, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        292, 283, 298, 299, 300, 304, 45, 40,
+        288, 289, 283, 283, 75, 302, 283, 283,
+        291, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 283, 292, 283,
+        295, 283, 361, 283, 342, 342, 45, 40,
+        288, 289, 283, 283, 283, 297, 283, 295,
+        283, 295, 283, 283, 283, 333, 333, 283,
+        40, 288, 289, 283, 283, 283, 297, 283,
+        295, 283, 295, 283, 283, 283, 333, 362,
+        283, 40, 288, 289, 283, 283, 283, 297,
+        283, 295, 283, 295, 283, 361, 283, 333,
+        333, 283, 40, 288, 289, 283, 283, 283,
+        297, 283, 295, 283, 76, 44, 44, 45,
+        40, 283, 283, 283, 283, 283, 76, 283,
+        295, 42, 283, 283, 58, 296, 283, 40,
+        288, 289, 283, 283, 283, 297, 283, 295,
+        283, 284, 285, 294, 287, 45, 40, 288,
+        289, 283, 283, 283, 290, 283, 283, 291,
+        283, 283, 283, 283, 283, 283, 283, 283,
+        283, 283, 283, 283, 283, 292, 283, 364,
+        191, 365, 365, 84, 79, 194, 195, 363,
+        363, 363, 197, 363, 363, 200, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 202, 363, 191, 365, 365,
+        84, 79, 194, 195, 363, 363, 363, 197,
+        363, 363, 200, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        202, 363, 366, 363, 363, 363, 98, 367,
+        363, 79, 194, 195, 363, 363, 363, 368,
+        363, 366, 363, 369, 370, 371, 372, 84,
+        79, 194, 195, 363, 363, 115, 373, 363,
+        363, 200, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 202,
+        363, 374, 370, 375, 375, 84, 79, 194,
+        195, 363, 363, 363, 373, 363, 363, 200,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 202, 363, 370,
+        375, 375, 84, 79, 194, 195, 363, 363,
+        363, 373, 363, 363, 200, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 202, 363, 376, 363, 363, 363,
+        98, 377, 363, 79, 194, 195, 363, 363,
+        363, 368, 363, 376, 363, 378, 379, 380,
+        381, 84, 79, 194, 195, 363, 363, 113,
+        382, 363, 363, 200, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 202, 363, 383, 379, 384, 384, 84,
+        79, 194, 195, 363, 363, 363, 382, 363,
+        363, 200, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 202,
+        363, 379, 384, 384, 84, 79, 194, 195,
+        363, 363, 363, 382, 363, 363, 200, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 202, 363, 385, 363,
+        363, 363, 98, 386, 363, 79, 194, 195,
+        363, 363, 363, 368, 363, 385, 363, 387,
+        388, 389, 390, 84, 79, 194, 195, 363,
+        363, 111, 391, 363, 363, 200, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 202, 363, 392, 388, 393,
+        393, 84, 79, 194, 195, 363, 363, 363,
+        391, 363, 363, 200, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 202, 363, 388, 393, 393, 84, 79,
+        194, 195, 363, 363, 363, 391, 363, 363,
+        200, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 202, 363,
+        394, 363, 363, 363, 98, 395, 363, 79,
+        194, 195, 363, 363, 363, 368, 363, 394,
+        363, 396, 397, 398, 399, 84, 79, 194,
+        195, 363, 363, 109, 400, 363, 363, 200,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 202, 363, 401,
+        397, 402, 402, 84, 79, 194, 195, 363,
+        363, 363, 400, 363, 363, 200, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 202, 363, 397, 402, 402,
+        84, 79, 194, 195, 363, 363, 363, 400,
+        363, 363, 200, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        202, 363, 98, 403, 363, 79, 194, 195,
+        363, 363, 363, 368, 363, 404, 404, 363,
+        79, 194, 195, 363, 363, 363, 368, 363,
+        405, 363, 363, 406, 194, 195, 363, 194,
+        195, 363, 407, 363, 194, 408, 363, 194,
+        409, 363, 194, 363, 405, 363, 363, 363,
+        194, 195, 363, 410, 363, 411, 412, 363,
+        79, 194, 195, 363, 363, 82, 363, 81,
+        363, 404, 404, 363, 79, 194, 195, 363,
+        404, 404, 363, 79, 194, 195, 363, 410,
+        363, 404, 404, 363, 79, 194, 195, 363,
+        410, 363, 411, 404, 363, 79, 194, 195,
+        363, 363, 82, 363, 98, 363, 413, 413,
+        84, 79, 194, 195, 363, 363, 363, 368,
+        363, 414, 107, 415, 416, 88, 79, 194,
+        195, 363, 363, 363, 368, 363, 107, 415,
+        416, 88, 79, 194, 195, 363, 363, 363,
+        368, 363, 415, 415, 88, 79, 194, 195,
+        363, 363, 363, 368, 363, 417, 104, 418,
+        419, 91, 79, 194, 195, 363, 363, 363,
+        368, 363, 104, 418, 419, 91, 79, 194,
+        195, 363, 363, 363, 368, 363, 418, 418,
+        91, 79, 194, 195, 363, 363, 363, 368,
+        363, 420, 101, 421, 422, 94, 79, 194,
+        195, 363, 363, 363, 368, 363, 101, 421,
+        422, 94, 79, 194, 195, 363, 363, 363,
+        368, 363, 421, 421, 94, 79, 194, 195,
+        363, 363, 363, 368, 363, 423, 98, 404,
+        424, 363, 79, 194, 195, 363, 363, 363,
+        368, 363, 98, 404, 424, 363, 79, 194,
+        195, 363, 363, 363, 368, 363, 404, 425,
+        363, 79, 194, 195, 363, 363, 363, 368,
+        363, 98, 363, 404, 404, 363, 79, 194,
+        195, 363, 363, 363, 368, 363, 80, 81,
+        363, 363, 98, 403, 363, 79, 194, 195,
+        363, 363, 363, 368, 363, 80, 363, 397,
+        402, 402, 84, 79, 194, 195, 363, 363,
+        363, 400, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 202, 363, 397, 402, 402, 84,
+        79, 194, 195, 363, 363, 363, 400, 363,
+        396, 397, 402, 402, 84, 79, 194, 195,
+        363, 363, 363, 400, 363, 363, 200, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 202, 363, 396, 397,
+        398, 402, 84, 79, 194, 195, 363, 363,
+        109, 400, 363, 363, 200, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 202, 363, 394, 363, 426, 363,
+        413, 413, 84, 79, 194, 195, 363, 363,
+        363, 368, 363, 394, 363, 394, 363, 363,
+        363, 404, 404, 363, 79, 194, 195, 363,
+        363, 363, 368, 363, 394, 363, 394, 363,
+        363, 363, 404, 427, 363, 79, 194, 195,
+        363, 363, 363, 368, 363, 394, 363, 394,
+        363, 426, 363, 404, 404, 363, 79, 194,
+        195, 363, 363, 363, 368, 363, 394, 363,
+        394, 81, 363, 363, 98, 395, 363, 79,
+        194, 195, 363, 363, 363, 368, 363, 394,
+        363, 387, 388, 393, 393, 84, 79, 194,
+        195, 363, 363, 363, 391, 363, 363, 200,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 202, 363, 387,
+        388, 389, 393, 84, 79, 194, 195, 363,
+        363, 111, 391, 363, 363, 200, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 202, 363, 385, 363, 428,
+        363, 413, 413, 84, 79, 194, 195, 363,
+        363, 363, 368, 363, 385, 363, 385, 363,
+        363, 363, 404, 404, 363, 79, 194, 195,
+        363, 363, 363, 368, 363, 385, 363, 385,
+        363, 363, 363, 404, 429, 363, 79, 194,
+        195, 363, 363, 363, 368, 363, 385, 363,
+        385, 363, 428, 363, 404, 404, 363, 79,
+        194, 195, 363, 363, 363, 368, 363, 385,
+        363, 385, 81, 363, 363, 98, 386, 363,
+        79, 194, 195, 363, 363, 363, 368, 363,
+        385, 363, 378, 379, 384, 384, 84, 79,
+        194, 195, 363, 363, 363, 382, 363, 363,
+        200, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 202, 363,
+        378, 379, 380, 384, 84, 79, 194, 195,
+        363, 363, 113, 382, 363, 363, 200, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 202, 363, 376, 363,
+        430, 363, 413, 413, 84, 79, 194, 195,
+        363, 363, 363, 368, 363, 376, 363, 376,
+        363, 363, 363, 404, 404, 363, 79, 194,
+        195, 363, 363, 363, 368, 363, 376, 363,
+        376, 363, 363, 363, 404, 431, 363, 79,
+        194, 195, 363, 363, 363, 368, 363, 376,
+        363, 376, 363, 430, 363, 404, 404, 363,
+        79, 194, 195, 363, 363, 363, 368, 363,
+        376, 363, 376, 81, 363, 363, 98, 377,
+        363, 79, 194, 195, 363, 363, 363, 368,
+        363, 376, 363, 369, 370, 375, 375, 84,
+        79, 194, 195, 363, 363, 363, 373, 363,
+        363, 200, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 202,
+        363, 369, 370, 371, 375, 84, 79, 194,
+        195, 363, 363, 115, 373, 363, 363, 200,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 202, 363, 366,
+        363, 432, 363, 413, 413, 84, 79, 194,
+        195, 363, 363, 363, 368, 363, 366, 363,
+        366, 363, 363, 363, 404, 404, 363, 79,
+        194, 195, 363, 363, 363, 368, 363, 366,
+        363, 366, 363, 363, 363, 404, 433, 363,
+        79, 194, 195, 363, 363, 363, 368, 363,
+        366, 363, 366, 363, 432, 363, 404, 404,
+        363, 79, 194, 195, 363, 363, 363, 368,
+        363, 366, 363, 366, 81, 363, 363, 98,
+        367, 363, 79, 194, 195, 363, 363, 363,
+        368, 363, 366, 363, 116, 83, 83, 84,
+        79, 434, 434, 434, 434, 156, 116, 434,
+        190, 191, 365, 365, 84, 79, 194, 195,
+        363, 363, 363, 197, 363, 363, 200, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 363, 363, 363, 202, 363, 116, 83,
+        83, 84, 79, 434, 434, 434, 434, 434,
+        116, 434, 436, 437, 438, 439, 123, 118,
+        440, 441, 435, 435, 155, 442, 435, 435,
+        443, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 444, 435,
+        445, 437, 439, 439, 123, 118, 440, 441,
+        435, 435, 435, 442, 435, 435, 443, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 444, 435, 437, 439,
+        439, 123, 118, 440, 441, 435, 435, 435,
+        442, 435, 435, 443, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 444, 435, 446, 435, 435, 435, 136,
+        447, 435, 118, 440, 441, 435, 435, 435,
+        448, 435, 446, 435, 449, 450, 451, 452,
+        123, 118, 440, 441, 435, 435, 153, 453,
+        435, 435, 443, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        444, 435, 454, 450, 455, 455, 123, 118,
+        440, 441, 435, 435, 435, 453, 435, 435,
+        443, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 444, 435,
+        450, 455, 455, 123, 118, 440, 441, 435,
+        435, 435, 453, 435, 435, 443, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 444, 435, 456, 435, 435,
+        435, 136, 457, 435, 118, 440, 441, 435,
+        435, 435, 448, 435, 456, 435, 458, 459,
+        460, 461, 123, 118, 440, 441, 435, 435,
+        151, 462, 435, 435, 443, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 444, 435, 463, 459, 464, 464,
+        123, 118, 440, 441, 435, 435, 435, 462,
+        435, 435, 443, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        444, 435, 459, 464, 464, 123, 118, 440,
+        441, 435, 435, 435, 462, 435, 435, 443,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 444, 435, 465,
+        435, 435, 435, 136, 466, 435, 118, 440,
+        441, 435, 435, 435, 448, 435, 465, 435,
+        467, 468, 469, 470, 123, 118, 440, 441,
+        435, 435, 149, 471, 435, 435, 443, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 444, 435, 472, 468,
+        473, 473, 123, 118, 440, 441, 435, 435,
+        435, 471, 435, 435, 443, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 444, 435, 468, 473, 473, 123,
+        118, 440, 441, 435, 435, 435, 471, 435,
+        435, 443, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 444,
+        435, 474, 435, 435, 435, 136, 475, 435,
+        118, 440, 441, 435, 435, 435, 448, 435,
+        474, 435, 476, 477, 478, 479, 123, 118,
+        440, 441, 435, 435, 147, 480, 435, 435,
+        443, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 444, 435,
+        481, 477, 482, 482, 123, 118, 440, 441,
+        435, 435, 435, 480, 435, 435, 443, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 444, 435, 477, 482,
+        482, 123, 118, 440, 441, 435, 435, 435,
+        480, 435, 435, 443, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 444, 435, 136, 483, 435, 118, 440,
+        441, 435, 435, 435, 448, 435, 484, 484,
+        435, 118, 440, 441, 435, 435, 435, 448,
+        435, 485, 435, 435, 486, 440, 441, 435,
+        440, 441, 435, 487, 435, 440, 488, 435,
+        440, 489, 435, 440, 435, 485, 435, 435,
+        435, 440, 441, 435, 490, 435, 491, 492,
+        435, 118, 440, 441, 435, 435, 121, 435,
+        120, 435, 484, 484, 435, 118, 440, 441,
+        435, 484, 484, 435, 118, 440, 441, 435,
+        490, 435, 484, 484, 435, 118, 440, 441,
+        435, 490, 435, 491, 484, 435, 118, 440,
+        441, 435, 435, 121, 435, 136, 435, 493,
+        493, 123, 118, 440, 441, 435, 435, 435,
+        448, 435, 494, 145, 495, 496, 126, 118,
+        440, 441, 435, 435, 435, 448, 435, 145,
+        495, 496, 126, 118, 440, 441, 435, 435,
+        435, 448, 435, 495, 495, 126, 118, 440,
+        441, 435, 435, 435, 448, 435, 497, 142,
+        498, 499, 129, 118, 440, 441, 435, 435,
+        435, 448, 435, 142, 498, 499, 129, 118,
+        440, 441, 435, 435, 435, 448, 435, 498,
+        498, 129, 118, 440, 441, 435, 435, 435,
+        448, 435, 500, 139, 501, 502, 132, 118,
+        440, 441, 435, 435, 435, 448, 435, 139,
+        501, 502, 132, 118, 440, 441, 435, 435,
+        435, 448, 435, 501, 501, 132, 118, 440,
+        441, 435, 435, 435, 448, 435, 503, 136,
+        484, 504, 435, 118, 440, 441, 435, 435,
+        435, 448, 435, 136, 484, 504, 435, 118,
+        440, 441, 435, 435, 435, 448, 435, 484,
+        505, 435, 118, 440, 441, 435, 435, 435,
+        448, 435, 136, 435, 484, 484, 435, 118,
+        440, 441, 435, 435, 435, 448, 435, 119,
+        120, 435, 435, 136, 483, 435, 118, 440,
+        441, 435, 435, 435, 448, 435, 119, 435,
+        477, 482, 482, 123, 118, 440, 441, 435,
+        435, 435, 480, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 444, 435, 477, 482, 482,
+        123, 118, 440, 441, 435, 435, 435, 480,
+        435, 476, 477, 482, 482, 123, 118, 440,
+        441, 435, 435, 435, 480, 435, 435, 443,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 444, 435, 476,
+        477, 478, 482, 123, 118, 440, 441, 435,
+        435, 147, 480, 435, 435, 443, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 444, 435, 474, 435, 506,
+        435, 493, 493, 123, 118, 440, 441, 435,
+        435, 435, 448, 435, 474, 435, 474, 435,
+        435, 435, 484, 484, 435, 118, 440, 441,
+        435, 435, 435, 448, 435, 474, 435, 474,
+        435, 435, 435, 484, 507, 435, 118, 440,
+        441, 435, 435, 435, 448, 435, 474, 435,
+        474, 435, 506, 435, 484, 484, 435, 118,
+        440, 441, 435, 435, 435, 448, 435, 474,
+        435, 474, 120, 435, 435, 136, 475, 435,
+        118, 440, 441, 435, 435, 435, 448, 435,
+        474, 435, 467, 468, 473, 473, 123, 118,
+        440, 441, 435, 435, 435, 471, 435, 435,
+        443, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 444, 435,
+        467, 468, 469, 473, 123, 118, 440, 441,
+        435, 435, 149, 471, 435, 435, 443, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 444, 435, 465, 435,
+        508, 435, 493, 493, 123, 118, 440, 441,
+        435, 435, 435, 448, 435, 465, 435, 465,
+        435, 435, 435, 484, 484, 435, 118, 440,
+        441, 435, 435, 435, 448, 435, 465, 435,
+        465, 435, 435, 435, 484, 509, 435, 118,
+        440, 441, 435, 435, 435, 448, 435, 465,
+        435, 465, 435, 508, 435, 484, 484, 435,
+        118, 440, 441, 435, 435, 435, 448, 435,
+        465, 435, 465, 120, 435, 435, 136, 466,
+        435, 118, 440, 441, 435, 435, 435, 448,
+        435, 465, 435, 458, 459, 464, 464, 123,
+        118, 440, 441, 435, 435, 435, 462, 435,
+        435, 443, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 444,
+        435, 458, 459, 460, 464, 123, 118, 440,
+        441, 435, 435, 151, 462, 435, 435, 443,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 444, 435, 456,
+        435, 510, 435, 493, 493, 123, 118, 440,
+        441, 435, 435, 435, 448, 435, 456, 435,
+        456, 435, 435, 435, 484, 484, 435, 118,
+        440, 441, 435, 435, 435, 448, 435, 456,
+        435, 456, 435, 435, 435, 484, 511, 435,
+        118, 440, 441, 435, 435, 435, 448, 435,
+        456, 435, 456, 435, 510, 435, 484, 484,
+        435, 118, 440, 441, 435, 435, 435, 448,
+        435, 456, 435, 456, 120, 435, 435, 136,
+        457, 435, 118, 440, 441, 435, 435, 435,
+        448, 435, 456, 435, 449, 450, 455, 455,
+        123, 118, 440, 441, 435, 435, 435, 453,
+        435, 435, 443, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        444, 435, 449, 450, 451, 455, 123, 118,
+        440, 441, 435, 435, 153, 453, 435, 435,
+        443, 435, 435, 435, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 444, 435,
+        446, 435, 512, 435, 493, 493, 123, 118,
+        440, 441, 435, 435, 435, 448, 435, 446,
+        435, 446, 435, 435, 435, 484, 484, 435,
+        118, 440, 441, 435, 435, 435, 448, 435,
+        446, 435, 446, 435, 435, 435, 484, 513,
+        435, 118, 440, 441, 435, 435, 435, 448,
+        435, 446, 435, 446, 435, 512, 435, 484,
+        484, 435, 118, 440, 441, 435, 435, 435,
+        448, 435, 446, 435, 446, 120, 435, 435,
+        136, 447, 435, 118, 440, 441, 435, 435,
+        435, 448, 435, 446, 435, 436, 437, 439,
+        439, 123, 118, 440, 441, 435, 435, 435,
+        442, 435, 435, 443, 435, 435, 435, 435,
+        435, 435, 435, 435, 435, 435, 435, 435,
+        435, 444, 435, 188, 189, 190, 191, 514,
+        365, 84, 79, 194, 195, 196, 196, 156,
+        197, 363, 188, 200, 363, 363, 363, 363,
+        363, 363, 363, 363, 363, 363, 363, 363,
+        363, 202, 363, 204, 515, 206, 207, 6,
+        1, 208, 209, 203, 203, 38, 210, 203,
+        203, 211, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 212,
+        203, 215, 189, 190, 191, 516, 517, 84,
+        157, 518, 519, 203, 196, 156, 520, 203,
+        215, 200, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 202,
+        203, 116, 521, 521, 84, 157, 208, 209,
+        203, 203, 156, 522, 203, 523, 203, 203,
+        524, 518, 519, 203, 518, 519, 203, 256,
+        203, 518, 525, 203, 518, 526, 203, 518,
+        203, 523, 203, 203, 203, 518, 519, 203,
+        527, 3, 363, 363, 404, 433, 363, 79,
+        194, 195, 363, 363, 363, 368, 363, 527,
+        363, 528, 370, 529, 530, 84, 157, 518,
+        519, 203, 203, 158, 373, 203, 203, 200,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 202, 203, 531,
+        370, 532, 532, 84, 157, 518, 519, 203,
+        203, 203, 373, 203, 203, 200, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 202, 203, 370, 532, 532,
+        84, 157, 518, 519, 203, 203, 203, 373,
+        203, 203, 200, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        202, 203, 528, 370, 532, 532, 84, 157,
+        518, 519, 203, 203, 203, 373, 203, 203,
+        200, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 203, 203, 202, 203,
+        528, 370, 529, 532, 84, 157, 518, 519,
+        203, 203, 158, 373, 203, 203, 200, 203,
+        203, 203, 203, 203, 203, 203, 203, 203,
+        203, 203, 203, 203, 202, 203, 215, 203,
+        281, 116, 533, 533, 160, 157, 208, 209,
+        203, 203, 203, 522, 203, 215, 203, 534,
+        184, 535, 536, 162, 157, 518, 519, 203,
+        203, 203, 537, 203, 184, 535, 536, 162,
+        157, 518, 519, 203, 203, 203, 537, 203,
+        535, 535, 162, 157, 518, 519, 203, 203,
+        203, 537, 203, 538, 181, 539, 540, 165,
+        157, 518, 519, 203, 203, 203, 537, 203,
+        181, 539, 540, 165, 157, 518, 519, 203,
+        203, 203, 537, 203, 539, 539, 165, 157,
+        518, 519, 203, 203, 203, 537, 203, 541,
+        178, 542, 543, 168, 157, 518, 519, 203,
+        203, 203, 537, 203, 178, 542, 543, 168,
+        157, 518, 519, 203, 203, 203, 537, 203,
+        542, 542, 168, 157, 518, 519, 203, 203,
+        203, 537, 203, 544, 175, 545, 546, 203,
+        157, 518, 519, 203, 203, 203, 537, 203,
+        175, 545, 546, 203, 157, 518, 519, 203,
+        203, 203, 537, 203, 545, 545, 203, 157,
+        518, 519, 203, 203, 203, 537, 203, 547,
+        203, 548, 549, 203, 157, 518, 519, 203,
+        203, 172, 203, 171, 203, 545, 545, 203,
+        157, 518, 519, 203, 545, 545, 203, 157,
+        518, 519, 203, 547, 203, 545, 545, 203,
+        157, 518, 519, 203, 547, 203, 548, 545,
+        203, 157, 518, 519, 203, 203, 172, 203,
+        527, 171, 363, 363, 98, 367, 363, 79,
+        194, 195, 363, 363, 363, 368, 363, 527,
+        363, 551, 550, 552, 552, 550, 186, 553,
+        554, 550, 552, 552, 550, 186, 553, 554,
+        550, 555, 550, 550, 556, 553, 554, 550,
+        553, 554, 550, 557, 550, 553, 558, 550,
+        553, 559, 550, 553, 550, 555, 550, 550,
+        550, 553, 554, 550, 0
+};
+
+static const short _indic_syllable_machine_trans_targs[] = {
+        178, 200, 207, 209, 210, 4, 213, 5,
+        7, 216, 8, 10, 219, 11, 13, 222,
+        14, 16, 17, 199, 19, 20, 221, 22,
+        23, 218, 25, 26, 215, 224, 229, 233,
+        236, 240, 243, 247, 250, 254, 257, 178,
+        280, 287, 289, 290, 41, 293, 42, 44,
+        296, 45, 47, 299, 48, 50, 302, 51,
+        53, 54, 279, 56, 57, 301, 59, 60,
+        298, 62, 63, 295, 304, 309, 313, 316,
+        320, 323, 327, 330, 334, 338, 178, 359,
+        366, 368, 369, 78, 372, 178, 79, 81,
+        375, 82, 84, 378, 85, 87, 381, 88,
+        90, 91, 358, 93, 94, 380, 96, 97,
+        377, 99, 100, 374, 383, 388, 392, 395,
+        399, 402, 406, 409, 413, 178, 440, 447,
+        449, 450, 114, 453, 115, 117, 456, 118,
+        120, 459, 121, 123, 462, 124, 126, 127,
+        439, 129, 130, 461, 132, 133, 458, 135,
+        136, 455, 464, 469, 473, 476, 480, 483,
+        487, 490, 494, 497, 417, 502, 513, 152,
+        516, 154, 519, 155, 157, 522, 158, 160,
+        525, 161, 528, 530, 531, 166, 167, 527,
+        169, 170, 524, 172, 173, 521, 175, 176,
+        518, 178, 536, 178, 179, 259, 339, 341,
+        416, 418, 361, 362, 419, 415, 498, 499,
+        386, 534, 387, 178, 180, 182, 36, 258,
+        202, 203, 256, 227, 228, 181, 35, 183,
+        252, 1, 184, 186, 34, 251, 249, 185,
+        33, 187, 245, 188, 190, 32, 244, 242,
+        189, 31, 191, 238, 192, 194, 30, 237,
+        235, 193, 29, 195, 231, 196, 198, 28,
+        230, 226, 197, 27, 212, 0, 201, 206,
+        178, 204, 205, 208, 2, 211, 3, 214,
+        6, 24, 217, 9, 21, 220, 12, 18,
+        223, 15, 225, 232, 234, 239, 241, 246,
+        248, 253, 255, 178, 260, 262, 73, 336,
+        282, 283, 337, 307, 308, 261, 72, 263,
+        332, 38, 264, 266, 71, 331, 329, 265,
+        70, 267, 325, 268, 270, 69, 324, 322,
+        269, 68, 271, 318, 272, 274, 67, 317,
+        315, 273, 66, 275, 311, 276, 278, 65,
+        310, 306, 277, 64, 292, 37, 281, 286,
+        178, 284, 285, 288, 39, 291, 40, 294,
+        43, 61, 297, 46, 58, 300, 49, 55,
+        303, 52, 305, 312, 314, 319, 321, 326,
+        328, 333, 335, 178, 340, 109, 342, 411,
+        75, 343, 345, 108, 410, 408, 344, 107,
+        346, 404, 347, 349, 106, 403, 401, 348,
+        105, 350, 397, 351, 353, 104, 396, 394,
+        352, 103, 354, 390, 355, 357, 102, 389,
+        385, 356, 101, 371, 74, 360, 365, 178,
+        363, 364, 367, 76, 370, 77, 373, 80,
+        98, 376, 83, 95, 379, 86, 92, 382,
+        89, 384, 391, 393, 398, 400, 405, 407,
+        412, 414, 178, 178, 420, 422, 146, 145,
+        442, 443, 496, 467, 468, 421, 423, 492,
+        111, 424, 426, 144, 491, 489, 425, 143,
+        427, 485, 428, 430, 142, 484, 482, 429,
+        141, 431, 478, 432, 434, 140, 477, 475,
+        433, 139, 435, 471, 436, 438, 138, 470,
+        466, 437, 137, 452, 110, 441, 446, 178,
+        444, 445, 448, 112, 451, 113, 454, 116,
+        134, 457, 119, 131, 460, 122, 128, 463,
+        125, 465, 472, 474, 479, 481, 486, 488,
+        493, 495, 147, 500, 501, 515, 504, 505,
+        533, 148, 509, 503, 508, 506, 507, 510,
+        511, 150, 514, 512, 149, 151, 517, 153,
+        174, 163, 520, 156, 171, 523, 159, 168,
+        526, 162, 165, 529, 164, 532, 178, 535,
+        177, 538, 539, 537, 542, 178, 540, 541
+};
+
+static const char _indic_syllable_machine_trans_actions[] = {
+        1, 0, 2, 2, 2, 0, 2, 0,
+        0, 2, 0, 0, 2, 0, 0, 2,
+        0, 0, 0, 2, 0, 0, 2, 0,
+        0, 2, 0, 0, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 2, 3,
+        0, 2, 2, 2, 0, 2, 0, 0,
+        2, 0, 0, 2, 0, 0, 2, 0,
+        0, 0, 2, 0, 0, 2, 0, 0,
+        2, 0, 0, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 2, 2, 4, 0,
+        2, 2, 2, 0, 2, 5, 0, 0,
+        2, 0, 0, 2, 0, 0, 2, 0,
+        0, 0, 2, 0, 0, 2, 0, 0,
+        2, 0, 0, 2, 2, 6, 2, 6,
+        2, 6, 2, 6, 2, 7, 0, 2,
+        2, 2, 0, 2, 0, 0, 2, 0,
+        0, 2, 0, 0, 2, 0, 0, 0,
+        2, 0, 0, 2, 0, 0, 2, 0,
+        0, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 2, 6, 0, 8, 0,
+        2, 0, 2, 0, 0, 2, 0, 0,
+        2, 0, 2, 2, 2, 0, 0, 2,
+        0, 0, 2, 0, 0, 2, 0, 0,
+        2, 9, 0, 12, 2, 2, 6, 2,
+        13, 13, 0, 0, 2, 2, 6, 2,
+        6, 2, 6, 14, 2, 2, 0, 2,
+        0, 0, 2, 2, 2, 2, 0, 2,
+        2, 0, 2, 2, 0, 2, 2, 2,
+        0, 2, 2, 2, 2, 0, 2, 2,
+        2, 0, 2, 2, 2, 2, 0, 2,
+        2, 2, 0, 2, 2, 2, 2, 0,
+        2, 2, 2, 0, 2, 0, 0, 0,
+        15, 0, 0, 2, 0, 2, 0, 2,
+        0, 0, 2, 0, 0, 2, 0, 0,
+        2, 0, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 16, 2, 2, 0, 2,
+        0, 0, 2, 2, 2, 2, 0, 2,
+        2, 0, 2, 2, 0, 2, 2, 2,
+        0, 2, 2, 2, 2, 0, 2, 2,
+        2, 0, 2, 2, 2, 2, 0, 2,
+        2, 2, 0, 2, 2, 2, 2, 0,
+        2, 2, 2, 0, 2, 0, 0, 0,
+        17, 0, 0, 2, 0, 2, 0, 2,
+        0, 0, 2, 0, 0, 2, 0, 0,
+        2, 0, 2, 2, 2, 2, 2, 2,
+        2, 2, 2, 18, 6, 0, 6, 6,
+        0, 6, 2, 0, 6, 2, 6, 0,
+        6, 6, 6, 2, 0, 6, 2, 6,
+        0, 6, 6, 6, 2, 0, 6, 2,
+        6, 0, 6, 6, 6, 2, 0, 6,
+        2, 6, 0, 6, 0, 0, 0, 19,
+        0, 0, 2, 0, 2, 0, 2, 0,
+        0, 2, 0, 0, 2, 0, 0, 2,
+        0, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 20, 21, 2, 2, 0, 0,
+        0, 0, 2, 2, 2, 2, 2, 2,
+        0, 2, 2, 0, 2, 2, 2, 0,
+        2, 2, 2, 2, 0, 2, 2, 2,
+        0, 2, 2, 2, 2, 0, 2, 2,
+        2, 0, 2, 2, 2, 2, 0, 2,
+        2, 2, 0, 2, 0, 0, 0, 22,
+        0, 0, 2, 0, 2, 0, 2, 0,
+        0, 2, 0, 0, 2, 0, 0, 2,
+        0, 2, 2, 2, 2, 2, 2, 2,
+        2, 2, 0, 0, 8, 2, 0, 0,
+        2, 0, 2, 0, 0, 0, 0, 8,
+        8, 0, 8, 8, 0, 0, 2, 0,
+        0, 0, 2, 0, 0, 2, 0, 0,
+        2, 0, 0, 2, 0, 2, 23, 2,
+        0, 0, 0, 0, 0, 24, 0, 0
+};
+
+static const char _indic_syllable_machine_to_state_actions[] = {
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 10, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0
+};
+
+static const char _indic_syllable_machine_from_state_actions[] = {
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 11, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0
+};
+
+static const short _indic_syllable_machine_eof_trans[] = {
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 40, 40, 40,
+        40, 40, 40, 40, 40, 40, 40, 40,
+        40, 40, 40, 40, 40, 40, 40, 40,
+        40, 40, 40, 40, 40, 40, 40, 40,
+        40, 40, 40, 40, 40, 40, 40, 40,
+        40, 40, 79, 79, 79, 79, 86, 86,
+        79, 79, 79, 79, 79, 79, 79, 79,
+        79, 79, 79, 79, 79, 79, 79, 79,
+        79, 79, 79, 79, 79, 79, 79, 79,
+        79, 79, 79, 79, 79, 79, 118, 118,
+        118, 118, 118, 118, 118, 118, 118, 118,
+        118, 118, 118, 118, 118, 118, 118, 118,
+        118, 118, 118, 118, 118, 118, 118, 118,
+        118, 118, 118, 118, 118, 118, 118, 118,
+        118, 118, 118, 79, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 1, 1, 1, 1,
+        1, 186, 0, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 284, 284, 284, 284, 284,
+        284, 284, 284, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        364, 364, 364, 364, 364, 364, 364, 364,
+        435, 364, 435, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 436, 436, 436, 436, 436, 436,
+        436, 436, 364, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 364, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 204, 204, 204,
+        204, 204, 204, 204, 204, 364, 551, 551,
+        551, 551, 551, 551, 551, 551, 551
+};
+
+static const int indic_syllable_machine_start = 178;
+static const int indic_syllable_machine_first_final = 178;
+static const int indic_syllable_machine_error = -1;
+
+static const int indic_syllable_machine_en_main = 178;
+
+
+#line 36 "hb-ot-shape-complex-indic-machine.rl"
+
+
+
+#line 97 "hb-ot-shape-complex-indic-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+  HB_STMT_START { \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+    for (unsigned int i = last; i < p+1; i++) \
+      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+    last = p+1; \
+    syllable_serial++; \
+    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+  } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  int cs;
+  hb_glyph_info_t *info = buffer->info;
+
+#line 1580 "hb-ot-shape-complex-indic-machine.hh"
+        {
+        cs = indic_syllable_machine_start;
+        ts = 0;
+        te = 0;
+        act = 0;
+        }
+
+#line 118 "hb-ot-shape-complex-indic-machine.rl"
+
+
+  p = 0;
+  pe = eof = buffer->len;
+
+  unsigned int last = 0;
+  unsigned int syllable_serial = 1;
+
+#line 1597 "hb-ot-shape-complex-indic-machine.hh"
+        {
+        int _slen;
+        int _trans;
+        const unsigned char *_keys;
+        const short *_inds;
+        if ( p == pe )
+                goto _test_eof;
+_resume:
+        switch ( _indic_syllable_machine_from_state_actions[cs] ) {
+        case 11:
+#line 1 "NONE"
+        {ts = p;}
+        break;
+#line 1611 "hb-ot-shape-complex-indic-machine.hh"
+        }
+
+        _keys = _indic_syllable_machine_trans_keys + (cs<<1);
+        _inds = _indic_syllable_machine_indicies + _indic_syllable_machine_index_offsets[cs];
+
+        _slen = _indic_syllable_machine_key_spans[cs];
+        _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].indic_category()) &&
+                ( info[p].indic_category()) <= _keys[1] ?
+                ( info[p].indic_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+        cs = _indic_syllable_machine_trans_targs[_trans];
+
+        if ( _indic_syllable_machine_trans_actions[_trans] == 0 )
+                goto _again;
+
+        switch ( _indic_syllable_machine_trans_actions[_trans] ) {
+        case 2:
+#line 1 "NONE"
+        {te = p+1;}
+        break;
+        case 15:
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p+1;{ found_syllable (consonant_syllable); }}
+        break;
+        case 17:
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p+1;{ found_syllable (vowel_syllable); }}
+        break;
+        case 22:
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p+1;{ found_syllable (standalone_cluster); }}
+        break;
+        case 24:
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p+1;{ found_syllable (symbol_cluster); }}
+        break;
+        case 19:
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p+1;{ found_syllable (broken_cluster); }}
+        break;
+        case 12:
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p+1;{ found_syllable (non_indic_cluster); }}
+        break;
+        case 14:
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p;p--;{ found_syllable (consonant_syllable); }}
+        break;
+        case 16:
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p;p--;{ found_syllable (vowel_syllable); }}
+        break;
+        case 21:
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p;p--;{ found_syllable (standalone_cluster); }}
+        break;
+        case 23:
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p;p--;{ found_syllable (symbol_cluster); }}
+        break;
+        case 18:
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p;p--;{ found_syllable (broken_cluster); }}
+        break;
+        case 20:
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
+        {te = p;p--;{ found_syllable (non_indic_cluster); }}
+        break;
+        case 1:
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
+        {{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
+        break;
+        case 3:
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
+        {{p = ((te))-1;}{ found_syllable (vowel_syllable); }}
+        break;
+        case 7:
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
+        {{p = ((te))-1;}{ found_syllable (standalone_cluster); }}
+        break;
+        case 9:
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
+        {{p = ((te))-1;}{ found_syllable (symbol_cluster); }}
+        break;
+        case 4:
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+        {{p = ((te))-1;}{ found_syllable (broken_cluster); }}
+        break;
+        case 5:
+#line 1 "NONE"
+        {       switch( act ) {
+        case 1:
+        {{p = ((te))-1;} found_syllable (consonant_syllable); }
+        break;
+        case 5:
+        {{p = ((te))-1;} found_syllable (broken_cluster); }
+        break;
+        case 6:
+        {{p = ((te))-1;} found_syllable (non_indic_cluster); }
+        break;
+        }
+        }
+        break;
+        case 8:
+#line 1 "NONE"
+        {te = p+1;}
+#line 88 "hb-ot-shape-complex-indic-machine.rl"
+        {act = 1;}
+        break;
+        case 6:
+#line 1 "NONE"
+        {te = p+1;}
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+        {act = 5;}
+        break;
+        case 13:
+#line 1 "NONE"
+        {te = p+1;}
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
+        {act = 6;}
+        break;
+#line 1734 "hb-ot-shape-complex-indic-machine.hh"
+        }
+
+_again:
+        switch ( _indic_syllable_machine_to_state_actions[cs] ) {
+        case 10:
+#line 1 "NONE"
+        {ts = 0;}
+        break;
+#line 1743 "hb-ot-shape-complex-indic-machine.hh"
+        }
+
+        if ( ++p != pe )
+                goto _resume;
+        _test_eof: {}
+        if ( p == eof )
+        {
+        if ( _indic_syllable_machine_eof_trans[cs] > 0 ) {
+                _trans = _indic_syllable_machine_eof_trans[cs] - 1;
+                goto _eof_trans;
+        }
+        }
+
+        }
+
+#line 127 "hb-ot-shape-complex-indic-machine.rl"
+
+}
+
+#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,180 @@
+/*
+ * Copyright © 2012  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_SHAPE_COMPLEX_INDIC_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-private.hh" /* XXX Remove */
+
+
+#define INDIC_TABLE_ELEMENT_TYPE uint16_t
+
+/* Cateories used in the OpenType spec:
+ * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
+ */
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum indic_category_t {
+  OT_X = 0,
+  OT_C = 1,
+  OT_V = 2,
+  OT_N = 3,
+  OT_H = 4,
+  OT_ZWNJ = 5,
+  OT_ZWJ = 6,
+  OT_M = 7,
+  OT_SM = 8,
+  OT_VD = 9,
+  OT_A = 10,
+  OT_PLACEHOLDER = 11,
+  OT_DOTTEDCIRCLE = 12,
+  OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
+  OT_Coeng = 14, /* Khmer-style Virama. */
+  OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
+  OT_Ra = 16,
+  OT_CM = 17,  /* Consonant-Medial. */
+  OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
+  OT_CM2 = 31 /* Consonant-Medial, second slot. */
+};
+
+#define MEDIAL_FLAGS (FLAG (OT_CM) | FLAG (OT_CM2))
+
+/* Note:
+ *
+ * We treat Vowels and placeholders as if they were consonants.  This is safe because Vowels
+ * cannot happen in a consonant syllable.  The plus side however is, we can call the
+ * consonant syllable logic from the vowel syllable function and get it all right! */
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
+#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
+#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
+
+
+/* Visual positions in a syllable from left to right. */
+enum indic_position_t {
+  POS_START,
+
+  POS_RA_TO_BECOME_REPH,
+  POS_PRE_M,
+  POS_PRE_C,
+
+  POS_BASE_C,
+  POS_AFTER_MAIN,
+
+  POS_ABOVE_C,
+
+  POS_BEFORE_SUB,
+  POS_BELOW_C,
+  POS_AFTER_SUB,
+
+  POS_BEFORE_POST,
+  POS_POST_C,
+  POS_AFTER_POST,
+
+  POS_FINAL_C,
+  POS_SMVD,
+
+  POS_END
+};
+
+/* Categories used in IndicSyllabicCategory.txt from UCD. */
+enum indic_syllabic_category_t {
+  INDIC_SYLLABIC_CATEGORY_OTHER                         = OT_X,
+
+  INDIC_SYLLABIC_CATEGORY_AVAGRAHA                      = OT_Symbol,
+  INDIC_SYLLABIC_CATEGORY_BINDU                         = OT_SM,
+  INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER         = OT_PLACEHOLDER, /* TODO */
+  INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK             = OT_A,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT                     = OT_C,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD                = OT_C,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL               = OT_CM,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER         = OT_C,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL              = OT_CM,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER         = OT_PLACEHOLDER,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA     = OT_Repha,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED           = OT_CM,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA    = OT_N,
+  INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK               = OT_SM,
+  INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER             = OT_H, /* TODO */
+  INDIC_SYLLABIC_CATEGORY_JOINER                        = OT_ZWJ,
+  INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER              = OT_X,
+  INDIC_SYLLABIC_CATEGORY_NON_JOINER                    = OT_ZWNJ,
+  INDIC_SYLLABIC_CATEGORY_NUKTA                         = OT_N,
+  INDIC_SYLLABIC_CATEGORY_NUMBER                        = OT_PLACEHOLDER,
+  INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER                 = OT_PLACEHOLDER, /* TODO */
+  INDIC_SYLLABIC_CATEGORY_PURE_KILLER                   = OT_H, /* TODO */
+  INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER              = OT_RS,
+  INDIC_SYLLABIC_CATEGORY_TONE_LETTER                   = OT_X,
+  INDIC_SYLLABIC_CATEGORY_TONE_MARK                     = OT_N,
+  INDIC_SYLLABIC_CATEGORY_VIRAMA                        = OT_H,
+  INDIC_SYLLABIC_CATEGORY_VISARGA                       = OT_SM,
+  INDIC_SYLLABIC_CATEGORY_VOWEL                         = OT_V,
+  INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT               = OT_M,
+  INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT             = OT_V
+};
+
+/* Categories used in IndicSMatraCategory.txt from UCD */
+enum indic_matra_category_t {
+  INDIC_MATRA_CATEGORY_NOT_APPLICABLE                   = POS_END,
+
+  INDIC_MATRA_CATEGORY_LEFT                             = POS_PRE_C,
+  INDIC_MATRA_CATEGORY_TOP                              = POS_ABOVE_C,
+  INDIC_MATRA_CATEGORY_BOTTOM                           = POS_BELOW_C,
+  INDIC_MATRA_CATEGORY_RIGHT                            = POS_POST_C,
+
+  /* These should resolve to the position of the last part of the split sequence. */
+  INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT                 = INDIC_MATRA_CATEGORY_RIGHT,
+  INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT                   = INDIC_MATRA_CATEGORY_RIGHT,
+  INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM                   = INDIC_MATRA_CATEGORY_BOTTOM,
+  INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT         = INDIC_MATRA_CATEGORY_RIGHT,
+  INDIC_MATRA_CATEGORY_TOP_AND_LEFT                     = INDIC_MATRA_CATEGORY_TOP,
+  INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT           = INDIC_MATRA_CATEGORY_RIGHT,
+  INDIC_MATRA_CATEGORY_TOP_AND_RIGHT                    = INDIC_MATRA_CATEGORY_RIGHT,
+
+  INDIC_MATRA_CATEGORY_OVERSTRUCK                       = POS_AFTER_MAIN,
+  INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT                = POS_PRE_M
+};
+
+#define INDIC_COMBINE_CATEGORIES(S,M) \
+  (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || \
+                            ( \
+                             S == INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL || \
+                             S == INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK || \
+                             S == INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER || \
+                             S == INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA || \
+                             S == INDIC_SYLLABIC_CATEGORY_VIRAMA || \
+                             S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT || \
+                             false)) + \
+   ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
+   ((M << 8) | S))
+
+HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE
+hb_indic_get_categories (hb_codepoint_t u);
+
+#endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-table.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,956 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ *   ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt
+ *
+ * on files with these headers:
+ *
+ * # IndicSyllabicCategory-7.0.0.txt
+ * # Date: 2014-06-03, 07:00:00 GMT [KW, LI, AG, RP]
+ * # IndicMatraCategory-7.0.0.txt
+ * # Date: 2014-06-03, 07:00:00 GMT [KW, LI, AG, RP]
+ * # Blocks-7.0.0.txt
+ * # Date: 2014-04-03, 23:23:00 GMT [RP, KW]
+ */
+
+#include "hb-ot-shape-complex-indic-private.hh"
+
+
+#define ISC_A   INDIC_SYLLABIC_CATEGORY_AVAGRAHA                /*  13 chars; Avagraha */
+#define ISC_Bi  INDIC_SYLLABIC_CATEGORY_BINDU                   /*  59 chars; Bindu */
+#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER   /*  20 chars; Brahmi_Joining_Number */
+#define ISC_Ca  INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK       /*  30 chars; Cantillation_Mark */
+#define ISC_C   INDIC_SYLLABIC_CATEGORY_CONSONANT               /* 1744 chars; Consonant */
+#define ISC_CD  INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD          /*   7 chars; Consonant_Dead */
+#define ISC_CF  INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL         /*  61 chars; Consonant_Final */
+#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER   /*   5 chars; Consonant_Head_Letter */
+#define ISC_CM  INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL        /*  19 chars; Consonant_Medial */
+#define ISC_CP  INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER   /*  11 chars; Consonant_Placeholder */
+#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA       /*   1 chars; Consonant_Preceding_Repha */
+#define ISC_CS  INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED     /*  61 chars; Consonant_Subjoined */
+#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA      /*   4 chars; Consonant_Succeeding_Repha */
+#define ISC_GM  INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK         /*   2 chars; Gemination_Mark */
+#define ISC_IS  INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER       /*   7 chars; Invisible_Stacker */
+#define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER                  /*   1 chars; Joiner */
+#define ISC_ML  INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER        /*   1 chars; Modifying_Letter */
+#define ISC_ZWNJ        INDIC_SYLLABIC_CATEGORY_NON_JOINER              /*   1 chars; Non_Joiner */
+#define ISC_N   INDIC_SYLLABIC_CATEGORY_NUKTA                   /*  18 chars; Nukta */
+#define ISC_Nd  INDIC_SYLLABIC_CATEGORY_NUMBER                  /* 408 chars; Number */
+#define ISC_NJ  INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER           /*   1 chars; Number_Joiner */
+#define ISC_x   INDIC_SYLLABIC_CATEGORY_OTHER                   /*   1 chars; Other */
+#define ISC_PK  INDIC_SYLLABIC_CATEGORY_PURE_KILLER             /*  15 chars; Pure_Killer */
+#define ISC_RS  INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER        /*   3 chars; Register_Shifter */
+#define ISC_TL  INDIC_SYLLABIC_CATEGORY_TONE_LETTER             /*   7 chars; Tone_Letter */
+#define ISC_TM  INDIC_SYLLABIC_CATEGORY_TONE_MARK               /*  62 chars; Tone_Mark */
+#define ISC_V   INDIC_SYLLABIC_CATEGORY_VIRAMA                  /*  22 chars; Virama */
+#define ISC_Vs  INDIC_SYLLABIC_CATEGORY_VISARGA                 /*  29 chars; Visarga */
+#define ISC_Vo  INDIC_SYLLABIC_CATEGORY_VOWEL                   /*  30 chars; Vowel */
+#define ISC_M   INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT         /* 553 chars; Vowel_Dependent */
+#define ISC_VI  INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT       /* 395 chars; Vowel_Independent */
+
+#define IMC_B   INDIC_MATRA_CATEGORY_BOTTOM                     /* 142 chars; Bottom */
+#define IMC_BR  INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT           /*   2 chars; Bottom_And_Right */
+#define IMC_L   INDIC_MATRA_CATEGORY_LEFT                       /*  57 chars; Left */
+#define IMC_LR  INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT             /*  21 chars; Left_And_Right */
+#define IMC_x   INDIC_MATRA_CATEGORY_NOT_APPLICABLE             /*   1 chars; Not_Applicable */
+#define IMC_O   INDIC_MATRA_CATEGORY_OVERSTRUCK                 /*   2 chars; Overstruck */
+#define IMC_R   INDIC_MATRA_CATEGORY_RIGHT                      /* 163 chars; Right */
+#define IMC_T   INDIC_MATRA_CATEGORY_TOP                        /* 169 chars; Top */
+#define IMC_TB  INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM             /*  10 chars; Top_And_Bottom */
+#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT   /*   1 chars; Top_And_Bottom_And_Right */
+#define IMC_TL  INDIC_MATRA_CATEGORY_TOP_AND_LEFT               /*   6 chars; Top_And_Left */
+#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT     /*   4 chars; Top_And_Left_And_Right */
+#define IMC_TR  INDIC_MATRA_CATEGORY_TOP_AND_RIGHT              /*  13 chars; Top_And_Right */
+#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT          /*  15 chars; Visual_Order_Left */
+
+#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
+
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
+
+
+#define indic_offset_0x0028u 0
+
+
+  /* Basic Latin */
+
+  /* 0028 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(CP,x),  _(x,x),  _(x,x),
+  /* 0030 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0038 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x00d0u 24
+
+
+  /* Latin-1 Supplement */
+
+  /* 00D0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(CP,x),
+
+#define indic_offset_0x0900u 32
+
+
+  /* Devanagari */
+
+  /* 0900 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0918 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0920 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0928 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0930 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0938 */  _(C,x),  _(C,x),  _(M,T),  _(M,R),  _(N,x),  _(A,x),  _(M,R),  _(M,L),
+  /* 0940 */  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(M,T),  _(M,T),  _(M,T),
+  /* 0948 */  _(M,T),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(V,B),  _(M,L),  _(M,R),
+  /* 0950 */  _(x,x), _(TM,x), _(TM,x),  _(x,x),  _(x,x),  _(M,T),  _(M,B),  _(M,B),
+  /* 0958 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0960 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0968 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0970 */  _(x,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0978 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+
+  /* Bengali */
+
+  /* 0980 */  _(x,x), _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x), _(VI,x),
+  /* 0990 */ _(VI,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0998 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 09A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 09A8 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 09B0 */  _(C,x),  _(x,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(C,x),
+  /* 09B8 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,x),  _(A,x),  _(M,R),  _(M,L),
+  /* 09C0 */  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(x,x),  _(x,x),  _(M,L),
+  /* 09C8 */  _(M,L),  _(x,x),  _(x,x), _(M,LR), _(M,LR),  _(V,B), _(CD,x),  _(x,x),
+  /* 09D0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,R),
+  /* 09D8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),
+  /* 09E0 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 09F0 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 09F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Gurmukhi */
+
+  /* 0A00 */  _(x,x), _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0A08 */ _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(VI,x),
+  /* 0A10 */ _(VI,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0A18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0A20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0A28 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0A30 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),
+  /* 0A38 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,x),  _(x,x),  _(M,R),  _(M,L),
+  /* 0A40 */  _(M,R),  _(M,B),  _(M,B),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,T),
+  /* 0A48 */  _(M,T),  _(x,x),  _(x,x),  _(M,T),  _(M,T),  _(V,B),  _(x,x),  _(x,x),
+  /* 0A50 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0A58 */  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(x,x),
+  /* 0A60 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0A70 */ _(Bi,x), _(GM,T), _(CP,x), _(CP,x),  _(x,x), _(CM,x),  _(x,x),  _(x,x),
+  /* 0A78 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Gujarati */
+
+  /* 0A80 */  _(x,x), _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x), _(VI,x),
+  /* 0A90 */ _(VI,x), _(VI,x),  _(x,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0A98 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0AA0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0AA8 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0AB0 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0AB8 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,x),  _(A,x),  _(M,R),  _(M,L),
+  /* 0AC0 */  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(M,T),  _(x,x),  _(M,T),
+  /* 0AC8 */  _(M,T), _(M,TR),  _(x,x),  _(M,R),  _(M,R),  _(V,B),  _(x,x),  _(x,x),
+  /* 0AD0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0AD8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0AE0 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0AF0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0AF8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Oriya */
+
+  /* 0B00 */  _(x,x), _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x), _(VI,x),
+  /* 0B10 */ _(VI,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0B18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0B20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0B28 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0B30 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0B38 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,x),  _(A,x),  _(M,R),  _(M,T),
+  /* 0B40 */  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(x,x),  _(x,x),  _(M,L),
+  /* 0B48 */ _(M,TL),  _(x,x),  _(x,x), _(M,LR),_(M,TLR),  _(V,B),  _(x,x),  _(x,x),
+  /* 0B50 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,T), _(M,TR),
+  /* 0B58 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),
+  /* 0B60 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0B68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0B70 */  _(x,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0B78 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Tamil */
+
+  /* 0B80 */  _(x,x),  _(x,x), _(Bi,x), _(ML,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0B88 */ _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x),
+  /* 0B90 */ _(VI,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(x,x),  _(x,x),
+  /* 0B98 */  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),
+  /* 0BA0 */  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0BA8 */  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(C,x),
+  /* 0BB0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0BB8 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,R),  _(M,R),
+  /* 0BC0 */  _(M,T),  _(M,B),  _(M,B),  _(x,x),  _(x,x),  _(x,x),  _(M,L),  _(M,L),
+  /* 0BC8 */  _(M,L),  _(x,x), _(M,LR), _(M,LR), _(M,LR),  _(V,T),  _(x,x),  _(x,x),
+  /* 0BD0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,R),
+  /* 0BD8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0BE0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0BE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0BF0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0BF8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Telugu */
+
+  /* 0C00 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x), _(VI,x), _(VI,x),
+  /* 0C10 */ _(VI,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0C18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0C20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0C28 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0C30 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0C38 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(A,x),  _(M,T),  _(M,T),
+  /* 0C40 */  _(M,T),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(x,x),  _(M,T),  _(M,T),
+  /* 0C48 */ _(M,TB),  _(x,x),  _(M,T),  _(M,T),  _(M,T),  _(V,T),  _(x,x),  _(x,x),
+  /* 0C50 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,T),  _(M,B),  _(x,x),
+  /* 0C58 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0C60 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0C70 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0C78 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Kannada */
+
+  /* 0C80 */  _(x,x), _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x), _(VI,x), _(VI,x),
+  /* 0C90 */ _(VI,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0C98 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0CA0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0CA8 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0CB0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0CB8 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,x),  _(A,x),  _(M,R),  _(M,T),
+  /* 0CC0 */ _(M,TR),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(x,x),  _(M,T), _(M,TR),
+  /* 0CC8 */ _(M,TR),  _(x,x), _(M,TR), _(M,TR),  _(M,T),  _(V,T),  _(x,x),  _(x,x),
+  /* 0CD0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,R),  _(M,R),  _(x,x),
+  /* 0CD8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(x,x),
+  /* 0CE0 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0CF0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0CF8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Malayalam */
+
+  /* 0D00 */  _(x,x), _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x), _(VI,x), _(VI,x),
+  /* 0D10 */ _(VI,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0D18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0D20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0D28 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0D30 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0D38 */  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(A,x),  _(M,R),  _(M,R),
+  /* 0D40 */  _(M,R),  _(M,R),  _(M,R),  _(M,B),  _(M,B),  _(x,x),  _(M,L),  _(M,L),
+  /* 0D48 */  _(M,L),  _(x,x), _(M,LR), _(M,LR), _(M,LR),  _(V,T),_(CPR,x),  _(x,x),
+  /* 0D50 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,R),
+  /* 0D58 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0D60 */ _(VI,x), _(VI,x),  _(M,B),  _(M,B),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0D70 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 0D78 */  _(x,x),  _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x),
+
+  /* Sinhala */
+
+  /* 0D80 */  _(x,x),  _(x,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x),
+  /* 0D98 */  _(x,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0DA0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0DA8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0DB0 */  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 0DB8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(x,x),  _(x,x),
+  /* 0DC0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),
+  /* 0DC8 */  _(x,x),  _(x,x),  _(V,T),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,R),
+  /* 0DD0 */  _(M,R),  _(M,R),  _(M,T),  _(M,T),  _(M,B),  _(x,x),  _(M,B),  _(x,x),
+  /* 0DD8 */  _(M,R),  _(M,L), _(M,TL),  _(M,L), _(M,LR),_(M,TLR), _(M,LR),  _(M,R),
+  /* 0DE0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 0DE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 0DF0 */  _(x,x),  _(x,x),  _(M,R),  _(M,R),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x1000u 1304
+
+
+  /* Myanmar */
+
+  /* 1000 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1008 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1010 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1018 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1020 */  _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 1028 */ _(VI,x), _(VI,x), _(VI,x),  _(M,R),  _(M,R),  _(M,T),  _(M,T),  _(M,B),
+  /* 1030 */  _(M,B),  _(M,L),  _(M,T),  _(M,T),  _(M,T),  _(M,T), _(Bi,x), _(TM,x),
+  /* 1038 */ _(Vs,x), _(IS,x), _(PK,T), _(CM,x), _(CM,x), _(CM,x), _(CM,x),  _(C,x),
+  /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 1048 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(CP,x),  _(x,x),
+  /* 1050 */  _(C,x),  _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(M,R),  _(M,R),
+  /* 1058 */  _(M,B),  _(M,B),  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(CM,x), _(CM,x),
+  /* 1060 */ _(CM,x),  _(C,x),  _(M,R), _(TM,x), _(TM,x),  _(C,x),  _(C,x),  _(M,R),
+  /* 1068 */  _(M,R), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x),  _(C,x),  _(C,x),
+  /* 1070 */  _(C,x),  _(M,T),  _(M,T),  _(M,T),  _(M,T),  _(C,x),  _(C,x),  _(C,x),
+  /* 1078 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1080 */  _(C,x),  _(C,x), _(CM,x),  _(M,R),  _(M,L),  _(M,T),  _(M,T), _(TM,x),
+  /* 1088 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x),  _(C,x), _(TM,x),
+  /* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 1098 */ _(Nd,x), _(Nd,x), _(TM,x), _(TM,x),  _(M,R),  _(M,T),  _(x,x),  _(x,x),
+
+#define indic_offset_0x1700u 1464
+
+
+  /* Tagalog */
+
+  /* 1700 */ _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1708 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),
+  /* 1710 */  _(C,x),  _(C,x),  _(M,T),  _(M,B), _(PK,B),  _(x,x),  _(x,x),  _(x,x),
+  /* 1718 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Hanunoo */
+
+  /* 1720 */ _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1728 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1730 */  _(C,x),  _(C,x),  _(M,T),  _(M,B), _(PK,B),  _(x,x),  _(x,x),  _(x,x),
+  /* 1738 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Buhid */
+
+  /* 1740 */ _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1748 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1750 */  _(C,x),  _(C,x),  _(M,T),  _(M,B),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1758 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Tagbanwa */
+
+  /* 1760 */ _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1768 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),
+  /* 1770 */  _(C,x),  _(x,x),  _(M,T),  _(M,B),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1778 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Khmer */
+
+  /* 1780 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1788 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1790 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1798 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 17A0 */  _(C,x),  _(C,x),  _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x),  _(M,R),  _(M,T),
+  /* 17B8 */  _(M,T),  _(M,T),  _(M,T),  _(M,B),  _(M,B),  _(M,B), _(M,TL),_(M,TLR),
+  /* 17C0 */ _(M,LR),  _(M,L),  _(M,L),  _(M,L), _(M,LR), _(M,LR), _(Bi,x), _(Vs,x),
+  /* 17C8 */  _(M,R), _(RS,T), _(RS,T), _(RS,T),_(CSR,T),  _(M,T),  _(M,T),  _(M,T),
+  /* 17D0 */  _(M,T), _(PK,T), _(IS,x),  _(M,T),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 17D8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(A,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 17E0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 17E8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x1900u 1704
+
+
+  /* Limbu */
+
+  /* 1900 */ _(CP,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1908 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1910 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1918 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),
+  /* 1920 */  _(M,T),  _(M,T),  _(M,B),  _(M,R),  _(M,R), _(M,TR), _(M,TR),  _(M,T),
+  /* 1928 */  _(M,T), _(CS,x), _(CS,x), _(CS,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1930 */ _(CF,x), _(CF,x), _(Bi,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
+  /* 1938 */ _(CF,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1940 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 1948 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+
+  /* Tai Le */
+
+  /* 1950 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1958 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1960 */  _(C,x),  _(C,x),  _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),
+  /* 1968 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),  _(x,x),  _(x,x),
+  /* 1970 */ _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(TL,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1978 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* New Tai Lue */
+
+  /* 1980 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1988 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1990 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1998 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 19A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 19A8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 19B0 */  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(M,L),  _(M,L),  _(M,L),
+  /* 19B8 */  _(M,R),  _(M,R),  _(M,L),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(M,R),
+  /* 19C0 */  _(M,R), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
+  /* 19C8 */ _(TM,x), _(TM,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 19D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 19D8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 19E0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 19E8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 19F0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 19F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Buginese */
+
+  /* 1A00 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1A08 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1A10 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(M,T),
+  /* 1A18 */  _(M,B),  _(M,L),  _(M,R),  _(M,T),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Tai Tham */
+
+  /* 1A20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1A28 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1A30 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1A38 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1A40 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1A48 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 1A50 */ _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x), _(CM,L), _(CM,x), _(CF,x),
+  /* 1A58 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),  _(x,x),
+  /* 1A60 */ _(IS,x),  _(M,R),  _(M,T),  _(M,R),  _(M,R),  _(M,T),  _(M,T),  _(M,T),
+  /* 1A68 */  _(M,T),  _(M,B),  _(M,B),  _(M,T),  _(M,B),  _(M,R),  _(M,L),  _(M,L),
+  /* 1A70 */  _(M,L),  _(M,L),  _(M,L),  _(M,T),  _(M,T), _(TM,x), _(TM,x), _(TM,x),
+  /* 1A78 */ _(TM,x), _(TM,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1A80 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 1A88 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1A90 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 1A98 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x1b00u 2120
+
+
+  /* Balinese */
+
+  /* 1B00 */ _(Bi,x), _(Bi,x), _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 1B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 1B10 */ _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1B18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1B20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1B28 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1B30 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(N,x),  _(M,R),  _(M,T),  _(M,T),
+  /* 1B38 */  _(M,B),  _(M,B),  _(M,B), _(M,BR), _(M,TB),_(M,TBR),  _(M,L),  _(M,L),
+  /* 1B40 */ _(M,LR), _(M,LR),  _(M,T), _(M,TR),  _(V,R),  _(C,x),  _(C,x),  _(C,x),
+  /* 1B48 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1B50 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 1B58 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1B60 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1B68 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1B70 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1B78 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Sundanese */
+
+  /* 1B80 */ _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 1B88 */ _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1B90 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1B98 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1BA0 */  _(C,x), _(CS,x), _(CS,x), _(CS,x),  _(M,T),  _(M,B),  _(M,L),  _(M,R),
+  /* 1BA8 */  _(M,T),  _(M,T), _(PK,R), _(IS,x), _(CS,x), _(CS,x),  _(C,x),  _(C,x),
+  /* 1BB0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 1BB8 */ _(Nd,x), _(Nd,x),  _(A,x),  _(C,x),  _(C,x),  _(C,x), _(CF,x), _(CF,x),
+
+  /* Batak */
+
+  /* 1BC0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1BC8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1BD0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1BD8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1BE0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(VI,x), _(VI,x),  _(N,x),  _(M,R),
+  /* 1BE8 */  _(M,T),  _(M,T),  _(M,R),  _(M,R),  _(M,R),  _(M,T),  _(M,R),  _(M,T),
+  /* 1BF0 */ _(CF,x), _(CF,x), _(PK,R), _(PK,R),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1BF8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Lepcha */
+
+  /* 1C00 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1C08 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1C10 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1C18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 1C20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(CS,x), _(CS,x),  _(M,R),  _(M,L),
+  /* 1C28 */  _(M,L), _(M,TL),  _(M,R),  _(M,R),  _(M,B), _(CF,x), _(CF,x), _(CF,x),
+  /* 1C30 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(Bi,L), _(Bi,L),  _(x,x),  _(N,x),
+  /* 1C38 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1C40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 1C48 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),
+
+#define indic_offset_0x1cd0u 2456
+
+
+  /* Vedic Extensions */
+
+  /* 1CD0 */ _(TM,x), _(TM,x), _(TM,x),  _(x,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x),
+  /* 1CD8 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x),
+  /* 1CE0 */ _(TM,x), _(TM,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1CE8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 1CF0 */  _(x,x),  _(x,x), _(Vs,x), _(Vs,x), _(TM,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x2008u 2496
+
+
+  /* General Punctuation */
+
+  /* 2008 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),_(ZWNJ,x),_(ZWJ,x),  _(x,x),  _(x,x),
+  /* 2010 */  _(x,x),  _(x,x), _(CP,x), _(CP,x), _(CP,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0xa800u 2512
+
+
+  /* Syloti Nagri */
+
+  /* A800 */ _(VI,x), _(VI,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x), _(PK,T),  _(C,x),
+  /* A808 */  _(C,x),  _(C,x),  _(C,x), _(Bi,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A810 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A818 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A820 */  _(C,x),  _(C,x),  _(C,x),  _(M,R),  _(M,R),  _(M,B),  _(M,T),  _(M,R),
+  /* A828 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A830 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A838 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Phags-pa */
+
+  /* A840 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A848 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A850 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A858 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(Vo,x), _(Vo,x),
+  /* A860 */ _(Vo,x), _(Vo,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(Vo,x), _(CS,x),
+  /* A868 */ _(CS,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A870 */  _(C,x), _(CS,x),  _(C,x), _(Bi,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A878 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Saurashtra */
+
+  /* A880 */ _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* A888 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* A890 */ _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A898 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A8A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A8A8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A8B0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(CF,x),  _(M,R),  _(M,R),  _(M,R),
+  /* A8B8 */  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(M,R),
+  /* A8C0 */  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(V,B),  _(x,x),  _(x,x),  _(x,x),
+  /* A8C8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A8D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* A8D8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Devanagari Extended */
+
+  /* A8E0 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x),
+  /* A8E8 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x),
+  /* A8F0 */ _(Ca,x), _(Ca,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A8F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Kayah Li */
+
+  /* A900 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* A908 */ _(Nd,x), _(Nd,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A910 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A918 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A920 */  _(C,x),  _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),
+  /* A928 */ _(Vo,x), _(Vo,x), _(Vo,x), _(TM,x), _(TM,x), _(TM,x),  _(x,x),  _(x,x),
+
+  /* Rejang */
+
+  /* A930 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A938 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A940 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(M,B),
+  /* A948 */  _(M,B),  _(M,B),  _(M,T),  _(M,B),  _(M,B),  _(M,B),  _(M,B), _(CF,x),
+  /* A950 */ _(CF,x), _(CF,x), _(CF,x), _(PK,R),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A958 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A960 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A968 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A970 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A978 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Javanese */
+
+  /* A980 */ _(Bi,x), _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* A988 */ _(VI,x),  _(C,x),  _(C,x),  _(C,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),
+  /* A990 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A998 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A9A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A9A8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A9B0 */  _(C,x),  _(C,x),  _(C,x),  _(N,x),  _(M,R),  _(M,R),  _(M,T),  _(M,T),
+  /* A9B8 */  _(M,B),  _(M,B),  _(M,L),  _(M,L),  _(M,T), _(CS,x), _(CM,x), _(CM,x),
+  /* A9C0 */ _(V,BR),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A9C8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* A9D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* A9D8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Myanmar Extended-B */
+
+  /* A9E0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(C,x),
+  /* A9E8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* A9F8 */ _(Nd,x), _(Nd,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),
+
+  /* Cham */
+
+  /* AA00 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),
+  /* AA08 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA10 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA18 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA28 */  _(C,x),  _(M,T),  _(M,T),  _(M,T),  _(M,T),  _(M,B),  _(M,T),  _(M,L),
+  /* AA30 */  _(M,L),  _(M,T),  _(M,B), _(CM,x), _(CM,L), _(CM,x), _(CM,x),  _(x,x),
+  /* AA38 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* AA40 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
+  /* AA48 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),  _(x,x),  _(x,x),
+  /* AA50 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* AA58 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Myanmar Extended-A */
+
+  /* AA60 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA68 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA70 */  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* AA78 */  _(x,x),  _(x,x),  _(C,x), _(TM,x), _(TM,x), _(TM,x),  _(C,x),  _(C,x),
+
+  /* Tai Viet */
+
+  /* AA80 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA88 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA90 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AA98 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AAA0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AAA8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AAB0 */  _(M,T),  _(M,R),  _(M,T),  _(M,T),  _(M,B),_(M,VOL),_(M,VOL),  _(M,T),
+  /* AAB8 */  _(M,T),_(M,VOL),  _(M,R),_(M,VOL),_(M,VOL),  _(M,R),  _(M,T), _(TM,x),
+  /* AAC0 */ _(TL,x), _(TM,x), _(TL,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* AAC8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* AAD0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* AAD8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Meetei Mayek Extensions */
+
+  /* AAE0 */ _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* AAE8 */  _(C,x),  _(C,x),  _(C,x),  _(M,L),  _(M,B),  _(M,T),  _(M,L),  _(M,R),
+  /* AAF0 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(Vs,x), _(IS,x),  _(x,x),
+
+#define indic_offset_0xabc0u 3272
+
+
+  /* Meetei Mayek */
+
+  /* ABC0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* ABC8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(VI,x), _(VI,x),
+  /* ABD0 */  _(C,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* ABD8 */  _(C,x),  _(C,x),  _(C,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
+  /* ABE0 */ _(CF,x), _(CF,x), _(CF,x),  _(M,R),  _(M,R),  _(M,T),  _(M,R),  _(M,R),
+  /* ABE8 */  _(M,B),  _(M,R),  _(M,R),  _(x,x), _(TM,x), _(PK,B),  _(x,x),  _(x,x),
+  /* ABF0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* ABF8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x10a00u 3336
+
+
+  /* Kharoshthi */
+
+  /* 10A00 */  _(C,x),  _(M,O),  _(M,B),  _(M,B),  _(x,x),  _(M,T),  _(M,O),  _(x,x),
+  /* 10A08 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,B),  _(x,x), _(Bi,x), _(Vs,x),
+  /* 10A10 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 10A18 */  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 10A20 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 10A28 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 10A30 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 10A38 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(IS,x),
+  /* 10A40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+
+#define indic_offset_0x11000u 3408
+
+
+  /* Brahmi */
+
+  /* 11000 */ _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11008 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11010 */ _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11018 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11020 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11028 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11030 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11038 */  _(M,T),  _(M,T),  _(M,T),  _(M,T),  _(M,B),  _(M,B),  _(M,B),  _(M,B),
+  /* 11040 */  _(M,B),  _(M,B),  _(M,T),  _(M,T),  _(M,T),  _(M,T),  _(V,T),  _(x,x),
+  /* 11048 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11050 */  _(x,x),  _(x,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),
+  /* 11058 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),
+  /* 11060 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), _(Nd,x), _(Nd,x),
+  /* 11068 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 11070 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11078 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x), _(NJ,x),
+
+  /* Kaithi */
+
+  /* 11080 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11088 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11090 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11098 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 110A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 110A8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 110B0 */  _(M,R),  _(M,L),  _(M,R),  _(M,B),  _(M,B),  _(M,T),  _(M,T),  _(M,R),
+  /* 110B8 */  _(M,R),  _(V,B),  _(N,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x11100u 3600
+
+
+  /* Chakma */
+
+  /* 11100 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),
+  /* 11108 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11110 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11118 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11120 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(M,T),
+  /* 11128 */  _(M,T),  _(M,T),  _(M,B),  _(M,B),  _(M,L),  _(M,T), _(M,TB), _(M,TB),
+  /* 11130 */  _(M,T),  _(M,B),  _(M,B), _(IS,x), _(PK,T),  _(x,x), _(Nd,x), _(Nd,x),
+  /* 11138 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 11140 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11148 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Mahajani */
+
+  /* 11150 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11158 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11160 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11168 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11170 */  _(C,x),  _(C,x),  _(C,x),  _(N,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11178 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Sharada */
+
+  /* 11180 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11188 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11190 */ _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11198 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 111A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 111A8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 111B0 */  _(C,x),  _(C,x),  _(C,x),  _(M,R),  _(M,L),  _(M,R),  _(M,B),  _(M,B),
+  /* 111B8 */  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(M,T),  _(M,T),  _(M,T), _(M,TR),
+  /* 111C0 */  _(V,R),  _(A,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 111C8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 111D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 111D8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Sinhala Archaic Numbers */
+
+  /* 111E0 */  _(x,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 111E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 111F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 111F8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Khojki */
+
+  /* 11200 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11208 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11210 */  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11218 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11220 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11228 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(M,R),  _(M,R),  _(M,R),  _(M,B),
+  /* 11230 */  _(M,T),  _(M,T), _(M,TR), _(M,TR), _(Bi,x),  _(V,R),  _(N,x), _(GM,T),
+
+#define indic_offset_0x112b0u 3912
+
+
+  /* Khudawadi */
+
+  /* 112B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 112B8 */ _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 112C0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 112C8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 112D0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 112D8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x), _(Bi,x),
+  /* 112E0 */  _(M,R),  _(M,L),  _(M,R),  _(M,B),  _(M,B),  _(M,T),  _(M,T),  _(M,T),
+  /* 112E8 */  _(M,T),  _(N,x), _(PK,B),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 112F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 112F8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Grantha */
+
+  /* 11300 */  _(x,x), _(Bi,x), _(Bi,x), _(Vs,x),  _(x,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11308 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(x,x),  _(x,x), _(VI,x),
+  /* 11310 */ _(VI,x),  _(x,x),  _(x,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11318 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11320 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11328 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11330 */  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(x,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11338 */  _(C,x),  _(C,x),  _(x,x),  _(x,x),  _(N,x),  _(A,x),  _(M,R),  _(M,R),
+  /* 11340 */  _(M,T),  _(M,R),  _(M,R),  _(M,R),  _(M,R),  _(x,x),  _(x,x),  _(M,L),
+  /* 11348 */  _(M,L),  _(x,x),  _(x,x), _(M,LR), _(M,LR),  _(V,R),  _(x,x),  _(x,x),
+  /* 11350 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(M,R),
+  /* 11358 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11360 */ _(VI,x), _(VI,x),  _(M,R),  _(M,R),  _(x,x),  _(x,x), _(Ca,x), _(Ca,x),
+  /* 11368 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11370 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x11480u 4112
+
+
+  /* Tirhuta */
+
+  /* 11480 */  _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11488 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),
+  /* 11490 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11498 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 114A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 114A8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 114B0 */  _(M,R),  _(M,L),  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(M,B),
+  /* 114B8 */  _(M,B),  _(M,L),  _(M,T), _(M,TL), _(M,LR),  _(M,R), _(M,LR), _(Bi,x),
+  /* 114C0 */ _(Bi,x), _(Vs,x),  _(V,B),  _(N,x),  _(A,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 114C8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 114D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 114D8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x11580u 4208
+
+
+  /* Siddham */
+
+  /* 11580 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11588 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),
+  /* 11590 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11598 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 115A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 115A8 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(M,R),
+  /* 115B0 */  _(M,L),  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(x,x),  _(x,x),
+  /* 115B8 */  _(M,L), _(M,TL), _(M,LR),_(M,TLR), _(Bi,x), _(Bi,x), _(Vs,x),  _(V,B),
+  /* 115C0 */  _(N,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+#define indic_offset_0x11600u 4280
+
+
+  /* Modi */
+
+  /* 11600 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11608 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),  _(C,x),  _(C,x),
+  /* 11610 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11618 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11620 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11628 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11630 */  _(M,R),  _(M,R),  _(M,R),  _(M,B),  _(M,B),  _(M,B),  _(M,B),  _(M,B),
+  /* 11638 */  _(M,B),  _(M,T),  _(M,T),  _(M,R),  _(M,R), _(Bi,x), _(Vs,x),  _(V,B),
+  /* 11640 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11648 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11650 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 11658 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11660 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11668 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11670 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 11678 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+  /* Takri */
+
+  /* 11680 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
+  /* 11688 */ _(VI,x), _(VI,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11690 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 11698 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 116A0 */  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),  _(C,x),
+  /* 116A8 */  _(C,x),  _(C,x),  _(C,x), _(Bi,x), _(Vs,x),  _(M,T),  _(M,L),  _(M,R),
+  /* 116B0 */  _(M,B),  _(M,B),  _(M,T),  _(M,T),  _(M,T),  _(M,T),  _(V,T),  _(N,x),
+  /* 116B8 */  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+  /* 116C0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x),
+  /* 116C8 */ _(Nd,x), _(Nd,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),  _(x,x),
+
+}; /* Table items: 4488; occupancy: 73% */
+
+INDIC_TABLE_ELEMENT_TYPE
+hb_indic_get_categories (hb_codepoint_t u)
+{
+  switch (u >> 12)
+  {
+    case 0x0u:
+      if (hb_in_range (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
+      if (hb_in_range (u, 0x00D0u, 0x00D7u)) return indic_table[u - 0x00D0u + indic_offset_0x00d0u];
+      if (hb_in_range (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
+      if (unlikely (u == 0x00A0u)) return _(CP,x);
+      break;
+
+    case 0x1u:
+      if (hb_in_range (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
+      if (hb_in_range (u, 0x1700u, 0x17EFu)) return indic_table[u - 0x1700u + indic_offset_0x1700u];
+      if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return indic_table[u - 0x1900u + indic_offset_0x1900u];
+      if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return indic_table[u - 0x1B00u + indic_offset_0x1b00u];
+      if (hb_in_range (u, 0x1CD0u, 0x1CF7u)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
+      break;
+
+    case 0x2u:
+      if (hb_in_range (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
+      if (unlikely (u == 0x25CCu)) return _(CP,x);
+      break;
+
+    case 0xAu:
+      if (hb_in_range (u, 0xA800u, 0xAAF7u)) return indic_table[u - 0xA800u + indic_offset_0xa800u];
+      if (hb_in_range (u, 0xABC0u, 0xABFFu)) return indic_table[u - 0xABC0u + indic_offset_0xabc0u];
+      break;
+
+    case 0x10u:
+      if (hb_in_range (u, 0x10A00u, 0x10A47u)) return indic_table[u - 0x10A00u + indic_offset_0x10a00u];
+      break;
+
+    case 0x11u:
+      if (hb_in_range (u, 0x11000u, 0x110BFu)) return indic_table[u - 0x11000u + indic_offset_0x11000u];
+      if (hb_in_range (u, 0x11100u, 0x11237u)) return indic_table[u - 0x11100u + indic_offset_0x11100u];
+      if (hb_in_range (u, 0x112B0u, 0x11377u)) return indic_table[u - 0x112B0u + indic_offset_0x112b0u];
+      if (hb_in_range (u, 0x11480u, 0x114DFu)) return indic_table[u - 0x11480u + indic_offset_0x11480u];
+      if (hb_in_range (u, 0x11580u, 0x115C7u)) return indic_table[u - 0x11580u + indic_offset_0x11580u];
+      if (hb_in_range (u, 0x11600u, 0x116CFu)) return indic_table[u - 0x11600u + indic_offset_0x11600u];
+      break;
+
+    default:
+      break;
+  }
+  return _(x,x);
+}
+
+#undef _
+
+#undef ISC_A
+#undef ISC_Bi
+#undef ISC_BJN
+#undef ISC_Ca
+#undef ISC_C
+#undef ISC_CD
+#undef ISC_CF
+#undef ISC_CHL
+#undef ISC_CM
+#undef ISC_CP
+#undef ISC_CPR
+#undef ISC_CS
+#undef ISC_CSR
+#undef ISC_GM
+#undef ISC_IS
+#undef ISC_ZWJ
+#undef ISC_ML
+#undef ISC_ZWNJ
+#undef ISC_N
+#undef ISC_Nd
+#undef ISC_NJ
+#undef ISC_x
+#undef ISC_PK
+#undef ISC_RS
+#undef ISC_TL
+#undef ISC_TM
+#undef ISC_V
+#undef ISC_Vs
+#undef ISC_Vo
+#undef ISC_M
+#undef ISC_VI
+
+#undef IMC_B
+#undef IMC_BR
+#undef IMC_L
+#undef IMC_LR
+#undef IMC_x
+#undef IMC_O
+#undef IMC_R
+#undef IMC_T
+#undef IMC_TB
+#undef IMC_TBR
+#undef IMC_TL
+#undef IMC_TLR
+#undef IMC_TR
+#undef IMC_VOL
+
+/* == End of generated table == */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1843 @@
+/*
+ * Copyright © 2011,2012  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
+ */
+
+#include "hb-ot-shape-complex-indic-private.hh"
+#include "hb-ot-layout-private.hh"
+
+/* buffer var allocations */
+#define indic_category() complex_var_u8_0() /* indic_category_t */
+#define indic_position() complex_var_u8_1() /* indic_position_t */
+
+
+/*
+ * Indic shaper.
+ */
+
+
+#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base))
+
+#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u))
+#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u))
+#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u))
+#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u))
+#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u))
+#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u))
+#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u))
+#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u))
+#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u))
+#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u))
+#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780u))
+
+
+#define MATRA_POS_LEFT(u)       POS_PRE_M
+#define MATRA_POS_RIGHT(u)      ( \
+                                  IS_DEVA(u) ? POS_AFTER_SUB  : \
+                                  IS_BENG(u) ? POS_AFTER_POST : \
+                                  IS_GURU(u) ? POS_AFTER_POST : \
+                                  IS_GUJR(u) ? POS_AFTER_POST : \
+                                  IS_ORYA(u) ? POS_AFTER_POST : \
+                                  IS_TAML(u) ? POS_AFTER_POST : \
+                                  IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
+                                  IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
+                                  IS_MLYM(u) ? POS_AFTER_POST : \
+                                  IS_SINH(u) ? POS_AFTER_SUB  : \
+                                  IS_KHMR(u) ? POS_AFTER_POST : \
+                                  /*default*/  POS_AFTER_SUB    \
+                                )
+#define MATRA_POS_TOP(u)        ( /* BENG and MLYM don't have top matras. */ \
+                                  IS_DEVA(u) ? POS_AFTER_SUB  : \
+                                  IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \
+                                  IS_GUJR(u) ? POS_AFTER_SUB  : \
+                                  IS_ORYA(u) ? POS_AFTER_MAIN : \
+                                  IS_TAML(u) ? POS_AFTER_SUB  : \
+                                  IS_TELU(u) ? POS_BEFORE_SUB : \
+                                  IS_KNDA(u) ? POS_BEFORE_SUB : \
+                                  IS_SINH(u) ? POS_AFTER_SUB  : \
+                                  IS_KHMR(u) ? POS_AFTER_POST : \
+                                  /*default*/  POS_AFTER_SUB    \
+                                )
+#define MATRA_POS_BOTTOM(u)     ( \
+                                  IS_DEVA(u) ? POS_AFTER_SUB  : \
+                                  IS_BENG(u) ? POS_AFTER_SUB  : \
+                                  IS_GURU(u) ? POS_AFTER_POST : \
+                                  IS_GUJR(u) ? POS_AFTER_POST : \
+                                  IS_ORYA(u) ? POS_AFTER_SUB  : \
+                                  IS_TAML(u) ? POS_AFTER_POST : \
+                                  IS_TELU(u) ? POS_BEFORE_SUB : \
+                                  IS_KNDA(u) ? POS_BEFORE_SUB : \
+                                  IS_MLYM(u) ? POS_AFTER_POST : \
+                                  IS_SINH(u) ? POS_AFTER_SUB  : \
+                                  IS_KHMR(u) ? POS_AFTER_POST : \
+                                  /*default*/  POS_AFTER_SUB    \
+                                )
+
+static inline indic_position_t
+matra_position (hb_codepoint_t u, indic_position_t side)
+{
+  switch ((int) side)
+  {
+    case POS_PRE_C:     return MATRA_POS_LEFT (u);
+    case POS_POST_C:    return MATRA_POS_RIGHT (u);
+    case POS_ABOVE_C:   return MATRA_POS_TOP (u);
+    case POS_BELOW_C:   return MATRA_POS_BOTTOM (u);
+  };
+  return side;
+}
+
+/* XXX
+ * This is a hack for now.  We should move this data into the main Indic table.
+ * Or completely remove it and just check in the tables.
+ */
+static const hb_codepoint_t ra_chars[] = {
+  0x0930u, /* Devanagari */
+  0x09B0u, /* Bengali */
+  0x09F0u, /* Bengali */
+  0x0A30u, /* Gurmukhi */       /* No Reph */
+  0x0AB0u, /* Gujarati */
+  0x0B30u, /* Oriya */
+  0x0BB0u, /* Tamil */          /* No Reph */
+  0x0C30u, /* Telugu */         /* Reph formed only with ZWJ */
+  0x0CB0u, /* Kannada */
+  0x0D30u, /* Malayalam */      /* No Reph, Logical Repha */
+
+  0x0DBBu, /* Sinhala */                /* Reph formed only with ZWJ */
+
+  0x179Au, /* Khmer */          /* No Reph, Visual Repha */
+};
+
+static inline bool
+is_ra (hb_codepoint_t u)
+{
+  for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++)
+    if (u == ra_chars[i])
+      return true;
+  return false;
+}
+
+static inline bool
+is_one_of (const hb_glyph_info_t &info, unsigned int flags)
+{
+  /* If it ligated, all bets are off. */
+  if (_hb_glyph_info_ligated (&info)) return false;
+  return !!(FLAG_SAFE (info.indic_category()) & flags);
+}
+
+static inline bool
+is_joiner (const hb_glyph_info_t &info)
+{
+  return is_one_of (info, JOINER_FLAGS);
+}
+
+static inline bool
+is_consonant (const hb_glyph_info_t &info)
+{
+  return is_one_of (info, CONSONANT_FLAGS);
+}
+
+static inline bool
+is_halant_or_coeng (const hb_glyph_info_t &info)
+{
+  return is_one_of (info, HALANT_OR_COENG_FLAGS);
+}
+
+static inline void
+set_indic_properties (hb_glyph_info_t &info)
+{
+  hb_codepoint_t u = info.codepoint;
+  unsigned int type = hb_indic_get_categories (u);
+  indic_category_t cat = (indic_category_t) (type & 0x7Fu);
+  indic_position_t pos = (indic_position_t) (type >> 8);
+
+
+  /*
+   * Re-assign category
+   */
+
+
+  /* The spec says U+0952 is OT_A.  However, testing shows that Uniscribe
+   * treats a whole bunch of characters similarly.
+   * TESTS: For example, for U+0951:
+   * U+092E,U+0947,U+0952
+   * U+092E,U+0952,U+0947
+   * U+092E,U+0947,U+0951
+   * U+092E,U+0951,U+0947
+   * U+092E,U+0951,U+0952
+   * U+092E,U+0952,U+0951
+   */
+  if (unlikely (hb_in_ranges (u, 0x0951u, 0x0952u,
+                                 0x1CD0u, 0x1CD2u,
+                                 0x1CD4u, 0x1CE1u) ||
+                            u == 0x1CF4u))
+    cat = OT_A;
+  /* The following act more like the Bindus. */
+  else if (unlikely (hb_in_range (u, 0x0953u, 0x0954u)))
+    cat = OT_SM;
+  /* The following act like consonants. */
+  else if (unlikely (hb_in_ranges (u, 0x0A72u, 0x0A73u,
+                                      0x1CF5u, 0x1CF6u)))
+    cat = OT_C;
+  /* TODO: The following should only be allowed after a Visarga.
+   * For now, just treat them like regular tone marks. */
+  else if (unlikely (hb_in_range (u, 0x1CE2u, 0x1CE8u)))
+    cat = OT_A;
+  /* TODO: The following should only be allowed after some of
+   * the nasalization marks, maybe only for U+1CE9..U+1CF1.
+   * For now, just treat them like tone marks. */
+  else if (unlikely (u == 0x1CEDu))
+    cat = OT_A;
+  /* The following take marks in standalone clusters, similar to Avagraha. */
+  else if (unlikely (hb_in_ranges (u, 0xA8F2u, 0xA8F7u,
+                                      0x1CE9u, 0x1CECu,
+                                      0x1CEEu, 0x1CF1u)))
+  {
+    cat = OT_Symbol;
+    ASSERT_STATIC ((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol);
+  }
+  else if (unlikely (hb_in_range (u, 0x17CDu, 0x17D1u) ||
+                     u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */
+  {
+    /* These are like Top Matras. */
+    cat = OT_M;
+    pos = POS_ABOVE_C;
+  }
+  else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */
+  else if (unlikely (u == 0x17D2u)) cat = OT_Coeng; /* Khmer coeng */
+  else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u)))
+                                    cat = OT_PLACEHOLDER;
+  else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
+  else if (unlikely (u == 0xA982u)) cat = OT_SM; /* Javanese repha. */
+  else if (unlikely (u == 0xA9BEu)) cat = OT_CM2; /* Javanese medial ya. */
+  else if (unlikely (u == 0xA9BDu)) { cat = OT_M; pos = POS_POST_C; } /* Javanese vocalic r. */
+
+
+  /*
+   * Re-assign position.
+   */
+
+  if ((FLAG_SAFE (cat) & CONSONANT_FLAGS))
+  {
+    pos = POS_BASE_C;
+    if (is_ra (u))
+      cat = OT_Ra;
+  }
+  else if (cat == OT_M)
+  {
+    pos = matra_position (u, pos);
+  }
+  else if ((FLAG_SAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol))))
+  {
+    pos = POS_SMVD;
+  }
+
+  if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */
+
+
+
+  info.indic_category() = cat;
+  info.indic_position() = pos;
+}
+
+/*
+ * Things above this line should ideally be moved to the Indic table itself.
+ */
+
+
+/*
+ * Indic configurations.  Note that we do not want to keep every single script-specific
+ * behavior in these tables necessarily.  This should mainly be used for per-script
+ * properties that are cheaper keeping here, than in the code.  Ie. if, say, one and
+ * only one script has an exception, that one script can be if'ed directly in the code,
+ * instead of adding a new flag in these structs.
+ */
+
+enum base_position_t {
+  BASE_POS_FIRST,
+  BASE_POS_LAST_SINHALA,
+  BASE_POS_LAST
+};
+enum reph_position_t {
+  REPH_POS_AFTER_MAIN  = POS_AFTER_MAIN,
+  REPH_POS_BEFORE_SUB  = POS_BEFORE_SUB,
+  REPH_POS_AFTER_SUB   = POS_AFTER_SUB,
+  REPH_POS_BEFORE_POST = POS_BEFORE_POST,
+  REPH_POS_AFTER_POST  = POS_AFTER_POST,
+  REPH_POS_DONT_CARE   = POS_RA_TO_BECOME_REPH
+};
+enum reph_mode_t {
+  REPH_MODE_IMPLICIT,  /* Reph formed out of initial Ra,H sequence. */
+  REPH_MODE_EXPLICIT,  /* Reph formed out of initial Ra,H,ZWJ sequence. */
+  REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */
+  REPH_MODE_LOG_REPHA  /* Encoded Repha character, needs reordering. */
+};
+enum blwf_mode_t {
+  BLWF_MODE_PRE_AND_POST, /* Below-forms feature applied to pre-base and post-base. */
+  BLWF_MODE_POST_ONLY     /* Below-forms feature applied to post-base only. */
+};
+enum pref_len_t {
+  PREF_LEN_1 = 1,
+  PREF_LEN_2 = 2,
+  PREF_LEN_DONT_CARE = PREF_LEN_2
+};
+struct indic_config_t
+{
+  hb_script_t     script;
+  bool            has_old_spec;
+  hb_codepoint_t  virama;
+  base_position_t base_pos;
+  reph_position_t reph_pos;
+  reph_mode_t     reph_mode;
+  blwf_mode_t     blwf_mode;
+  pref_len_t      pref_len;
+};
+
+static const indic_config_t indic_configs[] =
+{
+  /* Default.  Should be first. */
+  {HB_SCRIPT_INVALID,   false,      0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
+  {HB_SCRIPT_DEVANAGARI,true, 0x094Du,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+  {HB_SCRIPT_BENGALI,   true, 0x09CDu,BASE_POS_LAST, REPH_POS_AFTER_SUB,  REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+  {HB_SCRIPT_GURMUKHI,  true, 0x0A4Du,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+  {HB_SCRIPT_GUJARATI,  true, 0x0ACDu,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+  {HB_SCRIPT_ORIYA,     true, 0x0B4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+  {HB_SCRIPT_TAMIL,     true, 0x0BCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+  {HB_SCRIPT_TELUGU,    true, 0x0C4Du,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY,    PREF_LEN_2},
+  {HB_SCRIPT_KANNADA,   true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY,    PREF_LEN_2},
+  {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+  {HB_SCRIPT_SINHALA,   false,0x0DCAu,BASE_POS_LAST_SINHALA,
+                                                     REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+  {HB_SCRIPT_KHMER,     false,0x17D2u,BASE_POS_FIRST,REPH_POS_DONT_CARE,  REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+  {HB_SCRIPT_JAVANESE,  false,0xA9C0u,BASE_POS_FIRST,REPH_POS_DONT_CARE,  REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
+};
+
+
+
+/*
+ * Indic shaper.
+ */
+
+struct feature_list_t {
+  hb_tag_t tag;
+  hb_ot_map_feature_flags_t flags;
+};
+
+static const feature_list_t
+indic_features[] =
+{
+  /*
+   * Basic features.
+   * These features are applied in order, one at a time, after initial_reordering.
+   */
+  {HB_TAG('n','u','k','t'), F_GLOBAL},
+  {HB_TAG('a','k','h','n'), F_GLOBAL},
+  {HB_TAG('r','p','h','f'), F_NONE},
+  {HB_TAG('r','k','r','f'), F_GLOBAL},
+  {HB_TAG('p','r','e','f'), F_NONE},
+  {HB_TAG('b','l','w','f'), F_NONE},
+  {HB_TAG('a','b','v','f'), F_NONE},
+  {HB_TAG('h','a','l','f'), F_NONE},
+  {HB_TAG('p','s','t','f'), F_NONE},
+  {HB_TAG('v','a','t','u'), F_GLOBAL},
+  {HB_TAG('c','j','c','t'), F_GLOBAL},
+  {HB_TAG('c','f','a','r'), F_NONE},
+  /*
+   * Other features.
+   * These features are applied all at once, after final_reordering.
+   * Default Bengali font in Windows for example has intermixed
+   * lookups for init,pres,abvs,blws features.
+   */
+  {HB_TAG('i','n','i','t'), F_NONE},
+  {HB_TAG('p','r','e','s'), F_GLOBAL},
+  {HB_TAG('a','b','v','s'), F_GLOBAL},
+  {HB_TAG('b','l','w','s'), F_GLOBAL},
+  {HB_TAG('p','s','t','s'), F_GLOBAL},
+  {HB_TAG('h','a','l','n'), F_GLOBAL},
+  /* Positioning features, though we don't care about the types. */
+  {HB_TAG('d','i','s','t'), F_GLOBAL},
+  {HB_TAG('a','b','v','m'), F_GLOBAL},
+  {HB_TAG('b','l','w','m'), F_GLOBAL},
+};
+
+/*
+ * Must be in the same order as the indic_features array.
+ */
+enum {
+  _NUKT,
+  _AKHN,
+  RPHF,
+  _RKRF,
+  PREF,
+  BLWF,
+  ABVF,
+  HALF,
+  PSTF,
+  _VATU,
+  _CJCT,
+  CFAR,
+
+  INIT,
+  _PRES,
+  _ABVS,
+  _BLWS,
+  _PSTS,
+  _HALN,
+  _DIST,
+  _ABVM,
+  _BLWM,
+
+  INDIC_NUM_FEATURES,
+  INDIC_BASIC_FEATURES = INIT /* Don't forget to update this! */
+};
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+                 hb_font_t *font,
+                 hb_buffer_t *buffer);
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+                    hb_font_t *font,
+                    hb_buffer_t *buffer);
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+                  hb_font_t *font,
+                  hb_buffer_t *buffer);
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan,
+                 hb_font_t *font,
+                 hb_buffer_t *buffer);
+
+static void
+collect_features_indic (hb_ot_shape_planner_t *plan)
+{
+  hb_ot_map_builder_t *map = &plan->map;
+
+  /* Do this before any lookups have been applied. */
+  map->add_gsub_pause (setup_syllables);
+
+  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+  /* The Indic specs do not require ccmp, but we apply it here since if
+   * there is a use of it, it's typically at the beginning. */
+  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+
+
+  unsigned int i = 0;
+  map->add_gsub_pause (initial_reordering);
+  for (; i < INDIC_BASIC_FEATURES; i++) {
+    map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
+    map->add_gsub_pause (NULL);
+  }
+  map->add_gsub_pause (final_reordering);
+  for (; i < INDIC_NUM_FEATURES; i++) {
+    map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
+  }
+
+  map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+  map->add_global_bool_feature (HB_TAG('c','l','i','g'));
+
+  map->add_gsub_pause (clear_syllables);
+}
+
+static void
+override_features_indic (hb_ot_shape_planner_t *plan)
+{
+  /* Uniscribe does not apply 'kern' in Khmer. */
+  if (hb_options ().uniscribe_bug_compatible)
+  {
+    switch ((hb_tag_t) plan->props.script)
+    {
+      case HB_SCRIPT_KHMER:
+        plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+        break;
+    }
+  }
+
+  plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+}
+
+
+struct would_substitute_feature_t
+{
+  inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
+  {
+    zero_context = zero_context_;
+    map->get_stage_lookups (0/*GSUB*/,
+                            map->get_feature_stage (0/*GSUB*/, feature_tag),
+                            &lookups, &count);
+  }
+
+  inline bool would_substitute (const hb_codepoint_t *glyphs,
+                                unsigned int          glyphs_count,
+                                hb_face_t            *face) const
+  {
+    for (unsigned int i = 0; i < count; i++)
+      if (hb_ot_layout_lookup_would_substitute_fast (face, lookups[i].index, glyphs, glyphs_count, zero_context))
+        return true;
+    return false;
+  }
+
+  private:
+  const hb_ot_map_t::lookup_map_t *lookups;
+  unsigned int count;
+  bool zero_context;
+};
+
+struct indic_shape_plan_t
+{
+  ASSERT_POD ();
+
+  inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
+  {
+    hb_codepoint_t glyph = virama_glyph;
+    if (unlikely (virama_glyph == (hb_codepoint_t) -1))
+    {
+      if (!config->virama || !font->get_glyph (config->virama, 0, &glyph))
+        glyph = 0;
+      /* Technically speaking, the spec says we should apply 'locl' to virama too.
+       * Maybe one day... */
+
+      /* Our get_glyph() function needs a font, so we can't get the virama glyph
+       * during shape planning...  Instead, overwrite it here.  It's safe.  Don't worry! */
+      (const_cast<indic_shape_plan_t *> (this))->virama_glyph = glyph;
+    }
+
+    *pglyph = glyph;
+    return glyph != 0;
+  }
+
+  const indic_config_t *config;
+
+  bool is_old_spec;
+  hb_codepoint_t virama_glyph;
+
+  would_substitute_feature_t rphf;
+  would_substitute_feature_t pref;
+  would_substitute_feature_t blwf;
+  would_substitute_feature_t pstf;
+
+  hb_mask_t mask_array[INDIC_NUM_FEATURES];
+};
+
+static void *
+data_create_indic (const hb_ot_shape_plan_t *plan)
+{
+  indic_shape_plan_t *indic_plan = (indic_shape_plan_t *) calloc (1, sizeof (indic_shape_plan_t));
+  if (unlikely (!indic_plan))
+    return NULL;
+
+  indic_plan->config = &indic_configs[0];
+  for (unsigned int i = 1; i < ARRAY_LENGTH (indic_configs); i++)
+    if (plan->props.script == indic_configs[i].script) {
+      indic_plan->config = &indic_configs[i];
+      break;
+    }
+
+  indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
+  indic_plan->virama_glyph = (hb_codepoint_t) -1;
+
+  /* Use zero-context would_substitute() matching for new-spec of the main
+   * Indic scripts, and scripts with one spec only, but not for old-specs. */
+  bool zero_context = !indic_plan->is_old_spec;
+  indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context);
+  indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context);
+  indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context);
+  indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'), zero_context);
+
+  for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
+    indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
+                                 0 : plan->map.get_1_mask (indic_features[i].tag);
+
+  return indic_plan;
+}
+
+static void
+data_destroy_indic (void *data)
+{
+  free (data);
+}
+
+static indic_position_t
+consonant_position_from_face (const indic_shape_plan_t *indic_plan,
+                              const hb_codepoint_t consonant,
+                              const hb_codepoint_t virama,
+                              hb_face_t *face)
+{
+  /* For old-spec, the order of glyphs is Consonant,Virama,
+   * whereas for new-spec, it's Virama,Consonant.  However,
+   * some broken fonts (like Free Sans) simply copied lookups
+   * from old-spec to new-spec without modification.
+   * And oddly enough, Uniscribe seems to respect those lookups.
+   * Eg. in the sequence U+0924,U+094D,U+0930, Uniscribe finds
+   * base at 0.  The font however, only has lookups matching
+   * 930,94D in 'blwf', not the expected 94D,930 (with new-spec
+   * table).  As such, we simply match both sequences.  Seems
+   * to work. */
+  hb_codepoint_t glyphs[3] = {virama, consonant, virama};
+  if (indic_plan->blwf.would_substitute (glyphs  , 2, face) ||
+      indic_plan->blwf.would_substitute (glyphs+1, 2, face))
+    return POS_BELOW_C;
+  if (indic_plan->pstf.would_substitute (glyphs  , 2, face) ||
+      indic_plan->pstf.would_substitute (glyphs+1, 2, face))
+    return POS_POST_C;
+  unsigned int pref_len = indic_plan->config->pref_len;
+  if ((pref_len == PREF_LEN_2 &&
+       (indic_plan->pref.would_substitute (glyphs  , 2, face) ||
+        indic_plan->pref.would_substitute (glyphs+1, 2, face)))
+   || (pref_len == PREF_LEN_1 &&
+       indic_plan->pref.would_substitute (glyphs+1, 1, face)))
+    return POS_POST_C;
+  return POS_BASE_C;
+}
+
+
+enum syllable_type_t {
+  consonant_syllable,
+  vowel_syllable,
+  standalone_cluster,
+  symbol_cluster,
+  broken_cluster,
+  non_indic_cluster,
+};
+
+#include "hb-ot-shape-complex-indic-machine.hh"
+
+
+static void
+setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                   hb_buffer_t              *buffer,
+                   hb_font_t                *font HB_UNUSED)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
+  HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
+
+  /* We cannot setup masks here.  We save information about characters
+   * and setup masks later on in a pause-callback. */
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    set_indic_properties (info[i]);
+}
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                 hb_font_t *font HB_UNUSED,
+                 hb_buffer_t *buffer)
+{
+  find_syllables (buffer);
+}
+
+static int
+compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+  int a = pa->indic_position();
+  int b = pb->indic_position();
+
+  return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+
+static void
+update_consonant_positions (const hb_ot_shape_plan_t *plan,
+                            hb_font_t         *font,
+                            hb_buffer_t       *buffer)
+{
+  const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+
+  if (indic_plan->config->base_pos != BASE_POS_LAST)
+    return;
+
+  hb_codepoint_t virama;
+  if (indic_plan->get_virama_glyph (font, &virama))
+  {
+    hb_face_t *face = font->face;
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    for (unsigned int i = 0; i < count; i++)
+      if (info[i].indic_position() == POS_BASE_C)
+      {
+        hb_codepoint_t consonant = info[i].codepoint;
+        info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face);
+      }
+  }
+}
+
+
+/* Rules from:
+ * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
+
+static void
+initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
+                                       hb_face_t *face,
+                                       hb_buffer_t *buffer,
+                                       unsigned int start, unsigned int end)
+{
+  const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+  hb_glyph_info_t *info = buffer->info;
+
+
+  /* 1. Find base consonant:
+   *
+   * The shaping engine finds the base consonant of the syllable, using the
+   * following algorithm: starting from the end of the syllable, move backwards
+   * until a consonant is found that does not have a below-base or post-base
+   * form (post-base forms have to follow below-base forms), or that is not a
+   * pre-base reordering Ra, or arrive at the first consonant. The consonant
+   * stopped at will be the base.
+   *
+   *   o If the syllable starts with Ra + Halant (in a script that has Reph)
+   *     and has more than one consonant, Ra is excluded from candidates for
+   *     base consonants.
+   */
+
+  unsigned int base = end;
+  bool has_reph = false;
+
+  {
+    /* -> If the syllable starts with Ra + Halant (in a script that has Reph)
+     *    and has more than one consonant, Ra is excluded from candidates for
+     *    base consonants. */
+    unsigned int limit = start;
+    if (indic_plan->config->reph_pos != REPH_POS_DONT_CARE &&
+        indic_plan->mask_array[RPHF] &&
+        start + 3 <= end &&
+        (
+         (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
+         (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ)
+        ))
+    {
+      /* See if it matches the 'rphf' feature. */
+      hb_codepoint_t glyphs[3] = {info[start].codepoint,
+                                  info[start + 1].codepoint,
+                                  indic_plan->config->reph_mode == REPH_MODE_EXPLICIT ?
+                                    info[start + 2].codepoint : 0};
+      if (indic_plan->rphf.would_substitute (glyphs, 2, face) ||
+          (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT &&
+           indic_plan->rphf.would_substitute (glyphs, 3, face)))
+      {
+        limit += 2;
+        while (limit < end && is_joiner (info[limit]))
+          limit++;
+        base = start;
+        has_reph = true;
+      }
+    } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == OT_Repha)
+    {
+        limit += 1;
+        while (limit < end && is_joiner (info[limit]))
+          limit++;
+        base = start;
+        has_reph = true;
+    }
+
+    switch (indic_plan->config->base_pos)
+    {
+      default:
+        assert (false);
+        /* fallthrough */
+
+      case BASE_POS_LAST:
+      {
+        /* -> starting from the end of the syllable, move backwards */
+        unsigned int i = end;
+        bool seen_below = false;
+        do {
+          i--;
+          /* -> until a consonant is found */
+          if (is_consonant (info[i]))
+          {
+            /* -> that does not have a below-base or post-base form
+             * (post-base forms have to follow below-base forms), */
+            if (info[i].indic_position() != POS_BELOW_C &&
+                (info[i].indic_position() != POS_POST_C || seen_below))
+            {
+              base = i;
+              break;
+            }
+            if (info[i].indic_position() == POS_BELOW_C)
+              seen_below = true;
+
+            /* -> or that is not a pre-base reordering Ra,
+             *
+             * IMPLEMENTATION NOTES:
+             *
+             * Our pre-base reordering Ra's are marked POS_POST_C, so will be skipped
+             * by the logic above already.
+             */
+
+            /* -> or arrive at the first consonant. The consonant stopped at will
+             * be the base. */
+            base = i;
+          }
+          else
+          {
+            /* A ZWJ after a Halant stops the base search, and requests an explicit
+             * half form.
+             * A ZWJ before a Halant, requests a subjoined form instead, and hence
+             * search continues.  This is particularly important for Bengali
+             * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
+            if (start < i &&
+                info[i].indic_category() == OT_ZWJ &&
+                info[i - 1].indic_category() == OT_H)
+              break;
+          }
+        } while (i > limit);
+      }
+      break;
+
+      case BASE_POS_LAST_SINHALA:
+      {
+        /* Sinhala base positioning is slightly different from main Indic, in that:
+         * 1. Its ZWJ behavior is different,
+         * 2. We don't need to look into the font for consonant positions.
+         */
+
+        if (!has_reph)
+          base = limit;
+
+        /* Find the last base consonant that is not blocked by ZWJ.  If there is
+         * a ZWJ right before a base consonant, that would request a subjoined form. */
+        for (unsigned int i = limit; i < end; i++)
+          if (is_consonant (info[i]))
+          {
+            if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
+              break;
+            else
+              base = i;
+          }
+
+        /* Mark all subsequent consonants as below. */
+        for (unsigned int i = base + 1; i < end; i++)
+          if (is_consonant (info[i]))
+            info[i].indic_position() = POS_BELOW_C;
+      }
+      break;
+
+      case BASE_POS_FIRST:
+      {
+        /* The first consonant is always the base. */
+
+        assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA);
+        assert (!has_reph);
+
+        base = start;
+
+        /* Mark all subsequent consonants as below. */
+        for (unsigned int i = base + 1; i < end; i++)
+          if (is_consonant (info[i]))
+            info[i].indic_position() = POS_BELOW_C;
+      }
+      break;
+    }
+
+    /* -> If the syllable starts with Ra + Halant (in a script that has Reph)
+     *    and has more than one consonant, Ra is excluded from candidates for
+     *    base consonants.
+     *
+     *  Only do this for unforced Reph. (ie. not for Ra,H,ZWJ. */
+    if (has_reph && base == start && limit - base <= 2) {
+      /* Have no other consonant, so Reph is not formed and Ra becomes base. */
+      has_reph = false;
+    }
+  }
+
+
+  /* 2. Decompose and reorder Matras:
+   *
+   * Each matra and any syllable modifier sign in the cluster are moved to the
+   * appropriate position relative to the consonant(s) in the cluster. The
+   * shaping engine decomposes two- or three-part matras into their constituent
+   * parts before any repositioning. Matra characters are classified by which
+   * consonant in a conjunct they have affinity for and are reordered to the
+   * following positions:
+   *
+   *   o Before first half form in the syllable
+   *   o After subjoined consonants
+   *   o After post-form consonant
+   *   o After main consonant (for above marks)
+   *
+   * IMPLEMENTATION NOTES:
+   *
+   * The normalize() routine has already decomposed matras for us, so we don't
+   * need to worry about that.
+   */
+
+
+  /* 3.  Reorder marks to canonical order:
+   *
+   * Adjacent nukta and halant or nukta and vedic sign are always repositioned
+   * if necessary, so that the nukta is first.
+   *
+   * IMPLEMENTATION NOTES:
+   *
+   * We don't need to do this: the normalize() routine already did this for us.
+   */
+
+
+  /* Reorder characters */
+
+  for (unsigned int i = start; i < base; i++)
+    info[i].indic_position() = MIN (POS_PRE_C, (indic_position_t) info[i].indic_position());
+
+  if (base < end)
+    info[base].indic_position() = POS_BASE_C;
+
+  /* Mark final consonants.  A final consonant is one appearing after a matra,
+   * like in Khmer. */
+  for (unsigned int i = base + 1; i < end; i++)
+    if (info[i].indic_category() == OT_M) {
+      for (unsigned int j = i + 1; j < end; j++)
+        if (is_consonant (info[j])) {
+          info[j].indic_position() = POS_FINAL_C;
+          break;
+        }
+      break;
+    }
+
+  /* Handle beginning Ra */
+  if (has_reph)
+    info[start].indic_position() = POS_RA_TO_BECOME_REPH;
+
+  /* For old-style Indic script tags, move the first post-base Halant after
+   * last consonant.
+   *
+   * Reports suggest that in some scripts Uniscribe does this only if there
+   * is *not* a Halant after last consonant already (eg. Kannada), while it
+   * does it unconditionally in other scripts (eg. Malayalam).  We don't
+   * currently know about other scripts, so we single out Malayalam for now.
+   *
+   * Kannada test case:
+   * U+0C9A,U+0CCD,U+0C9A,U+0CCD
+   * With some versions of Lohit Kannada.
+   * https://bugs.freedesktop.org/show_bug.cgi?id=59118
+   *
+   * Malayalam test case:
+   * U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D
+   * With lohit-ttf-20121122/Lohit-Malayalam.ttf
+   */
+  if (indic_plan->is_old_spec)
+  {
+    bool disallow_double_halants = buffer->props.script != HB_SCRIPT_MALAYALAM;
+    for (unsigned int i = base + 1; i < end; i++)
+      if (info[i].indic_category() == OT_H)
+      {
+        unsigned int j;
+        for (j = end - 1; j > i; j--)
+          if (is_consonant (info[j]) ||
+              (disallow_double_halants && info[j].indic_category() == OT_H))
+            break;
+        if (info[j].indic_category() != OT_H && j > i) {
+          /* Move Halant to after last consonant. */
+          hb_glyph_info_t t = info[i];
+          memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0]));
+          info[j] = t;
+        }
+        break;
+      }
+  }
+
+  /* Attach misc marks to previous char to move with them. */
+  {
+    indic_position_t last_pos = POS_START;
+    for (unsigned int i = start; i < end; i++)
+    {
+      if ((FLAG_SAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS)))
+      {
+        info[i].indic_position() = last_pos;
+        if (unlikely (info[i].indic_category() == OT_H &&
+                      info[i].indic_position() == POS_PRE_M))
+        {
+          /*
+           * Uniscribe doesn't move the Halant with Left Matra.
+           * TEST: U+092B,U+093F,U+094DE
+           * We follow.  This is important for the Sinhala
+           * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA
+           * where U+0DD9 is a left matra and U+0DCA is the virama.
+           * We don't want to move the virama with the left matra.
+           * TEST: U+0D9A,U+0DDA
+           */
+          for (unsigned int j = i; j > start; j--)
+            if (info[j - 1].indic_position() != POS_PRE_M) {
+              info[i].indic_position() = info[j - 1].indic_position();
+              break;
+            }
+        }
+      } else if (info[i].indic_position() != POS_SMVD) {
+        last_pos = (indic_position_t) info[i].indic_position();
+      }
+    }
+  }
+  /* For post-base consonants let them own anything before them
+   * since the last consonant or matra. */
+  {
+    unsigned int last = base;
+    for (unsigned int i = base + 1; i < end; i++)
+      if (is_consonant (info[i]))
+      {
+        for (unsigned int j = last + 1; j < i; j++)
+          if (info[j].indic_position() < POS_SMVD)
+            info[j].indic_position() = info[i].indic_position();
+        last = i;
+      } else if (info[i].indic_category() == OT_M)
+        last = i;
+  }
+
+
+  {
+    /* Use syllable() for sort accounting temporarily. */
+    unsigned int syllable = info[start].syllable();
+    for (unsigned int i = start; i < end; i++)
+      info[i].syllable() = i - start;
+
+    /* Sit tight, rock 'n roll! */
+    hb_stable_sort (info + start, end - start, compare_indic_order);
+    /* Find base again */
+    base = end;
+    for (unsigned int i = start; i < end; i++)
+      if (info[i].indic_position() == POS_BASE_C)
+      {
+        base = i;
+        break;
+      }
+    /* Things are out-of-control for post base positions, they may shuffle
+     * around like crazy.  In old-spec mode, we move halants around, so in
+     * that case merge all clusters after base.  Otherwise, check the sort
+     * order and merge as needed.
+     * For pre-base stuff, we handle cluster issues in final reordering.
+     *
+     * We could use buffer->sort() for this, if there was no special
+     * reordering of pre-base stuff happening later...
+     */
+    if (indic_plan->is_old_spec || end - base > 127)
+      buffer->merge_clusters (base, end);
+    else
+    {
+      /* Note!  syllable() is a one-byte field. */
+      for (unsigned int i = base; i < end; i++)
+        if (info[i].syllable() != 255)
+        {
+          unsigned int max = i;
+          unsigned int j = start + info[i].syllable();
+          while (j != i)
+          {
+            max = MAX (max, j);
+            unsigned int next = start + info[j].syllable();
+            info[j].syllable() = 255; /* So we don't process j later again. */
+            j = next;
+          }
+          if (i != max)
+            buffer->merge_clusters (i, max + 1);
+        }
+    }
+
+    /* Put syllable back in. */
+    for (unsigned int i = start; i < end; i++)
+      info[i].syllable() = syllable;
+  }
+
+  /* Setup masks now */
+
+  {
+    hb_mask_t mask;
+
+    /* Reph */
+    for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++)
+      info[i].mask |= indic_plan->mask_array[RPHF];
+
+    /* Pre-base */
+    mask = indic_plan->mask_array[HALF];
+    if (!indic_plan->is_old_spec &&
+        indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
+      mask |= indic_plan->mask_array[BLWF];
+    for (unsigned int i = start; i < base; i++)
+      info[i].mask  |= mask;
+    /* Base */
+    mask = 0;
+    if (base < end)
+      info[base].mask |= mask;
+    /* Post-base */
+    mask = indic_plan->mask_array[BLWF] | indic_plan->mask_array[ABVF] | indic_plan->mask_array[PSTF];
+    for (unsigned int i = base + 1; i < end; i++)
+      info[i].mask  |= mask;
+  }
+
+  if (indic_plan->is_old_spec &&
+      buffer->props.script == HB_SCRIPT_DEVANAGARI)
+  {
+    /* Old-spec eye-lash Ra needs special handling.  From the
+     * spec:
+     *
+     * "The feature 'below-base form' is applied to consonants
+     * having below-base forms and following the base consonant.
+     * The exception is vattu, which may appear below half forms
+     * as well as below the base glyph. The feature 'below-base
+     * form' will be applied to all such occurrences of Ra as well."
+     *
+     * Test case: U+0924,U+094D,U+0930,U+094d,U+0915
+     * with Sanskrit 2003 font.
+     *
+     * However, note that Ra,Halant,ZWJ is the correct way to
+     * request eyelash form of Ra, so we wouldbn't inhibit it
+     * in that sequence.
+     *
+     * Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915
+     */
+    for (unsigned int i = start; i + 1 < base; i++)
+      if (info[i  ].indic_category() == OT_Ra &&
+          info[i+1].indic_category() == OT_H  &&
+          (i + 2 == base ||
+           info[i+2].indic_category() != OT_ZWJ))
+      {
+        info[i  ].mask |= indic_plan->mask_array[BLWF];
+        info[i+1].mask |= indic_plan->mask_array[BLWF];
+      }
+  }
+
+  unsigned int pref_len = indic_plan->config->pref_len;
+  if (indic_plan->mask_array[PREF] && base + pref_len < end)
+  {
+    assert (1 <= pref_len && pref_len <= 2);
+    /* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
+    for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
+      hb_codepoint_t glyphs[2];
+      for (unsigned int j = 0; j < pref_len; j++)
+        glyphs[j] = info[i + j].codepoint;
+      if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
+      {
+        for (unsigned int j = 0; j < pref_len; j++)
+          info[i++].mask |= indic_plan->mask_array[PREF];
+
+        /* Mark the subsequent stuff with 'cfar'.  Used in Khmer.
+         * Read the feature spec.
+         * This allows distinguishing the following cases with MS Khmer fonts:
+         * U+1784,U+17D2,U+179A,U+17D2,U+1782
+         * U+1784,U+17D2,U+1782,U+17D2,U+179A
+         */
+        if (indic_plan->mask_array[CFAR])
+          for (; i < end; i++)
+            info[i].mask |= indic_plan->mask_array[CFAR];
+
+        break;
+      }
+    }
+  }
+
+  /* Apply ZWJ/ZWNJ effects */
+  for (unsigned int i = start + 1; i < end; i++)
+    if (is_joiner (info[i])) {
+      bool non_joiner = info[i].indic_category() == OT_ZWNJ;
+      unsigned int j = i;
+
+      do {
+        j--;
+
+        /* ZWJ/ZWNJ should disable CJCT.  They do that by simply
+         * being there, since we don't skip them for the CJCT
+         * feature (ie. F_MANUAL_ZWJ) */
+
+        /* A ZWNJ disables HALF. */
+        if (non_joiner)
+          info[j].mask &= ~indic_plan->mask_array[HALF];
+
+      } while (j > start && !is_consonant (info[j]));
+    }
+}
+
+static void
+initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
+                                       hb_face_t *face,
+                                       hb_buffer_t *buffer,
+                                       unsigned int start, unsigned int end)
+{
+  /* We treat placeholder/dotted-circle as if they are consonants, so we
+   * should just chain.  Only if not in compatibility mode that is... */
+
+  if (hb_options ().uniscribe_bug_compatible)
+  {
+    /* For dotted-circle, this is what Uniscribe does:
+     * If dotted-circle is the last glyph, it just does nothing.
+     * Ie. It doesn't form Reph. */
+    if (buffer->info[end - 1].indic_category() == OT_DOTTEDCIRCLE)
+      return;
+  }
+
+  initial_reordering_consonant_syllable (plan, face, buffer, start, end);
+}
+
+static void
+initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
+                             hb_face_t *face,
+                             hb_buffer_t *buffer,
+                             unsigned int start, unsigned int end)
+{
+  syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+  switch (syllable_type)
+  {
+    case vowel_syllable: /* We made the vowels look like consonants.  So let's call the consonant logic! */
+    case consonant_syllable:
+     initial_reordering_consonant_syllable (plan, face, buffer, start, end);
+     break;
+
+    case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
+    case standalone_cluster:
+     initial_reordering_standalone_cluster (plan, face, buffer, start, end);
+     break;
+
+    case symbol_cluster:
+    case non_indic_cluster:
+      break;
+  }
+}
+
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                       hb_font_t *font,
+                       hb_buffer_t *buffer)
+{
+  /* Note: This loop is extra overhead, but should not be measurable. */
+  bool has_broken_syllables = false;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    if ((info[i].syllable() & 0x0F) == broken_cluster)
+    {
+      has_broken_syllables = true;
+      break;
+    }
+  if (likely (!has_broken_syllables))
+    return;
+
+
+  hb_codepoint_t dottedcircle_glyph;
+  if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph))
+    return;
+
+  hb_glyph_info_t dottedcircle = {0};
+  dottedcircle.codepoint = 0x25CCu;
+  set_indic_properties (dottedcircle);
+  dottedcircle.codepoint = dottedcircle_glyph;
+
+  buffer->clear_output ();
+
+  buffer->idx = 0;
+  unsigned int last_syllable = 0;
+  while (buffer->idx < buffer->len)
+  {
+    unsigned int syllable = buffer->cur().syllable();
+    syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+    if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+    {
+      last_syllable = syllable;
+
+      hb_glyph_info_t info = dottedcircle;
+      info.cluster = buffer->cur().cluster;
+      info.mask = buffer->cur().mask;
+      info.syllable() = buffer->cur().syllable();
+      /* TODO Set glyph_props? */
+
+      /* Insert dottedcircle after possible Repha. */
+      while (buffer->idx < buffer->len &&
+             last_syllable == buffer->cur().syllable() &&
+             buffer->cur().indic_category() == OT_Repha)
+        buffer->next_glyph ();
+
+      buffer->output_info (info);
+    }
+    else
+      buffer->next_glyph ();
+  }
+
+  buffer->swap_buffers ();
+}
+
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+                    hb_font_t *font,
+                    hb_buffer_t *buffer)
+{
+  update_consonant_positions (plan, font, buffer);
+  insert_dotted_circles (plan, font, buffer);
+
+  foreach_syllable (buffer, start, end)
+    initial_reordering_syllable (plan, font->face, buffer, start, end);
+}
+
+static void
+final_reordering_syllable (const hb_ot_shape_plan_t *plan,
+                           hb_buffer_t *buffer,
+                           unsigned int start, unsigned int end)
+{
+  const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
+  hb_glyph_info_t *info = buffer->info;
+
+
+  /* This function relies heavily on halant glyphs.  Lots of ligation
+   * and possibly multiplication substitutions happened prior to this
+   * phase, and that might have messed up our properties.  Recover
+   * from a particular case of that where we're fairly sure that a
+   * class of OT_H is desired but has been lost. */
+  if (indic_plan->virama_glyph)
+  {
+    unsigned int virama_glyph = indic_plan->virama_glyph;
+    for (unsigned int i = start; i < end; i++)
+      if (info[i].codepoint == virama_glyph &&
+          _hb_glyph_info_ligated (&info[i]) &&
+          _hb_glyph_info_multiplied (&info[i]))
+      {
+        /* This will make sure that this glyph passes is_halant_or_coeng() test. */
+        info[i].indic_category() = OT_H;
+        _hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
+      }
+  }
+
+
+  /* 4. Final reordering:
+   *
+   * After the localized forms and basic shaping forms GSUB features have been
+   * applied (see below), the shaping engine performs some final glyph
+   * reordering before applying all the remaining font features to the entire
+   * cluster.
+   */
+
+  bool try_pref = !!indic_plan->mask_array[PREF];
+
+  /* Find base again */
+  unsigned int base;
+  for (base = start; base < end; base++)
+    if (info[base].indic_position() >= POS_BASE_C)
+    {
+      if (try_pref && base + 1 < end && indic_plan->config->pref_len == 2)
+      {
+        for (unsigned int i = base + 1; i < end; i++)
+          if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
+          {
+            if (!(_hb_glyph_info_substituted (&info[i]) &&
+                  _hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
+            {
+              /* Ok, this was a 'pref' candidate but didn't form any.
+               * Base is around here... */
+              base = i;
+              while (base < end && is_halant_or_coeng (info[base]))
+                base++;
+              info[base].indic_position() = POS_BASE_C;
+
+              try_pref = false;
+            }
+            break;
+          }
+      }
+
+      if (start < base && info[base].indic_position() > POS_BASE_C)
+        base--;
+      break;
+    }
+  if (base == end && start < base &&
+      is_one_of (info[base - 1], FLAG (OT_ZWJ)))
+    base--;
+  if (base < end)
+    while (start < base &&
+           is_one_of (info[base], (FLAG (OT_N) | HALANT_OR_COENG_FLAGS)))
+      base--;
+
+
+  /*   o Reorder matras:
+   *
+   *     If a pre-base matra character had been reordered before applying basic
+   *     features, the glyph can be moved closer to the main consonant based on
+   *     whether half-forms had been formed. Actual position for the matra is
+   *     defined as “after last standalone halant glyph, after initial matra
+   *     position and before the main consonant”. If ZWJ or ZWNJ follow this
+   *     halant, position is moved after it.
+   */
+
+  if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */
+  {
+    /* If we lost track of base, alas, position before last thingy. */
+    unsigned int new_pos = base == end ? base - 2 : base - 1;
+
+    /* Malayalam / Tamil do not have "half" forms or explicit virama forms.
+     * The glyphs formed by 'half' are Chillus or ligated explicit viramas.
+     * We want to position matra after them.
+     */
+    if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
+    {
+      while (new_pos > start &&
+             !(is_one_of (info[new_pos], (FLAG (OT_M) | HALANT_OR_COENG_FLAGS))))
+        new_pos--;
+
+      /* If we found no Halant we are done.
+       * Otherwise only proceed if the Halant does
+       * not belong to the Matra itself! */
+      if (is_halant_or_coeng (info[new_pos]) &&
+          info[new_pos].indic_position() != POS_PRE_M)
+      {
+        /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
+        if (new_pos + 1 < end && is_joiner (info[new_pos + 1]))
+          new_pos++;
+      }
+      else
+        new_pos = start; /* No move. */
+    }
+
+    if (start < new_pos && info[new_pos].indic_position () != POS_PRE_M)
+    {
+      /* Now go see if there's actually any matras... */
+      for (unsigned int i = new_pos; i > start; i--)
+        if (info[i - 1].indic_position () == POS_PRE_M)
+        {
+          unsigned int old_pos = i - 1;
+          if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */
+            base--;
+
+          hb_glyph_info_t tmp = info[old_pos];
+          memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0]));
+          info[new_pos] = tmp;
+
+          /* Note: this merge_clusters() is intentionally *after* the reordering.
+           * Indic matra reordering is special and tricky... */
+          buffer->merge_clusters (new_pos, MIN (end, base + 1));
+
+          new_pos--;
+        }
+    } else {
+      for (unsigned int i = start; i < base; i++)
+        if (info[i].indic_position () == POS_PRE_M) {
+          buffer->merge_clusters (i, MIN (end, base + 1));
+          break;
+        }
+    }
+  }
+
+
+  /*   o Reorder reph:
+   *
+   *     Reph’s original position is always at the beginning of the syllable,
+   *     (i.e. it is not reordered at the character reordering stage). However,
+   *     it will be reordered according to the basic-forms shaping results.
+   *     Possible positions for reph, depending on the script, are; after main,
+   *     before post-base consonant forms, and after post-base consonant forms.
+   */
+
+  /* Two cases:
+   *
+   * - If repha is encoded as a sequence of characters (Ra,H or Ra,H,ZWJ), then
+   *   we should only move it if the sequence ligated to the repha form.
+   *
+   * - If repha is encoded separately and in the logical position, we should only
+   *   move it if it did NOT ligate.  If it ligated, it's probably the font trying
+   *   to make it work without the reordering.
+   */
+  if (start + 1 < end &&
+      info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
+      ((info[start].indic_category() == OT_Repha) ^
+       _hb_glyph_info_ligated_and_didnt_multiply (&info[start])))
+  {
+    unsigned int new_reph_pos;
+    reph_position_t reph_pos = indic_plan->config->reph_pos;
+
+    assert (reph_pos != REPH_POS_DONT_CARE);
+
+    /*       1. If reph should be positioned after post-base consonant forms,
+     *          proceed to step 5.
+     */
+    if (reph_pos == REPH_POS_AFTER_POST)
+    {
+      goto reph_step_5;
+    }
+
+    /*       2. If the reph repositioning class is not after post-base: target
+     *          position is after the first explicit halant glyph between the
+     *          first post-reph consonant and last main consonant. If ZWJ or ZWNJ
+     *          are following this halant, position is moved after it. If such
+     *          position is found, this is the target position. Otherwise,
+     *          proceed to the next step.
+     *
+     *          Note: in old-implementation fonts, where classifications were
+     *          fixed in shaping engine, there was no case where reph position
+     *          will be found on this step.
+     */
+    {
+      new_reph_pos = start + 1;
+      while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
+        new_reph_pos++;
+
+      if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
+      {
+        /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
+        if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
+          new_reph_pos++;
+        goto reph_move;
+      }
+    }
+
+    /*       3. If reph should be repositioned after the main consonant: find the
+     *          first consonant not ligated with main, or find the first
+     *          consonant that is not a potential pre-base reordering Ra.
+     */
+    if (reph_pos == REPH_POS_AFTER_MAIN)
+    {
+      new_reph_pos = base;
+      while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN)
+        new_reph_pos++;
+      if (new_reph_pos < end)
+        goto reph_move;
+    }
+
+    /*       4. If reph should be positioned before post-base consonant, find
+     *          first post-base classified consonant not ligated with main. If no
+     *          consonant is found, the target position should be before the
+     *          first matra, syllable modifier sign or vedic sign.
+     */
+    /* This is our take on what step 4 is trying to say (and failing, BADLY). */
+    if (reph_pos == REPH_POS_AFTER_SUB)
+    {
+      new_reph_pos = base;
+      while (new_reph_pos < end &&
+             !( FLAG_SAFE (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD))))
+        new_reph_pos++;
+      if (new_reph_pos < end)
+        goto reph_move;
+    }
+
+    /*       5. If no consonant is found in steps 3 or 4, move reph to a position
+     *          immediately before the first post-base matra, syllable modifier
+     *          sign or vedic sign that has a reordering class after the intended
+     *          reph position. For example, if the reordering position for reph
+     *          is post-main, it will skip above-base matras that also have a
+     *          post-main position.
+     */
+    reph_step_5:
+    {
+      /* Copied from step 2. */
+      new_reph_pos = start + 1;
+      while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
+        new_reph_pos++;
+
+      if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
+      {
+        /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
+        if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
+          new_reph_pos++;
+        goto reph_move;
+      }
+    }
+
+    /*       6. Otherwise, reorder reph to the end of the syllable.
+     */
+    {
+      new_reph_pos = end - 1;
+      while (new_reph_pos > start && info[new_reph_pos].indic_position() == POS_SMVD)
+        new_reph_pos--;
+
+      /*
+       * If the Reph is to be ending up after a Matra,Halant sequence,
+       * position it before that Halant so it can interact with the Matra.
+       * However, if it's a plain Consonant,Halant we shouldn't do that.
+       * Uniscribe doesn't do this.
+       * TEST: U+0930,U+094D,U+0915,U+094B,U+094D
+       */
+      if (!hb_options ().uniscribe_bug_compatible &&
+          unlikely (is_halant_or_coeng (info[new_reph_pos]))) {
+        for (unsigned int i = base + 1; i < new_reph_pos; i++)
+          if (info[i].indic_category() == OT_M) {
+            /* Ok, got it. */
+            new_reph_pos--;
+          }
+      }
+      goto reph_move;
+    }
+
+    reph_move:
+    {
+      /* Move */
+      buffer->merge_clusters (start, new_reph_pos + 1);
+      hb_glyph_info_t reph = info[start];
+      memmove (&info[start], &info[start + 1], (new_reph_pos - start) * sizeof (info[0]));
+      info[new_reph_pos] = reph;
+
+      if (start < base && base <= new_reph_pos)
+        base--;
+    }
+  }
+
+
+  /*   o Reorder pre-base reordering consonants:
+   *
+   *     If a pre-base reordering consonant is found, reorder it according to
+   *     the following rules:
+   */
+
+  if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
+  {
+    unsigned int pref_len = indic_plan->config->pref_len;
+    for (unsigned int i = base + 1; i < end; i++)
+      if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
+      {
+        /*       1. Only reorder a glyph produced by substitution during application
+         *          of the <pref> feature. (Note that a font may shape a Ra consonant with
+         *          the feature generally but block it in certain contexts.)
+         */
+        /* Note: We just check that something got substituted.  We don't check that
+         * the <pref> feature actually did it...
+         *
+         * If pref len is longer than one, then only reorder if it ligated.  If
+         * pref len is one, only reorder if it didn't ligate with other things. */
+        if (_hb_glyph_info_substituted (&info[i]) &&
+            ((pref_len == 1) ^ _hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
+        {
+          /*
+           *       2. Try to find a target position the same way as for pre-base matra.
+           *          If it is found, reorder pre-base consonant glyph.
+           *
+           *       3. If position is not found, reorder immediately before main
+           *          consonant.
+           */
+
+          unsigned int new_pos = base;
+          /* Malayalam / Tamil do not have "half" forms or explicit virama forms.
+           * The glyphs formed by 'half' are Chillus or ligated explicit viramas.
+           * We want to position matra after them.
+           */
+          if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
+          {
+            while (new_pos > start &&
+                   !(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS)))
+              new_pos--;
+
+            /* In Khmer coeng model, a H,Ra can go *after* matras.  If it goes after a
+             * split matra, it should be reordered to *before* the left part of such matra. */
+            if (new_pos > start && info[new_pos - 1].indic_category() == OT_M)
+            {
+              unsigned int old_pos = i;
+              for (unsigned int i = base + 1; i < old_pos; i++)
+                if (info[i].indic_category() == OT_M)
+                {
+                  new_pos--;
+                  break;
+                }
+            }
+          }
+
+          if (new_pos > start && is_halant_or_coeng (info[new_pos - 1]))
+          {
+            /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
+            if (new_pos < end && is_joiner (info[new_pos]))
+              new_pos++;
+          }
+
+          {
+            unsigned int old_pos = i;
+
+            buffer->merge_clusters (new_pos, old_pos + 1);
+            hb_glyph_info_t tmp = info[old_pos];
+            memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0]));
+            info[new_pos] = tmp;
+
+            if (new_pos <= base && base < old_pos)
+              base++;
+          }
+        }
+
+        break;
+      }
+  }
+
+
+  /* Apply 'init' to the Left Matra if it's a word start. */
+  if (info[start].indic_position () == POS_PRE_M &&
+      (!start ||
+       !(FLAG_SAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
+         FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))))
+    info[start].mask |= indic_plan->mask_array[INIT];
+
+
+  /*
+   * Finish off the clusters and go home!
+   */
+  if (hb_options ().uniscribe_bug_compatible)
+  {
+    switch ((hb_tag_t) plan->props.script)
+    {
+      case HB_SCRIPT_TAMIL:
+      case HB_SCRIPT_SINHALA:
+        break;
+
+      default:
+        /* Uniscribe merges the entire cluster... Except for Tamil & Sinhala.
+         * This means, half forms are submerged into the main consonants cluster.
+         * This is unnecessary, and makes cursor positioning harder, but that's what
+         * Uniscribe does. */
+        buffer->merge_clusters (start, end);
+        break;
+    }
+  }
+}
+
+
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+                  hb_font_t *font HB_UNUSED,
+                  hb_buffer_t *buffer)
+{
+  unsigned int count = buffer->len;
+  if (unlikely (!count)) return;
+
+  foreach_syllable (buffer, start, end)
+    final_reordering_syllable (plan, buffer, start, end);
+
+  HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
+}
+
+
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                 hb_font_t *font HB_UNUSED,
+                 hb_buffer_t *buffer)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    info[i].syllable() = 0;
+}
+
+
+static bool
+decompose_indic (const hb_ot_shape_normalize_context_t *c,
+                 hb_codepoint_t  ab,
+                 hb_codepoint_t *a,
+                 hb_codepoint_t *b)
+{
+  switch (ab)
+  {
+    /* Don't decompose these. */
+    case 0x0931u  : return false;
+    case 0x0B94u  : return false;
+
+
+    /*
+     * Decompose split matras that don't have Unicode decompositions.
+     */
+
+    case 0x0F77u  : *a = 0x0FB2u; *b= 0x0F81u; return true;
+    case 0x0F79u  : *a = 0x0FB3u; *b= 0x0F81u; return true;
+    case 0x17BEu  : *a = 0x17C1u; *b= 0x17BEu; return true;
+    case 0x17BFu  : *a = 0x17C1u; *b= 0x17BFu; return true;
+    case 0x17C0u  : *a = 0x17C1u; *b= 0x17C0u; return true;
+    case 0x17C4u  : *a = 0x17C1u; *b= 0x17C4u; return true;
+    case 0x17C5u  : *a = 0x17C1u; *b= 0x17C5u; return true;
+    case 0x1925u  : *a = 0x1920u; *b= 0x1923u; return true;
+    case 0x1926u  : *a = 0x1920u; *b= 0x1924u; return true;
+    case 0x1B3Cu  : *a = 0x1B42u; *b= 0x1B3Cu; return true;
+    case 0x1112Eu  : *a = 0x11127u; *b= 0x11131u; return true;
+    case 0x1112Fu  : *a = 0x11127u; *b= 0x11132u; return true;
+#if 0
+    /* This one has no decomposition in Unicode, but needs no decomposition either. */
+    /* case 0x0AC9u  : return false; */
+    case 0x0B57u  : *a = no decomp, -> RIGHT; return true;
+    case 0x1C29u  : *a = no decomp, -> LEFT; return true;
+    case 0xA9C0u  : *a = no decomp, -> RIGHT; return true;
+    case 0x111BuF  : *a = no decomp, -> ABOVE; return true;
+#endif
+  }
+
+  if ((ab == 0x0DDAu || hb_in_range (ab, 0x0DDCu, 0x0DDEu)))
+  {
+    /*
+     * Sinhala split matras...  Let the fun begin.
+     *
+     * These four characters have Unicode decompositions.  However, Uniscribe
+     * decomposes them "Khmer-style", that is, it uses the character itself to
+     * get the second half.  The first half of all four decompositions is always
+     * U+0DD9.
+     *
+     * Now, there are buggy fonts, namely, the widely used lklug.ttf, that are
+     * broken with Uniscribe.  But we need to support them.  As such, we only
+     * do the Uniscribe-style decomposition if the character is transformed into
+     * its "sec.half" form by the 'pstf' feature.  Otherwise, we fall back to
+     * Unicode decomposition.
+     *
+     * Note that we can't unconditionally use Unicode decomposition.  That would
+     * break some other fonts, that are designed to work with Uniscribe, and
+     * don't have positioning features for the Unicode-style decomposition.
+     *
+     * Argh...
+     *
+     * The Uniscribe behavior is now documented in the newly published Sinhala
+     * spec in 2012:
+     *
+     *   http://www.microsoft.com/typography/OpenTypeDev/sinhala/intro.htm#shaping
+     */
+
+    const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
+
+    hb_codepoint_t glyph;
+
+    if (hb_options ().uniscribe_bug_compatible ||
+        (c->font->get_glyph (ab, 0, &glyph) &&
+         indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
+    {
+      /* Ok, safe to use Uniscribe-style decomposition. */
+      *a = 0x0DD9u;
+      *b = ab;
+      return true;
+    }
+  }
+
+  return c->unicode->decompose (ab, a, b);
+}
+
+static bool
+compose_indic (const hb_ot_shape_normalize_context_t *c,
+               hb_codepoint_t  a,
+               hb_codepoint_t  b,
+               hb_codepoint_t *ab)
+{
+  /* Avoid recomposing split matras. */
+  if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a)))
+    return false;
+
+  /* Composition-exclusion exceptions that we want to recompose. */
+  if (a == 0x09AFu && b == 0x09BCu) { *ab = 0x09DFu; return true; }
+
+  return c->unicode->compose (a, b, ab);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
+{
+  "indic",
+  collect_features_indic,
+  override_features_indic,
+  data_create_indic,
+  data_destroy_indic,
+  NULL, /* preprocess_text */
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
+  decompose_indic,
+  compose_indic,
+  setup_masks_indic,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+  false, /* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar-machine.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,400 @@
+
+#line 1 "hb-ot-shape-complex-myanmar-machine.rl"
+/*
+ * Copyright © 2011,2012  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_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
+static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
+        1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
+        3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
+        3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
+        5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
+        3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
+        3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
+};
+
+static const char _myanmar_syllable_machine_key_spans[] = {
+        31, 28, 25, 4, 25, 23, 21, 21,
+        27, 27, 27, 27, 16, 27, 27, 27,
+        27, 27, 27, 27, 27, 27, 25, 4,
+        25, 23, 21, 21, 27, 27, 27, 27,
+        28, 27, 30, 27, 27, 27, 27, 27,
+        27, 27, 27, 27, 1
+};
+
+static const short _myanmar_syllable_machine_index_offsets[] = {
+        0, 32, 61, 87, 92, 118, 142, 164,
+        186, 214, 242, 270, 298, 315, 343, 371,
+        399, 427, 455, 483, 511, 539, 567, 593,
+        598, 624, 648, 670, 692, 720, 748, 776,
+        804, 833, 861, 892, 920, 948, 976, 1004,
+        1032, 1060, 1088, 1116, 1144
+};
+
+static const char _myanmar_syllable_machine_indicies[] = {
+        1, 1, 2, 3, 4, 4, 0, 5,
+        0, 6, 1, 0, 0, 0, 0, 7,
+        0, 8, 1, 0, 9, 10, 11, 12,
+        13, 14, 15, 16, 17, 18, 19, 0,
+        21, 22, 23, 23, 20, 24, 20, 25,
+        20, 20, 20, 20, 20, 20, 20, 26,
+        20, 20, 27, 28, 29, 30, 31, 32,
+        33, 34, 35, 36, 20, 23, 23, 20,
+        24, 20, 20, 20, 20, 20, 20, 20,
+        20, 20, 37, 20, 20, 20, 20, 20,
+        20, 31, 20, 20, 20, 35, 20, 23,
+        23, 20, 24, 20, 23, 23, 20, 24,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        31, 20, 20, 20, 35, 20, 38, 20,
+        23, 23, 20, 24, 20, 31, 20, 20,
+        20, 20, 20, 20, 20, 39, 20, 20,
+        20, 20, 20, 20, 31, 20, 23, 23,
+        20, 24, 20, 20, 20, 20, 20, 20,
+        20, 20, 20, 39, 20, 20, 20, 20,
+        20, 20, 31, 20, 23, 23, 20, 24,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        31, 20, 21, 20, 23, 23, 20, 24,
+        20, 25, 20, 20, 20, 20, 20, 20,
+        20, 40, 20, 20, 40, 20, 20, 20,
+        31, 41, 20, 20, 35, 20, 21, 20,
+        23, 23, 20, 24, 20, 25, 20, 20,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        20, 20, 20, 20, 31, 20, 20, 20,
+        35, 20, 21, 20, 23, 23, 20, 24,
+        20, 25, 20, 20, 20, 20, 20, 20,
+        20, 40, 20, 20, 20, 20, 20, 20,
+        31, 41, 20, 20, 35, 20, 21, 20,
+        23, 23, 20, 24, 20, 25, 20, 20,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        20, 20, 20, 20, 31, 41, 20, 20,
+        35, 20, 1, 1, 20, 20, 20, 20,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        20, 1, 20, 21, 20, 23, 23, 20,
+        24, 20, 25, 20, 20, 20, 20, 20,
+        20, 20, 26, 20, 20, 27, 28, 29,
+        30, 31, 32, 33, 34, 35, 20, 21,
+        20, 23, 23, 20, 24, 20, 25, 20,
+        20, 20, 20, 20, 20, 20, 34, 20,
+        20, 20, 20, 20, 20, 31, 32, 33,
+        34, 35, 20, 21, 20, 23, 23, 20,
+        24, 20, 25, 20, 20, 20, 20, 20,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        20, 31, 32, 33, 34, 35, 20, 21,
+        20, 23, 23, 20, 24, 20, 25, 20,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        20, 20, 20, 20, 20, 31, 32, 33,
+        20, 35, 20, 21, 20, 23, 23, 20,
+        24, 20, 25, 20, 20, 20, 20, 20,
+        20, 20, 20, 20, 20, 20, 20, 20,
+        20, 31, 20, 33, 20, 35, 20, 21,
+        20, 23, 23, 20, 24, 20, 25, 20,
+        20, 20, 20, 20, 20, 20, 34, 20,
+        20, 27, 20, 29, 20, 31, 32, 33,
+        34, 35, 20, 21, 20, 23, 23, 20,
+        24, 20, 25, 20, 20, 20, 20, 20,
+        20, 20, 34, 20, 20, 27, 20, 20,
+        20, 31, 32, 33, 34, 35, 20, 21,
+        20, 23, 23, 20, 24, 20, 25, 20,
+        20, 20, 20, 20, 20, 20, 34, 20,
+        20, 27, 28, 29, 20, 31, 32, 33,
+        34, 35, 20, 21, 22, 23, 23, 20,
+        24, 20, 25, 20, 20, 20, 20, 20,
+        20, 20, 26, 20, 20, 27, 28, 29,
+        30, 31, 32, 33, 34, 35, 20, 3,
+        3, 42, 5, 42, 42, 42, 42, 42,
+        42, 42, 42, 42, 43, 42, 42, 42,
+        42, 42, 42, 13, 42, 42, 42, 17,
+        42, 3, 3, 42, 5, 42, 3, 3,
+        42, 5, 42, 42, 42, 42, 42, 42,
+        42, 42, 42, 42, 42, 42, 42, 42,
+        42, 42, 13, 42, 42, 42, 17, 42,
+        44, 42, 3, 3, 42, 5, 42, 13,
+        42, 42, 42, 42, 42, 42, 42, 45,
+        42, 42, 42, 42, 42, 42, 13, 42,
+        3, 3, 42, 5, 42, 42, 42, 42,
+        42, 42, 42, 42, 42, 45, 42, 42,
+        42, 42, 42, 42, 13, 42, 3, 3,
+        42, 5, 42, 42, 42, 42, 42, 42,
+        42, 42, 42, 42, 42, 42, 42, 42,
+        42, 42, 13, 42, 2, 42, 3, 3,
+        42, 5, 42, 6, 42, 42, 42, 42,
+        42, 42, 42, 46, 42, 42, 46, 42,
+        42, 42, 13, 47, 42, 42, 17, 42,
+        2, 42, 3, 3, 42, 5, 42, 6,
+        42, 42, 42, 42, 42, 42, 42, 42,
+        42, 42, 42, 42, 42, 42, 13, 42,
+        42, 42, 17, 42, 2, 42, 3, 3,
+        42, 5, 42, 6, 42, 42, 42, 42,
+        42, 42, 42, 46, 42, 42, 42, 42,
+        42, 42, 13, 47, 42, 42, 17, 42,
+        2, 42, 3, 3, 42, 5, 42, 6,
+        42, 42, 42, 42, 42, 42, 42, 42,
+        42, 42, 42, 42, 42, 42, 13, 47,
+        42, 42, 17, 42, 21, 22, 23, 23,
+        20, 24, 20, 25, 20, 20, 20, 20,
+        20, 20, 20, 48, 20, 20, 27, 28,
+        29, 30, 31, 32, 33, 34, 35, 36,
+        20, 21, 49, 23, 23, 20, 24, 20,
+        25, 20, 20, 20, 20, 20, 20, 20,
+        26, 20, 20, 27, 28, 29, 30, 31,
+        32, 33, 34, 35, 20, 1, 1, 2,
+        3, 3, 3, 42, 5, 42, 6, 1,
+        42, 42, 42, 42, 1, 42, 8, 1,
+        42, 9, 10, 11, 12, 13, 14, 15,
+        16, 17, 18, 42, 2, 42, 3, 3,
+        42, 5, 42, 6, 42, 42, 42, 42,
+        42, 42, 42, 8, 42, 42, 9, 10,
+        11, 12, 13, 14, 15, 16, 17, 42,
+        2, 42, 3, 3, 42, 5, 42, 6,
+        42, 42, 42, 42, 42, 42, 42, 16,
+        42, 42, 42, 42, 42, 42, 13, 14,
+        15, 16, 17, 42, 2, 42, 3, 3,
+        42, 5, 42, 6, 42, 42, 42, 42,
+        42, 42, 42, 42, 42, 42, 42, 42,
+        42, 42, 13, 14, 15, 16, 17, 42,
+        2, 42, 3, 3, 42, 5, 42, 6,
+        42, 42, 42, 42, 42, 42, 42, 42,
+        42, 42, 42, 42, 42, 42, 13, 14,
+        15, 42, 17, 42, 2, 42, 3, 3,
+        42, 5, 42, 6, 42, 42, 42, 42,
+        42, 42, 42, 42, 42, 42, 42, 42,
+        42, 42, 13, 42, 15, 42, 17, 42,
+        2, 42, 3, 3, 42, 5, 42, 6,
+        42, 42, 42, 42, 42, 42, 42, 16,
+        42, 42, 9, 42, 11, 42, 13, 14,
+        15, 16, 17, 42, 2, 42, 3, 3,
+        42, 5, 42, 6, 42, 42, 42, 42,
+        42, 42, 42, 16, 42, 42, 9, 42,
+        42, 42, 13, 14, 15, 16, 17, 42,
+        2, 42, 3, 3, 42, 5, 42, 6,
+        42, 42, 42, 42, 42, 42, 42, 16,
+        42, 42, 9, 10, 11, 42, 13, 14,
+        15, 16, 17, 42, 2, 3, 3, 3,
+        42, 5, 42, 6, 42, 42, 42, 42,
+        42, 42, 42, 8, 42, 42, 9, 10,
+        11, 12, 13, 14, 15, 16, 17, 42,
+        51, 50, 0
+};
+
+static const char _myanmar_syllable_machine_trans_targs[] = {
+        0, 1, 22, 0, 0, 23, 29, 32,
+        35, 36, 40, 41, 42, 25, 38, 39,
+        37, 28, 43, 44, 0, 2, 12, 0,
+        3, 9, 13, 14, 18, 19, 20, 5,
+        16, 17, 15, 8, 21, 4, 6, 7,
+        10, 11, 0, 24, 26, 27, 30, 31,
+        33, 34, 0, 0
+};
+
+static const char _myanmar_syllable_machine_trans_actions[] = {
+        3, 0, 0, 4, 5, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 6, 0, 0, 7,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 8, 0, 0, 0, 0, 0,
+        0, 0, 9, 10
+};
+
+static const char _myanmar_syllable_machine_to_state_actions[] = {
+        1, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0
+};
+
+static const char _myanmar_syllable_machine_from_state_actions[] = {
+        2, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0
+};
+
+static const short _myanmar_syllable_machine_eof_trans[] = {
+        0, 21, 21, 21, 21, 21, 21, 21,
+        21, 21, 21, 21, 21, 21, 21, 21,
+        21, 21, 21, 21, 21, 21, 43, 43,
+        43, 43, 43, 43, 43, 43, 43, 43,
+        21, 21, 43, 43, 43, 43, 43, 43,
+        43, 43, 43, 43, 51
+};
+
+static const int myanmar_syllable_machine_start = 0;
+static const int myanmar_syllable_machine_first_final = 0;
+static const int myanmar_syllable_machine_error = -1;
+
+static const int myanmar_syllable_machine_en_main = 0;
+
+
+#line 36 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+
+#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+  HB_STMT_START { \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+    for (unsigned int i = last; i < p+1; i++) \
+      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+    last = p+1; \
+    syllable_serial++; \
+    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+  } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  int cs;
+  hb_glyph_info_t *info = buffer->info;
+
+#line 289 "hb-ot-shape-complex-myanmar-machine.hh"
+        {
+        cs = myanmar_syllable_machine_start;
+        ts = 0;
+        te = 0;
+        act = 0;
+        }
+
+#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
+
+
+  p = 0;
+  pe = eof = buffer->len;
+
+  unsigned int last = 0;
+  unsigned int syllable_serial = 1;
+
+#line 306 "hb-ot-shape-complex-myanmar-machine.hh"
+        {
+        int _slen;
+        int _trans;
+        const unsigned char *_keys;
+        const char *_inds;
+        if ( p == pe )
+                goto _test_eof;
+_resume:
+        switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
+        case 2:
+#line 1 "NONE"
+        {ts = p;}
+        break;
+#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
+        }
+
+        _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
+        _inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
+
+        _slen = _myanmar_syllable_machine_key_spans[cs];
+        _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
+                ( info[p].myanmar_category()) <= _keys[1] ?
+                ( info[p].myanmar_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+        cs = _myanmar_syllable_machine_trans_targs[_trans];
+
+        if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
+                goto _again;
+
+        switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
+        case 7:
+#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+        {te = p+1;{ found_syllable (consonant_syllable); }}
+        break;
+        case 5:
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
+        {te = p+1;{ found_syllable (non_myanmar_cluster); }}
+        break;
+        case 10:
+#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
+        {te = p+1;{ found_syllable (punctuation_cluster); }}
+        break;
+        case 4:
+#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
+        {te = p+1;{ found_syllable (broken_cluster); }}
+        break;
+        case 3:
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+        {te = p+1;{ found_syllable (non_myanmar_cluster); }}
+        break;
+        case 6:
+#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+        {te = p;p--;{ found_syllable (consonant_syllable); }}
+        break;
+        case 8:
+#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
+        {te = p;p--;{ found_syllable (broken_cluster); }}
+        break;
+        case 9:
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+        {te = p;p--;{ found_syllable (non_myanmar_cluster); }}
+        break;
+#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
+        }
+
+_again:
+        switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
+        case 1:
+#line 1 "NONE"
+        {ts = 0;}
+        break;
+#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
+        }
+
+        if ( ++p != pe )
+                goto _resume;
+        _test_eof: {}
+        if ( p == eof )
+        {
+        if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
+                _trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
+                goto _eof_trans;
+        }
+        }
+
+        }
+
+#line 123 "hb-ot-shape-complex-myanmar-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,532 @@
+/*
+ * Copyright © 2011,2012,2013  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
+ */
+
+#include "hb-ot-shape-complex-indic-private.hh"
+
+/* buffer var allocations */
+#define myanmar_category() complex_var_u8_0() /* myanmar_category_t */
+#define myanmar_position() complex_var_u8_1() /* myanmar_position_t */
+
+
+/*
+ * Myanmar shaper.
+ */
+
+static const hb_tag_t
+basic_features[] =
+{
+  /*
+   * Basic features.
+   * These features are applied in order, one at a time, after initial_reordering.
+   */
+  HB_TAG('r','p','h','f'),
+  HB_TAG('p','r','e','f'),
+  HB_TAG('b','l','w','f'),
+  HB_TAG('p','s','t','f'),
+};
+static const hb_tag_t
+other_features[] =
+{
+  /*
+   * Other features.
+   * These features are applied all at once, after final_reordering.
+   */
+  HB_TAG('p','r','e','s'),
+  HB_TAG('a','b','v','s'),
+  HB_TAG('b','l','w','s'),
+  HB_TAG('p','s','t','s'),
+  /* Positioning features, though we don't care about the types. */
+  HB_TAG('d','i','s','t'),
+  /* Pre-release version of Windows 8 Myanmar font had abvm,blwm
+   * features.  The released Windows 8 version of the font (as well
+   * as the released spec) used 'mark' instead.  The Windows 8
+   * shaper however didn't apply 'mark' but did apply 'mkmk'.
+   * Perhaps it applied abvm/blwm.  This was fixed in a Windows 8
+   * update, so now it applies mark/mkmk.  We are guessing that
+   * it still applies abvm/blwm too.
+   */
+  HB_TAG('a','b','v','m'),
+  HB_TAG('b','l','w','m'),
+};
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+                 hb_font_t *font,
+                 hb_buffer_t *buffer);
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+                    hb_font_t *font,
+                    hb_buffer_t *buffer);
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+                  hb_font_t *font,
+                  hb_buffer_t *buffer);
+
+static void
+collect_features_myanmar (hb_ot_shape_planner_t *plan)
+{
+  hb_ot_map_builder_t *map = &plan->map;
+
+  /* Do this before any lookups have been applied. */
+  map->add_gsub_pause (setup_syllables);
+
+  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+  /* The Indic specs do not require ccmp, but we apply it here since if
+   * there is a use of it, it's typically at the beginning. */
+  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+
+
+  map->add_gsub_pause (initial_reordering);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
+  {
+    map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+    map->add_gsub_pause (NULL);
+  }
+  map->add_gsub_pause (final_reordering);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
+    map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+}
+
+static void
+override_features_myanmar (hb_ot_shape_planner_t *plan)
+{
+  plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
+}
+
+
+enum syllable_type_t {
+  consonant_syllable,
+  punctuation_cluster,
+  broken_cluster,
+  non_myanmar_cluster,
+};
+
+#include "hb-ot-shape-complex-myanmar-machine.hh"
+
+
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum myanmar_category_t {
+  OT_As  = 18, /* Asat */
+  OT_D   = 19, /* Digits except zero */
+  OT_D0  = 20, /* Digit zero */
+  OT_DB  = OT_N, /* Dot below */
+  OT_GB  = OT_PLACEHOLDER,
+  OT_MH  = 21, /* Various consonant medial types */
+  OT_MR  = 22, /* Various consonant medial types */
+  OT_MW  = 23, /* Various consonant medial types */
+  OT_MY  = 24, /* Various consonant medial types */
+  OT_PT  = 25, /* Pwo and other tones */
+  OT_VAbv = 26,
+  OT_VBlw = 27,
+  OT_VPre = 28,
+  OT_VPst = 29,
+  OT_VS   = 30, /* Variation selectors */
+  OT_P    = 31  /* Punctuation */
+};
+
+
+static inline bool
+is_one_of (const hb_glyph_info_t &info, unsigned int flags)
+{
+  /* If it ligated, all bets are off. */
+  if (_hb_glyph_info_ligated (&info)) return false;
+  return !!(FLAG_SAFE (info.myanmar_category()) & flags);
+}
+
+static inline bool
+is_consonant (const hb_glyph_info_t &info)
+{
+  return is_one_of (info, CONSONANT_FLAGS);
+}
+
+
+static inline void
+set_myanmar_properties (hb_glyph_info_t &info)
+{
+  hb_codepoint_t u = info.codepoint;
+  unsigned int type = hb_indic_get_categories (u);
+  indic_category_t cat = (indic_category_t) (type & 0x7Fu);
+  indic_position_t pos = (indic_position_t) (type >> 8);
+
+  /* Myanmar
+   * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze
+   */
+  if (unlikely (hb_in_range (u, 0xFE00u, 0xFE0Fu)))
+    cat = (indic_category_t) OT_VS;
+
+  switch (u)
+  {
+    case 0x104Eu:
+      cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
+      break;
+
+    case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u:
+    case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u:
+    case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu:
+    case 0x25FEu:
+      cat = (indic_category_t) OT_GB;
+      break;
+
+    case 0x1004u: case 0x101Bu: case 0x105Au:
+      cat = (indic_category_t) OT_Ra;
+      break;
+
+    case 0x1032u: case 0x1036u:
+      cat = (indic_category_t) OT_A;
+      break;
+
+    case 0x103Au:
+      cat = (indic_category_t) OT_As;
+      break;
+
+    case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u:
+    case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u:
+    case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u:
+    case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u:
+    case 0x1097u: case 0x1098u: case 0x1099u:
+      cat = (indic_category_t) OT_D;
+      break;
+
+    case 0x1040u:
+      cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
+      break;
+
+    case 0x103Eu: case 0x1060u:
+      cat = (indic_category_t) OT_MH;
+      break;
+
+    case 0x103Cu:
+      cat = (indic_category_t) OT_MR;
+      break;
+
+    case 0x103Du: case 0x1082u:
+      cat = (indic_category_t) OT_MW;
+      break;
+
+    case 0x103Bu: case 0x105Eu: case 0x105Fu:
+      cat = (indic_category_t) OT_MY;
+      break;
+
+    case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au:
+    case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu:
+      cat = (indic_category_t) OT_PT;
+      break;
+
+    case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u:
+    case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du:
+    case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu:
+      cat = (indic_category_t) OT_SM;
+      break;
+
+    case 0x104Au: case 0x104Bu:
+      cat = (indic_category_t) OT_P;
+      break;
+  }
+
+  if (cat == OT_M)
+  {
+    switch ((int) pos)
+    {
+      case POS_PRE_C:   cat = (indic_category_t) OT_VPre;
+                        pos = POS_PRE_M;                  break;
+      case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break;
+      case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break;
+      case POS_POST_C:  cat = (indic_category_t) OT_VPst; break;
+    }
+  }
+
+  info.myanmar_category() = (myanmar_category_t) cat;
+  info.myanmar_position() = pos;
+}
+
+
+
+static void
+setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                   hb_buffer_t              *buffer,
+                   hb_font_t                *font HB_UNUSED)
+{
+  HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
+  HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
+
+  /* We cannot setup masks here.  We save information about characters
+   * and setup masks later on in a pause-callback. */
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    set_myanmar_properties (info[i]);
+}
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                 hb_font_t *font HB_UNUSED,
+                 hb_buffer_t *buffer)
+{
+  find_syllables (buffer);
+}
+
+static int
+compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+  int a = pa->myanmar_position();
+  int b = pb->myanmar_position();
+
+  return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+/* Rules from:
+ * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */
+
+static void
+initial_reordering_consonant_syllable (hb_buffer_t *buffer,
+                                       unsigned int start, unsigned int end)
+{
+  hb_glyph_info_t *info = buffer->info;
+
+  unsigned int base = end;
+  bool has_reph = false;
+
+  {
+    unsigned int limit = start;
+    if (start + 3 <= end &&
+        info[start  ].myanmar_category() == OT_Ra &&
+        info[start+1].myanmar_category() == OT_As &&
+        info[start+2].myanmar_category() == OT_H)
+    {
+      limit += 3;
+      base = start;
+      has_reph = true;
+    }
+
+    {
+      if (!has_reph)
+        base = limit;
+
+      for (unsigned int i = limit; i < end; i++)
+        if (is_consonant (info[i]))
+        {
+          base = i;
+          break;
+        }
+    }
+  }
+
+  /* Reorder! */
+  {
+    unsigned int i = start;
+    for (; i < start + (has_reph ? 3 : 0); i++)
+      info[i].myanmar_position() = POS_AFTER_MAIN;
+    for (; i < base; i++)
+      info[i].myanmar_position() = POS_PRE_C;
+    if (i < end)
+    {
+      info[i].myanmar_position() = POS_BASE_C;
+      i++;
+    }
+    indic_position_t pos = POS_AFTER_MAIN;
+    /* The following loop may be ugly, but it implements all of
+     * Myanmar reordering! */
+    for (; i < end; i++)
+    {
+      if (info[i].myanmar_category() == OT_MR) /* Pre-base reordering */
+      {
+        info[i].myanmar_position() = POS_PRE_C;
+        continue;
+      }
+      if (info[i].myanmar_position() < POS_BASE_C) /* Left matra */
+      {
+        continue;
+      }
+
+      if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == OT_VBlw)
+      {
+        pos = POS_BELOW_C;
+        info[i].myanmar_position() = pos;
+        continue;
+      }
+
+      if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_A)
+      {
+        info[i].myanmar_position() = POS_BEFORE_SUB;
+        continue;
+      }
+      if (pos == POS_BELOW_C && info[i].myanmar_category() == OT_VBlw)
+      {
+        info[i].myanmar_position() = pos;
+        continue;
+      }
+      if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A)
+      {
+        pos = POS_AFTER_SUB;
+        info[i].myanmar_position() = pos;
+        continue;
+      }
+      info[i].myanmar_position() = pos;
+    }
+  }
+
+  /* Sit tight, rock 'n roll! */
+  buffer->sort (start, end, compare_myanmar_order);
+}
+
+static void
+initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
+                             hb_face_t *face,
+                             hb_buffer_t *buffer,
+                             unsigned int start, unsigned int end)
+{
+  syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+  switch (syllable_type) {
+
+    case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
+    case consonant_syllable:
+      initial_reordering_consonant_syllable  (buffer, start, end);
+      break;
+
+    case punctuation_cluster:
+    case non_myanmar_cluster:
+      break;
+  }
+}
+
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                       hb_font_t *font,
+                       hb_buffer_t *buffer)
+{
+  /* Note: This loop is extra overhead, but should not be measurable. */
+  bool has_broken_syllables = false;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    if ((info[i].syllable() & 0x0F) == broken_cluster)
+    {
+      has_broken_syllables = true;
+      break;
+    }
+  if (likely (!has_broken_syllables))
+    return;
+
+
+  hb_codepoint_t dottedcircle_glyph;
+  if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph))
+    return;
+
+  hb_glyph_info_t dottedcircle = {0};
+  dottedcircle.codepoint = 0x25CCu;
+  set_myanmar_properties (dottedcircle);
+  dottedcircle.codepoint = dottedcircle_glyph;
+
+  buffer->clear_output ();
+
+  buffer->idx = 0;
+  unsigned int last_syllable = 0;
+  while (buffer->idx < buffer->len)
+  {
+    unsigned int syllable = buffer->cur().syllable();
+    syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+    if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+    {
+      last_syllable = syllable;
+
+      hb_glyph_info_t info = dottedcircle;
+      info.cluster = buffer->cur().cluster;
+      info.mask = buffer->cur().mask;
+      info.syllable() = buffer->cur().syllable();
+
+      buffer->output_info (info);
+    }
+    else
+      buffer->next_glyph ();
+  }
+
+  buffer->swap_buffers ();
+}
+
+static void
+initial_reordering (const hb_ot_shape_plan_t *plan,
+                    hb_font_t *font,
+                    hb_buffer_t *buffer)
+{
+  insert_dotted_circles (plan, font, buffer);
+
+  foreach_syllable (buffer, start, end)
+    initial_reordering_syllable (plan, font->face, buffer, start, end);
+}
+
+static void
+final_reordering (const hb_ot_shape_plan_t *plan,
+                  hb_font_t *font HB_UNUSED,
+                  hb_buffer_t *buffer)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+
+  /* Zero syllables now... */
+  for (unsigned int i = 0; i < count; i++)
+    info[i].syllable() = 0;
+
+  HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
+  HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
+}
+
+
+/* Uniscribe seems to have a shaper for 'mymr' that is like the
+ * generic shaper, except that it zeros mark advances GDEF_LATE. */
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
+{
+  "default",
+  NULL, /* collect_features */
+  NULL, /* override_features */
+  NULL, /* data_create */
+  NULL, /* data_destroy */
+  NULL, /* preprocess_text */
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+  NULL, /* decompose */
+  NULL, /* compose */
+  NULL, /* setup_masks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
+  true, /* fallback_position */
+};
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
+{
+  "myanmar",
+  collect_features_myanmar,
+  override_features_myanmar,
+  NULL, /* data_create */
+  NULL, /* data_destroy */
+  NULL, /* preprocess_text */
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
+  NULL, /* decompose */
+  NULL, /* compose */
+  setup_masks_myanmar,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
+  false, /* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,355 @@
+/*
+ * Copyright © 2010,2011,2012  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_SHAPE_COMPLEX_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-shape-private.hh"
+#include "hb-ot-shape-normalize-private.hh"
+
+
+
+/* buffer var allocations, used by complex shapers */
+#define complex_var_u8_0()      var2.u8[2]
+#define complex_var_u8_1()      var2.u8[3]
+
+
+enum hb_ot_shape_zero_width_marks_type_t {
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+//  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
+
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT = HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE
+};
+
+
+/* Master OT shaper list */
+#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
+  HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
+  HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \
+  HB_COMPLEX_SHAPER_IMPLEMENT (use) \
+  /* ^--- Add new shapers here */
+
+
+struct hb_ot_complex_shaper_t
+{
+  char name[8];
+
+  /* collect_features()
+   * Called during shape_plan().
+   * Shapers should use plan->map to add their features and callbacks.
+   * May be NULL.
+   */
+  void (*collect_features) (hb_ot_shape_planner_t *plan);
+
+  /* override_features()
+   * Called during shape_plan().
+   * Shapers should use plan->map to override features and add callbacks after
+   * common features are added.
+   * May be NULL.
+   */
+  void (*override_features) (hb_ot_shape_planner_t *plan);
+
+
+  /* data_create()
+   * Called at the end of shape_plan().
+   * Whatever shapers return will be accessible through plan->data later.
+   * If NULL is returned, means a plan failure.
+   */
+  void *(*data_create) (const hb_ot_shape_plan_t *plan);
+
+  /* data_destroy()
+   * Called when the shape_plan is being destroyed.
+   * plan->data is passed here for destruction.
+   * If NULL is returned, means a plan failure.
+   * May be NULL.
+   */
+  void (*data_destroy) (void *data);
+
+
+  /* preprocess_text()
+   * Called during shape().
+   * Shapers can use to modify text before shaping starts.
+   * May be NULL.
+   */
+  void (*preprocess_text) (const hb_ot_shape_plan_t *plan,
+                           hb_buffer_t              *buffer,
+                           hb_font_t                *font);
+
+
+  hb_ot_shape_normalization_mode_t normalization_preference;
+
+  /* decompose()
+   * Called during shape()'s normalization.
+   * May be NULL.
+   */
+  bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
+                     hb_codepoint_t  ab,
+                     hb_codepoint_t *a,
+                     hb_codepoint_t *b);
+
+  /* compose()
+   * Called during shape()'s normalization.
+   * May be NULL.
+   */
+  bool (*compose) (const hb_ot_shape_normalize_context_t *c,
+                   hb_codepoint_t  a,
+                   hb_codepoint_t  b,
+                   hb_codepoint_t *ab);
+
+  /* setup_masks()
+   * Called during shape().
+   * Shapers should use map to get feature masks and set on buffer.
+   * Shapers may NOT modify characters.
+   * May be NULL.
+   */
+  void (*setup_masks) (const hb_ot_shape_plan_t *plan,
+                       hb_buffer_t              *buffer,
+                       hb_font_t                *font);
+
+  hb_ot_shape_zero_width_marks_type_t zero_width_marks;
+
+  bool fallback_position;
+};
+
+#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
+HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
+#undef HB_COMPLEX_SHAPER_IMPLEMENT
+
+
+static inline const hb_ot_complex_shaper_t *
+hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
+{
+  switch ((hb_tag_t) planner->props.script)
+  {
+    default:
+      return &_hb_ot_complex_shaper_default;
+
+
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_ARABIC:
+
+    /* Unicode-3.0 additions */
+    case HB_SCRIPT_MONGOLIAN:
+    case HB_SCRIPT_SYRIAC:
+
+    /* Unicode-5.0 additions */
+    case HB_SCRIPT_NKO:
+    case HB_SCRIPT_PHAGS_PA:
+
+    /* Unicode-6.0 additions */
+    case HB_SCRIPT_MANDAIC:
+
+    /* Unicode-7.0 additions */
+    case HB_SCRIPT_MANICHAEAN:
+    case HB_SCRIPT_PSALTER_PAHLAVI:
+
+      /* For Arabic script, use the Arabic shaper even if no OT script tag was found.
+       * This is because we do fallback shaping for Arabic script (and not others).
+       * But note that Arabic shaping is applicable only to horizontal layout; for
+       * vertical text, just use the generic shaper instead. */
+      if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
+           planner->props.script == HB_SCRIPT_ARABIC) &&
+          HB_DIRECTION_IS_HORIZONTAL(planner->props.direction))
+        return &_hb_ot_complex_shaper_arabic;
+      else
+        return &_hb_ot_complex_shaper_default;
+
+
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_THAI:
+    case HB_SCRIPT_LAO:
+
+      return &_hb_ot_complex_shaper_thai;
+
+
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_HANGUL:
+
+      return &_hb_ot_complex_shaper_hangul;
+
+
+    /* Unicode-2.0 additions */
+    case HB_SCRIPT_TIBETAN:
+
+      return &_hb_ot_complex_shaper_tibetan;
+
+
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_HEBREW:
+
+      return &_hb_ot_complex_shaper_hebrew;
+
+
+    /* ^--- Add new shapers here */
+
+#if 0
+    /* Unicode-4.1 additions */
+    case HB_SCRIPT_NEW_TAI_LUE:
+#endif
+
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_BENGALI:
+    case HB_SCRIPT_DEVANAGARI:
+    case HB_SCRIPT_GUJARATI:
+    case HB_SCRIPT_GURMUKHI:
+    case HB_SCRIPT_KANNADA:
+    case HB_SCRIPT_MALAYALAM:
+    case HB_SCRIPT_ORIYA:
+    case HB_SCRIPT_TAMIL:
+    case HB_SCRIPT_TELUGU:
+
+    /* Unicode-3.0 additions */
+    case HB_SCRIPT_SINHALA:
+
+    /* Unicode-5.2 additions */
+    case HB_SCRIPT_JAVANESE:
+
+      /* If the designer designed the font for the 'DFLT' script,
+       * use the default shaper.  Otherwise, use the specific shaper.
+       * Note that for some simple scripts, there may not be *any*
+       * GSUB/GPOS needed, so there may be no scripts found! */
+      if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
+        return &_hb_ot_complex_shaper_default;
+      else
+        return &_hb_ot_complex_shaper_indic;
+
+    case HB_SCRIPT_KHMER:
+      /* A number of Khmer fonts in the wild don't have a 'pref' feature,
+       * and as such won't shape properly via the Indic shaper;
+       * however, they typically have 'liga' / 'clig' features that implement
+       * the necessary "reordering" by means of ligature substitutions.
+       * So we send such pref-less fonts through the generic shaper instead. */
+      if (planner->map.found_script[0] &&
+          hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
+                                              planner->map.script_index[0],
+                                              planner->map.language_index[0],
+                                              HB_TAG ('p','r','e','f'),
+                                              NULL))
+        return &_hb_ot_complex_shaper_indic;
+      else
+        return &_hb_ot_complex_shaper_default;
+
+    case HB_SCRIPT_MYANMAR:
+      if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
+        return &_hb_ot_complex_shaper_myanmar;
+      else if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','r'))
+        return &_hb_ot_complex_shaper_myanmar_old;
+      else
+        return &_hb_ot_complex_shaper_default;
+
+
+    /* Unicode-2.0 additions */
+    //case HB_SCRIPT_TIBETAN:
+
+    /* Unicode-3.0 additions */
+    //case HB_SCRIPT_MONGOLIAN:
+    //case HB_SCRIPT_SINHALA:
+
+    /* Unicode-3.2 additions */
+    case HB_SCRIPT_BUHID:
+    case HB_SCRIPT_HANUNOO:
+    case HB_SCRIPT_TAGALOG:
+    case HB_SCRIPT_TAGBANWA:
+
+    /* Unicode-4.0 additions */
+    case HB_SCRIPT_LIMBU:
+    case HB_SCRIPT_TAI_LE:
+
+    /* Unicode-4.1 additions */
+    case HB_SCRIPT_BUGINESE:
+    case HB_SCRIPT_KHAROSHTHI:
+    case HB_SCRIPT_SYLOTI_NAGRI:
+    case HB_SCRIPT_TIFINAGH:
+
+    /* Unicode-5.0 additions */
+    case HB_SCRIPT_BALINESE:
+    //case HB_SCRIPT_NKO:
+    //case HB_SCRIPT_PHAGS_PA:
+
+    /* Unicode-5.1 additions */
+    case HB_SCRIPT_CHAM:
+    case HB_SCRIPT_KAYAH_LI:
+    case HB_SCRIPT_LEPCHA:
+    case HB_SCRIPT_REJANG:
+    case HB_SCRIPT_SAURASHTRA:
+    case HB_SCRIPT_SUNDANESE:
+
+    /* Unicode-5.2 additions */
+    case HB_SCRIPT_EGYPTIAN_HIEROGLYPHS:
+    //case HB_SCRIPT_JAVANESE:
+    case HB_SCRIPT_KAITHI:
+    case HB_SCRIPT_MEETEI_MAYEK:
+    case HB_SCRIPT_TAI_THAM:
+    case HB_SCRIPT_TAI_VIET:
+
+    /* Unicode-6.0 additions */
+    case HB_SCRIPT_BATAK:
+    case HB_SCRIPT_BRAHMI:
+    //case HB_SCRIPT_MANDAIC:
+
+    /* Unicode-6.1 additions */
+    case HB_SCRIPT_CHAKMA:
+    case HB_SCRIPT_SHARADA:
+    case HB_SCRIPT_TAKRI:
+
+    /* Unicode-7.0 additions */
+    case HB_SCRIPT_DUPLOYAN:
+    case HB_SCRIPT_GRANTHA:
+    case HB_SCRIPT_KHOJKI:
+    case HB_SCRIPT_KHUDAWADI:
+    case HB_SCRIPT_MAHAJANI:
+    //case HB_SCRIPT_MANICHAEAN:
+    case HB_SCRIPT_MODI:
+    case HB_SCRIPT_PAHAWH_HMONG:
+    //case HB_SCRIPT_PSALTER_PAHLAVI:
+    case HB_SCRIPT_SIDDHAM:
+    case HB_SCRIPT_TIRHUTA:
+
+      /* If the designer designed the font for the 'DFLT' script,
+       * use the default shaper.  Otherwise, use the specific shaper.
+       * Note that for some simple scripts, there may not be *any*
+       * GSUB/GPOS needed, so there may be no scripts found! */
+      if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T'))
+        return &_hb_ot_complex_shaper_default;
+      else
+        return &_hb_ot_complex_shaper_use;
+  }
+}
+
+
+#endif /* HB_OT_SHAPE_COMPLEX_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-thai.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,381 @@
+/*
+ * Copyright © 2010,2012  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
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+/* Thai / Lao shaper */
+
+
+/* PUA shaping */
+
+
+enum thai_consonant_type_t
+{
+  NC,
+  AC,
+  RC,
+  DC,
+  NOT_CONSONANT,
+  NUM_CONSONANT_TYPES = NOT_CONSONANT
+};
+
+static thai_consonant_type_t
+get_consonant_type (hb_codepoint_t u)
+{
+  if (u == 0x0E1Bu || u == 0x0E1Du || u == 0x0E1Fu/* || u == 0x0E2Cu*/)
+    return AC;
+  if (u == 0x0E0Du || u == 0x0E10u)
+    return RC;
+  if (u == 0x0E0Eu || u == 0x0E0Fu)
+    return DC;
+  if (hb_in_range (u, 0x0E01u, 0x0E2Eu))
+    return NC;
+  return NOT_CONSONANT;
+}
+
+
+enum thai_mark_type_t
+{
+  AV,
+  BV,
+  T,
+  NOT_MARK,
+  NUM_MARK_TYPES = NOT_MARK
+};
+
+static thai_mark_type_t
+get_mark_type (hb_codepoint_t u)
+{
+  if (u == 0x0E31u || hb_in_range (u, 0x0E34u, 0x0E37u) ||
+      u == 0x0E47u || hb_in_range (u, 0x0E4Du, 0x0E4Eu))
+    return AV;
+  if (hb_in_range (u, 0x0E38u, 0x0E3Au))
+    return BV;
+  if (hb_in_range (u, 0x0E48u, 0x0E4Cu))
+    return T;
+  return NOT_MARK;
+}
+
+
+enum thai_action_t
+{
+  NOP,
+  SD,  /* Shift combining-mark down */
+  SL,  /* Shift combining-mark left */
+  SDL, /* Shift combining-mark down-left */
+  RD   /* Remove descender from base */
+};
+
+static hb_codepoint_t
+thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font)
+{
+  struct thai_pua_mapping_t {
+    hb_codepoint_t u;
+    hb_codepoint_t win_pua;
+    hb_codepoint_t mac_pua;
+  } const *pua_mappings = NULL;
+  static const thai_pua_mapping_t SD_mappings[] = {
+    {0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */
+    {0x0E49u, 0xF70Bu, 0xF88Eu}, /* MAI THO */
+    {0x0E4Au, 0xF70Cu, 0xF891u}, /* MAI TRI */
+    {0x0E4Bu, 0xF70Du, 0xF894u}, /* MAI CHATTAWA */
+    {0x0E4Cu, 0xF70Eu, 0xF897u}, /* THANTHAKHAT */
+    {0x0E38u, 0xF718u, 0xF89Bu}, /* SARA U */
+    {0x0E39u, 0xF719u, 0xF89Cu}, /* SARA UU */
+    {0x0E3Au, 0xF71Au, 0xF89Du}, /* PHINTHU */
+    {0x0000u, 0x0000u, 0x0000u}
+  };
+  static const thai_pua_mapping_t SDL_mappings[] = {
+    {0x0E48u, 0xF705u, 0xF88Cu}, /* MAI EK */
+    {0x0E49u, 0xF706u, 0xF88Fu}, /* MAI THO */
+    {0x0E4Au, 0xF707u, 0xF892u}, /* MAI TRI */
+    {0x0E4Bu, 0xF708u, 0xF895u}, /* MAI CHATTAWA */
+    {0x0E4Cu, 0xF709u, 0xF898u}, /* THANTHAKHAT */
+    {0x0000u, 0x0000u, 0x0000u}
+  };
+  static const thai_pua_mapping_t SL_mappings[] = {
+    {0x0E48u, 0xF713u, 0xF88Au}, /* MAI EK */
+    {0x0E49u, 0xF714u, 0xF88Du}, /* MAI THO */
+    {0x0E4Au, 0xF715u, 0xF890u}, /* MAI TRI */
+    {0x0E4Bu, 0xF716u, 0xF893u}, /* MAI CHATTAWA */
+    {0x0E4Cu, 0xF717u, 0xF896u}, /* THANTHAKHAT */
+    {0x0E31u, 0xF710u, 0xF884u}, /* MAI HAN-AKAT */
+    {0x0E34u, 0xF701u, 0xF885u}, /* SARA I */
+    {0x0E35u, 0xF702u, 0xF886u}, /* SARA II */
+    {0x0E36u, 0xF703u, 0xF887u}, /* SARA UE */
+    {0x0E37u, 0xF704u, 0xF888u}, /* SARA UEE */
+    {0x0E47u, 0xF712u, 0xF889u}, /* MAITAIKHU */
+    {0x0E4Du, 0xF711u, 0xF899u}, /* NIKHAHIT */
+    {0x0000u, 0x0000u, 0x0000u}
+  };
+  static const thai_pua_mapping_t RD_mappings[] = {
+    {0x0E0Du, 0xF70Fu, 0xF89Au}, /* YO YING */
+    {0x0E10u, 0xF700u, 0xF89Eu}, /* THO THAN */
+    {0x0000u, 0x0000u, 0x0000u}
+  };
+
+  switch (action) {
+    default: assert (false); /* Fallthrough */
+    case NOP: return u;
+    case SD:  pua_mappings = SD_mappings; break;
+    case SDL: pua_mappings = SDL_mappings; break;
+    case SL:  pua_mappings = SL_mappings; break;
+    case RD:  pua_mappings = RD_mappings; break;
+  }
+  for (; pua_mappings->u; pua_mappings++)
+    if (pua_mappings->u == u)
+    {
+      hb_codepoint_t glyph;
+      if (hb_font_get_glyph (font, pua_mappings->win_pua, 0, &glyph))
+        return pua_mappings->win_pua;
+      if (hb_font_get_glyph (font, pua_mappings->mac_pua, 0, &glyph))
+        return pua_mappings->mac_pua;
+      break;
+    }
+  return u;
+}
+
+
+static enum thai_above_state_t
+{     /* Cluster above looks like: */
+  T0, /*  ⣤                      */
+  T1, /*     ⣼                   */
+  T2, /*        ⣾                */
+  T3, /*           ⣿             */
+  NUM_ABOVE_STATES
+} thai_above_start_state[NUM_CONSONANT_TYPES + 1/* For NOT_CONSONANT */] =
+{
+  T0, /* NC */
+  T1, /* AC */
+  T0, /* RC */
+  T0, /* DC */
+  T3, /* NOT_CONSONANT */
+};
+
+static const struct thai_above_state_machine_edge_t {
+  thai_action_t action;
+  thai_above_state_t next_state;
+} thai_above_state_machine[NUM_ABOVE_STATES][NUM_MARK_TYPES] =
+{        /*AV*/    /*BV*/    /*T*/
+/*T0*/ {{NOP,T3}, {NOP,T0}, {SD, T3}},
+/*T1*/ {{SL, T2}, {NOP,T1}, {SDL,T2}},
+/*T2*/ {{NOP,T3}, {NOP,T2}, {SL, T3}},
+/*T3*/ {{NOP,T3}, {NOP,T3}, {NOP,T3}},
+};
+
+
+static enum thai_below_state_t
+{
+  B0, /* No descender */
+  B1, /* Removable descender */
+  B2, /* Strict descender */
+  NUM_BELOW_STATES
+} thai_below_start_state[NUM_CONSONANT_TYPES + 1/* For NOT_CONSONANT */] =
+{
+  B0, /* NC */
+  B0, /* AC */
+  B1, /* RC */
+  B2, /* DC */
+  B2, /* NOT_CONSONANT */
+};
+
+static const struct thai_below_state_machine_edge_t {
+  thai_action_t action;
+  thai_below_state_t next_state;
+} thai_below_state_machine[NUM_BELOW_STATES][NUM_MARK_TYPES] =
+{        /*AV*/    /*BV*/    /*T*/
+/*B0*/ {{NOP,B0}, {NOP,B2}, {NOP, B0}},
+/*B1*/ {{NOP,B1}, {RD, B2}, {NOP, B1}},
+/*B2*/ {{NOP,B2}, {SD, B2}, {NOP, B2}},
+};
+
+
+static void
+do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                     hb_buffer_t              *buffer,
+                     hb_font_t                *font)
+{
+  thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT];
+  thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT];
+  unsigned int base = 0;
+
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    thai_mark_type_t mt = get_mark_type (info[i].codepoint);
+
+    if (mt == NOT_MARK) {
+      thai_consonant_type_t ct = get_consonant_type (info[i].codepoint);
+      above_state = thai_above_start_state[ct];
+      below_state = thai_below_start_state[ct];
+      base = i;
+      continue;
+    }
+
+    const thai_above_state_machine_edge_t &above_edge = thai_above_state_machine[above_state][mt];
+    const thai_below_state_machine_edge_t &below_edge = thai_below_state_machine[below_state][mt];
+    above_state = above_edge.next_state;
+    below_state = below_edge.next_state;
+
+    /* At least one of the above/below actions is NOP. */
+    thai_action_t action = above_edge.action != NOP ? above_edge.action : below_edge.action;
+
+    if (action == RD)
+      info[base].codepoint = thai_pua_shape (info[base].codepoint, action, font);
+    else
+      info[i].codepoint = thai_pua_shape (info[i].codepoint, action, font);
+  }
+}
+
+
+static void
+preprocess_text_thai (const hb_ot_shape_plan_t *plan,
+                      hb_buffer_t              *buffer,
+                      hb_font_t                *font)
+{
+  /* This function implements the shaping logic documented here:
+   *
+   *   http://linux.thai.net/~thep/th-otf/shaping.html
+   *
+   * The first shaping rule listed there is needed even if the font has Thai
+   * OpenType tables.  The rest do fallback positioning based on PUA codepoints.
+   * We implement that only if there exist no Thai GSUB in the font.
+   */
+
+  /* The following is NOT specified in the MS OT Thai spec, however, it seems
+   * to be what Uniscribe and other engines implement.  According to Eric Muller:
+   *
+   * When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
+   * NIKHAHIT backwards over any tone mark (0E48-0E4B).
+   *
+   * <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32>
+   *
+   * This reordering is legit only when the NIKHAHIT comes from a SARA AM, not
+   * when it's there to start with. The string <0E14, 0E4B, 0E4D> is probably
+   * not what a user wanted, but the rendering is nevertheless nikhahit above
+   * chattawa.
+   *
+   * Same for Lao.
+   *
+   * Note:
+   *
+   * Uniscribe also does some below-marks reordering.  Namely, it positions U+0E3A
+   * after U+0E38 and U+0E39.  We do that by modifying the ccc for U+0E3A.
+   * See unicode->modified_combining_class ().  Lao does NOT have a U+0E3A
+   * equivalent.
+   */
+
+
+  /*
+   * Here are the characters of significance:
+   *
+   *                    Thai    Lao
+   * SARA AM:           U+0E33  U+0EB3
+   * SARA AA:           U+0E32  U+0EB2
+   * Nikhahit:          U+0E4D  U+0ECD
+   *
+   * Testing shows that Uniscribe reorder the following marks:
+   * Thai:      <0E31,0E34..0E37,0E47..0E4E>
+   * Lao:       <0EB1,0EB4..0EB7,0EC7..0ECE>
+   *
+   * Note how the Lao versions are the same as Thai + 0x80.
+   */
+
+  /* We only get one script at a time, so a script-agnostic implementation
+   * is adequate here. */
+#define IS_SARA_AM(x) (((x) & ~0x0080u) == 0x0E33u)
+#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0x0E33u + 0x0E4Du)
+#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
+#define IS_TONE_MARK(x) (hb_in_ranges ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u))
+
+  buffer->clear_output ();
+  unsigned int count = buffer->len;
+  for (buffer->idx = 0; buffer->idx < count;)
+  {
+    hb_codepoint_t u = buffer->cur().codepoint;
+    if (likely (!IS_SARA_AM (u))) {
+      buffer->next_glyph ();
+      continue;
+    }
+
+    /* Is SARA AM. Decompose and reorder. */
+    hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
+                                    hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
+    buffer->replace_glyphs (1, 2, decomposed);
+    if (unlikely (buffer->in_error))
+      return;
+
+    /* Make Nikhahit be recognized as a mark when zeroing widths. */
+    unsigned int end = buffer->out_len;
+    _hb_glyph_info_set_general_category (&buffer->out_info[end - 2], HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK);
+
+    /* Ok, let's see... */
+    unsigned int start = end - 2;
+    while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint))
+      start--;
+
+    if (start + 2 < end)
+    {
+      /* Move Nikhahit (end-2) to the beginning */
+      buffer->merge_out_clusters (start, end);
+      hb_glyph_info_t t = buffer->out_info[end - 2];
+      memmove (buffer->out_info + start + 1,
+               buffer->out_info + start,
+               sizeof (buffer->out_info[0]) * (end - start - 2));
+      buffer->out_info[start] = t;
+    }
+    else
+    {
+      /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the
+       * previous cluster. */
+      if (start && buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
+        buffer->merge_out_clusters (start - 1, end);
+    }
+  }
+  buffer->swap_buffers ();
+
+  /* If font has Thai GSUB, we are done. */
+  if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])
+    do_thai_pua_shaping (plan, buffer, font);
+}
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
+{
+  "thai",
+  NULL, /* collect_features */
+  NULL, /* override_features */
+  NULL, /* data_create */
+  NULL, /* data_destroy */
+  preprocess_text_thai,
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+  NULL, /* decompose */
+  NULL, /* compose */
+  NULL, /* setup_masks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
+  false,/* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-tibetan.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2010,2012  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
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+static const hb_tag_t tibetan_features[] =
+{
+  HB_TAG('a','b','v','s'),
+  HB_TAG('b','l','w','s'),
+  HB_TAG('a','b','v','m'),
+  HB_TAG('b','l','w','m'),
+  HB_TAG_NONE
+};
+
+static void
+collect_features_tibetan (hb_ot_shape_planner_t *plan)
+{
+  for (const hb_tag_t *script_features = tibetan_features; script_features && *script_features; script_features++)
+    plan->map.add_global_bool_feature (*script_features);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan =
+{
+  "default",
+  collect_features_tibetan,
+  NULL, /* override_features */
+  NULL, /* data_create */
+  NULL, /* data_destroy */
+  NULL, /* preprocess_text */
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+  NULL, /* decompose */
+  NULL, /* compose */
+  NULL, /* setup_masks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
+  true, /* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-machine.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,548 @@
+
+#line 1 "hb-ot-shape-complex-use-machine.rl"
+/*
+ * Copyright © 2015  Mozilla Foundation.
+ * Copyright © 2015  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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
+#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH
+
+#include "hb-private.hh"
+
+
+#line 38 "hb-ot-shape-complex-use-machine.hh"
+static const unsigned char _use_syllable_machine_trans_keys[] = {
+        0u, 0u, 4u, 4u, 1u, 1u, 0u, 39u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u,
+        8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u,
+        8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
+        8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u,
+        8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
+        8u, 39u, 12u, 21u, 12u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u,
+        8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
+        8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u,
+        42u, 42u, 0
+};
+
+static const char _use_syllable_machine_key_spans[] = {
+        0, 1, 1, 40, 1, 32, 32, 1,
+        32, 32, 32, 19, 19, 19, 32, 32,
+        32, 32, 32, 32, 32, 32, 32, 32,
+        32, 32, 32, 1, 32, 32, 19, 19,
+        19, 32, 32, 32, 32, 32, 32, 32,
+        32, 10, 2, 32, 32, 32, 32, 19,
+        19, 19, 32, 32, 32, 32, 32, 32,
+        32, 32, 32, 32, 39, 32, 22, 2,
+        1
+};
+
+static const short _use_syllable_machine_index_offsets[] = {
+        0, 0, 2, 4, 45, 47, 80, 113,
+        115, 148, 181, 214, 234, 254, 274, 307,
+        340, 373, 406, 439, 472, 505, 538, 571,
+        604, 637, 670, 703, 705, 738, 771, 791,
+        811, 831, 864, 897, 930, 963, 996, 1029,
+        1062, 1095, 1106, 1109, 1142, 1175, 1208, 1241,
+        1261, 1281, 1301, 1334, 1367, 1400, 1433, 1466,
+        1499, 1532, 1565, 1598, 1631, 1671, 1704, 1727,
+        1730
+};
+
+static const char _use_syllable_machine_indicies[] = {
+        1, 0, 3, 2, 4, 5, 6,
+        4, 1, 5, 8, 8, 7, 8, 8,
+        3, 9, 8, 8, 8, 4, 4, 10,
+        11, 8, 8, 12, 13, 14, 15, 16,
+        17, 18, 12, 19, 20, 21, 22, 23,
+        24, 8, 25, 26, 27, 8, 29, 28,
+        31, 30, 30, 32, 33, 30, 30, 30,
+        30, 30, 30, 30, 30, 34, 35, 36,
+        37, 38, 39, 40, 41, 35, 42, 34,
+        43, 44, 45, 46, 30, 47, 48, 49,
+        30, 31, 30, 30, 32, 33, 30, 30,
+        30, 30, 30, 30, 30, 30, 50, 35,
+        36, 37, 38, 39, 40, 41, 35, 42,
+        43, 43, 44, 45, 46, 30, 47, 48,
+        49, 30, 32, 51, 31, 30, 30, 32,
+        33, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 35, 36, 37, 38, 39, 40,
+        41, 35, 42, 43, 43, 44, 45, 46,
+        30, 47, 48, 49, 30, 31, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 35, 36, 37, 38, 39,
+        30, 30, 30, 30, 30, 30, 44, 45,
+        46, 30, 47, 48, 49, 30, 31, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 36, 37, 38,
+        39, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 47, 48, 49, 30, 31,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 37,
+        38, 39, 30, 31, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 38, 39, 30, 31,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 39, 30, 31, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 37, 38, 39, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        47, 48, 49, 30, 31, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 37, 38, 39, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 48, 49, 30, 31, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 37, 38, 39,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 49, 30, 31, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 36, 37, 38,
+        39, 30, 30, 30, 30, 30, 30, 44,
+        45, 46, 30, 47, 48, 49, 30, 31,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 36, 37,
+        38, 39, 30, 30, 30, 30, 30, 30,
+        30, 45, 46, 30, 47, 48, 49, 30,
+        31, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 36,
+        37, 38, 39, 30, 30, 30, 30, 30,
+        30, 30, 30, 46, 30, 47, 48, 49,
+        30, 31, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 35,
+        36, 37, 38, 39, 30, 41, 35, 30,
+        30, 30, 44, 45, 46, 30, 47, 48,
+        49, 30, 31, 30, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        35, 36, 37, 38, 39, 30, 30, 35,
+        30, 30, 30, 44, 45, 46, 30, 47,
+        48, 49, 30, 31, 30, 30, 30, 30,
+        30, 30, 30, 30, 30, 30, 30, 30,
+        30, 35, 36, 37, 38, 39, 40, 41,
+        35, 30, 30, 30, 44, 45, 46, 30,
+        47, 48, 49, 30, 31, 30, 30, 32,
+        33, 30, 30, 30, 30, 30, 30, 30,
+        30, 30, 35, 36, 37, 38, 39, 40,
+        41, 35, 42, 30, 43, 44, 45, 46,
+        30, 47, 48, 49, 30, 31, 30, 30,
+        32, 33, 30, 30, 30, 30, 30, 30,
+        30, 30, 30, 35, 36, 37, 38, 39,
+        40, 41, 35, 42, 34, 43, 44, 45,
+        46, 30, 47, 48, 49, 30, 53, 52,
+        52, 54, 55, 52, 52, 52, 52, 52,
+        52, 52, 52, 56, 52, 57, 58, 59,
+        60, 61, 62, 57, 63, 56, 64, 52,
+        52, 52, 52, 65, 66, 67, 52, 53,
+        52, 52, 54, 55, 52, 52, 52, 52,
+        52, 52, 52, 52, 68, 52, 57, 58,
+        59, 60, 61, 62, 57, 63, 64, 64,
+        52, 52, 52, 52, 65, 66, 67, 52,
+        54, 51, 53, 52, 52, 54, 55, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 57, 58, 59, 60, 61, 62, 57,
+        63, 64, 64, 52, 52, 52, 52, 65,
+        66, 67, 52, 53, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 57, 58, 59, 60, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        65, 66, 67, 52, 53, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 58, 59, 60, 52,
+        53, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 59, 60, 52, 53, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 60, 52,
+        53, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        58, 59, 60, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 65, 66, 67,
+        52, 53, 52, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 58, 59, 60, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 66,
+        67, 52, 53, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 58, 59, 60, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 67, 52, 53, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 57, 58, 59, 60, 52, 62,
+        57, 52, 52, 52, 52, 52, 52, 52,
+        65, 66, 67, 52, 53, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 52, 57, 58, 59, 60, 52,
+        52, 57, 52, 52, 52, 52, 52, 52,
+        52, 65, 66, 67, 52, 53, 52, 52,
+        52, 52, 52, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 57, 58, 59, 60,
+        61, 62, 57, 52, 52, 52, 52, 52,
+        52, 52, 65, 66, 67, 52, 53, 52,
+        52, 54, 55, 52, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 57, 58, 59,
+        60, 61, 62, 57, 63, 52, 64, 52,
+        52, 52, 52, 65, 66, 67, 52, 53,
+        52, 52, 54, 55, 52, 52, 52, 52,
+        52, 52, 52, 52, 52, 52, 57, 58,
+        59, 60, 61, 62, 57, 63, 56, 64,
+        52, 52, 52, 52, 65, 66, 67, 52,
+        70, 71, 69, 69, 69, 69, 69, 69,
+        69, 72, 69, 70, 71, 69, 7, 73,
+        73, 3, 9, 73, 73, 73, 73, 73,
+        73, 73, 73, 74, 12, 13, 14, 15,
+        16, 17, 18, 12, 19, 21, 21, 22,
+        23, 24, 73, 25, 26, 27, 73, 7,
+        73, 73, 3, 9, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 12, 13, 14,
+        15, 16, 17, 18, 12, 19, 21, 21,
+        22, 23, 24, 73, 25, 26, 27, 73,
+        7, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 12, 13,
+        14, 15, 16, 73, 73, 73, 73, 73,
+        73, 22, 23, 24, 73, 25, 26, 27,
+        73, 7, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        13, 14, 15, 16, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 25, 26,
+        27, 73, 7, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 14, 15, 16, 73, 7, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 15,
+        16, 73, 7, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 16, 73, 7, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 14, 15,
+        16, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 25, 26, 27, 73, 7,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 14,
+        15, 16, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 26, 27, 73,
+        7, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        14, 15, 16, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 27,
+        73, 7, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        13, 14, 15, 16, 73, 73, 73, 73,
+        73, 73, 22, 23, 24, 73, 25, 26,
+        27, 73, 7, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 13, 14, 15, 16, 73, 73, 73,
+        73, 73, 73, 73, 23, 24, 73, 25,
+        26, 27, 73, 7, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 13, 14, 15, 16, 73, 73,
+        73, 73, 73, 73, 73, 73, 24, 73,
+        25, 26, 27, 73, 7, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 12, 13, 14, 15, 16, 73,
+        18, 12, 73, 73, 73, 22, 23, 24,
+        73, 25, 26, 27, 73, 7, 73, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 12, 13, 14, 15, 16,
+        73, 73, 12, 73, 73, 73, 22, 23,
+        24, 73, 25, 26, 27, 73, 7, 73,
+        73, 73, 73, 73, 73, 73, 73, 73,
+        73, 73, 73, 73, 12, 13, 14, 15,
+        16, 17, 18, 12, 73, 73, 73, 22,
+        23, 24, 73, 25, 26, 27, 73, 7,
+        73, 73, 3, 9, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 12, 13, 14,
+        15, 16, 17, 18, 12, 19, 73, 21,
+        22, 23, 24, 73, 25, 26, 27, 73,
+        5, 6, 73, 73, 5, 73, 73, 7,
+        73, 73, 3, 9, 73, 73, 73, 73,
+        73, 73, 73, 73, 73, 12, 13, 14,
+        15, 16, 17, 18, 12, 19, 20, 21,
+        22, 23, 24, 73, 25, 26, 27, 73,
+        7, 73, 73, 3, 9, 73, 73, 73,
+        73, 73, 73, 73, 73, 73, 12, 13,
+        14, 15, 16, 17, 18, 12, 19, 20,
+        21, 22, 23, 24, 73, 25, 26, 27,
+        73, 76, 75, 75, 75, 75, 75, 75,
+        75, 75, 75, 75, 75, 75, 75, 75,
+        75, 75, 75, 75, 75, 76, 77, 75,
+        76, 77, 75, 77, 75, 0
+};
+
+static const char _use_syllable_machine_trans_targs[] = {
+        3, 41, 3, 43, 4, 5, 25, 3,
+        0, 2, 60, 62, 45, 46, 47, 48,
+        49, 56, 57, 58, 61, 59, 53, 54,
+        55, 50, 51, 52, 3, 3, 3, 3,
+        6, 7, 24, 9, 10, 11, 12, 13,
+        20, 21, 22, 23, 17, 18, 19, 14,
+        15, 16, 8, 3, 3, 3, 26, 27,
+        40, 29, 30, 31, 32, 36, 37, 38,
+        39, 33, 34, 35, 28, 3, 3, 1,
+        42, 3, 44, 3, 63, 64
+};
+
+static const char _use_syllable_machine_trans_actions[] = {
+        1, 2, 3, 4, 0, 0, 0, 7,
+        0, 0, 4, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 4, 4, 0, 0,
+        0, 0, 0, 0, 8, 9, 10, 11,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 12, 13, 14, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 15, 16, 0,
+        2, 17, 4, 18, 0, 0
+};
+
+static const char _use_syllable_machine_to_state_actions[] = {
+        0, 0, 0, 5, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0
+};
+
+static const char _use_syllable_machine_from_state_actions[] = {
+        0, 0, 0, 6, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0,
+        0
+};
+
+static const short _use_syllable_machine_eof_trans[] = {
+        0, 1, 3, 0, 29, 31, 31, 52,
+        31, 31, 31, 31, 31, 31, 31, 31,
+        31, 31, 31, 31, 31, 31, 31, 31,
+        31, 53, 53, 52, 53, 53, 53, 53,
+        53, 53, 53, 53, 53, 53, 53, 53,
+        53, 70, 70, 74, 74, 74, 74, 74,
+        74, 74, 74, 74, 74, 74, 74, 74,
+        74, 74, 74, 74, 74, 74, 76, 76,
+        76
+};
+
+static const int use_syllable_machine_start = 3;
+static const int use_syllable_machine_first_final = 3;
+static const int use_syllable_machine_error = 0;
+
+static const int use_syllable_machine_en_main = 3;
+
+
+#line 38 "hb-ot-shape-complex-use-machine.rl"
+
+
+
+#line 145 "hb-ot-shape-complex-use-machine.rl"
+
+
+#define found_syllable(syllable_type) \
+  HB_STMT_START { \
+    if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
+    for (unsigned int i = last; i < p+1; i++) \
+      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+    last = p+1; \
+    syllable_serial++; \
+    if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
+  } HB_STMT_END
+
+static void
+find_syllables (hb_buffer_t *buffer)
+{
+  unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
+  int cs;
+  hb_glyph_info_t *info = buffer->info;
+
+#line 388 "hb-ot-shape-complex-use-machine.hh"
+        {
+        cs = use_syllable_machine_start;
+        ts = 0;
+        te = 0;
+        act = 0;
+        }
+
+#line 166 "hb-ot-shape-complex-use-machine.rl"
+
+
+  p = 0;
+  pe = eof = buffer->len;
+
+  unsigned int last = 0;
+  unsigned int syllable_serial = 1;
+
+#line 405 "hb-ot-shape-complex-use-machine.hh"
+        {
+        int _slen;
+        int _trans;
+        const unsigned char *_keys;
+        const char *_inds;
+        if ( p == pe )
+                goto _test_eof;
+        if ( cs == 0 )
+                goto _out;
+_resume:
+        switch ( _use_syllable_machine_from_state_actions[cs] ) {
+        case 6:
+#line 1 "NONE"
+        {ts = p;}
+        break;
+#line 421 "hb-ot-shape-complex-use-machine.hh"
+        }
+
+        _keys = _use_syllable_machine_trans_keys + (cs<<1);
+        _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs];
+
+        _slen = _use_syllable_machine_key_spans[cs];
+        _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].use_category()) &&
+                ( info[p].use_category()) <= _keys[1] ?
+                ( info[p].use_category()) - _keys[0] : _slen ];
+
+_eof_trans:
+        cs = _use_syllable_machine_trans_targs[_trans];
+
+        if ( _use_syllable_machine_trans_actions[_trans] == 0 )
+                goto _again;
+
+        switch ( _use_syllable_machine_trans_actions[_trans] ) {
+        case 2:
+#line 1 "NONE"
+        {te = p+1;}
+        break;
+        case 9:
+#line 134 "hb-ot-shape-complex-use-machine.rl"
+        {te = p+1;{ found_syllable (independent_cluster); }}
+        break;
+        case 11:
+#line 136 "hb-ot-shape-complex-use-machine.rl"
+        {te = p+1;{ found_syllable (consonant_cluster); }}
+        break;
+        case 14:
+#line 137 "hb-ot-shape-complex-use-machine.rl"
+        {te = p+1;{ found_syllable (vowel_cluster); }}
+        break;
+        case 16:
+#line 138 "hb-ot-shape-complex-use-machine.rl"
+        {te = p+1;{ found_syllable (number_joiner_terminated_cluster); }}
+        break;
+        case 7:
+#line 141 "hb-ot-shape-complex-use-machine.rl"
+        {te = p+1;{ found_syllable (broken_cluster); }}
+        break;
+        case 8:
+#line 134 "hb-ot-shape-complex-use-machine.rl"
+        {te = p;p--;{ found_syllable (independent_cluster); }}
+        break;
+        case 12:
+#line 135 "hb-ot-shape-complex-use-machine.rl"
+        {te = p;p--;{ found_syllable (virama_terminated_cluster); }}
+        break;
+        case 10:
+#line 136 "hb-ot-shape-complex-use-machine.rl"
+        {te = p;p--;{ found_syllable (consonant_cluster); }}
+        break;
+        case 13:
+#line 137 "hb-ot-shape-complex-use-machine.rl"
+        {te = p;p--;{ found_syllable (vowel_cluster); }}
+        break;
+        case 15:
+#line 139 "hb-ot-shape-complex-use-machine.rl"
+        {te = p;p--;{ found_syllable (numeral_cluster); }}
+        break;
+        case 18:
+#line 140 "hb-ot-shape-complex-use-machine.rl"
+        {te = p;p--;{ found_syllable (symbol_cluster); }}
+        break;
+        case 17:
+#line 141 "hb-ot-shape-complex-use-machine.rl"
+        {te = p;p--;{ found_syllable (broken_cluster); }}
+        break;
+        case 1:
+#line 139 "hb-ot-shape-complex-use-machine.rl"
+        {{p = ((te))-1;}{ found_syllable (numeral_cluster); }}
+        break;
+        case 3:
+#line 1 "NONE"
+        {       switch( act ) {
+        case 0:
+        {{cs = 0; goto _again;}}
+        break;
+        case 8:
+        {{p = ((te))-1;} found_syllable (broken_cluster); }
+        break;
+        }
+        }
+        break;
+        case 4:
+#line 1 "NONE"
+        {te = p+1;}
+#line 141 "hb-ot-shape-complex-use-machine.rl"
+        {act = 8;}
+        break;
+#line 513 "hb-ot-shape-complex-use-machine.hh"
+        }
+
+_again:
+        switch ( _use_syllable_machine_to_state_actions[cs] ) {
+        case 5:
+#line 1 "NONE"
+        {ts = 0;}
+#line 1 "NONE"
+        {act = 0;}
+        break;
+#line 524 "hb-ot-shape-complex-use-machine.hh"
+        }
+
+        if ( cs == 0 )
+                goto _out;
+        if ( ++p != pe )
+                goto _resume;
+        _test_eof: {}
+        if ( p == eof )
+        {
+        if ( _use_syllable_machine_eof_trans[cs] > 0 ) {
+                _trans = _use_syllable_machine_eof_trans[cs] - 1;
+                goto _eof_trans;
+        }
+        }
+
+        _out: {}
+        }
+
+#line 175 "hb-ot-shape-complex-use-machine.rl"
+
+}
+
+#undef found_syllable
+
+#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2015  Mozilla Foundation.
+ * Copyright © 2015  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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+#define USE_TABLE_ELEMENT_TYPE uint8_t
+
+/* Cateories used in the Universal Shaping Engine spec:
+ * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm
+ */
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum use_category_t {
+  USE_O         = 0,    /* OTHER */
+
+  USE_B         = 1,    /* BASE */
+  USE_IV        = 2,    /* BASE_VOWEL */
+  USE_IND       = 3,    /* BASE_IND */
+  USE_N         = 4,    /* BASE_NUM */
+  USE_GB        = 5,    /* BASE_OTHER */
+  USE_CGJ       = 6,    /* CGJ */
+//  USE_F               = 7,    /* CONS_FINAL */
+  USE_FM        = 8,    /* CONS_FINAL_MOD */
+//  USE_M               = 9,    /* CONS_MED */
+//  USE_CM      = 10,   /* CONS_MOD */
+  USE_SUB       = 11,   /* CONS_SUB */
+  USE_H         = 12,   /* HALANT */
+
+  USE_HN        = 13,   /* HALANT_NUM */
+  USE_ZWNJ      = 14,   /* Zero width non-joiner */
+  USE_ZWJ       = 15,   /* Zero width joiner */
+  USE_WJ        = 16,   /* Word joiner */
+  USE_Rsv       = 17,   /* Reserved characters */
+  USE_R         = 18,   /* REPHA */
+  USE_S         = 19,   /* SYM */
+//  USE_SM      = 20,   /* SYM_MOD */
+  USE_VS        = 21,   /* VARIATION_SELECTOR */
+//  USE_V       = 36,   /* VOWEL */
+//  USE_VM      = 40,   /* VOWEL_MOD */
+
+  USE_FAbv      = 24,   /* CONS_FINAL_ABOVE */
+  USE_FBlw      = 25,   /* CONS_FINAL_BELOW */
+  USE_FPst      = 26,   /* CONS_FINAL_POST */
+  USE_MAbv      = 27,   /* CONS_MED_ABOVE */
+  USE_MBlw      = 28,   /* CONS_MED_BELOW */
+  USE_MPst      = 29,   /* CONS_MED_POST */
+  USE_MPre      = 30,   /* CONS_MED_PRE */
+  USE_CMAbv     = 31,   /* CONS_MOD_ABOVE */
+  USE_CMBlw     = 32,   /* CONS_MOD_BELOW */
+  USE_VAbv      = 33,   /* VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST */
+  USE_VBlw      = 34,   /* VOWEL_BELOW / VOWEL_BELOW_POST */
+  USE_VPst      = 35,   /* VOWEL_POST   UIPC = Right */
+  USE_VPre      = 22,   /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */
+  USE_VMAbv     = 37,   /* VOWEL_MOD_ABOVE */
+  USE_VMBlw     = 38,   /* VOWEL_MOD_BELOW */
+  USE_VMPst     = 39,   /* VOWEL_MOD_POST */
+  USE_VMPre     = 23,   /* VOWEL_MOD_PRE */
+  USE_SMAbv     = 41,   /* SYM_MOD_ABOVE */
+  USE_SMBlw     = 42    /* SYM_MOD_BELOW */
+};
+
+HB_INTERNAL USE_TABLE_ELEMENT_TYPE
+hb_use_get_categories (hb_codepoint_t u);
+
+#endif /* HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-table.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,696 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ *   ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
+ *
+ * on files with these headers:
+ *
+ * # IndicSyllabicCategory-8.0.0.txt
+ * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI]
+ * # IndicPositionalCategory-8.0.0.txt
+ * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI]
+ * # Blocks-8.0.0.txt
+ * # Date: 2014-11-10, 23:04:00 GMT [KW]
+ * UnicodeData.txt does not have a header.
+ */
+
+#include "hb-ot-shape-complex-use-private.hh"
+
+#define B       USE_B   /* BASE */
+#define CGJ     USE_CGJ /* CGJ */
+#define FM      USE_FM  /* CONS_FINAL_MOD */
+#define GB      USE_GB  /* BASE_OTHER */
+#define H       USE_H   /* HALANT */
+#define HN      USE_HN  /* HALANT_NUM */
+#define IND     USE_IND /* BASE_IND */
+#define IV      USE_IV  /* BASE_VOWEL */
+#define N       USE_N   /* BASE_NUM */
+#define O       USE_O   /* OTHER */
+#define R       USE_R   /* REPHA */
+#define Rsv     USE_Rsv /* Reserved */
+#define S       USE_S   /* SYM */
+#define SUB     USE_SUB /* CONS_SUB */
+#define VS      USE_VS  /* VARIATION_SELECTOR */
+#define WJ      USE_WJ  /* Word_Joiner */
+#define ZWJ     USE_ZWJ /* ZWJ */
+#define ZWNJ    USE_ZWNJ        /* ZWNJ */
+#define CMBlw   USE_CMBlw
+#define CMAbv   USE_CMAbv
+#define FBlw    USE_FBlw
+#define FPst    USE_FPst
+#define FAbv    USE_FAbv
+#define MPre    USE_MPre
+#define MBlw    USE_MBlw
+#define MPst    USE_MPst
+#define MAbv    USE_MAbv
+#define SMBlw   USE_SMBlw
+#define SMAbv   USE_SMAbv
+#define VPre    USE_VPre
+#define VBlw    USE_VBlw
+#define VPst    USE_VPst
+#define VAbv    USE_VAbv
+#define VMPre   USE_VMPre
+#define VMBlw   USE_VMBlw
+#define VMPst   USE_VMPst
+#define VMAbv   USE_VMAbv
+
+static const USE_TABLE_ELEMENT_TYPE use_table[] = {
+
+
+#define use_offset_0x0028u 0
+
+
+  /* Basic Latin */
+                                                                         O,     O,     O,     O,     O,    GB,     O,     O,
+  /* 0030 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+#define use_offset_0x00a0u 24
+
+
+  /* Latin-1 Supplement */
+
+  /* 00A0 */    GB,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 00B0 */     O,     O,    FM,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 00C0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 00D0 */     O,     O,     O,     O,     O,     O,     O,    GB,
+
+#define use_offset_0x0900u 80
+
+
+  /* Devanagari */
+
+  /* 0900 */ VMAbv, VMAbv, VMAbv, VMPst,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,
+  /* 0910 */    IV,    IV,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0920 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0930 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VPst, CMBlw,     B,  VPst,  VPre,
+  /* 0940 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,  VPst,  VPst,  VPst,  VPst,     H,  VPre,  VPst,
+  /* 0950 */     O, VMAbv, VMBlw,     O,     O,  VAbv,  VBlw,  VBlw,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0960 */    IV,    IV,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0970 */     O,     O,    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,
+
+  /* Bengali */
+
+  /* 0980 */     O, VMAbv, VMPst, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     O,     O,    IV,
+  /* 0990 */    IV,     O,     O,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 09A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 09B0 */     B,     O,     B,     O,     O,     O,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPre,
+  /* 09C0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,   IND,     O,
+  /* 09D0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     B,     B,     O,     B,
+  /* 09E0 */    IV,    IV,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Gurmukhi */
+
+  /* 0A00 */     O, VMAbv, VMAbv, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,     O,     O,     O,     O,    IV,
+  /* 0A10 */    IV,     O,     O,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 0A30 */     B,     O,     B,     B,     O,     B,     B,     O,     B,     B,     O,     O, CMBlw,     O,  VPst,  VPre,
+  /* 0A40 */  VPst,  VBlw,  VBlw,     O,     O,     O,     O,  VAbv,  VAbv,     O,     O,  VAbv,  VAbv,     H,     O,     O,
+  /* 0A50 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     O,     B,     O,
+  /* 0A60 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0A70 */ VMAbv, CMAbv,    GB,    GB,     O,  MBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Gujarati */
+
+  /* 0A80 */     O, VMAbv, VMAbv, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     O,    IV,
+  /* 0A90 */    IV,    IV,     O,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0AA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 0AB0 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPre,
+  /* 0AC0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,     O,  VAbv,  VAbv,  VAbv,     O,  VPst,  VPst,     H,     O,     O,
+  /* 0AD0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 0AE0 */    IV,    IV,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0AF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O,     O,     O,     O,     O,     O,
+
+  /* Oriya */
+
+  /* 0B00 */     O, VMAbv, VMPst, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     O,     O,    IV,
+  /* 0B10 */    IV,     O,     O,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 0B30 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VAbv,
+  /* 0B40 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
+  /* 0B50 */     O,     O,     O,     O,     O,     O,  VAbv,  VAbv,     O,     O,     O,     O,     B,     B,     O,     B,
+  /* 0B60 */    IV,    IV,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0B70 */     O,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Tamil */
+
+  /* 0B80 */     O,     O, VMAbv,   IND,     O,    IV,    IV,    IV,    IV,    IV,    IV,     O,     O,     O,    IV,    IV,
+  /* 0B90 */    IV,     O,    IV,    IV,    IV,     B,     O,     O,     O,     B,     B,     O,     B,     O,     B,     B,
+  /* 0BA0 */     O,     O,     O,     B,     B,     O,     O,     O,     B,     B,     B,     O,     O,     O,     B,     B,
+  /* 0BB0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,  VPst,  VPst,
+  /* 0BC0 */  VAbv,  VPst,  VPst,     O,     O,     O,  VPre,  VPre,  VPre,     O,  VPre,  VPre,  VPre,     H,     O,     O,
+  /* 0BD0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 0BE0 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0BF0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Telugu */
+
+  /* 0C00 */ VMAbv, VMPst, VMPst, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     O,    IV,    IV,
+  /* 0C10 */    IV,     O,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0C20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 0C30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,  VAbv,  VAbv,
+  /* 0C40 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,  VAbv,  VAbv,  VAbv,     O,  VAbv,  VAbv,  VAbv,     H,     O,     O,
+  /* 0C50 */     O,     O,     O,     O,     O,  VAbv,  VBlw,     O,     B,     B,     B,     O,     O,     O,     O,     O,
+  /* 0C60 */    IV,    IV,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0C70 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Kannada */
+
+  /* 0C80 */     O, VMAbv, VMPst, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     O,    IV,    IV,
+  /* 0C90 */    IV,     O,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0CA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 0CB0 */     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VAbv,
+  /* 0CC0 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,  VAbv,  VAbv,  VAbv,     O,  VAbv,  VAbv,  VAbv,     H,     O,     O,
+  /* 0CD0 */     O,     O,     O,     O,     O,  VPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     B,     O,
+  /* 0CE0 */    IV,    IV,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0CF0 */     O,     R,     R,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Malayalam */
+
+  /* 0D00 */     O, VMAbv, VMPst, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     O,    IV,    IV,
+  /* 0D10 */    IV,     O,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0D20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0D30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     B,  VPst,  VPst,
+  /* 0D40 */  VPst,  VPst,  VPst,  VBlw,  VBlw,     O,  VPre,  VPre,  VPre,     O,  VPre,  VPre,  VPre,     H,     R,     O,
+  /* 0D50 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     O,    IV,
+  /* 0D60 */    IV,    IV,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0D70 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,   IND,   IND,   IND,   IND,   IND,   IND,
+
+  /* Sinhala */
+
+  /* 0D80 */     O,     O, VMPst, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,
+  /* 0D90 */    IV,    IV,    IV,    IV,    IV,    IV,    IV,     O,     O,     O,     B,     B,     B,     B,     B,     B,
+  /* 0DA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0DB0 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     O,     O,
+  /* 0DC0 */     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     H,     O,     O,     O,     O,  VPst,
+  /* 0DD0 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,     O,  VBlw,     O,  VPst,  VPre,  VPre,  VPre,  VPre,  VPre,  VPre,  VPst,
+  /* 0DE0 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 0DF0 */     O,     O,  VPst,  VPst,     O,     O,     O,     O,
+
+#define use_offset_0x1000u 1352
+
+
+  /* Myanmar */
+
+  /* 1000 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1010 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1020 */     B,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,  VPst,  VPst,  VAbv,  VAbv,  VBlw,
+  /* 1030 */  VBlw,  VPre,  VAbv,  VAbv,  VAbv,  VAbv, VMAbv, VMBlw, VMPst,     H,  VAbv,  MPst,  MPre,  MBlw,  MBlw,     B,
+  /* 1040 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,    GB,     O,
+  /* 1050 */     B,     B,    IV,    IV,    IV,    IV,  VPst,  VPst,  VBlw,  VBlw,     B,     B,     B,     B,  MBlw,  MBlw,
+  /* 1060 */  MBlw,     B,  VPst, VMPst, VMPst,     B,     B,  VPst,  VPst, VMPst, VMPst, VMPst, VMPst, VMPst,     B,     B,
+  /* 1070 */     B,  VAbv,  VAbv,  VAbv,  VAbv,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1080 */     B,     B,  MBlw,  VPst,  VPre,  VAbv,  VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw,     B, VMPst,
+  /* 1090 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMPst, VMPst,  VPst,  VAbv,     O,     O,
+
+#define use_offset_0x1700u 1512
+
+
+  /* Tagalog */
+
+  /* 1700 */    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
+  /* 1710 */     B,     B,  VAbv,  VBlw,  VBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Hanunoo */
+
+  /* 1720 */    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1730 */     B,     B,  VAbv,  VBlw,  VBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Buhid */
+
+  /* 1740 */    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1750 */     B,     B,  VAbv,  VBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Tagbanwa */
+
+  /* 1760 */    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,
+  /* 1770 */     B,     O,  VAbv,  VBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Khmer */
+
+  /* 1780 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1790 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 17A0 */     B,     B,     B,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,
+  /* 17B0 */    IV,    IV,    IV,    IV,     O,     O,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VPre,  VPre,
+  /* 17C0 */  VPre,  VPre,  VPre,  VPre,  VPre,  VPre, VMAbv, VMPst,  VPst, VMAbv, VMAbv,    FM,  FAbv, CMAbv,    FM,    FM,
+  /* 17D0 */    FM,  VAbv,     H,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     B,  VAbv,     O,     O,
+  /* 17E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+#define use_offset_0x1900u 1752
+
+
+  /* Limbu */
+
+  /* 1900 */    GB,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1910 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,
+  /* 1920 */  VAbv,  VAbv,  VBlw,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,   SUB,   SUB,   SUB,     O,     O,     O,     O,
+  /* 1930 */  FPst,  FPst, VMBlw,  FPst,  FPst,  FPst,  FPst,  FPst,  FPst,  FBlw,  VAbv,    FM,     O,     O,     O,     O,
+  /* 1940 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+
+  /* Tai Le */
+
+  /* 1950 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1960 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,
+  /* 1970 */     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* New Tai Lue */
+
+  /* 1980 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1990 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 19A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
+  /* 19B0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 19C0 */     B,     B,     B,     B,     B,     B,     B,     B, VMPst, VMPst,     O,     O,     O,     O,     O,     O,
+  /* 19D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 19E0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 19F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Buginese */
+
+  /* 1A00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1A10 */     B,     B,     B,     B,     B,     B,     B,  VAbv,  VBlw,  VPre,  VPst,  VAbv,     O,     O,     O,     O,
+
+  /* Tai Tham */
+
+  /* 1A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1A30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    IV,    IV,    IV,
+  /* 1A50 */    IV,    IV,    IV,     B,     B,  MPre,  MBlw,  FPst,  FAbv,  FAbv,  FAbv,  FBlw,  FBlw,  FBlw,  FBlw,     O,
+  /* 1A60 */     H,  VPst,  VAbv,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VAbv,  VBlw,  VPst,  VPre,  VPre,
+  /* 1A70 */  VPre,  VPre,  VPre,  VAbv,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,    FM,    FM,    FM,     O,     O,    FM,
+  /* 1A80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 1A90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+#define use_offset_0x1b00u 2168
+
+
+  /* Balinese */
+
+  /* 1B00 */ VMAbv, VMAbv, VMAbv,  FAbv, VMPst,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,
+  /* 1B10 */    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1B30 */     B,     B,     B,     B, CMAbv,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPre,  VPre,
+  /* 1B40 */  VPre,  VPre,  VAbv,  VAbv,     H,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
+  /* 1B50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 1B60 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
+  /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Sundanese */
+
+  /* 1B80 */ VMAbv,  FAbv, VMPst,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,
+  /* 1B90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1BA0 */     B,   SUB,   SUB,   SUB,  VAbv,  VBlw,  VPre,  VPst,  VAbv,  VAbv,  VPst,     H,   SUB,   SUB,     B,     B,
+  /* 1BB0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+
+  /* Batak */
+
+  /* 1BC0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1BD0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1BE0 */     B,     B,     B,     B,    IV,    IV, CMAbv,  VPst,  VAbv,  VAbv,  VPst,  VPst,  VPst,  VAbv,  VPst,  VAbv,
+  /* 1BF0 */  FAbv,  FAbv,  VPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Lepcha */
+
+  /* 1C00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1C10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 1C20 */     B,     B,     B,     B,   SUB,   SUB,  VPst,  VPre,  VPre,  VPre,  VPst,  VPst,  VBlw,  FAbv,  FAbv,  FAbv,
+  /* 1C30 */  FAbv,  FAbv,  FAbv,  FAbv, VMPre, VMPre,    FM, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 1C40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,     B,     B,
+
+#define use_offset_0x1cd0u 2504
+
+
+  /* Vedic Extensions */
+
+  /* 1CD0 */ VMAbv, VMAbv, VMAbv,     O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw,
+  /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,     O,     O,     O,     O, VMBlw,     O,     O,
+  /* 1CF0 */     O,     O, VMPst, VMPst, VMAbv,     O,     O,     O, VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,
+
+#define use_offset_0x2008u 2552
+
+
+  /* General Punctuation */
+                                                                         O,     O,     O,     O,  ZWNJ,   ZWJ,     O,     O,
+  /* 2010 */    GB,    GB,    GB,    GB,    GB,     O,     O,     O,
+
+#define use_offset_0x2060u 2568
+
+  /* 2060 */    WJ,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Superscripts and Subscripts */
+
+  /* 2070 */     O,     O,     O,     O,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 2080 */     O,     O,    FM,    FM,    FM,     O,     O,     O,
+
+#define use_offset_0xa800u 2608
+
+
+  /* Syloti Nagri */
+
+  /* A800 */    IV,    IV,     O,    IV,    IV,    IV,  VAbv,     B,     B,     B,     B, VMAbv,     B,     B,     B,     B,
+  /* A810 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A820 */     B,     B,     B,  VPst,  VPst,  VBlw,  VAbv,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A830 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Phags-pa */
+
+  /* A840 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A850 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A860 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A870 */     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Saurashtra */
+
+  /* A880 */ VMPst, VMPst,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,
+  /* A890 */    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A8A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A8B0 */     B,     B,     B,     B,  FPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,  VPst,
+  /* A8C0 */  VPst,  VPst,  VPst,  VPst,     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A8D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+  /* Devanagari Extended */
+
+  /* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
+  /* A8F0 */ VMAbv, VMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Kayah Li */
+
+  /* A900 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A910 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A920 */     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv, VMBlw, VMBlw, VMBlw,     O,     O,
+
+  /* Rejang */
+
+  /* A930 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A940 */     B,     B,     B,     B,     B,     B,     B,  VBlw,  VBlw,  VBlw,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  FAbv,
+  /* A950 */  FAbv,  FAbv,  FPst,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A960 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A970 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Javanese */
+
+  /* A980 */ VMAbv, VMAbv,  FAbv, VMPst,    IV,    IV,    IV,    IV,    IV,     B,     B,     B,    IV,    IV,    IV,     B,
+  /* A990 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A9A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A9B0 */     B,     B,     B, CMAbv,  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VPre,  VAbv,   SUB,  MPst,  MPst,
+  /* A9C0 */     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* A9D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+  /* Myanmar Extended-B */
+
+  /* A9E0 */     B,     B,     B,     B,     B,  VAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* A9F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,
+
+  /* Cham */
+
+  /* AA00 */    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* AA10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* AA20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VAbv,  VPre,
+  /* AA30 */  VPre,  VAbv,  VBlw,  MPst,  MPre,  MBlw,  MBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* AA40 */     B,     B,     B,  FAbv,     B,     B,     B,     B,     B,     B,     B,     B,  FAbv,  FPst,     O,     O,
+  /* AA50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+  /* Myanmar Extended-A */
+
+  /* AA60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* AA70 */     O,     B,     B,     B,     O,     O,     O,     O,     O,     O,     B, VMPst, VMAbv, VMPst,     B,     B,
+
+  /* Tai Viet */
+
+  /* AA80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* AA90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* AAA0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* AAB0 */  VAbv,     B,  VAbv,  VAbv,  VBlw,     B,     B,  VAbv,  VAbv,     B,     B,     B,     B,     B,  VAbv, VMAbv,
+  /* AAC0 */     B, VMAbv,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* AAD0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Meetei Mayek Extensions */
+
+  /* AAE0 */    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPre,  VBlw,  VAbv,  VPre,  VPst,
+  /* AAF0 */     O,     O,     O,     O,     O, VMPst,     H,     O,
+
+#define use_offset_0xabc0u 3368
+
+
+  /* Meetei Mayek */
+
+  /* ABC0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,    IV,    IV,
+  /* ABD0 */     B,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* ABE0 */     B,     B,     B,  VPst,  VPst,  VAbv,  VPst,  VPst,  VBlw,  VPst,  VPst,     O, VMPst,  VBlw,     O,     O,
+  /* ABF0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+#define use_offset_0xfe00u 3432
+
+
+  /* Variation Selectors */
+
+  /* FE00 */    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,    VS,
+
+#define use_offset_0x10a00u 3448
+
+
+  /* Kharoshthi */
+
+  /* 10A00 */     B,  VBlw,  VBlw,  VBlw,     O,  VAbv,  VBlw,     O,     O,     O,     O,     O,  VBlw,  VBlw, VMBlw, VMAbv,
+  /* 10A10 */     B,     B,     B,     B,     O,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,
+  /* 10A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 10A30 */     B,     B,     B,     B,     O,     O,     O,     O, CMAbv, CMBlw, CMBlw,     O,     O,     O,     O,     H,
+  /* 10A40 */     B,     B,     B,     B,     B,     B,     B,     B,
+
+#define use_offset_0x11000u 3520
+
+
+  /* Brahmi */
+
+  /* 11000 */ VMPst, VMAbv, VMPst,     R,     R,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,
+  /* 11010 */    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11020 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11030 */     B,     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,
+  /* 11040 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,     H,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11050 */     O,     O,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,     N,
+  /* 11060 */     N,     N,     N,     N,     N,     N,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11070 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Kaithi */
+
+  /* 11080 */ VMAbv, VMAbv, VMPst,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,     B,
+  /* 11090 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 110A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 110B0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VAbv,  VAbv,  VPst,  VPst,     H, CMBlw,     O,     O,     O,     O,     O,
+
+#define use_offset_0x11100u 3712
+
+
+  /* Chakma */
+
+  /* 11100 */ VMAbv, VMAbv, VMAbv,    IV,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11110 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11120 */     B,     B,     B,     B,     B,     B,     B,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VAbv,  VAbv,
+  /* 11130 */  VAbv,  VBlw,  VBlw,     H,  VAbv,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11140 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Mahajani */
+
+  /* 11150 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11160 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11170 */     B,     B,     B, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Sharada */
+
+  /* 11180 */ VMAbv, VMAbv, VMPst,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,
+  /* 11190 */    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 111A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 111B0 */     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,
+  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,     O,     O, CMBlw,  VAbv,  VBlw,     O,     O,     O,
+  /* 111D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+  /* Sinhala Archaic Numbers */
+
+  /* 111E0 */     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 111F0 */     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Khojki */
+
+  /* 11200 */    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11210 */     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11220 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,  VPst,  VPst,  VBlw,
+  /* 11230 */  VAbv,  VAbv,  VAbv,  VAbv, VMAbv,     H, CMAbv, CMAbv,
+
+#define use_offset_0x11280u 4024
+
+
+  /* Multani */
+
+  /* 11280 */    IV,    IV,    IV,    IV,     B,     B,     B,     O,     B,     O,     B,     B,     B,     B,     O,     B,
+  /* 11290 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,
+  /* 112A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Khudawadi */
+
+  /* 112B0 */    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,
+  /* 112C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 112D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv,
+  /* 112E0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv, CMBlw,  VBlw,     O,     O,     O,     O,     O,
+  /* 112F0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+  /* Grantha */
+
+  /* 11300 */ VMAbv, VMAbv, VMPst, VMPst,     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     O,     O,    IV,
+  /* 11310 */    IV,     O,     O,    IV,    IV,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11320 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,
+  /* 11330 */     B,     O,     B,     B,     O,     B,     B,     B,     B,     B,     O,     O, CMBlw,     B,  VPst,  VPst,
+  /* 11340 */  VAbv,  VPst,  VPst,  VPst,  VPst,     O,     O,  VPre,  VPre,     O,     O,  VPre,  VPre,     H,     O,     O,
+  /* 11350 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11360 */    IV,    IV,  VPst,  VPst,     O,     O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
+  /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,     O,     O,     O,
+
+#define use_offset_0x11480u 4272
+
+
+  /* Tirhuta */
+
+  /* 11480 */     O,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     B,
+  /* 11490 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 114A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 114B0 */  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VPre,  VAbv,  VPre,  VPre,  VPst,  VPre, VMAbv,
+  /* 114C0 */ VMAbv, VMPst,     H, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 114D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+
+#define use_offset_0x11580u 4368
+
+
+  /* Siddham */
+
+  /* 11580 */    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,
+  /* 11590 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 115A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,  VPst,
+  /* 115B0 */  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,  VPre,  VPre, VMAbv, VMAbv, VMPst,     H,
+  /* 115C0 */ CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 115D0 */     O,     O,     O,     O,     O,     O,     O,     O,    IV,    IV,    IV,    IV,  VBlw,  VBlw,     O,     O,
+  /* 115E0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 115F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Modi */
+
+  /* 11600 */    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,
+  /* 11610 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11620 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11630 */  VPst,  VPst,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPst,  VPst, VMAbv, VMPst,     H,
+  /* 11640 */  VAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11650 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 11660 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 11670 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Takri */
+
+  /* 11680 */    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,    IV,     B,     B,     B,     B,     B,     B,
+  /* 11690 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 116A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B, VMAbv, VMPst,  VAbv,  VPre,  VPst,
+  /* 116B0 */  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,     H, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 116C0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
+  /* 116D0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 116E0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 116F0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+
+  /* Ahom */
+
+  /* 11700 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
+  /* 11710 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,  MBlw,  MPre,  MAbv,
+  /* 11720 */  VPst,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VPre,  VAbv,  VBlw,  VAbv,  VAbv,  VAbv,     O,     O,     O,     O,
+  /* 11730 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
+
+}; /* Table items: 4816; occupancy: 72% */
+
+USE_TABLE_ELEMENT_TYPE
+hb_use_get_categories (hb_codepoint_t u)
+{
+  switch (u >> 12)
+  {
+    case 0x0u:
+      if (hb_in_range (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
+      if (hb_in_range (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
+      if (hb_in_range (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u];
+      if (unlikely (u == 0x034Fu)) return CGJ;
+      break;
+
+    case 0x1u:
+      if (hb_in_range (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u];
+      if (hb_in_range (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u];
+      if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u];
+      if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u];
+      if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u];
+      break;
+
+    case 0x2u:
+      if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u];
+      if (hb_in_range (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u];
+      if (unlikely (u == 0x25CCu)) return GB;
+      break;
+
+    case 0xAu:
+      if (hb_in_range (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u];
+      if (hb_in_range (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u];
+      break;
+
+    case 0xFu:
+      if (hb_in_range (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
+      break;
+
+    case 0x10u:
+      if (hb_in_range (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
+      break;
+
+    case 0x11u:
+      if (hb_in_range (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u];
+      if (hb_in_range (u, 0x11100u, 0x11237u)) return use_table[u - 0x11100u + use_offset_0x11100u];
+      if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
+      if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u];
+      if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u];
+      if (unlikely (u == 0x1107Fu)) return HN;
+      break;
+
+    default:
+      break;
+  }
+  return USE_O;
+}
+
+#undef B
+#undef CGJ
+#undef FM
+#undef GB
+#undef H
+#undef HN
+#undef IND
+#undef IV
+#undef N
+#undef O
+#undef R
+#undef Rsv
+#undef S
+#undef SUB
+#undef VS
+#undef WJ
+#undef ZWJ
+#undef ZWNJ
+#undef CMBlw
+#undef CMAbv
+#undef FBlw
+#undef FPst
+#undef FAbv
+#undef MPre
+#undef MBlw
+#undef MPst
+#undef MAbv
+#undef SMBlw
+#undef SMAbv
+#undef VPre
+#undef VBlw
+#undef VPst
+#undef VAbv
+#undef VMPre
+#undef VMBlw
+#undef VMPst
+#undef VMAbv
+
+/* == End of generated table == */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,585 @@
+/*
+ * Copyright © 2015  Mozilla Foundation.
+ * Copyright © 2015  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.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-use-private.hh"
+#include "hb-ot-shape-complex-arabic-private.hh"
+
+/* buffer var allocations */
+#define use_category() complex_var_u8_0()
+
+
+/*
+ * Universal Shaping Engine.
+ * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm
+ */
+
+static const hb_tag_t
+basic_features[] =
+{
+  /*
+   * Basic features.
+   * These features are applied all at once, before reordering.
+   */
+  HB_TAG('r','k','r','f'),
+  HB_TAG('a','b','v','f'),
+  HB_TAG('b','l','w','f'),
+  HB_TAG('h','a','l','f'),
+  HB_TAG('p','s','t','f'),
+  HB_TAG('v','a','t','u'),
+  HB_TAG('c','j','c','t'),
+};
+static const hb_tag_t
+arabic_features[] =
+{
+  HB_TAG('i','s','o','l'),
+  HB_TAG('i','n','i','t'),
+  HB_TAG('m','e','d','i'),
+  HB_TAG('f','i','n','a'),
+  /* The spec doesn't specify these but we apply anyway, since our Arabic shaper
+   * does.  These are only used in Syriac spec. */
+  HB_TAG('m','e','d','2'),
+  HB_TAG('f','i','n','2'),
+  HB_TAG('f','i','n','3'),
+};
+/* Same order as arabic_features.  Don't need Syriac stuff.*/
+enum joining_form_t {
+  ISOL,
+  INIT,
+  MEDI,
+  FINA,
+  _NONE
+};
+static const hb_tag_t
+other_features[] =
+{
+  /*
+   * Other features.
+   * These features are applied all at once, after reordering.
+   */
+  HB_TAG('a','b','v','s'),
+  HB_TAG('b','l','w','s'),
+  HB_TAG('h','a','l','n'),
+  HB_TAG('p','r','e','s'),
+  HB_TAG('p','s','t','s'),
+  /* Positioning features, though we don't care about the types. */
+  HB_TAG('d','i','s','t'),
+  HB_TAG('a','b','v','m'),
+  HB_TAG('b','l','w','m'),
+};
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+                 hb_font_t *font,
+                 hb_buffer_t *buffer);
+static void
+clear_substitution_flags (const hb_ot_shape_plan_t *plan,
+                          hb_font_t *font,
+                          hb_buffer_t *buffer);
+static void
+record_rphf (const hb_ot_shape_plan_t *plan,
+             hb_font_t *font,
+             hb_buffer_t *buffer);
+static void
+record_pref (const hb_ot_shape_plan_t *plan,
+             hb_font_t *font,
+             hb_buffer_t *buffer);
+static void
+reorder (const hb_ot_shape_plan_t *plan,
+         hb_font_t *font,
+         hb_buffer_t *buffer);
+
+static void
+collect_features_use (hb_ot_shape_planner_t *plan)
+{
+  hb_ot_map_builder_t *map = &plan->map;
+
+  /* Do this before any lookups have been applied. */
+  map->add_gsub_pause (setup_syllables);
+
+  /* "Default glyph pre-processing group" */
+  map->add_global_bool_feature (HB_TAG('l','o','c','l'));
+  map->add_global_bool_feature (HB_TAG('c','c','m','p'));
+  map->add_global_bool_feature (HB_TAG('n','u','k','t'));
+  map->add_global_bool_feature (HB_TAG('a','k','h','n'));
+
+  /* "Reordering group" */
+  map->add_gsub_pause (clear_substitution_flags);
+  map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ);
+  map->add_gsub_pause (record_rphf);
+  map->add_gsub_pause (clear_substitution_flags);
+  map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ);
+  map->add_gsub_pause (record_pref);
+
+  /* "Orthographic unit shaping group" */
+  for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
+    map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+
+  map->add_gsub_pause (reorder);
+
+  /* "Topographical features" */
+  for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++)
+    map->add_feature (arabic_features[i], 1, F_NONE);
+  map->add_gsub_pause (NULL);
+
+  /* "Standard typographic presentation" and "Positional feature application" */
+  for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
+    map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
+}
+
+struct use_shape_plan_t
+{
+  ASSERT_POD ();
+
+  hb_mask_t rphf_mask;
+
+  arabic_shape_plan_t *arabic_plan;
+};
+
+static bool
+has_arabic_joining (hb_script_t script)
+{
+  /* List of scripts that have data in arabic-table. */
+  switch ((int) script)
+  {
+    /* Unicode-1.1 additions */
+    case HB_SCRIPT_ARABIC:
+
+    /* Unicode-3.0 additions */
+    case HB_SCRIPT_MONGOLIAN:
+    case HB_SCRIPT_SYRIAC:
+
+    /* Unicode-5.0 additions */
+    case HB_SCRIPT_NKO:
+    case HB_SCRIPT_PHAGS_PA:
+
+    /* Unicode-6.0 additions */
+    case HB_SCRIPT_MANDAIC:
+
+    /* Unicode-7.0 additions */
+    case HB_SCRIPT_MANICHAEAN:
+    case HB_SCRIPT_PSALTER_PAHLAVI:
+
+      return true;
+
+    default:
+      return false;
+  }
+}
+
+static void *
+data_create_use (const hb_ot_shape_plan_t *plan)
+{
+  use_shape_plan_t *use_plan = (use_shape_plan_t *) calloc (1, sizeof (use_shape_plan_t));
+  if (unlikely (!use_plan))
+    return NULL;
+
+  use_plan->rphf_mask = plan->map.get_1_mask (HB_TAG('r','p','h','f'));
+
+  if (has_arabic_joining (plan->props.script))
+  {
+    use_plan->arabic_plan = (arabic_shape_plan_t *) data_create_arabic (plan);
+    if (unlikely (!use_plan->arabic_plan))
+    {
+      free (use_plan);
+      return NULL;
+    }
+  }
+
+  return use_plan;
+}
+
+static void
+data_destroy_use (void *data)
+{
+  use_shape_plan_t *use_plan = (use_shape_plan_t *) data;
+
+  if (use_plan->arabic_plan)
+    data_destroy_arabic (use_plan->arabic_plan);
+
+  free (data);
+}
+
+enum syllable_type_t {
+  independent_cluster,
+  virama_terminated_cluster,
+  consonant_cluster,
+  vowel_cluster,
+  number_joiner_terminated_cluster,
+  numeral_cluster,
+  symbol_cluster,
+  broken_cluster,
+};
+
+#include "hb-ot-shape-complex-use-machine.hh"
+
+
+static void
+setup_masks_use (const hb_ot_shape_plan_t *plan,
+                 hb_buffer_t              *buffer,
+                 hb_font_t                *font HB_UNUSED)
+{
+  const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
+
+  /* Do this before allocating use_category(). */
+  if (use_plan->arabic_plan)
+  {
+    setup_masks_arabic_plan (use_plan->arabic_plan, buffer, plan->props.script);
+  }
+
+  HB_BUFFER_ALLOCATE_VAR (buffer, use_category);
+
+  /* We cannot setup masks here.  We save information about characters
+   * and setup masks later on in a pause-callback. */
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    info[i].use_category() = hb_use_get_categories (info[i].codepoint);
+}
+
+static void
+setup_rphf_mask (const hb_ot_shape_plan_t *plan,
+                 hb_buffer_t *buffer)
+{
+  const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
+
+  hb_mask_t mask = use_plan->rphf_mask;
+  if (!mask) return;
+
+  hb_glyph_info_t *info = buffer->info;
+
+  foreach_syllable (buffer, start, end)
+  {
+    unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start);
+    for (unsigned int i = start; i < start + limit; i++)
+      info[i].mask |= mask;
+  }
+}
+
+static void
+setup_topographical_masks (const hb_ot_shape_plan_t *plan,
+                           hb_buffer_t *buffer)
+{
+
+  ASSERT_STATIC (INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4);
+  hb_mask_t masks[4], all_masks = 0;
+  for (unsigned int i = 0; i < 4; i++)
+  {
+    masks[i] = plan->map.get_1_mask (arabic_features[i]);
+    if (masks[i] == plan->map.get_global_mask ())
+      masks[i] = 0;
+    all_masks |= masks[i];
+  }
+  if (!all_masks)
+    return;
+  hb_mask_t other_masks = ~all_masks;
+
+  unsigned int last_start = 0;
+  joining_form_t last_form = _NONE;
+  hb_glyph_info_t *info = buffer->info;
+  foreach_syllable (buffer, start, end)
+  {
+    syllable_type_t syllable_type = (syllable_type_t) (info[start].syllable() & 0x0F);
+    switch (syllable_type)
+    {
+      case independent_cluster:
+      case symbol_cluster:
+        /* These don't join.  Nothing to do. */
+        last_form = _NONE;
+        break;
+
+      case virama_terminated_cluster:
+      case consonant_cluster:
+      case vowel_cluster:
+      case number_joiner_terminated_cluster:
+      case numeral_cluster:
+      case broken_cluster:
+
+        bool join = last_form == FINA || last_form == ISOL;
+
+        if (join)
+        {
+          /* Fixup previous syllable's form. */
+          last_form = last_form == FINA ? MEDI : INIT;
+          for (unsigned int i = last_start; i < start; i++)
+            info[i].mask = (info[i].mask & other_masks) | masks[last_form];
+        }
+
+        /* Form for this syllable. */
+        last_form = join ? FINA : ISOL;
+        for (unsigned int i = start; i < end; i++)
+          info[i].mask = (info[i].mask & other_masks) | masks[last_form];
+
+        break;
+    }
+
+    last_start = start;
+  }
+}
+
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+                 hb_font_t *font HB_UNUSED,
+                 hb_buffer_t *buffer)
+{
+  find_syllables (buffer);
+  setup_rphf_mask (plan, buffer);
+  setup_topographical_masks (plan, buffer);
+}
+
+static void
+clear_substitution_flags (const hb_ot_shape_plan_t *plan,
+                          hb_font_t *font HB_UNUSED,
+                          hb_buffer_t *buffer)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (&info[i]);
+}
+
+static void
+record_rphf (const hb_ot_shape_plan_t *plan,
+             hb_font_t *font,
+             hb_buffer_t *buffer)
+{
+  const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
+
+  hb_mask_t mask = use_plan->rphf_mask;
+  if (!mask) return;
+  hb_glyph_info_t *info = buffer->info;
+
+  foreach_syllable (buffer, start, end)
+  {
+    /* Mark a substituted repha as USE_R. */
+    for (unsigned int i = start; i < end && (info[i].mask & mask); i++)
+      if (_hb_glyph_info_substituted (&info[i]))
+      {
+        info[i].use_category() = USE_R;
+        break;
+      }
+  }
+}
+
+static void
+record_pref (const hb_ot_shape_plan_t *plan,
+             hb_font_t *font,
+             hb_buffer_t *buffer)
+{
+  hb_glyph_info_t *info = buffer->info;
+
+  foreach_syllable (buffer, start, end)
+  {
+    /* Mark a substituted pref as VPre, as they behave the same way. */
+    for (unsigned int i = start; i < end; i++)
+      if (_hb_glyph_info_substituted (&info[i]))
+      {
+        info[i].use_category() = USE_VPre;
+        break;
+      }
+  }
+}
+
+static void
+reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
+{
+  syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+  /* Only a few syllable types need reordering. */
+  if (unlikely (!(FLAG_SAFE (syllable_type) &
+                  (FLAG (virama_terminated_cluster) |
+                   FLAG (consonant_cluster) |
+                   FLAG (vowel_cluster) |
+                   FLAG (broken_cluster) |
+                   0))))
+    return;
+
+  hb_glyph_info_t *info = buffer->info;
+
+#define HALANT_FLAGS FLAG(USE_H)
+#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV))
+
+  /* Move things forward. */
+  if (info[start].use_category() == USE_R && end - start > 1)
+  {
+    /* Got a repha.  Reorder it to after first base, before first halant. */
+    for (unsigned int i = start + 1; i < end; i++)
+      if (FLAG_UNSAFE (info[i].use_category()) & (HALANT_FLAGS | BASE_FLAGS))
+      {
+        /* If we hit a halant, move before it; otherwise it's a base: move to it's
+         * place, and shift things in between backward. */
+
+        if (info[i].use_category() == USE_H)
+          i--;
+
+        buffer->merge_clusters (start, i + 1);
+        hb_glyph_info_t t = info[start];
+        memmove (&info[start], &info[start + 1], (i - start) * sizeof (info[0]));
+        info[i] = t;
+
+        break;
+      }
+  }
+
+  /* Move things back. */
+  unsigned int j = end;
+  for (unsigned int i = start; i < end; i++)
+  {
+    uint32_t flag = FLAG_UNSAFE (info[i].use_category());
+    if (flag & (HALANT_FLAGS | BASE_FLAGS))
+    {
+      /* If we hit a halant, move before it; otherwise it's a base: move to it's
+       * place, and shift things in between backward. */
+      if (info[i].use_category() == USE_H)
+        j = i + 1;
+      else
+        j = i;
+    }
+    else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) &&
+             /* Only move the first component of a MultipleSubst. */
+             0 == _hb_glyph_info_get_lig_comp (&info[i]) &&
+             j < i)
+    {
+      buffer->merge_clusters (j, i + 1);
+      hb_glyph_info_t t = info[i];
+      memmove (&info[j + 1], &info[j], (i - j) * sizeof (info[0]));
+      info[j] = t;
+    }
+  }
+}
+
+static inline void
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                       hb_font_t *font,
+                       hb_buffer_t *buffer)
+{
+  /* Note: This loop is extra overhead, but should not be measurable. */
+  bool has_broken_syllables = false;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    if ((info[i].syllable() & 0x0F) == broken_cluster)
+    {
+      has_broken_syllables = true;
+      break;
+    }
+  if (likely (!has_broken_syllables))
+    return;
+
+
+  hb_codepoint_t dottedcircle_glyph;
+  if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph))
+    return;
+
+  hb_glyph_info_t dottedcircle = {0};
+  if (!font->get_glyph (0x25CCu, 0, &dottedcircle.codepoint))
+    return;
+  dottedcircle.use_category() = hb_use_get_categories (0x25CC);
+
+  buffer->clear_output ();
+
+  buffer->idx = 0;
+
+  unsigned int last_syllable = 0;
+  while (buffer->idx < buffer->len)
+  {
+    unsigned int syllable = buffer->cur().syllable();
+    syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
+    if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+    {
+      last_syllable = syllable;
+
+      hb_glyph_info_t info = dottedcircle;
+      info.cluster = buffer->cur().cluster;
+      info.mask = buffer->cur().mask;
+      info.syllable() = buffer->cur().syllable();
+      /* TODO Set glyph_props? */
+
+      /* Insert dottedcircle after possible Repha. */
+      while (buffer->idx < buffer->len &&
+             last_syllable == buffer->cur().syllable() &&
+             buffer->cur().use_category() == USE_R)
+        buffer->next_glyph ();
+
+      buffer->output_info (info);
+    }
+    else
+      buffer->next_glyph ();
+  }
+
+  buffer->swap_buffers ();
+}
+
+static void
+reorder (const hb_ot_shape_plan_t *plan,
+         hb_font_t *font,
+         hb_buffer_t *buffer)
+{
+  insert_dotted_circles (plan, font, buffer);
+
+  hb_glyph_info_t *info = buffer->info;
+
+  foreach_syllable (buffer, start, end)
+    reorder_syllable (buffer, start, end);
+
+  /* Zero syllables now... */
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    info[i].syllable() = 0;
+
+  HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
+}
+
+static bool
+compose_use (const hb_ot_shape_normalize_context_t *c,
+             hb_codepoint_t  a,
+             hb_codepoint_t  b,
+             hb_codepoint_t *ab)
+{
+  /* Avoid recomposing split matras. */
+  if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a)))
+    return false;
+
+  return c->unicode->compose (a, b, ab);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use =
+{
+  "use",
+  collect_features_use,
+  NULL, /* override_features */
+  data_create_use,
+  data_destroy_use,
+  NULL, /* preprocess_text */
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
+  NULL, /* decompose */
+  compose_use,
+  setup_masks_use,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+  false, /* fallback_position */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-fallback-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2012  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_SHAPE_FALLBACK_PRIVATE_HH
+#define HB_OT_SHAPE_FALLBACK_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-shape-private.hh"
+
+
+HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
+                                                 hb_font_t *font,
+                                                 hb_buffer_t  *buffer);
+
+HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
+                                                                    hb_font_t *font,
+                                                                    hb_buffer_t  *buffer);
+
+
+HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
+                                             hb_font_t *font,
+                                             hb_buffer_t  *buffer);
+
+
+#endif /* HB_OT_SHAPE_FALLBACK_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-fallback.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,484 @@
+/*
+ * Copyright © 2011,2012  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
+ */
+
+#include "hb-ot-shape-fallback-private.hh"
+#include "hb-ot-layout-gsubgpos-private.hh"
+
+static unsigned int
+recategorize_combining_class (hb_codepoint_t u,
+                              unsigned int klass)
+{
+  if (klass >= 200)
+    return klass;
+
+  /* Thai / Lao need some per-character work. */
+  if ((u & ~0xFF) == 0x0E00u)
+  {
+    if (unlikely (klass == 0))
+    {
+      switch (u)
+      {
+        case 0x0E31u:
+        case 0x0E34u:
+        case 0x0E35u:
+        case 0x0E36u:
+        case 0x0E37u:
+        case 0x0E47u:
+        case 0x0E4Cu:
+        case 0x0E4Du:
+        case 0x0E4Eu:
+          klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
+          break;
+
+        case 0x0EB1u:
+        case 0x0EB4u:
+        case 0x0EB5u:
+        case 0x0EB6u:
+        case 0x0EB7u:
+        case 0x0EBBu:
+        case 0x0ECCu:
+        case 0x0ECDu:
+          klass = HB_UNICODE_COMBINING_CLASS_ABOVE;
+          break;
+
+        case 0x0EBCu:
+          klass = HB_UNICODE_COMBINING_CLASS_BELOW;
+          break;
+      }
+    } else {
+      /* Thai virama is below-right */
+      if (u == 0x0E3Au)
+        klass = HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
+    }
+  }
+
+  switch (klass)
+  {
+
+    /* Hebrew */
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC10: /* sheva */
+    case HB_MODIFIED_COMBINING_CLASS_CCC11: /* hataf segol */
+    case HB_MODIFIED_COMBINING_CLASS_CCC12: /* hataf patah */
+    case HB_MODIFIED_COMBINING_CLASS_CCC13: /* hataf qamats */
+    case HB_MODIFIED_COMBINING_CLASS_CCC14: /* hiriq */
+    case HB_MODIFIED_COMBINING_CLASS_CCC15: /* tsere */
+    case HB_MODIFIED_COMBINING_CLASS_CCC16: /* segol */
+    case HB_MODIFIED_COMBINING_CLASS_CCC17: /* patah */
+    case HB_MODIFIED_COMBINING_CLASS_CCC18: /* qamats */
+    case HB_MODIFIED_COMBINING_CLASS_CCC20: /* qubuts */
+    case HB_MODIFIED_COMBINING_CLASS_CCC22: /* meteg */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC23: /* rafe */
+      return HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC24: /* shin dot */
+      return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC25: /* sin dot */
+    case HB_MODIFIED_COMBINING_CLASS_CCC19: /* holam */
+      return HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC26: /* point varika */
+      return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC21: /* dagesh */
+      break;
+
+
+    /* Arabic and Syriac */
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC27: /* fathatan */
+    case HB_MODIFIED_COMBINING_CLASS_CCC28: /* dammatan */
+    case HB_MODIFIED_COMBINING_CLASS_CCC30: /* fatha */
+    case HB_MODIFIED_COMBINING_CLASS_CCC31: /* damma */
+    case HB_MODIFIED_COMBINING_CLASS_CCC33: /* shadda */
+    case HB_MODIFIED_COMBINING_CLASS_CCC34: /* sukun */
+    case HB_MODIFIED_COMBINING_CLASS_CCC35: /* superscript alef */
+    case HB_MODIFIED_COMBINING_CLASS_CCC36: /* superscript alaph */
+      return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC29: /* kasratan */
+    case HB_MODIFIED_COMBINING_CLASS_CCC32: /* kasra */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+
+    /* Thai */
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC103: /* sara u / sara uu */
+      return HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC107: /* mai */
+      return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
+
+
+    /* Lao */
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC118: /* sign u / sign uu */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC122: /* mai */
+      return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+
+    /* Tibetan */
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC129: /* sign aa */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC130: /* sign i*/
+      return HB_UNICODE_COMBINING_CLASS_ABOVE;
+
+    case HB_MODIFIED_COMBINING_CLASS_CCC132: /* sign u */
+      return HB_UNICODE_COMBINING_CLASS_BELOW;
+
+  }
+
+  return klass;
+}
+
+void
+_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                                                   hb_font_t *font HB_UNUSED,
+                                                   hb_buffer_t  *buffer)
+{
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
+      unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&info[i]);
+      combining_class = recategorize_combining_class (info[i].codepoint, combining_class);
+      _hb_glyph_info_set_modified_combining_class (&info[i], combining_class);
+    }
+}
+
+
+static void
+zero_mark_advances (hb_buffer_t *buffer,
+                    unsigned int start,
+                    unsigned int end)
+{
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = start; i < end; i++)
+    if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+    {
+      buffer->pos[i].x_advance = 0;
+      buffer->pos[i].y_advance = 0;
+    }
+}
+
+static inline void
+position_mark (const hb_ot_shape_plan_t *plan,
+               hb_font_t *font,
+               hb_buffer_t  *buffer,
+               hb_glyph_extents_t &base_extents,
+               unsigned int i,
+               unsigned int combining_class)
+{
+  hb_glyph_extents_t mark_extents;
+  if (!font->get_glyph_extents (buffer->info[i].codepoint,
+                                &mark_extents))
+    return;
+
+  hb_position_t y_gap = font->y_scale / 16;
+
+  hb_glyph_position_t &pos = buffer->pos[i];
+  pos.x_offset = pos.y_offset = 0;
+
+
+  /* We dont position LEFT and RIGHT marks. */
+
+  /* X positioning */
+  switch (combining_class)
+  {
+    case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW:
+    case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
+      if (buffer->props.direction == HB_DIRECTION_LTR) {
+        pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing;
+        break;
+      } else if (buffer->props.direction == HB_DIRECTION_RTL) {
+        pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing;
+        break;
+      }
+      /* Fall through */
+
+    default:
+    case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
+    case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
+    case HB_UNICODE_COMBINING_CLASS_BELOW:
+    case HB_UNICODE_COMBINING_CLASS_ABOVE:
+      /* Center align. */
+      pos.x_offset += base_extents.x_bearing + (base_extents.width - mark_extents.width) / 2 - mark_extents.x_bearing;
+      break;
+
+    case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
+    case HB_UNICODE_COMBINING_CLASS_BELOW_LEFT:
+    case HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT:
+      /* Left align. */
+      pos.x_offset += base_extents.x_bearing - mark_extents.x_bearing;
+      break;
+
+    case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
+    case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT:
+    case HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT:
+      /* Right align. */
+      pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width - mark_extents.x_bearing;
+      break;
+  }
+
+  /* Y positioning */
+  switch (combining_class)
+  {
+    case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW:
+    case HB_UNICODE_COMBINING_CLASS_BELOW_LEFT:
+    case HB_UNICODE_COMBINING_CLASS_BELOW:
+    case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT:
+      /* Add gap, fall-through. */
+      base_extents.height -= y_gap;
+
+    case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
+    case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
+      pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
+      /* Never shift up "below" marks. */
+      if ((y_gap > 0) == (pos.y_offset > 0))
+      {
+        base_extents.height -= pos.y_offset;
+        pos.y_offset = 0;
+      }
+      base_extents.height += mark_extents.height;
+      break;
+
+    case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
+    case HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT:
+    case HB_UNICODE_COMBINING_CLASS_ABOVE:
+    case HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT:
+      /* Add gap, fall-through. */
+      base_extents.y_bearing += y_gap;
+      base_extents.height -= y_gap;
+
+    case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
+    case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
+      pos.y_offset = base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
+      /* Don't shift down "above" marks too much. */
+      if ((y_gap > 0) != (pos.y_offset > 0))
+      {
+        unsigned int correction = -pos.y_offset / 2;
+        base_extents.y_bearing += correction;
+        base_extents.height -= correction;
+        pos.y_offset += correction;
+      }
+      base_extents.y_bearing -= mark_extents.height;
+      base_extents.height += mark_extents.height;
+      break;
+  }
+}
+
+static inline void
+position_around_base (const hb_ot_shape_plan_t *plan,
+                      hb_font_t *font,
+                      hb_buffer_t  *buffer,
+                      unsigned int base,
+                      unsigned int end)
+{
+  hb_direction_t horiz_dir = HB_DIRECTION_INVALID;
+  hb_glyph_extents_t base_extents;
+  if (!font->get_glyph_extents (buffer->info[base].codepoint,
+                                &base_extents))
+  {
+    /* If extents don't work, zero marks and go home. */
+    zero_mark_advances (buffer, base + 1, end);
+    return;
+  }
+  base_extents.x_bearing += buffer->pos[base].x_offset;
+  base_extents.y_bearing += buffer->pos[base].y_offset;
+
+  unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[base]);
+  unsigned int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]);
+
+  hb_position_t x_offset = 0, y_offset = 0;
+  if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
+    x_offset -= buffer->pos[base].x_advance;
+    y_offset -= buffer->pos[base].y_advance;
+  }
+
+  hb_glyph_extents_t component_extents = base_extents;
+  unsigned int last_lig_component = (unsigned int) -1;
+  unsigned int last_combining_class = 255;
+  hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = base + 1; i < end; i++)
+    if (_hb_glyph_info_get_modified_combining_class (&info[i]))
+    {
+      if (num_lig_components > 1) {
+        unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&info[i]);
+        unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i]) - 1;
+        /* Conditions for attaching to the last component. */
+        if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
+          this_lig_component = num_lig_components - 1;
+        if (last_lig_component != this_lig_component)
+        {
+          last_lig_component = this_lig_component;
+          last_combining_class = 255;
+          component_extents = base_extents;
+          if (unlikely (horiz_dir == HB_DIRECTION_INVALID)) {
+            if (HB_DIRECTION_IS_HORIZONTAL (plan->props.direction))
+              horiz_dir = plan->props.direction;
+            else
+              horiz_dir = hb_script_get_horizontal_direction (plan->props.script);
+          }
+          if (horiz_dir == HB_DIRECTION_LTR)
+            component_extents.x_bearing += (this_lig_component * component_extents.width) / num_lig_components;
+          else
+            component_extents.x_bearing += ((num_lig_components - 1 - this_lig_component) * component_extents.width) / num_lig_components;
+          component_extents.width /= num_lig_components;
+        }
+      }
+
+      unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&info[i]);
+      if (last_combining_class != this_combining_class)
+      {
+        last_combining_class = this_combining_class;
+        cluster_extents = component_extents;
+      }
+
+      position_mark (plan, font, buffer, cluster_extents, i, this_combining_class);
+
+      buffer->pos[i].x_advance = 0;
+      buffer->pos[i].y_advance = 0;
+      buffer->pos[i].x_offset += x_offset;
+      buffer->pos[i].y_offset += y_offset;
+
+    } else {
+      if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
+        x_offset -= buffer->pos[i].x_advance;
+        y_offset -= buffer->pos[i].y_advance;
+      } else {
+        x_offset += buffer->pos[i].x_advance;
+        y_offset += buffer->pos[i].y_advance;
+      }
+    }
+}
+
+static inline void
+position_cluster (const hb_ot_shape_plan_t *plan,
+                  hb_font_t *font,
+                  hb_buffer_t  *buffer,
+                  unsigned int start,
+                  unsigned int end)
+{
+  if (end - start < 2)
+    return;
+
+  /* Find the base glyph */
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = start; i < end; i++)
+    if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
+    {
+      /* Find mark glyphs */
+      unsigned int j;
+      for (j = i + 1; j < end; j++)
+        if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[j])))
+          break;
+
+      position_around_base (plan, font, buffer, i, j);
+
+      i = j - 1;
+    }
+}
+
+void
+_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
+                                hb_font_t *font,
+                                hb_buffer_t  *buffer)
+{
+  _hb_buffer_assert_gsubgpos_vars (buffer);
+
+  unsigned int start = 0;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 1; i < count; i++)
+    if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) {
+      position_cluster (plan, font, buffer, start, i);
+      start = i;
+    }
+  position_cluster (plan, font, buffer, start, count);
+}
+
+
+/* Performs old-style TrueType kerning. */
+void
+_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
+                            hb_font_t *font,
+                            hb_buffer_t  *buffer)
+{
+  if (!plan->has_kern) return;
+
+  OT::hb_apply_context_t c (1, font, buffer);
+  c.set_lookup_mask (plan->kern_mask);
+  c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
+  OT::hb_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
+  skippy_iter.init (&c);
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  hb_glyph_position_t *pos = buffer->pos;
+  for (unsigned int idx = 0; idx < count;)
+  {
+    skippy_iter.reset (idx, 1);
+    if (!skippy_iter.next ())
+    {
+      idx++;
+      continue;
+    }
+
+    hb_position_t x_kern, y_kern;
+    font->get_glyph_kerning_for_direction (info[idx].codepoint,
+                                           info[skippy_iter.idx].codepoint,
+                                           buffer->props.direction,
+                                           &x_kern, &y_kern);
+
+    if (x_kern)
+    {
+      hb_position_t kern1 = x_kern >> 1;
+      hb_position_t kern2 = x_kern - kern1;
+      pos[idx].x_advance += kern1;
+      pos[skippy_iter.idx].x_advance += kern2;
+      pos[skippy_iter.idx].x_offset += kern2;
+    }
+
+    if (y_kern)
+    {
+      hb_position_t kern1 = y_kern >> 1;
+      hb_position_t kern2 = y_kern - kern1;
+      pos[idx].y_advance += kern1;
+      pos[skippy_iter.idx].y_advance += kern2;
+      pos[skippy_iter.idx].y_offset += kern2;
+    }
+
+    idx = skippy_iter.idx;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2012  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_SHAPE_NORMALIZE_PRIVATE_HH
+#define HB_OT_SHAPE_NORMALIZE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+/* buffer var allocations, used during the normalization process */
+#define glyph_index()   var1.u32
+
+struct hb_ot_shape_plan_t;
+
+enum hb_ot_shape_normalization_mode_t {
+  HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
+  HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
+  HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */
+
+  HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS
+};
+
+HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper,
+                                         hb_buffer_t *buffer,
+                                         hb_font_t *font);
+
+
+struct hb_ot_shape_normalize_context_t
+{
+  const hb_ot_shape_plan_t *plan;
+  hb_buffer_t *buffer;
+  hb_font_t *font;
+  hb_unicode_funcs_t *unicode;
+  bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
+                     hb_codepoint_t  ab,
+                     hb_codepoint_t *a,
+                     hb_codepoint_t *b);
+  bool (*compose) (const hb_ot_shape_normalize_context_t *c,
+                   hb_codepoint_t  a,
+                   hb_codepoint_t  b,
+                   hb_codepoint_t *ab);
+};
+
+
+#endif /* HB_OT_SHAPE_NORMALIZE_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,416 @@
+/*
+ * Copyright © 2011,2012  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
+ */
+
+#include "hb-ot-shape-normalize-private.hh"
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-private.hh"
+
+
+/*
+ * HIGHLEVEL DESIGN:
+ *
+ * This file exports one main function: _hb_ot_shape_normalize().
+ *
+ * This function closely reflects the Unicode Normalization Algorithm,
+ * yet it's different.
+ *
+ * Each shaper specifies whether it prefers decomposed (NFD) or composed (NFC).
+ * The logic however tries to use whatever the font can support.
+ *
+ * In general what happens is that: each grapheme is decomposed in a chain
+ * of 1:2 decompositions, marks reordered, and then recomposed if desired,
+ * so far it's like Unicode Normalization.  However, the decomposition and
+ * recomposition only happens if the font supports the resulting characters.
+ *
+ * The goals are:
+ *
+ *   - Try to render all canonically equivalent strings similarly.  To really
+ *     achieve this we have to always do the full decomposition and then
+ *     selectively recompose from there.  It's kinda too expensive though, so
+ *     we skip some cases.  For example, if composed is desired, we simply
+ *     don't touch 1-character clusters that are supported by the font, even
+ *     though their NFC may be different.
+ *
+ *   - When a font has a precomposed character for a sequence but the 'ccmp'
+ *     feature in the font is not adequate, use the precomposed character
+ *     which typically has better mark positioning.
+ *
+ *   - When a font does not support a combining mark, but supports it precomposed
+ *     with previous base, use that.  This needs the itemizer to have this
+ *     knowledge too.  We need to provide assistance to the itemizer.
+ *
+ *   - When a font does not support a character but supports its decomposition,
+ *     well, use the decomposition (preferring the canonical decomposition, but
+ *     falling back to the compatibility decomposition if necessary).  The
+ *     compatibility decomposition is really nice to have, for characters like
+ *     ellipsis, or various-sized space characters.
+ *
+ *   - The complex shapers can customize the compose and decompose functions to
+ *     offload some of their requirements to the normalizer.  For example, the
+ *     Indic shaper may want to disallow recomposing of two matras.
+ *
+ *   - We try compatibility decomposition if decomposing through canonical
+ *     decomposition alone failed to find a sequence that the font supports.
+ *     We don't try compatibility decomposition recursively during the canonical
+ *     decomposition phase.  This has minimal impact.  There are only a handful
+ *     of Greek letter that have canonical decompositions that include characters
+ *     with compatibility decomposition.  Those can be found using this command:
+ *
+ *     egrep  "`echo -n ';('; grep ';<' UnicodeData.txt | cut -d';' -f1 | tr '\n' '|'; echo ') '`" UnicodeData.txt
+ */
+
+static bool
+decompose_unicode (const hb_ot_shape_normalize_context_t *c,
+                   hb_codepoint_t  ab,
+                   hb_codepoint_t *a,
+                   hb_codepoint_t *b)
+{
+  return c->unicode->decompose (ab, a, b);
+}
+
+static bool
+compose_unicode (const hb_ot_shape_normalize_context_t *c,
+                 hb_codepoint_t  a,
+                 hb_codepoint_t  b,
+                 hb_codepoint_t *ab)
+{
+  return c->unicode->compose (a, b, ab);
+}
+
+static inline void
+set_glyph (hb_glyph_info_t &info, hb_font_t *font)
+{
+  font->get_glyph (info.codepoint, 0, &info.glyph_index());
+}
+
+static inline void
+output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
+{
+  buffer->cur().glyph_index() = glyph;
+  buffer->output_glyph (unichar);
+  _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer->unicode);
+}
+
+static inline void
+next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
+{
+  buffer->cur().glyph_index() = glyph;
+  buffer->next_glyph ();
+}
+
+static inline void
+skip_char (hb_buffer_t *buffer)
+{
+  buffer->skip_glyph ();
+}
+
+/* Returns 0 if didn't decompose, number of resulting characters otherwise. */
+static inline unsigned int
+decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
+{
+  hb_codepoint_t a, b, a_glyph, b_glyph;
+  hb_buffer_t * const buffer = c->buffer;
+  hb_font_t * const font = c->font;
+
+  if (!c->decompose (c, ab, &a, &b) ||
+      (b && !font->get_glyph (b, 0, &b_glyph)))
+    return 0;
+
+  bool has_a = font->get_glyph (a, 0, &a_glyph);
+  if (shortest && has_a) {
+    /* Output a and b */
+    output_char (buffer, a, a_glyph);
+    if (likely (b)) {
+      output_char (buffer, b, b_glyph);
+      return 2;
+    }
+    return 1;
+  }
+
+  unsigned int ret;
+  if ((ret = decompose (c, shortest, a))) {
+    if (b) {
+      output_char (buffer, b, b_glyph);
+      return ret + 1;
+    }
+    return ret;
+  }
+
+  if (has_a) {
+    output_char (buffer, a, a_glyph);
+    if (likely (b)) {
+      output_char (buffer, b, b_glyph);
+      return 2;
+    }
+    return 1;
+  }
+
+  return 0;
+}
+
+/* Returns 0 if didn't decompose, number of resulting characters otherwise. */
+static inline unsigned int
+decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t u)
+{
+  unsigned int len, i;
+  hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
+  hb_codepoint_t glyphs[HB_UNICODE_MAX_DECOMPOSITION_LEN];
+
+  len = c->buffer->unicode->decompose_compatibility (u, decomposed);
+  if (!len)
+    return 0;
+
+  for (i = 0; i < len; i++)
+    if (!c->font->get_glyph (decomposed[i], 0, &glyphs[i]))
+      return 0;
+
+  for (i = 0; i < len; i++)
+    output_char (c->buffer, decomposed[i], glyphs[i]);
+
+  return len;
+}
+
+static inline void
+decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest)
+{
+  hb_buffer_t * const buffer = c->buffer;
+  hb_codepoint_t u = buffer->cur().codepoint;
+  hb_codepoint_t glyph;
+
+  /* Kind of a cute waterfall here... */
+  if (shortest && c->font->get_glyph (u, 0, &glyph))
+    next_char (buffer, glyph);
+  else if (decompose (c, shortest, u))
+    skip_char (buffer);
+  else if (!shortest && c->font->get_glyph (u, 0, &glyph))
+    next_char (buffer, glyph);
+  else if (decompose_compatibility (c, u))
+    skip_char (buffer);
+  else
+    next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
+}
+
+static inline void
+handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
+{
+  /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
+  hb_buffer_t * const buffer = c->buffer;
+  hb_font_t * const font = c->font;
+  for (; buffer->idx < end - 1;) {
+    if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
+      /* The next two lines are some ugly lines... But work. */
+      if (font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
+      {
+        buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
+      }
+      else
+      {
+        /* Just pass on the two characters separately, let GSUB do its magic. */
+        set_glyph (buffer->cur(), font);
+        buffer->next_glyph ();
+        set_glyph (buffer->cur(), font);
+        buffer->next_glyph ();
+      }
+      /* Skip any further variation selectors. */
+      while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
+      {
+        set_glyph (buffer->cur(), font);
+        buffer->next_glyph ();
+      }
+    } else {
+      set_glyph (buffer->cur(), font);
+      buffer->next_glyph ();
+    }
+  }
+  if (likely (buffer->idx < end)) {
+    set_glyph (buffer->cur(), font);
+    buffer->next_glyph ();
+  }
+}
+
+static inline void
+decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
+{
+  hb_buffer_t * const buffer = c->buffer;
+  for (unsigned int i = buffer->idx; i < end; i++)
+    if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
+      handle_variation_selector_cluster (c, end, short_circuit);
+      return;
+    }
+
+  while (buffer->idx < end)
+    decompose_current_character (c, short_circuit);
+}
+
+static inline void
+decompose_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool might_short_circuit, bool always_short_circuit)
+{
+  if (likely (c->buffer->idx + 1 == end))
+    decompose_current_character (c, might_short_circuit);
+  else
+    decompose_multi_char_cluster (c, end, always_short_circuit);
+}
+
+
+static int
+compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+  unsigned int a = _hb_glyph_info_get_modified_combining_class (pa);
+  unsigned int b = _hb_glyph_info_get_modified_combining_class (pb);
+
+  return a < b ? -1 : a == b ? 0 : +1;
+}
+
+
+void
+_hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
+                        hb_buffer_t *buffer,
+                        hb_font_t *font)
+{
+  if (unlikely (!buffer->len)) return;
+
+  _hb_buffer_assert_unicode_vars (buffer);
+
+  hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
+  const hb_ot_shape_normalize_context_t c = {
+    plan,
+    buffer,
+    font,
+    buffer->unicode,
+    plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode,
+    plan->shaper->compose   ? plan->shaper->compose   : compose_unicode
+  };
+
+  bool always_short_circuit = mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE;
+  bool might_short_circuit = always_short_circuit ||
+                             (mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED &&
+                              mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT);
+  unsigned int count;
+
+  /* We do a fairly straightforward yet custom normalization process in three
+   * separate rounds: decompose, reorder, recompose (if desired).  Currently
+   * this makes two buffer swaps.  We can make it faster by moving the last
+   * two rounds into the inner loop for the first round, but it's more readable
+   * this way. */
+
+
+  /* First round, decompose */
+
+  buffer->clear_output ();
+  count = buffer->len;
+  for (buffer->idx = 0; buffer->idx < count;)
+  {
+    unsigned int end;
+    for (end = buffer->idx + 1; end < count; end++)
+      if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))))
+        break;
+
+    decompose_cluster (&c, end, might_short_circuit, always_short_circuit);
+  }
+  buffer->swap_buffers ();
+
+
+  /* Second round, reorder (inplace) */
+
+  count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
+      continue;
+
+    unsigned int end;
+    for (end = i + 1; end < count; end++)
+      if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
+        break;
+
+    /* We are going to do a O(n^2).  Only do this if the sequence is short. */
+    if (end - i > 10) {
+      i = end;
+      continue;
+    }
+
+    buffer->sort (i, end, compare_combining_class);
+
+    i = end;
+  }
+
+
+  if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
+      mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
+    return;
+
+  /* Third round, recompose */
+
+  /* As noted in the comment earlier, we don't try to combine
+   * ccc=0 chars with their previous Starter. */
+
+  buffer->clear_output ();
+  count = buffer->len;
+  unsigned int starter = 0;
+  buffer->next_glyph ();
+  while (buffer->idx < count)
+  {
+    hb_codepoint_t composed, glyph;
+    if (/* We don't try to compose a non-mark character with it's preceding starter.
+         * This is both an optimization to avoid trying to compose every two neighboring
+         * glyphs in most scripts AND a desired feature for Hangul.  Apparently Hangul
+         * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
+        HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->cur())) &&
+        /* If there's anything between the starter and this char, they should have CCC
+         * smaller than this character's. */
+        (starter == buffer->out_len - 1 ||
+         _hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
+        /* And compose. */
+        c.compose (&c,
+                   buffer->out_info[starter].codepoint,
+                   buffer->cur().codepoint,
+                   &composed) &&
+        /* And the font has glyph for the composite. */
+        font->get_glyph (composed, 0, &glyph))
+    {
+      /* Composes. */
+      buffer->next_glyph (); /* Copy to out-buffer. */
+      if (unlikely (buffer->in_error))
+        return;
+      buffer->merge_out_clusters (starter, buffer->out_len);
+      buffer->out_len--; /* Remove the second composable. */
+      /* Modify starter and carry on. */
+      buffer->out_info[starter].codepoint = composed;
+      buffer->out_info[starter].glyph_index() = glyph;
+      _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode);
+
+      continue;
+    }
+
+    /* Blocked, or doesn't compose. */
+    buffer->next_glyph ();
+
+    if (_hb_glyph_info_get_modified_combining_class (&buffer->prev()) == 0)
+      starter = buffer->out_len - 1;
+  }
+  buffer->swap_buffers ();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2010  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_SHAPE_PRIVATE_HH
+#define HB_OT_SHAPE_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-ot-map-private.hh"
+#include "hb-ot-layout-private.hh"
+
+
+
+struct hb_ot_shape_plan_t
+{
+  hb_segment_properties_t props;
+  const struct hb_ot_complex_shaper_t *shaper;
+  hb_ot_map_t map;
+  const void *data;
+  hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask;
+  hb_mask_t kern_mask;
+  unsigned int has_frac : 1;
+  unsigned int has_kern : 1;
+  unsigned int has_mark : 1;
+
+  inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
+  {
+    unsigned int table_index;
+    switch (table_tag) {
+      case HB_OT_TAG_GSUB: table_index = 0; break;
+      case HB_OT_TAG_GPOS: table_index = 1; break;
+      default: return;
+    }
+    map.collect_lookups (table_index, lookups);
+  }
+  inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
+  inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); }
+
+  void finish (void) { map.finish (); }
+};
+
+struct hb_ot_shape_planner_t
+{
+  /* In the order that they are filled in. */
+  hb_face_t *face;
+  hb_segment_properties_t props;
+  const struct hb_ot_complex_shaper_t *shaper;
+  hb_ot_map_builder_t map;
+
+  hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
+                         face (master_plan->face_unsafe),
+                         props (master_plan->props),
+                         shaper (NULL),
+                         map (face, &props) {}
+  ~hb_ot_shape_planner_t (void) { map.finish (); }
+
+  inline void compile (hb_ot_shape_plan_t &plan)
+  {
+    plan.props = props;
+    plan.shaper = shaper;
+    map.compile (plan.map);
+
+    plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
+    plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
+    plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
+    plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
+
+    plan.kern_mask = plan.map.get_mask (HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
+                                        HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
+
+    plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
+    plan.has_kern = !!plan.kern_mask;
+    plan.has_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
+  }
+
+  private:
+  NO_COPY (hb_ot_shape_planner_t);
+};
+
+
+#endif /* HB_OT_SHAPE_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,892 @@
+/*
+ * Copyright © 2009,2010  Red Hat, Inc.
+ * Copyright © 2010,2011,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#define HB_SHAPER ot
+#define hb_ot_shaper_face_data_t hb_ot_layout_t
+#define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
+#include "hb-shaper-impl-private.hh"
+
+#include "hb-ot-shape-private.hh"
+#include "hb-ot-shape-complex-private.hh"
+#include "hb-ot-shape-fallback-private.hh"
+#include "hb-ot-shape-normalize-private.hh"
+
+#include "hb-ot-layout-private.hh"
+#include "hb-unicode-private.hh"
+#include "hb-set-private.hh"
+
+
+static hb_tag_t common_features[] = {
+  HB_TAG('c','c','m','p'),
+  HB_TAG('l','o','c','l'),
+  HB_TAG('m','a','r','k'),
+  HB_TAG('m','k','m','k'),
+  HB_TAG('r','l','i','g'),
+};
+
+
+static hb_tag_t horizontal_features[] = {
+  HB_TAG('c','a','l','t'),
+  HB_TAG('c','l','i','g'),
+  HB_TAG('c','u','r','s'),
+  HB_TAG('k','e','r','n'),
+  HB_TAG('l','i','g','a'),
+  HB_TAG('r','c','l','t'),
+};
+
+
+
+static void
+hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
+                              const hb_segment_properties_t  *props,
+                              const hb_feature_t             *user_features,
+                              unsigned int                    num_user_features)
+{
+  hb_ot_map_builder_t *map = &planner->map;
+
+  switch (props->direction) {
+    case HB_DIRECTION_LTR:
+      map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
+      map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
+      break;
+    case HB_DIRECTION_RTL:
+      map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
+      map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
+      break;
+    case HB_DIRECTION_TTB:
+    case HB_DIRECTION_BTT:
+    case HB_DIRECTION_INVALID:
+    default:
+      break;
+  }
+
+  map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE);
+  map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE);
+  map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE);
+
+  if (planner->shaper->collect_features)
+    planner->shaper->collect_features (planner);
+
+  for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
+    map->add_global_bool_feature (common_features[i]);
+
+  if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
+    for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
+      map->add_feature (horizontal_features[i], 1, F_GLOBAL |
+                        (horizontal_features[i] == HB_TAG('k','e','r','n') ?
+                         F_HAS_FALLBACK : F_NONE));
+  else
+  {
+    /* We really want to find a 'vert' feature if there's any in the font, no
+     * matter which script/langsys it is listed (or not) under.
+     * See various bugs referenced from:
+     * https://github.com/behdad/harfbuzz/issues/63 */
+    map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH);
+  }
+
+  if (planner->shaper->override_features)
+    planner->shaper->override_features (planner);
+
+  for (unsigned int i = 0; i < num_user_features; i++) {
+    const hb_feature_t *feature = &user_features[i];
+    map->add_feature (feature->tag, feature->value,
+                      (feature->start == 0 && feature->end == (unsigned int) -1) ?
+                       F_GLOBAL : F_NONE);
+  }
+}
+
+
+/*
+ * shaper face data
+ */
+
+hb_ot_shaper_face_data_t *
+_hb_ot_shaper_face_data_create (hb_face_t *face)
+{
+  return _hb_ot_layout_create (face);
+}
+
+void
+_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
+{
+  _hb_ot_layout_destroy (data);
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_ot_shaper_font_data_t {};
+
+hb_ot_shaper_font_data_t *
+_hb_ot_shaper_font_data_create (hb_font_t *font)
+{
+  return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+hb_ot_shaper_shape_plan_data_t *
+_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t    *shape_plan,
+                                      const hb_feature_t *user_features,
+                                      unsigned int        num_user_features)
+{
+  hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
+  if (unlikely (!plan))
+    return NULL;
+
+  hb_ot_shape_planner_t planner (shape_plan);
+
+  planner.shaper = hb_ot_shape_complex_categorize (&planner);
+
+  hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
+
+  planner.compile (*plan);
+
+  if (plan->shaper->data_create) {
+    plan->data = plan->shaper->data_create (plan);
+    if (unlikely (!plan->data))
+      return NULL;
+  }
+
+  return plan;
+}
+
+void
+_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
+{
+  if (plan->shaper->data_destroy)
+    plan->shaper->data_destroy (const_cast<void *> (plan->data));
+
+  plan->finish ();
+
+  free (plan);
+}
+
+
+/*
+ * shaper
+ */
+
+struct hb_ot_shape_context_t
+{
+  hb_ot_shape_plan_t *plan;
+  hb_font_t *font;
+  hb_face_t *face;
+  hb_buffer_t  *buffer;
+  const hb_feature_t *user_features;
+  unsigned int        num_user_features;
+
+  /* Transient stuff */
+  hb_direction_t target_direction;
+};
+
+
+
+/* Main shaper */
+
+
+/* Prepare */
+
+static void
+hb_set_unicode_props (hb_buffer_t *buffer)
+{
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode);
+}
+
+static void
+hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
+{
+  if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
+      buffer->context_len[0] ||
+      _hb_glyph_info_get_general_category (&buffer->info[0]) !=
+      HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+    return;
+
+  if (!font->has_glyph (0x25CCu))
+    return;
+
+  hb_glyph_info_t dottedcircle = {0};
+  dottedcircle.codepoint = 0x25CCu;
+  _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode);
+
+  buffer->clear_output ();
+
+  buffer->idx = 0;
+  hb_glyph_info_t info = dottedcircle;
+  info.cluster = buffer->cur().cluster;
+  info.mask = buffer->cur().mask;
+  buffer->output_info (info);
+  while (buffer->idx < buffer->len)
+    buffer->next_glyph ();
+
+  buffer->swap_buffers ();
+}
+
+static void
+hb_form_clusters (hb_buffer_t *buffer)
+{
+  if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
+    return;
+
+  /* Loop duplicated in hb_ensure_native_direction(). */
+  unsigned int base = 0;
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 1; i < count; i++)
+  {
+    if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))))
+    {
+      buffer->merge_clusters (base, i);
+      base = i;
+    }
+  }
+  buffer->merge_clusters (base, count);
+}
+
+static void
+hb_ensure_native_direction (hb_buffer_t *buffer)
+{
+  hb_direction_t direction = buffer->props.direction;
+
+  /* TODO vertical:
+   * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType
+   * Ogham fonts are supposed to be implemented BTT or not.  Need to research that
+   * first. */
+  if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) ||
+      (HB_DIRECTION_IS_VERTICAL   (direction) && direction != HB_DIRECTION_TTB))
+  {
+    /* Same loop as hb_form_clusters().
+     * Since form_clusters() merged clusters already, we don't merge. */
+    unsigned int base = 0;
+    unsigned int count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    for (unsigned int i = 1; i < count; i++)
+    {
+      if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))))
+      {
+        if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
+          buffer->merge_clusters (base, i);
+        buffer->reverse_range (base, i);
+
+        base = i;
+      }
+    }
+    if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
+      buffer->merge_clusters (base, count);
+    buffer->reverse_range (base, count);
+
+    buffer->reverse ();
+
+    buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction);
+  }
+}
+
+
+/* Substitute */
+
+static inline void
+hb_ot_mirror_chars (hb_ot_shape_context_t *c)
+{
+  if (HB_DIRECTION_IS_FORWARD (c->target_direction))
+    return;
+
+  hb_buffer_t *buffer = c->buffer;
+  hb_unicode_funcs_t *unicode = buffer->unicode;
+  hb_mask_t rtlm_mask = c->plan->rtlm_mask;
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++) {
+    hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
+    if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint)))
+      info[i].mask |= rtlm_mask;
+    else
+      info[i].codepoint = codepoint;
+  }
+}
+
+static inline void
+hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
+{
+  if (!c->plan->has_frac)
+    return;
+
+  hb_buffer_t *buffer = c->buffer;
+
+  /* TODO look in pre/post context text also. */
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */
+    {
+      unsigned int start = i, end = i + 1;
+      while (start &&
+             _hb_glyph_info_get_general_category (&info[start - 1]) ==
+             HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
+        start--;
+      while (end < count &&
+             _hb_glyph_info_get_general_category (&info[end]) ==
+             HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
+        end++;
+
+      for (unsigned int j = start; j < i; j++)
+        info[j].mask |= c->plan->numr_mask | c->plan->frac_mask;
+      info[i].mask |= c->plan->frac_mask;
+      for (unsigned int j = i + 1; j < end; j++)
+        info[j].mask |= c->plan->frac_mask | c->plan->dnom_mask;
+
+      i = end - 1;
+    }
+  }
+}
+
+static inline void
+hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
+{
+  hb_ot_map_t *map = &c->plan->map;
+  hb_buffer_t *buffer = c->buffer;
+
+  hb_mask_t global_mask = map->get_global_mask ();
+  buffer->reset_masks (global_mask);
+}
+
+static inline void
+hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
+{
+  hb_ot_map_t *map = &c->plan->map;
+  hb_buffer_t *buffer = c->buffer;
+
+  hb_ot_shape_setup_masks_fraction (c);
+
+  if (c->plan->shaper->setup_masks)
+    c->plan->shaper->setup_masks (c->plan, buffer, c->font);
+
+  for (unsigned int i = 0; i < c->num_user_features; i++)
+  {
+    const hb_feature_t *feature = &c->user_features[i];
+    if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
+      unsigned int shift;
+      hb_mask_t mask = map->get_mask (feature->tag, &shift);
+      buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
+    }
+  }
+}
+
+static void
+hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
+{
+  hb_buffer_t *buffer = c->buffer;
+
+  if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
+    return;
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  hb_glyph_position_t *pos = buffer->pos;
+  unsigned int i = 0;
+  for (i = 0; i < count; i++)
+    if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i])))
+      pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0;
+}
+
+static void
+hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
+{
+  hb_buffer_t *buffer = c->buffer;
+
+  if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
+    return;
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  hb_glyph_position_t *pos = buffer->pos;
+  unsigned int i = 0;
+  for (i = 0; i < count; i++)
+  {
+    if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i])))
+      break;
+  }
+
+  /* No default-ignorables found; return. */
+  if (i == count)
+    return;
+
+  hb_codepoint_t space;
+  if (c->font->get_glyph (' ', 0, &space))
+  {
+    /* Replace default-ignorables with a zero-advance space glyph. */
+    for (/*continue*/; i < count; i++)
+    {
+      if (_hb_glyph_info_is_default_ignorable (&info[i]))
+        info[i].codepoint = space;
+    }
+  }
+  else
+  {
+    /* Merge clusters and delete default-ignorables.
+     * NOTE! We can't use out-buffer as we have positioning data. */
+    unsigned int j = i;
+    for (; i < count; i++)
+    {
+      if (_hb_glyph_info_is_default_ignorable (&info[i]))
+      {
+        /* Merge clusters.
+         * Same logic as buffer->delete_glyph(), but for in-place removal. */
+
+        unsigned int cluster = info[i].cluster;
+        if (i + 1 < count && cluster == info[i + 1].cluster)
+          continue; /* Cluster survives; do nothing. */
+
+        if (j)
+        {
+          /* Merge cluster backward. */
+          if (cluster < info[j - 1].cluster)
+          {
+            unsigned int old_cluster = info[j - 1].cluster;
+            for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
+              info[k - 1].cluster = cluster;
+          }
+          continue;
+        }
+
+        if (i + 1 < count)
+          buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */
+
+        continue;
+      }
+
+      if (j != i)
+      {
+        info[j] = info[i];
+        pos[j] = pos[i];
+      }
+      j++;
+    }
+    buffer->len = j;
+  }
+}
+
+
+static inline void
+hb_ot_map_glyphs_fast (hb_buffer_t  *buffer)
+{
+  /* Normalization process sets up glyph_index(), we just copy it. */
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    info[i].codepoint = info[i].glyph_index();
+
+  buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+}
+
+static inline void
+hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
+{
+  unsigned int count = c->buffer->len;
+  hb_glyph_info_t *info = c->buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    hb_ot_layout_glyph_class_mask_t klass;
+
+    /* Never mark default-ignorables as marks.
+     * They won't get in the way of lookups anyway,
+     * but having them as mark will cause them to be skipped
+     * over if the lookup-flag says so, but at least for the
+     * Mongolian variation selectors, looks like Uniscribe
+     * marks them as non-mark.  Some Mongolian fonts without
+     * GDEF rely on this.  Another notable character that
+     * this applies to is COMBINING GRAPHEME JOINER. */
+    klass = (_hb_glyph_info_get_general_category (&info[i]) !=
+             HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
+             _hb_glyph_info_is_default_ignorable (&info[i])) ?
+            HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
+            HB_OT_LAYOUT_GLYPH_PROPS_MARK;
+    _hb_glyph_info_set_glyph_props (&info[i], klass);
+  }
+}
+
+static inline void
+hb_ot_substitute_default (hb_ot_shape_context_t *c)
+{
+  hb_buffer_t *buffer = c->buffer;
+
+  if (c->plan->shaper->preprocess_text)
+    c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
+
+  hb_ot_shape_initialize_masks (c);
+
+  hb_ot_mirror_chars (c);
+
+  HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
+
+  _hb_ot_shape_normalize (c->plan, buffer, c->font);
+
+  hb_ot_shape_setup_masks (c);
+
+  /* This is unfortunate to go here, but necessary... */
+  if (!hb_ot_layout_has_positioning (c->face))
+    _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
+
+  hb_ot_map_glyphs_fast (buffer);
+
+  HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index);
+}
+
+static inline void
+hb_ot_substitute_complex (hb_ot_shape_context_t *c)
+{
+  hb_buffer_t *buffer = c->buffer;
+
+  _hb_buffer_allocate_gsubgpos_vars (buffer);
+  hb_ot_layout_substitute_start (c->font, buffer);
+
+  if (!hb_ot_layout_has_glyph_classes (c->face))
+    hb_synthesize_glyph_classes (c);
+
+  c->plan->substitute (c->font, buffer);
+
+  hb_ot_layout_substitute_finish (c->font, buffer);
+
+  return;
+}
+
+static inline void
+hb_ot_substitute (hb_ot_shape_context_t *c)
+{
+  hb_ot_substitute_default (c);
+  hb_ot_substitute_complex (c);
+}
+
+/* Position */
+
+static inline void
+adjust_mark_offsets (hb_glyph_position_t *pos)
+{
+  pos->x_offset -= pos->x_advance;
+  pos->y_offset -= pos->y_advance;
+}
+
+static inline void
+zero_mark_width (hb_glyph_position_t *pos)
+{
+  pos->x_advance = 0;
+  pos->y_advance = 0;
+}
+
+static inline void
+zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets)
+{
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+    {
+      if (adjust_offsets)
+        adjust_mark_offsets (&buffer->pos[i]);
+      zero_mark_width (&buffer->pos[i]);
+    }
+}
+
+static inline void
+zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
+{
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    if (_hb_glyph_info_is_mark (&info[i]))
+    {
+      if (adjust_offsets)
+        adjust_mark_offsets (&buffer->pos[i]);
+      zero_mark_width (&buffer->pos[i]);
+    }
+}
+
+static inline void
+hb_ot_position_default (hb_ot_shape_context_t *c)
+{
+  hb_direction_t direction = c->buffer->props.direction;
+  unsigned int count = c->buffer->len;
+  hb_glyph_info_t *info = c->buffer->info;
+  hb_glyph_position_t *pos = c->buffer->pos;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    c->font->get_glyph_advance_for_direction (info[i].codepoint,
+                                              direction,
+                                              &pos[i].x_advance,
+                                              &pos[i].y_advance);
+    c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
+                                                  direction,
+                                                  &pos[i].x_offset,
+                                                  &pos[i].y_offset);
+
+  }
+}
+
+static inline bool
+hb_ot_position_complex (hb_ot_shape_context_t *c)
+{
+  bool ret = false;
+  unsigned int count = c->buffer->len;
+  bool has_positioning = hb_ot_layout_has_positioning (c->face);
+  /* If the font has no GPOS, AND, no fallback positioning will
+   * happen, AND, direction is forward, then when zeroing mark
+   * widths, we shift the mark with it, such that the mark
+   * is positioned hanging over the previous glyph.  When
+   * direction is backward we don't shift and it will end up
+   * hanging over the next glyph after the final reordering.
+   * If fallback positinoing happens or GPOS is present, we don't
+   * care.
+   */
+  bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position ||
+                                       HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction));
+
+  switch (c->plan->shaper->zero_width_marks)
+  {
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+      zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
+      break;
+
+    /* Not currently used for any shaper:
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
+      zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
+      break;
+    */
+
+    default:
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+      break;
+  }
+
+  if (has_positioning)
+  {
+    hb_glyph_info_t *info = c->buffer->info;
+    hb_glyph_position_t *pos = c->buffer->pos;
+
+    /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
+
+    for (unsigned int i = 0; i < count; i++) {
+      c->font->add_glyph_origin_for_direction (info[i].codepoint,
+                                               HB_DIRECTION_LTR,
+                                               &pos[i].x_offset,
+                                               &pos[i].y_offset);
+    }
+
+    c->plan->position (c->font, c->buffer);
+
+    for (unsigned int i = 0; i < count; i++) {
+      c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
+                                                    HB_DIRECTION_LTR,
+                                                    &pos[i].x_offset,
+                                                    &pos[i].y_offset);
+    }
+
+    ret = true;
+  }
+
+  switch (c->plan->shaper->zero_width_marks)
+  {
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
+      zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
+      break;
+
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
+      zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
+      break;
+
+    default:
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+    //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
+      break;
+  }
+
+  return ret;
+}
+
+static inline void
+hb_ot_position (hb_ot_shape_context_t *c)
+{
+  hb_ot_layout_position_start (c->font, c->buffer);
+
+  hb_ot_position_default (c);
+
+  hb_bool_t fallback = !hb_ot_position_complex (c);
+
+  hb_ot_zero_width_default_ignorables (c);
+
+  hb_ot_layout_position_finish (c->font, c->buffer);
+
+  if (fallback && c->plan->shaper->fallback_position)
+    _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
+
+  if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
+    hb_buffer_reverse (c->buffer);
+
+  /* Visual fallback goes here. */
+
+  if (fallback)
+    _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
+
+  _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
+}
+
+
+/* Pull it all together! */
+
+static void
+hb_ot_shape_internal (hb_ot_shape_context_t *c)
+{
+  c->buffer->deallocate_var_all ();
+
+  /* Save the original direction, we use it later. */
+  c->target_direction = c->buffer->props.direction;
+
+  _hb_buffer_allocate_unicode_vars (c->buffer);
+
+  c->buffer->clear_output ();
+
+  hb_set_unicode_props (c->buffer);
+  hb_insert_dotted_circle (c->buffer, c->font);
+  hb_form_clusters (c->buffer);
+
+  hb_ensure_native_direction (c->buffer);
+
+  hb_ot_substitute (c);
+  hb_ot_position (c);
+
+  hb_ot_hide_default_ignorables (c);
+
+  _hb_buffer_deallocate_unicode_vars (c->buffer);
+
+  c->buffer->props.direction = c->target_direction;
+
+  c->buffer->deallocate_var_all ();
+}
+
+
+hb_bool_t
+_hb_ot_shape (hb_shape_plan_t    *shape_plan,
+              hb_font_t          *font,
+              hb_buffer_t        *buffer,
+              const hb_feature_t *features,
+              unsigned int        num_features)
+{
+  hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features};
+  hb_ot_shape_internal (&c);
+
+  return true;
+}
+
+
+/**
+ * Since: 0.9.7
+ **/
+void
+hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
+                                  hb_tag_t         table_tag,
+                                  hb_set_t        *lookup_indexes /* OUT */)
+{
+  /* XXX Does the first part always succeed? */
+  HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes);
+}
+
+
+/* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */
+static void
+add_char (hb_font_t          *font,
+          hb_unicode_funcs_t *unicode,
+          hb_bool_t           mirror,
+          hb_codepoint_t      u,
+          hb_set_t           *glyphs)
+{
+  hb_codepoint_t glyph;
+  if (font->get_glyph (u, 0, &glyph))
+    glyphs->add (glyph);
+  if (mirror)
+  {
+    hb_codepoint_t m = unicode->mirroring (u);
+    if (m != u && font->get_glyph (m, 0, &glyph))
+      glyphs->add (glyph);
+  }
+}
+
+
+/**
+ * Since: 0.9.2
+ **/
+void
+hb_ot_shape_glyphs_closure (hb_font_t          *font,
+                            hb_buffer_t        *buffer,
+                            const hb_feature_t *features,
+                            unsigned int        num_features,
+                            hb_set_t           *glyphs)
+{
+  hb_ot_shape_plan_t plan;
+
+  const char *shapers[] = {"ot", NULL};
+  hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
+                                                             features, num_features, shapers);
+
+  bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
+
+  unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
+  for (unsigned int i = 0; i < count; i++)
+    add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs);
+
+  hb_set_t lookups;
+  lookups.init ();
+  hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups);
+
+  /* And find transitive closure. */
+  hb_set_t copy;
+  copy.init ();
+  do {
+    copy.set (glyphs);
+    for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index);)
+      hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
+  } while (!copy.is_equal (glyphs));
+
+  hb_shape_plan_destroy (shape_plan);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2013  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_SHAPE_H
+#define HB_OT_SHAPE_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+/* TODO port to shape-plan / set. */
+void
+hb_ot_shape_glyphs_closure (hb_font_t          *font,
+                            hb_buffer_t        *buffer,
+                            const hb_feature_t *features,
+                            unsigned int        num_features,
+                            hb_set_t           *glyphs);
+
+void
+hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
+                                  hb_tag_t         table_tag,
+                                  hb_set_t        *lookup_indexes /* OUT */);
+
+HB_END_DECLS
+
+#endif /* HB_OT_SHAPE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-tag.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,931 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2011  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Roozbeh Pournader
+ */
+
+#include "hb-private.hh"
+
+#include <string.h>
+
+
+
+/* hb_script_t */
+
+static hb_tag_t
+hb_ot_old_tag_from_script (hb_script_t script)
+{
+  /* This seems to be accurate as of end of 2012. */
+
+  switch ((hb_tag_t) script) {
+    case HB_SCRIPT_INVALID:             return HB_OT_TAG_DEFAULT_SCRIPT;
+
+    /* KATAKANA and HIRAGANA both map to 'kana' */
+    case HB_SCRIPT_HIRAGANA:            return HB_TAG('k','a','n','a');
+
+    /* Spaces at the end are preserved, unlike ISO 15924 */
+    case HB_SCRIPT_LAO:                 return HB_TAG('l','a','o',' ');
+    case HB_SCRIPT_YI:                  return HB_TAG('y','i',' ',' ');
+    /* Unicode-5.0 additions */
+    case HB_SCRIPT_NKO:                 return HB_TAG('n','k','o',' ');
+    /* Unicode-5.1 additions */
+    case HB_SCRIPT_VAI:                 return HB_TAG('v','a','i',' ');
+    /* Unicode-5.2 additions */
+    /* Unicode-6.0 additions */
+  }
+
+  /* Else, just change first char to lowercase and return */
+  return ((hb_tag_t) script) | 0x20000000u;
+}
+
+static hb_script_t
+hb_ot_old_tag_to_script (hb_tag_t tag)
+{
+  if (unlikely (tag == HB_OT_TAG_DEFAULT_SCRIPT))
+    return HB_SCRIPT_INVALID;
+
+  /* This side of the conversion is fully algorithmic. */
+
+  /* Any spaces at the end of the tag are replaced by repeating the last
+   * letter.  Eg 'nko ' -> 'Nkoo' */
+  if (unlikely ((tag & 0x0000FF00u) == 0x00002000u))
+    tag |= (tag >> 8) & 0x0000FF00u; /* Copy second letter to third */
+  if (unlikely ((tag & 0x000000FFu) == 0x00000020u))
+    tag |= (tag >> 8) & 0x000000FFu; /* Copy third letter to fourth */
+
+  /* Change first char to uppercase and return */
+  return (hb_script_t) (tag & ~0x20000000u);
+}
+
+static hb_tag_t
+hb_ot_new_tag_from_script (hb_script_t script)
+{
+  switch ((hb_tag_t) script) {
+    case HB_SCRIPT_BENGALI:             return HB_TAG('b','n','g','2');
+    case HB_SCRIPT_DEVANAGARI:          return HB_TAG('d','e','v','2');
+    case HB_SCRIPT_GUJARATI:            return HB_TAG('g','j','r','2');
+    case HB_SCRIPT_GURMUKHI:            return HB_TAG('g','u','r','2');
+    case HB_SCRIPT_KANNADA:             return HB_TAG('k','n','d','2');
+    case HB_SCRIPT_MALAYALAM:           return HB_TAG('m','l','m','2');
+    case HB_SCRIPT_ORIYA:               return HB_TAG('o','r','y','2');
+    case HB_SCRIPT_TAMIL:               return HB_TAG('t','m','l','2');
+    case HB_SCRIPT_TELUGU:              return HB_TAG('t','e','l','2');
+    case HB_SCRIPT_MYANMAR:             return HB_TAG('m','y','m','2');
+  }
+
+  return HB_OT_TAG_DEFAULT_SCRIPT;
+}
+
+static hb_script_t
+hb_ot_new_tag_to_script (hb_tag_t tag)
+{
+  switch (tag) {
+    case HB_TAG('b','n','g','2'):       return HB_SCRIPT_BENGALI;
+    case HB_TAG('d','e','v','2'):       return HB_SCRIPT_DEVANAGARI;
+    case HB_TAG('g','j','r','2'):       return HB_SCRIPT_GUJARATI;
+    case HB_TAG('g','u','r','2'):       return HB_SCRIPT_GURMUKHI;
+    case HB_TAG('k','n','d','2'):       return HB_SCRIPT_KANNADA;
+    case HB_TAG('m','l','m','2'):       return HB_SCRIPT_MALAYALAM;
+    case HB_TAG('o','r','y','2'):       return HB_SCRIPT_ORIYA;
+    case HB_TAG('t','m','l','2'):       return HB_SCRIPT_TAMIL;
+    case HB_TAG('t','e','l','2'):       return HB_SCRIPT_TELUGU;
+    case HB_TAG('m','y','m','2'):       return HB_SCRIPT_MYANMAR;
+  }
+
+  return HB_SCRIPT_UNKNOWN;
+}
+
+/*
+ * Complete list at:
+ * https://www.microsoft.com/typography/otspec/scripttags.htm
+ * https://www.microsoft.com/typography/otspec160/scripttagsProposed.htm
+ *
+ * Most of the script tags are the same as the ISO 15924 tag but lowercased.
+ * So we just do that, and handle the exceptional cases in a switch.
+ */
+
+void
+hb_ot_tags_from_script (hb_script_t  script,
+                        hb_tag_t    *script_tag_1,
+                        hb_tag_t    *script_tag_2)
+{
+  hb_tag_t new_tag;
+
+  *script_tag_2 = HB_OT_TAG_DEFAULT_SCRIPT;
+  *script_tag_1 = hb_ot_old_tag_from_script (script);
+
+  new_tag = hb_ot_new_tag_from_script (script);
+  if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT)) {
+    *script_tag_2 = *script_tag_1;
+    *script_tag_1 = new_tag;
+  }
+}
+
+hb_script_t
+hb_ot_tag_to_script (hb_tag_t tag)
+{
+  if (unlikely ((tag & 0x000000FFu) == '2'))
+    return hb_ot_new_tag_to_script (tag);
+
+  return hb_ot_old_tag_to_script (tag);
+}
+
+
+/* hb_language_t */
+
+typedef struct {
+  char language[4];
+  hb_tag_t tag;
+} LangTag;
+
+/*
+ * Complete list at:
+ * http://www.microsoft.com/typography/otspec/languagetags.htm
+ *
+ * Generated by intersecting the OpenType language tag list from
+ * Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
+ * 2008-08-04, matching on name, and finally adjusted manually.
+ *
+ * Updated on 2012-12-07 with more research into remaining codes.
+ *
+ * Updated on 2013-11-23 based on usage in SIL and Microsoft fonts,
+ * the new proposal from Microsoft, and latest ISO 639-3 names.
+ *
+ * Some items still missing.  Those are commented out at the end.
+ * Keep sorted for bsearch.
+ *
+ * Updated as of 2015-05-06: OT1.7 on MS website has some newer
+ * items that we don't have here, eg. Zazaki.  This is the new
+ * items in OpenType 1.7 (red items), most of which we have:
+ * http://www.microsoft.com/typography/otspec170/languagetags.htm
+ */
+
+static const LangTag ot_languages[] = {
+  {"aa",        HB_TAG('A','F','R',' ')},       /* Afar */
+  {"ab",        HB_TAG('A','B','K',' ')},       /* Abkhazian */
+  {"abq",       HB_TAG('A','B','A',' ')},       /* Abaza */
+  {"ach",       HB_TAG('A','C','H',' ')},       /* Acoli */
+  {"ada",       HB_TAG('D','N','G',' ')},       /* Dangme */
+  {"ady",       HB_TAG('A','D','Y',' ')},       /* Adyghe */
+  {"af",        HB_TAG('A','F','K',' ')},       /* Afrikaans */
+  {"aii",       HB_TAG('S','W','A',' ')},       /* Swadaya Aramaic */
+  {"aio",       HB_TAG('A','I','O',' ')},       /* Aiton */
+  {"aiw",       HB_TAG('A','R','I',' ')},       /* Aari */
+  {"ak",        HB_TAG('T','W','I',' ')},       /* Akan [macrolanguage] */
+  {"alt",       HB_TAG('A','L','T',' ')},       /* [Southern] Altai */
+  {"am",        HB_TAG('A','M','H',' ')},       /* Amharic */
+  {"amf",       HB_TAG('H','B','N',' ')},       /* Hammer-Banna */
+  {"an",        HB_TAG('A','R','G',' ')},       /* Aragonese */
+  {"ang",       HB_TAG('A','N','G',' ')},       /* Old English (ca. 450-1100) */
+  {"ar",        HB_TAG('A','R','A',' ')},       /* Arabic [macrolanguage] */
+  {"arb",       HB_TAG('A','R','A',' ')},       /* Standard Arabic */
+  {"arn",       HB_TAG('M','A','P',' ')},       /* Mapudungun */
+  {"ary",       HB_TAG('M','O','R',' ')},       /* Moroccan Arabic */
+  {"as",        HB_TAG('A','S','M',' ')},       /* Assamese */
+  {"ast",       HB_TAG('A','S','T',' ')},       /* Asturian/Asturleonese/Bable/Leonese */
+  {"ath",       HB_TAG('A','T','H',' ')},       /* Athapaskan [family] */
+  {"atv",       HB_TAG('A','L','T',' ')},       /* [Northern] Altai */
+  {"av",        HB_TAG('A','V','R',' ')},       /* Avaric */
+  {"awa",       HB_TAG('A','W','A',' ')},       /* Awadhi */
+  {"ay",        HB_TAG('A','Y','M',' ')},       /* Aymara [macrolanguage] */
+  {"az",        HB_TAG('A','Z','E',' ')},       /* Azerbaijani [macrolanguage] */
+  {"azb",       HB_TAG('A','Z','B',' ')},       /* South Azerbaijani */
+  {"azj",       HB_TAG('A','Z','E',' ')},       /* North Azerbaijani */
+  {"ba",        HB_TAG('B','S','H',' ')},       /* Bashkir */
+  {"bai",       HB_TAG('B','M','L',' ')},       /* Bamileke [family] */
+  {"bal",       HB_TAG('B','L','I',' ')},       /* Baluchi [macrolangauge] */
+  {"ban",       HB_TAG('B','A','N',' ')},       /* Balinese */
+  {"bar",       HB_TAG('B','A','R',' ')},       /* Bavarian */
+  {"bbc",       HB_TAG('B','B','C',' ')},       /* Batak Toba */
+  {"bci",       HB_TAG('B','A','U',' ')},       /* Baoulé */
+  {"bcl",       HB_TAG('B','I','K',' ')},       /* Central Bikol */
+  {"bcq",       HB_TAG('B','C','H',' ')},       /* Bench */
+  {"be",        HB_TAG('B','E','L',' ')},       /* Belarusian */
+  {"bem",       HB_TAG('B','E','M',' ')},       /* Bemba (Zambia) */
+  {"ber",       HB_TAG('B','E','R',' ')},       /* Berber [family] */
+  {"bfq",       HB_TAG('B','A','D',' ')},       /* Badaga */
+  {"bft",       HB_TAG('B','L','T',' ')},       /* Balti */
+  {"bfy",       HB_TAG('B','A','G',' ')},       /* Baghelkhandi */
+  {"bg",        HB_TAG('B','G','R',' ')},       /* Bulgarian */
+  {"bgc",       HB_TAG('B','G','C',' ')},       /* Haryanvi */
+  {"bgq",       HB_TAG('B','G','Q',' ')},       /* Bagri */
+  {"bhb",       HB_TAG('B','H','I',' ')},       /* Bhili */
+  {"bhk",       HB_TAG('B','I','K',' ')},       /* Albay Bicolano (retired code) */
+  {"bho",       HB_TAG('B','H','O',' ')},       /* Bhojpuri */
+  {"bi",        HB_TAG('B','I','S',' ')},       /* Bislama */
+  {"bik",       HB_TAG('B','I','K',' ')},       /* Bikol [macrolanguage] */
+  {"bin",       HB_TAG('E','D','O',' ')},       /* Bini */
+  {"bjj",       HB_TAG('B','J','J',' ')},       /* Kanauji */
+  {"bjt",       HB_TAG('B','L','N',' ')},       /* Balanta-Ganja */
+  {"bla",       HB_TAG('B','K','F',' ')},       /* Blackfoot */
+  {"ble",       HB_TAG('B','L','N',' ')},       /* Balanta-Kentohe */
+  {"blk",       HB_TAG('B','L','K',' ')},       /* Pa'O/Pa'o Karen */
+  {"bln",       HB_TAG('B','I','K',' ')},       /* Southern Catanduanes Bikol */
+  {"bm",        HB_TAG('B','M','B',' ')},       /* Bambara */
+  {"bn",        HB_TAG('B','E','N',' ')},       /* Bengali */
+  {"bo",        HB_TAG('T','I','B',' ')},       /* Tibetan */
+  {"bpy",       HB_TAG('B','P','Y',' ')},       /* Bishnupriya */
+  {"bqi",       HB_TAG('L','R','C',' ')},       /* Bakhtiari */
+  {"br",        HB_TAG('B','R','E',' ')},       /* Breton */
+  {"bra",       HB_TAG('B','R','I',' ')},       /* Braj Bhasha */
+  {"brh",       HB_TAG('B','R','H',' ')},       /* Brahui */
+  {"brx",       HB_TAG('B','R','X',' ')},       /* Bodo (India) */
+  {"bs",        HB_TAG('B','O','S',' ')},       /* Bosnian */
+  {"btb",       HB_TAG('B','T','I',' ')},       /* Beti (Cameroon) */
+  {"bto",       HB_TAG('B','I','K',' ')},       /* Rinconada Bikol */
+  {"bts",       HB_TAG('B','T','S',' ')},       /* Batak Simalungun */
+  {"bug",       HB_TAG('B','U','G',' ')},       /* Buginese */
+  {"bxr",       HB_TAG('R','B','U',' ')},       /* Russian Buriat */
+  {"byn",       HB_TAG('B','I','L',' ')},       /* Bilen */
+  {"ca",        HB_TAG('C','A','T',' ')},       /* Catalan */
+  {"cbk",       HB_TAG('C','B','K',' ')},       /* Chavacano */
+  {"ce",        HB_TAG('C','H','E',' ')},       /* Chechen */
+  {"ceb",       HB_TAG('C','E','B',' ')},       /* Cebuano */
+  {"cgg",       HB_TAG('C','G','G',' ')},       /* Chiga */
+  {"ch",        HB_TAG('C','H','A',' ')},       /* Chamorro */
+  {"cho",       HB_TAG('C','H','O',' ')},       /* Choctaw */
+  {"chp",       HB_TAG('C','H','P',' ')},       /* Chipewyan */
+  {"chr",       HB_TAG('C','H','R',' ')},       /* Cherokee */
+  {"chy",       HB_TAG('C','H','Y',' ')},       /* Cheyenne */
+  {"ckb",       HB_TAG('K','U','R',' ')},       /* Central Kurdish (Sorani) */
+  {"ckt",       HB_TAG('C','H','K',' ')},       /* Chukchi */
+  {"cop",       HB_TAG('C','O','P',' ')},       /* Coptic */
+  {"cr",        HB_TAG('C','R','E',' ')},       /* Cree */
+  {"crh",       HB_TAG('C','R','T',' ')},       /* Crimean Tatar */
+  {"crj",       HB_TAG('E','C','R',' ')},       /* [Southern] East Cree */
+  {"crl",       HB_TAG('E','C','R',' ')},       /* [Northern] East Cree */
+  {"crm",       HB_TAG('M','C','R',' ')},       /* Moose Cree */
+  {"crx",       HB_TAG('C','R','R',' ')},       /* Carrier */
+  {"cs",        HB_TAG('C','S','Y',' ')},       /* Czech */
+  {"csb",       HB_TAG('C','S','B',' ')},       /* Kashubian */
+  {"ctg",       HB_TAG('C','T','G',' ')},       /* Chittagonian */
+  {"cts",       HB_TAG('B','I','K',' ')},       /* Northern Catanduanes Bikol */
+  {"cu",        HB_TAG('C','S','L',' ')},       /* Church Slavic */
+  {"cv",        HB_TAG('C','H','U',' ')},       /* Chuvash */
+  {"cwd",       HB_TAG('D','C','R',' ')},       /* Woods Cree */
+  {"cy",        HB_TAG('W','E','L',' ')},       /* Welsh */
+  {"da",        HB_TAG('D','A','N',' ')},       /* Danish */
+  {"dap",       HB_TAG('N','I','S',' ')},       /* Nisi (India) */
+  {"dar",       HB_TAG('D','A','R',' ')},       /* Dargwa */
+  {"de",        HB_TAG('D','E','U',' ')},       /* German */
+  {"dgo",       HB_TAG('D','G','O',' ')},       /* Dogri */
+  {"dhd",       HB_TAG('M','A','W',' ')},       /* Dhundari */
+  {"din",       HB_TAG('D','N','K',' ')},       /* Dinka [macrolanguage] */
+  {"diq",       HB_TAG('D','I','Q',' ')},       /* Dimli */
+  {"dje",       HB_TAG('D','J','R',' ')},       /* Zarma */
+  {"dng",       HB_TAG('D','U','N',' ')},       /* Dungan */
+  {"doi",       HB_TAG('D','G','R',' ')},       /* Dogri [macrolanguage] */
+  {"dsb",       HB_TAG('L','S','B',' ')},       /* Lower Sorbian */
+  {"dv",        HB_TAG('D','I','V',' ')},       /* Dhivehi/Divehi/Maldivian */
+  {"dyu",       HB_TAG('J','U','L',' ')},       /* Jula */
+  {"dz",        HB_TAG('D','Z','N',' ')},       /* Dzongkha */
+  {"ee",        HB_TAG('E','W','E',' ')},       /* Ewe */
+  {"efi",       HB_TAG('E','F','I',' ')},       /* Efik */
+  {"ekk",       HB_TAG('E','T','I',' ')},       /* Standard Estonian */
+  {"el",        HB_TAG('E','L','L',' ')},       /* Modern Greek (1453-) */
+  {"emk",       HB_TAG('M','N','K',' ')},       /* Eastern Maninkakan */
+  {"en",        HB_TAG('E','N','G',' ')},       /* English */
+  {"eo",        HB_TAG('N','T','O',' ')},       /* Esperanto */
+  {"eot",       HB_TAG('B','T','I',' ')},       /* Beti (Côte d'Ivoire) */
+  {"es",        HB_TAG('E','S','P',' ')},       /* Spanish */
+  {"et",        HB_TAG('E','T','I',' ')},       /* Estonian [macrolanguage] */
+  {"eu",        HB_TAG('E','U','Q',' ')},       /* Basque */
+  {"eve",       HB_TAG('E','V','N',' ')},       /* Even */
+  {"evn",       HB_TAG('E','V','K',' ')},       /* Evenki */
+  {"fa",        HB_TAG('F','A','R',' ')},       /* Persian [macrolanguage] */
+  {"ff",        HB_TAG('F','U','L',' ')},       /* Fulah [macrolanguage] */
+  {"fi",        HB_TAG('F','I','N',' ')},       /* Finnish */
+  {"fil",       HB_TAG('P','I','L',' ')},       /* Filipino */
+  {"fj",        HB_TAG('F','J','I',' ')},       /* Fijian */
+  {"fo",        HB_TAG('F','O','S',' ')},       /* Faroese */
+  {"fon",       HB_TAG('F','O','N',' ')},       /* Fon */
+  {"fr",        HB_TAG('F','R','A',' ')},       /* French */
+  {"frc",       HB_TAG('F','R','C',' ')},       /* Cajun French */
+  {"frp",       HB_TAG('F','R','P',' ')},       /* Arpitan/Francoprovençal */
+  {"fur",       HB_TAG('F','R','L',' ')},       /* Friulian */
+  {"fuv",       HB_TAG('F','U','V',' ')},       /* Nigerian Fulfulde */
+  {"fy",        HB_TAG('F','R','I',' ')},       /* Western Frisian */
+  {"ga",        HB_TAG('I','R','I',' ')},       /* Irish */
+  {"gaa",       HB_TAG('G','A','D',' ')},       /* Ga */
+  {"gag",       HB_TAG('G','A','G',' ')},       /* Gagauz */
+  {"gbm",       HB_TAG('G','A','W',' ')},       /* Garhwali */
+  {"gd",        HB_TAG('G','A','E',' ')},       /* Scottish Gaelic */
+  {"gez",       HB_TAG('G','E','Z',' ')},       /* Ge'ez */
+  {"ggo",       HB_TAG('G','O','N',' ')},       /* Southern Gondi */
+  {"gl",        HB_TAG('G','A','L',' ')},       /* Galician */
+  {"gld",       HB_TAG('N','A','N',' ')},       /* Nanai */
+  {"glk",       HB_TAG('G','L','K',' ')},       /* Gilaki */
+  {"gn",        HB_TAG('G','U','A',' ')},       /* Guarani [macrolanguage] */
+  {"gno",       HB_TAG('G','O','N',' ')},       /* Northern Gondi */
+  {"gog",       HB_TAG('G','O','G',' ')},       /* Gogo */
+  {"gon",       HB_TAG('G','O','N',' ')},       /* Gondi [macrolanguage] */
+  {"grt",       HB_TAG('G','R','O',' ')},       /* Garo */
+  {"gru",       HB_TAG('S','O','G',' ')},       /* Sodo Gurage */
+  {"gu",        HB_TAG('G','U','J',' ')},       /* Gujarati */
+  {"guc",       HB_TAG('G','U','C',' ')},       /* Wayuu */
+  {"guk",       HB_TAG('G','M','Z',' ')},       /* Gumuz */
+/*{"guk",       HB_TAG('G','U','K',' ')},*/     /* Gumuz (in SIL fonts) */
+  {"guz",       HB_TAG('G','U','Z',' ')},       /* Ekegusii/Gusii */
+  {"gv",        HB_TAG('M','N','X',' ')},       /* Manx */
+  {"ha",        HB_TAG('H','A','U',' ')},       /* Hausa */
+  {"har",       HB_TAG('H','R','I',' ')},       /* Harari */
+  {"haw",       HB_TAG('H','A','W',' ')},       /* Hawaiian */
+  {"hay",       HB_TAG('H','A','Y',' ')},       /* Haya */
+  {"haz",       HB_TAG('H','A','Z',' ')},       /* Hazaragi */
+  {"he",        HB_TAG('I','W','R',' ')},       /* Hebrew */
+  {"hz",        HB_TAG('H','E','R',' ')},       /* Herero */
+  {"hi",        HB_TAG('H','I','N',' ')},       /* Hindi */
+  {"hil",       HB_TAG('H','I','L',' ')},       /* Hiligaynon */
+  {"hnd",       HB_TAG('H','N','D',' ')},       /* [Southern] Hindko */
+  {"hne",       HB_TAG('C','H','H',' ')},       /* Chattisgarhi */
+  {"hno",       HB_TAG('H','N','D',' ')},       /* [Northern] Hindko */
+  {"ho",        HB_TAG('H','M','O',' ')},       /* Hiri Motu */
+  {"hoc",       HB_TAG('H','O',' ',' ')},       /* Ho */
+  {"hoj",       HB_TAG('H','A','R',' ')},       /* Harauti */
+  {"hr",        HB_TAG('H','R','V',' ')},       /* Croatian */
+  {"hsb",       HB_TAG('U','S','B',' ')},       /* Upper Sorbian */
+  {"ht",        HB_TAG('H','A','I',' ')},       /* Haitian/Haitian Creole */
+  {"hu",        HB_TAG('H','U','N',' ')},       /* Hungarian */
+  {"hy",        HB_TAG('H','Y','E',' ')},       /* Armenian */
+  {"hz",        HB_TAG('H','E','R',' ')},       /* Herero */
+  {"ia",        HB_TAG('I','N','A',' ')},       /* Interlingua (International Auxiliary Language Association) */
+  {"ibb",       HB_TAG('I','B','B',' ')},       /* Ibibio */
+  {"id",        HB_TAG('I','N','D',' ')},       /* Indonesian */
+  {"ie",        HB_TAG('I','L','E',' ')},       /* Interlingue/Occidental */
+  {"ig",        HB_TAG('I','B','O',' ')},       /* Igbo */
+  {"igb",       HB_TAG('E','B','I',' ')},       /* Ebira */
+  {"ijc",       HB_TAG('I','J','O',' ')},       /* Izon */
+  {"ijo",       HB_TAG('I','J','O',' ')},       /* Ijo [family] */
+  {"ik",        HB_TAG('I','P','K',' ')},       /* Inupiaq [macrolanguage] */
+  {"ilo",       HB_TAG('I','L','O',' ')},       /* Ilokano */
+  {"inh",       HB_TAG('I','N','G',' ')},       /* Ingush */
+  {"io",        HB_TAG('I','D','O',' ')},       /* Ido */
+  {"is",        HB_TAG('I','S','L',' ')},       /* Icelandic */
+  {"it",        HB_TAG('I','T','A',' ')},       /* Italian */
+  {"iu",        HB_TAG('I','N','U',' ')},       /* Inuktitut [macrolanguage] */
+  {"ja",        HB_TAG('J','A','N',' ')},       /* Japanese */
+  {"jam",       HB_TAG('J','A','M',' ')},       /* Jamaican Creole English */
+  {"jbo",       HB_TAG('J','B','O',' ')},       /* Lojban */
+  {"jv",        HB_TAG('J','A','V',' ')},       /* Javanese */
+  {"ka",        HB_TAG('K','A','T',' ')},       /* Georgian */
+  {"kaa",       HB_TAG('K','R','K',' ')},       /* Karakalpak */
+  {"kab",       HB_TAG('K','A','B',' ')},       /* Kabyle */
+  {"kam",       HB_TAG('K','M','B',' ')},       /* Kamba (Kenya) */
+  {"kar",       HB_TAG('K','R','N',' ')},       /* Karen [family] */
+  {"kbd",       HB_TAG('K','A','B',' ')},       /* Kabardian */
+  {"kde",       HB_TAG('K','D','E',' ')},       /* Makonde */
+  {"kdr",       HB_TAG('K','R','M',' ')},       /* Karaim */
+  {"kdt",       HB_TAG('K','U','Y',' ')},       /* Kuy */
+  {"kex",       HB_TAG('K','K','N',' ')},       /* Kokni */
+  {"kfr",       HB_TAG('K','A','C',' ')},       /* Kachchi */
+  {"kfy",       HB_TAG('K','M','N',' ')},       /* Kumaoni */
+  {"kg",        HB_TAG('K','O','N',' ')},       /* Kongo [macrolanguage] */
+  {"kha",       HB_TAG('K','S','I',' ')},       /* Khasi */
+  {"khb",       HB_TAG('X','B','D',' ')},       /* Lü */
+  {"kht",       HB_TAG('K','H','N',' ')},       /* Khamti (Microsoft fonts) */
+/*{"kht",       HB_TAG('K','H','T',' ')},*/     /* Khamti (OpenType spec and SIL fonts) */
+  {"khw",       HB_TAG('K','H','W',' ')},       /* Khowar */
+  {"ki",        HB_TAG('K','I','K',' ')},       /* Gikuyu/Kikuyu */
+  {"kj",        HB_TAG('K','U','A',' ')},       /* Kuanyama/Kwanyama */
+  {"kjh",       HB_TAG('K','H','A',' ')},       /* Khakass */
+  {"kjp",       HB_TAG('K','J','P',' ')},       /* Pwo Eastern Karen */
+  {"kk",        HB_TAG('K','A','Z',' ')},       /* Kazakh */
+  {"kl",        HB_TAG('G','R','N',' ')},       /* Kalaallisut */
+  {"kln",       HB_TAG('K','A','L',' ')},       /* Kalenjin */
+  {"km",        HB_TAG('K','H','M',' ')},       /* Central Khmer */
+  {"kmb",       HB_TAG('M','B','N',' ')},       /* Kimbundu */
+  {"kmw",       HB_TAG('K','M','O',' ')},       /* Komo (Democratic Republic of Congo) */
+  {"kn",        HB_TAG('K','A','N',' ')},       /* Kannada */
+  {"knn",       HB_TAG('K','O','K',' ')},       /* Konkani */
+  {"ko",        HB_TAG('K','O','R',' ')},       /* Korean */
+  {"koi",       HB_TAG('K','O','P',' ')},       /* Komi-Permyak */
+  {"kok",       HB_TAG('K','O','K',' ')},       /* Konkani [macrolanguage] */
+  {"kpe",       HB_TAG('K','P','L',' ')},       /* Kpelle [macrolanguage] */
+  {"kpv",       HB_TAG('K','O','Z',' ')},       /* Komi-Zyrian */
+  {"kpy",       HB_TAG('K','Y','K',' ')},       /* Koryak */
+  {"kqy",       HB_TAG('K','R','T',' ')},       /* Koorete */
+  {"kr",        HB_TAG('K','N','R',' ')},       /* Kanuri [macrolanguage] */
+  {"kri",       HB_TAG('K','R','I',' ')},       /* Krio */
+  {"krl",       HB_TAG('K','R','L',' ')},       /* Karelian */
+  {"kru",       HB_TAG('K','U','U',' ')},       /* Kurukh */
+  {"ks",        HB_TAG('K','S','H',' ')},       /* Kashmiri */
+  {"ksh",       HB_TAG('K','S','H',' ')},       /* Kölsch */
+/*{"ksw",       HB_TAG('K','R','N',' ')},*/     /* S'gaw Karen (Microsoft fonts?) */
+  {"ksw",       HB_TAG('K','S','W',' ')},       /* S'gaw Karen (OpenType spec and SIL fonts) */
+  {"ku",        HB_TAG('K','U','R',' ')},       /* Kurdish [macrolanguage] */
+  {"kum",       HB_TAG('K','U','M',' ')},       /* Kumyk */
+  {"kv",        HB_TAG('K','O','M',' ')},       /* Komi [macrolanguage] */
+  {"kvd",       HB_TAG('K','U','I',' ')},       /* Kui (Indonesia) */
+  {"kw",        HB_TAG('C','O','R',' ')},       /* Cornish */
+  {"kxc",       HB_TAG('K','M','S',' ')},       /* Komso */
+  {"kxu",       HB_TAG('K','U','I',' ')},       /* Kui (India) */
+  {"ky",        HB_TAG('K','I','R',' ')},       /* Kirghiz/Kyrgyz */
+  {"kyu",       HB_TAG('K','Y','U',' ')},       /* Western Kayah */
+  {"la",        HB_TAG('L','A','T',' ')},       /* Latin */
+  {"lad",       HB_TAG('J','U','D',' ')},       /* Ladino */
+  {"lb",        HB_TAG('L','T','Z',' ')},       /* Luxembourgish */
+  {"lbe",       HB_TAG('L','A','K',' ')},       /* Lak */
+  {"lbj",       HB_TAG('L','D','K',' ')},       /* Ladakhi */
+  {"lez",       HB_TAG('L','E','Z',' ')},       /* Lezgi */
+  {"lg",        HB_TAG('L','U','G',' ')},       /* Ganda */
+  {"li",        HB_TAG('L','I','M',' ')},       /* Limburgan/Limburger/Limburgish */
+  {"lif",       HB_TAG('L','M','B',' ')},       /* Limbu */
+  {"lij",       HB_TAG('L','I','J',' ')},       /* Ligurian */
+  {"lis",       HB_TAG('L','I','S',' ')},       /* Lisu */
+  {"ljp",       HB_TAG('L','J','P',' ')},       /* Lampung Api */
+  {"lki",       HB_TAG('L','K','I',' ')},       /* Laki */
+  {"lld",       HB_TAG('L','A','D',' ')},       /* Ladin */
+  {"lmn",       HB_TAG('L','A','M',' ')},       /* Lambani */
+  {"lmo",       HB_TAG('L','M','O',' ')},       /* Lombard */
+  {"ln",        HB_TAG('L','I','N',' ')},       /* Lingala */
+  {"lo",        HB_TAG('L','A','O',' ')},       /* Lao */
+  {"lrc",       HB_TAG('L','R','C',' ')},       /* Northern Luri */
+  {"lt",        HB_TAG('L','T','H',' ')},       /* Lithuanian */
+  {"lu",        HB_TAG('L','U','B',' ')},       /* Luba-Katanga */
+  {"lua",       HB_TAG('L','U','B',' ')},       /* Luba-Kasai */
+  {"luo",       HB_TAG('L','U','O',' ')},       /* Luo (Kenya and Tanzania) */
+  {"lus",       HB_TAG('M','I','Z',' ')},       /* Mizo */
+  {"luy",       HB_TAG('L','U','H',' ')},       /* Luyia/Oluluyia [macrolanguage] */
+  {"luz",       HB_TAG('L','R','C',' ')},       /* Southern Luri */
+  {"lv",        HB_TAG('L','V','I',' ')},       /* Latvian */
+  {"lzz",       HB_TAG('L','A','Z',' ')},       /* Laz */
+  {"mad",       HB_TAG('M','A','D',' ')},       /* Madurese */
+  {"mag",       HB_TAG('M','A','G',' ')},       /* Magahi */
+  {"mai",       HB_TAG('M','T','H',' ')},       /* Maithili */
+  {"mak",       HB_TAG('M','K','R',' ')},       /* Makasar */
+  {"man",       HB_TAG('M','N','K',' ')},       /* Manding/Mandingo [macrolanguage] */
+  {"mdc",       HB_TAG('M','L','E',' ')},       /* Male (Papua New Guinea) */
+  {"mdf",       HB_TAG('M','O','K',' ')},       /* Moksha */
+  {"mdr",       HB_TAG('M','D','R',' ')},       /* Mandar */
+  {"mdy",       HB_TAG('M','L','E',' ')},       /* Male (Ethiopia) */
+  {"men",       HB_TAG('M','D','E',' ')},       /* Mende (Sierra Leone) */
+  {"mer",       HB_TAG('M','E','R',' ')},       /* Meru */
+  {"mfe",       HB_TAG('M','F','E',' ')},       /* Morisyen */
+  {"mg",        HB_TAG('M','L','G',' ')},       /* Malagasy [macrolanguage] */
+  {"mh",        HB_TAG('M','A','H',' ')},       /* Marshallese */
+  {"mhr",       HB_TAG('L','M','A',' ')},       /* Low Mari */
+  {"mi",        HB_TAG('M','R','I',' ')},       /* Maori */
+  {"min",       HB_TAG('M','I','N',' ')},       /* Minangkabau */
+  {"mk",        HB_TAG('M','K','D',' ')},       /* Macedonian */
+  {"mku",       HB_TAG('M','N','K',' ')},       /* Konyanka Maninka */
+  {"mkw",       HB_TAG('M','K','W',' ')},       /* Kituba (Congo) */
+  {"ml",        HB_TAG('M','L','R',' ')},       /* Malayalam */
+  {"mlq",       HB_TAG('M','N','K',' ')},       /* Western Maninkakan */
+  {"mn",        HB_TAG('M','N','G',' ')},       /* Mongolian [macrolanguage] */
+  {"mnc",       HB_TAG('M','C','H',' ')},       /* Manchu */
+  {"mni",       HB_TAG('M','N','I',' ')},       /* Manipuri */
+  {"mnk",       HB_TAG('M','N','D',' ')},       /* Mandinka */
+  {"mns",       HB_TAG('M','A','N',' ')},       /* Mansi */
+  {"mnw",       HB_TAG('M','O','N',' ')},       /* Mon */
+  {"mo",        HB_TAG('M','O','L',' ')},       /* Moldavian */
+  {"moh",       HB_TAG('M','O','H',' ')},       /* Mohawk */
+  {"mos",       HB_TAG('M','O','S',' ')},       /* Mossi */
+  {"mpe",       HB_TAG('M','A','J',' ')},       /* Majang */
+  {"mr",        HB_TAG('M','A','R',' ')},       /* Marathi */
+  {"mrj",       HB_TAG('H','M','A',' ')},       /* High Mari */
+  {"ms",        HB_TAG('M','L','Y',' ')},       /* Malay [macrolanguage] */
+  {"msc",       HB_TAG('M','N','K',' ')},       /* Sankaran Maninka */
+  {"mt",        HB_TAG('M','T','S',' ')},       /* Maltese */
+  {"mtr",       HB_TAG('M','A','W',' ')},       /* Mewari */
+  {"mus",       HB_TAG('M','U','S',' ')},       /* Creek */
+  {"mve",       HB_TAG('M','A','W',' ')},       /* Marwari (Pakistan) */
+  {"mwk",       HB_TAG('M','N','K',' ')},       /* Kita Maninkakan */
+  {"mwl",       HB_TAG('M','W','L',' ')},       /* Mirandese */
+  {"mwr",       HB_TAG('M','A','W',' ')},       /* Marwari [macrolanguage] */
+  {"mww",       HB_TAG('M','W','W',' ')},       /* Hmong Daw */
+  {"my",        HB_TAG('B','R','M',' ')},       /* Burmese */
+  {"mym",       HB_TAG('M','E','N',' ')},       /* Me'en */
+  {"myq",       HB_TAG('M','N','K',' ')},       /* Forest Maninka (retired code) */
+  {"myv",       HB_TAG('E','R','Z',' ')},       /* Erzya */
+  {"mzn",       HB_TAG('M','Z','N',' ')},       /* Mazanderani */
+  {"na",        HB_TAG('N','A','U',' ')},       /* Nauru */
+  {"nag",       HB_TAG('N','A','G',' ')},       /* Naga-Assamese */
+  {"nah",       HB_TAG('N','A','H',' ')},       /* Nahuatl [family] */
+  {"nap",       HB_TAG('N','A','P',' ')},       /* Neapolitan */
+  {"nb",        HB_TAG('N','O','R',' ')},       /* Norwegian Bokmål */
+  {"nco",       HB_TAG('S','I','B',' ')},       /* Sibe */
+  {"nd",        HB_TAG('N','D','B',' ')},       /* [North] Ndebele */
+  {"ndc",       HB_TAG('N','D','C',' ')},       /* Ndau */
+  {"nds",       HB_TAG('N','D','S',' ')},       /* Low German/Low Saxon */
+  {"ne",        HB_TAG('N','E','P',' ')},       /* Nepali */
+  {"new",       HB_TAG('N','E','W',' ')},       /* Newari */
+  {"ng",        HB_TAG('N','D','G',' ')},       /* Ndonga */
+  {"nga",       HB_TAG('N','G','A',' ')},       /* Ngabaka */
+  {"ngl",       HB_TAG('L','M','W',' ')},       /* Lomwe */
+  {"niu",       HB_TAG('N','I','U',' ')},       /* Niuean */
+  {"niv",       HB_TAG('G','I','L',' ')},       /* Gilyak */
+  {"nl",        HB_TAG('N','L','D',' ')},       /* Dutch */
+  {"nn",        HB_TAG('N','Y','N',' ')},       /* Norwegian Nynorsk */
+  {"no",        HB_TAG('N','O','R',' ')},       /* Norwegian [macrolanguage] */
+  {"nod",       HB_TAG('N','T','A',' ')},       /* Northern Thai */
+  {"noe",       HB_TAG('N','O','E',' ')},       /* Nimadi */
+  {"nog",       HB_TAG('N','O','G',' ')},       /* Nogai */
+  {"nov",       HB_TAG('N','O','V',' ')},       /* Novial */
+  {"nqo",       HB_TAG('N','K','O',' ')},       /* N'Ko */
+  {"nr",        HB_TAG('N','D','B',' ')},       /* [South] Ndebele */
+  {"nsk",       HB_TAG('N','A','S',' ')},       /* Naskapi */
+  {"nso",       HB_TAG('S','O','T',' ')},       /* [Northern] Sotho */
+  {"nv",        HB_TAG('N','A','V',' ')},       /* Navajo */
+  {"ny",        HB_TAG('C','H','I',' ')},       /* Chewa/Chichwa/Nyanja */
+  {"nym",       HB_TAG('N','Y','M',' ')},       /* Nyamwezi */
+  {"nyn",       HB_TAG('N','K','L',' ')},       /* Nyankole */
+  {"oc",        HB_TAG('O','C','I',' ')},       /* Occitan (post 1500) */
+  {"oj",        HB_TAG('O','J','B',' ')},       /* Ojibwa [macrolanguage] */
+  {"ojs",       HB_TAG('O','C','R',' ')},       /* Oji-Cree */
+  {"om",        HB_TAG('O','R','O',' ')},       /* Oromo [macrolanguage] */
+  {"or",        HB_TAG('O','R','I',' ')},       /* Oriya */
+  {"os",        HB_TAG('O','S','S',' ')},       /* Ossetian */
+  {"pa",        HB_TAG('P','A','N',' ')},       /* Panjabi */
+  {"pag",       HB_TAG('P','A','G',' ')},       /* Pangasinan */
+  {"pam",       HB_TAG('P','A','M',' ')},       /* Kapampangan/Pampanga */
+  {"pap",       HB_TAG('P','A','P',' ')},       /* Papiamento */
+  {"pcc",       HB_TAG('P','C','C',' ')},       /* Bouyei */
+  {"pcd",       HB_TAG('P','C','D',' ')},       /* Picard */
+  {"pce",       HB_TAG('P','L','G',' ')},       /* [Ruching] Palaung */
+  {"pdc",       HB_TAG('P','D','C',' ')},       /* Pennsylvania German */
+  {"pes",       HB_TAG('F','A','R',' ')},       /* Iranian Persian */
+  {"phk",       HB_TAG('P','H','K',' ')},       /* Phake */
+  {"pi",        HB_TAG('P','A','L',' ')},       /* Pali */
+  {"pih",       HB_TAG('P','I','H',' ')},       /* Pitcairn-Norfolk */
+  {"pl",        HB_TAG('P','L','K',' ')},       /* Polish */
+  {"pll",       HB_TAG('P','L','G',' ')},       /* [Shwe] Palaung */
+  {"plp",       HB_TAG('P','A','P',' ')},       /* Palpa */
+  {"pms",       HB_TAG('P','M','S',' ')},       /* Piemontese */
+  {"pnb",       HB_TAG('P','N','B',' ')},       /* Western Panjabi */
+  {"prs",       HB_TAG('D','R','I',' ')},       /* Afghan Persian/Dari */
+  {"ps",        HB_TAG('P','A','S',' ')},       /* Pashto/Pushto [macrolanguage] */
+  {"pt",        HB_TAG('P','T','G',' ')},       /* Portuguese */
+  {"pwo",       HB_TAG('P','W','O',' ')},       /* Pwo Western Karen */
+  {"qu",        HB_TAG('Q','U','Z',' ')},       /* Quechua [macrolanguage] */
+  {"quc",       HB_TAG('Q','U','C',' ')},       /* K'iche'/Quiché */
+  {"quz",       HB_TAG('Q','U','Z',' ')},       /* Cusco Quechua */
+  {"raj",       HB_TAG('R','A','J',' ')},       /* Rajasthani [macrolanguage] */
+  {"rbb",       HB_TAG('P','L','G',' ')},       /* Rumai Palaung */
+  {"rej",       HB_TAG('R','E','J',' ')},       /* Rejang */
+  {"ria",       HB_TAG('R','I','A',' ')},       /* Riang (India) */
+  {"ril",       HB_TAG('R','I','A',' ')},       /* Riang (Myanmar) */
+  {"rki",       HB_TAG('A','R','K',' ')},       /* Rakhine */
+  {"rm",        HB_TAG('R','M','S',' ')},       /* Romansh */
+  {"rmy",       HB_TAG('R','M','Y',' ')},       /* Vlax Romani */
+  {"rn",        HB_TAG('R','U','N',' ')},       /* Rundi */
+  {"ro",        HB_TAG('R','O','M',' ')},       /* Romanian */
+  {"rom",       HB_TAG('R','O','Y',' ')},       /* Romany [macrolanguage] */
+  {"ru",        HB_TAG('R','U','S',' ')},       /* Russian */
+  {"rue",       HB_TAG('R','S','Y',' ')},       /* Rusyn */
+  {"rup",       HB_TAG('R','U','P',' ')},       /* Aromanian/Arumanian/Macedo-Romanian */
+  {"rw",        HB_TAG('R','U','A',' ')},       /* Kinyarwanda */
+  {"rwr",       HB_TAG('M','A','W',' ')},       /* Marwari (India) */
+  {"sa",        HB_TAG('S','A','N',' ')},       /* Sanskrit */
+  {"sah",       HB_TAG('Y','A','K',' ')},       /* Yakut */
+  {"sas",       HB_TAG('S','A','S',' ')},       /* Sasak */
+  {"sat",       HB_TAG('S','A','T',' ')},       /* Santali */
+  {"sck",       HB_TAG('S','A','D',' ')},       /* Sadri */
+  {"sc",        HB_TAG('S','R','D',' ')},       /* Sardinian [macrolanguage] */
+  {"scn",       HB_TAG('S','C','N',' ')},       /* Sicilian */
+  {"sco",       HB_TAG('S','C','O',' ')},       /* Scots */
+  {"scs",       HB_TAG('S','L','A',' ')},       /* [North] Slavey */
+  {"sd",        HB_TAG('S','N','D',' ')},       /* Sindhi */
+  {"se",        HB_TAG('N','S','M',' ')},       /* Northern Sami */
+  {"seh",       HB_TAG('S','N','A',' ')},       /* Sena */
+  {"sel",       HB_TAG('S','E','L',' ')},       /* Selkup */
+  {"sg",        HB_TAG('S','G','O',' ')},       /* Sango */
+  {"sga",       HB_TAG('S','G','A',' ')},       /* Old Irish (to 900) */
+  {"sgs",       HB_TAG('S','G','S',' ')},       /* Samogitian */
+  {"sgw",       HB_TAG('C','H','G',' ')},       /* Sebat Bet Gurage */
+/*{"sgw",       HB_TAG('S','G','W',' ')},*/     /* Sebat Bet Gurage (in SIL fonts) */
+  {"shn",       HB_TAG('S','H','N',' ')},       /* Shan */
+  {"si",        HB_TAG('S','N','H',' ')},       /* Sinhala */
+  {"sid",       HB_TAG('S','I','D',' ')},       /* Sidamo */
+  {"sjd",       HB_TAG('K','S','M',' ')},       /* Kildin Sami */
+  {"sk",        HB_TAG('S','K','Y',' ')},       /* Slovak */
+  {"skr",       HB_TAG('S','R','K',' ')},       /* Seraiki */
+  {"sl",        HB_TAG('S','L','V',' ')},       /* Slovenian */
+  {"sm",        HB_TAG('S','M','O',' ')},       /* Samoan */
+  {"sma",       HB_TAG('S','S','M',' ')},       /* Southern Sami */
+  {"smj",       HB_TAG('L','S','M',' ')},       /* Lule Sami */
+  {"smn",       HB_TAG('I','S','M',' ')},       /* Inari Sami */
+  {"sms",       HB_TAG('S','K','S',' ')},       /* Skolt Sami */
+  {"sn",        HB_TAG('S','N','A',' ')},       /* Shona */
+  {"snk",       HB_TAG('S','N','K',' ')},       /* Soninke */
+  {"so",        HB_TAG('S','M','L',' ')},       /* Somali */
+  {"sop",       HB_TAG('S','O','P',' ')},       /* Songe */
+  {"sq",        HB_TAG('S','Q','I',' ')},       /* Albanian [macrolanguage] */
+  {"sr",        HB_TAG('S','R','B',' ')},       /* Serbian */
+  {"srr",       HB_TAG('S','R','R',' ')},       /* Serer */
+  {"ss",        HB_TAG('S','W','Z',' ')},       /* Swati */
+  {"st",        HB_TAG('S','O','T',' ')},       /* [Southern] Sotho */
+  {"stq",       HB_TAG('S','T','Q',' ')},       /* Saterfriesisch */
+  {"stv",       HB_TAG('S','I','G',' ')},       /* Silt'e */
+  {"su",        HB_TAG('S','U','N',' ')},       /* Sundanese */
+  {"suk",       HB_TAG('S','U','K',' ')},       /* Sukama */
+  {"suq",       HB_TAG('S','U','R',' ')},       /* Suri */
+  {"sv",        HB_TAG('S','V','E',' ')},       /* Swedish */
+  {"sva",       HB_TAG('S','V','A',' ')},       /* Svan */
+  {"sw",        HB_TAG('S','W','K',' ')},       /* Swahili [macrolanguage] */
+  {"swb",       HB_TAG('C','M','R',' ')},       /* Comorian */
+  {"swh",       HB_TAG('S','W','K',' ')},       /* Kiswahili/Swahili */
+  {"swv",       HB_TAG('M','A','W',' ')},       /* Shekhawati */
+  {"sxu",       HB_TAG('S','X','U',' ')},       /* Upper Saxon */
+  {"syl",       HB_TAG('S','Y','L',' ')},       /* Sylheti */
+  {"syr",       HB_TAG('S','Y','R',' ')},       /* Syriac [macrolanguage] */
+  {"szl",       HB_TAG('S','Z','L',' ')},       /* Silesian */
+  {"ta",        HB_TAG('T','A','M',' ')},       /* Tamil */
+  {"tab",       HB_TAG('T','A','B',' ')},       /* Tabasaran */
+  {"tcy",       HB_TAG('T','U','L',' ')},       /* Tulu */
+  {"tdd",       HB_TAG('T','D','D',' ')},       /* Tai Nüa */
+  {"te",        HB_TAG('T','E','L',' ')},       /* Telugu */
+  {"tem",       HB_TAG('T','M','N',' ')},       /* Temne */
+  {"tet",       HB_TAG('T','E','T',' ')},       /* Tetum */
+  {"tg",        HB_TAG('T','A','J',' ')},       /* Tajik */
+  {"th",        HB_TAG('T','H','A',' ')},       /* Thai */
+  {"ti",        HB_TAG('T','G','Y',' ')},       /* Tigrinya */
+  {"tig",       HB_TAG('T','G','R',' ')},       /* Tigre */
+  {"tiv",       HB_TAG('T','I','V',' ')},       /* Tiv */
+  {"tk",        HB_TAG('T','K','M',' ')},       /* Turkmen */
+  {"tl",        HB_TAG('T','G','L',' ')},       /* Tagalog */
+  {"tmh",       HB_TAG('t','m','h',' ')},       /* Tamashek [macrolanguage] */
+  {"tn",        HB_TAG('T','N','A',' ')},       /* Tswana */
+  {"to",        HB_TAG('T','G','N',' ')},       /* Tonga (Tonga Islands) */
+  {"tpi",       HB_TAG('T','P','I',' ')},       /* Tok Pisin */
+  {"tr",        HB_TAG('T','R','K',' ')},       /* Turkish */
+  {"tru",       HB_TAG('T','U','A',' ')},       /* Turoyo Aramaic */
+  {"ts",        HB_TAG('T','S','G',' ')},       /* Tsonga */
+  {"tt",        HB_TAG('T','A','T',' ')},       /* Tatar */
+  {"tum",       HB_TAG('T','U','M',' ')},       /* Tumbuka */
+  {"tw",        HB_TAG('T','W','I',' ')},       /* Twi */
+  {"ty",        HB_TAG('T','H','T',' ')},       /* Tahitian */
+  {"tyv",       HB_TAG('T','U','V',' ')},       /* Tuvin */
+  {"tyz",       HB_TAG('T','Y','Z',' ')},       /* Tày */
+  {"tzm",       HB_TAG('T','Z','M',' ')},       /* Central Atlas Tamazight */
+  {"udm",       HB_TAG('U','D','M',' ')},       /* Udmurt */
+  {"ug",        HB_TAG('U','Y','G',' ')},       /* Uighur */
+  {"uk",        HB_TAG('U','K','R',' ')},       /* Ukrainian */
+  {"umb",       HB_TAG('U','M','B',' ')},       /* Umbundu */
+  {"unr",       HB_TAG('M','U','N',' ')},       /* Mundari */
+  {"ur",        HB_TAG('U','R','D',' ')},       /* Urdu */
+  {"uz",        HB_TAG('U','Z','B',' ')},       /* Uzbek [macrolanguage] */
+  {"uzn",       HB_TAG('U','Z','B',' ')},       /* Northern Uzbek */
+  {"uzs",       HB_TAG('U','Z','B',' ')},       /* Southern Uzbek */
+  {"ve",        HB_TAG('V','E','N',' ')},       /* Venda */
+  {"vec",       HB_TAG('V','E','C',' ')},       /* Venetian */
+  {"vls",       HB_TAG('F','L','E',' ')},       /* Vlaams */
+  {"vi",        HB_TAG('V','I','T',' ')},       /* Vietnamese */
+  {"vmw",       HB_TAG('M','A','K',' ')},       /* Makhuwa */
+  {"vo",        HB_TAG('V','O','L',' ')},       /* Volapük */
+  {"vro",       HB_TAG('V','R','O',' ')},       /* Võro */
+  {"wa",        HB_TAG('W','L','N',' ')},       /* Walloon */
+  {"war",       HB_TAG('W','A','R',' ')},       /* Waray (Philippines) */
+  {"wbm",       HB_TAG('W','A',' ',' ')},       /* Wa */
+  {"wbr",       HB_TAG('W','A','G',' ')},       /* Wagdi */
+  {"wle",       HB_TAG('S','I','G',' ')},       /* Wolane */
+  {"wry",       HB_TAG('M','A','W',' ')},       /* Merwari */
+  {"wtm",       HB_TAG('W','T','M',' ')},       /* Mewati */
+  {"wo",        HB_TAG('W','L','F',' ')},       /* Wolof */
+  {"xal",       HB_TAG('K','L','M',' ')},       /* Kalmyk */
+  {"xh",        HB_TAG('X','H','S',' ')},       /* Xhosa */
+  {"xog",       HB_TAG('X','O','G',' ')},       /* Soga */
+  {"xom",       HB_TAG('K','M','O',' ')},       /* Komo (Sudan) */
+  {"xsl",       HB_TAG('S','S','L',' ')},       /* South Slavey */
+  {"xst",       HB_TAG('S','I','G',' ')},       /* Silt'e (retired code) */
+  {"xwo",       HB_TAG('T','O','D',' ')},       /* Written Oirat (Todo) */
+  {"yao",       HB_TAG('Y','A','O',' ')},       /* Yao */
+  {"yi",        HB_TAG('J','I','I',' ')},       /* Yiddish [macrolanguage] */
+  {"yo",        HB_TAG('Y','B','A',' ')},       /* Yoruba */
+  {"yso",       HB_TAG('N','I','S',' ')},       /* Nisi (China) */
+  {"za",        HB_TAG('Z','H','A',' ')},       /* Chuang/Zhuang [macrolanguage] */
+  {"zea",       HB_TAG('Z','E','A',' ')},       /* Zeeuws */
+  {"zne",       HB_TAG('Z','N','D',' ')},       /* Zande */
+  {"zu",        HB_TAG('Z','U','L',' ')},       /* Zulu */
+  {"zum",       HB_TAG('L','R','C',' ')}        /* Kumzari */
+
+  /* The corresponding languages IDs for the following IDs are unclear,
+   * overlap, or are architecturally weird. Needs more research. */
+
+/*{"ahg/awn/xan?",      HB_TAG('A','G','W',' ')},*/     /* Agaw */
+/*{"gsw?/gsw-FR?",      HB_TAG('A','L','S',' ')},*/     /* Alsatian */
+/*{"krc",       HB_TAG('B','A','L',' ')},*/     /* Balkar */
+/*{"??",        HB_TAG('B','C','R',' ')},*/     /* Bible Cree */
+/*{"zh?",       HB_TAG('C','H','N',' ')},*/     /* Chinese (seen in Microsoft fonts) */
+/*{"acf/gcf?",  HB_TAG('F','A','N',' ')},*/     /* French Antillean */
+/*{"enf?/yrk?", HB_TAG('F','N','E',' ')},*/     /* Forest Nenets */
+/*{"fuf?",      HB_TAG('F','T','A',' ')},*/     /* Futa */
+/*{"ar-Syrc?",  HB_TAG('G','A','R',' ')},*/     /* Garshuni */
+/*{"cfm/rnl?",  HB_TAG('H','A','L',' ')},*/     /* Halam */
+/*{"ga-Latg?/Latg?",    HB_TAG('I','R','T',' ')},*/     /* Irish Traditional */
+/*{"krc",       HB_TAG('K','A','R',' ')},*/     /* Karachay */
+/*{"alw?/ktb?", HB_TAG('K','E','B',' ')},*/     /* Kebena */
+/*{"Geok",      HB_TAG('K','G','E',' ')},*/     /* Khutsuri Georgian */
+/*{"kca",       HB_TAG('K','H','K',' ')},*/     /* Khanty-Kazim */
+/*{"kca",       HB_TAG('K','H','S',' ')},*/     /* Khanty-Shurishkar */
+/*{"kca",       HB_TAG('K','H','V',' ')},*/     /* Khanty-Vakhi */
+/*{"guz?/kqs?/kss?",    HB_TAG('K','I','S',' ')},*/     /* Kisii */
+/*{"kfa/kfi?/kpb?/xua?/xuj?",   HB_TAG('K','O','D',' ')},*/     /* Kodagu */
+/*{"okm?/oko?", HB_TAG('K','O','H',' ')},*/     /* Korean Old Hangul */
+/*{"kon?/ktu?/...",     HB_TAG('K','O','N',' ')},*/     /* Kikongo */
+/*{"kfx?",      HB_TAG('K','U','L',' ')},*/     /* Kulvi */
+/*{"??",        HB_TAG('L','A','H',' ')},*/     /* Lahuli */
+/*{"??",        HB_TAG('L','C','R',' ')},*/     /* L-Cree */
+/*{"??",        HB_TAG('M','A','L',' ')},*/     /* Malayalam Traditional */
+/*{"mnk?/mlq?/...",     HB_TAG('M','L','N',' ')},*/     /* Malinke */
+/*{"??",        HB_TAG('N','C','R',' ')},*/     /* N-Cree */
+/*{"??",        HB_TAG('N','H','C',' ')},*/     /* Norway House Cree */
+/*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/     /* Palestinian Aramaic */
+/*{"polyton",   HB_TAG('P','G','R',' ')},*/     /* Polytonic Greek */
+/*{"??",        HB_TAG('Q','I','N',' ')},*/     /* Asho Chin */
+/*{"??",        HB_TAG('R','C','R',' ')},*/     /* R-Cree */
+/*{"chp?",      HB_TAG('S','A','Y',' ')},*/     /* Sayisi */
+/*{"xan?",      HB_TAG('S','E','K',' ')},*/     /* Sekota */
+/*{"ngo?",      HB_TAG('S','X','T',' ')},*/     /* Sutu */
+/*{"??",        HB_TAG('T','C','R',' ')},*/     /* TH-Cree */
+/*{"tnz?/tog?/toi?",    HB_TAG('T','N','G',' ')},*/     /* Tonga */
+/*{"enh?/yrk?", HB_TAG('T','N','E',' ')},*/     /* Tundra Nenets */
+/*{"??",        HB_TAG('W','C','R',' ')},*/     /* West-Cree */
+/*{"cre?",      HB_TAG('Y','C','R',' ')},*/     /* Y-Cree */
+/*{"??",        HB_TAG('Y','I','C',' ')},*/     /* Yi Classic */
+/*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/     /* Yi Modern */
+/*{"??",        HB_TAG('Z','H','P',' ')},*/     /* Chinese Phonetic */
+};
+
+typedef struct {
+  char language[8];
+  hb_tag_t tag;
+} LangTagLong;
+static const LangTagLong ot_languages_zh[] = {
+  {"zh-cn",     HB_TAG('Z','H','S',' ')},       /* Chinese (China) */
+  {"zh-hk",     HB_TAG('Z','H','H',' ')},       /* Chinese (Hong Kong) */
+  {"zh-mo",     HB_TAG('Z','H','T',' ')},       /* Chinese (Macao) */
+  {"zh-sg",     HB_TAG('Z','H','S',' ')},       /* Chinese (Singapore) */
+  {"zh-tw",     HB_TAG('Z','H','T',' ')},       /* Chinese (Taiwan) */
+  {"zh-hans",   HB_TAG('Z','H','S',' ')},       /* Chinese (Simplified) */
+  {"zh-hant",   HB_TAG('Z','H','T',' ')},       /* Chinese (Traditional) */
+};
+
+static int
+lang_compare_first_component (const char *a,
+                              const char *b)
+{
+  unsigned int da, db;
+  const char *p;
+
+  p = strchr (a, '-');
+  da = p ? (unsigned int) (p - a) : strlen (a);
+
+  p = strchr (b, '-');
+  db = p ? (unsigned int) (p - b) : strlen (b);
+
+  return strncmp (a, b, MAX (da, db));
+}
+
+static hb_bool_t
+lang_matches (const char *lang_str, const char *spec)
+{
+  unsigned int len = strlen (spec);
+
+  return strncmp (lang_str, spec, len) == 0 &&
+         (lang_str[len] == '\0' || lang_str[len] == '-');
+}
+
+hb_tag_t
+hb_ot_tag_from_language (hb_language_t language)
+{
+  const char *lang_str, *s;
+
+  if (language == HB_LANGUAGE_INVALID)
+    return HB_OT_TAG_DEFAULT_LANGUAGE;
+
+  lang_str = hb_language_to_string (language);
+
+  s = strstr (lang_str, "x-hbot");
+  if (s) {
+    char tag[4];
+    int i;
+    s += 6;
+    for (i = 0; i < 4 && ISALPHA (s[i]); i++)
+      tag[i] = TOUPPER (s[i]);
+    if (i) {
+      for (; i < 4; i++)
+        tag[i] = ' ';
+      return HB_TAG_CHAR4 (tag);
+    }
+  }
+
+  /*
+   * The International Phonetic Alphabet is a variant tag in BCP-47,
+   * which can be applied to any language.
+   */
+  if (strstr (lang_str, "-fonipa")) {
+    return HB_TAG('I','P','P','H');  /* Phonetic transcription—IPA conventions */
+  }
+
+  /* Find a language matching in the first component */
+  {
+    const LangTag *lang_tag;
+    lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
+                                    ARRAY_LENGTH (ot_languages), sizeof (LangTag),
+                                    (hb_compare_func_t) lang_compare_first_component);
+    if (lang_tag)
+      return lang_tag->tag;
+  }
+
+  /* Otherwise, check the Chinese ones */
+  if (0 == lang_compare_first_component (lang_str, "zh"))
+  {
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++)
+    {
+      const LangTagLong *lang_tag;
+      lang_tag = &ot_languages_zh[i];
+      if (lang_matches (lang_str, lang_tag->language))
+        return lang_tag->tag;
+    }
+
+    /* Otherwise just return 'ZHS ' */
+    return HB_TAG('Z','H','S',' ');
+  }
+
+  s = strchr (lang_str, '-');
+  if (!s)
+    s = lang_str + strlen (lang_str);
+  if (s - lang_str == 3) {
+    /* Assume it's ISO-639-3 and upper-case and use it. */
+    return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u;
+  }
+
+  return HB_OT_TAG_DEFAULT_LANGUAGE;
+}
+
+/**
+ * hb_ot_tag_to_language:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+hb_language_t
+hb_ot_tag_to_language (hb_tag_t tag)
+{
+  unsigned int i;
+
+  if (tag == HB_OT_TAG_DEFAULT_LANGUAGE)
+    return NULL;
+
+  for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
+    if (ot_languages[i].tag == tag)
+      return hb_language_from_string (ot_languages[i].language, -1);
+
+  /* If tag starts with ZH, it's Chinese */
+  if ((tag & 0xFFFF0000u)  == 0x5A480000u) {
+    switch (tag) {
+      case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */
+      case HB_TAG('Z','H','S',' '): return hb_language_from_string ("zh-Hans", -1); /* Simplified */
+      case HB_TAG('Z','H','T',' '): return hb_language_from_string ("zh-Hant", -1); /* Traditional */
+      default: break; /* Fall through */
+    }
+  }
+
+  /* struct LangTag has only room for 3-letter language tags. */
+  switch (tag) {
+  case HB_TAG('I','P','P','H'):  /* Phonetic transcription—IPA conventions */
+    return hb_language_from_string ("und-fonipa", -1);
+  }
+
+  /* Else return a custom language in the form of "x-hbotABCD" */
+  {
+    unsigned char buf[11] = "x-hbot";
+    buf[6] = tag >> 24;
+    buf[7] = (tag >> 16) & 0xFF;
+    buf[8] = (tag >> 8) & 0xFF;
+    buf[9] = tag & 0xFF;
+    if (buf[9] == 0x20)
+      buf[9] = '\0';
+    buf[10] = '\0';
+    return hb_language_from_string ((char *) buf, -1);
+  }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-tag.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2009  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_TAG_H
+#define HB_OT_TAG_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+
+#define HB_OT_TAG_DEFAULT_SCRIPT        HB_TAG ('D', 'F', 'L', 'T')
+#define HB_OT_TAG_DEFAULT_LANGUAGE      HB_TAG ('d', 'f', 'l', 't')
+
+void
+hb_ot_tags_from_script (hb_script_t  script,
+                        hb_tag_t    *script_tag_1,
+                        hb_tag_t    *script_tag_2);
+
+hb_script_t
+hb_ot_tag_to_script (hb_tag_t tag);
+
+hb_tag_t
+hb_ot_tag_from_language (hb_language_t language);
+
+hb_language_t
+hb_ot_tag_to_language (hb_tag_t tag);
+
+
+HB_END_DECLS
+
+#endif /* HB_OT_TAG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2009  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_H
+#define HB_OT_H
+#define HB_OT_H_IN
+
+#include "hb.h"
+
+#include "hb-ot-font.h"
+#include "hb-ot-layout.h"
+#include "hb-ot-tag.h"
+#include "hb-ot-shape.h"
+
+HB_BEGIN_DECLS
+
+HB_END_DECLS
+
+#undef HB_OT_H_IN
+#endif /* HB_OT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,953 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2011,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_PRIVATE_HH
+#define HB_PRIVATE_HH
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hb.h"
+#define HB_H_IN
+#ifdef HAVE_OT
+#include "hb-ot.h"
+#define HB_OT_H_IN
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <assert.h>
+
+/* We only use these two for debug output.  However, the debug code is
+ * always seen by the compiler (and optimized out in non-debug builds.
+ * If including these becomes a problem, we can start thinking about
+ * someway around that. */
+#include <stdio.h>
+#include <errno.h>
+#include <stdarg.h>
+
+
+/* Compile-time custom allocator support. */
+
+#if defined(hb_malloc_impl) \
+ && defined(hb_calloc_impl) \
+ && defined(hb_realloc_impl) \
+ && defined(hb_free_impl)
+extern "C" void* hb_malloc_impl(size_t size);
+extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
+extern "C" void* hb_realloc_impl(void *ptr, size_t size);
+extern "C" void  hb_free_impl(void *ptr);
+#define malloc hb_malloc_impl
+#define calloc hb_calloc_impl
+#define realloc hb_realloc_impl
+#define free hb_free_impl
+#endif
+
+
+/* Compiler attributes */
+
+
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
+#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
+#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
+#else
+#define likely(expr) (expr)
+#define unlikely(expr) (expr)
+#endif
+
+#ifndef __GNUC__
+#undef __attribute__
+#define __attribute__(x)
+#endif
+
+#if __GNUC__ >= 3
+#define HB_PURE_FUNC    __attribute__((pure))
+#define HB_CONST_FUNC   __attribute__((const))
+#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
+#else
+#define HB_PURE_FUNC
+#define HB_CONST_FUNC
+#define HB_PRINTF_FUNC(format_idx, arg_idx)
+#endif
+#if __GNUC__ >= 4
+#define HB_UNUSED       __attribute__((unused))
+#else
+#define HB_UNUSED
+#endif
+
+#ifndef HB_INTERNAL
+# if !defined(__MINGW32__) && !defined(__CYGWIN__)
+#  define HB_INTERNAL __attribute__((__visibility__("hidden")))
+# else
+#  define HB_INTERNAL
+# endif
+#endif
+
+#if __GNUC__ >= 3
+#define HB_FUNC __PRETTY_FUNCTION__
+#elif defined(_MSC_VER)
+#define HB_FUNC __FUNCSIG__
+#else
+#define HB_FUNC __func__
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+   /* We need Windows Vista for both Uniscribe backend and for
+    * MemoryBarrier.  We don't support compiling on Windows XP,
+    * though we run on it fine. */
+#  if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
+#    undef _WIN32_WINNT
+#  endif
+#  ifndef _WIN32_WINNT
+#    define _WIN32_WINNT 0x0600
+#  endif
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN 1
+#  endif
+#  ifndef STRICT
+#    define STRICT 1
+#  endif
+
+#  if defined(_WIN32_WCE)
+     /* Some things not defined on Windows CE. */
+#    define strdup _strdup
+#    define getenv(Name) NULL
+#    if _WIN32_WCE < 0x800
+#      define setlocale(Category, Locale) "C"
+static int errno = 0; /* Use something better? */
+#    endif
+#  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+#    define getenv(Name) NULL
+#  endif
+#  if defined(_MSC_VER) && _MSC_VER < 1900
+#    define snprintf _snprintf
+#  endif
+#endif
+
+#if HAVE_ATEXIT
+/* atexit() is only safe to be called from shared libraries on certain
+ * platforms.  Whitelist.
+ * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
+#  if defined(__linux) && defined(__GLIBC_PREREQ)
+#    if __GLIBC_PREREQ(2,3)
+/* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
+#      define HB_USE_ATEXIT 1
+#    endif
+#  elif defined(_MSC_VER) || defined(__MINGW32__)
+/* For MSVC:
+ * http://msdn.microsoft.com/en-ca/library/tze57ck3.aspx
+ * http://msdn.microsoft.com/en-ca/library/zk17ww08.aspx
+ * mingw32 headers say atexit is safe to use in shared libraries.
+ */
+#    define HB_USE_ATEXIT 1
+#  elif defined(__ANDROID__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+/* This was fixed in Android NKD r8 or r8b:
+ * https://code.google.com/p/android/issues/detail?id=6455
+ * which introduced GCC 4.6:
+ * https://developer.android.com/tools/sdk/ndk/index.html
+ */
+#    define HB_USE_ATEXIT 1
+#  endif
+#endif
+
+/* Basics */
+
+
+#ifndef NULL
+# define NULL ((void *) 0)
+#endif
+
+#undef MIN
+template <typename Type>
+static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
+
+#undef MAX
+template <typename Type>
+static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
+
+static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
+{ return (a + (b - 1)) / b; }
+
+
+#undef  ARRAY_LENGTH
+template <typename Type, unsigned int n>
+static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
+/* A const version, but does not detect erratically being called on pointers. */
+#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
+
+#define HB_STMT_START do
+#define HB_STMT_END   while (0)
+
+#define _ASSERT_STATIC1(_line, _cond)   HB_UNUSED typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
+#define _ASSERT_STATIC0(_line, _cond)   _ASSERT_STATIC1 (_line, (_cond))
+#define ASSERT_STATIC(_cond)            _ASSERT_STATIC0 (__LINE__, (_cond))
+
+/* Note: C++ allows sizeof() of variable-lengh arrays.  So, if _cond is not
+ * constant, it still compiles (ouch!), but at least we'll get a -Wvla warning. */
+#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1]))
+
+#define _PASTE1(a,b) a##b
+#define PASTE(a,b) _PASTE1(a,b)
+
+/* Lets assert int types.  Saves trouble down the road. */
+
+ASSERT_STATIC (sizeof (int8_t) == 1);
+ASSERT_STATIC (sizeof (uint8_t) == 1);
+ASSERT_STATIC (sizeof (int16_t) == 2);
+ASSERT_STATIC (sizeof (uint16_t) == 2);
+ASSERT_STATIC (sizeof (int32_t) == 4);
+ASSERT_STATIC (sizeof (uint32_t) == 4);
+ASSERT_STATIC (sizeof (int64_t) == 8);
+ASSERT_STATIC (sizeof (uint64_t) == 8);
+
+ASSERT_STATIC (sizeof (hb_codepoint_t) == 4);
+ASSERT_STATIC (sizeof (hb_position_t) == 4);
+ASSERT_STATIC (sizeof (hb_mask_t) == 4);
+ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
+
+
+/* We like our types POD */
+
+#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
+#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type)
+#define ASSERT_TYPE_POD(_type)          _ASSERT_TYPE_POD0 (__LINE__, _type)
+
+#ifdef __GNUC__
+# define _ASSERT_INSTANCE_POD1(_line, _instance) \
+        HB_STMT_START { \
+                typedef __typeof__(_instance) _type_##_line; \
+                _ASSERT_TYPE_POD1 (_line, _type_##_line); \
+        } HB_STMT_END
+#else
+# define _ASSERT_INSTANCE_POD1(_line, _instance)        typedef int _assertion_on_line_##_line##_not_tested
+#endif
+# define _ASSERT_INSTANCE_POD0(_line, _instance)        _ASSERT_INSTANCE_POD1 (_line, _instance)
+# define ASSERT_INSTANCE_POD(_instance)                 _ASSERT_INSTANCE_POD0 (__LINE__, _instance)
+
+/* Check _assertion in a method environment */
+#define _ASSERT_POD1(_line) \
+        HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \
+        { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
+# define _ASSERT_POD0(_line)    _ASSERT_POD1 (_line)
+# define ASSERT_POD()           _ASSERT_POD0 (__LINE__)
+
+
+
+/* Misc */
+
+/* Void! */
+struct _hb_void_t {};
+typedef const _hb_void_t *hb_void_t;
+#define HB_VOID ((const _hb_void_t *) NULL)
+
+/* Return the number of 1 bits in mask. */
+static inline HB_CONST_FUNC unsigned int
+_hb_popcount32 (uint32_t mask)
+{
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+  return __builtin_popcount (mask);
+#else
+  /* "HACKMEM 169" */
+  uint32_t y;
+  y = (mask >> 1) &033333333333;
+  y = mask - y - ((y >>1) & 033333333333);
+  return (((y + (y >> 3)) & 030707070707) % 077);
+#endif
+}
+
+/* Returns the number of bits needed to store number */
+static inline HB_CONST_FUNC unsigned int
+_hb_bit_storage (unsigned int number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+  return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0;
+#else
+  unsigned int n_bits = 0;
+  while (number) {
+    n_bits++;
+    number >>= 1;
+  }
+  return n_bits;
+#endif
+}
+
+/* Returns the number of zero bits in the least significant side of number */
+static inline HB_CONST_FUNC unsigned int
+_hb_ctz (unsigned int number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+  return likely (number) ? __builtin_ctz (number) : 0;
+#else
+  unsigned int n_bits = 0;
+  if (unlikely (!number)) return 0;
+  while (!(number & 1)) {
+    n_bits++;
+    number >>= 1;
+  }
+  return n_bits;
+#endif
+}
+
+static inline bool
+_hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
+{
+  return (size > 0) && (count >= ((unsigned int) -1) / size);
+}
+
+
+/* Type of bsearch() / qsort() compare function */
+typedef int (*hb_compare_func_t) (const void *, const void *);
+
+
+
+
+/* arrays and maps */
+
+
+#define HB_PREALLOCED_ARRAY_INIT {0, 0, NULL}
+template <typename Type, unsigned int StaticSize=16>
+struct hb_prealloced_array_t
+{
+  unsigned int len;
+  unsigned int allocated;
+  Type *array;
+  Type static_array[StaticSize];
+
+  void init (void) { memset (this, 0, sizeof (*this)); }
+
+  inline Type& operator [] (unsigned int i) { return array[i]; }
+  inline const Type& operator [] (unsigned int i) const { return array[i]; }
+
+  inline Type *push (void)
+  {
+    if (!array) {
+      array = static_array;
+      allocated = ARRAY_LENGTH (static_array);
+    }
+    if (likely (len < allocated))
+      return &array[len++];
+
+    /* Need to reallocate */
+    unsigned int new_allocated = allocated + (allocated >> 1) + 8;
+    Type *new_array = NULL;
+
+    if (array == static_array) {
+      new_array = (Type *) calloc (new_allocated, sizeof (Type));
+      if (new_array)
+        memcpy (new_array, array, len * sizeof (Type));
+    } else {
+      bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
+      if (likely (!overflows)) {
+        new_array = (Type *) realloc (array, new_allocated * sizeof (Type));
+      }
+    }
+
+    if (unlikely (!new_array))
+      return NULL;
+
+    array = new_array;
+    allocated = new_allocated;
+    return &array[len++];
+  }
+
+  inline void pop (void)
+  {
+    len--;
+  }
+
+  inline void remove (unsigned int i)
+  {
+     if (unlikely (i >= len))
+       return;
+     memmove (static_cast<void *> (&array[i]),
+              static_cast<void *> (&array[i + 1]),
+              (len - i - 1) * sizeof (Type));
+     len--;
+  }
+
+  inline void shrink (unsigned int l)
+  {
+     if (l < len)
+       len = l;
+  }
+
+  template <typename T>
+  inline Type *find (T v) {
+    for (unsigned int i = 0; i < len; i++)
+      if (array[i] == v)
+        return &array[i];
+    return NULL;
+  }
+  template <typename T>
+  inline const Type *find (T v) const {
+    for (unsigned int i = 0; i < len; i++)
+      if (array[i] == v)
+        return &array[i];
+    return NULL;
+  }
+
+  inline void qsort (void)
+  {
+    ::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+  }
+
+  inline void qsort (unsigned int start, unsigned int end)
+  {
+    ::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
+  }
+
+  template <typename T>
+  inline Type *bsearch (T *key)
+  {
+    return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+  }
+  template <typename T>
+  inline const Type *bsearch (T *key) const
+  {
+    return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
+  }
+
+  inline void finish (void)
+  {
+    if (array != static_array)
+      free (array);
+    array = NULL;
+    allocated = len = 0;
+  }
+};
+
+template <typename Type>
+struct hb_auto_array_t : hb_prealloced_array_t <Type>
+{
+  hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); }
+  ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); }
+};
+
+
+#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
+template <typename item_t, typename lock_t>
+struct hb_lockable_set_t
+{
+  hb_prealloced_array_t <item_t, 2> items;
+
+  inline void init (void) { items.init (); }
+
+  template <typename T>
+  inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
+  {
+    l.lock ();
+    item_t *item = items.find (v);
+    if (item) {
+      if (replace) {
+        item_t old = *item;
+        *item = v;
+        l.unlock ();
+        old.finish ();
+      }
+      else {
+        item = NULL;
+        l.unlock ();
+      }
+    } else {
+      item = items.push ();
+      if (likely (item))
+        *item = v;
+      l.unlock ();
+    }
+    return item;
+  }
+
+  template <typename T>
+  inline void remove (T v, lock_t &l)
+  {
+    l.lock ();
+    item_t *item = items.find (v);
+    if (item) {
+      item_t old = *item;
+      *item = items[items.len - 1];
+      items.pop ();
+      l.unlock ();
+      old.finish ();
+    } else {
+      l.unlock ();
+    }
+  }
+
+  template <typename T>
+  inline bool find (T v, item_t *i, lock_t &l)
+  {
+    l.lock ();
+    item_t *item = items.find (v);
+    if (item)
+      *i = *item;
+    l.unlock ();
+    return !!item;
+  }
+
+  template <typename T>
+  inline item_t *find_or_insert (T v, lock_t &l)
+  {
+    l.lock ();
+    item_t *item = items.find (v);
+    if (!item) {
+      item = items.push ();
+      if (likely (item))
+        *item = v;
+    }
+    l.unlock ();
+    return item;
+  }
+
+  inline void finish (lock_t &l)
+  {
+    if (!items.len) {
+      /* No need for locking. */
+      items.finish ();
+      return;
+    }
+    l.lock ();
+    while (items.len) {
+      item_t old = items[items.len - 1];
+        items.pop ();
+        l.unlock ();
+        old.finish ();
+        l.lock ();
+    }
+    items.finish ();
+    l.unlock ();
+  }
+
+};
+
+
+/* ASCII tag/character handling */
+
+static inline bool ISALPHA (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
+static inline bool ISALNUM (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
+static inline bool ISSPACE (unsigned char c)
+{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
+static inline unsigned char TOUPPER (unsigned char c)
+{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
+static inline unsigned char TOLOWER (unsigned char c)
+{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
+
+#define HB_TAG_CHAR4(s)   (HB_TAG(((const char *) s)[0], \
+                                  ((const char *) s)[1], \
+                                  ((const char *) s)[2], \
+                                  ((const char *) s)[3]))
+
+
+/* C++ helpers */
+
+/* Makes class uncopyable.  Use in private: section. */
+#define NO_COPY(T) \
+  T (const T &o); \
+  T &operator = (const T &o)
+
+
+/* Debug */
+
+
+#ifndef HB_DEBUG
+#define HB_DEBUG 0
+#endif
+
+static inline bool
+_hb_debug (unsigned int level,
+           unsigned int max_level)
+{
+  return level < max_level;
+}
+
+#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
+#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
+
+static inline void
+_hb_print_func (const char *func)
+{
+  if (func)
+  {
+    unsigned int func_len = strlen (func);
+    /* Skip "static" */
+    if (0 == strncmp (func, "static ", 7))
+      func += 7;
+    /* Skip "typename" */
+    if (0 == strncmp (func, "typename ", 9))
+      func += 9;
+    /* Skip return type */
+    const char *space = strchr (func, ' ');
+    if (space)
+      func = space + 1;
+    /* Skip parameter list */
+    const char *paren = strchr (func, '(');
+    if (paren)
+      func_len = paren - func;
+    fprintf (stderr, "%.*s", func_len, func);
+  }
+}
+
+template <int max_level> static inline void
+_hb_debug_msg_va (const char *what,
+                  const void *obj,
+                  const char *func,
+                  bool indented,
+                  unsigned int level,
+                  int level_dir,
+                  const char *message,
+                  va_list ap) HB_PRINTF_FUNC(7, 0);
+template <int max_level> static inline void
+_hb_debug_msg_va (const char *what,
+                  const void *obj,
+                  const char *func,
+                  bool indented,
+                  unsigned int level,
+                  int level_dir,
+                  const char *message,
+                  va_list ap)
+{
+  if (!_hb_debug (level, max_level))
+    return;
+
+  fprintf (stderr, "%-10s", what ? what : "");
+
+  if (obj)
+    fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj);
+  else
+    fprintf (stderr, " %*s  ", (unsigned int) (2 * sizeof (void *)), "");
+
+  if (indented) {
+/* One may want to add ASCII version of these.  See:
+ * https://bugs.freedesktop.org/show_bug.cgi?id=50970 */
+#define VBAR    "\342\224\202"  /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
+#define VRBAR   "\342\224\234"  /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+#define DLBAR   "\342\225\256"  /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */
+#define ULBAR   "\342\225\257"  /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */
+#define LBAR    "\342\225\264"  /* U+2574 BOX DRAWINGS LIGHT LEFT */
+    static const char bars[] = VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
+    fprintf (stderr, "%2u %s" VRBAR "%s",
+             level,
+             bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars), (unsigned int) (sizeof (VBAR) - 1) * level),
+             level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
+  } else
+    fprintf (stderr, "   " VRBAR LBAR);
+
+  _hb_print_func (func);
+
+  if (message)
+  {
+    fprintf (stderr, ": ");
+    vfprintf (stderr, message, ap);
+  }
+
+  fprintf (stderr, "\n");
+}
+template <> inline void
+_hb_debug_msg_va<0> (const char *what HB_UNUSED,
+                     const void *obj HB_UNUSED,
+                     const char *func HB_UNUSED,
+                     bool indented HB_UNUSED,
+                     unsigned int level HB_UNUSED,
+                     int level_dir HB_UNUSED,
+                     const char *message HB_UNUSED,
+                     va_list ap HB_UNUSED) {}
+
+template <int max_level> static inline void
+_hb_debug_msg (const char *what,
+               const void *obj,
+               const char *func,
+               bool indented,
+               unsigned int level,
+               int level_dir,
+               const char *message,
+               ...) HB_PRINTF_FUNC(7, 8);
+template <int max_level> static inline void
+_hb_debug_msg (const char *what,
+               const void *obj,
+               const char *func,
+               bool indented,
+               unsigned int level,
+               int level_dir,
+               const char *message,
+               ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  _hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap);
+  va_end (ap);
+}
+template <> inline void
+_hb_debug_msg<0> (const char *what HB_UNUSED,
+                  const void *obj HB_UNUSED,
+                  const char *func HB_UNUSED,
+                  bool indented HB_UNUSED,
+                  unsigned int level HB_UNUSED,
+                  int level_dir HB_UNUSED,
+                  const char *message HB_UNUSED,
+                  ...) HB_PRINTF_FUNC(7, 8);
+template <> inline void
+_hb_debug_msg<0> (const char *what HB_UNUSED,
+                  const void *obj HB_UNUSED,
+                  const char *func HB_UNUSED,
+                  bool indented HB_UNUSED,
+                  unsigned int level HB_UNUSED,
+                  int level_dir HB_UNUSED,
+                  const char *message HB_UNUSED,
+                  ...) {}
+
+#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...)       _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL,    true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
+#define DEBUG_MSG(WHAT, OBJ, ...)                               _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL,    false, 0, 0, __VA_ARGS__)
+#define DEBUG_MSG_FUNC(WHAT, OBJ, ...)                          _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
+
+
+/*
+ * Printer
+ */
+
+template <typename T>
+struct hb_printer_t {
+  const char *print (const T&) { return "something"; }
+};
+
+template <>
+struct hb_printer_t<bool> {
+  const char *print (bool v) { return v ? "true" : "false"; }
+};
+
+template <>
+struct hb_printer_t<hb_void_t> {
+  const char *print (hb_void_t) { return ""; }
+};
+
+
+/*
+ * Trace
+ */
+
+template <typename T>
+static inline void _hb_warn_no_return (bool returned)
+{
+  if (unlikely (!returned)) {
+    fprintf (stderr, "OUCH, returned with no call to return_trace().  This is a bug, please report.\n");
+  }
+}
+template <>
+/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
+{}
+
+template <int max_level, typename ret_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)
+  {
+    if (plevel) ++*plevel;
+
+    va_list ap;
+    va_start (ap, message);
+    _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
+    va_end (ap);
+  }
+  inline ~hb_auto_trace_t (void)
+  {
+    _hb_warn_no_return<ret_t> (returned);
+    if (!returned) {
+      _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " ");
+    }
+    if (plevel) --*plevel;
+  }
+
+  inline ret_t ret (ret_t v, unsigned int line = 0)
+  {
+    if (unlikely (returned)) {
+      fprintf (stderr, "OUCH, double calls to return_trace().  This is a bug, please report.\n");
+      return v;
+    }
+
+    _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
+                              "return %s (line %d)",
+                              hb_printer_t<ret_t>().print (v), line);
+    if (plevel) --*plevel;
+    plevel = NULL;
+    returned = true;
+    return v;
+  }
+
+  private:
+  unsigned int *plevel;
+  const char *what;
+  const void *obj;
+  bool returned;
+};
+template <typename ret_t> /* Optimize when tracing is disabled */
+struct hb_auto_trace_t<0, ret_t> {
+  explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED,
+                                   const char *what HB_UNUSED,
+                                   const void *obj HB_UNUSED,
+                                   const char *func HB_UNUSED,
+                                   const char *message HB_UNUSED,
+                                   ...) {}
+
+  inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
+};
+
+#define return_trace(RET) return trace.ret (RET, __LINE__)
+
+/* Misc */
+
+template <typename T> class hb_assert_unsigned_t;
+template <> class hb_assert_unsigned_t<unsigned char> {};
+template <> class hb_assert_unsigned_t<unsigned short> {};
+template <> class hb_assert_unsigned_t<unsigned int> {};
+template <> class hb_assert_unsigned_t<unsigned long> {};
+
+template <typename T> static inline bool
+hb_in_range (T u, T lo, T hi)
+{
+  /* The sizeof() is here to force template instantiation.
+   * I'm sure there are better ways to do this but can't think of
+   * one right now.  Declaring a variable won't work as HB_UNUSED
+   * is unusable on some platforms and unused types are less likely
+   * to generate a warning than unused variables. */
+  ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);
+
+  /* The casts below are important as if T is smaller than int,
+   * the subtract results will become a signed int! */
+  return (T)(u - lo) <= (T)(hi - lo);
+}
+
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
+{
+  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
+}
+
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
+{
+  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
+}
+
+
+/* Useful for set-operations on small enums.
+ * For example, for testing "x ∈ {x1, x2, x3}" use:
+ * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
+ */
+#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x)))
+#define FLAG_SAFE(x) (1U << (x))
+#define FLAG_UNSAFE(x) ((x) < 32 ? FLAG_SAFE(x) : 0)
+#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
+
+
+template <typename T, typename T2> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
+{
+  for (unsigned int i = 1; i < len; i++)
+  {
+    unsigned int j = i;
+    while (j && compar (&array[j - 1], &array[i]) > 0)
+      j--;
+    if (i == j)
+      continue;
+    /* Move item i to occupy place for item j, shift what's in between. */
+    {
+      T t = array[i];
+      memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
+      array[j] = t;
+    }
+    if (array2)
+    {
+      T2 t = array2[i];
+      memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2));
+      array2[j] = t;
+    }
+  }
+}
+
+template <typename T> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
+{
+  hb_stable_sort (array, len, compar, (int *) NULL);
+}
+
+static inline hb_bool_t
+hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
+{
+  /* Pain because we don't know whether s is nul-terminated. */
+  char buf[64];
+  len = MIN (ARRAY_LENGTH (buf) - 1, len);
+  strncpy (buf, s, len);
+  buf[len] = '\0';
+
+  char *end;
+  errno = 0;
+  unsigned long v = strtoul (buf, &end, base);
+  if (errno) return false;
+  if (*end) return false;
+  *out = v;
+  return true;
+}
+
+
+/* Global runtime options. */
+
+struct hb_options_t
+{
+  unsigned int initialized : 1;
+  unsigned int uniscribe_bug_compatible : 1;
+};
+
+union hb_options_union_t {
+  unsigned int i;
+  hb_options_t opts;
+};
+ASSERT_STATIC (sizeof (int) == sizeof (hb_options_union_t));
+
+HB_INTERNAL void
+_hb_options_init (void);
+
+extern HB_INTERNAL hb_options_union_t _hb_options;
+
+static inline hb_options_t
+hb_options (void)
+{
+  if (unlikely (!_hb_options.i))
+    _hb_options_init ();
+
+  return _hb_options.opts;
+}
+
+
+#endif /* HB_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,402 @@
+/*
+ * Copyright © 2012  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_SET_PRIVATE_HH
+#define HB_SET_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-object-private.hh"
+
+
+/*
+ * The set digests here implement various "filters" that support
+ * "approximate member query".  Conceptually these are like Bloom
+ * Filter and Quotient Filter, however, much smaller, faster, and
+ * designed to fit the requirements of our uses for glyph coverage
+ * queries.
+ *
+ * Our filters are highly accurate if the lookup covers fairly local
+ * set of glyphs, but fully flooded and ineffective if coverage is
+ * all over the place.
+ *
+ * The frozen-set can be used instead of a digest, to trade more
+ * memory for 100% accuracy, but in practice, that doesn't look like
+ * an attractive trade-off.
+ */
+
+template <typename mask_t, unsigned int shift>
+struct hb_set_digest_lowest_bits_t
+{
+  ASSERT_POD ();
+
+  static const unsigned int mask_bytes = sizeof (mask_t);
+  static const unsigned int mask_bits = sizeof (mask_t) * 8;
+  static const unsigned int num_bits = 0
+                                     + (mask_bytes >= 1 ? 3 : 0)
+                                     + (mask_bytes >= 2 ? 1 : 0)
+                                     + (mask_bytes >= 4 ? 1 : 0)
+                                     + (mask_bytes >= 8 ? 1 : 0)
+                                     + (mask_bytes >= 16? 1 : 0)
+                                     + 0;
+
+  ASSERT_STATIC (shift < sizeof (hb_codepoint_t) * 8);
+  ASSERT_STATIC (shift + num_bits <= sizeof (hb_codepoint_t) * 8);
+
+  inline void init (void) {
+    mask = 0;
+  }
+
+  inline void add (hb_codepoint_t g) {
+    mask |= mask_for (g);
+  }
+
+  inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
+    if ((b >> shift) - (a >> shift) >= mask_bits - 1)
+      mask = (mask_t) -1;
+    else {
+      mask_t ma = mask_for (a);
+      mask_t mb = mask_for (b);
+      mask |= mb + (mb - ma) - (mb < ma);
+    }
+  }
+
+  inline bool may_have (hb_codepoint_t g) const {
+    return !!(mask & mask_for (g));
+  }
+
+  private:
+
+  static inline mask_t mask_for (hb_codepoint_t g) {
+    return ((mask_t) 1) << ((g >> shift) & (mask_bits - 1));
+  }
+  mask_t mask;
+};
+
+template <typename head_t, typename tail_t>
+struct hb_set_digest_combiner_t
+{
+  ASSERT_POD ();
+
+  inline void init (void) {
+    head.init ();
+    tail.init ();
+  }
+
+  inline void add (hb_codepoint_t g) {
+    head.add (g);
+    tail.add (g);
+  }
+
+  inline void add_range (hb_codepoint_t a, hb_codepoint_t b) {
+    head.add_range (a, b);
+    tail.add_range (a, b);
+  }
+
+  inline bool may_have (hb_codepoint_t g) const {
+    return head.may_have (g) && tail.may_have (g);
+  }
+
+  private:
+  head_t head;
+  tail_t tail;
+};
+
+
+/*
+ * hb_set_digest_t
+ *
+ * This is a combination of digests that performs "best".
+ * There is not much science to this: it's a result of intuition
+ * and testing.
+ */
+typedef hb_set_digest_combiner_t
+<
+  hb_set_digest_lowest_bits_t<unsigned long, 4>,
+  hb_set_digest_combiner_t
+  <
+    hb_set_digest_lowest_bits_t<unsigned long, 0>,
+    hb_set_digest_lowest_bits_t<unsigned long, 9>
+  >
+> hb_set_digest_t;
+
+
+
+/*
+ * hb_set_t
+ */
+
+
+/* TODO Make this faster and memmory efficient. */
+
+struct hb_set_t
+{
+  friend struct hb_frozen_set_t;
+
+  hb_object_header_t header;
+  ASSERT_POD ();
+  bool in_error;
+
+  inline void init (void) {
+    hb_object_init (this);
+    clear ();
+  }
+  inline void fini (void) {
+  }
+  inline void clear (void) {
+    if (unlikely (hb_object_is_inert (this)))
+      return;
+    in_error = false;
+    memset (elts, 0, sizeof elts);
+  }
+  inline bool is_empty (void) const {
+    for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++)
+      if (elts[i])
+        return false;
+    return true;
+  }
+  inline void add (hb_codepoint_t g)
+  {
+    if (unlikely (in_error)) return;
+    if (unlikely (g == INVALID)) return;
+    if (unlikely (g > MAX_G)) return;
+    elt (g) |= mask (g);
+  }
+  inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
+  {
+    if (unlikely (in_error)) return;
+    /* TODO Speedup */
+    for (unsigned int i = a; i < b + 1; i++)
+      add (i);
+  }
+  inline void del (hb_codepoint_t g)
+  {
+    if (unlikely (in_error)) return;
+    if (unlikely (g > MAX_G)) return;
+    elt (g) &= ~mask (g);
+  }
+  inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
+  {
+    if (unlikely (in_error)) return;
+    /* TODO Speedup */
+    for (unsigned int i = a; i < b + 1; i++)
+      del (i);
+  }
+  inline bool has (hb_codepoint_t g) const
+  {
+    if (unlikely (g > MAX_G)) return false;
+    return !!(elt (g) & mask (g));
+  }
+  inline bool intersects (hb_codepoint_t first,
+                          hb_codepoint_t last) const
+  {
+    if (unlikely (first > MAX_G)) return false;
+    if (unlikely (last  > MAX_G)) last = MAX_G;
+    unsigned int end = last + 1;
+    for (hb_codepoint_t i = first; i < end; i++)
+      if (has (i))
+        return true;
+    return false;
+  }
+  inline bool is_equal (const hb_set_t *other) const
+  {
+    for (unsigned int i = 0; i < ELTS; i++)
+      if (elts[i] != other->elts[i])
+        return false;
+    return true;
+  }
+  inline void set (const hb_set_t *other)
+  {
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] = other->elts[i];
+  }
+  inline void union_ (const hb_set_t *other)
+  {
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] |= other->elts[i];
+  }
+  inline void intersect (const hb_set_t *other)
+  {
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] &= other->elts[i];
+  }
+  inline void subtract (const hb_set_t *other)
+  {
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] &= ~other->elts[i];
+  }
+  inline void symmetric_difference (const hb_set_t *other)
+  {
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] ^= other->elts[i];
+  }
+  inline void invert (void)
+  {
+    if (unlikely (in_error)) return;
+    for (unsigned int i = 0; i < ELTS; i++)
+      elts[i] = ~elts[i];
+  }
+  inline bool next (hb_codepoint_t *codepoint) const
+  {
+    if (unlikely (*codepoint == INVALID)) {
+      hb_codepoint_t i = get_min ();
+      if (i != INVALID) {
+        *codepoint = i;
+        return true;
+      } else {
+        *codepoint = INVALID;
+        return false;
+      }
+    }
+    for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++)
+      if (has (i)) {
+        *codepoint = i;
+        return true;
+      }
+    *codepoint = INVALID;
+    return false;
+  }
+  inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
+  {
+    hb_codepoint_t i;
+
+    i = *last;
+    if (!next (&i))
+    {
+      *last = *first = INVALID;
+      return false;
+    }
+
+    *last = *first = i;
+    while (next (&i) && i == *last + 1)
+      (*last)++;
+
+    return true;
+  }
+
+  inline unsigned int get_population (void) const
+  {
+    unsigned int count = 0;
+    for (unsigned int i = 0; i < ELTS; i++)
+      count += _hb_popcount32 (elts[i]);
+    return count;
+  }
+  inline hb_codepoint_t get_min (void) const
+  {
+    for (unsigned int i = 0; i < ELTS; i++)
+      if (elts[i])
+        for (unsigned int j = 0; j < BITS; j++)
+          if (elts[i] & (1 << j))
+            return i * BITS + j;
+    return INVALID;
+  }
+  inline hb_codepoint_t get_max (void) const
+  {
+    for (unsigned int i = ELTS; i; i--)
+      if (elts[i - 1])
+        for (unsigned int j = BITS; j; j--)
+          if (elts[i - 1] & (1 << (j - 1)))
+            return (i - 1) * BITS + (j - 1);
+    return INVALID;
+  }
+
+  typedef uint32_t elt_t;
+  static const unsigned int MAX_G = 65536 - 1; /* XXX Fix this... */
+  static const unsigned int SHIFT = 5;
+  static const unsigned int BITS = (1 << SHIFT);
+  static const unsigned int MASK = BITS - 1;
+  static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
+  static  const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
+
+  elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
+  elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
+  elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
+
+  elt_t elts[ELTS]; /* XXX 8kb */
+
+  ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
+  ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G);
+};
+
+struct hb_frozen_set_t
+{
+  static const unsigned int SHIFT = hb_set_t::SHIFT;
+  static const unsigned int BITS = hb_set_t::BITS;
+  static const unsigned int MASK = hb_set_t::MASK;
+  typedef hb_set_t::elt_t elt_t;
+
+  inline void init (const hb_set_t &set)
+  {
+    start = count = 0;
+    elts = NULL;
+
+    unsigned int max = set.get_max ();
+    if (max == set.INVALID)
+      return;
+    unsigned int min = set.get_min ();
+    const elt_t &min_elt = set.elt (min);
+
+    start = min & ~MASK;
+    count = max - start + 1;
+    unsigned int num_elts = (count + BITS - 1) / BITS;
+    unsigned int elts_size = num_elts * sizeof (elt_t);
+    elts = (elt_t *) malloc (elts_size);
+    if (unlikely (!elts))
+    {
+      start = count = 0;
+      return;
+    }
+    memcpy (elts, &min_elt, elts_size);
+  }
+
+  inline void fini (void)
+  {
+    if (elts)
+      free (elts);
+  }
+
+  inline bool has (hb_codepoint_t g) const
+  {
+    /* hb_codepoint_t is unsigned. */
+    g -= start;
+    if (unlikely (g > count)) return false;
+    return !!(elt (g) & mask (g));
+  }
+
+  elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
+  elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
+
+  private:
+  hb_codepoint_t start, count;
+  elt_t *elts;
+};
+
+
+#endif /* HB_SET_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,471 @@
+/*
+ * Copyright © 2012  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
+ */
+
+#include "hb-set-private.hh"
+
+
+/* Public API */
+
+
+/**
+ * hb_set_create: (Xconstructor)
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_set_t *
+hb_set_create (void)
+{
+  hb_set_t *set;
+
+  if (!(set = hb_object_create<hb_set_t> ()))
+    return hb_set_get_empty ();
+
+  set->clear ();
+
+  return set;
+}
+
+/**
+ * hb_set_get_empty:
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_set_t *
+hb_set_get_empty (void)
+{
+  static const hb_set_t _hb_set_nil = {
+    HB_OBJECT_HEADER_STATIC,
+    true, /* in_error */
+
+    {0} /* elts */
+  };
+
+  return const_cast<hb_set_t *> (&_hb_set_nil);
+}
+
+/**
+ * hb_set_reference: (skip)
+ * @set: a set.
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_set_t *
+hb_set_reference (hb_set_t *set)
+{
+  return hb_object_reference (set);
+}
+
+/**
+ * hb_set_destroy: (skip)
+ * @set: a set.
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_destroy (hb_set_t *set)
+{
+  if (!hb_object_destroy (set)) return;
+
+  set->fini ();
+
+  free (set);
+}
+
+/**
+ * hb_set_set_user_data: (skip)
+ * @set: a set.
+ * @key:
+ * @data:
+ * @destroy (closure data):
+ * @replace:
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_set_set_user_data (hb_set_t           *set,
+                      hb_user_data_key_t *key,
+                      void *              data,
+                      hb_destroy_func_t   destroy,
+                      hb_bool_t           replace)
+{
+  return hb_object_set_user_data (set, key, data, destroy, replace);
+}
+
+/**
+ * hb_set_get_user_data: (skip)
+ * @set: a set.
+ * @key:
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+void *
+hb_set_get_user_data (hb_set_t           *set,
+                      hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (set, key);
+}
+
+
+/**
+ * hb_set_allocation_successful:
+ * @set: a set.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_set_allocation_successful (const hb_set_t  *set HB_UNUSED)
+{
+  return !set->in_error;
+}
+
+/**
+ * hb_set_clear:
+ * @set: a set.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_clear (hb_set_t *set)
+{
+  set->clear ();
+}
+
+/**
+ * hb_set_is_empty:
+ * @set: a set.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.7
+ **/
+hb_bool_t
+hb_set_is_empty (const hb_set_t *set)
+{
+  return set->is_empty ();
+}
+
+/**
+ * hb_set_has:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_set_has (const hb_set_t *set,
+            hb_codepoint_t  codepoint)
+{
+  return set->has (codepoint);
+}
+
+/**
+ * hb_set_add:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_add (hb_set_t       *set,
+            hb_codepoint_t  codepoint)
+{
+  set->add (codepoint);
+}
+
+/**
+ * hb_set_add_range:
+ * @set: a set.
+ * @first:
+ * @last:
+ *
+ *
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_set_add_range (hb_set_t       *set,
+                  hb_codepoint_t  first,
+                  hb_codepoint_t  last)
+{
+  set->add_range (first, last);
+}
+
+/**
+ * hb_set_del:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_del (hb_set_t       *set,
+            hb_codepoint_t  codepoint)
+{
+  set->del (codepoint);
+}
+
+/**
+ * hb_set_del_range:
+ * @set: a set.
+ * @first:
+ * @last:
+ *
+ *
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_set_del_range (hb_set_t       *set,
+                  hb_codepoint_t  first,
+                  hb_codepoint_t  last)
+{
+  set->del_range (first, last);
+}
+
+/**
+ * hb_set_is_equal:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.7
+ **/
+hb_bool_t
+hb_set_is_equal (const hb_set_t *set,
+                 const hb_set_t *other)
+{
+  return set->is_equal (other);
+}
+
+/**
+ * hb_set_set:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_set (hb_set_t       *set,
+            const hb_set_t *other)
+{
+  set->set (other);
+}
+
+/**
+ * hb_set_union:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_union (hb_set_t       *set,
+              const hb_set_t *other)
+{
+  set->union_ (other);
+}
+
+/**
+ * hb_set_intersect:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_intersect (hb_set_t       *set,
+                  const hb_set_t *other)
+{
+  set->intersect (other);
+}
+
+/**
+ * hb_set_subtract:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_subtract (hb_set_t       *set,
+                 const hb_set_t *other)
+{
+  set->subtract (other);
+}
+
+/**
+ * hb_set_symmetric_difference:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_set_symmetric_difference (hb_set_t       *set,
+                             const hb_set_t *other)
+{
+  set->symmetric_difference (other);
+}
+
+/**
+ * hb_set_invert:
+ * @set: a set.
+ *
+ *
+ *
+ * Since: 0.9.10
+ **/
+void
+hb_set_invert (hb_set_t *set)
+{
+  set->invert ();
+}
+
+/**
+ * hb_set_get_population:
+ * @set: a set.
+ *
+ * Returns the number of numbers in the set.
+ *
+ * Return value: set population.
+ *
+ * Since: 0.9.7
+ **/
+unsigned int
+hb_set_get_population (const hb_set_t *set)
+{
+  return set->get_population ();
+}
+
+/**
+ * hb_set_get_min:
+ * @set: a set.
+ *
+ * Finds the minimum number in the set.
+ *
+ * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
+ *
+ * Since: 0.9.7
+ **/
+hb_codepoint_t
+hb_set_get_min (const hb_set_t *set)
+{
+  return set->get_min ();
+}
+
+/**
+ * hb_set_get_max:
+ * @set: a set.
+ *
+ * Finds the maximum number in the set.
+ *
+ * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
+ *
+ * Since: 0.9.7
+ **/
+hb_codepoint_t
+hb_set_get_max (const hb_set_t *set)
+{
+  return set->get_max ();
+}
+
+/**
+ * hb_set_next:
+ * @set: a set.
+ * @codepoint: (inout):
+ *
+ *
+ *
+ * Return value: whether there was a next value.
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_set_next (const hb_set_t *set,
+             hb_codepoint_t *codepoint)
+{
+  return set->next (codepoint);
+}
+
+/**
+ * hb_set_next_range:
+ * @set: a set.
+ * @first: (out): output first codepoint in the range.
+ * @last: (inout): input current last and output last codepoint in the range.
+ *
+ * Gets the next consecutive range of numbers in @set that
+ * are greater than current value of @last.
+ *
+ * Return value: whether there was a next range.
+ *
+ * Since: 0.9.7
+ **/
+hb_bool_t
+hb_set_next_range (const hb_set_t *set,
+                   hb_codepoint_t *first,
+                   hb_codepoint_t *last)
+{
+  return set->next_range (first, last);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2012  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_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_SET_H
+#define HB_SET_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * Since: 0.9.21
+ */
+#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
+
+typedef struct hb_set_t hb_set_t;
+
+
+hb_set_t *
+hb_set_create (void);
+
+hb_set_t *
+hb_set_get_empty (void);
+
+hb_set_t *
+hb_set_reference (hb_set_t *set);
+
+void
+hb_set_destroy (hb_set_t *set);
+
+hb_bool_t
+hb_set_set_user_data (hb_set_t           *set,
+                      hb_user_data_key_t *key,
+                      void *              data,
+                      hb_destroy_func_t   destroy,
+                      hb_bool_t           replace);
+
+void *
+hb_set_get_user_data (hb_set_t           *set,
+                      hb_user_data_key_t *key);
+
+
+/* Returns false if allocation has failed before */
+hb_bool_t
+hb_set_allocation_successful (const hb_set_t *set);
+
+void
+hb_set_clear (hb_set_t *set);
+
+hb_bool_t
+hb_set_is_empty (const hb_set_t *set);
+
+hb_bool_t
+hb_set_has (const hb_set_t *set,
+            hb_codepoint_t  codepoint);
+
+/* Right now limited to 16-bit integers.  Eventually will do full codepoint range, sans -1
+ * which we will use as a sentinel. */
+void
+hb_set_add (hb_set_t       *set,
+            hb_codepoint_t  codepoint);
+
+void
+hb_set_add_range (hb_set_t       *set,
+                  hb_codepoint_t  first,
+                  hb_codepoint_t  last);
+
+void
+hb_set_del (hb_set_t       *set,
+            hb_codepoint_t  codepoint);
+
+void
+hb_set_del_range (hb_set_t       *set,
+                  hb_codepoint_t  first,
+                  hb_codepoint_t  last);
+
+hb_bool_t
+hb_set_is_equal (const hb_set_t *set,
+                 const hb_set_t *other);
+
+void
+hb_set_set (hb_set_t       *set,
+            const hb_set_t *other);
+
+void
+hb_set_union (hb_set_t       *set,
+              const hb_set_t *other);
+
+void
+hb_set_intersect (hb_set_t       *set,
+                  const hb_set_t *other);
+
+void
+hb_set_subtract (hb_set_t       *set,
+                 const hb_set_t *other);
+
+void
+hb_set_symmetric_difference (hb_set_t       *set,
+                             const hb_set_t *other);
+
+void
+hb_set_invert (hb_set_t *set);
+
+unsigned int
+hb_set_get_population (const hb_set_t *set);
+
+/* Returns -1 if set empty. */
+hb_codepoint_t
+hb_set_get_min (const hb_set_t *set);
+
+/* Returns -1 if set empty. */
+hb_codepoint_t
+hb_set_get_max (const hb_set_t *set);
+
+/* Pass -1 in to get started. */
+hb_bool_t
+hb_set_next (const hb_set_t *set,
+             hb_codepoint_t *codepoint);
+
+/* Pass -1 for first and last to get started. */
+hb_bool_t
+hb_set_next_range (const hb_set_t *set,
+                   hb_codepoint_t *first,
+                   hb_codepoint_t *last);
+
+
+HB_END_DECLS
+
+#endif /* HB_SET_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape-plan-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2012  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_SHAPE_PLAN_PRIVATE_HH
+#define HB_SHAPE_PLAN_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-object-private.hh"
+#include "hb-shaper-private.hh"
+
+
+struct hb_shape_plan_t
+{
+  hb_object_header_t header;
+  ASSERT_POD ();
+
+  hb_bool_t default_shaper_list;
+  hb_face_t *face_unsafe; /* We don't carry a reference to face. */
+  hb_segment_properties_t props;
+
+  hb_shape_func_t *shaper_func;
+  const char *shaper_name;
+
+  hb_feature_t *user_features;
+  unsigned int num_user_features;
+
+  struct hb_shaper_data_t shaper_data;
+};
+
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \
+        , const hb_feature_t            *user_features \
+        , unsigned int                   num_user_features
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
+
+
+#endif /* HB_SHAPE_PLAN_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape-plan.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,500 @@
+/*
+ * Copyright © 2012  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
+ */
+
+#include "hb-shape-plan-private.hh"
+#include "hb-shaper-private.hh"
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
+
+
+#ifndef HB_DEBUG_SHAPE_PLAN
+#define HB_DEBUG_SHAPE_PLAN (HB_DEBUG+0)
+#endif
+
+
+#define HB_SHAPER_IMPLEMENT(shaper) \
+        HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \
+        HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font)
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+
+static void
+hb_shape_plan_plan (hb_shape_plan_t    *shape_plan,
+                    const hb_feature_t *user_features,
+                    unsigned int        num_user_features,
+                    const char * const *shaper_list)
+{
+  DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
+                  "num_features=%d shaper_list=%p",
+                  num_user_features,
+                  shaper_list);
+
+  const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+
+#define HB_SHAPER_PLAN(shaper) \
+        HB_STMT_START { \
+          if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
+            HB_SHAPER_DATA (shaper, shape_plan) = \
+              HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
+            shape_plan->shaper_func = _hb_##shaper##_shape; \
+            shape_plan->shaper_name = #shaper; \
+            return; \
+          } \
+        } HB_STMT_END
+
+  if (likely (!shaper_list)) {
+    for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
+      if (0)
+        ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+      else if (shapers[i].func == _hb_##shaper##_shape) \
+        HB_SHAPER_PLAN (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+  } else {
+    for (; *shaper_list; shaper_list++)
+      if (0)
+        ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+      else if (0 == strcmp (*shaper_list, #shaper)) \
+        HB_SHAPER_PLAN (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+  }
+
+#undef HB_SHAPER_PLAN
+}
+
+
+/*
+ * hb_shape_plan_t
+ */
+
+/**
+ * hb_shape_plan_create: (Xconstructor)
+ * @face:
+ * @props:
+ * @user_features: (array length=num_user_features):
+ * @num_user_features:
+ * @shaper_list: (array zero-terminated=1):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.7
+ **/
+hb_shape_plan_t *
+hb_shape_plan_create (hb_face_t                     *face,
+                      const hb_segment_properties_t *props,
+                      const hb_feature_t            *user_features,
+                      unsigned int                   num_user_features,
+                      const char * const            *shaper_list)
+{
+  DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
+                  "face=%p num_features=%d shaper_list=%p",
+                  face,
+                  num_user_features,
+                  shaper_list);
+
+  hb_shape_plan_t *shape_plan;
+  hb_feature_t *features = NULL;
+
+  if (unlikely (!face))
+    face = hb_face_get_empty ();
+  if (unlikely (!props))
+    return hb_shape_plan_get_empty ();
+  if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t))))
+    return hb_shape_plan_get_empty ();
+  if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) {
+    free (features);
+    return hb_shape_plan_get_empty ();
+  }
+
+  assert (props->direction != HB_DIRECTION_INVALID);
+
+  hb_face_make_immutable (face);
+  shape_plan->default_shaper_list = shaper_list == NULL;
+  shape_plan->face_unsafe = face;
+  shape_plan->props = *props;
+  shape_plan->num_user_features = num_user_features;
+  shape_plan->user_features = features;
+  if (num_user_features)
+    memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
+
+  hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
+
+  return shape_plan;
+}
+
+/**
+ * hb_shape_plan_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.7
+ **/
+hb_shape_plan_t *
+hb_shape_plan_get_empty (void)
+{
+  static const hb_shape_plan_t _hb_shape_plan_nil = {
+    HB_OBJECT_HEADER_STATIC,
+
+    true, /* default_shaper_list */
+    NULL, /* face */
+    HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
+
+    NULL, /* shaper_func */
+    NULL, /* shaper_name */
+
+    NULL, /* user_features */
+    0,    /* num_user_featurs */
+
+    {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
+}
+
+/**
+ * hb_shape_plan_reference: (skip)
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.7
+ **/
+hb_shape_plan_t *
+hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
+{
+  return hb_object_reference (shape_plan);
+}
+
+/**
+ * hb_shape_plan_destroy: (skip)
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Since: 0.9.7
+ **/
+void
+hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
+{
+  if (!hb_object_destroy (shape_plan)) return;
+
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+  free (shape_plan->user_features);
+
+  free (shape_plan);
+}
+
+/**
+ * hb_shape_plan_set_user_data: (skip)
+ * @shape_plan: a shape plan.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.7
+ **/
+hb_bool_t
+hb_shape_plan_set_user_data (hb_shape_plan_t    *shape_plan,
+                             hb_user_data_key_t *key,
+                             void *              data,
+                             hb_destroy_func_t   destroy,
+                             hb_bool_t           replace)
+{
+  return hb_object_set_user_data (shape_plan, key, data, destroy, replace);
+}
+
+/**
+ * hb_shape_plan_get_user_data: (skip)
+ * @shape_plan: a shape plan.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.7
+ **/
+void *
+hb_shape_plan_get_user_data (hb_shape_plan_t    *shape_plan,
+                             hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (shape_plan, key);
+}
+
+
+/**
+ * hb_shape_plan_execute:
+ * @shape_plan: a shape plan.
+ * @font: a font.
+ * @buffer: a buffer.
+ * @features: (array length=num_features):
+ * @num_features:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.7
+ **/
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan_t    *shape_plan,
+                       hb_font_t          *font,
+                       hb_buffer_t        *buffer,
+                       const hb_feature_t *features,
+                       unsigned int        num_features)
+{
+  DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
+                  "num_features=%d shaper_func=%p",
+                  num_features,
+                  shape_plan->shaper_func);
+
+  if (unlikely (!buffer->len))
+    return true;
+
+  assert (!hb_object_is_inert (buffer));
+  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
+
+  if (unlikely (hb_object_is_inert (shape_plan)))
+    return false;
+
+  assert (shape_plan->face_unsafe == font->face);
+  assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
+
+#define HB_SHAPER_EXECUTE(shaper) \
+        HB_STMT_START { \
+          return HB_SHAPER_DATA (shaper, shape_plan) && \
+                 hb_##shaper##_shaper_font_data_ensure (font) && \
+                 _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
+        } HB_STMT_END
+
+  if (0)
+    ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+  else if (shape_plan->shaper_func == _hb_##shaper##_shape) \
+    HB_SHAPER_EXECUTE (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+#undef HB_SHAPER_EXECUTE
+
+  return false;
+}
+
+
+/*
+ * caching
+ */
+
+#if 0
+static unsigned int
+hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
+{
+  return hb_segment_properties_hash (&shape_plan->props) +
+         shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_func;
+}
+#endif
+
+/* User-feature caching is currently somewhat dumb:
+ * it only finds matches where the feature array is identical,
+ * not cases where the feature lists would be compatible for plan purposes
+ * but have different ranges, for example.
+ */
+struct hb_shape_plan_proposal_t
+{
+  const hb_segment_properties_t  props;
+  const char * const            *shaper_list;
+  const hb_feature_t            *user_features;
+  unsigned int                   num_user_features;
+  hb_shape_func_t               *shaper_func;
+};
+
+static inline hb_bool_t
+hb_shape_plan_user_features_match (const hb_shape_plan_t          *shape_plan,
+                                   const hb_shape_plan_proposal_t *proposal)
+{
+  if (proposal->num_user_features != shape_plan->num_user_features) return false;
+  for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
+    if (proposal->user_features[i].tag   != shape_plan->user_features[i].tag   ||
+        proposal->user_features[i].value != shape_plan->user_features[i].value ||
+        proposal->user_features[i].start != shape_plan->user_features[i].start ||
+        proposal->user_features[i].end   != shape_plan->user_features[i].end) return false;
+  return true;
+}
+
+static hb_bool_t
+hb_shape_plan_matches (const hb_shape_plan_t          *shape_plan,
+                       const hb_shape_plan_proposal_t *proposal)
+{
+  return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
+         hb_shape_plan_user_features_match (shape_plan, proposal) &&
+         ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
+          (shape_plan->shaper_func == proposal->shaper_func));
+}
+
+static inline hb_bool_t
+hb_non_global_user_features_present (const hb_feature_t *user_features,
+                                     unsigned int        num_user_features)
+{
+  while (num_user_features)
+    if (user_features->start != 0 || user_features->end != (unsigned int) -1)
+      return true;
+    else
+      num_user_features--, user_features++;
+  return false;
+}
+
+/**
+ * hb_shape_plan_create_cached:
+ * @face:
+ * @props:
+ * @user_features: (array length=num_user_features):
+ * @num_user_features:
+ * @shaper_list: (array zero-terminated=1):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.7
+ **/
+hb_shape_plan_t *
+hb_shape_plan_create_cached (hb_face_t                     *face,
+                             const hb_segment_properties_t *props,
+                             const hb_feature_t            *user_features,
+                             unsigned int                   num_user_features,
+                             const char * const            *shaper_list)
+{
+  DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
+                  "face=%p num_features=%d shaper_list=%p",
+                  face,
+                  num_user_features,
+                  shaper_list);
+
+  hb_shape_plan_proposal_t proposal = {
+    *props,
+    shaper_list,
+    user_features,
+    num_user_features,
+    NULL
+  };
+
+  if (shaper_list) {
+    /* Choose shaper.  Adapted from hb_shape_plan_plan().
+     * Must choose shaper exactly the same way as that function. */
+    for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++)
+      if (0)
+        ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+      else if (0 == strcmp (*shaper_item, #shaper) && \
+               hb_##shaper##_shaper_face_data_ensure (face)) \
+      { \
+        proposal.shaper_func = _hb_##shaper##_shape; \
+        break; \
+      }
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+    if (unlikely (!proposal.shaper_func))
+      return hb_shape_plan_get_empty ();
+  }
+
+
+retry:
+  hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atomic_ptr_get (&face->shape_plans);
+  for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
+    if (hb_shape_plan_matches (node->shape_plan, &proposal))
+    {
+      DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
+      return hb_shape_plan_reference (node->shape_plan);
+    }
+
+  /* Not found. */
+
+  hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
+
+  /* Don't add to the cache if face is inert. */
+  if (unlikely (hb_object_is_inert (face)))
+    return shape_plan;
+
+  /* Don't add the plan to the cache if there were user features with non-global ranges */
+
+  if (hb_non_global_user_features_present (user_features, num_user_features))
+    return shape_plan;
+
+  hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
+  if (unlikely (!node))
+    return shape_plan;
+
+  node->shape_plan = shape_plan;
+  node->next = cached_plan_nodes;
+
+  if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) {
+    hb_shape_plan_destroy (shape_plan);
+    free (node);
+    goto retry;
+  }
+  DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, "inserted into cache");
+
+  return hb_shape_plan_reference (shape_plan);
+}
+
+/**
+ * hb_shape_plan_get_shaper:
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.7
+ **/
+const char *
+hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
+{
+  return shape_plan->shaper_name;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape-plan.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2012  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_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_SHAPE_PLAN_H
+#define HB_SHAPE_PLAN_H
+
+#include "hb-common.h"
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+typedef struct hb_shape_plan_t hb_shape_plan_t;
+
+hb_shape_plan_t *
+hb_shape_plan_create (hb_face_t                     *face,
+                      const hb_segment_properties_t *props,
+                      const hb_feature_t            *user_features,
+                      unsigned int                   num_user_features,
+                      const char * const            *shaper_list);
+
+hb_shape_plan_t *
+hb_shape_plan_create_cached (hb_face_t                     *face,
+                             const hb_segment_properties_t *props,
+                             const hb_feature_t            *user_features,
+                             unsigned int                   num_user_features,
+                             const char * const            *shaper_list);
+
+hb_shape_plan_t *
+hb_shape_plan_get_empty (void);
+
+hb_shape_plan_t *
+hb_shape_plan_reference (hb_shape_plan_t *shape_plan);
+
+void
+hb_shape_plan_destroy (hb_shape_plan_t *shape_plan);
+
+hb_bool_t
+hb_shape_plan_set_user_data (hb_shape_plan_t    *shape_plan,
+                             hb_user_data_key_t *key,
+                             void *              data,
+                             hb_destroy_func_t   destroy,
+                             hb_bool_t           replace);
+
+void *
+hb_shape_plan_get_user_data (hb_shape_plan_t    *shape_plan,
+                             hb_user_data_key_t *key);
+
+
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan_t    *shape_plan,
+                       hb_font_t          *font,
+                       hb_buffer_t        *buffer,
+                       const hb_feature_t *features,
+                       unsigned int        num_features);
+
+const char *
+hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan);
+
+
+HB_END_DECLS
+
+#endif /* HB_SHAPE_PLAN_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,406 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+#include "hb-buffer-private.hh"
+#include "hb-font-private.hh"
+
+/**
+ * SECTION:hb-shape
+ * @title: Shaping
+ * @short_description: Conversion of text strings into positioned glyphs
+ * @include: hb.h
+ *
+ * Shaping is the central operation of HarfBuzz. Shaping operates on buffers,
+ * which are sequences of Unicode characters that use the same font and have
+ * the same text direction, script and language. After shaping the buffer
+ * contains the output glyphs and their positions.
+ **/
+
+static bool
+parse_space (const char **pp, const char *end)
+{
+  while (*pp < end && ISSPACE (**pp))
+    (*pp)++;
+  return true;
+}
+
+static bool
+parse_char (const char **pp, const char *end, char c)
+{
+  parse_space (pp, end);
+
+  if (*pp == end || **pp != c)
+    return false;
+
+  (*pp)++;
+  return true;
+}
+
+static bool
+parse_uint (const char **pp, const char *end, unsigned int *pv)
+{
+  char buf[32];
+  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
+  strncpy (buf, *pp, len);
+  buf[len] = '\0';
+
+  char *p = buf;
+  char *pend = p;
+  unsigned int v;
+
+  /* Intentionally use strtol instead of strtoul, such that
+   * -1 turns into "big number"... */
+  errno = 0;
+  v = strtol (p, &pend, 0);
+  if (errno || p == pend)
+    return false;
+
+  *pv = v;
+  *pp += pend - p;
+  return true;
+}
+
+static bool
+parse_bool (const char **pp, const char *end, unsigned int *pv)
+{
+  parse_space (pp, end);
+
+  const char *p = *pp;
+  while (*pp < end && ISALPHA(**pp))
+    (*pp)++;
+
+  /* CSS allows on/off as aliases 1/0. */
+  if (*pp - p == 2 || 0 == strncmp (p, "on", 2))
+    *pv = 1;
+  else if (*pp - p == 3 || 0 == strncmp (p, "off", 2))
+    *pv = 0;
+  else
+    return false;
+
+  return true;
+}
+
+static bool
+parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
+{
+  if (parse_char (pp, end, '-'))
+    feature->value = 0;
+  else {
+    parse_char (pp, end, '+');
+    feature->value = 1;
+  }
+
+  return true;
+}
+
+static bool
+parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature)
+{
+  parse_space (pp, end);
+
+  char quote = 0;
+
+  if (*pp < end && (**pp == '\'' || **pp == '"'))
+  {
+    quote = **pp;
+    (*pp)++;
+  }
+
+  const char *p = *pp;
+  while (*pp < end && ISALNUM(**pp))
+    (*pp)++;
+
+  if (p == *pp || *pp - p > 4)
+    return false;
+
+  feature->tag = hb_tag_from_string (p, *pp - p);
+
+  if (quote)
+  {
+    /* CSS expects exactly four bytes.  And we only allow quotations for
+     * CSS compatibility.  So, enforce the length. */
+     if (*pp - p != 4)
+       return false;
+    if (*pp == end || **pp != quote)
+      return false;
+    (*pp)++;
+  }
+
+  return true;
+}
+
+static bool
+parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
+{
+  parse_space (pp, end);
+
+  bool has_start;
+
+  feature->start = 0;
+  feature->end = (unsigned int) -1;
+
+  if (!parse_char (pp, end, '['))
+    return true;
+
+  has_start = parse_uint (pp, end, &feature->start);
+
+  if (parse_char (pp, end, ':')) {
+    parse_uint (pp, end, &feature->end);
+  } else {
+    if (has_start)
+      feature->end = feature->start + 1;
+  }
+
+  return parse_char (pp, end, ']');
+}
+
+static bool
+parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
+{
+  bool had_equal = parse_char (pp, end, '=');
+  bool had_value = parse_uint (pp, end, &feature->value) ||
+                   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. */
+  return !had_equal || had_value;
+}
+
+
+static bool
+parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
+{
+  return parse_feature_value_prefix (pp, end, feature) &&
+         parse_feature_tag (pp, end, feature) &&
+         parse_feature_indices (pp, end, feature) &&
+         parse_feature_value_postfix (pp, end, feature) &&
+         parse_space (pp, end) &&
+         *pp == end;
+}
+
+/**
+ * hb_feature_from_string:
+ * @str: (array length=len) (element-type uint8_t): a string to parse
+ * @len: length of @str, or -1 if string is nul-terminated
+ * @feature: (out): the #hb_feature_t to initialize with the parsed values
+ *
+ * Parses a string into a #hb_feature_t. If @len is -1 then @str is
+ * %NULL-terminated.
+ *
+ * Return value: %TRUE if @str is successfully parsed, %FALSE otherwise
+ *
+ * Since: 0.9.5
+ **/
+hb_bool_t
+hb_feature_from_string (const char *str, int len,
+                        hb_feature_t *feature)
+{
+  hb_feature_t feat;
+
+  if (len < 0)
+    len = strlen (str);
+
+  if (likely (parse_one_feature (&str, str + len, &feat)))
+  {
+    if (feature)
+      *feature = feat;
+    return true;
+  }
+
+  if (feature)
+    memset (feature, 0, sizeof (*feature));
+  return false;
+}
+
+/**
+ * hb_feature_to_string:
+ * @feature: an #hb_feature_t to convert
+ * @buf: (array length=size) (out): output string
+ * @size: the allocated size of @buf
+ *
+ * Converts a #hb_feature_t into a %NULL-terminated string in the format
+ * understood by hb_feature_from_string(). The client in responsible for
+ * allocating big enough size for @buf, 128 bytes is more than enough.
+ *
+ * Since: 0.9.5
+ **/
+void
+hb_feature_to_string (hb_feature_t *feature,
+                      char *buf, unsigned int size)
+{
+  if (unlikely (!size)) return;
+
+  char s[128];
+  unsigned int len = 0;
+  if (feature->value == 0)
+    s[len++] = '-';
+  hb_tag_to_string (feature->tag, s + len);
+  len += 4;
+  while (len && s[len - 1] == ' ')
+    len--;
+  if (feature->start != 0 || feature->end != (unsigned int) -1)
+  {
+    s[len++] = '[';
+    if (feature->start)
+      len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
+    if (feature->end != feature->start + 1) {
+      s[len++] = ':';
+      if (feature->end != (unsigned int) -1)
+        len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
+    }
+    s[len++] = ']';
+  }
+  if (feature->value > 1)
+  {
+    s[len++] = '=';
+    len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
+  }
+  assert (len < ARRAY_LENGTH (s));
+  len = MIN (len, size - 1);
+  memcpy (buf, s, len);
+  buf[len] = '\0';
+}
+
+
+static const char **static_shaper_list;
+
+#ifdef HB_USE_ATEXIT
+static
+void free_static_shaper_list (void)
+{
+  free (static_shaper_list);
+}
+#endif
+
+/**
+ * hb_shape_list_shapers:
+ *
+ * Retrieves the list of shapers supported by HarfBuzz.
+ *
+ * Return value: (transfer none) (array zero-terminated=1): an array of
+ *    constant strings
+ *
+ * Since: 0.9.2
+ **/
+const char **
+hb_shape_list_shapers (void)
+{
+retry:
+  const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list);
+
+  if (unlikely (!shaper_list))
+  {
+    /* Not found; allocate one. */
+    shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
+    if (unlikely (!shaper_list)) {
+      static const char *nil_shaper_list[] = {NULL};
+      return nil_shaper_list;
+    }
+
+    const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+    unsigned int i;
+    for (i = 0; i < HB_SHAPERS_COUNT; i++)
+      shaper_list[i] = shapers[i].name;
+    shaper_list[i] = NULL;
+
+    if (!hb_atomic_ptr_cmpexch (&static_shaper_list, NULL, shaper_list)) {
+      free (shaper_list);
+      goto retry;
+    }
+
+#ifdef HB_USE_ATEXIT
+    atexit (free_static_shaper_list); /* First person registers atexit() callback. */
+#endif
+  }
+
+  return shaper_list;
+}
+
+
+/**
+ * hb_shape_full:
+ * @font: an #hb_font_t to use for shaping
+ * @buffer: an #hb_buffer_t to shape
+ * @features: (array length=num_features) (allow-none): an array of user
+ *    specified #hb_feature_t or %NULL
+ * @num_features: the length of @features array
+ * @shaper_list: (array zero-terminated=1) (allow-none): a %NULL-terminated
+ *    array of shapers to use or %NULL
+ *
+ * See hb_shape() for details. If @shaper_list is not %NULL, the specified
+ * shapers will be used in the given order, otherwise the default shapers list
+ * will be used.
+ *
+ * Return value: %FALSE if all shapers failed, %TRUE otherwise
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_shape_full (hb_font_t          *font,
+               hb_buffer_t        *buffer,
+               const hb_feature_t *features,
+               unsigned int        num_features,
+               const char * const *shaper_list)
+{
+  hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
+  hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
+  hb_shape_plan_destroy (shape_plan);
+
+  if (res)
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+  return res;
+}
+
+/**
+ * hb_shape:
+ * @font: an #hb_font_t to use for shaping
+ * @buffer: an #hb_buffer_t to shape
+ * @features: (array length=num_features) (allow-none): an array of user
+ *    specified #hb_feature_t or %NULL
+ * @num_features: the length of @features array
+ *
+ * Shapes @buffer using @font turning its Unicode characters content to
+ * positioned glyphs. If @features is not %NULL, it will be used to control the
+ * features applied during shaping.
+ *
+ * Return value: %FALSE if all shapers failed, %TRUE otherwise
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_shape (hb_font_t           *font,
+          hb_buffer_t         *buffer,
+          const hb_feature_t  *features,
+          unsigned int         num_features)
+{
+  hb_shape_full (font, buffer, features, num_features, NULL);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_SHAPE_H
+#define HB_SHAPE_H
+
+#include "hb-common.h"
+#include "hb-buffer.h"
+#include "hb-font.h"
+
+HB_BEGIN_DECLS
+
+
+typedef struct hb_feature_t {
+  hb_tag_t      tag;
+  uint32_t      value;
+  unsigned int  start;
+  unsigned int  end;
+} hb_feature_t;
+
+hb_bool_t
+hb_feature_from_string (const char *str, int len,
+                        hb_feature_t *feature);
+
+void
+hb_feature_to_string (hb_feature_t *feature,
+                      char *buf, unsigned int size);
+
+
+void
+hb_shape (hb_font_t           *font,
+          hb_buffer_t         *buffer,
+          const hb_feature_t  *features,
+          unsigned int         num_features);
+
+hb_bool_t
+hb_shape_full (hb_font_t          *font,
+               hb_buffer_t        *buffer,
+               const hb_feature_t *features,
+               unsigned int        num_features,
+               const char * const *shaper_list);
+
+const char **
+hb_shape_list_shapers (void);
+
+
+HB_END_DECLS
+
+#endif /* HB_SHAPE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shaper-impl-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2012  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_SHAPER_IMPL_PRIVATE_HH
+#define HB_SHAPER_IMPL_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
+
+
+#ifdef HB_SHAPER
+#define HB_SHAPER_DATA_GET(object) HB_SHAPER_DATA (HB_SHAPER, object)
+#endif
+
+
+#endif /* HB_SHAPER_IMPL_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shaper-list.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2012  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_SHAPER_LIST_HH
+#define HB_SHAPER_LIST_HH
+#endif /* HB_SHAPER_LIST_HH */ /* Dummy header guards */
+
+/* v--- Add new shapers in the right place here. */
+
+#ifdef HAVE_GRAPHITE2
+/* Only picks up fonts that have a "Silf" table. */
+HB_SHAPER_IMPLEMENT (graphite2)
+#endif
+#ifdef HAVE_CORETEXT
+/* Only picks up fonts that have a "mort" or "morx" table. */
+HB_SHAPER_IMPLEMENT (coretext_aat)
+#endif
+
+#ifdef HAVE_OT
+HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
+#endif
+
+#ifdef HAVE_UNISCRIBE
+HB_SHAPER_IMPLEMENT (uniscribe)
+#endif
+#ifdef HAVE_CORETEXT
+HB_SHAPER_IMPLEMENT (coretext)
+#endif
+
+#ifdef HAVE_FALLBACK
+HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shaper-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2012  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_SHAPER_PRIVATE_HH
+#define HB_SHAPER_PRIVATE_HH
+
+#include "hb-private.hh"
+
+typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t    *shape_plan,
+                                   hb_font_t          *font,
+                                   hb_buffer_t        *buffer,
+                                   const hb_feature_t *features,
+                                   unsigned int        num_features);
+
+#define HB_SHAPER_IMPLEMENT(name) \
+        extern "C" HB_INTERNAL hb_shape_func_t _hb_##name##_shape;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+struct hb_shaper_pair_t {
+  char name[16];
+  hb_shape_func_t *func;
+};
+
+HB_INTERNAL const hb_shaper_pair_t *
+_hb_shapers_get (void);
+
+
+/* For embedding in face / font / ... */
+struct hb_shaper_data_t {
+#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+};
+
+#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
+
+/* Means: succeeded, but don't need to keep any data. */
+#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
+
+/* Means: tried but failed to create. */
+#define HB_SHAPER_DATA_INVALID ((void *) -1)
+#define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID)
+
+#define HB_SHAPER_DATA_TYPE(shaper, object)             struct hb_##shaper##_shaper_##object##_data_t
+#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance)       (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper)
+#define HB_SHAPER_DATA(shaper, object)                  HB_SHAPER_DATA_INSTANCE (shaper, object, object)
+#define HB_SHAPER_DATA_CREATE_FUNC(shaper, object)      _hb_##shaper##_shaper_##object##_data_create
+#define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object)     _hb_##shaper##_shaper_##object##_data_destroy
+
+#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
+        HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
+        extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
+        HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \
+        extern "C" HB_INTERNAL void \
+        HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data)
+
+#define HB_SHAPER_DATA_DESTROY(shaper, object) \
+    if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object)) \
+      if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
+        HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
+
+#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
+static inline bool \
+hb_##shaper##_shaper_##object##_data_ensure (hb_##object##_t *object) \
+{\
+  retry: \
+  HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \
+  if (unlikely (!data)) { \
+    data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
+    if (unlikely (!data)) \
+      data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
+    if (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), NULL, data)) { \
+      if (data && \
+          data != HB_SHAPER_DATA_INVALID && \
+          data != HB_SHAPER_DATA_SUCCEEDED) \
+        HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
+      goto retry; \
+    } \
+  } \
+  return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \
+}
+
+
+#endif /* HB_SHAPER_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shaper.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2012  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
+ */
+
+#include "hb-private.hh"
+#include "hb-shaper-private.hh"
+#include "hb-atomic-private.hh"
+
+
+static const hb_shaper_pair_t all_shapers[] = {
+#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+};
+
+
+/* Thread-safe, lock-free, shapers */
+
+static const hb_shaper_pair_t *static_shapers;
+
+#ifdef HB_USE_ATEXIT
+static
+void free_static_shapers (void)
+{
+  if (unlikely (static_shapers != all_shapers))
+    free ((void *) static_shapers);
+}
+#endif
+
+const hb_shaper_pair_t *
+_hb_shapers_get (void)
+{
+retry:
+  hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
+
+  if (unlikely (!shapers))
+  {
+    char *env = getenv ("HB_SHAPER_LIST");
+    if (!env || !*env) {
+      (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
+      return (const hb_shaper_pair_t *) all_shapers;
+    }
+
+    /* Not found; allocate one. */
+    shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers));
+    if (unlikely (!shapers)) {
+      (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
+      return (const hb_shaper_pair_t *) all_shapers;
+    }
+
+    memcpy (shapers, all_shapers, sizeof (all_shapers));
+
+     /* Reorder shaper list to prefer requested shapers. */
+    unsigned int i = 0;
+    char *end, *p = env;
+    for (;;) {
+      end = strchr (p, ',');
+      if (!end)
+        end = p + strlen (p);
+
+      for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++)
+        if (end - p == (int) strlen (shapers[j].name) &&
+            0 == strncmp (shapers[j].name, p, end - p))
+        {
+          /* Reorder this shaper to position i */
+         struct hb_shaper_pair_t t = shapers[j];
+         memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
+         shapers[i] = t;
+         i++;
+        }
+
+      if (!*end)
+        break;
+      else
+        p = end + 1;
+    }
+
+    if (!hb_atomic_ptr_cmpexch (&static_shapers, NULL, shapers)) {
+      free (shapers);
+      goto retry;
+    }
+
+#ifdef HB_USE_ATEXIT
+    atexit (free_static_shapers); /* First person registers atexit() callback. */
+#endif
+  }
+
+  return shapers;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ucdn.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hb-private.hh"
+
+#include "hb-unicode-private.hh"
+
+#include "ucdn.h"
+
+static const hb_script_t ucdn_script_translate[] =
+{
+    HB_SCRIPT_COMMON,
+    HB_SCRIPT_LATIN,
+    HB_SCRIPT_GREEK,
+    HB_SCRIPT_CYRILLIC,
+    HB_SCRIPT_ARMENIAN,
+    HB_SCRIPT_HEBREW,
+    HB_SCRIPT_ARABIC,
+    HB_SCRIPT_SYRIAC,
+    HB_SCRIPT_THAANA,
+    HB_SCRIPT_DEVANAGARI,
+    HB_SCRIPT_BENGALI,
+    HB_SCRIPT_GURMUKHI,
+    HB_SCRIPT_GUJARATI,
+    HB_SCRIPT_ORIYA,
+    HB_SCRIPT_TAMIL,
+    HB_SCRIPT_TELUGU,
+    HB_SCRIPT_KANNADA,
+    HB_SCRIPT_MALAYALAM,
+    HB_SCRIPT_SINHALA,
+    HB_SCRIPT_THAI,
+    HB_SCRIPT_LAO,
+    HB_SCRIPT_TIBETAN,
+    HB_SCRIPT_MYANMAR,
+    HB_SCRIPT_GEORGIAN,
+    HB_SCRIPT_HANGUL,
+    HB_SCRIPT_ETHIOPIC,
+    HB_SCRIPT_CHEROKEE,
+    HB_SCRIPT_CANADIAN_SYLLABICS,
+    HB_SCRIPT_OGHAM,
+    HB_SCRIPT_RUNIC,
+    HB_SCRIPT_KHMER,
+    HB_SCRIPT_MONGOLIAN,
+    HB_SCRIPT_HIRAGANA,
+    HB_SCRIPT_KATAKANA,
+    HB_SCRIPT_BOPOMOFO,
+    HB_SCRIPT_HAN,
+    HB_SCRIPT_YI,
+    HB_SCRIPT_OLD_ITALIC,
+    HB_SCRIPT_GOTHIC,
+    HB_SCRIPT_DESERET,
+    HB_SCRIPT_INHERITED,
+    HB_SCRIPT_TAGALOG,
+    HB_SCRIPT_HANUNOO,
+    HB_SCRIPT_BUHID,
+    HB_SCRIPT_TAGBANWA,
+    HB_SCRIPT_LIMBU,
+    HB_SCRIPT_TAI_LE,
+    HB_SCRIPT_LINEAR_B,
+    HB_SCRIPT_UGARITIC,
+    HB_SCRIPT_SHAVIAN,
+    HB_SCRIPT_OSMANYA,
+    HB_SCRIPT_CYPRIOT,
+    HB_SCRIPT_BRAILLE,
+    HB_SCRIPT_BUGINESE,
+    HB_SCRIPT_COPTIC,
+    HB_SCRIPT_NEW_TAI_LUE,
+    HB_SCRIPT_GLAGOLITIC,
+    HB_SCRIPT_TIFINAGH,
+    HB_SCRIPT_SYLOTI_NAGRI,
+    HB_SCRIPT_OLD_PERSIAN,
+    HB_SCRIPT_KHAROSHTHI,
+    HB_SCRIPT_BALINESE,
+    HB_SCRIPT_CUNEIFORM,
+    HB_SCRIPT_PHOENICIAN,
+    HB_SCRIPT_PHAGS_PA,
+    HB_SCRIPT_NKO,
+    HB_SCRIPT_SUNDANESE,
+    HB_SCRIPT_LEPCHA,
+    HB_SCRIPT_OL_CHIKI,
+    HB_SCRIPT_VAI,
+    HB_SCRIPT_SAURASHTRA,
+    HB_SCRIPT_KAYAH_LI,
+    HB_SCRIPT_REJANG,
+    HB_SCRIPT_LYCIAN,
+    HB_SCRIPT_CARIAN,
+    HB_SCRIPT_LYDIAN,
+    HB_SCRIPT_CHAM,
+    HB_SCRIPT_TAI_THAM,
+    HB_SCRIPT_TAI_VIET,
+    HB_SCRIPT_AVESTAN,
+    HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,
+    HB_SCRIPT_SAMARITAN,
+    HB_SCRIPT_LISU,
+    HB_SCRIPT_BAMUM,
+    HB_SCRIPT_JAVANESE,
+    HB_SCRIPT_MEETEI_MAYEK,
+    HB_SCRIPT_IMPERIAL_ARAMAIC,
+    HB_SCRIPT_OLD_SOUTH_ARABIAN,
+    HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
+    HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,
+    HB_SCRIPT_OLD_TURKIC,
+    HB_SCRIPT_KAITHI,
+    HB_SCRIPT_BATAK,
+    HB_SCRIPT_BRAHMI,
+    HB_SCRIPT_MANDAIC,
+    HB_SCRIPT_CHAKMA,
+    HB_SCRIPT_MEROITIC_CURSIVE,
+    HB_SCRIPT_MEROITIC_HIEROGLYPHS,
+    HB_SCRIPT_MIAO,
+    HB_SCRIPT_SHARADA,
+    HB_SCRIPT_SORA_SOMPENG,
+    HB_SCRIPT_TAKRI,
+    HB_SCRIPT_UNKNOWN,
+    HB_SCRIPT_BASSA_VAH,
+    HB_SCRIPT_CAUCASIAN_ALBANIAN,
+    HB_SCRIPT_DUPLOYAN,
+    HB_SCRIPT_ELBASAN,
+    HB_SCRIPT_GRANTHA,
+    HB_SCRIPT_KHOJKI,
+    HB_SCRIPT_KHUDAWADI,
+    HB_SCRIPT_LINEAR_A,
+    HB_SCRIPT_MAHAJANI,
+    HB_SCRIPT_MANICHAEAN,
+    HB_SCRIPT_MENDE_KIKAKUI,
+    HB_SCRIPT_MODI,
+    HB_SCRIPT_MRO,
+    HB_SCRIPT_NABATAEAN,
+    HB_SCRIPT_OLD_NORTH_ARABIAN,
+    HB_SCRIPT_OLD_PERMIC,
+    HB_SCRIPT_PAHAWH_HMONG,
+    HB_SCRIPT_PALMYRENE,
+    HB_SCRIPT_PAU_CIN_HAU,
+    HB_SCRIPT_PSALTER_PAHLAVI,
+    HB_SCRIPT_SIDDHAM,
+    HB_SCRIPT_TIRHUTA,
+    HB_SCRIPT_WARANG_CITI,
+    HB_SCRIPT_AHOM,
+    HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,
+    HB_SCRIPT_HATRAN,
+    HB_SCRIPT_MULTANI,
+    HB_SCRIPT_OLD_HUNGARIAN,
+    HB_SCRIPT_SIGNWRITING,
+};
+
+static hb_unicode_combining_class_t
+hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+                        void *user_data HB_UNUSED)
+{
+    return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
+}
+
+static unsigned int
+hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+                        void *user_data HB_UNUSED)
+{
+    int w = ucdn_get_east_asian_width(unicode);
+    return (w == UCDN_EAST_ASIAN_F || w == UCDN_EAST_ASIAN_W) ? 2 : 1;
+}
+
+static hb_unicode_general_category_t
+hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+                         void *user_data HB_UNUSED)
+{
+    return (hb_unicode_general_category_t)ucdn_get_general_category(unicode);
+}
+
+static hb_codepoint_t
+hb_ucdn_mirroring(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+                  void *user_data HB_UNUSED)
+{
+    return ucdn_mirror(unicode);
+}
+
+static hb_script_t
+hb_ucdn_script(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+               void *user_data HB_UNUSED)
+{
+    return ucdn_script_translate[ucdn_get_script(unicode)];
+}
+
+static hb_bool_t
+hb_ucdn_compose(hb_unicode_funcs_t *ufuncs,
+                hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
+                void *user_data HB_UNUSED)
+{
+    return ucdn_compose(ab, a, b);
+}
+
+static hb_bool_t
+hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs,
+                  hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b,
+                  void *user_data HB_UNUSED)
+{
+    return ucdn_decompose(ab, a, b);
+}
+
+static unsigned int
+hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs,
+                                hb_codepoint_t u, hb_codepoint_t *decomposed,
+                                void *user_data HB_UNUSED)
+{
+    return ucdn_compat_decompose(u, decomposed);
+}
+
+extern "C" HB_INTERNAL
+hb_unicode_funcs_t *
+hb_ucdn_get_unicode_funcs (void)
+{
+  static const hb_unicode_funcs_t _hb_ucdn_unicode_funcs = {
+    HB_OBJECT_HEADER_STATIC,
+
+    NULL, /* parent */
+    true, /* immutable */
+    {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_ucdn_##name,
+      HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+    }
+  };
+
+  return const_cast<hb_unicode_funcs_t *> (&_hb_ucdn_unicode_funcs);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ucdn/ucdn.c	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ucdn.h"
+
+typedef struct {
+    unsigned char category;
+    unsigned char combining;
+    unsigned char bidi_class;
+    unsigned char mirrored;
+    unsigned char east_asian_width;
+    unsigned char normalization_check;
+    unsigned char script;
+} UCDRecord;
+
+typedef struct {
+    unsigned short from, to;
+} MirrorPair;
+
+typedef struct {
+    unsigned int start;
+    short count, index;
+} Reindex;
+
+#include "unicodedata_db.h"
+
+/* constants required for Hangul (de)composition */
+#define SBASE 0xAC00
+#define LBASE 0x1100
+#define VBASE 0x1161
+#define TBASE 0x11A7
+#define SCOUNT 11172
+#define LCOUNT 19
+#define VCOUNT 21
+#define TCOUNT 28
+#define NCOUNT (VCOUNT * TCOUNT)
+
+static const UCDRecord *get_ucd_record(uint32_t code)
+{
+    int index, offset;
+
+    if (code >= 0x110000)
+        index = 0;
+    else {
+        index  = index0[code >> (SHIFT1+SHIFT2)] << SHIFT1;
+        offset = (code >> SHIFT2) & ((1<<SHIFT1) - 1);
+        index  = index1[index + offset] << SHIFT2;
+        offset = code & ((1<<SHIFT2) - 1);
+        index  = index2[index + offset];
+    }
+
+    return &ucd_records[index];
+}
+
+static const unsigned short *get_decomp_record(uint32_t code)
+{
+    int index, offset;
+
+    if (code >= 0x110000)
+        index = 0;
+    else {
+        index  = decomp_index0[code >> (DECOMP_SHIFT1+DECOMP_SHIFT2)]
+            << DECOMP_SHIFT1;
+        offset = (code >> DECOMP_SHIFT2) & ((1<<DECOMP_SHIFT1) - 1);
+        index  = decomp_index1[index + offset] << DECOMP_SHIFT2;
+        offset = code & ((1<<DECOMP_SHIFT2) - 1);
+        index  = decomp_index2[index + offset];
+    }
+
+    return &decomp_data[index];
+}
+
+static int get_comp_index(uint32_t code, const Reindex *idx)
+{
+    int i;
+
+    for (i = 0; idx[i].start; i++) {
+        const Reindex *cur = &idx[i];
+        if (code < cur->start)
+            return -1;
+        if (code <= cur->start + cur->count) {
+            return cur->index + (code - cur->start);
+        }
+    }
+
+    return -1;
+}
+
+static int compare_mp(const void *a, const void *b)
+{
+    MirrorPair *mpa = (MirrorPair *)a;
+    MirrorPair *mpb = (MirrorPair *)b;
+    return mpa->from - mpb->from;
+}
+
+static int hangul_pair_decompose(uint32_t code, uint32_t *a, uint32_t *b)
+{
+    int si = code - SBASE;
+
+    if (si < 0 || si >= SCOUNT)
+        return 0;
+
+    if (si % TCOUNT) {
+        /* LV,T */
+        *a = SBASE + (si / TCOUNT) * TCOUNT;
+        *b = TBASE + (si % TCOUNT);
+        return 3;
+    } else {
+        /* L,V */
+        *a = LBASE + (si / NCOUNT);
+        *b = VBASE + (si % NCOUNT) / TCOUNT;
+        return 2;
+    }
+}
+
+static int hangul_pair_compose(uint32_t *code, uint32_t a, uint32_t b)
+{
+    if (b < VBASE || b >= (TBASE + TCOUNT))
+        return 0;
+
+    if ((a < LBASE || a >= (LBASE + LCOUNT))
+            && (a < SBASE || a >= (SBASE + SCOUNT)))
+        return 0;
+
+    if (a >= SBASE) {
+        /* LV,T */
+        *code = a + (b - TBASE);
+        return 3;
+    } else {
+        /* L,V */
+        int li = a - LBASE;
+        int vi = b - VBASE;
+        *code = SBASE + li * NCOUNT + vi * TCOUNT;
+        return 2;
+    }
+}
+
+static uint32_t decode_utf16(const unsigned short **code_ptr)
+{
+    const unsigned short *code = *code_ptr;
+
+    if ((code[0] & 0xd800) != 0xd800) {
+        *code_ptr += 1;
+        return (uint32_t)code[0];
+    } else {
+        *code_ptr += 2;
+        return 0x10000 + ((uint32_t)code[1] - 0xdc00) +
+            (((uint32_t)code[0] - 0xd800) << 10);
+    }
+}
+
+const char *ucdn_get_unicode_version(void)
+{
+    return UNIDATA_VERSION;
+}
+
+int ucdn_get_combining_class(uint32_t code)
+{
+    return get_ucd_record(code)->combining;
+}
+
+int ucdn_get_east_asian_width(uint32_t code)
+{
+    return get_ucd_record(code)->east_asian_width;
+}
+
+int ucdn_get_general_category(uint32_t code)
+{
+    return get_ucd_record(code)->category;
+}
+
+int ucdn_get_bidi_class(uint32_t code)
+{
+    return get_ucd_record(code)->bidi_class;
+}
+
+int ucdn_get_mirrored(uint32_t code)
+{
+    return get_ucd_record(code)->mirrored;
+}
+
+int ucdn_get_script(uint32_t code)
+{
+    return get_ucd_record(code)->script;
+}
+
+uint32_t ucdn_mirror(uint32_t code)
+{
+    MirrorPair mp = {0};
+    MirrorPair *res;
+
+    if (get_ucd_record(code)->mirrored == 0)
+        return code;
+
+    mp.from = code;
+    res = bsearch(&mp, mirror_pairs, BIDI_MIRROR_LEN, sizeof(MirrorPair),
+            compare_mp);
+
+    if (res == NULL)
+        return code;
+    else
+        return res->to;
+}
+
+int ucdn_decompose(uint32_t code, uint32_t *a, uint32_t *b)
+{
+    const unsigned short *rec;
+    int len;
+
+    if (hangul_pair_decompose(code, a, b))
+        return 1;
+
+    rec = get_decomp_record(code);
+    len = rec[0] >> 8;
+
+    if ((rec[0] & 0xff) != 0 || len == 0)
+        return 0;
+
+    rec++;
+    *a = decode_utf16(&rec);
+    if (len > 1)
+        *b = decode_utf16(&rec);
+    else
+        *b = 0;
+
+    return 1;
+}
+
+int ucdn_compose(uint32_t *code, uint32_t a, uint32_t b)
+{
+    int l, r, index, indexi, offset;
+
+    if (hangul_pair_compose(code, a, b))
+        return 1;
+
+    l = get_comp_index(a, nfc_first);
+    r = get_comp_index(b, nfc_last);
+
+    if (l < 0 || r < 0)
+        return 0;
+
+    indexi = l * TOTAL_LAST + r;
+    index  = comp_index0[indexi >> (COMP_SHIFT1+COMP_SHIFT2)] << COMP_SHIFT1;
+    offset = (indexi >> COMP_SHIFT2) & ((1<<COMP_SHIFT1) - 1);
+    index  = comp_index1[index + offset] << COMP_SHIFT2;
+    offset = indexi & ((1<<COMP_SHIFT2) - 1);
+    *code  = comp_data[index + offset];
+
+    return *code != 0;
+}
+
+int ucdn_compat_decompose(uint32_t code, uint32_t *decomposed)
+{
+    int i, len;
+    const unsigned short *rec = get_decomp_record(code);
+    len = rec[0] >> 8;
+
+    if (len == 0)
+        return 0;
+
+    rec++;
+    for (i = 0; i < len; i++)
+        decomposed[i] = decode_utf16(&rec);
+
+    return len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ucdn/ucdn.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef UCDN_H
+#define UCDN_H
+
+#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
+# define HB_BEGIN_VISIBILITY _Pragma ("GCC visibility push(hidden)")
+# define HB_END_VISIBILITY _Pragma ("GCC visibility pop")
+#else
+# define HB_BEGIN_VISIBILITY
+# define HB_END_VISIBILITY
+#endif
+#ifdef __cplusplus
+# define HB_BEGIN_HEADER  extern "C" { HB_BEGIN_VISIBILITY
+# define HB_END_HEADER  HB_END_VISIBILITY }
+#else
+# define HB_BEGIN_HEADER  HB_BEGIN_VISIBILITY
+# define HB_END_HEADER  HB_END_VISIBILITY
+#endif
+
+HB_BEGIN_HEADER
+
+#if !defined (HB_DONT_DEFINE_STDINT)
+
+#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
+    defined (_sgi) || defined (__sun) || defined (sun) || \
+    defined (__digital__) || defined (__HP_cc)
+#  include <inttypes.h>
+#elif defined (_AIX)
+#  include <sys/inttypes.h>
+/* VS 2010 (_MSC_VER 1600) has stdint.h */
+#elif defined (_MSC_VER) && _MSC_VER < 1600
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#  include <stdint.h>
+#endif
+
+#endif
+
+#define UCDN_EAST_ASIAN_F 0
+#define UCDN_EAST_ASIAN_H 1
+#define UCDN_EAST_ASIAN_W 2
+#define UCDN_EAST_ASIAN_NA 3
+#define UCDN_EAST_ASIAN_A 4
+#define UCDN_EAST_ASIAN_N 5
+
+#define UCDN_SCRIPT_COMMON 0
+#define UCDN_SCRIPT_LATIN 1
+#define UCDN_SCRIPT_GREEK 2
+#define UCDN_SCRIPT_CYRILLIC 3
+#define UCDN_SCRIPT_ARMENIAN 4
+#define UCDN_SCRIPT_HEBREW 5
+#define UCDN_SCRIPT_ARABIC 6
+#define UCDN_SCRIPT_SYRIAC 7
+#define UCDN_SCRIPT_THAANA 8
+#define UCDN_SCRIPT_DEVANAGARI 9
+#define UCDN_SCRIPT_BENGALI 10
+#define UCDN_SCRIPT_GURMUKHI 11
+#define UCDN_SCRIPT_GUJARATI 12
+#define UCDN_SCRIPT_ORIYA 13
+#define UCDN_SCRIPT_TAMIL 14
+#define UCDN_SCRIPT_TELUGU 15
+#define UCDN_SCRIPT_KANNADA 16
+#define UCDN_SCRIPT_MALAYALAM 17
+#define UCDN_SCRIPT_SINHALA 18
+#define UCDN_SCRIPT_THAI 19
+#define UCDN_SCRIPT_LAO 20
+#define UCDN_SCRIPT_TIBETAN 21
+#define UCDN_SCRIPT_MYANMAR 22
+#define UCDN_SCRIPT_GEORGIAN 23
+#define UCDN_SCRIPT_HANGUL 24
+#define UCDN_SCRIPT_ETHIOPIC 25
+#define UCDN_SCRIPT_CHEROKEE 26
+#define UCDN_SCRIPT_CANADIAN_ABORIGINAL 27
+#define UCDN_SCRIPT_OGHAM 28
+#define UCDN_SCRIPT_RUNIC 29
+#define UCDN_SCRIPT_KHMER 30
+#define UCDN_SCRIPT_MONGOLIAN 31
+#define UCDN_SCRIPT_HIRAGANA 32
+#define UCDN_SCRIPT_KATAKANA 33
+#define UCDN_SCRIPT_BOPOMOFO 34
+#define UCDN_SCRIPT_HAN 35
+#define UCDN_SCRIPT_YI 36
+#define UCDN_SCRIPT_OLD_ITALIC 37
+#define UCDN_SCRIPT_GOTHIC 38
+#define UCDN_SCRIPT_DESERET 39
+#define UCDN_SCRIPT_INHERITED 40
+#define UCDN_SCRIPT_TAGALOG 41
+#define UCDN_SCRIPT_HANUNOO 42
+#define UCDN_SCRIPT_BUHID 43
+#define UCDN_SCRIPT_TAGBANWA 44
+#define UCDN_SCRIPT_LIMBU 45
+#define UCDN_SCRIPT_TAI_LE 46
+#define UCDN_SCRIPT_LINEAR_B 47
+#define UCDN_SCRIPT_UGARITIC 48
+#define UCDN_SCRIPT_SHAVIAN 49
+#define UCDN_SCRIPT_OSMANYA 50
+#define UCDN_SCRIPT_CYPRIOT 51
+#define UCDN_SCRIPT_BRAILLE 52
+#define UCDN_SCRIPT_BUGINESE 53
+#define UCDN_SCRIPT_COPTIC 54
+#define UCDN_SCRIPT_NEW_TAI_LUE 55
+#define UCDN_SCRIPT_GLAGOLITIC 56
+#define UCDN_SCRIPT_TIFINAGH 57
+#define UCDN_SCRIPT_SYLOTI_NAGRI 58
+#define UCDN_SCRIPT_OLD_PERSIAN 59
+#define UCDN_SCRIPT_KHAROSHTHI 60
+#define UCDN_SCRIPT_BALINESE 61
+#define UCDN_SCRIPT_CUNEIFORM 62
+#define UCDN_SCRIPT_PHOENICIAN 63
+#define UCDN_SCRIPT_PHAGS_PA 64
+#define UCDN_SCRIPT_NKO 65
+#define UCDN_SCRIPT_SUNDANESE 66
+#define UCDN_SCRIPT_LEPCHA 67
+#define UCDN_SCRIPT_OL_CHIKI 68
+#define UCDN_SCRIPT_VAI 69
+#define UCDN_SCRIPT_SAURASHTRA 70
+#define UCDN_SCRIPT_KAYAH_LI 71
+#define UCDN_SCRIPT_REJANG 72
+#define UCDN_SCRIPT_LYCIAN 73
+#define UCDN_SCRIPT_CARIAN 74
+#define UCDN_SCRIPT_LYDIAN 75
+#define UCDN_SCRIPT_CHAM 76
+#define UCDN_SCRIPT_TAI_THAM 77
+#define UCDN_SCRIPT_TAI_VIET 78
+#define UCDN_SCRIPT_AVESTAN 79
+#define UCDN_SCRIPT_EGYPTIAN_HIEROGLYPHS 80
+#define UCDN_SCRIPT_SAMARITAN 81
+#define UCDN_SCRIPT_LISU 82
+#define UCDN_SCRIPT_BAMUM 83
+#define UCDN_SCRIPT_JAVANESE 84
+#define UCDN_SCRIPT_MEETEI_MAYEK 85
+#define UCDN_SCRIPT_IMPERIAL_ARAMAIC 86
+#define UCDN_SCRIPT_OLD_SOUTH_ARABIAN 87
+#define UCDN_SCRIPT_INSCRIPTIONAL_PARTHIAN 88
+#define UCDN_SCRIPT_INSCRIPTIONAL_PAHLAVI 89
+#define UCDN_SCRIPT_OLD_TURKIC 90
+#define UCDN_SCRIPT_KAITHI 91
+#define UCDN_SCRIPT_BATAK 92
+#define UCDN_SCRIPT_BRAHMI 93
+#define UCDN_SCRIPT_MANDAIC 94
+#define UCDN_SCRIPT_CHAKMA 95
+#define UCDN_SCRIPT_MEROITIC_CURSIVE 96
+#define UCDN_SCRIPT_MEROITIC_HIEROGLYPHS 97
+#define UCDN_SCRIPT_MIAO 98
+#define UCDN_SCRIPT_SHARADA 99
+#define UCDN_SCRIPT_SORA_SOMPENG 100
+#define UCDN_SCRIPT_TAKRI 101
+#define UCDN_SCRIPT_UNKNOWN 102
+#define UCDN_SCRIPT_BASSA_VAH 103
+#define UCDN_SCRIPT_CAUCASIAN_ALBANIAN 104
+#define UCDN_SCRIPT_DUPLOYAN 105
+#define UCDN_SCRIPT_ELBASAN 106
+#define UCDN_SCRIPT_GRANTHA 107
+#define UCDN_SCRIPT_KHOJKI 108
+#define UCDN_SCRIPT_KHUDAWADI 109
+#define UCDN_SCRIPT_LINEAR_A 110
+#define UCDN_SCRIPT_MAHAJANI 111
+#define UCDN_SCRIPT_MANICHAEAN 112
+#define UCDN_SCRIPT_MENDE_KIKAKUI 113
+#define UCDN_SCRIPT_MODI 114
+#define UCDN_SCRIPT_MRO 115
+#define UCDN_SCRIPT_NABATAEAN 116
+#define UCDN_SCRIPT_OLD_NORTH_ARABIAN 117
+#define UCDN_SCRIPT_OLD_PERMIC 118
+#define UCDN_SCRIPT_PAHAWH_HMONG 119
+#define UCDN_SCRIPT_PALMYRENE 120
+#define UCDN_SCRIPT_PAU_CIN_HAU 121
+#define UCDN_SCRIPT_PSALTER_PAHLAVI 122
+#define UCDN_SCRIPT_SIDDHAM 123
+#define UCDN_SCRIPT_TIRHUTA 124
+#define UCDN_SCRIPT_WARANG_CITI 125
+#define UCDN_SCRIPT_AHOM 126
+#define UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS 127
+#define UCDN_SCRIPT_HATRAN 128
+#define UCDN_SCRIPT_MULTANI 129
+#define UCDN_SCRIPT_OLD_HUNGARIAN 130
+#define UCDN_SCRIPT_SIGNWRITING 131
+
+#define UCDN_GENERAL_CATEGORY_CC 0
+#define UCDN_GENERAL_CATEGORY_CF 1
+#define UCDN_GENERAL_CATEGORY_CN 2
+#define UCDN_GENERAL_CATEGORY_CO 3
+#define UCDN_GENERAL_CATEGORY_CS 4
+#define UCDN_GENERAL_CATEGORY_LL 5
+#define UCDN_GENERAL_CATEGORY_LM 6
+#define UCDN_GENERAL_CATEGORY_LO 7
+#define UCDN_GENERAL_CATEGORY_LT 8
+#define UCDN_GENERAL_CATEGORY_LU 9
+#define UCDN_GENERAL_CATEGORY_MC 10
+#define UCDN_GENERAL_CATEGORY_ME 11
+#define UCDN_GENERAL_CATEGORY_MN 12
+#define UCDN_GENERAL_CATEGORY_ND 13
+#define UCDN_GENERAL_CATEGORY_NL 14
+#define UCDN_GENERAL_CATEGORY_NO 15
+#define UCDN_GENERAL_CATEGORY_PC 16
+#define UCDN_GENERAL_CATEGORY_PD 17
+#define UCDN_GENERAL_CATEGORY_PE 18
+#define UCDN_GENERAL_CATEGORY_PF 19
+#define UCDN_GENERAL_CATEGORY_PI 20
+#define UCDN_GENERAL_CATEGORY_PO 21
+#define UCDN_GENERAL_CATEGORY_PS 22
+#define UCDN_GENERAL_CATEGORY_SC 23
+#define UCDN_GENERAL_CATEGORY_SK 24
+#define UCDN_GENERAL_CATEGORY_SM 25
+#define UCDN_GENERAL_CATEGORY_SO 26
+#define UCDN_GENERAL_CATEGORY_ZL 27
+#define UCDN_GENERAL_CATEGORY_ZP 28
+#define UCDN_GENERAL_CATEGORY_ZS 29
+
+#define UCDN_BIDI_CLASS_L 0
+#define UCDN_BIDI_CLASS_LRE 1
+#define UCDN_BIDI_CLASS_LRO 2
+#define UCDN_BIDI_CLASS_R 3
+#define UCDN_BIDI_CLASS_AL 4
+#define UCDN_BIDI_CLASS_RLE 5
+#define UCDN_BIDI_CLASS_RLO 6
+#define UCDN_BIDI_CLASS_PDF 7
+#define UCDN_BIDI_CLASS_EN 8
+#define UCDN_BIDI_CLASS_ES 9
+#define UCDN_BIDI_CLASS_ET 10
+#define UCDN_BIDI_CLASS_AN 11
+#define UCDN_BIDI_CLASS_CS 12
+#define UCDN_BIDI_CLASS_NSM 13
+#define UCDN_BIDI_CLASS_BN 14
+#define UCDN_BIDI_CLASS_B 15
+#define UCDN_BIDI_CLASS_S 16
+#define UCDN_BIDI_CLASS_WS 17
+#define UCDN_BIDI_CLASS_ON 18
+#define UCDN_BIDI_CLASS_LRI 19
+#define UCDN_BIDI_CLASS_RLI 20
+#define UCDN_BIDI_CLASS_FSI 21
+#define UCDN_BIDI_CLASS_PDI 22
+
+/**
+ * Return version of the Unicode database.
+ *
+ * @return Unicode database version
+ */
+const char *ucdn_get_unicode_version(void);
+
+/**
+ * Get combining class of a codepoint.
+ *
+ * @param code Unicode codepoint
+ * @return combining class value, as defined in UAX#44
+ */
+int ucdn_get_combining_class(uint32_t code);
+
+/**
+ * Get east-asian width of a codepoint.
+ *
+ * @param code Unicode codepoint
+ * @return value according to UCDN_EAST_ASIAN_* and as defined in UAX#11.
+ */
+int ucdn_get_east_asian_width(uint32_t code);
+
+/**
+ * Get general category of a codepoint.
+ *
+ * @param code Unicode codepoint
+ * @return value according to UCDN_GENERAL_CATEGORY_* and as defined in
+ * UAX#44.
+ */
+int ucdn_get_general_category(uint32_t code);
+
+/**
+ * Get bidirectional class of a codepoint.
+ *
+ * @param code Unicode codepoint
+ * @return value according to UCDN_BIDI_CLASS_* and as defined in UAX#44.
+ */
+int ucdn_get_bidi_class(uint32_t code);
+
+/**
+ * Get script of a codepoint.
+ *
+ * @param code Unicode codepoint
+ * @return value according to UCDN_SCRIPT_* and as defined in UAX#24.
+ */
+int ucdn_get_script(uint32_t code);
+
+/**
+ * Check if codepoint can be mirrored.
+ *
+ * @param code Unicode codepoint
+ * @return 1 if mirrored character exists, otherwise 0
+ */
+int ucdn_get_mirrored(uint32_t code);
+
+/**
+ * Mirror a codepoint.
+ *
+ * @param code Unicode codepoint
+ * @return mirrored codepoint or the original codepoint if no
+ * mirrored character exists
+ */
+uint32_t ucdn_mirror(uint32_t code);
+
+/**
+ * Pairwise canonical decomposition of a codepoint. This includes
+ * Hangul Jamo decomposition (see chapter 3.12 of the Unicode core
+ * specification).
+ *
+ * Hangul is decomposed into L and V jamos for LV forms, and an
+ * LV precomposed syllable and a T jamo for LVT forms.
+ *
+ * @param code Unicode codepoint
+ * @param a filled with first codepoint of decomposition
+ * @param b filled with second codepoint of decomposition, or 0
+ * @return success
+ */
+int ucdn_decompose(uint32_t code, uint32_t *a, uint32_t *b);
+
+/**
+ * Compatibility decomposition of a codepoint.
+ *
+ * @param code Unicode codepoint
+ * @param decomposed filled with decomposition, must be able to hold 18
+ * characters
+ * @return length of decomposition or 0 in case none exists
+ */
+int ucdn_compat_decompose(uint32_t code, uint32_t *decomposed);
+
+/**
+ * Pairwise canonical composition of two codepoints. This includes
+ * Hangul Jamo composition (see chapter 3.12 of the Unicode core
+ * specification).
+ *
+ * Hangul composition expects either L and V jamos, or an LV
+ * precomposed syllable and a T jamo. This is exactly the inverse
+ * of pairwise Hangul decomposition.
+ *
+ * @param code filled with composition
+ * @param a first codepoint
+ * @param b second codepoint
+ * @return success
+ */
+int ucdn_compose(uint32_t *code, uint32_t a, uint32_t b);
+
+HB_END_HEADER
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ucdn/unicodedata_db.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,5062 @@
+/* this file was generated by makeunicodedata.py 3.2 */
+
+#define UNIDATA_VERSION "8.0.0"
+/* a list of unique database records */
+static const UCDRecord ucd_records[] = {
+    {2, 0, 18, 0, 5, 0, 102},
+    {0, 0, 14, 0, 5, 0, 0},
+    {0, 0, 16, 0, 5, 0, 0},
+    {0, 0, 15, 0, 5, 0, 0},
+    {0, 0, 17, 0, 5, 0, 0},
+    {29, 0, 17, 0, 3, 0, 0},
+    {21, 0, 18, 0, 3, 0, 0},
+    {21, 0, 10, 0, 3, 0, 0},
+    {23, 0, 10, 0, 3, 0, 0},
+    {22, 0, 18, 1, 3, 0, 0},
+    {18, 0, 18, 1, 3, 0, 0},
+    {25, 0, 9, 0, 3, 0, 0},
+    {21, 0, 12, 0, 3, 0, 0},
+    {17, 0, 9, 0, 3, 0, 0},
+    {13, 0, 8, 0, 3, 0, 0},
+    {25, 0, 18, 1, 3, 0, 0},
+    {25, 0, 18, 0, 3, 0, 0},
+    {9, 0, 0, 0, 3, 0, 1},
+    {24, 0, 18, 0, 3, 0, 0},
+    {16, 0, 18, 0, 3, 0, 0},
+    {5, 0, 0, 0, 3, 0, 1},
+    {29, 0, 12, 0, 5, 0, 0},
+    {21, 0, 18, 0, 4, 0, 0},
+    {23, 0, 10, 0, 4, 0, 0},
+    {26, 0, 18, 0, 3, 0, 0},
+    {24, 0, 18, 0, 4, 0, 0},
+    {26, 0, 18, 0, 5, 0, 0},
+    {7, 0, 0, 0, 4, 0, 1},
+    {20, 0, 18, 1, 5, 0, 0},
+    {1, 0, 14, 0, 4, 0, 0},
+    {26, 0, 18, 0, 4, 0, 0},
+    {26, 0, 10, 0, 4, 0, 0},
+    {25, 0, 10, 0, 4, 0, 0},
+    {15, 0, 8, 0, 4, 0, 0},
+    {5, 0, 0, 0, 5, 0, 0},
+    {19, 0, 18, 1, 5, 0, 0},
+    {15, 0, 18, 0, 4, 0, 0},
+    {9, 0, 0, 0, 5, 0, 1},
+    {9, 0, 0, 0, 4, 0, 1},
+    {25, 0, 18, 0, 4, 0, 0},
+    {5, 0, 0, 0, 4, 0, 1},
+    {5, 0, 0, 0, 5, 0, 1},
+    {7, 0, 0, 0, 5, 0, 1},
+    {8, 0, 0, 0, 5, 0, 1},
+    {6, 0, 0, 0, 5, 0, 1},
+    {6, 0, 18, 0, 5, 0, 0},
+    {6, 0, 0, 0, 5, 0, 0},
+    {24, 0, 18, 0, 5, 0, 0},
+    {6, 0, 18, 0, 4, 0, 0},
+    {6, 0, 0, 0, 4, 0, 0},
+    {24, 0, 18, 0, 5, 0, 34},
+    {12, 230, 13, 0, 4, 0, 40},
+    {12, 232, 13, 0, 4, 0, 40},
+    {12, 220, 13, 0, 4, 0, 40},
+    {12, 216, 13, 0, 4, 0, 40},
+    {12, 202, 13, 0, 4, 0, 40},
+    {12, 1, 13, 0, 4, 0, 40},
+    {12, 240, 13, 0, 4, 0, 40},
+    {12, 0, 13, 0, 4, 0, 40},
+    {12, 233, 13, 0, 4, 0, 40},
+    {12, 234, 13, 0, 4, 0, 40},
+    {9, 0, 0, 0, 5, 0, 2},
+    {5, 0, 0, 0, 5, 0, 2},
+    {24, 0, 18, 0, 5, 0, 2},
+    {2, 0, 18, 0, 5, 0, 102},
+    {6, 0, 0, 0, 5, 0, 2},
+    {21, 0, 18, 0, 5, 0, 0},
+    {9, 0, 0, 0, 4, 0, 2},
+    {5, 0, 0, 0, 4, 0, 2},
+    {9, 0, 0, 0, 5, 0, 54},
+    {5, 0, 0, 0, 5, 0, 54},
+    {25, 0, 18, 0, 5, 0, 2},
+    {9, 0, 0, 0, 5, 0, 3},
+    {9, 0, 0, 0, 4, 0, 3},
+    {5, 0, 0, 0, 4, 0, 3},
+    {5, 0, 0, 0, 5, 0, 3},
+    {26, 0, 0, 0, 5, 0, 3},
+    {12, 230, 13, 0, 5, 0, 3},
+    {12, 230, 13, 0, 5, 0, 40},
+    {11, 0, 13, 0, 5, 0, 3},
+    {9, 0, 0, 0, 5, 0, 4},
+    {6, 0, 0, 0, 5, 0, 4},
+    {21, 0, 0, 0, 5, 0, 4},
+    {5, 0, 0, 0, 5, 0, 4},
+    {21, 0, 0, 0, 5, 0, 0},
+    {17, 0, 18, 0, 5, 0, 4},
+    {26, 0, 18, 0, 5, 0, 4},
+    {23, 0, 10, 0, 5, 0, 4},
+    {12, 220, 13, 0, 5, 0, 5},
+    {12, 230, 13, 0, 5, 0, 5},
+    {12, 222, 13, 0, 5, 0, 5},
+    {12, 228, 13, 0, 5, 0, 5},
+    {12, 10, 13, 0, 5, 0, 5},
+    {12, 11, 13, 0, 5, 0, 5},
+    {12, 12, 13, 0, 5, 0, 5},
+    {12, 13, 13, 0, 5, 0, 5},
+    {12, 14, 13, 0, 5, 0, 5},
+    {12, 15, 13, 0, 5, 0, 5},
+    {12, 16, 13, 0, 5, 0, 5},
+    {12, 17, 13, 0, 5, 0, 5},
+    {12, 18, 13, 0, 5, 0, 5},
+    {12, 19, 13, 0, 5, 0, 5},
+    {12, 20, 13, 0, 5, 0, 5},
+    {12, 21, 13, 0, 5, 0, 5},
+    {12, 22, 13, 0, 5, 0, 5},
+    {17, 0, 3, 0, 5, 0, 5},
+    {12, 23, 13, 0, 5, 0, 5},
+    {21, 0, 3, 0, 5, 0, 5},
+    {12, 24, 13, 0, 5, 0, 5},
+    {12, 25, 13, 0, 5, 0, 5},
+    {7, 0, 3, 0, 5, 0, 5},
+    {1, 0, 11, 0, 5, 0, 6},
+    {1, 0, 11, 0, 5, 0, 0},
+    {25, 0, 18, 0, 5, 0, 6},
+    {25, 0, 4, 0, 5, 0, 6},
+    {21, 0, 10, 0, 5, 0, 6},
+    {23, 0, 4, 0, 5, 0, 6},
+    {21, 0, 12, 0, 5, 0, 0},
+    {21, 0, 4, 0, 5, 0, 6},
+    {26, 0, 18, 0, 5, 0, 6},
+    {12, 230, 13, 0, 5, 0, 6},
+    {12, 30, 13, 0, 5, 0, 6},
+    {12, 31, 13, 0, 5, 0, 6},
+    {12, 32, 13, 0, 5, 0, 6},
+    {21, 0, 4, 0, 5, 0, 0},
+    {1, 0, 4, 0, 5, 0, 0},
+    {7, 0, 4, 0, 5, 0, 6},
+    {6, 0, 4, 0, 5, 0, 0},
+    {12, 27, 13, 0, 5, 0, 40},
+    {12, 28, 13, 0, 5, 0, 40},
+    {12, 29, 13, 0, 5, 0, 40},
+    {12, 30, 13, 0, 5, 0, 40},
+    {12, 31, 13, 0, 5, 0, 40},
+    {12, 32, 13, 0, 5, 0, 40},
+    {12, 33, 13, 0, 5, 0, 40},
+    {12, 34, 13, 0, 5, 0, 40},
+    {12, 220, 13, 0, 5, 0, 40},
+    {12, 220, 13, 0, 5, 0, 6},
+    {13, 0, 11, 0, 5, 0, 6},
+    {21, 0, 11, 0, 5, 0, 6},
+    {12, 35, 13, 0, 5, 0, 40},
+    {6, 0, 4, 0, 5, 0, 6},
+    {13, 0, 8, 0, 5, 0, 6},
+    {26, 0, 4, 0, 5, 0, 6},
+    {21, 0, 4, 0, 5, 0, 7},
+    {1, 0, 4, 0, 5, 0, 7},
+    {7, 0, 4, 0, 5, 0, 7},
+    {12, 36, 13, 0, 5, 0, 7},
+    {12, 230, 13, 0, 5, 0, 7},
+    {12, 220, 13, 0, 5, 0, 7},
+    {7, 0, 4, 0, 5, 0, 8},
+    {12, 0, 13, 0, 5, 0, 8},
+    {13, 0, 3, 0, 5, 0, 65},
+    {7, 0, 3, 0, 5, 0, 65},
+    {12, 230, 13, 0, 5, 0, 65},
+    {12, 220, 13, 0, 5, 0, 65},
+    {6, 0, 3, 0, 5, 0, 65},
+    {26, 0, 18, 0, 5, 0, 65},
+    {21, 0, 18, 0, 5, 0, 65},
+    {7, 0, 3, 0, 5, 0, 81},
+    {12, 230, 13, 0, 5, 0, 81},
+    {6, 0, 3, 0, 5, 0, 81},
+    {21, 0, 3, 0, 5, 0, 81},
+    {7, 0, 3, 0, 5, 0, 94},
+    {12, 220, 13, 0, 5, 0, 94},
+    {21, 0, 3, 0, 5, 0, 94},
+    {12, 27, 13, 0, 5, 0, 6},
+    {12, 28, 13, 0, 5, 0, 6},
+    {12, 29, 13, 0, 5, 0, 6},
+    {12, 0, 13, 0, 5, 0, 9},
+    {10, 0, 0, 0, 5, 0, 9},
+    {7, 0, 0, 0, 5, 0, 9},
+    {12, 7, 13, 0, 5, 0, 9},
+    {12, 9, 13, 0, 5, 0, 9},
+    {12, 230, 13, 0, 5, 0, 9},
+    {13, 0, 0, 0, 5, 0, 9},
+    {21, 0, 0, 0, 5, 0, 9},
+    {6, 0, 0, 0, 5, 0, 9},
+    {7, 0, 0, 0, 5, 0, 10},
+    {12, 0, 13, 0, 5, 0, 10},
+    {10, 0, 0, 0, 5, 0, 10},
+    {12, 7, 13, 0, 5, 0, 10},
+    {12, 9, 13, 0, 5, 0, 10},
+    {13, 0, 0, 0, 5, 0, 10},
+    {23, 0, 10, 0, 5, 0, 10},
+    {15, 0, 0, 0, 5, 0, 10},
+    {26, 0, 0, 0, 5, 0, 10},
+    {12, 0, 13, 0, 5, 0, 11},
+    {10, 0, 0, 0, 5, 0, 11},
+    {7, 0, 0, 0, 5, 0, 11},
+    {12, 7, 13, 0, 5, 0, 11},
+    {12, 9, 13, 0, 5, 0, 11},
+    {13, 0, 0, 0, 5, 0, 11},
+    {12, 0, 13, 0, 5, 0, 12},
+    {10, 0, 0, 0, 5, 0, 12},
+    {7, 0, 0, 0, 5, 0, 12},
+    {12, 7, 13, 0, 5, 0, 12},
+    {12, 9, 13, 0, 5, 0, 12},
+    {13, 0, 0, 0, 5, 0, 12},
+    {21, 0, 0, 0, 5, 0, 12},
+    {23, 0, 10, 0, 5, 0, 12},
+    {12, 0, 13, 0, 5, 0, 13},
+    {10, 0, 0, 0, 5, 0, 13},
+    {7, 0, 0, 0, 5, 0, 13},
+    {12, 7, 13, 0, 5, 0, 13},
+    {12, 9, 13, 0, 5, 0, 13},
+    {13, 0, 0, 0, 5, 0, 13},
+    {26, 0, 0, 0, 5, 0, 13},
+    {15, 0, 0, 0, 5, 0, 13},
+    {12, 0, 13, 0, 5, 0, 14},
+    {7, 0, 0, 0, 5, 0, 14},
+    {10, 0, 0, 0, 5, 0, 14},
+    {12, 9, 13, 0, 5, 0, 14},
+    {13, 0, 0, 0, 5, 0, 14},
+    {15, 0, 0, 0, 5, 0, 14},
+    {26, 0, 18, 0, 5, 0, 14},
+    {23, 0, 10, 0, 5, 0, 14},
+    {12, 0, 13, 0, 5, 0, 15},
+    {10, 0, 0, 0, 5, 0, 15},
+    {7, 0, 0, 0, 5, 0, 15},
+    {12, 9, 13, 0, 5, 0, 15},
+    {12, 84, 13, 0, 5, 0, 15},
+    {12, 91, 13, 0, 5, 0, 15},
+    {13, 0, 0, 0, 5, 0, 15},
+    {15, 0, 18, 0, 5, 0, 15},
+    {26, 0, 0, 0, 5, 0, 15},
+    {12, 0, 13, 0, 5, 0, 16},
+    {10, 0, 0, 0, 5, 0, 16},
+    {7, 0, 0, 0, 5, 0, 16},
+    {12, 7, 13, 0, 5, 0, 16},
+    {12, 0, 0, 0, 5, 0, 16},
+    {12, 9, 13, 0, 5, 0, 16},
+    {13, 0, 0, 0, 5, 0, 16},
+    {12, 0, 13, 0, 5, 0, 17},
+    {10, 0, 0, 0, 5, 0, 17},
+    {7, 0, 0, 0, 5, 0, 17},
+    {12, 9, 13, 0, 5, 0, 17},
+    {13, 0, 0, 0, 5, 0, 17},
+    {15, 0, 0, 0, 5, 0, 17},
+    {26, 0, 0, 0, 5, 0, 17},
+    {10, 0, 0, 0, 5, 0, 18},
+    {7, 0, 0, 0, 5, 0, 18},
+    {12, 9, 13, 0, 5, 0, 18},
+    {12, 0, 13, 0, 5, 0, 18},
+    {13, 0, 0, 0, 5, 0, 18},
+    {21, 0, 0, 0, 5, 0, 18},
+    {7, 0, 0, 0, 5, 0, 19},
+    {12, 0, 13, 0, 5, 0, 19},
+    {12, 103, 13, 0, 5, 0, 19},
+    {12, 9, 13, 0, 5, 0, 19},
+    {23, 0, 10, 0, 5, 0, 0},
+    {6, 0, 0, 0, 5, 0, 19},
+    {12, 107, 13, 0, 5, 0, 19},
+    {21, 0, 0, 0, 5, 0, 19},
+    {13, 0, 0, 0, 5, 0, 19},
+    {7, 0, 0, 0, 5, 0, 20},
+    {12, 0, 13, 0, 5, 0, 20},
+    {12, 118, 13, 0, 5, 0, 20},
+    {6, 0, 0, 0, 5, 0, 20},
+    {12, 122, 13, 0, 5, 0, 20},
+    {13, 0, 0, 0, 5, 0, 20},
+    {7, 0, 0, 0, 5, 0, 21},
+    {26, 0, 0, 0, 5, 0, 21},
+    {21, 0, 0, 0, 5, 0, 21},
+    {12, 220, 13, 0, 5, 0, 21},
+    {13, 0, 0, 0, 5, 0, 21},
+    {15, 0, 0, 0, 5, 0, 21},
+    {12, 216, 13, 0, 5, 0, 21},
+    {22, 0, 18, 1, 5, 0, 21},
+    {18, 0, 18, 1, 5, 0, 21},
+    {10, 0, 0, 0, 5, 0, 21},
+    {12, 129, 13, 0, 5, 0, 21},
+    {12, 130, 13, 0, 5, 0, 21},
+    {12, 0, 13, 0, 5, 0, 21},
+    {12, 132, 13, 0, 5, 0, 21},
+    {12, 230, 13, 0, 5, 0, 21},
+    {12, 9, 13, 0, 5, 0, 21},
+    {26, 0, 0, 0, 5, 0, 0},
+    {7, 0, 0, 0, 5, 0, 22},
+    {10, 0, 0, 0, 5, 0, 22},
+    {12, 0, 13, 0, 5, 0, 22},
+    {12, 7, 13, 0, 5, 0, 22},
+    {12, 9, 13, 0, 5, 0, 22},
+    {13, 0, 0, 0, 5, 0, 22},
+    {21, 0, 0, 0, 5, 0, 22},
+    {12, 220, 13, 0, 5, 0, 22},
+    {26, 0, 0, 0, 5, 0, 22},
+    {9, 0, 0, 0, 5, 0, 23},
+    {7, 0, 0, 0, 5, 0, 23},
+    {6, 0, 0, 0, 5, 0, 23},
+    {7, 0, 0, 0, 2, 0, 24},
+    {7, 0, 0, 0, 5, 0, 24},
+    {7, 0, 0, 0, 5, 0, 25},
+    {12, 230, 13, 0, 5, 0, 25},
+    {21, 0, 0, 0, 5, 0, 25},
+    {15, 0, 0, 0, 5, 0, 25},
+    {26, 0, 18, 0, 5, 0, 25},
+    {9, 0, 0, 0, 5, 0, 26},
+    {5, 0, 0, 0, 5, 0, 26},
+    {17, 0, 18, 0, 5, 0, 27},
+    {7, 0, 0, 0, 5, 0, 27},
+    {21, 0, 0, 0, 5, 0, 27},
+    {29, 0, 17, 0, 5, 0, 28},
+    {7, 0, 0, 0, 5, 0, 28},
+    {22, 0, 18, 1, 5, 0, 28},
+    {18, 0, 18, 1, 5, 0, 28},
+    {7, 0, 0, 0, 5, 0, 29},
+    {14, 0, 0, 0, 5, 0, 29},
+    {7, 0, 0, 0, 5, 0, 41},
+    {12, 0, 13, 0, 5, 0, 41},
+    {12, 9, 13, 0, 5, 0, 41},
+    {7, 0, 0, 0, 5, 0, 42},
+    {12, 0, 13, 0, 5, 0, 42},
+    {12, 9, 13, 0, 5, 0, 42},
+    {7, 0, 0, 0, 5, 0, 43},
+    {12, 0, 13, 0, 5, 0, 43},
+    {7, 0, 0, 0, 5, 0, 44},
+    {12, 0, 13, 0, 5, 0, 44},
+    {7, 0, 0, 0, 5, 0, 30},
+    {12, 0, 13, 0, 5, 0, 30},
+    {10, 0, 0, 0, 5, 0, 30},
+    {12, 9, 13, 0, 5, 0, 30},
+    {21, 0, 0, 0, 5, 0, 30},
+    {6, 0, 0, 0, 5, 0, 30},
+    {23, 0, 10, 0, 5, 0, 30},
+    {12, 230, 13, 0, 5, 0, 30},
+    {13, 0, 0, 0, 5, 0, 30},
+    {15, 0, 18, 0, 5, 0, 30},
+    {21, 0, 18, 0, 5, 0, 31},
+    {17, 0, 18, 0, 5, 0, 31},
+    {12, 0, 13, 0, 5, 0, 31},
+    {1, 0, 14, 0, 5, 0, 31},
+    {13, 0, 0, 0, 5, 0, 31},
+    {7, 0, 0, 0, 5, 0, 31},
+    {6, 0, 0, 0, 5, 0, 31},
+    {12, 228, 13, 0, 5, 0, 31},
+    {7, 0, 0, 0, 5, 0, 45},
+    {12, 0, 13, 0, 5, 0, 45},
+    {10, 0, 0, 0, 5, 0, 45},
+    {12, 222, 13, 0, 5, 0, 45},
+    {12, 230, 13, 0, 5, 0, 45},
+    {12, 220, 13, 0, 5, 0, 45},
+    {26, 0, 18, 0, 5, 0, 45},
+    {21, 0, 18, 0, 5, 0, 45},
+    {13, 0, 0, 0, 5, 0, 45},
+    {7, 0, 0, 0, 5, 0, 46},
+    {7, 0, 0, 0, 5, 0, 55},
+    {13, 0, 0, 0, 5, 0, 55},
+    {15, 0, 0, 0, 5, 0, 55},
+    {26, 0, 18, 0, 5, 0, 55},
+    {26, 0, 18, 0, 5, 0, 30},
+    {7, 0, 0, 0, 5, 0, 53},
+    {12, 230, 13, 0, 5, 0, 53},
+    {12, 220, 13, 0, 5, 0, 53},
+    {10, 0, 0, 0, 5, 0, 53},
+    {12, 0, 13, 0, 5, 0, 53},
+    {21, 0, 0, 0, 5, 0, 53},
+    {7, 0, 0, 0, 5, 0, 77},
+    {10, 0, 0, 0, 5, 0, 77},
+    {12, 0, 13, 0, 5, 0, 77},
+    {12, 9, 13, 0, 5, 0, 77},
+    {12, 230, 13, 0, 5, 0, 77},
+    {12, 220, 13, 0, 5, 0, 77},
+    {13, 0, 0, 0, 5, 0, 77},
+    {21, 0, 0, 0, 5, 0, 77},
+    {6, 0, 0, 0, 5, 0, 77},
+    {11, 0, 13, 0, 5, 0, 40},
+    {12, 0, 13, 0, 5, 0, 61},
+    {10, 0, 0, 0, 5, 0, 61},
+    {7, 0, 0, 0, 5, 0, 61},
+    {12, 7, 13, 0, 5, 0, 61},
+    {10, 9, 0, 0, 5, 0, 61},
+    {13, 0, 0, 0, 5, 0, 61},
+    {21, 0, 0, 0, 5, 0, 61},
+    {26, 0, 0, 0, 5, 0, 61},
+    {12, 230, 13, 0, 5, 0, 61},
+    {12, 220, 13, 0, 5, 0, 61},
+    {12, 0, 13, 0, 5, 0, 66},
+    {10, 0, 0, 0, 5, 0, 66},
+    {7, 0, 0, 0, 5, 0, 66},
+    {10, 9, 0, 0, 5, 0, 66},
+    {12, 9, 13, 0, 5, 0, 66},
+    {13, 0, 0, 0, 5, 0, 66},
+    {7, 0, 0, 0, 5, 0, 92},
+    {12, 7, 13, 0, 5, 0, 92},
+    {10, 0, 0, 0, 5, 0, 92},
+    {12, 0, 13, 0, 5, 0, 92},
+    {10, 9, 0, 0, 5, 0, 92},
+    {21, 0, 0, 0, 5, 0, 92},
+    {7, 0, 0, 0, 5, 0, 67},
+    {10, 0, 0, 0, 5, 0, 67},
+    {12, 0, 13, 0, 5, 0, 67},
+    {12, 7, 13, 0, 5, 0, 67},
+    {21, 0, 0, 0, 5, 0, 67},
+    {13, 0, 0, 0, 5, 0, 67},
+    {13, 0, 0, 0, 5, 0, 68},
+    {7, 0, 0, 0, 5, 0, 68},
+    {6, 0, 0, 0, 5, 0, 68},
+    {21, 0, 0, 0, 5, 0, 68},
+    {21, 0, 0, 0, 5, 0, 66},
+    {12, 1, 13, 0, 5, 0, 40},
+    {10, 0, 0, 0, 5, 0, 0},
+    {7, 0, 0, 0, 5, 0, 0},
+    {6, 0, 0, 0, 5, 0, 3},
+    {12, 234, 13, 0, 5, 0, 40},
+    {12, 214, 13, 0, 5, 0, 40},
+    {12, 202, 13, 0, 5, 0, 40},
+    {12, 233, 13, 0, 5, 0, 40},
+    {8, 0, 0, 0, 5, 0, 2},
+    {29, 0, 17, 0, 5, 0, 0},
+    {1, 0, 14, 0, 5, 0, 0},
+    {1, 0, 14, 0, 5, 0, 40},
+    {1, 0, 0, 0, 5, 0, 0},
+    {1, 0, 3, 0, 5, 0, 0},
+    {17, 0, 18, 0, 4, 0, 0},
+    {17, 0, 18, 0, 5, 0, 0},
+    {20, 0, 18, 0, 4, 0, 0},
+    {19, 0, 18, 0, 4, 0, 0},
+    {22, 0, 18, 0, 5, 0, 0},
+    {20, 0, 18, 0, 5, 0, 0},
+    {27, 0, 17, 0, 5, 0, 0},
+    {28, 0, 15, 0, 5, 0, 0},
+    {1, 0, 1, 0, 5, 0, 0},
+    {1, 0, 5, 0, 5, 0, 0},
+    {1, 0, 7, 0, 5, 0, 0},
+    {1, 0, 2, 0, 5, 0, 0},
+    {1, 0, 6, 0, 5, 0, 0},
+    {21, 0, 10, 0, 4, 0, 0},
+    {21, 0, 10, 0, 5, 0, 0},
+    {16, 0, 18, 0, 5, 0, 0},
+    {25, 0, 12, 0, 5, 0, 0},
+    {22, 0, 18, 1, 5, 0, 0},
+    {18, 0, 18, 1, 5, 0, 0},
+    {25, 0, 18, 0, 5, 0, 0},
+    {1, 0, 19, 0, 5, 0, 0},
+    {1, 0, 20, 0, 5, 0, 0},
+    {1, 0, 21, 0, 5, 0, 0},
+    {1, 0, 22, 0, 5, 0, 0},
+    {15, 0, 8, 0, 5, 0, 0},
+    {25, 0, 9, 0, 5, 0, 0},
+    {6, 0, 0, 0, 4, 0, 1},
+    {23, 0, 10, 0, 1, 0, 0},
+    {9, 0, 0, 0, 5, 0, 0},
+    {5, 0, 0, 0, 4, 0, 0},
+    {26, 0, 10, 0, 5, 0, 0},
+    {25, 0, 18, 1, 5, 0, 0},
+    {15, 0, 18, 0, 5, 0, 0},
+    {14, 0, 0, 0, 4, 0, 1},
+    {14, 0, 0, 0, 5, 0, 1},
+    {25, 0, 18, 1, 4, 0, 0},
+    {25, 0, 10, 0, 5, 0, 0},
+    {22, 0, 18, 1, 2, 0, 0},
+    {18, 0, 18, 1, 2, 0, 0},
+    {26, 0, 0, 0, 4, 0, 0},
+    {26, 0, 0, 0, 5, 0, 52},
+    {9, 0, 0, 0, 5, 0, 56},
+    {5, 0, 0, 0, 5, 0, 56},
+    {26, 0, 18, 0, 5, 0, 54},
+    {12, 230, 13, 0, 5, 0, 54},
+    {21, 0, 18, 0, 5, 0, 54},
+    {15, 0, 18, 0, 5, 0, 54},
+    {5, 0, 0, 0, 5, 0, 23},
+    {7, 0, 0, 0, 5, 0, 57},
+    {6, 0, 0, 0, 5, 0, 57},
+    {21, 0, 0, 0, 5, 0, 57},
+    {12, 9, 13, 0, 5, 0, 57},
+    {26, 0, 18, 0, 2, 0, 35},
+    {26, 0, 18, 0, 2, 0, 0},
+    {29, 0, 17, 0, 0, 0, 0},
+    {21, 0, 18, 0, 2, 0, 0},
+    {6, 0, 0, 0, 2, 0, 35},
+    {7, 0, 0, 0, 2, 0, 0},
+    {14, 0, 0, 0, 2, 0, 35},
+    {17, 0, 18, 0, 2, 0, 0},
+    {22, 0, 18, 0, 2, 0, 0},
+    {18, 0, 18, 0, 2, 0, 0},
+    {12, 218, 13, 0, 2, 0, 40},
+    {12, 228, 13, 0, 2, 0, 40},
+    {12, 232, 13, 0, 2, 0, 40},
+    {12, 222, 13, 0, 2, 0, 40},
+    {10, 224, 0, 0, 2, 0, 24},
+    {6, 0, 0, 0, 2, 0, 0},
+    {7, 0, 0, 0, 2, 0, 32},
+    {12, 8, 13, 0, 2, 0, 40},
+    {24, 0, 18, 0, 2, 0, 0},
+    {6, 0, 0, 0, 2, 0, 32},
+    {7, 0, 0, 0, 2, 0, 33},
+    {6, 0, 0, 0, 2, 0, 33},
+    {7, 0, 0, 0, 2, 0, 34},
+    {26, 0, 0, 0, 2, 0, 0},
+    {15, 0, 0, 0, 2, 0, 0},
+    {26, 0, 0, 0, 2, 0, 24},
+    {26, 0, 18, 0, 2, 0, 24},
+    {15, 0, 0, 0, 4, 0, 0},
+    {15, 0, 18, 0, 2, 0, 0},
+    {26, 0, 0, 0, 2, 0, 33},
+    {7, 0, 0, 0, 2, 0, 35},
+    {2, 0, 18, 0, 2, 0, 102},
+    {7, 0, 0, 0, 2, 0, 36},
+    {6, 0, 0, 0, 2, 0, 36},
+    {26, 0, 18, 0, 2, 0, 36},
+    {7, 0, 0, 0, 5, 0, 82},
+    {6, 0, 0, 0, 5, 0, 82},
+    {21, 0, 0, 0, 5, 0, 82},
+    {7, 0, 0, 0, 5, 0, 69},
+    {6, 0, 0, 0, 5, 0, 69},
+    {21, 0, 18, 0, 5, 0, 69},
+    {13, 0, 0, 0, 5, 0, 69},
+    {7, 0, 0, 0, 5, 0, 3},
+    {21, 0, 18, 0, 5, 0, 3},
+    {6, 0, 18, 0, 5, 0, 3},
+    {7, 0, 0, 0, 5, 0, 83},
+    {14, 0, 0, 0, 5, 0, 83},
+    {12, 230, 13, 0, 5, 0, 83},
+    {21, 0, 0, 0, 5, 0, 83},
+    {24, 0, 0, 0, 5, 0, 0},
+    {7, 0, 0, 0, 5, 0, 58},
+    {12, 0, 13, 0, 5, 0, 58},
+    {12, 9, 13, 0, 5, 0, 58},
+    {10, 0, 0, 0, 5, 0, 58},
+    {26, 0, 18, 0, 5, 0, 58},
+    {15, 0, 0, 0, 5, 0, 0},
+    {7, 0, 0, 0, 5, 0, 64},
+    {21, 0, 18, 0, 5, 0, 64},
+    {10, 0, 0, 0, 5, 0, 70},
+    {7, 0, 0, 0, 5, 0, 70},
+    {12, 9, 13, 0, 5, 0, 70},
+    {21, 0, 0, 0, 5, 0, 70},
+    {13, 0, 0, 0, 5, 0, 70},
+    {13, 0, 0, 0, 5, 0, 71},
+    {7, 0, 0, 0, 5, 0, 71},
+    {12, 0, 13, 0, 5, 0, 71},
+    {12, 220, 13, 0, 5, 0, 71},
+    {21, 0, 0, 0, 5, 0, 71},
+    {7, 0, 0, 0, 5, 0, 72},
+    {12, 0, 13, 0, 5, 0, 72},
+    {10, 0, 0, 0, 5, 0, 72},
+    {10, 9, 0, 0, 5, 0, 72},
+    {21, 0, 0, 0, 5, 0, 72},
+    {12, 0, 13, 0, 5, 0, 84},
+    {10, 0, 0, 0, 5, 0, 84},
+    {7, 0, 0, 0, 5, 0, 84},
+    {12, 7, 13, 0, 5, 0, 84},
+    {10, 9, 0, 0, 5, 0, 84},
+    {21, 0, 0, 0, 5, 0, 84},
+    {13, 0, 0, 0, 5, 0, 84},
+    {6, 0, 0, 0, 5, 0, 22},
+    {7, 0, 0, 0, 5, 0, 76},
+    {12, 0, 13, 0, 5, 0, 76},
+    {10, 0, 0, 0, 5, 0, 76},
+    {13, 0, 0, 0, 5, 0, 76},
+    {21, 0, 0, 0, 5, 0, 76},
+    {7, 0, 0, 0, 5, 0, 78},
+    {12, 230, 13, 0, 5, 0, 78},
+    {12, 220, 13, 0, 5, 0, 78},
+    {6, 0, 0, 0, 5, 0, 78},
+    {21, 0, 0, 0, 5, 0, 78},
+    {7, 0, 0, 0, 5, 0, 85},
+    {10, 0, 0, 0, 5, 0, 85},
+    {12, 0, 13, 0, 5, 0, 85},
+    {21, 0, 0, 0, 5, 0, 85},
+    {6, 0, 0, 0, 5, 0, 85},
+    {12, 9, 13, 0, 5, 0, 85},
+    {13, 0, 0, 0, 5, 0, 85},
+    {4, 0, 0, 0, 5, 0, 102},
+    {3, 0, 0, 0, 4, 0, 102},
+    {12, 26, 13, 0, 5, 0, 5},
+    {25, 0, 9, 0, 5, 0, 5},
+    {24, 0, 4, 0, 5, 0, 6},
+    {18, 0, 18, 0, 5, 0, 0},
+    {16, 0, 18, 0, 2, 0, 0},
+    {21, 0, 12, 0, 2, 0, 0},
+    {21, 0, 10, 0, 2, 0, 0},
+    {25, 0, 9, 0, 2, 0, 0},
+    {17, 0, 9, 0, 2, 0, 0},
+    {25, 0, 18, 1, 2, 0, 0},
+    {25, 0, 18, 0, 2, 0, 0},
+    {23, 0, 10, 0, 2, 0, 0},
+    {21, 0, 18, 0, 0, 0, 0},
+    {21, 0, 10, 0, 0, 0, 0},
+    {23, 0, 10, 0, 0, 0, 0},
+    {22, 0, 18, 1, 0, 0, 0},
+    {18, 0, 18, 1, 0, 0, 0},
+    {25, 0, 9, 0, 0, 0, 0},
+    {21, 0, 12, 0, 0, 0, 0},
+    {17, 0, 9, 0, 0, 0, 0},
+    {13, 0, 8, 0, 0, 0, 0},
+    {25, 0, 18, 1, 0, 0, 0},
+    {25, 0, 18, 0, 0, 0, 0},
+    {9, 0, 0, 0, 0, 0, 1},
+    {24, 0, 18, 0, 0, 0, 0},
+    {16, 0, 18, 0, 0, 0, 0},
+    {5, 0, 0, 0, 0, 0, 1},
+    {21, 0, 18, 0, 1, 0, 0},
+    {22, 0, 18, 1, 1, 0, 0},
+    {18, 0, 18, 1, 1, 0, 0},
+    {7, 0, 0, 0, 1, 0, 33},
+    {6, 0, 0, 0, 1, 0, 0},
+    {7, 0, 0, 0, 1, 0, 24},
+    {26, 0, 18, 0, 0, 0, 0},
+    {26, 0, 18, 0, 1, 0, 0},
+    {25, 0, 18, 0, 1, 0, 0},
+    {1, 0, 18, 0, 5, 0, 0},
+    {7, 0, 0, 0, 5, 0, 47},
+    {14, 0, 18, 0, 5, 0, 2},
+    {15, 0, 18, 0, 5, 0, 2},
+    {26, 0, 18, 0, 5, 0, 2},
+    {7, 0, 0, 0, 5, 0, 73},
+    {7, 0, 0, 0, 5, 0, 74},
+    {7, 0, 0, 0, 5, 0, 37},
+    {15, 0, 0, 0, 5, 0, 37},
+    {7, 0, 0, 0, 5, 0, 38},
+    {14, 0, 0, 0, 5, 0, 38},
+    {7, 0, 0, 0, 5, 0, 118},
+    {12, 230, 13, 0, 5, 0, 118},
+    {7, 0, 0, 0, 5, 0, 48},
+    {21, 0, 0, 0, 5, 0, 48},
+    {7, 0, 0, 0, 5, 0, 59},
+    {21, 0, 0, 0, 5, 0, 59},
+    {14, 0, 0, 0, 5, 0, 59},
+    {9, 0, 0, 0, 5, 0, 39},
+    {5, 0, 0, 0, 5, 0, 39},
+    {7, 0, 0, 0, 5, 0, 49},
+    {7, 0, 0, 0, 5, 0, 50},
+    {13, 0, 0, 0, 5, 0, 50},
+    {7, 0, 0, 0, 5, 0, 106},
+    {7, 0, 0, 0, 5, 0, 104},
+    {21, 0, 0, 0, 5, 0, 104},
+    {7, 0, 0, 0, 5, 0, 110},
+    {7, 0, 3, 0, 5, 0, 51},
+    {7, 0, 3, 0, 5, 0, 86},
+    {21, 0, 3, 0, 5, 0, 86},
+    {15, 0, 3, 0, 5, 0, 86},
+    {7, 0, 3, 0, 5, 0, 120},
+    {26, 0, 3, 0, 5, 0, 120},
+    {15, 0, 3, 0, 5, 0, 120},
+    {7, 0, 3, 0, 5, 0, 116},
+    {15, 0, 3, 0, 5, 0, 116},
+    {7, 0, 3, 0, 5, 0, 128},
+    {15, 0, 3, 0, 5, 0, 128},
+    {7, 0, 3, 0, 5, 0, 63},
+    {15, 0, 3, 0, 5, 0, 63},
+    {21, 0, 18, 0, 5, 0, 63},
+    {7, 0, 3, 0, 5, 0, 75},
+    {21, 0, 3, 0, 5, 0, 75},
+    {7, 0, 3, 0, 5, 0, 97},
+    {7, 0, 3, 0, 5, 0, 96},
+    {15, 0, 3, 0, 5, 0, 96},
+    {7, 0, 3, 0, 5, 0, 60},
+    {12, 0, 13, 0, 5, 0, 60},
+    {12, 220, 13, 0, 5, 0, 60},
+    {12, 230, 13, 0, 5, 0, 60},
+    {12, 1, 13, 0, 5, 0, 60},
+    {12, 9, 13, 0, 5, 0, 60},
+    {15, 0, 3, 0, 5, 0, 60},
+    {21, 0, 3, 0, 5, 0, 60},
+    {7, 0, 3, 0, 5, 0, 87},
+    {15, 0, 3, 0, 5, 0, 87},
+    {21, 0, 3, 0, 5, 0, 87},
+    {7, 0, 3, 0, 5, 0, 117},
+    {15, 0, 3, 0, 5, 0, 117},
+    {7, 0, 3, 0, 5, 0, 112},
+    {26, 0, 3, 0, 5, 0, 112},
+    {12, 230, 13, 0, 5, 0, 112},
+    {12, 220, 13, 0, 5, 0, 112},
+    {15, 0, 3, 0, 5, 0, 112},
+    {21, 0, 3, 0, 5, 0, 112},
+    {7, 0, 3, 0, 5, 0, 79},
+    {21, 0, 18, 0, 5, 0, 79},
+    {7, 0, 3, 0, 5, 0, 88},
+    {15, 0, 3, 0, 5, 0, 88},
+    {7, 0, 3, 0, 5, 0, 89},
+    {15, 0, 3, 0, 5, 0, 89},
+    {7, 0, 3, 0, 5, 0, 122},
+    {21, 0, 3, 0, 5, 0, 122},
+    {15, 0, 3, 0, 5, 0, 122},
+    {7, 0, 3, 0, 5, 0, 90},
+    {9, 0, 3, 0, 5, 0, 130},
+    {5, 0, 3, 0, 5, 0, 130},
+    {15, 0, 3, 0, 5, 0, 130},
+    {15, 0, 11, 0, 5, 0, 6},
+    {10, 0, 0, 0, 5, 0, 93},
+    {12, 0, 13, 0, 5, 0, 93},
+    {7, 0, 0, 0, 5, 0, 93},
+    {12, 9, 13, 0, 5, 0, 93},
+    {21, 0, 0, 0, 5, 0, 93},
+    {15, 0, 18, 0, 5, 0, 93},
+    {13, 0, 0, 0, 5, 0, 93},
+    {12, 0, 13, 0, 5, 0, 91},
+    {10, 0, 0, 0, 5, 0, 91},
+    {7, 0, 0, 0, 5, 0, 91},
+    {12, 9, 13, 0, 5, 0, 91},
+    {12, 7, 13, 0, 5, 0, 91},
+    {21, 0, 0, 0, 5, 0, 91},
+    {1, 0, 0, 0, 5, 0, 91},
+    {7, 0, 0, 0, 5, 0, 100},
+    {13, 0, 0, 0, 5, 0, 100},
+    {12, 230, 13, 0, 5, 0, 95},
+    {7, 0, 0, 0, 5, 0, 95},
+    {12, 0, 13, 0, 5, 0, 95},
+    {10, 0, 0, 0, 5, 0, 95},
+    {12, 9, 13, 0, 5, 0, 95},
+    {13, 0, 0, 0, 5, 0, 95},
+    {21, 0, 0, 0, 5, 0, 95},
+    {7, 0, 0, 0, 5, 0, 111},
+    {12, 7, 13, 0, 5, 0, 111},
+    {21, 0, 0, 0, 5, 0, 111},
+    {12, 0, 13, 0, 5, 0, 99},
+    {10, 0, 0, 0, 5, 0, 99},
+    {7, 0, 0, 0, 5, 0, 99},
+    {10, 9, 0, 0, 5, 0, 99},
+    {21, 0, 0, 0, 5, 0, 99},
+    {12, 7, 13, 0, 5, 0, 99},
+    {13, 0, 0, 0, 5, 0, 99},
+    {15, 0, 0, 0, 5, 0, 18},
+    {7, 0, 0, 0, 5, 0, 108},
+    {10, 0, 0, 0, 5, 0, 108},
+    {12, 0, 13, 0, 5, 0, 108},
+    {10, 9, 0, 0, 5, 0, 108},
+    {12, 7, 13, 0, 5, 0, 108},
+    {21, 0, 0, 0, 5, 0, 108},
+    {7, 0, 0, 0, 5, 0, 129},
+    {21, 0, 0, 0, 5, 0, 129},
+    {7, 0, 0, 0, 5, 0, 109},
+    {12, 0, 13, 0, 5, 0, 109},
+    {10, 0, 0, 0, 5, 0, 109},
+    {12, 7, 13, 0, 5, 0, 109},
+    {12, 9, 13, 0, 5, 0, 109},
+    {13, 0, 0, 0, 5, 0, 109},
+    {12, 0, 13, 0, 5, 0, 107},
+    {10, 0, 0, 0, 5, 0, 107},
+    {7, 0, 0, 0, 5, 0, 107},
+    {12, 7, 13, 0, 5, 0, 107},
+    {10, 9, 0, 0, 5, 0, 107},
+    {12, 230, 13, 0, 5, 0, 107},
+    {7, 0, 0, 0, 5, 0, 124},
+    {10, 0, 0, 0, 5, 0, 124},
+    {12, 0, 13, 0, 5, 0, 124},
+    {12, 9, 13, 0, 5, 0, 124},
+    {12, 7, 13, 0, 5, 0, 124},
+    {21, 0, 0, 0, 5, 0, 124},
+    {13, 0, 0, 0, 5, 0, 124},
+    {7, 0, 0, 0, 5, 0, 123},
+    {10, 0, 0, 0, 5, 0, 123},
+    {12, 0, 13, 0, 5, 0, 123},
+    {12, 9, 13, 0, 5, 0, 123},
+    {12, 7, 13, 0, 5, 0, 123},
+    {21, 0, 0, 0, 5, 0, 123},
+    {7, 0, 0, 0, 5, 0, 114},
+    {10, 0, 0, 0, 5, 0, 114},
+    {12, 0, 13, 0, 5, 0, 114},
+    {12, 9, 13, 0, 5, 0, 114},
+    {21, 0, 0, 0, 5, 0, 114},
+    {13, 0, 0, 0, 5, 0, 114},
+    {7, 0, 0, 0, 5, 0, 101},
+    {12, 0, 13, 0, 5, 0, 101},
+    {10, 0, 0, 0, 5, 0, 101},
+    {10, 9, 0, 0, 5, 0, 101},
+    {12, 7, 13, 0, 5, 0, 101},
+    {13, 0, 0, 0, 5, 0, 101},
+    {7, 0, 0, 0, 5, 0, 126},
+    {12, 0, 13, 0, 5, 0, 126},
+    {10, 0, 0, 0, 5, 0, 126},
+    {12, 9, 13, 0, 5, 0, 126},
+    {13, 0, 0, 0, 5, 0, 126},
+    {15, 0, 0, 0, 5, 0, 126},
+    {21, 0, 0, 0, 5, 0, 126},
+    {26, 0, 0, 0, 5, 0, 126},
+    {9, 0, 0, 0, 5, 0, 125},
+    {5, 0, 0, 0, 5, 0, 125},
+    {13, 0, 0, 0, 5, 0, 125},
+    {15, 0, 0, 0, 5, 0, 125},
+    {7, 0, 0, 0, 5, 0, 125},
+    {7, 0, 0, 0, 5, 0, 121},
+    {7, 0, 0, 0, 5, 0, 62},
+    {14, 0, 0, 0, 5, 0, 62},
+    {21, 0, 0, 0, 5, 0, 62},
+    {7, 0, 0, 0, 5, 0, 80},
+    {7, 0, 0, 0, 5, 0, 127},
+    {7, 0, 0, 0, 5, 0, 115},
+    {13, 0, 0, 0, 5, 0, 115},
+    {21, 0, 0, 0, 5, 0, 115},
+    {7, 0, 0, 0, 5, 0, 103},
+    {12, 1, 13, 0, 5, 0, 103},
+    {21, 0, 0, 0, 5, 0, 103},
+    {7, 0, 0, 0, 5, 0, 119},
+    {12, 230, 13, 0, 5, 0, 119},
+    {21, 0, 0, 0, 5, 0, 119},
+    {26, 0, 0, 0, 5, 0, 119},
+    {6, 0, 0, 0, 5, 0, 119},
+    {13, 0, 0, 0, 5, 0, 119},
+    {15, 0, 0, 0, 5, 0, 119},
+    {7, 0, 0, 0, 5, 0, 98},
+    {10, 0, 0, 0, 5, 0, 98},
+    {12, 0, 13, 0, 5, 0, 98},
+    {6, 0, 0, 0, 5, 0, 98},
+    {7, 0, 0, 0, 5, 0, 105},
+    {26, 0, 0, 0, 5, 0, 105},
+    {12, 0, 13, 0, 5, 0, 105},
+    {12, 1, 13, 0, 5, 0, 105},
+    {21, 0, 0, 0, 5, 0, 105},
+    {10, 216, 0, 0, 5, 0, 0},
+    {10, 226, 0, 0, 5, 0, 0},
+    {12, 230, 13, 0, 5, 0, 2},
+    {25, 0, 0, 0, 5, 0, 0},
+    {13, 0, 8, 0, 5, 0, 0},
+    {26, 0, 0, 0, 5, 0, 131},
+    {12, 0, 13, 0, 5, 0, 131},
+    {21, 0, 0, 0, 5, 0, 131},
+    {7, 0, 3, 0, 5, 0, 113},
+    {15, 0, 3, 0, 5, 0, 113},
+    {12, 220, 13, 0, 5, 0, 113},
+    {26, 0, 0, 0, 2, 0, 32},
+};
+
+#define BIDI_MIRROR_LEN 364
+static const MirrorPair mirror_pairs[] = {
+    {40, 41},
+    {41, 40},
+    {60, 62},
+    {62, 60},
+    {91, 93},
+    {93, 91},
+    {123, 125},
+    {125, 123},
+    {171, 187},
+    {187, 171},
+    {3898, 3899},
+    {3899, 3898},
+    {3900, 3901},
+    {3901, 3900},
+    {5787, 5788},
+    {5788, 5787},
+    {8249, 8250},
+    {8250, 8249},
+    {8261, 8262},
+    {8262, 8261},
+    {8317, 8318},
+    {8318, 8317},
+    {8333, 8334},
+    {8334, 8333},
+    {8712, 8715},
+    {8713, 8716},
+    {8714, 8717},
+    {8715, 8712},
+    {8716, 8713},
+    {8717, 8714},
+    {8725, 10741},
+    {8764, 8765},
+    {8765, 8764},
+    {8771, 8909},
+    {8786, 8787},
+    {8787, 8786},
+    {8788, 8789},
+    {8789, 8788},
+    {8804, 8805},
+    {8805, 8804},
+    {8806, 8807},
+    {8807, 8806},
+    {8808, 8809},
+    {8809, 8808},
+    {8810, 8811},
+    {8811, 8810},
+    {8814, 8815},
+    {8815, 8814},
+    {8816, 8817},
+    {8817, 8816},
+    {8818, 8819},
+    {8819, 8818},
+    {8820, 8821},
+    {8821, 8820},
+    {8822, 8823},
+    {8823, 8822},
+    {8824, 8825},
+    {8825, 8824},
+    {8826, 8827},
+    {8827, 8826},
+    {8828, 8829},
+    {8829, 8828},
+    {8830, 8831},
+    {8831, 8830},
+    {8832, 8833},
+    {8833, 8832},
+    {8834, 8835},
+    {8835, 8834},
+    {8836, 8837},
+    {8837, 8836},
+    {8838, 8839},
+    {8839, 8838},
+    {8840, 8841},
+    {8841, 8840},
+    {8842, 8843},
+    {8843, 8842},
+    {8847, 8848},
+    {8848, 8847},
+    {8849, 8850},
+    {8850, 8849},
+    {8856, 10680},
+    {8866, 8867},
+    {8867, 8866},
+    {8870, 10974},
+    {8872, 10980},
+    {8873, 10979},
+    {8875, 10981},
+    {8880, 8881},
+    {8881, 8880},
+    {8882, 8883},
+    {8883, 8882},
+    {8884, 8885},
+    {8885, 8884},
+    {8886, 8887},
+    {8887, 8886},
+    {8905, 8906},
+    {8906, 8905},
+    {8907, 8908},
+    {8908, 8907},
+    {8909, 8771},
+    {8912, 8913},
+    {8913, 8912},
+    {8918, 8919},
+    {8919, 8918},
+    {8920, 8921},
+    {8921, 8920},
+    {8922, 8923},
+    {8923, 8922},
+    {8924, 8925},
+    {8925, 8924},
+    {8926, 8927},
+    {8927, 8926},
+    {8928, 8929},
+    {8929, 8928},
+    {8930, 8931},
+    {8931, 8930},
+    {8932, 8933},
+    {8933, 8932},
+    {8934, 8935},
+    {8935, 8934},
+    {8936, 8937},
+    {8937, 8936},
+    {8938, 8939},
+    {8939, 8938},
+    {8940, 8941},
+    {8941, 8940},
+    {8944, 8945},
+    {8945, 8944},
+    {8946, 8954},
+    {8947, 8955},
+    {8948, 8956},
+    {8950, 8957},
+    {8951, 8958},
+    {8954, 8946},
+    {8955, 8947},
+    {8956, 8948},
+    {8957, 8950},
+    {8958, 8951},
+    {8968, 8969},
+    {8969, 8968},
+    {8970, 8971},
+    {8971, 8970},
+    {9001, 9002},
+    {9002, 9001},
+    {10088, 10089},
+    {10089, 10088},
+    {10090, 10091},
+    {10091, 10090},
+    {10092, 10093},
+    {10093, 10092},
+    {10094, 10095},
+    {10095, 10094},
+    {10096, 10097},
+    {10097, 10096},
+    {10098, 10099},
+    {10099, 10098},
+    {10100, 10101},
+    {10101, 10100},
+    {10179, 10180},
+    {10180, 10179},
+    {10181, 10182},
+    {10182, 10181},
+    {10184, 10185},
+    {10185, 10184},
+    {10187, 10189},
+    {10189, 10187},
+    {10197, 10198},
+    {10198, 10197},
+    {10205, 10206},
+    {10206, 10205},
+    {10210, 10211},
+    {10211, 10210},
+    {10212, 10213},
+    {10213, 10212},
+    {10214, 10215},
+    {10215, 10214},
+    {10216, 10217},
+    {10217, 10216},
+    {10218, 10219},
+    {10219, 10218},
+    {10220, 10221},
+    {10221, 10220},
+    {10222, 10223},
+    {10223, 10222},
+    {10627, 10628},
+    {10628, 10627},
+    {10629, 10630},
+    {10630, 10629},
+    {10631, 10632},
+    {10632, 10631},
+    {10633, 10634},
+    {10634, 10633},
+    {10635, 10636},
+    {10636, 10635},
+    {10637, 10640},
+    {10638, 10639},
+    {10639, 10638},
+    {10640, 10637},
+    {10641, 10642},
+    {10642, 10641},
+    {10643, 10644},
+    {10644, 10643},
+    {10645, 10646},
+    {10646, 10645},
+    {10647, 10648},
+    {10648, 10647},
+    {10680, 8856},
+    {10688, 10689},
+    {10689, 10688},
+    {10692, 10693},
+    {10693, 10692},
+    {10703, 10704},
+    {10704, 10703},
+    {10705, 10706},
+    {10706, 10705},
+    {10708, 10709},
+    {10709, 10708},
+    {10712, 10713},
+    {10713, 10712},
+    {10714, 10715},
+    {10715, 10714},
+    {10741, 8725},
+    {10744, 10745},
+    {10745, 10744},
+    {10748, 10749},
+    {10749, 10748},
+    {10795, 10796},
+    {10796, 10795},
+    {10797, 10798},
+    {10798, 10797},
+    {10804, 10805},
+    {10805, 10804},
+    {10812, 10813},
+    {10813, 10812},
+    {10852, 10853},
+    {10853, 10852},
+    {10873, 10874},
+    {10874, 10873},
+    {10877, 10878},
+    {10878, 10877},
+    {10879, 10880},
+    {10880, 10879},
+    {10881, 10882},
+    {10882, 10881},
+    {10883, 10884},
+    {10884, 10883},
+    {10891, 10892},
+    {10892, 10891},
+    {10897, 10898},
+    {10898, 10897},
+    {10899, 10900},
+    {10900, 10899},
+    {10901, 10902},
+    {10902, 10901},
+    {10903, 10904},
+    {10904, 10903},
+    {10905, 10906},
+    {10906, 10905},
+    {10907, 10908},
+    {10908, 10907},
+    {10913, 10914},
+    {10914, 10913},
+    {10918, 10919},
+    {10919, 10918},
+    {10920, 10921},
+    {10921, 10920},
+    {10922, 10923},
+    {10923, 10922},
+    {10924, 10925},
+    {10925, 10924},
+    {10927, 10928},
+    {10928, 10927},
+    {10931, 10932},
+    {10932, 10931},
+    {10939, 10940},
+    {10940, 10939},
+    {10941, 10942},
+    {10942, 10941},
+    {10943, 10944},
+    {10944, 10943},
+    {10945, 10946},
+    {10946, 10945},
+    {10947, 10948},
+    {10948, 10947},
+    {10949, 10950},
+    {10950, 10949},
+    {10957, 10958},
+    {10958, 10957},
+    {10959, 10960},
+    {10960, 10959},
+    {10961, 10962},
+    {10962, 10961},
+    {10963, 10964},
+    {10964, 10963},
+    {10965, 10966},
+    {10966, 10965},
+    {10974, 8870},
+    {10979, 8873},
+    {10980, 8872},
+    {10981, 8875},
+    {10988, 10989},
+    {10989, 10988},
+    {10999, 11000},
+    {11000, 10999},
+    {11001, 11002},
+    {11002, 11001},
+    {11778, 11779},
+    {11779, 11778},
+    {11780, 11781},
+    {11781, 11780},
+    {11785, 11786},
+    {11786, 11785},
+    {11788, 11789},
+    {11789, 11788},
+    {11804, 11805},
+    {11805, 11804},
+    {11808, 11809},
+    {11809, 11808},
+    {11810, 11811},
+    {11811, 11810},
+    {11812, 11813},
+    {11813, 11812},
+    {11814, 11815},
+    {11815, 11814},
+    {11816, 11817},
+    {11817, 11816},
+    {12296, 12297},
+    {12297, 12296},
+    {12298, 12299},
+    {12299, 12298},
+    {12300, 12301},
+    {12301, 12300},
+    {12302, 12303},
+    {12303, 12302},
+    {12304, 12305},
+    {12305, 12304},
+    {12308, 12309},
+    {12309, 12308},
+    {12310, 12311},
+    {12311, 12310},
+    {12312, 12313},
+    {12313, 12312},
+    {12314, 12315},
+    {12315, 12314},
+    {65113, 65114},
+    {65114, 65113},
+    {65115, 65116},
+    {65116, 65115},
+    {65117, 65118},
+    {65118, 65117},
+    {65124, 65125},
+    {65125, 65124},
+    {65288, 65289},
+    {65289, 65288},
+    {65308, 65310},
+    {65310, 65308},
+    {65339, 65341},
+    {65341, 65339},
+    {65371, 65373},
+    {65373, 65371},
+    {65375, 65376},
+    {65376, 65375},
+    {65378, 65379},
+    {65379, 65378},
+};
+
+/* Reindexing of NFC first characters. */
+#define TOTAL_FIRST 376
+#define TOTAL_LAST 62
+static const Reindex nfc_first[] = {
+  { 60, 2, 0},
+  { 65, 15, 3},
+  { 82, 8, 19},
+  { 97, 15, 28},
+  { 114, 8, 44},
+  { 168, 0, 53},
+  { 194, 0, 54},
+  { 196, 3, 55},
+  { 202, 0, 59},
+  { 207, 0, 60},
+  { 212, 2, 61},
+  { 216, 0, 64},
+  { 220, 0, 65},
+  { 226, 0, 66},
+  { 228, 3, 67},
+  { 234, 0, 71},
+  { 239, 0, 72},
+  { 244, 2, 73},
+  { 248, 0, 76},
+  { 252, 0, 77},
+  { 258, 1, 78},
+  { 274, 1, 80},
+  { 332, 1, 82},
+  { 346, 1, 84},
+  { 352, 1, 86},
+  { 360, 3, 88},
+  { 383, 0, 92},
+  { 416, 1, 93},
+  { 431, 1, 95},
+  { 439, 0, 97},
+  { 490, 1, 98},
+  { 550, 3, 100},
+  { 558, 1, 104},
+  { 658, 0, 106},
+  { 913, 0, 107},
+  { 917, 0, 108},
+  { 919, 0, 109},
+  { 921, 0, 110},
+  { 927, 0, 111},
+  { 929, 0, 112},
+  { 933, 0, 113},
+  { 937, 0, 114},
+  { 940, 0, 115},
+  { 942, 0, 116},
+  { 945, 0, 117},
+  { 949, 0, 118},
+  { 951, 0, 119},
+  { 953, 0, 120},
+  { 959, 0, 121},
+  { 961, 0, 122},
+  { 965, 0, 123},
+  { 969, 2, 124},
+  { 974, 0, 127},
+  { 978, 0, 128},
+  { 1030, 0, 129},
+  { 1040, 0, 130},
+  { 1043, 0, 131},
+  { 1045, 3, 132},
+  { 1050, 0, 136},
+  { 1054, 0, 137},
+  { 1059, 0, 138},
+  { 1063, 0, 139},
+  { 1067, 0, 140},
+  { 1069, 0, 141},
+  { 1072, 0, 142},
+  { 1075, 0, 143},
+  { 1077, 3, 144},
+  { 1082, 0, 148},
+  { 1086, 0, 149},
+  { 1091, 0, 150},
+  { 1095, 0, 151},
+  { 1099, 0, 152},
+  { 1101, 0, 153},
+  { 1110, 0, 154},
+  { 1140, 1, 155},
+  { 1240, 1, 157},
+  { 1256, 1, 159},
+  { 1575, 0, 161},
+  { 1608, 0, 162},
+  { 1610, 0, 163},
+  { 1729, 0, 164},
+  { 1746, 0, 165},
+  { 1749, 0, 166},
+  { 2344, 0, 167},
+  { 2352, 0, 168},
+  { 2355, 0, 169},
+  { 2503, 0, 170},
+  { 2887, 0, 171},
+  { 2962, 0, 172},
+  { 3014, 1, 173},
+  { 3142, 0, 175},
+  { 3263, 0, 176},
+  { 3270, 0, 177},
+  { 3274, 0, 178},
+  { 3398, 1, 179},
+  { 3545, 0, 181},
+  { 3548, 0, 182},
+  { 4133, 0, 183},
+  { 6917, 0, 184},
+  { 6919, 0, 185},
+  { 6921, 0, 186},
+  { 6923, 0, 187},
+  { 6925, 0, 188},
+  { 6929, 0, 189},
+  { 6970, 0, 190},
+  { 6972, 0, 191},
+  { 6974, 1, 192},
+  { 6978, 0, 194},
+  { 7734, 1, 195},
+  { 7770, 1, 197},
+  { 7778, 1, 199},
+  { 7840, 1, 201},
+  { 7864, 1, 203},
+  { 7884, 1, 205},
+  { 7936, 17, 207},
+  { 7960, 1, 225},
+  { 7968, 17, 227},
+  { 7992, 1, 245},
+  { 8000, 1, 247},
+  { 8008, 1, 249},
+  { 8016, 1, 251},
+  { 8025, 0, 253},
+  { 8032, 16, 254},
+  { 8052, 0, 271},
+  { 8060, 0, 272},
+  { 8118, 0, 273},
+  { 8127, 0, 274},
+  { 8134, 0, 275},
+  { 8182, 0, 276},
+  { 8190, 0, 277},
+  { 8592, 0, 278},
+  { 8594, 0, 279},
+  { 8596, 0, 280},
+  { 8656, 0, 281},
+  { 8658, 0, 282},
+  { 8660, 0, 283},
+  { 8707, 0, 284},
+  { 8712, 0, 285},
+  { 8715, 0, 286},
+  { 8739, 0, 287},
+  { 8741, 0, 288},
+  { 8764, 0, 289},
+  { 8771, 0, 290},
+  { 8773, 0, 291},
+  { 8776, 0, 292},
+  { 8781, 0, 293},
+  { 8801, 0, 294},
+  { 8804, 1, 295},
+  { 8818, 1, 297},
+  { 8822, 1, 299},
+  { 8826, 3, 301},
+  { 8834, 1, 305},
+  { 8838, 1, 307},
+  { 8849, 1, 309},
+  { 8866, 0, 311},
+  { 8872, 1, 312},
+  { 8875, 0, 314},
+  { 8882, 3, 315},
+  { 12358, 0, 319},
+  { 12363, 0, 320},
+  { 12365, 0, 321},
+  { 12367, 0, 322},
+  { 12369, 0, 323},
+  { 12371, 0, 324},
+  { 12373, 0, 325},
+  { 12375, 0, 326},
+  { 12377, 0, 327},
+  { 12379, 0, 328},
+  { 12381, 0, 329},
+  { 12383, 0, 330},
+  { 12385, 0, 331},
+  { 12388, 0, 332},
+  { 12390, 0, 333},
+  { 12392, 0, 334},
+  { 12399, 0, 335},
+  { 12402, 0, 336},
+  { 12405, 0, 337},
+  { 12408, 0, 338},
+  { 12411, 0, 339},
+  { 12445, 0, 340},
+  { 12454, 0, 341},
+  { 12459, 0, 342},
+  { 12461, 0, 343},
+  { 12463, 0, 344},
+  { 12465, 0, 345},
+  { 12467, 0, 346},
+  { 12469, 0, 347},
+  { 12471, 0, 348},
+  { 12473, 0, 349},
+  { 12475, 0, 350},
+  { 12477, 0, 351},
+  { 12479, 0, 352},
+  { 12481, 0, 353},
+  { 12484, 0, 354},
+  { 12486, 0, 355},
+  { 12488, 0, 356},
+  { 12495, 0, 357},
+  { 12498, 0, 358},
+  { 12501, 0, 359},
+  { 12504, 0, 360},
+  { 12507, 0, 361},
+  { 12527, 3, 362},
+  { 12541, 0, 366},
+  { 69785, 0, 367},
+  { 69787, 0, 368},
+  { 69797, 0, 369},
+  { 69937, 1, 370},
+  { 70471, 0, 372},
+  { 70841, 0, 373},
+  { 71096, 1, 374},
+  {0,0,0}
+};
+
+static const Reindex nfc_last[] = {
+  { 768, 4, 0},
+  { 774, 6, 5},
+  { 783, 0, 12},
+  { 785, 0, 13},
+  { 787, 1, 14},
+  { 795, 0, 16},
+  { 803, 5, 17},
+  { 813, 1, 23},
+  { 816, 1, 25},
+  { 824, 0, 27},
+  { 834, 0, 28},
+  { 837, 0, 29},
+  { 1619, 2, 30},
+  { 2364, 0, 33},
+  { 2494, 0, 34},
+  { 2519, 0, 35},
+  { 2878, 0, 36},
+  { 2902, 1, 37},
+  { 3006, 0, 39},
+  { 3031, 0, 40},
+  { 3158, 0, 41},
+  { 3266, 0, 42},
+  { 3285, 1, 43},
+  { 3390, 0, 45},
+  { 3415, 0, 46},
+  { 3530, 0, 47},
+  { 3535, 0, 48},
+  { 3551, 0, 49},
+  { 4142, 0, 50},
+  { 6965, 0, 51},
+  { 12441, 1, 52},
+  { 69818, 0, 54},
+  { 69927, 0, 55},
+  { 70462, 0, 56},
+  { 70487, 0, 57},
+  { 70832, 0, 58},
+  { 70842, 0, 59},
+  { 70845, 0, 60},
+  { 71087, 0, 61},
+  {0,0,0}
+};
+
+#define UCDN_EAST_ASIAN_F 0
+#define UCDN_EAST_ASIAN_H 1
+#define UCDN_EAST_ASIAN_W 2
+#define UCDN_EAST_ASIAN_NA 3
+#define UCDN_EAST_ASIAN_A 4
+#define UCDN_EAST_ASIAN_N 5
+
+#define UCDN_SCRIPT_COMMON 0
+#define UCDN_SCRIPT_LATIN 1
+#define UCDN_SCRIPT_GREEK 2
+#define UCDN_SCRIPT_CYRILLIC 3
+#define UCDN_SCRIPT_ARMENIAN 4
+#define UCDN_SCRIPT_HEBREW 5
+#define UCDN_SCRIPT_ARABIC 6
+#define UCDN_SCRIPT_SYRIAC 7
+#define UCDN_SCRIPT_THAANA 8
+#define UCDN_SCRIPT_DEVANAGARI 9
+#define UCDN_SCRIPT_BENGALI 10
+#define UCDN_SCRIPT_GURMUKHI 11
+#define UCDN_SCRIPT_GUJARATI 12
+#define UCDN_SCRIPT_ORIYA 13
+#define UCDN_SCRIPT_TAMIL 14
+#define UCDN_SCRIPT_TELUGU 15
+#define UCDN_SCRIPT_KANNADA 16
+#define UCDN_SCRIPT_MALAYALAM 17
+#define UCDN_SCRIPT_SINHALA 18
+#define UCDN_SCRIPT_THAI 19
+#define UCDN_SCRIPT_LAO 20
+#define UCDN_SCRIPT_TIBETAN 21
+#define UCDN_SCRIPT_MYANMAR 22
+#define UCDN_SCRIPT_GEORGIAN 23
+#define UCDN_SCRIPT_HANGUL 24
+#define UCDN_SCRIPT_ETHIOPIC 25
+#define UCDN_SCRIPT_CHEROKEE 26
+#define UCDN_SCRIPT_CANADIAN_ABORIGINAL 27
+#define UCDN_SCRIPT_OGHAM 28
+#define UCDN_SCRIPT_RUNIC 29
+#define UCDN_SCRIPT_KHMER 30
+#define UCDN_SCRIPT_MONGOLIAN 31
+#define UCDN_SCRIPT_HIRAGANA 32
+#define UCDN_SCRIPT_KATAKANA 33
+#define UCDN_SCRIPT_BOPOMOFO 34
+#define UCDN_SCRIPT_HAN 35
+#define UCDN_SCRIPT_YI 36
+#define UCDN_SCRIPT_OLD_ITALIC 37
+#define UCDN_SCRIPT_GOTHIC 38
+#define UCDN_SCRIPT_DESERET 39
+#define UCDN_SCRIPT_INHERITED 40
+#define UCDN_SCRIPT_TAGALOG 41
+#define UCDN_SCRIPT_HANUNOO 42
+#define UCDN_SCRIPT_BUHID 43
+#define UCDN_SCRIPT_TAGBANWA 44
+#define UCDN_SCRIPT_LIMBU 45
+#define UCDN_SCRIPT_TAI_LE 46
+#define UCDN_SCRIPT_LINEAR_B 47
+#define UCDN_SCRIPT_UGARITIC 48
+#define UCDN_SCRIPT_SHAVIAN 49
+#define UCDN_SCRIPT_OSMANYA 50
+#define UCDN_SCRIPT_CYPRIOT 51
+#define UCDN_SCRIPT_BRAILLE 52
+#define UCDN_SCRIPT_BUGINESE 53
+#define UCDN_SCRIPT_COPTIC 54
+#define UCDN_SCRIPT_NEW_TAI_LUE 55
+#define UCDN_SCRIPT_GLAGOLITIC 56
+#define UCDN_SCRIPT_TIFINAGH 57
+#define UCDN_SCRIPT_SYLOTI_NAGRI 58
+#define UCDN_SCRIPT_OLD_PERSIAN 59
+#define UCDN_SCRIPT_KHAROSHTHI 60
+#define UCDN_SCRIPT_BALINESE 61
+#define UCDN_SCRIPT_CUNEIFORM 62
+#define UCDN_SCRIPT_PHOENICIAN 63
+#define UCDN_SCRIPT_PHAGS_PA 64
+#define UCDN_SCRIPT_NKO 65
+#define UCDN_SCRIPT_SUNDANESE 66
+#define UCDN_SCRIPT_LEPCHA 67
+#define UCDN_SCRIPT_OL_CHIKI 68
+#define UCDN_SCRIPT_VAI 69
+#define UCDN_SCRIPT_SAURASHTRA 70
+#define UCDN_SCRIPT_KAYAH_LI 71
+#define UCDN_SCRIPT_REJANG 72
+#define UCDN_SCRIPT_LYCIAN 73
+#define UCDN_SCRIPT_CARIAN 74
+#define UCDN_SCRIPT_LYDIAN 75
+#define UCDN_SCRIPT_CHAM 76
+#define UCDN_SCRIPT_TAI_THAM 77
+#define UCDN_SCRIPT_TAI_VIET 78
+#define UCDN_SCRIPT_AVESTAN 79
+#define UCDN_SCRIPT_EGYPTIAN_HIEROGLYPHS 80
+#define UCDN_SCRIPT_SAMARITAN 81
+#define UCDN_SCRIPT_LISU 82
+#define UCDN_SCRIPT_BAMUM 83
+#define UCDN_SCRIPT_JAVANESE 84
+#define UCDN_SCRIPT_MEETEI_MAYEK 85
+#define UCDN_SCRIPT_IMPERIAL_ARAMAIC 86
+#define UCDN_SCRIPT_OLD_SOUTH_ARABIAN 87
+#define UCDN_SCRIPT_INSCRIPTIONAL_PARTHIAN 88
+#define UCDN_SCRIPT_INSCRIPTIONAL_PAHLAVI 89
+#define UCDN_SCRIPT_OLD_TURKIC 90
+#define UCDN_SCRIPT_KAITHI 91
+#define UCDN_SCRIPT_BATAK 92
+#define UCDN_SCRIPT_BRAHMI 93
+#define UCDN_SCRIPT_MANDAIC 94
+#define UCDN_SCRIPT_CHAKMA 95
+#define UCDN_SCRIPT_MEROITIC_CURSIVE 96
+#define UCDN_SCRIPT_MEROITIC_HIEROGLYPHS 97
+#define UCDN_SCRIPT_MIAO 98
+#define UCDN_SCRIPT_SHARADA 99
+#define UCDN_SCRIPT_SORA_SOMPENG 100
+#define UCDN_SCRIPT_TAKRI 101
+#define UCDN_SCRIPT_UNKNOWN 102
+#define UCDN_SCRIPT_BASSA_VAH 103
+#define UCDN_SCRIPT_CAUCASIAN_ALBANIAN 104
+#define UCDN_SCRIPT_DUPLOYAN 105
+#define UCDN_SCRIPT_ELBASAN 106
+#define UCDN_SCRIPT_GRANTHA 107
+#define UCDN_SCRIPT_KHOJKI 108
+#define UCDN_SCRIPT_KHUDAWADI 109
+#define UCDN_SCRIPT_LINEAR_A 110
+#define UCDN_SCRIPT_MAHAJANI 111
+#define UCDN_SCRIPT_MANICHAEAN 112
+#define UCDN_SCRIPT_MENDE_KIKAKUI 113
+#define UCDN_SCRIPT_MODI 114
+#define UCDN_SCRIPT_MRO 115
+#define UCDN_SCRIPT_NABATAEAN 116
+#define UCDN_SCRIPT_OLD_NORTH_ARABIAN 117
+#define UCDN_SCRIPT_OLD_PERMIC 118
+#define UCDN_SCRIPT_PAHAWH_HMONG 119
+#define UCDN_SCRIPT_PALMYRENE 120
+#define UCDN_SCRIPT_PAU_CIN_HAU 121
+#define UCDN_SCRIPT_PSALTER_PAHLAVI 122
+#define UCDN_SCRIPT_SIDDHAM 123
+#define UCDN_SCRIPT_TIRHUTA 124
+#define UCDN_SCRIPT_WARANG_CITI 125
+#define UCDN_SCRIPT_AHOM 126
+#define UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS 127
+#define UCDN_SCRIPT_HATRAN 128
+#define UCDN_SCRIPT_MULTANI 129
+#define UCDN_SCRIPT_OLD_HUNGARIAN 130
+#define UCDN_SCRIPT_SIGNWRITING 131
+
+#define UCDN_GENERAL_CATEGORY_CC 0
+#define UCDN_GENERAL_CATEGORY_CF 1
+#define UCDN_GENERAL_CATEGORY_CN 2
+#define UCDN_GENERAL_CATEGORY_CO 3
+#define UCDN_GENERAL_CATEGORY_CS 4
+#define UCDN_GENERAL_CATEGORY_LL 5
+#define UCDN_GENERAL_CATEGORY_LM 6
+#define UCDN_GENERAL_CATEGORY_LO 7
+#define UCDN_GENERAL_CATEGORY_LT 8
+#define UCDN_GENERAL_CATEGORY_LU 9
+#define UCDN_GENERAL_CATEGORY_MC 10
+#define UCDN_GENERAL_CATEGORY_ME 11
+#define UCDN_GENERAL_CATEGORY_MN 12
+#define UCDN_GENERAL_CATEGORY_ND 13
+#define UCDN_GENERAL_CATEGORY_NL 14
+#define UCDN_GENERAL_CATEGORY_NO 15
+#define UCDN_GENERAL_CATEGORY_PC 16
+#define UCDN_GENERAL_CATEGORY_PD 17
+#define UCDN_GENERAL_CATEGORY_PE 18
+#define UCDN_GENERAL_CATEGORY_PF 19
+#define UCDN_GENERAL_CATEGORY_PI 20
+#define UCDN_GENERAL_CATEGORY_PO 21
+#define UCDN_GENERAL_CATEGORY_PS 22
+#define UCDN_GENERAL_CATEGORY_SC 23
+#define UCDN_GENERAL_CATEGORY_SK 24
+#define UCDN_GENERAL_CATEGORY_SM 25
+#define UCDN_GENERAL_CATEGORY_SO 26
+#define UCDN_GENERAL_CATEGORY_ZL 27
+#define UCDN_GENERAL_CATEGORY_ZP 28
+#define UCDN_GENERAL_CATEGORY_ZS 29
+
+#define UCDN_BIDI_CLASS_L 0
+#define UCDN_BIDI_CLASS_LRE 1
+#define UCDN_BIDI_CLASS_LRO 2
+#define UCDN_BIDI_CLASS_R 3
+#define UCDN_BIDI_CLASS_AL 4
+#define UCDN_BIDI_CLASS_RLE 5
+#define UCDN_BIDI_CLASS_RLO 6
+#define UCDN_BIDI_CLASS_PDF 7
+#define UCDN_BIDI_CLASS_EN 8
+#define UCDN_BIDI_CLASS_ES 9
+#define UCDN_BIDI_CLASS_ET 10
+#define UCDN_BIDI_CLASS_AN 11
+#define UCDN_BIDI_CLASS_CS 12
+#define UCDN_BIDI_CLASS_NSM 13
+#define UCDN_BIDI_CLASS_BN 14
+#define UCDN_BIDI_CLASS_B 15
+#define UCDN_BIDI_CLASS_S 16
+#define UCDN_BIDI_CLASS_WS 17
+#define UCDN_BIDI_CLASS_ON 18
+#define UCDN_BIDI_CLASS_LRI 19
+#define UCDN_BIDI_CLASS_RLI 20
+#define UCDN_BIDI_CLASS_FSI 21
+#define UCDN_BIDI_CLASS_PDI 22
+
+/* index tables for the database records */
+#define SHIFT1 5
+#define SHIFT2 3
+static const unsigned char index0[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+    39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 55, 56, 56, 56, 57,
+    58, 59, 60, 61, 62, 63, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+    65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+    65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 67, 67, 67,
+    67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 52, 69, 70, 71, 72, 73,
+    74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 88, 90,
+    91, 92, 93, 94, 95, 96, 97, 98, 88, 99, 88, 88, 88, 88, 88, 100, 100,
+    100, 101, 102, 103, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 104, 104,
+    104, 104, 105, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 106, 106, 107, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 108, 108, 109, 110, 88, 88, 88, 111, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 112, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 113, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 114,
+    115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 124, 88, 88, 88, 88, 88, 125, 88, 126, 127,
+    128, 129, 130, 131, 132, 133, 134, 135, 88, 88, 88, 88, 88, 88, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 136, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 137, 138, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+    52, 52, 52, 52, 52, 52, 139, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 52, 52, 141, 140, 140, 140, 140, 142, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+    142, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 143, 144, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+    88, 88, 88, 88, 88, 88, 88, 88, 88, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 145, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 145,
+};
+
+static const unsigned short index1[] = {
+    0, 1, 0, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13, 0, 0, 0, 14, 15,
+    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 29, 31, 32,
+    33, 34, 35, 27, 30, 29, 27, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+    47, 48, 27, 27, 49, 27, 27, 27, 27, 27, 27, 27, 50, 51, 52, 27, 53, 54,
+    53, 54, 54, 54, 54, 54, 55, 54, 54, 54, 56, 57, 58, 59, 60, 61, 62, 63,
+    64, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 65, 77, 78,
+    79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+    97, 97, 97, 97, 98, 98, 98, 98, 99, 100, 101, 101, 101, 101, 102, 103,
+    101, 101, 101, 101, 101, 101, 104, 105, 101, 101, 101, 101, 101, 101,
+    101, 101, 101, 101, 101, 101, 106, 107, 107, 107, 108, 109, 110, 111,
+    111, 111, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 121,
+    121, 122, 123, 120, 124, 125, 126, 127, 128, 128, 128, 128, 129, 130,
+    131, 132, 133, 134, 135, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+    128, 128, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 145, 145,
+    146, 147, 148, 149, 128, 128, 128, 128, 128, 128, 150, 150, 150, 150,
+    151, 152, 153, 120, 154, 155, 156, 156, 156, 157, 158, 159, 160, 160,
+    161, 162, 163, 164, 165, 166, 167, 167, 167, 168, 120, 120, 120, 120,
+    120, 120, 120, 120, 128, 128, 169, 120, 120, 120, 120, 120, 170, 171,
+    172, 173, 174, 175, 175, 175, 175, 175, 175, 176, 177, 178, 179, 175,
+    180, 181, 182, 175, 183, 184, 185, 186, 186, 187, 188, 189, 190, 191,
+    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 201, 202, 203, 204,
+    205, 206, 207, 208, 209, 210, 211, 120, 212, 213, 214, 215, 215, 216,
+    217, 218, 219, 220, 221, 120, 222, 223, 224, 225, 226, 227, 228, 229,
+    229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 120, 240, 241,
+    242, 243, 244, 241, 245, 246, 247, 248, 249, 120, 250, 251, 252, 253,
+    254, 255, 256, 257, 257, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+    120, 265, 266, 267, 268, 269, 269, 268, 270, 271, 272, 273, 274, 275,
+    276, 277, 278, 120, 279, 280, 281, 282, 282, 282, 282, 283, 284, 285,
+    286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 293, 293, 296, 297,
+    294, 298, 299, 300, 301, 302, 303, 120, 304, 305, 305, 305, 305, 305,
+    306, 307, 308, 309, 310, 311, 120, 120, 120, 120, 312, 313, 314, 315,
+    316, 317, 318, 319, 320, 321, 322, 323, 120, 120, 120, 120, 324, 325,
+    326, 327, 328, 329, 330, 331, 332, 333, 332, 332, 332, 334, 335, 336,
+    337, 338, 339, 340, 339, 339, 339, 341, 342, 343, 344, 345, 120, 120,
+    120, 120, 346, 346, 346, 346, 346, 347, 348, 349, 350, 351, 352, 353,
+    354, 355, 356, 346, 357, 358, 350, 359, 360, 360, 360, 360, 361, 362,
+    363, 363, 363, 363, 363, 364, 365, 365, 365, 365, 365, 365, 365, 365,
+    365, 365, 365, 365, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
+    366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 367, 367, 367, 367,
+    367, 367, 367, 367, 367, 368, 369, 368, 367, 367, 367, 367, 367, 368,
+    367, 367, 367, 367, 368, 369, 368, 367, 369, 367, 367, 367, 367, 367,
+    367, 367, 368, 367, 367, 367, 367, 367, 367, 367, 367, 370, 371, 372,
+    373, 374, 367, 367, 375, 376, 377, 377, 377, 377, 377, 377, 377, 377,
+    377, 377, 378, 379, 380, 381, 381, 381, 381, 381, 381, 381, 381, 381,
+    381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
+    381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
+    381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
+    381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
+    381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 382, 381, 381,
+    383, 384, 384, 385, 386, 386, 386, 386, 386, 386, 386, 386, 386, 387,
+    388, 389, 390, 391, 392, 120, 393, 393, 394, 120, 395, 395, 396, 120,
+    397, 398, 399, 120, 400, 400, 400, 400, 400, 400, 401, 402, 403, 404,
+    405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 415, 415, 415,
+    416, 415, 415, 415, 415, 415, 415, 120, 415, 415, 415, 415, 415, 417,
+    381, 381, 381, 381, 381, 381, 381, 381, 418, 120, 419, 419, 419, 420,
+    421, 422, 423, 424, 425, 426, 427, 427, 427, 428, 429, 120, 430, 430,
+    430, 430, 430, 431, 430, 430, 430, 432, 433, 434, 435, 435, 435, 435,
+    436, 436, 437, 438, 439, 439, 439, 439, 439, 439, 440, 441, 442, 443,
+    444, 445, 446, 447, 446, 447, 448, 449, 450, 451, 120, 120, 120, 120,
+    120, 120, 120, 120, 452, 453, 453, 453, 453, 453, 454, 455, 456, 457,
+    458, 459, 460, 461, 462, 463, 464, 465, 465, 465, 466, 467, 468, 469,
+    470, 470, 470, 470, 471, 472, 473, 474, 475, 475, 475, 475, 476, 477,
+    478, 479, 480, 481, 482, 483, 484, 484, 484, 485, 120, 120, 120, 120,
+    120, 120, 120, 120, 486, 120, 487, 488, 489, 490, 491, 492, 54, 54, 54,
+    54, 493, 494, 56, 56, 56, 56, 56, 495, 496, 497, 54, 498, 54, 54, 54,
+    499, 56, 56, 56, 500, 501, 502, 503, 504, 504, 504, 505, 506, 27, 27, 27,
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 507, 508, 27,
+    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 509, 510, 511, 512, 509, 510,
+    509, 510, 511, 512, 509, 513, 509, 510, 509, 511, 509, 514, 509, 514,
+    509, 514, 515, 516, 517, 518, 519, 520, 509, 521, 522, 523, 524, 525,
+    526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539,
+    540, 541, 56, 542, 543, 544, 543, 545, 120, 120, 546, 547, 548, 549, 550,
+    120, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
+    564, 563, 565, 566, 567, 568, 569, 570, 571, 572, 573, 572, 574, 575,
+    572, 576, 572, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587,
+    588, 589, 590, 591, 592, 587, 587, 593, 594, 595, 596, 597, 587, 587,
+    598, 578, 599, 600, 587, 587, 601, 587, 587, 572, 602, 603, 572, 604,
+    605, 606, 607, 607, 607, 607, 607, 607, 607, 607, 608, 572, 572, 609,
+    610, 578, 578, 611, 572, 572, 572, 572, 577, 612, 572, 572, 613, 572,
+    572, 572, 572, 614, 120, 120, 120, 572, 613, 120, 120, 615, 615, 615,
+    615, 615, 616, 616, 617, 618, 618, 618, 618, 618, 618, 618, 618, 618,
+    619, 615, 615, 620, 620, 620, 620, 620, 620, 620, 620, 620, 621, 620,
+    620, 620, 620, 621, 572, 620, 620, 622, 572, 623, 573, 624, 625, 626,
+    627, 573, 572, 622, 576, 572, 578, 628, 629, 625, 630, 572, 572, 572,
+    572, 631, 572, 572, 572, 632, 633, 572, 572, 572, 572, 572, 634, 572,
+    635, 572, 634, 636, 637, 620, 620, 638, 620, 620, 620, 572, 572, 572,
+    572, 572, 572, 572, 639, 572, 572, 576, 572, 572, 640, 641, 615, 642,
+    642, 643, 572, 572, 572, 572, 572, 644, 645, 646, 647, 648, 649, 578,
+    578, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650,
+    650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650,
+    650, 650, 650, 650, 650, 578, 578, 578, 578, 578, 578, 578, 578, 578,
+    578, 578, 578, 578, 578, 578, 578, 651, 652, 652, 653, 587, 587, 578,
+    654, 601, 655, 656, 657, 658, 659, 660, 661, 578, 662, 587, 663, 664,
+    665, 666, 647, 578, 578, 590, 654, 666, 667, 668, 669, 587, 587, 587,
+    587, 670, 671, 587, 587, 587, 587, 672, 673, 674, 647, 675, 676, 572,
+    572, 572, 572, 572, 572, 578, 578, 677, 678, 679, 573, 572, 572, 680,
+    572, 572, 572, 681, 572, 572, 572, 572, 682, 572, 683, 684, 120, 120,
+    685, 120, 120, 686, 686, 686, 686, 686, 687, 688, 688, 688, 688, 688,
+    689, 690, 691, 692, 693, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    694, 695, 696, 697, 698, 698, 698, 698, 699, 700, 701, 701, 701, 701,
+    701, 701, 701, 702, 703, 704, 367, 367, 369, 120, 369, 369, 369, 369,
+    369, 369, 369, 369, 705, 705, 705, 705, 706, 707, 708, 709, 710, 711,
+    533, 712, 713, 120, 120, 120, 120, 120, 120, 120, 714, 714, 714, 715,
+    714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 716, 120, 714, 714,
+    714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714,
+    714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 717, 120, 120, 120,
+    718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 729, 729,
+    729, 729, 729, 729, 729, 729, 730, 731, 732, 733, 733, 733, 733, 733,
+    733, 733, 733, 733, 733, 734, 735, 736, 736, 736, 736, 737, 738, 365,
+    365, 365, 365, 365, 365, 365, 365, 365, 365, 739, 740, 741, 736, 736,
+    736, 742, 718, 718, 718, 718, 719, 120, 733, 733, 743, 743, 743, 744,
+    745, 746, 741, 741, 741, 747, 748, 749, 743, 743, 743, 750, 745, 746,
+    741, 741, 741, 741, 751, 749, 741, 752, 753, 753, 753, 753, 753, 754,
+    753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 741, 741, 741,
+    755, 756, 741, 741, 741, 741, 741, 741, 741, 741, 741, 741, 741, 757,
+    741, 741, 741, 755, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 759, 760, 572, 572, 572, 572, 572, 572, 572, 572, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 759, 760, 760, 760,
+    760, 760, 761, 761, 762, 761, 761, 761, 761, 761, 761, 761, 761, 761,
+    761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
+    761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
+    761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
+    761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761,
+    761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 763,
+    764, 764, 764, 764, 764, 764, 765, 120, 766, 766, 766, 766, 766, 767,
+    768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768,
+    768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768,
+    768, 768, 768, 768, 768, 769, 768, 768, 770, 771, 120, 120, 101, 101,
+    101, 101, 101, 772, 773, 774, 101, 101, 101, 775, 776, 776, 776, 776,
+    776, 776, 776, 776, 777, 778, 779, 120, 64, 64, 780, 781, 782, 27, 783,
+    27, 27, 27, 27, 27, 27, 27, 784, 785, 27, 786, 787, 27, 27, 788, 789,
+    120, 120, 120, 120, 120, 120, 120, 790, 791, 792, 793, 794, 794, 795,
+    796, 797, 798, 799, 799, 799, 799, 799, 799, 800, 120, 801, 802, 802,
+    802, 802, 802, 803, 804, 805, 806, 807, 808, 809, 809, 810, 811, 812,
+    813, 814, 814, 815, 816, 817, 817, 818, 819, 820, 821, 365, 365, 365,
+    822, 823, 824, 824, 824, 824, 824, 825, 826, 827, 828, 829, 830, 831,
+    346, 350, 832, 833, 833, 833, 833, 833, 834, 835, 120, 836, 837, 838,
+    839, 346, 346, 840, 841, 842, 842, 842, 842, 842, 842, 843, 844, 845,
+    120, 120, 846, 847, 848, 849, 120, 850, 850, 850, 120, 369, 369, 54, 54,
+    54, 54, 54, 851, 852, 120, 853, 853, 853, 853, 853, 853, 853, 853, 853,
+    853, 847, 847, 847, 847, 854, 855, 856, 857, 365, 365, 365, 365, 365,
+    365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365,
+    365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365,
+    365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365,
+    365, 365, 365, 365, 365, 858, 120, 366, 366, 859, 860, 366, 366, 366,
+    366, 366, 861, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862,
+    862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862,
+    862, 862, 862, 862, 862, 862, 862, 863, 863, 863, 863, 863, 863, 863,
+    863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863,
+    863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 759, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 864, 760, 760, 760,
+    760, 865, 120, 866, 867, 121, 868, 869, 870, 871, 121, 128, 128, 128,
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 872, 873, 874, 120, 875,
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+    128, 128, 876, 120, 120, 128, 128, 128, 128, 128, 128, 128, 128, 877,
+    128, 128, 128, 128, 128, 128, 120, 120, 120, 120, 120, 128, 878, 879,
+    879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892,
+    128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+    128, 128, 893, 894, 895, 896, 897, 898, 899, 899, 900, 901, 902, 902,
+    903, 904, 905, 906, 905, 905, 905, 905, 907, 908, 908, 908, 909, 910,
+    910, 910, 911, 912, 913, 120, 914, 915, 916, 915, 915, 917, 915, 915,
+    918, 915, 919, 915, 919, 120, 120, 120, 120, 915, 915, 915, 915, 915,
+    915, 915, 915, 915, 915, 915, 915, 915, 915, 915, 920, 921, 922, 922,
+    922, 922, 922, 923, 607, 924, 924, 924, 924, 924, 924, 925, 926, 927,
+    928, 572, 929, 930, 120, 120, 120, 120, 120, 607, 607, 607, 607, 607,
+    931, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 932, 932, 932, 933, 934, 934, 934, 934, 934, 934, 935,
+    120, 936, 937, 937, 938, 939, 939, 939, 939, 940, 120, 941, 941, 942,
+    943, 944, 944, 944, 944, 945, 946, 947, 947, 947, 948, 949, 949, 949,
+    949, 950, 949, 951, 120, 120, 120, 120, 120, 952, 952, 952, 952, 952,
+    953, 953, 953, 953, 953, 954, 954, 954, 954, 954, 954, 955, 955, 955,
+    956, 957, 958, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 959,
+    959, 959, 959, 959, 120, 960, 960, 960, 960, 960, 960, 961, 962, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963,
+    963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963,
+    963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 964,
+    120, 963, 963, 965, 120, 963, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 966, 967, 968,
+    968, 968, 968, 969, 970, 971, 971, 972, 973, 974, 974, 975, 976, 977,
+    977, 977, 978, 979, 980, 120, 120, 120, 120, 120, 120, 981, 981, 982,
+    983, 984, 984, 985, 986, 987, 987, 987, 988, 120, 120, 120, 120, 120,
+    120, 120, 120, 989, 989, 989, 989, 990, 990, 990, 991, 992, 992, 993,
+    992, 992, 992, 992, 992, 994, 995, 996, 997, 998, 998, 999, 1000, 1001,
+    120, 1002, 1003, 1004, 1004, 1004, 1005, 1006, 1006, 1006, 1007, 120,
+    120, 120, 120, 1008, 1009, 1008, 1008, 1010, 1011, 1012, 120, 1013, 1013,
+    1013, 1013, 1013, 1013, 1014, 1015, 1016, 1016, 1017, 1018, 1019, 1019,
+    1020, 1021, 1022, 1022, 1023, 1024, 120, 1025, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026,
+    1026, 1027, 120, 120, 120, 120, 120, 120, 1028, 1028, 1028, 1028, 1028,
+    1028, 1029, 120, 1030, 1030, 1030, 1030, 1030, 1030, 1031, 1032, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 1033, 1033, 1033, 1034, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 1035, 1036, 1036, 1036, 1036, 1036,
+    1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 120, 1044, 1045, 1046,
+    1046, 1046, 1046, 1046, 1047, 1048, 1049, 120, 1050, 1050, 1050, 1051,
+    1052, 1053, 1054, 1055, 1055, 1055, 1056, 1057, 1058, 1059, 1060, 120,
+    1061, 1061, 1061, 1061, 1062, 120, 1063, 1064, 1064, 1064, 1064, 1064,
+    1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 120, 1074, 1074,
+    1075, 1074, 1074, 1076, 1077, 1078, 120, 120, 120, 120, 120, 120, 120,
+    120, 1079, 1080, 1081, 1082, 1081, 1083, 1084, 1084, 1084, 1084, 1084,
+    1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1093, 1094, 1095,
+    1096, 1097, 1098, 1099, 1100, 1101, 1102, 1102, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    1103, 1103, 1103, 1103, 1103, 1103, 1104, 1105, 1106, 120, 1107, 1108,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 1109, 1109, 1109, 1109, 1109, 1110, 1111,
+    1112, 1113, 1114, 1114, 1115, 120, 120, 120, 120, 1116, 1116, 1116, 1116,
+    1116, 1116, 1117, 1118, 1119, 120, 1120, 1121, 120, 120, 120, 120, 1122,
+    1122, 1122, 1122, 1122, 1123, 1124, 120, 1125, 1126, 120, 120, 120, 120,
+    120, 120, 1127, 1127, 1127, 1128, 1129, 1130, 1131, 1132, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1133,
+    1133, 1133, 1133, 1134, 1134, 1134, 1134, 1135, 1136, 1137, 1138, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 1139, 1139, 1139, 1139,
+    1139, 1139, 1139, 1140, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141,
+    1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141,
+    1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141,
+    1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141,
+    1141, 1141, 1141, 1141, 1141, 1141, 1141, 1142, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 1143, 1143, 1143, 1143, 1143, 1143,
+    1143, 1143, 1143, 1143, 1143, 1143, 1143, 1144, 1145, 120, 1141, 1141,
+    1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141,
+    1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1146, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 1147, 1147, 1147, 1147, 1147,
+    1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147,
+    1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147,
+    1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1148, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 1149, 1149, 1149, 1149, 1149,
+    1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149,
+    1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149,
+    1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1150,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 776, 776, 776, 776, 776,
+    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776,
+    776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776,
+    776, 776, 776, 776, 776, 776, 1151, 1152, 1152, 1152, 1153, 1154, 1155,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1156, 1156,
+    1156, 1157, 1158, 120, 1159, 1159, 1159, 1159, 1159, 1159, 1160, 1161,
+    1162, 120, 1163, 1164, 1165, 1159, 1159, 1166, 1159, 1159, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1167, 1167, 1167,
+    1167, 1167, 1167, 1167, 1167, 1168, 120, 1169, 1170, 1170, 1170, 1170,
+    1171, 120, 1172, 1173, 1174, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 1175, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 1176, 1176, 1176, 1176, 1176, 1176,
+    1176, 1176, 1176, 1176, 1176, 1176, 1176, 1177, 1176, 1178, 1176, 1179,
+    1176, 1180, 1181, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607,
+    607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607,
+    607, 607, 1182, 120, 607, 607, 607, 607, 1183, 1184, 607, 607, 607, 607,
+    607, 607, 1185, 1186, 1187, 1188, 1189, 1190, 607, 607, 607, 1191, 607,
+    607, 607, 607, 607, 607, 607, 1192, 120, 120, 927, 927, 927, 927, 927,
+    927, 927, 927, 1193, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 572,
+    572, 572, 572, 572, 572, 572, 572, 572, 572, 614, 120, 922, 922, 1194,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 1195, 1195, 1195, 1196, 1197, 1197, 1198, 1195, 1195,
+    1199, 1200, 1197, 1197, 1195, 1195, 1195, 1196, 1197, 1197, 1201, 1202,
+    1203, 1199, 1204, 1205, 1197, 1195, 1195, 1195, 1196, 1197, 1197, 1206,
+    1207, 1208, 1209, 1197, 1197, 1197, 1210, 1211, 1212, 1213, 1197, 1197,
+    1198, 1195, 1195, 1199, 1197, 1197, 1197, 1195, 1195, 1195, 1196, 1197,
+    1197, 1198, 1195, 1195, 1199, 1197, 1197, 1197, 1195, 1195, 1195, 1196,
+    1197, 1197, 1198, 1195, 1195, 1199, 1197, 1197, 1197, 1195, 1195, 1195,
+    1196, 1197, 1197, 1214, 1195, 1195, 1195, 1215, 1197, 1197, 1216, 1217,
+    1195, 1195, 1218, 1197, 1197, 1219, 1198, 1195, 1195, 1220, 1197, 1197,
+    1221, 1222, 1195, 1195, 1223, 1197, 1197, 1197, 1224, 1195, 1195, 1195,
+    1215, 1197, 1197, 1216, 1225, 1226, 1226, 1226, 1226, 1226, 1226, 1227,
+    1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227,
+    1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227,
+    1227, 1227, 1227, 1227, 1227, 1227, 1227, 1228, 1228, 1228, 1228, 1228,
+    1228, 1229, 1230, 1228, 1228, 1228, 1228, 1228, 1231, 1232, 1227, 1233,
+    1234, 120, 1235, 1236, 1228, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237,
+    1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237,
+    1237, 1238, 1239, 1240, 120, 120, 120, 120, 120, 1241, 128, 128, 128,
+    1242, 1243, 1244, 1245, 1246, 1247, 1242, 1248, 1242, 1244, 1244, 1249,
+    128, 1250, 128, 1251, 1252, 1250, 128, 1251, 120, 120, 120, 120, 120,
+    120, 1253, 120, 572, 572, 572, 572, 572, 929, 572, 572, 572, 572, 572,
+    572, 572, 572, 572, 572, 572, 572, 929, 120, 572, 614, 1254, 572, 1254,
+    572, 1254, 572, 572, 572, 681, 120, 616, 1255, 618, 618, 618, 1256, 618,
+    618, 618, 618, 618, 618, 618, 1257, 618, 618, 618, 618, 618, 1258, 120,
+    120, 120, 120, 120, 120, 120, 120, 1259, 607, 607, 607, 1260, 120, 741,
+    741, 741, 741, 741, 1261, 741, 1262, 1263, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 572, 572, 572, 1264, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 1265, 572, 572, 572,
+    572, 1266, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 1267, 120, 572,
+    1268, 929, 120, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 572, 572, 929, 120, 572, 572, 572, 572, 572, 572, 572, 572, 572,
+    572, 1268, 120, 120, 120, 120, 120, 572, 929, 572, 572, 572, 572, 572,
+    572, 572, 120, 572, 684, 572, 572, 572, 572, 572, 120, 572, 572, 572,
+    681, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 572,
+    1267, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1268,
+    120, 120, 120, 120, 120, 120, 120, 1267, 120, 120, 120, 120, 120, 120,
+    120, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 1269,
+    760, 760, 760, 760, 760, 758, 758, 758, 758, 758, 758, 1270, 760, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 759, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758,
+    758, 758, 758, 758, 758, 864, 760, 760, 760, 760, 760, 760, 760, 760,
+    760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+    760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+    760, 760, 760, 760, 760, 760, 760, 758, 758, 758, 759, 760, 760, 760,
+    760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+    760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+    760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+    760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+    1271, 1272, 120, 120, 120, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
+    1273, 1273, 1273, 1273, 1273, 120, 120, 120, 120, 120, 120, 120, 120,
+    120, 120, 120, 120, 120, 120, 120, 120, 879, 879, 879, 879, 879, 879,
+    879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879,
+    879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 120, 120, 863, 863,
+    863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863,
+    863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863,
+    863, 1274,
+};
+
+static const unsigned short index2[] = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 2,
+    5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12, 12, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17, 17, 17, 17, 17, 17, 17,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 9, 6, 10, 18, 19, 18, 20, 20,
+    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 9, 16,
+    10, 16, 1, 1, 1, 1, 1, 1, 3, 1, 1, 21, 22, 8, 8, 23, 8, 24, 22, 25, 26,
+    27, 28, 16, 29, 30, 18, 31, 32, 33, 33, 25, 34, 22, 22, 25, 33, 27, 35,
+    36, 36, 36, 22, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37,
+    37, 37, 38, 37, 37, 37, 37, 37, 37, 39, 38, 37, 37, 37, 37, 37, 38, 40,
+    40, 40, 41, 41, 41, 41, 40, 41, 40, 40, 40, 41, 40, 40, 41, 41, 40, 41,
+    40, 40, 41, 41, 41, 39, 40, 40, 40, 41, 40, 41, 40, 41, 37, 40, 37, 41,
+    37, 41, 37, 41, 37, 41, 37, 41, 37, 41, 37, 41, 37, 40, 37, 40, 37, 41,
+    37, 41, 37, 41, 37, 40, 37, 41, 37, 41, 37, 41, 37, 41, 37, 41, 38, 40,
+    37, 40, 38, 40, 37, 41, 37, 41, 40, 37, 41, 37, 41, 37, 41, 38, 40, 38,
+    40, 37, 40, 37, 41, 37, 40, 40, 38, 40, 37, 40, 37, 41, 37, 41, 38, 40,
+    37, 41, 37, 41, 37, 37, 41, 37, 41, 37, 41, 41, 41, 37, 37, 41, 37, 41,
+    37, 37, 41, 37, 37, 37, 41, 41, 37, 37, 37, 37, 41, 37, 37, 41, 37, 37,
+    37, 41, 41, 41, 37, 37, 41, 37, 37, 41, 37, 41, 37, 41, 37, 37, 41, 37,
+    41, 41, 37, 41, 37, 37, 41, 37, 37, 37, 41, 37, 41, 37, 37, 41, 41, 42,
+    37, 41, 41, 41, 42, 42, 42, 42, 37, 43, 41, 37, 43, 41, 37, 43, 41, 37,
+    40, 37, 40, 37, 40, 37, 40, 37, 40, 37, 40, 37, 40, 37, 40, 41, 37, 41,
+    41, 37, 43, 41, 37, 41, 37, 37, 37, 41, 37, 41, 41, 41, 41, 41, 41, 41,
+    37, 37, 41, 37, 37, 41, 41, 37, 41, 37, 37, 37, 37, 41, 41, 40, 41, 41,
+    41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 41,
+    41, 41, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 46, 46, 46, 46, 46,
+    46, 46, 47, 47, 25, 47, 45, 48, 45, 48, 48, 48, 45, 48, 45, 45, 49, 46,
+    47, 47, 47, 47, 47, 47, 25, 25, 25, 25, 47, 25, 47, 25, 44, 44, 44, 44,
+    44, 47, 47, 47, 47, 47, 50, 50, 45, 47, 46, 47, 47, 47, 47, 47, 47, 47,
+    47, 47, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 53, 53,
+    53, 53, 52, 54, 53, 53, 53, 53, 53, 55, 55, 53, 53, 53, 53, 55, 55, 53,
+    53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 53, 53, 53,
+    53, 51, 51, 51, 51, 51, 51, 51, 51, 57, 51, 53, 53, 53, 51, 51, 51, 53,
+    53, 58, 51, 51, 51, 53, 53, 53, 53, 51, 52, 53, 53, 51, 59, 60, 60, 59,
+    60, 60, 59, 51, 51, 51, 51, 51, 61, 62, 61, 62, 45, 63, 61, 62, 64, 64,
+    65, 62, 62, 62, 66, 61, 64, 64, 64, 64, 63, 47, 61, 66, 61, 61, 61, 64,
+    61, 64, 61, 61, 62, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,
+    67, 67, 67, 67, 64, 67, 67, 67, 67, 67, 67, 67, 61, 61, 62, 62, 62, 62,
+    62, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+    62, 68, 68, 68, 68, 68, 68, 68, 62, 62, 62, 62, 62, 61, 62, 62, 61, 61,
+    61, 62, 62, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 69, 70, 69, 70,
+    69, 70, 69, 70, 69, 70, 69, 70, 69, 70, 62, 62, 62, 62, 61, 62, 71, 61,
+    62, 61, 61, 62, 62, 61, 61, 61, 72, 73, 72, 72, 72, 72, 72, 72, 72, 72,
+    72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74,
+    74, 74, 74, 74, 75, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+    75, 75, 72, 75, 72, 75, 72, 75, 72, 75, 72, 75, 76, 77, 77, 78, 78, 77,
+    79, 79, 72, 75, 72, 75, 72, 75, 72, 72, 75, 72, 75, 72, 75, 72, 75, 72,
+    75, 72, 75, 72, 75, 75, 64, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+    80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 64, 64, 81, 82, 82, 82, 82,
+    82, 82, 64, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+    64, 84, 85, 64, 64, 86, 86, 87, 64, 88, 89, 89, 89, 89, 88, 89, 89, 89,
+    90, 88, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89, 89, 88, 89,
+    89, 90, 91, 89, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 101, 102, 103,
+    104, 105, 106, 107, 108, 109, 107, 89, 88, 107, 100, 64, 64, 64, 64, 64,
+    64, 64, 64, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 64,
+    64, 64, 64, 64, 110, 110, 110, 107, 107, 64, 64, 64, 111, 111, 111, 111,
+    111, 112, 113, 113, 114, 115, 115, 116, 117, 118, 119, 119, 120, 120,
+    120, 120, 120, 120, 120, 120, 121, 122, 123, 124, 125, 64, 118, 124, 126,
+    126, 126, 126, 126, 126, 126, 126, 127, 126, 126, 126, 126, 126, 126,
+    126, 126, 126, 126, 128, 129, 130, 131, 132, 133, 134, 135, 78, 78, 136,
+    137, 120, 120, 120, 120, 120, 137, 120, 120, 137, 138, 138, 138, 138,
+    138, 138, 138, 138, 138, 138, 115, 139, 139, 118, 126, 126, 140, 126,
+    126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 118, 126, 120, 120,
+    120, 120, 120, 120, 120, 112, 119, 120, 120, 120, 120, 137, 120, 141,
+    141, 120, 120, 119, 137, 120, 120, 137, 126, 126, 142, 142, 142, 142,
+    142, 142, 142, 142, 142, 142, 126, 126, 126, 143, 143, 126, 144, 144,
+    144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 64, 145, 146,
+    147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
+    146, 148, 149, 148, 148, 149, 148, 148, 149, 149, 149, 148, 149, 149,
+    148, 149, 148, 148, 148, 149, 148, 149, 148, 149, 148, 149, 148, 148, 64,
+    64, 146, 146, 146, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
+    150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151,
+    150, 64, 64, 64, 64, 64, 64, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+    152, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
+    153, 153, 153, 153, 154, 154, 154, 154, 154, 154, 154, 155, 154, 156,
+    156, 157, 158, 158, 158, 156, 64, 64, 64, 64, 64, 159, 159, 159, 159,
+    159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 160, 160, 160, 160,
+    161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 160, 160, 160,
+    161, 160, 160, 160, 160, 160, 64, 64, 162, 162, 162, 162, 162, 162, 162,
+    162, 162, 162, 162, 162, 162, 162, 162, 64, 163, 163, 163, 163, 163, 163,
+    163, 163, 163, 164, 164, 164, 64, 64, 165, 64, 126, 126, 126, 126, 126,
+    64, 64, 64, 64, 64, 64, 137, 120, 120, 137, 120, 120, 137, 120, 120, 120,
+    137, 137, 137, 166, 167, 168, 120, 120, 120, 137, 120, 120, 137, 137,
+    120, 120, 120, 120, 120, 169, 169, 169, 170, 171, 171, 171, 171, 171,
+    171, 171, 171, 171, 171, 171, 171, 171, 171, 169, 170, 172, 171, 170,
+    170, 170, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170,
+    173, 170, 170, 171, 78, 136, 174, 174, 169, 169, 169, 171, 171, 169, 169,
+    84, 84, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 177, 171,
+    171, 171, 171, 171, 171, 178, 179, 180, 180, 64, 178, 178, 178, 178, 178,
+    178, 178, 178, 64, 64, 178, 178, 64, 64, 178, 178, 178, 178, 178, 178,
+    178, 178, 178, 178, 178, 178, 178, 178, 64, 178, 178, 178, 178, 178, 178,
+    178, 64, 178, 64, 64, 64, 178, 178, 178, 178, 64, 64, 181, 178, 180, 180,
+    180, 179, 179, 179, 179, 64, 64, 180, 180, 64, 64, 180, 180, 182, 178,
+    64, 64, 64, 64, 64, 64, 64, 64, 180, 64, 64, 64, 64, 178, 178, 64, 178,
+    178, 178, 179, 179, 64, 64, 183, 183, 183, 183, 183, 183, 183, 183, 183,
+    183, 178, 178, 184, 184, 185, 185, 185, 185, 185, 185, 186, 184, 64, 64,
+    64, 64, 64, 187, 187, 188, 64, 189, 189, 189, 189, 189, 189, 64, 64, 64,
+    64, 189, 189, 64, 64, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189,
+    189, 189, 189, 189, 64, 189, 189, 189, 189, 189, 189, 189, 64, 189, 189,
+    64, 189, 189, 64, 189, 189, 64, 64, 190, 64, 188, 188, 188, 187, 187, 64,
+    64, 64, 64, 187, 187, 64, 64, 187, 187, 191, 64, 64, 64, 187, 64, 64, 64,
+    64, 64, 64, 64, 189, 189, 189, 189, 64, 189, 64, 64, 64, 64, 64, 64, 64,
+    192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 187, 187, 189, 189,
+    189, 187, 64, 64, 64, 193, 193, 194, 64, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 64, 195, 195, 195, 64, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 64, 195, 195, 195, 195, 195, 195, 195,
+    64, 195, 195, 64, 195, 195, 195, 195, 195, 64, 64, 196, 195, 194, 194,
+    194, 193, 193, 193, 193, 193, 64, 193, 193, 194, 64, 194, 194, 197, 64,
+    64, 195, 64, 64, 64, 64, 64, 64, 64, 195, 195, 193, 193, 64, 64, 198,
+    198, 198, 198, 198, 198, 198, 198, 198, 198, 199, 200, 64, 64, 64, 64,
+    64, 64, 64, 195, 64, 64, 64, 64, 64, 64, 64, 201, 202, 202, 64, 203, 203,
+    203, 203, 203, 203, 203, 203, 64, 64, 203, 203, 64, 64, 203, 203, 203,
+    203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 64, 203, 203, 203,
+    203, 203, 203, 203, 64, 203, 203, 64, 203, 203, 203, 203, 203, 64, 64,
+    204, 203, 202, 201, 202, 201, 201, 201, 201, 64, 64, 202, 202, 64, 64,
+    202, 202, 205, 64, 64, 64, 64, 64, 64, 64, 64, 201, 202, 64, 64, 64, 64,
+    203, 203, 64, 203, 203, 203, 201, 201, 64, 64, 206, 206, 206, 206, 206,
+    206, 206, 206, 206, 206, 207, 203, 208, 208, 208, 208, 208, 208, 64, 64,
+    209, 210, 64, 210, 210, 210, 210, 210, 210, 64, 64, 64, 210, 210, 210,
+    64, 210, 210, 210, 210, 64, 64, 64, 210, 210, 64, 210, 64, 210, 210, 64,
+    64, 64, 210, 210, 64, 64, 64, 210, 210, 210, 210, 210, 210, 210, 210,
+    210, 210, 64, 64, 64, 64, 211, 211, 209, 211, 211, 64, 64, 64, 211, 211,
+    211, 64, 211, 211, 211, 212, 64, 64, 210, 64, 64, 64, 64, 64, 64, 211,
+    64, 64, 64, 64, 64, 64, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213,
+    214, 214, 214, 215, 215, 215, 215, 215, 215, 216, 215, 64, 64, 64, 64,
+    64, 217, 218, 218, 218, 64, 219, 219, 219, 219, 219, 219, 219, 219, 64,
+    219, 219, 219, 64, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219,
+    219, 219, 219, 219, 219, 64, 64, 64, 219, 217, 217, 217, 218, 218, 218,
+    218, 64, 217, 217, 217, 64, 217, 217, 217, 220, 64, 64, 64, 64, 64, 64,
+    64, 221, 222, 64, 219, 219, 219, 64, 64, 64, 64, 64, 219, 219, 217, 217,
+    64, 64, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 224, 224, 224,
+    224, 224, 224, 224, 225, 64, 226, 227, 227, 64, 228, 228, 228, 228, 228,
+    228, 228, 228, 64, 228, 228, 228, 64, 228, 228, 228, 228, 228, 228, 228,
+    228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 64, 228, 228, 228,
+    228, 228, 64, 64, 229, 228, 227, 230, 227, 227, 227, 227, 227, 64, 230,
+    227, 227, 64, 227, 227, 226, 231, 64, 64, 64, 64, 64, 64, 64, 227, 227,
+    64, 64, 64, 64, 64, 64, 64, 228, 64, 228, 228, 226, 226, 64, 64, 232,
+    232, 232, 232, 232, 232, 232, 232, 232, 232, 64, 228, 228, 64, 64, 64,
+    64, 64, 64, 233, 234, 234, 64, 235, 235, 235, 235, 235, 235, 235, 235,
+    64, 235, 235, 235, 64, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235,
+    235, 235, 235, 235, 235, 235, 235, 64, 64, 235, 234, 234, 234, 233, 233,
+    233, 233, 64, 234, 234, 234, 64, 234, 234, 234, 236, 235, 64, 64, 64, 64,
+    64, 64, 64, 64, 234, 64, 64, 64, 64, 64, 64, 64, 235, 235, 235, 233, 233,
+    64, 64, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 238, 238, 238,
+    238, 238, 238, 64, 64, 64, 239, 235, 235, 235, 235, 235, 235, 64, 64,
+    240, 240, 64, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+    241, 241, 241, 241, 241, 241, 64, 64, 64, 241, 241, 241, 241, 241, 241,
+    241, 241, 64, 241, 241, 241, 241, 241, 241, 241, 241, 241, 64, 241, 64,
+    64, 64, 64, 242, 64, 64, 64, 64, 240, 240, 240, 243, 243, 243, 64, 243,
+    64, 240, 240, 240, 240, 240, 240, 240, 240, 64, 64, 64, 64, 64, 64, 244,
+    244, 244, 244, 244, 244, 244, 244, 244, 244, 64, 64, 240, 240, 245, 64,
+    64, 64, 64, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
+    246, 246, 246, 246, 247, 246, 246, 247, 247, 247, 247, 248, 248, 249, 64,
+    64, 64, 64, 250, 246, 246, 246, 246, 246, 246, 251, 247, 252, 252, 252,
+    252, 247, 247, 247, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254,
+    254, 253, 253, 64, 64, 64, 64, 64, 255, 255, 64, 255, 64, 64, 255, 255,
+    64, 255, 64, 64, 255, 64, 64, 64, 64, 64, 64, 255, 255, 255, 255, 64,
+    255, 255, 255, 255, 255, 255, 255, 64, 255, 255, 255, 64, 255, 64, 255,
+    64, 64, 255, 255, 64, 255, 255, 255, 255, 256, 255, 255, 256, 256, 256,
+    256, 257, 257, 64, 256, 256, 255, 64, 64, 255, 255, 255, 255, 255, 64,
+    258, 64, 259, 259, 259, 259, 256, 256, 64, 64, 260, 260, 260, 260, 260,
+    260, 260, 260, 260, 260, 64, 64, 255, 255, 255, 255, 261, 262, 262, 262,
+    263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263,
+    263, 262, 263, 262, 262, 262, 264, 264, 262, 262, 262, 262, 262, 262,
+    265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266,
+    266, 266, 266, 266, 266, 266, 262, 264, 262, 264, 262, 267, 268, 269,
+    268, 269, 270, 270, 261, 261, 261, 261, 261, 261, 261, 261, 64, 261, 261,
+    261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 64, 64, 64, 64, 271,
+    272, 273, 274, 273, 273, 273, 273, 273, 272, 272, 272, 272, 273, 270,
+    272, 273, 275, 275, 276, 263, 275, 275, 261, 261, 261, 261, 261, 273,
+    273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 64, 273, 273, 273, 273,
+    273, 273, 273, 273, 273, 273, 273, 273, 64, 262, 262, 262, 262, 262, 262,
+    262, 262, 264, 262, 262, 262, 262, 262, 262, 64, 262, 262, 263, 263, 263,
+    263, 263, 277, 277, 277, 277, 263, 263, 64, 64, 64, 64, 64, 278, 278,
+    278, 278, 278, 278, 278, 278, 278, 278, 278, 279, 279, 280, 280, 280,
+    280, 279, 280, 280, 280, 280, 280, 281, 279, 282, 282, 279, 279, 280,
+    280, 278, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, 284,
+    284, 284, 284, 284, 278, 278, 278, 278, 278, 278, 279, 279, 280, 280,
+    278, 278, 278, 278, 280, 280, 280, 278, 279, 279, 279, 278, 278, 279,
+    279, 279, 279, 279, 279, 279, 278, 278, 278, 280, 280, 280, 280, 278,
+    278, 278, 278, 278, 280, 279, 279, 280, 280, 279, 279, 279, 279, 279,
+    279, 285, 278, 279, 283, 283, 279, 279, 279, 280, 286, 286, 287, 287,
+    287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 64, 287, 64,
+    64, 64, 64, 64, 287, 64, 64, 288, 288, 288, 288, 288, 288, 288, 288, 288,
+    288, 288, 84, 289, 288, 288, 288, 290, 290, 290, 290, 290, 290, 290, 290,
+    291, 291, 291, 291, 291, 291, 291, 291, 292, 292, 292, 292, 292, 292,
+    292, 292, 292, 64, 292, 292, 292, 292, 64, 64, 292, 292, 292, 292, 292,
+    292, 292, 64, 292, 292, 292, 64, 64, 293, 293, 293, 294, 294, 294, 294,
+    294, 294, 294, 294, 294, 295, 295, 295, 295, 295, 295, 295, 295, 295,
+    295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 64, 64, 64, 296,
+    296, 296, 296, 296, 296, 296, 296, 296, 296, 64, 64, 64, 64, 64, 64, 297,
+    297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 64, 64,
+    298, 298, 298, 298, 298, 298, 64, 64, 299, 300, 300, 300, 300, 300, 300,
+    300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
+    301, 301, 300, 302, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303,
+    303, 303, 303, 303, 303, 303, 303, 303, 304, 305, 64, 64, 64, 306, 306,
+    306, 306, 306, 306, 306, 306, 306, 306, 306, 84, 84, 84, 307, 307, 307,
+    306, 306, 306, 306, 306, 306, 306, 306, 64, 64, 64, 64, 64, 64, 64, 308,
+    308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 64, 308, 308,
+    308, 308, 309, 309, 310, 64, 64, 64, 311, 311, 311, 311, 311, 311, 311,
+    311, 311, 311, 312, 312, 313, 84, 84, 64, 314, 314, 314, 314, 314, 314,
+    314, 314, 314, 314, 315, 315, 64, 64, 64, 64, 316, 316, 316, 316, 316,
+    316, 316, 316, 316, 316, 316, 316, 316, 64, 316, 316, 316, 64, 317, 317,
+    64, 64, 64, 64, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
+    318, 319, 319, 320, 319, 319, 319, 319, 319, 319, 319, 320, 320, 320,
+    320, 320, 320, 320, 320, 319, 320, 320, 319, 319, 319, 319, 319, 319,
+    319, 319, 319, 321, 319, 322, 322, 322, 323, 322, 322, 322, 324, 318,
+    325, 64, 64, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 64, 64,
+    64, 64, 64, 64, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 64, 64,
+    64, 64, 64, 64, 328, 328, 66, 66, 328, 66, 329, 328, 328, 328, 328, 330,
+    330, 330, 331, 64, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 64,
+    64, 64, 64, 64, 64, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333,
+    333, 334, 333, 333, 333, 333, 333, 335, 333, 64, 64, 64, 64, 64, 300,
+    300, 300, 300, 300, 300, 64, 64, 336, 336, 336, 336, 336, 336, 336, 336,
+    336, 336, 336, 336, 336, 336, 336, 64, 337, 337, 337, 338, 338, 338, 338,
+    337, 337, 338, 338, 338, 64, 64, 64, 64, 338, 338, 337, 338, 338, 338,
+    338, 338, 338, 339, 340, 341, 64, 64, 64, 64, 342, 64, 64, 64, 343, 343,
+    344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 345, 345, 345, 345,
+    345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 64, 64, 345, 345, 345,
+    345, 345, 64, 64, 64, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346,
+    346, 346, 64, 64, 64, 64, 346, 346, 64, 64, 64, 64, 64, 64, 347, 347,
+    347, 347, 347, 347, 347, 347, 347, 347, 348, 64, 64, 64, 349, 349, 350,
+    350, 350, 350, 350, 350, 350, 350, 351, 351, 351, 351, 351, 351, 351,
+    351, 351, 351, 351, 351, 351, 351, 351, 352, 353, 354, 354, 355, 64, 64,
+    356, 356, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
+    357, 358, 359, 358, 359, 359, 359, 359, 359, 359, 359, 64, 360, 358, 359,
+    358, 358, 359, 359, 359, 359, 359, 359, 359, 359, 358, 358, 358, 358,
+    358, 358, 359, 359, 361, 361, 361, 361, 361, 361, 361, 361, 64, 64, 362,
+    363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 64, 64, 64, 64, 64, 64,
+    364, 364, 364, 364, 364, 364, 364, 365, 364, 364, 364, 364, 364, 364, 64,
+    64, 78, 78, 78, 78, 78, 136, 136, 136, 136, 136, 136, 78, 78, 136, 366,
+    64, 367, 367, 367, 367, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369,
+    369, 369, 369, 369, 369, 369, 370, 368, 367, 367, 367, 367, 367, 368,
+    367, 368, 368, 368, 368, 368, 367, 368, 371, 369, 369, 369, 369, 369,
+    369, 369, 64, 64, 64, 64, 372, 372, 372, 372, 372, 372, 372, 372, 372,
+    372, 373, 373, 373, 373, 373, 373, 373, 374, 374, 374, 374, 374, 374,
+    374, 374, 374, 374, 375, 376, 375, 375, 375, 375, 375, 375, 375, 374,
+    374, 374, 374, 374, 374, 374, 374, 374, 64, 64, 64, 377, 377, 378, 379,
+    379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 378,
+    377, 377, 377, 377, 378, 378, 377, 377, 380, 381, 377, 377, 379, 379,
+    382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 379, 379, 379, 379,
+    379, 379, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383,
+    383, 383, 384, 385, 386, 386, 385, 385, 385, 386, 385, 386, 386, 386,
+    387, 387, 64, 64, 64, 64, 64, 64, 64, 64, 388, 388, 388, 388, 389, 389,
+    389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, 390, 390, 390,
+    390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, 390, 390,
+    391, 392, 64, 64, 64, 393, 393, 393, 393, 393, 394, 394, 394, 394, 394,
+    394, 394, 394, 394, 394, 64, 64, 64, 389, 389, 389, 395, 395, 395, 395,
+    395, 395, 395, 395, 395, 395, 396, 396, 396, 396, 396, 396, 396, 396,
+    396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, 398, 398,
+    399, 399, 399, 399, 399, 399, 399, 399, 78, 78, 78, 84, 400, 136, 136,
+    136, 136, 136, 78, 78, 136, 136, 136, 136, 78, 401, 400, 400, 400, 400,
+    400, 400, 400, 402, 402, 402, 402, 136, 402, 402, 402, 402, 401, 401, 78,
+    402, 402, 64, 78, 78, 64, 64, 64, 64, 64, 64, 41, 41, 41, 41, 41, 41, 62,
+    62, 62, 62, 62, 75, 44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65,
+    65, 44, 44, 44, 44, 65, 65, 65, 65, 65, 41, 41, 41, 41, 41, 403, 41, 41,
+    41, 41, 41, 41, 41, 41, 41, 41, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+    44, 44, 65, 78, 78, 136, 78, 78, 78, 78, 78, 78, 78, 136, 78, 78, 404,
+    405, 136, 406, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+    78, 78, 78, 78, 78, 78, 78, 64, 64, 64, 64, 64, 64, 407, 136, 78, 136,
+    37, 41, 37, 41, 37, 41, 41, 41, 41, 41, 41, 41, 41, 41, 37, 41, 62, 62,
+    62, 62, 62, 62, 62, 62, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62,
+    62, 62, 64, 64, 61, 61, 61, 61, 61, 61, 64, 64, 64, 61, 64, 61, 64, 61,
+    64, 61, 408, 408, 408, 408, 408, 408, 408, 408, 62, 62, 62, 62, 62, 64,
+    62, 62, 61, 61, 61, 61, 408, 63, 62, 63, 63, 63, 62, 62, 62, 64, 62, 62,
+    61, 61, 61, 61, 408, 63, 63, 63, 62, 62, 62, 62, 64, 64, 62, 62, 61, 61,
+    61, 61, 64, 63, 63, 63, 61, 61, 61, 61, 61, 63, 63, 63, 64, 64, 62, 62,
+    62, 64, 62, 62, 61, 61, 61, 61, 408, 63, 63, 64, 409, 409, 409, 409, 409,
+    409, 409, 409, 409, 409, 409, 410, 411, 411, 412, 413, 414, 415, 415,
+    414, 414, 414, 22, 66, 416, 417, 418, 419, 416, 417, 418, 419, 22, 22,
+    22, 66, 22, 22, 22, 22, 420, 421, 422, 423, 424, 425, 426, 21, 427, 428,
+    427, 427, 428, 22, 66, 66, 66, 28, 35, 22, 66, 66, 22, 429, 429, 66, 66,
+    66, 430, 431, 432, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 433, 66,
+    429, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 409, 410, 410, 410, 410,
+    410, 64, 434, 435, 436, 437, 410, 410, 410, 410, 410, 410, 438, 44, 64,
+    64, 33, 438, 438, 438, 438, 438, 439, 439, 433, 431, 432, 440, 438, 33,
+    33, 33, 33, 438, 438, 438, 438, 438, 439, 439, 433, 431, 432, 64, 44, 44,
+    44, 44, 44, 64, 64, 64, 250, 250, 250, 250, 250, 250, 250, 250, 250, 441,
+    250, 250, 23, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 64, 78,
+    78, 400, 400, 78, 78, 78, 78, 400, 400, 400, 78, 78, 366, 366, 366, 366,
+    78, 366, 366, 366, 400, 400, 78, 136, 78, 400, 400, 136, 136, 136, 136,
+    78, 64, 64, 64, 64, 64, 64, 64, 26, 26, 442, 30, 26, 30, 26, 442, 26, 30,
+    34, 442, 442, 442, 34, 34, 442, 442, 442, 443, 26, 442, 30, 26, 433, 442,
+    442, 442, 442, 442, 26, 26, 26, 30, 30, 26, 442, 26, 67, 26, 442, 26, 37,
+    38, 442, 442, 444, 34, 442, 442, 37, 442, 34, 402, 402, 402, 402, 34, 26,
+    26, 34, 34, 442, 442, 445, 433, 433, 433, 433, 442, 34, 34, 34, 34, 26,
+    433, 26, 26, 41, 277, 446, 446, 446, 36, 36, 446, 446, 446, 446, 446,
+    446, 36, 36, 36, 36, 446, 447, 447, 447, 447, 447, 447, 447, 447, 447,
+    447, 447, 447, 448, 448, 448, 448, 447, 447, 448, 448, 448, 448, 448,
+    448, 448, 448, 448, 37, 41, 448, 448, 448, 448, 36, 26, 26, 64, 64, 64,
+    64, 39, 39, 39, 39, 39, 30, 30, 30, 30, 30, 433, 433, 26, 26, 26, 26,
+    433, 26, 26, 433, 26, 26, 433, 26, 26, 26, 26, 26, 26, 26, 433, 26, 26,
+    26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+    26, 26, 26, 433, 433, 26, 26, 39, 26, 39, 26, 26, 26, 26, 26, 26, 26, 26,
+    26, 26, 30, 26, 26, 26, 26, 433, 433, 433, 433, 433, 433, 433, 433, 433,
+    433, 433, 433, 39, 445, 449, 449, 445, 433, 433, 39, 449, 445, 445, 449,
+    445, 445, 433, 39, 433, 449, 439, 450, 433, 449, 445, 433, 433, 433, 449,
+    445, 445, 449, 39, 449, 449, 445, 445, 39, 445, 39, 445, 39, 39, 39, 39,
+    449, 449, 445, 449, 445, 445, 445, 445, 445, 39, 39, 39, 39, 433, 445,
+    433, 445, 449, 449, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445,
+    449, 445, 445, 445, 449, 433, 433, 433, 433, 433, 449, 445, 445, 445,
+    433, 433, 433, 433, 433, 433, 433, 433, 433, 445, 449, 39, 445, 433, 449,
+    449, 449, 449, 445, 445, 449, 449, 433, 433, 449, 449, 445, 445, 449,
+    449, 445, 445, 449, 449, 445, 445, 445, 445, 445, 433, 433, 445, 445,
+    445, 445, 433, 433, 39, 433, 433, 445, 39, 433, 433, 433, 433, 433, 433,
+    433, 433, 445, 445, 433, 39, 445, 445, 445, 433, 433, 433, 433, 433, 445,
+    449, 433, 445, 445, 445, 445, 445, 433, 433, 445, 445, 433, 433, 433,
+    433, 445, 445, 445, 445, 445, 445, 445, 445, 433, 433, 431, 432, 431,
+    432, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 445, 445, 26, 26,
+    26, 26, 26, 26, 26, 451, 452, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+    277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 433,
+    26, 26, 26, 26, 26, 26, 26, 26, 277, 26, 26, 26, 26, 26, 433, 433, 433,
+    433, 433, 433, 433, 433, 433, 26, 26, 26, 26, 433, 433, 26, 26, 26, 26,
+    26, 26, 26, 26, 26, 64, 64, 64, 64, 64, 26, 26, 26, 26, 26, 26, 26, 64,
+    36, 36, 36, 36, 36, 36, 36, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+    33, 33, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453,
+    453, 446, 36, 36, 36, 36, 36, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+    30, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 26, 26, 30, 30, 26, 30, 30,
+    30, 30, 30, 26, 26, 30, 30, 26, 26, 30, 39, 26, 26, 26, 26, 30, 30, 26,
+    26, 30, 39, 26, 26, 26, 26, 30, 30, 30, 26, 26, 30, 26, 26, 30, 30, 26,
+    26, 26, 26, 26, 30, 30, 26, 26, 30, 26, 26, 26, 26, 30, 30, 26, 26, 26,
+    26, 30, 26, 30, 26, 30, 26, 30, 26, 26, 26, 26, 26, 30, 30, 26, 30, 30,
+    30, 26, 30, 30, 30, 30, 26, 30, 30, 26, 39, 26, 26, 26, 26, 26, 26, 30,
+    30, 26, 26, 26, 26, 277, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 30,
+    30, 30, 30, 30, 30, 26, 30, 30, 30, 26, 30, 26, 26, 26, 26, 26, 26, 26,
+    26, 26, 30, 26, 26, 431, 432, 431, 432, 431, 432, 431, 432, 431, 432,
+    431, 432, 431, 432, 36, 36, 446, 446, 446, 446, 446, 446, 446, 446, 446,
+    446, 446, 446, 26, 26, 26, 26, 445, 433, 433, 445, 445, 431, 432, 433,
+    445, 445, 433, 445, 445, 445, 433, 433, 433, 433, 433, 445, 445, 445,
+    445, 433, 433, 433, 433, 433, 445, 445, 445, 433, 433, 433, 445, 445,
+    445, 445, 9, 10, 9, 10, 9, 10, 9, 10, 431, 432, 454, 454, 454, 454, 454,
+    454, 454, 454, 433, 433, 433, 431, 432, 9, 10, 431, 432, 431, 432, 431,
+    432, 431, 432, 431, 432, 433, 433, 445, 445, 445, 445, 445, 445, 433,
+    433, 433, 433, 433, 433, 433, 433, 445, 433, 433, 433, 433, 445, 445,
+    445, 445, 445, 433, 445, 445, 433, 433, 431, 432, 431, 432, 445, 433,
+    433, 433, 433, 445, 433, 445, 445, 445, 433, 433, 445, 445, 433, 433,
+    433, 433, 433, 433, 433, 433, 433, 433, 445, 445, 445, 445, 445, 445,
+    433, 433, 431, 432, 433, 433, 433, 433, 445, 445, 445, 445, 445, 445,
+    445, 445, 445, 445, 445, 433, 445, 445, 445, 445, 433, 433, 445, 433,
+    445, 433, 433, 445, 433, 445, 445, 445, 445, 433, 433, 433, 433, 433,
+    445, 445, 433, 433, 433, 433, 445, 445, 445, 445, 433, 445, 445, 433,
+    433, 445, 445, 433, 433, 433, 433, 445, 445, 445, 445, 445, 445, 445,
+    445, 445, 445, 445, 433, 433, 445, 445, 445, 445, 445, 445, 445, 445,
+    433, 445, 445, 445, 445, 445, 445, 445, 445, 433, 433, 433, 433, 433,
+    445, 433, 445, 433, 433, 433, 445, 445, 445, 445, 445, 433, 433, 433,
+    433, 445, 433, 433, 433, 445, 445, 445, 445, 445, 433, 445, 433, 433,
+    433, 433, 433, 433, 433, 26, 26, 433, 433, 433, 433, 433, 433, 26, 26,
+    26, 26, 26, 26, 26, 26, 30, 30, 30, 26, 26, 26, 26, 64, 64, 26, 26, 26,
+    26, 26, 26, 26, 26, 64, 64, 26, 26, 64, 64, 64, 26, 26, 26, 26, 64, 26,
+    26, 26, 26, 26, 26, 26, 26, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 26,
+    26, 26, 26, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455,
+    455, 455, 455, 64, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
+    456, 456, 456, 456, 64, 37, 41, 37, 37, 37, 41, 41, 37, 41, 37, 41, 37,
+    41, 37, 37, 37, 37, 41, 37, 41, 41, 37, 41, 41, 41, 41, 41, 41, 44, 44,
+    37, 37, 69, 70, 69, 70, 70, 457, 457, 457, 457, 457, 457, 69, 70, 69, 70,
+    458, 458, 458, 69, 70, 64, 64, 64, 64, 64, 459, 459, 459, 459, 460, 459,
+    459, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, 461,
+    461, 64, 461, 64, 64, 64, 64, 64, 461, 64, 64, 462, 462, 462, 462, 462,
+    462, 462, 462, 64, 64, 64, 64, 64, 64, 64, 463, 464, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 64, 64, 465, 77, 77, 77, 77, 77, 77, 77, 77,
+    66, 66, 28, 35, 28, 35, 66, 66, 66, 28, 35, 66, 28, 35, 66, 66, 66, 66,
+    66, 66, 66, 66, 66, 415, 66, 66, 415, 66, 28, 35, 66, 66, 28, 35, 431,
+    432, 431, 432, 431, 432, 431, 432, 66, 66, 66, 66, 66, 45, 66, 66, 415,
+    415, 66, 66, 66, 66, 415, 66, 418, 64, 64, 64, 64, 64, 466, 466, 466,
+    466, 466, 466, 466, 466, 466, 466, 64, 466, 466, 466, 466, 466, 466, 466,
+    466, 466, 64, 64, 64, 64, 466, 466, 466, 466, 466, 466, 64, 64, 467, 467,
+    467, 467, 467, 467, 467, 467, 467, 467, 467, 467, 64, 64, 64, 64, 468,
+    469, 469, 469, 467, 470, 471, 472, 451, 452, 451, 452, 451, 452, 451,
+    452, 451, 452, 467, 467, 451, 452, 451, 452, 451, 452, 451, 452, 473,
+    474, 475, 475, 467, 472, 472, 472, 472, 472, 472, 472, 472, 472, 476,
+    477, 478, 479, 480, 480, 473, 481, 481, 481, 481, 481, 467, 467, 472,
+    472, 472, 470, 471, 469, 467, 26, 64, 482, 482, 482, 482, 482, 482, 482,
+    482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482,
+    482, 64, 64, 483, 483, 484, 484, 485, 485, 482, 473, 486, 486, 486, 486,
+    486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486,
+    469, 481, 487, 487, 486, 64, 64, 64, 64, 64, 488, 488, 488, 488, 488,
+    488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 488, 64, 64, 64,
+    290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 64,
+    489, 489, 490, 490, 490, 490, 489, 489, 489, 489, 489, 489, 489, 489,
+    489, 489, 488, 488, 488, 64, 64, 64, 64, 64, 491, 491, 491, 491, 491,
+    491, 491, 491, 491, 491, 491, 491, 491, 492, 492, 64, 490, 490, 490, 490,
+    490, 490, 490, 490, 490, 490, 489, 489, 489, 489, 489, 489, 493, 493,
+    493, 493, 493, 493, 493, 493, 467, 494, 494, 494, 494, 494, 494, 494,
+    494, 494, 494, 494, 494, 494, 494, 494, 491, 491, 491, 491, 492, 492,
+    492, 489, 489, 494, 494, 494, 494, 494, 494, 494, 489, 489, 489, 489,
+    467, 467, 467, 467, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495,
+    495, 495, 495, 495, 495, 64, 489, 489, 489, 489, 489, 489, 489, 467, 467,
+    467, 467, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 467,
+    467, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496,
+    496, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 498, 498,
+    498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 499, 498, 498, 498,
+    498, 498, 498, 498, 64, 64, 64, 500, 500, 500, 500, 500, 500, 500, 500,
+    500, 500, 500, 500, 500, 500, 500, 64, 501, 501, 501, 501, 501, 501, 501,
+    501, 502, 502, 502, 502, 502, 502, 503, 503, 504, 504, 504, 504, 504,
+    504, 504, 504, 504, 504, 504, 504, 505, 506, 506, 506, 507, 507, 507,
+    507, 507, 507, 507, 507, 507, 507, 504, 504, 64, 64, 64, 64, 72, 75, 72,
+    75, 72, 75, 508, 77, 79, 79, 79, 509, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+    77, 509, 510, 72, 75, 72, 75, 403, 403, 77, 77, 511, 511, 511, 511, 511,
+    511, 511, 511, 511, 511, 511, 511, 511, 511, 512, 512, 512, 512, 512,
+    512, 512, 512, 512, 512, 513, 513, 514, 514, 514, 514, 514, 514, 47, 47,
+    47, 47, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 37, 41,
+    37, 41, 37, 41, 41, 41, 37, 41, 37, 41, 37, 41, 44, 41, 41, 41, 41, 41,
+    41, 41, 41, 37, 41, 37, 41, 37, 37, 41, 45, 515, 515, 37, 41, 37, 41, 42,
+    37, 41, 37, 41, 41, 41, 37, 41, 37, 41, 37, 37, 37, 37, 64, 64, 37, 37,
+    37, 37, 37, 41, 37, 41, 64, 64, 64, 64, 64, 64, 64, 42, 44, 44, 41, 42,
+    42, 42, 42, 42, 516, 516, 517, 516, 516, 516, 518, 516, 516, 516, 516,
+    517, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516,
+    516, 516, 519, 519, 517, 517, 519, 520, 520, 520, 520, 64, 64, 64, 64,
+    521, 521, 521, 521, 521, 521, 277, 277, 250, 444, 64, 64, 64, 64, 64, 64,
+    522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 523, 523,
+    523, 523, 524, 524, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525,
+    525, 525, 525, 525, 525, 525, 525, 525, 524, 524, 524, 524, 524, 524,
+    524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 526, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 527, 527, 528, 528, 528, 528, 528, 528, 528, 528,
+    528, 528, 64, 64, 64, 64, 64, 64, 174, 174, 174, 174, 174, 174, 174, 174,
+    174, 174, 171, 171, 171, 171, 171, 171, 176, 176, 176, 171, 176, 171, 64,
+    64, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 530, 530, 530, 530,
+    530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530,
+    530, 530, 531, 531, 531, 531, 531, 532, 532, 532, 84, 533, 534, 534, 534,
+    534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 535, 535,
+    535, 535, 535, 535, 535, 535, 535, 535, 535, 536, 537, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 64, 538, 290, 290, 290, 290, 290, 64, 64, 64,
+    539, 539, 539, 540, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541,
+    541, 541, 541, 541, 541, 542, 540, 540, 539, 539, 539, 539, 540, 540,
+    539, 540, 540, 540, 543, 544, 544, 544, 544, 544, 544, 544, 544, 544,
+    544, 544, 544, 544, 64, 46, 545, 545, 545, 545, 545, 545, 545, 545, 545,
+    545, 64, 64, 64, 64, 544, 544, 278, 278, 278, 278, 278, 280, 546, 278,
+    283, 283, 278, 278, 278, 278, 278, 64, 547, 547, 547, 547, 547, 547, 547,
+    547, 547, 548, 548, 548, 548, 548, 548, 549, 549, 548, 548, 549, 549,
+    548, 548, 64, 547, 547, 547, 548, 547, 547, 547, 547, 547, 547, 547, 547,
+    548, 549, 64, 64, 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, 64,
+    64, 551, 551, 551, 551, 546, 278, 278, 278, 278, 278, 278, 286, 286, 286,
+    278, 279, 280, 279, 278, 278, 552, 552, 552, 552, 552, 552, 552, 552,
+    553, 552, 553, 553, 554, 552, 552, 553, 553, 552, 552, 552, 552, 552,
+    553, 553, 552, 553, 552, 64, 64, 64, 64, 64, 64, 64, 64, 552, 552, 555,
+    556, 556, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558,
+    559, 559, 558, 558, 560, 560, 557, 561, 561, 558, 562, 64, 64, 292, 292,
+    292, 292, 292, 292, 64, 41, 41, 41, 515, 44, 44, 44, 44, 41, 41, 41, 41,
+    41, 62, 64, 64, 298, 298, 298, 298, 298, 298, 298, 298, 557, 557, 557,
+    558, 558, 559, 558, 558, 559, 558, 558, 560, 558, 562, 64, 64, 563, 563,
+    563, 563, 563, 563, 563, 563, 563, 563, 64, 64, 64, 64, 64, 64, 290, 290,
+    290, 290, 64, 64, 64, 64, 291, 291, 291, 291, 291, 291, 291, 64, 64, 64,
+    64, 291, 291, 291, 291, 291, 291, 291, 291, 291, 64, 64, 64, 64, 564,
+    564, 564, 564, 564, 564, 564, 564, 565, 565, 565, 565, 565, 565, 565,
+    565, 496, 496, 497, 497, 497, 497, 497, 497, 41, 41, 41, 41, 41, 41, 41,
+    64, 64, 64, 64, 83, 83, 83, 83, 83, 64, 64, 64, 64, 64, 110, 566, 110,
+    110, 567, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+    110, 64, 110, 110, 110, 110, 110, 64, 110, 64, 110, 110, 64, 110, 110,
+    64, 110, 110, 126, 126, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568,
+    568, 568, 568, 568, 568, 568, 64, 64, 64, 64, 64, 64, 64, 64, 64, 126,
+    126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 569, 418, 64, 64, 126,
+    126, 126, 126, 126, 126, 126, 126, 126, 126, 116, 119, 64, 64, 58, 58,
+    58, 58, 58, 58, 58, 58, 469, 469, 469, 469, 469, 469, 469, 474, 475, 469,
+    64, 64, 64, 64, 64, 64, 78, 78, 78, 78, 78, 78, 78, 136, 136, 136, 136,
+    136, 136, 136, 77, 77, 469, 473, 473, 570, 570, 474, 475, 474, 475, 474,
+    475, 474, 475, 474, 475, 474, 475, 474, 475, 474, 475, 469, 469, 474,
+    475, 469, 469, 469, 469, 570, 570, 570, 571, 469, 571, 64, 469, 571, 469,
+    469, 473, 451, 452, 451, 452, 451, 452, 572, 469, 469, 573, 574, 575,
+    575, 576, 64, 469, 577, 572, 469, 64, 64, 64, 64, 126, 126, 126, 126,
+    126, 64, 126, 126, 126, 126, 126, 126, 126, 64, 64, 410, 64, 578, 578,
+    579, 580, 579, 578, 578, 581, 582, 578, 583, 584, 585, 584, 584, 586,
+    586, 586, 586, 586, 586, 586, 586, 586, 586, 584, 578, 587, 588, 587,
+    578, 578, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589,
+    589, 589, 589, 589, 589, 589, 581, 578, 582, 590, 591, 590, 592, 592,
+    592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592,
+    592, 592, 581, 588, 582, 588, 581, 582, 593, 594, 595, 593, 593, 596,
+    596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 596, 596, 596, 596,
+    596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 597, 598, 598, 598,
+    598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 64, 64, 64,
+    598, 598, 598, 598, 598, 598, 64, 64, 598, 598, 598, 64, 64, 64, 580,
+    580, 588, 590, 599, 580, 580, 64, 600, 601, 601, 601, 601, 600, 600, 64,
+    64, 602, 602, 602, 26, 30, 64, 64, 603, 603, 603, 603, 603, 603, 603,
+    603, 603, 603, 603, 603, 64, 603, 603, 603, 603, 603, 603, 603, 603, 603,
+    603, 64, 603, 603, 603, 64, 603, 603, 64, 603, 603, 603, 603, 603, 603,
+    603, 64, 64, 603, 603, 603, 64, 64, 64, 64, 64, 84, 66, 84, 64, 64, 64,
+    64, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 64,
+    64, 64, 277, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604,
+    604, 605, 605, 605, 605, 606, 606, 606, 606, 606, 606, 606, 606, 606,
+    606, 606, 606, 606, 606, 606, 606, 606, 605, 605, 606, 64, 64, 64, 26,
+    26, 26, 26, 64, 64, 64, 64, 606, 64, 64, 64, 64, 64, 64, 64, 277, 277,
+    277, 277, 277, 136, 64, 64, 607, 607, 607, 607, 607, 607, 607, 607, 607,
+    607, 607, 607, 607, 64, 64, 64, 608, 608, 608, 608, 608, 608, 608, 608,
+    608, 64, 64, 64, 64, 64, 64, 64, 136, 438, 438, 438, 438, 438, 438, 438,
+    438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 64, 64, 64,
+    64, 609, 609, 609, 609, 609, 609, 609, 609, 610, 610, 610, 610, 64, 64,
+    64, 64, 611, 611, 611, 611, 611, 611, 611, 611, 611, 612, 611, 611, 611,
+    611, 611, 611, 611, 611, 612, 64, 64, 64, 64, 64, 613, 613, 613, 613,
+    613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 614, 614, 614, 614,
+    614, 64, 64, 64, 64, 64, 615, 615, 615, 615, 615, 615, 615, 615, 615,
+    615, 615, 615, 615, 615, 64, 616, 617, 617, 617, 617, 617, 617, 617, 617,
+    617, 617, 617, 617, 64, 64, 64, 64, 618, 619, 619, 619, 619, 619, 64, 64,
+    620, 620, 620, 620, 620, 620, 620, 620, 621, 621, 621, 621, 621, 621,
+    621, 621, 622, 622, 622, 622, 622, 622, 622, 622, 623, 623, 623, 623,
+    623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 64, 64, 624, 624, 624,
+    624, 624, 624, 624, 624, 624, 624, 64, 64, 64, 64, 64, 64, 625, 625, 625,
+    625, 625, 625, 625, 625, 626, 626, 626, 626, 626, 626, 626, 626, 626,
+    626, 626, 626, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 627, 628, 628,
+    628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 64, 628,
+    628, 628, 628, 628, 628, 64, 64, 629, 629, 629, 629, 629, 629, 64, 64,
+    629, 64, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629,
+    629, 629, 629, 629, 629, 629, 629, 64, 629, 629, 64, 64, 64, 629, 64, 64,
+    629, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630,
+    630, 64, 631, 632, 632, 632, 632, 632, 632, 632, 632, 633, 633, 633, 633,
+    633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 634, 634, 635,
+    635, 635, 635, 635, 635, 635, 636, 636, 636, 636, 636, 636, 636, 636,
+    636, 636, 636, 636, 636, 636, 636, 64, 64, 64, 64, 64, 64, 64, 64, 637,
+    637, 637, 637, 637, 637, 637, 637, 637, 638, 638, 638, 638, 638, 638,
+    638, 638, 638, 638, 638, 64, 638, 638, 64, 64, 64, 64, 64, 639, 639, 639,
+    639, 639, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640,
+    640, 640, 641, 641, 641, 641, 641, 641, 64, 64, 64, 642, 643, 643, 643,
+    643, 643, 643, 643, 643, 643, 643, 64, 64, 64, 64, 64, 644, 645, 645,
+    645, 645, 645, 645, 645, 645, 646, 646, 646, 646, 646, 646, 646, 646, 64,
+    64, 64, 64, 647, 647, 646, 646, 647, 647, 647, 647, 647, 647, 647, 647,
+    64, 64, 647, 647, 647, 647, 647, 647, 648, 649, 649, 649, 64, 649, 649,
+    64, 64, 64, 64, 64, 649, 650, 649, 651, 648, 648, 648, 648, 64, 648, 648,
+    648, 64, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648,
+    648, 648, 648, 648, 648, 648, 64, 64, 64, 64, 651, 652, 650, 64, 64, 64,
+    64, 653, 654, 654, 654, 654, 654, 654, 654, 654, 655, 655, 655, 655, 655,
+    655, 655, 655, 655, 64, 64, 64, 64, 64, 64, 64, 656, 656, 656, 656, 656,
+    656, 656, 656, 656, 656, 656, 656, 656, 657, 657, 658, 659, 659, 659,
+    659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 660, 660, 660, 661,
+    661, 661, 661, 661, 661, 661, 661, 662, 661, 661, 661, 661, 661, 661,
+    661, 661, 661, 661, 661, 661, 663, 664, 64, 64, 64, 64, 665, 665, 665,
+    665, 665, 666, 666, 666, 666, 666, 666, 666, 64, 667, 667, 667, 667, 667,
+    667, 667, 667, 667, 667, 667, 667, 667, 667, 64, 64, 64, 668, 668, 668,
+    668, 668, 668, 668, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669,
+    669, 669, 669, 669, 64, 64, 670, 670, 670, 670, 670, 670, 670, 670, 671,
+    671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 64, 64, 64, 64, 64,
+    672, 672, 672, 672, 672, 672, 672, 672, 673, 673, 673, 673, 673, 673,
+    673, 673, 673, 673, 64, 64, 64, 64, 64, 64, 64, 674, 674, 674, 674, 64,
+    64, 64, 64, 675, 675, 675, 675, 675, 675, 675, 676, 676, 676, 676, 676,
+    676, 676, 676, 676, 64, 64, 64, 64, 64, 64, 64, 677, 677, 677, 677, 677,
+    677, 677, 677, 677, 677, 677, 64, 64, 64, 64, 64, 678, 678, 678, 678,
+    678, 678, 678, 678, 678, 678, 678, 64, 64, 64, 64, 64, 64, 64, 679, 679,
+    679, 679, 679, 679, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680,
+    680, 680, 680, 680, 680, 64, 681, 682, 681, 683, 683, 683, 683, 683, 683,
+    683, 683, 683, 683, 683, 683, 683, 682, 682, 682, 682, 682, 682, 682,
+    682, 682, 682, 682, 682, 682, 682, 684, 685, 685, 685, 685, 685, 685,
+    685, 64, 64, 64, 64, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686,
+    686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 687, 687, 687, 687,
+    687, 687, 687, 687, 687, 687, 64, 64, 64, 64, 64, 64, 64, 684, 688, 688,
+    689, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690,
+    689, 689, 689, 688, 688, 688, 688, 689, 689, 691, 692, 693, 693, 694,
+    693, 693, 693, 693, 64, 64, 64, 64, 64, 64, 695, 695, 695, 695, 695, 695,
+    695, 695, 695, 64, 64, 64, 64, 64, 64, 64, 696, 696, 696, 696, 696, 696,
+    696, 696, 696, 696, 64, 64, 64, 64, 64, 64, 697, 697, 697, 698, 698, 698,
+    698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698,
+    698, 698, 698, 699, 699, 699, 699, 699, 700, 699, 699, 699, 699, 699,
+    699, 701, 701, 64, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 703,
+    703, 703, 703, 64, 64, 64, 64, 704, 704, 704, 704, 704, 704, 704, 704,
+    704, 704, 704, 705, 706, 706, 704, 64, 707, 707, 708, 709, 709, 709, 709,
+    709, 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, 708, 708,
+    708, 707, 707, 707, 707, 707, 707, 707, 707, 707, 708, 710, 709, 709,
+    709, 709, 711, 711, 711, 711, 711, 712, 707, 707, 711, 64, 64, 713, 713,
+    713, 713, 713, 713, 713, 713, 713, 713, 709, 711, 709, 711, 711, 711, 64,
+    714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714,
+    714, 714, 714, 714, 714, 714, 64, 64, 64, 715, 715, 715, 715, 715, 715,
+    715, 715, 715, 715, 64, 715, 715, 715, 715, 715, 715, 715, 715, 715, 716,
+    716, 716, 717, 717, 717, 716, 716, 717, 718, 719, 717, 720, 720, 720,
+    720, 720, 720, 64, 64, 721, 721, 721, 721, 721, 721, 721, 64, 721, 64,
+    721, 721, 721, 721, 64, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721,
+    721, 721, 721, 721, 721, 64, 721, 721, 722, 64, 64, 64, 64, 64, 64, 723,
+    723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723,
+    724, 725, 725, 725, 724, 724, 724, 724, 724, 724, 726, 727, 64, 64, 64,
+    64, 64, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 64, 64, 64, 64,
+    64, 64, 729, 729, 730, 730, 64, 731, 731, 731, 731, 731, 731, 731, 731,
+    64, 64, 731, 731, 64, 64, 731, 731, 731, 731, 731, 731, 731, 731, 731,
+    731, 731, 731, 731, 731, 64, 731, 731, 731, 731, 731, 731, 731, 64, 731,
+    731, 64, 731, 731, 731, 731, 731, 64, 64, 732, 731, 730, 730, 729, 730,
+    730, 730, 730, 64, 64, 730, 730, 64, 64, 730, 730, 733, 64, 64, 731, 64,
+    64, 64, 64, 64, 64, 730, 64, 64, 64, 64, 64, 731, 731, 731, 731, 731,
+    730, 730, 64, 64, 734, 734, 734, 734, 734, 734, 734, 64, 64, 64, 735,
+    735, 735, 735, 735, 735, 735, 735, 736, 736, 736, 737, 737, 737, 737,
+    737, 737, 736, 737, 736, 736, 736, 736, 737, 737, 736, 738, 739, 735,
+    735, 740, 735, 741, 741, 741, 741, 741, 741, 741, 741, 741, 741, 64, 64,
+    64, 64, 64, 64, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742,
+    742, 742, 742, 742, 743, 743, 743, 744, 744, 744, 744, 64, 64, 743, 743,
+    743, 743, 744, 744, 743, 745, 746, 747, 747, 747, 747, 747, 747, 747,
+    747, 747, 747, 747, 747, 747, 747, 747, 742, 742, 742, 742, 744, 744, 64,
+    64, 748, 748, 748, 748, 748, 748, 748, 748, 749, 749, 749, 750, 750, 750,
+    750, 750, 750, 750, 750, 749, 749, 750, 749, 751, 750, 752, 752, 752,
+    748, 64, 64, 64, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 64,
+    64, 64, 64, 64, 64, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754,
+    754, 755, 756, 755, 756, 756, 755, 755, 755, 755, 755, 755, 757, 758,
+    759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 64, 64, 64, 64, 64, 64,
+    760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 64, 64, 64, 761, 761,
+    761, 762, 762, 761, 761, 761, 761, 762, 761, 761, 761, 761, 763, 64, 64,
+    64, 64, 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, 765, 765, 766,
+    766, 766, 767, 768, 768, 768, 768, 768, 768, 768, 768, 769, 769, 769,
+    769, 769, 769, 769, 769, 770, 770, 770, 770, 770, 770, 770, 770, 770,
+    770, 771, 771, 771, 771, 771, 771, 771, 771, 771, 64, 64, 64, 64, 64, 64,
+    64, 64, 64, 64, 64, 64, 772, 773, 773, 773, 773, 773, 773, 773, 773, 773,
+    64, 64, 64, 64, 64, 64, 64, 774, 774, 774, 774, 774, 774, 774, 774, 774,
+    774, 64, 64, 64, 64, 64, 64, 775, 775, 775, 775, 775, 775, 775, 775, 775,
+    775, 775, 775, 775, 775, 775, 64, 776, 776, 776, 776, 776, 64, 64, 64,
+    774, 774, 774, 774, 64, 64, 64, 64, 777, 777, 777, 777, 777, 777, 777,
+    777, 777, 777, 777, 777, 777, 777, 777, 64, 778, 778, 778, 778, 778, 778,
+    778, 778, 778, 778, 778, 778, 778, 778, 778, 64, 511, 64, 64, 64, 64, 64,
+    64, 64, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779,
+    779, 779, 64, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 64, 64,
+    64, 64, 781, 781, 782, 782, 782, 782, 782, 782, 782, 782, 782, 782, 782,
+    782, 782, 782, 64, 64, 783, 783, 783, 783, 783, 784, 64, 64, 785, 785,
+    785, 785, 785, 785, 785, 785, 786, 786, 786, 786, 786, 786, 786, 787,
+    787, 787, 787, 787, 788, 788, 788, 788, 789, 789, 789, 789, 787, 788, 64,
+    64, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 64, 791, 791, 791,
+    791, 791, 791, 791, 64, 785, 785, 785, 785, 785, 64, 64, 64, 64, 64, 785,
+    785, 785, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792,
+    792, 64, 64, 64, 792, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793,
+    793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 64, 64, 64,
+    64, 64, 64, 64, 64, 794, 794, 794, 794, 795, 795, 795, 795, 795, 795,
+    795, 795, 795, 795, 795, 795, 795, 486, 482, 64, 64, 64, 64, 64, 64, 796,
+    796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 64, 64, 64, 64, 64,
+    796, 796, 796, 796, 796, 64, 64, 64, 796, 64, 64, 64, 64, 64, 64, 64,
+    796, 796, 64, 64, 797, 798, 799, 800, 410, 410, 410, 410, 64, 64, 64, 64,
+    277, 277, 277, 277, 277, 277, 64, 64, 277, 277, 277, 277, 277, 277, 277,
+    64, 64, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 801,
+    801, 400, 400, 400, 277, 277, 277, 802, 801, 801, 801, 801, 801, 410,
+    410, 410, 410, 410, 410, 410, 410, 136, 136, 136, 136, 136, 136, 136,
+    136, 277, 277, 78, 78, 78, 78, 78, 136, 136, 277, 277, 277, 277, 277,
+    277, 78, 78, 78, 78, 277, 277, 277, 64, 64, 64, 64, 64, 64, 64, 606, 606,
+    803, 803, 803, 606, 64, 64, 521, 521, 64, 64, 64, 64, 64, 64, 442, 442,
+    442, 442, 442, 442, 442, 442, 442, 442, 34, 34, 34, 34, 34, 34, 34, 34,
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, 442, 442,
+    442, 442, 442, 442, 34, 34, 34, 34, 34, 34, 34, 64, 34, 34, 34, 34, 34,
+    34, 442, 64, 442, 442, 64, 64, 442, 64, 64, 442, 442, 64, 64, 442, 442,
+    442, 442, 64, 442, 442, 34, 34, 64, 34, 64, 34, 34, 34, 34, 34, 34, 34,
+    64, 34, 34, 34, 34, 34, 34, 34, 442, 442, 64, 442, 442, 442, 442, 64, 64,
+    442, 442, 442, 442, 442, 442, 442, 442, 64, 442, 442, 442, 442, 442, 442,
+    442, 64, 34, 34, 442, 442, 64, 442, 442, 442, 442, 64, 442, 442, 442,
+    442, 442, 64, 442, 64, 64, 64, 442, 442, 442, 442, 442, 442, 442, 64, 34,
+    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 64, 64, 442, 804, 34, 34, 34,
+    34, 34, 34, 34, 34, 34, 445, 34, 34, 34, 34, 34, 34, 442, 442, 442, 442,
+    442, 442, 442, 442, 442, 804, 34, 34, 34, 34, 34, 34, 34, 34, 34, 445,
+    34, 34, 442, 442, 442, 442, 442, 804, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+    445, 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, 442, 442, 442, 442, 442,
+    804, 34, 445, 34, 34, 34, 34, 34, 34, 34, 34, 442, 34, 64, 64, 805, 805,
+    805, 805, 805, 805, 805, 805, 805, 805, 806, 806, 806, 806, 806, 806,
+    806, 806, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807,
+    807, 807, 807, 806, 806, 806, 806, 807, 807, 807, 807, 807, 807, 807,
+    807, 807, 807, 806, 806, 806, 806, 806, 806, 806, 806, 807, 806, 806,
+    806, 806, 806, 806, 807, 806, 806, 808, 808, 808, 808, 808, 64, 64, 64,
+    64, 64, 64, 64, 807, 807, 807, 807, 807, 64, 807, 807, 807, 807, 807,
+    807, 807, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809,
+    809, 64, 64, 810, 810, 810, 810, 810, 810, 810, 810, 810, 811, 811, 811,
+    811, 811, 811, 811, 64, 126, 126, 126, 126, 64, 126, 126, 126, 64, 126,
+    126, 64, 126, 64, 64, 126, 64, 126, 126, 126, 126, 126, 126, 126, 126,
+    126, 126, 64, 126, 126, 126, 126, 64, 126, 64, 126, 64, 64, 64, 64, 64,
+    64, 126, 64, 64, 64, 64, 126, 64, 126, 64, 126, 64, 126, 126, 126, 64,
+    126, 64, 126, 64, 126, 64, 126, 64, 126, 126, 126, 126, 64, 126, 64, 126,
+    126, 64, 126, 126, 126, 126, 126, 126, 126, 126, 126, 64, 64, 64, 64, 64,
+    126, 126, 126, 64, 126, 126, 126, 113, 113, 64, 64, 64, 64, 64, 64, 64,
+    26, 26, 26, 26, 26, 26, 26, 33, 33, 33, 446, 446, 64, 64, 64, 453, 453,
+    453, 453, 453, 453, 277, 64, 453, 453, 26, 26, 64, 64, 64, 64, 453, 453,
+    453, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 277, 277, 812, 489, 489,
+    64, 64, 64, 64, 64, 489, 489, 489, 64, 64, 64, 64, 64, 489, 64, 64, 64,
+    64, 64, 64, 64, 489, 489, 64, 64, 64, 64, 64, 64, 26, 26, 26, 47, 47, 47,
+    47, 47, 26, 26, 64, 26, 26, 26, 26, 26, 26, 26, 26, 26, 64, 26, 26, 26,
+    26, 64, 64, 64, 64, 64, 64, 64, 26, 26, 26, 26, 26, 64, 64, 64, 496, 496,
+    496, 496, 496, 496, 496, 497, 496, 496, 496, 496, 496, 497, 497, 497,
+    497, 497, 497, 497, 497, 497, 64, 64, 64, 410, 64, 64, 64, 64, 64, 64,
+    410, 410, 410, 410, 410, 410, 410, 410, 565, 565, 565, 565, 565, 565, 64,
+    64,
+};
+
+/* decomposition data */
+static const unsigned short decomp_data[] = {
+    0, 257, 32, 514, 32, 776, 259, 97, 514, 32, 772, 259, 50, 259, 51, 514,
+    32, 769, 258, 956, 514, 32, 807, 259, 49, 259, 111, 772, 49, 8260, 52,
+    772, 49, 8260, 50, 772, 51, 8260, 52, 512, 65, 768, 512, 65, 769, 512,
+    65, 770, 512, 65, 771, 512, 65, 776, 512, 65, 778, 512, 67, 807, 512, 69,
+    768, 512, 69, 769, 512, 69, 770, 512, 69, 776, 512, 73, 768, 512, 73,
+    769, 512, 73, 770, 512, 73, 776, 512, 78, 771, 512, 79, 768, 512, 79,
+    769, 512, 79, 770, 512, 79, 771, 512, 79, 776, 512, 85, 768, 512, 85,
+    769, 512, 85, 770, 512, 85, 776, 512, 89, 769, 512, 97, 768, 512, 97,
+    769, 512, 97, 770, 512, 97, 771, 512, 97, 776, 512, 97, 778, 512, 99,
+    807, 512, 101, 768, 512, 101, 769, 512, 101, 770, 512, 101, 776, 512,
+    105, 768, 512, 105, 769, 512, 105, 770, 512, 105, 776, 512, 110, 771,
+    512, 111, 768, 512, 111, 769, 512, 111, 770, 512, 111, 771, 512, 111,
+    776, 512, 117, 768, 512, 117, 769, 512, 117, 770, 512, 117, 776, 512,
+    121, 769, 512, 121, 776, 512, 65, 772, 512, 97, 772, 512, 65, 774, 512,
+    97, 774, 512, 65, 808, 512, 97, 808, 512, 67, 769, 512, 99, 769, 512, 67,
+    770, 512, 99, 770, 512, 67, 775, 512, 99, 775, 512, 67, 780, 512, 99,
+    780, 512, 68, 780, 512, 100, 780, 512, 69, 772, 512, 101, 772, 512, 69,
+    774, 512, 101, 774, 512, 69, 775, 512, 101, 775, 512, 69, 808, 512, 101,
+    808, 512, 69, 780, 512, 101, 780, 512, 71, 770, 512, 103, 770, 512, 71,
+    774, 512, 103, 774, 512, 71, 775, 512, 103, 775, 512, 71, 807, 512, 103,
+    807, 512, 72, 770, 512, 104, 770, 512, 73, 771, 512, 105, 771, 512, 73,
+    772, 512, 105, 772, 512, 73, 774, 512, 105, 774, 512, 73, 808, 512, 105,
+    808, 512, 73, 775, 514, 73, 74, 514, 105, 106, 512, 74, 770, 512, 106,
+    770, 512, 75, 807, 512, 107, 807, 512, 76, 769, 512, 108, 769, 512, 76,
+    807, 512, 108, 807, 512, 76, 780, 512, 108, 780, 514, 76, 183, 514, 108,
+    183, 512, 78, 769, 512, 110, 769, 512, 78, 807, 512, 110, 807, 512, 78,
+    780, 512, 110, 780, 514, 700, 110, 512, 79, 772, 512, 111, 772, 512, 79,
+    774, 512, 111, 774, 512, 79, 779, 512, 111, 779, 512, 82, 769, 512, 114,
+    769, 512, 82, 807, 512, 114, 807, 512, 82, 780, 512, 114, 780, 512, 83,
+    769, 512, 115, 769, 512, 83, 770, 512, 115, 770, 512, 83, 807, 512, 115,
+    807, 512, 83, 780, 512, 115, 780, 512, 84, 807, 512, 116, 807, 512, 84,
+    780, 512, 116, 780, 512, 85, 771, 512, 117, 771, 512, 85, 772, 512, 117,
+    772, 512, 85, 774, 512, 117, 774, 512, 85, 778, 512, 117, 778, 512, 85,
+    779, 512, 117, 779, 512, 85, 808, 512, 117, 808, 512, 87, 770, 512, 119,
+    770, 512, 89, 770, 512, 121, 770, 512, 89, 776, 512, 90, 769, 512, 122,
+    769, 512, 90, 775, 512, 122, 775, 512, 90, 780, 512, 122, 780, 258, 115,
+    512, 79, 795, 512, 111, 795, 512, 85, 795, 512, 117, 795, 514, 68, 381,
+    514, 68, 382, 514, 100, 382, 514, 76, 74, 514, 76, 106, 514, 108, 106,
+    514, 78, 74, 514, 78, 106, 514, 110, 106, 512, 65, 780, 512, 97, 780,
+    512, 73, 780, 512, 105, 780, 512, 79, 780, 512, 111, 780, 512, 85, 780,
+    512, 117, 780, 512, 220, 772, 512, 252, 772, 512, 220, 769, 512, 252,
+    769, 512, 220, 780, 512, 252, 780, 512, 220, 768, 512, 252, 768, 512,
+    196, 772, 512, 228, 772, 512, 550, 772, 512, 551, 772, 512, 198, 772,
+    512, 230, 772, 512, 71, 780, 512, 103, 780, 512, 75, 780, 512, 107, 780,
+    512, 79, 808, 512, 111, 808, 512, 490, 772, 512, 491, 772, 512, 439, 780,
+    512, 658, 780, 512, 106, 780, 514, 68, 90, 514, 68, 122, 514, 100, 122,
+    512, 71, 769, 512, 103, 769, 512, 78, 768, 512, 110, 768, 512, 197, 769,
+    512, 229, 769, 512, 198, 769, 512, 230, 769, 512, 216, 769, 512, 248,
+    769, 512, 65, 783, 512, 97, 783, 512, 65, 785, 512, 97, 785, 512, 69,
+    783, 512, 101, 783, 512, 69, 785, 512, 101, 785, 512, 73, 783, 512, 105,
+    783, 512, 73, 785, 512, 105, 785, 512, 79, 783, 512, 111, 783, 512, 79,
+    785, 512, 111, 785, 512, 82, 783, 512, 114, 783, 512, 82, 785, 512, 114,
+    785, 512, 85, 783, 512, 117, 783, 512, 85, 785, 512, 117, 785, 512, 83,
+    806, 512, 115, 806, 512, 84, 806, 512, 116, 806, 512, 72, 780, 512, 104,
+    780, 512, 65, 775, 512, 97, 775, 512, 69, 807, 512, 101, 807, 512, 214,
+    772, 512, 246, 772, 512, 213, 772, 512, 245, 772, 512, 79, 775, 512, 111,
+    775, 512, 558, 772, 512, 559, 772, 512, 89, 772, 512, 121, 772, 259, 104,
+    259, 614, 259, 106, 259, 114, 259, 633, 259, 635, 259, 641, 259, 119,
+    259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514,
+    32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661,
+    256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256,
+    59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769,
+    512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937,
+    769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512,
+    949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776,
+    512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946,
+    258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960,
+    258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045,
+    768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512,
+    1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077,
+    768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512,
+    1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046,
+    774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512,
+    1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241,
+    776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512,
+    1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054,
+    776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512,
+    1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091,
+    776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512,
+    1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575,
+    1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652,
+    514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512,
+    1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355,
+    2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364,
+    512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512,
+    2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479,
+    2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620,
+    512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512,
+    2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014,
+    3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285,
+    512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512,
+    3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545,
+    3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762,
+    514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916,
+    4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021,
+    512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512,
+    4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996,
+    4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021,
+    512, 4133, 4142, 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921,
+    6965, 512, 6923, 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965,
+    512, 6972, 6965, 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259,
+    65, 259, 198, 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259,
+    73, 259, 74, 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259,
+    80, 259, 82, 259, 84, 259, 85, 259, 87, 259, 97, 259, 592, 259, 593, 259,
+    7426, 259, 98, 259, 100, 259, 101, 259, 601, 259, 603, 259, 604, 259,
+    103, 259, 107, 259, 109, 259, 331, 259, 111, 259, 596, 259, 7446, 259,
+    7447, 259, 112, 259, 116, 259, 117, 259, 7453, 259, 623, 259, 118, 259,
+    7461, 259, 946, 259, 947, 259, 948, 259, 966, 259, 967, 261, 105, 261,
+    114, 261, 117, 261, 118, 261, 946, 261, 947, 261, 961, 261, 966, 261,
+    967, 259, 1085, 259, 594, 259, 99, 259, 597, 259, 240, 259, 604, 259,
+    102, 259, 607, 259, 609, 259, 613, 259, 616, 259, 617, 259, 618, 259,
+    7547, 259, 669, 259, 621, 259, 7557, 259, 671, 259, 625, 259, 624, 259,
+    626, 259, 627, 259, 628, 259, 629, 259, 632, 259, 642, 259, 643, 259,
+    427, 259, 649, 259, 650, 259, 7452, 259, 651, 259, 652, 259, 122, 259,
+    656, 259, 657, 259, 658, 259, 952, 512, 65, 805, 512, 97, 805, 512, 66,
+    775, 512, 98, 775, 512, 66, 803, 512, 98, 803, 512, 66, 817, 512, 98,
+    817, 512, 199, 769, 512, 231, 769, 512, 68, 775, 512, 100, 775, 512, 68,
+    803, 512, 100, 803, 512, 68, 817, 512, 100, 817, 512, 68, 807, 512, 100,
+    807, 512, 68, 813, 512, 100, 813, 512, 274, 768, 512, 275, 768, 512, 274,
+    769, 512, 275, 769, 512, 69, 813, 512, 101, 813, 512, 69, 816, 512, 101,
+    816, 512, 552, 774, 512, 553, 774, 512, 70, 775, 512, 102, 775, 512, 71,
+    772, 512, 103, 772, 512, 72, 775, 512, 104, 775, 512, 72, 803, 512, 104,
+    803, 512, 72, 776, 512, 104, 776, 512, 72, 807, 512, 104, 807, 512, 72,
+    814, 512, 104, 814, 512, 73, 816, 512, 105, 816, 512, 207, 769, 512, 239,
+    769, 512, 75, 769, 512, 107, 769, 512, 75, 803, 512, 107, 803, 512, 75,
+    817, 512, 107, 817, 512, 76, 803, 512, 108, 803, 512, 7734, 772, 512,
+    7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, 813, 512, 108, 813, 512,
+    77, 769, 512, 109, 769, 512, 77, 775, 512, 109, 775, 512, 77, 803, 512,
+    109, 803, 512, 78, 775, 512, 110, 775, 512, 78, 803, 512, 110, 803, 512,
+    78, 817, 512, 110, 817, 512, 78, 813, 512, 110, 813, 512, 213, 769, 512,
+    245, 769, 512, 213, 776, 512, 245, 776, 512, 332, 768, 512, 333, 768,
+    512, 332, 769, 512, 333, 769, 512, 80, 769, 512, 112, 769, 512, 80, 775,
+    512, 112, 775, 512, 82, 775, 512, 114, 775, 512, 82, 803, 512, 114, 803,
+    512, 7770, 772, 512, 7771, 772, 512, 82, 817, 512, 114, 817, 512, 83,
+    775, 512, 115, 775, 512, 83, 803, 512, 115, 803, 512, 346, 775, 512, 347,
+    775, 512, 352, 775, 512, 353, 775, 512, 7778, 775, 512, 7779, 775, 512,
+    84, 775, 512, 116, 775, 512, 84, 803, 512, 116, 803, 512, 84, 817, 512,
+    116, 817, 512, 84, 813, 512, 116, 813, 512, 85, 804, 512, 117, 804, 512,
+    85, 816, 512, 117, 816, 512, 85, 813, 512, 117, 813, 512, 360, 769, 512,
+    361, 769, 512, 362, 776, 512, 363, 776, 512, 86, 771, 512, 118, 771, 512,
+    86, 803, 512, 118, 803, 512, 87, 768, 512, 119, 768, 512, 87, 769, 512,
+    119, 769, 512, 87, 776, 512, 119, 776, 512, 87, 775, 512, 119, 775, 512,
+    87, 803, 512, 119, 803, 512, 88, 775, 512, 120, 775, 512, 88, 776, 512,
+    120, 776, 512, 89, 775, 512, 121, 775, 512, 90, 770, 512, 122, 770, 512,
+    90, 803, 512, 122, 803, 512, 90, 817, 512, 122, 817, 512, 104, 817, 512,
+    116, 776, 512, 119, 778, 512, 121, 778, 514, 97, 702, 512, 383, 775, 512,
+    65, 803, 512, 97, 803, 512, 65, 777, 512, 97, 777, 512, 194, 769, 512,
+    226, 769, 512, 194, 768, 512, 226, 768, 512, 194, 777, 512, 226, 777,
+    512, 194, 771, 512, 226, 771, 512, 7840, 770, 512, 7841, 770, 512, 258,
+    769, 512, 259, 769, 512, 258, 768, 512, 259, 768, 512, 258, 777, 512,
+    259, 777, 512, 258, 771, 512, 259, 771, 512, 7840, 774, 512, 7841, 774,
+    512, 69, 803, 512, 101, 803, 512, 69, 777, 512, 101, 777, 512, 69, 771,
+    512, 101, 771, 512, 202, 769, 512, 234, 769, 512, 202, 768, 512, 234,
+    768, 512, 202, 777, 512, 234, 777, 512, 202, 771, 512, 234, 771, 512,
+    7864, 770, 512, 7865, 770, 512, 73, 777, 512, 105, 777, 512, 73, 803,
+    512, 105, 803, 512, 79, 803, 512, 111, 803, 512, 79, 777, 512, 111, 777,
+    512, 212, 769, 512, 244, 769, 512, 212, 768, 512, 244, 768, 512, 212,
+    777, 512, 244, 777, 512, 212, 771, 512, 244, 771, 512, 7884, 770, 512,
+    7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, 768, 512, 417, 768,
+    512, 416, 777, 512, 417, 777, 512, 416, 771, 512, 417, 771, 512, 416,
+    803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, 85, 777, 512, 117,
+    777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, 432, 768, 512,
+    431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, 512, 431, 803,
+    512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, 512, 121, 803,
+    512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, 512, 945, 787,
+    512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, 769, 512, 7937,
+    769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, 913, 788, 512,
+    7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, 512, 7944,
+    834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, 768, 512,
+    7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, 917, 788,
+    512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, 512, 951,
+    787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, 769, 512,
+    7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, 919, 788,
+    512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, 512,
+    7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, 768,
+    512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512,
+    7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768, 512, 7993, 768,
+    512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512, 7993, 834, 512, 959,
+    787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768, 512, 8000, 769, 512,
+    8001, 769, 512, 927, 787, 512, 927, 788, 512, 8008, 768, 512, 8009, 768,
+    512, 8008, 769, 512, 8009, 769, 512, 965, 787, 512, 965, 788, 512, 8016,
+    768, 512, 8017, 768, 512, 8016, 769, 512, 8017, 769, 512, 8016, 834, 512,
+    8017, 834, 512, 933, 788, 512, 8025, 768, 512, 8025, 769, 512, 8025, 834,
+    512, 969, 787, 512, 969, 788, 512, 8032, 768, 512, 8033, 768, 512, 8032,
+    769, 512, 8033, 769, 512, 8032, 834, 512, 8033, 834, 512, 937, 787, 512,
+    937, 788, 512, 8040, 768, 512, 8041, 768, 512, 8040, 769, 512, 8041, 769,
+    512, 8040, 834, 512, 8041, 834, 512, 945, 768, 256, 940, 512, 949, 768,
+    256, 941, 512, 951, 768, 256, 942, 512, 953, 768, 256, 943, 512, 959,
+    768, 256, 972, 512, 965, 768, 256, 973, 512, 969, 768, 256, 974, 512,
+    7936, 837, 512, 7937, 837, 512, 7938, 837, 512, 7939, 837, 512, 7940,
+    837, 512, 7941, 837, 512, 7942, 837, 512, 7943, 837, 512, 7944, 837, 512,
+    7945, 837, 512, 7946, 837, 512, 7947, 837, 512, 7948, 837, 512, 7949,
+    837, 512, 7950, 837, 512, 7951, 837, 512, 7968, 837, 512, 7969, 837, 512,
+    7970, 837, 512, 7971, 837, 512, 7972, 837, 512, 7973, 837, 512, 7974,
+    837, 512, 7975, 837, 512, 7976, 837, 512, 7977, 837, 512, 7978, 837, 512,
+    7979, 837, 512, 7980, 837, 512, 7981, 837, 512, 7982, 837, 512, 7983,
+    837, 512, 8032, 837, 512, 8033, 837, 512, 8034, 837, 512, 8035, 837, 512,
+    8036, 837, 512, 8037, 837, 512, 8038, 837, 512, 8039, 837, 512, 8040,
+    837, 512, 8041, 837, 512, 8042, 837, 512, 8043, 837, 512, 8044, 837, 512,
+    8045, 837, 512, 8046, 837, 512, 8047, 837, 512, 945, 774, 512, 945, 772,
+    512, 8048, 837, 512, 945, 837, 512, 940, 837, 512, 945, 834, 512, 8118,
+    837, 512, 913, 774, 512, 913, 772, 512, 913, 768, 256, 902, 512, 913,
+    837, 514, 32, 787, 256, 953, 514, 32, 787, 514, 32, 834, 512, 168, 834,
+    512, 8052, 837, 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134,
+    837, 512, 917, 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837,
+    512, 8127, 768, 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953,
+    772, 512, 970, 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921,
+    774, 512, 921, 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190,
+    769, 512, 8190, 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256,
+    944, 512, 961, 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512,
+    933, 774, 512, 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512,
+    168, 768, 256, 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974,
+    837, 512, 969, 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937,
+    768, 256, 911, 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256,
+    8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32, 257, 32, 258, 32, 258,
+    32, 258, 32, 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46,
+    46, 257, 32, 514, 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245,
+    770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63,
+    33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258, 32, 259, 48, 259,
+    105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259, 57, 259, 43, 259,
+    8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48, 261, 49, 261, 50,
+    261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56, 261, 57, 261, 43,
+    261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261, 101, 261, 111, 261,
+    120, 261, 601, 261, 104, 261, 107, 261, 108, 261, 109, 261, 110, 261,
+    112, 261, 115, 261, 116, 514, 82, 115, 770, 97, 47, 99, 770, 97, 47, 115,
+    262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117, 258, 400, 514,
+    176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104, 262, 295, 262,
+    73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, 80, 262, 81,
+    262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77,
+    262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66, 262, 67, 262,
+    101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258, 1489, 258,
+    1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262, 947, 262, 915,
+    262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262, 105, 262, 106,
+    772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, 49, 48, 772, 49,
+    8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, 8260, 53, 772,
+    51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, 53, 8260, 54,
+    772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, 772, 55, 8260,
+    56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, 514, 73, 86,
+    258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, 514, 73, 88,
+    258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, 258, 68, 258,
+    77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, 118, 258, 118,
+    514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, 105, 514, 105,
+    120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, 108, 258, 99, 258,
+    100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, 8594, 824, 512,
+    8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512, 8707,
+    824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741, 824, 514,
+    8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750, 8750,
+    8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776, 824,
+    512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62, 824,
+    512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512,
+    8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834,
+    824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512,
+    8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829,
+    824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512,
+    8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263,
+    51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48,
+    519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49,
+    54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41,
+    770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770,
+    40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40,
+    49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51,
+    41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41,
+    1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026,
+    40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514,
+    53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48,
+    46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46,
+    770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770,
+    49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40,
+    99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40,
+    103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40,
+    107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40,
+    111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40,
+    115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40,
+    119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65,
+    263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73,
+    263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81,
+    263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89,
+    263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263,
+    103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263,
+    110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263,
+    117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026,
+    8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61,
+    512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, 40863,
+    258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101,
+    258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843,
+    258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992,
+    258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313,
+    258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475,
+    258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805,
+    258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567,
+    258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037,
+    258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308,
+    258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435,
+    258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908,
+    258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085,
+    258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513,
+    258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668,
+    258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247,
+    258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577,
+    258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000,
+    258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399,
+    258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160,
+    258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992,
+    258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780,
+    258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258,
+    258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390,
+    258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892,
+    258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895,
+    258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208,
+    258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789,
+    258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263,
+    258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737,
+    258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899,
+    258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321,
+    258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727,
+    258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575,
+    258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697,
+    258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778,
+    258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258,
+    21313, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512,
+    12367, 12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441,
+    512, 12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381,
+    12441, 512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512,
+    12390, 12441, 512, 12392, 12441, 512, 12399, 12441, 512, 12399, 12442,
+    512, 12402, 12441, 512, 12402, 12442, 512, 12405, 12441, 512, 12405,
+    12442, 512, 12408, 12441, 512, 12408, 12442, 512, 12411, 12441, 512,
+    12411, 12442, 512, 12358, 12441, 514, 32, 12441, 514, 32, 12442, 512,
+    12445, 12441, 521, 12424, 12426, 512, 12459, 12441, 512, 12461, 12441,
+    512, 12463, 12441, 512, 12465, 12441, 512, 12467, 12441, 512, 12469,
+    12441, 512, 12471, 12441, 512, 12473, 12441, 512, 12475, 12441, 512,
+    12477, 12441, 512, 12479, 12441, 512, 12481, 12441, 512, 12484, 12441,
+    512, 12486, 12441, 512, 12488, 12441, 512, 12495, 12441, 512, 12495,
+    12442, 512, 12498, 12441, 512, 12498, 12442, 512, 12501, 12441, 512,
+    12501, 12442, 512, 12504, 12441, 512, 12504, 12442, 512, 12507, 12441,
+    512, 12507, 12442, 512, 12454, 12441, 512, 12527, 12441, 512, 12528,
+    12441, 512, 12529, 12441, 512, 12530, 12441, 512, 12541, 12441, 521,
+    12467, 12488, 258, 4352, 258, 4353, 258, 4522, 258, 4354, 258, 4524, 258,
+    4525, 258, 4355, 258, 4356, 258, 4357, 258, 4528, 258, 4529, 258, 4530,
+    258, 4531, 258, 4532, 258, 4533, 258, 4378, 258, 4358, 258, 4359, 258,
+    4360, 258, 4385, 258, 4361, 258, 4362, 258, 4363, 258, 4364, 258, 4365,
+    258, 4366, 258, 4367, 258, 4368, 258, 4369, 258, 4370, 258, 4449, 258,
+    4450, 258, 4451, 258, 4452, 258, 4453, 258, 4454, 258, 4455, 258, 4456,
+    258, 4457, 258, 4458, 258, 4459, 258, 4460, 258, 4461, 258, 4462, 258,
+    4463, 258, 4464, 258, 4465, 258, 4466, 258, 4467, 258, 4468, 258, 4469,
+    258, 4448, 258, 4372, 258, 4373, 258, 4551, 258, 4552, 258, 4556, 258,
+    4558, 258, 4563, 258, 4567, 258, 4569, 258, 4380, 258, 4573, 258, 4575,
+    258, 4381, 258, 4382, 258, 4384, 258, 4386, 258, 4387, 258, 4391, 258,
+    4393, 258, 4395, 258, 4396, 258, 4397, 258, 4398, 258, 4399, 258, 4402,
+    258, 4406, 258, 4416, 258, 4423, 258, 4428, 258, 4593, 258, 4594, 258,
+    4439, 258, 4440, 258, 4441, 258, 4484, 258, 4485, 258, 4488, 258, 4497,
+    258, 4498, 258, 4500, 258, 4510, 258, 4513, 259, 19968, 259, 20108, 259,
+    19977, 259, 22235, 259, 19978, 259, 20013, 259, 19979, 259, 30002, 259,
+    20057, 259, 19993, 259, 19969, 259, 22825, 259, 22320, 259, 20154, 770,
+    40, 4352, 41, 770, 40, 4354, 41, 770, 40, 4355, 41, 770, 40, 4357, 41,
+    770, 40, 4358, 41, 770, 40, 4359, 41, 770, 40, 4361, 41, 770, 40, 4363,
+    41, 770, 40, 4364, 41, 770, 40, 4366, 41, 770, 40, 4367, 41, 770, 40,
+    4368, 41, 770, 40, 4369, 41, 770, 40, 4370, 41, 1026, 40, 4352, 4449, 41,
+    1026, 40, 4354, 4449, 41, 1026, 40, 4355, 4449, 41, 1026, 40, 4357, 4449,
+    41, 1026, 40, 4358, 4449, 41, 1026, 40, 4359, 4449, 41, 1026, 40, 4361,
+    4449, 41, 1026, 40, 4363, 4449, 41, 1026, 40, 4364, 4449, 41, 1026, 40,
+    4366, 4449, 41, 1026, 40, 4367, 4449, 41, 1026, 40, 4368, 4449, 41, 1026,
+    40, 4369, 4449, 41, 1026, 40, 4370, 4449, 41, 1026, 40, 4364, 4462, 41,
+    1794, 40, 4363, 4457, 4364, 4453, 4523, 41, 1538, 40, 4363, 4457, 4370,
+    4462, 41, 770, 40, 19968, 41, 770, 40, 20108, 41, 770, 40, 19977, 41,
+    770, 40, 22235, 41, 770, 40, 20116, 41, 770, 40, 20845, 41, 770, 40,
+    19971, 41, 770, 40, 20843, 41, 770, 40, 20061, 41, 770, 40, 21313, 41,
+    770, 40, 26376, 41, 770, 40, 28779, 41, 770, 40, 27700, 41, 770, 40,
+    26408, 41, 770, 40, 37329, 41, 770, 40, 22303, 41, 770, 40, 26085, 41,
+    770, 40, 26666, 41, 770, 40, 26377, 41, 770, 40, 31038, 41, 770, 40,
+    21517, 41, 770, 40, 29305, 41, 770, 40, 36001, 41, 770, 40, 31069, 41,
+    770, 40, 21172, 41, 770, 40, 20195, 41, 770, 40, 21628, 41, 770, 40,
+    23398, 41, 770, 40, 30435, 41, 770, 40, 20225, 41, 770, 40, 36039, 41,
+    770, 40, 21332, 41, 770, 40, 31085, 41, 770, 40, 20241, 41, 770, 40,
+    33258, 41, 770, 40, 33267, 41, 263, 21839, 263, 24188, 263, 25991, 263,
+    31631, 778, 80, 84, 69, 519, 50, 49, 519, 50, 50, 519, 50, 51, 519, 50,
+    52, 519, 50, 53, 519, 50, 54, 519, 50, 55, 519, 50, 56, 519, 50, 57, 519,
+    51, 48, 519, 51, 49, 519, 51, 50, 519, 51, 51, 519, 51, 52, 519, 51, 53,
+    263, 4352, 263, 4354, 263, 4355, 263, 4357, 263, 4358, 263, 4359, 263,
+    4361, 263, 4363, 263, 4364, 263, 4366, 263, 4367, 263, 4368, 263, 4369,
+    263, 4370, 519, 4352, 4449, 519, 4354, 4449, 519, 4355, 4449, 519, 4357,
+    4449, 519, 4358, 4449, 519, 4359, 4449, 519, 4361, 4449, 519, 4363, 4449,
+    519, 4364, 4449, 519, 4366, 4449, 519, 4367, 4449, 519, 4368, 4449, 519,
+    4369, 4449, 519, 4370, 4449, 1287, 4366, 4449, 4535, 4352, 4457, 1031,
+    4364, 4462, 4363, 4468, 519, 4363, 4462, 263, 19968, 263, 20108, 263,
+    19977, 263, 22235, 263, 20116, 263, 20845, 263, 19971, 263, 20843, 263,
+    20061, 263, 21313, 263, 26376, 263, 28779, 263, 27700, 263, 26408, 263,
+    37329, 263, 22303, 263, 26085, 263, 26666, 263, 26377, 263, 31038, 263,
+    21517, 263, 29305, 263, 36001, 263, 31069, 263, 21172, 263, 31192, 263,
+    30007, 263, 22899, 263, 36969, 263, 20778, 263, 21360, 263, 27880, 263,
+    38917, 263, 20241, 263, 20889, 263, 27491, 263, 19978, 263, 20013, 263,
+    19979, 263, 24038, 263, 21491, 263, 21307, 263, 23447, 263, 23398, 263,
+    30435, 263, 20225, 263, 36039, 263, 21332, 263, 22812, 519, 51, 54, 519,
+    51, 55, 519, 51, 56, 519, 51, 57, 519, 52, 48, 519, 52, 49, 519, 52, 50,
+    519, 52, 51, 519, 52, 52, 519, 52, 53, 519, 52, 54, 519, 52, 55, 519, 52,
+    56, 519, 52, 57, 519, 53, 48, 514, 49, 26376, 514, 50, 26376, 514, 51,
+    26376, 514, 52, 26376, 514, 53, 26376, 514, 54, 26376, 514, 55, 26376,
+    514, 56, 26376, 514, 57, 26376, 770, 49, 48, 26376, 770, 49, 49, 26376,
+    770, 49, 50, 26376, 522, 72, 103, 778, 101, 114, 103, 522, 101, 86, 778,
+    76, 84, 68, 263, 12450, 263, 12452, 263, 12454, 263, 12456, 263, 12458,
+    263, 12459, 263, 12461, 263, 12463, 263, 12465, 263, 12467, 263, 12469,
+    263, 12471, 263, 12473, 263, 12475, 263, 12477, 263, 12479, 263, 12481,
+    263, 12484, 263, 12486, 263, 12488, 263, 12490, 263, 12491, 263, 12492,
+    263, 12493, 263, 12494, 263, 12495, 263, 12498, 263, 12501, 263, 12504,
+    263, 12507, 263, 12510, 263, 12511, 263, 12512, 263, 12513, 263, 12514,
+    263, 12516, 263, 12518, 263, 12520, 263, 12521, 263, 12522, 263, 12523,
+    263, 12524, 263, 12525, 263, 12527, 263, 12528, 263, 12529, 263, 12530,
+    1034, 12450, 12497, 12540, 12488, 1034, 12450, 12523, 12501, 12449, 1034,
+    12450, 12531, 12506, 12450, 778, 12450, 12540, 12523, 1034, 12452, 12491,
+    12531, 12464, 778, 12452, 12531, 12481, 778, 12454, 12457, 12531, 1290,
+    12456, 12473, 12463, 12540, 12489, 1034, 12456, 12540, 12459, 12540, 778,
+    12458, 12531, 12473, 778, 12458, 12540, 12512, 778, 12459, 12452, 12522,
+    1034, 12459, 12521, 12483, 12488, 1034, 12459, 12525, 12522, 12540, 778,
+    12460, 12525, 12531, 778, 12460, 12531, 12510, 522, 12462, 12460, 778,
+    12462, 12491, 12540, 1034, 12461, 12517, 12522, 12540, 1034, 12462,
+    12523, 12480, 12540, 522, 12461, 12525, 1290, 12461, 12525, 12464, 12521,
+    12512, 1546, 12461, 12525, 12513, 12540, 12488, 12523, 1290, 12461,
+    12525, 12527, 12483, 12488, 778, 12464, 12521, 12512, 1290, 12464, 12521,
+    12512, 12488, 12531, 1290, 12463, 12523, 12476, 12452, 12525, 1034,
+    12463, 12525, 12540, 12493, 778, 12465, 12540, 12473, 778, 12467, 12523,
+    12490, 778, 12467, 12540, 12509, 1034, 12469, 12452, 12463, 12523, 1290,
+    12469, 12531, 12481, 12540, 12512, 1034, 12471, 12522, 12531, 12464, 778,
+    12475, 12531, 12481, 778, 12475, 12531, 12488, 778, 12480, 12540, 12473,
+    522, 12487, 12471, 522, 12489, 12523, 522, 12488, 12531, 522, 12490,
+    12494, 778, 12494, 12483, 12488, 778, 12495, 12452, 12484, 1290, 12497,
+    12540, 12475, 12531, 12488, 778, 12497, 12540, 12484, 1034, 12496, 12540,
+    12524, 12523, 1290, 12500, 12450, 12473, 12488, 12523, 778, 12500, 12463,
+    12523, 522, 12500, 12467, 522, 12499, 12523, 1290, 12501, 12449, 12521,
+    12483, 12489, 1034, 12501, 12451, 12540, 12488, 1290, 12502, 12483,
+    12471, 12455, 12523, 778, 12501, 12521, 12531, 1290, 12504, 12463, 12479,
+    12540, 12523, 522, 12506, 12477, 778, 12506, 12491, 12498, 778, 12504,
+    12523, 12484, 778, 12506, 12531, 12473, 778, 12506, 12540, 12472, 778,
+    12505, 12540, 12479, 1034, 12509, 12452, 12531, 12488, 778, 12508, 12523,
+    12488, 522, 12507, 12531, 778, 12509, 12531, 12489, 778, 12507, 12540,
+    12523, 778, 12507, 12540, 12531, 1034, 12510, 12452, 12463, 12525, 778,
+    12510, 12452, 12523, 778, 12510, 12483, 12495, 778, 12510, 12523, 12463,
+    1290, 12510, 12531, 12471, 12519, 12531, 1034, 12511, 12463, 12525,
+    12531, 522, 12511, 12522, 1290, 12511, 12522, 12496, 12540, 12523, 522,
+    12513, 12460, 1034, 12513, 12460, 12488, 12531, 1034, 12513, 12540,
+    12488, 12523, 778, 12516, 12540, 12489, 778, 12516, 12540, 12523, 778,
+    12518, 12450, 12531, 1034, 12522, 12483, 12488, 12523, 522, 12522, 12521,
+    778, 12523, 12500, 12540, 1034, 12523, 12540, 12502, 12523, 522, 12524,
+    12512, 1290, 12524, 12531, 12488, 12466, 12531, 778, 12527, 12483, 12488,
+    514, 48, 28857, 514, 49, 28857, 514, 50, 28857, 514, 51, 28857, 514, 52,
+    28857, 514, 53, 28857, 514, 54, 28857, 514, 55, 28857, 514, 56, 28857,
+    514, 57, 28857, 770, 49, 48, 28857, 770, 49, 49, 28857, 770, 49, 50,
+    28857, 770, 49, 51, 28857, 770, 49, 52, 28857, 770, 49, 53, 28857, 770,
+    49, 54, 28857, 770, 49, 55, 28857, 770, 49, 56, 28857, 770, 49, 57,
+    28857, 770, 50, 48, 28857, 770, 50, 49, 28857, 770, 50, 50, 28857, 770,
+    50, 51, 28857, 770, 50, 52, 28857, 778, 104, 80, 97, 522, 100, 97, 522,
+    65, 85, 778, 98, 97, 114, 522, 111, 86, 522, 112, 99, 522, 100, 109, 778,
+    100, 109, 178, 778, 100, 109, 179, 522, 73, 85, 522, 24179, 25104, 522,
+    26157, 21644, 522, 22823, 27491, 522, 26126, 27835, 1034, 26666, 24335,
+    20250, 31038, 522, 112, 65, 522, 110, 65, 522, 956, 65, 522, 109, 65,
+    522, 107, 65, 522, 75, 66, 522, 77, 66, 522, 71, 66, 778, 99, 97, 108,
+    1034, 107, 99, 97, 108, 522, 112, 70, 522, 110, 70, 522, 956, 70, 522,
+    956, 103, 522, 109, 103, 522, 107, 103, 522, 72, 122, 778, 107, 72, 122,
+    778, 77, 72, 122, 778, 71, 72, 122, 778, 84, 72, 122, 522, 956, 8467,
+    522, 109, 8467, 522, 100, 8467, 522, 107, 8467, 522, 102, 109, 522, 110,
+    109, 522, 956, 109, 522, 109, 109, 522, 99, 109, 522, 107, 109, 778, 109,
+    109, 178, 778, 99, 109, 178, 522, 109, 178, 778, 107, 109, 178, 778, 109,
+    109, 179, 778, 99, 109, 179, 522, 109, 179, 778, 107, 109, 179, 778, 109,
+    8725, 115, 1034, 109, 8725, 115, 178, 522, 80, 97, 778, 107, 80, 97, 778,
+    77, 80, 97, 778, 71, 80, 97, 778, 114, 97, 100, 1290, 114, 97, 100, 8725,
+    115, 1546, 114, 97, 100, 8725, 115, 178, 522, 112, 115, 522, 110, 115,
+    522, 956, 115, 522, 109, 115, 522, 112, 86, 522, 110, 86, 522, 956, 86,
+    522, 109, 86, 522, 107, 86, 522, 77, 86, 522, 112, 87, 522, 110, 87, 522,
+    956, 87, 522, 109, 87, 522, 107, 87, 522, 77, 87, 522, 107, 937, 522, 77,
+    937, 1034, 97, 46, 109, 46, 522, 66, 113, 522, 99, 99, 522, 99, 100,
+    1034, 67, 8725, 107, 103, 778, 67, 111, 46, 522, 100, 66, 522, 71, 121,
+    522, 104, 97, 522, 72, 80, 522, 105, 110, 522, 75, 75, 522, 75, 77, 522,
+    107, 116, 522, 108, 109, 522, 108, 110, 778, 108, 111, 103, 522, 108,
+    120, 522, 109, 98, 778, 109, 105, 108, 778, 109, 111, 108, 522, 80, 72,
+    1034, 112, 46, 109, 46, 778, 80, 80, 77, 522, 80, 82, 522, 115, 114, 522,
+    83, 118, 522, 87, 98, 778, 86, 8725, 109, 778, 65, 8725, 109, 514, 49,
+    26085, 514, 50, 26085, 514, 51, 26085, 514, 52, 26085, 514, 53, 26085,
+    514, 54, 26085, 514, 55, 26085, 514, 56, 26085, 514, 57, 26085, 770, 49,
+    48, 26085, 770, 49, 49, 26085, 770, 49, 50, 26085, 770, 49, 51, 26085,
+    770, 49, 52, 26085, 770, 49, 53, 26085, 770, 49, 54, 26085, 770, 49, 55,
+    26085, 770, 49, 56, 26085, 770, 49, 57, 26085, 770, 50, 48, 26085, 770,
+    50, 49, 26085, 770, 50, 50, 26085, 770, 50, 51, 26085, 770, 50, 52,
+    26085, 770, 50, 53, 26085, 770, 50, 54, 26085, 770, 50, 55, 26085, 770,
+    50, 56, 26085, 770, 50, 57, 26085, 770, 51, 48, 26085, 770, 51, 49,
+    26085, 778, 103, 97, 108, 259, 1098, 259, 1100, 259, 42863, 259, 294,
+    259, 339, 259, 42791, 259, 43831, 259, 619, 259, 43858, 256, 35912, 256,
+    26356, 256, 36554, 256, 36040, 256, 28369, 256, 20018, 256, 21477, 256,
+    40860, 256, 40860, 256, 22865, 256, 37329, 256, 21895, 256, 22856, 256,
+    25078, 256, 30313, 256, 32645, 256, 34367, 256, 34746, 256, 35064, 256,
+    37007, 256, 27138, 256, 27931, 256, 28889, 256, 29662, 256, 33853, 256,
+    37226, 256, 39409, 256, 20098, 256, 21365, 256, 27396, 256, 29211, 256,
+    34349, 256, 40478, 256, 23888, 256, 28651, 256, 34253, 256, 35172, 256,
+    25289, 256, 33240, 256, 34847, 256, 24266, 256, 26391, 256, 28010, 256,
+    29436, 256, 37070, 256, 20358, 256, 20919, 256, 21214, 256, 25796, 256,
+    27347, 256, 29200, 256, 30439, 256, 32769, 256, 34310, 256, 34396, 256,
+    36335, 256, 38706, 256, 39791, 256, 40442, 256, 30860, 256, 31103, 256,
+    32160, 256, 33737, 256, 37636, 256, 40575, 256, 35542, 256, 22751, 256,
+    24324, 256, 31840, 256, 32894, 256, 29282, 256, 30922, 256, 36034, 256,
+    38647, 256, 22744, 256, 23650, 256, 27155, 256, 28122, 256, 28431, 256,
+    32047, 256, 32311, 256, 38475, 256, 21202, 256, 32907, 256, 20956, 256,
+    20940, 256, 31260, 256, 32190, 256, 33777, 256, 38517, 256, 35712, 256,
+    25295, 256, 27138, 256, 35582, 256, 20025, 256, 23527, 256, 24594, 256,
+    29575, 256, 30064, 256, 21271, 256, 30971, 256, 20415, 256, 24489, 256,
+    19981, 256, 27852, 256, 25976, 256, 32034, 256, 21443, 256, 22622, 256,
+    30465, 256, 33865, 256, 35498, 256, 27578, 256, 36784, 256, 27784, 256,
+    25342, 256, 33509, 256, 25504, 256, 30053, 256, 20142, 256, 20841, 256,
+    20937, 256, 26753, 256, 31975, 256, 33391, 256, 35538, 256, 37327, 256,
+    21237, 256, 21570, 256, 22899, 256, 24300, 256, 26053, 256, 28670, 256,
+    31018, 256, 38317, 256, 39530, 256, 40599, 256, 40654, 256, 21147, 256,
+    26310, 256, 27511, 256, 36706, 256, 24180, 256, 24976, 256, 25088, 256,
+    25754, 256, 28451, 256, 29001, 256, 29833, 256, 31178, 256, 32244, 256,
+    32879, 256, 36646, 256, 34030, 256, 36899, 256, 37706, 256, 21015, 256,
+    21155, 256, 21693, 256, 28872, 256, 35010, 256, 35498, 256, 24265, 256,
+    24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, 20196, 256,
+    22265, 256, 23527, 256, 23994, 256, 24604, 256, 29618, 256, 29801, 256,
+    32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, 256,
+    20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, 256,
+    20698, 256, 23534, 256, 23615, 256, 26009, 256, 27138, 256, 29134, 256,
+    30274, 256, 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, 256,
+    21129, 256, 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, 256,
+    30041, 256, 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, 256,
+    38520, 256, 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, 256,
+    24900, 256, 26647, 256, 29575, 256, 38534, 256, 21033, 256, 21519, 256,
+    23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, 256,
+    30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, 256,
+    21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, 256,
+    38563, 256, 40023, 256, 40607, 256, 26519, 256, 28107, 256, 33256, 256,
+    31435, 256, 31520, 256, 31890, 256, 29376, 256, 28825, 256, 35672, 256,
+    20160, 256, 33590, 256, 21050, 256, 20999, 256, 24230, 256, 25299, 256,
+    31958, 256, 23429, 256, 27934, 256, 26292, 256, 36667, 256, 34892, 256,
+    38477, 256, 35211, 256, 24275, 256, 20800, 256, 21952, 256, 22618, 256,
+    26228, 256, 20958, 256, 29482, 256, 30410, 256, 31036, 256, 31070, 256,
+    31077, 256, 31119, 256, 38742, 256, 31934, 256, 32701, 256, 34322, 256,
+    35576, 256, 36920, 256, 37117, 256, 39151, 256, 39164, 256, 39208, 256,
+    40372, 256, 37086, 256, 38583, 256, 20398, 256, 20711, 256, 20813, 256,
+    21193, 256, 21220, 256, 21329, 256, 21917, 256, 22022, 256, 22120, 256,
+    22592, 256, 22696, 256, 23652, 256, 23662, 256, 24724, 256, 24936, 256,
+    24974, 256, 25074, 256, 25935, 256, 26082, 256, 26257, 256, 26757, 256,
+    28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, 256,
+    30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, 256,
+    31069, 256, 31117, 256, 31118, 256, 31296, 256, 31361, 256, 31680, 256,
+    32244, 256, 32265, 256, 32321, 256, 32626, 256, 32773, 256, 33261, 256,
+    33401, 256, 33401, 256, 33879, 256, 35088, 256, 35222, 256, 35585, 256,
+    35641, 256, 36051, 256, 36104, 256, 36790, 256, 36920, 256, 38627, 256,
+    38911, 256, 38971, 256, 24693, 256, 55376, 57070, 256, 33304, 256, 20006,
+    256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, 21191,
+    256, 21242, 256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, 22618,
+    256, 22707, 256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274,
+    256, 24281, 256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840,
+    256, 24974, 256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, 25628,
+    256, 25682, 256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, 26454,
+    256, 27513, 256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, 28450,
+    256, 28702, 256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, 29482,
+    256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, 30410,
+    256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, 31409,
+    256, 31680, 256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, 32773,
+    256, 33618, 256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, 35222,
+    256, 35519, 256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, 35565,
+    256, 35641, 256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, 37273,
+    256, 37494, 256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, 38911,
+    256, 38923, 256, 38971, 256, 39698, 256, 40860, 256, 55370, 56394, 256,
+    55370, 56388, 256, 55372, 57301, 256, 15261, 256, 16408, 256, 16441, 256,
+    55380, 56905, 256, 55383, 56528, 256, 55391, 57043, 256, 40771, 256,
+    40846, 514, 102, 102, 514, 102, 105, 514, 102, 108, 770, 102, 102, 105,
+    770, 102, 102, 108, 514, 383, 116, 514, 115, 116, 514, 1396, 1398, 514,
+    1396, 1381, 514, 1396, 1387, 514, 1406, 1398, 514, 1396, 1389, 512, 1497,
+    1460, 512, 1522, 1463, 262, 1506, 262, 1488, 262, 1491, 262, 1492, 262,
+    1499, 262, 1500, 262, 1501, 262, 1512, 262, 1514, 262, 43, 512, 1513,
+    1473, 512, 1513, 1474, 512, 64329, 1473, 512, 64329, 1474, 512, 1488,
+    1463, 512, 1488, 1464, 512, 1488, 1468, 512, 1489, 1468, 512, 1490, 1468,
+    512, 1491, 1468, 512, 1492, 1468, 512, 1493, 1468, 512, 1494, 1468, 512,
+    1496, 1468, 512, 1497, 1468, 512, 1498, 1468, 512, 1499, 1468, 512, 1500,
+    1468, 512, 1502, 1468, 512, 1504, 1468, 512, 1505, 1468, 512, 1507, 1468,
+    512, 1508, 1468, 512, 1510, 1468, 512, 1511, 1468, 512, 1512, 1468, 512,
+    1513, 1468, 512, 1514, 1468, 512, 1493, 1465, 512, 1489, 1471, 512, 1499,
+    1471, 512, 1508, 1471, 514, 1488, 1500, 267, 1649, 268, 1649, 267, 1659,
+    268, 1659, 269, 1659, 270, 1659, 267, 1662, 268, 1662, 269, 1662, 270,
+    1662, 267, 1664, 268, 1664, 269, 1664, 270, 1664, 267, 1658, 268, 1658,
+    269, 1658, 270, 1658, 267, 1663, 268, 1663, 269, 1663, 270, 1663, 267,
+    1657, 268, 1657, 269, 1657, 270, 1657, 267, 1700, 268, 1700, 269, 1700,
+    270, 1700, 267, 1702, 268, 1702, 269, 1702, 270, 1702, 267, 1668, 268,
+    1668, 269, 1668, 270, 1668, 267, 1667, 268, 1667, 269, 1667, 270, 1667,
+    267, 1670, 268, 1670, 269, 1670, 270, 1670, 267, 1671, 268, 1671, 269,
+    1671, 270, 1671, 267, 1677, 268, 1677, 267, 1676, 268, 1676, 267, 1678,
+    268, 1678, 267, 1672, 268, 1672, 267, 1688, 268, 1688, 267, 1681, 268,
+    1681, 267, 1705, 268, 1705, 269, 1705, 270, 1705, 267, 1711, 268, 1711,
+    269, 1711, 270, 1711, 267, 1715, 268, 1715, 269, 1715, 270, 1715, 267,
+    1713, 268, 1713, 269, 1713, 270, 1713, 267, 1722, 268, 1722, 267, 1723,
+    268, 1723, 269, 1723, 270, 1723, 267, 1728, 268, 1728, 267, 1729, 268,
+    1729, 269, 1729, 270, 1729, 267, 1726, 268, 1726, 269, 1726, 270, 1726,
+    267, 1746, 268, 1746, 267, 1747, 268, 1747, 267, 1709, 268, 1709, 269,
+    1709, 270, 1709, 267, 1735, 268, 1735, 267, 1734, 268, 1734, 267, 1736,
+    268, 1736, 267, 1655, 267, 1739, 268, 1739, 267, 1733, 268, 1733, 267,
+    1737, 268, 1737, 267, 1744, 268, 1744, 269, 1744, 270, 1744, 269, 1609,
+    270, 1609, 523, 1574, 1575, 524, 1574, 1575, 523, 1574, 1749, 524, 1574,
+    1749, 523, 1574, 1608, 524, 1574, 1608, 523, 1574, 1735, 524, 1574, 1735,
+    523, 1574, 1734, 524, 1574, 1734, 523, 1574, 1736, 524, 1574, 1736, 523,
+    1574, 1744, 524, 1574, 1744, 525, 1574, 1744, 523, 1574, 1609, 524, 1574,
+    1609, 525, 1574, 1609, 267, 1740, 268, 1740, 269, 1740, 270, 1740, 523,
+    1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 523, 1574, 1609, 523, 1574,
+    1610, 523, 1576, 1580, 523, 1576, 1581, 523, 1576, 1582, 523, 1576, 1605,
+    523, 1576, 1609, 523, 1576, 1610, 523, 1578, 1580, 523, 1578, 1581, 523,
+    1578, 1582, 523, 1578, 1605, 523, 1578, 1609, 523, 1578, 1610, 523, 1579,
+    1580, 523, 1579, 1605, 523, 1579, 1609, 523, 1579, 1610, 523, 1580, 1581,
+    523, 1580, 1605, 523, 1581, 1580, 523, 1581, 1605, 523, 1582, 1580, 523,
+    1582, 1581, 523, 1582, 1605, 523, 1587, 1580, 523, 1587, 1581, 523, 1587,
+    1582, 523, 1587, 1605, 523, 1589, 1581, 523, 1589, 1605, 523, 1590, 1580,
+    523, 1590, 1581, 523, 1590, 1582, 523, 1590, 1605, 523, 1591, 1581, 523,
+    1591, 1605, 523, 1592, 1605, 523, 1593, 1580, 523, 1593, 1605, 523, 1594,
+    1580, 523, 1594, 1605, 523, 1601, 1580, 523, 1601, 1581, 523, 1601, 1582,
+    523, 1601, 1605, 523, 1601, 1609, 523, 1601, 1610, 523, 1602, 1581, 523,
+    1602, 1605, 523, 1602, 1609, 523, 1602, 1610, 523, 1603, 1575, 523, 1603,
+    1580, 523, 1603, 1581, 523, 1603, 1582, 523, 1603, 1604, 523, 1603, 1605,
+    523, 1603, 1609, 523, 1603, 1610, 523, 1604, 1580, 523, 1604, 1581, 523,
+    1604, 1582, 523, 1604, 1605, 523, 1604, 1609, 523, 1604, 1610, 523, 1605,
+    1580, 523, 1605, 1581, 523, 1605, 1582, 523, 1605, 1605, 523, 1605, 1609,
+    523, 1605, 1610, 523, 1606, 1580, 523, 1606, 1581, 523, 1606, 1582, 523,
+    1606, 1605, 523, 1606, 1609, 523, 1606, 1610, 523, 1607, 1580, 523, 1607,
+    1605, 523, 1607, 1609, 523, 1607, 1610, 523, 1610, 1580, 523, 1610, 1581,
+    523, 1610, 1582, 523, 1610, 1605, 523, 1610, 1609, 523, 1610, 1610, 523,
+    1584, 1648, 523, 1585, 1648, 523, 1609, 1648, 779, 32, 1612, 1617, 779,
+    32, 1613, 1617, 779, 32, 1614, 1617, 779, 32, 1615, 1617, 779, 32, 1616,
+    1617, 779, 32, 1617, 1648, 524, 1574, 1585, 524, 1574, 1586, 524, 1574,
+    1605, 524, 1574, 1606, 524, 1574, 1609, 524, 1574, 1610, 524, 1576, 1585,
+    524, 1576, 1586, 524, 1576, 1605, 524, 1576, 1606, 524, 1576, 1609, 524,
+    1576, 1610, 524, 1578, 1585, 524, 1578, 1586, 524, 1578, 1605, 524, 1578,
+    1606, 524, 1578, 1609, 524, 1578, 1610, 524, 1579, 1585, 524, 1579, 1586,
+    524, 1579, 1605, 524, 1579, 1606, 524, 1579, 1609, 524, 1579, 1610, 524,
+    1601, 1609, 524, 1601, 1610, 524, 1602, 1609, 524, 1602, 1610, 524, 1603,
+    1575, 524, 1603, 1604, 524, 1603, 1605, 524, 1603, 1609, 524, 1603, 1610,
+    524, 1604, 1605, 524, 1604, 1609, 524, 1604, 1610, 524, 1605, 1575, 524,
+    1605, 1605, 524, 1606, 1585, 524, 1606, 1586, 524, 1606, 1605, 524, 1606,
+    1606, 524, 1606, 1609, 524, 1606, 1610, 524, 1609, 1648, 524, 1610, 1585,
+    524, 1610, 1586, 524, 1610, 1605, 524, 1610, 1606, 524, 1610, 1609, 524,
+    1610, 1610, 525, 1574, 1580, 525, 1574, 1581, 525, 1574, 1582, 525, 1574,
+    1605, 525, 1574, 1607, 525, 1576, 1580, 525, 1576, 1581, 525, 1576, 1582,
+    525, 1576, 1605, 525, 1576, 1607, 525, 1578, 1580, 525, 1578, 1581, 525,
+    1578, 1582, 525, 1578, 1605, 525, 1578, 1607, 525, 1579, 1605, 525, 1580,
+    1581, 525, 1580, 1605, 525, 1581, 1580, 525, 1581, 1605, 525, 1582, 1580,
+    525, 1582, 1605, 525, 1587, 1580, 525, 1587, 1581, 525, 1587, 1582, 525,
+    1587, 1605, 525, 1589, 1581, 525, 1589, 1582, 525, 1589, 1605, 525, 1590,
+    1580, 525, 1590, 1581, 525, 1590, 1582, 525, 1590, 1605, 525, 1591, 1581,
+    525, 1592, 1605, 525, 1593, 1580, 525, 1593, 1605, 525, 1594, 1580, 525,
+    1594, 1605, 525, 1601, 1580, 525, 1601, 1581, 525, 1601, 1582, 525, 1601,
+    1605, 525, 1602, 1581, 525, 1602, 1605, 525, 1603, 1580, 525, 1603, 1581,
+    525, 1603, 1582, 525, 1603, 1604, 525, 1603, 1605, 525, 1604, 1580, 525,
+    1604, 1581, 525, 1604, 1582, 525, 1604, 1605, 525, 1604, 1607, 525, 1605,
+    1580, 525, 1605, 1581, 525, 1605, 1582, 525, 1605, 1605, 525, 1606, 1580,
+    525, 1606, 1581, 525, 1606, 1582, 525, 1606, 1605, 525, 1606, 1607, 525,
+    1607, 1580, 525, 1607, 1605, 525, 1607, 1648, 525, 1610, 1580, 525, 1610,
+    1581, 525, 1610, 1582, 525, 1610, 1605, 525, 1610, 1607, 526, 1574, 1605,
+    526, 1574, 1607, 526, 1576, 1605, 526, 1576, 1607, 526, 1578, 1605, 526,
+    1578, 1607, 526, 1579, 1605, 526, 1579, 1607, 526, 1587, 1605, 526, 1587,
+    1607, 526, 1588, 1605, 526, 1588, 1607, 526, 1603, 1604, 526, 1603, 1605,
+    526, 1604, 1605, 526, 1606, 1605, 526, 1606, 1607, 526, 1610, 1605, 526,
+    1610, 1607, 782, 1600, 1614, 1617, 782, 1600, 1615, 1617, 782, 1600,
+    1616, 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 1593, 1609, 523, 1593,
+    1610, 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 1609, 523, 1587, 1610,
+    523, 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 523, 1581, 1610, 523,
+    1580, 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 1582, 1610, 523, 1589,
+    1609, 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 1610, 523, 1588, 1580,
+    523, 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 523, 1588, 1585, 523,
+    1587, 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 1591, 1609, 524, 1591,
+    1610, 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 1609, 524, 1594, 1610,
+    524, 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 524, 1588, 1610, 524,
+    1581, 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 1580, 1610, 524, 1582,
+    1609, 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 1610, 524, 1590, 1609,
+    524, 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 524, 1588, 1582, 524,
+    1588, 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 1589, 1585, 524, 1590,
+    1585, 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 1582, 525, 1588, 1605,
+    525, 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 526, 1587, 1580, 526,
+    1587, 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 1588, 1581, 526, 1588,
+    1582, 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 1611, 523, 1575, 1611,
+    781, 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 1578, 1581, 1580, 781,
+    1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 1578, 1605, 1580, 781,
+    1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 1580, 1605, 1581, 781,
+    1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 1581, 1605, 1609, 781,
+    1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 1587, 1580, 1609, 780,
+    1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 1587, 1605, 1580, 780,
+    1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 1589, 1581, 1581, 781,
+    1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 1588, 1581, 1605, 781,
+    1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 1588, 1605, 1582, 781,
+    1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 1588, 1605, 1605, 780,
+    1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 1590, 1582, 1605, 780,
+    1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 1591, 1605, 1605, 780,
+    1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 1593, 1605, 1605, 781,
+    1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 1594, 1605, 1605, 780,
+    1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 1601, 1582, 1605, 781,
+    1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 1602, 1605, 1605, 780,
+    1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 1604, 1581, 1609, 781,
+    1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 1604, 1582, 1605, 781,
+    1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 1604, 1605, 1581, 781,
+    1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 1605, 1581, 1610, 781,
+    1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 1605, 1582, 1580, 781,
+    1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 1607, 1605, 1580, 781,
+    1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 1606, 1581, 1609, 780,
+    1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 1606, 1580, 1609, 780,
+    1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 1610, 1605, 1605, 781,
+    1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 1578, 1580, 1610, 780,
+    1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 1578, 1582, 1609, 780,
+    1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 1580, 1605, 1610, 780,
+    1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 1587, 1582, 1609, 780,
+    1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 1590, 1581, 1610, 780,
+    1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 1610, 1581, 1610, 780,
+    1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 1605, 1605, 1610, 780,
+    1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 1602, 1605, 1581, 781,
+    1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 1603, 1605, 1610, 781,
+    1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 1604, 1580, 1605, 780,
+    1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 1606, 1580, 1581, 780,
+    1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 1605, 1580, 1610, 780,
+    1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 1603, 1605, 1605, 781,
+    1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 1587, 1582, 1610, 780,
+    1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 1602, 1604, 1746, 1035,
+    1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 1585, 1035, 1605, 1581,
+    1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 1585, 1587, 1608, 1604,
+    1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 1604, 1605, 779, 1589,
+    1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593,
+    1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 2059, 1580, 1604, 32, 1580,
+    1604, 1575, 1604, 1607, 1035, 1585, 1740, 1575, 1604, 265, 44, 265,
+    12289, 265, 12290, 265, 58, 265, 59, 265, 33, 265, 63, 265, 12310, 265,
+    12311, 265, 8230, 265, 8229, 265, 8212, 265, 8211, 265, 95, 265, 95, 265,
+    40, 265, 41, 265, 123, 265, 125, 265, 12308, 265, 12309, 265, 12304, 265,
+    12305, 265, 12298, 265, 12299, 265, 12296, 265, 12297, 265, 12300, 265,
+    12301, 265, 12302, 265, 12303, 265, 91, 265, 93, 258, 8254, 258, 8254,
+    258, 8254, 258, 8254, 258, 95, 258, 95, 258, 95, 271, 44, 271, 12289,
+    271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 271, 8212, 271, 40, 271, 41,
+    271, 123, 271, 125, 271, 12308, 271, 12309, 271, 35, 271, 38, 271, 42,
+    271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 271, 92, 271, 36, 271, 37,
+    271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 32, 1612, 523, 32, 1613,
+    523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 526, 1600, 1615, 523, 32,
+    1616, 526, 1600, 1616, 523, 32, 1617, 526, 1600, 1617, 523, 32, 1618,
+    526, 1600, 1618, 267, 1569, 267, 1570, 268, 1570, 267, 1571, 268, 1571,
+    267, 1572, 268, 1572, 267, 1573, 268, 1573, 267, 1574, 268, 1574, 269,
+    1574, 270, 1574, 267, 1575, 268, 1575, 267, 1576, 268, 1576, 269, 1576,
+    270, 1576, 267, 1577, 268, 1577, 267, 1578, 268, 1578, 269, 1578, 270,
+    1578, 267, 1579, 268, 1579, 269, 1579, 270, 1579, 267, 1580, 268, 1580,
+    269, 1580, 270, 1580, 267, 1581, 268, 1581, 269, 1581, 270, 1581, 267,
+    1582, 268, 1582, 269, 1582, 270, 1582, 267, 1583, 268, 1583, 267, 1584,
+    268, 1584, 267, 1585, 268, 1585, 267, 1586, 268, 1586, 267, 1587, 268,
+    1587, 269, 1587, 270, 1587, 267, 1588, 268, 1588, 269, 1588, 270, 1588,
+    267, 1589, 268, 1589, 269, 1589, 270, 1589, 267, 1590, 268, 1590, 269,
+    1590, 270, 1590, 267, 1591, 268, 1591, 269, 1591, 270, 1591, 267, 1592,
+    268, 1592, 269, 1592, 270, 1592, 267, 1593, 268, 1593, 269, 1593, 270,
+    1593, 267, 1594, 268, 1594, 269, 1594, 270, 1594, 267, 1601, 268, 1601,
+    269, 1601, 270, 1601, 267, 1602, 268, 1602, 269, 1602, 270, 1602, 267,
+    1603, 268, 1603, 269, 1603, 270, 1603, 267, 1604, 268, 1604, 269, 1604,
+    270, 1604, 267, 1605, 268, 1605, 269, 1605, 270, 1605, 267, 1606, 268,
+    1606, 269, 1606, 270, 1606, 267, 1607, 268, 1607, 269, 1607, 270, 1607,
+    267, 1608, 268, 1608, 267, 1609, 268, 1609, 267, 1610, 268, 1610, 269,
+    1610, 270, 1610, 523, 1604, 1570, 524, 1604, 1570, 523, 1604, 1571, 524,
+    1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 523, 1604, 1575, 524, 1604,
+    1575, 264, 33, 264, 34, 264, 35, 264, 36, 264, 37, 264, 38, 264, 39, 264,
+    40, 264, 41, 264, 42, 264, 43, 264, 44, 264, 45, 264, 46, 264, 47, 264,
+    48, 264, 49, 264, 50, 264, 51, 264, 52, 264, 53, 264, 54, 264, 55, 264,
+    56, 264, 57, 264, 58, 264, 59, 264, 60, 264, 61, 264, 62, 264, 63, 264,
+    64, 264, 65, 264, 66, 264, 67, 264, 68, 264, 69, 264, 70, 264, 71, 264,
+    72, 264, 73, 264, 74, 264, 75, 264, 76, 264, 77, 264, 78, 264, 79, 264,
+    80, 264, 81, 264, 82, 264, 83, 264, 84, 264, 85, 264, 86, 264, 87, 264,
+    88, 264, 89, 264, 90, 264, 91, 264, 92, 264, 93, 264, 94, 264, 95, 264,
+    96, 264, 97, 264, 98, 264, 99, 264, 100, 264, 101, 264, 102, 264, 103,
+    264, 104, 264, 105, 264, 106, 264, 107, 264, 108, 264, 109, 264, 110,
+    264, 111, 264, 112, 264, 113, 264, 114, 264, 115, 264, 116, 264, 117,
+    264, 118, 264, 119, 264, 120, 264, 121, 264, 122, 264, 123, 264, 124,
+    264, 125, 264, 126, 264, 10629, 264, 10630, 272, 12290, 272, 12300, 272,
+    12301, 272, 12289, 272, 12539, 272, 12530, 272, 12449, 272, 12451, 272,
+    12453, 272, 12455, 272, 12457, 272, 12515, 272, 12517, 272, 12519, 272,
+    12483, 272, 12540, 272, 12450, 272, 12452, 272, 12454, 272, 12456, 272,
+    12458, 272, 12459, 272, 12461, 272, 12463, 272, 12465, 272, 12467, 272,
+    12469, 272, 12471, 272, 12473, 272, 12475, 272, 12477, 272, 12479, 272,
+    12481, 272, 12484, 272, 12486, 272, 12488, 272, 12490, 272, 12491, 272,
+    12492, 272, 12493, 272, 12494, 272, 12495, 272, 12498, 272, 12501, 272,
+    12504, 272, 12507, 272, 12510, 272, 12511, 272, 12512, 272, 12513, 272,
+    12514, 272, 12516, 272, 12518, 272, 12520, 272, 12521, 272, 12522, 272,
+    12523, 272, 12524, 272, 12525, 272, 12527, 272, 12531, 272, 12441, 272,
+    12442, 272, 12644, 272, 12593, 272, 12594, 272, 12595, 272, 12596, 272,
+    12597, 272, 12598, 272, 12599, 272, 12600, 272, 12601, 272, 12602, 272,
+    12603, 272, 12604, 272, 12605, 272, 12606, 272, 12607, 272, 12608, 272,
+    12609, 272, 12610, 272, 12611, 272, 12612, 272, 12613, 272, 12614, 272,
+    12615, 272, 12616, 272, 12617, 272, 12618, 272, 12619, 272, 12620, 272,
+    12621, 272, 12622, 272, 12623, 272, 12624, 272, 12625, 272, 12626, 272,
+    12627, 272, 12628, 272, 12629, 272, 12630, 272, 12631, 272, 12632, 272,
+    12633, 272, 12634, 272, 12635, 272, 12636, 272, 12637, 272, 12638, 272,
+    12639, 272, 12640, 272, 12641, 272, 12642, 272, 12643, 264, 162, 264,
+    163, 264, 172, 264, 175, 264, 166, 264, 165, 264, 8361, 272, 9474, 272,
+    8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, 9675, 512, 55300,
+    56473, 55300, 56506, 512, 55300, 56475, 55300, 56506, 512, 55300, 56485,
+    55300, 56506, 512, 55300, 56625, 55300, 56615, 512, 55300, 56626, 55300,
+    56615, 512, 55300, 57159, 55300, 57150, 512, 55300, 57159, 55300, 57175,
+    512, 55301, 56505, 55301, 56506, 512, 55301, 56505, 55301, 56496, 512,
+    55301, 56505, 55301, 56509, 512, 55301, 56760, 55301, 56751, 512, 55301,
+    56761, 55301, 56751, 512, 55348, 56663, 55348, 56677, 512, 55348, 56664,
+    55348, 56677, 512, 55348, 56671, 55348, 56686, 512, 55348, 56671, 55348,
+    56687, 512, 55348, 56671, 55348, 56688, 512, 55348, 56671, 55348, 56689,
+    512, 55348, 56671, 55348, 56690, 512, 55348, 56761, 55348, 56677, 512,
+    55348, 56762, 55348, 56677, 512, 55348, 56763, 55348, 56686, 512, 55348,
+    56764, 55348, 56686, 512, 55348, 56763, 55348, 56687, 512, 55348, 56764,
+    55348, 56687, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262,
+    71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262,
+    79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262,
+    87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262,
+    101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262,
+    108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262,
+    115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262,
+    122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262,
+    72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262,
+    80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262,
+    88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262,
+    102, 262, 103, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262,
+    110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262,
+    117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66,
+    262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74,
+    262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82,
+    262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90,
+    262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262,
+    104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262,
+    111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262,
+    118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 67, 262, 68,
+    262, 71, 262, 74, 262, 75, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83,
+    262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97,
+    262, 98, 262, 99, 262, 100, 262, 102, 262, 104, 262, 105, 262, 106, 262,
+    107, 262, 108, 262, 109, 262, 110, 262, 112, 262, 113, 262, 114, 262,
+    115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262,
+    122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262,
+    72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262,
+    80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262,
+    88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262,
+    102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262,
+    109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262,
+    116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65,
+    262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 74, 262, 75, 262, 76,
+    262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85,
+    262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100,
+    262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107,
+    262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114,
+    262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121,
+    262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 73,
+    262, 74, 262, 75, 262, 76, 262, 77, 262, 79, 262, 83, 262, 84, 262, 85,
+    262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100,
+    262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107,
+    262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114,
+    262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121,
+    262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71,
+    262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79,
+    262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87,
+    262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101,
+    262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108,
+    262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115,
+    262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122,
+    262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72,
+    262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80,
+    262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88,
+    262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262,
+    102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262,
+    109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262,
+    116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65,
+    262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73,
+    262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81,
+    262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89,
+    262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262,
+    103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262,
+    110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262,
+    117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66,
+    262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74,
+    262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82,
+    262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90,
+    262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262,
+    104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262,
+    111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262,
+    118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67,
+    262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75,
+    262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83,
+    262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97,
+    262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262,
+    105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262,
+    112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262,
+    119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68,
+    262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76,
+    262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84,
+    262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98,
+    262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262,
+    106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262,
+    113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262,
+    120, 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, 262, 914, 262,
+    915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262,
+    922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262,
+    929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262,
+    936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262,
+    949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262,
+    956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262,
+    963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262,
+    8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262,
+    913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262,
+    920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262,
+    927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262,
+    934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262,
+    947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262,
+    954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262,
+    961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262,
+    968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262,
+    1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262,
+    918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262,
+    925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262,
+    932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262,
+    945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262,
+    952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262,
+    959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262,
+    966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262,
+    1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262,
+    916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262,
+    923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262,
+    1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262,
+    937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262,
+    950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262,
+    957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262,
+    964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262,
+    1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262,
+    914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262,
+    921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262,
+    928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262,
+    935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262,
+    948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262,
+    955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262,
+    962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262,
+    969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262,
+    982, 262, 988, 262, 989, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52,
+    262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50,
+    262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48,
+    262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56,
+    262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54,
+    262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52,
+    262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 1575, 262, 1576, 262,
+    1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610,
+    262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262,
+    1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579,
+    262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262,
+    1722, 262, 1697, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581,
+    262, 1610, 262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262,
+    1593, 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579,
+    262, 1582, 262, 1590, 262, 1594, 262, 1580, 262, 1581, 262, 1610, 262,
+    1604, 262, 1606, 262, 1587, 262, 1593, 262, 1589, 262, 1602, 262, 1588,
+    262, 1582, 262, 1590, 262, 1594, 262, 1722, 262, 1647, 262, 1576, 262,
+    1580, 262, 1607, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1605,
+    262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262,
+    1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1592, 262, 1594,
+    262, 1646, 262, 1697, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262,
+    1607, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1604,
+    262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262,
+    1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584,
+    262, 1590, 262, 1592, 262, 1594, 262, 1576, 262, 1580, 262, 1583, 262,
+    1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605,
+    262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262,
+    1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590,
+    262, 1592, 262, 1594, 514, 48, 46, 514, 48, 44, 514, 49, 44, 514, 50, 44,
+    514, 51, 44, 514, 52, 44, 514, 53, 44, 514, 54, 44, 514, 55, 44, 514, 56,
+    44, 514, 57, 44, 770, 40, 65, 41, 770, 40, 66, 41, 770, 40, 67, 41, 770,
+    40, 68, 41, 770, 40, 69, 41, 770, 40, 70, 41, 770, 40, 71, 41, 770, 40,
+    72, 41, 770, 40, 73, 41, 770, 40, 74, 41, 770, 40, 75, 41, 770, 40, 76,
+    41, 770, 40, 77, 41, 770, 40, 78, 41, 770, 40, 79, 41, 770, 40, 80, 41,
+    770, 40, 81, 41, 770, 40, 82, 41, 770, 40, 83, 41, 770, 40, 84, 41, 770,
+    40, 85, 41, 770, 40, 86, 41, 770, 40, 87, 41, 770, 40, 88, 41, 770, 40,
+    89, 41, 770, 40, 90, 41, 770, 12308, 83, 12309, 263, 67, 263, 82, 519,
+    67, 68, 519, 87, 90, 266, 65, 266, 66, 266, 67, 266, 68, 266, 69, 266,
+    70, 266, 71, 266, 72, 266, 73, 266, 74, 266, 75, 266, 76, 266, 77, 266,
+    78, 266, 79, 266, 80, 266, 81, 266, 82, 266, 83, 266, 84, 266, 85, 266,
+    86, 266, 87, 266, 88, 266, 89, 266, 90, 522, 72, 86, 522, 77, 86, 522,
+    83, 68, 522, 83, 83, 778, 80, 80, 86, 522, 87, 67, 515, 77, 67, 515, 77,
+    68, 522, 68, 74, 522, 12411, 12363, 522, 12467, 12467, 266, 12469, 266,
+    25163, 266, 23383, 266, 21452, 266, 12487, 266, 20108, 266, 22810, 266,
+    35299, 266, 22825, 266, 20132, 266, 26144, 266, 28961, 266, 26009, 266,
+    21069, 266, 24460, 266, 20877, 266, 26032, 266, 21021, 266, 32066, 266,
+    29983, 266, 36009, 266, 22768, 266, 21561, 266, 28436, 266, 25237, 266,
+    25429, 266, 19968, 266, 19977, 266, 36938, 266, 24038, 266, 20013, 266,
+    21491, 266, 25351, 266, 36208, 266, 25171, 266, 31105, 266, 31354, 266,
+    21512, 266, 28288, 266, 26377, 266, 26376, 266, 30003, 266, 21106, 266,
+    21942, 770, 12308, 26412, 12309, 770, 12308, 19977, 12309, 770, 12308,
+    20108, 12309, 770, 12308, 23433, 12309, 770, 12308, 28857, 12309, 770,
+    12308, 25171, 12309, 770, 12308, 30423, 12309, 770, 12308, 21213, 12309,
+    770, 12308, 25943, 12309, 263, 24471, 263, 21487, 256, 20029, 256, 20024,
+    256, 20033, 256, 55360, 56610, 256, 20320, 256, 20398, 256, 20411, 256,
+    20482, 256, 20602, 256, 20633, 256, 20711, 256, 20687, 256, 13470, 256,
+    55361, 56890, 256, 20813, 256, 20820, 256, 20836, 256, 20855, 256, 55361,
+    56604, 256, 13497, 256, 20839, 256, 20877, 256, 55361, 56651, 256, 20887,
+    256, 20900, 256, 20172, 256, 20908, 256, 20917, 256, 55396, 56799, 256,
+    20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062, 256, 21106, 256,
+    21111, 256, 13589, 256, 21191, 256, 21193, 256, 21220, 256, 21242, 256,
+    21253, 256, 21254, 256, 21271, 256, 21321, 256, 21329, 256, 21338, 256,
+    21363, 256, 21373, 256, 21375, 256, 21375, 256, 21375, 256, 55362, 56876,
+    256, 28784, 256, 21450, 256, 21471, 256, 55362, 57187, 256, 21483, 256,
+    21489, 256, 21510, 256, 21662, 256, 21560, 256, 21576, 256, 21608, 256,
+    21666, 256, 21750, 256, 21776, 256, 21843, 256, 21859, 256, 21892, 256,
+    21892, 256, 21913, 256, 21931, 256, 21939, 256, 21954, 256, 22294, 256,
+    22022, 256, 22295, 256, 22097, 256, 22132, 256, 20999, 256, 22766, 256,
+    22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, 256,
+    22700, 256, 55365, 56548, 256, 22770, 256, 22775, 256, 22790, 256, 22810,
+    256, 22818, 256, 22882, 256, 55365, 57000, 256, 55365, 57066, 256, 23020,
+    256, 23067, 256, 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076,
+    256, 23304, 256, 23358, 256, 23358, 256, 55366, 56776, 256, 23491, 256,
+    23512, 256, 23527, 256, 23539, 256, 55366, 57112, 256, 23551, 256, 23558,
+    256, 24403, 256, 23586, 256, 14209, 256, 23648, 256, 23662, 256, 23744,
+    256, 23693, 256, 55367, 56804, 256, 23875, 256, 55367, 56806, 256, 23918,
+    256, 23915, 256, 23932, 256, 24033, 256, 24034, 256, 14383, 256, 24061,
+    256, 24104, 256, 24125, 256, 24169, 256, 14434, 256, 55368, 56707, 256,
+    14460, 256, 24240, 256, 24243, 256, 24246, 256, 24266, 256, 55400, 57234,
+    256, 24318, 256, 55368, 57137, 256, 55368, 57137, 256, 33281, 256, 24354,
+    256, 24354, 256, 14535, 256, 55372, 57016, 256, 55384, 56794, 256, 24418,
+    256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 24569,
+    256, 24705, 256, 14650, 256, 14620, 256, 24724, 256, 55369, 57044, 256,
+    24775, 256, 24904, 256, 24908, 256, 24910, 256, 24908, 256, 24954, 256,
+    24974, 256, 25010, 256, 24996, 256, 25007, 256, 25054, 256, 25074, 256,
+    25078, 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256,
+    25424, 256, 55370, 57100, 256, 25405, 256, 25340, 256, 25448, 256, 25475,
+    256, 25572, 256, 55370, 57329, 256, 25634, 256, 25541, 256, 25513, 256,
+    14894, 256, 25705, 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256,
+    25935, 256, 25964, 256, 55372, 56330, 256, 26083, 256, 26360, 256, 26185,
+    256, 15129, 256, 26257, 256, 15112, 256, 15076, 256, 20882, 256, 20885,
+    256, 26368, 256, 26268, 256, 32941, 256, 17369, 256, 26391, 256, 26395,
+    256, 26401, 256, 26462, 256, 26451, 256, 55372, 57283, 256, 15177, 256,
+    26618, 256, 26501, 256, 26706, 256, 26757, 256, 55373, 56429, 256, 26766,
+    256, 26655, 256, 26900, 256, 15261, 256, 26946, 256, 27043, 256, 27114,
+    256, 27304, 256, 55373, 56995, 256, 27355, 256, 15384, 256, 27425, 256,
+    55374, 56487, 256, 27476, 256, 15438, 256, 27506, 256, 27551, 256, 27578,
+    256, 27579, 256, 55374, 56973, 256, 55367, 56587, 256, 55374, 57082, 256,
+    27726, 256, 55375, 56508, 256, 27839, 256, 27853, 256, 27751, 256, 27926,
+    256, 27966, 256, 28023, 256, 27969, 256, 28009, 256, 28024, 256, 28037,
+    256, 55375, 56606, 256, 27956, 256, 28207, 256, 28270, 256, 15667, 256,
+    28363, 256, 28359, 256, 55375, 57041, 256, 28153, 256, 28526, 256, 55375,
+    57182, 256, 55375, 57230, 256, 28614, 256, 28729, 256, 28702, 256, 28699,
+    256, 15766, 256, 28746, 256, 28797, 256, 28791, 256, 28845, 256, 55361,
+    56613, 256, 28997, 256, 55376, 56931, 256, 29084, 256, 55376, 57259, 256,
+    29224, 256, 29237, 256, 29264, 256, 55377, 56840, 256, 29312, 256, 29333,
+    256, 55377, 57141, 256, 55378, 56340, 256, 29562, 256, 29579, 256, 16044,
+    256, 29605, 256, 16056, 256, 16056, 256, 29767, 256, 29788, 256, 29809,
+    256, 29829, 256, 29898, 256, 16155, 256, 29988, 256, 55379, 56374, 256,
+    30014, 256, 55379, 56466, 256, 30064, 256, 55368, 56735, 256, 30224, 256,
+    55379, 57249, 256, 55379, 57272, 256, 55380, 56388, 256, 16380, 256,
+    16392, 256, 30452, 256, 55380, 56563, 256, 55380, 56562, 256, 55380,
+    56601, 256, 55380, 56627, 256, 30494, 256, 30495, 256, 30495, 256, 30538,
+    256, 16441, 256, 30603, 256, 16454, 256, 16534, 256, 55381, 56349, 256,
+    30798, 256, 30860, 256, 30924, 256, 16611, 256, 55381, 56870, 256, 31062,
+    256, 55381, 56986, 256, 55381, 57029, 256, 31119, 256, 31211, 256, 16687,
+    256, 31296, 256, 31306, 256, 31311, 256, 55382, 56700, 256, 55382, 56999,
+    256, 55382, 56999, 256, 31470, 256, 16898, 256, 55382, 57259, 256, 31686,
+    256, 31689, 256, 16935, 256, 55383, 56448, 256, 31954, 256, 17056, 256,
+    31976, 256, 31971, 256, 32000, 256, 55383, 57222, 256, 32099, 256, 17153,
+    256, 32199, 256, 32258, 256, 32325, 256, 17204, 256, 55384, 56872, 256,
+    55384, 56903, 256, 17241, 256, 55384, 57049, 256, 32634, 256, 55384,
+    57150, 256, 32661, 256, 32762, 256, 32773, 256, 55385, 56538, 256, 55385,
+    56611, 256, 32864, 256, 55385, 56744, 256, 32880, 256, 55372, 57183, 256,
+    17365, 256, 32946, 256, 33027, 256, 17419, 256, 33086, 256, 23221, 256,
+    55385, 57255, 256, 55385, 57269, 256, 55372, 57235, 256, 55372, 57244,
+    256, 33281, 256, 33284, 256, 36766, 256, 17515, 256, 33425, 256, 33419,
+    256, 33437, 256, 21171, 256, 33457, 256, 33459, 256, 33469, 256, 33510,
+    256, 55386, 57148, 256, 33509, 256, 33565, 256, 33635, 256, 33709, 256,
+    33571, 256, 33725, 256, 33767, 256, 33879, 256, 33619, 256, 33738, 256,
+    33740, 256, 33756, 256, 55387, 56374, 256, 55387, 56683, 256, 55387,
+    56533, 256, 17707, 256, 34033, 256, 34035, 256, 34070, 256, 55388, 57290,
+    256, 34148, 256, 55387, 57132, 256, 17757, 256, 17761, 256, 55387, 57265,
+    256, 55388, 56530, 256, 17771, 256, 34384, 256, 34396, 256, 34407, 256,
+    34409, 256, 34473, 256, 34440, 256, 34574, 256, 34530, 256, 34681, 256,
+    34600, 256, 34667, 256, 34694, 256, 17879, 256, 34785, 256, 34817, 256,
+    17913, 256, 34912, 256, 34915, 256, 55389, 56935, 256, 35031, 256, 35038,
+    256, 17973, 256, 35066, 256, 13499, 256, 55390, 56494, 256, 55390, 56678,
+    256, 18110, 256, 18119, 256, 35488, 256, 35565, 256, 35722, 256, 35925,
+    256, 55391, 56488, 256, 36011, 256, 36033, 256, 36123, 256, 36215, 256,
+    55391, 57135, 256, 55362, 56324, 256, 36299, 256, 36284, 256, 36336, 256,
+    55362, 56542, 256, 36564, 256, 36664, 256, 55393, 56786, 256, 55393,
+    56813, 256, 37012, 256, 37105, 256, 37137, 256, 55393, 57134, 256, 37147,
+    256, 37432, 256, 37591, 256, 37592, 256, 37500, 256, 37881, 256, 37909,
+    256, 55394, 57338, 256, 38283, 256, 18837, 256, 38327, 256, 55395, 56695,
+    256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 55396, 56645, 256,
+    55396, 56858, 256, 19054, 256, 19062, 256, 38880, 256, 55397, 56330, 256,
+    19122, 256, 55397, 56470, 256, 38923, 256, 38923, 256, 38953, 256, 55397,
+    56758, 256, 39138, 256, 19251, 256, 39209, 256, 39335, 256, 39362, 256,
+    39422, 256, 19406, 256, 55398, 57136, 256, 39698, 256, 40000, 256, 40189,
+    256, 19662, 256, 19693, 256, 40295, 256, 55400, 56526, 256, 19704, 256,
+    55400, 56581, 256, 55400, 56846, 256, 55400, 56977, 256, 40635, 256,
+    19798, 256, 40697, 256, 40702, 256, 40709, 256, 40719, 256, 40726, 256,
+    40763, 256, 55401, 56832,
+};
+
+/* index tables for the decomposition data */
+#define DECOMP_SHIFT1 6
+#define DECOMP_SHIFT2 4
+static const unsigned char decomp_index0[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 13, 14, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 16, 5, 5, 5, 5, 17, 18,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 19, 20,
+    5, 5, 5, 5, 5, 21, 22, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    23, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+};
+
+static const unsigned short decomp_index1[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+    14, 0, 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0,
+    25, 0, 26, 27, 0, 0, 0, 0, 0, 28, 0, 0, 29, 30, 31, 32, 33, 34, 35, 0,
+    36, 37, 38, 0, 39, 0, 40, 0, 41, 0, 0, 0, 0, 42, 43, 44, 45, 0, 0, 0, 0,
+    0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 48, 0, 0, 0,
+    0, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 52, 0, 53, 0, 0, 0, 0,
+    0, 0, 54, 55, 0, 0, 0, 0, 0, 56, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 58, 59, 0, 0, 0, 60, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0,
+    0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0,
+    0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 67, 0, 68, 0, 0, 69, 0, 0, 0, 70,
+    71, 72, 73, 74, 75, 76, 77, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 81, 0,
+    82, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 84, 85, 86, 87, 88, 89, 0, 90, 91, 92, 0, 0, 0, 0,
+    93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+    109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
+    123, 124, 125, 126, 127, 128, 129, 130, 0, 131, 132, 133, 134, 0, 0, 0,
+    0, 0, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 146, 0,
+    0, 0, 147, 0, 148, 149, 150, 0, 151, 152, 153, 0, 154, 0, 0, 0, 155, 0,
+    0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157,
+    158, 159, 160, 161, 162, 163, 164, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 0,
+    0, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    171, 0, 0, 0, 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
+    182, 183, 184, 185, 186, 0, 0, 187, 0, 0, 188, 189, 190, 191, 192, 0,
+    193, 194, 195, 196, 197, 0, 198, 0, 0, 0, 199, 200, 201, 202, 203, 204,
+    205, 0, 0, 0, 0, 0, 0, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
+    216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
+    230, 231, 232, 233, 234, 235, 236, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0,
+    0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 243, 244, 245, 246, 247,
+    248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
+    262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 0, 0, 272, 273, 274,
+    275, 276, 277, 278, 279, 280, 281, 282, 283, 0, 284, 285, 286, 287, 288,
+    289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
+    303, 304, 305, 306, 0, 307, 308, 309, 310, 311, 312, 313, 314, 0, 0, 315,
+    0, 316, 0, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328,
+    329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+    343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 345, 346, 0, 0, 0, 0, 0, 0, 0,
+    347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 352, 0, 0, 0, 0, 353, 354, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+    365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378,
+    379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392,
+    393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406,
+    407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 431, 432, 433, 434, 435, 0, 436, 0,
+    0, 437, 0, 0, 0, 0, 0, 0, 438, 439, 440, 441, 442, 443, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 445,
+    446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459,
+    460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473,
+    474, 475, 476, 477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const unsigned short decomp_index2[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+    3, 0, 6, 0, 0, 0, 0, 8, 0, 0, 11, 13, 15, 18, 0, 0, 20, 23, 25, 0, 27,
+    31, 35, 0, 39, 42, 45, 48, 51, 54, 0, 57, 60, 63, 66, 69, 72, 75, 78, 81,
+    0, 84, 87, 90, 93, 96, 99, 0, 0, 102, 105, 108, 111, 114, 0, 0, 117, 120,
+    123, 126, 129, 132, 0, 135, 138, 141, 144, 147, 150, 153, 156, 159, 0,
+    162, 165, 168, 171, 174, 177, 0, 0, 180, 183, 186, 189, 192, 0, 195, 198,
+    201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240,
+    243, 0, 0, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279,
+    282, 285, 288, 291, 294, 297, 300, 303, 0, 0, 306, 309, 312, 315, 318,
+    321, 324, 327, 330, 0, 333, 336, 339, 342, 345, 348, 0, 351, 354, 357,
+    360, 363, 366, 369, 372, 0, 0, 375, 378, 381, 384, 387, 390, 393, 0, 0,
+    396, 399, 402, 405, 408, 411, 0, 0, 414, 417, 420, 423, 426, 429, 432,
+    435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 0, 0, 468, 471,
+    474, 477, 480, 483, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513,
+    516, 519, 522, 525, 528, 531, 534, 537, 539, 542, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 545, 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 551, 554, 557, 560, 563, 566, 569, 572, 575, 578, 581, 584, 587,
+    590, 593, 596, 599, 602, 605, 608, 611, 614, 617, 620, 623, 0, 626, 629,
+    632, 635, 638, 641, 0, 0, 644, 647, 650, 653, 656, 659, 662, 665, 668,
+    671, 674, 677, 680, 683, 686, 689, 0, 0, 692, 695, 698, 701, 704, 707,
+    710, 713, 716, 719, 722, 725, 728, 731, 734, 737, 740, 743, 746, 749,
+    752, 755, 758, 761, 764, 767, 770, 773, 776, 779, 782, 785, 788, 791,
+    794, 797, 0, 0, 800, 803, 0, 0, 0, 0, 0, 0, 806, 809, 812, 815, 818, 821,
+    824, 827, 830, 833, 836, 839, 842, 845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 848, 850, 852, 854, 856, 858, 860, 862, 864, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 866, 869, 872, 875, 878, 881, 0, 0, 884, 886, 888,
+    890, 892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, 0, 905, 0, 0, 0,
+    908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, 0, 930, 0, 933,
+    936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, 969, 972, 975,
+    0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994,
+    996, 998, 0, 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0,
+    1012, 0, 0, 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0,
+    0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, 0, 1045, 1048,
+    1051, 0, 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060,
+    1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0,
+    0, 1078, 1081, 0, 0, 1084, 1087, 1090, 1093, 1096, 1099, 0, 0, 1102,
+    1105, 1108, 1111, 1114, 1117, 0, 0, 1120, 1123, 1126, 1129, 1132, 1135,
+    1138, 1141, 1144, 1147, 1150, 1153, 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 1162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1165, 1168,
+    1171, 1174, 1177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1180, 1183,
+    1186, 1189, 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, 1213, 1216,
+    1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1234,
+    1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, 0, 1246,
+    0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1267,
+    0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1276,
+    1279, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 1285, 1288, 1291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    1294, 0, 0, 0, 0, 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 1306,
+    1309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1312, 1315, 1318, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0,
+    1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1339, 1342, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 1347, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0,
+    0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 1365, 0, 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 0, 0, 0,
+    1383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0,
+    1398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 1407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, 1415, 0,
+    1418, 0, 1421, 0, 0, 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1427, 0, 1430, 0, 0, 1433, 1436, 0, 1439,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    1442, 1444, 1446, 0, 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462,
+    1464, 1466, 1468, 0, 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484,
+    1486, 1488, 1490, 1492, 1494, 1496, 1498, 1500, 1502, 1504, 0, 1506,
+    1508, 1510, 1512, 1514, 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1530,
+    1532, 1534, 1536, 1538, 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554,
+    1556, 1558, 1560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1562, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1564, 1566, 1568, 1570,
+    1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, 1588, 1590, 1592, 1594,
+    1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, 1612, 1614, 1616, 1618,
+    1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, 1636, 1638, 1641, 1644,
+    1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680,
+    1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716,
+    1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752,
+    1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788,
+    1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824,
+    1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860,
+    1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896,
+    1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932,
+    1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968,
+    1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004,
+    2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040,
+    2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076,
+    2079, 2082, 2085, 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106,
+    2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142,
+    2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178,
+    2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214,
+    2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250,
+    2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286,
+    2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322,
+    2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358,
+    2361, 2364, 2367, 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385,
+    2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421,
+    2424, 2427, 2430, 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454,
+    2457, 0, 0, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487,
+    2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523,
+    2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559,
+    2562, 2565, 2568, 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0,
+    2592, 2595, 2598, 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0,
+    2622, 0, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652,
+    2655, 2658, 2661, 2664, 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686,
+    2689, 2691, 2694, 2696, 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714,
+    2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750,
+    2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786,
+    2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822,
+    2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858,
+    2861, 2864, 2867, 0, 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890,
+    2893, 2895, 2898, 2901, 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922,
+    2924, 2927, 2929, 2932, 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952,
+    2955, 2958, 2961, 2964, 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984,
+    2987, 2989, 2992, 2995, 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018,
+    3020, 0, 0, 3022, 3025, 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045,
+    3047, 3050, 3052, 0, 3055, 3057, 3059, 3061, 3063, 3065, 3067, 3069,
+    3071, 3073, 3075, 0, 0, 0, 0, 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0,
+    3091, 0, 0, 0, 3093, 3096, 0, 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0,
+    0, 0, 0, 0, 0, 0, 0, 3113, 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 3122, 0, 0, 0, 0, 0, 0, 0, 3127, 3129, 3131, 0, 0, 3133, 3135,
+    3137, 3139, 3141, 3143, 3145, 3147, 3149, 3151, 3153, 3155, 3157, 3159,
+    3161, 3163, 3165, 3167, 3169, 3171, 3173, 3175, 3177, 3179, 3181, 3183,
+    3185, 0, 3187, 3189, 3191, 3193, 3195, 3197, 3199, 3201, 3203, 3205,
+    3207, 3209, 3211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3213, 0, 0, 0, 0, 0,
+    0, 0, 3216, 3220, 3224, 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244,
+    3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0,
+    3267, 3269, 3271, 3273, 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289,
+    0, 3291, 0, 3293, 3295, 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309,
+    3311, 3313, 3315, 3317, 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0,
+    0, 0, 0, 3335, 3337, 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349,
+    3353, 3358, 3362, 3366, 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398,
+    3402, 3406, 3409, 3411, 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438,
+    3440, 3443, 3447, 3449, 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469,
+    3472, 3476, 3481, 3484, 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    3505, 3508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3514, 3517, 3520, 0, 0, 0, 0,
+    3523, 0, 0, 0, 0, 3526, 0, 0, 3529, 0, 0, 0, 0, 0, 0, 0, 3532, 0, 3535,
+    0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, 0, 3561, 0, 0, 0, 0, 0,
+    0, 3564, 0, 3567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579,
+    3582, 0, 0, 3585, 3588, 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600,
+    0, 0, 3603, 3606, 0, 0, 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 3615, 3618, 3621, 3624, 3627, 3630, 3633, 3636, 0, 0,
+    0, 0, 0, 0, 3639, 3642, 3645, 3648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    3651, 3653, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667,
+    3669, 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700,
+    3703, 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747,
+    3752, 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803,
+    3806, 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844,
+    3848, 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892,
+    3896, 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940,
+    3944, 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980,
+    3982, 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004,
+    4006, 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028,
+    4030, 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052,
+    4054, 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0,
+    0, 0, 4083, 4087, 4090, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097,
+    4099, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4101, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 4105, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 4107, 4109, 4111, 4113, 4115, 4117, 4119, 4121,
+    4123, 4125, 4127, 4129, 4131, 4133, 4135, 4137, 4139, 4141, 4143, 4145,
+    4147, 4149, 4151, 4153, 4155, 4157, 4159, 4161, 4163, 4165, 4167, 4169,
+    4171, 4173, 4175, 4177, 4179, 4181, 4183, 4185, 4187, 4189, 4191, 4193,
+    4195, 4197, 4199, 4201, 4203, 4205, 4207, 4209, 4211, 4213, 4215, 4217,
+    4219, 4221, 4223, 4225, 4227, 4229, 4231, 4233, 4235, 4237, 4239, 4241,
+    4243, 4245, 4247, 4249, 4251, 4253, 4255, 4257, 4259, 4261, 4263, 4265,
+    4267, 4269, 4271, 4273, 4275, 4277, 4279, 4281, 4283, 4285, 4287, 4289,
+    4291, 4293, 4295, 4297, 4299, 4301, 4303, 4305, 4307, 4309, 4311, 4313,
+    4315, 4317, 4319, 4321, 4323, 4325, 4327, 4329, 4331, 4333, 4335, 4337,
+    4339, 4341, 4343, 4345, 4347, 4349, 4351, 4353, 4355, 4357, 4359, 4361,
+    4363, 4365, 4367, 4369, 4371, 4373, 4375, 4377, 4379, 4381, 4383, 4385,
+    4387, 4389, 4391, 4393, 4395, 4397, 4399, 4401, 4403, 4405, 4407, 4409,
+    4411, 4413, 4415, 4417, 4419, 4421, 4423, 4425, 4427, 4429, 4431, 4433,
+    4435, 4437, 4439, 4441, 4443, 4445, 4447, 4449, 4451, 4453, 4455, 4457,
+    4459, 4461, 4463, 4465, 4467, 4469, 4471, 4473, 4475, 4477, 4479, 4481,
+    4483, 4485, 4487, 4489, 4491, 4493, 4495, 4497, 4499, 4501, 4503, 4505,
+    4507, 4509, 4511, 4513, 4515, 4517, 4519, 4521, 4523, 4525, 4527, 4529,
+    4531, 4533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, 4541, 4543, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, 4548, 0, 4551, 0,
+    4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, 4572, 0, 4575, 0,
+    4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, 4590, 4593, 0,
+    4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, 0, 0, 0, 0, 0,
+    0, 4620, 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0,
+    4653, 0, 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674,
+    0, 4677, 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0,
+    4698, 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716,
+    4719, 4722, 0, 0, 0, 4725, 4728, 0, 4731, 4733, 4735, 4737, 4739, 4741,
+    4743, 4745, 4747, 4749, 4751, 4753, 4755, 4757, 4759, 4761, 4763, 4765,
+    4767, 4769, 4771, 4773, 4775, 4777, 4779, 4781, 4783, 4785, 4787, 4789,
+    4791, 4793, 4795, 4797, 4799, 4801, 4803, 4805, 4807, 4809, 4811, 4813,
+    4815, 4817, 4819, 4821, 4823, 4825, 4827, 4829, 4831, 4833, 4835, 4837,
+    4839, 4841, 4843, 4845, 4847, 4849, 4851, 4853, 4855, 4857, 4859, 4861,
+    4863, 4865, 4867, 4869, 4871, 4873, 4875, 4877, 4879, 4881, 4883, 4885,
+    4887, 4889, 4891, 4893, 4895, 4897, 4899, 4901, 4903, 4905, 4907, 4909,
+    4911, 4913, 4915, 4917, 0, 0, 0, 4919, 4921, 4923, 4925, 4927, 4929,
+    4931, 4933, 4935, 4937, 4939, 4941, 4943, 4945, 4947, 4951, 4955, 4959,
+    4963, 4967, 4971, 4975, 4979, 4983, 4987, 4991, 4995, 4999, 5003, 5008,
+    5013, 5018, 5023, 5028, 5033, 5038, 5043, 5048, 5053, 5058, 5063, 5068,
+    5073, 5078, 5086, 0, 5093, 5097, 5101, 5105, 5109, 5113, 5117, 5121,
+    5125, 5129, 5133, 5137, 5141, 5145, 5149, 5153, 5157, 5161, 5165, 5169,
+    5173, 5177, 5181, 5185, 5189, 5193, 5197, 5201, 5205, 5209, 5213, 5217,
+    5221, 5225, 5229, 5233, 5237, 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0,
+    5245, 5249, 5252, 5255, 5258, 5261, 5264, 5267, 5270, 5273, 5276, 5279,
+    5282, 5285, 5288, 5291, 5294, 5296, 5298, 5300, 5302, 5304, 5306, 5308,
+    5310, 5312, 5314, 5316, 5318, 5320, 5322, 5325, 5328, 5331, 5334, 5337,
+    5340, 5343, 5346, 5349, 5352, 5355, 5358, 5361, 5364, 5370, 5375, 0,
+    5378, 5380, 5382, 5384, 5386, 5388, 5390, 5392, 5394, 5396, 5398, 5400,
+    5402, 5404, 5406, 5408, 5410, 5412, 5414, 5416, 5418, 5420, 5422, 5424,
+    5426, 5428, 5430, 5432, 5434, 5436, 5438, 5440, 5442, 5444, 5446, 5448,
+    5450, 5452, 5454, 5456, 5458, 5460, 5462, 5464, 5466, 5468, 5470, 5472,
+    5474, 5476, 5479, 5482, 5485, 5488, 5491, 5494, 5497, 5500, 5503, 5506,
+    5509, 5512, 5515, 5518, 5521, 5524, 5527, 5530, 5533, 5536, 5539, 5542,
+    5545, 5548, 5552, 5556, 5560, 5563, 5567, 5570, 5574, 5576, 5578, 5580,
+    5582, 5584, 5586, 5588, 5590, 5592, 5594, 5596, 5598, 5600, 5602, 5604,
+    5606, 5608, 5610, 5612, 5614, 5616, 5618, 5620, 5622, 5624, 5626, 5628,
+    5630, 5632, 5634, 5636, 5638, 5640, 5642, 5644, 5646, 5648, 5650, 5652,
+    5654, 5656, 5658, 5660, 5662, 5664, 5666, 0, 5668, 5673, 5678, 5683,
+    5687, 5692, 5696, 5700, 5706, 5711, 5715, 5719, 5723, 5728, 5733, 5737,
+    5741, 5744, 5748, 5753, 5758, 5761, 5767, 5774, 5780, 5784, 5790, 5796,
+    5801, 5805, 5809, 5813, 5818, 5824, 5829, 5833, 5837, 5841, 5844, 5847,
+    5850, 5853, 5857, 5861, 5867, 5871, 5876, 5882, 5886, 5889, 5892, 5898,
+    5903, 5909, 5913, 5919, 5922, 5926, 5930, 5934, 5938, 5942, 5947, 5951,
+    5954, 5958, 5962, 5966, 5971, 5975, 5979, 5983, 5989, 5994, 5997, 6003,
+    6006, 6011, 6016, 6020, 6024, 6028, 6033, 6036, 6040, 6045, 6048, 6054,
+    6058, 6061, 6064, 6067, 6070, 6073, 6076, 6079, 6082, 6085, 6088, 6092,
+    6096, 6100, 6104, 6108, 6112, 6116, 6120, 6124, 6128, 6132, 6136, 6140,
+    6144, 6148, 6152, 6155, 6158, 6162, 6165, 6168, 6171, 6175, 6179, 6182,
+    6185, 6188, 6191, 6194, 6199, 6202, 6205, 6208, 6211, 6214, 6217, 6220,
+    6223, 6227, 6232, 6235, 6238, 6241, 6244, 6247, 6250, 6253, 6257, 6261,
+    6265, 6269, 6272, 6275, 6278, 6281, 6284, 6287, 6290, 6293, 6296, 6299,
+    6303, 6307, 6310, 6314, 6318, 6322, 6325, 6329, 6333, 6338, 6341, 6345,
+    6349, 6353, 6357, 6363, 6370, 6373, 6376, 6379, 6382, 6385, 6388, 6391,
+    6394, 6397, 6400, 6403, 6406, 6409, 6412, 6415, 6418, 6421, 6424, 6429,
+    6432, 6435, 6438, 6443, 6447, 6450, 6453, 6456, 6459, 6462, 6465, 6468,
+    6471, 6474, 6477, 6481, 6484, 6487, 6491, 6495, 6498, 6503, 6507, 6510,
+    6513, 6516, 6519, 6523, 6527, 6530, 6533, 6536, 6539, 6542, 6545, 6548,
+    6551, 6554, 6558, 6562, 6566, 6570, 6574, 6578, 6582, 6586, 6590, 6594,
+    6598, 6602, 6606, 6610, 6614, 6618, 6622, 6626, 6630, 6634, 6638, 6642,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6646, 6648, 0, 0, 6650, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6652, 6654, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6656, 6658, 6660,
+    6662, 6664, 6666, 6668, 6670, 6672, 6674, 6676, 6678, 6680, 6682, 6684,
+    6686, 6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, 6704, 6706, 6708,
+    6710, 6712, 6714, 6716, 6718, 6720, 6722, 6724, 6726, 6728, 6730, 6732,
+    6734, 6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, 6752, 6754, 6756,
+    6758, 6760, 6762, 6764, 6766, 6768, 6770, 6772, 6774, 6776, 6778, 6780,
+    6782, 6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, 6800, 6802, 6804,
+    6806, 6808, 6810, 6812, 6814, 6816, 6818, 6820, 6822, 6824, 6826, 6828,
+    6830, 6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, 6848, 6850, 6852,
+    6854, 6856, 6858, 6860, 6862, 6864, 6866, 6868, 6870, 6872, 6874, 6876,
+    6878, 6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, 6896, 6898, 6900,
+    6902, 6904, 6906, 6908, 6910, 6912, 6914, 6916, 6918, 6920, 6922, 6924,
+    6926, 6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, 6944, 6946, 6948,
+    6950, 6952, 6954, 6956, 6958, 6960, 6962, 6964, 6966, 6968, 6970, 6972,
+    6974, 6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, 6992, 6994, 6996,
+    6998, 7000, 7002, 7004, 7006, 7008, 7010, 7012, 7014, 7016, 7018, 7020,
+    7022, 7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, 7042, 7044,
+    7046, 7048, 7050, 7052, 7054, 7056, 7058, 7060, 7062, 7064, 7066, 7068,
+    7070, 7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, 7088, 7090, 7092,
+    7094, 7096, 7098, 7100, 7102, 7104, 7106, 7108, 7110, 7112, 7114, 7116,
+    7118, 7120, 7122, 7124, 7126, 7128, 7130, 7132, 7134, 7136, 7138, 7140,
+    7142, 7144, 7146, 7148, 7150, 7152, 7154, 7156, 7158, 7160, 7162, 7164,
+    7166, 7168, 7170, 7172, 7174, 7176, 7178, 7180, 7182, 7184, 7186, 7188,
+    7190, 7192, 7194, 7196, 7198, 7200, 7202, 0, 0, 7204, 0, 7206, 0, 0,
+    7208, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, 7226, 0, 7228, 0,
+    7230, 0, 0, 7232, 7234, 0, 0, 0, 7236, 7238, 7240, 7242, 7244, 7246,
+    7248, 7250, 7252, 7254, 7256, 7258, 7260, 7262, 7264, 7266, 7268, 7270,
+    7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294,
+    7296, 7298, 7300, 7302, 7304, 7306, 7308, 7310, 7312, 7314, 7316, 7318,
+    7320, 7322, 7324, 7326, 7328, 7330, 7332, 7334, 7336, 7338, 7340, 7342,
+    7344, 7346, 7348, 7350, 7352, 7354, 7356, 7358, 7360, 7362, 7364, 7366,
+    7368, 7371, 0, 0, 7373, 7375, 7377, 7379, 7381, 7383, 7385, 7387, 7389,
+    7391, 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, 7413,
+    7415, 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, 7437,
+    7439, 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, 7461,
+    7463, 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, 7485,
+    7487, 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, 7509,
+    7511, 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, 7533,
+    7535, 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7553, 7555, 7557,
+    7559, 7561, 7563, 7566, 7569, 7572, 7574, 7576, 7578, 7581, 7584, 7587,
+    7589, 0, 0, 0, 0, 0, 0, 7591, 7594, 7597, 7600, 7604, 7608, 7611, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7614, 7617, 7620, 7623, 7626, 0, 0, 0, 0,
+    0, 7629, 0, 7632, 7635, 7637, 7639, 7641, 7643, 7645, 7647, 7649, 7651,
+    7653, 7655, 7658, 7661, 7664, 7667, 7670, 7673, 7676, 7679, 7682, 7685,
+    7688, 7691, 0, 7694, 7697, 7700, 7703, 7706, 0, 7709, 0, 7712, 7715, 0,
+    7718, 7721, 0, 7724, 7727, 7730, 7733, 7736, 7739, 7742, 7745, 7748,
+    7751, 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, 7770, 7772, 7774,
+    7776, 7778, 7780, 7782, 7784, 7786, 7788, 7790, 7792, 7794, 7796, 7798,
+    7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, 7818, 7820, 7822,
+    7824, 7826, 7828, 7830, 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846,
+    7848, 7850, 7852, 7854, 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870,
+    7872, 7874, 7876, 7878, 7880, 7882, 7884, 7886, 7888, 7890, 7892, 7894,
+    7896, 7898, 7900, 7902, 7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918,
+    7920, 7922, 7924, 7926, 7928, 7930, 7932, 7934, 7936, 7938, 7940, 7942,
+    7944, 7946, 7948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    7950, 7952, 7954, 7956, 7958, 7960, 7962, 7964, 7966, 7968, 7970, 7972,
+    7974, 7976, 7978, 7980, 7982, 7984, 7986, 7988, 7990, 7992, 7994, 7996,
+    7999, 8002, 8005, 8008, 8011, 8014, 8017, 8020, 8023, 8026, 8029, 8032,
+    8035, 8038, 8041, 8044, 8047, 8050, 8052, 8054, 8056, 8058, 8061, 8064,
+    8067, 8070, 8073, 8076, 8079, 8082, 8085, 8088, 8091, 8094, 8097, 8100,
+    8103, 8106, 8109, 8112, 8115, 8118, 8121, 8124, 8127, 8130, 8133, 8136,
+    8139, 8142, 8145, 8148, 8151, 8154, 8157, 8160, 8163, 8166, 8169, 8172,
+    8175, 8178, 8181, 8184, 8187, 8190, 8193, 8196, 8199, 8202, 8205, 8208,
+    8211, 8214, 8217, 8220, 8223, 8226, 8229, 8232, 8235, 8238, 8241, 8244,
+    8247, 8250, 8253, 8256, 8259, 8262, 8265, 8268, 8271, 8274, 8277, 8280,
+    8283, 8286, 8289, 8292, 8295, 8298, 8301, 8304, 8307, 8310, 8313, 8316,
+    8319, 8322, 8325, 8328, 8331, 8334, 8337, 8340, 8344, 8348, 8352, 8356,
+    8360, 8364, 8367, 8370, 8373, 8376, 8379, 8382, 8385, 8388, 8391, 8394,
+    8397, 8400, 8403, 8406, 8409, 8412, 8415, 8418, 8421, 8424, 8427, 8430,
+    8433, 8436, 8439, 8442, 8445, 8448, 8451, 8454, 8457, 8460, 8463, 8466,
+    8469, 8472, 8475, 8478, 8481, 8484, 8487, 8490, 8493, 8496, 8499, 8502,
+    8505, 8508, 8511, 8514, 8517, 8520, 8523, 8526, 8529, 8532, 8535, 8538,
+    8541, 8544, 8547, 8550, 8553, 8556, 8559, 8562, 8565, 8568, 8571, 8574,
+    8577, 8580, 8583, 8586, 8589, 8592, 8595, 8598, 8601, 8604, 8607, 8610,
+    8613, 8616, 8619, 8622, 8625, 8628, 8631, 8634, 8637, 8640, 8643, 8646,
+    8649, 8652, 8655, 8658, 8661, 8664, 8667, 8670, 8673, 8676, 8679, 8682,
+    8685, 8688, 8691, 8694, 8697, 8700, 8703, 8706, 8709, 8712, 8715, 8718,
+    8721, 8724, 8727, 8730, 8733, 8736, 8739, 8742, 8745, 8748, 8751, 8754,
+    8757, 8760, 8763, 8766, 8769, 8772, 8775, 8778, 8781, 8784, 8787, 8790,
+    8794, 8798, 8802, 8805, 8808, 8811, 8814, 8817, 8820, 8823, 8826, 8829,
+    8832, 8835, 8838, 8841, 8844, 8847, 8850, 8853, 8856, 8859, 8862, 8865,
+    8868, 8871, 8874, 8877, 8880, 8883, 8886, 8889, 8892, 8895, 8898, 8901,
+    8904, 8907, 8910, 8913, 8916, 8919, 8922, 8925, 8928, 8931, 8934, 8937,
+    8940, 8943, 8946, 8949, 8952, 8955, 8958, 8961, 8964, 8967, 8970, 8973,
+    8976, 8979, 8982, 8985, 8988, 8991, 8994, 8997, 9000, 9003, 9006, 9009,
+    9012, 9015, 9018, 0, 0, 9021, 9025, 9029, 9033, 9037, 9041, 9045, 9049,
+    9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093, 9097,
+    9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, 9137, 9141, 9145,
+    9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, 9181, 9185, 9189, 9193,
+    9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9233, 9237, 9241,
+    9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, 0, 0, 9277, 9281, 9285,
+    9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, 9325, 9329, 9333,
+    9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 9369, 9373, 9377, 9381,
+    9385, 9389, 9393, 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429,
+    9433, 9437, 9441, 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477,
+    9481, 9485, 9489, 0, 0, 0, 0, 0, 0, 0, 0, 9493, 9497, 9501, 9506, 9511,
+    9516, 9521, 9526, 9531, 9536, 9540, 9559, 9568, 0, 0, 0, 9573, 9575,
+    9577, 9579, 9581, 9583, 9585, 9587, 9589, 9591, 0, 0, 0, 0, 0, 0, 9593,
+    9595, 9597, 9599, 9601, 9603, 9605, 9607, 9609, 9611, 9613, 9615, 9617,
+    9619, 9621, 9623, 9625, 9627, 9629, 9631, 9633, 0, 0, 9635, 9637, 9639,
+    9641, 9643, 9645, 9647, 9649, 9651, 9653, 9655, 9657, 0, 9659, 9661,
+    9663, 9665, 9667, 9669, 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685,
+    9687, 9689, 9691, 9693, 9695, 0, 9697, 9699, 9701, 9703, 0, 0, 0, 0,
+    9705, 9708, 9711, 0, 9714, 0, 9717, 9720, 9723, 9726, 9729, 9732, 9735,
+    9738, 9741, 9744, 9747, 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763,
+    9765, 9767, 9769, 9771, 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787,
+    9789, 9791, 9793, 9795, 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811,
+    9813, 9815, 9817, 9819, 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835,
+    9837, 9839, 9841, 9843, 9845, 9847, 9849, 9851, 9853, 9855, 9857, 9859,
+    9861, 9863, 9865, 9867, 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883,
+    9885, 9887, 9889, 9891, 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907,
+    9909, 9911, 9913, 9915, 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931,
+    9933, 9935, 9937, 9939, 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955,
+    9957, 9959, 9961, 9963, 9965, 9967, 9969, 9971, 9973, 9975, 9977, 9979,
+    9981, 9984, 9987, 9990, 9993, 9996, 9999, 10002, 0, 0, 0, 0, 10005,
+    10007, 10009, 10011, 10013, 10015, 10017, 10019, 10021, 10023, 10025,
+    10027, 10029, 10031, 10033, 10035, 10037, 10039, 10041, 10043, 10045,
+    10047, 10049, 10051, 10053, 10055, 10057, 10059, 10061, 10063, 10065,
+    10067, 10069, 10071, 10073, 10075, 10077, 10079, 10081, 10083, 10085,
+    10087, 10089, 10091, 10093, 10095, 10097, 10099, 10101, 10103, 10105,
+    10107, 10109, 10111, 10113, 10115, 10117, 10119, 10121, 10123, 10125,
+    10127, 10129, 10131, 10133, 10135, 10137, 10139, 10141, 10143, 10145,
+    10147, 10149, 10151, 10153, 10155, 10157, 10159, 10161, 10163, 10165,
+    10167, 10169, 10171, 10173, 10175, 10177, 10179, 10181, 10183, 10185,
+    10187, 10189, 10191, 10193, 10195, 10197, 10199, 10201, 10203, 10205,
+    10207, 10209, 10211, 10213, 10215, 10217, 10219, 10221, 10223, 10225,
+    10227, 10229, 10231, 10233, 10235, 10237, 10239, 10241, 10243, 10245,
+    10247, 10249, 10251, 10253, 10255, 10257, 10259, 10261, 10263, 10265,
+    10267, 10269, 10271, 10273, 10275, 10277, 10279, 10281, 10283, 10285,
+    10287, 10289, 10291, 10293, 10295, 10297, 10299, 10301, 10303, 10305,
+    10307, 10309, 10311, 10313, 10315, 10317, 10319, 10321, 10323, 10325,
+    10327, 10329, 10331, 10333, 10335, 10337, 10339, 10341, 10343, 10345,
+    10347, 10349, 10351, 10353, 10355, 10357, 10359, 10361, 10363, 10365,
+    10367, 10369, 10371, 10373, 10375, 10377, 10379, 10381, 10383, 0, 0, 0,
+    10385, 10387, 10389, 10391, 10393, 10395, 0, 0, 10397, 10399, 10401,
+    10403, 10405, 10407, 0, 0, 10409, 10411, 10413, 10415, 10417, 10419, 0,
+    0, 10421, 10423, 10425, 0, 0, 0, 10427, 10429, 10431, 10433, 10435,
+    10437, 10439, 0, 10441, 10443, 10445, 10447, 10449, 10451, 10453, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 10455, 0, 10460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 10465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    10470, 10475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10480, 10485, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10490, 10495, 0, 10500, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 10505, 10510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 10515, 10520, 10525, 10530, 10535, 10540, 10545, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10550, 10555, 10560,
+    10565, 10570, 10575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10580,
+    10582, 10584, 10586, 10588, 10590, 10592, 10594, 10596, 10598, 10600,
+    10602, 10604, 10606, 10608, 10610, 10612, 10614, 10616, 10618, 10620,
+    10622, 10624, 10626, 10628, 10630, 10632, 10634, 10636, 10638, 10640,
+    10642, 10644, 10646, 10648, 10650, 10652, 10654, 10656, 10658, 10660,
+    10662, 10664, 10666, 10668, 10670, 10672, 10674, 10676, 10678, 10680,
+    10682, 10684, 10686, 10688, 10690, 10692, 10694, 10696, 10698, 10700,
+    10702, 10704, 10706, 10708, 10710, 10712, 10714, 10716, 10718, 10720,
+    10722, 10724, 10726, 10728, 10730, 10732, 10734, 10736, 10738, 10740,
+    10742, 10744, 10746, 10748, 0, 10750, 10752, 10754, 10756, 10758, 10760,
+    10762, 10764, 10766, 10768, 10770, 10772, 10774, 10776, 10778, 10780,
+    10782, 10784, 10786, 10788, 10790, 10792, 10794, 10796, 10798, 10800,
+    10802, 10804, 10806, 10808, 10810, 10812, 10814, 10816, 10818, 10820,
+    10822, 10824, 10826, 10828, 10830, 10832, 10834, 10836, 10838, 10840,
+    10842, 10844, 10846, 10848, 10850, 10852, 10854, 10856, 10858, 10860,
+    10862, 10864, 10866, 10868, 10870, 10872, 10874, 10876, 10878, 10880,
+    10882, 10884, 10886, 10888, 10890, 0, 10892, 10894, 0, 0, 10896, 0, 0,
+    10898, 10900, 0, 0, 10902, 10904, 10906, 10908, 0, 10910, 10912, 10914,
+    10916, 10918, 10920, 10922, 10924, 10926, 10928, 10930, 10932, 0, 10934,
+    0, 10936, 10938, 10940, 10942, 10944, 10946, 10948, 0, 10950, 10952,
+    10954, 10956, 10958, 10960, 10962, 10964, 10966, 10968, 10970, 10972,
+    10974, 10976, 10978, 10980, 10982, 10984, 10986, 10988, 10990, 10992,
+    10994, 10996, 10998, 11000, 11002, 11004, 11006, 11008, 11010, 11012,
+    11014, 11016, 11018, 11020, 11022, 11024, 11026, 11028, 11030, 11032,
+    11034, 11036, 11038, 11040, 11042, 11044, 11046, 11048, 11050, 11052,
+    11054, 11056, 11058, 11060, 11062, 11064, 11066, 11068, 11070, 11072,
+    11074, 11076, 11078, 0, 11080, 11082, 11084, 11086, 0, 0, 11088, 11090,
+    11092, 11094, 11096, 11098, 11100, 11102, 0, 11104, 11106, 11108, 11110,
+    11112, 11114, 11116, 0, 11118, 11120, 11122, 11124, 11126, 11128, 11130,
+    11132, 11134, 11136, 11138, 11140, 11142, 11144, 11146, 11148, 11150,
+    11152, 11154, 11156, 11158, 11160, 11162, 11164, 11166, 11168, 11170,
+    11172, 0, 11174, 11176, 11178, 11180, 0, 11182, 11184, 11186, 11188,
+    11190, 0, 11192, 0, 0, 0, 11194, 11196, 11198, 11200, 11202, 11204,
+    11206, 0, 11208, 11210, 11212, 11214, 11216, 11218, 11220, 11222, 11224,
+    11226, 11228, 11230, 11232, 11234, 11236, 11238, 11240, 11242, 11244,
+    11246, 11248, 11250, 11252, 11254, 11256, 11258, 11260, 11262, 11264,
+    11266, 11268, 11270, 11272, 11274, 11276, 11278, 11280, 11282, 11284,
+    11286, 11288, 11290, 11292, 11294, 11296, 11298, 11300, 11302, 11304,
+    11306, 11308, 11310, 11312, 11314, 11316, 11318, 11320, 11322, 11324,
+    11326, 11328, 11330, 11332, 11334, 11336, 11338, 11340, 11342, 11344,
+    11346, 11348, 11350, 11352, 11354, 11356, 11358, 11360, 11362, 11364,
+    11366, 11368, 11370, 11372, 11374, 11376, 11378, 11380, 11382, 11384,
+    11386, 11388, 11390, 11392, 11394, 11396, 11398, 11400, 11402, 11404,
+    11406, 11408, 11410, 11412, 11414, 11416, 11418, 11420, 11422, 11424,
+    11426, 11428, 11430, 11432, 11434, 11436, 11438, 11440, 11442, 11444,
+    11446, 11448, 11450, 11452, 11454, 11456, 11458, 11460, 11462, 11464,
+    11466, 11468, 11470, 11472, 11474, 11476, 11478, 11480, 11482, 11484,
+    11486, 11488, 11490, 11492, 11494, 11496, 11498, 11500, 11502, 11504,
+    11506, 11508, 11510, 11512, 11514, 11516, 11518, 11520, 11522, 11524,
+    11526, 11528, 11530, 11532, 11534, 11536, 11538, 11540, 11542, 11544,
+    11546, 11548, 11550, 11552, 11554, 11556, 11558, 11560, 11562, 11564,
+    11566, 11568, 11570, 11572, 11574, 11576, 11578, 11580, 11582, 11584,
+    11586, 11588, 11590, 11592, 11594, 11596, 11598, 11600, 11602, 11604,
+    11606, 11608, 11610, 11612, 11614, 11616, 11618, 11620, 11622, 11624,
+    11626, 11628, 11630, 11632, 11634, 11636, 11638, 11640, 11642, 11644,
+    11646, 11648, 11650, 11652, 11654, 11656, 11658, 11660, 11662, 11664,
+    11666, 11668, 11670, 11672, 11674, 11676, 11678, 11680, 11682, 11684,
+    11686, 11688, 11690, 11692, 11694, 11696, 11698, 11700, 11702, 11704,
+    11706, 11708, 11710, 11712, 11714, 11716, 11718, 11720, 11722, 11724,
+    11726, 11728, 11730, 11732, 11734, 11736, 11738, 11740, 11742, 11744,
+    11746, 11748, 11750, 11752, 11754, 11756, 11758, 11760, 11762, 11764,
+    11766, 11768, 11770, 11772, 11774, 11776, 11778, 11780, 11782, 11784,
+    11786, 11788, 11790, 11792, 11794, 11796, 11798, 11800, 11802, 11804,
+    11806, 11808, 11810, 11812, 11814, 11816, 11818, 11820, 11822, 11824,
+    11826, 11828, 11830, 11832, 11834, 11836, 11838, 11840, 11842, 11844,
+    11846, 11848, 11850, 11852, 11854, 11856, 11858, 11860, 11862, 11864,
+    11866, 11868, 11870, 11872, 11874, 11876, 11878, 11880, 11882, 11884,
+    11886, 0, 0, 11888, 11890, 11892, 11894, 11896, 11898, 11900, 11902,
+    11904, 11906, 11908, 11910, 11912, 11914, 11916, 11918, 11920, 11922,
+    11924, 11926, 11928, 11930, 11932, 11934, 11936, 11938, 11940, 11942,
+    11944, 11946, 11948, 11950, 11952, 11954, 11956, 11958, 11960, 11962,
+    11964, 11966, 11968, 11970, 11972, 11974, 11976, 11978, 11980, 11982,
+    11984, 11986, 11988, 11990, 11992, 11994, 11996, 11998, 12000, 12002,
+    12004, 12006, 12008, 12010, 12012, 12014, 12016, 12018, 12020, 12022,
+    12024, 12026, 12028, 12030, 12032, 12034, 12036, 12038, 12040, 12042,
+    12044, 12046, 12048, 12050, 12052, 12054, 12056, 12058, 12060, 12062,
+    12064, 12066, 12068, 12070, 12072, 12074, 12076, 12078, 12080, 12082,
+    12084, 12086, 12088, 12090, 12092, 12094, 12096, 12098, 12100, 12102,
+    12104, 12106, 12108, 12110, 12112, 12114, 12116, 12118, 12120, 12122,
+    12124, 12126, 12128, 12130, 12132, 12134, 12136, 12138, 12140, 12142,
+    12144, 12146, 12148, 12150, 12152, 12154, 12156, 12158, 12160, 12162,
+    12164, 12166, 12168, 12170, 12172, 12174, 12176, 12178, 12180, 12182,
+    12184, 12186, 12188, 12190, 12192, 12194, 12196, 12198, 12200, 12202,
+    12204, 12206, 12208, 12210, 12212, 12214, 12216, 12218, 12220, 12222,
+    12224, 12226, 12228, 12230, 12232, 12234, 12236, 12238, 12240, 12242,
+    12244, 12246, 12248, 12250, 12252, 12254, 12256, 12258, 12260, 12262,
+    12264, 12266, 12268, 12270, 12272, 12274, 12276, 12278, 12280, 12282,
+    12284, 12286, 12288, 12290, 12292, 12294, 12296, 12298, 12300, 12302,
+    12304, 12306, 12308, 12310, 12312, 12314, 12316, 12318, 12320, 12322,
+    12324, 12326, 12328, 12330, 12332, 12334, 12336, 12338, 12340, 12342,
+    12344, 12346, 12348, 12350, 12352, 12354, 12356, 12358, 12360, 12362,
+    12364, 12366, 12368, 12370, 12372, 12374, 12376, 12378, 12380, 12382,
+    12384, 12386, 12388, 12390, 12392, 12394, 12396, 12398, 12400, 12402,
+    12404, 12406, 12408, 12410, 12412, 12414, 12416, 12418, 12420, 12422,
+    12424, 12426, 12428, 12430, 12432, 12434, 12436, 12438, 12440, 12442,
+    12444, 12446, 12448, 12450, 12452, 12454, 12456, 12458, 12460, 12462,
+    12464, 12466, 12468, 12470, 0, 0, 12472, 12474, 12476, 12478, 12480,
+    12482, 12484, 12486, 12488, 12490, 12492, 12494, 12496, 12498, 12500,
+    12502, 12504, 12506, 12508, 12510, 12512, 12514, 12516, 12518, 12520,
+    12522, 12524, 12526, 12528, 12530, 12532, 12534, 12536, 12538, 12540,
+    12542, 12544, 12546, 12548, 12550, 12552, 12554, 12556, 12558, 12560,
+    12562, 12564, 12566, 12568, 12570, 12572, 12574, 12576, 12578, 0, 12580,
+    12582, 12584, 12586, 12588, 12590, 12592, 12594, 12596, 12598, 12600,
+    12602, 12604, 12606, 12608, 12610, 12612, 12614, 12616, 12618, 12620,
+    12622, 12624, 12626, 12628, 12630, 12632, 0, 12634, 12636, 0, 12638, 0,
+    0, 12640, 0, 12642, 12644, 12646, 12648, 12650, 12652, 12654, 12656,
+    12658, 12660, 0, 12662, 12664, 12666, 12668, 0, 12670, 0, 12672, 0, 0, 0,
+    0, 0, 0, 12674, 0, 0, 0, 0, 12676, 0, 12678, 0, 12680, 0, 12682, 12684,
+    12686, 0, 12688, 12690, 0, 12692, 0, 0, 12694, 0, 12696, 0, 12698, 0,
+    12700, 0, 12702, 0, 12704, 12706, 0, 12708, 0, 0, 12710, 12712, 12714,
+    12716, 0, 12718, 12720, 12722, 12724, 12726, 12728, 12730, 0, 12732,
+    12734, 12736, 12738, 0, 12740, 12742, 12744, 12746, 0, 12748, 0, 12750,
+    12752, 12754, 12756, 12758, 12760, 12762, 12764, 12766, 12768, 0, 12770,
+    12772, 12774, 12776, 12778, 12780, 12782, 12784, 12786, 12788, 12790,
+    12792, 12794, 12796, 12798, 12800, 12802, 0, 0, 0, 0, 0, 12804, 12806,
+    12808, 0, 12810, 12812, 12814, 12816, 12818, 0, 12820, 12822, 12824,
+    12826, 12828, 12830, 12832, 12834, 12836, 12838, 12840, 12842, 12844,
+    12846, 12848, 12850, 12852, 0, 0, 0, 0, 12854, 12857, 12860, 12863,
+    12866, 12869, 12872, 12875, 12878, 12881, 12884, 0, 0, 0, 0, 0, 12887,
+    12891, 12895, 12899, 12903, 12907, 12911, 12915, 12919, 12923, 12927,
+    12931, 12935, 12939, 12943, 12947, 12951, 12955, 12959, 12963, 12967,
+    12971, 12975, 12979, 12983, 12987, 12991, 12995, 12997, 12999, 13002, 0,
+    13005, 13007, 13009, 13011, 13013, 13015, 13017, 13019, 13021, 13023,
+    13025, 13027, 13029, 13031, 13033, 13035, 13037, 13039, 13041, 13043,
+    13045, 13047, 13049, 13051, 13053, 13055, 13057, 13060, 13063, 13066,
+    13069, 13073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13076, 13079, 0, 0, 0, 0,
+    13082, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13085, 13088, 13091,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13093, 13095, 13097, 13099, 13101,
+    13103, 13105, 13107, 13109, 13111, 13113, 13115, 13117, 13119, 13121,
+    13123, 13125, 13127, 13129, 13131, 13133, 13135, 13137, 13139, 13141,
+    13143, 13145, 13147, 13149, 13151, 13153, 13155, 13157, 13159, 13161,
+    13163, 13165, 13167, 13169, 13171, 13173, 13175, 13177, 0, 0, 0, 0, 0,
+    13179, 13183, 13187, 13191, 13195, 13199, 13203, 13207, 13211, 0, 0, 0,
+    0, 0, 0, 0, 13215, 13217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    13219, 13221, 13223, 13225, 13228, 13230, 13232, 13234, 13236, 13238,
+    13240, 13242, 13244, 13246, 13249, 13251, 13253, 13255, 13257, 13260,
+    13262, 13264, 13266, 13269, 13271, 13273, 13275, 13277, 13279, 13282,
+    13284, 13286, 13288, 13290, 13292, 13294, 13296, 13298, 13300, 13302,
+    13304, 13306, 13308, 13310, 13312, 13314, 13316, 13318, 13320, 13322,
+    13324, 13326, 13328, 13331, 13333, 13335, 13337, 13340, 13342, 13344,
+    13346, 13348, 13350, 13352, 13354, 13356, 13358, 13360, 13362, 13364,
+    13366, 13368, 13370, 13372, 13374, 13376, 13378, 13380, 13382, 13384,
+    13386, 13388, 13390, 13392, 13394, 13396, 13398, 13400, 13402, 13404,
+    13407, 13409, 13411, 13413, 13415, 13417, 13419, 13422, 13425, 13427,
+    13429, 13431, 13433, 13435, 13437, 13439, 13441, 13443, 13445, 13448,
+    13450, 13452, 13454, 13456, 13459, 13461, 13463, 13465, 13467, 13469,
+    13471, 13473, 13475, 13477, 13480, 13482, 13485, 13487, 13489, 13491,
+    13493, 13495, 13497, 13499, 13501, 13503, 13505, 13507, 13510, 13512,
+    13514, 13516, 13518, 13520, 13523, 13525, 13528, 13531, 13533, 13535,
+    13537, 13539, 13542, 13545, 13547, 13549, 13551, 13553, 13555, 13557,
+    13559, 13561, 13563, 13565, 13567, 13570, 13572, 13574, 13576, 13578,
+    13580, 13582, 13584, 13586, 13588, 13590, 13592, 13594, 13596, 13598,
+    13600, 13602, 13604, 13606, 13608, 13611, 13613, 13615, 13617, 13619,
+    13621, 13624, 13626, 13628, 13630, 13632, 13634, 13636, 13638, 13640,
+    13642, 13644, 13646, 13649, 13651, 13653, 13655, 13657, 13659, 13661,
+    13663, 13665, 13667, 13669, 13671, 13673, 13675, 13677, 13679, 13681,
+    13683, 13685, 13688, 13690, 13692, 13694, 13696, 13698, 13701, 13703,
+    13705, 13707, 13709, 13711, 13713, 13715, 13717, 13720, 13722, 13724,
+    13726, 13729, 13731, 13733, 13735, 13737, 13739, 13741, 13744, 13747,
+    13750, 13752, 13755, 13757, 13759, 13761, 13763, 13765, 13767, 13769,
+    13771, 13773, 13775, 13778, 13780, 13782, 13784, 13786, 13788, 13790,
+    13793, 13795, 13797, 13800, 13803, 13805, 13807, 13809, 13811, 13813,
+    13815, 13817, 13819, 13821, 13824, 13826, 13829, 13831, 13834, 13836,
+    13838, 13840, 13843, 13845, 13847, 13850, 13853, 13855, 13857, 13859,
+    13861, 13863, 13865, 13867, 13869, 13871, 13873, 13875, 13877, 13879,
+    13882, 13884, 13887, 13889, 13892, 13894, 13897, 13900, 13903, 13905,
+    13907, 13909, 13912, 13915, 13918, 13921, 13923, 13925, 13927, 13929,
+    13931, 13933, 13935, 13937, 13940, 13942, 13944, 13946, 13948, 13951,
+    13953, 13956, 13959, 13961, 13963, 13965, 13967, 13969, 13971, 13974,
+    13977, 13980, 13982, 13984, 13987, 13989, 13991, 13993, 13996, 13998,
+    14000, 14002, 14004, 14006, 14009, 14011, 14013, 14015, 14017, 14019,
+    14021, 14024, 14027, 14029, 14032, 14034, 14037, 14039, 14041, 14043,
+    14046, 14049, 14051, 14054, 14056, 14059, 14061, 14063, 14065, 14067,
+    14069, 14071, 14074, 14077, 14080, 14083, 14085, 14087, 14089, 14091,
+    14093, 14095, 14097, 14099, 14101, 14103, 14105, 14107, 14110, 14112,
+    14114, 14116, 14118, 14120, 14122, 14124, 14126, 14128, 14130, 14132,
+    14134, 14137, 14140, 14143, 14145, 14147, 14149, 14151, 14154, 14156,
+    14159, 14161, 14163, 14166, 14169, 14171, 14173, 14175, 14177, 14179,
+    14181, 14183, 14185, 14187, 14189, 14191, 14193, 14195, 14197, 14199,
+    14201, 14203, 14205, 14207, 14210, 14212, 14214, 14216, 14218, 14220,
+    14223, 14226, 14228, 14230, 14232, 14234, 14236, 14238, 14241, 14243,
+    14245, 14247, 14249, 14252, 14255, 14257, 14259, 14261, 14264, 14266,
+    14268, 14271, 14274, 14276, 14278, 14280, 14283, 14285, 14287, 14289,
+    14291, 14293, 14295, 14297, 14300, 14302, 14304, 14306, 14309, 14311,
+    14313, 14315, 14317, 14320, 14323, 14325, 14327, 14329, 14332, 14334,
+    14337, 14339, 14341, 14343, 14346, 14348, 14350, 14352, 14354, 14356,
+    14358, 14360, 14363, 14365, 14367, 14369, 14371, 14373, 14375, 14378,
+    14380, 14383, 14386, 14389, 14391, 14393, 14395, 14397, 14399, 14401,
+    14403, 14405, 0, 0,
+};
+
+/* NFC pairs */
+#define COMP_SHIFT1 2
+#define COMP_SHIFT2 1
+static const unsigned short comp_index0[] = {
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4,
+    5, 6, 7, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 11, 12, 13, 14, 0, 0, 0, 0, 0,
+    15, 16, 17, 0, 0, 0, 0, 18, 19, 20, 21, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0,
+    23, 24, 25, 26, 0, 0, 0, 0, 27, 28, 29, 30, 0, 0, 0, 0, 31, 32, 33, 34,
+    0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 36, 0, 37, 38, 39, 0, 0, 0, 40, 41, 42,
+    43, 0, 0, 0, 0, 44, 45, 46, 0, 0, 0, 0, 0, 47, 48, 49, 50, 0, 0, 0, 51,
+    52, 53, 54, 0, 0, 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, 57, 58, 59, 60, 0, 0,
+    0, 0, 61, 62, 63, 0, 0, 0, 0, 0, 64, 65, 66, 67, 0, 0, 0, 68, 69, 70, 71,
+    0, 0, 0, 0, 72, 0, 73, 0, 0, 0, 0, 0, 74, 0, 75, 0, 0, 0, 0, 0, 76, 0, 0,
+    0, 0, 0, 0, 77, 78, 79, 0, 0, 0, 0, 0, 80, 81, 82, 83, 0, 0, 0, 0, 84,
+    85, 86, 0, 0, 0, 0, 0, 87, 88, 0, 89, 0, 0, 0, 90, 91, 0, 92, 0, 0, 0, 0,
+    0, 93, 94, 95, 0, 0, 0, 0, 96, 97, 98, 99, 0, 0, 0, 0, 100, 0, 0, 0, 0,
+    0, 0, 101, 102, 0, 103, 0, 0, 0, 0, 104, 105, 106, 107, 0, 0, 0, 0, 108,
+    109, 110, 111, 0, 0, 0, 0, 112, 113, 0, 0, 0, 0, 0, 114, 115, 116, 117,
+    0, 0, 0, 0, 118, 119, 120, 121, 0, 0, 0, 0, 122, 0, 123, 0, 0, 0, 0, 124,
+    125, 126, 127, 128, 0, 0, 0, 129, 130, 131, 132, 0, 0, 0, 0, 133, 134, 0,
+    0, 0, 0, 0, 0, 135, 136, 137, 138, 0, 0, 0, 139, 140, 141, 142, 0, 0, 0,
+    0, 0, 143, 144, 145, 0, 0, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0, 150, 0,
+    151, 0, 0, 0, 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, 155, 0, 0, 0, 0, 0, 0,
+    156, 157, 158, 0, 0, 0, 0, 0, 159, 160, 161, 162, 0, 0, 0, 163, 0, 0, 0,
+    164, 0, 0, 0, 165, 166, 0, 0, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 0, 0, 168,
+    0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0,
+    172, 173, 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 175, 176, 0, 0, 0, 0,
+    0, 0, 177, 178, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0,
+    0, 0, 0, 181, 182, 183, 0, 0, 0, 0, 0, 184, 185, 0, 0, 0, 0, 0, 0, 186,
+    0, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, 188, 189, 0, 0, 0, 0, 0, 0,
+    190, 0, 0, 0, 0, 0, 0, 0, 191, 192, 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, 0, 0,
+    0, 194, 195, 0, 0, 0, 0, 0, 0, 196, 197, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0,
+    0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 200, 201, 202, 0, 0, 0, 0, 0, 203,
+    204, 0, 0, 0, 0, 0, 0, 205, 206, 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, 0, 0, 0,
+    208, 0, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, 0,
+    0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0,
+    0, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0,
+    0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 219, 0,
+    0, 0, 0, 0, 0, 220, 221, 222, 0, 0, 0, 0, 0, 223, 224, 225, 0, 0, 0, 0,
+    0, 226, 227, 228, 0, 0, 0, 0, 0, 229, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0,
+    0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 235, 0,
+    0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 238,
+    0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0,
+    241, 0, 0, 0, 0, 0, 0, 242, 0, 243, 244, 0, 0, 0, 0, 245, 246, 0, 0, 0,
+    0, 0, 247, 0, 248, 0, 249, 0, 0, 0, 250, 251, 252, 0, 0, 0, 0, 0, 253, 0,
+    254, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 256, 257, 258, 0, 0, 0, 0, 0,
+    259, 0, 260, 0, 261, 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 263, 0,
+    0, 0, 264, 265, 266, 0, 267, 0, 0, 0, 268, 0, 269, 0, 0, 0, 0, 0, 270, 0,
+    271, 272, 0, 0, 0, 0, 273, 274, 0, 275, 0, 0, 0, 276, 0, 277, 0, 0, 0, 0,
+    0, 0, 0, 278, 0, 0, 0, 0, 0, 279, 280, 281, 282, 0, 0, 0, 0, 283, 284, 0,
+    285, 0, 0, 0, 286, 0, 0, 0, 287, 0, 0, 0, 288, 0, 0, 0, 289, 0, 0, 0, 0,
+    0, 0, 290, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 292, 0, 0, 0, 0, 0, 0,
+    0, 293, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0,
+    0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 298, 299, 0, 0, 0,
+    0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 302, 0, 0,
+    0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 305, 0,
+    0, 0, 0, 0, 0, 0, 306, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 308,
+    0, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, 0,
+    311, 312, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0,
+    0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 317, 0, 0, 0, 0,
+    0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 320, 0, 0,
+    0, 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 0, 0, 323, 0,
+    0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 326, 0, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 328, 0, 0, 0, 0,
+    0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0,
+    0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, 333, 0, 0, 0, 0, 0, 0, 334, 0, 0,
+    0, 0, 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 336, 337, 0, 0, 0, 0, 0, 0, 0,
+    338, 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 0, 340, 0, 0, 0, 0, 0, 0,
+    0, 341, 0, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0,
+    0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 345, 346, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0,
+    0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 350, 0,
+    0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 353,
+    0, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 0,
+    356, 0, 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 358, 0, 0, 0, 0, 0, 0,
+    0, 359, 0, 0, 0, 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 361, 0, 362, 0, 0, 0,
+    0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 364, 0, 0, 0, 0, 0, 0, 0, 365, 0,
+    0, 0, 0, 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, 367, 0, 0, 0, 0, 0, 0, 0, 368,
+    0, 0, 0, 0, 0, 0, 369, 370, 0, 0, 0, 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 0,
+    372, 0, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 374, 0, 0, 0, 0, 0, 0,
+    0, 375, 0, 0, 376, 0, 0, 0, 0, 377, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 379,
+    0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 0,
+    382, 0, 0, 0, 0, 0, 0, 0, 383, 0, 0, 0, 0, 0, 0, 0, 384, 0, 0, 0, 385, 0,
+    0, 386, 0, 0, 0, 0, 387, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0,
+    0, 0, 0, 390, 0, 0, 0, 0, 0, 0, 391, 0, 0, 0, 0, 0, 0, 0, 392, 0, 0, 0,
+    0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 395, 0, 0, 0, 0, 0,
+    0, 0, 396, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0,
+    0, 0, 0, 399, 0, 0, 400, 0, 0, 0, 0, 401, 0, 0, 402, 0, 0, 0, 0, 0, 0, 0,
+    403, 0, 0, 0, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 0, 405, 0, 0, 0, 0, 0, 0,
+    0, 406, 0, 0, 0, 0, 0, 0, 0, 407, 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, 0, 409,
+    0, 0, 410, 0, 0, 0, 0, 411, 0, 0, 412, 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, 0,
+    0, 0, 0, 0, 414, 0, 0, 0, 0, 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0,
+    0, 0, 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, 0, 418, 0, 0, 0, 419, 0, 0, 420, 0,
+    0, 0, 0, 421, 0, 0, 422, 0, 0, 0, 423, 0, 0, 0, 424, 0, 0, 0, 425, 0, 0,
+    0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 429, 0,
+    0, 0, 0, 0, 0, 0, 430, 0, 0, 0, 0, 0, 0, 0, 431, 0, 0, 432, 0, 0, 0, 0,
+    433, 0, 0, 434, 0, 0, 0, 435, 0, 0, 0, 436, 0, 0, 0, 437, 0, 0, 0, 438,
+    0, 0, 0, 439, 0, 0, 440, 0, 0, 0, 0, 0, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0,
+    442, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 444, 0, 0, 0, 0, 0, 0,
+    0, 445, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 447, 0, 0, 0, 448, 0, 0, 0,
+    449, 0, 0, 450, 0, 0, 0, 0, 0, 0, 0, 451, 0, 0, 0, 0, 0, 0, 0, 452, 0, 0,
+    0, 0, 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 454, 0, 0, 0, 0, 0, 0, 0, 455, 0,
+    0, 0, 0, 0, 0, 0, 456, 0, 0, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0, 458,
+    0, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, 461, 0, 0,
+    0, 462, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 464, 0, 0, 0, 465, 0,
+    0, 0, 466, 0, 0, 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, 0, 0, 468, 0, 0, 0, 0,
+    0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 0, 471, 0, 0, 0,
+    0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, 0, 0, 474, 0,
+    0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, 476, 0, 0, 0, 0, 0, 0, 0, 477,
+    0, 0, 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 0, 0, 0,
+    480, 0, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0,
+    0, 483, 0, 0, 0, 0, 0, 0, 0, 484, 0, 0, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0,
+    0, 0, 0, 486, 0, 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, 0,
+    0, 0, 0, 0, 489, 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 491, 0, 0,
+    0, 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, 0, 0, 494,
+    0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0,
+    497, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, 0, 0,
+    0, 500, 0, 0, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0,
+    0, 0, 503, 0, 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 0, 505, 0, 0, 0,
+    0, 0, 0, 0, 506, 0, 0, 0, 0, 0, 0, 507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    508, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0,
+    0, 0, 511, 0, 0, 0, 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, 0,
+    0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 515, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0,
+    0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 0, 518, 0, 0, 0, 0, 0, 0, 0, 519, 0,
+    0, 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, 0, 0, 522,
+    0, 0, 0, 0, 0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0,
+    525, 0, 0, 0, 0, 0, 0, 0, 526, 0, 0, 0, 0, 0, 0, 0, 527, 0, 0, 0, 0, 0,
+    0, 528, 0, 0, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0, 530, 0, 0, 0, 0,
+    0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0,
+    0, 0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 536, 0, 0,
+    0, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, 0, 0, 0, 0, 539,
+    0, 0, 0, 0, 0, 0, 540, 0, 0, 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 0,
+    542, 0, 0, 0, 0, 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 0,
+    0, 545, 0, 0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 0, 0, 0, 0, 547, 0, 0, 0, 0,
+    0, 0, 548, 0, 0, 0, 0, 0, 0, 0, 549, 0, 0, 0, 0, 0, 0, 0, 550, 0, 0, 0,
+    0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 0, 553, 0, 0,
+    0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 556,
+    0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 0, 0, 0,
+    559, 0, 0, 0, 0, 0, 0, 0, 560, 0, 0, 0, 0, 0, 0, 0, 561, 0, 0, 0, 0, 0,
+    0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 564,
+};
+
+static const unsigned short comp_index1[] = {
+    0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10,
+    0, 11, 12, 0, 13, 0, 0, 0, 0, 0, 0, 14, 15, 0, 0, 0, 0, 16, 0, 0, 0, 0,
+    0, 17, 18, 0, 19, 0, 20, 0, 0, 0, 0, 21, 0, 0, 0, 22, 0, 23, 0, 0, 24, 0,
+    25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 33, 34, 0, 35, 0, 36, 37, 38, 0, 0,
+    0, 0, 0, 39, 0, 0, 0, 40, 41, 42, 43, 0, 44, 0, 0, 0, 0, 45, 0, 0, 0, 0,
+    0, 46, 0, 47, 0, 48, 0, 0, 49, 0, 50, 0, 51, 0, 0, 52, 53, 54, 55, 56,
+    57, 58, 0, 59, 0, 0, 60, 61, 0, 0, 0, 62, 0, 0, 0, 0, 0, 63, 64, 0, 0,
+    65, 0, 66, 0, 0, 67, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 69, 0, 0, 70, 0, 71,
+    72, 0, 73, 0, 74, 0, 0, 75, 0, 0, 0, 0, 76, 0, 0, 77, 78, 0, 79, 0, 80,
+    0, 0, 81, 0, 82, 83, 0, 84, 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, 90, 91, 0,
+    92, 0, 0, 93, 0, 0, 0, 94, 0, 0, 95, 0, 0, 0, 96, 0, 0, 97, 0, 98, 99, 0,
+    100, 0, 101, 0, 0, 102, 0, 103, 104, 0, 105, 0, 106, 0, 0, 107, 0, 108,
+    0, 0, 0, 109, 0, 110, 0, 0, 111, 0, 112, 113, 0, 114, 0, 0, 0, 0, 0, 115,
+    116, 117, 118, 119, 120, 121, 0, 122, 123, 0, 124, 125, 0, 0, 0, 126, 0,
+    0, 127, 0, 0, 128, 129, 0, 130, 131, 0, 0, 0, 0, 0, 132, 0, 0, 0, 133,
+    134, 135, 136, 137, 0, 0, 0, 138, 0, 0, 139, 140, 0, 141, 0, 142, 0, 0,
+    143, 0, 0, 0, 0, 144, 0, 145, 146, 147, 148, 149, 150, 151, 0, 152, 153,
+    0, 154, 0, 0, 155, 0, 0, 0, 0, 156, 157, 0, 0, 0, 0, 0, 158, 159, 0, 160,
+    0, 161, 162, 0, 0, 0, 163, 0, 164, 0, 0, 165, 0, 166, 167, 0, 168, 0,
+    169, 170, 171, 172, 173, 174, 175, 0, 176, 0, 177, 178, 179, 0, 0, 0, 0,
+    0, 180, 0, 0, 0, 181, 182, 183, 184, 0, 185, 186, 0, 0, 0, 0, 0, 187, 0,
+    188, 0, 189, 0, 0, 190, 0, 191, 0, 192, 193, 0, 194, 195, 196, 197, 198,
+    199, 200, 0, 201, 0, 0, 202, 203, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 0,
+    0, 206, 0, 0, 0, 0, 207, 0, 0, 208, 0, 209, 0, 0, 210, 0, 211, 0, 0, 0,
+    0, 212, 0, 0, 213, 0, 214, 215, 0, 216, 0, 217, 0, 0, 218, 219, 0, 0, 0,
+    0, 0, 0, 220, 221, 0, 222, 0, 223, 0, 0, 224, 0, 225, 226, 0, 227, 0, 0,
+    0, 0, 0, 228, 229, 230, 231, 232, 233, 234, 0, 235, 0, 0, 236, 0, 0, 0,
+    237, 0, 0, 238, 0, 0, 0, 239, 0, 0, 240, 0, 241, 242, 0, 243, 0, 244, 0,
+    0, 245, 0, 0, 0, 0, 0, 246, 247, 0, 248, 0, 249, 0, 0, 250, 0, 251, 0, 0,
+    0, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 0, 258, 259, 260, 261,
+    262, 263, 264, 0, 265, 266, 0, 267, 268, 0, 0, 0, 269, 0, 0, 270, 0, 0,
+    0, 0, 0, 0, 271, 272, 0, 273, 274, 0, 0, 0, 275, 0, 276, 0, 0, 0, 277,
+    278, 279, 280, 281, 0, 0, 0, 282, 0, 0, 283, 284, 0, 285, 0, 286, 0, 0,
+    287, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 289, 0, 290, 0, 0, 0, 0, 291, 292,
+    0, 0, 293, 0, 0, 0, 0, 294, 295, 0, 0, 0, 0, 0, 0, 296, 0, 297, 0, 0, 0,
+    0, 298, 0, 0, 299, 300, 0, 0, 301, 0, 0, 302, 0, 0, 0, 0, 0, 0, 303, 304,
+    0, 0, 305, 0, 0, 306, 0, 307, 308, 0, 0, 0, 0, 0, 309, 310, 0, 0, 0, 0,
+    0, 0, 311, 0, 312, 0, 0, 313, 0, 0, 0, 0, 0, 314, 315, 0, 0, 316, 0, 0,
+    0, 0, 317, 318, 0, 0, 0, 0, 0, 0, 319, 0, 320, 0, 0, 0, 0, 321, 0, 0,
+    322, 323, 0, 0, 324, 0, 0, 325, 0, 0, 0, 0, 0, 0, 326, 327, 0, 0, 328, 0,
+    0, 329, 0, 330, 331, 0, 0, 0, 0, 0, 332, 333, 0, 0, 0, 0, 0, 0, 334, 0,
+    335, 0, 0, 336, 0, 0, 0, 0, 0, 337, 338, 0, 0, 339, 0, 0, 340, 341, 0, 0,
+    342, 0, 0, 343, 0, 0, 0, 0, 0, 0, 344, 0, 0, 345, 0, 0, 346, 0, 0, 0, 0,
+    0, 347, 0, 0, 348, 0, 0, 349, 0, 0, 350, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0,
+    352, 0, 353, 0, 0, 354, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 356, 357, 0, 0,
+    358, 0, 0, 0, 359, 0, 0, 360, 361, 0, 0, 362, 0, 0, 0, 363, 0, 0, 364,
+    365, 0, 0, 366, 0, 0, 0, 367, 0, 0, 368, 369, 0, 0, 370, 0, 0, 0, 371, 0,
+    0, 0, 372, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 374, 0, 0, 375, 0, 0, 376, 0,
+    0, 377, 0, 0, 0, 0, 0, 0, 378, 0, 0, 379, 0, 0, 380, 0, 0, 0, 0, 0, 381,
+    0, 382, 0, 383, 384, 0, 0, 0, 0, 0, 0, 385, 386, 0, 0, 0, 0, 0, 0, 387,
+    0, 0, 0, 388, 0, 0, 389, 0, 0, 390, 0, 0, 0, 0, 391, 0, 392, 393, 0, 0,
+    0, 394, 0, 0, 0, 395, 0, 0, 396, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 398, 0,
+    399, 400, 0, 0, 0, 401, 0, 0, 0, 402, 0, 0, 403, 0, 0, 404, 0, 0, 0, 0,
+    0, 0, 405, 0, 0, 406, 0, 0, 0, 0, 407, 0, 408, 0, 0, 0, 0, 409, 0, 0,
+    410, 0, 0, 0, 0, 411, 0, 0, 412, 0, 0, 0, 413, 0, 0, 414, 0, 0, 0, 0, 0,
+    0, 415, 416, 0, 417, 418, 0, 0, 0, 419, 0, 0, 420, 0, 0, 0, 0, 421, 0, 0,
+    422, 0, 0, 423, 0, 0, 0, 424, 0, 425, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0,
+    0, 428, 429, 0, 0, 0, 0, 0, 0, 430, 0, 0, 431, 0, 0, 0, 0, 432, 0, 433,
+    0, 0, 0, 0, 434, 0, 435, 0, 0, 0, 0, 0, 0, 436, 437, 0, 0, 438, 0, 0,
+    439, 0, 440, 441, 0, 0, 0, 442, 0, 0, 443, 0, 444, 445, 0, 446, 447, 0,
+    0, 448, 0, 0, 0, 449, 0, 450, 451, 0, 0, 0, 452, 0, 0, 0, 0, 0, 453, 0,
+    454, 455, 0, 456, 457, 0, 0, 0, 0, 0, 0, 458, 0, 0, 459, 0, 460, 461, 0,
+    0, 0, 462, 0, 0, 463, 0, 464, 465, 0, 466, 467, 0, 0, 468, 0, 0, 0, 469,
+    0, 470, 471, 0, 0, 0, 472, 0, 0, 0, 0, 0, 473, 0, 474, 475, 0, 476, 477,
+    0, 0, 0, 0, 0, 0, 478, 0, 0, 479, 0, 0, 480, 0, 0, 0, 0, 0, 481, 0, 0,
+    482, 0, 0, 0, 483, 0, 0, 484, 0, 0, 485, 0, 0, 0, 0, 0, 0, 486, 0, 0,
+    487, 488, 0, 489, 0, 0, 490, 0, 0, 0, 0, 0, 0, 491, 0, 0, 492, 0, 0, 493,
+    0, 0, 0, 494, 0, 0, 495, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 497, 0, 0, 0,
+    498, 499, 0, 0, 0, 500, 0, 0, 0, 0, 0, 501, 502, 0, 503, 0, 0, 0, 504, 0,
+    0, 0, 505, 0, 0, 506, 507, 0, 0, 0, 0, 0, 508, 0, 0, 0, 509, 510, 0, 0,
+    0, 0, 0, 511, 0, 0, 0, 512, 513, 0, 514, 0, 0, 0, 0, 515, 0, 0, 516, 0,
+    0, 517, 0, 0, 0, 0, 0, 0, 518, 0, 0, 519, 0, 0, 520, 0, 0, 521, 0, 0, 0,
+    0, 0, 0, 522, 0, 0, 523, 0, 0, 524, 0, 0, 525, 0, 0, 0, 0, 0, 0, 526, 0,
+    0, 0, 527, 0, 0, 528, 0, 0, 529, 0, 0, 530, 0, 0, 0, 531, 0, 0, 0, 0, 0,
+    0, 532, 533, 534, 0, 0, 0, 0, 0, 535, 536, 0, 0, 0, 0, 0, 537, 0, 0, 538,
+    0, 0, 539, 0, 0, 0, 0, 0, 0, 540, 0, 541, 0, 0, 0, 0, 0, 542, 543, 0, 0,
+    0, 0, 0, 544, 0, 0, 545, 0, 0, 546, 0, 0, 0, 0, 0, 0, 547, 0, 0, 548, 0,
+    0, 549, 0, 0, 550, 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 552, 553, 0, 0, 0, 0,
+    0, 554, 0, 0, 555, 0, 0, 556, 0, 0, 0, 0, 0, 0, 557, 0, 0, 558, 0, 0,
+    559, 0, 0, 560, 0, 0, 0, 0, 561, 0, 0, 562, 0, 0, 0, 0, 0, 0, 563, 0, 0,
+    564, 0, 0, 565, 0, 0, 0, 0, 0, 566, 567, 0, 0, 0, 0, 0, 568, 0, 0, 569,
+    0, 0, 570, 0, 0, 0, 0, 0, 0, 571, 0, 0, 572, 0, 0, 573, 0, 0, 574, 0, 0,
+    0, 0, 575, 0, 0, 0, 0, 0, 576, 577, 0, 0, 0, 0, 0, 578, 0, 0, 579, 0, 0,
+    580, 0, 0, 0, 0, 0, 0, 581, 0, 0, 582, 0, 0, 583, 0, 0, 584, 0, 0, 0, 0,
+    585, 0, 0, 0, 0, 0, 586, 587, 0, 0, 0, 0, 0, 588, 0, 0, 0, 0, 589, 0,
+    590, 0, 0, 0, 0, 591, 0, 592, 0, 0, 0, 0, 593, 0, 0, 594, 0, 0, 0, 0, 0,
+    0, 595, 0, 0, 596, 0, 0, 597, 0, 0, 0, 0, 0, 598, 599, 0, 0, 0, 0, 0,
+    600, 0, 0, 0, 0, 601, 0, 602, 0, 0, 0, 0, 603, 0, 604, 0, 0, 0, 0, 605,
+    0, 0, 0, 0, 0, 606, 0, 0, 607, 0, 0, 608, 0, 0, 609, 0, 0, 0, 0, 0, 0,
+    610, 0, 0, 611, 0, 0, 612, 0, 0, 0, 0, 613, 0, 614, 0, 0, 0, 0, 615, 0,
+    0, 0, 0, 0, 616, 0, 0, 617, 0, 0, 618, 0, 0, 619, 0, 0, 0, 0, 0, 0, 620,
+    0, 0, 621, 0, 0, 622, 0, 0, 623, 0, 0, 0, 0, 0, 0, 624, 0, 0, 625, 0, 0,
+    626, 0, 0, 0, 0, 627, 0, 628, 0, 0, 0, 0, 0, 0, 629, 0, 0, 630, 0, 0, 0,
+    0, 631, 0, 632, 0, 0, 0, 0, 0, 633, 0, 0, 634, 0, 0, 635, 0, 0, 636, 0,
+    0, 0, 0, 0, 0, 637, 0, 0, 638, 0, 0, 639, 0, 0, 640, 0, 0, 0, 0, 0, 0,
+    641, 0, 0, 642, 0, 0, 643, 0, 0, 644, 0, 0, 0, 0, 0, 0, 645, 0, 0, 646,
+    0, 0, 647, 0, 0, 648, 0, 0, 0, 0, 0, 0, 649, 0, 0, 650, 0, 0, 651, 0, 0,
+    652, 0, 0, 0, 0, 0, 0, 653, 0, 0, 654, 0, 0, 655, 0, 0, 656, 0, 0, 0, 0,
+    0, 0, 657, 0, 0, 658, 0, 0, 659, 0, 0, 660, 0, 0, 0, 0, 0, 0, 661, 0, 0,
+    662, 0, 0, 663, 0, 0, 664, 0, 0, 0, 0, 0, 0, 665, 0, 0, 666, 0, 0, 667,
+    0, 0, 668, 0, 0, 0, 0, 0, 0, 669, 0, 0, 670, 0, 0, 671, 0, 0, 672, 0, 0,
+    0, 0, 0, 0, 673, 0, 0, 0, 674, 0, 0, 675, 0, 0, 676, 0, 0, 677, 0, 0, 0,
+    0, 0, 0, 678, 0, 0, 679, 0, 0, 680, 0, 0, 681, 0, 0, 0, 0, 0, 0, 682, 0,
+    0, 683, 0, 0, 684, 0, 0, 685, 0, 0, 0, 0, 0, 0, 686, 0, 0, 687, 0, 0,
+    688, 0, 0, 689, 0, 0, 0, 0, 0, 0, 690, 0, 0, 691, 0, 0, 692, 0, 0, 693,
+    0, 0, 0, 0, 0, 0, 694, 0, 0, 695, 0, 0, 696, 0, 0, 697, 0, 0, 0, 0, 0, 0,
+    698, 0, 0, 699, 0, 0, 700, 0, 0, 701, 0, 0, 0, 0, 0, 0, 702, 0, 0, 703,
+    0, 0, 704, 0, 0, 705, 0, 0, 0, 0, 0, 0, 706, 0, 0, 707, 0, 0, 708, 0, 0,
+    709, 0, 0, 0, 0, 0, 0, 710, 0, 0, 711, 0, 0, 712, 0, 0, 713, 0, 0, 0, 0,
+    0, 0, 714, 0, 0, 715, 0, 0, 716, 0, 0, 717, 0, 0, 0, 0, 0, 0, 718, 0, 0,
+    719, 0, 0, 720, 0, 0, 721, 0, 0, 0, 722, 0, 0, 0, 0, 0, 0, 723, 0, 0,
+    724, 0, 0, 725, 0, 0, 726, 0, 0, 0, 727, 0, 0, 0, 728, 729, 0, 0, 730, 0,
+    0, 0, 0, 0, 0, 731,
+};
+
+static const unsigned int comp_data[] = {
+    0, 0, 0, 8814, 0, 8800, 0, 8815, 192, 193, 194, 195, 256, 258, 550, 196,
+    7842, 197, 0, 461, 512, 514, 0, 7840, 0, 7680, 260, 0, 7682, 0, 0, 7684,
+    7686, 0, 0, 262, 264, 0, 266, 0, 0, 268, 0, 199, 7690, 0, 0, 270, 0,
+    7692, 0, 7696, 0, 7698, 7694, 0, 200, 201, 202, 7868, 274, 276, 278, 203,
+    7866, 0, 0, 282, 516, 518, 0, 7864, 0, 552, 280, 7704, 0, 7706, 7710, 0,
+    0, 500, 284, 0, 7712, 286, 288, 0, 0, 486, 0, 290, 292, 0, 7714, 7718, 0,
+    542, 0, 7716, 0, 7720, 7722, 0, 204, 205, 206, 296, 298, 300, 304, 207,
+    7880, 0, 0, 463, 520, 522, 0, 7882, 302, 0, 0, 7724, 308, 0, 0, 7728, 0,
+    488, 0, 7730, 0, 310, 7732, 0, 0, 313, 0, 317, 0, 7734, 0, 315, 0, 7740,
+    7738, 0, 0, 7742, 7744, 0, 0, 7746, 504, 323, 0, 209, 7748, 0, 0, 327, 0,
+    7750, 0, 325, 0, 7754, 7752, 0, 210, 211, 212, 213, 332, 334, 558, 214,
+    7886, 0, 336, 465, 524, 526, 416, 7884, 490, 0, 0, 7764, 7766, 0, 0, 340,
+    7768, 0, 0, 344, 528, 530, 0, 7770, 0, 342, 7774, 0, 0, 346, 348, 0,
+    7776, 0, 0, 352, 0, 7778, 536, 350, 7786, 0, 0, 356, 0, 7788, 538, 354,
+    0, 7792, 7790, 0, 217, 218, 219, 360, 362, 364, 0, 220, 7910, 366, 368,
+    467, 532, 534, 431, 7908, 7794, 0, 370, 7798, 0, 7796, 0, 7804, 0, 7806,
+    7808, 7810, 372, 0, 7814, 7812, 0, 7816, 7818, 7820, 7922, 221, 374,
+    7928, 562, 0, 7822, 376, 7926, 0, 0, 7924, 0, 377, 7824, 0, 379, 0, 0,
+    381, 0, 7826, 7828, 0, 224, 225, 226, 227, 257, 259, 551, 228, 7843, 229,
+    0, 462, 513, 515, 0, 7841, 0, 7681, 261, 0, 7683, 0, 0, 7685, 7687, 0, 0,
+    263, 265, 0, 267, 0, 0, 269, 0, 231, 7691, 0, 0, 271, 0, 7693, 0, 7697,
+    0, 7699, 7695, 0, 232, 233, 234, 7869, 275, 277, 279, 235, 7867, 0, 0,
+    283, 517, 519, 0, 7865, 0, 553, 281, 7705, 0, 7707, 7711, 0, 0, 501, 285,
+    0, 7713, 287, 289, 0, 0, 487, 0, 291, 293, 0, 7715, 7719, 0, 543, 0,
+    7717, 0, 7721, 7723, 0, 7830, 0, 236, 237, 238, 297, 299, 301, 0, 239,
+    7881, 0, 0, 464, 521, 523, 0, 7883, 303, 0, 0, 7725, 309, 0, 0, 496, 0,
+    7729, 0, 489, 0, 7731, 0, 311, 7733, 0, 0, 314, 0, 318, 0, 7735, 0, 316,
+    0, 7741, 7739, 0, 0, 7743, 7745, 0, 0, 7747, 505, 324, 0, 241, 7749, 0,
+    0, 328, 0, 7751, 0, 326, 0, 7755, 7753, 0, 242, 243, 244, 245, 333, 335,
+    559, 246, 7887, 0, 337, 466, 525, 527, 417, 7885, 491, 0, 0, 7765, 7767,
+    0, 0, 341, 7769, 0, 0, 345, 529, 531, 0, 7771, 0, 343, 7775, 0, 0, 347,
+    349, 0, 7777, 0, 0, 353, 0, 7779, 537, 351, 7787, 7831, 0, 357, 0, 7789,
+    539, 355, 0, 7793, 7791, 0, 249, 250, 251, 361, 363, 365, 0, 252, 7911,
+    367, 369, 468, 533, 535, 432, 7909, 7795, 0, 371, 7799, 0, 7797, 0, 7805,
+    0, 7807, 7809, 7811, 373, 0, 7815, 7813, 0, 7832, 0, 7817, 7819, 7821,
+    7923, 253, 375, 7929, 563, 0, 7823, 255, 7927, 7833, 0, 7925, 0, 378,
+    7825, 0, 380, 0, 0, 382, 0, 7827, 7829, 0, 8173, 901, 8129, 0, 7846,
+    7844, 0, 7850, 7848, 0, 478, 0, 0, 506, 0, 508, 482, 0, 0, 7688, 7872,
+    7870, 0, 7876, 7874, 0, 0, 7726, 7890, 7888, 0, 7894, 7892, 0, 0, 7756,
+    556, 0, 0, 7758, 554, 0, 0, 510, 475, 471, 469, 0, 0, 473, 7847, 7845, 0,
+    7851, 7849, 0, 479, 0, 0, 507, 0, 509, 483, 0, 0, 7689, 7873, 7871, 0,
+    7877, 7875, 0, 0, 7727, 7891, 7889, 0, 7895, 7893, 0, 0, 7757, 557, 0, 0,
+    7759, 555, 0, 0, 511, 476, 472, 470, 0, 0, 474, 7856, 7854, 0, 7860,
+    7858, 0, 7857, 7855, 0, 7861, 7859, 0, 7700, 7702, 7701, 7703, 7760,
+    7762, 7761, 7763, 7780, 0, 7781, 0, 7782, 0, 7783, 0, 0, 7800, 0, 7801,
+    0, 7802, 0, 7803, 7835, 0, 7900, 7898, 0, 7904, 7902, 0, 0, 7906, 7901,
+    7899, 0, 7905, 7903, 0, 0, 7907, 7914, 7912, 0, 7918, 7916, 0, 0, 7920,
+    7915, 7913, 0, 7919, 7917, 0, 0, 7921, 0, 494, 492, 0, 493, 0, 480, 0,
+    481, 0, 0, 7708, 0, 7709, 560, 0, 561, 0, 0, 495, 8122, 902, 8121, 8120,
+    7944, 7945, 0, 8124, 8136, 904, 7960, 7961, 8138, 905, 7976, 7977, 0,
+    8140, 8154, 906, 8153, 8152, 0, 938, 7992, 7993, 8184, 908, 8008, 8009,
+    0, 8172, 8170, 910, 8169, 8168, 0, 939, 0, 8025, 8186, 911, 8040, 8041,
+    0, 8188, 0, 8116, 0, 8132, 8048, 940, 8113, 8112, 7936, 7937, 8118, 8115,
+    8050, 941, 7952, 7953, 8052, 942, 7968, 7969, 8134, 8131, 8054, 943,
+    8145, 8144, 0, 970, 7984, 7985, 8150, 0, 8056, 972, 8000, 8001, 8164,
+    8165, 8058, 973, 8161, 8160, 0, 971, 8016, 8017, 8166, 0, 8060, 974,
+    8032, 8033, 8182, 8179, 8146, 912, 8151, 0, 8162, 944, 8167, 0, 0, 8180,
+    0, 979, 0, 980, 0, 1031, 0, 1232, 0, 1234, 0, 1027, 1024, 0, 0, 1238, 0,
+    1025, 0, 1217, 0, 1244, 0, 1246, 1037, 0, 1250, 1049, 0, 1252, 0, 1036,
+    0, 1254, 1262, 1038, 0, 1264, 1266, 0, 0, 1268, 0, 1272, 0, 1260, 0,
+    1233, 0, 1235, 0, 1107, 1104, 0, 0, 1239, 0, 1105, 0, 1218, 0, 1245, 0,
+    1247, 1117, 0, 1251, 1081, 0, 1253, 0, 1116, 0, 1255, 1263, 1118, 0,
+    1265, 1267, 0, 0, 1269, 0, 1273, 0, 1261, 0, 1111, 1142, 0, 1143, 0, 0,
+    1242, 0, 1243, 0, 1258, 0, 1259, 1570, 1571, 1573, 0, 0, 1572, 0, 1574,
+    0, 1730, 0, 1747, 0, 1728, 0, 2345, 0, 2353, 0, 2356, 2507, 2508, 2891,
+    2888, 2892, 0, 2964, 0, 0, 3018, 3020, 0, 0, 3019, 0, 3144, 0, 3264,
+    3274, 3271, 3272, 0, 0, 3275, 0, 3402, 3404, 0, 0, 3403, 0, 3546, 3548,
+    3550, 0, 3549, 4134, 0, 0, 6918, 0, 6920, 0, 6922, 0, 6924, 0, 6926, 0,
+    6930, 0, 6971, 0, 6973, 0, 6976, 0, 6977, 0, 6979, 7736, 0, 7737, 0,
+    7772, 0, 7773, 0, 7784, 0, 7785, 0, 7852, 0, 0, 7862, 7853, 0, 0, 7863,
+    7878, 0, 7879, 0, 7896, 0, 7897, 0, 7938, 7940, 7942, 8064, 7939, 7941,
+    7943, 8065, 0, 8066, 0, 8067, 0, 8068, 0, 8069, 0, 8070, 0, 8071, 7946,
+    7948, 7950, 8072, 7947, 7949, 7951, 8073, 0, 8074, 0, 8075, 0, 8076, 0,
+    8077, 0, 8078, 0, 8079, 7954, 7956, 7955, 7957, 7962, 7964, 7963, 7965,
+    7970, 7972, 7974, 8080, 7971, 7973, 7975, 8081, 0, 8082, 0, 8083, 0,
+    8084, 0, 8085, 0, 8086, 0, 8087, 7978, 7980, 7982, 8088, 7979, 7981,
+    7983, 8089, 0, 8090, 0, 8091, 0, 8092, 0, 8093, 0, 8094, 0, 8095, 7986,
+    7988, 7990, 0, 7987, 7989, 7991, 0, 7994, 7996, 7998, 0, 7995, 7997,
+    7999, 0, 8002, 8004, 8003, 8005, 8010, 8012, 8011, 8013, 8018, 8020,
+    8022, 0, 8019, 8021, 8023, 0, 8027, 8029, 8031, 0, 8034, 8036, 8038,
+    8096, 8035, 8037, 8039, 8097, 0, 8098, 0, 8099, 0, 8100, 0, 8101, 0,
+    8102, 0, 8103, 8042, 8044, 8046, 8104, 8043, 8045, 8047, 8105, 0, 8106,
+    0, 8107, 0, 8108, 0, 8109, 0, 8110, 0, 8111, 0, 8114, 0, 8130, 0, 8178,
+    0, 8119, 8141, 8142, 8143, 0, 0, 8135, 0, 8183, 8157, 8158, 8159, 0, 0,
+    8602, 0, 8603, 0, 8622, 0, 8653, 0, 8655, 0, 8654, 0, 8708, 0, 8713, 0,
+    8716, 0, 8740, 0, 8742, 0, 8769, 0, 8772, 0, 8775, 0, 8777, 0, 8813, 0,
+    8802, 0, 8816, 0, 8817, 0, 8820, 0, 8821, 0, 8824, 0, 8825, 0, 8832, 0,
+    8833, 0, 8928, 0, 8929, 0, 8836, 0, 8837, 0, 8840, 0, 8841, 0, 8930, 0,
+    8931, 0, 8876, 0, 8877, 0, 8878, 0, 8879, 0, 8938, 0, 8939, 0, 8940, 0,
+    8941, 12436, 0, 12364, 0, 12366, 0, 12368, 0, 12370, 0, 12372, 0, 12374,
+    0, 12376, 0, 12378, 0, 12380, 0, 12382, 0, 12384, 0, 12386, 0, 12389, 0,
+    12391, 0, 12393, 0, 12400, 12401, 12403, 12404, 12406, 12407, 12409,
+    12410, 12412, 12413, 12446, 0, 12532, 0, 12460, 0, 12462, 0, 12464, 0,
+    12466, 0, 12468, 0, 12470, 0, 12472, 0, 12474, 0, 12476, 0, 12478, 0,
+    12480, 0, 12482, 0, 12485, 0, 12487, 0, 12489, 0, 12496, 12497, 12499,
+    12500, 12502, 12503, 12505, 12506, 12508, 12509, 12535, 0, 12536, 0,
+    12537, 0, 12538, 0, 12542, 0, 69786, 0, 69788, 0, 69803, 0, 0, 69934, 0,
+    69935, 70475, 70476, 70844, 70843, 70846, 0, 0, 71098, 0, 71099,
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,317 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2011  Codethink Limited
+ * Copyright © 2010,2011,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Codethink Author(s): Ryan Lortie
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_UNICODE_PRIVATE_HH
+#define HB_UNICODE_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-object-private.hh"
+
+
+extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256];
+
+/*
+ * hb_unicode_funcs_t
+ */
+
+#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \
+  HB_UNICODE_FUNC_IMPLEMENT (combining_class) \
+  HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \
+  HB_UNICODE_FUNC_IMPLEMENT (general_category) \
+  HB_UNICODE_FUNC_IMPLEMENT (mirroring) \
+  HB_UNICODE_FUNC_IMPLEMENT (script) \
+  HB_UNICODE_FUNC_IMPLEMENT (compose) \
+  HB_UNICODE_FUNC_IMPLEMENT (decompose) \
+  HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility) \
+  /* ^--- Add new callbacks here */
+
+/* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
+#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_combining_class_t, combining_class) \
+  HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \
+  HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \
+  /* ^--- Add new simple callbacks here */
+
+struct hb_unicode_funcs_t {
+  hb_object_header_t header;
+  ASSERT_POD ();
+
+  hb_unicode_funcs_t *parent;
+
+  bool immutable;
+
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \
+  inline return_type name (hb_codepoint_t unicode) { return func.name (this, unicode, user_data.name); }
+HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+  inline hb_bool_t compose (hb_codepoint_t a, hb_codepoint_t b,
+                            hb_codepoint_t *ab)
+  {
+    *ab = 0;
+    if (unlikely (!a || !b)) return false;
+    return func.compose (this, a, b, ab, user_data.compose);
+  }
+
+  inline hb_bool_t decompose (hb_codepoint_t ab,
+                              hb_codepoint_t *a, hb_codepoint_t *b)
+  {
+    *a = ab; *b = 0;
+    return func.decompose (this, ab, a, b, user_data.decompose);
+  }
+
+  inline unsigned int decompose_compatibility (hb_codepoint_t  u,
+                                               hb_codepoint_t *decomposed)
+  {
+    unsigned int ret = func.decompose_compatibility (this, u, decomposed, user_data.decompose_compatibility);
+    if (ret == 1 && u == decomposed[0]) {
+      decomposed[0] = 0;
+      return 0;
+    }
+    decomposed[ret] = 0;
+    return ret;
+  }
+
+
+  inline unsigned int
+  modified_combining_class (hb_codepoint_t unicode)
+  {
+    /* XXX This hack belongs to the Myanmar shaper. */
+    if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
+
+    /* XXX This hack belongs to the SEA shaper (for Tai Tham):
+     * Reorder SAKOT to ensure it comes after any tone marks. */
+    if (unlikely (unicode == 0x1A60u)) return 254;
+
+    /* XXX This hack belongs to the Tibetan shaper:
+     * Reorder PADMA to ensure it comes after any vowel marks. */
+    if (unlikely (unicode == 0x0FC6u)) return 254;
+
+    return _hb_modified_combining_class[combining_class (unicode)];
+  }
+
+  static inline hb_bool_t
+  is_variation_selector (hb_codepoint_t unicode)
+  {
+    /* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the
+     * Arabic shaper.  No need to match them here. */
+    return unlikely (hb_in_ranges (unicode,
+                                   0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */
+                                   0xE0100u, 0xE01EFu));  /* VARIATION SELECTOR-17..256 */
+  }
+
+  /* Default_Ignorable codepoints:
+   *
+   * Note: While U+115F, U+1160, U+3164 and U+FFA0 are Default_Ignorable,
+   * we do NOT want to hide them, as the way Uniscribe has implemented them
+   * is with regular spacing glyphs, and that's the way fonts are made to work.
+   * As such, we make exceptions for those four.
+   *
+   * Unicode 7.0:
+   * $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
+   * 00AD          # Cf       SOFT HYPHEN
+   * 034F          # Mn       COMBINING GRAPHEME JOINER
+   * 061C          # Cf       ARABIC LETTER MARK
+   * 115F..1160    # Lo   [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER
+   * 17B4..17B5    # Mn   [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
+   * 180B..180D    # Mn   [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+   * 180E          # Cf       MONGOLIAN VOWEL SEPARATOR
+   * 200B..200F    # Cf   [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
+   * 202A..202E    # Cf   [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
+   * 2060..2064    # Cf   [5] WORD JOINER..INVISIBLE PLUS
+   * 2065          # Cn       <reserved-2065>
+   * 2066..206F    # Cf  [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
+   * 3164          # Lo       HANGUL FILLER
+   * FE00..FE0F    # Mn  [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
+   * FEFF          # Cf       ZERO WIDTH NO-BREAK SPACE
+   * FFA0          # Lo       HALFWIDTH HANGUL FILLER
+   * FFF0..FFF8    # Cn   [9] <reserved-FFF0>..<reserved-FFF8>
+   * 1BCA0..1BCA3  # Cf   [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
+   * 1D173..1D17A  # Cf   [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
+   * E0000         # Cn       <reserved-E0000>
+   * E0001         # Cf       LANGUAGE TAG
+   * E0002..E001F  # Cn  [30] <reserved-E0002>..<reserved-E001F>
+   * E0020..E007F  # Cf  [96] TAG SPACE..CANCEL TAG
+   * E0080..E00FF  # Cn [128] <reserved-E0080>..<reserved-E00FF>
+   * E0100..E01EF  # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
+   * E01F0..E0FFF  # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
+   */
+  static inline hb_bool_t
+  is_default_ignorable (hb_codepoint_t ch)
+  {
+    hb_codepoint_t plane = ch >> 16;
+    if (likely (plane == 0))
+    {
+      /* BMP */
+      hb_codepoint_t page = ch >> 8;
+      switch (page) {
+        case 0x00: return unlikely (ch == 0x00ADu);
+        case 0x03: return unlikely (ch == 0x034Fu);
+        case 0x06: return unlikely (ch == 0x061Cu);
+        case 0x17: return hb_in_range (ch, 0x17B4u, 0x17B5u);
+        case 0x18: return hb_in_range (ch, 0x180Bu, 0x180Eu);
+        case 0x20: return hb_in_ranges (ch, 0x200Bu, 0x200Fu,
+                                                            0x202Au, 0x202Eu,
+                                                            0x2060u, 0x206Fu);
+        case 0xFE: return hb_in_range (ch, 0xFE00u, 0xFE0Fu) || ch == 0xFEFFu;
+        case 0xFF: return hb_in_range (ch, 0xFFF0u, 0xFFF8u);
+        default: return false;
+      }
+    }
+    else
+    {
+      /* Other planes */
+      switch (plane) {
+        case 0x01: return hb_in_ranges (ch, 0x1BCA0u, 0x1BCA3u,
+                                            0x1D173u, 0x1D17Au);
+        case 0x0E: return hb_in_range (ch, 0xE0000u, 0xE0FFFu);
+        default: return false;
+      }
+    }
+  }
+
+
+  struct {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name;
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+  } func;
+
+  struct {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) void *name;
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+  } user_data;
+
+  struct {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+  } destroy;
+};
+
+
+extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
+
+
+/* Modified combining marks */
+
+/* Hebrew
+ *
+ * We permute the "fixed-position" classes 10-26 into the order
+ * described in the SBL Hebrew manual:
+ *
+ * http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
+ *
+ * (as recommended by:
+ *  http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html)
+ *
+ * More details here:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=662055
+ */
+#define HB_MODIFIED_COMBINING_CLASS_CCC10 22 /* sheva */
+#define HB_MODIFIED_COMBINING_CLASS_CCC11 15 /* hataf segol */
+#define HB_MODIFIED_COMBINING_CLASS_CCC12 16 /* hataf patah */
+#define HB_MODIFIED_COMBINING_CLASS_CCC13 17 /* hataf qamats */
+#define HB_MODIFIED_COMBINING_CLASS_CCC14 23 /* hiriq */
+#define HB_MODIFIED_COMBINING_CLASS_CCC15 18 /* tsere */
+#define HB_MODIFIED_COMBINING_CLASS_CCC16 19 /* segol */
+#define HB_MODIFIED_COMBINING_CLASS_CCC17 20 /* patah */
+#define HB_MODIFIED_COMBINING_CLASS_CCC18 21 /* qamats */
+#define HB_MODIFIED_COMBINING_CLASS_CCC19 14 /* holam */
+#define HB_MODIFIED_COMBINING_CLASS_CCC20 24 /* qubuts */
+#define HB_MODIFIED_COMBINING_CLASS_CCC21 12 /* dagesh */
+#define HB_MODIFIED_COMBINING_CLASS_CCC22 25 /* meteg */
+#define HB_MODIFIED_COMBINING_CLASS_CCC23 13 /* rafe */
+#define HB_MODIFIED_COMBINING_CLASS_CCC24 10 /* shin dot */
+#define HB_MODIFIED_COMBINING_CLASS_CCC25 11 /* sin dot */
+#define HB_MODIFIED_COMBINING_CLASS_CCC26 26 /* point varika */
+
+/*
+ * Arabic
+ *
+ * Modify to move Shadda (ccc=33) before other marks.  See:
+ * http://unicode.org/faq/normalization.html#8
+ * http://unicode.org/faq/normalization.html#9
+ */
+#define HB_MODIFIED_COMBINING_CLASS_CCC27 28 /* fathatan */
+#define HB_MODIFIED_COMBINING_CLASS_CCC28 29 /* dammatan */
+#define HB_MODIFIED_COMBINING_CLASS_CCC29 30 /* kasratan */
+#define HB_MODIFIED_COMBINING_CLASS_CCC30 31 /* fatha */
+#define HB_MODIFIED_COMBINING_CLASS_CCC31 32 /* damma */
+#define HB_MODIFIED_COMBINING_CLASS_CCC32 33 /* kasra */
+#define HB_MODIFIED_COMBINING_CLASS_CCC33 27 /* shadda */
+#define HB_MODIFIED_COMBINING_CLASS_CCC34 34 /* sukun */
+#define HB_MODIFIED_COMBINING_CLASS_CCC35 35 /* superscript alef */
+
+/* Syriac */
+#define HB_MODIFIED_COMBINING_CLASS_CCC36 36 /* superscript alaph */
+
+/* Telugu
+ *
+ * Modify Telugu length marks (ccc=84, ccc=91).
+ * These are the only matras in the main Indic scripts range that have
+ * a non-zero ccc.  That makes them reorder with the Halant that is
+ * ccc=9.  Just zero them, we don't need them in our Indic shaper.
+ */
+#define HB_MODIFIED_COMBINING_CLASS_CCC84 0 /* length mark */
+#define HB_MODIFIED_COMBINING_CLASS_CCC91 0 /* ai length mark */
+
+/* Thai
+ *
+ * Modify U+0E38 and U+0E39 (ccc=103) to be reordered before U+0E3A (ccc=9).
+ * Assign 3, which is unassigned otherwise.
+ * Uniscribe does this reordering too.
+ */
+#define HB_MODIFIED_COMBINING_CLASS_CCC103 3 /* sara u / sara uu */
+#define HB_MODIFIED_COMBINING_CLASS_CCC107 107 /* mai * */
+
+/* Lao */
+#define HB_MODIFIED_COMBINING_CLASS_CCC118 118 /* sign u / sign uu */
+#define HB_MODIFIED_COMBINING_CLASS_CCC122 122 /* mai * */
+
+/* Tibetan */
+#define HB_MODIFIED_COMBINING_CLASS_CCC129 129 /* sign aa */
+#define HB_MODIFIED_COMBINING_CLASS_CCC130 130 /* sign i */
+#define HB_MODIFIED_COMBINING_CLASS_CCC132 132 /* sign u */
+
+
+/* Misc */
+
+#define HB_UNICODE_GENERAL_CATEGORY_IS_MARK(gen_cat) \
+        (FLAG_SAFE (gen_cat) & \
+         (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
+          FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
+          FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
+
+
+#endif /* HB_UNICODE_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,563 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2011  Codethink Limited
+ * Copyright © 2010,2011,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Codethink Author(s): Ryan Lortie
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-unicode-private.hh"
+
+
+
+/*
+ * hb_unicode_funcs_t
+ */
+
+static hb_unicode_combining_class_t
+hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+                                hb_codepoint_t      unicode   HB_UNUSED,
+                                void               *user_data HB_UNUSED)
+{
+  return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
+}
+
+static unsigned int
+hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+                                hb_codepoint_t      unicode   HB_UNUSED,
+                                void               *user_data HB_UNUSED)
+{
+  return 1;
+}
+
+static hb_unicode_general_category_t
+hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+                                 hb_codepoint_t      unicode   HB_UNUSED,
+                                 void               *user_data HB_UNUSED)
+{
+  return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
+}
+
+static hb_codepoint_t
+hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+                          hb_codepoint_t      unicode   HB_UNUSED,
+                          void               *user_data HB_UNUSED)
+{
+  return unicode;
+}
+
+static hb_script_t
+hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+                       hb_codepoint_t      unicode   HB_UNUSED,
+                       void               *user_data HB_UNUSED)
+{
+  return HB_SCRIPT_UNKNOWN;
+}
+
+static hb_bool_t
+hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+                        hb_codepoint_t      a         HB_UNUSED,
+                        hb_codepoint_t      b         HB_UNUSED,
+                        hb_codepoint_t     *ab        HB_UNUSED,
+                        void               *user_data HB_UNUSED)
+{
+  return false;
+}
+
+static hb_bool_t
+hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
+                          hb_codepoint_t      ab        HB_UNUSED,
+                          hb_codepoint_t     *a         HB_UNUSED,
+                          hb_codepoint_t     *b         HB_UNUSED,
+                          void               *user_data HB_UNUSED)
+{
+  return false;
+}
+
+
+static unsigned int
+hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs     HB_UNUSED,
+                                        hb_codepoint_t      u          HB_UNUSED,
+                                        hb_codepoint_t     *decomposed HB_UNUSED,
+                                        void               *user_data  HB_UNUSED)
+{
+  return 0;
+}
+
+
+#define HB_UNICODE_FUNCS_IMPLEMENT_SET \
+  HB_UNICODE_FUNCS_IMPLEMENT (glib) \
+  HB_UNICODE_FUNCS_IMPLEMENT (icu) \
+  HB_UNICODE_FUNCS_IMPLEMENT (ucdn) \
+  HB_UNICODE_FUNCS_IMPLEMENT (nil) \
+  /* ^--- Add new callbacks before nil */
+
+#define hb_nil_get_unicode_funcs hb_unicode_funcs_get_empty
+
+/* Prototype them all */
+#define HB_UNICODE_FUNCS_IMPLEMENT(set) \
+extern "C" hb_unicode_funcs_t *hb_##set##_get_unicode_funcs (void);
+HB_UNICODE_FUNCS_IMPLEMENT_SET
+#undef HB_UNICODE_FUNCS_IMPLEMENT
+
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_default (void)
+{
+#define HB_UNICODE_FUNCS_IMPLEMENT(set) \
+  return hb_##set##_get_unicode_funcs ();
+
+#ifdef HAVE_GLIB
+  HB_UNICODE_FUNCS_IMPLEMENT(glib)
+#elif defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
+  HB_UNICODE_FUNCS_IMPLEMENT(icu)
+#elif defined(HAVE_UCDN)
+  HB_UNICODE_FUNCS_IMPLEMENT(ucdn)
+#else
+#define HB_UNICODE_FUNCS_NIL 1
+  HB_UNICODE_FUNCS_IMPLEMENT(nil)
+#endif
+
+#undef HB_UNICODE_FUNCS_IMPLEMENT
+}
+
+#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
+#error "Could not find any Unicode functions implementation, you have to provide your own"
+#error "Consider building hb-ucdn.c.  If you absolutely want to build without any, check the code."
+#endif
+
+/**
+ * hb_unicode_funcs_create: (Xconstructor)
+ * @parent: (nullable):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_unicode_funcs_t *
+hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
+{
+  hb_unicode_funcs_t *ufuncs;
+
+  if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
+    return hb_unicode_funcs_get_empty ();
+
+  if (!parent)
+    parent = hb_unicode_funcs_get_empty ();
+
+  hb_unicode_funcs_make_immutable (parent);
+  ufuncs->parent = hb_unicode_funcs_reference (parent);
+
+  ufuncs->func = parent->func;
+
+  /* We can safely copy user_data from parent since we hold a reference
+   * onto it and it's immutable.  We should not copy the destroy notifiers
+   * though. */
+  ufuncs->user_data = parent->user_data;
+
+  return ufuncs;
+}
+
+
+const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
+  HB_OBJECT_HEADER_STATIC,
+
+  NULL, /* parent */
+  true, /* immutable */
+  {
+#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+  }
+};
+
+/**
+ * hb_unicode_funcs_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_empty (void)
+{
+  return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
+}
+
+/**
+ * hb_unicode_funcs_reference: (skip)
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 0.9.2
+ **/
+hb_unicode_funcs_t *
+hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
+{
+  return hb_object_reference (ufuncs);
+}
+
+/**
+ * hb_unicode_funcs_destroy: (skip)
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
+{
+  if (!hb_object_destroy (ufuncs)) return;
+
+#define HB_UNICODE_FUNC_IMPLEMENT(name) \
+  if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
+    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+  hb_unicode_funcs_destroy (ufuncs->parent);
+
+  free (ufuncs);
+}
+
+/**
+ * hb_unicode_funcs_set_user_data: (skip)
+ * @ufuncs: Unicode functions.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
+                                hb_user_data_key_t *key,
+                                void *              data,
+                                hb_destroy_func_t   destroy,
+                                hb_bool_t           replace)
+{
+  return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
+}
+
+/**
+ * hb_unicode_funcs_get_user_data: (skip)
+ * @ufuncs: Unicode functions.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 0.9.2
+ **/
+void *
+hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
+                                hb_user_data_key_t *key)
+{
+  return hb_object_get_user_data (ufuncs, key);
+}
+
+
+/**
+ * hb_unicode_funcs_make_immutable:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
+{
+  if (unlikely (hb_object_is_inert (ufuncs)))
+    return;
+
+  ufuncs->immutable = true;
+}
+
+/**
+ * hb_unicode_funcs_is_immutable:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
+{
+  return ufuncs->immutable;
+}
+
+/**
+ * hb_unicode_funcs_get_parent:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
+{
+  return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
+}
+
+
+#define HB_UNICODE_FUNC_IMPLEMENT(name)                                         \
+                                                                                \
+void                                                                            \
+hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t             *ufuncs,     \
+                                    hb_unicode_##name##_func_t      func,       \
+                                    void                           *user_data,  \
+                                    hb_destroy_func_t               destroy)    \
+{                                                                               \
+  if (ufuncs->immutable)                                                        \
+    return;                                                                     \
+                                                                                \
+  if (ufuncs->destroy.name)                                                     \
+    ufuncs->destroy.name (ufuncs->user_data.name);                              \
+                                                                                \
+  if (func) {                                                                   \
+    ufuncs->func.name = func;                                                   \
+    ufuncs->user_data.name = user_data;                                         \
+    ufuncs->destroy.name = destroy;                                             \
+  } else {                                                                      \
+    ufuncs->func.name = ufuncs->parent->func.name;                              \
+    ufuncs->user_data.name = ufuncs->parent->user_data.name;                    \
+    ufuncs->destroy.name = NULL;                                                \
+  }                                                                             \
+}
+
+HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+
+#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)                            \
+                                                                                \
+return_type                                                                     \
+hb_unicode_##name (hb_unicode_funcs_t *ufuncs,                                  \
+                   hb_codepoint_t      unicode)                                 \
+{                                                                               \
+  return ufuncs->name (unicode);                                                \
+}
+HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
+#undef HB_UNICODE_FUNC_IMPLEMENT
+
+/**
+ * hb_unicode_compose:
+ * @ufuncs: Unicode functions.
+ * @a:
+ * @b:
+ * @ab: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
+                    hb_codepoint_t      a,
+                    hb_codepoint_t      b,
+                    hb_codepoint_t     *ab)
+{
+  return ufuncs->compose (a, b, ab);
+}
+
+/**
+ * hb_unicode_decompose:
+ * @ufuncs: Unicode functions.
+ * @ab:
+ * @a: (out):
+ * @b: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
+                      hb_codepoint_t      ab,
+                      hb_codepoint_t     *a,
+                      hb_codepoint_t     *b)
+{
+  return ufuncs->decompose (ab, a, b);
+}
+
+/**
+ * hb_unicode_decompose_compatibility:
+ * @ufuncs: Unicode functions.
+ * @u:
+ * @decomposed: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 0.9.2
+ **/
+unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+                                    hb_codepoint_t      u,
+                                    hb_codepoint_t     *decomposed)
+{
+  return ufuncs->decompose_compatibility (u, decomposed);
+}
+
+
+/* See hb-unicode-private.hh for details. */
+const uint8_t
+_hb_modified_combining_class[256] =
+{
+  0, /* HB_UNICODE_COMBINING_CLASS_NOT_REORDERED */
+  1, /* HB_UNICODE_COMBINING_CLASS_OVERLAY */
+  2, 3, 4, 5, 6,
+  7, /* HB_UNICODE_COMBINING_CLASS_NUKTA */
+  8, /* HB_UNICODE_COMBINING_CLASS_KANA_VOICING */
+  9, /* HB_UNICODE_COMBINING_CLASS_VIRAMA */
+
+  /* Hebrew */
+  HB_MODIFIED_COMBINING_CLASS_CCC10,
+  HB_MODIFIED_COMBINING_CLASS_CCC11,
+  HB_MODIFIED_COMBINING_CLASS_CCC12,
+  HB_MODIFIED_COMBINING_CLASS_CCC13,
+  HB_MODIFIED_COMBINING_CLASS_CCC14,
+  HB_MODIFIED_COMBINING_CLASS_CCC15,
+  HB_MODIFIED_COMBINING_CLASS_CCC16,
+  HB_MODIFIED_COMBINING_CLASS_CCC17,
+  HB_MODIFIED_COMBINING_CLASS_CCC18,
+  HB_MODIFIED_COMBINING_CLASS_CCC19,
+  HB_MODIFIED_COMBINING_CLASS_CCC20,
+  HB_MODIFIED_COMBINING_CLASS_CCC21,
+  HB_MODIFIED_COMBINING_CLASS_CCC22,
+  HB_MODIFIED_COMBINING_CLASS_CCC23,
+  HB_MODIFIED_COMBINING_CLASS_CCC24,
+  HB_MODIFIED_COMBINING_CLASS_CCC25,
+  HB_MODIFIED_COMBINING_CLASS_CCC26,
+
+  /* Arabic */
+  HB_MODIFIED_COMBINING_CLASS_CCC27,
+  HB_MODIFIED_COMBINING_CLASS_CCC28,
+  HB_MODIFIED_COMBINING_CLASS_CCC29,
+  HB_MODIFIED_COMBINING_CLASS_CCC30,
+  HB_MODIFIED_COMBINING_CLASS_CCC31,
+  HB_MODIFIED_COMBINING_CLASS_CCC32,
+  HB_MODIFIED_COMBINING_CLASS_CCC33,
+  HB_MODIFIED_COMBINING_CLASS_CCC34,
+  HB_MODIFIED_COMBINING_CLASS_CCC35,
+
+  /* Syriac */
+  HB_MODIFIED_COMBINING_CLASS_CCC36,
+
+  37, 38, 39,
+  40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+  60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+  80, 81, 82, 83,
+
+  /* Telugu */
+  HB_MODIFIED_COMBINING_CLASS_CCC84,
+  85, 86, 87, 88, 89, 90,
+  HB_MODIFIED_COMBINING_CLASS_CCC91,
+  92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+
+  /* Thai */
+  HB_MODIFIED_COMBINING_CLASS_CCC103,
+  104, 105, 106,
+  HB_MODIFIED_COMBINING_CLASS_CCC107,
+  108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+
+  /* Lao */
+  HB_MODIFIED_COMBINING_CLASS_CCC118,
+  119, 120, 121,
+  HB_MODIFIED_COMBINING_CLASS_CCC122,
+  123, 124, 125, 126, 127, 128,
+
+  /* Tibetan */
+  HB_MODIFIED_COMBINING_CLASS_CCC129,
+  HB_MODIFIED_COMBINING_CLASS_CCC130,
+  131,
+  HB_MODIFIED_COMBINING_CLASS_CCC132,
+  133, 134, 135, 136, 137, 138, 139,
+
+
+  140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+  150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+  160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+  170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
+  180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
+  190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
+
+  200, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT */
+  201,
+  202, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW */
+  203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
+  214, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE */
+  215,
+  216, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT */
+  217,
+  218, /* HB_UNICODE_COMBINING_CLASS_BELOW_LEFT */
+  219,
+  220, /* HB_UNICODE_COMBINING_CLASS_BELOW */
+  221,
+  222, /* HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT */
+  223,
+  224, /* HB_UNICODE_COMBINING_CLASS_LEFT */
+  225,
+  226, /* HB_UNICODE_COMBINING_CLASS_RIGHT */
+  227,
+  228, /* HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT */
+  229,
+  230, /* HB_UNICODE_COMBINING_CLASS_ABOVE */
+  231,
+  232, /* HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT */
+  233, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW */
+  234, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE */
+  235, 236, 237, 238, 239,
+  240, /* HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT */
+  241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+  255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,470 @@
+/*
+ * Copyright © 2009  Red Hat, Inc.
+ * Copyright © 2011  Codethink Limited
+ * Copyright © 2011,2012  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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Codethink Author(s): Ryan Lortie
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_UNICODE_H
+#define HB_UNICODE_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+/* hb_unicode_general_category_t */
+
+/* Unicode Character Database property: General_Category (gc) */
+typedef enum
+{
+  HB_UNICODE_GENERAL_CATEGORY_CONTROL,                  /* Cc */
+  HB_UNICODE_GENERAL_CATEGORY_FORMAT,                   /* Cf */
+  HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED,               /* Cn */
+  HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE,              /* Co */
+  HB_UNICODE_GENERAL_CATEGORY_SURROGATE,                /* Cs */
+  HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER,         /* Ll */
+  HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER,          /* Lm */
+  HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER,             /* Lo */
+  HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER,         /* Lt */
+  HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER,         /* Lu */
+  HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK,             /* Mc */
+  HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK,           /* Me */
+  HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK,         /* Mn */
+  HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER,           /* Nd */
+  HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER,            /* Nl */
+  HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER,             /* No */
+  HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION,      /* Pc */
+  HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION,         /* Pd */
+  HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION,        /* Pe */
+  HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION,        /* Pf */
+  HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION,      /* Pi */
+  HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION,        /* Po */
+  HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION,         /* Ps */
+  HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL,          /* Sc */
+  HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL,          /* Sk */
+  HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL,              /* Sm */
+  HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL,             /* So */
+  HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR,           /* Zl */
+  HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR,      /* Zp */
+  HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR           /* Zs */
+} hb_unicode_general_category_t;
+
+/* hb_unicode_combining_class_t */
+
+/* Note: newer versions of Unicode may add new values.  Clients should be ready to handle
+ * any value in the 0..254 range being returned from hb_unicode_combining_class().
+ */
+
+/* Unicode Character Database property: Canonical_Combining_Class (ccc) */
+typedef enum
+{
+  HB_UNICODE_COMBINING_CLASS_NOT_REORDERED      = 0,
+  HB_UNICODE_COMBINING_CLASS_OVERLAY            = 1,
+  HB_UNICODE_COMBINING_CLASS_NUKTA              = 7,
+  HB_UNICODE_COMBINING_CLASS_KANA_VOICING       = 8,
+  HB_UNICODE_COMBINING_CLASS_VIRAMA             = 9,
+
+  /* Hebrew */
+  HB_UNICODE_COMBINING_CLASS_CCC10      =  10,
+  HB_UNICODE_COMBINING_CLASS_CCC11      =  11,
+  HB_UNICODE_COMBINING_CLASS_CCC12      =  12,
+  HB_UNICODE_COMBINING_CLASS_CCC13      =  13,
+  HB_UNICODE_COMBINING_CLASS_CCC14      =  14,
+  HB_UNICODE_COMBINING_CLASS_CCC15      =  15,
+  HB_UNICODE_COMBINING_CLASS_CCC16      =  16,
+  HB_UNICODE_COMBINING_CLASS_CCC17      =  17,
+  HB_UNICODE_COMBINING_CLASS_CCC18      =  18,
+  HB_UNICODE_COMBINING_CLASS_CCC19      =  19,
+  HB_UNICODE_COMBINING_CLASS_CCC20      =  20,
+  HB_UNICODE_COMBINING_CLASS_CCC21      =  21,
+  HB_UNICODE_COMBINING_CLASS_CCC22      =  22,
+  HB_UNICODE_COMBINING_CLASS_CCC23      =  23,
+  HB_UNICODE_COMBINING_CLASS_CCC24      =  24,
+  HB_UNICODE_COMBINING_CLASS_CCC25      =  25,
+  HB_UNICODE_COMBINING_CLASS_CCC26      =  26,
+
+  /* Arabic */
+  HB_UNICODE_COMBINING_CLASS_CCC27      =  27,
+  HB_UNICODE_COMBINING_CLASS_CCC28      =  28,
+  HB_UNICODE_COMBINING_CLASS_CCC29      =  29,
+  HB_UNICODE_COMBINING_CLASS_CCC30      =  30,
+  HB_UNICODE_COMBINING_CLASS_CCC31      =  31,
+  HB_UNICODE_COMBINING_CLASS_CCC32      =  32,
+  HB_UNICODE_COMBINING_CLASS_CCC33      =  33,
+  HB_UNICODE_COMBINING_CLASS_CCC34      =  34,
+  HB_UNICODE_COMBINING_CLASS_CCC35      =  35,
+
+  /* Syriac */
+  HB_UNICODE_COMBINING_CLASS_CCC36      =  36,
+
+  /* Telugu */
+  HB_UNICODE_COMBINING_CLASS_CCC84      =  84,
+  HB_UNICODE_COMBINING_CLASS_CCC91      =  91,
+
+  /* Thai */
+  HB_UNICODE_COMBINING_CLASS_CCC103     = 103,
+  HB_UNICODE_COMBINING_CLASS_CCC107     = 107,
+
+  /* Lao */
+  HB_UNICODE_COMBINING_CLASS_CCC118     = 118,
+  HB_UNICODE_COMBINING_CLASS_CCC122     = 122,
+
+  /* Tibetan */
+  HB_UNICODE_COMBINING_CLASS_CCC129     = 129,
+  HB_UNICODE_COMBINING_CLASS_CCC130     = 130,
+  HB_UNICODE_COMBINING_CLASS_CCC133     = 132,
+
+
+  HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT        = 200,
+  HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW             = 202,
+  HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE             = 214,
+  HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT       = 216,
+  HB_UNICODE_COMBINING_CLASS_BELOW_LEFT                 = 218,
+  HB_UNICODE_COMBINING_CLASS_BELOW                      = 220,
+  HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT                = 222,
+  HB_UNICODE_COMBINING_CLASS_LEFT                       = 224,
+  HB_UNICODE_COMBINING_CLASS_RIGHT                      = 226,
+  HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT                 = 228,
+  HB_UNICODE_COMBINING_CLASS_ABOVE                      = 230,
+  HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT                = 232,
+  HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW               = 233,
+  HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE               = 234,
+
+  HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT             = 240,
+
+  HB_UNICODE_COMBINING_CLASS_INVALID    = 255
+} hb_unicode_combining_class_t;
+
+
+/*
+ * hb_unicode_funcs_t
+ */
+
+typedef struct hb_unicode_funcs_t hb_unicode_funcs_t;
+
+
+/*
+ * just give me the best implementation you've got there.
+ */
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_default (void);
+
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_create (hb_unicode_funcs_t *parent);
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_empty (void);
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs);
+
+void
+hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
+
+hb_bool_t
+hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
+                                hb_user_data_key_t *key,
+                                void *              data,
+                                hb_destroy_func_t   destroy,
+                                hb_bool_t           replace);
+
+
+void *
+hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
+                                hb_user_data_key_t *key);
+
+
+void
+hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs);
+
+hb_bool_t
+hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs);
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
+
+
+/*
+ * funcs
+ */
+
+/* typedefs */
+
+typedef hb_unicode_combining_class_t    (*hb_unicode_combining_class_func_t)    (hb_unicode_funcs_t *ufuncs,
+                                                                                 hb_codepoint_t      unicode,
+                                                                                 void               *user_data);
+typedef unsigned int                    (*hb_unicode_eastasian_width_func_t)    (hb_unicode_funcs_t *ufuncs,
+                                                                                 hb_codepoint_t      unicode,
+                                                                                 void               *user_data);
+typedef hb_unicode_general_category_t   (*hb_unicode_general_category_func_t)   (hb_unicode_funcs_t *ufuncs,
+                                                                                 hb_codepoint_t      unicode,
+                                                                                 void               *user_data);
+typedef hb_codepoint_t                  (*hb_unicode_mirroring_func_t)          (hb_unicode_funcs_t *ufuncs,
+                                                                                 hb_codepoint_t      unicode,
+                                                                                 void               *user_data);
+typedef hb_script_t                     (*hb_unicode_script_func_t)             (hb_unicode_funcs_t *ufuncs,
+                                                                                 hb_codepoint_t      unicode,
+                                                                                 void               *user_data);
+
+typedef hb_bool_t                       (*hb_unicode_compose_func_t)            (hb_unicode_funcs_t *ufuncs,
+                                                                                 hb_codepoint_t      a,
+                                                                                 hb_codepoint_t      b,
+                                                                                 hb_codepoint_t     *ab,
+                                                                                 void               *user_data);
+typedef hb_bool_t                       (*hb_unicode_decompose_func_t)          (hb_unicode_funcs_t *ufuncs,
+                                                                                 hb_codepoint_t      ab,
+                                                                                 hb_codepoint_t     *a,
+                                                                                 hb_codepoint_t     *b,
+                                                                                 void               *user_data);
+
+/**
+ * hb_unicode_decompose_compatibility_func_t:
+ * @ufuncs: a Unicode function structure
+ * @u: codepoint to decompose
+ * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
+ * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
+ *
+ * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
+ * The complete length of the decomposition will be returned.
+ *
+ * If @u has no compatibility decomposition, zero should be returned.
+ *
+ * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
+ * compatibility decomposition plus an terminating value of 0.  Consequently, @decompose must be allocated by the caller to be at least this length.  Implementations
+ * of this function type must ensure that they do not write past the provided array.
+ *
+ * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
+ */
+typedef unsigned int                    (*hb_unicode_decompose_compatibility_func_t)    (hb_unicode_funcs_t *ufuncs,
+                                                                                         hb_codepoint_t      u,
+                                                                                         hb_codepoint_t     *decomposed,
+                                                                                         void               *user_data);
+
+/* See Unicode 6.1 for details on the maximum decomposition length. */
+#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
+
+/* setters */
+
+/**
+ * hb_unicode_funcs_set_combining_class_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
+                                           hb_unicode_combining_class_func_t func,
+                                           void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_funcs_set_eastasian_width_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
+                                           hb_unicode_eastasian_width_func_t func,
+                                           void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_funcs_set_general_category_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
+                                            hb_unicode_general_category_func_t func,
+                                            void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_funcs_set_mirroring_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
+                                     hb_unicode_mirroring_func_t func,
+                                     void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_funcs_set_script_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
+                                  hb_unicode_script_func_t func,
+                                  void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_funcs_set_compose_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
+                                   hb_unicode_compose_func_t func,
+                                   void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_funcs_set_decompose_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
+                                     hb_unicode_decompose_func_t func,
+                                     void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_unicode_funcs_set_decompose_compatibility_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
+                                                   hb_unicode_decompose_compatibility_func_t func,
+                                                   void *user_data, hb_destroy_func_t destroy);
+
+/* accessors */
+
+/**
+ * Since: 0.9.2
+ **/
+hb_unicode_combining_class_t
+hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
+                            hb_codepoint_t unicode);
+
+/**
+ * Since: 0.9.2
+ **/
+unsigned int
+hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
+                            hb_codepoint_t unicode);
+
+/**
+ * Since: 0.9.2
+ **/
+hb_unicode_general_category_t
+hb_unicode_general_category (hb_unicode_funcs_t *ufuncs,
+                             hb_codepoint_t unicode);
+
+/**
+ * Since: 0.9.2
+ **/
+hb_codepoint_t
+hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs,
+                      hb_codepoint_t unicode);
+
+/**
+ * Since: 0.9.2
+ **/
+hb_script_t
+hb_unicode_script (hb_unicode_funcs_t *ufuncs,
+                   hb_codepoint_t unicode);
+
+/**
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
+                    hb_codepoint_t      a,
+                    hb_codepoint_t      b,
+                    hb_codepoint_t     *ab);
+
+/**
+ * Since: 0.9.2
+ **/
+hb_bool_t
+hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
+                      hb_codepoint_t      ab,
+                      hb_codepoint_t     *a,
+                      hb_codepoint_t     *b);
+
+/**
+ * Since: 0.9.2
+ **/
+unsigned int
+hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+                                    hb_codepoint_t      u,
+                                    hb_codepoint_t     *decomposed);
+
+HB_END_DECLS
+
+#endif /* HB_UNICODE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-utf-private.hh	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,278 @@
+/*
+ * Copyright © 2011,2012,2014  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_UTF_PRIVATE_HH
+#define HB_UTF_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+struct hb_utf8_t
+{
+  typedef uint8_t codepoint_t;
+
+  static inline const uint8_t *
+  next (const uint8_t *text,
+        const uint8_t *end,
+        hb_codepoint_t *unicode,
+        hb_codepoint_t replacement)
+  {
+    /* Written to only accept well-formed sequences.
+     * Based on ideas from ICU's U8_NEXT.
+     * Generates one "replacement" for each ill-formed byte. */
+
+    hb_codepoint_t c = *text++;
+
+    if (c > 0x7Fu)
+    {
+      if (hb_in_range (c, 0xC2u, 0xDFu)) /* Two-byte */
+      {
+        unsigned int t1;
+        if (likely (text < end &&
+                    (t1 = text[0] - 0x80u) <= 0x3Fu))
+        {
+          c = ((c&0x1Fu)<<6) | t1;
+          text++;
+        }
+        else
+          goto error;
+      }
+      else if (hb_in_range (c, 0xE0u, 0xEFu)) /* Three-byte */
+      {
+        unsigned int t1, t2;
+        if (likely (1 < end - text &&
+                    (t1 = text[0] - 0x80u) <= 0x3Fu &&
+                    (t2 = text[1] - 0x80u) <= 0x3Fu))
+        {
+          c = ((c&0xFu)<<12) | (t1<<6) | t2;
+          if (unlikely (c < 0x0800u || hb_in_range (c, 0xD800u, 0xDFFFu)))
+            goto error;
+          text += 2;
+        }
+        else
+          goto error;
+      }
+      else if (hb_in_range (c, 0xF0u, 0xF4u)) /* Four-byte */
+      {
+        unsigned int t1, t2, t3;
+        if (likely (2 < end - text &&
+                    (t1 = text[0] - 0x80u) <= 0x3Fu &&
+                    (t2 = text[1] - 0x80u) <= 0x3Fu &&
+                    (t3 = text[2] - 0x80u) <= 0x3Fu))
+        {
+          c = ((c&0x7u)<<18) | (t1<<12) | (t2<<6) | t3;
+          if (unlikely (!hb_in_range (c, 0x10000u, 0x10FFFFu)))
+            goto error;
+          text += 3;
+        }
+        else
+          goto error;
+      }
+      else
+        goto error;
+    }
+
+    *unicode = c;
+    return text;
+
+  error:
+    *unicode = replacement;
+    return text;
+  }
+
+  static inline const uint8_t *
+  prev (const uint8_t *text,
+        const uint8_t *start,
+        hb_codepoint_t *unicode,
+        hb_codepoint_t replacement)
+  {
+    const uint8_t *end = text--;
+    while (start < text && (*text & 0xc0) == 0x80 && end - text < 4)
+      text--;
+
+    if (likely (next (text, end, unicode, replacement) == end))
+      return text;
+
+    *unicode = replacement;
+    return end - 1;
+  }
+
+  static inline unsigned int
+  strlen (const uint8_t *text)
+  {
+    return ::strlen ((const char *) text);
+  }
+};
+
+
+struct hb_utf16_t
+{
+  typedef uint16_t codepoint_t;
+
+  static inline const uint16_t *
+  next (const uint16_t *text,
+        const uint16_t *end,
+        hb_codepoint_t *unicode,
+        hb_codepoint_t replacement)
+  {
+    hb_codepoint_t c = *text++;
+
+    if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu)))
+    {
+      *unicode = c;
+      return text;
+    }
+
+    if (likely (hb_in_range (c, 0xD800u, 0xDBFFu)))
+    {
+      /* High-surrogate in c */
+      hb_codepoint_t l;
+      if (text < end && ((l = *text), likely (hb_in_range (l, 0xDC00u, 0xDFFFu))))
+      {
+        /* Low-surrogate in l */
+        *unicode = (c << 10) + l - ((0xD800u << 10) - 0x10000u + 0xDC00u);
+         text++;
+         return text;
+      }
+    }
+
+    /* Lonely / out-of-order surrogate. */
+    *unicode = replacement;
+    return text;
+  }
+
+  static inline const uint16_t *
+  prev (const uint16_t *text,
+        const uint16_t *start,
+        hb_codepoint_t *unicode,
+        hb_codepoint_t replacement)
+  {
+    const uint16_t *end = text--;
+    hb_codepoint_t c = *text;
+
+    if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu)))
+    {
+      *unicode = c;
+      return text;
+    }
+
+    if (likely (start < text && hb_in_range (c, 0xDC00u, 0xDFFFu)))
+      text--;
+
+    if (likely (next (text, end, unicode, replacement) == end))
+      return text;
+
+    *unicode = replacement;
+    return end - 1;
+  }
+
+
+  static inline unsigned int
+  strlen (const uint16_t *text)
+  {
+    unsigned int l = 0;
+    while (*text++) l++;
+    return l;
+  }
+};
+
+
+template <bool validate=true>
+struct hb_utf32_t
+{
+  typedef uint32_t codepoint_t;
+
+  static inline const uint32_t *
+  next (const uint32_t *text,
+        const uint32_t *end HB_UNUSED,
+        hb_codepoint_t *unicode,
+        hb_codepoint_t replacement)
+  {
+    hb_codepoint_t c = *text++;
+    if (validate && unlikely (c > 0x10FFFFu || hb_in_range (c, 0xD800u, 0xDFFFu)))
+      goto error;
+    *unicode = c;
+    return text;
+
+  error:
+    *unicode = replacement;
+    return text;
+  }
+
+  static inline const uint32_t *
+  prev (const uint32_t *text,
+        const uint32_t *start HB_UNUSED,
+        hb_codepoint_t *unicode,
+        hb_codepoint_t replacement)
+  {
+    next (text - 1, text, unicode, replacement);
+    return text - 1;
+  }
+
+  static inline unsigned int
+  strlen (const uint32_t *text)
+  {
+    unsigned int l = 0;
+    while (*text++) l++;
+    return l;
+  }
+};
+
+
+struct hb_latin1_t
+{
+  typedef uint8_t codepoint_t;
+
+  static inline const uint8_t *
+  next (const uint8_t *text,
+        const uint8_t *end HB_UNUSED,
+        hb_codepoint_t *unicode,
+        hb_codepoint_t replacement HB_UNUSED)
+  {
+    *unicode = *text++;
+    return text;
+  }
+
+  static inline const uint8_t *
+  prev (const uint8_t *text,
+        const uint8_t *start HB_UNUSED,
+        hb_codepoint_t *unicode,
+        hb_codepoint_t replacement)
+  {
+    *unicode = *--text;
+    return text;
+  }
+
+  static inline unsigned int
+  strlen (const uint8_t *text)
+  {
+    unsigned int l = 0;
+    while (*text++) l++;
+    return l;
+  }
+};
+
+#endif /* HB_UTF_PRIVATE_HH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-version.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2011  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_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_VERSION_H
+#define HB_VERSION_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+#define HB_VERSION_MAJOR 1
+#define HB_VERSION_MINOR 0
+#define HB_VERSION_MICRO 5
+
+#define HB_VERSION_STRING "1.0.5"
+
+#define HB_VERSION_ATLEAST(major,minor,micro) \
+        ((major)*10000+(minor)*100+(micro) <= \
+         HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
+
+
+void
+hb_version (unsigned int *major,
+            unsigned int *minor,
+            unsigned int *micro);
+
+const char *
+hb_version_string (void);
+
+hb_bool_t
+hb_version_atleast (unsigned int major,
+                    unsigned int minor,
+                    unsigned int micro);
+
+
+HB_END_DECLS
+
+#endif /* HB_VERSION_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-warning.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2012  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
+ */
+
+#include "hb-atomic-private.hh"
+#include "hb-mutex-private.hh"
+
+
+#if defined(HB_ATOMIC_INT_NIL)
+#error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe"
+#error "Check hb-atomic-private.hh for possible resolutions."
+#endif
+
+#if defined(HB_MUTEX_IMPL_NIL)
+#error "Could not find any system to define mutex macros, library WILL NOT be thread-safe"
+#error "Check hb-mutex-private.hh for possible resolutions."
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/harfbuzz/hb.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2009  Red Hat, 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H
+#define HB_H
+#define HB_H_IN
+
+#include "hb-blob.h"
+#include "hb-buffer.h"
+#include "hb-common.h"
+#include "hb-deprecated.h"
+#include "hb-face.h"
+#include "hb-font.h"
+#include "hb-set.h"
+#include "hb-shape.h"
+#include "hb-shape-plan.h"
+#include "hb-unicode.h"
+#include "hb-version.h"
+
+HB_BEGIN_DECLS
+HB_END_DECLS
+
+#undef HB_H_IN
+#endif /* HB_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "hb.h"
+#include "hb-jdk.h"
+#ifdef MACOSX
+#include "hb-coretext.h"
+#endif
+#include <stdlib.h>
+
+#if defined(__GNUC__) &&  __GNUC__ >= 4
+#define HB_UNUSED       __attribute__((unused))
+#else
+#define HB_UNUSED
+#endif
+
+static hb_bool_t
+hb_jdk_get_glyph (hb_font_t *font HB_UNUSED,
+		 void *font_data,
+		 hb_codepoint_t unicode,
+		 hb_codepoint_t variation_selector,
+		 hb_codepoint_t *glyph,
+		 void *user_data HB_UNUSED)
+{
+
+    JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
+    JNIEnv* env = jdkFontInfo->env;
+    jobject font2D = jdkFontInfo->font2D;
+    hb_codepoint_t u = (variation_selector==0) ? unicode : variation_selector;
+ 
+    *glyph = (hb_codepoint_t)
+          env->CallIntMethod(font2D, sunFontIDs.f2dCharToGlyphMID, u);
+    return (*glyph != 0);
+}
+
+// This is also define in freetypescaler.c and similar macros are
+// in fontscalerdefs.h. Consider tidying this up.
+#define FloatToF26Dot6(x) ((unsigned int) ((x)*64))
+
+static hb_position_t
+hb_jdk_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
+			   void *font_data,
+			   hb_codepoint_t glyph,
+			   void *user_data HB_UNUSED)
+{
+    
+    float fadv = 0.0f;
+    if ((glyph & 0xfffe) == 0xfffe) {
+        return 0; // JDK uses this glyph code.
+    }
+
+    JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
+    JNIEnv* env = jdkFontInfo->env;
+    jobject fontStrike = jdkFontInfo->fontStrike;
+    jobject pt = env->CallObjectMethod(fontStrike,
+                                       sunFontIDs.getGlyphMetricsMID, glyph);
+  
+    if (pt == NULL) {
+        return 0;
+    }
+    fadv = env->GetFloatField(pt, sunFontIDs.xFID);
+    env->DeleteLocalRef(pt);
+
+    return FloatToF26Dot6(fadv); // should this round ?
+}
+
+static hb_position_t
+hb_jdk_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
+			   void *font_data,
+			   hb_codepoint_t glyph,
+			   void *user_data HB_UNUSED)
+{
+  
+    float fadv = 0.0f;
+    if ((glyph & 0xfffe) == 0xfffe) {
+        return 0; // JDK uses this glyph code.
+    }
+
+    JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
+    JNIEnv* env = jdkFontInfo->env;
+    jobject fontStrike = jdkFontInfo->fontStrike;
+    jobject pt = env->CallObjectMethod(fontStrike,
+                                       sunFontIDs.getGlyphMetricsMID, glyph);
+  
+    if (pt == NULL) {
+        return 0;
+    }
+    fadv = env->GetFloatField(pt, sunFontIDs.yFID);
+    env->DeleteLocalRef(pt);
+
+    return FloatToF26Dot6(fadv); // should this round ?
+  
+}
+
+static hb_bool_t
+hb_jdk_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
+			  void *font_data HB_UNUSED,
+			  hb_codepoint_t glyph HB_UNUSED,
+			  hb_position_t *x HB_UNUSED,
+			  hb_position_t *y HB_UNUSED,
+			  void *user_data HB_UNUSED)
+{
+  /* We always work in the horizontal coordinates. */
+  return true;
+}
+
+static hb_bool_t
+hb_jdk_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
+			  void *font_data,
+			  hb_codepoint_t glyph,
+			  hb_position_t *x,
+			  hb_position_t *y,
+			  void *user_data HB_UNUSED)
+{
+  return false;
+}
+
+static hb_position_t
+hb_jdk_get_glyph_h_kerning (hb_font_t *font,
+			   void *font_data,
+			   hb_codepoint_t lejdk_glyph,
+			   hb_codepoint_t right_glyph,
+			   void *user_data HB_UNUSED)
+{
+  /* Not implemented. This seems to be in the HB API
+   * as a way to fall back to Freetype's kerning support
+   * which could be based on some on-the fly glyph analysis.
+   * But more likely it reads the kern table. That is easy
+   * enough code to add if we find a need to fall back
+   * to that instead of using gpos. It seems like if
+   * there is a gpos table at all, the practice is to
+   * use that and ignore kern, no matter that gpos does
+   * not implement the kern feature.
+   */
+  return 0;
+}
+
+static hb_position_t
+hb_jdk_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
+			   void *font_data HB_UNUSED,
+			   hb_codepoint_t top_glyph HB_UNUSED,
+			   hb_codepoint_t bottom_glyph HB_UNUSED,
+			   void *user_data HB_UNUSED)
+{
+  /* OpenType doesn't have vertical-kerning other than GPOS. */
+  return 0;
+}
+
+static hb_bool_t
+hb_jdk_get_glyph_extents (hb_font_t *font HB_UNUSED,
+			 void *font_data,
+			 hb_codepoint_t glyph,
+			 hb_glyph_extents_t *extents,
+			 void *user_data HB_UNUSED)
+{
+  /* TODO */
+  return false;
+}
+
+static hb_bool_t
+hb_jdk_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
+			       void *font_data,
+			       hb_codepoint_t glyph,
+			       unsigned int point_index,
+			       hb_position_t *x,
+			       hb_position_t *y,
+			       void *user_data HB_UNUSED)
+{
+    if ((glyph & 0xfffe) == 0xfffe) {
+        *x = 0; *y = 0;
+        return true;
+    }
+
+    JDKFontInfo *jdkFontInfo = (JDKFontInfo*)font_data;
+    JNIEnv* env = jdkFontInfo->env;
+    jobject fontStrike = jdkFontInfo->fontStrike;
+    jobject pt = env->CallObjectMethod(fontStrike,
+                                       sunFontIDs.getGlyphPointMID,
+                                       glyph, point_index);
+  
+    if (pt == NULL) {
+        *x = 0; *y = 0;
+        return true;
+    }
+    *x = FloatToF26Dot6(env->GetFloatField(pt, sunFontIDs.xFID));
+    *y = FloatToF26Dot6(env->GetFloatField(pt, sunFontIDs.yFID));
+    env->DeleteLocalRef(pt);
+
+  return true;
+}
+
+static hb_bool_t
+hb_jdk_get_glyph_name (hb_font_t *font HB_UNUSED,
+		      void *font_data,
+		      hb_codepoint_t glyph,
+		      char *name, unsigned int size,
+		      void *user_data HB_UNUSED)
+{
+  return false;
+}
+
+static hb_bool_t
+hb_jdk_get_glyph_from_name (hb_font_t *font HB_UNUSED,
+			   void *font_data,
+			   const char *name, int len,
+			   hb_codepoint_t *glyph,
+			   void *user_data HB_UNUSED)
+{
+  return false;
+}
+
+// remind : can we initialise this from the code we call
+// from the class static method in Java to make it
+// completely thread safe.
+static hb_font_funcs_t *
+_hb_jdk_get_font_funcs (void)
+{
+  static hb_font_funcs_t *jdk_ffuncs = NULL;
+  hb_font_funcs_t *ff;
+
+  if (!jdk_ffuncs) {
+      ff = hb_font_funcs_create(); 
+      
+      hb_font_funcs_set_glyph_func(ff, hb_jdk_get_glyph, NULL, NULL);
+      hb_font_funcs_set_glyph_h_advance_func(ff,
+                    hb_jdk_get_glyph_h_advance, NULL, NULL);
+      hb_font_funcs_set_glyph_v_advance_func(ff,
+                    hb_jdk_get_glyph_v_advance, NULL, NULL);
+      hb_font_funcs_set_glyph_h_origin_func(ff,
+                    hb_jdk_get_glyph_h_origin, NULL, NULL);
+      hb_font_funcs_set_glyph_v_origin_func(ff,
+                    hb_jdk_get_glyph_v_origin, NULL, NULL);
+      hb_font_funcs_set_glyph_h_kerning_func(ff,
+                    hb_jdk_get_glyph_h_kerning, NULL, NULL);
+      hb_font_funcs_set_glyph_v_kerning_func(ff,
+                    hb_jdk_get_glyph_v_kerning, NULL, NULL);
+      hb_font_funcs_set_glyph_extents_func(ff,
+                    hb_jdk_get_glyph_extents, NULL, NULL);
+      hb_font_funcs_set_glyph_contour_point_func(ff,
+                    hb_jdk_get_glyph_contour_point, NULL, NULL);
+      hb_font_funcs_set_glyph_name_func(ff,
+                    hb_jdk_get_glyph_name, NULL, NULL);
+      hb_font_funcs_set_glyph_from_name_func(ff,
+                    hb_jdk_get_glyph_from_name, NULL, NULL);
+      hb_font_funcs_make_immutable(ff); // done setting functions.
+      jdk_ffuncs = ff;
+  }
+  return jdk_ffuncs;
+}
+
+static void _do_nothing(void) {
+}
+
+static hb_blob_t *
+reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) {
+
+  JDKFontInfo *jdkFontInfo = (JDKFontInfo*)user_data;
+  JNIEnv* env = jdkFontInfo->env;
+  jobject font2D = jdkFontInfo->font2D;
+  jsize length;
+  jbyte* buffer;
+  
+  // HB_TAG_NONE is 0 and is used to get the whole font file.
+  // It is not expected not be needed for JDK.
+  if (tag == 0) {
+      return NULL;
+  }
+  jbyteArray tableBytes = (jbyteArray)
+     env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag);
+  if (tableBytes == NULL) {
+      return NULL;
+  }
+  length = env->GetArrayLength(tableBytes);
+  buffer = new jbyte[length];
+  env->GetByteArrayRegion(tableBytes, 0, length, buffer);
+
+  return hb_blob_create((const char *)buffer, length,
+                         HB_MEMORY_MODE_WRITABLE,
+                         buffer, free);
+}
+
+hb_face_t*
+hb_jdk_face_create(JDKFontInfo *jdkFontInfo,
+                   hb_destroy_func_t destroy) {
+
+    hb_face_t *face =
+         hb_face_create_for_tables(reference_table, jdkFontInfo, destroy);
+
+    return face;
+}
+
+static hb_font_t* _hb_jdk_font_create(JDKFontInfo *jdkFontInfo,
+                                      hb_destroy_func_t destroy) {
+
+    hb_font_t *font;
+    hb_face_t *face;
+
+    face = hb_jdk_face_create(jdkFontInfo, destroy);
+    font = hb_font_create(face);
+    hb_face_destroy (face);
+    hb_font_set_funcs (font,
+                       _hb_jdk_get_font_funcs (),
+                       jdkFontInfo, (hb_destroy_func_t) _do_nothing);
+    hb_font_set_scale (font,
+                      FloatToF26Dot6(jdkFontInfo->xPtSize),
+                      FloatToF26Dot6(jdkFontInfo->yPtSize));
+  return font;
+}
+
+#ifdef MACOSX
+static hb_font_t* _hb_jdk_ct_font_create(JDKFontInfo *jdkFontInfo) {
+
+    hb_font_t *font = NULL;
+    hb_face_t *face = NULL;
+    if (jdkFontInfo->nativeFont == 0) {
+        return NULL;
+    }
+    face = hb_coretext_face_create((CGFontRef)(jdkFontInfo->nativeFont));
+    font = hb_font_create(face);
+    hb_face_destroy(face);
+
+    hb_font_set_scale(font,
+                     FloatToF26Dot6(jdkFontInfo->ptSize),
+                     FloatToF26Dot6(jdkFontInfo->ptSize));
+    return font;
+}
+#endif
+
+hb_font_t* hb_jdk_font_create(JDKFontInfo *jdkFontInfo,
+                             hb_destroy_func_t destroy) {
+
+   hb_font_t* font = NULL;
+
+#ifdef MACOSX
+     if (jdkFontInfo->aat) {
+         font = _hb_jdk_ct_font_create(jdkFontInfo);
+     }
+#endif
+    if (font == NULL) {
+        font = _hb_jdk_font_create(jdkFontInfo, destroy);
+    }
+    return font;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef HB_JDK_H
+#define HB_JDK_H
+
+#include "hb.h"
+#include <jni.h>
+#include <sunfontids.h>
+
+# ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct JDKFontInfo_Struct {
+    JNIEnv* env;
+    jobject font2D;
+    jobject fontStrike;
+    long nativeFont;
+    float matrix[4];
+    float ptSize;
+    float xPtSize;
+    float yPtSize;
+    jboolean aat;
+} JDKFontInfo;
+
+
+/*
+ * Note:
+ *
+ * Set face size on ft-face before creating hb-font from it.
+ * Otherwise hb-ft would NOT pick up the font size correctly.
+ */
+
+hb_face_t *
+hb_jdk_face_create(JDKFontInfo*   jdkFontInfo,
+                   hb_destroy_func_t destroy);
+hb_font_t *
+hb_jdk_font_create(JDKFontInfo*   jdkFontInfo,
+                   hb_destroy_func_t destroy);
+
+
+/* Makes an hb_font_t use JDK internally to implement font functions. */
+void
+hb_jdk_font_set_funcs(hb_font_t *font);
+
+
+# ifdef __cplusplus
+}
+#endif
+
+#endif /* HB_JDK_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/scriptMapping.c	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "scriptMapping.h"
+/*
+ * Java level-code has a script code indexes that correspond to
+ * the indexes used by the ICU layout library. In order to call
+ * harfbuzz we must map these to the equivalent harfbuzz codes.
+ * Some of these happen to be the same but not many.
+ */
+
+hb_script_t ICU_to_Harfbuzz_ScriptCode[] = {
+
+    HB_SCRIPT_COMMON,           /* 0 */
+    HB_SCRIPT_INHERITED,        /* 1 */
+    HB_SCRIPT_ARABIC,           /* 2 */
+    HB_SCRIPT_ARMENIAN,         /* 3 */
+    HB_SCRIPT_BENGALI,          /* 4 */
+    HB_SCRIPT_BOPOMOFO,         /* 5 */
+    HB_SCRIPT_CHEROKEE,         /* 6 */
+    HB_SCRIPT_COPTIC,           /* 7 */
+    HB_SCRIPT_CYRILLIC,         /* 8 */
+    HB_SCRIPT_DESERET,          /* 9 */
+    HB_SCRIPT_DEVANAGARI,       /* 10 */
+    HB_SCRIPT_ETHIOPIC,         /* 11 */
+    HB_SCRIPT_GEORGIAN,         /* 12 */
+    HB_SCRIPT_GOTHIC,           /* 13 */
+    HB_SCRIPT_GREEK,            /* 14 */
+    HB_SCRIPT_GUJARATI,         /* 15 */
+    HB_SCRIPT_GURMUKHI,         /* 16 */
+    HB_SCRIPT_HAN,              /* 17 */
+    HB_SCRIPT_HANGUL,           /* 18 */
+    HB_SCRIPT_HEBREW,           /* 19 */
+    HB_SCRIPT_HIRAGANA,         /* 20 */
+    HB_SCRIPT_KANNADA,          /* 21 */
+    HB_SCRIPT_KATAKANA,         /* 22 */
+    HB_SCRIPT_KHMER,            /* 23 */
+    HB_SCRIPT_LAO,              /* 24 */
+    HB_SCRIPT_LATIN,            /* 25 */
+    HB_SCRIPT_MALAYALAM,        /* 26 */
+    HB_SCRIPT_MONGOLIAN,        /* 27 */
+    HB_SCRIPT_MYANMAR,          /* 28 */
+    HB_SCRIPT_OGHAM,            /* 29 */
+    HB_SCRIPT_OLD_ITALIC,       /* 30 */
+    HB_SCRIPT_ORIYA,            /* 31 */
+    HB_SCRIPT_RUNIC,            /* 32 */
+    HB_SCRIPT_SINHALA,          /* 33 */
+    HB_SCRIPT_SYRIAC,           /* 34 */
+    HB_SCRIPT_TAMIL,            /* 35 */
+    HB_SCRIPT_TELUGU,           /* 36 */
+    HB_SCRIPT_THAANA,           /* 37 */
+    HB_SCRIPT_THAI,             /* 38 */
+    HB_SCRIPT_TIBETAN,          /* 39 */
+    HB_SCRIPT_CANADIAN_SYLLABICS,   /* 40 */
+    HB_SCRIPT_YI,               /* 41 */
+    HB_SCRIPT_TAGALOG,          /* 42 */
+    HB_SCRIPT_HANUNOO,          /* 43 */
+    HB_SCRIPT_BUHID,            /* 44 */
+    HB_SCRIPT_TAGBANWA,         /* 45 */
+
+};
+
+int MAX_ICU_SCRIPTCODE = 45;
+
+hb_script_t getHBScriptCode(int code) {
+    if (code > MAX_ICU_SCRIPTCODE) {
+        return HB_SCRIPT_INVALID;
+    }
+    return ICU_to_Harfbuzz_ScriptCode[code];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/scriptMapping.h	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <hb.h>
+
+extern int MAX_ICU_SCRIPTCODE;
+
+extern hb_script_t ICU_to_Harfbuzz_ScriptCode[];
+
+hb_script_t getHBScriptCode(int code);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/TextLayout/TestLayoutVsICU.java	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,889 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Copyright (C) 2013-2014 IBM Corporation and Others. All Rights Reserved.
+ */
+
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontFormatException;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Paint;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.RenderingHints.Key;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.TextLayout;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.AttributedCharacterIterator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.TreeMap;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * This test runs against a test XML file. It opens the fonts and attempts
+ * to shape and layout glyphs.
+ * Note that the test is highly environment dependent- you must have
+ * the same versions of the same fonts available or the test will fail.
+ *
+ * It is similar to letest which is part of ICU.
+ * For reference, here are some reference items:
+ * ICU's test file:
+ *  http://source.icu-project.org/repos/icu/icu/trunk/source/test/testdata/letest.xml
+ * ICU's readme for the similar test:
+ *  http://source.icu-project.org/repos/icu/icu/trunk/source/test/letest/readme.html
+ *
+ * @bug 8054203
+ * @test
+ * @summary manual test of layout engine behavior. Takes an XML control file.
+ * @compile TestLayoutVsICU.java
+ * @author srl
+ * @run main/manual
+ */
+public class TestLayoutVsICU {
+
+    public static boolean OPT_DRAW = false;
+    public static boolean OPT_VERBOSE = false;
+    public static boolean OPT_FAILMISSING = false;
+    public static boolean OPT_NOTHROW= false; // if true - don't stop on failure
+
+    public static int docs = 0; // # docs processed
+    public static int skipped = 0; // cases skipped due to bad font
+    public static int total = 0; // cases processed
+    public static int bad = 0; // cases with errs
+
+    public static final String XML_LAYOUT_TESTS = "layout-tests"; // top level
+    public static final String XML_TEST_CASE = "test-case";
+    public static final String XML_TEST_FONT = "test-font";
+    public static final String XML_TEST_TEXT = "test-text";
+    public static final String XML_RESULT_GLYPHS = "result-glyphs";
+    public static final String XML_ID = "id";
+    public static final String XML_SCRIPT = "script";
+    public static final String XML_NAME = "name";
+    public static final String XML_VERSION = "version";
+    public static final String XML_CHECKSUM = "checksum";
+    public static final String XML_RESULT_INDICES = "result-indices";
+    public static final String XML_RESULT_POSITIONS = "result-positions";
+
+    /**
+     * @param args
+     * @throws IOException
+     * @throws SAXException
+     * @throws ParserConfigurationException
+     */
+    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
+        System.out.println("Java " + System.getProperty("java.version") + " from " + System.getProperty("java.vendor"));
+        TestLayoutVsICU tlvi = null;
+        for(String arg : args) {
+            if(arg.equals("-d")) {
+                OPT_DRAW = true;
+            } else if(arg.equals("-n")) {
+                OPT_NOTHROW = true;
+            } else if(arg.equals("-v")) {
+                OPT_VERBOSE = true;
+            } else if(arg.equals("-f")) {
+                OPT_FAILMISSING = true;
+            } else {
+                if(tlvi == null) {
+                    tlvi = new TestLayoutVsICU();
+                }
+                try {
+                    tlvi.show(arg);
+                } finally {
+                    if(OPT_VERBOSE) {
+                        System.out.println("# done with " + arg);
+                    }
+                }
+            }
+        }
+
+        if(tlvi == null) {
+            throw new IllegalArgumentException("No XML input. Usage: " + TestLayoutVsICU.class.getSimpleName() + " [-d][-v][-f] letest.xml ...");
+        } else {
+            System.out.println("\n\nRESULTS:\n");
+            System.out.println(skipped+"\tskipped due to missing font");
+            System.out.println(total+"\ttested of which:");
+            System.out.println(bad+"\twere bad");
+
+            if(bad>0) {
+                throw new InternalError("One or more failure(s)");
+            }
+        }
+    }
+
+    String id;
+
+    private void show(String arg) throws ParserConfigurationException, SAXException, IOException {
+        id = "<none>";
+        File xmlFile = new File(arg);
+        if(!xmlFile.exists()) {
+            throw new FileNotFoundException("Can't open input XML file " + arg);
+        }
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        DocumentBuilder db = dbf.newDocumentBuilder();
+        if(OPT_VERBOSE) {
+            System.out.println("# Parsing " + xmlFile.getAbsolutePath());
+        }
+        Document doc = db.parse(xmlFile);
+        Element e = doc.getDocumentElement();
+        if(!XML_LAYOUT_TESTS.equals(e.getNodeName())) {
+            throw new IllegalArgumentException("Document " + xmlFile.getAbsolutePath() + " does not have <layout-tests> as its base");
+        }
+
+        NodeList testCases = e.getElementsByTagName(XML_TEST_CASE);
+        for(int caseNo=0;caseNo<testCases.getLength();caseNo++) {
+            final Node testCase = testCases.item(caseNo);
+            final Map<String,String> testCaseAttrs = attrs(testCase);
+            id = testCaseAttrs.get(XML_ID);
+            final String script = testCaseAttrs.get(XML_SCRIPT);
+            String testText = null;
+            Integer[] expectGlyphs = null;
+            Integer[] expectIndices = null;
+            Map<String,String> fontAttrs = null;
+            if(OPT_VERBOSE) {
+                System.out.println("#"+caseNo+" id="+id + ", script="+script);
+            }
+            NodeList children = testCase.getChildNodes();
+            for(int sub=0;sub<children.getLength();sub++) {
+                Node n = children.item(sub);
+                if(n.getNodeType()!=Node.ELEMENT_NODE) continue;
+                String nn = n.getNodeName();
+                if(nn.equals(XML_TEST_FONT)) {
+                    fontAttrs = attrs(n);
+                } else if(nn.equals(XML_TEST_TEXT)) {
+                    testText = n.getTextContent();
+                } else if(nn.equals(XML_RESULT_GLYPHS)) {
+                    String hex = n.getTextContent();
+                    expectGlyphs = parseHexArray(hex);
+                } else if(nn.equals(XML_RESULT_INDICES)) {
+                    String hex = n.getTextContent();
+                    expectIndices = parseHexArray(hex);
+                } else if(OPT_VERBOSE) {
+                    System.out.println("Ignoring node " + nn);
+                }
+            }
+            if(fontAttrs == null) {
+                throw new IllegalArgumentException(id + " Missing node " + XML_TEST_FONT);
+            }
+            if(testText == null) {
+                throw new IllegalArgumentException(id + " Missing node " + XML_TEST_TEXT);
+            }
+
+            String fontName = fontAttrs.get(XML_NAME);
+            Font f = getFont(fontName, fontAttrs);
+            if(f==null) {
+                if(OPT_FAILMISSING) {
+                    throw new MissingResourceException("Missing font,  abort test", Font.class.getName(), fontName);
+                }
+                System.out.println("Skipping " + id + " because font is missing: " + fontName);
+                skipped++;
+                continue;
+            }
+            FontRenderContext frc = new FontRenderContext(null, true, true);
+            TextLayout tl = new TextLayout(testText,f,frc);
+            final List<GlyphVector> glyphs = new ArrayList<GlyphVector>();
+            Graphics2D myg2 = new Graphics2D(){
+
+                    @Override
+                    public void draw(Shape s) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public boolean drawImage(Image img, AffineTransform xform,
+                                             ImageObserver obs) {
+                        // TODO Auto-generated method stub
+                        return false;
+                    }
+
+                    @Override
+                    public void drawImage(BufferedImage img,
+                                          BufferedImageOp op, int x, int y) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawRenderedImage(RenderedImage img,
+                                                  AffineTransform xform) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawRenderableImage(RenderableImage img,
+                                                    AffineTransform xform) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawString(String str, int x, int y) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawString(String str, float x, float y) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawString(
+                                           AttributedCharacterIterator iterator, int x, int y) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawString(
+                                           AttributedCharacterIterator iterator, float x,
+                                           float y) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawGlyphVector(GlyphVector g, float x, float y) {
+                        if(x!=0.0 || y!=0.0) {
+                            throw new InternalError("x,y should be 0 but got " + x+","+y);
+                        }
+                        //System.err.println("dGV : " + g.toString() + " @ "+x+","+y);
+                        glyphs.add(g);
+                    }
+
+                    @Override
+                    public void fill(Shape s) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
+                        // TODO Auto-generated method stub
+                        return false;
+                    }
+
+                    @Override
+                    public GraphicsConfiguration getDeviceConfiguration() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void setComposite(Composite comp) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void setPaint(Paint paint) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void setStroke(Stroke s) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void setRenderingHint(Key hintKey, Object hintValue) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public Object getRenderingHint(Key hintKey) {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void setRenderingHints(Map<?, ?> hints) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void addRenderingHints(Map<?, ?> hints) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public RenderingHints getRenderingHints() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void translate(int x, int y) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void translate(double tx, double ty) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void rotate(double theta) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void rotate(double theta, double x, double y) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void scale(double sx, double sy) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void shear(double shx, double shy) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void transform(AffineTransform Tx) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void setTransform(AffineTransform Tx) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public AffineTransform getTransform() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public Paint getPaint() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public Composite getComposite() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void setBackground(Color color) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public Color getBackground() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public Stroke getStroke() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void clip(Shape s) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public FontRenderContext getFontRenderContext() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public Graphics create() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public Color getColor() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void setColor(Color c) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void setPaintMode() {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void setXORMode(Color c1) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public Font getFont() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void setFont(Font font) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public FontMetrics getFontMetrics(Font f) {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public Rectangle getClipBounds() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void clipRect(int x, int y, int width, int height) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void setClip(int x, int y, int width, int height) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public Shape getClip() {
+                        // TODO Auto-generated method stub
+                        return null;
+                    }
+
+                    @Override
+                    public void setClip(Shape clip) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void copyArea(int x, int y, int width, int height,
+                                         int dx, int dy) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawLine(int x1, int y1, int x2, int y2) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void fillRect(int x, int y, int width, int height) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void clearRect(int x, int y, int width, int height) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawRoundRect(int x, int y, int width,
+                                              int height, int arcWidth, int arcHeight) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void fillRoundRect(int x, int y, int width,
+                                              int height, int arcWidth, int arcHeight) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawOval(int x, int y, int width, int height) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void fillOval(int x, int y, int width, int height) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawArc(int x, int y, int width, int height,
+                                        int startAngle, int arcAngle) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void fillArc(int x, int y, int width, int height,
+                                        int startAngle, int arcAngle) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawPolyline(int[] xPoints, int[] yPoints,
+                                             int nPoints) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void drawPolygon(int[] xPoints, int[] yPoints,
+                                            int nPoints) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public void fillPolygon(int[] xPoints, int[] yPoints,
+                                            int nPoints) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    @Override
+                    public boolean drawImage(Image img, int x, int y,
+                                             ImageObserver observer) {
+                        // TODO Auto-generated method stub
+                        return false;
+                    }
+
+                    @Override
+                    public boolean drawImage(Image img, int x, int y,
+                                             int width, int height, ImageObserver observer) {
+                        // TODO Auto-generated method stub
+                        return false;
+                    }
+
+                    @Override
+                    public boolean drawImage(Image img, int x, int y,
+                                             Color bgcolor, ImageObserver observer) {
+                        // TODO Auto-generated method stub
+                        return false;
+                    }
+
+                    @Override
+                    public boolean drawImage(Image img, int x, int y,
+                                             int width, int height, Color bgcolor,
+                                             ImageObserver observer) {
+                        // TODO Auto-generated method stub
+                        return false;
+                    }
+
+                    @Override
+                    public boolean drawImage(Image img, int dx1, int dy1,
+                                             int dx2, int dy2, int sx1, int sy1, int sx2,
+                                             int sy2, ImageObserver observer) {
+                        // TODO Auto-generated method stub
+                        return false;
+                    }
+
+                    @Override
+                    public boolean drawImage(Image img, int dx1, int dy1,
+                                             int dx2, int dy2, int sx1, int sy1, int sx2,
+                                             int sy2, Color bgcolor, ImageObserver observer) {
+                        // TODO Auto-generated method stub
+                        return false;
+                    }
+
+                    @Override
+                    public void dispose() {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                };
+            tl.draw(myg2, 0, 0);
+            if(glyphs.size() != 1) {
+                err("drew " + glyphs.size() + " times - expected 1");
+                total++;
+                bad++;
+                continue;
+            }
+            boolean isBad = false;
+            GlyphVector gv = glyphs.get(0);
+
+            // GLYPHS
+            int gotGlyphs[] = gv.getGlyphCodes(0, gv.getNumGlyphs(), new int[gv.getNumGlyphs()]);
+
+            int count = Math.min(gotGlyphs.length, expectGlyphs.length); // go up to this count
+
+            for(int i=0;i<count;i++) {
+                if(gotGlyphs[i]!=expectGlyphs[i]) {
+                    err("@"+i+" - got \tglyph 0x" + Integer.toHexString(gotGlyphs[i]) + " wanted 0x" + Integer.toHexString(expectGlyphs[i]));
+                    isBad=true;
+                    break;
+                }
+            }
+
+            // INDICES
+            int gotIndices[] = gv.getGlyphCharIndices(0, gv.getNumGlyphs(), new int[gv.getNumGlyphs()]);
+            for(int i=0;i<count;i++) {
+                if(gotIndices[i]!=expectIndices[i]) {
+                    err("@"+i+" - got \tindex 0x" + Integer.toHexString(gotGlyphs[i]) + " wanted 0x" + Integer.toHexString(expectGlyphs[i]));
+                    isBad=true;
+                    break;
+                }
+            }
+
+
+            // COUNT
+            if(gotGlyphs.length != expectGlyphs.length) {
+                System.out.println("Got " + gotGlyphs.length + " wanted " + expectGlyphs.length + " glyphs");
+                isBad=true;
+            } else {
+                if(OPT_VERBOSE) {
+                    System.out.println(">> OK: " + gotGlyphs.length + " glyphs");
+                }
+            }
+
+
+            if(isBad) {
+                bad++;
+                System.out.println("* FAIL: " + id + "  /\t" + fontName);
+            } else {
+                System.out.println("* OK  : " + id + "  /\t" + fontName);
+            }
+            total++;
+        }
+    }
+
+
+    private boolean verifyFont(File f, Map<String, String> fontAttrs) {
+        InputStream fis = null;
+        String fontName = fontAttrs.get(XML_NAME);
+        int count=0;
+        try {
+            fis = new BufferedInputStream(new FileInputStream(f));
+
+            int i = 0;
+            int r;
+            try {
+                while((r=fis.read())!=-1) {
+                    i+=(int)r;
+                    count++;
+                }
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+                return false;
+            }
+            if(OPT_VERBOSE) {
+                System.out.println("for " + f.getAbsolutePath() + " chks = 0x" + Integer.toHexString(i) + " size=" + count);
+            }
+            String theirStr = fontAttrs.get("rchecksum");
+
+            String ourStr = Integer.toHexString(i).toLowerCase();
+
+            if(theirStr!=null) {
+                if(theirStr.startsWith("0x")) {
+                    theirStr = theirStr.substring(2).toLowerCase();
+                } else {
+                    theirStr = theirStr.toLowerCase();
+                }
+                long theirs = Integer.parseInt(theirStr, 16);
+                if(theirs != i) {
+                    err("WARNING: rchecksum for " + fontName + " was " + i  + " (0x"+ourStr+") "+ " but file said " + theirs +" (0x"+theirStr+")  - perhaps a different font?");
+                    return false;
+                } else {
+                    if(OPT_VERBOSE) {
+                        System.out.println(" rchecksum for " + fontName + " OK");
+                    }
+                    return true;
+                }
+            } else {
+                //if(OPT_VERBOSE) {
+                System.err.println("WARNING: rchecksum for " + fontName + " was " + i  + " (0x"+ourStr+") "+ " but rchecksum was MISSING. Old ICU data?");
+                //}
+            }
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            return false;
+        } finally {
+            try {
+                fis.close();
+            } catch (IOException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+        return true;
+    }
+
+
+    private Integer[] parseHexArray(String hex) {
+        List<Integer> ret = new ArrayList<Integer>();
+        String items[] = hex.split("[\\s,]");
+        for(String i : items) {
+            if(i.isEmpty()) continue;
+            if(i.startsWith("0x")) {
+                i = i.substring(2);
+            }
+            ret.add(Integer.parseInt(i, 16));
+        }
+        return ret.toArray(new Integer[0]);
+    }
+
+
+    private void err(String string) {
+        if(OPT_NOTHROW) {
+            System.out.println(id+" ERROR: " + string +" (continuing due to -n)");
+        } else {
+            throw new InternalError(id+ ": " + string);
+        }
+    }
+
+
+    private Font getFont(String fontName, Map<String, String> fontAttrs) {
+        Font f;
+        if(false)
+            try {
+                f = Font.getFont(fontName);
+                if(f!=null)  {
+                    if(OPT_VERBOSE) {
+                        System.out.println("Loaded default path to " + fontName);
+                    }
+                    return f;
+                }
+            } catch(Throwable t) {
+                if(OPT_VERBOSE) {
+                    t.printStackTrace();
+                    System.out.println("problem loading font " + fontName + " - " + t.toString());
+                }
+            }
+
+        File homeDir = new File(System.getProperty("user.home"));
+        File fontDir = new File(homeDir, "fonts");
+        File fontFile = new File(fontDir, fontName);
+        //System.out.println("## trying " + fontFile.getAbsolutePath());
+        if(fontFile.canRead()) {
+            try {
+                if(!verifyFont(fontFile,fontAttrs)) {
+                    System.out.println("Warning: failed to verify " + fontName);
+                }
+                f = Font.createFont(Font.TRUETYPE_FONT, fontFile);
+                if(f!=null & OPT_VERBOSE) {
+                    System.out.println("> loaded from " + fontFile.getAbsolutePath() + " - " + f.toString());
+                }
+                return f;
+            } catch (FontFormatException e) {
+                if(OPT_VERBOSE) {
+                    e.printStackTrace();
+                    System.out.println("problem loading font " + fontName + " - " + e.toString());
+                }
+            } catch (IOException e) {
+                if(OPT_VERBOSE) {
+                    e.printStackTrace();
+                    System.out.println("problem loading font " + fontName + " - " + e.toString());
+                }
+            }
+        }
+        return null;
+    }
+
+
+    private static Map<String, String> attrs(Node testCase) {
+        Map<String,String> rv = new TreeMap<String,String>();
+        NamedNodeMap nnm = testCase.getAttributes();
+        for(int i=0;i<nnm.getLength();i++) {
+            Node n = nnm.item(i);
+            String k = n.getNodeName();
+            String v = n.getNodeValue();
+            rv.put(k, v);
+        }
+        return rv;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/TextLayout/TestLayoutVsICU_jdkbase.xml	Mon Nov 23 09:58:44 2015 -0800
@@ -0,0 +1,1827 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-->
+<!--
+   NOTE: You are unlikely to have all needed fonts.
+ -->
+<!--
+  Copyright (c) 1999-2014 International Business Machines
+  Corporation and others. All rights reserved.
+
+  WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT
+  UNLESS YOU REALLY KNOW WHAT YOU'RE DOING.
+
+  file name:    letest.xml
+  generated on: 03/04/2013 10:28:51 PM PST
+  generated by: gendata.cpp
+-->
+
+<layout-tests>
+    <test-case id="Ghita" script="deva">
+        <test-font name="raghu.ttf" version="Original Version 1.00 (2005)" checksum="0x088DB135" rchecksum="0x00803FCE"/>
+
+        <test-text>श्रीमद् भगवद्गीता अध्याय अर्जुन विषाद योग धृतराष्ट्र उवाचृ धर्मक्षेत्रे कुरुक्षेत्रे समवेता युयुत्सवः मामकाः पाण्डवाश्चैव किमकुर्वत संजव</test-text>
+
+        <result-glyphs>
+            0x0000009E, 0x0000009A, 0x00000051, 0x00000222, 0x00000098, 0x00000091, 0x00000051, 0x00000003, 
+            0x00000097, 0x00000082, 0x0000009D, 0x000001A5, 0x0000FFFF, 0x0000FFFF, 0x00000222, 0x0000008F, 
+            0x00000221, 0x00000003, 0x0000005C, 0x000000DA, 0x0000FFFF, 0x00000099, 0x00000221, 0x00000099, 
+            0x00000003, 0x0000005C, 0x00000087, 0x000001D5, 0x0000005B, 0x0000FFFF, 0x00000093, 0x00000003, 
+            0x000001D2, 0x0000009D, 0x0000009F, 0x00000221, 0x00000091, 0x00000003, 0x00000099, 0x0000022A, 
+            0x00000082, 0x00000003, 0x00000092, 0x000001D9, 0x0000008F, 0x0000009A, 0x00000221, 0x000001B4, 
+            0x0000FFFF, 0x0000FFFF, 0x0000009A, 0x00000051, 0x00000003, 0x00000060, 0x0000009D, 0x00000221, 
+            0x00000085, 0x000001D9, 0x00000003, 0x00000092, 0x00000098, 0x0000005B, 0x0000FFFF, 0x000000A2, 
+            0x0000FFFF, 0x0000FFFF, 0x0000022F, 0x0000008F, 0x0000009A, 0x00000051, 0x0000022F, 0x00000003, 
+            0x00000080, 0x000001D5, 0x0000009A, 0x000001FD, 0x000000A2, 0x0000FFFF, 0x0000FFFF, 0x0000022F, 
+            0x0000008F, 0x0000009A, 0x00000051, 0x0000022F, 0x00000003, 0x000000A0, 0x00000098, 0x0000009D, 
+            0x0000022F, 0x0000008F, 0x00000221, 0x00000003, 0x00000099, 0x000001D5, 0x00000099, 0x000001D5, 
+            0x000000D7, 0x0000FFFF, 0x000000A0, 0x0000009D, 0x0000022C, 0x00000003, 0x00000098, 0x00000221, 
+            0x00000098, 0x00000080, 0x00000221, 0x0000022C, 0x00000003, 0x00000094, 0x00000221, 0x000000D6, 
+            0x0000FFFF, 0x0000008C, 0x0000009D, 0x00000221, 0x000001B1, 0x0000FFFF, 0x0000FFFF, 0x00000230, 
+            0x0000009D, 0x00000003, 0x000001D1, 0x00000080, 0x00000098, 0x00000080, 0x000001D5, 0x0000009D, 
+            0x0000005B, 0x0000FFFF, 0x0000008F, 0x00000003, 0x000000A0, 0x00000232, 0x00000087, 0x0000009D
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 
+            0x00000018, 0x00000019, 0x0000001C, 0x0000001D, 0x0000001A, 0x0000001B, 0x0000001E, 0x0000001F, 
+            0x00000021, 0x00000020, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026, 0x00000027, 
+            0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, 0x0000002E, 0x0000002F, 
+            0x00000030, 0x00000031, 0x00000033, 0x00000032, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 
+            0x00000038, 0x00000039, 0x0000003A, 0x0000003B, 0x0000003E, 0x0000003C, 0x0000003D, 0x0000003F, 
+            0x00000040, 0x00000041, 0x00000042, 0x00000043, 0x00000045, 0x00000044, 0x00000046, 0x00000047, 
+            0x00000048, 0x00000049, 0x0000004A, 0x0000004B, 0x0000004C, 0x0000004D, 0x0000004E, 0x0000004F, 
+            0x00000050, 0x00000052, 0x00000051, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 
+            0x00000058, 0x00000059, 0x0000005A, 0x0000005B, 0x0000005C, 0x0000005D, 0x0000005E, 0x0000005F, 
+            0x00000060, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 
+            0x00000068, 0x00000069, 0x0000006A, 0x0000006B, 0x0000006C, 0x0000006D, 0x0000006E, 0x0000006F, 
+            0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 
+            0x00000078, 0x00000079, 0x0000007B, 0x0000007A, 0x0000007C, 0x0000007D, 0x0000007E, 0x00000081, 
+            0x0000007F, 0x00000080, 0x00000082, 0x00000083, 0x00000084, 0x00000085, 0x00000086, 0x00000087
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 9.468750, 0.000000, 19.130859, -0.451172, 15.984375, 0.000000, 
+            19.640625, 0.000000, 29.109375, 0.000000, 40.177734, -0.451172, 37.078125, 0.000000, 
+            43.078125, 0.000000, 52.546875, 0.000000, 62.015625, 0.000000, 69.984375, 0.000000, 
+            77.953125, 0.000000, 77.953125, 0.000000, 77.953125, 0.000000, 81.609375, 0.000000, 
+            89.578125, 0.000000, 93.234375, 0.000000, 99.234375, 0.000000, 109.171875, 0.000000, 
+            116.437500, 0.000000, 116.437500, 0.000000, 125.906250, 0.000000, 129.562500, 0.000000, 
+            139.031250, 0.000000, 145.031250, 0.000000, 154.968750, 0.000000, 164.718750, -0.011719, 
+            164.718750, 0.263672, 164.437500, 0.000000, 164.437500, 0.000000, 173.906250, 0.000000, 
+            179.906250, 0.000000, 184.265625, 0.000000, 192.234375, 0.000000, 200.203125, 0.000000, 
+            203.859375, 0.000000, 211.828125, 0.000000, 217.828125, 0.000000, 227.296875, 0.000000, 
+            231.375000, 0.000000, 240.843750, 0.000000, 246.843750, 0.000000, 256.740234, -0.011719, 
+            256.312500, 0.000000, 264.281250, 0.000000, 270.796875, 0.000000, 274.453125, 0.000000, 
+            282.796875, 0.000000, 282.796875, 0.000000, 282.796875, 0.000000, 292.458984, -0.451172, 
+            289.312500, 0.000000, 295.312500, 0.000000, 303.281250, 0.000000, 311.250000, 0.000000, 
+            314.906250, 0.000000, 324.890625, -0.011719, 324.375000, 0.000000, 330.375000, 0.000000, 
+            339.843750, 0.000000, 349.675781, 0.263672, 349.312500, 0.000000, 349.312500, 0.000000, 
+            360.187500, 0.000000, 360.187500, 0.000000, 359.384766, 0.275391, 360.187500, 0.000000, 
+            368.156250, 0.000000, 377.818359, -0.451172, 372.996094, 0.263672, 374.671875, 0.000000, 
+            380.671875, 0.000000, 388.371094, -0.011719, 391.546875, 0.000000, 398.062500, 0.000000, 
+            399.421875, 0.000000, 410.296875, 0.000000, 410.296875, 0.000000, 409.494141, 0.275391, 
+            410.296875, 0.000000, 418.265625, 0.000000, 427.927734, -0.451172, 423.105469, 0.263672, 
+            424.781250, 0.000000, 430.781250, 0.000000, 440.250000, 0.000000, 449.718750, 0.000000, 
+            456.832031, 0.263672, 457.687500, 0.000000, 465.656250, 0.000000, 469.312500, 0.000000, 
+            475.312500, 0.000000, 484.921875, -0.011719, 484.781250, 0.000000, 494.390625, -0.011719, 
+            494.250000, 0.000000, 500.179688, 0.000000, 500.179688, 0.000000, 509.648438, 0.000000, 
+            517.617188, 0.000000, 521.976562, 0.000000, 527.976562, 0.000000, 537.445312, 0.000000, 
+            541.101562, 0.000000, 550.570312, 0.000000, 561.445312, 0.000000, 565.101562, 0.000000, 
+            569.460938, 0.000000, 575.460938, 0.000000, 583.429688, 0.000000, 587.085938, 0.000000, 
+            594.351562, 0.000000, 594.351562, 0.000000, 602.320312, 0.000000, 610.289062, 0.000000, 
+            613.945312, 0.000000, 624.820312, 0.000000, 624.820312, 0.000000, 624.691406, 0.263672, 
+            624.820312, 0.000000, 632.789062, 0.000000, 638.789062, 0.000000, 643.148438, 0.000000, 
+            654.023438, 0.000000, 663.492188, 0.000000, 671.191406, -0.011719, 674.367188, 0.000000, 
+            682.628906, 0.263672, 682.335938, 0.000000, 682.335938, 0.000000, 690.304688, 0.000000, 
+            696.304688, 0.000000, 705.140625, 0.439453, 705.773438, 0.000000, 715.242188, 0.000000, 
+            723.210938, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Arabic" script="arab">
+        <test-font name="CODE2000.TTF" version="Version 1.171" checksum="0xD025B1AD" rchecksum="0x1F6E6F2A"/>
+
+        <test-text>أساسًا، تتعامل الحواسيب فقط مع الأرقام، وتقوم بتخزين الأحرف والمحارف الأخرى بعد أن تُعطي رقما معينا لكل واحد منها. وقبل اختراع "يونِكود"، كان هناك مئات الأنظمة للتشفير وتخصيص هذه الأرقام للمحارف، ولم يوجد نظام تشفير واحد يحتوي على جميع المحارف الضرورية</test-text>
+
+        <result-glyphs>
+            0x0000CE28, 0x0000CE87, 0x0000CE41, 0x0000CE81, 0x0000CE42, 0x0000CE54, 0x0000CE73, 0x0000CE21, 
+            0x00000003, 0x0000CE65, 0x0000CE41, 0x0000CE22, 0x0000CE38, 0x0000CE78, 0x0000CE73, 0x0000CE21, 
+            0x00000003, 0x0000CE5E, 0x0000CE88, 0x0000CE78, 0x0000CE33, 0x00000003, 0x0000CE84, 0x0000CE74, 
+            0x0000CE5F, 0x00000003, 0x0000CE85, 0x0000CE82, 0x0000CE2C, 0x0000CE38, 0x0000CE87, 0x00000003, 
+            0x0000CE3E, 0x0000CE37, 0x0000CE21, 0x0000CE81, 0x00000003, 0x0000CE42, 0x0000CE88, 0x0000CE68, 
+            0x0000CE4C, 0x0000CE2B, 0x00000003, 0x0000CE75, 0x0000CE22, 0x0000CE5C, 0x0000CE7B, 0x00000003, 
+            0x0000CE3E, 0x0000CE33, 0x0000CE82, 0x0000CE87, 0x00000003, 0x0000CE76, 0x0000CE73, 0x0000CE81, 
+            0x00000003, 0x00000588, 0x0000CE65, 0x0000CE41, 0x0000CE22, 0x0000CE38, 0x0000CE78, 0x0000CE74, 
+            0x0000CE73, 0x00000003, 0x0000CE75, 0x0000CE22, 0x0000CE6B, 0x0000CE41, 0x0000FFFE, 0x0000CE8B, 
+            0x0000CE21, 0x00000003, 0x0000CE7D, 0x0000CE40, 0x0000CE7F, 0x00000003, 0x0000CE4E, 0x0000CE88, 
+            0x0000CE50, 0x0000CE3C, 0x0000CE2B, 0x0000CE81, 0x00000003, 0x0000CE42, 0x0000CE88, 0x0000CE68, 
+            0x0000CE4C, 0x0000CE2C, 0x0000CE74, 0x0000CE73, 0x00000003, 0x0000CE28, 0x0000CE78, 0x0000CE5C, 
+            0x0000CE7B, 0x0000FFFE, 0x0000CE8B, 0x0000CE21, 0x00000003, 0x0000CE29, 0x0000CE22, 0x0000CE20, 
+            0x0000CE77, 0x00000003, 0x0000CE6D, 0x0000CE22, 0x0000CE7C, 0x0000CE7F, 0x00000003, 0x0000CE79, 
+            0x0000CE22, 0x0000CE6F, 0x00000003, 0x00000588, 0x00000005, 0x0000CE3D, 0x0000CE82, 0x0000CE70, 
+            0x000005B5, 0x0000CE7B, 0x0000CE82, 0x0000CE87, 0x00000005, 0x00000003, 0x0000CE5D, 0x0000CE21, 
+            0x0000CE42, 0x0000CE2C, 0x0000CE3B, 0x0000CE21, 0x00000003, 0x0000CE72, 0x0000CE26, 0x0000CE6B, 
+            0x0000CE81, 0x00000003, 0x00000011, 0x0000CE22, 0x0000CE80, 0x0000CE7C, 0x0000CE77, 0x00000003, 
+            0x0000CE3E, 0x0000CE37, 0x0000CE21, 0x0000CE81, 0x00000003, 0x0000CE72, 0x0000CE70, 0x0000CE73, 
+            0x00000003, 0x0000CE22, 0x0000CE7C, 0x0000CE88, 0x0000CE60, 0x0000CE77, 0x00000003, 0x0000CE22, 
+            0x0000CE78, 0x0000CE6B, 0x0000CE41, 0x00000003, 0x0000CE86, 0x0000CE58, 0x0000CE60, 0x000005B4, 
+            0x0000CE2B, 0x00000003, 0x0000CE79, 0x0000CE17, 0x00000003, 0x0000CE3E, 0x0000CE60, 0x0000CE25, 
+            0x00000003, 0x0000CE83, 0x0000CE42, 0x0000CE3B, 0x0000FFFE, 0x0000CE8B, 0x0000CE21, 0x00000003, 
+            0x0000CE65, 0x0000CE41, 0x0000CE22, 0x0000CE38, 0x0000CE78, 0x0000CE73, 0x0000CE21, 0x0000CE81, 
+            0x00000003, 0x0000CE65, 0x0000CE42, 0x0000CE37, 0x0000FFFE, 0x0000CE8B, 0x0000CE21, 0x00000003, 
+            0x0000CE7A, 0x0000CE87, 0x0000CE44, 0x0000CE3C, 0x0000CE2C, 0x0000CE25, 0x00000003, 0x0000CE75, 
+            0x0000CE82, 0x0000CE6C, 0x0000CE2B, 0x0000CE81, 0x00000003, 0x00000588, 0x0000CE75, 0x0000CE22, 
+            0x0000CE6B, 0x0000CE41, 0x0000FFFE, 0x0000CE8B, 0x0000CE21, 0x00000003, 0x0000CE5E, 0x0000CE77, 
+            0x00000003, 0x0000CE56, 0x0000CE6C, 0x0000CE67, 0x00000003, 0x0000CE24, 0x0000CE88, 0x0000CE47, 
+            0x0000CE21, 0x0000CE82, 0x0000CE38, 0x0000CE73, 0x0000CE21, 0x00000003, 0x0000CE72, 0x0000CE77, 
+            0x0000CE22, 0x0000CE60, 0x0000CE2C, 0x0000CE2B, 0x00000003, 0x00000588, 0x0000CE22, 0x000005B0, 
+            0x0000CE47, 0x0000CE22, 0x0000CE47, 0x0000CE17
+        </result-glyphs>
+
+        <result-indices>
+            0x000000FB, 0x000000FA, 0x000000F9, 0x000000F8, 0x000000F7, 0x000000F6, 0x000000F5, 0x000000F4, 
+            0x000000F3, 0x000000F2, 0x000000F1, 0x000000F0, 0x000000EF, 0x000000EE, 0x000000ED, 0x000000EC, 
+            0x000000EB, 0x000000EA, 0x000000E9, 0x000000E8, 0x000000E7, 0x000000E6, 0x000000E5, 0x000000E4, 
+            0x000000E3, 0x000000E2, 0x000000E1, 0x000000E0, 0x000000DF, 0x000000DE, 0x000000DD, 0x000000DC, 
+            0x000000DB, 0x000000DA, 0x000000D9, 0x000000D8, 0x000000D7, 0x000000D6, 0x000000D5, 0x000000D4, 
+            0x000000D3, 0x000000D2, 0x000000D1, 0x000000D0, 0x000000CF, 0x000000CE, 0x000000CD, 0x000000CC, 
+            0x000000CB, 0x000000CA, 0x000000C9, 0x000000C8, 0x000000C7, 0x000000C6, 0x000000C5, 0x000000C4, 
+            0x000000C3, 0x000000C2, 0x000000C1, 0x000000C0, 0x000000BF, 0x000000BE, 0x000000BD, 0x000000BC, 
+            0x000000BB, 0x000000BA, 0x000000B9, 0x000000B8, 0x000000B7, 0x000000B6, 0x000000B5, 0x000000B4, 
+            0x000000B3, 0x000000B2, 0x000000B1, 0x000000B0, 0x000000AF, 0x000000AE, 0x000000AD, 0x000000AC, 
+            0x000000AB, 0x000000AA, 0x000000A9, 0x000000A8, 0x000000A7, 0x000000A6, 0x000000A5, 0x000000A4, 
+            0x000000A3, 0x000000A2, 0x000000A1, 0x000000A0, 0x0000009F, 0x0000009E, 0x0000009D, 0x0000009C, 
+            0x0000009B, 0x0000009A, 0x00000099, 0x00000098, 0x00000097, 0x00000096, 0x00000095, 0x00000094, 
+            0x00000093, 0x00000092, 0x00000091, 0x00000090, 0x0000008F, 0x0000008E, 0x0000008D, 0x0000008C, 
+            0x0000008B, 0x0000008A, 0x00000089, 0x00000088, 0x00000087, 0x00000086, 0x00000085, 0x00000084, 
+            0x00000083, 0x00000082, 0x00000081, 0x00000080, 0x0000007F, 0x0000007E, 0x0000007D, 0x0000007C, 
+            0x0000007B, 0x0000007A, 0x00000079, 0x00000078, 0x00000077, 0x00000076, 0x00000075, 0x00000074, 
+            0x00000073, 0x00000072, 0x00000071, 0x00000070, 0x0000006F, 0x0000006E, 0x0000006D, 0x0000006C, 
+            0x0000006B, 0x0000006A, 0x00000069, 0x00000068, 0x00000067, 0x00000066, 0x00000065, 0x00000064, 
+            0x00000063, 0x00000062, 0x00000061, 0x00000060, 0x0000005F, 0x0000005E, 0x0000005D, 0x0000005C, 
+            0x0000005B, 0x0000005A, 0x00000059, 0x00000058, 0x00000057, 0x00000056, 0x00000055, 0x00000054, 
+            0x00000053, 0x00000052, 0x00000051, 0x00000050, 0x0000004F, 0x0000004E, 0x0000004D, 0x0000004C, 
+            0x0000004B, 0x0000004A, 0x00000049, 0x00000048, 0x00000047, 0x00000046, 0x00000045, 0x00000044, 
+            0x00000043, 0x00000042, 0x00000041, 0x00000040, 0x0000003F, 0x0000003E, 0x0000003D, 0x0000003C, 
+            0x0000003B, 0x0000003A, 0x00000039, 0x00000038, 0x00000037, 0x00000036, 0x00000035, 0x00000034, 
+            0x00000033, 0x00000032, 0x00000031, 0x00000030, 0x0000002F, 0x0000002E, 0x0000002D, 0x0000002C, 
+            0x0000002B, 0x0000002A, 0x00000029, 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 
+            0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001F, 0x0000001E, 0x0000001D, 0x0000001C, 
+            0x0000001B, 0x0000001A, 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 0x00000014, 
+            0x00000013, 0x00000012, 0x00000011, 0x00000010, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000C, 
+            0x0000000B, 0x0000000A, 0x00000009, 0x00000008, 0x00000007, 0x00000006, 0x00000005, 0x00000004, 
+            0x00000003, 0x00000002, 0x00000001, 0x00000000
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 4.007812, 0.000000, 8.226562, 0.000000, 12.679688, 0.000000, 
+            18.679688, 0.000000, 23.132812, 0.000000, 31.289062, 0.000000, 34.312500, 0.000000, 
+            36.375000, 0.000000, 41.062500, 0.000000, 50.296875, 0.000000, 54.750000, 0.000000, 
+            56.859375, 0.000000, 62.367188, 0.000000, 66.632812, 0.000000, 69.656250, 0.000000, 
+            71.718750, 0.000000, 76.406250, 0.000000, 81.421875, 0.000000, 85.664062, 0.000000, 
+            89.929688, 0.000000, 95.742188, 0.000000, 100.429688, 0.000000, 108.796875, 0.000000, 
+            112.171875, 0.000000, 115.734375, 0.000000, 120.421875, 0.000000, 128.765625, 0.000000, 
+            134.765625, 0.000000, 139.007812, 0.000000, 144.515625, 0.000000, 148.734375, 0.000000, 
+            153.421875, 0.000000, 157.359375, 0.000000, 163.171875, 0.000000, 165.234375, 0.000000, 
+            171.234375, 0.000000, 175.921875, 0.000000, 180.375000, 0.000000, 184.617188, 0.000000, 
+            188.085938, 0.000000, 195.117188, 0.000000, 199.312500, 0.000000, 204.000000, 0.000000, 
+            208.007812, 0.000000, 210.117188, 0.000000, 217.054688, 0.000000, 220.429688, 0.000000, 
+            225.117188, 0.000000, 229.054688, 0.000000, 234.867188, 0.000000, 240.867188, 0.000000, 
+            245.085938, 0.000000, 249.773438, 0.000000, 253.781250, 0.000000, 256.804688, 0.000000, 
+            262.804688, 0.000000, 267.492188, 0.000000, 271.007812, 0.000000, 280.242188, 0.000000, 
+            284.695312, 0.000000, 286.804688, 0.000000, 292.312500, 0.000000, 296.578125, 0.000000, 
+            299.953125, 0.000000, 302.976562, 0.000000, 307.664062, 0.000000, 311.671875, 0.000000, 
+            313.781250, 0.000000, 317.882812, 0.000000, 322.335938, 0.000000, 322.335938, 0.000000, 
+            328.500000, 0.000000, 330.562500, 0.000000, 335.250000, 0.000000, 339.140625, 0.000000, 
+            343.078125, 0.000000, 348.984375, 0.000000, 353.671875, 0.000000, 366.445312, 0.000000, 
+            370.687500, 0.000000, 378.843750, 0.000000, 384.351562, 0.000000, 388.546875, 0.000000, 
+            394.546875, 0.000000, 399.234375, 0.000000, 403.687500, 0.000000, 407.929688, 0.000000, 
+            411.398438, 0.000000, 418.429688, 0.000000, 422.671875, 0.000000, 426.046875, 0.000000, 
+            429.070312, 0.000000, 433.757812, 0.000000, 437.765625, 0.000000, 442.031250, 0.000000, 
+            448.968750, 0.000000, 452.343750, 0.000000, 452.343750, 0.000000, 458.507812, 0.000000, 
+            460.570312, 0.000000, 465.257812, 0.000000, 474.492188, 0.000000, 476.601562, 0.000000, 
+            480.843750, 0.000000, 485.109375, 0.000000, 489.796875, 0.000000, 497.437500, 0.000000, 
+            499.546875, 0.000000, 503.765625, 0.000000, 509.671875, 0.000000, 514.359375, 0.000000, 
+            521.671875, 0.000000, 523.781250, 0.000000, 529.453125, 0.000000, 534.140625, 0.000000, 
+            537.656250, 0.000000, 543.046875, 0.000000, 546.585938, 0.000000, 552.585938, 0.000000, 
+            560.367188, 0.000000, 560.367188, 0.000000, 563.742188, 0.000000, 569.742188, 0.000000, 
+            573.960938, 0.000000, 579.351562, 0.000000, 584.039062, 0.000000, 589.851562, 0.000000, 
+            591.914062, 0.000000, 596.367188, 0.000000, 600.609375, 0.000000, 606.421875, 0.000000, 
+            608.484375, 0.000000, 613.171875, 0.000000, 619.570312, 0.000000, 623.812500, 0.000000, 
+            627.914062, 0.000000, 633.914062, 0.000000, 638.601562, 0.000000, 641.929688, 0.000000, 
+            644.039062, 0.000000, 647.789062, 0.000000, 652.007812, 0.000000, 656.273438, 0.000000, 
+            660.960938, 0.000000, 664.898438, 0.000000, 670.710938, 0.000000, 672.773438, 0.000000, 
+            678.773438, 0.000000, 683.460938, 0.000000, 689.859375, 0.000000, 697.640625, 0.000000, 
+            700.664062, 0.000000, 705.351562, 0.000000, 707.460938, 0.000000, 711.679688, 0.000000, 
+            715.921875, 0.000000, 719.390625, 0.000000, 723.656250, 0.000000, 728.343750, 0.000000, 
+            730.453125, 0.000000, 734.718750, 0.000000, 738.820312, 0.000000, 743.273438, 0.000000, 
+            747.960938, 0.000000, 756.328125, 0.000000, 763.265625, 0.000000, 766.734375, 0.000000, 
+            766.734375, 0.000000, 770.929688, 0.000000, 775.617188, 0.000000, 782.929688, 0.000000, 
+            785.273438, 0.000000, 789.960938, 0.000000, 793.898438, 0.000000, 797.367188, 0.000000, 
+            800.812500, 0.000000, 805.500000, 0.000000, 813.843750, 0.000000, 818.296875, 0.000000, 
+            824.109375, 0.000000, 824.109375, 0.000000, 830.273438, 0.000000, 832.335938, 0.000000, 
+            837.023438, 0.000000, 846.257812, 0.000000, 850.710938, 0.000000, 852.820312, 0.000000, 
+            858.328125, 0.000000, 862.593750, 0.000000, 865.617188, 0.000000, 867.679688, 0.000000, 
+            873.679688, 0.000000, 878.367188, 0.000000, 887.601562, 0.000000, 892.054688, 0.000000, 
+            897.867188, 0.000000, 897.867188, 0.000000, 904.031250, 0.000000, 906.093750, 0.000000, 
+            910.781250, 0.000000, 918.257812, 0.000000, 922.476562, 0.000000, 926.929688, 0.000000, 
+            932.437500, 0.000000, 936.679688, 0.000000, 940.125000, 0.000000, 944.812500, 0.000000, 
+            948.820312, 0.000000, 954.820312, 0.000000, 958.289062, 0.000000, 962.484375, 0.000000, 
+            968.484375, 0.000000, 973.171875, 0.000000, 976.687500, 0.000000, 980.695312, 0.000000, 
+            982.804688, 0.000000, 986.906250, 0.000000, 991.359375, 0.000000, 991.359375, 0.000000, 
+            997.523438, 0.000000, 999.585938, 0.000000, 1004.273438, 0.000000, 1009.289062, 0.000000, 
+            1013.554688, 0.000000, 1018.242188, 0.000000, 1026.187500, 0.000000, 1029.656250, 0.000000, 
+            1033.757812, 0.000000, 1038.445312, 0.000000, 1047.796875, 0.000000, 1052.039062, 0.000000, 
+            1058.859375, 0.000000, 1060.921875, 0.000000, 1066.921875, 0.000000, 1072.429688, 0.000000, 
+            1075.453125, 0.000000, 1077.515625, 0.000000, 1082.203125, 0.000000, 1088.601562, 0.000000, 
+            1092.867188, 0.000000, 1094.976562, 0.000000, 1098.445312, 0.000000, 1102.687500, 0.000000, 
+            1106.882812, 0.000000, 1111.570312, 0.000000, 1115.085938, 0.000000, 1117.195312, 0.000000, 
+            1117.195312, 0.000000, 1124.015625, 0.000000, 1126.125000, 0.000000, 1132.945312, 0.000000, 
+            1135.289062, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Unicode Arabic" script="arab">
+        <test-font name="LucidaSansRegular.ttf" version="Version 1.20 - October 2000" checksum="0xF5D9BA6D" rchecksum="0x029B644F"/>
+
+        <test-text>أساسًا، تتعامل الحواسيب فقط مع الأرقام، وتقوم بتخزين الأحرف والمحارف الأخرى بعد أن تُعطي رقما معينا لكل واحد منها. وقبل اختراع "يونِكود"، كان هناك مئات الأنظمة للتشفير وتخصيص هذه الأرقام للمحارف، ولم يوجد نظام تشفير واحد يحتوي على جميع المحارف الضرورية</test-text>
+
+        <result-glyphs>
+            0x00000872, 0x000008D1, 0x000003F9, 0x0000040B, 0x0000088C, 0x0000089E, 0x000008BD, 0x000003EF, 
+            0x00000003, 0x00000404, 0x000003F9, 0x0000086C, 0x00000882, 0x000008C2, 0x000008BD, 0x000003EF, 
+            0x00000003, 0x000008A8, 0x000008D2, 0x000008C2, 0x0000087D, 0x00000003, 0x000008CE, 0x000008BE, 
+            0x000008A9, 0x00000003, 0x0000040D, 0x000008CC, 0x00000876, 0x00000882, 0x000008D1, 0x00000003, 
+            0x00000888, 0x00000881, 0x000003EF, 0x0000040B, 0x00000003, 0x0000088C, 0x000008D2, 0x000008B2, 
+            0x00000896, 0x00000875, 0x00000003, 0x00000408, 0x0000086C, 0x000008A6, 0x000008C5, 0x00000003, 
+            0x00000888, 0x0000087D, 0x000008CC, 0x000008D1, 0x00000003, 0x000008C0, 0x000008BD, 0x0000040B, 
+            0x00000003, 0x000003E6, 0x00000404, 0x000003F9, 0x0000086C, 0x00000882, 0x000008C2, 0x000008BE, 
+            0x000008BD, 0x00000003, 0x00000408, 0x0000086C, 0x000008B5, 0x000003F9, 0x0000FFFF, 0x000008D5, 
+            0x000003EF, 0x00000003, 0x0000040A, 0x0000088A, 0x000008C9, 0x00000003, 0x00000898, 0x000008D2, 
+            0x0000089A, 0x00000886, 0x00000875, 0x0000040B, 0x00000003, 0x0000088C, 0x000008D2, 0x000008B2, 
+            0x00000896, 0x00000876, 0x000008BE, 0x000008BD, 0x00000003, 0x00000872, 0x000008C2, 0x000008A6, 
+            0x000008C5, 0x0000FFFF, 0x000008D5, 0x000003EF, 0x00000003, 0x000003F2, 0x0000086C, 0x0000086A, 
+            0x000008C1, 0x00000003, 0x00000406, 0x0000086C, 0x000008C6, 0x000008C9, 0x00000003, 0x00000409, 
+            0x0000086C, 0x000008B9, 0x00000003, 0x000003E6, 0x00000005, 0x000003F7, 0x000008CC, 0x000008BA, 
+            0x00000413, 0x000008C5, 0x000008CC, 0x000008D1, 0x00000005, 0x00000003, 0x00000401, 0x000003EF, 
+            0x0000088C, 0x00000876, 0x00000885, 0x000003EF, 0x00000003, 0x000008BC, 0x00000870, 0x000008B5, 
+            0x0000040B, 0x00000003, 0x00000011, 0x0000086C, 0x000008CA, 0x000008C6, 0x000008C1, 0x00000003, 
+            0x00000888, 0x00000881, 0x000003EF, 0x0000040B, 0x00000003, 0x000008BC, 0x000008BA, 0x000008BD, 
+            0x00000003, 0x0000086C, 0x000008C6, 0x000008D2, 0x000008AA, 0x000008C1, 0x00000003, 0x0000086C, 
+            0x000008C2, 0x000008B5, 0x000003F9, 0x00000003, 0x000008D0, 0x000008A2, 0x000008AA, 0x00000412, 
+            0x00000875, 0x00000003, 0x00000409, 0x000003EB, 0x00000003, 0x00000888, 0x000008AA, 0x0000086F, 
+            0x00000003, 0x0000040C, 0x0000088C, 0x00000885, 0x0000FFFF, 0x000008D5, 0x000003EF, 0x00000003, 
+            0x00000404, 0x000003F9, 0x0000086C, 0x00000882, 0x000008C2, 0x000008BD, 0x000003EF, 0x0000040B, 
+            0x00000003, 0x00000404, 0x0000088C, 0x00000881, 0x0000FFFF, 0x000008D5, 0x000003EF, 0x00000003, 
+            0x000008C4, 0x000008D1, 0x0000088E, 0x00000886, 0x00000876, 0x0000086F, 0x00000003, 0x00000408, 
+            0x000008CC, 0x000008B6, 0x00000875, 0x0000040B, 0x00000003, 0x000003E6, 0x00000408, 0x0000086C, 
+            0x000008B5, 0x000003F9, 0x0000FFFF, 0x000008D5, 0x000003EF, 0x00000003, 0x000008A8, 0x000008C1, 
+            0x00000003, 0x000008A0, 0x000008B6, 0x000008B1, 0x00000003, 0x0000086E, 0x000008D2, 0x00000891, 
+            0x000003EF, 0x000008CC, 0x00000882, 0x000008BD, 0x000003EF, 0x00000003, 0x000008BC, 0x000008C1, 
+            0x0000086C, 0x000008AA, 0x00000876, 0x00000875, 0x00000003, 0x000003E6, 0x0000086C, 0x0000040E, 
+            0x00000891, 0x0000086C, 0x00000891, 0x000003EB
+        </result-glyphs>
+
+        <result-indices>
+            0x000000FB, 0x000000FA, 0x000000F9, 0x000000F8, 0x000000F7, 0x000000F6, 0x000000F5, 0x000000F4, 
+            0x000000F3, 0x000000F2, 0x000000F1, 0x000000F0, 0x000000EF, 0x000000EE, 0x000000ED, 0x000000EC, 
+            0x000000EB, 0x000000EA, 0x000000E9, 0x000000E8, 0x000000E7, 0x000000E6, 0x000000E5, 0x000000E4, 
+            0x000000E3, 0x000000E2, 0x000000E1, 0x000000E0, 0x000000DF, 0x000000DE, 0x000000DD, 0x000000DC, 
+            0x000000DB, 0x000000DA, 0x000000D9, 0x000000D8, 0x000000D7, 0x000000D6, 0x000000D5, 0x000000D4, 
+            0x000000D3, 0x000000D2, 0x000000D1, 0x000000D0, 0x000000CF, 0x000000CE, 0x000000CD, 0x000000CC, 
+            0x000000CB, 0x000000CA, 0x000000C9, 0x000000C8, 0x000000C7, 0x000000C6, 0x000000C5, 0x000000C4, 
+            0x000000C3, 0x000000C2, 0x000000C1, 0x000000C0, 0x000000BF, 0x000000BE, 0x000000BD, 0x000000BC, 
+            0x000000BB, 0x000000BA, 0x000000B9, 0x000000B8, 0x000000B7, 0x000000B6, 0x000000B5, 0x000000B4, 
+            0x000000B3, 0x000000B2, 0x000000B1, 0x000000B0, 0x000000AF, 0x000000AE, 0x000000AD, 0x000000AC, 
+            0x000000AB, 0x000000AA, 0x000000A9, 0x000000A8, 0x000000A7, 0x000000A6, 0x000000A5, 0x000000A4, 
+            0x000000A3, 0x000000A2, 0x000000A1, 0x000000A0, 0x0000009F, 0x0000009E, 0x0000009D, 0x0000009C, 
+            0x0000009B, 0x0000009A, 0x00000099, 0x00000098, 0x00000097, 0x00000096, 0x00000095, 0x00000094, 
+            0x00000093, 0x00000092, 0x00000091, 0x00000090, 0x0000008F, 0x0000008E, 0x0000008D, 0x0000008C, 
+            0x0000008B, 0x0000008A, 0x00000089, 0x00000088, 0x00000087, 0x00000086, 0x00000085, 0x00000084, 
+            0x00000083, 0x00000082, 0x00000081, 0x00000080, 0x0000007F, 0x0000007E, 0x0000007D, 0x0000007C, 
+            0x0000007B, 0x0000007A, 0x00000079, 0x00000078, 0x00000077, 0x00000076, 0x00000075, 0x00000074, 
+            0x00000073, 0x00000072, 0x00000071, 0x00000070, 0x0000006F, 0x0000006E, 0x0000006D, 0x0000006C, 
+            0x0000006B, 0x0000006A, 0x00000069, 0x00000068, 0x00000067, 0x00000066, 0x00000065, 0x00000064, 
+            0x00000063, 0x00000062, 0x00000061, 0x00000060, 0x0000005F, 0x0000005E, 0x0000005D, 0x0000005C, 
+            0x0000005B, 0x0000005A, 0x00000059, 0x00000058, 0x00000057, 0x00000056, 0x00000055, 0x00000054, 
+            0x00000053, 0x00000052, 0x00000051, 0x00000050, 0x0000004F, 0x0000004E, 0x0000004D, 0x0000004C, 
+            0x0000004B, 0x0000004A, 0x00000049, 0x00000048, 0x00000047, 0x00000046, 0x00000045, 0x00000044, 
+            0x00000043, 0x00000042, 0x00000041, 0x00000040, 0x0000003F, 0x0000003E, 0x0000003D, 0x0000003C, 
+            0x0000003B, 0x0000003A, 0x00000039, 0x00000038, 0x00000037, 0x00000036, 0x00000035, 0x00000034, 
+            0x00000033, 0x00000032, 0x00000031, 0x00000030, 0x0000002F, 0x0000002E, 0x0000002D, 0x0000002C, 
+            0x0000002B, 0x0000002A, 0x00000029, 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 
+            0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001F, 0x0000001E, 0x0000001D, 0x0000001C, 
+            0x0000001B, 0x0000001A, 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 0x00000014, 
+            0x00000013, 0x00000012, 0x00000011, 0x00000010, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000C, 
+            0x0000000B, 0x0000000A, 0x00000009, 0x00000008, 0x00000007, 0x00000006, 0x00000005, 0x00000004, 
+            0x00000003, 0x00000002, 0x00000001, 0x00000000
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 6.316406, 0.000000, 10.382812, 0.000000, 15.492188, 0.000000, 
+            21.035156, 0.000000, 27.058594, 0.000000, 39.527344, 0.000000, 43.792969, 0.000000, 
+            47.408203, 0.000000, 51.205078, 0.000000, 66.216797, 0.000000, 71.326172, 0.000000, 
+            74.695312, 0.000000, 83.367188, 0.000000, 90.826172, 0.000000, 95.091797, 0.000000, 
+            98.707031, 0.000000, 102.503906, 0.000000, 109.962891, 0.000000, 114.949219, 0.000000, 
+            122.408203, 0.000000, 130.687500, 0.000000, 134.484375, 0.000000, 145.787109, 0.000000, 
+            150.773438, 0.000000, 156.884766, 0.000000, 160.681641, 0.000000, 172.277344, 0.000000, 
+            177.919922, 0.000000, 182.906250, 0.000000, 191.578125, 0.000000, 195.644531, 0.000000, 
+            199.441406, 0.000000, 206.507812, 0.000000, 214.787109, 0.000000, 218.402344, 0.000000, 
+            223.945312, 0.000000, 227.742188, 0.000000, 233.765625, 0.000000, 238.751953, 0.000000, 
+            245.185547, 0.000000, 257.982422, 0.000000, 262.048828, 0.000000, 265.845703, 0.000000, 
+            272.654297, 0.000000, 276.023438, 0.000000, 285.240234, 0.000000, 289.306641, 0.000000, 
+            293.103516, 0.000000, 300.169922, 0.000000, 308.449219, 0.000000, 314.091797, 0.000000, 
+            318.158203, 0.000000, 321.955078, 0.000000, 329.572266, 0.000000, 333.837891, 0.000000, 
+            339.380859, 0.000000, 343.177734, 0.000000, 346.974609, 0.000000, 361.986328, 0.000000, 
+            367.095703, 0.000000, 370.464844, 0.000000, 379.136719, 0.000000, 386.595703, 0.000000, 
+            391.582031, 0.000000, 395.847656, 0.000000, 399.644531, 0.000000, 406.453125, 0.000000, 
+            409.822266, 0.000000, 415.523438, 0.000000, 420.632812, 0.000000, 420.632812, 0.000000, 
+            427.441406, 0.000000, 431.056641, 0.000000, 434.853516, 0.000000, 441.357422, 0.000000, 
+            448.423828, 0.000000, 455.912109, 0.000000, 459.708984, 0.000000, 479.255859, 0.000000, 
+            484.242188, 0.000000, 496.710938, 0.000000, 505.382812, 0.000000, 509.449219, 0.000000, 
+            514.992188, 0.000000, 518.789062, 0.000000, 524.812500, 0.000000, 529.798828, 0.000000, 
+            536.232422, 0.000000, 549.029297, 0.000000, 554.015625, 0.000000, 559.001953, 0.000000, 
+            563.267578, 0.000000, 567.064453, 0.000000, 573.380859, 0.000000, 580.839844, 0.000000, 
+            590.056641, 0.000000, 594.123047, 0.000000, 594.123047, 0.000000, 600.931641, 0.000000, 
+            604.546875, 0.000000, 608.343750, 0.000000, 620.636719, 0.000000, 624.005859, 0.000000, 
+            628.992188, 0.000000, 635.830078, 0.000000, 639.626953, 0.000000, 653.361328, 0.000000, 
+            656.730469, 0.000000, 661.716797, 0.000000, 669.205078, 0.000000, 673.001953, 0.000000, 
+            683.777344, 0.000000, 687.146484, 0.000000, 692.660156, 0.000000, 696.457031, 0.000000, 
+            700.253906, 0.000000, 704.736328, 0.000000, 711.105469, 0.000000, 716.748047, 0.000000, 
+            722.994141, 0.000000, 722.994141, 0.000000, 727.060547, 0.000000, 732.703125, 0.000000, 
+            736.769531, 0.000000, 741.251953, 0.000000, 745.048828, 0.000000, 752.507812, 0.000000, 
+            756.123047, 0.000000, 762.146484, 0.000000, 767.132812, 0.000000, 775.412109, 0.000000, 
+            779.027344, 0.000000, 782.824219, 0.000000, 794.203125, 0.000000, 799.189453, 0.000000, 
+            804.890625, 0.000000, 810.433594, 0.000000, 814.230469, 0.000000, 818.027344, 0.000000, 
+            821.396484, 0.000000, 828.128906, 0.000000, 833.115234, 0.000000, 839.953125, 0.000000, 
+            843.750000, 0.000000, 850.816406, 0.000000, 859.095703, 0.000000, 862.710938, 0.000000, 
+            868.253906, 0.000000, 872.050781, 0.000000, 883.429688, 0.000000, 889.675781, 0.000000, 
+            893.941406, 0.000000, 897.738281, 0.000000, 901.107422, 0.000000, 906.093750, 0.000000, 
+            911.080078, 0.000000, 917.800781, 0.000000, 924.638672, 0.000000, 928.435547, 0.000000, 
+            931.804688, 0.000000, 939.263672, 0.000000, 944.964844, 0.000000, 950.074219, 0.000000, 
+            953.871094, 0.000000, 965.173828, 0.000000, 974.390625, 0.000000, 981.111328, 0.000000, 
+            981.111328, 0.000000, 985.177734, 0.000000, 988.974609, 0.000000, 999.750000, 0.000000, 
+            1003.365234, 0.000000, 1007.162109, 0.000000, 1014.228516, 0.000000, 1020.949219, 0.000000, 
+            1025.015625, 0.000000, 1028.812500, 0.000000, 1040.408203, 0.000000, 1046.431641, 0.000000, 
+            1054.710938, 0.000000, 1054.710938, 0.000000, 1061.519531, 0.000000, 1065.134766, 0.000000, 
+            1068.931641, 0.000000, 1083.943359, 0.000000, 1089.052734, 0.000000, 1092.421875, 0.000000, 
+            1101.093750, 0.000000, 1108.552734, 0.000000, 1112.818359, 0.000000, 1116.433594, 0.000000, 
+            1121.976562, 0.000000, 1125.773438, 0.000000, 1140.785156, 0.000000, 1146.808594, 0.000000, 
+            1155.087891, 0.000000, 1155.087891, 0.000000, 1161.896484, 0.000000, 1165.511719, 0.000000, 
+            1169.308594, 0.000000, 1180.541016, 0.000000, 1184.607422, 0.000000, 1190.630859, 0.000000, 
+            1199.302734, 0.000000, 1204.289062, 0.000000, 1208.355469, 0.000000, 1212.152344, 0.000000, 
+            1218.960938, 0.000000, 1224.603516, 0.000000, 1231.037109, 0.000000, 1235.103516, 0.000000, 
+            1240.646484, 0.000000, 1244.443359, 0.000000, 1248.240234, 0.000000, 1255.048828, 0.000000, 
+            1258.417969, 0.000000, 1264.119141, 0.000000, 1269.228516, 0.000000, 1269.228516, 0.000000, 
+            1276.037109, 0.000000, 1279.652344, 0.000000, 1283.449219, 0.000000, 1290.908203, 0.000000, 
+            1297.746094, 0.000000, 1301.542969, 0.000000, 1311.427734, 0.000000, 1317.861328, 0.000000, 
+            1323.562500, 0.000000, 1327.359375, 0.000000, 1341.492188, 0.000000, 1346.478516, 0.000000, 
+            1357.904297, 0.000000, 1361.519531, 0.000000, 1367.162109, 0.000000, 1375.833984, 0.000000, 
+            1380.099609, 0.000000, 1383.714844, 0.000000, 1387.511719, 0.000000, 1398.890625, 0.000000, 
+            1405.728516, 0.000000, 1409.097656, 0.000000, 1415.818359, 0.000000, 1420.804688, 0.000000, 
+            1424.871094, 0.000000, 1428.667969, 0.000000, 1432.464844, 0.000000, 1435.833984, 0.000000, 
+            1435.833984, 0.000000, 1447.259766, 0.000000, 1450.628906, 0.000000, 1462.054688, 0.000000, 
+            1465.669922, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Thai" script="thai">
+        <test-font name="angsd___.ttf" version="Version 2.1 - July 1995" checksum="0x49B67200" rchecksum="0x003C2EE9"/>
+
+        <test-text>บทที่๑พายุไซโคลนโดโรธีอาศัยอยู่ท่ามกลางทุ่งใหญ่ในแคนซัสกับลุงเฮนรีชาวไร่และป้าเอ็มภรรยาชาวไร่บ้านของพวกเขาหลังเล็กเพราะไม้สร้างบ้านต้องขนมาด้วยเกวียนเป็นระยะทางหลายไมล์</test-text>
+
+        <result-glyphs>
+            0x000000F3, 0x000000F0, 0x000000F0, 0x0000010E, 0x0000011D, 0x00000126, 0x000000F7, 0x0000010B, 
+            0x000000FB, 0x00000111, 0x00000119, 0x000000E4, 0x00000117, 0x000000DD, 0x000000FE, 0x000000F2, 
+            0x00000117, 0x000000ED, 0x00000117, 0x000000FC, 0x000000F1, 0x0000010E, 0x00000106, 0x0000010B, 
+            0x00000101, 0x0000010A, 0x000000FB, 0x00000106, 0x000000FB, 0x00000112, 0x0000013B, 0x000000F0, 
+            0x0000013B, 0x0000010B, 0x000000FA, 0x000000DA, 0x000000FE, 0x0000010B, 0x000000E0, 0x000000F0, 
+            0x00000111, 0x0000013B, 0x000000E0, 0x00000118, 0x00000104, 0x000000E6, 0x0000013B, 0x00000118, 
+            0x000000F2, 0x00000116, 0x000000DD, 0x000000F2, 0x000000E4, 0x0000010A, 0x00000103, 0x000000DA, 
+            0x0000010A, 0x000000F3, 0x000000FE, 0x00000111, 0x000000E0, 0x00000115, 0x00000107, 0x000000F2, 
+            0x000000FC, 0x0000010E, 0x000000E3, 0x0000010B, 0x00000100, 0x00000119, 0x000000FC, 0x0000013B, 
+            0x00000116, 0x000000FE, 0x00000109, 0x000000F4, 0x00000137, 0x0000010B, 0x00000115, 0x00000106, 
+            0x0000011C, 0x000000FA, 0x000000F9, 0x000000FC, 0x000000FC, 0x000000FB, 0x0000010B, 0x000000E3, 
+            0x0000010B, 0x00000100, 0x00000119, 0x000000FC, 0x0000013B, 0x000000F3, 0x0000013C, 0x0000010B, 
+            0x000000F2, 0x000000DB, 0x00000106, 0x000000E0, 0x000000F7, 0x00000100, 0x000000DA, 0x00000115, 
+            0x000000DB, 0x0000010B, 0x00000104, 0x000000FE, 0x0000010A, 0x000000E0, 0x00000115, 0x000000FE, 
+            0x0000011C, 0x000000DA, 0x00000115, 0x000000F7, 0x000000FC, 0x0000010B, 0x00000109, 0x00000119, 
+            0x000000FA, 0x0000013C, 0x00000103, 0x000000FC, 0x0000013C, 0x0000010B, 0x000000E0, 0x000000F3, 
+            0x0000013C, 0x0000010B, 0x000000F2, 0x000000EE, 0x0000013C, 0x00000106, 0x000000E0, 0x000000DB, 
+            0x000000F2, 0x000000FA, 0x0000010B, 0x000000ED, 0x0000013C, 0x00000100, 0x000000FB, 0x00000115, 
+            0x000000DA, 0x00000100, 0x0000010E, 0x000000FB, 0x000000F2, 0x00000115, 0x000000F4, 0x00000143, 
+            0x000000F2, 0x000000FC, 0x00000109, 0x000000FB, 0x00000109, 0x000000F0, 0x0000010B, 0x000000E0, 
+            0x00000104, 0x000000FE, 0x0000010B, 0x000000FB, 0x00000119, 0x000000FA, 0x000000FE, 0x0000013F
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 
+            0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x0000001E, 0x0000001F, 
+            0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026, 0x00000027, 
+            0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, 0x0000002E, 0x0000002F, 
+            0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 
+            0x00000038, 0x00000039, 0x0000003A, 0x0000003B, 0x0000003C, 0x0000003D, 0x0000003E, 0x0000003F, 
+            0x00000040, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 
+            0x00000048, 0x00000049, 0x0000004A, 0x0000004B, 0x0000004C, 0x0000004D, 0x0000004E, 0x0000004F, 
+            0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 
+            0x00000058, 0x00000059, 0x0000005A, 0x0000005B, 0x0000005C, 0x0000005D, 0x0000005E, 0x0000005F, 
+            0x00000060, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 
+            0x00000068, 0x00000069, 0x0000006A, 0x0000006B, 0x0000006C, 0x0000006D, 0x0000006E, 0x0000006F, 
+            0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 
+            0x00000078, 0x00000079, 0x0000007A, 0x0000007B, 0x0000007C, 0x0000007D, 0x0000007E, 0x0000007F, 
+            0x00000080, 0x00000081, 0x00000082, 0x00000083, 0x00000084, 0x00000085, 0x00000086, 0x00000087, 
+            0x00000088, 0x00000089, 0x0000008A, 0x0000008B, 0x0000008C, 0x0000008D, 0x0000008E, 0x0000008F, 
+            0x00000090, 0x00000091, 0x00000092, 0x00000093, 0x00000094, 0x00000095, 0x00000096, 0x00000097, 
+            0x00000098, 0x00000099, 0x0000009A, 0x0000009B, 0x0000009C, 0x0000009D, 0x0000009E, 0x0000009F, 
+            0x000000A0, 0x000000A1, 0x000000A2, 0x000000A3, 0x000000A4, 0x000000A5, 0x000000A6, 0x000000A7
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 5.399414, 0.000000, 10.798828, 0.000000, 16.198242, 0.000000, 
+            16.198242, 0.000000, 16.198242, 0.000000, 21.046875, 0.000000, 26.616211, 0.000000, 
+            30.035156, 0.000000, 34.151367, 0.000000, 34.151367, 0.000000, 38.279297, 0.000000, 
+            43.558594, 0.000000, 47.663086, 0.000000, 52.438477, 0.000000, 57.178711, 0.000000, 
+            62.698242, 0.000000, 66.802734, 0.000000, 71.601562, 0.000000, 75.706055, 0.000000, 
+            79.810547, 0.000000, 84.369141, 0.000000, 84.369141, 0.000000, 89.097656, 0.000000, 
+            92.516602, 0.000000, 97.195312, 0.000000, 97.195312, 0.000000, 101.311523, 0.000000, 
+            106.040039, 0.000000, 110.156250, 0.000000, 110.156250, 0.000000, 110.156250, 0.000000, 
+            115.555664, 0.000000, 115.555664, 0.000000, 118.974609, 0.000000, 124.013672, 0.000000, 
+            128.765625, 0.000000, 133.505859, 0.000000, 136.924805, 0.000000, 140.704102, 0.000000, 
+            146.103516, 0.000000, 146.103516, 0.000000, 146.103516, 0.000000, 149.882812, 0.000000, 
+            153.553711, 0.000000, 159.158203, 0.000000, 165.421875, 0.000000, 165.421875, 0.000000, 
+            169.092773, 0.000000, 174.612305, 0.000000, 179.135742, 0.000000, 183.911133, 0.000000, 
+            189.430664, 0.000000, 194.709961, 0.000000, 194.709961, 0.000000, 199.989258, 0.000000, 
+            204.741211, 0.000000, 204.741211, 0.000000, 210.140625, 0.000000, 214.880859, 0.000000, 
+            214.880859, 0.000000, 218.660156, 0.000000, 220.675781, 0.000000, 225.128906, 0.000000, 
+            230.648438, 0.000000, 234.752930, 0.000000, 234.752930, 0.000000, 239.613281, 0.000000, 
+            243.032227, 0.000000, 247.280273, 0.000000, 251.408203, 0.000000, 255.512695, 0.000000, 
+            255.512695, 0.000000, 260.036133, 0.000000, 264.776367, 0.000000, 269.071289, 0.000000, 
+            274.470703, 0.000000, 274.470703, 0.000000, 277.889648, 0.000000, 279.905273, 0.000000, 
+            284.633789, 0.000000, 284.633789, 0.000000, 289.672852, 0.000000, 294.641602, 0.000000, 
+            298.746094, 0.000000, 302.850586, 0.000000, 306.966797, 0.000000, 310.385742, 0.000000, 
+            315.246094, 0.000000, 318.665039, 0.000000, 322.913086, 0.000000, 327.041016, 0.000000, 
+            331.145508, 0.000000, 331.145508, 0.000000, 336.544922, 0.000000, 336.544922, 0.000000, 
+            339.963867, 0.000000, 345.483398, 0.000000, 350.258789, 0.000000, 354.987305, 0.000000, 
+            358.766602, 0.000000, 364.335938, 0.000000, 368.583984, 0.000000, 373.335938, 0.000000, 
+            375.351562, 0.000000, 380.126953, 0.000000, 383.545898, 0.000000, 389.150391, 0.000000, 
+            393.890625, 0.000000, 393.890625, 0.000000, 397.669922, 0.000000, 399.685547, 0.000000, 
+            404.425781, 0.000000, 404.425781, 0.000000, 409.177734, 0.000000, 411.193359, 0.000000, 
+            416.762695, 0.000000, 420.867188, 0.000000, 424.286133, 0.000000, 428.581055, 0.000000, 
+            432.708984, 0.000000, 437.748047, 0.000000, 437.748047, 0.000000, 443.027344, 0.000000, 
+            447.131836, 0.000000, 447.131836, 0.000000, 450.550781, 0.000000, 454.330078, 0.000000, 
+            459.729492, 0.000000, 459.729492, 0.000000, 463.148438, 0.000000, 468.667969, 0.000000, 
+            473.478516, 0.000000, 473.478516, 0.000000, 478.207031, 0.000000, 481.986328, 0.000000, 
+            486.761719, 0.000000, 492.281250, 0.000000, 497.320312, 0.000000, 500.739258, 0.000000, 
+            505.538086, 0.000000, 505.538086, 0.000000, 509.786133, 0.000000, 513.902344, 0.000000, 
+            515.917969, 0.000000, 520.669922, 0.000000, 524.917969, 0.000000, 524.917969, 0.000000, 
+            529.034180, 0.000000, 534.553711, 0.000000, 536.569336, 0.000000, 541.968750, 0.000000, 
+            541.968750, 0.000000, 547.488281, 0.000000, 551.592773, 0.000000, 555.887695, 0.000000, 
+            560.003906, 0.000000, 564.298828, 0.000000, 569.698242, 0.000000, 573.117188, 0.000000, 
+            576.896484, 0.000000, 582.500977, 0.000000, 587.241211, 0.000000, 590.660156, 0.000000, 
+            594.776367, 0.000000, 598.904297, 0.000000, 603.943359, 0.000000, 608.683594, 0.000000, 
+            608.683594, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Arabic Simple" script="arab">
+        <test-font name="LucidaSansRegular.ttf" version="Version 1.20 - October 2000" checksum="0xF5D9BA6D" rchecksum="0x029B644F"/>
+
+        <test-text>أساسًا، تتعامل الحواسيب فقط مع الأرقام، وتقوم بتخزين الأحرف والمحارف الأخرى بعد أن تُعطي رقما معينا لكل واحد منها. وقبل اختراع "يونِكود"، كان هناك مئات الأنظمة للتشفير وتخصيص هذه الأرقام للمحارف، ولم يوجد نظام تشفير واحد يحتوي على جميع المحارف الضرورية</test-text>
+
+        <result-glyphs>
+            0x00000872, 0x000008D1, 0x000003F9, 0x0000040B, 0x0000088C, 0x0000089E, 0x000008BD, 0x000003EF, 
+            0x00000003, 0x00000404, 0x000003F9, 0x0000086C, 0x00000882, 0x000008C2, 0x000008BD, 0x000003EF, 
+            0x00000003, 0x000008A8, 0x000008D2, 0x000008C2, 0x0000087D, 0x00000003, 0x000008CE, 0x000008BE, 
+            0x000008A9, 0x00000003, 0x0000040D, 0x000008CC, 0x00000876, 0x00000882, 0x000008D1, 0x00000003, 
+            0x00000888, 0x00000881, 0x000003EF, 0x0000040B, 0x00000003, 0x0000088C, 0x000008D2, 0x000008B2, 
+            0x00000896, 0x00000875, 0x00000003, 0x00000408, 0x0000086C, 0x000008A6, 0x000008C5, 0x00000003, 
+            0x00000888, 0x0000087D, 0x000008CC, 0x000008D1, 0x00000003, 0x000008C0, 0x000008BD, 0x0000040B, 
+            0x00000003, 0x000003E6, 0x00000404, 0x000003F9, 0x0000086C, 0x00000882, 0x000008C2, 0x000008BE, 
+            0x000008BD, 0x00000003, 0x00000408, 0x0000086C, 0x000008B5, 0x000003F9, 0x0000FFFF, 0x000008D5, 
+            0x000003EF, 0x00000003, 0x0000040A, 0x0000088A, 0x000008C9, 0x00000003, 0x00000898, 0x000008D2, 
+            0x0000089A, 0x00000886, 0x00000875, 0x0000040B, 0x00000003, 0x0000088C, 0x000008D2, 0x000008B2, 
+            0x00000896, 0x00000876, 0x000008BE, 0x000008BD, 0x00000003, 0x00000872, 0x000008C2, 0x000008A6, 
+            0x000008C5, 0x0000FFFF, 0x000008D5, 0x000003EF, 0x00000003, 0x000003F2, 0x0000086C, 0x0000086A, 
+            0x000008C1, 0x00000003, 0x00000406, 0x0000086C, 0x000008C6, 0x000008C9, 0x00000003, 0x00000409, 
+            0x0000086C, 0x000008B9, 0x00000003, 0x000003E6, 0x00000005, 0x000003F7, 0x000008CC, 0x000008BA, 
+            0x00000413, 0x000008C5, 0x000008CC, 0x000008D1, 0x00000005, 0x00000003, 0x00000401, 0x000003EF, 
+            0x0000088C, 0x00000876, 0x00000885, 0x000003EF, 0x00000003, 0x000008BC, 0x00000870, 0x000008B5, 
+            0x0000040B, 0x00000003, 0x00000011, 0x0000086C, 0x000008CA, 0x000008C6, 0x000008C1, 0x00000003, 
+            0x00000888, 0x00000881, 0x000003EF, 0x0000040B, 0x00000003, 0x000008BC, 0x000008BA, 0x000008BD, 
+            0x00000003, 0x0000086C, 0x000008C6, 0x000008D2, 0x000008AA, 0x000008C1, 0x00000003, 0x0000086C, 
+            0x000008C2, 0x000008B5, 0x000003F9, 0x00000003, 0x000008D0, 0x000008A2, 0x000008AA, 0x00000412, 
+            0x00000875, 0x00000003, 0x00000409, 0x000003EB, 0x00000003, 0x00000888, 0x000008AA, 0x0000086F, 
+            0x00000003, 0x0000040C, 0x0000088C, 0x00000885, 0x0000FFFF, 0x000008D5, 0x000003EF, 0x00000003, 
+            0x00000404, 0x000003F9, 0x0000086C, 0x00000882, 0x000008C2, 0x000008BD, 0x000003EF, 0x0000040B, 
+            0x00000003, 0x00000404, 0x0000088C, 0x00000881, 0x0000FFFF, 0x000008D5, 0x000003EF, 0x00000003, 
+            0x000008C4, 0x000008D1, 0x0000088E, 0x00000886, 0x00000876, 0x0000086F, 0x00000003, 0x00000408, 
+            0x000008CC, 0x000008B6, 0x00000875, 0x0000040B, 0x00000003, 0x000003E6, 0x00000408, 0x0000086C, 
+            0x000008B5, 0x000003F9, 0x0000FFFF, 0x000008D5, 0x000003EF, 0x00000003, 0x000008A8, 0x000008C1, 
+            0x00000003, 0x000008A0, 0x000008B6, 0x000008B1, 0x00000003, 0x0000086E, 0x000008D2, 0x00000891, 
+            0x000003EF, 0x000008CC, 0x00000882, 0x000008BD, 0x000003EF, 0x00000003, 0x000008BC, 0x000008C1, 
+            0x0000086C, 0x000008AA, 0x00000876, 0x00000875, 0x00000003, 0x000003E6, 0x0000086C, 0x0000040E, 
+            0x00000891, 0x0000086C, 0x00000891, 0x000003EB
+        </result-glyphs>
+
+        <result-indices>
+            0x000000FB, 0x000000FA, 0x000000F9, 0x000000F8, 0x000000F7, 0x000000F6, 0x000000F5, 0x000000F4, 
+            0x000000F3, 0x000000F2, 0x000000F1, 0x000000F0, 0x000000EF, 0x000000EE, 0x000000ED, 0x000000EC, 
+            0x000000EB, 0x000000EA, 0x000000E9, 0x000000E8, 0x000000E7, 0x000000E6, 0x000000E5, 0x000000E4, 
+            0x000000E3, 0x000000E2, 0x000000E1, 0x000000E0, 0x000000DF, 0x000000DE, 0x000000DD, 0x000000DC, 
+            0x000000DB, 0x000000DA, 0x000000D9, 0x000000D8, 0x000000D7, 0x000000D6, 0x000000D5, 0x000000D4, 
+            0x000000D3, 0x000000D2, 0x000000D1, 0x000000D0, 0x000000CF, 0x000000CE, 0x000000CD, 0x000000CC, 
+            0x000000CB, 0x000000CA, 0x000000C9, 0x000000C8, 0x000000C7, 0x000000C6, 0x000000C5, 0x000000C4, 
+            0x000000C3, 0x000000C2, 0x000000C1, 0x000000C0, 0x000000BF, 0x000000BE, 0x000000BD, 0x000000BC, 
+            0x000000BB, 0x000000BA, 0x000000B9, 0x000000B8, 0x000000B7, 0x000000B6, 0x000000B5, 0x000000B4, 
+            0x000000B3, 0x000000B2, 0x000000B1, 0x000000B0, 0x000000AF, 0x000000AE, 0x000000AD, 0x000000AC, 
+            0x000000AB, 0x000000AA, 0x000000A9, 0x000000A8, 0x000000A7, 0x000000A6, 0x000000A5, 0x000000A4, 
+            0x000000A3, 0x000000A2, 0x000000A1, 0x000000A0, 0x0000009F, 0x0000009E, 0x0000009D, 0x0000009C, 
+            0x0000009B, 0x0000009A, 0x00000099, 0x00000098, 0x00000097, 0x00000096, 0x00000095, 0x00000094, 
+            0x00000093, 0x00000092, 0x00000091, 0x00000090, 0x0000008F, 0x0000008E, 0x0000008D, 0x0000008C, 
+            0x0000008B, 0x0000008A, 0x00000089, 0x00000088, 0x00000087, 0x00000086, 0x00000085, 0x00000084, 
+            0x00000083, 0x00000082, 0x00000081, 0x00000080, 0x0000007F, 0x0000007E, 0x0000007D, 0x0000007C, 
+            0x0000007B, 0x0000007A, 0x00000079, 0x00000078, 0x00000077, 0x00000076, 0x00000075, 0x00000074, 
+            0x00000073, 0x00000072, 0x00000071, 0x00000070, 0x0000006F, 0x0000006E, 0x0000006D, 0x0000006C, 
+            0x0000006B, 0x0000006A, 0x00000069, 0x00000068, 0x00000067, 0x00000066, 0x00000065, 0x00000064, 
+            0x00000063, 0x00000062, 0x00000061, 0x00000060, 0x0000005F, 0x0000005E, 0x0000005D, 0x0000005C, 
+            0x0000005B, 0x0000005A, 0x00000059, 0x00000058, 0x00000057, 0x00000056, 0x00000055, 0x00000054, 
+            0x00000053, 0x00000052, 0x00000051, 0x00000050, 0x0000004F, 0x0000004E, 0x0000004D, 0x0000004C, 
+            0x0000004B, 0x0000004A, 0x00000049, 0x00000048, 0x00000047, 0x00000046, 0x00000045, 0x00000044, 
+            0x00000043, 0x00000042, 0x00000041, 0x00000040, 0x0000003F, 0x0000003E, 0x0000003D, 0x0000003C, 
+            0x0000003B, 0x0000003A, 0x00000039, 0x00000038, 0x00000037, 0x00000036, 0x00000035, 0x00000034, 
+            0x00000033, 0x00000032, 0x00000031, 0x00000030, 0x0000002F, 0x0000002E, 0x0000002D, 0x0000002C, 
+            0x0000002B, 0x0000002A, 0x00000029, 0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024, 
+            0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001F, 0x0000001E, 0x0000001D, 0x0000001C, 
+            0x0000001B, 0x0000001A, 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 0x00000014, 
+            0x00000013, 0x00000012, 0x00000011, 0x00000010, 0x0000000F, 0x0000000E, 0x0000000D, 0x0000000C, 
+            0x0000000B, 0x0000000A, 0x00000009, 0x00000008, 0x00000007, 0x00000006, 0x00000005, 0x00000004, 
+            0x00000003, 0x00000002, 0x00000001, 0x00000000
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 6.316406, 0.000000, 10.382812, 0.000000, 15.492188, 0.000000, 
+            21.035156, 0.000000, 27.058594, 0.000000, 39.527344, 0.000000, 43.792969, 0.000000, 
+            47.408203, 0.000000, 51.205078, 0.000000, 66.216797, 0.000000, 71.326172, 0.000000, 
+            74.695312, 0.000000, 83.367188, 0.000000, 90.826172, 0.000000, 95.091797, 0.000000, 
+            98.707031, 0.000000, 102.503906, 0.000000, 109.962891, 0.000000, 114.949219, 0.000000, 
+            122.408203, 0.000000, 130.687500, 0.000000, 134.484375, 0.000000, 145.787109, 0.000000, 
+            150.773438, 0.000000, 156.884766, 0.000000, 160.681641, 0.000000, 172.277344, 0.000000, 
+            177.919922, 0.000000, 182.906250, 0.000000, 191.578125, 0.000000, 195.644531, 0.000000, 
+            199.441406, 0.000000, 206.507812, 0.000000, 214.787109, 0.000000, 218.402344, 0.000000, 
+            223.945312, 0.000000, 227.742188, 0.000000, 233.765625, 0.000000, 238.751953, 0.000000, 
+            245.185547, 0.000000, 257.982422, 0.000000, 262.048828, 0.000000, 265.845703, 0.000000, 
+            272.654297, 0.000000, 276.023438, 0.000000, 285.240234, 0.000000, 289.306641, 0.000000, 
+            293.103516, 0.000000, 300.169922, 0.000000, 308.449219, 0.000000, 314.091797, 0.000000, 
+            318.158203, 0.000000, 321.955078, 0.000000, 329.572266, 0.000000, 333.837891, 0.000000, 
+            339.380859, 0.000000, 343.177734, 0.000000, 346.974609, 0.000000, 361.986328, 0.000000, 
+            367.095703, 0.000000, 370.464844, 0.000000, 379.136719, 0.000000, 386.595703, 0.000000, 
+            391.582031, 0.000000, 395.847656, 0.000000, 399.644531, 0.000000, 406.453125, 0.000000, 
+            409.822266, 0.000000, 415.523438, 0.000000, 420.632812, 0.000000, 420.632812, 0.000000, 
+            427.441406, 0.000000, 431.056641, 0.000000, 434.853516, 0.000000, 441.357422, 0.000000, 
+            448.423828, 0.000000, 455.912109, 0.000000, 459.708984, 0.000000, 479.255859, 0.000000, 
+            484.242188, 0.000000, 496.710938, 0.000000, 505.382812, 0.000000, 509.449219, 0.000000, 
+            514.992188, 0.000000, 518.789062, 0.000000, 524.812500, 0.000000, 529.798828, 0.000000, 
+            536.232422, 0.000000, 549.029297, 0.000000, 554.015625, 0.000000, 559.001953, 0.000000, 
+            563.267578, 0.000000, 567.064453, 0.000000, 573.380859, 0.000000, 580.839844, 0.000000, 
+            590.056641, 0.000000, 594.123047, 0.000000, 594.123047, 0.000000, 600.931641, 0.000000, 
+            604.546875, 0.000000, 608.343750, 0.000000, 620.636719, 0.000000, 624.005859, 0.000000, 
+            628.992188, 0.000000, 635.830078, 0.000000, 639.626953, 0.000000, 653.361328, 0.000000, 
+            656.730469, 0.000000, 661.716797, 0.000000, 669.205078, 0.000000, 673.001953, 0.000000, 
+            683.777344, 0.000000, 687.146484, 0.000000, 692.660156, 0.000000, 696.457031, 0.000000, 
+            700.253906, 0.000000, 704.736328, 0.000000, 711.105469, 0.000000, 716.748047, 0.000000, 
+            722.994141, 0.000000, 722.994141, 0.000000, 727.060547, 0.000000, 732.703125, 0.000000, 
+            736.769531, 0.000000, 741.251953, 0.000000, 745.048828, 0.000000, 752.507812, 0.000000, 
+            756.123047, 0.000000, 762.146484, 0.000000, 767.132812, 0.000000, 775.412109, 0.000000, 
+            779.027344, 0.000000, 782.824219, 0.000000, 794.203125, 0.000000, 799.189453, 0.000000, 
+            804.890625, 0.000000, 810.433594, 0.000000, 814.230469, 0.000000, 818.027344, 0.000000, 
+            821.396484, 0.000000, 828.128906, 0.000000, 833.115234, 0.000000, 839.953125, 0.000000, 
+            843.750000, 0.000000, 850.816406, 0.000000, 859.095703, 0.000000, 862.710938, 0.000000, 
+            868.253906, 0.000000, 872.050781, 0.000000, 883.429688, 0.000000, 889.675781, 0.000000, 
+            893.941406, 0.000000, 897.738281, 0.000000, 901.107422, 0.000000, 906.093750, 0.000000, 
+            911.080078, 0.000000, 917.800781, 0.000000, 924.638672, 0.000000, 928.435547, 0.000000, 
+            931.804688, 0.000000, 939.263672, 0.000000, 944.964844, 0.000000, 950.074219, 0.000000, 
+            953.871094, 0.000000, 965.173828, 0.000000, 974.390625, 0.000000, 981.111328, 0.000000, 
+            981.111328, 0.000000, 985.177734, 0.000000, 988.974609, 0.000000, 999.750000, 0.000000, 
+            1003.365234, 0.000000, 1007.162109, 0.000000, 1014.228516, 0.000000, 1020.949219, 0.000000, 
+            1025.015625, 0.000000, 1028.812500, 0.000000, 1040.408203, 0.000000, 1046.431641, 0.000000, 
+            1054.710938, 0.000000, 1054.710938, 0.000000, 1061.519531, 0.000000, 1065.134766, 0.000000, 
+            1068.931641, 0.000000, 1083.943359, 0.000000, 1089.052734, 0.000000, 1092.421875, 0.000000, 
+            1101.093750, 0.000000, 1108.552734, 0.000000, 1112.818359, 0.000000, 1116.433594, 0.000000, 
+            1121.976562, 0.000000, 1125.773438, 0.000000, 1140.785156, 0.000000, 1146.808594, 0.000000, 
+            1155.087891, 0.000000, 1155.087891, 0.000000, 1161.896484, 0.000000, 1165.511719, 0.000000, 
+            1169.308594, 0.000000, 1180.541016, 0.000000, 1184.607422, 0.000000, 1190.630859, 0.000000, 
+            1199.302734, 0.000000, 1204.289062, 0.000000, 1208.355469, 0.000000, 1212.152344, 0.000000, 
+            1218.960938, 0.000000, 1224.603516, 0.000000, 1231.037109, 0.000000, 1235.103516, 0.000000, 
+            1240.646484, 0.000000, 1244.443359, 0.000000, 1248.240234, 0.000000, 1255.048828, 0.000000, 
+            1258.417969, 0.000000, 1264.119141, 0.000000, 1269.228516, 0.000000, 1269.228516, 0.000000, 
+            1276.037109, 0.000000, 1279.652344, 0.000000, 1283.449219, 0.000000, 1290.908203, 0.000000, 
+            1297.746094, 0.000000, 1301.542969, 0.000000, 1311.427734, 0.000000, 1317.861328, 0.000000, 
+            1323.562500, 0.000000, 1327.359375, 0.000000, 1341.492188, 0.000000, 1346.478516, 0.000000, 
+            1357.904297, 0.000000, 1361.519531, 0.000000, 1367.162109, 0.000000, 1375.833984, 0.000000, 
+            1380.099609, 0.000000, 1383.714844, 0.000000, 1387.511719, 0.000000, 1398.890625, 0.000000, 
+            1405.728516, 0.000000, 1409.097656, 0.000000, 1415.818359, 0.000000, 1420.804688, 0.000000, 
+            1424.871094, 0.000000, 1428.667969, 0.000000, 1432.464844, 0.000000, 1435.833984, 0.000000, 
+            1435.833984, 0.000000, 1447.259766, 0.000000, 1450.628906, 0.000000, 1462.054688, 0.000000, 
+            1465.669922, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Matra Test" script="deva">
+        <test-font name="raghu.ttf" version="Original Version 1.00 (2005)" checksum="0x088DB135" rchecksum="0x00803FCE"/>
+
+        <test-text>ुं ं॑</test-text>
+
+        <result-glyphs>
+            0x0000029C, 0x000001D5, 0x00000232, 0x00000003, 0x0000029C, 0x00000232, 0x00000233
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000003, 0x00000004
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 7.541016, 0.000000, 7.541016, 0.000000, 7.541016, 0.000000, 
+            13.541016, 0.000000, 21.082031, 0.000000, 19.953125, -6.052734, 21.082031, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Deva Stress Test" script="deva">
+        <test-font name="raghu.ttf" version="Original Version 1.00 (2005)" checksum="0x088DB135" rchecksum="0x00803FCE"/>
+
+        <test-text>कँ कं कः क॑ क॒ कँ॑ कं॒ कँंः क॒॑</test-text>
+
+        <result-glyphs>
+            0x00000080, 0x00000231, 0x00000003, 0x00000080, 0x00000232, 0x00000003, 0x00000080, 0x0000022C, 
+            0x00000003, 0x00000080, 0x00000233, 0x00000003, 0x00000080, 0x000001DF, 0x00000003, 0x00000080, 
+            0x00000231, 0x00000233, 0x00000003, 0x00000080, 0x000001DF, 0x00000232, 0x00000003, 0x00000080, 
+            0x00000231, 0x0000029C, 0x00000232, 0x0000029C, 0x0000022C, 0x00000003, 0x00000080, 0x00000233, 
+            0x0000029C, 0x000001DF
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000015, 0x00000014, 0x00000016, 0x00000017, 
+            0x00000018, 0x00000019, 0x00000019, 0x0000001A, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 
+            0x0000001E, 0x0000001E
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 10.001953, -0.087891, 10.875000, 0.000000, 16.875000, 0.000000, 
+            23.783203, 0.439453, 27.750000, 0.000000, 33.750000, 0.000000, 44.625000, 0.000000, 
+            48.984375, 0.000000, 54.984375, 0.000000, 63.546875, -1.669922, 65.859375, 0.000000, 
+            71.859375, 0.000000, 80.332031, 0.492188, 82.734375, 0.000000, 88.734375, 0.000000, 
+            98.736328, -0.087891, 97.431641, -6.228516, 99.609375, 0.000000, 105.609375, 0.000000, 
+            114.082031, 0.492188, 112.517578, 0.439453, 116.484375, 0.000000, 122.484375, 0.000000, 
+            132.486328, -0.087891, 133.359375, 0.000000, 140.900391, 0.000000, 140.900391, 0.000000, 
+            148.441406, 0.000000, 152.800781, 0.000000, 158.800781, 0.000000, 167.363281, -1.669922, 
+            169.675781, 0.000000, 177.216797, 0.000000, 177.216797, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Deva Test" script="deva">
+        <test-font name="raghu.ttf" version="Original Version 1.00 (2005)" checksum="0x088DB135" rchecksum="0x00803FCE"/>
+
+        <test-text>रू क़् क्ष क्कि क्रि ट्रि हिन्दी र्क्रिं क्षत्रज्ञत्रक्ष श्र थ्र श्र कके र्कें केूकूेकेृ र्कू क़ क क् क्ष क्ष् क्ष्क  ज़ ज ज् ज्ञ ज्ञ् ज्ञ्क र्क र्क्क ड्र क्क क़्क क़्क क़् क्ष्क क्ष् त्र्क द्द कि हि रू रु र्के र्कं क् कु के द्द्द क़्ष क्ष र्क्षे द्दत्र्क ज्ञ क्त्व ज्ञ्क र्कँ र्किँ र्केँ र्क्रिँ हिंदी ह्मिह्यिखि ङ्क ङ्म ङ्क्त ङ्ख ङ्ग ङ्घ ङ्क्ष ङ्क्ष्व ङ्क्ष्य र्क्त्वि र्र्र्र कै के कु कू कृ कॅ कॆ हु हू हॆ है हे</test-text>
+
+        <result-glyphs>
+            0x0000009A, 0x000001FE, 0x00000003, 0x000000A4, 0x00000051, 0x00000003, 0x000000A2, 0x0000FFFF, 
+            0x0000FFFF, 0x00000003, 0x000001D4, 0x000000C8, 0x0000FFFF, 0x00000080, 0x00000003, 0x000001D1, 
+            0x00000080, 0x0000009A, 0x00000051, 0x00000003, 0x000001D1, 0x0000008A, 0x0000009A, 0x00000051, 
+            0x00000003, 0x000001D1, 0x000000A1, 0x000000DB, 0x0000FFFF, 0x00000091, 0x00000223, 0x00000003, 
+            0x000001D1, 0x00000080, 0x000000E2, 0x0000FFFF, 0x0000009A, 0x00000051, 0x00000232, 0x00000003, 
+            0x000000A2, 0x0000FFFF, 0x0000FFFF, 0x0000008F, 0x000000E2, 0x0000FFFF, 0x000000A3, 0x0000FFFF, 
+            0x0000FFFF, 0x0000008F, 0x000000E2, 0x0000FFFF, 0x000000A2, 0x0000FFFF, 0x0000FFFF, 0x00000003, 
+            0x0000009E, 0x0000009A, 0x00000051, 0x00000003, 0x00000090, 0x0000009A, 0x00000051, 0x00000003, 
+            0x0000009E, 0x0000009A, 0x00000051, 0x00000003, 0x00000080, 0x00000080, 0x0000022F, 0x00000003, 
+            0x00000080, 0x0000022F, 0x0000024D, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x00000080, 0x0000022F, 
+            0x0000029C, 0x000001D7, 0x00000080, 0x000001D7, 0x0000029C, 0x0000022F, 0x00000080, 0x0000022F, 
+            0x0000029C, 0x000001D9, 0x00000003, 0x00000080, 0x000001D7, 0x0000005B, 0x0000FFFF, 0x00000003, 
+            0x000000A4, 0x00000003, 0x00000080, 0x00000003, 0x00000080, 0x00000051, 0x00000003, 0x000000A2, 
+            0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000A2, 0x0000FFFF, 0x0000FFFF, 0x00000051, 0x00000003, 
+            0x000000EA, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000080, 0x00000003, 0x00000003, 0x000000AB, 
+            0x0000FFFF, 0x00000003, 0x00000087, 0x00000003, 0x00000087, 0x00000051, 0x00000003, 0x000000A3, 
+            0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000A3, 0x0000FFFF, 0x0000FFFF, 0x00000051, 0x00000003, 
+            0x000000EB, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000080, 0x00000003, 0x00000080, 0x0000005B, 
+            0x0000FFFF, 0x00000003, 0x000000C8, 0x0000FFFF, 0x00000080, 0x0000005B, 0x0000FFFF, 0x00000003, 
+            0x0000008C, 0x0000009A, 0x00000051, 0x00000003, 0x000000C8, 0x0000FFFF, 0x00000080, 0x00000003, 
+            0x000000EC, 0x0000FFFF, 0x00000080, 0x00000003, 0x000000EC, 0x0000FFFF, 0x00000080, 0x00000003, 
+            0x000000A4, 0x00000051, 0x00000003, 0x000000EA, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000080, 
+            0x00000003, 0x000000A2, 0x0000FFFF, 0x0000FFFF, 0x00000051, 0x00000003, 0x000000D7, 0x0000FFFF, 
+            0x000000E2, 0x0000FFFF, 0x00000080, 0x00000003, 0x000001A7, 0x0000FFFF, 0x0000FFFF, 0x00000003, 
+            0x000001D1, 0x00000080, 0x00000003, 0x000001D1, 0x000000A1, 0x00000003, 0x0000009A, 0x000001FE, 
+            0x00000003, 0x0000009A, 0x000001FD, 0x00000003, 0x00000080, 0x0000022F, 0x0000005A, 0x0000FFFF, 
+            0x00000003, 0x00000080, 0x0000024D, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x00000080, 0x00000051, 
+            0x00000003, 0x00000080, 0x000001D5, 0x00000003, 0x00000080, 0x0000022F, 0x00000003, 0x000000D9, 
+            0x0000FFFF, 0x000001A7, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000EC, 0x0000FFFF, 0x0000009F, 
+            0x00000003, 0x000000A2, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000A2, 0x0000FFFF, 0x0000FFFF, 
+            0x0000022F, 0x0000005A, 0x0000FFFF, 0x00000003, 0x000001A7, 0x0000FFFF, 0x0000FFFF, 0x000000D7, 
+            0x0000FFFF, 0x000000E2, 0x0000FFFF, 0x00000080, 0x00000003, 0x000000A3, 0x0000FFFF, 0x0000FFFF, 
+            0x00000003, 0x000000C8, 0x0000FFFF, 0x000000D7, 0x0000FFFF, 0x0000009D, 0x00000003, 0x000000EB, 
+            0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000080, 0x00000003, 0x00000080, 0x0000024C, 0x0000FFFF, 
+            0x0000FFFF, 0x00000003, 0x000001D1, 0x00000080, 0x0000024C, 0x0000FFFF, 0x0000FFFF, 0x00000003, 
+            0x00000080, 0x0000022F, 0x0000024C, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000001D1, 0x00000080, 
+            0x000000E2, 0x0000FFFF, 0x0000009A, 0x00000051, 0x00000231, 0x00000003, 0x000001D1, 0x000000A1, 
+            0x00000232, 0x00000091, 0x00000223, 0x00000003, 0x000001D3, 0x000001BA, 0x0000FFFF, 0x0000FFFF, 
+            0x000001D3, 0x000001BB, 0x0000FFFF, 0x0000FFFF, 0x000001D4, 0x00000081, 0x00000003, 0x000000CC, 
+            0x0000FFFF, 0x00000080, 0x00000003, 0x000001A2, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000CC, 
+            0x0000FFFF, 0x000001A0, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000CC, 0x0000FFFF, 0x00000081, 
+            0x00000003, 0x000000CC, 0x0000FFFF, 0x00000082, 0x00000003, 0x000000CC, 0x0000FFFF, 0x00000083, 
+            0x00000003, 0x000000CC, 0x0000FFFF, 0x000000A2, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000CC, 
+            0x0000FFFF, 0x000000EA, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000009D, 0x00000003, 0x000000CC, 
+            0x0000FFFF, 0x000000EA, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000099, 0x00000003, 0x000001D4, 
+            0x000000C8, 0x0000FFFF, 0x000000D7, 0x0000FFFF, 0x0000009D, 0x0000005B, 0x0000FFFF, 0x00000003, 
+            0x0000009A, 0x00000051, 0x0000009A, 0x000000E2, 0x0000FFFF, 0x0000009A, 0x00000051, 0x00000003, 
+            0x00000080, 0x00000230, 0x00000003, 0x00000080, 0x0000022F, 0x00000003, 0x00000080, 0x000001D5, 
+            0x00000003, 0x00000080, 0x000001D7, 0x00000003, 0x00000080, 0x000001D9, 0x00000003, 0x00000080, 
+            0x0000022D, 0x00000003, 0x00000080, 0x0000022E, 0x00000003, 0x000000A1, 0x000001D5, 0x00000003, 
+            0x000000A1, 0x000001D7, 0x00000003, 0x000000A1, 0x0000022E, 0x00000003, 0x000000A1, 0x00000230, 
+            0x00000003, 0x000000A1, 0x0000022F
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000D, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000E, 0x00000012, 
+            0x0000000F, 0x00000011, 0x00000010, 0x00000013, 0x00000017, 0x00000014, 0x00000016, 0x00000015, 
+            0x00000018, 0x0000001A, 0x00000019, 0x0000001B, 0x0000001C, 0x0000001D, 0x0000001E, 0x0000001F, 
+            0x00000025, 0x00000022, 0x00000024, 0x00000023, 0x00000020, 0x00000021, 0x00000026, 0x00000027, 
+            0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002D, 0x0000002C, 0x0000002E, 0x0000002F, 
+            0x00000030, 0x00000031, 0x00000033, 0x00000032, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 
+            0x00000038, 0x0000003A, 0x00000039, 0x0000003B, 0x0000003C, 0x0000003E, 0x0000003D, 0x0000003F, 
+            0x00000040, 0x00000042, 0x00000041, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 
+            0x0000004A, 0x0000004B, 0x00000048, 0x00000049, 0x0000004C, 0x0000004D, 0x0000004E, 0x0000004F, 
+            0x00000050, 0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000053, 0x00000054, 0x00000055, 
+            0x00000056, 0x00000056, 0x00000057, 0x0000005A, 0x0000005B, 0x00000058, 0x00000059, 0x0000005C, 
+            0x0000005D, 0x0000005E, 0x0000005F, 0x00000060, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 
+            0x00000065, 0x00000066, 0x00000067, 0x00000068, 0x00000069, 0x0000006A, 0x0000006B, 0x0000006C, 
+            0x0000006D, 0x0000006E, 0x0000006F, 0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 
+            0x00000075, 0x00000076, 0x00000077, 0x00000078, 0x00000079, 0x0000007A, 0x0000007B, 0x0000007C, 
+            0x0000007D, 0x0000007E, 0x0000007F, 0x00000080, 0x00000081, 0x00000082, 0x00000083, 0x00000084, 
+            0x00000085, 0x00000086, 0x00000087, 0x00000088, 0x00000089, 0x0000008A, 0x0000008D, 0x0000008B, 
+            0x0000008C, 0x0000008E, 0x00000091, 0x00000092, 0x00000093, 0x0000008F, 0x00000090, 0x00000094, 
+            0x00000095, 0x00000097, 0x00000096, 0x00000098, 0x00000099, 0x0000009A, 0x0000009B, 0x0000009C, 
+            0x0000009D, 0x0000009E, 0x0000009F, 0x000000A0, 0x000000A1, 0x000000A2, 0x000000A3, 0x000000A4, 
+            0x000000A5, 0x000000A6, 0x000000A7, 0x000000A8, 0x000000A9, 0x000000AA, 0x000000AB, 0x000000AC, 
+            0x000000AD, 0x000000AE, 0x000000AF, 0x000000B0, 0x000000B1, 0x000000B2, 0x000000B3, 0x000000B4, 
+            0x000000B5, 0x000000B6, 0x000000B7, 0x000000B8, 0x000000B9, 0x000000BA, 0x000000BB, 0x000000BC, 
+            0x000000BE, 0x000000BD, 0x000000BF, 0x000000C1, 0x000000C0, 0x000000C2, 0x000000C3, 0x000000C4, 
+            0x000000C5, 0x000000C6, 0x000000C7, 0x000000C8, 0x000000CB, 0x000000CC, 0x000000C9, 0x000000CA, 
+            0x000000CD, 0x000000D0, 0x000000CE, 0x000000CF, 0x000000D1, 0x000000D2, 0x000000D3, 0x000000D4, 
+            0x000000D5, 0x000000D6, 0x000000D7, 0x000000D8, 0x000000D9, 0x000000DA, 0x000000DB, 0x000000DC, 
+            0x000000DD, 0x000000DE, 0x000000DF, 0x000000E0, 0x000000E1, 0x000000E2, 0x000000E3, 0x000000E4, 
+            0x000000E5, 0x000000E6, 0x000000E7, 0x000000E8, 0x000000E9, 0x000000EC, 0x000000ED, 0x000000EE, 
+            0x000000EF, 0x000000EA, 0x000000EB, 0x000000F0, 0x000000F1, 0x000000F2, 0x000000F3, 0x000000F4, 
+            0x000000F5, 0x000000F6, 0x000000F7, 0x000000F8, 0x000000F9, 0x000000FA, 0x000000FB, 0x000000FC, 
+            0x000000FD, 0x000000FE, 0x000000FF, 0x00000100, 0x00000101, 0x00000102, 0x00000103, 0x00000104, 
+            0x00000105, 0x00000106, 0x00000107, 0x00000108, 0x00000109, 0x0000010C, 0x0000010A, 0x0000010B, 
+            0x0000010D, 0x0000010E, 0x00000112, 0x00000111, 0x0000010F, 0x00000110, 0x00000113, 0x00000114, 
+            0x00000117, 0x00000118, 0x00000115, 0x00000116, 0x00000119, 0x0000011A, 0x00000120, 0x0000011D, 
+            0x0000011F, 0x0000011E, 0x0000011B, 0x0000011C, 0x00000121, 0x00000122, 0x00000124, 0x00000123, 
+            0x00000125, 0x00000126, 0x00000127, 0x00000128, 0x0000012C, 0x00000129, 0x0000012A, 0x0000012B, 
+            0x00000130, 0x0000012D, 0x0000012E, 0x0000012F, 0x00000132, 0x00000131, 0x00000133, 0x00000134, 
+            0x00000135, 0x00000136, 0x00000137, 0x00000138, 0x00000139, 0x0000013A, 0x0000013B, 0x0000013C, 
+            0x0000013D, 0x0000013E, 0x0000013F, 0x00000140, 0x00000141, 0x00000142, 0x00000143, 0x00000144, 
+            0x00000145, 0x00000146, 0x00000147, 0x00000148, 0x00000149, 0x0000014A, 0x0000014B, 0x0000014C, 
+            0x0000014D, 0x0000014E, 0x0000014F, 0x00000150, 0x00000151, 0x00000152, 0x00000153, 0x00000154, 
+            0x00000155, 0x00000156, 0x00000157, 0x00000158, 0x00000159, 0x0000015A, 0x0000015B, 0x0000015C, 
+            0x0000015D, 0x0000015E, 0x0000015F, 0x00000160, 0x00000161, 0x00000162, 0x00000163, 0x0000016B, 
+            0x00000166, 0x00000167, 0x00000168, 0x00000169, 0x0000016A, 0x00000164, 0x00000165, 0x0000016C, 
+            0x0000016F, 0x00000170, 0x00000171, 0x00000173, 0x00000172, 0x0000016D, 0x0000016E, 0x00000174, 
+            0x00000175, 0x00000176, 0x00000177, 0x00000178, 0x00000179, 0x0000017A, 0x0000017B, 0x0000017C, 
+            0x0000017D, 0x0000017E, 0x0000017F, 0x00000180, 0x00000181, 0x00000182, 0x00000183, 0x00000184, 
+            0x00000185, 0x00000186, 0x00000187, 0x00000188, 0x00000189, 0x0000018A, 0x0000018B, 0x0000018C, 
+            0x0000018D, 0x0000018E, 0x0000018F, 0x00000190, 0x00000191, 0x00000192, 0x00000193, 0x00000194, 
+            0x00000195, 0x00000196, 0x00000197
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 6.515625, 0.000000, 8.121094, 0.000000, 14.121094, 0.000000, 
+            24.861328, -0.451172, 24.996094, 0.000000, 30.996094, 0.000000, 41.871094, 0.000000, 
+            41.871094, 0.000000, 41.871094, 0.000000, 47.871094, 0.000000, 52.230469, 0.000000, 
+            60.949219, 0.000000, 60.949219, 0.000000, 71.824219, 0.000000, 77.824219, 0.000000, 
+            82.183594, 0.000000, 93.058594, 0.000000, 102.720703, -0.451172, 99.574219, 0.000000, 
+            105.574219, 0.000000, 109.933594, 0.000000, 117.902344, 0.000000, 127.564453, -0.451172, 
+            124.417969, 0.000000, 130.417969, 0.000000, 134.777344, 0.000000, 142.746094, 0.000000, 
+            150.011719, 0.000000, 150.011719, 0.000000, 157.980469, 0.000000, 161.636719, 0.000000, 
+            167.636719, 0.000000, 171.996094, 0.000000, 182.871094, 0.000000, 186.621094, 0.000000, 
+            186.621094, 0.000000, 196.283203, -0.451172, 191.613281, 0.439453, 193.136719, 0.000000, 
+            199.136719, 0.000000, 210.011719, 0.000000, 210.011719, 0.000000, 210.011719, 0.000000, 
+            217.980469, 0.000000, 221.730469, 0.000000, 221.730469, 0.000000, 232.605469, 0.000000, 
+            232.605469, 0.000000, 232.605469, 0.000000, 240.574219, 0.000000, 244.324219, 0.000000, 
+            244.324219, 0.000000, 255.199219, 0.000000, 255.199219, 0.000000, 255.199219, 0.000000, 
+            261.199219, 0.000000, 270.667969, 0.000000, 280.330078, -0.451172, 277.183594, 0.000000, 
+            283.183594, 0.000000, 292.652344, 0.000000, 302.314453, -0.451172, 299.167969, 0.000000, 
+            305.167969, 0.000000, 314.636719, 0.000000, 324.298828, -0.451172, 321.152344, 0.000000, 
+            327.152344, 0.000000, 338.027344, 0.000000, 344.783203, 0.263672, 348.902344, 0.000000, 
+            354.902344, 0.000000, 361.658203, 0.263672, 362.279297, 0.263672, 365.777344, 0.000000, 
+            365.777344, 0.000000, 365.777344, 0.000000, 371.777344, 0.000000, 378.533203, 0.263672, 
+            382.652344, 0.000000, 390.193359, 0.000000, 390.193359, 0.000000, 397.916016, -0.011719, 
+            401.068359, 0.000000, 408.609375, 0.000000, 408.609375, 0.000000, 415.365234, 0.263672, 
+            419.484375, 0.000000, 427.025391, 0.000000, 427.025391, 0.000000, 433.025391, 0.000000, 
+            440.748047, -0.011719, 440.929688, 0.263672, 443.900391, 0.000000, 443.900391, 0.000000, 
+            449.900391, 0.000000, 460.775391, 0.000000, 466.775391, 0.000000, 477.650391, 0.000000, 
+            483.650391, 0.000000, 494.390625, -0.451172, 494.525391, 0.000000, 500.525391, 0.000000, 
+            511.400391, 0.000000, 511.400391, 0.000000, 511.400391, 0.000000, 517.400391, 0.000000, 
+            528.275391, 0.000000, 528.275391, 0.000000, 531.457031, -0.451172, 528.275391, 0.000000, 
+            534.275391, 0.000000, 542.994141, 0.000000, 542.994141, 0.000000, 542.994141, 0.000000, 
+            542.994141, 0.000000, 553.869141, 0.000000, 559.869141, 0.000000, 565.869141, 0.000000, 
+            575.337891, 0.000000, 575.337891, 0.000000, 581.337891, 0.000000, 590.806641, 0.000000, 
+            596.806641, 0.000000, 609.597656, -0.451172, 606.275391, 0.000000, 612.275391, 0.000000, 
+            623.150391, 0.000000, 623.150391, 0.000000, 623.150391, 0.000000, 629.150391, 0.000000, 
+            640.025391, 0.000000, 640.025391, 0.000000, 643.207031, -0.451172, 640.025391, 0.000000, 
+            646.025391, 0.000000, 653.994141, 0.000000, 653.994141, 0.000000, 653.994141, 0.000000, 
+            653.994141, 0.000000, 664.869141, 0.000000, 670.869141, 0.000000, 678.773438, 0.263672, 
+            681.744141, 0.000000, 681.744141, 0.000000, 687.744141, 0.000000, 696.462891, 0.000000, 
+            696.462891, 0.000000, 704.367188, 0.263672, 707.337891, 0.000000, 707.337891, 0.000000, 
+            713.337891, 0.000000, 721.306641, 0.000000, 730.968750, -0.451172, 727.822266, 0.000000, 
+            733.822266, 0.000000, 742.541016, 0.000000, 742.541016, 0.000000, 753.416016, 0.000000, 
+            759.416016, 0.000000, 768.134766, 0.000000, 768.134766, 0.000000, 779.009766, 0.000000, 
+            785.009766, 0.000000, 793.728516, 0.000000, 793.728516, 0.000000, 804.603516, 0.000000, 
+            810.603516, 0.000000, 821.343750, -0.451172, 821.478516, 0.000000, 827.478516, 0.000000, 
+            836.197266, 0.000000, 836.197266, 0.000000, 836.197266, 0.000000, 836.197266, 0.000000, 
+            847.072266, 0.000000, 853.072266, 0.000000, 863.947266, 0.000000, 863.947266, 0.000000, 
+            867.128906, -0.451172, 863.947266, 0.000000, 869.947266, 0.000000, 875.876953, 0.000000, 
+            875.876953, 0.000000, 879.626953, 0.000000, 879.626953, 0.000000, 890.501953, 0.000000, 
+            896.501953, 0.000000, 903.064453, 0.000000, 903.064453, 0.000000, 903.064453, 0.000000, 
+            909.064453, 0.000000, 913.423828, 0.000000, 924.298828, 0.000000, 930.298828, 0.000000, 
+            934.658203, 0.000000, 942.626953, 0.000000, 948.626953, 0.000000, 955.142578, 0.000000, 
+            956.748047, 0.000000, 962.748047, 0.000000, 969.263672, 0.000000, 970.623047, 0.000000, 
+            976.623047, 0.000000, 983.378906, 0.263672, 983.853516, 0.164062, 987.498047, 0.000000, 
+            987.498047, 0.000000, 993.498047, 0.000000, 1000.875000, 0.263672, 1004.373047, 0.000000, 
+            1004.373047, 0.000000, 1004.373047, 0.000000, 1010.373047, 0.000000, 1021.113281, -0.451172, 
+            1021.248047, 0.000000, 1027.248047, 0.000000, 1034.947266, -0.011719, 1038.123047, 0.000000, 
+            1044.123047, 0.000000, 1050.878906, 0.263672, 1054.998047, 0.000000, 1060.998047, 0.000000, 
+            1068.966797, 0.000000, 1068.966797, 0.000000, 1075.529297, 0.000000, 1075.529297, 0.000000, 
+            1075.529297, 0.000000, 1081.529297, 0.000000, 1090.248047, 0.000000, 1090.248047, 0.000000, 
+            1098.216797, 0.000000, 1104.216797, 0.000000, 1115.091797, 0.000000, 1115.091797, 0.000000, 
+            1115.091797, 0.000000, 1121.091797, 0.000000, 1131.966797, 0.000000, 1131.966797, 0.000000, 
+            1131.164062, 0.275391, 1131.638672, 0.175781, 1131.966797, 0.000000, 1131.966797, 0.000000, 
+            1137.966797, 0.000000, 1144.529297, 0.000000, 1144.529297, 0.000000, 1144.529297, 0.000000, 
+            1150.458984, 0.000000, 1150.458984, 0.000000, 1154.208984, 0.000000, 1154.208984, 0.000000, 
+            1165.083984, 0.000000, 1171.083984, 0.000000, 1181.958984, 0.000000, 1181.958984, 0.000000, 
+            1181.958984, 0.000000, 1187.958984, 0.000000, 1196.677734, 0.000000, 1196.677734, 0.000000, 
+            1202.607422, 0.000000, 1202.607422, 0.000000, 1210.576172, 0.000000, 1216.576172, 0.000000, 
+            1224.544922, 0.000000, 1224.544922, 0.000000, 1224.544922, 0.000000, 1224.544922, 0.000000, 
+            1235.419922, 0.000000, 1241.419922, 0.000000, 1249.236328, 0.263672, 1252.294922, 0.000000, 
+            1252.294922, 0.000000, 1252.294922, 0.000000, 1258.294922, 0.000000, 1262.654297, 0.000000, 
+            1270.470703, 0.263672, 1273.529297, 0.000000, 1273.529297, 0.000000, 1273.529297, 0.000000, 
+            1279.529297, 0.000000, 1286.285156, 0.263672, 1287.345703, 0.263672, 1290.404297, 0.000000, 
+            1290.404297, 0.000000, 1290.404297, 0.000000, 1296.404297, 0.000000, 1300.763672, 0.000000, 
+            1311.638672, 0.000000, 1315.388672, 0.000000, 1315.388672, 0.000000, 1325.050781, -0.451172, 
+            1323.474609, -0.087891, 1321.904297, 0.000000, 1327.904297, 0.000000, 1332.263672, 0.000000, 
+            1338.767578, 0.439453, 1340.232422, 0.000000, 1348.201172, 0.000000, 1351.857422, 0.000000, 
+            1357.857422, 0.000000, 1362.216797, 0.000000, 1372.388672, 0.000000, 1372.388672, 0.000000, 
+            1372.388672, 0.000000, 1376.748047, 0.000000, 1386.919922, 0.000000, 1386.919922, 0.000000, 
+            1386.919922, 0.000000, 1391.279297, 0.000000, 1402.154297, 0.000000, 1408.154297, 0.000000, 
+            1416.123047, 0.000000, 1416.123047, 0.000000, 1426.998047, 0.000000, 1432.998047, 0.000000, 
+            1446.076172, 0.000000, 1446.076172, 0.000000, 1446.076172, 0.000000, 1452.076172, 0.000000, 
+            1460.044922, 0.000000, 1460.044922, 0.000000, 1471.294922, 0.000000, 1471.294922, 0.000000, 
+            1471.294922, 0.000000, 1477.294922, 0.000000, 1485.263672, 0.000000, 1485.263672, 0.000000, 
+            1496.138672, 0.000000, 1502.138672, 0.000000, 1510.107422, 0.000000, 1510.107422, 0.000000, 
+            1519.576172, 0.000000, 1525.576172, 0.000000, 1533.544922, 0.000000, 1533.544922, 0.000000, 
+            1543.013672, 0.000000, 1549.013672, 0.000000, 1556.982422, 0.000000, 1556.982422, 0.000000, 
+            1567.857422, 0.000000, 1567.857422, 0.000000, 1567.857422, 0.000000, 1573.857422, 0.000000, 
+            1581.826172, 0.000000, 1581.826172, 0.000000, 1590.544922, 0.000000, 1590.544922, 0.000000, 
+            1590.544922, 0.000000, 1590.544922, 0.000000, 1598.513672, 0.000000, 1604.513672, 0.000000, 
+            1612.482422, 0.000000, 1612.482422, 0.000000, 1621.201172, 0.000000, 1621.201172, 0.000000, 
+            1621.201172, 0.000000, 1621.201172, 0.000000, 1630.669922, 0.000000, 1636.669922, 0.000000, 
+            1641.029297, 0.000000, 1649.748047, 0.000000, 1649.748047, 0.000000, 1655.677734, 0.000000, 
+            1655.677734, 0.000000, 1663.939453, 0.263672, 1663.646484, 0.000000, 1663.646484, 0.000000, 
+            1669.646484, 0.000000, 1679.308594, -0.451172, 1676.162109, 0.000000, 1682.677734, 0.000000, 
+            1686.427734, 0.000000, 1686.427734, 0.000000, 1696.089844, -0.451172, 1692.943359, 0.000000, 
+            1698.943359, 0.000000, 1706.314453, 0.263672, 1709.818359, 0.000000, 1715.818359, 0.000000, 
+            1722.574219, 0.263672, 1726.693359, 0.000000, 1732.693359, 0.000000, 1740.392578, -0.011719, 
+            1743.568359, 0.000000, 1749.568359, 0.000000, 1757.291016, -0.011719, 1760.443359, 0.000000, 
+            1766.443359, 0.000000, 1774.376953, -0.011719, 1777.318359, 0.000000, 1783.318359, 0.000000, 
+            1791.738281, -0.439453, 1794.193359, 0.000000, 1800.193359, 0.000000, 1808.121094, 0.263672, 
+            1811.068359, 0.000000, 1817.068359, 0.000000, 1823.085938, -0.011719, 1825.037109, 0.000000, 
+            1831.037109, 0.000000, 1837.078125, -0.011719, 1839.005859, 0.000000, 1845.005859, 0.000000, 
+            1852.529297, 0.263672, 1852.974609, 0.000000, 1858.974609, 0.000000, 1865.941406, 0.263672, 
+            1866.943359, 0.000000, 1872.943359, 0.000000, 1879.294922, 0.263672, 1880.912109, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Japanese Han" script="hani" lang="JAN">
+        <test-font name="Arial Unicode.ttf" version="Version 1.01x" checksum="0x609C497F" rchecksum="0x63451FC0"/>
+
+        <test-text>中华人民共和国 台湾 中華人民共和國 臺灣</test-text>
+
+        <result-glyphs>
+            0x000020BC, 0x000025DD, 0x00002149, 0x00003EA0, 0x00002400, 0x0000271B, 0x0000298C, 0x00000003, 
+            0x0000267F, 0x0000410D, 0x00000003, 0x000020BC, 0x0000567E, 0x00002149, 0x00003EA0, 0x00002400, 
+            0x0000271B, 0x0000299A, 0x00000003, 0x00005489, 0x000042F2
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 12.000000, 0.000000, 24.000000, 0.000000, 36.000000, 0.000000, 
+            48.000000, 0.000000, 60.000000, 0.000000, 72.000000, 0.000000, 84.000000, 0.000000, 
+            87.333984, 0.000000, 99.333984, 0.000000, 111.333984, 0.000000, 114.667969, 0.000000, 
+            126.667969, 0.000000, 138.667969, 0.000000, 150.667969, 0.000000, 162.667969, 0.000000, 
+            174.667969, 0.000000, 186.667969, 0.000000, 198.667969, 0.000000, 202.001953, 0.000000, 
+            214.001953, 0.000000, 226.001953, 0.000000
+        </result-positions>
+    </test-case>
+<!-- known to fail in base JDK7, skip
+    <test-case id="Korean Han" script="hani" lang="KOR">
+        <test-font name="Arial Unicode.ttf" version="Version 1.01x" checksum="0x609C497F" rchecksum="0x63451FC0"/>
+
+        <test-text>中华人民共和国 台湾 中華人民共和國 臺灣</test-text>
+
+        <result-glyphs>
+            0x000020BC, 0x000025DD, 0x00002149, 0x00003EA0, 0x00002400, 0x0000271B, 0x0000298C, 0x00000003, 
+            0x0000267F, 0x0000410D, 0x00000003, 0x000020BC, 0x00007492, 0x00002149, 0x00003EA0, 0x00002400, 
+            0x0000271B, 0x0000299A, 0x00000003, 0x00005489, 0x000042F2
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 12.000000, 0.000000, 24.000000, 0.000000, 36.000000, 0.000000, 
+            48.000000, 0.000000, 60.000000, 0.000000, 72.000000, 0.000000, 84.000000, 0.000000, 
+            87.333984, 0.000000, 99.333984, 0.000000, 111.333984, 0.000000, 114.667969, 0.000000, 
+            126.667969, 0.000000, 138.667969, 0.000000, 150.667969, 0.000000, 162.667969, 0.000000, 
+            174.667969, 0.000000, 186.667969, 0.000000, 198.667969, 0.000000, 202.001953, 0.000000, 
+            214.001953, 0.000000, 226.001953, 0.000000
+        </result-positions>
+    </test-case>
+-->
+
+<!-- known to fail in base JDK7, skip
+    <test-case id="Traditional Han" script="hani" lang="ZHT">
+        <test-font name="Arial Unicode.ttf" version="Version 1.01x" checksum="0x609C497F" rchecksum="0x63451FC0"/>
+
+        <test-text>中华人民共和国 台湾 中華人民共和國 臺灣</test-text>
+
+        <result-glyphs>
+            0x000020BC, 0x000025DD, 0x00002149, 0x000079EB, 0x00002400, 0x0000271B, 0x0000298C, 0x00000003, 
+            0x00007677, 0x0000410D, 0x00000003, 0x000020BC, 0x00007E26, 0x00002149, 0x000079EB, 0x00002400, 
+            0x0000271B, 0x0000299A, 0x00000003, 0x00007D8F, 0x00007A97
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 12.000000, 0.000000, 24.000000, 0.000000, 36.000000, 0.000000, 
+            48.000000, 0.000000, 60.000000, 0.000000, 72.000000, 0.000000, 84.000000, 0.000000, 
+            87.333984, 0.000000, 99.333984, 0.000000, 111.333984, 0.000000, 114.667969, 0.000000, 
+            126.667969, 0.000000, 138.667969, 0.000000, 150.667969, 0.000000, 162.667969, 0.000000, 
+            174.667969, 0.000000, 186.667969, 0.000000, 198.667969, 0.000000, 202.001953, 0.000000, 
+            214.001953, 0.000000, 226.001953, 0.000000
+        </result-positions>
+    </test-case>
+-->
+
+<!-- known to fail in base JDK7, skip
+    <test-case id="Simplified Han" script="hani" lang="ZHS">
+        <test-font name="Arial Unicode.ttf" version="Version 1.01x" checksum="0x609C497F" rchecksum="0x63451FC0"/>
+
+        <test-text>中华人民共和国 台湾 中華人民共和國 臺灣</test-text>
+
+        <result-glyphs>
+            0x000020BC, 0x000025DD, 0x00002149, 0x000079EB, 0x00002400, 0x0000271B, 0x0000298C, 0x00000003, 
+            0x00007677, 0x00008886, 0x00000003, 0x000020BC, 0x0000567E, 0x00002149, 0x000079EB, 0x00002400, 
+            0x0000271B, 0x0000299A, 0x00000003, 0x00007D8F, 0x00007A97
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 12.000000, 0.000000, 24.000000, 0.000000, 36.000000, 0.000000, 
+            48.000000, 0.000000, 60.000000, 0.000000, 72.000000, 0.000000, 84.000000, 0.000000, 
+            87.333984, 0.000000, 99.333984, 0.000000, 111.333984, 0.000000, 114.667969, 0.000000, 
+            126.667969, 0.000000, 138.667969, 0.000000, 150.667969, 0.000000, 162.667969, 0.000000, 
+            174.667969, 0.000000, 186.667969, 0.000000, 198.667969, 0.000000, 202.001953, 0.000000, 
+            214.001953, 0.000000, 226.001953, 0.000000
+        </result-positions>
+    </test-case>
+-->
+
+    <test-case id="Deva locl Hindi" script="deva" lang="HIN">
+        <test-font name="TestFont1.otf" version="Version 001.000 " checksum="0x75B4A535" rchecksum="0x0004D80A"/>
+
+        <test-text>शङ़ु</test-text>
+
+        <result-glyphs>
+            0x00000002, 0x00000001, 0x00000006, 0x0000FFFF
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 7.572000, 0.000000, 15.108000, 0.000000, 15.108000, 0.000000, 
+            15.108000, 0.000000
+        </result-positions>
+    </test-case>
+
+<!-- known to fail in base JDK7, skip
+    <test-case id="Deva locl Marathi" script="deva" lang="MAR">
+        <test-font name="TestFont1.otf" version="Version 001.000 " checksum="0x75B4A535" rchecksum="0x0004D80A"/>
+
+        <test-text>शङ़ु</test-text>
+
+        <result-glyphs>
+            0x00000005, 0x00000001, 0x00000006, 0x0000FFFF
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 7.392000, 0.000000, 14.927999, 0.000000, 14.927999, 0.000000, 
+            14.927999, 0.000000
+        </result-positions>
+    </test-case>
+-->
+
+    <test-case id="Deva ZWJ" script="deva">
+        <test-font name="raghu.ttf" version="Original Version 1.00 (2005)" checksum="0x088DB135" rchecksum="0x00803FCE"/>
+
+        <test-text>क्ष र्क क्‍ष र्‍क</test-text>
+
+        <result-glyphs>
+            0x000000A2, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x00000080, 0x0000005B, 0x0000FFFF, 0x00000003, 
+            0x00000080, 0x00000051, 0x00000001, 0x0000009F, 0x00000003, 0x0000009A, 0x00000051, 0x00000001, 
+            0x00000080
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000006, 0x00000004, 0x00000005, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 10.875000, 0.000000, 10.875000, 0.000000, 10.875000, 0.000000, 
+            16.875000, 0.000000, 24.779297, 0.263672, 27.750000, 0.000000, 27.750000, 0.000000, 
+            33.750000, 0.000000, 44.490234, -0.451172, 44.625000, 0.000000, 44.625000, 0.000000, 
+            52.593750, 0.000000, 58.593750, 0.000000, 68.255859, -0.451172, 65.109375, 0.000000, 
+            65.109375, 0.000000, 75.984375, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Hangul" script="hang">
+        <test-font name="LucidaSansRegular.ttf" version="Version 1.20 - October 2000" checksum="0xF5D9BA6D" rchecksum="0x029B644F"/>
+
+        <test-text>마만만</test-text>
+
+        <result-glyphs>
+            0x00000000, 0x0000FFFF, 0x00000000, 0x0000FFFF, 0x0000FFFF, 0x00000000, 0x0000FFFF
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 9.000000, 0.000000, 9.000000, 0.000000, 18.000000, 0.000000, 
+            18.000000, 0.000000, 18.000000, 0.000000, 27.000000, 0.000000, 27.000000, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Hebrew Mark Test" script="hebr">
+        <test-font name="SBL_Hbrw.ttf" version="Version 1.51 Build 001" checksum="0x5126B325" rchecksum="0x00F5C25B"/>
+
+        <test-text>מָשְׁכֵנִיאַחֲרֶיךָנָּרוּצָההֱבִיאַנִיהַמֶּלֶךְחֲדָרָיונָגִילָהוְנִשְׂמְחָהבָּךְנַזְכִּירָהדֹדֶיךָמִיַּיִןמֵישָׁרִיםאֲהֵבוּךָ</test-text>
+
+        <result-glyphs>
+            0x0000FFFF, 0x00000055, 0x0000FFFF, 0x0000004B, 0x0000001D, 0x00000097, 0x00000021, 0x00000094, 
+            0x0000001B, 0x0000002D, 0x00000027, 0x00000096, 0x0000003A, 0x0000009A, 0x0000FFFF, 0x00000066, 
+            0x00000027, 0x00000097, 0x0000002F, 0x00000030, 0x00000096, 0x00000027, 0x00000099, 0x0000FFFF, 
+            0x00000051, 0x00000096, 0x0000002F, 0x0000FFFF, 0x00000055, 0x00000027, 0x00000098, 0x0000001F, 
+            0x0000009C, 0x0000001F, 0x00000021, 0x0000009A, 0x0000003A, 0x00000027, 0x00000096, 0x0000FFFF, 
+            0x00000056, 0x00000092, 0x00000024, 0x00000099, 0x00000031, 0x0000FFFF, 0x00000054, 0x0000009A, 
+            0x0000FFFF, 0x00000043, 0x00000021, 0x0000009A, 0x00000025, 0x00000092, 0x0000002F, 0x00000092, 
+            0x0000FFFF, 0x00000067, 0x00000096, 0x00000031, 0x00000092, 0x00000023, 0x00000021, 0x0000009A, 
+            0x0000002B, 0x00000027, 0x00000096, 0x0000001E, 0x0000009A, 0x00000031, 0x00000023, 0x00000027, 
+            0x0000009A, 0x0000003A, 0x0000009A, 0x0000001F, 0x00000094, 0x00000025, 0x0000FFFF, 0x00000054, 
+            0x00000098, 0x0000002B, 0x00000098, 0x0000FFFF, 0x0000005D, 0x00000099, 0x00000021, 0x00000027, 
+            0x00000096, 0x00000031, 0x00000099, 0x0000001B, 0x00000027, 0x00000096, 0x0000001D, 0x00000093, 
+            0x00000021, 0x00000021, 0x0000009A, 0x00000038, 0x0000FFFF, 0x0000004B, 0x0000003A, 0x0000009A, 
+            0x0000FFFF, 0x0000005E, 0x0000FFFF, 0x00000055, 0x00000027, 0x00000098, 0x0000003A, 0x00000094, 
+            0x00000025, 0x00000099, 0x0000001B, 0x00000027, 0x00000096, 0x00000031, 0x00000097, 0x00000029, 
+            0x00000092, 0x0000FFFF, 0x00000066, 0x0000009A, 0x0000002F
+        </result-glyphs>
+
+        <result-indices>
+            0x0000007C, 0x0000007B, 0x0000007A, 0x00000079, 0x00000078, 0x00000077, 0x00000076, 0x00000075, 
+            0x00000074, 0x00000073, 0x00000072, 0x00000071, 0x00000070, 0x0000006F, 0x0000006E, 0x0000006D, 
+            0x0000006C, 0x0000006B, 0x0000006A, 0x00000069, 0x00000068, 0x00000067, 0x00000066, 0x00000065, 
+            0x00000064, 0x00000063, 0x00000062, 0x00000061, 0x00000060, 0x0000005F, 0x0000005E, 0x0000005D, 
+            0x0000005C, 0x0000005B, 0x0000005A, 0x00000059, 0x00000058, 0x00000057, 0x00000056, 0x00000055, 
+            0x00000054, 0x00000053, 0x00000052, 0x00000051, 0x00000050, 0x0000004F, 0x0000004E, 0x0000004D, 
+            0x0000004C, 0x0000004B, 0x0000004A, 0x00000049, 0x00000048, 0x00000047, 0x00000046, 0x00000045, 
+            0x00000044, 0x00000043, 0x00000042, 0x00000041, 0x00000040, 0x0000003F, 0x0000003E, 0x0000003D, 
+            0x0000003C, 0x0000003B, 0x0000003A, 0x00000039, 0x00000038, 0x00000037, 0x00000036, 0x00000035, 
+            0x00000034, 0x00000033, 0x00000032, 0x00000031, 0x00000030, 0x0000002F, 0x0000002E, 0x0000002D, 
+            0x0000002C, 0x0000002B, 0x0000002A, 0x00000029, 0x00000028, 0x00000027, 0x00000026, 0x00000025, 
+            0x00000024, 0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001F, 0x0000001E, 0x0000001D, 
+            0x0000001C, 0x0000001B, 0x0000001A, 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015, 
+            0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000010, 0x0000000F, 0x0000000E, 0x0000000D, 
+            0x0000000C, 0x0000000B, 0x0000000A, 0x00000009, 0x00000008, 0x00000007, 0x00000006, 0x00000005, 
+            0x00000004, 0x00000003, 0x00000002, 0x00000001, 0x00000000
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 0.000000, 0.000000, 5.806641, 0.000000, 5.806641, 0.000000, 
+            9.087891, 0.000000, 18.679688, 0.000000, 15.251953, 0.000000, 25.365234, 0.000000, 
+            21.878906, 0.000000, 28.787109, 0.000000, 35.191406, 0.000000, 42.966797, 0.000000, 
+            38.279297, 0.000000, 47.982422, 0.000000, 44.085938, 0.000000, 44.085938, 0.000000, 
+            52.347656, 0.000000, 58.453125, 0.000000, 55.113281, 0.000000, 62.021484, 0.000000, 
+            66.292969, 0.000000, 64.886719, 0.000000, 69.292969, 0.000000, 67.886719, 0.000000, 
+            67.886719, 0.000000, 74.050781, 0.000000, 70.710938, 0.000000, 77.619141, 0.000000, 
+            77.619141, 0.000000, 83.425781, 0.000000, 90.527344, 0.000000, 86.513672, 0.000000, 
+            91.804688, 0.000000, 92.390625, 0.000000, 98.267578, 0.000000, 109.347656, 0.000000, 
+            104.894531, 0.000000, 110.701172, 0.000000, 116.250000, 0.000000, 113.701172, 0.000000, 
+            113.554688, 0.000000, 121.242188, 0.000000, 119.484375, 0.000000, 124.552734, 0.000000, 
+            122.677734, 0.000000, 126.679688, 0.000000, 126.679688, 0.000000, 135.210938, 0.000000, 
+            132.486328, 0.000000, 132.251953, 0.000000, 138.416016, 0.000000, 148.734375, 0.000000, 
+            145.042969, 0.000000, 155.308594, 0.000000, 151.968750, 0.000000, 162.773438, 0.000000, 
+            158.876953, 0.000000, 158.876953, 0.000000, 168.398438, 0.000000, 166.523438, 0.000000, 
+            172.546875, 0.000000, 170.525391, 0.000000, 173.689453, 0.000000, 182.718750, 0.000000, 
+            180.199219, 0.000000, 185.583984, 0.000000, 190.107422, 0.000000, 187.998047, 0.000000, 
+            194.132812, 0.000000, 192.257812, 0.000000, 196.259766, 0.000000, 199.423828, 0.000000, 
+            206.964844, 0.000000, 202.511719, 0.000000, 212.332031, 0.000000, 208.318359, 0.000000, 
+            217.886719, 0.000000, 214.195312, 0.000000, 221.121094, 0.000000, 221.121094, 0.000000, 
+            229.447266, 0.000000, 226.927734, 0.000000, 235.652344, 0.000000, 232.312500, 0.000000, 
+            232.312500, 0.000000, 242.648438, 0.000000, 239.220703, 0.000000, 245.847656, 0.000000, 
+            250.195312, 0.000000, 248.320312, 0.000000, 255.808594, 0.000000, 252.322266, 0.000000, 
+            259.230469, 0.000000, 265.042969, 0.000000, 262.083984, 0.000000, 271.675781, 0.000000, 
+            268.248047, 0.000000, 274.875000, 0.000000, 284.197266, 0.000000, 281.501953, 0.000000, 
+            287.250000, 0.000000, 287.250000, 0.000000, 290.531250, 0.000000, 298.212891, 0.000000, 
+            296.337891, 0.000000, 296.337891, 0.000000, 300.339844, 0.000000, 300.339844, 0.000000, 
+            306.146484, 0.000000, 313.687500, 0.000000, 309.234375, 0.000000, 318.732422, 0.000000, 
+            315.041016, 0.000000, 325.453125, 0.000000, 321.966797, 0.000000, 328.875000, 0.000000, 
+            333.222656, 0.000000, 331.347656, 0.000000, 338.044922, 0.000000, 335.349609, 0.000000, 
+            345.175781, 0.000000, 341.279297, 0.000000, 341.279297, 0.000000, 352.558594, 0.000000, 
+            349.218750, 0.000000, 356.126953, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Not Language Specific" script="latn">
+        <test-font name="fp9r8a.otf" version="Version 0.9.6 " checksum="0x62C6805F" rchecksum="0x00813376"/>
+
+        <test-text>Ţhiş iş a ţeşţ.</test-text>
+
+        <result-glyphs>
+            0x00000107, 0x00000049, 0x0000004A, 0x00000104, 0x00000001, 0x0000004A, 0x00000104, 0x00000001, 
+            0x00000042, 0x00000001, 0x00000108, 0x00000046, 0x00000104, 0x00000108, 0x0000000F
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 7.356000, 0.000000, 14.340000, 0.000000, 17.832001, 0.000000, 
+            22.920000, 0.000000, 25.920000, 0.000000, 29.412001, 0.000000, 34.500000, 0.000000, 
+            37.500000, 0.000000, 43.500000, 0.000000, 46.500000, 0.000000, 50.411999, 0.000000, 
+            56.160000, 0.000000, 61.248001, 0.000000, 65.160004, 0.000000, 68.160004, 0.000000
+        </result-positions>
+    </test-case>
+
+<!-- known to fail in base JDK7, skip ('lang' not supported)
+    <test-case id="Romanian Language Specific" script="latn" lang="ROM">
+        <test-font name="fp9r8a.otf" version="Version 0.9.6 " checksum="0x62C6805F" rchecksum="0x00813376"/>
+
+        <test-text>Ţhiş iş a ţeşţ.</test-text>
+
+        <result-glyphs>
+            0x00000127, 0x00000049, 0x0000004A, 0x00000126, 0x00000001, 0x0000004A, 0x00000126, 0x00000001, 
+            0x00000042, 0x00000001, 0x00000128, 0x00000046, 0x00000126, 0x00000128, 0x0000000F
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 7.356000, 0.000000, 14.340000, 0.000000, 17.832001, 0.000000, 
+            22.920000, 0.000000, 25.920000, 0.000000, 29.412001, 0.000000, 34.500000, 0.000000, 
+            37.500000, 0.000000, 43.500000, 0.000000, 46.500000, 0.000000, 50.411999, 0.000000, 
+            56.160000, 0.000000, 61.248001, 0.000000, 65.160004, 0.000000, 68.160004, 0.000000
+        </result-positions>
+    </test-case>
+-->
+
+    <test-case id="Nafees Nastaleeq Cursive Positioning Test" script="arab">
+        <test-font name="Nafees Nastaleeq v1.02.ttf" version="Version 1.02" checksum="0x1BD85538" rchecksum="0x0111F234"/>
+
+        <test-text>فتح بینچ خلیج شیخ پہنچ</test-text>
+
+        <result-glyphs>
+            0x0000003B, 0x00000344, 0x000001D5, 0x00000318, 0x00000349, 0x0000007C, 0x00000003, 0x0000003D, 
+            0x00000348, 0x000001D5, 0x00000346, 0x000000B5, 0x00000003, 0x0000003A, 0x00000348, 0x000001D5, 
+            0x000002E3, 0x00000344, 0x00000087, 0x00000003, 0x0000003B, 0x00000344, 0x000001D5, 0x00000348, 
+            0x000001E5, 0x00000347, 0x0000006E, 0x00000003, 0x0000003C, 0x00000345, 0x000001D5, 0x00000344, 
+            0x0000011D
+        </result-glyphs>
+
+        <result-indices>
+            0x00000015, 0x00000014, 0x00000014, 0x00000013, 0x00000012, 0x00000012, 0x00000011, 0x00000010, 
+            0x0000000F, 0x0000000F, 0x0000000E, 0x0000000E, 0x0000000D, 0x0000000C, 0x0000000B, 0x0000000B, 
+            0x0000000A, 0x00000009, 0x00000009, 0x00000008, 0x00000007, 0x00000006, 0x00000006, 0x00000005, 
+            0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000002, 0x00000001, 0x00000001, 0x00000000, 
+            0x00000000
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 3.205078, -11.097656, 1.406250, 0.000000, 4.558594, -1.376953, 
+            9.421875, -5.273438, 7.505859, -6.843750, 11.537109, 0.000000, 12.726562, 0.000000, 
+            20.455078, -4.798828, 15.357422, 0.000000, 19.289062, -13.072266, 18.509766, -1.376953, 
+            22.552734, 0.000000, 23.742188, 0.000000, 30.246094, -4.798828, 25.148438, 0.000000, 
+            28.300781, -1.376953, 32.917969, -13.792969, 30.158203, -7.792969, 35.208984, 0.000000, 
+            36.398438, 0.000000, 39.603516, -11.097656, 37.804688, 0.000000, 45.632812, 3.181641, 
+            40.957031, -1.376953, 44.853516, -6.046875, 42.457031, -5.572266, 46.066406, 0.000000, 
+            47.255859, 0.000000, 49.376953, -11.396484, 48.662109, 0.000000, 52.769531, -14.332031, 
+            51.814453, -1.376953, 56.789062, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Malayalam Samvruthokaram Test" script="mlym">
+        <test-font name="lohit_ml.ttf" version="Version 1.00" checksum="0x66CB0B82" rchecksum="0x002EEBD8"/>
+
+        <test-text>ണു്</test-text>
+
+        <result-glyphs>
+            0x00000023, 0x0000003C, 0x00000045
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 15.117188, 0.000000, 18.503906, 0.000000, 18.503906, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Broken Font Test" script="hani" lang="ZHT">
+        <test-font name="BMIN00M.TTF" version="Version 2.00" checksum="0xF16BE0C6" rchecksum="0x15E106D0"/>
+
+        <test-text>中華人民共和國 臺灣</test-text>
+
+        <result-glyphs>
+            0x00000292, 0x000024E8, 0x000002D1, 0x00001582, 0x000004A1, 0x00000650, 0x000007E2, 0x00000021, 
+            0x00002395, 0x00001896
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 12.000000, 0.000000, 24.000000, 0.000000, 36.000000, 0.000000, 
+            48.000000, 0.000000, 60.000000, 0.000000, 72.000000, 0.000000, 84.000000, 0.000000, 
+            90.000000, 0.000000, 102.000000, 0.000000, 114.000000, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Telugu Syllable Boundary Test" script="telu">
+        <test-font name="gautami.ttf" version="Version 5.02" checksum="0x45C66919" rchecksum="0x00DBFA1A"/>
+
+        <test-text>ప్రకాష్</test-text>
+
+        <result-glyphs>
+            0x00000057, 0x0000023B, 0x0000FFFF, 0x00000125, 0x00000066, 0x00000241, 0x0000FFFF
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x00000004, 0x00000005, 0x00000006
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 8.285156, 0.000000, 14.894531, 0.000000, 14.894531, 0.000000, 
+            21.503906, 0.000000, 25.136719, 0.000000, 33.421875, 0.000000, 33.421875, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Angsana New Mark Test" script="thai">
+        <test-font name="ANGSA.TTF" version="Version 5.00" checksum="0x95F16337" rchecksum="0x00724BC4"/>
+
+        <test-text>บทที่๑พายุไซโคลนโดโรธีอาศัยอยู่ท่ามกลางทุ่งใหญ่ในแคนซัสกับลุงเฮนรีชาวไร่และป้าเอ็มภรรยาชาวไร่บ้านของพวกเขาหลังเล็กเพราะไม้สร้างบ้านต้องขนมาด้วยเกวียนเป็นระยะทางหลายไมล์</test-text>
+
+        <result-glyphs>
+            0x0000009D, 0x0000009A, 0x0000009A, 0x000000B8, 0x000000C9, 0x000000D2, 0x000000A1, 0x000000B5, 
+            0x000000A5, 0x000000BB, 0x000000C5, 0x0000008E, 0x000000C3, 0x00000087, 0x000000A8, 0x0000009C, 
+            0x000000C3, 0x00000097, 0x000000C3, 0x000000A6, 0x0000009B, 0x000000B8, 0x000000B0, 0x000000B5, 
+            0x000000AB, 0x000000B4, 0x000000A5, 0x000000B0, 0x000000A5, 0x000000BC, 0x0000006E, 0x0000009A, 
+            0x0000006E, 0x000000B5, 0x000000A4, 0x00000084, 0x000000A8, 0x000000B5, 0x0000008A, 0x0000009A, 
+            0x000000BB, 0x0000006E, 0x0000008A, 0x000000C4, 0x000000AE, 0x00000090, 0x0000006E, 0x000000C4, 
+            0x0000009C, 0x000000C2, 0x00000087, 0x0000009C, 0x0000008E, 0x000000B4, 0x000000AD, 0x00000084, 
+            0x000000B4, 0x0000009D, 0x000000A8, 0x000000BB, 0x0000008A, 0x000000C1, 0x000000B1, 0x0000009C, 
+            0x000000A6, 0x000000B8, 0x0000008D, 0x000000B5, 0x000000AA, 0x000000C5, 0x000000A6, 0x0000006E, 
+            0x000000C2, 0x000000A8, 0x000000B3, 0x0000009E, 0x0000006F, 0x000000B5, 0x000000C1, 0x000000B0, 
+            0x000000C8, 0x000000A4, 0x000000A3, 0x000000A6, 0x000000A6, 0x000000A5, 0x000000B5, 0x0000008D, 
+            0x000000B5, 0x000000AA, 0x000000C5, 0x000000A6, 0x0000006E, 0x0000009D, 0x0000006F, 0x000000B5, 
+            0x0000009C, 0x00000085, 0x000000B0, 0x0000008A, 0x000000A1, 0x000000AA, 0x00000084, 0x000000C1, 
+            0x00000085, 0x000000B5, 0x000000AE, 0x000000A8, 0x000000B4, 0x0000008A, 0x000000C1, 0x000000A8, 
+            0x000000C8, 0x00000084, 0x000000C1, 0x000000A1, 0x000000A6, 0x000000B5, 0x000000B3, 0x000000C5, 
+            0x000000A4, 0x0000006F, 0x000000AD, 0x000000A6, 0x0000006F, 0x000000B5, 0x0000008A, 0x0000009D, 
+            0x0000006F, 0x000000B5, 0x0000009C, 0x00000098, 0x0000006F, 0x000000B0, 0x0000008A, 0x00000085, 
+            0x0000009C, 0x000000A4, 0x000000B5, 0x00000097, 0x0000006F, 0x000000AA, 0x000000A5, 0x000000C1, 
+            0x00000084, 0x000000AA, 0x000000B8, 0x000000A5, 0x0000009C, 0x000000C1, 0x0000009E, 0x000000C8, 
+            0x0000009C, 0x000000A6, 0x000000B3, 0x000000A5, 0x000000B3, 0x0000009A, 0x000000B5, 0x0000008A, 
+            0x000000AE, 0x000000A8, 0x000000B5, 0x000000A5, 0x000000C5, 0x000000A4, 0x000000A8, 0x00000072
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 
+            0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x0000001E, 0x0000001F, 
+            0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026, 0x00000027, 
+            0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, 0x0000002E, 0x0000002F, 
+            0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 
+            0x00000038, 0x00000039, 0x0000003A, 0x0000003B, 0x0000003C, 0x0000003D, 0x0000003E, 0x0000003F, 
+            0x00000040, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 
+            0x00000048, 0x00000049, 0x0000004A, 0x0000004B, 0x0000004C, 0x0000004D, 0x0000004E, 0x0000004F, 
+            0x00000050, 0x00000051, 0x00000052, 0x00000053, 0x00000054, 0x00000055, 0x00000056, 0x00000057, 
+            0x00000058, 0x00000059, 0x0000005A, 0x0000005B, 0x0000005C, 0x0000005D, 0x0000005E, 0x0000005F, 
+            0x00000060, 0x00000061, 0x00000062, 0x00000063, 0x00000064, 0x00000065, 0x00000066, 0x00000067, 
+            0x00000068, 0x00000069, 0x0000006A, 0x0000006B, 0x0000006C, 0x0000006D, 0x0000006E, 0x0000006F, 
+            0x00000070, 0x00000071, 0x00000072, 0x00000073, 0x00000074, 0x00000075, 0x00000076, 0x00000077, 
+            0x00000078, 0x00000079, 0x0000007A, 0x0000007B, 0x0000007C, 0x0000007D, 0x0000007E, 0x0000007F, 
+            0x00000080, 0x00000081, 0x00000082, 0x00000083, 0x00000084, 0x00000085, 0x00000086, 0x00000087, 
+            0x00000088, 0x00000089, 0x0000008A, 0x0000008B, 0x0000008C, 0x0000008D, 0x0000008E, 0x0000008F, 
+            0x00000090, 0x00000091, 0x00000092, 0x00000093, 0x00000094, 0x00000095, 0x00000096, 0x00000097, 
+            0x00000098, 0x00000099, 0x0000009A, 0x0000009B, 0x0000009C, 0x0000009D, 0x0000009E, 0x0000009F, 
+            0x000000A0, 0x000000A1, 0x000000A2, 0x000000A3, 0x000000A4, 0x000000A5, 0x000000A6, 0x000000A7
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 5.399414, 0.000000, 10.798828, 0.000000, 15.072266, 0.000000, 
+            15.072266, 0.000000, 16.198242, 0.000000, 21.046875, 0.000000, 26.616211, 0.000000, 
+            30.035156, 0.000000, 31.312500, 0.000000, 34.151367, 0.000000, 38.279297, 0.000000, 
+            43.558594, 0.000000, 47.663086, 0.000000, 52.438477, 0.000000, 57.178711, 0.000000, 
+            62.698242, 0.000000, 66.802734, 0.000000, 71.601562, 0.000000, 75.706055, 0.000000, 
+            79.810547, 0.000000, 84.029297, 0.000000, 84.369141, 0.000000, 89.097656, 0.000000, 
+            92.516602, 0.000000, 97.614258, 0.000000, 97.195312, 0.000000, 101.311523, 0.000000, 
+            106.040039, 0.000000, 107.375977, 0.000000, 108.326172, -0.084961, 110.156250, 0.000000, 
+            113.497070, -0.084961, 115.555664, 0.000000, 118.974609, 0.000000, 124.013672, 0.000000, 
+            128.765625, 0.000000, 133.505859, 0.000000, 136.924805, 0.000000, 140.704102, 0.000000, 
+            143.036133, 0.000000, 144.044922, -0.084961, 146.103516, 0.000000, 149.882812, 0.000000, 
+            153.553711, 0.000000, 159.158203, 0.000000, 163.377930, -0.084961, 165.421875, 0.000000, 
+            169.092773, 0.000000, 174.612305, 0.000000, 179.135742, 0.000000, 183.911133, 0.000000, 
+            189.430664, 0.000000, 194.879883, 0.000000, 194.709961, 0.000000, 199.989258, 0.000000, 
+            204.092773, -0.084961, 204.741211, 0.000000, 210.140625, 0.000000, 212.828125, 0.000000, 
+            214.880859, 0.000000, 218.660156, 0.000000, 220.675781, 0.000000, 225.128906, 0.000000, 
+            230.648438, 0.000000, 234.105469, 0.000000, 234.752930, 0.000000, 239.613281, 0.000000, 
+            243.032227, 0.000000, 247.280273, 0.000000, 251.408203, 0.000000, 253.932617, -0.084961, 
+            255.512695, 0.000000, 260.036133, 0.000000, 264.776367, 0.000000, 269.071289, 0.000000, 
+            272.704102, 0.000000, 274.470703, 0.000000, 277.889648, 0.000000, 279.905273, 0.000000, 
+            284.768555, 0.000000, 284.633789, 0.000000, 289.672852, 0.000000, 294.641602, 0.000000, 
+            298.746094, 0.000000, 302.850586, 0.000000, 306.966797, 0.000000, 310.385742, 0.000000, 
+            315.246094, 0.000000, 318.665039, 0.000000, 322.913086, 0.000000, 327.041016, 0.000000, 
+            329.565430, -0.084961, 331.145508, 0.000000, 335.911133, 0.000000, 336.544922, 0.000000, 
+            339.963867, 0.000000, 345.483398, 0.000000, 350.258789, 0.000000, 354.987305, 0.000000, 
+            358.766602, 0.000000, 364.335938, 0.000000, 368.583984, 0.000000, 373.335938, 0.000000, 
+            375.351562, 0.000000, 380.126953, 0.000000, 383.545898, 0.000000, 389.150391, 0.000000, 
+            394.306641, 0.000000, 393.890625, 0.000000, 397.669922, 0.000000, 399.685547, 0.000000, 
+            404.548828, 0.000000, 404.425781, 0.000000, 409.177734, 0.000000, 411.193359, 0.000000, 
+            416.762695, 0.000000, 420.867188, 0.000000, 424.286133, 0.000000, 428.581055, 0.000000, 
+            432.708984, 0.000000, 438.123047, 0.000000, 437.748047, 0.000000, 443.027344, 0.000000, 
+            446.976562, 0.000000, 447.131836, 0.000000, 450.550781, 0.000000, 454.330078, 0.000000, 
+            459.095703, 0.000000, 459.729492, 0.000000, 463.148438, 0.000000, 468.667969, 0.000000, 
+            473.847656, 0.000000, 473.478516, 0.000000, 478.207031, 0.000000, 481.986328, 0.000000, 
+            486.761719, 0.000000, 492.281250, 0.000000, 497.320312, 0.000000, 500.739258, 0.000000, 
+            505.860352, 0.000000, 505.538086, 0.000000, 509.786133, 0.000000, 513.902344, 0.000000, 
+            515.917969, 0.000000, 520.669922, 0.000000, 523.947266, 0.000000, 524.917969, 0.000000, 
+            529.034180, 0.000000, 534.553711, 0.000000, 536.569336, 0.000000, 540.846680, 0.000000, 
+            541.968750, 0.000000, 547.488281, 0.000000, 551.592773, 0.000000, 555.887695, 0.000000, 
+            560.003906, 0.000000, 564.298828, 0.000000, 569.698242, 0.000000, 573.117188, 0.000000, 
+            576.896484, 0.000000, 582.500977, 0.000000, 587.241211, 0.000000, 590.660156, 0.000000, 
+            594.776367, 0.000000, 598.904297, 0.000000, 603.943359, 0.000000, 608.894531, 0.000000, 
+            608.683594, 0.000000
+        </result-positions>
+    </test-case>
+
+<!-- known to fail in base JDK7, skip  (come back to this later)
+    <test-case id="Sinhala Al-Lakuna Test" script="sinh">
+        <test-font name="lklug.hj.ttf" version="Version 0.6 " checksum="0xA190C2F4" rchecksum="0x00922218"/>
+
+        <test-text>ක්‍රෙ ක්‍යෙ ක්‍ෂෙ ක්‍ෂ්‍යෙ ක්ෂෙ කර්‍මෙ ස්ට්‍රේ ස‍්සෙ ස්ස</test-text>
+
+        <result-glyphs>
+            0x0000004A, 0x000001D5, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x0000004A, 0x00000018, 
+            0x0000008B, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x0000004A, 0x0000008A, 0x0000FFFF, 0x0000FFFF, 
+            0x0000FFFF, 0x00000003, 0x0000004A, 0x0000008A, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000008B, 
+            0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000001D6, 0x0000FFFF, 0x0000004A, 0x0000003C, 0x00000003, 
+            0x00000018, 0x0000004A, 0x000001F8, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000A9, 
+            0x0000FFFF, 0x0000004A, 0x0000007A, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000003, 
+            0x0000004A, 0x00000203, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00000003, 0x000000A9, 0x0000FFFF, 
+            0x0000003D
+        </result-glyphs>
+
+        <result-indices>
+            0x00000004, 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000005, 0x0000000A, 0x00000006, 
+            0x00000007, 0x00000008, 0x00000009, 0x0000000B, 0x00000010, 0x0000000C, 0x0000000D, 0x0000000E, 
+            0x0000000F, 0x00000011, 0x00000019, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 
+            0x00000017, 0x00000018, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001E, 0x0000001D, 0x0000001F, 
+            0x00000020, 0x00000025, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000026, 0x00000027, 
+            0x00000028, 0x0000002D, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, 0x0000002E, 
+            0x00000033, 0x0000002F, 0x00000030, 0x00000031, 0x00000032, 0x00000034, 0x00000035, 0x00000036, 
+            0x00000037
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 8.520000, 0.000000, 19.224001, 0.000000, 19.224001, 0.000000, 
+            19.224001, 0.000000, 19.224001, 0.000000, 26.640001, 0.000000, 35.160004, 0.000000, 
+            45.864006, 0.000000, 51.936005, 0.000000, 51.936005, 0.000000, 51.936005, 0.000000, 
+            59.352005, 0.000000, 67.872009, 0.000000, 82.704010, 0.000000, 82.704010, 0.000000, 
+            82.704010, 0.000000, 82.704010, 0.000000, 90.120010, 0.000000, 98.640015, 0.000000, 
+            113.472015, 0.000000, 113.472015, 0.000000, 113.472015, 0.000000, 113.472015, 0.000000, 
+            119.544014, 0.000000, 119.544014, 0.000000, 119.544014, 0.000000, 126.960014, 0.000000, 
+            137.664017, 0.000000, 137.664017, 0.000000, 146.184021, 0.000000, 154.296021, 0.000000, 
+            161.712021, 0.000000, 172.416016, 0.000000, 180.936020, 0.000000, 189.552017, 0.000000, 
+            189.552017, 0.000000, 189.552017, 0.000000, 189.552017, 0.000000, 196.968018, 0.000000, 
+            205.584015, 0.000000, 205.584015, 0.000000, 214.104019, 0.000000, 222.720016, 0.000000, 
+            222.720016, 0.000000, 222.720016, 0.000000, 222.720016, 0.000000, 222.720016, 0.000000, 
+            230.136017, 0.000000, 238.656021, 0.000000, 254.784027, 0.000000, 254.784027, 0.000000, 
+            254.784027, 0.000000, 254.784027, 0.000000, 262.200012, 0.000000, 270.816010, 0.000000, 
+            270.816010, 0.000000, 279.432007, 0.000000
+        </result-positions>
+    </test-case>
+-->
+
+    <test-case id="Arabic Presentation Forms LRO Test" script="arab">
+        <test-font name="trado.ttf" version="Version 1.01" checksum="0x7B68B462" rchecksum="0x00708871"/>
+
+        <test-text>‭ﻲﺑﺮﻌﻟﺎﺑ</test-text>
+
+        <result-glyphs>
+            0x0000FFFF, 0x00000206, 0x000001A5, 0x000001C2, 0x000001E0, 0x000001F3, 0x000001A2, 0x000001A5
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 0.000000, 0.000000, 5.759766, 0.000000, 7.980469, 0.000000, 
+            11.748047, 0.000000, 15.298828, 0.000000, 17.302734, 0.000000, 19.763672, 0.000000, 
+            21.984375, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Arabic Presentation Forms No LRO Test" script="arab">
+        <test-font name="trado.ttf" version="Version 1.01" checksum="0x7B68B462" rchecksum="0x00708871"/>
+
+        <test-text>ﻲﺑﺮﻌﻟﺎﺑ</test-text>
+
+        <result-glyphs>
+            0x000001A5, 0x000001A2, 0x000001F3, 0x000001E0, 0x000001C2, 0x000001A5, 0x00000206
+        </result-glyphs>
+
+        <result-indices>
+            0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000001, 0x00000000
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 2.220703, 0.000000, 4.681641, 0.000000, 6.685547, 0.000000, 
+            10.236328, 0.000000, 14.003906, 0.000000, 16.224609, 0.000000, 21.984375, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Canonical Char Indices Test" script="latn">
+        <test-font name="arial.ttf" version="Version 5.01.2x" checksum="0x92F28CF6" rchecksum="0x02CF4C8A"/>
+
+        <test-text>ḤḤ</test-text>
+
+        <result-glyphs>
+            0x000009A3, 0x000009A3
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 8.666016, 0.000000, 17.332031, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="REPH ZWNJ Test" script="deva">
+        <test-font name="raghu.ttf" version="Original Version 1.00 (2005)" checksum="0x088DB135" rchecksum="0x00803FCE"/>
+
+        <test-text>र्य र्‌य</test-text>
+
+        <result-glyphs>
+            0x00000099, 0x0000005B, 0x0000FFFF, 0x00000003, 0x0000009A, 0x00000051, 0x00000001, 0x00000099
+        </result-glyphs>
+
+        <result-indices>
+            0x00000002, 0x00000000, 0x00000001, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 9.726562, 0.263672, 9.468750, 0.000000, 9.468750, 0.000000, 
+            15.468750, 0.000000, 25.130859, -0.451172, 21.984375, 0.000000, 21.984375, 0.000000, 
+            31.453125, 0.000000
+        </result-positions>
+    </test-case>
+
+<!-- known to fail in base JDK7, skip  ( won't load, 'bad font name' )
+    <test-case id="AppleChancery mort" script="latn">
+        <test-font name="Apple Chancery.ttf" version="6.1d4e1" checksum="0xC01C5902" rchecksum="0x014278BD"/>
+
+        <test-text>The quick brown fox jumps over the lazy dog. • Jackdaws love my big sphinx of quartz</test-text>
+
+        <result-glyphs>
+            0x00000157, 0x0000FFFF, 0x00000048, 0x00000003, 0x00000054, 0x00000058, 0x0000004C, 0x00000046, 
+            0x0000004E, 0x00000003, 0x00000045, 0x00000055, 0x00000052, 0x0000005A, 0x00000051, 0x00000003, 
+            0x00000049, 0x00000052, 0x0000005B, 0x00000003, 0x0000004D, 0x00000058, 0x00000050, 0x00000053, 
+            0x00000056, 0x00000003, 0x00000052, 0x00000059, 0x00000048, 0x00000055, 0x00000003, 0x00000152, 
+            0x0000FFFF, 0x00000048, 0x00000003, 0x0000004F, 0x00000044, 0x0000005D, 0x0000005C, 0x00000003, 
+            0x00000047, 0x00000052, 0x0000004A, 0x00000011, 0x00000003, 0x00000087, 0x00000003, 0x0000002D, 
+            0x00000044, 0x00000046, 0x0000004E, 0x00000047, 0x00000044, 0x0000005A, 0x00000056, 0x00000003, 
+            0x0000004F, 0x00000052, 0x00000059, 0x00000048, 0x00000003, 0x00000050, 0x0000005C, 0x00000003, 
+            0x00000045, 0x0000004C, 0x0000004A, 0x00000003, 0x00000056, 0x00000053, 0x0000004B, 0x0000004C, 
+            0x00000051, 0x0000005B, 0x00000003, 0x00000052, 0x00000049, 0x00000003, 0x00000054, 0x00000058, 
+            0x00000044, 0x00000055, 0x00000057, 0x0000005D
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 
+            0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x0000001E, 0x0000001F, 
+            0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026, 0x00000027, 
+            0x00000028, 0x00000029, 0x0000002A, 0x0000002B, 0x0000002C, 0x0000002D, 0x0000002E, 0x0000002F, 
+            0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034, 0x00000035, 0x00000036, 0x00000037, 
+            0x00000038, 0x00000039, 0x0000003A, 0x0000003B, 0x0000003C, 0x0000003D, 0x0000003E, 0x0000003F, 
+            0x00000040, 0x00000041, 0x00000042, 0x00000043, 0x00000044, 0x00000045, 0x00000046, 0x00000047, 
+            0x00000048, 0x00000049, 0x0000004A, 0x0000004B, 0x0000004C, 0x0000004D, 0x0000004E, 0x0000004F, 
+            0x00000050, 0x00000051, 0x00000052, 0x00000053
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 13.523438, 0.000000, 13.523438, 0.000000, 17.982422, 0.000000, 
+            21.316406, 0.000000, 27.134766, 0.000000, 33.861328, 0.000000, 37.412109, 0.000000, 
+            42.005859, 0.000000, 47.554688, 0.000000, 50.888672, 0.000000, 56.707031, 0.000000, 
+            61.705078, 0.000000, 66.849609, 0.000000, 74.378906, 0.000000, 81.152344, 0.000000, 
+            84.486328, 0.000000, 88.230469, 0.000000, 93.375000, 0.000000, 99.386719, 0.000000, 
+            102.720703, 0.000000, 105.914062, 0.000000, 112.640625, 0.000000, 122.109375, 0.000000, 
+            128.080078, 0.000000, 132.345703, 0.000000, 135.679688, 0.000000, 140.824219, 0.000000, 
+            146.232422, 0.000000, 150.691406, 0.000000, 155.689453, 0.000000, 159.023438, 0.000000, 
+            168.908203, 0.000000, 168.908203, 0.000000, 173.367188, 0.000000, 176.701172, 0.000000, 
+            179.900391, 0.000000, 186.058594, 0.000000, 190.998047, 0.000000, 197.501953, 0.000000, 
+            200.835938, 0.000000, 206.994141, 0.000000, 212.138672, 0.000000, 217.734375, 0.000000, 
+            220.212891, 0.000000, 223.546875, 0.000000, 230.214844, 0.000000, 233.548828, 0.000000, 
+            239.003906, 0.000000, 245.162109, 0.000000, 249.755859, 0.000000, 255.304688, 0.000000, 
+            261.462891, 0.000000, 267.621094, 0.000000, 275.150391, 0.000000, 279.416016, 0.000000, 
+            282.750000, 0.000000, 285.949219, 0.000000, 291.093750, 0.000000, 296.501953, 0.000000, 
+            300.960938, 0.000000, 304.294922, 0.000000, 313.763672, 0.000000, 320.267578, 0.000000, 
+            323.601562, 0.000000, 329.419922, 0.000000, 332.970703, 0.000000, 338.566406, 0.000000, 
+            341.900391, 0.000000, 346.166016, 0.000000, 352.136719, 0.000000, 358.523438, 0.000000, 
+            362.074219, 0.000000, 368.847656, 0.000000, 374.859375, 0.000000, 378.193359, 0.000000, 
+            383.337891, 0.000000, 387.082031, 0.000000, 390.416016, 0.000000, 396.234375, 0.000000, 
+            402.960938, 0.000000, 409.119141, 0.000000, 414.117188, 0.000000, 418.365234, 0.000000, 
+            423.304688, 0.000000
+        </result-positions>
+    </test-case>
+-->
+
+<!-- known to fail in base JDK7, skip  ( won't load, 'bad font name') 
+    <test-case id="Zapfino morx" script="latn">
+        <test-font name="Zapfino.ttf" version="8.0d1e1" checksum="0x78FF7638" rchecksum="0x00EDBCB6"/>
+
+        <test-text>Pack my bags with six dozen liquor jugs</test-text>
+
+        <result-glyphs>
+            0x00000040, 0x000001F8, 0x00000203, 0x00000230, 0x00000003, 0x00000239, 0x00000274, 0x00000003, 
+            0x000001FE, 0x000001F8, 0x0000021D, 0x00000255, 0x00000003, 0x0000026C, 0x00000228, 0x0000025C, 
+            0x00000223, 0x00000003, 0x00000255, 0x00000228, 0x00000270, 0x00000003, 0x00000207, 0x00000244, 
+            0x0000027A, 0x00000210, 0x0000023D, 0x00000003, 0x00000235, 0x00000228, 0x0000024D, 0x00000264, 
+            0x00000244, 0x00000251, 0x00000003, 0x0000022C, 0x00000264, 0x0000021D, 0x00000255
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 
+            0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C, 0x0000001D, 0x0000001E, 0x0000001F, 
+            0x00000020, 0x00000021, 0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000026
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 12.630000, 0.000000, 21.180000, 0.000000, 27.600000, 0.000000, 
+            36.599998, 0.000000, 42.599998, 0.000000, 53.160000, 0.000000, 59.970001, 0.000000, 
+            65.970001, 0.000000, 73.620003, 0.000000, 82.170006, 0.000000, 89.370003, 0.000000, 
+            94.740005, 0.000000, 100.740005, 0.000000, 112.050003, 0.000000, 117.480003, 0.000000, 
+            123.420006, 0.000000, 131.400009, 0.000000, 137.400009, 0.000000, 142.770004, 0.000000, 
+            148.199997, 0.000000, 155.699997, 0.000000, 161.699997, 0.000000, 169.830002, 0.000000, 
+            177.330002, 0.000000, 184.020004, 0.000000, 190.169998, 0.000000, 198.000000, 0.000000, 
+            204.000000, 0.000000, 210.089996, 0.000000, 215.519989, 0.000000, 223.229996, 0.000000, 
+            230.940002, 0.000000, 238.440002, 0.000000, 244.290009, 0.000000, 250.290009, 0.000000, 
+            256.140015, 0.000000, 263.850006, 0.000000, 271.050018, 0.000000, 276.420013, 0.000000
+        </result-positions>
+    </test-case>
+-->
+
+    <test-case id="SourceCodePro-Regular.otf" script="latn">
+        <test-font name="SourceCodePro-Regular.otf" version="Version 1.009;PS 1.000;hotconv 1.0.70;makeotf.lib2.5.5900" checksum="0x9EFE425F" rchecksum="0x0074AEC5"/>
+
+        <test-text>Li kien kien, li kieku kieku.</test-text>
+
+        <result-glyphs>
+            0x0000000D, 0x00000024, 0x00000001, 0x00000026, 0x00000024, 0x00000020, 0x00000029, 0x00000001, 
+            0x00000026, 0x00000024, 0x00000020, 0x00000029, 0x000001D0, 0x00000001, 0x00000027, 0x00000024, 
+            0x00000001, 0x00000026, 0x00000024, 0x00000020, 0x00000026, 0x00000030, 0x00000001, 0x00000026, 
+            0x00000024, 0x00000020, 0x00000026, 0x00000030, 0x000001CF
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 
+            0x00000018, 0x00000019, 0x0000001A, 0x0000001B, 0x0000001C
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 7.200000, 0.000000, 14.400000, 0.000000, 21.599998, 0.000000, 
+            28.799999, 0.000000, 36.000000, 0.000000, 43.200001, 0.000000, 50.400002, 0.000000, 
+            57.600002, 0.000000, 64.800003, 0.000000, 72.000000, 0.000000, 79.199997, 0.000000, 
+            86.399994, 0.000000, 93.599991, 0.000000, 100.799988, 0.000000, 107.999985, 0.000000, 
+            115.199982, 0.000000, 122.399979, 0.000000, 129.599976, 0.000000, 136.799973, 0.000000, 
+            143.999969, 0.000000, 151.199966, 0.000000, 158.399963, 0.000000, 165.599960, 0.000000, 
+            172.799957, 0.000000, 179.999954, 0.000000, 187.199951, 0.000000, 194.399948, 0.000000, 
+            201.599945, 0.000000, 208.799942, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="SourceSansPro-Regular.otf" script="latn">
+        <test-font name="SourceSansPro-Regular.otf" version="Version 1.036;PS 1.000;hotconv 1.0.70;makeotf.lib2.5.5900" checksum="0x0EDDDCF3" rchecksum="0x008F9D5C"/>
+
+        <test-text>Il-Mistoqsija oħt l-għerf.</test-text>
+
+        <result-glyphs>
+            0x0000000A, 0x00000027, 0x00000210, 0x0000000E, 0x00000024, 0x0000002E, 0x0000002F, 0x0000002A, 
+            0x0000002C, 0x0000002E, 0x00000024, 0x00000025, 0x0000001C, 0x00000001, 0x0000002A, 0x0000011F, 
+            0x0000002F, 0x00000001, 0x00000027, 0x00000210, 0x00000022, 0x0000011F, 0x00000020, 0x0000002D, 
+            0x00000021, 0x000001FB
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017, 
+            0x00000018, 0x00000019
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 3.096000, 0.000000, 6.156000, 0.000000, 9.888000, 0.000000, 
+            18.552000, 0.000000, 21.504000, 0.000000, 26.532000, 0.000000, 30.467999, 0.000000, 
+            36.972000, 0.000000, 43.571999, 0.000000, 48.599998, 0.000000, 51.551998, 0.000000, 
+            54.515999, 0.000000, 60.660000, 0.000000, 63.084000, 0.000000, 69.587997, 0.000000, 
+            76.115997, 0.000000, 80.171997, 0.000000, 82.596001, 0.000000, 85.655998, 0.000000, 
+            89.388000, 0.000000, 95.435997, 0.000000, 101.963997, 0.000000, 107.916000, 0.000000, 
+            112.080002, 0.000000, 114.984001, 0.000000, 117.972000, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Tibetan" script="tibt">
+        <test-font name="Jomolhari-alpha3c-0605331.ttf" version="Version alpha 0.003c 2006" checksum="0x0C1F08DC" rchecksum="0x067378EF"/>
+
+        <test-text>༄༅།། ཏིན་ཏིན་གྱི་དཔའ་རྩལ</test-text>
+
+        <result-glyphs>
+            0x00000145, 0x0000FFFF, 0x00000151, 0x00000151, 0x00000003, 0x0000046C, 0x00000BFD, 0x0000059A, 
+            0x0000014E, 0x0000046C, 0x00000BFD, 0x0000059A, 0x0000014E, 0x000002CA, 0x0000FFFF, 0x00000BFD, 
+            0x0000014E, 0x0000050E, 0x00000611, 0x00000848, 0x0000014E, 0x0000093C, 0x0000FFFF, 0x0000098B
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F, 
+            0x00000010, 0x00000011, 0x00000012, 0x00000013, 0x00000014, 0x00000015, 0x00000016, 0x00000017
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 14.906250, 0.000000, 14.906250, 0.000000, 17.648438, 0.000000, 
+            20.390625, 0.000000, 23.906250, 0.000000, 29.109375, 0.000000, 29.109375, 0.000000, 
+            34.171875, 0.000000, 35.929688, 0.000000, 41.132812, 0.000000, 41.132812, 0.000000, 
+            46.195312, 0.000000, 47.953125, 0.000000, 54.773438, 0.000000, 54.773438, 0.000000, 
+            54.773438, 0.000000, 56.531250, 0.000000, 61.875000, 0.000000, 67.570312, 0.000000, 
+            73.195312, 0.000000, 74.953125, 0.000000, 80.437500, 0.000000, 80.437500, 0.000000, 
+            87.328125, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="Old Hangul" script="hang">
+        <test-font name="UnBatangOdal.ttf" version="Version 1.00" checksum="0x4BA78B70" rchecksum="0x0A18D67F"/>
+
+        <test-text>ᄊᆞᆷ ᄒᆞᆫ글 ᄀᆞᇹ ᄫᆞᆼ</test-text>
+
+        <result-glyphs>
+            0x000044FF, 0x00004707, 0x00004859, 0x00000005, 0x0000462B, 0x00004707, 0x00004785, 0x000019B2, 
+            0x00000005, 0x00004361, 0x00004707, 0x0000498D, 0x00000005, 0x000044C3, 0x00004707, 0x00004911
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 12.000000, 0.000000, 12.000000, 0.000000, 12.000000, 0.000000, 
+            14.700000, 0.000000, 26.700001, 0.000000, 26.700001, 0.000000, 26.700001, 0.000000, 
+            38.700001, 0.000000, 41.400002, 0.000000, 53.400002, 0.000000, 53.400002, 0.000000, 
+            53.400002, 0.000000, 56.100002, 0.000000, 68.100006, 0.000000, 68.100006, 0.000000, 
+            68.100006, 0.000000
+        </result-positions>
+    </test-case>
+
+    <test-case id="DevaRotate" script="deva">
+        <test-font name="LucidaSansRegular.ttf" version="Version 1.20 - October 2000" checksum="0xF5D9BA6D" rchecksum="0x029B644F"/>
+
+        <test-text>के े</test-text>
+
+        <result-glyphs>
+            0x00000901, 0x00000931, 0x00000003, 0x00000956, 0x00000931
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000003
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 5.935547, 0.000000, 8.548828, 0.000000, 12.345703, 0.000000, 
+            17.085938, 0.000000, 18.345703, 0.000000
+        </result-positions>
+    </test-case>
+
+
+    <test-case id="DevaGASP" script="deva">
+        <test-font name="LucidaSansRegular.ttf" version="Version 1.20 - October 2000" checksum="0xF5D9BA6D" rchecksum="0x029B644F"/>
+
+        <test-text>अँग्रेज़ी</test-text>
+
+        <result-glyphs>
+            0x000008F1, 0x000008EE, 0x000009CB, 0x0000FFFF, 0x0000FFFF, 0x00000931, 0x00000940, 0x0000FFFF, 
+            0x0000092A
+        </result-glyphs>
+
+        <result-indices>
+            0x00000000, 0x00000001, 0x00000002, 0x00000004, 0x00000003, 0x00000005, 0x00000006, 0x00000007, 
+            0x00000008
+        </result-indices>
+
+        <result-positions>
+            0.000000, 0.000000, 9.076172, 0.000000, 9.076172, 0.000000, 16.025391, 0.000000, 
+            16.025391, 0.000000, 16.025391, 0.000000, 16.025391, 0.000000, 23.976562, 0.000000, 
+            23.976562, 0.000000, 27.304688, 0.000000
+        </result-positions>
+    </test-case>
+
+</layout-tests>