changeset 5223:932cecc14e49

RT-32255 [win only]
author Felipe Heidrich <felipe.heidrich@oracle.com>
date Tue, 01 Oct 2013 13:54:17 -0700
parents 4600cb2846c1
children 19431d2dcdd5
files modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontFile.java modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java modules/graphics/src/main/java/com/sun/javafx/font/directwrite/ID2D1RenderTarget.java modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteFactory.java modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteFontFace.java modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteLocalizedStrings.java modules/graphics/src/main/java/com/sun/javafx/font/directwrite/OS.java modules/graphics/src/main/native-font/directwrite.cpp
diffstat 9 files changed, 203 insertions(+), 244 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontFile.java	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWFontFile.java	Tue Oct 01 13:54:17 2013 -0700
@@ -58,6 +58,7 @@
     private IDWriteFontFace createEmbeddedFontFace() {
         IDWriteFactory factory = DWFactory.getDWriteFactory();
         IDWriteFontFile fontFile = factory.CreateFontFileReference(getFileName());
+        if (fontFile == null) return null;
         boolean[] isSupportedFontType = new boolean[1];
         int[] fontFileType = new int[1];
         int[] fontFaceType = new int[1];
@@ -67,7 +68,7 @@
         if (hr == OS.S_OK && isSupportedFontType[0]) {
             int faceIndex = getFontIndex();
             int simulation = OS.DWRITE_FONT_SIMULATIONS_NONE;
-            face = factory.CreateFontFace(fontFaceType[0], 1, fontFile, faceIndex, simulation);
+            face = factory.CreateFontFace(fontFaceType[0], fontFile, faceIndex, simulation);
         }
         fontFile.Release();
         return face;
@@ -92,16 +93,17 @@
         }
 
         IDWriteFontFamily family = collection.GetFontFamily(index);
+        if (family == null) return null;
         int weight = isBold() ? OS.DWRITE_FONT_WEIGHT_BOLD :
                                 OS.DWRITE_FONT_WEIGHT_NORMAL;
         int stretch = OS.DWRITE_FONT_STRETCH_NORMAL;
         int style = isItalic() ? OS.DWRITE_FONT_STYLE_ITALIC :
                                  OS.DWRITE_FONT_STYLE_NORMAL;
         IDWriteFont font = family.GetFirstMatchingFont(weight, stretch, style);
+        family.Release();
+        if (font == null) return null;
         IDWriteFontFace face = font.CreateFontFace();
-
         font.Release();
-        family.Release();
         return face;
     }
 
@@ -125,6 +127,7 @@
     @Override protected int[] createGlyphBoundingBox(int gc) {
         if (fontFace == null) return null;
         DWRITE_GLYPH_METRICS metrics = fontFace.GetDesignGlyphMetrics((short)gc, false);
+        if (metrics == null) return null;
         int[] bb = new int[4];
         bb[0] = metrics.leftSideBearing;
         bb[1] = metrics.verticalOriginY - metrics.advanceHeight + metrics.bottomSideBearing;
@@ -134,8 +137,8 @@
     }
 
     @Override
