changeset 4019:86a1b36090e4

RT-31139: Open source javafx-font and javafx-font-native
author kcr
date Thu, 20 Jun 2013 09:48:36 -0700
parents 983af42d54d0
children 646fda36947d
files build.gradle build.xml generator.gradle gradleBuildSrc/armv6hf.gradle gradleBuildSrc/armv6sf.gradle gradleBuildSrc/ios.gradle gradleBuildSrc/linux.gradle gradleBuildSrc/mac.gradle gradleBuildSrc/win.gradle javafx-font-native/Android.mk javafx-font-native/Makefile javafx-font-native/nbproject/Makefile-Debug.mk javafx-font-native/nbproject/Makefile-Release.mk javafx-font-native/nbproject/Makefile-impl.mk javafx-font-native/nbproject/Package-Debug.bash javafx-font-native/nbproject/Package-Release.bash javafx-font-native/nbproject/configurations.xml javafx-font-native/nbproject/project.xml javafx-font-native/src/MacFontFinder.c javafx-font-native/src/coretext.c javafx-font-native/src/dfontdecoder.c javafx-font-native/src/directwrite.cpp javafx-font-native/src/fontpath.c javafx-font-native/src/fontpath_linux.c javafx-font/build-android.xml javafx-font/build-closed.xml javafx-font/build-common.xml javafx-font/build-ios.xml javafx-font/build-linux.xml javafx-font/build-macosx.xml javafx-font/build-solaris.xml javafx-font/build-windows.xml javafx-font/build.xml javafx-font/javafx-font.iml javafx-font/nbproject/project.xml javafx-font/project.properties javafx-font/src/com/sun/javafx/font/AndroidFontFinder.java javafx-font/src/com/sun/javafx/font/CMap.java javafx-font/src/com/sun/javafx/font/CharToGlyphMapper.java javafx-font/src/com/sun/javafx/font/CompositeFontResource.java javafx-font/src/com/sun/javafx/font/CompositeGlyphMapper.java javafx-font/src/com/sun/javafx/font/CompositeStrike.java javafx-font/src/com/sun/javafx/font/CompositeStrikeDisposer.java javafx-font/src/com/sun/javafx/font/DFontDecoder.java javafx-font/src/com/sun/javafx/font/Disposer.java javafx-font/src/com/sun/javafx/font/DisposerRecord.java javafx-font/src/com/sun/javafx/font/FallbackResource.java javafx-font/src/com/sun/javafx/font/FontConfigManager.java javafx-font/src/com/sun/javafx/font/FontConstants.java javafx-font/src/com/sun/javafx/font/FontFactory.java javafx-font/src/com/sun/javafx/font/FontFileReader.java javafx-font/src/com/sun/javafx/font/FontFileWriter.java javafx-font/src/com/sun/javafx/font/FontResource.java javafx-font/src/com/sun/javafx/font/FontStrike.java javafx-font/src/com/sun/javafx/font/FontStrikeDesc.java javafx-font/src/com/sun/javafx/font/Glyph.java javafx-font/src/com/sun/javafx/font/LogicalFont.java javafx-font/src/com/sun/javafx/font/MacFontFinder.java javafx-font/src/com/sun/javafx/font/Metrics.java javafx-font/src/com/sun/javafx/font/OpenTypeGlyphMapper.java javafx-font/src/com/sun/javafx/font/PGFont.java javafx-font/src/com/sun/javafx/font/PrismCompositeFontResource.java javafx-font/src/com/sun/javafx/font/PrismFont.java javafx-font/src/com/sun/javafx/font/PrismFontFactory.java javafx-font/src/com/sun/javafx/font/PrismFontFile.java javafx-font/src/com/sun/javafx/font/PrismFontLoader.java javafx-font/src/com/sun/javafx/font/PrismFontStrike.java javafx-font/src/com/sun/javafx/font/PrismFontUtils.java javafx-font/src/com/sun/javafx/font/PrismMetrics.java javafx-font/src/com/sun/javafx/font/WindowsFontMap.java javafx-font/src/com/sun/javafx/font/WoffDecoder.java javafx-font/src/com/sun/javafx/font/android_system_fonts.xml javafx-font/src/com/sun/javafx/font/coretext/CFRange.java javafx-font/src/com/sun/javafx/font/coretext/CGAffineTransform.java javafx-font/src/com/sun/javafx/font/coretext/CGPoint.java javafx-font/src/com/sun/javafx/font/coretext/CGRect.java javafx-font/src/com/sun/javafx/font/coretext/CGSize.java javafx-font/src/com/sun/javafx/font/coretext/CTFactory.java javafx-font/src/com/sun/javafx/font/coretext/CTFontFile.java javafx-font/src/com/sun/javafx/font/coretext/CTFontStrike.java javafx-font/src/com/sun/javafx/font/coretext/CTGlyph.java javafx-font/src/com/sun/javafx/font/coretext/CTGlyphLayout.java javafx-font/src/com/sun/javafx/font/coretext/CTStrikeDisposer.java javafx-font/src/com/sun/javafx/font/coretext/OS.java javafx-font/src/com/sun/javafx/font/directwrite/D2D1_COLOR_F.java javafx-font/src/com/sun/javafx/font/directwrite/D2D1_MATRIX_3X2_F.java javafx-font/src/com/sun/javafx/font/directwrite/D2D1_PIXEL_FORMAT.java javafx-font/src/com/sun/javafx/font/directwrite/D2D1_POINT_2F.java javafx-font/src/com/sun/javafx/font/directwrite/D2D1_RENDER_TARGET_PROPERTIES.java javafx-font/src/com/sun/javafx/font/directwrite/DWDisposer.java javafx-font/src/com/sun/javafx/font/directwrite/DWFactory.java javafx-font/src/com/sun/javafx/font/directwrite/DWFontFile.java javafx-font/src/com/sun/javafx/font/directwrite/DWFontStrike.java javafx-font/src/com/sun/javafx/font/directwrite/DWGlyph.java javafx-font/src/com/sun/javafx/font/directwrite/DWGlyphLayout.java javafx-font/src/com/sun/javafx/font/directwrite/DWRITE_GLYPH_METRICS.java javafx-font/src/com/sun/javafx/font/directwrite/DWRITE_GLYPH_RUN.java javafx-font/src/com/sun/javafx/font/directwrite/DWRITE_MATRIX.java javafx-font/src/com/sun/javafx/font/directwrite/DWRITE_SCRIPT_ANALYSIS.java javafx-font/src/com/sun/javafx/font/directwrite/ID2D1Brush.java javafx-font/src/com/sun/javafx/font/directwrite/ID2D1Factory.java javafx-font/src/com/sun/javafx/font/directwrite/ID2D1RenderTarget.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteFactory.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteFont.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteFontCollection.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteFontFace.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteFontFamily.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteFontFile.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteFontList.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteGlyphRunAnalysis.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteLocalizedStrings.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteTextAnalyzer.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteTextFormat.java javafx-font/src/com/sun/javafx/font/directwrite/IDWriteTextLayout.java javafx-font/src/com/sun/javafx/font/directwrite/IUnknown.java javafx-font/src/com/sun/javafx/font/directwrite/IWICBitmap.java javafx-font/src/com/sun/javafx/font/directwrite/IWICBitmapLock.java javafx-font/src/com/sun/javafx/font/directwrite/IWICImagingFactory.java javafx-font/src/com/sun/javafx/font/directwrite/JFXTextAnalysisSink.java javafx-font/src/com/sun/javafx/font/directwrite/JFXTextRenderer.java javafx-font/src/com/sun/javafx/font/directwrite/OS.java javafx-font/src/com/sun/javafx/font/directwrite/RECT.java javafx-font/src/com/sun/javafx/text/CharArrayIterator.java javafx-font/src/com/sun/javafx/text/GlyphLayout.java javafx-font/src/com/sun/javafx/text/LayoutCache.java javafx-font/src/com/sun/javafx/text/PrismTextLayout.java javafx-font/src/com/sun/javafx/text/PrismTextLayoutFactory.java javafx-font/src/com/sun/javafx/text/ScriptMapper.java javafx-font/src/com/sun/javafx/text/TextLine.java javafx-font/src/com/sun/javafx/text/TextRun.java javafx-font/test/com/sun/javafx/font/PrismFontFactoryTest.java javafx-font/test/com/sun/javafx/text/TextLayoutTest.java javafx-font/test/com/sun/javafx/text/TextNodeTest.java javafx-font/tools/UnicodeScript.java javafx-geom/project.properties javafx-sg-prism/build-closed.xml javafx-sg-prism/project.properties javafx-ui-quantum/build-closed.xml javafx-ui-quantum/project.properties prism-common/build-closed.xml prism-common/project.properties prism-es2/build-closed.xml prism-es2/project.properties prism-j2d/build-closed.xml prism-j2d/project.properties prism-ps/build-closed.xml prism-ps/project.properties prism-sw/build-closed.xml prism-sw/project.properties webview/project.properties
diffstat 150 files changed, 24806 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/build.gradle	Thu Jun 20 09:21:12 2013 -0700
+++ b/build.gradle	Thu Jun 20 09:48:36 2013 -0700
@@ -877,7 +877,7 @@
     addNative(project, "glass");
     addNative(project, "prism")
     addNative(project, "prismSW")
-
+    addNative(project, "font")
     addNative(project, "iio")
     addNative(project, "prismES2")
 
@@ -1608,6 +1608,7 @@
                 from("modules/graphics/build/libs/jsl-decora/${t.name}/${library(targetProperties.decora.lib)}",
                      "modules/graphics/build/libs/prism/${t.name}/${library(targetProperties.prism.lib)}",
                      "modules/graphics/build/libs/prismSW/${t.name}/${library(targetProperties.prismSW.lib)}",
+                     "modules/graphics/build/libs/font/${t.name}/${library(targetProperties.font.lib)}",
                      "modules/graphics/build/libs/iio/${t.name}/${library(targetProperties.iio.lib)}");
                 def es2Variants = targetProperties.prismES2.containsKey("variants") ? targetProperties.prismES2.variants : [""];
                 es2Variants.each { variant ->
@@ -1989,7 +1990,7 @@
     }
 }
 
-// TODO need to do the iOS stuff (ios package of prism-es2-native, ios package of javafx-iio-native)
+// TODO need to do the iOS stuff (ios package of prism-es2-native, ios package of javafx-iio-native javafx-font-native)
 
 project(":graphics") {
     idea {
--- a/build.xml	Thu Jun 20 09:21:12 2013 -0700
+++ b/build.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -132,6 +132,7 @@
         <ant antfile="${rt.root.dir}/decora-prism-sw/build.xml" target="jar" inheritAll="false"/>
         <ant antfile="${rt.root.dir}/decora-prism-ps/build.xml" target="jar" inheritAll="false"/>
         <antcall target="jar-decora-sse"/>
+        <ant antfile="${rt.root.dir}/javafx-font/build.xml" target="jar" inheritAll="false"/>
         <ant antfile="${rt.root.dir}/prism-util/build.xml" target="jar" inheritAll="false"/>
         <ant antfile="${rt.root.dir}/prism-common/build.xml" target="jar" inheritAll="false"/>
         <ant antfile="${rt.root.dir}/prism-j2d/build.xml" target="jar" inheritAll="false"/>
@@ -268,6 +269,7 @@
         <ant antfile="${rt.root.dir}/decora-prism-sw/build.xml" target="clean" inheritAll="false"/>
         <ant antfile="${rt.root.dir}/decora-prism-ps/build.xml" target="clean" inheritAll="false"/>
         <antcall target="clean-decora-sse"/>
+        <ant antfile="${rt.root.dir}/javafx-font/build.xml" target="clean" inheritAll="false"/>
         <ant antfile="${rt.root.dir}/prism-util/build.xml" target="clean" inheritAll="false"/>
         <ant antfile="${rt.root.dir}/prism-common/build.xml" target="clean" inheritAll="false"/>
         <ant antfile="${rt.root.dir}/prism-j2d/build.xml" target="clean" inheritAll="false"/>
--- a/generator.gradle	Thu Jun 20 09:21:12 2013 -0700
+++ b/generator.gradle	Thu Jun 20 09:48:36 2013 -0700
@@ -246,6 +246,7 @@
              "${RTDir}/javafx-accessible/src",
              "${RTDir}/javafx-ui-common/src",
              "${RTDir}/javafx-concurrent/src",
+             "${RTDir}/javafx-font/src",
              "${RTDir}/javafx-geom/src",
              "${RTDir}/javafx-geom/cagsrc.double",
              "${RTDir}/javafx-iio/src",
@@ -286,6 +287,7 @@
              "${RTDir}/decora-sse/src",
              "${RTDir}/javafx-ui-common/src",
              "${RTDir}/javafx-concurrent/src",
+             "${RTDir}/javafx-font/src",
              "${RTDir}/javafx-geom/src",
              "${RTDir}/javafx-geom/cagsrc.double",
              "${RTDir}/javafx-iio/src",
@@ -410,6 +412,14 @@
     }
 
     copy {
+        from "${RTDir}/javafx-font-native/src"
+        into "${FXDir}/modules/graphics/src/main/native-font"
+        eachFile { f ->
+            fileList.add(f.file);
+        }
+    }
+
+    copy {
         from "${RTDir}/javafx-iio-native/src"
         into "${FXDir}/modules/graphics/src/main/native-iio"
         eachFile { f ->
--- a/gradleBuildSrc/armv6hf.gradle	Thu Jun 20 09:21:12 2013 -0700
+++ b/gradleBuildSrc/armv6hf.gradle	Thu Jun 20 09:48:36 2013 -0700
@@ -362,7 +362,7 @@
 ARMV6HF.font.javahInclude = [
         "com/sun/javafx/font/**/*",
         "com/sun/javafx/text/**/*"]
-ARMV6HF.font.nativeSource = [file("$closedDir/javafx-font-native/src")]
+ARMV6HF.font.nativeSource = [file("modules/graphics/src/main/native-font")]
 ARMV6HF.font.compiler = compiler
 ARMV6HF.font.ccFlags = fontCFlags
 ARMV6HF.font.linker = linker
--- a/gradleBuildSrc/armv6sf.gradle	Thu Jun 20 09:21:12 2013 -0700
+++ b/gradleBuildSrc/armv6sf.gradle	Thu Jun 20 09:48:36 2013 -0700
@@ -376,7 +376,7 @@
 ARMV6SF.font.javahInclude = [
         "com/sun/javafx/font/**/*",
         "com/sun/javafx/text/**/*"]
-ARMV6SF.font.nativeSource = [file("$closedDir/javafx-font-native/src")]
+ARMV6SF.font.nativeSource = [file("modules/graphics/src/main/native-font")]
 ARMV6SF.font.compiler = compiler
 ARMV6SF.font.ccFlags = fontCFlags
 ARMV6SF.font.linker = linker
--- a/gradleBuildSrc/ios.gradle	Thu Jun 20 09:21:12 2013 -0700
+++ b/gradleBuildSrc/ios.gradle	Thu Jun 20 09:48:36 2013 -0700
@@ -216,7 +216,7 @@
 IOS.font.variants = ["arm", "x86"];
 
 IOS.font.arm = [:]
-IOS.font.arm.nativeSource = [file("$closedDir/javafx-font-native/src")]
+IOS.font.arm.nativeSource = [file("modules/graphics/src/main/native-font")]
 IOS.font.arm.compiler = compiler
 IOS.font.arm.ccFlags = ["-DJFXFONT_PLUS", ccFlags, "-arch", archArm, "-isysroot", sdkPath(iPhoneOS)].flatten()
 IOS.font.arm.linker = linker
--- a/gradleBuildSrc/linux.gradle	Thu Jun 20 09:21:12 2013 -0700
+++ b/gradleBuildSrc/linux.gradle	Thu Jun 20 09:48:36 2013 -0700
@@ -178,7 +178,7 @@
         "com/sun/javafx/font/**/*",
         "com/sun/javafx/text/**/*"]
 LINUX.font.compiler = compiler
-LINUX.font.nativeSource = [file("$closedDir/javafx-font-native/src")]
+LINUX.font.nativeSource = [file("modules/graphics/src/main/native-font")]
 LINUX.font.ccFlags = ["-DJFXFONT_PLUS", ccFlags].flatten()
 LINUX.font.linker = linker
 LINUX.font.linkFlags = [linkFlags].flatten()
--- a/gradleBuildSrc/mac.gradle	Thu Jun 20 09:21:12 2013 -0700
+++ b/gradleBuildSrc/mac.gradle	Thu Jun 20 09:48:36 2013 -0700
@@ -176,7 +176,7 @@
 MAC.font.javahInclude = [
         "com/sun/javafx/font/**/*",
         "com/sun/javafx/text/**/*"]
-MAC.font.nativeSource = [file("$closedDir/javafx-font-native/src")]
+MAC.font.nativeSource = [file("modules/graphics/src/main/native-font")]
 MAC.font.compiler = compiler
 MAC.font.ccFlags = ["-DJFXFONT_PLUS", ccFlags].flatten()
 MAC.font.linker = linker
--- a/gradleBuildSrc/win.gradle	Thu Jun 20 09:21:12 2013 -0700
+++ b/gradleBuildSrc/win.gradle	Thu Jun 20 09:48:36 2013 -0700
@@ -240,7 +240,7 @@
 WIN.font.javahInclude = [
         "com/sun/javafx/font/**/*",
         "com/sun/javafx/text/**/*"]
-WIN.font.nativeSource = [file("$closedDir/javafx-font-native/src")]
+WIN.font.nativeSource = [file("modules/graphics/src/main/native-font")]
 WIN.font.compiler = compiler
 WIN.font.ccFlags = ["/DJFXFONT_PLUS", ccFlags].flatten()
 WIN.font.linker = linker
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/Android.mk	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,51 @@
+# 
+# Copyright (c) 2012, 2013, 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 $(CLEAR_VARS)
+LOCAL_PATH := src
+PREFIX := $(LOCAL_PATH)/
+
+C_SOURCES := $(wildcard $(LOCAL_PATH)/*.c)
+CPP_SOURCES := $(wildcard $(LOCAL_PATH)/*.cpp)
+
+LOCAL_MODULE := javafx-font
+
+LOCAL_SRC_FILES := $(C_SOURCES:$(PREFIX)%=%)
+LOCAL_SRC_FILES += $(CPP_SOURCES:$(PREFIX)%=%)
+
+LOCAL_C_INCLUDES := build/android \
+                    $(LOCAL_PATH) 
+
+$(info ===> LOCAL_PATH=$(LOCAL_PATH))
+$(info ===> PREFIX=$(PREFIX))
+$(info ===> C_SOURCES=$(C_SOURCES))
+$(info ===> CPP_SOURCES=$(CPP_SOURCES))
+$(info ===> LOCAL_SRC_FILES=$(LOCAL_SRC_FILES))
+$(info ===> LOCAL_C_INCLUDES=$(LOCAL_C_INCLUDES))
+ 
+
+LOCAL_CFLAGS += -DANDROID_NDK -std=c99
+LOCAL_LDLIBS := -llog -ldl
+include $(BUILD_SHARED_LIBRARY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/Makefile	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,297 @@
+#
+#  There exist several targets which are by default empty and which can be
+#  used for execution of your targets. These targets are usually executed
+#  before and after some main targets. They are:
+#
+#     .build-pre:              called before 'build' target
+#     .build-post:             called after 'build' target
+#     .clean-pre:              called before 'clean' target
+#     .clean-post:             called after 'clean' target
+#     .clobber-pre:            called before 'clobber' target
+#     .clobber-post:           called after 'clobber' target
+#     .all-pre:                called before 'all' target
+#     .all-post:               called after 'all' target
+#     .help-pre:                called before 'help' target
+#     .help-post:               called after 'help' target
+#
+#  Targets beginning with '.' are not intended to be called on their own.
+#
+#  Main targets can be executed directly, and they are:
+#
+#     build                    build a specific configuration
+#     clean                    remove built files from a configuration
+#     clobber                  remove all built files
+#     all                      build all configurations
+#     help                     print help mesage
+#
+#  Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+#  .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+# NOCDDL
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+
+# NOTE: the following variables are passed in from
+# the javafx-font/build-*.xml files
+ifndef DIST_DIR
+	DIST_DIR	= dist
+endif
+ifndef BUILD_DIR
+	BUILD_DIR	= build
+endif
+ifndef JFXFONT_CP
+	JFXFONT_CP	= ../javafx-font/build/classes
+endif
+ifndef JFXFONT_JAVA
+	JFXFONT_JAVA = ../javafx-font/src
+endif
+ifndef JAVAH_CP
+    JAVAH_CP = "../javafx-font/build/classes:../../rt/javafx-geom/build/classes:../../rt/javafx-ui-common/build/classes"
+endif
+
+ifndef CONF
+	CONF		= Release
+endif
+
+ifeq ($(CONF), Release)
+# -DNDEBUG is important to disable assert, widely used in t2k.
+		CC_PARAMS +=  -DNDEBUG
+endif
+
+JFXFONT_SRC	= src
+INCLUDES = $(wildcard $(JFXFONT_SRC)/*.h)
+
+ifndef JNI_FILES
+	JNI_FILES = \
+		com/sun/javafx/font/PrismFontFactory.java \
+		com/sun/javafx/font/FontConfigManager.java \
+		com/sun/javafx/font/DFontDecoder.java \
+		com/sun/javafx/font/MacFontFinder.java \
+		com/sun/javafx/font/coretext/OS.java \
+		com/sun/javafx/font/directwrite/OS.java 
+endif 
+
+JNI_INCLUDES = $(addprefix $(BUILD_DIR)/,$(subst /,_,$(subst .java,.h, $(JNI_FILES))))
+
+SYSTEM_UNAME := $(shell uname)
+JAVAH_FIX_CP = $(JAVAH_CP)
+
+ifneq (,$(findstring CYGWIN,$(SYSTEM_UNAME)))
+	fix_path = $(shell cygpath $1 $2)
+
+	ifndef JDK_HOME
+		JDK_HOME = c:/jdk1.6.0
+	endif
+	OBJ_SUFFIX  = obj
+	OUTPUT_FLAG = -Fo
+	JFXFONT_LIB	= $(DIST_DIR)/javafx-font.dll
+	JFXFONT_MAP	= $(DIST_DIR)/javafx-font.map
+	JFXFONT_PDB	= $(DIST_DIR)/javafx-font.pdb
+
+	JAVAH_FIX_CP = $(call fix_path,-mp,$(JAVAH_CP))
+
+	LINK		=  link.exe
+	CC		=  cl.exe
+
+# Need to link against some windows platform libs for font lookup.
+# advapi32.lib - for Windows Registry functions
+# user32.lib - for GetDC
+# gdi32.lib - for EnumFontFamilies
+
+	LINK_PARAMS	= -dll -out:$(JFXFONT_LIB) -pdb:$(JFXFONT_PDB) -map:$(JFXFONT_MAP) -nologo /manifest /opt:REF /incremental:no advapi32.lib gdi32.lib user32.lib dwrite.lib d2d1.lib windowscodecs.lib ole32.lib
+	CC_PARAMS	+= -nologo /D_STATIC_CPPLIB /D_DISABLE_DEPRECATE_STATIC_CPPLIB -Fd$(BUILD_DIR)/ -W3 -EHsc -DJFXFONT_PLUS -DLOGGING -DWIN32 -DIAL -D_LITTLE_ENDIAN -DWIN32_LEAN_AND_MEAN -I$(JFXFONT_SRC) -I$(BUILD_DIR) -I$(JDK_HOME)/include -I$(JDK_HOME)/include/win32 -c
+	ifeq ($(CONF), Release)
+		CC_PARAMS += -Ox -MD
+	else
+		LINK_PARAMS += /debug
+		CC_PARAMS += -MDd -Zi -Od -DDEBUG
+	endif
+endif
+
+ifeq ($(SYSTEM_UNAME), SunOS)
+	fix_path = $2
+
+	ifndef JDK_HOME
+		JDK_HOME = /java/re/jdk/1.6.0_10/latest/binaries/solaris-i586
+	endif
+	OBJ_SUFFIX  = o
+	OUTPUT_FLAG = -o # trailing blank required
+	JFXFONT_LIB	= $(DIST_DIR)/libjavafx-font.so
+
+	COMMON_PARAMS = -fno-strict-aliasing -fPIC -W -Wall  -Wno-unused -Wno-parentheses -fno-omit-frame-pointer
+    ifeq ($(CC), parfait-gcc)
+		LINK = parfait-gcc
+	else
+		CC = gcc
+		LINK = gcc
+	endif
+	LINK_PARAMS	= $(COMMON_PARAMS) -shared -o $(JFXFONT_LIB)
+	CC_PARAMS	= -O2 -ffast-math -Fd$(BUILD_DIR) $(COMMON_PARAMS) -DJFXFONT_PLUS -I$(JFXFONT_SRC) -I$(BUILD_DIR) -I$(JDK_HOME)/include -I$(JDK_HOME)/include/solaris -c
+endif
+
+ifeq ($(SYSTEM_UNAME), Linux)
+	fix_path = $2
+
+	ifndef JDK_HOME
+		JDK_HOME = /home/java2d/jdk/jdk1.6.0_10
+	endif
+	OBJ_SUFFIX  = o
+	OUTPUT_FLAG = -o # trailing blank required
+	JFXFONT_LIB	= $(DIST_DIR)/libjavafx-font.so
+
+	COMMON_PARAMS = -fno-strict-aliasing -fPIC -W -Wall  -Wno-unused -Wno-parentheses -fno-omit-frame-pointer -Wl,--no-as-needed
+# Link using g++ because of C++ usage. This gets us lstdc++ in the
+# dependencies. Alternatively link it statically using gcc by adding the
+# following variable definition at the end of the gcc link command line.
+# LINK_EXTRA_PARAMS = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
+# The advantage of g++ dynamic linking is smaller .so. But JDK has used
+# static linking with gcc because the ABI was not stable. Hopefully that's
+# changed in the Linux distros we'd support.
+	ifeq ($(CC), parfait-gcc)
+		LINK = parfait-g++
+	else
+		LINK = g++
+	endif
+	LINK_PARAMS	= $(COMMON_PARAMS) -shared -o $(JFXFONT_LIB)
+	CC_PARAMS	= -O2 -ffast-math -Fd$(BUILD_DIR) $(COMMON_PARAMS) -DJFXFONT_PLUS -I$(JFXFONT_SRC) -I$(BUILD_DIR) -I$(JDK_HOME)/include -I$(JDK_HOME)/include/linux -c
+
+endif
+
+ifeq ($(SYSTEM_UNAME), Darwin)
+	fix_path = $2
+
+	ifndef JDK_HOME
+		JDK_HOME = $(shell /usr/libexec/java_home)
+	endif
+	OBJ_SUFFIX  = o
+	OUTPUT_FLAG = -o # trailing blank required
+	
+	ifeq ($(IS_IOS),true)
+		IOS_SDK_BASE := $(shell xcode-select -print-path)
+		IOS_DEV = $(IOS_SDK_BASE)/Platforms/$(IOS_PLATFORM).platform/Developer
+		IOS_SDK = $(IOS_DEV)/SDKs/$(IOS_PLATFORM)$(IOS_VERSION).sdk
+
+		CC = $(IOS_DEV)/usr/bin/gcc
+		LINK = libtool
+	
+		JFXFONT_LIB	= $(DIST_DIR)/libjavafx-font-$(IOS_ARCH).a
+
+		ifeq ($(CONF),Debug)
+			COMMON_PARAMS = -gdwarf-2
+		endif
+		LINK_PARAMS = -static -arch_only $(IOS_ARCH) -syslibroot $(IOS_SDK) $(COMMON_PARAMS) -framework Foundation -framework CoreText -L$(IOS_SDK)/usr/lib -o $(JFXFONT_LIB)
+		CC_PARAMS   = -arch $(IOS_ARCH) -isysroot $(IOS_SDK) -miphoneos-version-min=5.0
+		CC_PARAMS  += -fno-common -Wall -fno-strict-aliasing -fwrapv  -fpascal-strings -O2 -ffast-math
+		CC_PARAMS  += -Fd$(BUILD_DIR) $(COMMON_PARAMS) -DJFXFONT_PLUS -I$(JFXFONT_SRC) -I$(BUILD_DIR) -I$(JDK_HOME)/include -I$(JDK_HOME)/include/darwin -c
+	else
+		JFXFONT_LIB	= $(DIST_DIR)/libjavafx-font.dylib
+
+		ifeq ($(CC), parfait-gcc)
+			COMMON_PARAMS = -mmacosx-version-min=10.6
+			LINK = parfait-g++
+		else
+			COMMON_PARAMS = -mmacosx-version-min=10.6 -arch i386 -arch x86_64 #-arch ppc
+			LINK = g++
+		endif
+		LINK_PARAMS = -framework ApplicationServices -dynamiclib $(COMMON_PARAMS) -o $(JFXFONT_LIB)
+		CC_PARAMS = -O2 -ffast-math -Fd$(BUILD_DIR) $(COMMON_PARAMS) -DJFXFONT_PLUS -I$(JFXFONT_SRC) -I$(BUILD_DIR) -I$(JDK_HOME)/include -I$(JDK_HOME)/include/darwin -c
+	endif
+endif
+
+
+OBJS += $(patsubst $(JFXFONT_SRC)/%.c,$(BUILD_DIR)/%.$(OBJ_SUFFIX),$(wildcard $(JFXFONT_SRC)/*.c))
+OBJS += $(patsubst $(JFXFONT_SRC)/%.cpp,$(BUILD_DIR)/%.$(OBJ_SUFFIX),$(wildcard $(JFXFONT_SRC)/*.cpp))
+
+JAVAH	= $(call fix_path,-u,$(JDK_HOME)/bin/javah)
+
+# build
+build: .build-pre $(JFXFONT_LIB) .build-post
+
+# generate parfait report, make must be launched with
+# CC=parfait-gcc CXX=parfait-g++ CPP=parfait-g++ cc=parfait-gcc LINK=parfait-g++
+parfait: build
+	parfait $(JFXFONT_LIB).bc -g $(DIST_DIR)/parfait
+
+$(JFXFONT_LIB) : $(OBJS)
+	$(LINK) $(LINK_PARAMS) $^
+
+VPATH = $(JFXFONT_SRC)
+
+$(BUILD_DIR)/%.$(OBJ_SUFFIX): %.cpp $(JNI_INCLUDES) $(INCLUDES)
+	$(CC) $(CC_PARAMS) $(OUTPUT_FLAG)$@ $<
+
+$(BUILD_DIR)/%.$(OBJ_SUFFIX): %.c $(JNI_INCLUDES) $(INCLUDES)
+	$(CC) $(CC_PARAMS) $(OUTPUT_FLAG)$@ $<
+
+.SECONDEXPANSION:
+$(BUILD_DIR)/%.h: $(JFXFONT_CP)/$$(subst _,/,%).class
+	$(JAVAH) -force -o $@ -jni -classpath "$(JAVAH_FIX_CP)" $(subst _,.,$*)
+
+sanity:
+	@if [ ! -d "$(JDK_HOME)" ]; then \
+		echo "ERROR: path to Java 6 SDK: $(JDK_HOME) is not found."; \
+		echo "Override the location on the command line"; \
+		echo "using ALT_BOOTDIR variable."; \
+		echo "Sanity check failed."; \
+		exit 1; \
+	fi;
+
+.build-pre: sanity
+	@mkdir -p $(BUILD_DIR) $(DIST_DIR)
+
+.build-post:
+# Add your post 'build' code here...
+
+
+# clean
+#clean: .clean-pre .clean-impl .clean-post
+clean: .clean-pre .clean-post
+	rm -rf $(BUILD_DIR) $(DIST_DIR)
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post:
+# Add your post 'clean' code here...
+
+
+# clobber
+#clobber: .clobber-pre .clobber-impl .clobber-post
+clobber: .clobber-pre .clobber-post
+	rm -rf $(BUILD_DIR) $(DIST_DIR)
+
+.clobber-pre:
+
+.clobber-post:
+# Add your post 'clobber' code here...
+
+
+# all
+#all: .all-pre .all-impl .all-post
+all: .all-pre build .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post:
+# Add your post 'all' code here...
+
+
+# help
+help: .help-pre .help-impl .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post:
+# Add your post 'help' code here...
+
+.PRECIOUS: $(JNI_INCLUDES)
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/nbproject/Makefile-Debug.mk	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,62 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=
+
+# Macros
+PLATFORM=Cygwin-Windows
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=build/Debug/${PLATFORM}
+
+# Object Files
+OBJECTFILES=
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+	${MAKE}  -f nbproject/Makefile-Debug.mk dist/Debug/${PLATFORM}/libjavafx-font-native.dll
+
+dist/Debug/${PLATFORM}/libjavafx-font-native.dll: ${OBJECTFILES}
+	${MKDIR} -p dist/Debug/${PLATFORM}
+	${LINK.c} -mno-cygwin -shared -o dist/Debug/${PLATFORM}/libjavafx-font-native.dll -fPIC ${OBJECTFILES} ${LDLIBSOPTIONS} 
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf:
+	${RM} -r build/Debug
+	${RM} dist/Debug/${PLATFORM}/libjavafx-font-native.dll
+
+# Subprojects
+.clean-subprojects:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/nbproject/Makefile-Release.mk	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,62 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=
+
+# Macros
+PLATFORM=Cygwin-Windows
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=build/Release/${PLATFORM}
+
+# Object Files
+OBJECTFILES=
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+	${MAKE}  -f nbproject/Makefile-Release.mk dist/Release/${PLATFORM}/libjavafx-font-native.dll
+
+dist/Release/${PLATFORM}/libjavafx-font-native.dll: ${OBJECTFILES}
+	${MKDIR} -p dist/Release/${PLATFORM}
+	${LINK.c} -mno-cygwin -shared -o dist/Release/${PLATFORM}/libjavafx-font-native.dll -fPIC ${OBJECTFILES} ${LDLIBSOPTIONS} 
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf:
+	${RM} -r build/Release
+	${RM} dist/Release/${PLATFORM}/libjavafx-font-native.dll
+
+# Subprojects
+.clean-subprojects:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/nbproject/Makefile-impl.mk	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,123 @@
+# 
+# Generated Makefile - do not edit! 
+# 
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a pre- and a post- target defined where you can add customization code.
+#
+# This makefile implements macros and targets common to all configurations.
+#
+# NOCDDL
+
+
+# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
+# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
+# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
+# and .clean-reqprojects-conf unless SUB has the value 'no'
+SUB_no=NO
+SUBPROJECTS=${SUB_${SUB}}
+BUILD_SUBPROJECTS_=.build-subprojects
+BUILD_SUBPROJECTS_NO=
+BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
+CLEAN_SUBPROJECTS_=.clean-subprojects
+CLEAN_SUBPROJECTS_NO=
+CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
+
+
+# Project Name
+PROJECTNAME=javafx-font-native
+
+# Active Configuration
+DEFAULTCONF=Debug
+CONF=${DEFAULTCONF}
+
+# All Configurations
+ALLCONFS=Debug Release 
+
+
+# build
+.build-impl: .build-pre .validate-impl .depcheck-impl
+	@#echo "=> Running $@... Configuration=$(CONF)"
+	${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf
+
+
+# clean
+.clean-impl: .clean-pre .validate-impl .depcheck-impl
+	@#echo "=> Running $@... Configuration=$(CONF)"
+	${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf
+
+
+# clobber 
+.clobber-impl: .clobber-pre .depcheck-impl
+	@#echo "=> Running $@..."
+	for CONF in ${ALLCONFS}; \
+	do \
+	    ${MAKE} -f nbproject/Makefile-$${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
+	done
+
+# all 
+.all-impl: .all-pre .depcheck-impl
+	@#echo "=> Running $@..."
+	for CONF in ${ALLCONFS}; \
+	do \
+	    ${MAKE} -f nbproject/Makefile-$${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf; \
+	done
+
+# dependency checking support
+.depcheck-impl:
+	@echo "# This code depends on make tool being used" >.dep.inc
+	@if [ -n "${MAKE_VERSION}" ]; then \
+	    echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
+	    echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
+	    echo "include \$${DEPFILES}" >>.dep.inc; \
+	    echo "endif" >>.dep.inc; \
+	else \
+	    echo ".KEEP_STATE:" >>.dep.inc; \
+	    echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
+	fi
+
+# configuration validation
+.validate-impl:
+	@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+	then \
+	    echo ""; \
+	    echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
+	    echo "See 'make help' for details."; \
+	    echo "Current directory: " `pwd`; \
+	    echo ""; \
+	fi
+	@if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+	then \
+	    exit 1; \
+	fi
+
+
+# help
+.help-impl: .help-pre
+	@echo "This makefile supports the following configurations:"
+	@echo "    ${ALLCONFS}"
+	@echo ""
+	@echo "and the following targets:"
+	@echo "    build  (default target)"
+	@echo "    clean"
+	@echo "    clobber"
+	@echo "    all"
+	@echo "    help"
+	@echo ""
+	@echo "Makefile Usage:"
+	@echo "    make [CONF=<CONFIGURATION>] [SUB=no] build"
+	@echo "    make [CONF=<CONFIGURATION>] [SUB=no] clean"
+	@echo "    make [SUB=no] clobber"
+	@echo "    make [SUB=no] all"
+	@echo "    make help"
+	@echo ""
+	@echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
+	@echo "    also build subprojects."
+	@echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
+	@echo "    also clean subprojects."
+	@echo "Target 'clobber' will remove all built files from all configurations and,"
+	@echo "    unless 'SUB=no', also from subprojects."
+	@echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
+	@echo "    also build subprojects."
+	@echo "Target 'help' prints this message."
+	@echo ""
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/nbproject/Package-Debug.bash	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,72 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+PLATFORM=Cygwin-Windows
+TMPDIR=build/Debug/${PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=dist/Debug/${PLATFORM}/libjavafx-font-native.dll
+OUTPUT_BASENAME=libjavafx-font-native.dll
+PACKAGE_TOP_DIR=libjavafx-font-native.dll/
+
+# Functions
+function checkReturnCode
+{
+    rc=$?
+    if [ $rc != 0 ]
+    then
+        exit $rc
+    fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+    mkdir -p "$1"
+    checkReturnCode
+    if [ "$2" != "" ]
+    then
+      chmod $2 "$1"
+      checkReturnCode
+    fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+    cp "$1" "$2"
+    checkReturnCode
+    if [ "$3" != "" ]
+    then
+        chmod $3 "$2"
+        checkReturnCode
+    fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p dist/Debug/${PLATFORM}/package
+rm -rf ${TMPDIR}
+mkdir -p ${TMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory ${TMPDIR}/libjavafx-font-native.dll/lib
+copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f dist/Debug/${PLATFORM}/package/libjavafx-font-native.dll.tar
+cd ${TMPDIR}
+tar -vcf ../../../../dist/Debug/${PLATFORM}/package/libjavafx-font-native.dll.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${TMPDIR}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/nbproject/Package-Release.bash	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,72 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+PLATFORM=Cygwin-Windows
+TMPDIR=build/Release/${PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=dist/Release/${PLATFORM}/libjavafx-font-native.dll
+OUTPUT_BASENAME=libjavafx-font-native.dll
+PACKAGE_TOP_DIR=libjavafx-font-native.dll/
+
+# Functions
+function checkReturnCode
+{
+    rc=$?
+    if [ $rc != 0 ]
+    then
+        exit $rc
+    fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+    mkdir -p "$1"
+    checkReturnCode
+    if [ "$2" != "" ]
+    then
+      chmod $2 "$1"
+      checkReturnCode
+    fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+    cp "$1" "$2"
+    checkReturnCode
+    if [ "$3" != "" ]
+    then
+        chmod $3 "$2"
+        checkReturnCode
+    fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p dist/Release/${PLATFORM}/package
+rm -rf ${TMPDIR}
+mkdir -p ${TMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory ${TMPDIR}/libjavafx-font-native.dll/lib
+copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f dist/Release/${PLATFORM}/package/libjavafx-font-native.dll.tar
+cd ${TMPDIR}
+tar -vcf ../../../../dist/Release/${PLATFORM}/package/libjavafx-font-native.dll.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${TMPDIR}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/nbproject/configurations.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="51">
+  <logicalFolder name="root" displayName="root" projectFiles="true">
+    <logicalFolder name="HeaderFiles"
+                   displayName="Header Files"
+                   projectFiles="true">
+    </logicalFolder>
+    <logicalFolder name="ResourceFiles"
+                   displayName="Resource Files"
+                   projectFiles="true">
+    </logicalFolder>
+    <logicalFolder name="SourceFiles"
+                   displayName="Source Files"
+                   projectFiles="true">
+    </logicalFolder>
+    <logicalFolder name="ExternalFiles"
+                   displayName="Important Files"
+                   projectFiles="false">
+      <itemPath>Makefile</itemPath>
+    </logicalFolder>
+  </logicalFolder>
+  <projectmakefile>Makefile</projectmakefile>
+  <confs>
+    <conf name="Debug" type="2">
+      <toolsSet>
+        <developmentServer>localhost</developmentServer>
+        <compilerSet>Cygwin|Cygwin</compilerSet>
+        <platform>3</platform>
+      </toolsSet>
+      <compileType>
+        <linkerTool>
+          <linkerLibItems>
+          </linkerLibItems>
+        </linkerTool>
+      </compileType>
+    </conf>
+    <conf name="Release" type="2">
+      <toolsSet>
+        <developmentServer>localhost</developmentServer>
+        <compilerSet>Cygwin|Cygwin</compilerSet>
+        <platform>3</platform>
+      </toolsSet>
+      <compileType>
+        <cCompilerTool>
+          <developmentMode>5</developmentMode>
+        </cCompilerTool>
+        <ccCompilerTool>
+          <developmentMode>5</developmentMode>
+        </ccCompilerTool>
+        <fortranCompilerTool>
+          <developmentMode>5</developmentMode>
+        </fortranCompilerTool>
+        <linkerTool>
+          <linkerLibItems>
+          </linkerLibItems>
+        </linkerTool>
+      </compileType>
+    </conf>
+  </confs>
+</configurationDescriptor>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/nbproject/project.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.cnd.makeproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/make-project/1">
+            <name>javafx-font-native</name>
+            <make-project-type>0</make-project-type>
+            <c-extensions/>
+            <cpp-extensions/>
+            <header-extensions/>
+            <make-dep-projects/>
+            <sourceEncoding>UTF-8</sourceEncoding>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/src/MacFontFinder.c	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2012, 2013, 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.
+ */
+
+#ifdef __APPLE__
+
+#include <TargetConditionals.h>
+
+#include <jni.h>
+#include <com_sun_javafx_font_MacFontFinder.h>
+
+#if TARGET_OS_IPHONE /* iOS */
+
+#import <CoreText/CoreText.h>
+
+JNIEXPORT jint JNICALL
+JNI_OnLoad_javafx_font(JavaVM * vm, void * reserved) {
+#ifdef JNI_VERSION_1_8
+    //min. returned JNI_VERSION required by JDK8 for builtin libraries
+    JNIEnv *env;
+    if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) {
+        return JNI_VERSION_1_4;
+    }
+    return JNI_VERSION_1_8;
+#else
+    return JNI_VERSION_1_4;
+#endif
+}
+
+#else /* MAC OS X */
+
+#import <CoreFoundation/CoreFoundation.h>
+#import <ApplicationServices/ApplicationServices.h>
+
+#endif
+
+
+jstring createJavaString(JNIEnv *env, CFStringRef stringRef)
+{
+    CFIndex length = CFStringGetLength(stringRef);
+    UniChar buffer[length];
+    CFStringGetCharacters(stringRef, CFRangeMake(0, length), buffer);
+    return (*env)->NewString(env, (jchar *)buffer, length);
+}
+
+/*
+ * Class:     com_sun_javafx_font_MacFontFinder
+ * Method:    getSystemFontSize
+ * Signature: ()F
+ */
+JNIEXPORT jfloat JNICALL Java_com_sun_javafx_font_MacFontFinder_getSystemFontSize
+  (JNIEnv *env, jclass obj)
+{
+    CTFontRef font = CTFontCreateUIFontForLanguage(
+                         kCTFontSystemFontType, 
+                         0.0, //get system font with default size
+                         NULL);
+    jfloat systemFontDefaultSize = (jfloat) CTFontGetSize (font);
+    CFRelease(font);
+    return systemFontDefaultSize;
+}
+
+/*
+ * Class:     com_sun_javafx_font_MacFontFinder
+ * Method:    getFont
+ * Signature: (I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_sun_javafx_font_MacFontFinder_getFont
+  (JNIEnv *env, jclass obj, jint type)
+{
+    CTFontRef font = CTFontCreateUIFontForLanguage(type, 0, NULL);
+    CFStringRef family = CTFontCopyFamilyName(font);
+    jstring jfamily = createJavaString(env, family);
+    CFRelease(family);
+    CFRelease(font);
+    return jfamily;
+}
+
+/*
+ * Class:     com_sun_javafx_font_MacFontFinder
+ * Method:    getFontData
+ * Signature: ()[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_com_sun_javafx_font_MacFontFinder_getFontData
+(JNIEnv *env, jclass obj)
+{
+    /* No caching as this method is only invoked once */
+    jclass jStringClass = (*env)->FindClass(env, "java/lang/String");
+    if (jStringClass == NULL) return NULL;
+
+    CTFontCollectionRef collection = CTFontCollectionCreateFromAvailableFonts(NULL);
+    CFArrayRef fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
+    CFRelease(collection);
+
+#if TARGET_OS_IPHONE /* iOS */
+    /* Sometimes a font name starting with dot (internal font, e.g. ".Helvetica NeueUI")
+     * is returned as a system UI font, but such font is not available in the colection
+     * of available fonts, thus this font has to be added to the array, otherwise
+     * first font from the array is returned if default font is requested from JFX
+     */
+    CTFontRef font = CTFontCreateUIFontForLanguage(kCTFontSystemFontType, 0, NULL);
+    CFStringRef fullName = CTFontCopyFullName(font);
+    CFStringRef dot = CFSTR(".");
+    CFComparisonResult res = CFStringCompareWithOptions(fullName, dot, CFRangeMake(0, 1), 0);
+    // if font name starts with dot
+    if (res == kCFCompareEqualTo) {
+        CTFontDescriptorRef fd = CTFontCopyFontDescriptor(font);
+        CFMutableArrayRef fontsMutableArray =
+            CFArrayCreateMutableCopy(kCFAllocatorDefault, CFArrayGetCount(fonts) + 1, fonts);
+        CFArrayAppendValue(fontsMutableArray, fd);
+        CFRelease(fd);
+        CFRelease(fonts);
+        fonts = fontsMutableArray;
+    }
+    CFRelease(font);
+    CFRelease(fullName);
+#endif
+
+    CFIndex count = CFArrayGetCount(fonts);
+    jobjectArray result = (*env)->NewObjectArray(env, count * 3, jStringClass, NULL);
+    if (result == NULL) {
+        /* out of memory */
+        CFRelease(fonts);
+        return NULL;
+    }
+
+    CFIndex i = 0, j = 0;
+    while (i < count) {
+        CTFontDescriptorRef fd = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i++);
+        if (fd) {
+            CFStringRef name = CTFontDescriptorCopyAttribute(fd, kCTFontDisplayNameAttribute);
+            CFStringRef family = CTFontDescriptorCopyAttribute(fd, kCTFontFamilyNameAttribute);
+            CFURLRef url = CTFontDescriptorCopyAttribute(fd, kCTFontURLAttribute);
+            CFStringRef file = url ? CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle) : NULL;
+            if (name && family && file) {
+                jstring jname = createJavaString(env, name);
+                jstring jfamily = createJavaString(env, family);
+                jstring jfile = createJavaString(env, file);
+                (*env)->SetObjectArrayElement(env, result, j++, jname);
+                (*env)->SetObjectArrayElement(env, result, j++, jfamily);
+                (*env)->SetObjectArrayElement(env, result, j++, jfile);
+            }
+            if (name) CFRelease(name);
+            if (family) CFRelease(family);
+            if (url) CFRelease(url);
+            if (file) CFRelease(file);
+        }
+    }
+    CFRelease(fonts);
+    return result;
+}
+
+#endif /* __APPLE__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/src/coretext.c	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,961 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+
+#if TARGET_OS_MAC && !(TARGET_OS_IPHONE)
+
+#include <jni.h>
+#include <com_sun_javafx_font_coretext_OS.h>
+
+#import <CoreFoundation/CoreFoundation.h>
+#import <ApplicationServices/ApplicationServices.h>
+
+#define OS_NATIVE(func) Java_com_sun_javafx_font_coretext_OS_##func
+
+/**************************************************************************/
+/*                                                                        */
+/*                            Structs                                     */
+/*                                                                        */
+/**************************************************************************/
+typedef struct CGAffineTransform_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID a, b, c, d, tx, ty;
+    jmethodID init;
+} CGAffineTransform_FID_CACHE;
+
+CGAffineTransform_FID_CACHE CGAffineTransformFc;
+
+void cacheCGAffineTransformFields(JNIEnv *env)
+{
+    if (CGAffineTransformFc.cached) return;
+    jclass tmpClass = (*env)->FindClass(env, "com/sun/javafx/font/coretext/CGAffineTransform");
+    CGAffineTransformFc.clazz =  (jclass)(*env)->NewGlobalRef(env, tmpClass);
+    CGAffineTransformFc.a = (*env)->GetFieldID(env, CGAffineTransformFc.clazz, "a", "D");
+    CGAffineTransformFc.b = (*env)->GetFieldID(env, CGAffineTransformFc.clazz, "b", "D");
+    CGAffineTransformFc.c = (*env)->GetFieldID(env, CGAffineTransformFc.clazz, "c", "D");
+    CGAffineTransformFc.d = (*env)->GetFieldID(env, CGAffineTransformFc.clazz, "d", "D");
+    CGAffineTransformFc.tx = (*env)->GetFieldID(env, CGAffineTransformFc.clazz, "tx", "D");
+    CGAffineTransformFc.ty = (*env)->GetFieldID(env, CGAffineTransformFc.clazz, "ty", "D");
+    CGAffineTransformFc.init = (*env)->GetMethodID(env, CGAffineTransformFc.clazz, "<init>", "()V");
+    CGAffineTransformFc.cached = 1;
+}
+
+CGAffineTransform *getCGAffineTransformFields(JNIEnv *env, jobject lpObject, CGAffineTransform *lpStruct)
+{
+    if (!CGAffineTransformFc.cached) cacheCGAffineTransformFields(env);
+    lpStruct->a = (*env)->GetDoubleField(env, lpObject, CGAffineTransformFc.a);
+    lpStruct->b = (*env)->GetDoubleField(env, lpObject, CGAffineTransformFc.b);
+    lpStruct->c = (*env)->GetDoubleField(env, lpObject, CGAffineTransformFc.c);
+    lpStruct->d = (*env)->GetDoubleField(env, lpObject, CGAffineTransformFc.d);
+    lpStruct->tx = (*env)->GetDoubleField(env, lpObject, CGAffineTransformFc.tx);
+    lpStruct->ty = (*env)->GetDoubleField(env, lpObject, CGAffineTransformFc.ty);
+    return lpStruct;
+}
+
+void setCGAffineTransformFields(JNIEnv *env, jobject lpObject, CGAffineTransform *lpStruct)
+{
+    if (!CGAffineTransformFc.cached) cacheCGAffineTransformFields(env);
+    (*env)->SetDoubleField(env, lpObject, CGAffineTransformFc.a, (jdouble)lpStruct->a);
+    (*env)->SetDoubleField(env, lpObject, CGAffineTransformFc.b, (jdouble)lpStruct->b);
+    (*env)->SetDoubleField(env, lpObject, CGAffineTransformFc.c, (jdouble)lpStruct->c);
+    (*env)->SetDoubleField(env, lpObject, CGAffineTransformFc.d, (jdouble)lpStruct->d);
+    (*env)->SetDoubleField(env, lpObject, CGAffineTransformFc.tx, (jdouble)lpStruct->tx);
+    (*env)->SetDoubleField(env, lpObject, CGAffineTransformFc.ty, (jdouble)lpStruct->ty);
+}
+
+jobject newCGAffineTransform(JNIEnv *env, CGAffineTransform *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!CGAffineTransformFc.cached) cacheCGAffineTransformFields(env);
+    lpObject = (*env)->NewObject(env, CGAffineTransformFc.clazz, CGAffineTransformFc.init);
+    if (lpObject && lpStruct) setCGAffineTransformFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct CFRange_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID location, length;
+    jmethodID init;
+} CFRange_FID_CACHE;
+
+CFRange_FID_CACHE CFRangeFc;
+
+void cacheCFRangeFields(JNIEnv *env)
+{
+    if (CFRangeFc.cached) return;
+    jclass tmpClass = (*env)->FindClass(env, "com/sun/javafx/font/coretext/CFRange");
+    CFRangeFc.clazz =  (jclass)(*env)->NewGlobalRef(env, tmpClass);
+    CFRangeFc.location = (*env)->GetFieldID(env, CFRangeFc.clazz, "location", "J");
+    CFRangeFc.length = (*env)->GetFieldID(env, CFRangeFc.clazz, "length", "J");
+    CFRangeFc.init = (*env)->GetMethodID(env, CFRangeFc.clazz, "<init>", "()V");
+    CFRangeFc.cached = 1;
+}
+
+CFRange *getCFRangeFields(JNIEnv *env, jobject lpObject, CFRange *lpStruct)
+{
+    if (!CFRangeFc.cached) cacheCFRangeFields(env);
+    lpStruct->location = (*env)->GetLongField(env, lpObject, CFRangeFc.location);
+    lpStruct->length = (*env)->GetLongField(env, lpObject, CFRangeFc.length);
+    return lpStruct;
+}
+
+void setCFRangeFields(JNIEnv *env, jobject lpObject, CFRange *lpStruct)
+{
+    if (!CFRangeFc.cached) cacheCFRangeFields(env);
+    (*env)->SetLongField(env, lpObject, CFRangeFc.location, (jlong)lpStruct->location);
+    (*env)->SetLongField(env, lpObject, CFRangeFc.length, (jlong)lpStruct->length);
+}
+
+jobject newCFRange(JNIEnv *env, CFRange *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!CFRangeFc.cached) cacheCFRangeFields(env);
+    lpObject = (*env)->NewObject(env, CFRangeFc.clazz, CFRangeFc.init);
+    if (lpObject && lpStruct) setCFRangeFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct CGPoint_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID x, y;
+    jmethodID init;
+} CGPoint_FID_CACHE;
+
+CGPoint_FID_CACHE CGPointFc;
+
+void cacheCGPointFields(JNIEnv *env)
+{
+    if (CGPointFc.cached) return;
+    jclass tmpClass = (*env)->FindClass(env, "com/sun/javafx/font/coretext/CGPoint");
+    CGPointFc.clazz =  (jclass)(*env)->NewGlobalRef(env, tmpClass);
+    CGPointFc.x = (*env)->GetFieldID(env, CGPointFc.clazz, "x", "D");
+    CGPointFc.y = (*env)->GetFieldID(env, CGPointFc.clazz, "y", "D");
+    CGPointFc.init = (*env)->GetMethodID(env, CGPointFc.clazz, "<init>", "()V");
+    CGPointFc.cached = 1;
+}
+
+CGPoint *getCGPointFields(JNIEnv *env, jobject lpObject, CGPoint *lpStruct)
+{
+    if (!CGPointFc.cached) cacheCGPointFields(env);
+    lpStruct->x = (*env)->GetDoubleField(env, lpObject, CGPointFc.x);
+    lpStruct->y = (*env)->GetDoubleField(env, lpObject, CGPointFc.y);
+    return lpStruct;
+}
+
+void setCGPointFields(JNIEnv *env, jobject lpObject, CGPoint *lpStruct)
+{
+    if (!CGPointFc.cached) cacheCGPointFields(env);
+    (*env)->SetDoubleField(env, lpObject, CGPointFc.x, (jdouble)lpStruct->x);
+    (*env)->SetDoubleField(env, lpObject, CGPointFc.y, (jdouble)lpStruct->y);
+}
+
+jobject newCGPoint(JNIEnv *env, CGPoint *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!CGPointFc.cached) cacheCGPointFields(env);
+    lpObject = (*env)->NewObject(env, CGPointFc.clazz, CGPointFc.init);
+    if (lpObject && lpStruct) setCGPointFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct CGSize_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID width, height;
+    jmethodID init;
+} CGSize_FID_CACHE;
+
+CGSize_FID_CACHE CGSizeFc;
+
+void cacheCGSizeFields(JNIEnv *env)
+{
+    if (CGSizeFc.cached) return;
+    jclass tmpClass = (*env)->FindClass(env, "com/sun/javafx/font/coretext/CGSize");
+    CGSizeFc.clazz =  (jclass)(*env)->NewGlobalRef(env, tmpClass);
+    CGSizeFc.width = (*env)->GetFieldID(env, CGSizeFc.clazz, "width", "D");
+    CGSizeFc.height = (*env)->GetFieldID(env, CGSizeFc.clazz, "height", "D");
+    CGSizeFc.init = (*env)->GetMethodID(env, CGSizeFc.clazz, "<init>", "()V");
+    CGSizeFc.cached = 1;
+}
+
+CGSize *getCGSizeFields(JNIEnv *env, jobject lpObject, CGSize *lpStruct)
+{
+    if (!CGSizeFc.cached) cacheCGSizeFields(env);
+    lpStruct->width = (*env)->GetDoubleField(env, lpObject, CGSizeFc.width);
+    lpStruct->height = (*env)->GetDoubleField(env, lpObject, CGSizeFc.height);
+    return lpStruct;
+}
+
+void setCGSizeFields(JNIEnv *env, jobject lpObject, CGSize *lpStruct)
+{
+    if (!CGSizeFc.cached) cacheCGSizeFields(env);
+    (*env)->SetDoubleField(env, lpObject, CGSizeFc.width, (jdouble)lpStruct->width);
+    (*env)->SetDoubleField(env, lpObject, CGSizeFc.height, (jdouble)lpStruct->height);
+}
+
+jobject newCGSize(JNIEnv *env, CGSize *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!CGSizeFc.cached) cacheCGSizeFields(env);
+    lpObject = (*env)->NewObject(env, CGSizeFc.clazz, CGSizeFc.init);
+    if (lpObject && lpStruct) setCGSizeFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct CGRect_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID origin, size;
+    jmethodID init;
+} CGRect_FID_CACHE;
+
+CGRect_FID_CACHE CGRectFc;
+
+void cacheCGRectFields(JNIEnv *env)
+{
+    if (CGRectFc.cached) return;
+    jclass tmpClass = (*env)->FindClass(env, "com/sun/javafx/font/coretext/CGRect");
+    CGRectFc.clazz =  (jclass)(*env)->NewGlobalRef(env, tmpClass);
+    CGRectFc.origin = (*env)->GetFieldID(env, CGRectFc.clazz, "origin", "Lcom/sun/javafx/font/coretext/CGPoint;");
+    CGRectFc.size = (*env)->GetFieldID(env, CGRectFc.clazz, "size", "Lcom/sun/javafx/font/coretext/CGSize;");
+    CGRectFc.init = (*env)->GetMethodID(env, CGRectFc.clazz, "<init>", "()V");
+    CGRectFc.cached = 1;
+}
+
+CGRect *getCGRectFields(JNIEnv *env, jobject lpObject, CGRect *lpStruct)
+{
+    if (!CGRectFc.cached) cacheCGRectFields(env);
+    {
+    jobject lpObject1 = (*env)->GetObjectField(env, lpObject, CGRectFc.origin);
+    if (lpObject1 != NULL) getCGPointFields(env, lpObject1, &lpStruct->origin);
+    }
+    {
+    jobject lpObject1 = (*env)->GetObjectField(env, lpObject, CGRectFc.size);
+    if (lpObject1 != NULL) getCGSizeFields(env, lpObject1, &lpStruct->size);
+    }
+    return lpStruct;
+}
+
+void setCGRectFields(JNIEnv *env, jobject lpObject, CGRect *lpStruct)
+{
+    if (!CGRectFc.cached) cacheCGRectFields(env);
+    {
+    jobject lpObject1 = (*env)->GetObjectField(env, lpObject, CGRectFc.origin);
+    if (lpObject1 != NULL) setCGPointFields(env, lpObject1, &lpStruct->origin);
+    }
+    {
+    jobject lpObject1 = (*env)->GetObjectField(env, lpObject, CGRectFc.size);
+    if (lpObject1 != NULL) setCGSizeFields(env, lpObject1, &lpStruct->size);
+    }
+}
+
+jobject newCGRect(JNIEnv *env, CGRect *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!CGRectFc.cached) cacheCGRectFields(env);
+    lpObject = (*env)->NewObject(env, CGRectFc.clazz, CGRectFc.init);
+    if (lpObject && lpStruct) setCGRectFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+/**************************************************************************/
+/*                                                                        */
+/*                            Functions                                   */
+/*                                                                        */
+/**************************************************************************/
+
+JNIEXPORT jlong JNICALL OS_NATIVE(kCFAllocatorDefault)
+    (JNIEnv *env, jclass that)
+{
+    return (jlong)kCFAllocatorDefault;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CFStringCreateWithCharacters__J_3CJ)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1, jlong arg2)
+{
+    jchar *lparg1=NULL;
+    jlong rc = 0;
+    if (arg1) if ((lparg1 = (*env)->GetCharArrayElements(env, arg1, NULL)) == NULL) goto fail;
+    rc = (jlong)CFStringCreateWithCharacters((CFAllocatorRef)arg0, (UniChar*)lparg1, (CFIndex)arg2);
+fail:
+    if (arg1 && lparg1) (*env)->ReleaseCharArrayElements(env, arg1, lparg1, 0);
+    return rc;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CTFontCreateWithName)
+    (JNIEnv *env, jclass that, jlong arg0, jdouble arg1, jobject arg2)
+{
+    CGAffineTransform _arg2, *lparg2=NULL;
+    jlong rc = 0;
+    if (arg2) if ((lparg2 = getCGAffineTransformFields(env, arg2, &_arg2)) == NULL) goto fail;
+    rc = (jlong)CTFontCreateWithName((CFStringRef)arg0, (CGFloat)arg1, (CGAffineTransform*)lparg2);
+fail:
+    /* In only */
+//    if (arg2 && lparg2) setCGAffineTransformFields(env, arg2, lparg2);
+    return rc;
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CFRelease)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CFRelease((CFTypeRef)arg0);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CFURLCreateWithFileSystemPath)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jboolean arg3)
+{
+    return (jlong)CFURLCreateWithFileSystemPath((CFAllocatorRef)arg0, (CFStringRef)arg1, (CFURLPathStyle)arg2, (Boolean)arg3);
+}
+
+JNIEXPORT jboolean JNICALL OS_NATIVE(CTFontManagerRegisterFontsForURL)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jlong arg2)
+{
+    return (jboolean)CTFontManagerRegisterFontsForURL((CFURLRef)arg0, (CTFontManagerScope)arg1, (CFErrorRef*)arg2);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CTFontCreatePathForGlyph)
+    (JNIEnv *env, jclass that, jlong arg0, jshort arg1, jobject arg2)
+{
+    CGAffineTransform _arg2, *lparg2=NULL;
+    jlong rc = 0;
+    if (arg2) if ((lparg2 = getCGAffineTransformFields(env, arg2, &_arg2)) == NULL) goto fail;
+    rc = (jlong)CTFontCreatePathForGlyph((CTFontRef)arg0, (CGGlyph)arg1, (CGAffineTransform*)lparg2);
+fail:
+    /* In Only */
+//    if (arg2 && lparg2) setCGAffineTransformFields(env, arg2, lparg2);
+    return rc;
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGPathRelease)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CGPathRelease((CGPathRef)arg0);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CGColorSpaceCreateDeviceRGB)
+    (JNIEnv *env, jclass that)
+{
+    return (jlong)CGColorSpaceCreateDeviceRGB();
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CGColorSpaceCreateDeviceGray)
+    (JNIEnv *env, jclass that)
+{
+    return (jlong)CGColorSpaceCreateDeviceGray();
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CGBitmapContextCreate)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5, jint arg6)
+{
+    return (jlong)CGBitmapContextCreate((void*)arg0, (size_t)arg1, (size_t)arg2, (size_t)arg3, (size_t)arg4, (CGColorSpaceRef)arg5, (CGBitmapInfo)arg6);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGContextSetAllowsFontSmoothing)
+    (JNIEnv *env, jclass that, jlong arg0, jboolean arg1)
+{
+    CGContextSetAllowsFontSmoothing((CGContextRef)arg0, (_Bool)arg1);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGContextSetAllowsAntialiasing)
+    (JNIEnv *env, jclass that, jlong arg0, jboolean arg1)
+{
+    CGContextSetAllowsAntialiasing((CGContextRef)arg0, (_Bool)arg1);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGContextSetAllowsFontSubpixelPositioning)
+    (JNIEnv *env, jclass that, jlong arg0, jboolean arg1)
+{
+    CGContextSetAllowsFontSubpixelPositioning((CGContextRef)arg0, (_Bool)arg1);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGContextSetAllowsFontSubpixelQuantization)
+    (JNIEnv *env, jclass that, jlong arg0, jboolean arg1)
+{
+    CGContextSetAllowsFontSubpixelQuantization((CGContextRef)arg0, (_Bool)arg1);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGContextSetRGBFillColor)
+    (JNIEnv *env, jclass that, jlong arg0, jdouble arg1, jdouble arg2, jdouble arg3, jdouble arg4)
+{
+    CGContextSetRGBFillColor((CGContextRef)arg0, (CGFloat)arg1, (CGFloat)arg2, (CGFloat)arg3, (CGFloat)arg4);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGContextFillRect)
+    (JNIEnv *env, jclass that, jlong arg0, jobject arg1)
+{
+    CGRect _arg1, *lparg1=NULL;
+    /* In Only */
+    if (arg1) if ((lparg1 = getCGRectFields(env, arg1, &_arg1)) == NULL) return;
+    CGContextFillRect((CGContextRef)arg0, *lparg1);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGContextTranslateCTM)
+    (JNIEnv *env, jclass that, jlong arg0, jdouble arg1, jdouble arg2)
+{
+    CGContextTranslateCTM((CGContextRef)arg0, (CGFloat)arg1, (CGFloat)arg2);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGContextRelease)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CGContextRelease((CGContextRef)arg0);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGColorSpaceRelease)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CGColorSpaceRelease((CGColorSpaceRef)arg0);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(kCFTypeDictionaryKeyCallBacks)
+    (JNIEnv *env, jclass that)
+{
+    return (jlong)&kCFTypeDictionaryKeyCallBacks;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(kCFTypeDictionaryValueCallBacks)
+    (JNIEnv *env, jclass that)
+{
+    return (jlong)&kCFTypeDictionaryValueCallBacks;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CFDictionaryCreateMutable)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jlong arg3)
+{
+    return (jlong)CFDictionaryCreateMutable((CFAllocatorRef)arg0, (CFIndex)arg1, (CFDictionaryKeyCallBacks*)arg2, (CFDictionaryValueCallBacks*)arg3);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CFDictionaryAddValue)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
+{
+    CFDictionaryAddValue((CFMutableDictionaryRef)arg0, (void*)arg1, (void*)arg2);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CFDictionaryGetValue)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1)
+{
+    return (jlong)CFDictionaryGetValue((CFDictionaryRef)arg0, (void*)arg1);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(kCTFontAttributeName)
+    (JNIEnv *env, jclass that)
+{
+    return (jlong)kCTFontAttributeName;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CFAttributedStringCreate)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
+{
+    return (jlong)CFAttributedStringCreate((CFAllocatorRef)arg0, (CFStringRef)arg1, (CFDictionaryRef)arg2);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CTLineCreateWithAttributedString)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jlong)CTLineCreateWithAttributedString((CFAttributedStringRef)arg0);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CTLineGetGlyphRuns)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jlong)CTLineGetGlyphRuns((CTLineRef)arg0);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CFArrayGetCount)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jlong)CFArrayGetCount((CFArrayRef)arg0);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CFArrayGetValueAtIndex)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1)
+{
+    return (jlong)CFArrayGetValueAtIndex((CFArrayRef)arg0, (CFIndex)arg1);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CTRunGetGlyphCount)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jlong)CTRunGetGlyphCount((CTRunRef)arg0);
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(CTRunGetStatus)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jint)CTRunGetStatus((CTRunRef)arg0);
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CTRunGetAttributes)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jlong)CTRunGetAttributes((CTRunRef)arg0);
+}
+
+/**************************************************************************/
+/*                                                                        */
+/*                           Custom Functions                             */
+/*                                                                        */
+/**************************************************************************/
+
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CFStringCreateWithCharacters__J_3CJJ)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1, jlong arg2, jlong arg3)
+{
+    jchar *lparg1=NULL;
+    jlong rc = 0;
+    if (arg1) if ((lparg1 = (*env)->GetPrimitiveArrayCritical(env, arg1, NULL)) == NULL) goto fail;
+    UniChar* str = lparg1 + arg2;
+    rc = (jlong)CFStringCreateWithCharacters((CFAllocatorRef)arg0, str, (CFIndex)arg3);
+fail:
+    if (arg1 && lparg1) (*env)->ReleasePrimitiveArrayCritical(env, arg1, lparg1, 0);
+    return rc;
+}
+
+JNIEXPORT jfloatArray JNICALL OS_NATIVE(CTRunGetAdvancesPtr)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CTRunRef run = (CTRunRef)arg0;
+    const CGSize* advances = CTRunGetAdvancesPtr(run);
+    if (advances) {
+        CFIndex count = CTRunGetGlyphCount(run);
+        jfloatArray result = (*env)->NewFloatArray(env, count * 2);
+        if (result) {
+            int i, j;
+            jfloat data[count*2];
+            for(i = 0, j = 0; i < count; i++) {
+                CGSize advance = advances[i];
+                data[j++] = advance.width;
+                data[j++] = advance.height;
+            }
+            (*env)->SetFloatArrayRegion(env, result, 0, count * 2, data);
+            return result;
+        }
+    }
+    return NULL;
+}
+
+JNIEXPORT jintArray JNICALL OS_NATIVE(CTRunGetGlyphsPtr)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CTRunRef run = (CTRunRef)arg0;
+    const CGGlyph * glyphs = CTRunGetGlyphsPtr(run);
+    if (glyphs) {
+        CFIndex count = CTRunGetGlyphCount(run);
+        jintArray result = (*env)->NewIntArray(env, count);
+        if (result) {
+            int i;
+            jint data[count];
+            for(i = 0; i < count; i++) {
+                data[i] = glyphs[i];
+            }
+            (*env)->SetIntArrayRegion(env, result, 0, count, data);
+            return result;
+        }
+    }
+    return NULL;
+}
+
+JNIEXPORT jfloatArray JNICALL OS_NATIVE(CTRunGetPositionsPtr)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CTRunRef run = (CTRunRef)arg0;
+    const CGPoint* positions = CTRunGetPositionsPtr(run);
+    if (positions) {
+        CFIndex count = CTRunGetGlyphCount(run);
+        jfloatArray result = (*env)->NewFloatArray(env, count * 2 + 2);
+        if (result) {
+            int i, j;
+            CGFloat x = positions[0].x;
+            CGFloat y = positions[0].y;
+            jfloat data[count * 2 + 2];
+            for(i = 0, j = 0; i < count; i++) {
+                CGPoint pos = positions[i];
+                data[j++] = pos.x - x;
+                data[j++] = pos.y - y;
+            }
+            data[j++] = CTRunGetTypographicBounds(run, CFRangeMake(0, 0), NULL, NULL, NULL);
+            data[j++] = 0;
+            (*env)->SetFloatArrayRegion(env, result, 0, count * 2 + 2, data);
+            return result;
+        }
+    }
+    return NULL;
+}
+
+JNIEXPORT jintArray JNICALL OS_NATIVE(CTRunGetStringIndicesPtr)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CTRunRef run = (CTRunRef)arg0;
+    const CFIndex* indices = CTRunGetStringIndicesPtr(run);
+    if (indices) {
+        CFIndex count = CTRunGetGlyphCount(run);
+        CFIndex start = CTRunGetStringRange(run).location;
+        jintArray result = (*env)->NewIntArray(env, count);
+        if (result) {
+            int i;
+            jint data[count];
+            for(i = 0; i < count; i++) {
+                data[i] = indices[i] - start;
+            }
+            (*env)->SetIntArrayRegion(env, result, 0, count, data);
+            return result;
+        }
+    }
+    return NULL;
+}
+
+JNIEXPORT jobject JNICALL OS_NATIVE(CTRunGetStringRange)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CTRunRef run = (CTRunRef)arg0;
+    CFRange result = CTRunGetStringRange(run);
+    return newCFRange(env, &result);
+}
+
+JNIEXPORT jstring JNICALL OS_NATIVE(CTFontCopyDisplayName)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CFStringRef stringRef = CTFontCopyDisplayName((CTFontRef)arg0);
+
+    /* Copied from MacFontFinder#createJavaString */
+    CFIndex length = CFStringGetLength(stringRef);
+    UniChar buffer[length];
+    CFStringGetCharacters(stringRef, CFRangeMake(0, length), buffer);
+    CFRelease(stringRef);
+    return (*env)->NewString(env, (jchar *)buffer, length);
+}
+
+JNIEXPORT jbyteArray JNICALL OS_NATIVE(CGBitmapContextGetData__J)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    jbyteArray result = NULL;
+    CGContextRef context = (CGContextRef)arg0;
+    void* data = CGBitmapContextGetData(context);
+    if (data) {
+        size_t size = CGBitmapContextGetBytesPerRow(context) * CGBitmapContextGetHeight(context);
+        result = (*env)->NewByteArray(env, size);
+        if (result) {
+            (*env)->SetByteArrayRegion(env, result, 0, size, data);
+        }
+    }
+    return result;
+}
+
+JNIEXPORT jbyteArray JNICALL OS_NATIVE(CGBitmapContextGetData__JIII)
+    (JNIEnv *env, jclass that, jlong arg0, jint dstWidth, jint dstHeight, jint bpp)
+{
+    jbyteArray result = NULL;
+    CGContextRef context = (CGContextRef)arg0;
+    jbyte *srcData = (jbyte*)CGBitmapContextGetData(context);
+
+    if (srcData) {
+        /* Use one byte per pixel for grayscale */
+        size_t srcWidth = CGBitmapContextGetWidth(context);
+        size_t srcHeight =  CGBitmapContextGetHeight(context);
+        size_t srcBytesPerRow = CGBitmapContextGetBytesPerRow(context);
+        size_t srcStep = CGBitmapContextGetBitsPerPixel(context) / 8;
+        int srcOffset = (srcHeight - dstHeight) * srcBytesPerRow;
+
+
+        //bits per pixel, either 8 for gray or 24 for LCD.
+        int dstStep = bpp / 8;
+        size_t size = dstWidth * dstHeight * dstStep;
+        jbyte data[size];
+
+        int x, y, sx;
+        int dstOffset = 0;
+        for (y = 0; y < dstHeight; y++) {
+            for (x = 0, sx = 0; x < dstWidth; x++, dstOffset += dstStep, sx += srcStep) {
+                if (dstStep == 1) {
+                    /* BGRA or Gray to Gray*/
+                    data[dstOffset] = 0xFF - srcData[srcOffset + sx];
+                } else {
+                    /* BGRA to RGB */
+                    data[dstOffset]     = 0xFF - srcData[srcOffset + sx + 2];
+                    data[dstOffset + 1] = 0xFF - srcData[srcOffset + sx + 1];
+                    data[dstOffset + 2] = 0xFF - srcData[srcOffset + sx];
+                }
+            }
+            srcOffset += srcBytesPerRow;
+        }
+
+        result = (*env)->NewByteArray(env, size);
+        if (result) {
+            (*env)->SetByteArrayRegion(env, result, 0, size, data);
+        }
+    }
+    return result;
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGPointApplyAffineTransform)
+    (JNIEnv *env, jclass that, jobject arg0, jobject arg1)
+{
+    CGPoint _arg0, *lparg0=NULL;
+    CGAffineTransform _arg1, *lparg1=NULL;
+    if (arg0) if ((lparg0 = getCGPointFields(env, arg0, &_arg0)) == NULL) goto fail;
+    if (arg1) if ((lparg1 = getCGAffineTransformFields(env, arg1, &_arg1)) == NULL) goto fail;
+    _arg0 = CGPointApplyAffineTransform(*lparg0, *lparg1);
+fail:
+    /* In Only */
+//    if (arg1 && lparg1) setCGAffineTransformFields(env, arg1, lparg1);
+    if (arg0 && lparg0) setCGPointFields(env, arg0, lparg0);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CGRectApplyAffineTransform)
+    (JNIEnv *env, jclass that, jobject arg0, jobject arg1)
+{
+    CGRect _arg0, *lparg0=NULL;
+    CGAffineTransform _arg1, *lparg1=NULL;
+    if (arg0) if ((lparg0 = getCGRectFields(env, arg0, &_arg0)) == NULL) goto fail;
+    if (arg1) if ((lparg1 = getCGAffineTransformFields(env, arg1, &_arg1)) == NULL) goto fail;
+    _arg0 = CGRectApplyAffineTransform(*lparg0, *lparg1);
+fail:
+    /* In Only */
+//    if (arg1 && lparg1) setCGAffineTransformFields(env, arg1, lparg1);
+    if (arg0 && lparg0) setCGRectFields(env, arg0, lparg0);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(CTFontDrawGlyphs)
+    (JNIEnv *env, jclass that, jlong arg0, jshort arg1, jdouble arg2, jdouble arg3, jlong arg4, jlong arg5)
+{
+    /* Custom: only takes one glyph at the time */
+    CGGlyph glyphs[] = {arg1};
+    CGPoint pos[] = {CGPointMake(arg2, arg3)};
+    CTFontDrawGlyphs((CTFontRef)arg0, glyphs, pos, 1, (CGContextRef)arg5);
+}
+
+JNIEXPORT jobject JNICALL OS_NATIVE(CTFontGetBoundingRectsForGlyphs)
+    (JNIEnv *env, jclass that, jlong arg1, jint arg2, jshort arg3, jobject arg4, jlong arg5)
+{
+    /* Custom: only takes one glyph at the time */
+    jobject rc = NULL;
+    CGRect result;
+    CGGlyph glyphs[] = {arg3};
+    CGRect _arg4, *lparg4=NULL;
+    if (arg4) if ((lparg4 = getCGRectFields(env, arg4, &_arg4)) == NULL) goto fail;
+    result = CTFontGetBoundingRectsForGlyphs((CTFontRef)arg1, (CTFontOrientation)arg2, glyphs, lparg4, 1);
+    rc = newCGRect(env, &result);
+fail:
+    if (arg4 && lparg4) setCGRectFields(env, arg4, &_arg4);
+    return rc;
+}
+
+JNIEXPORT jboolean JNICALL OS_NATIVE(CTFontGetBoundingRectForGlyphUsingTables)
+    (JNIEnv *env, jclass that, jlong arg1, jshort arg2, jshort arg3, jintArray arg4)
+{
+    /* The following code is based on scalerMethods.c#getGlyphBoundingBoxNative */
+    CTFontRef fontRef = (CTFontRef)arg1;
+    CTFontTableOptions options = kCTFontTableOptionNoOptions;
+    CFDataRef tableData;
+    CFIndex length;
+
+    /* indexToLocFormat is stored in Java for performance */
+//    tableData = CTFontCopyTable(fontRef, kCTFontTableHead, options);
+//    const UInt8 * head = CFDataGetBytePtr(tableData);
+//    UInt16 indexToLocFormat = CFSwapInt16BigToHost(*((SInt16*)(head + 50)));
+//    printf("here0 indexToLocFormat=%u \n", indexToLocFormat); fflush(stdout);
+//    CFRelease(tableData);
+    UInt16 indexToLocFormat = arg3;
+
+    tableData = CTFontCopyTable(fontRef, kCTFontTableLoca, options);
+    if (tableData == NULL) return FALSE;
+    length = CFDataGetLength(tableData);
+    UInt32 offset1 = 0, offset2 = 0;
+    if (indexToLocFormat) {
+        const UInt32 * loca = (const UInt32 *)CFDataGetBytePtr(tableData);
+        if (loca != NULL && length / 4 > arg2) {
+            offset1 = CFSwapInt32BigToHost(loca[arg2]);
+            offset2 = CFSwapInt32BigToHost(loca[arg2 + 1]);
+        }
+    } else {
+        const UInt16 * loca = (const UInt16 *)CFDataGetBytePtr(tableData);
+        if (loca != NULL && length / 2 > arg2) {
+            offset1 = CFSwapInt16BigToHost(loca[arg2]) << 1;
+            offset2 = CFSwapInt16BigToHost(loca[arg2 + 1]) << 1;
+        }
+    }
+    CFRelease(tableData);
+
+    if (offset2 > offset1 && (offset2 - offset1) >= 10) {
+        tableData = CTFontCopyTable(fontRef, kCTFontTableGlyf, options);
+        if (tableData == NULL) return FALSE;
+        length = CFDataGetLength(tableData);
+        const UInt8 * ptr = CFDataGetBytePtr(tableData);
+        if (ptr != NULL && length > (offset1 + 10)) {
+            const SInt16 * glyf = (const SInt16 *)(ptr + offset1);
+            /*
+             * CFSwapInt16BigToHost returns an unsigned short, need
+             * to cast back to signed short before assigning to jint.
+             */
+            jint data[] = {
+                (SInt16)CFSwapInt16BigToHost(glyf[1]),
+                (SInt16)CFSwapInt16BigToHost(glyf[2]),
+                (SInt16)CFSwapInt16BigToHost(glyf[3]),
+                (SInt16)CFSwapInt16BigToHost(glyf[4]),
+            };
+            (*env)->SetIntArrayRegion(env, arg4, 0, 4, data);
+        }
+        CFRelease(tableData);
+    }
+    return TRUE;
+}
+
+JNIEXPORT jdouble JNICALL OS_NATIVE(CTFontGetAdvancesForGlyphs)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jshort arg2, jobject arg3, jlong arg4)
+{
+    /* Custom: only takes one glyph at the time */
+    jdouble rc = 0;
+    CGGlyph glyphs[] = {arg2};
+    CGSize _arg3, *lparg3=NULL;
+    if (arg3) if ((lparg3 = getCGSizeFields(env, arg3, &_arg3)) == NULL) goto fail;
+    rc = (jdouble)CTFontGetAdvancesForGlyphs((CTFontRef)arg0, (CTFontOrientation)arg1, glyphs, lparg3, 1);
+fail:
+    if (arg3 && lparg3) setCGSizeFields(env, arg3, &_arg3);
+    return rc;
+}
+
+JNIEXPORT jobject JNICALL OS_NATIVE(CGPathGetPathBoundingBox)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    CGRect result = CGPathGetPathBoundingBox((CGPathRef)arg0);
+    return newCGRect(env, &result);
+}
+
+JNIEXPORT jobject JNICALL OS_NATIVE(CGAffineTransformInvert)
+    (JNIEnv *env, jclass that, jobject arg0)
+{
+    jobject rc = NULL;
+    CGAffineTransform result;
+    CGAffineTransform _arg0, *lparg0=NULL;
+    if (arg0) if ((lparg0 = getCGAffineTransformFields(env, arg0, &_arg0)) == NULL) goto fail;
+    result = CGAffineTransformInvert(*lparg0);
+    rc = newCGAffineTransform(env, &result);
+fail:
+    /* In Only */
+//    if (arg0 && lparg0) setCGAffineTransformFields(env, arg0, lparg0);
+    return rc;
+}
+
+/***********************************************/
+/*                Glyph Outline                */
+/***********************************************/
+
+static const int DEFAULT_LEN_TYPES = 10;
+static const int DEFAULT_LEN_COORDS = 50;
+typedef struct _PathData {
+    jbyte* pointTypes;
+    int numTypes;
+    int lenTypes;
+    jfloat* pointCoords;
+    int numCoords;
+    int lenCoords;
+} PathData;
+
+void pathApplierFunctionFast(void *i, const CGPathElement *e) {
+    PathData *info = (PathData *)i;
+    if (info->numTypes == info->lenTypes) {
+        info->lenTypes += DEFAULT_LEN_TYPES;
+        info->pointTypes = (jbyte*)realloc(info->pointTypes, info->lenTypes * sizeof(jbyte));
+    }
+    jint type;
+    int coordCount = 0;
+    switch (e->type) {
+    case kCGPathElementMoveToPoint:
+        type = 0;
+        coordCount = 1;
+        break;
+    case kCGPathElementAddLineToPoint:
+        type = 1;
+        coordCount = 1;
+        break;
+    case kCGPathElementAddQuadCurveToPoint:
+        type = 2;
+        coordCount = 2;
+        break;
+    case kCGPathElementAddCurveToPoint:
+        type = 3;
+        coordCount = 3;
+        break;
+    case kCGPathElementCloseSubpath:
+        type = 4;
+        coordCount = 0;
+        break;
+    }
+    info->pointTypes[info->numTypes++] = type;
+
+    if (info->numCoords + (coordCount * 2) > info->lenCoords) {
+        info->lenCoords += DEFAULT_LEN_COORDS;
+        info->pointCoords = (jfloat*)realloc(info->pointCoords, info->lenCoords * sizeof(jfloat));
+    }
+    int j;
+    for (j = 0; j < coordCount; j++) {
+        CGPoint pt = e->points[j];
+        info->pointCoords[info->numCoords++] = pt.x;
+        info->pointCoords[info->numCoords++] = pt.y;
+    }
+}
+
+jclass path2DClass = NULL;
+jmethodID path2DCtr = NULL;
+JNIEXPORT jobject JNICALL OS_NATIVE(CGPathApply)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    PathData data;
+    data.pointTypes = (jbyte*)malloc(sizeof(jbyte) * DEFAULT_LEN_TYPES);
+    data.numTypes = 0;
+    data.lenTypes = DEFAULT_LEN_TYPES;
+    data.pointCoords = (jfloat*)malloc(sizeof(jfloat) * DEFAULT_LEN_COORDS);
+    data.numCoords = 0;
+    data.lenCoords = DEFAULT_LEN_COORDS;
+
+    CGPathApply((CGPathRef)arg0, &data, pathApplierFunctionFast);
+
+    if (path2DClass == NULL) {
+        jclass tmpClass = (*env)->FindClass(env, "com/sun/javafx/geom/Path2D");
+        path2DClass = (jclass)(*env)->NewGlobalRef(env, tmpClass);
+        path2DCtr = (*env)->GetMethodID(env, path2DClass, "<init>", "(I[BI[FI)V");
+    }
+
+    jbyteArray types = (*env)->NewByteArray(env, data.numTypes);
+    jfloatArray coords = (*env)->NewFloatArray(env, data.numCoords);
+    if (types && coords) {
+        (*env)->SetByteArrayRegion(env, types, 0, data.numTypes, data.pointTypes);
+        (*env)->SetFloatArrayRegion(env, coords, 0, data.numCoords, data.pointCoords);
+        return (*env)->NewObject(env, path2DClass, path2DCtr,
+                                 0 /*winding rule*/,
+                                 types, data.numTypes,
+                                 coords, data.numCoords);
+      }
+      return NULL;
+}
+
+#endif /* TARGET_OS_MAC */
+#endif /* __APPLE__ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/src/dfontdecoder.c	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2012, 2013, 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.
+ */
+
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+
+#if TARGET_OS_MAC && !(TARGET_OS_IPHONE)
+
+#include <jni.h>
+#include <com_sun_javafx_font_DFontDecoder.h>
+
+#import <CoreFoundation/CoreFoundation.h>
+#import <ApplicationServices/ApplicationServices.h>
+
+
+JNIEXPORT jlong JNICALL Java_com_sun_javafx_font_DFontDecoder_createCTFont
+(JNIEnv *env, jclass clazz, jstring fontName)
+{
+    CFIndex numChars = (*env)->GetStringLength(env, fontName);
+    const jchar *fontBuffer = (*env)->GetStringChars(env, fontName, NULL);
+    CFStringRef fontNameRef = CFStringCreateWithCharacters(kCFAllocatorDefault, 
+                                                           fontBuffer, 
+                                                           numChars);
+    
+    CTFontRef fontRef = CTFontCreateWithName(fontNameRef, 0, NULL);
+    CFRelease(fontNameRef);
+    return (jlong)fontRef;
+}
+
+JNIEXPORT void JNICALL Java_com_sun_javafx_font_DFontDecoder_releaseCTFont
+(JNIEnv *env, jclass clazz, jlong fontPtr)
+{
+    CTFontRef fontRef = (CTFontRef)fontPtr;
+    CFRelease(fontRef);
+}
+
+JNIEXPORT jint JNICALL Java_com_sun_javafx_font_DFontDecoder_getCTFontFormat
+(JNIEnv *env, jclass clazz, jlong fontPtr)
+{
+    CTFontRef fontRef = (CTFontRef)fontPtr;
+    CFNumberRef formatRef = CTFontCopyAttribute(fontRef, kCTFontFormatAttribute);
+    CTFontFormat formatValue;
+    CFNumberGetValue(formatRef, kCFNumberIntType, &formatValue);
+    CFRelease(formatRef);
+    switch (formatValue) {
+        case kCTFontFormatOpenTypePostScript:
+            return 0x4f54544f; // 'otto' - OpenType CFF font
+        case kCTFontFormatOpenTypeTrueType:
+            return 0x00010000; // 'v1tt' - MS TrueType font
+        case kCTFontFormatTrueType:
+            return 0x74727565; // 'true' - Mac TrueType font
+        case kCTFontFormatPostScript:
+        case kCTFontFormatBitmap:
+        case kCTFontFormatUnrecognized:
+        default:
+            return 0;
+    }
+}
+
+JNIEXPORT jintArray JNICALL Java_com_sun_javafx_font_DFontDecoder_getCTFontTags
+(JNIEnv *env, jclass clazz, jlong fontPtr)
+{
+    CTFontRef fontRef = (CTFontRef)fontPtr;
+    CTFontTableOptions  options = kCTFontTableOptionNoOptions;
+    CFArrayRef tags = CTFontCopyAvailableTables(fontRef, options);
+    CFIndex count = CFArrayGetCount(tags);
+    jintArray intArrObj = (*env)->NewIntArray(env, count);
+    if (intArrObj == NULL) {
+        CFRelease(tags);
+        return intArrObj;
+    }
+    jint* data = (*env)->GetIntArrayElements(env, intArrObj, NULL);
+    if (data == NULL) {
+        CFRelease(tags);
+        return intArrObj;
+    }
+    int i;
+    for (i = 0; i < count; i++) {
+        data[i] = (uintptr_t)CFArrayGetValueAtIndex(tags, i);
+    }
+    CFRelease(tags);
+    (*env)->ReleaseIntArrayElements(env, intArrObj, data, (jint)0);
+    return intArrObj;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_com_sun_javafx_font_DFontDecoder_getCTFontTable
+(JNIEnv *env, jclass clazz, jlong fontPtr, jint tag)
+{
+    CTFontRef fontRef = (CTFontRef)fontPtr;
+    CTFontTableTag cttag = (CTFontTableTag)tag;
+    CTFontTableOptions options = kCTFontTableOptionNoOptions;
+    CFDataRef tableData = CTFontCopyTable(fontRef, cttag, options);
+    CFIndex length = CFDataGetLength(tableData);
+    jbyteArray byteArrObj = (*env)->NewByteArray(env, length);
+    if (byteArrObj == NULL) {
+        CFRelease(tableData);
+        return byteArrObj;
+    }
+    jbyte* data = (*env)->GetByteArrayElements(env, byteArrObj, NULL);
+    if (data == NULL) {
+        CFRelease(tableData);
+        return byteArrObj;
+    }
+    const UInt8 *src = CFDataGetBytePtr(tableData);
+    memcpy(data, src, length);
+    (*env)->ReleaseByteArrayElements(env, byteArrObj, data, 0);
+    CFRelease(tableData);
+    return byteArrObj;
+}
+
+#endif /* TARGET_OS_MAC */
+#endif /* __APPLE__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/src/directwrite.cpp	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,2219 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+#ifdef WIN32
+
+#include <windows.h>
+#include <dwrite.h>
+#include <d2d1.h>
+#include <wincodec.h>
+#include <vector>
+#include <new>
+
+#include <com_sun_javafx_font_directwrite_OS.h>
+
+#define OS_NATIVE(func) Java_com_sun_javafx_font_directwrite_OS_##func
+
+/* DirectWrite is not available on all platforms. */
+typedef HRESULT (WINAPI*DWriteCreateFactoryProc)(
+  DWRITE_FACTORY_TYPE factoryType,
+  REFIID iid,
+  IUnknown **factory
+);
+
+/* Direct2D is not available on all platforms. */
+typedef HRESULT (WINAPI*D2D1CreateFactoryProc)(
+  D2D1_FACTORY_TYPE factoryType,
+  REFIID iid,
+  const D2D1_FACTORY_OPTIONS *pFactoryOptions,
+  void **factory
+);
+
+/**************************************************************************/
+/*                                                                        */
+/*                            Structs                                     */
+/*                                                                        */
+/**************************************************************************/
+
+typedef struct DWRITE_GLYPH_METRICS_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID leftSideBearing, advanceWidth, rightSideBearing, topSideBearing, advanceHeight, bottomSideBearing, verticalOriginY;
+    jmethodID init;
+} DWRITE_GLYPH_METRICS_FID_CACHE;
+
+DWRITE_GLYPH_METRICS_FID_CACHE DWRITE_GLYPH_METRICSFc;
+
+void cacheDWRITE_GLYPH_METRICSFields(JNIEnv *env)
+{
+    if (DWRITE_GLYPH_METRICSFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/DWRITE_GLYPH_METRICS");
+    DWRITE_GLYPH_METRICSFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    DWRITE_GLYPH_METRICSFc.leftSideBearing = env->GetFieldID(DWRITE_GLYPH_METRICSFc.clazz, "leftSideBearing", "I");
+    DWRITE_GLYPH_METRICSFc.advanceWidth = env->GetFieldID(DWRITE_GLYPH_METRICSFc.clazz, "advanceWidth", "I");
+    DWRITE_GLYPH_METRICSFc.rightSideBearing = env->GetFieldID(DWRITE_GLYPH_METRICSFc.clazz, "rightSideBearing", "I");
+    DWRITE_GLYPH_METRICSFc.topSideBearing = env->GetFieldID(DWRITE_GLYPH_METRICSFc.clazz, "topSideBearing", "I");
+    DWRITE_GLYPH_METRICSFc.advanceHeight = env->GetFieldID(DWRITE_GLYPH_METRICSFc.clazz, "advanceHeight", "I");
+    DWRITE_GLYPH_METRICSFc.bottomSideBearing = env->GetFieldID(DWRITE_GLYPH_METRICSFc.clazz, "bottomSideBearing", "I");
+    DWRITE_GLYPH_METRICSFc.verticalOriginY = env->GetFieldID(DWRITE_GLYPH_METRICSFc.clazz, "verticalOriginY", "I");
+    DWRITE_GLYPH_METRICSFc.init = env->GetMethodID(DWRITE_GLYPH_METRICSFc.clazz, "<init>", "()V");
+    DWRITE_GLYPH_METRICSFc.cached = 1;
+}
+
+DWRITE_GLYPH_METRICS *getDWRITE_GLYPH_METRICSFields(JNIEnv *env, jobject lpObject, DWRITE_GLYPH_METRICS *lpStruct)
+{
+    if (!DWRITE_GLYPH_METRICSFc.cached) cacheDWRITE_GLYPH_METRICSFields(env);
+    lpStruct->leftSideBearing = env->GetIntField(lpObject, DWRITE_GLYPH_METRICSFc.leftSideBearing);
+    lpStruct->advanceWidth = env->GetIntField(lpObject, DWRITE_GLYPH_METRICSFc.advanceWidth);
+    lpStruct->rightSideBearing = env->GetIntField(lpObject, DWRITE_GLYPH_METRICSFc.rightSideBearing);
+    lpStruct->topSideBearing = env->GetIntField(lpObject, DWRITE_GLYPH_METRICSFc.topSideBearing);
+    lpStruct->advanceHeight = env->GetIntField(lpObject, DWRITE_GLYPH_METRICSFc.advanceHeight);
+    lpStruct->bottomSideBearing = env->GetIntField(lpObject, DWRITE_GLYPH_METRICSFc.bottomSideBearing);
+    lpStruct->verticalOriginY = env->GetIntField(lpObject, DWRITE_GLYPH_METRICSFc.verticalOriginY);
+    return lpStruct;
+}
+
+void setDWRITE_GLYPH_METRICSFields(JNIEnv *env, jobject lpObject, DWRITE_GLYPH_METRICS *lpStruct)
+{
+    if (!DWRITE_GLYPH_METRICSFc.cached) cacheDWRITE_GLYPH_METRICSFields(env);
+    env->SetIntField(lpObject, DWRITE_GLYPH_METRICSFc.leftSideBearing, (jint)lpStruct->leftSideBearing);
+    env->SetIntField(lpObject, DWRITE_GLYPH_METRICSFc.advanceWidth, (jint)lpStruct->advanceWidth);
+    env->SetIntField(lpObject, DWRITE_GLYPH_METRICSFc.rightSideBearing, (jint)lpStruct->rightSideBearing);
+    env->SetIntField(lpObject, DWRITE_GLYPH_METRICSFc.topSideBearing, (jint)lpStruct->topSideBearing);
+    env->SetIntField(lpObject, DWRITE_GLYPH_METRICSFc.advanceHeight, (jint)lpStruct->advanceHeight);
+    env->SetIntField(lpObject, DWRITE_GLYPH_METRICSFc.bottomSideBearing, (jint)lpStruct->bottomSideBearing);
+    env->SetIntField(lpObject, DWRITE_GLYPH_METRICSFc.verticalOriginY, (jint)lpStruct->verticalOriginY);
+}
+
+jobject newDWRITE_GLYPH_METRICS(JNIEnv *env, DWRITE_GLYPH_METRICS *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!DWRITE_GLYPH_METRICSFc.cached) cacheDWRITE_GLYPH_METRICSFields(env);
+    lpObject = env->NewObject(DWRITE_GLYPH_METRICSFc.clazz, DWRITE_GLYPH_METRICSFc.init);
+    if (lpObject && lpStruct) setDWRITE_GLYPH_METRICSFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct DWRITE_MATRIX_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID m11, m12, m21, m22, dx, dy;
+    jmethodID init;
+} DWRITE_MATRIX_FID_CACHE;
+
+DWRITE_MATRIX_FID_CACHE DWRITE_MATRIXFc;
+
+void cacheDWRITE_MATRIXFields(JNIEnv *env)
+{
+    if (DWRITE_MATRIXFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/DWRITE_MATRIX");
+    DWRITE_MATRIXFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    DWRITE_MATRIXFc.m11 = env->GetFieldID(DWRITE_MATRIXFc.clazz, "m11", "F");
+    DWRITE_MATRIXFc.m12 = env->GetFieldID(DWRITE_MATRIXFc.clazz, "m12", "F");
+    DWRITE_MATRIXFc.m21 = env->GetFieldID(DWRITE_MATRIXFc.clazz, "m21", "F");
+    DWRITE_MATRIXFc.m22 = env->GetFieldID(DWRITE_MATRIXFc.clazz, "m22", "F");
+    DWRITE_MATRIXFc.dx = env->GetFieldID(DWRITE_MATRIXFc.clazz, "dx", "F");
+    DWRITE_MATRIXFc.dy = env->GetFieldID(DWRITE_MATRIXFc.clazz, "dy", "F");
+    DWRITE_MATRIXFc.init = env->GetMethodID(DWRITE_MATRIXFc.clazz, "<init>", "()V");
+    DWRITE_MATRIXFc.cached = 1;
+}
+
+DWRITE_MATRIX *getDWRITE_MATRIXFields(JNIEnv *env, jobject lpObject, DWRITE_MATRIX *lpStruct)
+{
+    if (!DWRITE_MATRIXFc.cached) cacheDWRITE_MATRIXFields(env);
+    lpStruct->m11 = env->GetFloatField(lpObject, DWRITE_MATRIXFc.m11);
+    lpStruct->m12 = env->GetFloatField(lpObject, DWRITE_MATRIXFc.m12);
+    lpStruct->m21 = env->GetFloatField(lpObject, DWRITE_MATRIXFc.m21);
+    lpStruct->m22 = env->GetFloatField(lpObject, DWRITE_MATRIXFc.m22);
+    lpStruct->dx = env->GetFloatField(lpObject, DWRITE_MATRIXFc.dx);
+    lpStruct->dy = env->GetFloatField(lpObject, DWRITE_MATRIXFc.dy);
+    return lpStruct;
+}
+
+void setDWRITE_MATRIXFields(JNIEnv *env, jobject lpObject, DWRITE_MATRIX *lpStruct)
+{
+    if (!DWRITE_MATRIXFc.cached) cacheDWRITE_MATRIXFields(env);
+    env->SetFloatField(lpObject, DWRITE_MATRIXFc.m11, (jfloat)lpStruct->m11);
+    env->SetFloatField(lpObject, DWRITE_MATRIXFc.m12, (jfloat)lpStruct->m12);
+    env->SetFloatField(lpObject, DWRITE_MATRIXFc.m21, (jfloat)lpStruct->m21);
+    env->SetFloatField(lpObject, DWRITE_MATRIXFc.m22, (jfloat)lpStruct->m22);
+    env->SetFloatField(lpObject, DWRITE_MATRIXFc.dx, (jfloat)lpStruct->dx);
+    env->SetFloatField(lpObject, DWRITE_MATRIXFc.dy, (jfloat)lpStruct->dy);
+}
+
+jobject newDWRITE_MATRIX(JNIEnv *env, DWRITE_MATRIX *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!DWRITE_MATRIXFc.cached) cacheDWRITE_MATRIXFields(env);
+    lpObject = env->NewObject(DWRITE_MATRIXFc.clazz, DWRITE_MATRIXFc.init);
+    if (lpObject && lpStruct) setDWRITE_MATRIXFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct DWRITE_GLYPH_RUN_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID fontFace, fontEmSize, glyphCount, glyphIndices, glyphAdvances/*, glyphOffsets*/, isSideways, bidiLevel;
+    jmethodID init;
+} DWRITE_GLYPH_RUN_FID_CACHE;
+
+DWRITE_GLYPH_RUN_FID_CACHE DWRITE_GLYPH_RUNFc;
+
+void cacheDWRITE_GLYPH_RUNFields(JNIEnv *env)
+{
+    if (DWRITE_GLYPH_RUNFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/DWRITE_GLYPH_RUN");
+    DWRITE_GLYPH_RUNFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    DWRITE_GLYPH_RUNFc.fontFace = env->GetFieldID(DWRITE_GLYPH_RUNFc.clazz, "fontFace", "J");
+    DWRITE_GLYPH_RUNFc.fontEmSize = env->GetFieldID(DWRITE_GLYPH_RUNFc.clazz, "fontEmSize", "F");
+    DWRITE_GLYPH_RUNFc.glyphCount = env->GetFieldID(DWRITE_GLYPH_RUNFc.clazz, "glyphCount", "I");
+    DWRITE_GLYPH_RUNFc.glyphIndices = env->GetFieldID(DWRITE_GLYPH_RUNFc.clazz, "glyphIndices", "S");
+    DWRITE_GLYPH_RUNFc.glyphAdvances = env->GetFieldID(DWRITE_GLYPH_RUNFc.clazz, "glyphAdvances", "F");
+    DWRITE_GLYPH_RUNFc.isSideways = env->GetFieldID(DWRITE_GLYPH_RUNFc.clazz, "isSideways", "Z");
+    DWRITE_GLYPH_RUNFc.bidiLevel = env->GetFieldID(DWRITE_GLYPH_RUNFc.clazz, "bidiLevel", "I");
+    DWRITE_GLYPH_RUNFc.init = env->GetMethodID(DWRITE_GLYPH_RUNFc.clazz, "<init>", "()V");
+    DWRITE_GLYPH_RUNFc.cached = 1;
+}
+
+DWRITE_GLYPH_RUN *getDWRITE_GLYPH_RUNFields(JNIEnv *env, jobject lpObject, DWRITE_GLYPH_RUN *lpStruct)
+{
+    if (!DWRITE_GLYPH_RUNFc.cached) cacheDWRITE_GLYPH_RUNFields(env);
+    lpStruct->fontFace = (IDWriteFontFace *)env->GetLongField(lpObject, DWRITE_GLYPH_RUNFc.fontFace);
+    lpStruct->fontEmSize = env->GetFloatField(lpObject, DWRITE_GLYPH_RUNFc.fontEmSize);
+    lpStruct->glyphCount = env->GetIntField(lpObject, DWRITE_GLYPH_RUNFc.glyphCount);
+    ((jshort*)lpStruct->glyphIndices)[0] = env->GetShortField(lpObject, DWRITE_GLYPH_RUNFc.glyphIndices);
+    ((jfloat*)lpStruct->glyphAdvances)[0] = env->GetFloatField(lpObject, DWRITE_GLYPH_RUNFc.glyphAdvances);
+    lpStruct->glyphOffsets = NULL;
+    lpStruct->isSideways = env->GetBooleanField(lpObject, DWRITE_GLYPH_RUNFc.isSideways);
+    lpStruct->bidiLevel = env->GetIntField(lpObject, DWRITE_GLYPH_RUNFc.bidiLevel);
+    return lpStruct;
+}
+
+void setDWRITE_GLYPH_RUNFields(JNIEnv *env, jobject lpObject, DWRITE_GLYPH_RUN *lpStruct)
+{
+    if (!DWRITE_GLYPH_RUNFc.cached) cacheDWRITE_GLYPH_RUNFields(env);
+    //NOT USED
+}
+
+jobject newDWRITE_GLYPH_RUN(JNIEnv *env, DWRITE_GLYPH_RUN *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!DWRITE_GLYPH_RUNFc.cached) cacheDWRITE_GLYPH_RUNFields(env);
+    lpObject = env->NewObject(DWRITE_GLYPH_RUNFc.clazz, DWRITE_GLYPH_RUNFc.init);
+    if (lpObject && lpStruct) setDWRITE_GLYPH_RUNFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct DWRITE_SCRIPT_ANALYSIS_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID script, shapes;
+    jmethodID init;
+} DWRITE_SCRIPT_ANALYSIS_FID_CACHE;
+
+DWRITE_SCRIPT_ANALYSIS_FID_CACHE DWRITE_SCRIPT_ANALYSISFc;
+
+void cacheDWRITE_SCRIPT_ANALYSISFields(JNIEnv *env)
+{
+    if (DWRITE_SCRIPT_ANALYSISFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/DWRITE_SCRIPT_ANALYSIS");
+    DWRITE_SCRIPT_ANALYSISFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    DWRITE_SCRIPT_ANALYSISFc.script = env->GetFieldID(DWRITE_SCRIPT_ANALYSISFc.clazz, "script", "S");
+    DWRITE_SCRIPT_ANALYSISFc.shapes = env->GetFieldID(DWRITE_SCRIPT_ANALYSISFc.clazz, "shapes", "I");
+    DWRITE_SCRIPT_ANALYSISFc.init = env->GetMethodID(DWRITE_SCRIPT_ANALYSISFc.clazz, "<init>", "()V");
+    DWRITE_SCRIPT_ANALYSISFc.cached = 1;
+}
+
+DWRITE_SCRIPT_ANALYSIS *getDWRITE_SCRIPT_ANALYSISFields(JNIEnv *env, jobject lpObject, DWRITE_SCRIPT_ANALYSIS *lpStruct)
+{
+    if (!DWRITE_SCRIPT_ANALYSISFc.cached) cacheDWRITE_SCRIPT_ANALYSISFields(env);
+    lpStruct->script = env->GetShortField(lpObject, DWRITE_SCRIPT_ANALYSISFc.script);
+    lpStruct->shapes = (DWRITE_SCRIPT_SHAPES)env->GetIntField(lpObject, DWRITE_SCRIPT_ANALYSISFc.shapes);
+    return lpStruct;
+}
+
+void setDWRITE_SCRIPT_ANALYSISFields(JNIEnv *env, jobject lpObject, DWRITE_SCRIPT_ANALYSIS *lpStruct)
+{
+    if (!DWRITE_SCRIPT_ANALYSISFc.cached) cacheDWRITE_SCRIPT_ANALYSISFields(env);
+    env->SetShortField(lpObject, DWRITE_SCRIPT_ANALYSISFc.script, (jshort)lpStruct->script);
+    env->SetIntField(lpObject, DWRITE_SCRIPT_ANALYSISFc.shapes, (jint)lpStruct->shapes);
+}
+
+jobject newDWRITE_SCRIPT_ANALYSIS(JNIEnv *env, DWRITE_SCRIPT_ANALYSIS *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!DWRITE_SCRIPT_ANALYSISFc.cached) cacheDWRITE_SCRIPT_ANALYSISFields(env);
+    lpObject = env->NewObject(DWRITE_SCRIPT_ANALYSISFc.clazz, DWRITE_SCRIPT_ANALYSISFc.init);
+    if (lpObject && lpStruct) setDWRITE_SCRIPT_ANALYSISFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct RECT_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID left, top, right, bottom;
+    jmethodID init;
+} RECT_FID_CACHE;
+
+RECT_FID_CACHE RECTFc;
+
+void cacheRECTFields(JNIEnv *env)
+{
+    if (RECTFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/RECT");
+    RECTFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    RECTFc.left = env->GetFieldID(RECTFc.clazz, "left", "I");
+    RECTFc.top = env->GetFieldID(RECTFc.clazz, "top", "I");
+    RECTFc.right = env->GetFieldID(RECTFc.clazz, "right", "I");
+    RECTFc.bottom = env->GetFieldID(RECTFc.clazz, "bottom", "I");
+    RECTFc.init = env->GetMethodID(RECTFc.clazz, "<init>", "()V");
+    RECTFc.cached = 1;
+}
+
+RECT *getRECTFields(JNIEnv *env, jobject lpObject, RECT *lpStruct)
+{
+    if (!RECTFc.cached) cacheRECTFields(env);
+    lpStruct->left = env->GetIntField(lpObject, RECTFc.left);
+    lpStruct->top = env->GetIntField(lpObject, RECTFc.top);
+    lpStruct->right = env->GetIntField(lpObject, RECTFc.right);
+    lpStruct->bottom = env->GetIntField(lpObject, RECTFc.bottom);
+    return lpStruct;
+}
+
+void setRECTFields(JNIEnv *env, jobject lpObject, RECT *lpStruct)
+{
+    if (!RECTFc.cached) cacheRECTFields(env);
+    env->SetIntField(lpObject, RECTFc.left, (jint)lpStruct->left);
+    env->SetIntField(lpObject, RECTFc.top, (jint)lpStruct->top);
+    env->SetIntField(lpObject, RECTFc.right, (jint)lpStruct->right);
+    env->SetIntField(lpObject, RECTFc.bottom, (jint)lpStruct->bottom);
+}
+
+jobject newRECT(JNIEnv *env, RECT *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!RECTFc.cached) cacheRECTFields(env);
+    lpObject = env->NewObject(RECTFc.clazz, RECTFc.init);
+    if (lpObject && lpStruct) setRECTFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct D2D1_PIXEL_FORMAT_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID format, alphaMode;
+    jmethodID init;
+} D2D1_PIXEL_FORMAT_FID_CACHE;
+
+D2D1_PIXEL_FORMAT_FID_CACHE D2D1_PIXEL_FORMATFc;
+
+void cacheD2D1_PIXEL_FORMATFields(JNIEnv *env)
+{
+    if (D2D1_PIXEL_FORMATFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/D2D1_PIXEL_FORMAT");
+    D2D1_PIXEL_FORMATFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    D2D1_PIXEL_FORMATFc.format = env->GetFieldID(D2D1_PIXEL_FORMATFc.clazz, "format", "I");
+    D2D1_PIXEL_FORMATFc.alphaMode = env->GetFieldID(D2D1_PIXEL_FORMATFc.clazz, "alphaMode", "I");
+    D2D1_PIXEL_FORMATFc.init = env->GetMethodID(D2D1_PIXEL_FORMATFc.clazz, "<init>", "()V");
+    D2D1_PIXEL_FORMATFc.cached = 1;
+}
+
+D2D1_PIXEL_FORMAT *getD2D1_PIXEL_FORMATFields(JNIEnv *env, jobject lpObject, D2D1_PIXEL_FORMAT *lpStruct)
+{
+    if (!D2D1_PIXEL_FORMATFc.cached) cacheD2D1_PIXEL_FORMATFields(env);
+    lpStruct->format = (DXGI_FORMAT)env->GetIntField(lpObject, D2D1_PIXEL_FORMATFc.format);
+    lpStruct->alphaMode = (D2D1_ALPHA_MODE)env->GetIntField(lpObject, D2D1_PIXEL_FORMATFc.alphaMode);
+    return lpStruct;
+}
+
+void setD2D1_PIXEL_FORMATFields(JNIEnv *env, jobject lpObject, D2D1_PIXEL_FORMAT *lpStruct)
+{
+    if (!D2D1_PIXEL_FORMATFc.cached) cacheD2D1_PIXEL_FORMATFields(env);
+    env->SetIntField(lpObject, D2D1_PIXEL_FORMATFc.format, (jint)lpStruct->format);
+    env->SetIntField(lpObject, D2D1_PIXEL_FORMATFc.alphaMode, (jint)lpStruct->alphaMode);
+}
+
+jobject newD2D1_PIXEL_FORMAT(JNIEnv *env, D2D1_PIXEL_FORMAT *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!D2D1_PIXEL_FORMATFc.cached) cacheD2D1_PIXEL_FORMATFields(env);
+    lpObject = env->NewObject(D2D1_PIXEL_FORMATFc.clazz, D2D1_PIXEL_FORMATFc.init);
+    if (lpObject && lpStruct) setD2D1_PIXEL_FORMATFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct D2D1_RENDER_TARGET_PROPERTIES_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID type, pixelFormat, dpiX, dpiY, usage, minLevel;
+    jmethodID init;
+} D2D1_RENDER_TARGET_PROPERTIES_FID_CACHE;
+
+D2D1_RENDER_TARGET_PROPERTIES_FID_CACHE D2D1_RENDER_TARGET_PROPERTIESFc;
+
+void cacheD2D1_RENDER_TARGET_PROPERTIESFields(JNIEnv *env)
+{
+    if (D2D1_RENDER_TARGET_PROPERTIESFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/D2D1_RENDER_TARGET_PROPERTIES");
+    D2D1_RENDER_TARGET_PROPERTIESFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    D2D1_RENDER_TARGET_PROPERTIESFc.type = env->GetFieldID(D2D1_RENDER_TARGET_PROPERTIESFc.clazz, "type", "I");
+    D2D1_RENDER_TARGET_PROPERTIESFc.pixelFormat = env->GetFieldID(D2D1_RENDER_TARGET_PROPERTIESFc.clazz, "pixelFormat", "Lcom/sun/javafx/font/directwrite/D2D1_PIXEL_FORMAT;");
+    D2D1_RENDER_TARGET_PROPERTIESFc.dpiX = env->GetFieldID(D2D1_RENDER_TARGET_PROPERTIESFc.clazz, "dpiX", "F");
+    D2D1_RENDER_TARGET_PROPERTIESFc.dpiY = env->GetFieldID(D2D1_RENDER_TARGET_PROPERTIESFc.clazz, "dpiY", "F");
+    D2D1_RENDER_TARGET_PROPERTIESFc.usage = env->GetFieldID(D2D1_RENDER_TARGET_PROPERTIESFc.clazz, "usage", "I");
+    D2D1_RENDER_TARGET_PROPERTIESFc.minLevel = env->GetFieldID(D2D1_RENDER_TARGET_PROPERTIESFc.clazz, "minLevel", "I");
+    D2D1_RENDER_TARGET_PROPERTIESFc.init = env->GetMethodID(D2D1_RENDER_TARGET_PROPERTIESFc.clazz, "<init>", "()V");
+    D2D1_RENDER_TARGET_PROPERTIESFc.cached = 1;
+}
+
+D2D1_RENDER_TARGET_PROPERTIES *getD2D1_RENDER_TARGET_PROPERTIESFields(JNIEnv *env, jobject lpObject, D2D1_RENDER_TARGET_PROPERTIES *lpStruct)
+{
+    if (!D2D1_RENDER_TARGET_PROPERTIESFc.cached) cacheD2D1_RENDER_TARGET_PROPERTIESFields(env);
+    lpStruct->type = (D2D1_RENDER_TARGET_TYPE)env->GetIntField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.type);
+    {
+    jobject lpObject1 = env->GetObjectField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.pixelFormat);
+    if (lpObject1 != NULL) getD2D1_PIXEL_FORMATFields(env, lpObject1, &lpStruct->pixelFormat);
+    }
+    lpStruct->dpiX = env->GetFloatField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.dpiX);
+    lpStruct->dpiY = env->GetFloatField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.dpiY);
+    lpStruct->usage = (D2D1_RENDER_TARGET_USAGE)env->GetIntField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.usage);
+    lpStruct->minLevel = (D2D1_FEATURE_LEVEL)env->GetIntField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.minLevel);
+    return lpStruct;
+}
+
+void setD2D1_RENDER_TARGET_PROPERTIESFields(JNIEnv *env, jobject lpObject, D2D1_RENDER_TARGET_PROPERTIES *lpStruct)
+{
+    if (!D2D1_RENDER_TARGET_PROPERTIESFc.cached) cacheD2D1_RENDER_TARGET_PROPERTIESFields(env);
+    env->SetIntField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.type, (jint)lpStruct->type);
+    {
+    jobject lpObject1 = env->GetObjectField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.pixelFormat);
+    if (lpObject1 != NULL) setD2D1_PIXEL_FORMATFields(env, lpObject1, &lpStruct->pixelFormat);
+    }
+    env->SetFloatField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.dpiX, (jfloat)lpStruct->dpiX);
+    env->SetFloatField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.dpiY, (jfloat)lpStruct->dpiY);
+    env->SetIntField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.usage, (jint)lpStruct->usage);
+    env->SetIntField(lpObject, D2D1_RENDER_TARGET_PROPERTIESFc.minLevel, (jint)lpStruct->minLevel);
+}
+
+jobject newD2D1_RENDER_TARGET_PROPERTIES(JNIEnv *env, D2D1_RENDER_TARGET_PROPERTIES *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!D2D1_RENDER_TARGET_PROPERTIESFc.cached) cacheD2D1_RENDER_TARGET_PROPERTIESFields(env);
+    lpObject = env->NewObject(D2D1_RENDER_TARGET_PROPERTIESFc.clazz, D2D1_RENDER_TARGET_PROPERTIESFc.init);
+    if (lpObject && lpStruct) setD2D1_RENDER_TARGET_PROPERTIESFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct D2D1_COLOR_F_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID r, g, b, a;
+    jmethodID init;
+} D2D1_COLOR_F_FID_CACHE;
+
+D2D1_COLOR_F_FID_CACHE D2D1_COLOR_FFc;
+
+void cacheD2D1_COLOR_FFields(JNIEnv *env)
+{
+    if (D2D1_COLOR_FFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/D2D1_COLOR_F");
+    D2D1_COLOR_FFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    D2D1_COLOR_FFc.r = env->GetFieldID(D2D1_COLOR_FFc.clazz, "r", "F");
+    D2D1_COLOR_FFc.g = env->GetFieldID(D2D1_COLOR_FFc.clazz, "g", "F");
+    D2D1_COLOR_FFc.b = env->GetFieldID(D2D1_COLOR_FFc.clazz, "b", "F");
+    D2D1_COLOR_FFc.a = env->GetFieldID(D2D1_COLOR_FFc.clazz, "a", "F");
+    D2D1_COLOR_FFc.init = env->GetMethodID(D2D1_COLOR_FFc.clazz, "<init>", "()V");
+    D2D1_COLOR_FFc.cached = 1;
+}
+
+D2D1_COLOR_F *getD2D1_COLOR_FFields(JNIEnv *env, jobject lpObject, D2D1_COLOR_F *lpStruct)
+{
+    if (!D2D1_COLOR_FFc.cached) cacheD2D1_COLOR_FFields(env);
+    lpStruct->r = env->GetFloatField(lpObject, D2D1_COLOR_FFc.r);
+    lpStruct->g = env->GetFloatField(lpObject, D2D1_COLOR_FFc.g);
+    lpStruct->b = env->GetFloatField(lpObject, D2D1_COLOR_FFc.b);
+    lpStruct->a = env->GetFloatField(lpObject, D2D1_COLOR_FFc.a);
+    return lpStruct;
+}
+
+void setD2D1_COLOR_FFields(JNIEnv *env, jobject lpObject, D2D1_COLOR_F *lpStruct)
+{
+    if (!D2D1_COLOR_FFc.cached) cacheD2D1_COLOR_FFields(env);
+    env->SetFloatField(lpObject, D2D1_COLOR_FFc.r, (jfloat)lpStruct->r);
+    env->SetFloatField(lpObject, D2D1_COLOR_FFc.g, (jfloat)lpStruct->g);
+    env->SetFloatField(lpObject, D2D1_COLOR_FFc.b, (jfloat)lpStruct->b);
+    env->SetFloatField(lpObject, D2D1_COLOR_FFc.a, (jfloat)lpStruct->a);
+}
+
+jobject newD2D1_COLOR_F(JNIEnv *env, D2D1_COLOR_F *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!D2D1_COLOR_FFc.cached) cacheD2D1_COLOR_FFields(env);
+    lpObject = env->NewObject(D2D1_COLOR_FFc.clazz, D2D1_COLOR_FFc.init);
+    if (lpObject && lpStruct) setD2D1_COLOR_FFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct D2D1_POINT_2F_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID x, y;
+    jmethodID init;
+} D2D1_POINT_2F_FID_CACHE;
+
+D2D1_POINT_2F_FID_CACHE D2D1_POINT_2FFc;
+
+void cacheD2D1_POINT_2FFields(JNIEnv *env)
+{
+    if (D2D1_POINT_2FFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/D2D1_POINT_2F");
+    D2D1_POINT_2FFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    D2D1_POINT_2FFc.x = env->GetFieldID(D2D1_POINT_2FFc.clazz, "x", "F");
+    D2D1_POINT_2FFc.y = env->GetFieldID(D2D1_POINT_2FFc.clazz, "y", "F");
+    D2D1_POINT_2FFc.init = env->GetMethodID(D2D1_POINT_2FFc.clazz, "<init>", "()V");
+    D2D1_POINT_2FFc.cached = 1;
+}
+
+D2D1_POINT_2F *getD2D1_POINT_2FFields(JNIEnv *env, jobject lpObject, D2D1_POINT_2F *lpStruct)
+{
+    if (!D2D1_POINT_2FFc.cached) cacheD2D1_POINT_2FFields(env);
+    lpStruct->x = env->GetFloatField(lpObject, D2D1_POINT_2FFc.x);
+    lpStruct->y = env->GetFloatField(lpObject, D2D1_POINT_2FFc.y);
+    return lpStruct;
+}
+
+void setD2D1_POINT_2FFields(JNIEnv *env, jobject lpObject, D2D1_POINT_2F *lpStruct)
+{
+    if (!D2D1_POINT_2FFc.cached) cacheD2D1_POINT_2FFields(env);
+    env->SetFloatField(lpObject, D2D1_POINT_2FFc.x, (jfloat)lpStruct->x);
+    env->SetFloatField(lpObject, D2D1_POINT_2FFc.y, (jfloat)lpStruct->y);
+}
+
+jobject newD2D1_POINT_2F(JNIEnv *env, D2D1_POINT_2F *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!D2D1_POINT_2FFc.cached) cacheD2D1_POINT_2FFields(env);
+    lpObject = env->NewObject(D2D1_POINT_2FFc.clazz, D2D1_POINT_2FFc.init);
+    if (lpObject && lpStruct) setD2D1_POINT_2FFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+
+typedef struct D2D1_MATRIX_3X2_F_FID_CACHE {
+    int cached;
+    jclass clazz;
+    jfieldID _11, _12, _21, _22, _31, _32;
+    jmethodID init;
+} D2D1_MATRIX_3X2_F_FID_CACHE;
+
+D2D1_MATRIX_3X2_F_FID_CACHE D2D1_MATRIX_3X2_FFc;
+
+void cacheD2D1_MATRIX_3X2_FFields(JNIEnv *env)
+{
+    if (D2D1_MATRIX_3X2_FFc.cached) return;
+    jclass tmpClass = env->FindClass("com/sun/javafx/font/directwrite/D2D1_MATRIX_3X2_F");
+    D2D1_MATRIX_3X2_FFc.clazz =  (jclass)env->NewGlobalRef(tmpClass);
+    D2D1_MATRIX_3X2_FFc._11 = env->GetFieldID(D2D1_MATRIX_3X2_FFc.clazz, "_11", "F");
+    D2D1_MATRIX_3X2_FFc._12 = env->GetFieldID(D2D1_MATRIX_3X2_FFc.clazz, "_12", "F");
+    D2D1_MATRIX_3X2_FFc._21 = env->GetFieldID(D2D1_MATRIX_3X2_FFc.clazz, "_21", "F");
+    D2D1_MATRIX_3X2_FFc._22 = env->GetFieldID(D2D1_MATRIX_3X2_FFc.clazz, "_22", "F");
+    D2D1_MATRIX_3X2_FFc._31 = env->GetFieldID(D2D1_MATRIX_3X2_FFc.clazz, "_31", "F");
+    D2D1_MATRIX_3X2_FFc._32 = env->GetFieldID(D2D1_MATRIX_3X2_FFc.clazz, "_32", "F");
+    D2D1_MATRIX_3X2_FFc.init = env->GetMethodID(D2D1_MATRIX_3X2_FFc.clazz, "<init>", "()V");
+    D2D1_MATRIX_3X2_FFc.cached = 1;
+}
+
+D2D1_MATRIX_3X2_F *getD2D1_MATRIX_3X2_FFields(JNIEnv *env, jobject lpObject, D2D1_MATRIX_3X2_F *lpStruct)
+{
+    if (!D2D1_MATRIX_3X2_FFc.cached) cacheD2D1_MATRIX_3X2_FFields(env);
+    lpStruct->_11 = env->GetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._11);
+    lpStruct->_12 = env->GetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._12);
+    lpStruct->_21 = env->GetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._21);
+    lpStruct->_22 = env->GetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._22);
+    lpStruct->_31 = env->GetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._31);
+    lpStruct->_32 = env->GetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._32);
+    return lpStruct;
+}
+
+void setD2D1_MATRIX_3X2_FFields(JNIEnv *env, jobject lpObject, D2D1_MATRIX_3X2_F *lpStruct)
+{
+    if (!D2D1_MATRIX_3X2_FFc.cached) cacheD2D1_MATRIX_3X2_FFields(env);
+    env->SetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._11, (jfloat)lpStruct->_11);
+    env->SetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._12, (jfloat)lpStruct->_12);
+    env->SetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._21, (jfloat)lpStruct->_21);
+    env->SetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._22, (jfloat)lpStruct->_22);
+    env->SetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._31, (jfloat)lpStruct->_31);
+    env->SetFloatField(lpObject, D2D1_MATRIX_3X2_FFc._32, (jfloat)lpStruct->_32);
+}
+
+jobject newD2D1_MATRIX_3X2_F(JNIEnv *env, D2D1_MATRIX_3X2_F *lpStruct)
+{
+    jobject lpObject = NULL;
+    if (!D2D1_MATRIX_3X2_FFc.cached) cacheD2D1_MATRIX_3X2_FFields(env);
+    lpObject = env->NewObject(D2D1_MATRIX_3X2_FFc.clazz, D2D1_MATRIX_3X2_FFc.init);
+    if (lpObject && lpStruct) setD2D1_MATRIX_3X2_FFields(env, lpObject, lpStruct);
+    return lpObject;
+}
+/**************************************************************************/
+/*                                                                        */
+/*                            Functions                                   */
+/*                                                                        */
+/**************************************************************************/
+
+JNIEXPORT jlong JNICALL OS_NATIVE(_1WICCreateImagingFactory)
+    (JNIEnv *env, jclass that)
+{
+    HRESULT hr = E_FAIL;
+    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+    IWICImagingFactory* result = NULL;
+    hr = CoCreateInstance(
+            CLSID_WICImagingFactory,
+            NULL,
+            CLSCTX_INPROC_SERVER,
+            IID_PPV_ARGS(&result)
+            );
+    CoUninitialize();   /* NOT COOL BUT SEEMS TO WORK */
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(_1D2D1CreateFactory)
+    (JNIEnv *env, jclass that, jint arg0)
+{
+    HRESULT hr = E_FAIL;
+    ID2D1Factory* result = NULL;
+    HMODULE module = LoadLibrary(TEXT("d2d1.dll"));
+    D2D1CreateFactoryProc createProc = NULL;
+    if (module) {
+        createProc = (D2D1CreateFactoryProc)GetProcAddress(module, "D2D1CreateFactory");
+    }
+    if (createProc) {
+        D2D1_FACTORY_OPTIONS options;
+        options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
+        hr = createProc((D2D1_FACTORY_TYPE)arg0,
+                        __uuidof(ID2D1Factory),
+                        &options,
+                        reinterpret_cast<void**>(&result));
+    }
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(_1DWriteCreateFactory)
+    (JNIEnv *env, jclass that, jint arg0)
+{
+    HRESULT hr = E_FAIL;
+    IDWriteFactory* result = NULL;
+    HMODULE module = LoadLibrary(TEXT("dwrite.dll"));
+    DWriteCreateFactoryProc createProc = NULL;
+    if (module) {
+        createProc = (DWriteCreateFactoryProc)GetProcAddress(module, "DWriteCreateFactory");
+    }
+    if (createProc) {
+        hr = createProc((DWRITE_FACTORY_TYPE)arg0,
+                        __uuidof(IDWriteFactory),
+                        reinterpret_cast<IUnknown**>(&result));
+    }
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+/* IUnknown */
+JNIEXPORT jint JNICALL OS_NATIVE(AddRef)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return ((IUnknown *)arg0)->AddRef();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(Release)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return ((IUnknown *)arg0)->Release();
+}
+
+/***********************************************/
+/*         Text Source and Sink                */
+/***********************************************/
+
+class JFXTextAnalysisSink : public IDWriteTextAnalysisSink, public IDWriteTextAnalysisSource {
+public:
+    JFXTextAnalysisSink(
+        JNIEnv *env,
+        jcharArray text,
+        jint start,
+        jint length,
+        jcharArray locale,
+        jint direction,
+        jlong numberSubstitution
+    );
+    ~JFXTextAnalysisSink();
+
+/* IDWriteTextAnalysisSink */
+public:
+    IFACEMETHOD (SetScriptAnalysis) (
+        UINT32 textPosition,
+        UINT32 textLength,
+        DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis);
+
+    IFACEMETHOD (SetLineBreakpoints) (
+        UINT32 textPosition,
+        UINT32 textLength,
+        const DWRITE_LINE_BREAKPOINT* lineBreakpoints);
+
+    IFACEMETHOD (SetBidiLevel) (
+        UINT32 textPosition,
+        UINT32 textLength,
+        UINT8 explicitLevel,
+        UINT8 resolvedLevel);
+
+    IFACEMETHOD (SetNumberSubstitution) (
+        UINT32 textPosition,
+        UINT32 textLength,
+        IDWriteNumberSubstitution* numberSubstitution);
+
+/* IDWriteTextAnalysisSource */
+    IFACEMETHOD (GetTextAtPosition) (
+        UINT32 textPosition,
+        OUT WCHAR const** textString,
+        OUT UINT32* textLength);
+
+    IFACEMETHOD (GetTextBeforePosition) (
+        UINT32 textPosition,
+        OUT WCHAR const** textString,
+        OUT UINT32* textLength);
+
+    IFACEMETHOD_(DWRITE_READING_DIRECTION, GetParagraphReadingDirection) ();
+
+    IFACEMETHOD (GetLocaleName) (
+        UINT32 textPosition,
+        OUT UINT32* textLength,
+        OUT WCHAR const** localeName);
+
+    IFACEMETHOD (GetNumberSubstitution) (
+        UINT32 textPosition,
+        OUT UINT32* textLength,
+        OUT IDWriteNumberSubstitution** numberSubstitution);
+
+/* IUnknown */
+public:
+    IFACEMETHOD_(ULONG, AddRef) ();
+    IFACEMETHOD_(ULONG,  Release) ();
+    IFACEMETHOD(QueryInterface) (
+                IID const& riid,
+                void** ppvObject);
+
+public:
+    BOOL Next();
+    UINT32 GetStart();
+    UINT32 GetLength();
+    DWRITE_SCRIPT_ANALYSIS* GetAnalysis();
+
+private:
+    struct Run {
+        UINT32 start;
+        UINT32 length;
+        DWRITE_SCRIPT_ANALYSIS analysis;
+    };
+    ULONG cRefCount_;
+    UINT32 textLength_;
+    const WCHAR* text_;
+    const WCHAR* locale_;
+    IDWriteNumberSubstitution* numberSubstitution_;
+    DWRITE_READING_DIRECTION readingDirection_;
+    std::vector<Run> runs_;
+    INT32 position_;
+};
+
+JFXTextAnalysisSink::JFXTextAnalysisSink(
+        JNIEnv *env,
+        jcharArray text,
+        jint start,
+        jint length,
+        jcharArray locale,
+        jint direction,
+        jlong numberSubstitution
+    )
+:   cRefCount_(0),
+    position_(-1),
+    textLength_(length),
+    numberSubstitution_((IDWriteNumberSubstitution*)numberSubstitution),
+    readingDirection_((DWRITE_READING_DIRECTION)direction)
+{
+    text_ = new (std::nothrow) WCHAR [textLength_];
+    env->GetCharArrayRegion(text, start, textLength_, (jchar*)text_);
+    UINT32 localeLength = env->GetArrayLength(locale);
+    locale_ = new (std::nothrow) WCHAR [localeLength];
+    env->GetCharArrayRegion(locale, 0, localeLength, (jchar*)locale_);
+    if (numberSubstitution_) numberSubstitution_->AddRef();
+}
+
+JFXTextAnalysisSink::~JFXTextAnalysisSink() {
+    delete [] text_;
+    delete [] locale_;
+    if (numberSubstitution_) {
+        numberSubstitution_->Release();
+    }
+    text_ = NULL;
+    locale_ = NULL;
+    numberSubstitution_ = NULL;
+}
+
+/* IDWriteTextAnalysisSink */
+IFACEMETHODIMP JFXTextAnalysisSink::SetScriptAnalysis(
+    UINT32 textPosition,
+    UINT32 textLength,
+    DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) {
+    runs_.resize(runs_.size() + 1);
+    Run& run  = runs_.back();
+    run.start = textPosition;
+    run.length = textLength;
+    run.analysis = *scriptAnalysis;
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextAnalysisSink::SetLineBreakpoints(
+    UINT32 textPosition,
+    UINT32 textLength,
+    const DWRITE_LINE_BREAKPOINT* lineBreakpoints) {
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextAnalysisSink::SetBidiLevel(
+    UINT32 textPosition,
+    UINT32 textLength,
+    UINT8 explicitLevel,
+    UINT8 resolvedLevel) {
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextAnalysisSink::SetNumberSubstitution(
+    UINT32 textPosition,
+    UINT32 textLength,
+    IDWriteNumberSubstitution* numberSubstitution) {
+    return S_OK;
+}
+
+/* IDWriteTextAnalysisSource */
+IFACEMETHODIMP JFXTextAnalysisSink::GetTextAtPosition(
+    UINT32 textPosition,
+    WCHAR const** textString,
+    UINT32* textLength) {
+    if (textPosition < textLength_) {
+        *textString = &text_[textPosition];
+        *textLength = textLength_ - textPosition;
+    } else {
+        *textString = NULL;
+        *textLength = 0;
+    }
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextAnalysisSink::GetTextBeforePosition(
+    UINT32 textPosition,
+    OUT WCHAR const** textString,
+    OUT UINT32* textLength) {
+    if (textPosition == 0 || textPosition > textLength_) {
+        *textString = NULL;
+        *textLength = 0;
+    } else {
+        *textString = text_;
+        *textLength = textPosition;
+    }
+    return S_OK;
+}
+
+IFACEMETHODIMP_(DWRITE_READING_DIRECTION) JFXTextAnalysisSink::GetParagraphReadingDirection() {
+    return readingDirection_;
+}
+
+IFACEMETHODIMP JFXTextAnalysisSink::GetLocaleName(
+    UINT32 textPosition,
+    OUT UINT32* textLength,
+    OUT WCHAR const** localeName) {
+    fflush(stdout);
+    *localeName = locale_;
+    *textLength = textLength_ - textPosition;
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextAnalysisSink::GetNumberSubstitution(
+    UINT32 textPosition,
+    OUT UINT32* textLength,
+    OUT IDWriteNumberSubstitution** numberSubstitution) {
+    
+    if (numberSubstitution_ != NULL)
+        numberSubstitution_->AddRef();
+
+    *numberSubstitution = numberSubstitution_;
+    *textLength = textLength_ - textPosition;
+
+    return S_OK;
+}
+
+BOOL JFXTextAnalysisSink::Next() {
+    position_++;
+    return ((UINT32)position_) < runs_.size();
+}
+
+UINT32 JFXTextAnalysisSink::GetStart() {
+    return runs_[position_].start;
+}
+
+UINT32 JFXTextAnalysisSink::GetLength() {
+    return runs_[position_].length;
+}
+
+DWRITE_SCRIPT_ANALYSIS* JFXTextAnalysisSink::GetAnalysis() {
+    return &runs_[position_].analysis;
+}
+
+/* IUnknown */
+IFACEMETHODIMP_(ULONG) JFXTextAnalysisSink::AddRef() {
+    return InterlockedIncrement(&cRefCount_);
+}
+
+IFACEMETHODIMP_(ULONG) JFXTextAnalysisSink::Release() {
+    ULONG newCount = InterlockedDecrement(&cRefCount_);
+    if (newCount == 0) {
+        delete this;
+        return 0;
+    }
+    return newCount;
+}
+
+IFACEMETHODIMP JFXTextAnalysisSink::QueryInterface(IID const& riid, void** ppvObject) {
+    if (__uuidof(IDWriteTextAnalysisSink) == riid) {
+        *ppvObject = this;
+    } else if (__uuidof(IDWriteTextAnalysisSource) == riid) {
+        *ppvObject = this;
+    } else if (__uuidof(IUnknown) == riid) {
+        *ppvObject = this;
+    } else {
+        *ppvObject = NULL;
+        return E_FAIL;
+    }
+    this->AddRef();
+    return S_OK;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(_1NewJFXTextAnalysisSink)
+(JNIEnv *env, jclass that, jcharArray arg0, jint arg1, jint arg2, jcharArray arg3, jint arg4, jlong arg5)
+{
+    if (arg0 == NULL || arg3 == NULL) return 0L;
+    return (jlong) new (std::nothrow) JFXTextAnalysisSink(env, arg0, arg1, arg2, arg3, arg4, arg5);
+}
+
+JNIEXPORT jboolean JNICALL OS_NATIVE(Next)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return ((JFXTextAnalysisSink*)arg0)->Next();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetStart)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return ((JFXTextAnalysisSink*)arg0)->GetStart();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetLength)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return ((JFXTextAnalysisSink*)arg0)->GetLength();
+}
+
+JNIEXPORT jobject JNICALL OS_NATIVE(GetAnalysis)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return newDWRITE_SCRIPT_ANALYSIS(env, ((JFXTextAnalysisSink*)arg0)->GetAnalysis());
+}
+
+/***********************************************/
+/*                Text Renderer                */
+/***********************************************/
+
+class JFXTextRenderer : public IDWriteTextRenderer
+{
+public:
+    JFXTextRenderer();
+    ~JFXTextRenderer();
+
+/* IDWriteTextRenderer */
+public:
+    IFACEMETHOD(DrawGlyphRun)(
+        void* clientDrawingContext,
+        FLOAT baselineOriginX,
+        FLOAT baselineOriginY,
+        DWRITE_MEASURING_MODE measuringMode,
+        DWRITE_GLYPH_RUN const* glyphRun,
+        DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
+        IUnknown* clientDrawingEffect);
+
+    IFACEMETHOD(DrawUnderline)(
+        void* clientDrawingContext,
+        FLOAT baselineOriginX,
+        FLOAT baselineOriginY,
+        DWRITE_UNDERLINE const* underline,
+        IUnknown* clientDrawingEffect);
+
+    IFACEMETHOD(DrawStrikethrough)(
+        void* clientDrawingContext,
+        FLOAT baselineOriginX,
+        FLOAT baselineOriginY,
+        DWRITE_STRIKETHROUGH const* strikethrough,
+        IUnknown* clientDrawingEffect);
+
+    IFACEMETHOD(DrawInlineObject)(
+        void* clientDrawingContext,
+        FLOAT originX,
+        FLOAT originY,
+        IDWriteInlineObject* inlineObject,
+        BOOL isSideways,
+        BOOL isRightToLeft,
+        IUnknown* clientDrawingEffect);
+
+/* IDWritePixelSnapping */
+public:
+    IFACEMETHOD(IsPixelSnappingDisabled)(
+        void* clientDrawingContext,
+        BOOL* isDisabled);
+
+    IFACEMETHOD(GetCurrentTransform)(
+        void* clientDrawingContext,
+        DWRITE_MATRIX* transform);
+
+    IFACEMETHOD(GetPixelsPerDip)(
+        void* clientDrawingContext,
+        FLOAT* pixelsPerDip);
+
+/* IUnknown */
+public:
+    IFACEMETHOD_(ULONG, AddRef) ();
+    IFACEMETHOD_(ULONG,  Release) ();
+    IFACEMETHOD(QueryInterface) (
+                IID const& riid,
+                void** ppvObject);
+
+public:
+    BOOL Next();
+    UINT32 GetStart();
+    UINT32 GetLength();
+    UINT32 GetGlyphCount();
+    UINT32 GetTotalGlyphCount();
+    IDWriteFontFace* GetFontFace();
+    const UINT16* GetClusterMap();
+    const UINT16* GetGlyphIndices();
+    const FLOAT*  GetGlyphAdvances();
+
+private:
+    ULONG cRefCount_;
+    struct Run {
+        DWRITE_GLYPH_RUN glyphRun;
+        DWRITE_GLYPH_RUN_DESCRIPTION glyphRunDescription;
+    };
+    std::vector<Run> runs_;
+    INT32 position_;
+    INT32 totalGlyphCount_;
+};
+
+JFXTextRenderer::JFXTextRenderer()
+: cRefCount_(0),
+  position_(-1),
+  totalGlyphCount_(0) {
+}
+
+JFXTextRenderer::~JFXTextRenderer() {
+}
+
+/* IDWriteTextRenderer */
+IFACEMETHODIMP JFXTextRenderer::DrawGlyphRun (
+        void* clientDrawingContext,
+        FLOAT baselineOriginX,
+        FLOAT baselineOriginY,
+        DWRITE_MEASURING_MODE measuringMode,
+        DWRITE_GLYPH_RUN const* glyphRun,
+        DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
+        IUnknown* clientDrawingEffect)
+{
+    runs_.resize(runs_.size() + 1);
+    Run& run  = runs_.back();
+    run.glyphRun = *glyphRun;
+    run.glyphRunDescription = *glyphRunDescription;
+    totalGlyphCount_ += glyphRun->glyphCount;
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextRenderer::DrawUnderline (
+        void* clientDrawingContext,
+        FLOAT baselineOriginX,
+        FLOAT baselineOriginY,
+        DWRITE_UNDERLINE const* underline,
+        IUnknown* clientDrawingEffect)
+{
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextRenderer::DrawStrikethrough (
+        void* clientDrawingContext,
+        FLOAT baselineOriginX,
+        FLOAT baselineOriginY,
+        DWRITE_STRIKETHROUGH const* strikethrough,
+        IUnknown* clientDrawingEffect)
+{
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextRenderer::DrawInlineObject (
+        void* clientDrawingContext,
+        FLOAT originX,
+        FLOAT originY,
+        IDWriteInlineObject* inlineObject,
+        BOOL isSideways,
+        BOOL isRightToLeft,
+        IUnknown* clientDrawingEffect)
+{
+    return S_OK;
+}
+
+/* IDWritePixelSnapping */
+IFACEMETHODIMP JFXTextRenderer::IsPixelSnappingDisabled (
+        void* clientDrawingContext,
+        BOOL* isDisabled)
+{
+    *isDisabled = FALSE;
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextRenderer::GetCurrentTransform (
+        void* clientDrawingContext,
+        DWRITE_MATRIX* transform)
+{
+    const DWRITE_MATRIX ident = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
+    *transform = ident;
+    return S_OK;
+}
+
+IFACEMETHODIMP JFXTextRenderer::GetPixelsPerDip (
+        void* clientDrawingContext,
+        FLOAT* pixelsPerDip)
+{
+    *pixelsPerDip = 1.0f;
+    return S_OK;
+}
+
+/* IUnknown */
+IFACEMETHODIMP_(ULONG) JFXTextRenderer::AddRef() {
+    return InterlockedIncrement(&cRefCount_);
+}
+
+IFACEMETHODIMP_(ULONG) JFXTextRenderer::Release() {
+    ULONG newCount = InterlockedDecrement(&cRefCount_);
+    if (newCount == 0) {
+        delete this;
+        return 0;
+    }
+    return newCount;
+}
+
+IFACEMETHODIMP JFXTextRenderer::QueryInterface(IID const& riid, void** ppvObject) {
+    if (__uuidof(IDWriteTextRenderer) == riid) {
+        *ppvObject = this;
+    } else if (__uuidof(IDWritePixelSnapping) == riid) {
+        *ppvObject = this;
+    } else if (__uuidof(IUnknown) == riid) {
+        *ppvObject = this;
+    } else {
+        *ppvObject = NULL;
+        return E_FAIL;
+    }
+    this->AddRef();
+    return S_OK;
+}
+
+BOOL JFXTextRenderer::Next() {
+    position_++;
+    return ((UINT32)position_) < runs_.size();
+}
+
+UINT32 JFXTextRenderer::GetStart() {
+    return runs_[position_].glyphRunDescription.textPosition;
+}
+
+UINT32 JFXTextRenderer::GetLength() {
+    return runs_[position_].glyphRunDescription.stringLength;
+}
+
+UINT32 JFXTextRenderer::GetGlyphCount() {
+    return runs_[position_].glyphRun.glyphCount;
+}
+
+UINT32 JFXTextRenderer::GetTotalGlyphCount() {
+    return totalGlyphCount_;
+}
+
+IDWriteFontFace* JFXTextRenderer::GetFontFace() {
+    return runs_[position_].glyphRun.fontFace;
+}
+
+const FLOAT* JFXTextRenderer::GetGlyphAdvances() {
+    return runs_[position_].glyphRun.glyphAdvances;
+}
+
+const UINT16* JFXTextRenderer::GetGlyphIndices() {
+    return runs_[position_].glyphRun.glyphIndices;
+}
+
+const UINT16* JFXTextRenderer::GetClusterMap() {
+    return runs_[position_].glyphRunDescription.clusterMap;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(_1NewJFXTextRenderer)
+(JNIEnv *env, jclass that)
+{
+    return (jlong) new (std::nothrow) JFXTextRenderer();
+}
+
+JNIEXPORT jboolean JNICALL OS_NATIVE(JFXTextRendererNext)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return ((JFXTextRenderer*)arg0)->Next();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(JFXTextRendererGetStart)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return ((JFXTextRenderer*)arg0)->GetStart();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(JFXTextRendererGetLength)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return ((JFXTextRenderer*)arg0)->GetLength();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(JFXTextRendererGetGlyphCount)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return ((JFXTextRenderer*)arg0)->GetGlyphCount();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(JFXTextRendererGetTotalGlyphCount)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return ((JFXTextRenderer*)arg0)->GetTotalGlyphCount();
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(JFXTextRendererGetFontFace)
+(JNIEnv *env, jclass that, jlong arg0) {
+    return (jlong)((JFXTextRenderer*)arg0)->GetFontFace();
+}
+
+JNIEXPORT jintArray JNICALL OS_NATIVE(JFXTextRendererGetGlyphIndices__J)
+(JNIEnv *env, jclass that, jlong arg0) {
+    JFXTextRenderer* renderer = (JFXTextRenderer*)arg0;
+    UINT32 length = renderer->GetGlyphCount();
+    jintArray result = env->NewIntArray(length);
+    if (!result) return NULL;
+    jint* data = env->GetIntArrayElements(result, NULL);
+    if (!data) return NULL;
+    const UINT16* indices = renderer->GetGlyphIndices();
+    UINT32 i;
+    for (i = 0; i < length; i++) {
+        data[i] = indices[i];
+    }
+    env->ReleaseIntArrayElements(result, data, NULL);
+    return result;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(JFXTextRendererGetGlyphIndices__J_3III)
+(JNIEnv *env, jclass that, jlong arg0, jintArray arg1, jint start, jint slot) {
+    if (!arg1) return 0;
+    jint* data = env->GetIntArrayElements(arg1, NULL);
+    if (!data) return 0;
+
+    JFXTextRenderer* renderer = (JFXTextRenderer*)arg0;
+    UINT32 glyphCount = renderer->GetGlyphCount();
+    UINT32 length = env->GetArrayLength(arg1);
+    UINT32 copiedCount = length - start > glyphCount ? glyphCount : length - start;
+
+    const UINT16* indices = renderer->GetGlyphIndices();
+    UINT32 i;
+    for (i = 0; i < copiedCount; i++) {
+        data[i + start] = (indices[i] | slot);
+    }
+    env->ReleaseIntArrayElements(arg1, data, NULL);
+    return copiedCount;
+}
+
+JNIEXPORT jfloatArray JNICALL OS_NATIVE(JFXTextRendererGetGlyphAdvances__J)
+(JNIEnv *env, jclass that, jlong arg0) {
+    JFXTextRenderer* renderer = (JFXTextRenderer*)arg0;
+    UINT32 length = renderer->GetGlyphCount();
+    jfloatArray result = env->NewFloatArray(length);
+    if (!result) return NULL;
+    jfloat* data = env->GetFloatArrayElements(result, NULL);
+    if (!data) return NULL;
+    const FLOAT* advances = renderer->GetGlyphAdvances();
+    UINT32 i;
+    for (i = 0; i < length; i++) {
+        data[i] = advances[i];
+    }
+    env->ReleaseFloatArrayElements(result, data, NULL);
+    return result;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(JFXTextRendererGetGlyphAdvances__J_3FI)
+(JNIEnv *env, jclass that, jlong arg0, jfloatArray arg1, jint start) {
+    if (!arg1) return 0;
+    jfloat* data = env->GetFloatArrayElements(arg1, NULL);
+    if (!data) return 0;
+
+    JFXTextRenderer* renderer = (JFXTextRenderer*)arg0;
+    UINT32 glyphCount = renderer->GetGlyphCount();
+    UINT32 length = env->GetArrayLength(arg1);
+    UINT32 copiedCount = length - start > glyphCount ? glyphCount : length - start;
+
+    const FLOAT* advances = renderer->GetGlyphAdvances();
+    UINT32 i;
+    for (i = 0; i < copiedCount; i++) {
+        data[i + start] = advances[i];
+    }
+    env->ReleaseFloatArrayElements(arg1, data, NULL);
+    return copiedCount;
+}
+
+JNIEXPORT jintArray JNICALL OS_NATIVE(JFXTextRendererGetClusterMap__J)
+(JNIEnv *env, jclass that, jlong arg0) {
+    JFXTextRenderer* renderer = (JFXTextRenderer*)arg0;
+    UINT32 length = renderer->GetLength();
+    jintArray result = env->NewIntArray(length);
+    if (!result) return NULL;
+    jint* data = env->GetIntArrayElements(result, NULL);
+    if (!data) return NULL;
+    const UINT16* map = renderer->GetClusterMap();
+    UINT32 i;
+    for (i = 0; i < length; i++) {
+        data[i] = map[i];
+    }
+    env->ReleaseIntArrayElements(result, data, NULL);
+    return result;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(JFXTextRendererGetClusterMap__J_3II)
+(JNIEnv *env, jclass that, jlong arg0, jintArray arg1, jint start) {
+    if (!arg1) return 0;
+    jint* data = env->GetIntArrayElements(arg1, NULL);
+    if (!data) return 0;
+
+    JFXTextRenderer* renderer = (JFXTextRenderer*)arg0;
+    UINT32 textLength = renderer->GetLength();
+    UINT32 length = env->GetArrayLength(arg1);
+    UINT32 copiedCount = length - start > textLength ? textLength : length - start;
+
+    const UINT16* map = renderer->GetClusterMap();
+    UINT32 i;
+    /* Adding start to the result as in Java it needs the cluster map
+     * relative to start of the TextRun and the cluster map computed
+     * by DirectWrite has it relative to the DWRITE_GLYPH_RUN.
+     */
+    for (i = 0; i < copiedCount; i++) {
+        data[i + start] = map[i] + start;
+    }
+    env->ReleaseIntArrayElements(arg1, data, NULL);
+    return copiedCount;
+}
+
+/***********************************************/
+/*                Glyph Outline                */
+/***********************************************/
+
+class JFXGeometrySink : public IDWriteGeometrySink {
+public:
+    JFXGeometrySink();
+    ~JFXGeometrySink();
+    int numTypes();
+    int numCoords();
+    jbyte* types();
+    jfloat* coords();
+
+/* IDWriteGeometrySink */
+public:
+    IFACEMETHOD_(void, SetFillMode)(
+        D2D1_FILL_MODE fillMode);
+
+    IFACEMETHOD_(void, SetSegmentFlags)(
+        D2D1_PATH_SEGMENT vertexFlags);
+
+    IFACEMETHOD_(void, BeginFigure)(
+        D2D1_POINT_2F startPoint,
+        D2D1_FIGURE_BEGIN figureBegin);
+
+    IFACEMETHOD_(void, AddLines)(
+        CONST D2D1_POINT_2F *points,
+        UINT32 pointsCount);
+
+    IFACEMETHOD_(void, AddBeziers)(
+        CONST D2D1_BEZIER_SEGMENT *beziers,
+        UINT32 beziersCount);
+
+    IFACEMETHOD_(void, EndFigure)(
+        D2D1_FIGURE_END figureEnd);
+
+    IFACEMETHOD(Close)();
+
+/* IUnknown */
+public:
+    IFACEMETHOD_(ULONG, AddRef) ();
+    IFACEMETHOD_(ULONG, Release) ();
+    IFACEMETHOD(QueryInterface) (
+        IID const& riid,
+        void** ppvObject
+    );
+
+private:
+    ULONG cRefCount_;
+    std::vector<jbyte> vtypes_;
+    std::vector<jfloat> vcoords_;
+};
+
+JFXGeometrySink::JFXGeometrySink()
+: cRefCount_(0) {
+}
+
+JFXGeometrySink::~JFXGeometrySink() {
+}
+
+int JFXGeometrySink::numTypes() {
+    return vtypes_.size();
+}
+
+int JFXGeometrySink::numCoords() {
+    return vcoords_.size();
+}
+
+jbyte* JFXGeometrySink::types() {
+    return vtypes_.data();
+}
+
+jfloat* JFXGeometrySink::coords() {
+    return vcoords_.data();
+}
+
+/* IDWriteGeometrySink */
+IFACEMETHODIMP_(void) JFXGeometrySink::SetFillMode(D2D1_FILL_MODE fillMode) {
+    /* ignored */
+}
+
+IFACEMETHODIMP_(void) JFXGeometrySink::SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags) {
+    /* ignored */
+}
+
+IFACEMETHODIMP_(void) JFXGeometrySink::BeginFigure(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin) {
+    /* Handle as move to point, ignore figureBegin (hollow/filled) */
+    vtypes_.push_back(0);
+    vcoords_.push_back(startPoint.x);
+    vcoords_.push_back(startPoint.y);
+}
+
+IFACEMETHODIMP_(void) JFXGeometrySink::AddLines(CONST D2D1_POINT_2F *points, UINT32 pointsCount) {
+    UINT i;
+    for (i = 0; i < pointsCount; i++) {
+        D2D1_POINT_2F pt = points[i];
+        vtypes_.push_back(1);
+        vcoords_.push_back(pt.x);
+        vcoords_.push_back(pt.y);
+    }
+}
+
+IFACEMETHODIMP_(void) JFXGeometrySink::AddBeziers(CONST D2D1_BEZIER_SEGMENT *beziers, UINT32 beziersCount) {
+    UINT i;
+    for (i = 0; i < beziersCount; i++) {
+        /* The API for simplified geometry sink does not have quad bezier curve (type2),
+         * which I suspect is done using cubic bezier with point1==point2 */
+        D2D1_BEZIER_SEGMENT b = beziers[i];
+        vtypes_.push_back(3);
+        vcoords_.push_back(b.point1.x);
+        vcoords_.push_back(b.point1.y);
+        vcoords_.push_back(b.point2.x);
+        vcoords_.push_back(b.point2.y);
+        vcoords_.push_back(b.point3.x);
+        vcoords_.push_back(b.point3.y);
+    }
+}
+
+IFACEMETHODIMP_(void) JFXGeometrySink::EndFigure (D2D1_FIGURE_END figureEnd) {
+    /* Handle as close subpath */
+    vtypes_.push_back(4);
+}
+
+IFACEMETHODIMP JFXGeometrySink::Close () {
+    /* should close the sink and check figure beging == figure end but this impl expects the user to be good */
+    return S_OK;
+}
+
+/* IUnknown */
+IFACEMETHODIMP_(ULONG) JFXGeometrySink::AddRef() {
+    return InterlockedIncrement(&cRefCount_);
+}
+
+IFACEMETHODIMP_(ULONG) JFXGeometrySink::Release() {
+    ULONG newCount = InterlockedDecrement(&cRefCount_);
+    if (newCount == 0) {
+        delete this;
+        return 0;
+    }
+    return newCount;
+}
+
+IFACEMETHODIMP JFXGeometrySink::QueryInterface(IID const& riid, void** ppvObject) {
+    if (__uuidof(IDWriteGeometrySink) == riid) {
+        *ppvObject = this;
+    } else if (__uuidof(ID2D1SimplifiedGeometrySink) == riid) {
+        *ppvObject = this;
+    } else if (__uuidof(IUnknown) == riid) {
+        *ppvObject = this;
+    } else {
+        *ppvObject = NULL;
+        return E_FAIL;
+    }
+    this->AddRef();
+    return S_OK;
+}
+
+/* IDWriteFontFace */
+jclass path2DClass = NULL;
+jmethodID path2DCtr = NULL;
+JNIEXPORT jobject JNICALL OS_NATIVE(GetGlyphRunOutline)
+    (JNIEnv *env, jclass that, jlong arg0, jfloat arg1, jshort arg2, jboolean arg3)
+{
+    HRESULT hr = E_FAIL;
+    jobject result = NULL;
+    const UINT32  glyphCount = 1;
+    const UINT16 glyphIndices[glyphCount] = {arg2};
+    JFXGeometrySink* sink = new (std::nothrow) JFXGeometrySink();
+
+    hr = ((IDWriteFontFace *)arg0)->GetGlyphRunOutline(arg1, glyphIndices, NULL, NULL, glyphCount, arg3, FALSE, sink);
+
+    if (SUCCEEDED(hr)) {
+        if (path2DClass == NULL) {
+            jclass tmpClass = env->FindClass("com/sun/javafx/geom/Path2D");
+            path2DClass = (jclass)env->NewGlobalRef(tmpClass);
+            path2DCtr = env->GetMethodID(path2DClass, "<init>", "(I[BI[FI)V");
+        }
+
+        jbyteArray types = env->NewByteArray(sink->numTypes());
+        jfloatArray coords = env->NewFloatArray(sink->numCoords());
+        if (types && coords) {
+            env->SetByteArrayRegion(types, 0, sink->numTypes(), sink->types());
+            env->SetFloatArrayRegion(coords, 0, sink->numCoords(), sink->coords());
+            result = env->NewObject(path2DClass, path2DCtr,
+                                    0 /*winding rule*/,
+                                    types, sink->numTypes(),
+                                    coords, sink->numCoords());
+          }
+    }
+    delete sink;
+    return result;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetType)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return ((IDWriteFontFace *)arg0)->GetType();
+}
+
+JNIEXPORT jobject JNICALL OS_NATIVE(GetDesignGlyphMetrics)
+    (JNIEnv *env, jclass that, jlong arg0, jshort arg1, jboolean arg2)
+{
+    HRESULT hr = E_FAIL;
+    jobject result = NULL;
+    const UINT32  glyphCount = 1;
+    const UINT16 glyphIndices[glyphCount] = {arg1};
+    DWRITE_GLYPH_METRICS glyphMetrics[glyphCount];
+
+    hr = ((IDWriteFontFace *)arg0)->GetDesignGlyphMetrics(glyphIndices, glyphCount, glyphMetrics, arg2);
+    if (SUCCEEDED(hr)) {
+        result = newDWRITE_GLYPH_METRICS(env, &glyphMetrics[0]);
+    }
+    return result;
+}
+
+JNIEXPORT jshortArray JNICALL OS_NATIVE(GetGlyphIndices)
+    (JNIEnv *env, jclass that, jlong arg0, jintArray arg1, jint arg2)
+{
+    HRESULT hr = E_FAIL;
+    jint *lparg1 = NULL;
+    jshortArray result = NULL;
+    UINT16* buffer = new (std::nothrow) UINT16 [arg2];
+    if (arg1) if ((lparg1 = env->GetIntArrayElements(arg1, NULL)) == NULL) goto fail;
+    hr = ((IDWriteFontFace *)arg0)->GetGlyphIndices((const UINT32 *) lparg1, arg2, buffer);
+fail:
+    if (arg1 && lparg1) env->ReleaseIntArrayElements(arg1, lparg1, 0);
+    if (SUCCEEDED(hr)) {
+        result = env->NewShortArray(arg2);
+        if (result) {
+            env->SetShortArrayRegion(result, 0, arg2, (const short*)buffer);
+        }
+    }
+    delete [] buffer;
+    return result;
+}
+
+/* IDWriteFactory */
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateTextAnalyzer)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    IDWriteTextAnalyzer* result = NULL;
+    HRESULT hr = ((IDWriteFactory *)arg0)->CreateTextAnalyzer(&result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateTextFormat)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1, jlong arg2, jint arg3,
+    jint arg4, jint arg5, jfloat arg6, jcharArray arg7)
+{
+    HRESULT hr = E_FAIL;
+    IDWriteTextFormat* result = NULL;
+    jchar *lparg1 = NULL;
+    jchar *lparg7 = NULL;
+    if (arg1) if ((lparg1 = env->GetCharArrayElements(arg1, NULL)) == NULL) goto fail;
+    if (arg7) if ((lparg7 = env->GetCharArrayElements(arg7, NULL)) == NULL) goto fail;
+    hr = ((IDWriteFactory *)arg0)->CreateTextFormat((const WCHAR *)lparg1,
+                                                    (IDWriteFontCollection *)arg2,
+                                                    (DWRITE_FONT_WEIGHT)arg3,
+                                                    (DWRITE_FONT_STYLE)arg4,
+                                                    (DWRITE_FONT_STRETCH)arg5,
+                                                    arg6,
+                                                    (const WCHAR *)lparg7,
+                                                    &result);
+fail:
+    if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
+    if (arg7 && lparg7) env->ReleaseCharArrayElements(arg7, lparg7, 0);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateFontFileReference)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1)
+{
+    HRESULT hr = E_FAIL;
+    IDWriteFontFile* result = NULL;
+    jchar *lparg1 = NULL;
+    if (arg1) if ((lparg1 = env->GetCharArrayElements(arg1, NULL)) == NULL) goto fail;
+    hr = ((IDWriteFactory *)arg0)->CreateFontFileReference((const WCHAR *)lparg1, NULL, &result);
+fail:
+    if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateFontFace__JIIJII)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2, jlong arg3, jint arg4, jint arg5)
+{
+    IDWriteFontFace* result = NULL;
+    if (arg2 != 1) return NULL;
+    IDWriteFontFile* fontFileArray[] = {(IDWriteFontFile*)arg3};
+    HRESULT hr = ((IDWriteFactory *)arg0)->CreateFontFace((DWRITE_FONT_FACE_TYPE)arg1,
+                                                          (UINT32)arg2,
+                                                          fontFileArray,
+                                                          (UINT32)arg4,
+                                                          (DWRITE_FONT_SIMULATIONS)arg5,
+                                                          &result);
+
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateTextLayout)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1, jint arg2, jint arg3, jlong arg4,
+    jfloat arg5, jfloat arg6)
+{
+    HRESULT hr = E_FAIL;
+    IDWriteTextLayout* result = NULL;
+    jchar *lparg1 = NULL;
+    if (arg1) if ((lparg1 = env->GetCharArrayElements(arg1, NULL)) == NULL) goto fail;
+    const WCHAR * text = (const WCHAR *)(lparg1 + arg2);
+
+    hr = ((IDWriteFactory *)arg0)->CreateTextLayout(text,
+                                                    (UINT32)arg3,
+                                                    (IDWriteTextFormat *)arg4,
+                                                    (FLOAT)arg5,
+                                                    (FLOAT)arg6,
+                                                    &result);
+fail:
+    if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
+
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(GetSystemFontCollection)
+    (JNIEnv *env, jclass that, jlong arg0, jboolean arg1)
+{
+    IDWriteFontCollection* result = NULL;
+    HRESULT hr = ((IDWriteFactory *)arg0)->GetSystemFontCollection(&result, arg1);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateGlyphRunAnalysis)
+    (JNIEnv *env, jclass that, jlong arg0, jobject arg1, jfloat arg2, jobject arg3, jint arg4, jint arg5, jfloat arg6, jfloat arg7)
+{
+    HRESULT hr = E_FAIL;
+    IDWriteGlyphRunAnalysis* result = NULL;
+    DWRITE_GLYPH_RUN _arg1, *lparg1 = NULL;
+    DWRITE_MATRIX _arg3, *lparg3 = NULL;
+    _arg1.glyphIndices = new (std::nothrow) UINT16 [1];
+    _arg1.glyphAdvances = new (std::nothrow) FLOAT [1];
+
+    /* In Only */
+    if (arg1) if ((lparg1 = getDWRITE_GLYPH_RUNFields(env, arg1, &_arg1)) == NULL) goto fail;
+    if (arg3) if ((lparg3 = getDWRITE_MATRIXFields(env, arg3, &_arg3)) == NULL) goto fail;
+    hr = ((IDWriteFactory *)arg0)->CreateGlyphRunAnalysis(lparg1,
+                                                          (FLOAT)arg2,
+                                                          lparg3,
+                                                          (DWRITE_RENDERING_MODE)arg4,
+                                                          (DWRITE_MEASURING_MODE)arg5,
+                                                          (FLOAT)arg6,
+                                                          (FLOAT)arg7,
+                                                          &result);
+
+fail:
+    delete [] _arg1.glyphIndices;
+    delete [] _arg1.glyphAdvances;
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+/* IDWriteFontFile */
+JNIEXPORT jint JNICALL OS_NATIVE(Analyze)
+    (JNIEnv *env, jclass that, jlong arg0, jbooleanArray arg1, jintArray arg2, jintArray arg3, jintArray arg4)
+{
+    HRESULT hr = E_FAIL;
+    jboolean *lparg1 = NULL;
+    jint *lparg2 = NULL;
+    jint *lparg3 = NULL;
+    jint *lparg4 = NULL;
+
+    if (arg1) if ((lparg1 = env->GetBooleanArrayElements(arg1, NULL)) == NULL) goto fail;
+    if (arg2) if ((lparg2 = env->GetIntArrayElements(arg2, NULL)) == NULL) goto fail;
+    if (arg3) lparg3 = env->GetIntArrayElements(arg3, NULL); /* Optional */
+    if (arg4) if ((lparg4 = env->GetIntArrayElements(arg4, NULL)) == NULL) goto fail;
+
+    hr = ((IDWriteFontFile *)arg0)->Analyze((BOOL *)lparg1,
+                                            (DWRITE_FONT_FILE_TYPE *)lparg2,
+                                            (DWRITE_FONT_FACE_TYPE *)lparg3,
+                                            (UINT32 *)lparg4);
+fail:
+    if (arg1 && lparg1) env->ReleaseBooleanArrayElements(arg1, lparg1, 0);
+    if (arg2 && lparg2) env->ReleaseIntArrayElements(arg2, lparg2, 0);
+    if (arg3 && lparg3) env->ReleaseIntArrayElements(arg3, lparg3, 0);
+    if (arg4 && lparg4) env->ReleaseIntArrayElements(arg4, lparg4, 0);
+    return hr;
+}
+
+/* IDWriteFont */
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateFontFace__J)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    IDWriteFontFace* result = NULL;
+    HRESULT hr = ((IDWriteFont *)arg0)->CreateFontFace(&result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(GetFaceNames)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    IDWriteLocalizedStrings* result = NULL;
+    HRESULT hr = ((IDWriteFont *)arg0)->GetFaceNames(&result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(GetFontFamily__J)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    IDWriteFontFamily* result = NULL;
+    HRESULT hr = ((IDWriteFont *)arg0)->GetFontFamily(&result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetStretch)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jint)((IDWriteFont *)arg0)->GetStretch();
+}
+JNIEXPORT jint JNICALL OS_NATIVE(GetStyle)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jint)((IDWriteFont *)arg0)->GetStyle();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetWeight)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jint)((IDWriteFont *)arg0)->GetWeight();
+}
+
+/* IDWriteFontList */
+JNIEXPORT jint JNICALL OS_NATIVE(GetFontCount)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return ((IDWriteFontList *)arg0)->GetFontCount();
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(GetFont)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1)
+{
+    IDWriteFont* result = NULL;
+    HRESULT hr = ((IDWriteFontList *)arg0)->GetFont(arg1, &result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+/* IDWriteLocalizedStrings */
+JNIEXPORT jcharArray JNICALL OS_NATIVE(GetLocaleName)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2)
+{
+    jcharArray result = NULL;
+    WCHAR* buffer = new (std::nothrow) WCHAR[arg2];
+    HRESULT hr = ((IDWriteLocalizedStrings *)arg0)->GetLocaleName(arg1, buffer, arg2);
+    if (SUCCEEDED(hr)) {
+        result = env->NewCharArray(arg2);
+        if (result) {
+            env->SetCharArrayRegion(result, 0, arg2, (const jchar*)buffer);
+        }
+    }
+    delete [] buffer;
+    return result;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetLocaleNameLength)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1)
+{
+    UINT32 result = 0;
+    HRESULT hr = ((IDWriteLocalizedStrings *)arg0)->GetLocaleNameLength(arg1, &result);
+    return SUCCEEDED(hr) ? result : 0;
+}
+
+JNIEXPORT jcharArray JNICALL OS_NATIVE(GetString)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2)
+{
+    jcharArray result = NULL;
+    WCHAR* buffer = new (std::nothrow) WCHAR[arg2];
+    HRESULT hr = ((IDWriteLocalizedStrings *)arg0)->GetString(arg1, buffer, arg2);
+    if (SUCCEEDED(hr)) {
+        result = env->NewCharArray(arg2);
+        if (result) {
+            env->SetCharArrayRegion(result, 0, arg2, (const jchar*)buffer);
+        }
+    }
+    delete [] buffer;
+    return result;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetStringLength)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1)
+{
+    UINT32 result = 0;
+    HRESULT hr = ((IDWriteLocalizedStrings *)arg0)->GetStringLength(arg1, &result);
+    return SUCCEEDED(hr) ? result : 0;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(FindLocaleName)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1)
+{
+    HRESULT hr = E_FAIL;
+    jchar *lparg1 = NULL;
+    UINT32 result = 0;
+    BOOL exists = FALSE;
+    if (arg1) if ((lparg1 = env->GetCharArrayElements(arg1, NULL)) == NULL) goto fail;
+    hr = ((IDWriteLocalizedStrings *)arg0)->FindLocaleName((const WCHAR *) lparg1,&result, &exists);
+fail:
+    if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
+    return SUCCEEDED(hr) && exists ? result : -1;
+}
+
+/* IDWriteFontFamily */
+JNIEXPORT jlong JNICALL OS_NATIVE(GetFamilyNames)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    IDWriteLocalizedStrings* result = NULL;
+    HRESULT hr = ((IDWriteFontFamily *)arg0)->GetFamilyNames(&result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(GetFirstMatchingFont)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2, jint arg3)
+{
+    IDWriteFont* result = NULL;
+    HRESULT hr = ((IDWriteFontFamily *)arg0)->GetFirstMatchingFont((DWRITE_FONT_WEIGHT)arg1, (DWRITE_FONT_STRETCH)arg2, (DWRITE_FONT_STYLE)arg3, &result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+/* IDWriteFontCollection */
+JNIEXPORT jint JNICALL OS_NATIVE(GetFontFamilyCount)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return ((IDWriteFontCollection *)arg0)->GetFontFamilyCount();
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(GetFontFamily__JI)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1)
+{
+    IDWriteFontFamily* result = NULL;
+    HRESULT hr = ((IDWriteFontCollection *)arg0)->GetFontFamily(arg1, &result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(FindFamilyName)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1)
+{
+    HRESULT hr = E_FAIL;
+    jchar *lparg1 = NULL;
+    UINT32 result = 0;
+    BOOL exists = FALSE;
+    if (arg1) if ((lparg1 = env->GetCharArrayElements(arg1, NULL)) == NULL) goto fail;
+    hr = ((IDWriteFontCollection *)arg0)->FindFamilyName((const WCHAR *) lparg1, &result, &exists);
+    fail:
+    if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
+    return SUCCEEDED(hr) && exists ? result : -1;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(GetFontFromFontFace)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1)
+{
+    IDWriteFont* result = NULL;
+    HRESULT hr = ((IDWriteFontCollection *)arg0)->GetFontFromFontFace((IDWriteFontFace *)arg1, &result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+/* IDWriteGlyphRunAnalysis */
+JNIEXPORT jbyteArray JNICALL OS_NATIVE(CreateAlphaTexture)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jobject arg2)
+{
+    jbyteArray result = NULL;
+    RECT _arg2, *lparg2 = NULL;
+    /* In Only */
+    if (arg2) lparg2 = getRECTFields(env, arg2, &_arg2);
+    if (!lparg2) return NULL;
+    DWRITE_TEXTURE_TYPE textureType = (DWRITE_TEXTURE_TYPE)arg1;
+    UINT32 width = lparg2->right - lparg2->left;
+    UINT32 height = lparg2->bottom - lparg2->top;
+    UINT32 bpp = textureType == DWRITE_TEXTURE_CLEARTYPE_3x1 ? 3 : 1;
+    UINT32 bufferSize = width * height * bpp;
+    BYTE * buffer = new (std::nothrow) BYTE[bufferSize];
+    HRESULT hr = ((IDWriteGlyphRunAnalysis *)arg0)->CreateAlphaTexture(textureType, lparg2, buffer, bufferSize);
+    if (SUCCEEDED(hr)) {
+        result = env->NewByteArray(bufferSize);
+        if (result) {
+            env->SetByteArrayRegion(result, 0, bufferSize, (jbyte*)buffer);
+        }
+    }
+    delete [] buffer;
+    return result;
+}
+
+JNIEXPORT jobject JNICALL OS_NATIVE(GetAlphaTextureBounds)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1)
+{
+    jobject result = NULL;
+    RECT rect;
+    HRESULT hr = ((IDWriteGlyphRunAnalysis *)arg0)->GetAlphaTextureBounds((DWRITE_TEXTURE_TYPE)arg1, &rect);
+    if (SUCCEEDED(hr)) {
+        result = newRECT(env, &rect);
+    }
+    return result;
+}
+
+/* IDWriteTextAnalyzer */
+JNIEXPORT jint JNICALL OS_NATIVE(AnalyzeScript)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jint arg2, jint arg3, jlong arg4)
+{
+    JFXTextAnalysisSink* source = (JFXTextAnalysisSink *)arg1;
+    JFXTextAnalysisSink* sink = (JFXTextAnalysisSink *)arg4;
+    IDWriteTextAnalyzer* analyzer = (IDWriteTextAnalyzer *)arg0;
+    return analyzer->AnalyzeScript(source, arg2, arg3, sink);
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetGlyphs)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1, jint textStart, jint arg2, jlong arg3, jboolean arg4,
+    jboolean arg5, jobject arg6, jcharArray arg7, jlong arg8, jlongArray arg9, jintArray arg10,
+    jint arg11, jint arg12, jshortArray arg13, jshortArray arg14, jshortArray arg15, jshortArray arg16, jintArray arg17)
+{
+    HRESULT hr = E_FAIL;
+    jchar *lparg1=NULL;
+    DWRITE_SCRIPT_ANALYSIS _arg6, *lparg6=NULL;
+    jchar *lparg7=NULL;
+    jlong *lparg9=NULL;
+    jint *lparg10=NULL;
+    jshort *lparg13=NULL;
+    jshort *lparg14=NULL;
+    jshort *lparg15=NULL;
+    jshort *lparg16=NULL;
+    jint *lparg17=NULL;
+
+    if (arg1) if ((lparg1 = env->GetCharArrayElements(arg1, NULL)) == NULL) goto fail;
+    if (arg6) if ((lparg6 = getDWRITE_SCRIPT_ANALYSISFields(env, arg6, &_arg6)) == NULL) goto fail;
+    if (arg7) lparg7 = env->GetCharArrayElements(arg7, NULL); /*Optional*/
+    if (arg9) if ((lparg9 = env->GetLongArrayElements(arg9, NULL)) == NULL) goto fail;
+    if (arg10) if ((lparg10 = env->GetIntArrayElements(arg10, NULL)) == NULL) goto fail;
+    if (arg13) if ((lparg13 = env->GetShortArrayElements(arg13, NULL)) == NULL) goto fail;
+    if (arg14) if ((lparg14 = env->GetShortArrayElements(arg14, NULL)) == NULL) goto fail;
+    if (arg15) if ((lparg15 = env->GetShortArrayElements(arg15, NULL)) == NULL) goto fail;
+    if (arg16) if ((lparg16 = env->GetShortArrayElements(arg16, NULL)) == NULL) goto fail;
+    if (arg17) if ((lparg17 = env->GetIntArrayElements(arg17, NULL)) == NULL) goto fail;
+    const WCHAR* text = (const WCHAR*)(lparg1 + textStart);
+
+    hr = ((IDWriteTextAnalyzer *)arg0)->GetGlyphs(text,
+                                                  (UINT32)arg2,
+                                                  (IDWriteFontFace *)arg3,
+                                                  (BOOL)arg4,
+                                                  (BOOL)arg5,
+                                                  (const DWRITE_SCRIPT_ANALYSIS *)lparg6,
+                                                  (const WCHAR *)lparg7,
+                                                  (IDWriteNumberSubstitution *)arg8,
+                                                  (const DWRITE_TYPOGRAPHIC_FEATURES **)lparg9,
+                                                  (const UINT32 *)lparg10,
+                                                  (UINT32)arg11,
+                                                  (UINT32)arg12,
+                                                  (UINT16 *)lparg13,
+                                                  (DWRITE_SHAPING_TEXT_PROPERTIES *)lparg14,
+                                                  (UINT16 *)lparg15,
+                                                  (DWRITE_SHAPING_GLYPH_PROPERTIES *)lparg16,
+                                                  (UINT32 *)lparg17);
+
+    fail:
+    if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
+    if (arg7 && lparg7) env->ReleaseCharArrayElements(arg7, lparg7, 0);
+    if (arg9 && lparg9) env->ReleaseLongArrayElements(arg9, lparg9, 0);
+    if (arg10 && lparg10) env->ReleaseIntArrayElements(arg10, lparg10, 0);
+    if (arg13 && lparg13) env->ReleaseShortArrayElements(arg13, lparg13, 0);
+    if (arg14 && lparg14) env->ReleaseShortArrayElements(arg14, lparg14, 0);
+    if (arg15 && lparg15) env->ReleaseShortArrayElements(arg15, lparg15, 0);
+    if (arg16 && lparg16) env->ReleaseShortArrayElements(arg16, lparg16, 0);
+    if (arg17 && lparg17) env->ReleaseIntArrayElements(arg17, lparg17, 0);
+    return hr;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetGlyphPlacements)
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1, jshortArray arg2,
+    jshortArray arg3, jint textStart, jint arg4, jshortArray arg5, jshortArray arg6, jint arg7,
+    jlong arg8, jfloat arg9, jboolean arg10, jboolean arg11, jobject arg12,
+    jcharArray arg13, jlongArray arg14, jintArray arg15, jint arg16,
+    jfloatArray arg17, jfloatArray arg18) {
+
+    HRESULT hr = E_FAIL;
+    jchar *lparg1=NULL;
+    jshort *lparg2=NULL;
+    jshort *lparg3=NULL;
+    jshort *lparg5=NULL;
+    jshort *lparg6=NULL;
+    DWRITE_SCRIPT_ANALYSIS _arg12, *lparg12=NULL;
+    jchar *lparg13=NULL;
+    jlong *lparg14=NULL;
+    jint *lparg15=NULL;
+    jfloat *lparg17=NULL;
+    jfloat *lparg18=NULL;
+
+    if (arg1) if ((lparg1 = env->GetCharArrayElements(arg1, NULL)) == NULL) goto fail;
+    if (arg2) if ((lparg2 = env->GetShortArrayElements(arg2, NULL)) == NULL) goto fail;
+    if (arg3) if ((lparg3 = env->GetShortArrayElements(arg3, NULL)) == NULL) goto fail;
+    if (arg5) if ((lparg5 = env->GetShortArrayElements(arg5, NULL)) == NULL) goto fail;
+    if (arg6) if ((lparg6 = env->GetShortArrayElements(arg6, NULL)) == NULL) goto fail;
+    if (arg12) if ((lparg12 = getDWRITE_SCRIPT_ANALYSISFields(env, arg12, &_arg12)) == NULL) goto fail;
+    if (arg13) lparg13 = env->GetCharArrayElements(arg13, NULL); /* Optional */
+    if (arg14) if ((lparg14 = env->GetLongArrayElements(arg14, NULL)) == NULL) goto fail;
+    if (arg15) if ((lparg15 = env->GetIntArrayElements(arg15, NULL)) == NULL) goto fail;
+    if (arg17) if ((lparg17 = env->GetFloatArrayElements(arg17, NULL)) == NULL) goto fail;
+    if (arg18) if ((lparg18 = env->GetFloatArrayElements(arg18, NULL)) == NULL) goto fail;
+    const WCHAR* text = (const WCHAR*)(lparg1 + textStart);
+
+    hr = ((IDWriteTextAnalyzer *)arg0)->GetGlyphPlacements(text,
+                                                           (const UINT16 *)lparg2,
+                                                           (DWRITE_SHAPING_TEXT_PROPERTIES *)lparg3,
+                                                           (UINT32)arg4,
+                                                           (const UINT16 *)lparg5,
+                                                           (const DWRITE_SHAPING_GLYPH_PROPERTIES *)lparg6,
+                                                           (UINT32)arg7,
+                                                           (IDWriteFontFace *)arg8,
+                                                           (FLOAT)arg9,
+                                                           (BOOL)arg10,
+                                                           (BOOL)arg11,
+                                                           (const DWRITE_SCRIPT_ANALYSIS *)lparg12,
+                                                           (const WCHAR *)lparg13,
+                                                           (const DWRITE_TYPOGRAPHIC_FEATURES **)lparg14,
+                                                           (const UINT32 *)lparg15,
+                                                           (UINT32)arg16,
+                                                           (FLOAT *)lparg17,
+                                                           (DWRITE_GLYPH_OFFSET *)lparg18);
+
+fail:
+    if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
+    if (arg2 && lparg2) env->ReleaseShortArrayElements(arg2, lparg2, 0);
+    if (arg3 && lparg3) env->ReleaseShortArrayElements(arg3, lparg3, 0);
+    if (arg5 && lparg5) env->ReleaseShortArrayElements(arg5, lparg5, 0);
+    if (arg6 && lparg6) env->ReleaseShortArrayElements(arg6, lparg6, 0);
+    if (arg13 && lparg13) env->ReleaseCharArrayElements(arg13, lparg13, 0);
+    if (arg14 && lparg14) env->ReleaseLongArrayElements(arg14, lparg14, 0);
+    if (arg15 && lparg15) env->ReleaseIntArrayElements(arg15, lparg15, 0);
+    if (arg17 && lparg17) env->ReleaseFloatArrayElements(arg17, lparg17, 0);
+    if (arg18 && lparg18) env->ReleaseFloatArrayElements(arg18, lparg18, 0);
+
+    return hr;
+}
+
+/*IDWriteTextLayout*/
+JNIEXPORT jint JNICALL OS_NATIVE(Draw)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jfloat arg3, jfloat arg4)
+{
+    return ((IDWriteTextLayout *)arg0)->Draw((void*) arg1, (IDWriteTextRenderer *)arg2, arg3, arg4);
+}
+
+/* IWICImagingFactory*/
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateBitmap)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2, jint arg3, jint arg4)
+{
+
+    IWICBitmap* result = NULL;
+    GUID pixelFormat;
+    switch (arg3) {
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat8bppGray:pixelFormat = GUID_WICPixelFormat8bppGray; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat8bppAlpha:pixelFormat = GUID_WICPixelFormat8bppAlpha; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat16bppGray: pixelFormat = GUID_WICPixelFormat16bppGray; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat24bppRGB: pixelFormat = GUID_WICPixelFormat24bppRGB; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat24bppBGR: pixelFormat = GUID_WICPixelFormat24bppBGR; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppBGR: pixelFormat = GUID_WICPixelFormat32bppBGR; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppBGRA: pixelFormat = GUID_WICPixelFormat32bppBGRA; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppPBGRA: pixelFormat = GUID_WICPixelFormat32bppPBGRA; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppGrayFloat: pixelFormat = GUID_WICPixelFormat32bppGrayFloat; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppRGBA: pixelFormat = GUID_WICPixelFormat32bppRGBA; break;
+    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppPRGBA: pixelFormat = GUID_WICPixelFormat32bppPRGBA; break;
+    }
+    HRESULT hr = ((IWICImagingFactory *)arg0)->CreateBitmap(arg1, arg2, (REFWICPixelFormatGUID)pixelFormat, (WICBitmapCreateCacheOption)arg4, &result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+/*IWICBitmap*/
+JNIEXPORT jlong JNICALL OS_NATIVE(Lock)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2, jint arg3, jint arg4, jint arg5)
+{
+    HRESULT hr = E_FAIL;
+    IWICBitmapLock* result = NULL;
+    const WICRect rcLock = {arg1, arg2, arg3, arg4};
+    hr = ((IWICBitmap *)arg0)->Lock(&rcLock, arg5, &result);
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+/*IWICBitmapLock*/
+JNIEXPORT jbyteArray JNICALL OS_NATIVE(GetDataPointer)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    jbyteArray result = NULL;
+    UINT cbBufferSize = 0;
+    BYTE *pv = NULL;
+    HRESULT hr = ((IWICBitmapLock *)arg0)->GetDataPointer(&cbBufferSize, &pv);
+    if (SUCCEEDED(hr)) {
+        result = env->NewByteArray(cbBufferSize);
+        if (result) {
+            env->SetByteArrayRegion(result, 0, cbBufferSize, (const jbyte*)pv);
+        }
+    }
+    return result;
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(GetStride)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    UINT result;
+    HRESULT hr = ((IWICBitmapLock *)arg0)->GetStride(&result);
+    return SUCCEEDED(hr) ? result : NULL;
+}
+
+
+/*ID2D1Factory */
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateWicBitmapRenderTarget)
+    (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jobject arg2)
+{
+    HRESULT hr = E_FAIL;
+    ID2D1RenderTarget* result = NULL;
+    D2D1_RENDER_TARGET_PROPERTIES _arg2, *lparg2=NULL;
+    if (arg2) if ((lparg2 = getD2D1_RENDER_TARGET_PROPERTIESFields(env, arg2, &_arg2)) == NULL) goto fail;
+    hr = ((ID2D1Factory *)arg0)->CreateWicBitmapRenderTarget((IWICBitmap *)arg1, lparg2, &result);
+fail:
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+/*ID2D1RenderTarget*/
+JNIEXPORT void JNICALL OS_NATIVE(BeginDraw)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    ((ID2D1RenderTarget *)arg0)->BeginDraw();
+}
+
+JNIEXPORT jint JNICALL OS_NATIVE(EndDraw)
+    (JNIEnv *env, jclass that, jlong arg0)
+{
+    return (jint) ((ID2D1RenderTarget *)arg0)->EndDraw();
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(Clear)
+    (JNIEnv *env, jclass that, jlong arg0, jobject arg1)
+{
+    D2D1_COLOR_F _arg1, *lparg1=NULL;
+    if (arg1) if ((lparg1 = getD2D1_COLOR_FFields(env, arg1, &_arg1)) == NULL) return;
+    ((ID2D1RenderTarget *)arg0)->Clear(lparg1);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(SetTextAntialiasMode)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1)
+{
+    ((ID2D1RenderTarget *)arg0)->SetTextAntialiasMode((D2D1_TEXT_ANTIALIAS_MODE)arg1);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(SetTransform)
+    (JNIEnv *env, jclass that, jlong arg0, jobject arg1)
+{
+    D2D1_MATRIX_3X2_F _arg1, *lparg1=NULL;
+    if (arg1) if ((lparg1 = getD2D1_MATRIX_3X2_FFields(env, arg1, &_arg1)) == NULL) return;
+    ((ID2D1RenderTarget *)arg0)->SetTransform(lparg1);
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(DrawGlyphRun)
+    (JNIEnv *env, jclass that, jlong arg0, jobject arg1, jobject arg2, jlong arg3, jint arg4)
+{
+    D2D1_POINT_2F _arg1, *lparg1=NULL;
+    DWRITE_GLYPH_RUN _arg2, *lparg2=NULL;
+    _arg2.glyphIndices = new (std::nothrow) UINT16 [1];
+    _arg2.glyphAdvances = new (std::nothrow) FLOAT [1];
+    if (arg1) if ((lparg1 = getD2D1_POINT_2FFields(env, arg1, &_arg1)) == NULL) goto fail;
+    if (arg2) if ((lparg2 = getDWRITE_GLYPH_RUNFields(env, arg2, &_arg2)) == NULL) goto fail;
+    ((ID2D1RenderTarget *)arg0)->DrawGlyphRun(_arg1, lparg2, (ID2D1Brush *)arg3, (DWRITE_MEASURING_MODE)arg4);
+fail:
+    delete [] _arg2.glyphIndices;
+    delete [] _arg2.glyphAdvances;
+}
+
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateSolidColorBrush)
+    (JNIEnv *env, jclass that, jlong arg0, jobject arg1)
+{
+    HRESULT hr = E_FAIL;
+    ID2D1SolidColorBrush* result = NULL;
+    D2D1_COLOR_F _arg1, *lparg1=NULL;
+    if (arg1) if ((lparg1 = getD2D1_COLOR_FFields(env, arg1, &_arg1)) == NULL) goto fail;
+    hr = ((ID2D1RenderTarget *)arg0)->CreateSolidColorBrush(_arg1, &result);
+fail:
+    return SUCCEEDED(hr) ? (jlong)result : NULL;
+}
+
+JNIEXPORT void JNICALL OS_NATIVE(DrawLine)
+    (JNIEnv *env, jclass that, jlong arg0, jobject arg1, jobject arg2, jlong arg3, jfloat arg4, jlong arg5)
+{
+    D2D1_POINT_2F _arg1, *lparg1=NULL;
+    D2D1_POINT_2F _arg2, *lparg2=NULL;
+    if (arg1) if ((lparg1 = getD2D1_POINT_2FFields(env, arg1, &_arg1)) == NULL) return;
+    if (arg2) if ((lparg2 = getD2D1_POINT_2FFields(env, arg2, &_arg2)) == NULL) return;
+    ((ID2D1RenderTarget *)arg0)->DrawLine(_arg1, _arg2, (ID2D1Brush *)arg3, arg4, (ID2D1StrokeStyle *)arg5);
+}
+
+#endif /* WIN32 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/src/fontpath.c	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,753 @@
+/*
+ * Copyright (c) 2009, 2013, 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.
+ */
+
+#ifdef WIN32
+
+#include <windows.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include <jni.h>
+#include <com_sun_javafx_font_PrismFontFactory.h>
+
+#define BSIZE (max(512, MAX_PATH+1))
+
+JNIEXPORT jbyteArray JNICALL
+Java_com_sun_javafx_font_PrismFontFactory_getFontPath(JNIEnv *env, jobject thiz)
+{
+    char windir[BSIZE];
+    char sysdir[BSIZE];
+    char fontpath[BSIZE*2];
+    char *end;
+    jbyteArray byteArrObj;
+    int pathLen;
+    unsigned char *data;
+
+    /* Locate fonts directories relative to the Windows System directory.
+     * If Windows System location is different than the user's window
+     * directory location, as in a shared Windows installation,
+     * return both locations as potential font directories
+     */
+    GetSystemDirectory(sysdir, BSIZE);
+    end = strrchr(sysdir,'\\');
+    if (end && (stricmp(end,"\\System") || stricmp(end,"\\System32"))) {
+        *end = 0;
+         strcat(sysdir, "\\Fonts");
+    }
+
+    GetWindowsDirectory(windir, BSIZE);
+    if (strlen(windir) > BSIZE-7) {
+        *windir = 0;
+    } else {
+        strcat(windir, "\\Fonts");
+    }
+
+    strcpy(fontpath,sysdir);
+    if (stricmp(sysdir,windir)) {
+        strcat(fontpath,";");
+        strcat(fontpath,windir);
+    }
+
+    pathLen = strlen(fontpath);
+
+    byteArrObj = (*env)->NewByteArray(env, pathLen);
+    if (byteArrObj == NULL) {
+        return (jbyteArray)NULL;
+    }
+    data = (*env)->GetByteArrayElements(env, byteArrObj, NULL);
+    if (data == NULL) {
+        return byteArrObj;
+    }
+    memcpy(data, fontpath, pathLen);
+    (*env)->ReleaseByteArrayElements(env, byteArrObj, (jbyte*) data, (jint)0);
+
+    return byteArrObj;
+}
+
+/* The code below is used to obtain information from the windows font APIS
+ * and registry on which fonts are available and what font files hold those
+ * fonts. The results are used to speed font lookup.
+ */
+
+typedef struct GdiFontMapInfo {
+    JNIEnv *env;
+    jstring family;
+    jobject fontToFamilyMap;
+    jobject familyToFontListMap;
+    jobject list;
+    jmethodID putMID;
+    jmethodID containsKeyMID;
+    jclass arrayListClass;
+    jmethodID arrayListCtr;
+    jmethodID addMID;
+    jmethodID toLowerCaseMID;
+    jobject locale;
+    HDC screenDC;
+} GdiFontMapInfo;
+
+/* NT is W2K & XP, Vista, Win 7 etc. ie anything later than win9x */
+static const char FONTKEY_NT[] =
+    "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts";
+
+
+typedef struct CheckFamilyInfo {
+  wchar_t *family;
+  wchar_t* fullName;
+  int isDifferent;
+} CheckFamilyInfo;
+
+static int CALLBACK CheckFontFamilyProcW(
+  ENUMLOGFONTEXW *lpelfe,
+  NEWTEXTMETRICEX *lpntme,
+  int FontType,
+  LPARAM lParam)
+{
+    CheckFamilyInfo *info = (CheckFamilyInfo*)lParam;
+    info->isDifferent = wcscmp(lpelfe->elfLogFont.lfFaceName, info->family);
+
+/*     if (!info->isDifferent) { */
+/*         wprintf(LFor font %s expected family=%s instead got %s\n", */
+/*                 lpelfe->elfFullName, */
+/*                 info->family, */
+/*                 lpelfe->elfLogFont.lfFaceName); */
+/*         fflush(stdout); */
+/*     } */
+    return 0;
+}
+
+static int DifferentFamily(wchar_t *family, wchar_t* fullName,
+                           GdiFontMapInfo *fmi) {
+    LOGFONTW lfw;
+    CheckFamilyInfo info;
+
+    /* If fullName can't be stored in the struct, assume correct family */
+    if (wcslen((LPWSTR)fullName) >= LF_FACESIZE) {
+        return 0;
+    }
+
+    memset(&info, 0, sizeof(CheckFamilyInfo));
+    info.family = family;
+    info.fullName = fullName;
+    info.isDifferent = 0;
+
+    memset(&lfw, 0, sizeof(lfw));
+    wcscpy(lfw.lfFaceName, fullName);
+    lfw.lfCharSet = DEFAULT_CHARSET;
+    EnumFontFamiliesExW(fmi->screenDC, &lfw,
+                        (FONTENUMPROCW)CheckFontFamilyProcW,
+                        (LPARAM)(&info), 0L);
+
+    return info.isDifferent;
+}
+
+/* Callback for call to EnumFontFamiliesEx in the EnumFamilyNames function.
+ * Expects to be called once for each face name in the family specified
+ * in the call. We extract the full name for the font which is expected
+ * to be in the "system encoding" and create canonical and lower case
+ * Java strings for the name which are added to the maps. The lower case
+ * name is used as key to the family name value in the font to family map,
+ * the canonical name is one of the"list" of members of the family.
+ */
+static int CALLBACK EnumFontFacesInFamilyProcW(
+  ENUMLOGFONTEXW *lpelfe,
+  NEWTEXTMETRICEX *lpntme,
+  int FontType,
+  LPARAM lParam)
+{
+    GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam;
+    JNIEnv *env = fmi->env;
+    jstring fullname, fullnameLC;
+
+    /* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
+    if (FontType != TRUETYPE_FONTTYPE && FontType != DEVICE_FONTTYPE) {
+        return 1;
+    }
+
+    /* Windows has font aliases and so may enumerate fonts from
+     * the aliased family if any actual font of that family is installed.
+     * To protect against it ignore fonts which aren't enumerated under
+     * their true family.
+     */
+    if (DifferentFamily(lpelfe->elfLogFont.lfFaceName,
+                        lpelfe->elfFullName, fmi))  {
+      return 1;
+    }
+
+    fullname = (*env)->NewString(env, lpelfe->elfFullName,
+                                 wcslen((LPWSTR)lpelfe->elfFullName));
+    fullnameLC = (*env)->CallObjectMethod(env, fullname,
+                                          fmi->toLowerCaseMID, fmi->locale);
+    (*env)->CallBooleanMethod(env, fmi->list, fmi->addMID, fullname);
+    (*env)->CallObjectMethod(env, fmi->fontToFamilyMap,
+                             fmi->putMID, fullnameLC, fmi->family);
+    return 1;
+}
+
+/* Callback for EnumFontFamiliesEx in populateFontFileNameMap.
+ * Expects to be called for every charset of every font family.
+ * If this is the first time we have been called for this family,
+ * add a new mapping to the familyToFontListMap from this family to a
+ * list of its members. To populate that list, further enumerate all faces
+ * in this family for the matched charset. This assumes that all fonts
+ * in a family support the same charset, which is a fairly safe assumption
+ * and saves time as the call we make here to EnumFontFamiliesEx will
+ * enumerate the members of this family just once each.
+ * Because we set fmi->list to be the newly created list the call back
+ * can safely add to that list without a search.
+ */
+static int CALLBACK EnumFamilyNamesW(
+  ENUMLOGFONTEXW *lpelfe,    /* pointer to logical-font data */
+  NEWTEXTMETRICEX *lpntme,  /* pointer to physical-font data */
+  int FontType,             /* type of font */
+  LPARAM lParam )           /* application-defined data */
+{
+    GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam;
+    JNIEnv *env = fmi->env;
+    jstring familyLC;
+    int slen;
+    LOGFONTW lfw;
+
+    /* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
+    if (FontType != TRUETYPE_FONTTYPE && FontType != DEVICE_FONTTYPE) {
+        return 1;
+    }
+/*     wprintf(L"FAMILY=%s charset=%d FULL=%s\n", */
+/*          lpelfe->elfLogFont.lfFaceName, */
+/*          lpelfe->elfLogFont.lfCharSet, */
+/*          lpelfe->elfFullName); */
+/*     fflush(stdout); */
+
+    /* Windows lists fonts which have a vmtx (vertical metrics) table twice.
+     * Once using their normal name, and again preceded by '@'. These appear
+     * in font lists in some windows apps, such as wordpad. We don't want
+     * these so we skip any font where the first character is '@'
+     */
+    if (lpelfe->elfLogFont.lfFaceName[0] == L'@') {
+            return 1;
+    }
+    slen = wcslen(lpelfe->elfLogFont.lfFaceName);
+    fmi->family = (*env)->NewString(env,lpelfe->elfLogFont.lfFaceName, slen);
+    familyLC = (*env)->CallObjectMethod(env, fmi->family,
+                                        fmi->toLowerCaseMID, fmi->locale);
+    /* check if already seen this family with a different charset */
+    if ((*env)->CallBooleanMethod(env,fmi->familyToFontListMap,
+                                  fmi->containsKeyMID, familyLC)) {
+        return 1;
+    }
+    fmi->list = (*env)->NewObject(env,
+                                  fmi->arrayListClass, fmi->arrayListCtr, 4);
+
+    (*env)->CallObjectMethod(env, fmi->familyToFontListMap,
+                             fmi->putMID, familyLC, fmi->list);
+
+    memset(&lfw, 0, sizeof(lfw));
+    wcscpy(lfw.lfFaceName, lpelfe->elfLogFont.lfFaceName);
+    lfw.lfCharSet = lpelfe->elfLogFont.lfCharSet;
+    EnumFontFamiliesExW(fmi->screenDC, &lfw,
+                        (FONTENUMPROCW)EnumFontFacesInFamilyProcW,
+                        lParam, 0L);
+    return 1;
+}
+
+
+/* It looks like TrueType fonts have " (TrueType)" tacked on the end of their
+ * name, so we can try to use that to distinguish TT from other fonts.
+ * However if a program "installed" a font in the registry the key may
+ * not include that. We could also try to "pass" fonts which have no "(..)"
+ * at the end. But that turns out to pass a few .FON files that MS supply.
+ * If there's no parenthesised type string, we could next try to infer
+ * the file type from the file name extension. Since the MS entries that
+ * have no type string are very few, and have odd names like "MS-DOS CP 437"
+ * and would never return a Java Font anyway its currently OK to put these
+ * in the font map, although clearly the returned names must never percolate
+ * up into a list of available fonts returned to the application.
+ * Additionally for TTC font files the key looks like
+ * Font 1 & Font 2 (TrueType)
+ * or sometimes even :
+ * Font 1 & Font 2 & Font 3 (TrueType)
+ * Also if a Font has a name for this locale that name also
+ * exists in the registry using the appropriate platform encoding.
+ * What do we do then?
+ *
+ * Note: OpenType fonts seems to have " (TrueType)" suffix on Vista
+ *   but " (OpenType)" on XP.
+ */
+static BOOL RegistryToBaseTTNameW(LPWSTR name) {
+    static const wchar_t TTSUFFIX[] = L" (TrueType)";
+    static const wchar_t OTSUFFIX[] = L" (OpenType)";
+    int TTSLEN = wcslen(TTSUFFIX);
+    wchar_t *suffix;
+
+    int len = wcslen(name);
+    if (len == 0) {
+        return FALSE;
+    }
+    if (name[len-1] != L')') {
+        return FALSE;
+    }
+    if (len <= TTSLEN) {
+        return FALSE;
+    }
+    /* suffix length is the same for truetype and opentype fonts */
+    suffix = name + (len - TTSLEN);
+    // REMIND : renable OpenType (.otf) some day.
+    if (wcscmp(suffix, TTSUFFIX) == 0 /*|| wcscmp(suffix, OTSUFFIX) == 0*/) {
+        suffix[0] = L'\0'; /* truncate name */
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap,
+                          LPWSTR name, LPWSTR data) {
+
+    wchar_t *ptr1, *ptr2;
+    jstring fontStr;
+    JNIEnv *env = fmi->env;
+    int dslen = wcslen(data);
+    jstring fileStr = (*env)->NewString(env, data, dslen);
+
+    /* TTC or ttc means it may be a collection. Need to parse out
+     * multiple font face names separated by " & "
+     * By only doing this for fonts which look like collections based on
+     * file name we are adhering to MS recommendations for font file names
+     * so it seems that we can be sure that this identifies precisely
+     * the MS-supplied truetype collections.
+     * This avoids any potential issues if a TTF file happens to have
+     * a & in the font name (I can't find anything which prohibits this)
+     * and also means we only parse the key in cases we know to be
+     * worthwhile.
+     */
+
+    if ((data[dslen-1] == L'C' || data[dslen-1] == L'c') &&
+        (ptr1 = wcsstr(name, L" & ")) != NULL) {
+        ptr1+=3;
+        while (ptr1 >= name) { /* marginally safer than while (true) */
+            while ((ptr2 = wcsstr(ptr1, L" & ")) != NULL) {
+                ptr1 = ptr2+3;
+            }
+            fontStr = (*env)->NewString(env, ptr1, wcslen(ptr1));
+            fontStr = (*env)->CallObjectMethod(env, fontStr,
+                                               fmi->toLowerCaseMID,
+                                               fmi->locale);
+            (*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
+                                     fontStr, fileStr);
+            if (ptr1 == name) {
+                break;
+            } else {
+                *(ptr1-3) = L'\0';
+                ptr1 = name;
+            }
+        }
+    } else {
+        fontStr = (*env)->NewString(env, name, wcslen(name));
+        fontStr = (*env)->CallObjectMethod(env, fontStr,
+                                           fmi->toLowerCaseMID, fmi->locale);
+        (*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
+                                 fontStr, fileStr);
+    }
+}
+
+/* Obtain all the fontname -> filename mappings.
+ * This is called once and the results returned to Java code which can
+ * use it for lookups to reduce or avoid the need to search font files.
+ */
+JNIEXPORT void JNICALL
+Java_com_sun_javafx_font_PrismFontFactory_populateFontFileNameMap
+(JNIEnv *env, jclass obj, jobject fontToFileMap,
+ jobject fontToFamilyMap, jobject familyToFontListMap, jobject locale)
+{
+#define MAX_BUFFER (FILENAME_MAX+1)
+    const wchar_t wname[MAX_BUFFER];
+    const char data[MAX_BUFFER];
+
+    DWORD type;
+    LONG ret;
+    HKEY hkeyFonts;
+    DWORD dwNameSize;
+    DWORD dwDataValueSize;
+    DWORD nval;
+    LPCSTR fontKeyName;
+    DWORD dwNumValues, dwMaxValueNameLen, dwMaxValueDataLen;
+    DWORD numValues = 0;
+    jclass classID;
+    jmethodID putMID;
+    GdiFontMapInfo fmi;
+    LOGFONTW lfw;
+
+    /* Check we were passed all the maps we need, and do lookup of
+     * methods for JNI up-calls
+     */
+    if (fontToFileMap == NULL ||
+        fontToFamilyMap == NULL ||
+        familyToFontListMap == NULL) {
+        return;
+    }
+    classID = (*env)->FindClass(env, "java/util/HashMap");
+    if (classID == NULL) {
+        return;
+    }
+    putMID = (*env)->GetMethodID(env, classID, "put",
+                 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+    if (putMID == NULL) {
+        return;
+    }
+
+    fmi.env = env;
+    fmi.fontToFamilyMap = fontToFamilyMap;
+    fmi.familyToFontListMap = familyToFontListMap;
+    fmi.putMID = putMID;
+    fmi.locale = locale;
+    fmi.containsKeyMID = (*env)->GetMethodID(env, classID, "containsKey",
+                                             "(Ljava/lang/Object;)Z");
+    if (fmi.containsKeyMID == NULL) {
+        return;
+    }
+
+    fmi.arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
+    if (fmi.arrayListClass == NULL) {
+        return;
+    }
+    fmi.arrayListCtr = (*env)->GetMethodID(env, fmi.arrayListClass,
+                                              "<init>", "(I)V");
+    if (fmi.arrayListCtr == NULL) {
+        return;
+    }
+    fmi.addMID = (*env)->GetMethodID(env, fmi.arrayListClass,
+                                     "add", "(Ljava/lang/Object;)Z");
+    if (fmi.addMID == NULL) {
+        return;
+    }
+    classID = (*env)->FindClass(env, "java/lang/String");
+    if (classID == NULL) {
+        return;
+    }
+    fmi.toLowerCaseMID =
+        (*env)->GetMethodID(env, classID, "toLowerCase",
+                            "(Ljava/util/Locale;)Ljava/lang/String;");
+    if (fmi.toLowerCaseMID == NULL) {
+        return;
+    }
+
+    /* This HDC is initialised and released in this populate family map
+     * JNI entry point, and used within the call which would otherwise
+     * create many DCs.
+     */
+    fmi.screenDC = GetDC(NULL);
+    if (fmi.screenDC == NULL) {
+        return;
+    }
+
+    /* Enumerate fonts via GDI to build maps of fonts and families */
+    memset(&lfw, 0, sizeof(lfw));
+    lfw.lfCharSet = DEFAULT_CHARSET;  /* all charsets */
+    wcscpy(lfw.lfFaceName, L"");      /* one face per family (CHECK) */
+    EnumFontFamiliesExW(fmi.screenDC, &lfw,
+                        (FONTENUMPROCW)EnumFamilyNamesW,
+                        (LPARAM)(&fmi), 0L);
+
+    /* Use the windows registry to map font names to files */
+    fontKeyName =  FONTKEY_NT;
+    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                       fontKeyName, 0L, KEY_READ, &hkeyFonts);
+    if (ret != ERROR_SUCCESS) {
+        ReleaseDC(NULL, fmi.screenDC);
+        fmi.screenDC = NULL;
+        return;
+    }
+
+    ret = RegQueryInfoKeyW(hkeyFonts, NULL, NULL, NULL, NULL, NULL, NULL,
+                           &dwNumValues, &dwMaxValueNameLen,
+                           &dwMaxValueDataLen, NULL, NULL);
+    
+    if (ret != ERROR_SUCCESS ||
+        dwMaxValueNameLen >= MAX_BUFFER ||
+        dwMaxValueDataLen >= MAX_BUFFER) {
+        RegCloseKey(hkeyFonts);
+        ReleaseDC(NULL, fmi.screenDC);
+        fmi.screenDC = NULL;
+        return;
+    }
+    for (nval = 0; nval < dwNumValues; nval++ ) {
+        dwNameSize = MAX_BUFFER;
+        dwDataValueSize = MAX_BUFFER;
+            ret = RegEnumValueW(hkeyFonts, nval, (LPWSTR)wname, &dwNameSize,
+                                NULL, &type, (LPBYTE)data, &dwDataValueSize);
+        if (ret != ERROR_SUCCESS) {
+            break;
+        }
+        if (type != REG_SZ) { /* REG_SZ means a null-terminated string */
+            continue;
+        }
+            if (!RegistryToBaseTTNameW((LPWSTR)wname) ) {
+                /* If the filename ends with ".ttf" or ".otf" also accept it.
+                 * REMIND : in fact not accepting .otf's for now as the
+                 * upstream code isn't expecting them.
+                 * Not expecting to need to do this for .ttc files.
+                 * Also note this code is not mirrored in the "A" (win9x) path.
+                 */
+                LPWSTR dot = wcsrchr((LPWSTR)data, L'.');
+                if (dot == NULL || ((wcsicmp(dot, L".ttf") != 0)
+                                    /* && (wcsicmp(dot, L".otf") != 0) */)) {
+                    continue;  /* not a TT font... */
+                }
+            }
+            registerFontW(&fmi, fontToFileMap, (LPWSTR)wname, (LPWSTR)data);
+    }
+    RegCloseKey(hkeyFonts);
+    ReleaseDC(NULL, fmi.screenDC);
+    fmi.screenDC = NULL;
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_sun_javafx_font_PrismFontFactory_regReadFontLink(JNIEnv *env, jclass obj, jstring lpFontName)
+{
+    LONG lResult;
+    BYTE* buf;
+    DWORD dwBufSize = sizeof(buf);
+    DWORD dwType = REG_MULTI_SZ;
+    HKEY hKey;
+    LPCWSTR fontpath = NULL;
+    jstring linkStr;
+
+    LPWSTR lpSubKey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink";
+    lResult = RegOpenKeyExW (HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey);
+    if (lResult != ERROR_SUCCESS) 
+    {
+        return (jstring)NULL;
+    } 
+
+    fontpath = (*env)->GetStringChars(env, lpFontName, (jboolean*) NULL);
+
+    //get the buffer size
+    lResult = RegQueryValueExW(hKey, fontpath, 0, &dwType, NULL, &dwBufSize);
+    if ((lResult == ERROR_SUCCESS) && (dwBufSize > 0)) {
+        buf = malloc( dwBufSize );
+        if (buf == NULL) {
+            (*env)->ReleaseStringChars(env, lpFontName, fontpath);
+            RegCloseKey (hKey);
+            return (jstring)NULL;
+        }
+        lResult = RegQueryValueExW(hKey, fontpath, 0, &dwType, (BYTE*)buf, 
+                                   &dwBufSize);
+        (*env)->ReleaseStringChars(env, lpFontName, fontpath);
+        RegCloseKey (hKey);
+        
+        if (lResult != ERROR_SUCCESS) {
+            free(buf);
+            return (jstring)NULL;                       
+        }       
+    } else {
+        return (jstring)NULL;
+    }
+
+    linkStr = (*env)->NewString(env, (LPWSTR)buf, dwBufSize/sizeof(WCHAR));
+    free(buf);
+    return linkStr;
+}
+
+
+typedef  unsigned short  LANGID;
+
+
+#define LANGID_JA_JP   0x411
+#define LANGID_ZH_CN   0x0804
+#define LANGID_ZH_SG   0x1004
+#define LANGID_ZH_TW   0x0404
+#define LANGID_ZH_HK   0x0c04
+#define LANGID_ZH_MO   0x1404
+#define LANGID_KO_KR   0x0412
+#define LANGID_US      0x409
+
+static const wchar_t EUDCKEY_JA_JP[] = L"EUDC\\932";
+static const wchar_t EUDCKEY_ZH_CN[] = L"EUDC\\936";
+static const wchar_t EUDCKEY_ZH_TW[] = L"EUDC\\950";
+static const wchar_t EUDCKEY_KO_KR[] = L"EUDC\\949";
+static const wchar_t EUDCKEY_DEFAULT[] = L"EUDC\\1252";
+
+
+JNIEXPORT jstring JNICALL
+Java_com_sun_javafx_font_PrismFontFactory_getEUDCFontFile(JNIEnv *env, jclass cl) {
+    int    rc;
+    HKEY   key;
+    DWORD  type;
+    WCHAR  fontPathBuf[MAX_PATH + 1];
+    DWORD  fontPathLen = MAX_PATH + 1;
+    WCHAR  tmpPath[MAX_PATH + 1];
+    LPWSTR fontPath = fontPathBuf;
+    LPWSTR eudcKey = NULL;
+                
+    LANGID langID = GetSystemDefaultLangID();
+
+    //lookup for encoding ID, EUDC only supported in
+    //codepage 932, 936, 949, 950 (and unicode)
+    if (langID == LANGID_JA_JP) {
+        eudcKey = EUDCKEY_JA_JP;
+    } else if (langID == LANGID_ZH_CN || langID == LANGID_ZH_SG) {
+        eudcKey = EUDCKEY_ZH_CN;
+    } else if (langID == LANGID_ZH_HK || langID == LANGID_ZH_TW ||
+               langID == LANGID_ZH_MO) {
+        eudcKey = EUDCKEY_ZH_TW;
+    } else if (langID == LANGID_KO_KR) {
+        eudcKey = EUDCKEY_KO_KR;
+    } else if (langID == LANGID_US) {
+        eudcKey = EUDCKEY_DEFAULT;
+    } else {
+        return NULL;
+    }
+
+    rc = RegOpenKeyExW(HKEY_CURRENT_USER, eudcKey, 0, KEY_READ, &key);
+    if (rc != ERROR_SUCCESS) {
+        return NULL;
+    }
+    rc = RegQueryValueExW(key,
+                         L"SystemDefaultEUDCFont",
+                         0,
+                         &type,
+                         (LPBYTE)fontPath,
+                         &fontPathLen);
+    RegCloseKey(key);
+    fontPathLen /= sizeof(WCHAR);
+    if (rc != ERROR_SUCCESS || type != REG_SZ ||
+        (fontPathLen > MAX_PATH)) {
+        return NULL;
+    }
+
+    fontPath[fontPathLen] = L'\0';
+    if (wcsstr(fontPath, L"%SystemRoot%") == fontPath) {
+        //if the fontPath includes %SystemRoot%
+        LPWSTR systemRoot = _wgetenv(L"SystemRoot");
+        // Subtract 12, being the length of "SystemRoot".
+        if ((systemRoot == NULL) || 
+           (fontPathLen-12 +wcslen(systemRoot) > MAX_PATH)) {
+                return NULL;
+        }
+        wcscpy(tmpPath, systemRoot);
+        wcscat(tmpPath, (wchar_t *)(fontPath+12));
+        fontPath = tmpPath;
+        fontPathLen = wcslen(tmpPath);
+
+    } else if (wcscmp(fontPath, L"EUDC.TTE") == 0) {
+        //else to see if it only inludes "EUDC.TTE"
+        WCHAR systemRoot[MAX_PATH];
+        UINT ret = GetWindowsDirectoryW(systemRoot, MAX_PATH); 
+        if ( ret != 0) {
+            if (ret + 16 > MAX_PATH) {
+                return NULL;
+            }
+            wcscpy(fontPath, systemRoot);
+            wcscat(fontPath, L"\\FONTS\\EUDC.TTE");
+            fontPathLen = wcslen(fontPath);
+        }
+        else {
+            return NULL;
+        }
+    }
+    return (*env)->NewString(env, (LPWSTR)fontPath, fontPathLen);
+}
+
+static BOOL getSysParams(NONCLIENTMETRICSW* ncmetrics) {
+
+    OSVERSIONINFOEX osvi;
+    int cbsize;
+
+    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+    if (!(GetVersionEx((OSVERSIONINFO *)&osvi))) {
+        return FALSE;
+    }
+  
+    // See JDK bug 6944516: specify correct size for ncmetrics on Windows XP
+    // Microsoft recommend to subtract the size of the 'iPaddedBorderWidth'
+    // field when running on XP. Yuck.
+    if (osvi.dwMajorVersion < 6) { // 5 is XP, 6 is Vista.
+        cbsize = offsetof(NONCLIENTMETRICSW, iPaddedBorderWidth);
+    } else {
+        cbsize = sizeof(*ncmetrics);
+    }
+    ZeroMemory(ncmetrics, cbsize);
+    ncmetrics->cbSize = cbsize;
+
+    return SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
+                                 ncmetrics->cbSize, ncmetrics, FALSE);
+}
+
+
+/*
+ * Class:     Java_com_sun_javafx_font_PrismFontFactory
+ * Method:    getLCDContrast
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_javafx_font_PrismFontFactory_getLCDContrast
+  (JNIEnv *env, jobject klass) {
+
+    unsigned int fontSmoothingContrast;
+    static const int fontSmoothingContrastDefault = 1300;
+
+    return SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0,
+        &fontSmoothingContrast, 0) ? fontSmoothingContrast : fontSmoothingContrastDefault;
+}
+
+JNIEXPORT jint JNICALL
+Java_com_sun_javafx_font_PrismFontFactory_getSystemFontSizeNative(JNIEnv *env, jclass cl)
+{
+    NONCLIENTMETRICSW ncmetrics;
+
+    if (getSysParams(&ncmetrics)) {
+        return -ncmetrics.lfMessageFont.lfHeight;
+    } else {
+        return 12;
+    }
+}
+
+JNIEXPORT jstring JNICALL
+Java_com_sun_javafx_font_PrismFontFactory_getSystemFontNative(JNIEnv *env, jclass cl) {
+
+    NONCLIENTMETRICSW ncmetrics;
+
+    if (getSysParams(&ncmetrics)) {
+        int len = wcslen(ncmetrics.lfMessageFont.lfFaceName);
+        return (*env)->NewString(env, ncmetrics.lfMessageFont.lfFaceName, len);
+    } else {
+        return NULL;
+    }
+}
+
+
+JNIEXPORT jshort JNICALL
+Java_com_sun_javafx_font_PrismFontFactory_getSystemLCID(JNIEnv *env, jclass cl)
+{
+    LCID lcid = GetSystemDefaultLCID();
+    DWORD value;
+
+    int ret = GetLocaleInfoW(lcid,
+                             LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER,
+                             (LPTSTR)&value,
+                             sizeof(value) / sizeof(TCHAR));
+    return (jshort)value;
+}
+
+#endif /* WIN32 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font-native/src/fontpath_linux.c	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,773 @@
+/*
+ * Copyright (c) 2012, 2013, 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.
+ */
+
+#if defined (__linux__) && ! defined (ANDROID_NDK)
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <dlfcn.h>
+#include <fontconfig/fontconfig.h>
+
+#include <jni.h>
+
+/*
+ * We are not explicitly linking against fontconfig. This isn't so
+ * relevant for desktop platforms any more but could help on embedded
+ * platforms where it may not exist.
+ */
+
+static void* openFontConfig() {
+
+    char *homeEnv;
+    static char *homeEnvStr = "HOME="; /* must be static */
+    void* libfontconfig = NULL;
+
+    /* 64 bit sparc should pick up the right version from the lib path.
+     * New features may be added to libfontconfig, this is expected to
+     * be compatible with old features, but we may need to start
+     * distinguishing the library version, to know whether to expect
+     * certain symbols - and functionality - to be available.
+     * Also add explicit search for .so.1 in case .so symlink doesn't exist.
+     */
+    libfontconfig = dlopen("libfontconfig.so.1", RTLD_LOCAL|RTLD_LAZY);
+    if (libfontconfig == NULL) {
+        libfontconfig = dlopen("libfontconfig.so", RTLD_LOCAL|RTLD_LAZY);
+        if (libfontconfig == NULL) {
+            return NULL;
+        }
+    }
+
+    /* Version 1.0 of libfontconfig crashes if HOME isn't defined in
+     * the environment. This should generally never happen, but we can't
+     * control it, and can't control the version of fontconfig, so iff
+     * its not defined we set it to an empty value which is sufficient
+     * to prevent a crash. I considered unsetting it before exit, but
+     * it doesn't appear to work on Solaris, so I will leave it set.
+     */
+    homeEnv = getenv("HOME");
+    if (homeEnv == NULL) {
+        putenv(homeEnvStr);
+    }
+
+    return libfontconfig;
+}
+
+typedef void* (FcFiniFuncType)();
+
+static void closeFontConfig(void* libfontconfig, jboolean fcFini) {
+
+  /* NB FcFini is not in (eg) the Solaris 10 version of fontconfig. Its not
+   * clear if this means we are really leaking resources in those cases
+   * but it seems we should call this function when its available.
+   * But since the Swing GTK code may be still accessing the lib, its probably
+   * safest for now to just let this "leak" rather than potentially
+   * concurrently free global data still in use by other code.
+   */
+#if 0
+    if (fcFini) { /* release resources */
+        FcFiniFuncType FcFini = (FcFiniFuncType)dlsym(libfontconfig, "FcFini");
+
+        if (FcFini != NULL) {
+            (*FcFini)();
+        }
+    }
+#endif
+    dlclose(libfontconfig);
+}
+
+typedef FcConfig* (*FcInitLoadConfigFuncType)();
+typedef FcPattern* (*FcPatternBuildFuncType)(FcPattern *orig, ...);
+typedef FcObjectSet* (*FcObjectSetFuncType)(const char *first, ...);
+typedef FcFontSet* (*FcFontListFuncType)(FcConfig *config,
+                                         FcPattern *p,
+                                         FcObjectSet *os);
+typedef FcResult (*FcPatternGetBoolFuncType)(const FcPattern *p,
+                                               const char *object,
+                                               int n,
+                                               FcBool *b);
+typedef FcResult (*FcPatternGetIntegerFuncType)(const FcPattern *p,
+                                                const char *object,
+                                                int n,
+                                                int *i);
+typedef FcResult (*FcPatternGetStringFuncType)(const FcPattern *p,
+                                               const char *object,
+                                               int n,
+                                               FcChar8 ** s);
+typedef void (*FcPatternDestroyFuncType)(FcPattern *p);
+typedef void (*FcFontSetDestroyFuncType)(FcFontSet *s);
+typedef FcPattern* (*FcNameParseFuncType)(const FcChar8 *name);
+typedef FcBool (*FcPatternAddStringFuncType)(FcPattern *p,
+                                             const char *object,
+                                             const FcChar8 *s);
+typedef void (*FcDefaultSubstituteFuncType)(FcPattern *p);
+typedef FcBool (*FcConfigSubstituteFuncType)(FcConfig *config,
+                                             FcPattern *p,
+                                             FcMatchKind kind);
+typedef FcPattern* (*FcFontMatchFuncType)(FcConfig *config,
+                                          FcPattern *p,
+                                          FcResult *result);
+typedef FcFontSet* (*FcFontSetCreateFuncType)();
+typedef FcBool (*FcFontSetAddFuncType)(FcFontSet *s, FcPattern *font);
+
+typedef FcResult (*FcPatternGetCharSetFuncType)(FcPattern *p,
+                                                const char *object,
+                                                int n,
+                                                FcCharSet **c);
+typedef FcFontSet* (*FcFontSortFuncType)(FcConfig *config,
+                                         FcPattern *p,
+                                         FcBool trim,
+                                         FcCharSet **csp,
+                                         FcResult *result);
+
+typedef FcCharSet* (*FcCharSetUnionFuncType)(const FcCharSet *a,
+                                             const FcCharSet *b);
+typedef FcChar32 (*FcCharSetSubtractCountFuncType)(const FcCharSet *a,
+                                                   const FcCharSet *b);
+
+JNIEXPORT jboolean JNICALL
+Java_com_sun_javafx_font_FontConfigManager_getFontConfig
+(JNIEnv *env, jclass obj, jstring localeStr,
+ jobjectArray fcCompFontArray, jboolean includeFallbacks) {
+
+    FcNameParseFuncType FcNameParse;
+    FcPatternAddStringFuncType FcPatternAddString;
+    FcConfigSubstituteFuncType FcConfigSubstitute;
+    FcDefaultSubstituteFuncType  FcDefaultSubstitute;
+    FcFontMatchFuncType FcFontMatch;
+    FcPatternGetStringFuncType FcPatternGetString;
+    FcPatternDestroyFuncType FcPatternDestroy;
+    FcPatternGetCharSetFuncType FcPatternGetCharSet;
+    FcFontSortFuncType FcFontSort;
+    FcFontSetDestroyFuncType FcFontSetDestroy;
+    FcCharSetUnionFuncType FcCharSetUnion;
+    FcCharSetSubtractCountFuncType FcCharSetSubtractCount;
+
+    int i, arrlen;
+    jstring fcNameStr, jstr;
+    const char *locale, *fcName;
+    FcPattern *pattern;
+    FcResult result;
+    void* libfontconfig;
+    jfieldID fcNameFID, fcFirstFontFID, fcAllFontsFID;
+    jfieldID familyNameFID, styleNameFID, fullNameFID, fontFileFID;
+    jmethodID fcFontCons;
+    jclass fcCompFontClass, fcFontClass;
+
+
+    // Deleting local refs as we go along so this should be plenty
+    // Unlikely to matter even if it fails.
+    (*env)->EnsureLocalCapacity(env, 64);
+
+    fcCompFontClass =
+        (*env)->FindClass(env,
+                       "com/sun/javafx/font/FontConfigManager$FcCompFont");
+    fcFontClass =
+         (*env)->FindClass(env,
+                       "com/sun/javafx/font/FontConfigManager$FontConfigFont");
+
+    if (fcCompFontArray == NULL ||
+        fcCompFontClass == NULL ||
+        fcFontClass == NULL)
+    {
+        return JNI_FALSE;
+    }
+
+    fcNameFID = (*env)->GetFieldID(env, fcCompFontClass,
+                                   "fcName", "Ljava/lang/String;");
+    fcFirstFontFID =
+        (*env)->GetFieldID(env, fcCompFontClass, "firstFont",
+                  "Lcom/sun/javafx/font/FontConfigManager$FontConfigFont;");
+
+    fcAllFontsFID =
+        (*env)->GetFieldID(env, fcCompFontClass, "allFonts",
+                  "[Lcom/sun/javafx/font/FontConfigManager$FontConfigFont;");
+
+    fcFontCons = (*env)->GetMethodID(env, fcFontClass, "<init>", "()V");
+
+    familyNameFID = (*env)->GetFieldID(env, fcFontClass,
+                                       "familyName", "Ljava/lang/String;");
+    styleNameFID = (*env)->GetFieldID(env, fcFontClass,
+                                      "styleStr", "Ljava/lang/String;");
+    fullNameFID = (*env)->GetFieldID(env, fcFontClass,
+                                     "fullName", "Ljava/lang/String;");
+    fontFileFID = (*env)->GetFieldID(env, fcFontClass,
+                                     "fontFile", "Ljava/lang/String;");
+
+    if (fcNameFID == NULL ||
+        fcFirstFontFID == NULL ||
+        fcAllFontsFID == NULL ||
+        fcFontCons == NULL ||
+        familyNameFID == NULL ||
+        styleNameFID == NULL ||
+        fullNameFID == NULL ||
+        fontFileFID == NULL)
+    {
+        return JNI_FALSE;
+    }
+
+    if ((libfontconfig = openFontConfig()) == NULL) {
+        return JNI_FALSE;
+    }
+
+    FcNameParse = (FcNameParseFuncType)dlsym(libfontconfig, "FcNameParse");
+    FcPatternAddString =
+        (FcPatternAddStringFuncType)dlsym(libfontconfig, "FcPatternAddString");
+    FcConfigSubstitute =
+        (FcConfigSubstituteFuncType)dlsym(libfontconfig, "FcConfigSubstitute");
+    FcDefaultSubstitute = (FcDefaultSubstituteFuncType)
+        dlsym(libfontconfig, "FcDefaultSubstitute");
+    FcFontMatch = (FcFontMatchFuncType)dlsym(libfontconfig, "FcFontMatch");
+    FcPatternGetString =
+        (FcPatternGetStringFuncType)dlsym(libfontconfig, "FcPatternGetString");
+    FcPatternDestroy =
+        (FcPatternDestroyFuncType)dlsym(libfontconfig, "FcPatternDestroy");
+    FcPatternGetCharSet =
+        (FcPatternGetCharSetFuncType)dlsym(libfontconfig,
+                                           "FcPatternGetCharSet");
+    FcFontSort =
+        (FcFontSortFuncType)dlsym(libfontconfig, "FcFontSort");
+    FcFontSetDestroy =
+        (FcFontSetDestroyFuncType)dlsym(libfontconfig, "FcFontSetDestroy");
+    FcCharSetUnion =
+        (FcCharSetUnionFuncType)dlsym(libfontconfig, "FcCharSetUnion");
+    FcCharSetSubtractCount =
+        (FcCharSetSubtractCountFuncType)dlsym(libfontconfig,
+                                              "FcCharSetSubtractCount");
+
+    if (FcNameParse          == NULL ||
+        FcPatternAddString   == NULL ||
+        FcConfigSubstitute   == NULL ||
+        FcDefaultSubstitute  == NULL ||
+        FcFontMatch          == NULL ||
+        FcPatternGetString   == NULL ||
+        FcPatternDestroy     == NULL ||
+        FcPatternGetCharSet  == NULL ||
+        FcFontSetDestroy     == NULL ||
+        FcCharSetUnion       == NULL ||
+        FcCharSetSubtractCount == NULL) {/* problem with the library: return.*/
+        closeFontConfig(libfontconfig, JNI_FALSE);
+        return JNI_FALSE;
+    }
+
+    locale = (*env)->GetStringUTFChars(env, localeStr, 0);
+
+    arrlen = (*env)->GetArrayLength(env, fcCompFontArray);
+    for (i=0; i<arrlen; i++) {
+        FcFontSet* fontset;
+        int fn, j, fontCount, nfonts;
+        unsigned int minGlyphs;
+        FcChar8 **family, **styleStr, **fullname, **file;
+        jarray fcFontArr;
+        jobject fcCompFontObj;
+
+        fcCompFontObj = (*env)->GetObjectArrayElement(env, fcCompFontArray, i);
+        fcNameStr =
+            (jstring)((*env)->GetObjectField(env, fcCompFontObj, fcNameFID));
+        fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
+        if (fcName == NULL) {
+            continue;
+        }
+        pattern = (*FcNameParse)((FcChar8 *)fcName);
+        if (pattern == NULL) {
+            (*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
+            closeFontConfig(libfontconfig, JNI_FALSE);
+            return JNI_FALSE;
+        }
+
+        /* locale may not usually be necessary as fontconfig appears to apply
+         * this anyway based on the user's environment. However we want
+         * to use the value of the JDK startup locale so this should take
+         * care of it.
+         */
+        if (locale != NULL) {
+            (*FcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
+        }
+        (*FcConfigSubstitute)(NULL, pattern, FcMatchPattern);
+        (*FcDefaultSubstitute)(pattern);
+        fontset = (*FcFontSort)(NULL, pattern, FcTrue, NULL, &result);
+        if (fontset == NULL) {
+            (*FcPatternDestroy)(pattern);
+            (*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
+            closeFontConfig(libfontconfig, JNI_FALSE);
+            return JNI_FALSE;
+        }
+
+        /* fontconfig returned us "nfonts". It may include Type 1 fonts
+         * but we are going to skip those.
+         * Next create separate C arrays of length nfonts for family file etc.
+         * Inspect the returned fonts and the ones we like (adds enough glyphs)
+         * are added to the arrays and we increment 'fontCount'.
+         */
+        nfonts = fontset->nfont;
+        family   = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
+        styleStr = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
+        fullname = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
+        file     = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
+        if (family == NULL || styleStr == NULL ||
+            fullname == NULL || file == NULL) {
+            if (family != NULL) {
+                free(family);
+            }
+            if (styleStr != NULL) {
+                free(styleStr);
+            }
+            if (fullname != NULL) {
+                free(fullname);
+            }
+            if (file != NULL) {
+                free(file);
+            }
+            (*FcPatternDestroy)(pattern);
+            (*FcFontSetDestroy)(fontset);
+            (*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
+            closeFontConfig(libfontconfig, JNI_FALSE);
+            return JNI_FALSE;
+        }
+        fontCount = 0;
+        minGlyphs = 20;
+        for (j=0; j<nfonts; j++) {
+            FcPattern *fontPattern = fontset->fonts[j];
+            FcChar8 *fontformat;
+            FcCharSet *unionCharset = NULL, *charset;
+
+            fontformat = NULL;
+            (*FcPatternGetString)(fontPattern, FC_FONTFORMAT, 0, &fontformat);
+            /* We only want TrueType fonts for Java FX */
+            if (fontformat != NULL
+                && (strcmp((char*)fontformat, "TrueType") != 0)) {
+                continue;
+            }
+            result = (*FcPatternGetCharSet)(fontPattern,
+                                            FC_CHARSET, 0, &charset);
+            if (result != FcResultMatch) {
+                free(family);
+                free(fullname);
+                free(styleStr);
+                free(file);
+                (*FcPatternDestroy)(pattern);
+                (*FcFontSetDestroy)(fontset);
+                (*env)->ReleaseStringUTFChars(env,
+                                              fcNameStr, (const char*)fcName);
+                closeFontConfig(libfontconfig, JNI_FALSE);
+                return JNI_FALSE;
+            }
+
+            /* We don't want 20 or 30 fonts, so once we hit 10 fonts,
+             * then require that they really be adding value. Too many
+             * adversely affects load time for minimal value-add.
+             * This is still likely far more than we've had in the past.
+             */
+            if (j==10) {
+                minGlyphs = 50;
+            }
+            if (unionCharset == NULL) {
+                unionCharset = charset;
+            } else {
+                if ((*FcCharSetSubtractCount)(charset, unionCharset)
+                    > minGlyphs) {
+                    unionCharset = (* FcCharSetUnion)(unionCharset, charset);
+                } else {
+                    continue;
+                }
+            }
+
+            fontCount++; // found a font we will use.
+            (*FcPatternGetString)(fontPattern, FC_FILE, 0, &file[j]);
+            (*FcPatternGetString)(fontPattern, FC_FAMILY, 0, &family[j]);
+            (*FcPatternGetString)(fontPattern, FC_STYLE, 0, &styleStr[j]);
+            (*FcPatternGetString)(fontPattern, FC_FULLNAME, 0, &fullname[j]);
+            if (!includeFallbacks) {
+                break;
+            }
+        }
+
+        /* Once we get here 'fontCount' is the number of returned fonts
+         * we actually want to use, so we create 'fcFontArr' of that length.
+         * The non-null entries of "family[]" etc are those fonts.
+         * Then loop again over all nfonts adding just those non-null ones
+         * to 'fcFontArr'. If its null (we didn't want the font)
+         * then we don't enter the main body.
+         * So we should never get more than 'fontCount' entries.
+         */
+        if (includeFallbacks) {
+            fcFontArr =
+                (*env)->NewObjectArray(env, fontCount, fcFontClass, NULL);
+            (*env)->SetObjectField(env,
+                                   fcCompFontObj, fcAllFontsFID, fcFontArr);
+        } else {
+            fcFontArr = NULL;
+        }
+        fn=0;
+
+        for (j=0;j<nfonts;j++) {
+            if (family[j] != NULL) {
+                jobject fcFont =
+                    (*env)->NewObject(env, fcFontClass, fcFontCons);
+                jstr = (*env)->NewStringUTF(env, (const char*)family[j]);
+                (*env)->SetObjectField(env, fcFont, familyNameFID, jstr);
+                (*env)->DeleteLocalRef(env, jstr);
+                if (file[j] != NULL) {
+                    jstr = (*env)->NewStringUTF(env, (const char*)file[j]);
+                    (*env)->SetObjectField(env, fcFont, fontFileFID, jstr);
+                }
+                if (styleStr[j] != NULL) {
+                    jstr = (*env)->NewStringUTF(env, (const char*)styleStr[j]);
+                    (*env)->SetObjectField(env, fcFont, styleNameFID, jstr);
+                    (*env)->DeleteLocalRef(env, jstr);
+                }
+                if (fullname[j] != NULL) {
+                    jstr = (*env)->NewStringUTF(env, (const char*)fullname[j]);
+                    (*env)->SetObjectField(env, fcFont, fullNameFID, jstr);
+                    (*env)->DeleteLocalRef(env, jstr);
+                }
+                if (fn==0) {
+                    (*env)->SetObjectField(env, fcCompFontObj,
+                                           fcFirstFontFID, fcFont);
+                }
+                if (includeFallbacks && fcFontArr != NULL) {
+                    (*env)->SetObjectArrayElement(env, fcFontArr, fn++,fcFont);
+                    (*env)->DeleteLocalRef(env, fcFont);
+                } else {
+                    (*env)->DeleteLocalRef(env, fcFont);
+                    break;
+                }
+            }
+        }
+        if (fcFontArr != NULL) {
+            (*env)->DeleteLocalRef(env, fcFontArr);
+        }
+        (*env)->ReleaseStringUTFChars (env, fcNameStr, (const char*)fcName);
+        (*FcFontSetDestroy)(fontset);
+        (*FcPatternDestroy)(pattern);
+        free(family);
+        free(styleStr);
+        free(fullname);
+        free(file);
+    }
+
+    /* release resources and close the ".so" */
+
+    if (locale) {
+        (*env)->ReleaseStringUTFChars (env, localeStr, (const char*)locale);
+    }
+    closeFontConfig(libfontconfig, JNI_TRUE);
+    return JNI_TRUE;
+}
+
+
+JNIEXPORT jboolean JNICALL
+Java_com_sun_javafx_font_FontConfigManager_populateMapsNative
+(JNIEnv *env, jclass obj,
+ jobject fontToFileMap,
+ jobject fontToFamilyNameMap,
+ jobject familyToFontListMap,
+ jobject locale
+ )
+{
+    void *libfontconfig;
+    const char *lang;
+    int langLen, f;
+    FcPatternBuildFuncType FcPatternBuild;
+    FcObjectSetFuncType FcObjectSetBuild;
+    FcFontListFuncType FcFontList;
+    FcPatternGetStringFuncType FcPatternGetString;
+    FcFontSetDestroyFuncType FcFontSetDestroy;
+    FcPattern *pattern;
+    FcObjectSet *objset;
+    FcFontSet *fontSet;
+    jclass classID, arrayListClass;
+    jmethodID arrayListCtr, addMID, getMID;
+    jmethodID toLowerCaseMID;
+    jmethodID putMID, containsKeyMID;
+    jboolean debugFC = getenv("PRISM_FONTCONFIG_DEBUG") != NULL;
+
+    if (fontToFileMap == NULL ||
+        fontToFamilyNameMap == NULL ||
+        familyToFontListMap == NULL ||
+        locale == NULL)
+    {
+        if (debugFC) {
+            fprintf(stderr, "Null arg to native fontconfig lookup");
+        }
+        return JNI_FALSE;
+    }
+    if ((libfontconfig = openFontConfig()) == NULL) {
+        if (debugFC) {
+            fprintf(stderr,"Could not open libfontconfig\n");
+        }
+        return JNI_FALSE;
+    }
+
+    FcPatternBuild     =
+        (FcPatternBuildFuncType)dlsym(libfontconfig, "FcPatternBuild");
+    FcObjectSetBuild   =
+        (FcObjectSetFuncType)dlsym(libfontconfig, "FcObjectSetBuild");
+    FcFontList         =
+        (FcFontListFuncType)dlsym(libfontconfig, "FcFontList");
+    FcPatternGetString =
+        (FcPatternGetStringFuncType)dlsym(libfontconfig, "FcPatternGetString");
+    FcFontSetDestroy   =
+        (FcFontSetDestroyFuncType)dlsym(libfontconfig, "FcFontSetDestroy");
+
+    if (FcPatternBuild     == NULL ||
+        FcObjectSetBuild   == NULL ||
+        FcPatternGetString == NULL ||
+        FcFontList         == NULL ||
+        FcFontSetDestroy   == NULL) { /* problem with the library: return. */
+        if (debugFC) {
+           fprintf(stderr,"Could not find symbols in libfontconfig\n"); 
+        }
+        closeFontConfig(libfontconfig, JNI_FALSE);
+        return JNI_FALSE;
+    }
+
+    // Deleting local refs as we go along so this should be plenty
+    // Unlikely to matter even if it fails.
+    (*env)->EnsureLocalCapacity(env, 64);
+    classID = (*env)->FindClass(env, "java/util/HashMap");
+    if (classID == NULL) {
+        return JNI_FALSE;
+    }
+    getMID = (*env)->GetMethodID(env, classID, "get",
+                 "(Ljava/lang/Object;)Ljava/lang/Object;");
+    if (getMID == NULL) {
+        return JNI_FALSE;
+    }
+    putMID = (*env)->GetMethodID(env, classID, "put",
+                 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+    if (putMID == NULL) {
+        return JNI_FALSE;
+    }
+
+    containsKeyMID = (*env)->GetMethodID(env, classID, "containsKey",
+                                             "(Ljava/lang/Object;)Z");
+    if (containsKeyMID == NULL) {
+        return JNI_FALSE;
+    }
+
+    arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
+    if (arrayListClass == NULL) {
+        return JNI_FALSE;
+    }
+    arrayListCtr = (*env)->GetMethodID(env, arrayListClass,
+                                              "<init>", "(I)V");
+    if (arrayListCtr == NULL) {
+        return JNI_FALSE;
+    }
+    addMID = (*env)->GetMethodID(env, arrayListClass,
+                                 "add", "(Ljava/lang/Object;)Z");
+    if (addMID == NULL) {
+        return JNI_FALSE;
+    }
+
+    classID = (*env)->FindClass(env, "java/lang/String");
+    if (classID == NULL) {
+        return JNI_FALSE;
+    }
+    toLowerCaseMID =
+        (*env)->GetMethodID(env, classID, "toLowerCase",
+                            "(Ljava/util/Locale;)Ljava/lang/String;");
+    if (toLowerCaseMID == NULL) {
+        return JNI_FALSE;
+    }
+    pattern = (*FcPatternBuild)(NULL, FC_OUTLINE, FcTypeBool, FcTrue, NULL);
+    objset = (*FcObjectSetBuild)(FC_FAMILY, FC_FAMILYLANG,
+                                 FC_FULLNAME, FC_FULLNAMELANG,
+                                 FC_FILE, FC_FONTFORMAT, NULL);
+    fontSet = (*FcFontList)(NULL, pattern, objset);
+
+    if (debugFC) {
+        fprintf(stderr,"Fontconfig found %d fonts\n", fontSet->nfont);
+    }
+
+    for (f=0; f < fontSet->nfont; f++) {
+        int n=0, done=0;
+        FcPattern *fp = fontSet->fonts[f];
+
+        FcChar8 *family = NULL;
+        FcChar8 *familyEN = NULL;
+        FcChar8 *familyLang = NULL;
+        FcChar8 *fullName = NULL;
+        FcChar8 *fullNameEN = NULL;
+        FcChar8 *fullNameLang = NULL;
+        FcChar8 *file;
+        FcResult res;
+        jstring jFileStr;
+        jstring jFamilyStr, jFamilyStrLC;
+        jstring jFullNameStr, jFullNameStrLC;
+        jobject jList;
+        FcChar8 *format = NULL;
+
+        /* We only want TrueType & OpenType fonts for Java FX */
+        format = NULL;
+        if ((*FcPatternGetString)(fp, FC_FONTFORMAT, 0, &format)
+            != FcResultMatch) {
+            continue;
+        }
+        if (format == NULL ||
+            ((strcmp((char*)format, "TrueType") != 0) &&
+             (strcmp((char*)format, "CFF") != 0))) {
+            continue;
+        }
+        if ((*FcPatternGetString)(fp, FC_FILE, 0, &file) != FcResultMatch) {
+            continue;
+        } else {
+            char pathname[PATH_MAX+1];
+            char* path = realpath((char*)file, pathname);
+            if (path == NULL) {
+                continue;
+            } else {
+                file = (FcChar8*)path;
+            }
+        }
+        n=0;
+        while (!done) {
+            family = NULL;
+            familyLang = NULL;
+            fullName = NULL;
+            fullNameLang = NULL;
+
+            if (((*FcPatternGetString)(fp, FC_FAMILY, n, &family)
+                == FcResultMatch) &&
+                ((*FcPatternGetString)(fp, FC_FAMILYLANG, n, &familyLang)
+                == FcResultMatch) &&
+                (family != NULL && familyLang != NULL) &&
+                (familyEN == NULL || (strcmp((char*)familyLang, "en") == 0)))
+            {
+                familyEN = family;
+            }
+            if (((*FcPatternGetString)(fp, FC_FULLNAME, n, &fullName)
+                == FcResultMatch) &&
+                ((*FcPatternGetString)(fp, FC_FULLNAMELANG, n, &fullNameLang)
+                == FcResultMatch) &&
+                (fullName != NULL && fullNameLang != NULL) &&
+                (fullNameEN == NULL ||
+                 (strcmp((char*)fullNameLang,"en") == 0)))
+            {
+                fullNameEN = fullName;
+            }
+            if (family == NULL && fullName == NULL) {
+                done = 1;
+                break;
+            }
+            n++;
+        }
+
+        if (debugFC) {
+            fprintf(stderr,"Read FC font family=%s fullname=%s file=%s\n",
+                    (familyEN == NULL) ? "null" : (char*)familyEN,
+                    (fullNameEN == NULL) ? "null" : (char*)fullNameEN,
+                    (file == NULL) ? "null" : (char*)file);
+            fflush(stderr);
+        }
+
+        /* We set the names from the first found names for a font, updating
+         * to the English ones as they are found. If these are null
+         * we must not have found any name, so we'd better skip.
+         */
+        if (familyEN == NULL || fullNameEN == NULL || file == NULL) {
+            if (debugFC) {
+                fprintf(stderr,"FC: Skipping on error for above font\n");
+                fflush(stderr);
+            }
+            continue;
+        }
+
+        jFileStr = (*env)->NewStringUTF(env, (const char*)file);
+        jFamilyStr = (*env)->NewStringUTF(env, (const char*)familyEN);
+        jFullNameStr = (*env)->NewStringUTF(env, (const char*)fullNameEN);
+
+        if (jFileStr == NULL || jFamilyStr == NULL || jFullNameStr == NULL) {
+            if (debugFC) {
+                fprintf(stderr,"Failed to create string object");
+            }
+            continue;
+        }
+
+        jFamilyStrLC = (*env)->CallObjectMethod(env, jFamilyStr,
+                                                toLowerCaseMID, locale);
+        jFullNameStrLC = (*env)->CallObjectMethod(env, jFullNameStr,
+                                                  toLowerCaseMID, locale);
+
+        if (jFamilyStrLC == NULL || jFullNameStrLC == NULL) {
+            if (debugFC) {
+                fprintf(stderr,"Failed to create lower case string object");
+                fflush(stderr);
+            }
+            continue;
+        }
+
+        (*env)->CallObjectMethod(env, fontToFileMap, putMID,
+                                 jFullNameStrLC, jFileStr);
+        (*env)->CallObjectMethod(env, fontToFamilyNameMap, putMID,
+                                 jFullNameStrLC, jFamilyStr);
+
+        jList = (*env)->CallObjectMethod(env, familyToFontListMap,
+                                         getMID, jFamilyStrLC);
+
+        if (jList == NULL) {
+            jList = (*env)->NewObject(env, arrayListClass, arrayListCtr, 4);
+            (*env)->CallObjectMethod(env, familyToFontListMap,
+                                     putMID, jFamilyStrLC, jList);
+        }
+        if (jList == NULL) {
+            if (debugFC) {
+                fprintf(stderr,"Fontconfig: List is null\n");
+                fflush(stderr);
+            }
+            continue;
+        }
+        (*env)->CallObjectMethod(env, jList, addMID, jFullNameStr);
+
+        /* Now referenced from the passed in maps, so can delete local refs. */
+        (*env)->DeleteLocalRef(env, jFileStr);
+        (*env)->DeleteLocalRef(env, jFamilyStr);
+        (*env)->DeleteLocalRef(env, jFamilyStrLC);
+        (*env)->DeleteLocalRef(env, jFullNameStr);
+        (*env)->DeleteLocalRef(env, jFullNameStrLC);
+        (*env)->DeleteLocalRef(env, jList);
+
+    }
+    if (debugFC) {
+        fprintf(stderr,"Done enumerating fontconfig fonts\n");
+        fflush(stderr);
+    }
+    (*FcFontSetDestroy)(fontSet);
+    closeFontConfig(libfontconfig, JNI_TRUE);
+
+    return JNI_TRUE;
+}
+
+
+#endif /* __linux__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build-android.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font" default="all" basedir=".">
+
+  <script language="javascript">
+      var files = project.getProperty("javafx-font.jni.files");
+      project.setProperty("jni.classes", files.replaceAll("(.)java\\b", ",").replaceAll("/","."));
+  </script>
+  
+  <target name="compile-native" depends="jheaders, amble-fonts">
+      <exec executable="${android.ndk}/${ndk.build.cmd}" dir="${cpp.dir}" failonerror="true">
+          <arg line="APP_BUILD_SCRIPT=Android.mk NDK_PROJECT_PATH=. TARGET_PLATFORM=${android.ndk.target}"/>
+        </exec>
+        <copy todir="${native.dist.dir}" flatten="true">
+       <fileset dir="../javafx-font-native/libs" includes="${cross.platform.arch}/libjavafx-font.so"/>
+       </copy>
+  </target>
+
+  <target name="jheaders">
+        <echo>Generate jheaders for font t2k support</echo>
+        <mkdir dir="${native.build.dir}"/>
+     <javah 
+         destdir="${native.build.dir}" 
+         classpath="${javafx-font.classes.dir}:${javafx-font.javah.path}" force="yes"
+         class="${jni.classes}"/>
+  </target>
+
+  <target name="amble-fonts" unless="cross.amble-fonts.dontEmbedd">
+    <mkdir dir="build/classes/fonts"/>
+    <unzip src="${jfx.amble-fonts.jar}" dest="build/classes/fonts">
+      <patternset>
+        <include name="**/*.ttf"/>
+      </patternset>
+      <mapper type="flatten"/>
+    </unzip>
+  </target>
+
+  <target name="clean-native">
+      <delete dir="../javafx-font-native/libs"/>
+      <delete dir="../javafx-font-native/obj"/>
+      <delete dir="../javafx-font-native/build"/>
+      <delete dir="../javafx-font-native/dist"/>
+  </target>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build-closed.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font" default="jar" basedir=".">
+    <description>Builds, tests, and jars the closed version of the javafx-font project.</description>
+
+    <property name="rt.dist.root.dir" value="../../rt" />
+    <property name="runtime.dist.root.dir" value="../../rt-closed" />
+    <path id="javac.closed.classpath.path" path="
+        ${rt.dist.root.dir}/javafx-common/dist/javafx-common.jar:
+        ${rt.dist.root.dir}/javafx-ui-common/dist/javafx-ui-common.jar:
+        ${rt.dist.root.dir}/javafx-geom/dist/javafx-geom.jar:
+        ${rt.dist.root.dir}/glass/dist/lib/glass.jar" />
+    <property name="javac.classpath" refid="javac.closed.classpath.path"/>
+
+    <import file="../build-defs.xml"/>
+    <import file="build-common.xml"/>
+
+    <target name="jar" depends="javafx-font-common.jar"/>
+    <target name="clean" depends="javafx-font-common.clean"/>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build-common.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font-common" default="jar" basedir=".">
+
+  <property name="javafx-font.jni.files" 
+ value="com/sun/javafx/font/PrismFontFactory.java
+ com/sun/javafx/font/FontConfigManager.java
+ com/sun/javafx/font/DFontDecoder.java
+ com/sun/javafx/font/MacFontFinder.java
+ com/sun/javafx/font/coretext/OS.java
+ com/sun/javafx/font/directwrite/OS.java"/>
+  
+  <property name="cpp.dir" value="../javafx-font-native"/>
+
+  <!-- NOTE: the following properties are passed to the native makefile and
+       are overridden by the tv build -->
+  <property name="native.dist.dir" value="../javafx-font-native/dist${cross.name.suffix}"/>
+  <property name="native.build.dir" value="../javafx-font-native/build${cross.name.suffix}"/>
+  <property name="native.makefile" value="Makefile"/>
+  <property name="javafx-font.javah.path" value="../javafx-font/build/classes:../javafx-geom/build/classes:../javafx-ui-common/build/classes"/>
+  <property name="javafx-font.classes.dir" value="../javafx-font/build/classes"/>
+  <property name="nativelib.suffix.macosx" value=".dylib"/>
+  
+  <target name="get-libname-android" if="isAndroid">
+    <property name="native.lib.file" value="libjavafx-font.so"/>
+  </target>
+  <target name="get-libname-macosx" if="isMacOSX">
+    <property name="native.lib.file" value="libjavafx-font${nativelib.suffix.macosx}"/>
+  </target>
+  <target name="get-libname-linux" if="isLinux">
+    <property name="native.lib.file" value="libjavafx-font.so"/>
+  </target>
+  <target name="get-libname-solaris" if="isSolaris">
+    <property name="native.lib.file" value="libjavafx-font.so"/>
+  </target>
+  <target name="get-libname-windows" if="isWindows">
+    <property name="native.lib.file" value="javafx-font.dll"/>
+  </target>
+  <target name="get-libname-ios" if="isIOS">
+    <property name="native.lib.file" value="javafx-font.a"/>
+  </target>
+  <target name="get-libname" depends="get-libname-android,get-libname-macosx,get-libname-linux,get-libname-solaris,get-libname-windows,get-libname-ios"/>
+
+  <target name="-pre-init" depends="get-libname"/>
+
+  <target name="check-native">
+    <uptodate property="native.uptodate" targetfile="${native.dist.dir}/${native.lib.file}" >
+      <srcfiles dir= "${cpp.dir}/src" includes="*.c"/>
+      <srcfiles dir= "${cpp.dir}/src" includes="*.cpp"/>
+      <srcfiles dir= "${cpp.dir}/src" includes="*.h"/>
+    </uptodate>
+  </target>
+
+  <target name="compile-native" depends="check-native" unless="native.uptodate">
+    <ant antfile="build-${os_name}.xml" target="compile-native" inheritAll="true"/>
+  </target>
+
+  <target name="jar" depends="init">
+    <build-project/>
+    <antcall target="compile-native"/>
+    <jar destfile="${dist.dir}/javafx-font-native.jar"
+         basedir="${native.dist.dir}"
+         includes="${native.lib.file}"/>
+  </target>
+
+  <target name="test" depends="jar">
+    <test-project/>
+  </target>
+
+  <target name="test-single" depends="jar">
+    <test-single/>
+  </target>
+
+  <target name="clean">
+    <clean-project/>
+    <ant antfile="build-${os_name}.xml" target="clean-native" inheritAll="true"/>
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build-ios.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font" default="all" basedir=".">
+
+  <target name="compile-native">
+    <exec executable="make" dir="../javafx-font-native" failonerror="true">
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}/armv7"/>
+      <arg value="JFXFONT_CP=${javafx-font.classes.dir}"/>
+      <arg value="JAVAH_CP=${javafx-font.javah.path}"/>
+      <arg value="JNI_FILES=${javafx-font.jni.files}"/>
+      <arg value="JDK_HOME=${platform.home}"/>
+      <arg value="IS_IOS=true"/>
+      <arg value="IOS_ARCH=armv7"/>
+      <arg value="IOS_PLATFORM=iPhoneOS"/>
+      <arg value="IOS_VERSION=${ios.version}"/>
+      <arg value="CONF=${build.conf}"/>
+      <arg value="all"/>
+    </exec>
+
+    <exec executable="make" dir="../javafx-font-native" failonerror="true">
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}/i386"/>
+      <arg value="JFXFONT_CP=${javafx-font.classes.dir}"/>
+      <arg value="JAVAH_CP=${javafx-font.javah.path}"/>
+      <arg value="JNI_FILES=${javafx-font.jni.files}"/>
+      <arg value="JDK_HOME=${platform.home}"/>
+      <arg value="IS_IOS=true"/>
+      <arg value="IOS_ARCH=i386"/>
+      <arg value="IOS_PLATFORM=iPhoneSimulator"/>
+      <arg value="IOS_VERSION=${ios.version}"/>
+      <arg value="CONF=${build.conf}"/>
+      <arg value="all"/>
+    </exec>
+    
+    <exec executable="lipo" dir="../javafx-font-native" failonerror="true">
+      <arg value="-create"/>
+      <arg value="-output"/>
+      <arg value="${native.dist.dir}/libjavafx-font.a"/>
+      <arg value="${native.dist.dir}/libjavafx-font-armv7.a"/>
+      <arg value="${native.dist.dir}/libjavafx-font-i386.a"/>
+    </exec>
+  </target>
+
+  <target name="clean-native">
+    <exec executable="make" dir="../javafx-font-native" failonerror="true">
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}"/>
+      <arg value="clean"/>
+    </exec>
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build-linux.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font" default="all" basedir=".">
+
+  <target name="compile-native-cross" if="cross.platform" >
+    <fail unless="cross.rt.font.cflags" message="Missing cross.rt.font.cflags definition"/>
+    <fail unless="cross.rt.font.ldflags" message="Missing cross.rt.font.ldflags definition"/>
+    <exec executable="make" dir="../javafx-font-native" failonerror="true">
+      <arg value="JDK_HOME=${platform.home}"/>
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}"/>
+      <arg value="JFXFONT_CP=${javafx-font.classes.dir}"/>
+      <arg value="JAVAH_CP=${javafx-font.javah.path}"/>
+      <arg value="JNI_FILES=${javafx-font.jni.files}"/>
+      <arg value="CC=${crosstools.gcc} ${cross.rt.font.cflags}"/>
+      <arg value="LINK=${crosstools.gpp} ${cross.rt.font.ldflags}"/>
+      <arg value="all"/>
+    </exec>
+  </target>
+
+  <target name="compile-native-host" unless="cross.platform" >
+    <exec executable="make" dir="../javafx-font-native" failonerror="true">
+      <arg value="JDK_HOME=${platform.home}"/>
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}"/>
+      <arg value="JFXFONT_CP=${javafx-font.classes.dir}"/>
+      <arg value="JAVAH_CP=${javafx-font.javah.path}"/>
+      <arg value="JNI_FILES=${javafx-font.jni.files}"/>
+      <arg value="all"/>
+    </exec>
+  </target>
+
+  <target name="compile-native" depends="compile-native-host,compile-native-cross"/>
+
+  <target name="clean-native">
+    <exec executable="make" dir="../javafx-font-native" failonerror="true">
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}"/>
+      <arg value="clean"/>
+    </exec>
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build-macosx.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font" default="all" basedir=".">
+
+  <target name="compile-native">
+    <exec executable="make" dir="../javafx-font-native" failonerror="true">
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}"/>
+      <arg value="JFXFONT_CP=${javafx-font.classes.dir}"/>
+      <arg value="JAVAH_CP=${javafx-font.javah.path}"/>
+      <arg value="JNI_FILES=${javafx-font.jni.files}"/>
+      <arg value="JDK_HOME=${platform.home}"/>
+      <arg value="all"/>
+    </exec>
+  </target>
+
+  <target name="clean-native">
+    <exec executable="make" dir="../javafx-font-native" failonerror="true">
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}"/>
+      <arg value="clean"/>
+    </exec>
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build-solaris.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font" default="all" basedir=".">
+
+  <target name="compile-native">
+    <exec executable="gnumake" dir="../javafx-font-native" failonerror="true">
+      <arg value="JDK_HOME=${platform.home}"/>
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}"/>
+      <arg value="JFXFONT_CP=${javafx-font.classes.dir}"/>
+      <arg value="JAVAH_CP=${javafx-font.javah.path}"/>
+      <arg value="JNI_FILES=${javafx-font.jni.files}"/>
+      <arg value="all"/>
+    </exec>
+  </target>
+
+  <target name="clean-native">
+    <exec executable="gnumake" dir="../javafx-font-native" failonerror="true">
+      <arg value="DIST_DIR=${native.dist.dir}"/>
+      <arg value="BUILD_DIR=${native.build.dir}"/>
+      <arg value="clean"/>
+    </exec>
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build-windows.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font" default="all" basedir=".">
+
+  <import file="../../build-defs.xml"/>
+
+  <property name="jfx.build.needs.visual.studio" value="true"/>
+  <property name="jfx.build.needs.make.utility" value="true"/>
+
+  <target name="compile-native" depends="needs-vs-properties">
+    <exec executable="cygpath" dir="." outputproperty="short.platform.home" failonerror="true">
+      <arg value="-m"/>
+      <arg value="-a"/>
+      <arg value="-s"/>
+      <arg value="${platform.home}"/>
+    </exec>
+    <get-cygwin-path/>
+    <property file="${vs.properties}"/>
+    <!-- TODO: reuse do-make macro here -->
+    <exec executable="${cmd.utility}" dir="../javafx-font-native" failonerror="true">
+      <env key="JDK_HOME" value="${short.platform.home}"/>
+      <env key="INCLUDE" value="${windows.vs.INCLUDE}"/>
+      <env key="LIB" value="${windows.vs.LIB}"/>
+      <env key="LIBPATH" value="${windows.vs.LIBPATH}"/>
+      <env key="PATH" value="${windows.vs.PATH}"/>
+      <env key="CONF" value="${build.conf}"/>
+      <env key="DIST_DIR" value="${native.dist.dir}"/>
+      <env key="BUILD_DIR" value="${native.build.dir}"/>
+      <env key="JFXFONT_CP" value="${javafx-font.classes.dir}"/>
+      <env key="JAVAH_CP" value="${javafx-font.javah.path}"/>
+      <env key="JNI_FILES" value="${javafx-font.jni.files}"/>
+      <arg value="/C"/>
+      <arg value="${make.utility}"/>
+      <arg value="-f"/>
+      <arg value="${native.makefile}"/>
+      <arg value="all"/>
+    </exec>
+  </target>
+
+  <target name="clean-native">
+    <get-cygwin-path/>
+    <!-- TODO: reuse do-make macro here -->
+    <exec executable="${cmd.utility}" dir="../javafx-font-native" failonerror="true">
+      <env key="DIST_DIR" value="${native.dist.dir}"/>
+      <env key="BUILD_DIR" value="${native.build.dir}"/>
+      <arg value="/C"/>
+      <arg value="${make.utility}"/>
+      <arg value="-f"/>
+      <arg value="${native.makefile}"/>
+      <arg value="clean"/>
+    </exec>
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/build.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="javafx-font" default="jar" basedir=".">
+    <description>Builds, tests, and runs the OpenJFX javafx-font project.</description>
+
+    <import file="../build-defs.xml"/>
+    <import file="build-common.xml"/>
+
+    <target name="jar" depends="javafx-font-common.jar"/>
+    <target name="clean" depends="javafx-font-common.clean"/>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/javafx-font.iml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/classes" />
+    <output-test url="file://$MODULE_DIR$/build/test/classes" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/build" />
+      <excludeFolder url="file://$MODULE_DIR$/dist" />
+      <excludeFolder url="file://$MODULE_DIR$/nbproject" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="javafx-geom" />
+    <orderEntry type="module" module-name="javafx-common" />
+    <orderEntry type="module" module-name="javafx-ui-common" />
+    <orderEntry type="module" module-name="javafx-iio" />
+    <orderEntry type="module" module-name="pisces" />
+    <orderEntry type="module" module-name="prism-jogl" />
+  </component>
+  <component name="org.twodividedbyzero.idea.findbugs">
+    <option name="_basePreferences">
+      <map>
+        <entry key="property.analysisEffortLevel" value="default" />
+        <entry key="property.analyzeAfterCompile" value="false" />
+        <entry key="property.exportAsHtml" value="true" />
+        <entry key="property.exportAsXml" value="true" />
+        <entry key="property.exportBaseDir" value="" />
+        <entry key="property.exportCreateArchiveDir" value="false" />
+        <entry key="property.exportOpenBrowser" value="true" />
+        <entry key="property.minPriorityToReport" value="Medium" />
+        <entry key="property.runAnalysisInBackground" value="false" />
+        <entry key="property.showHiddenDetectors" value="false" />
+        <entry key="property.toolWindowToFront" value="true" />
+      </map>
+    </option>
+    <option name="_detectors">
+      <map>
+        <entry key="AppendingToAnObjectOutputStream" value="true" />
+        <entry key="BCPMethodReturnCheck" value="false" />
+        <entry key="BadAppletConstructor" value="false" />
+        <entry key="BadResultSetAccess" value="true" />
+        <entry key="BadSyntaxForRegularExpression" value="true" />
+        <entry key="BadUseOfReturnValue" value="true" />
+        <entry key="BadlyOverriddenAdapter" value="true" />
+        <entry key="BooleanReturnNull" value="true" />
+        <entry key="BuildInterproceduralCallGraph" value="false" />
+        <entry key="BuildObligationPolicyDatabase" value="true" />
+        <entry key="CallToUnsupportedMethod" value="false" />
+        <entry key="CalledMethods" value="true" />
+        <entry key="CheckCalls" value="false" />
+        <entry key="CheckExpectedWarnings" value="false" />
+        <entry key="CheckImmutableAnnotation" value="true" />
+        <entry key="CheckTypeQualifiers" value="true" />
+        <entry key="CloneIdiom" value="true" />
+        <entry key="ComparatorIdiom" value="true" />
+        <entry key="ConfusedInheritance" value="true" />
+        <entry key="ConfusionBetweenInheritedAndOuterMethod" value="true" />
+        <entry key="CrossSiteScripting" value="true" />
+        <entry key="DoInsideDoPrivileged" value="true" />
+        <entry key="DontCatchIllegalMonitorStateException" value="true" />
+        <entry key="DontIgnoreResultOfPutIfAbsent" value="true" />
+        <entry key="DontUseEnum" value="true" />
+        <entry key="DroppedException" value="true" />
+        <entry key="DumbMethodInvocations" value="true" />
+        <entry key="DumbMethods" value="true" />
+        <entry key="DuplicateBranches" value="true" />
+        <entry key="EmptyZipFileEntry" value="true" />
+        <entry key="EqStringTest" value="false" />
+        <entry key="EqualsOperandShouldHaveClassCompatibleWithThis" value="true" />
+        <entry key="FieldItemSummary" value="true" />
+        <entry key="FinalizerNullsFields" value="true" />
+        <entry key="FindBadCast" value="false" />
+        <entry key="FindBadCast2" value="true" />
+        <entry key="FindBadEqualsImplementation" value="false" />
+        <entry key="FindBadForLoop" value="true" />
+        <entry key="FindBugsSummaryStats" value="true" />
+        <entry key="FindCircularDependencies" value="false" />
+        <entry key="FindDeadLocalStores" value="true" />
+        <entry key="FindDoubleCheck" value="true" />
+        <entry key="FindEmptySynchronizedBlock" value="true" />
+        <entry key="FindFieldSelfAssignment" value="true" />
+        <entry key="FindFinalizeInvocations" value="true" />
+        <entry key="FindFloatEquality" value="true" />
+        <entry key="FindFloatMath" value="false" />
+        <entry key="FindHEmismatch" value="true" />
+        <entry key="FindInconsistentSync2" value="true" />
+        <entry key="FindJSR166LockMonitorenter" value="true" />
+        <entry key="FindLocalSelfAssignment2" value="true" />
+        <entry key="FindMaskedFields" value="true" />
+        <entry key="FindMismatchedWaitOrNotify" value="true" />
+        <entry key="FindNakedNotify" value="true" />
+        <entry key="FindNonSerializableStoreIntoSession" value="true" />
+        <entry key="FindNonSerializableValuePassedToWriteObject" value="true" />
+        <entry key="FindNonShortCircuit" value="true" />
+        <entry key="FindNullDeref" value="true" />
+        <entry key="FindNullDerefsInvolvingNonShortCircuitEvaluation" value="true" />
+        <entry key="FindOpenStream" value="true" />
+        <entry key="FindPuzzlers" value="true" />
+        <entry key="FindRefComparison" value="true" />
+        <entry key="FindReturnRef" value="true" />
+        <entry key="FindRunInvocations" value="true" />
+        <entry key="FindSelfComparison" value="true" />
+        <entry key="FindSelfComparison2" value="true" />
+        <entry key="FindSleepWithLockHeld" value="true" />
+        <entry key="FindSpinLoop" value="true" />
+        <entry key="FindSqlInjection" value="true" />
+        <entry key="FindTwoLockWait" value="true" />
+        <entry key="FindUncalledPrivateMethods" value="true" />
+        <entry key="FindUnconditionalWait" value="true" />
+        <entry key="FindUninitializedGet" value="true" />
+        <entry key="FindUnrelatedTypesInGenericContainer" value="true" />
+        <entry key="FindUnreleasedLock" value="true" />
+        <entry key="FindUnsatisfiedObligation" value="true" />
+        <entry key="FindUnsyncGet" value="true" />
+        <entry key="FindUselessControlFlow" value="true" />
+        <entry key="FormatStringChecker" value="true" />
+        <entry key="HugeSharedStringConstants" value="true" />
+        <entry key="IDivResultCastToDouble" value="true" />
+        <entry key="IncompatMask" value="true" />
+        <entry key="InconsistentAnnotations" value="true" />
+        <entry key="InefficientMemberAccess" value="false" />
+        <entry key="InefficientToArray" value="true" />
+        <entry key="InfiniteLoop" value="true" />
+        <entry key="InfiniteRecursiveLoop" value="true" />
+        <entry key="InfiniteRecursiveLoop2" value="false" />
+        <entry key="InheritanceUnsafeGetResource" value="true" />
+        <entry key="InitializationChain" value="true" />
+        <entry key="InstantiateStaticClass" value="true" />
+        <entry key="InvalidJUnitTest" value="true" />
+        <entry key="IteratorIdioms" value="true" />
+        <entry key="LazyInit" value="true" />
+        <entry key="LoadOfKnownNullValue" value="true" />
+        <entry key="LockedFields" value="false" />
+        <entry key="LostLoggerDueToWeakReference" value="true" />
+        <entry key="MethodReturnCheck" value="true" />
+        <entry key="Methods" value="true" />
+        <entry key="MultithreadedInstanceAccess" value="true" />
+        <entry key="MutableLock" value="true" />
+        <entry key="MutableStaticFields" value="true" />
+        <entry key="Naming" value="true" />
+        <entry key="Noise" value="false" />
+        <entry key="NoiseNullDeref" value="false" />
+        <entry key="NoteAnnotationRetention" value="true" />
+        <entry key="NoteCheckReturnValue" value="true" />
+        <entry key="NoteCheckReturnValueAnnotations" value="true" />
+        <entry key="NoteDirectlyRelevantTypeQualifiers" value="true" />
+        <entry key="NoteJCIPAnnotation" value="true" />
+        <entry key="NoteNonNullAnnotations" value="true" />
+        <entry key="NoteNonnullReturnValues" value="true" />
+        <entry key="NoteSuppressedWarnings" value="true" />
+        <entry key="NoteUnconditionalParamDerefs" value="true" />
+        <entry key="NumberConstructor" value="true" />
+        <entry key="OverridingEqualsNotSymmetrical" value="true" />
+        <entry key="PreferZeroLengthArrays" value="true" />
+        <entry key="PublicSemaphores" value="false" />
+        <entry key="QuestionableBooleanAssignment" value="true" />
+        <entry key="ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass" value="true" />
+        <entry key="ReadReturnShouldBeChecked" value="true" />
+        <entry key="RedundantInterfaces" value="true" />
+        <entry key="ReflectiveClasses" value="true" />
+        <entry key="RepeatedConditionals" value="true" />
+        <entry key="ResolveAllReferences" value="false" />
+        <entry key="RuntimeExceptionCapture" value="true" />
+        <entry key="SerializableIdiom" value="true" />
+        <entry key="StartInConstructor" value="true" />
+        <entry key="StaticCalendarDetector" value="true" />
+        <entry key="StringConcatenation" value="true" />
+        <entry key="SuperfluousInstanceOf" value="true" />
+        <entry key="SuspiciousThreadInterrupted" value="true" />
+        <entry key="SwitchFallthrough" value="true" />
+        <entry key="SynchronizationOnSharedBuiltinConstant" value="true" />
+        <entry key="SynchronizeAndNullCheckField" value="true" />
+        <entry key="SynchronizeOnClassLiteralNotGetClass" value="true" />
+        <entry key="SynchronizingOnContentsOfFieldToProtectField" value="true" />
+        <entry key="TestASM" value="false" />
+        <entry key="TestDataflowAnalysis" value="false" />
+        <entry key="TestingGround" value="false" />
+        <entry key="TrainFieldStoreTypes" value="true" />
+        <entry key="TrainNonNullAnnotations" value="true" />
+        <entry key="TrainUnconditionalDerefParams" value="true" />
+        <entry key="URLProblems" value="true" />
+        <entry key="UncallableMethodOfAnonymousClass" value="true" />
+        <entry key="UnnecessaryMath" value="true" />
+        <entry key="UnreadFields" value="true" />
+        <entry key="UseObjectEquals" value="false" />
+        <entry key="UselessSubclassMethod" value="false" />
+        <entry key="VarArgsProblems" value="true" />
+        <entry key="VolatileUsage" value="true" />
+        <entry key="WaitInLoop" value="true" />
+        <entry key="WrongMapIterator" value="true" />
+        <entry key="XMLFactoryBypass" value="true" />
+      </map>
+    </option>
+    <option name="_reportCategories">
+      <map>
+        <entry key="BAD_PRACTICE" value="true" />
+        <entry key="CORRECTNESS" value="true" />
+        <entry key="EXPERIMENTAL" value="true" />
+        <entry key="I18N" value="true" />
+        <entry key="MALICIOUS_CODE" value="true" />
+        <entry key="MT_CORRECTNESS" value="true" />
+        <entry key="NOISE" value="false" />
+        <entry key="PERFORMANCE" value="true" />
+        <entry key="SECURITY" value="true" />
+        <entry key="STYLE" value="true" />
+      </map>
+    </option>
+  </component>
+</module>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/nbproject/project.xml	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.ant.freeform</type>
+    <configuration>
+        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+            <!-- Do not use Project Properties customizer when editing this file manually. -->
+            <name>javafx-font</name>
+            <properties>
+                <property-file>../base.properties</property-file>
+                <property-file>project.properties</property-file>
+                <property-file>../common.properties</property-file>
+            </properties>
+            <folders>
+                <source-folder>
+                    <label>Source Packages</label>
+                    <type>java</type>
+                    <location>${src.dir}</location>
+                </source-folder>
+                <source-folder>
+                    <label>Generated Sources</label>
+                    <type>java</type>
+                    <location>build/gensrc</location>
+                </source-folder>
+                <source-folder>
+                    <label>Test Packages</label>
+                    <type>java</type>
+                    <location>${test.dir}</location>
+                </source-folder>
+            </folders>
+            <ide-actions>
+                <action name="build">
+                    <target>jar</target>
+                </action>
+                <action name="clean">
+                    <target>clean</target>
+                </action>
+                <action name="test">
+                    <target>test</target>
+                </action>
+                <action name="rebuild">
+                    <target>clean</target>
+                    <target>jar</target>
+                </action>
+                <action name="run.single">
+                    <target>test-single</target>
+                    <context>
+                        <property>run.file</property>
+                        <folder>${test.dir}</folder>
+                        <pattern>\.java$</pattern>
+                        <format>relative-path</format>
+                        <arity>
+                            <one-file-only/>
+                        </arity>
+                    </context>
+                </action>
+                <action name="test.single">
+                    <target>test-single</target>
+                    <context>
+                        <property>run.file</property>
+                        <folder>${test.dir}</folder>
+                        <pattern>\.java$</pattern>
+                        <format>relative-path</format>
+                        <arity>
+                            <one-file-only/>
+                        </arity>
+                    </context>
+                </action>
+            </ide-actions>
+            <export>
+                <type>jar</type>
+                <location>dist/javafx-font.jar</location>
+                <build-target>jar</build-target>
+            </export>
+            <export>
+                <type>jar</type>
+                <location>dist/javafx-font.jar</location>
+                <build-target>jar</build-target>
+            </export>
+            <export>
+                <type>folder</type>
+                <location>${build.test.classes.dir}</location>
+                <build-target>jar</build-target>
+            </export>
+            <view>
+                <items>
+                    <source-folder style="packages">
+                        <label>Source Packages</label>
+                        <location>${src.dir}</location>
+                    </source-folder>
+                    <source-folder style="packages">
+                        <label>Generated Sources</label>
+                        <location>build/gensrc</location>
+                    </source-folder>
+                    <source-folder style="packages">
+                        <label>Test Packages</label>
+                        <location>${test.dir}</location>
+                    </source-folder>
+                    <source-file>
+                        <location>build.xml</location>
+                    </source-file>
+                </items>
+                <context-menu>
+                    <ide-action name="build"/>
+                    <ide-action name="rebuild"/>
+                    <ide-action name="clean"/>
+                    <ide-action name="test"/>
+                </context-menu>
+            </view>
+            <subprojects/>
+        </general-data>
+        <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
+            <compilation-unit>
+                <package-root>${src.dir}</package-root>
+                <classpath mode="compile">${javac.classpath}</classpath>
+                <built-to>dist/javafx-font.jar</built-to>
+                <source-level>1.5</source-level>
+            </compilation-unit>
+            <compilation-unit>
+                <package-root>build/gensrc</package-root>
+                <classpath mode="compile">${javac.classpath}:${build.classes.dir}</classpath>
+                <built-to>dist/javafx-font.jar</built-to>
+                <source-level>1.5</source-level>
+            </compilation-unit>
+            <compilation-unit>
+                <package-root>${test.dir}</package-root>
+                <unit-tests/>
+                <classpath mode="compile">${javac.test.classpath}</classpath>
+                <built-to>${build.test.classes.dir}</built-to>
+                <source-level>1.5</source-level>
+            </compilation-unit>
+        </java-data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/project.properties	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,8 @@
+JFXRT_HOME=\
+    ${rt.dist.root.dir}/../artifacts/sdk/rt
+javac.classpath=\
+    ${rt.dist.root.dir}/javafx-common/dist/javafx-common.jar:\
+    ${rt.dist.root.dir}/javafx-ui-common/dist/javafx-ui-common.jar:\
+    ${rt.dist.root.dir}/javafx-geom/dist/javafx-geom.jar:\
+    ${rt.dist.root.dir}/glass/dist/lib/glass.jar:\
+    ${JFXRT_HOME}/lib/ext/jfxrt.jar
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/AndroidFontFinder.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2012, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.sun.glass.utils.NativeLibLoader;
+
+/**
+ * Class AndroidFontFinder reads font descriptor from
+ * /system/etc/system_fonts.xml. If that file doesn't exist it is replaced by
+ * embedded font descriptor {@link com/sun/t2k/android_system_fonts.xml} which
+ * defines some basic mappings based on best guess which fonts are mandatory on
+ * platforms lower than 4.0 and how they map to typefaces.
+ */
+class AndroidFontFinder {
+
+    private final static String SYSTEM_FONT_NAME    = "sans serif";
+    private final static float SYSTEM_FONT_SIZE     = 16.0f;
+    
+    final static String fontDescriptor_2_X_Path = "/com/sun/javafx/font/android_system_fonts.xml";
+    final static String fontDescriptor_4_X_Path = "/system/etc/system_fonts.xml";
+    final static String systemFontsDir = "/system/fonts";
+
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                NativeLibLoader.loadLibrary("javafx-font");
+                return null;
+            }
+        });
+    }
+
+    public static String getSystemFont() {
+        return SYSTEM_FONT_NAME;
+    }
+
+    public static float getSystemFontSize() {
+        return SYSTEM_FONT_SIZE;
+    }
+    
+    public static String getSystemFontsDir() {
+        return systemFontsDir;
+    }
+
+    private static boolean parse_2_X_SystemDefaultFonts(
+            final HashMap<String, String> fontToFileMap,
+            final HashMap<String, String> fontToFamilyNameMap,
+            final HashMap<String, ArrayList<String>> familyToFontListMap) {
+
+        InputStream is = AndroidFontFinder.class
+                .getResourceAsStream(fontDescriptor_2_X_Path);
+        if (is == null) {
+            System.err
+                    .println("Resource not found: " + fontDescriptor_2_X_Path);
+            return false;
+        }
+        return parseSystemDefaultFonts(is, fontToFileMap, fontToFamilyNameMap,
+                familyToFontListMap);
+    }
+
+    private static boolean parse_4_X_SystemDefaultFonts(
+            final HashMap<String, String> fontToFileMap,
+            final HashMap<String, String> fontToFamilyNameMap,
+            final HashMap<String, ArrayList<String>> familyToFontListMap) {
+        File iFile = new File(fontDescriptor_4_X_Path);
+        try {
+            return parseSystemDefaultFonts(new FileInputStream(iFile),
+                    fontToFileMap, fontToFamilyNameMap, familyToFontListMap);
+
+        } catch (FileNotFoundException e) {
+            System.err.println("File not found: " + fontDescriptor_4_X_Path);
+        }
+        return false;
+    }
+
+    private static boolean parseSystemDefaultFonts(final InputStream is,
+            final HashMap<String, String> fontToFileMap,
+            final HashMap<String, String> fontToFamilyNameMap,
+            final HashMap<String, ArrayList<String>> familyToFontListMap) {
+
+        try {
+
+            SAXParserFactory factory = SAXParserFactory.newInstance();
+            SAXParser saxParser = factory.newSAXParser();
+
+            DefaultHandler handler = new DefaultHandler() {
+                private final static char DASH      = '-';
+                private final static String FAMILY  = "family";
+
+                private final static String FILE    = "file";
+                private final static String FILESET = "fileset";
+                private final static String NAME    = "name";
+                private final static String NAMESET = "nameset";
+                private final static char SPACE     = ' ';
+                final List<String> filesets = new ArrayList<>();
+
+                boolean inFamily = false;
+                boolean inFile = false;
+                boolean inFileset = false;
+                boolean inName = false;
+                boolean inNameset = false;
+
+                private final List<String> namesets = new ArrayList<>();
+                private final String[] styles = new String[] {
+                        "regular", "bold", "italic", "bold italic" };
+
+                public void characters(char[] ch, int start, int length)
+                        throws SAXException {
+                    if (inName) {
+                        String nameset = new String(ch, start, length)
+                                .toLowerCase();
+                        namesets.add(nameset);
+                    } else if (inFile) {
+                        String fileset = new String(ch, start, length);
+                        filesets.add(fileset);
+                    }
+                }
+
+                public void endElement(String uri, String localName,
+                        String qName) throws SAXException {
+                    if (qName.equalsIgnoreCase(FAMILY)) {
+                        for (String family : namesets) {
+                            int i = 0;
+                            String familyName = family.replace(DASH, SPACE);
+                            for (String file : filesets) {
+                                String fullName = familyName + " " + styles[i];
+                                String fullFile = systemFontsDir
+                                        + File.separator + file;
+                                File f = new File(fullFile);
+                                if (!f.exists() || !f.canRead()) {
+                                    continue;
+                                }
+                                fontToFileMap.put(fullName, fullFile);
+                                fontToFamilyNameMap.put(fullName, familyName);
+                                ArrayList<String> list = familyToFontListMap
+                                        .get(familyName);
+                                if (list == null) {
+                                    list = new ArrayList<String>();
+                                    familyToFontListMap.put(familyName, list);
+                                }
+                                list.add(fullName);
+                                i++;
+                            }
+                        }
+                        inFamily = false;
+                    } else if (qName.equalsIgnoreCase(NAMESET)) {
+                        inNameset = false;
+                    } else if (qName.equalsIgnoreCase(FILESET)) {
+                        inFileset = false;
+                    } else if (qName.equalsIgnoreCase(NAME)) {
+                        inName = false;
+                    } else if (qName.equalsIgnoreCase(FILE)) {
+                        inFile = false;
+                    }
+                }
+
+                @Override
+                public void startElement(String uri, String localName,
+                        String qName, Attributes attributes)
+                        throws SAXException {
+                    if (qName.equalsIgnoreCase(FAMILY)) {
+                        inFamily = true;
+                        namesets.clear();
+                        filesets.clear();
+                    } else if (qName.equalsIgnoreCase(NAMESET)) {
+                        inNameset = true;
+                    } else if (qName.equalsIgnoreCase(FILESET)) {
+                        inFileset = true;
+                    } else if (qName.equalsIgnoreCase(NAME)) {
+                        inName = true;
+                    } else if (qName.equalsIgnoreCase(FILE)) {
+                        inFile = true;
+                    }
+                }
+            };// DefaultHandler
+
+            saxParser.parse(is, handler);
+            return true;
+
+        } catch (IOException e) {
+            System.err.println("Failed to load default fonts descriptor: "
+                    + fontDescriptor_4_X_Path);
+        } catch (Exception e) {
+            System.err.println("Failed parsing default fonts descriptor;");
+            e.printStackTrace();
+        }
+        return false;
+    }
+
+    public static void populateFontFileNameMap(
+            HashMap<String, String> fontToFileMap,
+            HashMap<String, String> fontToFamilyNameMap,
+            HashMap<String, ArrayList<String>> familyToFontListMap,
+            Locale locale) {
+
+        if (fontToFileMap == null || fontToFamilyNameMap == null
+                || familyToFontListMap == null) {
+            return;
+        }
+        if (locale == null) {
+            locale = Locale.ENGLISH;
+        }
+
+        boolean systemFonts_4_X_DescriptorFound = parse_4_X_SystemDefaultFonts(
+                fontToFileMap, fontToFamilyNameMap, familyToFontListMap);
+        if (!systemFonts_4_X_DescriptorFound) {
+            parse_2_X_SystemDefaultFonts(fontToFileMap, fontToFamilyNameMap,
+                    familyToFontListMap);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/CMap.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,610 @@
+/*
+ * Copyright (c) 2011, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+import com.sun.javafx.font.FontFileReader.Buffer;
+
+/*
+ * A tt font has a CMAP table which is in turn made up of sub-tables which
+ * describe the char to glyph mapping in (possibly) multiple ways.
+ * CMAP subtables are described by 3 values.
+ * 1. Platform ID (eg 3=Microsoft, which is the id we look for in JDK)
+ * 2. Encoding (eg 0=symbol, 1=unicode)
+ * 3. TrueType subtable format (how the char->glyph mapping for the encoding
+ * is stored in the subtable). See the TrueType spec. Format 4 is required
+ * by MS in fonts for windows. Its uses segmented mapping to delta values.
+ * Most typically we see are (3,1,4) :
+ * CMAP Platform ID=3 is what we prefer. After that any 0,*.
+ */
+abstract class CMap {
+
+    static final char noSuchChar = (char)0xfffd;
+    static final int SHORTMASK = 0x0000ffff;
+    static final int INTMASK   = 0xffffffff;
+
+    static CMap initialize(PrismFontFile font) {
+
+        CMap cmap = null;
+
+        int offset, platformID, encodingID=-1;
+
+        int three0=0, three1=0, three10=0, zeroStarOffset=0;
+        boolean zeroStar = false, threeStar = false;
+
+        Buffer cmapBuffer = font.readTable(FontConstants.cmapTag);
+        short numberSubTables = cmapBuffer.getShort(2);
+
+        /* Locate the offsets of supported 3,* Microsoft platform encodings,
+         * and any 0,* Unicode platform encoding. The latter is used by
+         * all current OS X fonts that don't have a Microsoft cmap.
+         * We will always prefer the Microsoft cmap, for the fonts that
+         * provide both. They ought to perform the same mappings. Although
+         * I can imagine that a vendor might provide a different looking
+         * glyph for some special characters for OS X vs Windows, I'm not
+         * actually aware of any such case.
+         */
+        for (int i=0; i<numberSubTables; i++) {
+            cmapBuffer.position(i * 8 + 4);
+            platformID = cmapBuffer.getShort();
+
+            if (platformID == 0) {
+                zeroStar = true;
+                encodingID = cmapBuffer.getShort();
+                zeroStarOffset = cmapBuffer.getInt();
+            }
+            else if (platformID == 3) {
+                threeStar = true;
+                encodingID = cmapBuffer.getShort();
+                offset     = cmapBuffer.getInt();
+                switch (encodingID) {
+                case 0:  three0  = offset; break; // MS Symbol encoding
+                case 1:  three1  = offset; break; // MS Unicode cmap
+                case 10: three10 = offset; break; // MS Unicode surrogates
+                }
+            }
+        }
+
+        /* This defines the preference order for cmap subtables */
+        if (threeStar) {
+            if (three10 != 0) {
+                cmap = createCMap(cmapBuffer, three10);
+            }
+            else if  (three0 != 0) {
+                cmap = createCMap(cmapBuffer, three0);
+            }
+            else if (three1 != 0) {
+                cmap = createCMap(cmapBuffer, three1);
+            }
+        } else if (zeroStar && zeroStarOffset != 0) {
+            cmap = createCMap(cmapBuffer, zeroStarOffset);
+        } else {
+            /* No 0,* or supported 3,* subtable was found.
+             * Use whatever is the first table listed.
+             * Since these are supposed to be sorted, there's a good chance
+             * it will be Mac Roman (1,0). If its not that then its
+             * likely a really old font but not one that's found on either
+             * Windows or OS X
+             * In fact I didn't even find any OS X font that supported
+             * only (1,*).
+             * So this seems likely to be an untravelled path which is
+             * just as well given that its not likely to work properly.
+             */
+            cmap = createCMap(cmapBuffer, cmapBuffer.getInt(8));
+        }
+        return cmap;
+    }
+
+    static CMap createCMap(Buffer buffer, int offset) {
+        /* First do a sanity check that this cmap subtable is contained
+         * within the cmap table.
+         */
+        int subtableFormat = buffer.getChar(offset);
+
+        switch (subtableFormat) {
+        case 0:  return new CMapFormat0(buffer, offset);
+        case 2:  return new CMapFormat2(buffer, offset);
+        case 4:  return new CMapFormat4(buffer, offset);
+        case 6:  return new CMapFormat6(buffer, offset);
+        case 8:  return new CMapFormat8(buffer, offset);
+        case 10: return new CMapFormat10(buffer, offset);
+        case 12: return new CMapFormat12(buffer, offset);
+        default: throw new RuntimeException("Cmap format unimplemented: " +
+                                            (int)buffer.getChar(offset));
+        }
+    }
+
+    abstract char getGlyph(int charCode);
+
+    /* Format 4 Header is
+     * ushort format (off=0)
+     * ushort length (off=2)
+     * ushort language (off=4)
+     * ushort segCountX2 (off=6)
+     * ushort searchRange (off=8)
+     * ushort entrySelector (off=10)
+     * ushort rangeShift (off=12)
+     * ushort endCount[segCount] (off=14)
+     * ushort reservedPad
+     * ushort startCount[segCount]
+     * short idDelta[segCount]
+     * idRangeOFfset[segCount]
+     * ushort glyphIdArray[]
+     */
+    static class CMapFormat4 extends CMap {
+        int segCount;
+        int entrySelector;
+        int rangeShift;
+        char[] endCount;
+        char[] startCount;
+        short[] idDelta;
+        char[] idRangeOffset;
+        char[] glyphIds;
+
+        CMapFormat4(Buffer buffer, int offset) {
+
+            buffer.position(offset);
+            buffer.getChar(); // skip, we already know format=4
+            int subtableLength = buffer.getChar();
+            /* Try to recover from some bad fonts which specify a subtable
+             * length that would overflow the byte buffer holding the whole
+             * cmap table. If this isn't a recoverable situation an exception
+             * may be thrown which is caught higher up the call stack.
+             * Whilst this may seem lenient, in practice, unless the "bad"
+             * subtable we are using is the last one in the cmap table we
+             * would have no way of knowing about this problem anyway.
+             */
+            if (offset+subtableLength > buffer.capacity()) {
+                subtableLength = buffer.capacity() - offset;
+            }
+            buffer.getChar(); // skip language
+            segCount = buffer.getChar()/2;
+            buffer.getChar(); // skip searchRange
+            entrySelector = buffer.getChar();
+            rangeShift    = buffer.getChar()/2;
+            startCount = new char[segCount];
+            endCount = new char[segCount];
+            idDelta = new short[segCount];
+            idRangeOffset = new char[segCount];
+
+            for (int i=0; i<segCount; i++) {
+                endCount[i] = buffer.getChar();
+            }
+            buffer.getChar(); // 2 bytes for reserved pad
+            for (int i=0; i<segCount; i++) {
+                startCount[i] = buffer.getChar();
+            }
+
+            for (int i=0; i<segCount; i++) {
+                idDelta[i] = (short)buffer.getChar();
+            }
+
+            for (int i=0; i<segCount; i++) {
+                char ctmp = buffer.getChar();
+                idRangeOffset[i] = (char)((ctmp>>1)&0xffff);
+            }
+            /* Can calculate the number of glyph IDs by subtracting
+             * "pos" from the length of the cmap
+             */
+            int pos = (segCount*8+16)/2;
+            buffer.position(pos*2+offset); // * 2 for chars
+            int numGlyphIds = (subtableLength/2 - pos);
+            glyphIds = new char[numGlyphIds];
+            for (int i=0;i<numGlyphIds;i++) {
+                glyphIds[i] = buffer.getChar();
+            }
+        }
+
+        char getGlyph(int charCode) {
+
+            int index = 0;
+            char glyphCode = 0;
+
+            int controlGlyph = getControlCodeGlyph(charCode, true);
+            if (controlGlyph >= 0) {
+                return (char)controlGlyph;
+            }
+
+            /*
+             * Citation from the TrueType (and OpenType) spec:
+             *   The segments are sorted in order of increasing endCode
+             *   values, and the segment values are specified in four parallel
+             *   arrays. You search for the first endCode that is greater than
+             *   or equal to the character code you want to map. If the
+             *   corresponding startCode is less than or equal to the
+             *   character code, then you use the corresponding idDelta and
+             *   idRangeOffset to map the character code to a glyph index
+             *   (otherwise, the missingGlyph is returned).
+             */
+
+            /*
+             * CMAP format4 defines several fields for optimized search of
+             * the segment list (entrySelector, searchRange, rangeShift).
+             * However, benefits are neglible and some fonts have incorrect
+             * data - so we use straightforward binary search (see bug 6247425)
+             */
+            int left = 0, right = startCount.length;
+            index = startCount.length >> 1;
+            while (left < right) {
+                if (endCount[index] < charCode) {
+                    left = index + 1;
+                } else {
+                    right = index;
+                }
+                index = (left + right) >> 1;
+            }
+
+            if (charCode >= startCount[index] && charCode <= endCount[index]) {
+                int rangeOffset = idRangeOffset[index];
+
+                if (rangeOffset == 0) {
+                    glyphCode = (char)(charCode + idDelta[index]);
+                } else {
+                    /* Calculate an index into the glyphIds array */
+                    int glyphIDIndex = rangeOffset - segCount + index
+                                         + (charCode - startCount[index]);
+                    glyphCode = glyphIds[glyphIDIndex];
+                    if (glyphCode != 0) {
+                        glyphCode = (char)(glyphCode + idDelta[index]);
+                    }
+                }
+            }
+            return glyphCode;
+        }
+    }
+
+    // Format 0: Byte Encoding table
+    static class CMapFormat0 extends CMap {
+        byte [] cmap;
+
+        CMapFormat0(Buffer buffer, int offset) {
+
+            /* skip 6 bytes of format, length, and version */
+            int len = buffer.getChar(offset+2);
+            cmap = new byte[len-6];
+            buffer.get(offset+6, cmap, 0, len-6);
+        }
+
+        char getGlyph(int charCode) {
+            if (charCode < 256) {
+                if (charCode < 0x0010) {
+                    switch (charCode) {
+                    case 0x0009:
+                    case 0x000a:
+                    case 0x000d: return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
+                    }
+                }
+                return (char)(0xff & cmap[charCode]);
+            } else {
+                return 0;
+            }
+        }
+    }
+
+    // Format 2: High-byte mapping through table
+    static class CMapFormat2 extends CMap {
+
+        char[] subHeaderKey = new char[256];
+         /* Store subheaders in individual arrays
+          * A SubHeader entry theoretically looks like {
+          *   char firstCode;
+          *   char entryCount;
+          *   short idDelta;
+          *   char idRangeOffset;
+          * }
+          */
+        char[] firstCodeArray;
+        char[] entryCountArray;
+        short[] idDeltaArray;
+        char[] idRangeOffSetArray;
+
+        char[] glyphIndexArray;
+
+        CMapFormat2(Buffer buffer, int offset) {
+
+            int tableLen = buffer.getChar(offset+2);
+            buffer.position(offset+6);
+            char maxSubHeader = 0;
+            for (int i=0;i<256;i++) {
+                subHeaderKey[i] = buffer.getChar();
+                if (subHeaderKey[i] > maxSubHeader) {
+                    maxSubHeader = subHeaderKey[i];
+                }
+            }
+            /* The value of the subHeaderKey is 8 * the subHeader index,
+             * so the number of subHeaders can be obtained by dividing
+             * this value bv 8 and adding 1.
+             */
+            int numSubHeaders = (maxSubHeader >> 3) +1;
+            firstCodeArray = new char[numSubHeaders];
+            entryCountArray = new char[numSubHeaders];
+            idDeltaArray  = new short[numSubHeaders];
+            idRangeOffSetArray  = new char[numSubHeaders];
+            for (int i=0; i<numSubHeaders; i++) {
+                firstCodeArray[i] = buffer.getChar();
+                entryCountArray[i] = buffer.getChar();
+                idDeltaArray[i] = (short)buffer.getChar();
+                idRangeOffSetArray[i] = buffer.getChar();
+            }
+
+            int glyphIndexArrSize = (tableLen-518-numSubHeaders*8)/2;
+            glyphIndexArray = new char[glyphIndexArrSize];
+            for (int i=0; i<glyphIndexArrSize;i++) {
+                glyphIndexArray[i] = buffer.getChar();
+            }
+        }
+
+        char getGlyph(int charCode) {
+            int controlGlyph = getControlCodeGlyph(charCode, true);
+            if (controlGlyph >= 0) {
+                return (char)controlGlyph;
+            }
+
+            char highByte = (char)(charCode >> 8);
+            char lowByte = (char)(charCode & 0xff);
+            int key = subHeaderKey[highByte]>>3; // index into subHeaders
+            char mapMe;
+
+            if (key != 0) {
+                mapMe = lowByte;
+            } else {
+                mapMe = highByte;
+                if (mapMe == 0) {
+                    mapMe = lowByte;
+                }
+            }
+            char firstCode = firstCodeArray[key];
+            if (mapMe < firstCode) {
+                return 0;
+            } else {
+                mapMe -= firstCode;
+            }
+
+            if (mapMe < entryCountArray[key]) {
+                /* "address" arithmetic is needed to calculate the offset
+                 * into glyphIndexArray. "idRangeOffSetArray[key]" specifies
+                 * the number of bytes from that location in the table where
+                 * the subarray of glyphIndexes starting at "firstCode" begins.
+                 * Each entry in the subHeader table is 8 bytes, and the
+                 * idRangeOffSetArray field is at offset 6 in the entry.
+                 * The glyphIndexArray immediately follows the subHeaders.
+                 * So if there are "N" entries then the number of bytes to the
+                 * start of glyphIndexArray is (N-key)*8-6.
+                 * Subtract this from the idRangeOffSetArray value to get
+                 * the number of bytes into glyphIndexArray and divide by 2 to
+                 * get the (char) array index.
+                 */
+                int glyphArrayOffset = ((idRangeOffSetArray.length-key)*8)-6;
+                int glyphSubArrayStart =
+                        (idRangeOffSetArray[key] - glyphArrayOffset)/2;
+                char glyphCode = glyphIndexArray[glyphSubArrayStart+mapMe];
+                if (glyphCode != 0) {
+                    glyphCode += idDeltaArray[key]; //idDelta
+                    return glyphCode;
+                }
+            }
+            return 0;
+        }
+    }
+
+    // Format 6: Trimmed table mapping
+    static class CMapFormat6 extends CMap {
+
+        char firstCode;
+        char entryCount;
+        char[] glyphIdArray;
+
+        CMapFormat6(Buffer buffer, int offset) {
+
+             buffer.position(offset+6);
+             firstCode = buffer.getChar();
+             entryCount = buffer.getChar();
+             glyphIdArray = new char[entryCount];
+             for (int i=0; i< entryCount; i++) {
+                 glyphIdArray[i] = buffer.getChar();
+             }
+         }
+
+         char getGlyph(int charCode) {
+             int controlGlyph = getControlCodeGlyph(charCode, true);
+             if (controlGlyph >= 0) {
+                 return (char)controlGlyph;
+             }
+
+             charCode -= firstCode;
+             if (charCode < 0 || charCode >= entryCount) {
+                  return 0;
+             } else {
+                  return glyphIdArray[charCode];
+             }
+         }
+    }
+
+    // Format 8: mixed 16-bit and 32-bit coverage
+    // Seems unlikely this code will ever get tested as we look for
+    // MS platform Cmaps and MS states (in the Opentype spec on their website)
+    // that MS doesn't support this format
+    static class CMapFormat8 extends CMap {
+
+         CMapFormat8(Buffer buffer, int offset) {
+         }
+
+        char getGlyph(int charCode) {
+            return 0;
+        }
+
+    }
+
+
+    // Format 4-byte 10: Trimmed table mapping
+    // MS platform Cmaps and MS states (in the Opentype spec on their website)
+    // that MS doesn't support this format
+    static class CMapFormat10 extends CMap {
+         
+         long startCharCode;
+         int numChars;
+         char[] glyphIdArray;
+
+         CMapFormat10(Buffer buffer, int offset) {
+
+             buffer.position(offset+12);
+             startCharCode = buffer.getInt() & INTMASK;
+             numChars = buffer.getInt() & INTMASK;
+             glyphIdArray = new char[numChars];
+             for (int i=0; i< numChars; i++) {
+                 glyphIdArray[i] = buffer.getChar();
+             }
+         }
+
+         char getGlyph(int charCode) {
+
+             int code = (int)(charCode - startCharCode);
+             if (code < 0 || code >= numChars) {
+                 return 0;
+             } else {
+                 return glyphIdArray[code];
+             }
+         }
+    }
+
+    // Format 12: Segmented coverage for UCS-4 (fonts supporting
+    // surrogate pairs)
+    static class CMapFormat12 extends CMap {
+
+        int numGroups;
+        int highBit =0;
+        int power;
+        int extra;
+        long[] startCharCode;
+        long[] endCharCode;
+        int[] startGlyphID;
+
+        CMapFormat12(Buffer buffer, int offset) {
+
+            numGroups = buffer.getInt(offset+12);
+            startCharCode = new long[numGroups];
+            endCharCode = new long[numGroups];
+            startGlyphID = new int[numGroups];
+            buffer.position(offset+16);
+            // REMIND: why slice ?
+            //buffer = buffer.slice();
+            for (int i=0; i<numGroups; i++) {
+                startCharCode[i] = buffer.getInt() & INTMASK;
+                endCharCode[i] = buffer.getInt() & INTMASK;
+                startGlyphID[i] = buffer.getInt() & INTMASK;
+            }
+
+            /* Finds the high bit by binary searching through the bits */
+            int value = numGroups;
+
+            if (value >= 1 << 16) {
+                value >>= 16;
+                highBit += 16;
+            }
+
+            if (value >= 1 << 8) {
+                value >>= 8;
+                highBit += 8;
+            }
+
+            if (value >= 1 << 4) {
+                value >>= 4;
+                highBit += 4;
+            }
+
+            if (value >= 1 << 2) {
+                value >>= 2;
+                highBit += 2;
+            }
+
+            if (value >= 1 << 1) {
+                value >>= 1;
+                highBit += 1;
+            }
+
+            power = 1 << highBit;
+            extra = numGroups - power;
+        }
+
+        char getGlyph(int charCode) {
+            int controlGlyph = getControlCodeGlyph(charCode, false);
+            if (controlGlyph >= 0) {
+                return (char)controlGlyph;
+            }
+            int probe = power;
+            int range = 0;
+
+            if (startCharCode[extra] <= charCode) {
+                range = extra;
+            }
+
+            while (probe > 1) {
+                probe >>= 1;
+
+                if (startCharCode[range+probe] <= charCode) {
+                    range += probe;
+                }
+            }
+
+            if (startCharCode[range] <= charCode &&
+                  endCharCode[range] >= charCode) {
+                return (char)
+                    (startGlyphID[range] + (charCode - startCharCode[range]));
+            }
+
+            return 0;
+        }
+
+    }
+
+    /* Used to substitute for bad Cmaps. */
+    static class NullCMapClass extends CMap {
+
+        char getGlyph(int charCode) {
+            return 0;
+        }
+    }
+
+    public static final NullCMapClass theNullCmap = new NullCMapClass();
+
+    final int getControlCodeGlyph(int charCode, boolean noSurrogates) {
+        if (charCode < 0x0010) {
+            switch (charCode) {
+            case 0x0009:
+            case 0x000a:
+            case 0x000d: return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
+            }
+        } else if (charCode >= 0x200c) {
+            if ((charCode <= 0x200f) ||
+                (charCode >= 0x2028 && charCode <= 0x202e) ||
+                (charCode >= 0x206a && charCode <= 0x206f)) {
+                return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
+            } else if (noSurrogates && charCode >= 0xFFFF) {
+                return 0;
+            }
+        }
+        return -1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/CharToGlyphMapper.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2011, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+/*
+ * NB the versions that take a char as an int are used by the opentype
+ * layout engine. If that remains in native these methods may not be
+ * needed in the Java class.
+ */
+public abstract class CharToGlyphMapper {
+
+    public static final int HI_SURROGATE_SHIFT = 10;
+    public static final int HI_SURROGATE_START = 0xD800;
+    public static final int HI_SURROGATE_END = 0xDBFF;
+    public static final int LO_SURROGATE_START = 0xDC00;
+    public static final int LO_SURROGATE_END = 0xDFFF;
+    public static final int SURROGATES_START = 0x10000;
+
+    public static final int MISSING_GLYPH = 0;
+    public static final int INVISIBLE_GLYPH_ID = 0xffff;
+
+    protected int missingGlyph = MISSING_GLYPH;
+    
+    public boolean canDisplay(char cp) {
+        int glyph = charToGlyph(cp);
+        return glyph != missingGlyph;
+    }
+
+    public int getMissingGlyphCode() {
+        return missingGlyph;
+    }
+
+    public abstract int getGlyphCode(int charCode);
+
+    public int charToGlyph(char unicode) {
+        return getGlyphCode(unicode);
+    }
+
+    public int charToGlyph(int unicode) {
+        return getGlyphCode(unicode);
+    }
+
+    public void charsToGlyphs(int start, int count, char[] unicodes, 
+                              int[] glyphs, int glyphStart) {
+        for (int i=0; i<count; i++) {
+            int code = unicodes[start + i]; // char is unsigned.
+            if (code >= HI_SURROGATE_START &&
+                code <= HI_SURROGATE_END && i + 1 < count) {
+                char low = unicodes[start + i + 1];
+
+                if (low >= LO_SURROGATE_START &&
+                    low <= LO_SURROGATE_END) {
+                    code = ((code - HI_SURROGATE_START) << HI_SURROGATE_SHIFT) +
+                        low - LO_SURROGATE_START + SURROGATES_START;
+                    glyphs[glyphStart + i] = getGlyphCode(code);
+                    i += 1; // Empty glyph slot after surrogate
+                    glyphs[glyphStart + i] = INVISIBLE_GLYPH_ID;
+                    continue;
+                }
+            }
+            glyphs[glyphStart + i] = getGlyphCode(code);
+        }
+    }
+    
+    public void charsToGlyphs(int start, int count, char[] unicodes, int[] glyphs) {
+        charsToGlyphs(start, count, unicodes, glyphs, 0);
+    }
+    
+    public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {
+        charsToGlyphs(0, count, unicodes, glyphs, 0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/CompositeFontResource.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+
+public interface CompositeFontResource extends FontResource {
+
+    public FontResource getSlotResource(int slot);
+
+    public int getNumSlots();
+
+    /**
+     * Returns the slot for the given font name.
+     * Adds fontName as a new fallback font if needed.
+     */
+    public int getSlotForFont(String fontName);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/CompositeGlyphMapper.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2011, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+import java.util.HashMap;
+
+public class CompositeGlyphMapper extends CharToGlyphMapper {
+
+    public static final int SLOTMASK =  0xff000000;
+    public static final int GLYPHMASK = 0x00ffffff;
+
+    public static final int NBLOCKS = 216;
+    public static final int BLOCKSZ = 256;
+    public static final int MAXUNICODE = NBLOCKS*BLOCKSZ;
+
+    private static final int SIMPLE_ASCII_MASK_START =  0x0020;
+    private static final int SIMPLE_ASCII_MASK_END =    0x007e;
+    private static final int ASCII_COUNT =
+            SIMPLE_ASCII_MASK_END - SIMPLE_ASCII_MASK_START + 1;
+
+    private boolean asciiCacheOK;
+    private char charToGlyph[]; // Quick lookup
+
+    CompositeFontResource font;
+    CharToGlyphMapper slotMappers[];
+
+    /* For now, we'll use a Map to store the char->glyph lookup result.
+     * Maybe later I could use arrays for "common" values and
+     * perhaps for less common values, just not cache at all if
+     * lookup is relatively inexpensive. Or let the slot fonts do
+     * the caching ? So a variety of strategies are possible.
+     */
+    HashMap<Integer, Integer> glyphMap;
+
+    public CompositeGlyphMapper(CompositeFontResource compFont) {
+        font = compFont;
+        missingGlyph = 0; // TrueType font standard, avoids lookup.
+        glyphMap = new HashMap<Integer, Integer>();
+        slotMappers = new CharToGlyphMapper[compFont.getNumSlots()];
+        asciiCacheOK = true;
+    }
+
+    private final CharToGlyphMapper getSlotMapper(int slot) {
+        CharToGlyphMapper mapper = slotMappers[slot];
+        if (mapper == null) {
+            mapper = font.getSlotResource(slot).getGlyphMapper();
+            slotMappers[slot] = mapper;
+        }
+        return mapper;
+    }
+
+    public int getMissingGlyphCode() {
+        return missingGlyph; 
+    }
+
+    /* Making the glyph codes of a composite including the first
+     * slot have bits in the top byte set will indicate to the rendering
+     * loops that they need to locate the glyphs by dereferencing to
+     * the physical font strike.
+     */
+    public final int compositeGlyphCode(int slot, int glyphCode) {
+        return ((slot) << 24 | (glyphCode & GLYPHMASK));
+    }
+
+    private final int convertToGlyph(int unicode) {
+        for (int slot = 0; slot < font.getNumSlots(); slot++) {
+            CharToGlyphMapper mapper = getSlotMapper(slot);
+            int glyphCode = mapper.charToGlyph(unicode);
+            if (glyphCode != mapper.getMissingGlyphCode()) {
+                glyphCode = compositeGlyphCode(slot, glyphCode);
+                glyphMap.put(unicode, glyphCode);
+                return glyphCode;
+            }
+        }
+        glyphMap.put(unicode, missingGlyph);
+        return missingGlyph;
+    }
+
+    private int getAsciiGlyphCode(int charCode) {
+
+        // Check if charCode is in ASCII range
+        if (!asciiCacheOK ||
+            (charCode > SIMPLE_ASCII_MASK_END) ||
+            (charCode < SIMPLE_ASCII_MASK_START)) {
+            return -1;
+        }
+
+        // Construct charToGlyph array of all ASCII characters
+        if (charToGlyph == null) {
+            char glyphCodes[] = new char[ASCII_COUNT];
+            CharToGlyphMapper mapper = getSlotMapper(0);
+            int missingGlyphCode = mapper.getMissingGlyphCode();
+            for (int i = 0; i < ASCII_COUNT; i++) {
+                int glyphCode = mapper.charToGlyph(SIMPLE_ASCII_MASK_START + i);
+                if (glyphCode == missingGlyphCode) {
+                    // If any glyphCode is missing, then do not use charToGlyph
+                    // array.
+                    charToGlyph = null;
+                    asciiCacheOK = false;
+                    return -1;
+                }
+                // Slot 0 mask is 0, so can use this glyphCode directly
+                glyphCodes[i] = (char)glyphCode;
+            }
+            charToGlyph = glyphCodes;
+        }
+
+        int index = charCode - SIMPLE_ASCII_MASK_START;
+        return charToGlyph[index];
+    }
+
+    public int getGlyphCode(int charCode) {
+        // If ASCII then array lookup, else use glyphMap
+        int retVal = getAsciiGlyphCode(charCode);
+        if (retVal >= 0) {
+            return retVal;
+        }
+
+        Integer codeInt = glyphMap.get(charCode);
+        if (codeInt != null) {
+            return codeInt.intValue();
+        } else {
+            return convertToGlyph(charCode);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/CompositeStrike.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2011, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+import com.sun.javafx.scene.text.GlyphList;
+import com.sun.javafx.geom.transform.Affine2D;
+import com.sun.javafx.geom.transform.BaseTransform;
+import com.sun.javafx.geom.Path2D;
+import com.sun.javafx.geom.Shape;
+
+public class CompositeStrike implements FontStrike {
+
+    private CompositeFontResource fontResource;
+    private float size;
+    private int aaMode;
+    BaseTransform transform;
+    private FontStrike slot0Strike;
+    private FontStrike[] strikeSlots;
+
+    private FontStrikeDesc desc;
+    DisposerRecord disposer;
+
+    public void clearDesc() {
+        fontResource.getStrikeMap().remove(desc);
+        // For a composite strike, you also need to remove the strike
+        // refs of the raw fonts. At the least this needs to remove
+        // the slot 0 strike, but it may be that the fallback strikes
+        // should be left alone as they could be shared. This needs
+        // to be re-visited.
+        if (slot0Strike != null) {
+            slot0Strike.clearDesc();
+        }
+        if (strikeSlots != null) {
+            for (int i=1; i<strikeSlots.length; i++) {
+                if (strikeSlots[i] != null) {
+                    strikeSlots[i].clearDesc();
+                }
+            }
+        }
+    }
+
+    CompositeStrike(CompositeFontResource fontResource,
+                    float size, BaseTransform graphicsTransform, int aaMode,
+                    FontStrikeDesc desc) {
+
+        this.fontResource = fontResource;
+        this.size = size;
+        if (graphicsTransform.isTranslateOrIdentity()) {
+            this.transform = BaseTransform.IDENTITY_TRANSFORM;
+        } else {
+            this.transform = graphicsTransform.copy();
+        }
+        this.desc = desc;
+        this.aaMode = aaMode;
+        // CompositeStrikes do not directly hold any native resources
+        // but we need to free the desc key from the strike map after
+        // we find the strike has been GC'd.
+        disposer = new CompositeStrikeDisposer(fontResource, desc);
+    }
+
+    public int getAAMode() {
+        if (PrismFontLoader.isLCDTextSupported()) {
+            return this.aaMode;
+        } else {
+            return FontResource.AA_GREYSCALE;
+        }
+    }
+
+    /**
+     * Trusting caller to NOT mutate the returned result, to
+     * avoid a clone.
+     */
+    public BaseTransform getTransform() {
+        return transform;
+    }
+
+    public FontStrike getStrikeSlot(int slot) {
+        if (slot == 0) {
+            if (slot0Strike == null) {
+                FontResource slot0Resource = fontResource.getSlotResource(0);
+                slot0Strike = slot0Resource.getStrike(size, transform,
+                                                      getAAMode());
+            }
+            return slot0Strike;
+        } else {
+            if (strikeSlots == null) {
+                strikeSlots = new FontStrike[fontResource.getNumSlots()];
+            }
+
+            if (slot >= strikeSlots.length) {
+                FontStrike[] tmp = new FontStrike[fontResource.getNumSlots()];
+                System.arraycopy(strikeSlots, 0, tmp, 0, strikeSlots.length);
+                strikeSlots = tmp;
+            }
+            if (strikeSlots[slot] == null) {
+                FontResource slotResource = fontResource.getSlotResource(slot);
+                strikeSlots[slot] = slotResource.getStrike(size, transform,
+                                                           getAAMode());
+            }
+            return strikeSlots[slot];
+        }
+    }
+
+    public boolean isSubPixelGlyph() {
+        return getStrikeSlot(0).isSubPixelGlyph();
+    }
+
+    public FontResource getFontResource() {
+        return fontResource;
+    }
+
+    public int getStrikeSlotForGlyph(int glyphCode) {
+        return (glyphCode >>> 24);
+    }
+
+    public float getSize() {
+        return size;
+    }
+
+    public boolean drawAsShapes() {
+        return getStrikeSlot(0).drawAsShapes();
+    }
+
+    private PrismMetrics metrics;
+
+    public Metrics getMetrics() {
+        if (metrics == null) {
+            PrismFontFile fr = (PrismFontFile)fontResource.getSlotResource(0);
+            metrics = fr.getFontMetrics(size);
+        }
+        return metrics;
+    }
+
+    public Glyph getGlyph(char symbol) {
+        int glyphCode = fontResource.getGlyphMapper().charToGlyph(symbol);
+        return getGlyph(glyphCode);
+    }
+
+    public Glyph getGlyph(int glyphCode) {
+        int slot = (glyphCode >>> 24);
+        int slotglyphCode = glyphCode & CompositeGlyphMapper.GLYPHMASK;
+        return getStrikeSlot(slot).getGlyph(slotglyphCode);
+    }
+
+     /**
+     * Access to individual character advances are frequently needed for layout
+     * understand that advance may vary for single glyph if ligatures or kerning
+     * are enabled
+     * @param ch char
+     * @return advance of single char
+     */
+    public float getCharAdvance(char ch) {
+        int glyphCode = fontResource.getGlyphMapper().charToGlyph((int)ch);
+        return fontResource.getAdvance(glyphCode, size);
+    }
+
+    public Shape getOutline(GlyphList gl, BaseTransform transform) {
+
+        Path2D result = new Path2D();
+        getOutline(gl, transform, result);
+        return result;
+    }
+
+    void getOutline(GlyphList gl, BaseTransform transform, Path2D p) {
+        p.reset();
+        if (gl == null) {
+            return;
+        }
+        if (transform == null) {
+            transform = BaseTransform.IDENTITY_TRANSFORM;
+        }
+        Affine2D t = new Affine2D();
+        for (int i = 0; i < gl.getGlyphCount(); i++) {
+            int glyphCode = gl.getGlyphCode(i);
+            if (glyphCode != CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
+                t.setTransform(transform);
+                Glyph glyph = getGlyph(glyphCode);
+                Shape gp = glyph.getShape();
+                t.translate(gl.getPosX(i), gl.getPosY(i));
+                p.append(gp.getPathIterator(t), false);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/CompositeStrikeDisposer.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+package com.sun.javafx.font;
+import java.lang.ref.WeakReference;
+
+import com.sun.javafx.font.DisposerRecord;
+import com.sun.javafx.font.FontResource;
+import com.sun.javafx.font.FontStrikeDesc;
+
+class CompositeStrikeDisposer implements DisposerRecord {
+
+    FontResource fontResource;
+    FontStrikeDesc desc;
+    boolean disposed = false;
+
+    public CompositeStrikeDisposer(FontResource font, FontStrikeDesc desc) {
+        this.fontResource = font;
+        this.desc = desc;
+    }
+
+    public synchronized void dispose() {
+        if (!disposed) {
+            // Careful here. The original strike we are collecting
+            // may now be superseded in the map, so only remove
+            // the desc if the value reference has been cleared
+            WeakReference ref = fontResource.getStrikeMap().get(desc);
+            if (ref != null) {
+                Object o = ref.get();
+                if (o == null) {
+                    fontResource.getStrikeMap().remove(desc);
+                }
+            }
+
+            disposed = true;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/DFontDecoder.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import com.sun.glass.utils.NativeLibLoader;
+
+class DFontDecoder extends FontFileWriter {
+    static {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            public Void run() {
+                NativeLibLoader.loadLibrary("javafx-font");
+                return null;
+            }
+        });
+    }
+    private native static long createCTFont(String fontName);
+    private native static void releaseCTFont(long font);
+    private native static int getCTFontFormat(long font);
+    private native static int[] getCTFontTags(long font);
+    private native static byte[] getCTFontTable(long font, int tag);
+
+    public DFontDecoder() {
+        super();
+    }
+
+    public void decode(String fontName) throws IOException { 
+        if (fontName == null) {
+            throw new IOException("Invalid font name");
+        }
+        long fontRef = 0;
+        try {
+            fontRef = DFontDecoder.createCTFont(fontName);
+            if (fontRef == 0) {
+                throw new IOException("Failure creating CTFont");
+            }
+            int format = DFontDecoder.getCTFontFormat(fontRef);
+            if (format != trueTag && format != v1ttTag && format != ottoTag) {
+                throw new IOException("Unsupported Dfont");
+            }
+            int[] tags = DFontDecoder.getCTFontTags(fontRef);
+            short numTables = (short)tags.length;
+            int size = TTCHEADERSIZE + (DIRECTORYENTRYSIZE * numTables);
+            byte[][] tableData = new byte[numTables][];
+            for (int i = 0; i < tags.length; i++) {
+                int tag = tags[i];          
+                tableData[i] = DFontDecoder.getCTFontTable(fontRef, tag);
+                int length = tableData[i].length;
+                size += (length + 3) & ~3;
+            }
+            DFontDecoder.releaseCTFont(fontRef);
+            fontRef = 0;
+
+            /* write header */
+            setLength(size);
+            writeHeader(format, numTables);
+
+            int dataOffset = TTCHEADERSIZE + (DIRECTORYENTRYSIZE * numTables);
+            for (int i = 0; i < numTables; i++) {
+                int tag = tags[i];
+                byte[] data = tableData[i];
+
+                /* write directory entry */
+                writeDirectoryEntry(i, tag, 0, dataOffset, data.length);
+
+                /* write table */
+                seek(dataOffset);
+                writeBytes(data);
+
+                dataOffset += (data.length + 3) & ~3;
+            }
+
+        } finally {
+            if (fontRef != 0) {
+                DFontDecoder.releaseCTFont(fontRef);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/Disposer.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2011, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Hashtable;
+
+/**
+ * This class is used for registering and disposing the native
+ * data associated with java objects.
+ *
+ * The object can register itself by calling the addRecord method and
+ * providing a descendant of the DisposerRecord class with overridden
+ * dispose() method.
+ *
+ * When the object becomes unreachable, the dispose() method
+ * of the associated DisposerRecord object will be called.
+ *
+ * @see DisposerRecord
+ */
+public class Disposer implements Runnable {
+    private static final ReferenceQueue queue = new ReferenceQueue();
+    private static final Hashtable records = new Hashtable();
+    private static Disposer disposerInstance;
+
+    static {
+        disposerInstance = new Disposer();
+
+        ThreadGroup tg = Thread.currentThread().getThreadGroup();
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction() {
+                public Object run() {
+                    /* The thread must be a member of a thread group
+                     * which will not get GCed before VM exit.
+                     * Make its parent the top-level thread group.
+                     */
+                    ThreadGroup tg = Thread.currentThread().getThreadGroup();
+                    for (ThreadGroup tgn = tg;
+                         tgn != null;
+                         tg = tgn, tgn = tg.getParent());
+                    Thread t =
+                        new Thread(tg, disposerInstance, "Prism Font Disposer");
+                    t.setContextClassLoader(null);
+                    t.setDaemon(true);
+                    t.setPriority(Thread.MAX_PRIORITY);
+                    t.start();
+                    return null;
+                }
+            }
+        );
+    }
+
+    /**
+     * Registers the object and the native data for later disposal.
+     * @param target Object to be registered
+     * @param rec the associated DisposerRecord object
+     * @see DisposerRecord
+     */
+    public static WeakReference addRecord(Object target, DisposerRecord rec) {
+        WeakReference ref = new WeakReference(target, queue);
+        disposerInstance.records.put(ref, rec);
+        return ref;
+    }
+
+    public void run() {
+        while (true) {
+            try {
+                Object obj = queue.remove();
+                ((Reference)obj).clear();
+                DisposerRecord rec = (DisposerRecord)records.remove(obj);
+                rec.dispose();
+                obj = null;
+                rec = null;
+            } catch (Exception e) {
+                System.out.println("Exception while removing reference: " + e);
+                e.printStackTrace();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/DisposerRecord.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+/**
+ * This class is used to hold the resource to be disposed.
+ */
+public interface DisposerRecord {
+    public void dispose();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/FallbackResource.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2011, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.sun.javafx.geom.transform.BaseTransform;
+
+
+/*
+ * Create a singleton fallback resource per style to be shared across
+ * all physical fonts. "Per style" refers to the Bold and Italic styles,
+ * thus will (eventually) be 4 in all.
+ */
+
+class FallbackResource implements CompositeFontResource {
+
+
+    private ArrayList<String> linkedFontFiles;
+    private ArrayList<String> linkedFontNames;
+    private FontResource[] fallbacks;
+    private FontResource[] nativeFallbacks;
+    private boolean isBold, isItalic;
+    private int aaMode;
+    private CompositeGlyphMapper mapper;
+
+    Map<FontStrikeDesc, WeakReference<FontStrike>> strikeMap =
+       new ConcurrentHashMap<FontStrikeDesc, WeakReference<FontStrike>>();
+
+
+    public Map<FontStrikeDesc, WeakReference<FontStrike>> getStrikeMap() {
+        return strikeMap;
+    }
+
+    FallbackResource(boolean bold, boolean italic, int aaMode) {
+        this.isBold = bold;
+        this.isItalic = italic;
+        this.aaMode = aaMode;
+    }
+
+    static FallbackResource[] greyFallBackResource = new FallbackResource[4];
+    static FallbackResource[] lcdFallBackResource = new FallbackResource[4];
+
+    static FallbackResource
+        getFallbackResource(boolean bold, boolean italic, int aaMode) {
+        FallbackResource[] arr =
+            (aaMode == FontResource.AA_GREYSCALE) ?
+            greyFallBackResource : lcdFallBackResource;
+        int index = bold ? 1 : 0;
+        if (italic) {
+            index +=2;
+        }
+        FallbackResource font = arr[index];
+        if (font == null) {
+            font = new FallbackResource(bold, italic, aaMode);
+            arr[index] = font;
+        }
+        return font;
+    }
+
+    public int getDefaultAAMode() {
+        return aaMode;  // for now, has to be same as main font.
+    }
+
+    /* Superficially implement the FontResource interface,
+     * but for this fall back resource, we should not be asked for
+     * the names or number of glyphs as those are reported for the
+     * primary font.
+     */
+    private String throwException() {
+         throw new UnsupportedOperationException("Not supported");
+    }
+
+    public String getFullName() {
+        return throwException();
+    }
+
+    public String getPSName() {
+        return throwException();
+    }
+
+    public String getFamilyName() {
+        return throwException();
+    }
+
+    public String getStyleName() {
+        return throwException();
+    }
+
+    public String getLocaleFullName() {
+        return throwException();
+    }
+
+    public String getLocaleFamilyName() {
+        return throwException();
+    }
+
+    public String getLocaleStyleName() {
+        return throwException();
+    }
+
+
+    public boolean isBold() {
+        throw new UnsupportedOperationException("Not supported");
+    }
+
+    public boolean isItalic() {
+        throw new UnsupportedOperationException("Not supported");
+
+    }
+
+    public int getFeatures() {
+        throw new UnsupportedOperationException("Not supported");
+    }
+
+    public String getFileName() {
+        return throwException();
+    }
+
+    public Object getPeer() {
+        return null;
+    }
+
+    public void setPeer(Object peer) {
+        throwException();
+    }
+
+    public boolean isEmbeddedFont() {
+        return false;
+    }
+
+    public CharToGlyphMapper getGlyphMapper() {
+        if (mapper == null) {
+            mapper = new CompositeGlyphMapper(this);
+        }
+        return mapper;
+    }
+
+    public int getSlotForFont(String fontName) {
+        getLinkedFonts();
+        int i = 0;
+        for (String linkedFontName : linkedFontNames) {
+            if (fontName.equalsIgnoreCase(linkedFontName)) {
+                return i;
+            }
+            i++;
+        }
+        if (nativeFallbacks != null) {
+            for (FontResource nativeFallback : nativeFallbacks) {
+                if (fontName.equalsIgnoreCase(nativeFallback.getFullName())) {
+                    return i;
+                }
+                i++;
+            }
+        }
+
+        /* Add the font to the list of native fallbacks */
+        FontResource[] tmp;
+        if (nativeFallbacks == null) {
+            tmp = new FontResource[1];
+        } else {
+            tmp = new FontResource[nativeFallbacks.length + 1];
+            System.arraycopy(nativeFallbacks, 0, tmp, 0, nativeFallbacks.length);
+        }
+        PrismFontFactory factory = PrismFontFactory.getFontFactory();
+        tmp[tmp.length - 1] = factory.getFontResource(fontName, null, false);
+        nativeFallbacks = tmp;
+
+        return i;
+    }
+
+    /* To start with we will use the exact same fall back list for
+     * everything.
+     */
+    private void getLinkedFonts() {
+        if (fallbacks == null) {
+            if (PrismFontFactory.isLinux) {
+                FontConfigManager.FcCompFont font =
+                    FontConfigManager.getFontConfigFont("sans",
+                                                        isBold, isItalic);
+                linkedFontFiles = FontConfigManager.getFileNames(font, false);
+                linkedFontNames = FontConfigManager.getFontNames(font, false);
+                fallbacks = new FontResource[linkedFontFiles.size()];
+            } else {
+                ArrayList<String>[] linkedFontInfo;
+                if (PrismFontFactory.isMacOSX) {
+                    linkedFontInfo =
+                        PrismFontFactory.getLinkedFonts("Arial Unicode MS", true);
+                } else {
+                    linkedFontInfo =
+                        PrismFontFactory.getLinkedFonts("Tahoma", true);
+                }
+                linkedFontFiles = linkedFontInfo[0];
+                linkedFontNames = linkedFontInfo[1];
+                fallbacks = new FontResource[linkedFontFiles.size()];
+            }
+        }
+    }
+
+    public int getNumSlots() {
+        getLinkedFonts();
+        int num = linkedFontFiles.size();
+        if (nativeFallbacks != null) {
+            num += nativeFallbacks.length;
+        }
+        return num;
+    }
+
+    public float[] getGlyphBoundingBox(int glyphCode,
+                                float size, float[] retArr) {
+        int slot = (glyphCode >>> 24);
+        int slotglyphCode = glyphCode & CompositeGlyphMapper.GLYPHMASK;
+        FontResource slotResource = getSlotResource(slot);
+        return slotResource.getGlyphBoundingBox(slotglyphCode, size, retArr);
+    }
+
+    public float getAdvance(int glyphCode, float size) {
+        int slot = (glyphCode >>> 24);
+        int slotglyphCode = glyphCode & CompositeGlyphMapper.GLYPHMASK;
+        FontResource slotResource = getSlotResource(slot);
+        return slotResource.getAdvance(slotglyphCode, size);
+    }
+
+    public synchronized FontResource getSlotResource(int slot) {
+        getLinkedFonts();
+        if (slot >= fallbacks.length) {
+            slot = slot - fallbacks.length;
+            if (nativeFallbacks == null || slot >= nativeFallbacks.length) {
+                return null;
+            }
+            return nativeFallbacks[slot];
+        }
+        if (fallbacks[slot] == null) {
+            String file = linkedFontFiles.get(slot);
+            String name = linkedFontNames.get(slot);
+            fallbacks[slot] =
+                PrismFontFactory.getFontFactory().
+                getFontResource(name, file, false);
+        }
+        return fallbacks[slot];
+    }
+
+    public FontStrike getStrike(float size, BaseTransform transform) {
+        return getStrike(size, transform, getDefaultAAMode());
+    }
+
+    public FontStrike getStrike(float size, BaseTransform transform,
+                                int aaMode) {
+
+        FontStrikeDesc desc = new FontStrikeDesc(size, transform, aaMode);
+        WeakReference<FontStrike> ref = strikeMap.get(desc);
+        CompositeStrike strike = null;
+
+        if (ref != null) {
+            strike = (CompositeStrike)ref.get();
+        }
+        if (strike == null) {
+            strike = new CompositeStrike(this, size, transform, aaMode, desc);
+            if (strike.disposer != null) {
+                ref = Disposer.addRecord(strike, strike.disposer);
+            } else {
+                ref = new WeakReference<FontStrike>(strike);
+            }
+            strikeMap.put(desc, ref);
+        }
+        return strike;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-font/src/com/sun/javafx/font/FontConfigManager.java	Thu Jun 20 09:48:36 2013 -0700
@@ -0,0 +1,566 @@
+/*
+ * Copyright (c) 2012, 2013, 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.
+ */
+
+package com.sun.javafx.font;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Properties;
+
+class FontConfigManager {
+
+    static boolean debugFonts = false;
+    static boolean fontConfigFailed = false;
+    static boolean useEmbeddedFontSupport = false;
+
+    static {
+        AccessController.doPrivileged(
+            new PrivilegedAction<Void>() {
+                public Void run() {
+                    String dbg = System.getProperty("prism.debugfonts", "");
+                    debugFonts = "true".equals(dbg);
+                    String emb = System.getProperty("prism.embeddedfonts", "");
+                    useEmbeddedFontSupport = "true".equals(emb);
+                    return null;
+                }
+            }
+        );
+    }
+
+    /* These next three classes are just data structures.
+     */
+    public static class FontConfigFont {
+        public String familyName;        // eg Bitstream Vera Sans
+        public String styleStr;          // eg Bold
+        public String fullName;          // eg Bitstream Vera Sans Bold
+        public String fontFile;          // eg /usr/X11/lib/fonts/foo.ttf
+    }
+
+    public static class FcCompFont {
+        public String fcName;            // eg sans
+        public String fcFamily;          // eg sans
+        //public String fxName;           // eg sans serif
+        public int style;                // eg 0=PLAIN
+        public FontConfigFont firstFont;
+        public FontConfigFont[] allFonts;
+        //public CompositeFont compFont;   // null if not yet created/known.
+    }
+
+    /* fontconfig recognises slants roman, italic, as well as oblique,
+     * and a slew of weights, where the ones that matter here are
+     * regular and bold.
+     * To fully qualify what we want, we can for example ask for (eg)
+     * Font.PLAIN             : "serif:regular:roman"
+     * Font.BOLD              : "serif:bold:roman"
+     * Font.ITALIC            : "serif:regular:italic"
+     * Font.BOLD|Font.ITALIC  : "serif:bold:italic"
+     */
+    private static final String[] fontConfigNames = {
+        "sans:regular:roman",
+        "sans:bold:roman",
+        "sans:regular:italic",
+        "sans:bold:italic",
+
+        "serif:regular:roman",
+        "serif:bold:roman",
+        "serif:regular:italic",
+        "serif:bold:italic",
+
+        "monospace:regular:roman",
+        "monospace:bold:roman",
+        "monospace:regular:italic",
+        "monospace:bold:italic",
+    };
+
+    /* This array has the array elements created in Java code and is
+     * passed down to native to be filled in.
+     */
+    private static FcCompFont[] fontConfigFonts;
+
+    private FontConfigManager() {
+    }
+
+    private static String[] getFontConfigNames() {
+        return fontConfigNames;
+    }
+
+    private static String getFCLocaleStr() {
+        Locale l = Locale.getDefault();
+        String localeStr = l.getLanguage();
+        String country = l.getCountry();
+        if (!country.equals("")) {
+            localeStr = localeStr + "-" + country;
+        }
+        return localeStr;
+    }
+
+    /* Return an array of FcCompFont structs describing the primary
+     * font located for each of fontconfig/GTK/Pango's logical font names.
+     */
+    private static native boolean getFontConfig(String locale,
+                                                FcCompFont[] fonts,
+                                                boolean includeFallbacks);
+
+    private static synchronized void initFontConfigLogFonts() {
+
+        if (fontConfigFonts != null || fontConfigFailed) {
+            return;
+        }
+
+        long t0 = 0;
+        if (debugFonts) {
+            t0 = System.nanoTime();
+        }
+
+        String[] fontConfigNames = FontConfigManager.getFontConfigNames();
+        FcCompFont[] fontArr = new FcCompFont[fontConfigNames.length];
+
+        for (int i = 0; i< fontArr.length; i++) {
+            fontArr[i] = new FcCompFont();
+            fontArr[i].fcName = fontConfigNames[i];
+            int colonPos = fontArr[i].fcName.indexOf(':');
+            fontArr[i].fcFamily = fontArr[i].fcName.substring(0, colonPos);
+            fontArr[i].style = i % 4; // depends on array order.
+        }
+        if (useEmbeddedFontSupport ||
+            !getFontConfig(getFCLocaleStr(), fontArr, true))
+        {
+            EmbeddedFontSupport.initLogicalFonts(fontArr);
+        }
+        FontConfigFont anyFont = null;
+        /* If don't find anything (eg no libfontconfig), then just return */
+        for (int i = 0; i< fontArr.length; i++) {
+            FcCompFont fci = fontArr[i];
+            if (fci.firstFont == null) {
+                if (debugFonts) {
+                    System.err.println("Fontconfig returned no font for " +
+                                fontArr[i].fcName);
+                }
+                fontConfigFailed = true;
+            } else if (anyFont == null) {
+                anyFont = fci.firstFont;
+                defaultFontFile = anyFont.fontFile;
+            }
+        }
+
+        if (anyFont == null) {
+            if (debugFonts) {
+                System.err.println("Fontconfig returned no fonts at all.");
+            }
+            fontConfigFailed = true;
+            return;
+        } else if (fontConfigFailed) {
+            for (int i = 0; i< fontArr.length; i++) {
+                if (fontArr[i].firstFont == null) {
+                    fontArr[i].firstFont = anyFont;
+                }
+            }
+        }
+
+        fontConfigFonts = fontArr;
+
+        if (debugFonts) {
+
+            long t1 = System.nanoTime();
+            System.err.println("Time spent accessing fontconfig="
+                               + ((t1 - t0) / 1000000) + "ms.");
+
+            for (int i = 0; i<fontConfigFonts.length; i++) {
+                FcCompFont fci = fontConfigFonts[i];
+                System.err.println("FC font " + fci.fcName+" maps to " +
+                                   fci.firstFont.fullName +
+                                   " in file " + fci.firstFont.fontFile);
+                if (fci.allFonts != null) {
+                    for (int f=0;f<fci.allFonts.length;f++) {
+                        FontConfigFont fcf = fci.allFonts[f];
+                        System.err.println(" "+f+ ") Family=" +
+                                           fcf.familyName +
+                                           ", Style="+ fcf.styleStr +
+                                           ", Fullname="+fcf.fullName +
+                                           ", File="+fcf.fontFile);
+                    }
+                }
+            }
+        }
+    }
+
+    private static native boolean populateMapsNative
+        (HashMap<String,String> fontToFileMap,
+         HashMap<String,String> fontToFamilyNameMap,
+         HashMap<String,ArrayList<String>> familyToFontListMap,
+         Locale locale);
+
+    public static void populateMaps
+        (HashMap<String,String> fontToFileMap,
+         HashMap<String,String> fontToFamilyNameMap,
+         HashMap<String,ArrayList<String>> familyToFontListMap,
+         Locale locale) {
+
+        if (fontConfigFailed ||
+            useEmbeddedFontSupport ||
+            !populateMapsNative(fontToFileMap, fontToFamilyNameMap,
+                                familyToFontListMap, locale)) {
+            EmbeddedFontSupport.populateMaps(fontToFileMap,
+                                             fontToFamilyNameMap,
+                                             familyToFontListMap, locale);
+        }
+    }
+
+    private static String mapFxToFcLogicalFamilyName(String fxName) {
+        if (fxName.equals("serif")) {
+            return "serif";
+        } else if (fxName.equals("monospaced")) {
+            return "monospace";
+        } else {
+             return "sans";
+        }
+    }
+
+    public static FcCompFont getFontConfigFont(String fxFamilyName,
+                                               boolean bold, boolean italic) {
+
+        initFontConfigLogFonts();
+
+        if (fontConfigFonts == null) {
+            return null;
+        }
+
+        String name = mapFxToFcLogicalFamilyName(fxFamilyName.toLowerCase());
+        int style = (bold) ? 1 : 0;
+        if (italic) {
+            style +=2;
+        }
+
+        FcCompFont fcInfo = null;
+        for (int i=0; i<fontConfigFonts.length; i++) {
+            if (name.equals(fontConfigFonts[i].fcFamily) &&
+                style == fontConfigFonts[i].style) {
+                fcInfo = fontConfigFonts[i];
+                break;
+            }
+        }
+        if (fcInfo == null) {
+            fcInfo = fontConfigFonts[0];
+        }
+
+        if (debugFonts) {
+            System.err.println("FC name=" + name + " style=" + style +
+                               " uses " + fcInfo.firstFont.fullName +
+                               " in file: " + fcInfo.firstFont.fontFile);
+        }
+        return fcInfo;
+    }
+
+    private static String defaultFontFile;
+    public static String getDefaultFontPath() {
+        if (fontConfigFonts == null && !fontConfigFailed) {
+            // trigger font config initialisation
+            getFontConfigFont("System", false, false);
+        }
+        return defaultFontFile;
+    }
+
+    public static ArrayList<String>
+        getFileNames(FcCompFont font, boolean fallBacksOnly) {
+
+        ArrayList fileList = new ArrayList<String>();
+
+        if (font.allFonts != null) {
+            int start = (fallBacksOnly) ? 1 : 0;
+            for (int i=start; i<font.allFonts.length; i++) {
+                fileList.add(font.allFonts[i].fontFile);
+            }
+        }
+        return fileList;
+    }
+
+    public static ArrayList<String>
+        getFontNames(FcCompFont font, boolean fallBacksOnly) {
+
+        ArrayList fontList = new ArrayList<String>();
+
+        if (font.allFonts != null) {
+            int start = (fallBacksOnly) ? 1 : 0;
+            for (int i=start; i<font.allFonts.length; i++) {
+                fontList.add(font.allFonts[i].fullName);
+            }
+        }
+        return fontList;
+    }
+
+    /* Embedded Linux may not have fontconfig, in which case we look for
+     * 1) A single directory which contains all font files.
+     * 2) A java properties style file which describes which of these files
+     * to use for the logical fonts.
+     * Optionally a system property can be used to set the directory
+     * else it will default to "{FXHOME}/rt/lib/fonts".
+     */
+    private static class EmbeddedFontSupport {
+
+        private static String fontDirProp = null;
+        private static String fontDir;
+
+        static {
+            AccessController.doPrivileged(
+                new PrivilegedAction<Void>() {
+                    public Void run() {
+                        initEmbeddedFonts();
+                    return null;
+                    }
+                }
+            );
+        }
+
+        private static void initEmbeddedFonts() {