-    protected PrismFontStrike createStrike(float size, BaseTransform transform,
-                                           int aaMode, FontStrikeDesc desc) {
+    protected PrismFontStrike<DWFontFile> createStrike(float size, BaseTransform transform,
+                                                       int aaMode, FontStrikeDesc desc) {
         return new DWFontStrike(this, size, transform, aaMode, desc);
     }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java	Tue Oct 01 13:54:17 2013 -0700
@@ -39,7 +39,7 @@
     private float pixelXAdvance, pixelYAdvance;
     private RECT rect;
     private boolean drawShapes;
-    byte[] pixelData;
+    private byte[] pixelData;
 
     private static final boolean CACHE_TARGET = true;
     private static IWICBitmap cachedBitmap;
@@ -58,13 +58,13 @@
 
         IDWriteFontFace face = strike.getFontFace();
         run = new DWRITE_GLYPH_RUN();
-        run.fontFace = face.ptr;
+        run.fontFace = face != null ? face.ptr : 0;
         run.fontEmSize = strike.getSize();
         run.glyphIndices = (short)glyphCode;
         run.glyphAdvances = 0;
         run.advanceOffset = 0;
         run.ascenderOffset = 0;
-        run.bidiLevel = 0; //should not matter as it draws just one glyph
+        run.bidiLevel = 0;
         run.isSideways = false;
 
         /* Note: glyphs can be created on the JFX thread to create shapes
@@ -77,15 +77,18 @@
         if (metrics != null) return;
         //TODO could the metrics cached in DWFontFile be used ?
         IDWriteFontFace face = strike.getFontFace();
+        if (face == null) return;
         metrics = face.GetDesignGlyphMetrics(run.glyphIndices, false);
-        float upem = strike.getUpem();
-        pixelXAdvance = metrics.advanceWidth * strike.getSize() / upem;
-        pixelYAdvance = 0;
-        if (strike.matrix != null) {
-            Point2D pt = new Point2D(pixelXAdvance, pixelYAdvance);
-            strike.getTransform().transform(pt, pt);
-            pixelXAdvance = pt.x;
-            pixelYAdvance = pt.y;
+        if (metrics != null) {
+            float upem = strike.getUpem();
+            pixelXAdvance = metrics.advanceWidth * strike.getSize() / upem;
+            pixelYAdvance = 0;
+            if (strike.matrix != null) {
+                Point2D pt = new Point2D(pixelXAdvance, pixelYAdvance);
+                strike.getTransform().transform(pt, pt);
+                pixelXAdvance = pt.x;
+                pixelYAdvance = pt.y;
+            }
         }
     }
 
@@ -139,7 +142,7 @@
 
     byte[] getD2DMask(float subPixelX, float subPixelY, boolean lcd) {
         checkBounds();
-        if (getWidth() == 0 || getHeight() == 0) {
+        if (getWidth() == 0 || getHeight() == 0 || run.fontFace == 0) {
             return new byte[0];
         }
 
@@ -162,6 +165,9 @@
             bitmap = createBitmap(w, h);
             target = createRenderingTarget(bitmap);
         }
+        if (bitmap == null || target == null) {
+            return new byte[0];
+        }
 
         DWRITE_MATRIX matrix = strike.matrix;
         D2D1_MATRIX_3X2_F transform;
@@ -201,38 +207,42 @@
             return null;
         }
 
+        byte[] result = null;
         IWICBitmapLock lock = bitmap.Lock(0, 0, w, h, OS.WICBitmapLockRead);
-        //TODO instead of copying the entire buffer to java it would be faster to
-        //blit in native code.
-        byte[] buffer = lock.GetDataPointer();
-        int stride = lock.GetStride();
-        byte[] result;
-        int i = 0, j = 0;
-        byte one = (byte)0xFF;
-        if (lcd) {
-            result = new byte[w*h*3];
-            for (int y = 0; y < h; y++) {
-                int row = j;
-                for (int x = 0; x < w; x++) {
-                    result[i++] = (byte)(one - buffer[row++]);
-                    result[i++] = (byte)(one - buffer[row++]);
-                    result[i++] = (byte)(one - buffer[row++]);
-                    row++;
+        if (lock != null) {
+            byte[] buffer = lock.GetDataPointer();
+            // TODO instead of copying the entire buffer to java it would
+            // be faster to blit in native code.
+            if (buffer != null) {
+                int stride = lock.GetStride();
+                int i = 0, j = 0;
+                byte one = (byte)0xFF;
+                if (lcd) {
+                    result = new byte[w*h*3];
+                    for (int y = 0; y < h; y++) {
+                        int row = j;
+                        for (int x = 0; x < w; x++) {
+                            result[i++] = (byte)(one - buffer[row++]);
+                            result[i++] = (byte)(one - buffer[row++]);
+                            result[i++] = (byte)(one - buffer[row++]);
+                            row++;
+                        }
+                        j += stride;
+                    }
+                } else {
+                    result = new byte[w*h];
+                    for (int y = 0; y < h; y++) {
+                        int row = j;
+                        for (int x = 0; x < w; x++) {
+                            result[i++] = (byte)(one - buffer[row]);
+                            row += 4;
+                        }
+                        j += stride;
+                    }
                 }
-                j += stride;
             }
-        } else {
-            result = new byte[w*h];
-            for (int y = 0; y < h; y++) {
-                int row = j;
-                for (int x = 0; x < w; x++) {
-                    result[i++] = (byte)(one - buffer[row]);
-                    row += 4;
-                }
-                j += stride;
-            }
+            lock.Release();
         }
-        lock.Release();
 
         if (!cache) {
             bitmap.Release();
@@ -242,6 +252,7 @@
     }
 
     IDWriteGlyphRunAnalysis createAnalysis(float x, float y) {
+        if (run.fontFace == 0) return null;
         IDWriteFactory factory = DWFactory.getDWriteFactory();
         int renderingMode = OS.DWRITE_RENDERING_MODE_NATURAL;
         int measuringMode = OS.DWRITE_MEASURING_MODE_NATURAL;
@@ -296,6 +307,7 @@
     @Override
     public float getAdvance() {
         checkMetrics();
+        if (metrics == null) return 0;
         float upem = strike.getUpem();
         return metrics.advanceWidth * strike.getSize() / upem;
     }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java	Tue Oct 01 13:54:17 2013 -0700
@@ -44,24 +44,33 @@
     @Override
     protected TextRun addTextRun(PrismTextLayout layout, char[] chars, int start,
                                  int length, PGFont font, TextSpan span, byte level) {
-        TextRun textRun = null;
+
+        IDWriteFactory factory = DWFactory.getDWriteFactory();
+        IDWriteTextAnalyzer analyzer = factory.CreateTextAnalyzer();
+        if (analyzer == null) {
+            return new TextRun(start, length, level, false, 0, span, 0, false);
+        }
+
         int dir = (level & 1) != 0 ? OS.DWRITE_READING_DIRECTION_RIGHT_TO_LEFT :
                                      OS.DWRITE_READING_DIRECTION_LEFT_TO_RIGHT;
         JFXTextAnalysisSink sink = OS.NewJFXTextAnalysisSink(chars, start, length, LOCALE, dir);
+        if (sink == null) {
+            return new TextRun(start, length, level, false, 0, span, 0, false);
+        }
         sink.AddRef();
 
-        IDWriteFactory factory = DWFactory.getDWriteFactory();
-        IDWriteTextAnalyzer analyzer = factory.CreateTextAnalyzer();
-        analyzer.AnalyzeScript(sink, 0, length, sink);
-
-        while (sink.Next()) {
-            int runStart = sink.GetStart();
-            int runLength = sink.GetLength();
-            DWRITE_SCRIPT_ANALYSIS analysis = sink.GetAnalysis();
-            textRun = new TextRun(start + runStart, runLength, level, true,
-                                  analysis.script, span,
-                                  analysis.shapes, false);
-            layout.addTextRun(textRun) ;
+        TextRun textRun = null;
+        int hr = analyzer.AnalyzeScript(sink, 0, length, sink);
+        if (hr == OS.S_OK) {
+            while (sink.Next()) {
+                int runStart = sink.GetStart();
+                int runLength = sink.GetLength();
+                DWRITE_SCRIPT_ANALYSIS analysis = sink.GetAnalysis();
+                textRun = new TextRun(start + runStart, runLength, level, true,
+                                      analysis.script, span,
+                                      analysis.shapes, false);
+                layout.addTextRun(textRun);
+            }
         }
 
         analyzer.Release();
@@ -70,6 +79,19 @@
     }
 
     public void layout(TextRun run, PGFont font, FontStrike strike, char[] text) {
+
+        FontResource fr = font.getFontResource();
+        boolean composite = fr instanceof CompositeFontResource;
+        if (composite) {
+            fr = ((CompositeFontResource)fr).getSlotResource(0);
+        }
+        IDWriteFontFace face = ((DWFontFile)fr).getFontFace();
+        if (face == null) return;
+
+        IDWriteFactory factory = DWFactory.getDWriteFactory();
+        IDWriteTextAnalyzer analyzer = factory.CreateTextAnalyzer();
+        if (analyzer == null) return;
+
         /* ignore typographic feature for now */
         long[] features = null;
         int[] featuresRangeLengths = null;
@@ -84,14 +106,6 @@
         int[] retGlyphcount = new int[1];
         boolean rtl = !run.isLeftToRight();
 
-        IDWriteFactory factory = DWFactory.getDWriteFactory();
-        IDWriteTextAnalyzer analyzer = factory.CreateTextAnalyzer();
-        FontResource fr = font.getFontResource();
-        boolean composite = fr instanceof CompositeFontResource;
-        if (composite) {
-            fr = ((CompositeFontResource)fr).getSlotResource(0);
-        }
-        IDWriteFontFace face = ((DWFontFile)fr).getFontFace();
         DWRITE_SCRIPT_ANALYSIS analysis = new DWRITE_SCRIPT_ANALYSIS();
         analysis.script = (short)run.getScript();
         analysis.shapes = run.getSlot();
@@ -145,10 +159,18 @@
                                     glyphProps, glyphCount, face, size, false, rtl,
                                     analysis, null, features, featuresRangeLengths,
                                     featuresCount, advances, offsets);
+        analyzer.Release();
 
-        /* Adjust glyphs positions */
+        float[] pos = getPositions(advances, offsets, glyphCount, rtl);
+        int[] indices = getIndices(clusterMap, glyphCount, rtl);
+        run.shape(glyphCount, iglyphs, pos, indices);
+    }
+
+    private float[] getPositions(float[] advances, float[] offsets, int glyphCount, boolean rtl) {
         float[] pos = new float[glyphCount * 2 + 2];
-        i = 0; j = rtl ? glyphCount - 1 : 0;
+        int i = 0;
+        int j = rtl ? glyphCount - 1 : 0;
+        int step = rtl ? -1 : 1;
         float x = 0;
         while (i < pos.length - 2) {
             int g = j << 1;
@@ -159,10 +181,7 @@
         }
         pos[i++] = x;
         pos[i++] = 0;
-
-        analyzer.Release();
-        int[] indices = getIndices(clusterMap, glyphCount, rtl);
-        run.shape(glyphCount, iglyphs, pos, indices);
+        return pos;
     }
 
     private int[] getIndices(short[] clusterMap, int glyphCount, boolean rtl) {
@@ -233,12 +252,14 @@
 
     private int getFontSlot(IDWriteFontFace face, CompositeFontResource composite,
                             String primaryFont) {
+        if (face == null) return -1;
         IDWriteFontCollection collection = DWFactory.getFontCollection();
         PrismFontFactory prismFactory = PrismFontFactory.getFontFactory();
 
 
         /* Collecting information about the font */
         IDWriteFont font = collection.GetFontFromFontFace(face);
+        if (font == null) return -1;
         IDWriteFontFamily fallbackFamily = font.GetFontFamily();
         String family = getName(fallbackFamily.GetFamilyNames());
         fallbackFamily.Release();
@@ -327,64 +348,59 @@
                                                             stretch,
                                                             fontsize,
                                                             LOCALE);
+        if (format == null) return;
 
         int start = run.getStart();
         int length = run.getLength();
         IDWriteTextLayout layout = factory.CreateTextLayout(text, start, length, format, 100000, 100000);
-        JFXTextRenderer renderer = OS.NewJFXTextRenderer();
-        renderer.AddRef();
-        layout.Draw(0, renderer, 0, 0);
+        if (layout != null) {
+            JFXTextRenderer renderer = OS.NewJFXTextRenderer();
+            if (renderer != null) {
+                renderer.AddRef();
 
-        int glyphCount = renderer.GetTotalGlyphCount();
-        int[] glyphs = new int[glyphCount];
-        float[] advances = new float[glyphCount];
-        float[] offsets = new float[glyphCount * 2];
-        short[] clusterMap = new short[length];
-        int glyphStart = 0;
-        int textStart = 0;
-        while (renderer.Next()) {
-            IDWriteFontFace fallback = renderer.GetFontFace();
-            int slot = getFontSlot(fallback, composite, fullName);
-            if (slot >= 0) {
-                renderer.GetGlyphIndices(glyphs, glyphStart, slot << 24);
-                renderer.GetGlyphOffsets(offsets, glyphStart * 2);
+                /* Use renderer to produce glyph information */
+                layout.Draw(0, renderer, 0, 0);
+
+                /* Read data from renderer */
+                int glyphCount = renderer.GetTotalGlyphCount();
+                int[] glyphs = new int[glyphCount];
+                float[] advances = new float[glyphCount];
+                float[] offsets = new float[glyphCount * 2];
+                short[] clusterMap = new short[length];
+                int glyphStart = 0;
+                int textStart = 0;
+                while (renderer.Next()) {
+                    IDWriteFontFace fallback = renderer.GetFontFace();
+                    int slot = getFontSlot(fallback, composite, fullName);
+                    if (slot >= 0) {
+                        renderer.GetGlyphIndices(glyphs, glyphStart, slot << 24);
+                        renderer.GetGlyphOffsets(offsets, glyphStart * 2);
+                    }
+                    if (size > 0) {
+                        /* Keep advances to zero if font size is zero */
+                        renderer.GetGlyphAdvances(advances, glyphStart);
+                    }
+                    renderer.GetClusterMap(clusterMap, textStart);
+                    glyphStart += renderer.GetGlyphCount();
+                    textStart += renderer.GetLength();
+                }
+                renderer.Release();
+
+                /* Converting data to be used by the JavaFX run */
+                boolean rtl = !run.isLeftToRight();
+                if (rtl) {
+                    for (int i = 0; i < glyphCount / 2; i++) {
+                        int tmp = glyphs[i];
+                        glyphs[i] = glyphs[glyphCount - i - 1];
+                        glyphs[glyphCount - i - 1] = tmp;
+                    }
+                }
+                float[] pos = getPositions(advances, offsets, glyphCount, rtl);
+                int[] indices = getIndices(clusterMap, glyphCount, rtl);
+                run.shape(glyphCount, glyphs, pos, indices);
             }
-            if (size > 0) {
-                /* Keep advances to zero if font size is zero */
-                renderer.GetGlyphAdvances(advances, glyphStart);
-            }
-            renderer.GetClusterMap(clusterMap, textStart);
-            glyphStart += renderer.GetGlyphCount();
-            textStart += renderer.GetLength();
+            layout.Release();
         }
-        renderer.Release();
-        layout.Release();
         format.Release();
-
-        /* Adjust glyphs positions */
-        float[] pos = new float[glyphCount * 2 + 2];
-        boolean rtl = !run.isLeftToRight();
-        int i = 0, j = rtl ? glyphCount - 1 : 0;
-        int step = rtl ? -1 : 1;
-        float x = 0;
-        while (i < pos.length - 2) {
-            int g = j << 1;
-            pos[i++] = (rtl ? -offsets[g] : offsets[g]) + x;
-            pos[i++] = -offsets[g + 1];
-            x += advances[j];
-            j+=step;
-        }
-        pos[i++] = x;
-        pos[i++] = 0;
-        if (rtl) {
-            /* Adjust glyphs */
-            for (i = 0; i < glyphCount / 2; i++) {
-                int tmp = glyphs[i];
-                glyphs[i] = glyphs[glyphCount - i - 1];
-                glyphs[glyphCount - i - 1] = tmp;
-            }
-        }
-        int[] indices = getIndices(clusterMap, glyphCount, rtl);
-        run.shape(glyphCount, glyphs, pos, indices);
     }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/ID2D1RenderTarget.java	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/ID2D1RenderTarget.java	Tue Oct 01 13:54:17 2013 -0700
@@ -58,8 +58,4 @@
         long result = OS.CreateSolidColorBrush(ptr, color);
         return result != 0 ? new ID2D1Brush(result) : null;
     }
-
-    void DrawLine(D2D1_POINT_2F point0, D2D1_POINT_2F point1, ID2D1Brush brush, float strokeWidth, IUnknown strokeStyle) {
-        OS.DrawLine(ptr, point0, point1, brush.ptr, strokeWidth, strokeStyle != null ? strokeStyle.ptr : 0);
-    }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteFactory.java	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteFactory.java	Tue Oct 01 13:54:17 2013 -0700
@@ -98,12 +98,11 @@
     }
 
     IDWriteFontFace CreateFontFace(int fontFaceType,
-                                   int numberOfFiles,  //native only supports 1
                                    IDWriteFontFile fontFiles,
                                    int faceIndex,
                                    int fontFaceSimulationFlags) {
 
-        long result = OS.CreateFontFace(ptr, fontFaceType, numberOfFiles, fontFiles.ptr, faceIndex, fontFaceSimulationFlags);
+        long result = OS.CreateFontFace(ptr, fontFaceType, fontFiles.ptr, faceIndex, fontFaceSimulationFlags);
         return result != 0 ? new IDWriteFontFace(result) : null;
     }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteFontFace.java	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteFontFace.java	Tue Oct 01 13:54:17 2013 -0700
@@ -32,14 +32,6 @@
         super(ptr);
     }
 
-    int GetType() {
-        return OS.GetType(ptr);
-    }
-
-    short[] GetGlyphIndices(int[] codePoints, int codePointCount) {
-        return OS.GetGlyphIndices(ptr, codePoints, codePointCount);
-    }
-
     /* Based on GetDesignGlyphMetrics but only handles a single codePoint,
      * as opposite of taking in an array and returing an array.
      * - performance and simplicity based on JavaFX needs */
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteLocalizedStrings.java	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/IDWriteLocalizedStrings.java	Tue Oct 01 13:54:17 2013 -0700
@@ -34,15 +34,6 @@
         return OS.FindLocaleName(ptr, (locale+'\0').toCharArray());
     }
 
-    int GetLocaleNameLength(int index) {
-        return OS.GetLocaleNameLength(ptr, index);
-    }
-
-    String GetLocaleName(int index, int size) {
-        char[] buffer = OS.GetLocaleName(ptr, index, size + 1);//length must include space for null-terminator
-        return buffer != null ? new String(buffer, 0, size) : null;
-    }
-
     int GetStringLength(int index) {
         return OS.GetStringLength(ptr, index);
     }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/OS.java	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/OS.java	Tue Oct 01 13:54:17 2013 -0700
@@ -196,13 +196,6 @@
         return ptr != 0 ? new JFXTextAnalysisSink(ptr) : null;
     }
 
-    static final JFXTextAnalysisSink NewJFXTextAnalysisSink(String text,
-                                                            String locale,
-                                                            int direction) {
-        char[] buffer = text.toCharArray();
-        return NewJFXTextAnalysisSink(buffer, 0, buffer.length, locale, direction);
-    }
-
     private static final native long _NewJFXTextRenderer();
     static final JFXTextRenderer NewJFXTextRenderer() {
         long ptr = _NewJFXTextRenderer();
@@ -228,10 +221,8 @@
     static final native int JFXTextRendererGetClusterMap(long ptr, short[] clusterMap, int start);
 
     //IDWriteFontFace
-    static final native int GetType(long ptr);
     static final native DWRITE_GLYPH_METRICS GetDesignGlyphMetrics(long ptr, short glyphIndex, boolean isSideways);
     static final native Path2D GetGlyphRunOutline(long ptr, float emSize, short glyphIndex, boolean isSideways);
-    static final native short[] GetGlyphIndices(long ptr, int[] codePoints, int codePointCount);
 
     //IDWriteFont
     static final native long CreateFontFace(long ptr);
@@ -251,8 +242,6 @@
     static final native int Analyze(long ptr, boolean[] isSupportedFontType, int[] fontFileType, int[] fontFaceType, int[] numberOfFaces);
 
     //IDWriteLocalizedStrings
-    static final native char[] GetLocaleName(long ptr, int index, int size);
-    static final native int GetLocaleNameLength(long ptr, int index);
     static final native char[] GetString(long ptr, int index, int size);
     static final native int GetStringLength(long ptr, int index);
     static final native int FindLocaleName(long ptr, char[] locale);
@@ -300,7 +289,6 @@
     static final native long CreateFontFileReference(long ptr, char[] filePath);
     static final native long CreateFontFace(long ptr,
                                             int fontFaceType,
-                                            int numberOfFiles,  //native only supports 1
                                             long fontFiles,
                                             int faceIndex,
                                             int fontFaceSimulationFlags);
@@ -375,5 +363,4 @@
     static final native void SetTransform(long ptr, D2D1_MATRIX_3X2_F transform);
     static final native void DrawGlyphRun(long ptr, D2D1_POINT_2F baselineOrigin, DWRITE_GLYPH_RUN glyphRun, long foregroundBrush, int measuringMode);
     static final native long CreateSolidColorBrush(long ptr, D2D1_COLOR_F color);
-    static final native void DrawLine(long ptr, D2D1_POINT_2F point0,  D2D1_POINT_2F point1, long brush, float strokeWidth, long strokeStyle);
 }
--- a/modules/graphics/src/main/native-font/directwrite.cpp	Tue Oct 01 14:10:58 2013 -0700
+++ b/modules/graphics/src/main/native-font/directwrite.cpp	Tue Oct 01 13:54:17 2013 -0700
@@ -570,8 +570,17 @@
 JNIEXPORT jlong JNICALL OS_NATIVE(_1WICCreateImagingFactory)
     (JNIEnv *env, jclass that)
 {
-    HRESULT hr = E_FAIL;
-    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+    /* This routine initialize COM in order to create an WICImagingFactory.
+     * It runs on the prism thread and expects no other codes in this thread
+     * to interface with COM.
+     * Note: This method is called by DWFactory a single time.
+     */
+    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+
+    /* This means COM has been initialize with a different concurrency model.
+     * This should never happen. */
+    if (hr == RPC_E_CHANGED_MODE) return NULL;
+
     IWICImagingFactory* result = NULL;
     hr = CoCreateInstance(
             CLSID_WICImagingFactory,
@@ -579,7 +588,9 @@
             CLSCTX_INPROC_SERVER,
             IID_PPV_ARGS(&result)
             );
-    CoUninitialize();   /* NOT COOL BUT SEEMS TO WORK */
+
+    /* Unload COM as no other COM objects will be create directly */
+    CoUninitialize();
     return SUCCEEDED(hr) ? (jlong)result : NULL;
 }
 
@@ -860,14 +871,17 @@
 }
 
 UINT32 JFXTextAnalysisSink::GetStart() {
+    if (((UINT32)position_) >= runs_.size()) return 0;
     return runs_[position_].start;
 }
 
 UINT32 JFXTextAnalysisSink::GetLength() {
+    if (((UINT32)position_) >= runs_.size()) return 0;
     return runs_[position_].length;
 }
 
 DWRITE_SCRIPT_ANALYSIS* JFXTextAnalysisSink::GetAnalysis() {
+    if (((UINT32)position_) >= runs_.size()) return NULL;
     return &runs_[position_].analysis;
 }
 
@@ -1136,14 +1150,17 @@
 }
 
 UINT32 JFXTextRenderer::GetStart() {
+    if (((UINT32)position_) >= runs_.size()) return 0;
     return runs_[position_].glyphRunDescription.textPosition;
 }
 
 UINT32 JFXTextRenderer::GetLength() {
+    if (((UINT32)position_) >= runs_.size()) return 0;
     return runs_[position_].glyphRunDescription.stringLength;
 }
 
 UINT32 JFXTextRenderer::GetGlyphCount() {
+    if (((UINT32)position_) >= runs_.size()) return 0;
     return runs_[position_].glyphRun.glyphCount;
 }
 
@@ -1152,22 +1169,27 @@
 }
 
 IDWriteFontFace* JFXTextRenderer::GetFontFace() {
+    if (((UINT32)position_) >= runs_.size()) return NULL;
     return runs_[position_].glyphRun.fontFace;
 }
 
 const FLOAT* JFXTextRenderer::GetGlyphAdvances() {
+    if (((UINT32)position_) >= runs_.size()) return NULL;
     return runs_[position_].glyphRun.glyphAdvances;
 }
 
 const DWRITE_GLYPH_OFFSET* JFXTextRenderer::GetGlyphOffsets() {
+    if (((UINT32)position_) >= runs_.size()) return NULL;
     return runs_[position_].glyphRun.glyphOffsets;
 }
 
 const UINT16* JFXTextRenderer::GetGlyphIndices() {
+    if (((UINT32)position_) >= runs_.size()) return NULL;
     return runs_[position_].glyphRun.glyphIndices;
 }
 
 const UINT16* JFXTextRenderer::GetClusterMap() {
+    if (((UINT32)position_) >= runs_.size()) return NULL;
     return runs_[position_].glyphRunDescription.clusterMap;
 }
 
@@ -1417,7 +1439,6 @@
 }
 
 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;
 }
 
@@ -1451,8 +1472,6 @@
 }
 
 /* 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)
 {
@@ -1461,16 +1480,19 @@
     const UINT32  glyphCount = 1;
     const UINT16 glyphIndices[glyphCount] = {arg2};
     JFXGeometrySink* sink = new (std::nothrow) JFXGeometrySink();
+    if (sink == NULL) return NULL;
 
     hr = ((IDWriteFontFace *)arg0)->GetGlyphRunOutline(arg1, glyphIndices, NULL, NULL, glyphCount, arg3, FALSE, sink);
 
+    static jclass path2DClass = NULL;
+    static jmethodID path2DCtr = NULL;
+    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");
+    }
+
     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) {
@@ -1486,12 +1508,6 @@
     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)
 {
@@ -1508,27 +1524,6 @@
     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)
@@ -1575,14 +1570,14 @@
     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)
+JNIEXPORT jlong JNICALL OS_NATIVE(CreateFontFace__JIJII)
+    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jlong arg3, jint arg4, jint arg5)
 {
     IDWriteFontFace* result = NULL;
-    if (arg2 != 1) return NULL;
-    IDWriteFontFile* fontFileArray[] = {(IDWriteFontFile*)arg3};
+    const UINT32  numberOfFiles = 1;
+    IDWriteFontFile* fontFileArray[numberOfFiles] = {(IDWriteFontFile*)arg3};
     HRESULT hr = ((IDWriteFactory *)arg0)->CreateFontFace((DWRITE_FONT_FACE_TYPE)arg1,
-                                                          (UINT32)arg2,
+                                                          numberOfFiles,
                                                           fontFileArray,
                                                           (UINT32)arg4,
                                                           (DWRITE_FONT_SIMULATIONS)arg5,
@@ -1592,17 +1587,19 @@
 }
 
 JNIEXPORT jlong JNICALL OS_NATIVE(CreateTextLayout)
-    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1, jint arg2, jint arg3, jlong arg4,
+    (JNIEnv *env, jclass that, jlong arg0, jcharArray arg1, jint start, jint count, 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);
+    if (start + count > env->GetArrayLength(arg1)) goto fail;
+
+    const WCHAR * text = (const WCHAR *)(lparg1 + start);
 
     hr = ((IDWriteFactory *)arg0)->CreateTextLayout(text,
-                                                    (UINT32)arg3,
+                                                    (UINT32)count,
                                                     (IDWriteTextFormat *)arg4,
                                                     (FLOAT)arg5,
                                                     (FLOAT)arg6,
@@ -1773,30 +1770,6 @@
 }
 
 /* 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)
 {
@@ -1829,7 +1802,7 @@
     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);
+    hr = ((IDWriteLocalizedStrings *)arg0)->FindLocaleName((const WCHAR *) lparg1, &result, &exists);
 fail:
     if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
     return SUCCEEDED(hr) && exists ? result : -1;
@@ -1876,7 +1849,7 @@
     BOOL exists = FALSE;
     if (arg1) if ((lparg1 = env->GetCharArrayElements(arg1, NULL)) == NULL) goto fail;
     hr = ((IDWriteFontCollection *)arg0)->FindFamilyName((const WCHAR *) lparg1, &result, &exists);
-    fail:
+fail:
     if (arg1 && lparg1) env->ReleaseCharArrayElements(arg1, lparg1, 0);
     return SUCCEEDED(hr) && exists ? result : -1;
 }
@@ -1984,7 +1957,7 @@
                                                   (DWRITE_SHAPING_GLYPH_PROPERTIES *)lparg16,
                                                   (UINT32 *)lparg17);
 
-    fail:
+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);
@@ -2126,7 +2099,7 @@
 JNIEXPORT jint JNICALL OS_NATIVE(GetStride)
     (JNIEnv *env, jclass that, jlong arg0)
 {
-    UINT result;
+    UINT result = 0;
     HRESULT hr = ((IWICBitmapLock *)arg0)->GetStride(&result);
     return SUCCEEDED(hr) ? result : NULL;
 }
@@ -2210,14 +2183,4 @@
     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 */