changeset 4205:593512351daa

merge
author Martin Soch <Martin.Soch@oracle.com>
date Tue, 09 Jul 2013 16:04:06 +0200
parents b3e19138d374 1220a4b96aaa
children 56e31708e758
files
diffstat 27 files changed, 760 insertions(+), 790 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/.name	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,1 @@
+3DViewer
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/compiler.xml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/copyright/profiles_settings.xml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,5 @@
+<component name="CopyrightManager">
+  <settings default="">
+    <module2copyright />
+  </settings>
+</component>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/encodings.xml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/misc.xml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/modules.xml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/3DViewer.iml" filepath="$PROJECT_DIR$/3DViewer.iml" />
+    </modules>
+  </component>
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/runConfigurations/3DViewer.xml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,18 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="3DViewer" type="Application" factoryName="Application">
+    <option name="MAIN_CLASS_NAME" value="com.javafx.experiments.jfx3dviewer.Jfx3dViewerApp" />
+    <option name="VM_PARAMETERS" value="-Dprism.verbose=true" />
+    <option name="PROGRAM_PARAMETERS" value="" />
+    <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
+    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+    <option name="ALTERNATIVE_JRE_PATH" value="" />
+    <option name="ENABLE_SWING_INSPECTOR" value="false" />
+    <option name="ENV_VARIABLES" />
+    <option name="PASS_PARENT_ENVS" value="true" />
+    <module name="3DViewer" />
+    <envs />
+    <RunnerSettings RunnerId="Run" />
+    <ConfigurationWrapper RunnerId="Run" />
+    <method />
+  </configuration>
+</component>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/scopes/scope_settings.xml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+  <state>
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </state>
+</component>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/.idea/vcs.xml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="hg4idea" />
+  </component>
+</project>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/experiments/3DViewer/3DViewer.iml	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,19 @@
+<?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/classes" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/.idea" />
+      <excludeFolder url="file://$MODULE_DIR$/nbproject" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
--- a/build.gradle	Tue Jul 09 16:00:44 2013 +0200
+++ b/build.gradle	Tue Jul 09 16:04:06 2013 +0200
@@ -688,6 +688,16 @@
                 linkTask.dependsOn rcTask;
             }
         }
+
+        def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
+        if (useLipo) {
+            def lipoTask = project.task("lipo${t.capital}$capitalName", type: LipoTask, dependsOn: javahTask, group: "Build") {
+                description = "Creates native fat library for $name for ${t.name}"
+                libDir = file("$libRootDir/${t.name}")
+                lib = file("$libRootDir/${t.name}/${library(properties.lib)}")
+            }
+            nativeTask.dependsOn(lipoTask)
+        }
     }
 }
 
@@ -1665,10 +1675,12 @@
              "modules/graphics/build/resources/jsl-prism");
         if (COMPILE_SWING) from ("modules/swing/build/classes/main", "modules/swing/build/resources/main")
         if (COMPILE_SWT) from ("modules/swt/build/classes/main", "modules/swt/build/resources/main")
-        if (t.name != 'android') {
+        if (t.name == 'android') {
+            from ("modules/web/build/classes/android", "modules/web/build/resources/android")
+        } else if (t.name == 'ios') {
+            from ("modules/web/build/classes/ios", "modules/web/build/resources/ios")
+        } else {
             from ("modules/web/build/classes/main", "modules/web/build/resources/main")
-        } else {
-            from ("modules/web/build/classes/android", "modules/web/build/resources/android")
         }
         exclude("js/**/*", // er...
                 "PrismLoaderBackend*", // More decora stuff
@@ -1691,9 +1703,10 @@
             // TODO instead of using copy everywhere, I probably want to use "sync" instead?
             // Copy all of the .dll / .so / .dylib native libraries into build/sdk/rt/lib/
             copy {
+                def useLipo = targetProperties.containsKey('useLipo') ? targetProperties.useLipo : false
                 from("modules/graphics/build/libs/jsl-decora/${t.name}/${library(targetProperties.decora.lib)}")
                 ['font', 'prism', 'prismSW', 'prismES2', 'glass', 'iio'].each { lib ->
-                    def variants = targetProperties[lib].containsKey('variants') ? targetProperties[lib].variants : [null]
+                    def variants = targetProperties[lib].containsKey('variants') && !useLipo ? targetProperties[lib].variants : [null]
                     variants.each { variant ->
                         def variantProperties = variant ? targetProperties[lib][variant] : targetProperties[lib]
                         println "modules/graphics/build/libs/$lib/$t.name/${library(variantProperties.lib)}"
@@ -1709,7 +1722,7 @@
                         from ("modules/web/src/main/native/WebKitLibraries/import/runtime")
                     }
                 } else {
-                    if (IS_MAC) from ("$LIBRARY_STUB/libjfxwebkit.dylib")
+                    if (IS_MAC && COMPILE_TARGETS != "ios") from ("$LIBRARY_STUB/libjfxwebkit.dylib")
                     else if (IS_WINDOWS) {
                         from ("$LIBRARY_STUB/jfxwebkit.dll")
                         from ("$LIBRARY_STUB/libxml2.dll")
@@ -1772,6 +1785,18 @@
         dependsOn(jfxrtTask)
         dependsOn(javadoc)
     }
+
+    def generateSymbols = targetProperties.containsKey('generateSymbols') ? targetProperties.generateSymbols : false
+    if (generateSymbols) {
+        def exportedSymbolsTask = project.task("exportedSymbols${t.capital}", type: ExportedSymbolsTask, dependsOn: sdkTask, group: "Build") {
+            description = "Generates exported symbols file for iOS build (from .a libraries)"
+            def libDirName = "build/${t.name}-sdk/rt/$targetProperties.libDest"
+            libDir = file("$libDirName")
+            outputFile = file("$libDirName/exported.symbols")
+        }
+        sdk.dependsOn(exportedSymbolsTask)
+    }
+
     sdk.dependsOn(sdkTask)
 }
 
--- a/buildSrc/android.gradle	Tue Jul 09 16:00:44 2013 +0200
+++ b/buildSrc/android.gradle	Tue Jul 09 16:04:06 2013 +0200
@@ -145,6 +145,10 @@
     }
 
     afterEvaluate {
+        if (!BUILD_CLOSED) {
+            logger.warn("OpenJFX build. Skipping webkit build on Android.")
+            return
+        }
         def compileWebJavaAndroid = task("compileWebJavaAndroid",
             type: JavaCompile, group: "Build") {
             
--- a/buildSrc/ios.gradle	Tue Jul 09 16:00:44 2013 +0200
+++ b/buildSrc/ios.gradle	Tue Jul 09 16:04:06 2013 +0200
@@ -29,11 +29,20 @@
 IOS.canBuild = IS_MAC
 if (!IOS.canBuild) return;
 
+IOS.artifactsName = "ios"
+
 IOS.compileSwing = false;
 IOS.compileSWT = false;
 IOS.compileFXPackager = false;
 IOS.compileDesignTime = false;
 
+defineProperty("USE_LIPO", "false")
+defineProperty("GENERATE_SYMBOLS", "false")
+if (USE_LIPO instanceof String) IOS.useLipo = Boolean.parseBoolean(USE_LIPO)
+if (GENERATE_SYMBOLS instanceof String) IOS.generateSymbols = Boolean.parseBoolean(GENERATE_SYMBOLS)
+
+defineProperty("IOS_VERSION", "6.1")
+
 // Lambda for naming the generated libs
 IOS.library = { name -> return "lib${name}.a" as String }
 
@@ -73,7 +82,7 @@
 def iPhoneSim = "iPhoneSimulator"
 
 String sdkPath(String platform) {
-    return "/Applications/Xcode.app/Contents/Developer/Platforms/${platform}.platform/Developer/SDKs/${platform}6.1.sdk";
+    return "/Applications/Xcode.app/Contents/Developer/Platforms/${platform}.platform/Developer/SDKs/${platform}${IOS_VERSION}.sdk";
 }
 
 def linkFlags = [
@@ -86,7 +95,7 @@
     "-framework", "OpenGLES"].flatten()
 
 def ccFlags = [
-    "-miphoneos-version-min=6.1", "-fmessage-length=0", "-std=c99", "-fno-common",
+    "-miphoneos-version-min=6.0", "-fmessage-length=0", "-std=c99", "-fno-common",
     "-Wall", "-fno-strict-aliasing", "-fwrapv", "-fpascal-strings", "-fobjc-abi-version=2", "-fobjc-legacy-dispatch",
     "-I$JDK_HOME/include", "-I$JDK_HOME/include/darwin", "-c",
     IS_DEBUG ? "-DDEBUG" : ["-O3", "-DNDEBUG"]].flatten()
@@ -126,6 +135,7 @@
 IOS.decora.lib = "decora-sse-${archArm}"
 
 IOS.prism = [:]
+IOS.prism.lib = "prism-common"
 IOS.prism.javahInclude = ["com/sun/prism/impl/**/*", "com/sun/prism/PresentableState*"]
 IOS.prism.variants = ["arm", "x86"];
 
@@ -146,6 +156,7 @@
 IOS.prism.x86.lib = "prism-common-${archX86}"
 
 IOS.prismSW = [:]
+IOS.prismSW.lib = "prism-sw"
 IOS.prismSW.javahInclude = ["com/sun/pisces/**/*"]
 IOS.prismSW.variants = ["arm", "x86"];
 
@@ -166,6 +177,7 @@
 IOS.prismSW.x86.lib = "prism-sw-${archX86}"
 
 IOS.iio = [:]
+IOS.iio.lib = "javafx-iio"
 IOS.iio.javahInclude = ["com/sun/javafx/iio/**/*"]
 IOS.iio.variants = ["arm", "x86"];
 
@@ -189,6 +201,7 @@
 IOS.iio.x86.lib = "javafx-iio-${archX86}"
 
 IOS.prismES2 = [:]
+IOS.prismES2.lib = "prism-es2"
 IOS.prismES2.javahInclude = ["com/sun/prism/es2/**/*"]
 IOS.prismES2.variants = ["arm", "x86"];
 
@@ -214,6 +227,7 @@
 
 def closedDir = file("$projectDir/../rt-closed")
 IOS.font = [:]
+IOS.font.lib = "javafx-font"
 IOS.font.javahInclude = [
         "com/sun/javafx/font/**/*",
         "com/sun/javafx/text/**/*"]
@@ -236,6 +250,7 @@
 IOS.font.x86.lib = "javafx-font-${archX86}"
 
 IOS.fontT2K = [:]
+IOS.fontT2K.lib = "javafx-font-t2k"
 IOS.fontT2K.javahInclude = ["com/sun/javafx/font/t2k/**/*"]
 IOS.fontT2K.variants = ["arm", "x86"];
 
@@ -257,3 +272,79 @@
 IOS.fontT2K.x86.linker = linker
 IOS.fontT2K.x86.linkFlags = ["-arch_only", archX86, "-syslibroot", sdkPath(iPhoneSim), linkFlags].flatten()
 IOS.fontT2K.x86.lib = "javafx-font-t2k-${archX86}"
+
+IOS.webview = [:]
+IOS.webview.lib = "javafx-ios-webnode"
+IOS.webview.javahInclude = ["javafx/scene/web/*"]
+IOS.webview.variants = ["arm", "x86"];
+
+IOS.webview.arm = [:]
+IOS.webview.arm.nativeSource = file("$closedDir/javafx-ios-webnode/native")
+IOS.webview.arm.compiler = compiler
+IOS.webview.arm.ccFlags = [ccFlags, "-arch", archArm, "-isysroot", sdkPath(iPhoneOS)].flatten()
+IOS.webview.arm.linker = linker
+IOS.webview.arm.linkFlags = ["-arch_only", archArm, "-syslibroot", sdkPath(iPhoneOS), linkFlags].flatten()
+IOS.webview.arm.lib = "javafx-ios-webnode-${archArm}"
+
+IOS.webview.x86 = [:]
+IOS.webview.x86.nativeSource = [IOS.webview.arm.nativeSource].flatten()
+IOS.webview.x86.compiler = compiler
+IOS.webview.x86.ccFlags = [ccFlags, "-arch", archX86, "-isysroot", sdkPath(iPhoneSim)].flatten()
+IOS.webview.x86.linker = linker
+IOS.webview.x86.linkFlags = ["-arch_only", archX86, "-syslibroot", sdkPath(iPhoneSim), linkFlags].flatten()
+IOS.webview.x86.lib = "javafx-ios-webnode-${archX86}"
+
+project(":web") {
+    if (BUILD_CLOSED) {
+        apply plugin: 'java'
+
+        compileJava {
+            enabled = false
+        }
+
+        afterEvaluate {
+            def compileWebJavaIos = task("compileWebJavaIos",
+                type: JavaCompile, group: "Build") {
+
+                dependsOn(project(":graphics").classes, project(":base").classes)
+                description = "Task compiles web component for iOS."
+                classpath = files(
+                    project(":controls").sourceSets.main.output.classesDir,
+                    project(":graphics").sourceSets.main.output.classesDir,
+                    project(":base").sourceSets.main.output.classesDir
+                )
+                destinationDir = file("modules/web/build/classes/ios")
+                dependencyCacheDir = file("modules/web/build/dependency-cache")
+                source file("$closedDir/javafx-ios-webnode/src")
+            }
+
+            def jarWebJavaIos = task("jarWebJavaIos",
+                type: Jar, group: "Build") {
+                description = "Creates web.jar for iOS."
+                dependsOn(compileWebJavaIos)
+                archiveName = "web.jar"
+                includeEmptyDirs = false
+                destinationDir = project.file("build/libs/ios")
+                from("build/classes/ios")
+            }
+
+            addNative(project, "webview")
+            javahIosWebview.dependsOn(compileWebJavaIos)
+
+            jfxrtIos {
+                from "modules/web/build/classes/ios"
+            }
+
+            sdkIos  {
+                dependsOn(jarWebJavaIos)
+                doLast {
+                    def props = project.ext["IOS"]
+                    copy {
+                        from ("modules/web/build/libs/webview/ios/${props.library(props.webview.lib)}")
+                        into ("build/ios-sdk/rt/${props.libDest}")
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildSrc/src/main/groovy/com/sun/javafx/gradle/ExportedSymbolsTask.groovy	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+
+class ExportedSymbolsTask extends DefaultTask {
+    @OutputFile File outputFile;
+    @InputDirectory File libDir;
+
+
+    @TaskAction void generateExportedSymbols() {
+        // Get symbols only from .a libraries
+        List<String> libNames = [];
+        List<File> files = libDir.listFiles();
+        files.each { file ->
+            if (!file.isDirectory() && file.getName().endsWith(".a")) {
+                libNames.add(file.getAbsolutePath())
+            }
+        }
+
+        def baos = new ByteArrayOutputStream();
+
+        // Execute nm on .a libraries
+        project.exec({
+            commandLine("nm", "-jg");
+            args(libNames);
+            setStandardOutput(baos);
+        });
+
+        def bais = new ByteArrayInputStream(baos.toByteArray());
+
+        outputFile.withWriter { out ->
+            bais.eachLine { line ->
+                // Remove unnecessary lines
+                line = (line =~ /^(?!(_Java|_JNI_)).*$/).replaceFirst("");
+                line = (line =~ /^(_Java|_JNI_).*(.eh)$/).replaceFirst("");
+
+                if (!line.isEmpty()) {
+                    out.writeLine(line);
+                }
+            }
+        }
+
+        baos.close();
+        bais.close();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildSrc/src/main/groovy/com/sun/javafx/gradle/LipoTask.groovy	Tue Jul 09 16:04:06 2013 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+
+
+class LipoTask extends DefaultTask {
+    @InputDirectory File libDir;
+    @OutputFile File lib;
+    @TaskAction void compile() {
+        List<String> libNames = [];
+        List<File> files = libDir.listFiles();
+        files.each { file ->
+            String fileName = file.getName();
+            // process only thin libraries
+            if (!file.isDirectory() && (fileName.indexOf("armv7") != -1 || fileName.indexOf("i386") != -1)) {
+                libNames.add(file.getAbsolutePath())
+            }
+        }
+        // Create a fat library (.a)
+        project.exec({
+            commandLine("lipo", "-create", "-output", "$lib");
+            args(libNames);
+        });
+    }
+}
+
--- a/buildSrc/win.gradle	Tue Jul 09 16:00:44 2013 +0200
+++ b/buildSrc/win.gradle	Tue Jul 09 16:04:06 2013 +0200
@@ -59,7 +59,7 @@
 ]
 
 def ccFlags = ["/nologo", "/W3", "/EHsc", "/c",
-        "/D_STATIC_CPP_LIB", "/D_DISABLE_DEPRECATE_STATIC_CPPLIB", "/DINLINE=__inline",
+        "/D_STATIC_CPPLIB", "/D_DISABLE_DEPRECATE_STATIC_CPPLIB", "/DINLINE=__inline",
         "/DUNICODE", "/D_UNICODE", "/DWIN32", "/DIAL", "/D_LITTLE_ENDIAN", "/DWIN32_LEAN_AND_MEAN",
         "/I$JDK_HOME/include", "/I$JDK_HOME/include/win32", "/arch:SSE", "/fp:fast",
         IS_DEBUG ? ["/MDd", "/Od", "/Zi", "/DDEBUG"] : ["/O2", "/MD"]].flatten();
--- a/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java	Tue Jul 09 16:04:06 2013 +0200
@@ -203,10 +203,10 @@
     }
 
     PrismFontFile createFontResource(String name, String filename,
-                                          boolean register,
-                                          boolean embedded,
-                                          boolean copy,
-                                          boolean tracked) {
+                                     boolean register,
+                                     boolean embedded,
+                                     boolean copy,
+                                     boolean tracked) {
         if (filename == null) {
             return null;
         } else {
@@ -228,8 +228,8 @@
                             }
                         } else {
                             fr = createFontFile(name, filename, index,
-                                                embedded,
-                                                register, copy, tracked);
+                                                register, embedded,
+                                                copy, tracked);
                         }
                     } catch (Exception e) {
                         if (PrismFontFactory.debugFonts) {
@@ -1467,7 +1467,7 @@
          * know to reference the file directly.
          */
         PrismFontFile fr = createFontResource(name, path, register,
-                                            true, copy, tracked);
+                                              true, copy, tracked);
         if (fr == null) {
             return null; // yes, this means the caller needs to handle null.
         }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyph.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyph.java	Tue Jul 09 16:04:06 2013 +0200
@@ -143,7 +143,7 @@
     private synchronized byte[] getImage(double x, double y, int w, int h,
                                          double subPixelX, double subPixelY) {
 
-        if (w == 0 || h == 0) return null;
+        if (w == 0 || h == 0) return new byte[0];
 
         long fontRef = strike.getFontRef();
         boolean lcd = isLCDGlyph();
--- a/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyphLayout.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyphLayout.java	Tue Jul 09 16:04:06 2013 +0200
@@ -27,308 +27,108 @@
 
 import com.sun.javafx.font.CompositeFontResource;
 import com.sun.javafx.font.CompositeStrike;
-import com.sun.javafx.font.FontResource;
 import com.sun.javafx.font.FontStrike;
 import com.sun.javafx.font.PGFont;
 import com.sun.javafx.font.PrismFontFactory;
 import com.sun.javafx.geom.transform.BaseTransform;
 import com.sun.javafx.scene.text.TextSpan;
 import com.sun.javafx.text.GlyphLayout;
-import com.sun.javafx.text.ScriptMapper;
 import com.sun.javafx.text.PrismTextLayout;
 import com.sun.javafx.text.TextRun;
 
-import java.text.Bidi;
 import java.util.Arrays;
 
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_ANALYSIS_VALID;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_COMPLEX;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_BIDI;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_TABS;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_EMBEDDED;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_RTL_BASE;
-
 class CTGlyphLayout extends GlyphLayout {
 
-    private TextRun addTextRun(PrismTextLayout layout, char[] chars, int start, int length,
-                               PGFont font, TextSpan span, byte level, boolean complex) {
+    protected TextRun addTextRun(PrismTextLayout layout, char[] chars, int start,
+                                 int length, PGFont font, TextSpan span, byte level) {
 
         TextRun textRun = null;
-        if (complex) {
-            /* Use CoreText to analize the run */
-            long alloc = OS.kCFAllocatorDefault();
-            long textRef = OS.CFStringCreateWithCharacters(alloc, chars, start, length);
 
-            FontStrike fontStrike = font.getStrike(BaseTransform.IDENTITY_TRANSFORM);
-            boolean composite = fontStrike instanceof CompositeStrike;
-            if (composite) {
-                fontStrike = ((CompositeStrike)fontStrike).getStrikeSlot(0);
+        /* Use CoreText to analize the run */
+        long alloc = OS.kCFAllocatorDefault();
+        long textRef = OS.CFStringCreateWithCharacters(alloc, chars, start, length);
+
+        FontStrike fontStrike = font.getStrike(BaseTransform.IDENTITY_TRANSFORM);
+        boolean composite = fontStrike instanceof CompositeStrike;
+        if (composite) {
+            fontStrike = ((CompositeStrike)fontStrike).getStrikeSlot(0);
+        }
+        CTFontStrike strike = (CTFontStrike)fontStrike;
+        long fontRef = strike.getFontRef();
+
+        long attributes = OS.CFDictionaryCreateMutable(alloc, 4, OS.kCFTypeDictionaryKeyCallBacks(), OS.kCFTypeDictionaryValueCallBacks());
+        OS.CFDictionaryAddValue(attributes, OS.kCTFontAttributeName(), fontRef);
+        /* Note that by default CoreText will apply kerning depending on the font*/
+        long attString = OS.CFAttributedStringCreate(alloc, textRef, attributes);
+        long lineRef = OS.CTLineCreateWithAttributedString(attString);
+        OS.CFRelease(attributes);
+        OS.CFRelease(attString);
+        OS.CFRelease(textRef);
+
+        long runs = OS.CTLineGetGlyphRuns(lineRef);
+        long runCount = OS.CFArrayGetCount(runs);
+
+        /*
+         * Need to undo the bidi reordering done by CoreText as it will be
+         * done again in text layout after wrapping.
+         */
+        boolean bidi = (level & 1) != 0;
+        int i = bidi ? (int)runCount - 1 : 0;
+        int step = bidi ? -1 : 1;
+        for (; 0 <= i && i < runCount; i += step) {
+            long run = OS.CFArrayGetValueAtIndex(runs, i);
+            int status = OS.CTRunGetStatus(run);
+            boolean runBidi = (status & OS.kCTRunStatusRightToLeft) != 0;
+            if (bidi != runBidi) {
+                if (PrismFontFactory.debugFonts) {
+                    System.err.println("[CoreText] not expecing bidi level to differ.");
+                }
             }
-            CTFontStrike strike = (CTFontStrike)fontStrike;
-            long fontRef = strike.getFontRef();
-
-            long attributes = OS.CFDictionaryCreateMutable(alloc, 4, OS.kCFTypeDictionaryKeyCallBacks(), OS.kCFTypeDictionaryValueCallBacks());
-            OS.CFDictionaryAddValue(attributes, OS.kCTFontAttributeName(), fontRef);
-            /* Note that by default CoreText will apply kerning depending on the font*/
-            long attString = OS.CFAttributedStringCreate(alloc, textRef, attributes);
-            long lineRef = OS.CTLineCreateWithAttributedString(attString);
-            OS.CFRelease(attributes);
-            OS.CFRelease(attString);
-            OS.CFRelease(textRef);
-
-            long runs = OS.CTLineGetGlyphRuns(lineRef);
-            long runCount = OS.CFArrayGetCount(runs);
+            CFRange range = OS.CTRunGetStringRange(run);
+            int glyphCount = (int)OS.CTRunGetGlyphCount(run);
+            int[] glyphs = OS.CTRunGetGlyphsPtr(run);
 
             /*
-             * Need to undo the bidi reordering done by CoreText as it will be
-             * done again in text layout after wrapping.
+             * The positions and indices returned by core text are
+             * relative to the line, the following native methods
+             * are custom to return values relative to the run.
              */
-            boolean bidi = (level & 1) != 0;
-            int i = bidi ? (int)runCount - 1 : 0;
-            int step = bidi ? -1 : 1;
-            for (; 0 <= i && i < runCount; i += step) {
-                long run = OS.CFArrayGetValueAtIndex(runs, i);
-                int status = OS.CTRunGetStatus(run);
-                boolean runBidi = (status & OS.kCTRunStatusRightToLeft) != 0;
-                if (bidi != runBidi) {
+            float[] positions = OS.CTRunGetPositionsPtr(run);
+            int[] indices = OS.CTRunGetStringIndicesPtr(run);
+
+            if (PrismFontFactory.debugFonts) {
+                System.err.println("Run " + i + " range " + (start+range.location) + ", " + range.length);
+                System.err.println("\tText=[" + new String(chars, start + (int)range.location, (int)range.length) + "]");
+                System.err.println("\tFont=" +strike.getFontResource());
+                System.err.println("\tStatus="+status);
+                System.err.println("\tGlyphs="+Arrays.toString(glyphs));
+                System.err.println("\tPositions="+Arrays.toString(positions));
+                System.err.println("\tIndices="+Arrays.toString(indices));
+            }
+            if (composite) {
+                long runAttrs = OS.CTRunGetAttributes(run);
+                long actualFont = OS.CFDictionaryGetValue(runAttrs, OS.kCTFontAttributeName());
+                String fontName = OS.CTFontCopyDisplayName(actualFont);
+                if (!fontName.equalsIgnoreCase(strike.getFontResource().getFullName())) {
+                    CompositeFontResource fr = (CompositeFontResource)font.getFontResource();
+                    int slot = fr.getSlotForFont(fontName) << 24;
                     if (PrismFontFactory.debugFonts) {
-                        System.err.println("[CoreText] not expecing bidi level to differ.");
+                        System.err.println("\tFallback front= "+ fontName + " slot=" + (slot>>24));
+                    }
+                    for (int j = 0; j < glyphs.length; j++) {
+                        glyphs[j] |= slot;
                     }
                 }
-                CFRange range = OS.CTRunGetStringRange(run);
-                int glyphCount = (int)OS.CTRunGetGlyphCount(run);
-                int[] glyphs = OS.CTRunGetGlyphsPtr(run);
-
-                /*
-                 * The positions and indices returned by core text are
-                 * relative to the line, the following native methods
-                 * are custom to return values relative to the run.
-                 */
-                float[] positions = OS.CTRunGetPositionsPtr(run);
-                int[] indices = OS.CTRunGetStringIndicesPtr(run);
-
-                if (PrismFontFactory.debugFonts) {
-                    System.err.println("Run " + i + " range " + (start+range.location) + ", " + range.length);
-                    System.err.println("\tText=[" + new String(chars, start + (int)range.location, (int)range.length) + "]");
-                    System.err.println("\tFont=" +strike.getFontResource());
-                    System.err.println("\tStatus="+status);
-                    System.err.println("\tGlyphs="+Arrays.toString(glyphs));
-                    System.err.println("\tPositions="+Arrays.toString(positions));
-                    System.err.println("\tIndices="+Arrays.toString(indices));
-                }
-                if (composite) {
-                    long runAttrs = OS.CTRunGetAttributes(run);
-                    long actualFont = OS.CFDictionaryGetValue(runAttrs, OS.kCTFontAttributeName());
-                    String fontName = OS.CTFontCopyDisplayName(actualFont);
-                    if (!fontName.equalsIgnoreCase(strike.getFontResource().getFullName())) {
-                        CompositeFontResource fr = (CompositeFontResource)font.getFontResource();
-                        int slot = fr.getSlotForFont(fontName) << 24;
-                        if (PrismFontFactory.debugFonts) {
-                            System.err.println("\tFallback front= "+ fontName + " slot=" + (slot>>24));
-                        }
-                        for (int j = 0; j < glyphs.length; j++) {
-                            glyphs[j] |= slot;
-                        }
-                    }
-                }
-                textRun = new TextRun(start + (int)range.location, (int)range.length, level, true, 0, span, 0, false);
-                textRun.shape(glyphCount, glyphs, positions, indices);
-                layout.addTextRun(textRun);
             }
-            OS.CFRelease(lineRef);
-        } else {
-            textRun = new TextRun(start, length, level, false, 0, span, 0, false);
+            textRun = new TextRun(start + (int)range.location, (int)range.length, level, true, 0, span, 0, false);
+            textRun.shape(glyphCount, glyphs, positions, indices);
             layout.addTextRun(textRun);
         }
+        OS.CFRelease(lineRef);
         return textRun;
     }
 
-    public int breakRuns(PrismTextLayout layout, char[] chars, int flags) {
-        int length = chars.length;
-        boolean complexRun = false;
-        boolean complex = false;
-        boolean feature = false;
-
-        boolean checkComplex = true;
-        boolean checkBidi = true;
-        if ((flags & FLAGS_ANALYSIS_VALID) != 0) {
-            /* Avoid work when it is known neither complex
-             * text nor bidi are not present. */
-            checkComplex = (flags & FLAGS_HAS_COMPLEX) != 0;
-            checkBidi = (flags & FLAGS_HAS_BIDI) != 0;
-        }
-
-        TextRun run = null;
-        Bidi bidi = null;
-        byte bidiLevel = 0;
-        int bidiEnd = length;
-        int bidiIndex = 0;
-        int spanIndex = 0;
-        TextSpan span = null;
-        int spanEnd = length;
-        PGFont font = null;
-        TextSpan[] spans = layout.getTextSpans();
-        if (spans != null) {
-            if (spans.length > 0) {
-                span = spans[spanIndex];
-                spanEnd = span.getText().length();
-                font = (PGFont)span.getFont();
-                if (font == null) {
-                    flags |= FLAGS_HAS_EMBEDDED;
-                }
-            }
-        } else {
-            font = layout.getFont();
-        }
-        if (font != null) {
-            FontResource fr = font.getFontResource();
-            int requestedFeatures = font.getFeatures();
-            int supportedFeatures = fr.getFeatures();
-            feature = (requestedFeatures & supportedFeatures) != 0;
-        }
-        if (checkBidi && length > 0) {
-            int direction = layout.getDirection();
-            bidi = new Bidi(chars, 0, null, 0, length, direction);
-            /* Temporary Code: See RT-26997 */
-//            bidiLevel = (byte)bidi.getRunLevel(bidiIndex);
-            bidiLevel = (byte)bidi.getLevelAt(bidi.getRunStart(bidiIndex));
-            bidiEnd = bidi.getRunLimit(bidiIndex);
-            if ((bidiLevel & 1) != 0) {
-                flags |= FLAGS_HAS_BIDI;
-            }
-        }
-
-        int start = 0;
-        int i = 0;
-        while (i < length) {
-            char ch = chars[i];
-            int codePoint = ch;
-
-            boolean delimiterChanged = ch == '\t' || ch == '\n' || ch == '\r';
-            boolean spanChanged = i >= spanEnd;
-            boolean levelChanged = i >= bidiEnd;
-            boolean complexChanged = false;
-
-            if (checkComplex) {
-                if (Character.isHighSurrogate(ch)) {
-                    /* Only merge surrogate when the pair is in the same span. */
-                    if (i + 1 < spanEnd && Character.isLowSurrogate(chars[i + 1])) {
-                        codePoint = Character.toCodePoint(ch, chars[++i]);
-                    }
-                }
-                if (Character.isWhitespace(codePoint)) {
-                    complex = feature || complexRun;
-                } else {
-                    complex = feature || ScriptMapper.isComplexCharCode(codePoint);
-                }
-                complexChanged = complex != complexRun;
-            }
-
-            if (delimiterChanged || spanChanged || levelChanged || complexChanged) {
-
-                /* Create text run */
-                if (i != start) {
-                    run = addTextRun(layout, chars, start, i - start,
-                                     font, span, bidiLevel, complexRun);
-                    if (complexRun) {
-                        flags |= FLAGS_HAS_COMPLEX;
-                    }
-                    start = i;
-                }
-
-                if (delimiterChanged) {
-                    i++;
-                    /* Only merge \r\n when the are in the same text span */
-                    if (ch == '\r' && i < spanEnd && chars[i] == '\n') {
-                        i++;
-                    }
-
-                    /* Create delimiter run */
-                    run = new TextRun(start, i - start, bidiLevel, false,
-                                      ScriptMapper.COMMON, span, 0, false);
-                    if (ch == '\t') {
-                        run.setTab();
-                        flags |= FLAGS_HAS_TABS;
-                    } else {
-                        run.setLinebreak();
-                    }
-                    layout.addTextRun(run);
-
-                    start = i;
-                    if (i == length) break;
-                    spanChanged = i >= spanEnd;
-                    levelChanged = i >= bidiEnd;
-                }
-                if (spanChanged) {
-                    /* Only true for rich text (spans != null) */
-                    span = spans[++spanIndex];
-                    spanEnd += span.getText().length();
-                    font = (PGFont)span.getFont();
-                    if (font == null) {
-                        flags |= FLAGS_HAS_EMBEDDED;
-                    } else {
-                        FontResource fr = font.getFontResource();
-                        int requestedFeatures = font.getFeatures();
-                        int supportedFeatures = fr.getFeatures();
-                        feature = (requestedFeatures & supportedFeatures) != 0;
-                    }
-                }
-                if (levelChanged) {
-                    bidiIndex++;
-                    /* Temporary Code: See RT-26997 */
-//                    bidiLevel = (byte)bidi.getRunLevel(bidiIndex);
-                    bidiLevel = (byte)bidi.getLevelAt(bidi.getRunStart(bidiIndex));
-                    bidiEnd = bidi.getRunLimit(bidiIndex);
-                    if ((bidiLevel & 1) != 0) {
-                        flags |= FLAGS_HAS_BIDI;
-                    }
-                }
-
-                if (complexChanged) {
-                    if (delimiterChanged) {
-                        ch = chars[i]; /* update ch because of delimiterChanged */
-                        if (Character.isHighSurrogate(ch)) {
-                            /* Only merge surrogate when the pair is in the same span */
-                            if (i + 1 < spanEnd && Character.isLowSurrogate(chars[i + 1])) {
-                                codePoint = Character.toCodePoint(ch, chars[++i]);
-                            }
-                        }
-                        if (Character.isWhitespace(codePoint)) {
-                            complex = feature || complexRun;
-                        } else {
-                            complex = feature || ScriptMapper.isComplexCharCode(codePoint);
-                        }
-                    }
-                    complexRun = complex;
-                }
-            }
-            if (!delimiterChanged) i++;
-        }
-
-        /* Create final text run */
-        if (start < length) {
-            addTextRun(layout, chars, start, length - start,
-                       font, span, bidiLevel, complexRun);
-            if (complexRun) {
-                flags |= FLAGS_HAS_COMPLEX;
-            }
-        } else {
-            /* Ensure every lines has at least one run */
-            if (run == null || run.isLinebreak()) {
-                run = new TextRun(start, 0, (byte)0, false,
-                                  ScriptMapper.COMMON, span, 0, false);
-                layout.addTextRun(run);
-            }
-        }
-        if (bidi != null) {
-            if (!bidi.baseIsLeftToRight()) {
-                flags |= FLAGS_RTL_BASE;
-            }
-        }
-        flags |= FLAGS_ANALYSIS_VALID;
-        return flags;
-    }
-
     public void layout(TextRun run, PGFont font, FontStrike strike, char[] text) {
         // Nothing - complex run are analyzed by CoreText during break run
     }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java	Tue Jul 09 16:04:06 2013 +0200
@@ -101,6 +101,10 @@
         int textureType = OS.DWRITE_TEXTURE_CLEARTYPE_3x1;
         IDWriteGlyphRunAnalysis runAnalysis = createAnalysis(subPixelX, subPixelY);
         rect = runAnalysis.GetAlphaTextureBounds(textureType);
+        if ((rect.right - rect.left == 0) ||
+            (rect.bottom - rect.top == 0)) {
+            return new byte[0];
+        }
         byte[] buffer = runAnalysis.CreateAlphaTexture(textureType, rect);
         runAnalysis.Release();
         return buffer;
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java	Tue Jul 09 16:04:06 2013 +0200
@@ -25,7 +25,6 @@
 
 package com.sun.javafx.font.directwrite;
 
-import java.text.Bidi;
 import com.sun.javafx.font.CompositeFontResource;
 import com.sun.javafx.font.FontResource;
 import com.sun.javafx.font.FontStrike;
@@ -34,43 +33,36 @@
 import com.sun.javafx.scene.text.TextSpan;
 import com.sun.javafx.text.GlyphLayout;
 import com.sun.javafx.text.PrismTextLayout;
-import com.sun.javafx.text.ScriptMapper;
 import com.sun.javafx.text.TextRun;
-import static com.sun.javafx.scene.text.TextLayout.*;
 
 public class DWGlyphLayout extends GlyphLayout {
 
     private static final String LOCALE = "en-us";
 
-    private TextRun addTextRun(PrismTextLayout layout, char[] chars, int start, int length,
-                               PGFont font, TextSpan span, byte level, boolean complex) {
+    protected TextRun addTextRun(PrismTextLayout layout, char[] chars, int start,
+                                 int length, PGFont font, TextSpan span, byte level) {
         TextRun textRun = null;
-        if (complex) {
-            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);
-            sink.AddRef();
+        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);
+        sink.AddRef();
 
-            IDWriteFactory factory = DWFactory.getDWriteFactory();
-            IDWriteTextAnalyzer analyzer = factory.CreateTextAnalyzer();
-            analyzer.AnalyzeScript(sink, 0, length, sink);
+        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) ;
-            }
+        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();
-            sink.Release();
-        } else {
-            textRun = new TextRun(start, length, level, false, 0, span, 0, false);
-            layout.addTextRun(textRun);
-        }
+        analyzer.Release();
+        sink.Release();
         return textRun;
     }
 
@@ -279,198 +271,4 @@
         }
         run.shape(totalGlyphCount, glyphs, pos, clusterMap);
     }
-
-    /*
-    * Ideally DirectWrite could be used to do the entire job.
-    * Still need to verify if JFX handling of non-complex is indeed faster
-    * than DirectWrite.
-    *
-    * (this method was copied from the CoreText implementation).
-    */
-    public int breakRuns(PrismTextLayout layout, char[] chars, int flags) {
-        int length = chars.length;
-        boolean complexRun = false;
-        boolean complex = false;
-        boolean feature = false;
-
-        boolean checkComplex = true;
-        boolean checkBidi = true;
-        if ((flags & FLAGS_ANALYSIS_VALID) != 0) {
-            /* Avoid work when it is known neither complex
-             * text nor bidi are not present. */
-            checkComplex = (flags & FLAGS_HAS_COMPLEX) != 0;
-            checkBidi = (flags & FLAGS_HAS_BIDI) != 0;
-        }
-
-        TextRun run = null;
-        Bidi bidi = null;
-        byte bidiLevel = 0;
-        int bidiEnd = length;
-        int bidiIndex = 0;
-        int spanIndex = 0;
-        TextSpan span = null;
-        int spanEnd = length;
-        PGFont font = null;
-        TextSpan[] spans = layout.getTextSpans();
-        if (spans != null) {
-            if (spans.length > 0) {
-                span = spans[spanIndex];
-                spanEnd = span.getText().length();
-                font = (PGFont)span.getFont();
-                if (font == null) {
-                    flags |= FLAGS_HAS_EMBEDDED;
-                }
-            }
-        } else {
-            font = layout.getFont();
-        }
-        if (font != null) {
-            FontResource fr = font.getFontResource();
-            int requestedFeatures = font.getFeatures();
-            int supportedFeatures = fr.getFeatures();
-            feature = (requestedFeatures & supportedFeatures) != 0;
-        }
-        if (checkBidi && length > 0) {
-            int direction = layout.getDirection();
-            bidi = new Bidi(chars, 0, null, 0, length, direction);
-            /* Temporary Code: See RT-26997 */
-//            bidiLevel = (byte)bidi.getRunLevel(bidiIndex);
-            bidiLevel = (byte)bidi.getLevelAt(bidi.getRunStart(bidiIndex));
-            bidiEnd = bidi.getRunLimit(bidiIndex);
-            if ((bidiLevel & 1) != 0) {
-                flags |= FLAGS_HAS_BIDI;
-            }
-        }
-
-        int start = 0;
-        int i = 0;
-        while (i < length) {
-            char ch = chars[i];
-            int codePoint = ch;
-
-            boolean delimiterChanged = ch == '\t' || ch == '\n' || ch == '\r';
-            boolean spanChanged = i >= spanEnd;
-            boolean levelChanged = i >= bidiEnd;
-            boolean complexChanged = false;
-
-            if (checkComplex) {
-                if (Character.isHighSurrogate(ch)) {
-                    /* Only merge surrogate when the pair is in the same span. */
-                    if (i + 1 < spanEnd && Character.isLowSurrogate(chars[i + 1])) {
-                        codePoint = Character.toCodePoint(ch, chars[++i]);
-                    }
-                }
-                if (Character.isWhitespace(codePoint)) {
-                    complex = feature || complexRun;
-                } else {
-                    complex = feature || ScriptMapper.isComplexCharCode(codePoint);
-                }
-                complexChanged = complex != complexRun;
-            }
-
-            if (delimiterChanged || spanChanged || levelChanged || complexChanged) {
-
-                /* Create text run */
-                if (i != start) {
-                    run = addTextRun(layout, chars, start, i - start,
-                                     font, span, bidiLevel, complexRun);
-                    if (complexRun) {
-                        flags |= FLAGS_HAS_COMPLEX;
-                    }
-                    start = i;
-                }
-
-                if (delimiterChanged) {
-                    i++;
-                    /* Only merge \r\n when the are in the same text span */
-                    if (ch == '\r' && i < spanEnd && chars[i] == '\n') {
-                        i++;
-                    }
-
-                    /* Create delimiter run */
-                    run = new TextRun(start, i - start, bidiLevel, false,
-                                      ScriptMapper.COMMON, span, 0, false);
-                    if (ch == '\t') {
-                        run.setTab();
-                        flags |= FLAGS_HAS_TABS;
-                    } else {
-                        run.setLinebreak();
-                    }
-                    layout.addTextRun(run);
-
-                    start = i;
-                    if (i == length) break;
-                    spanChanged = i >= spanEnd;
-                    levelChanged = i >= bidiEnd;
-                }
-                if (spanChanged) {
-                    /* Only true for rich text (spans != null) */
-                    span = spans[++spanIndex];
-                    spanEnd += span.getText().length();
-                    font = (PGFont)span.getFont();
-                    if (font == null) {
-                        flags |= FLAGS_HAS_EMBEDDED;
-                    } else {
-                        FontResource fr = font.getFontResource();
-                        int requestedFeatures = font.getFeatures();
-                        int supportedFeatures = fr.getFeatures();
-                        feature = (requestedFeatures & supportedFeatures) != 0;
-                    }
-                }
-                if (levelChanged) {
-                    bidiIndex++;
-                    /* Temporary Code: See RT-26997 */
-//                    bidiLevel = (byte)bidi.getRunLevel(bidiIndex);
-                    bidiLevel = (byte)bidi.getLevelAt(bidi.getRunStart(bidiIndex));
-                    bidiEnd = bidi.getRunLimit(bidiIndex);
-                    if ((bidiLevel & 1) != 0) {
-                        flags |= FLAGS_HAS_BIDI;
-                    }
-                }
-
-                if (complexChanged) {
-                    if (delimiterChanged) {
-                        ch = chars[i]; /* update ch because of delimiterChanged */
-                        if (Character.isHighSurrogate(ch)) {
-                            /* Only merge surrogate when the pair is in the same span */
-                            if (i + 1 < spanEnd && Character.isLowSurrogate(chars[i + 1])) {
-                                codePoint = Character.toCodePoint(ch, chars[++i]);
-                            }
-                        }
-                        if (Character.isWhitespace(codePoint)) {
-                            complex = feature || complexRun;
-                        } else {
-                            complex = feature || ScriptMapper.isComplexCharCode(codePoint);
-                        }
-                    }
-                    complexRun = complex;
-                }
-            }
-            if (!delimiterChanged) i++;
-        }
-
-        /* Create final text run */
-        if (start < length) {
-            addTextRun(layout, chars, start, length - start,
-                       font, span, bidiLevel, complexRun);
-            if (complexRun) {
-                flags |= FLAGS_HAS_COMPLEX;
-            }
-        } else {
-            /* Ensure every lines has at least one run */
-            if (run == null || run.isLinebreak()) {
-                run = new TextRun(start, 0, (byte)0, false,
-                                  ScriptMapper.COMMON, span, 0, false);
-                layout.addTextRun(run);
-            }
-        }
-        if (bidi != null) {
-            if (!bidi.baseIsLeftToRight()) {
-                flags |= FLAGS_RTL_BASE;
-            }
-        }
-        flags |= FLAGS_ANALYSIS_VALID;
-        return flags;
-    }
-
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/font/pango/PangoGlyphLayout.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/pango/PangoGlyphLayout.java	Tue Jul 09 16:04:06 2013 +0200
@@ -25,21 +25,12 @@
 
 package com.sun.javafx.font.pango;
 
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_ANALYSIS_VALID;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_BIDI;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_COMPLEX;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_EMBEDDED;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_TABS;
-import static com.sun.javafx.scene.text.TextLayout.FLAGS_RTL_BASE;
-
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.StandardCharsets;
-import java.text.Bidi;
-
 import com.sun.javafx.font.CompositeFontResource;
 import com.sun.javafx.font.FontResource;
 import com.sun.javafx.font.FontStrike;
@@ -48,7 +39,6 @@
 import com.sun.javafx.scene.text.TextSpan;
 import com.sun.javafx.text.GlyphLayout;
 import com.sun.javafx.text.PrismTextLayout;
-import com.sun.javafx.text.ScriptMapper;
 import com.sun.javafx.text.TextRun;
 
 class PangoGlyphLayout extends GlyphLayout {
@@ -80,279 +70,88 @@
         return slot;
     }
 
-    private TextRun addTextRun(PrismTextLayout layout, char[] chars, int start, int length,
-                               PGFont font, TextSpan span, byte level, boolean complex) {
+    protected TextRun addTextRun(PrismTextLayout layout, char[] chars, int start,
+                                 int length, PGFont font, TextSpan span, byte level) {
 
         TextRun textRun = null;
-        if (complex) {
-            Charset utf8 = StandardCharsets.UTF_8;
-            CharsetEncoder encoder = utf8.newEncoder();
-            CharBuffer in = CharBuffer.wrap(chars, start, length);
-            int capacity = (int)(length * (double)encoder.averageBytesPerChar());
-            ByteBuffer out = ByteBuffer.allocateDirect(capacity);
-            CoderResult result = encoder.encode(in, out, true);
-            if (result.isOverflow()) {
-                capacity = (int)(length * (double)encoder.maxBytesPerChar());
-                in.rewind();
-                out = ByteBuffer.allocateDirect(capacity);
-                encoder.encode(in, out, true);
-                if (PrismFontFactory.debugFonts) {
-                    System.err.println("[PANGO] ByteBuffer capacity increased " + out);
-                }
+        Charset utf8 = StandardCharsets.UTF_8;
+        CharsetEncoder encoder = utf8.newEncoder();
+        CharBuffer in = CharBuffer.wrap(chars, start, length);
+        int capacity = (int)(length * (double)encoder.averageBytesPerChar());
+        ByteBuffer out = ByteBuffer.allocateDirect(capacity);
+        CoderResult result = encoder.encode(in, out, true);
+        if (result.isOverflow()) {
+            capacity = (int)(length * (double)encoder.maxBytesPerChar());
+            in.rewind();
+            out = ByteBuffer.allocateDirect(capacity);
+            encoder.encode(in, out, true);
+            if (PrismFontFactory.debugFonts) {
+                System.err.println("[PANGO] ByteBuffer capacity increased " + out);
+            }
+        }
+
+        FontResource fr = font.getFontResource();
+        boolean composite = fr instanceof CompositeFontResource;
+        if (composite) {
+            fr = ((CompositeFontResource)fr).getSlotResource(0);
+        }
+
+        long fontmap = OS.pango_ft2_font_map_new();
+        long context = OS.pango_font_map_create_context(fontmap);
+        float size = font.getSize();
+        int style = fr.isItalic() ? OS.PANGO_STYLE_ITALIC : OS.PANGO_STYLE_NORMAL;
+        int weight = fr.isBold() ? OS.PANGO_WEIGHT_BOLD : OS.PANGO_WEIGHT_NORMAL;
+        long desc = OS.pango_font_description_new();
+        OS.pango_font_description_set_family(desc, fr.getFamilyName());
+        OS.pango_font_description_set_absolute_size(desc, size * OS.PANGO_SCALE);
+        OS.pango_font_description_set_stretch(desc, OS.PANGO_STRETCH_NORMAL);
+        OS.pango_font_description_set_style(desc, style);
+        OS.pango_font_description_set_weight(desc, weight);
+        long attrList = OS.pango_attr_list_new();
+        long attr = OS.pango_attr_font_desc_new(desc);
+        OS.pango_attr_list_insert(attrList, attr);
+        if (!composite) {
+            attr = OS.pango_attr_fallback_new(false);
+            OS.pango_attr_list_insert(attrList, attr);
+        }
+        long runs = OS.pango_itemize(context, out, 0, out.position(), attrList, 0);
+        int runsCount = OS.g_list_length(runs);
+        int runStart = start;
+        for (int i = 0; i < runsCount; i++) {
+            long pangoItem = OS.g_list_nth_data(runs, i);
+            PangoGlyphString glyphString = OS.pango_shape(out, pangoItem);
+            OS.pango_item_free(pangoItem);
+            int slot = composite ? getSlot(font, glyphString) : 0;
+            int glyphCount = glyphString.num_glyphs;
+            int[] glyphs = new int[glyphCount];
+            float[] pos = new float[glyphCount*2+2];
+            PangoGlyphInfo info = null;
+            int k = 2;
+            int width = 0;
+            for (int j = 0; j < glyphCount; j++) {
+                info = glyphString.glyphs[j];
+                glyphs[j] = slot | info.glyph;
+                width += info.width;
+                pos[k] = ((float)width) / OS.PANGO_SCALE;
+                k += 2;
             }
 
-            FontResource fr = font.getFontResource();
-            boolean composite = fr instanceof CompositeFontResource;
-            if (composite) {
-                fr = ((CompositeFontResource)fr).getSlotResource(0);
-            }
-
-            long fontmap = OS.pango_ft2_font_map_new();
-            long context = OS.pango_font_map_create_context(fontmap);
-            float size = font.getSize();
-            int style = fr.isItalic() ? OS.PANGO_STYLE_ITALIC : OS.PANGO_STYLE_NORMAL;
-            int weight = fr.isBold() ? OS.PANGO_WEIGHT_BOLD : OS.PANGO_WEIGHT_NORMAL;
-            long desc = OS.pango_font_description_new();
-            OS.pango_font_description_set_family(desc, fr.getFamilyName());
-            OS.pango_font_description_set_absolute_size(desc, size * OS.PANGO_SCALE);
-            OS.pango_font_description_set_stretch(desc, OS.PANGO_STRETCH_NORMAL);
-            OS.pango_font_description_set_style(desc, style);
-            OS.pango_font_description_set_weight(desc, weight);
-            long attrList = OS.pango_attr_list_new();
-            long attr = OS.pango_attr_font_desc_new(desc);
-            OS.pango_attr_list_insert(attrList, attr);
-            if (!composite) {
-                attr = OS.pango_attr_fallback_new(false);
-                OS.pango_attr_list_insert(attrList, attr);
-            }
-            long runs = OS.pango_itemize(context, out, 0, out.position(), attrList, 0);
-            int runsCount = OS.g_list_length(runs);
-            int runStart = start;
-            for (int i = 0; i < runsCount; i++) {
-                long pangoItem = OS.g_list_nth_data(runs, i);
-                PangoGlyphString glyphString = OS.pango_shape(out, pangoItem);
-                OS.pango_item_free(pangoItem);
-                int slot = composite ? getSlot(font, glyphString) : 0;
-                int glyphCount = glyphString.num_glyphs;
-                int[] glyphs = new int[glyphCount];
-                float[] pos = new float[glyphCount*2+2];
-                PangoGlyphInfo info = null;
-                int k = 2;
-                int width = 0;
-                for (int j = 0; j < glyphCount; j++) {
-                    info = glyphString.glyphs[j];
-                    glyphs[j] = slot | info.glyph;
-                    width += info.width;
-                    pos[k] = ((float)width) / OS.PANGO_SCALE;
-                    k += 2;
-                }
-
-                int runLength = glyphString.num_chars;
-                textRun = new TextRun(runStart, runLength, level, true, 0, span, 0, false);
-                textRun.shape(glyphCount, glyphs, pos, glyphString.log_clusters);
-                layout.addTextRun(textRun);
-                runStart += runLength;
-            }
-            OS.g_list_free(runs);
-            /* pango_attr_list_unref() also frees the attributes it contains */
-            OS.pango_attr_list_unref(attrList);
-            OS.pango_font_description_free(desc);
-            OS.g_object_unref(context);
-            OS.g_object_unref(fontmap);
-        } else {
-            textRun = new TextRun(start, length, level, false, 0, span, 0, false);
+            int runLength = glyphString.num_chars;
+            textRun = new TextRun(runStart, runLength, level, true, 0, span, 0, false);
+            textRun.shape(glyphCount, glyphs, pos, glyphString.log_clusters);
             layout.addTextRun(textRun);
+            runStart += runLength;
         }
+        OS.g_list_free(runs);
+        /* pango_attr_list_unref() also frees the attributes it contains */
+        OS.pango_attr_list_unref(attrList);
+        OS.pango_font_description_free(desc);
+        OS.g_object_unref(context);
+        OS.g_object_unref(fontmap);
         return textRun;
     }
 
     public void layout(TextRun run, PGFont font, FontStrike strike, char[] text) {
         // Nothing - complex run are analyzed by Pango during break run
     }
-
-    public int breakRuns(PrismTextLayout layout, char[] chars, int flags) {
-        int length = chars.length;
-        boolean complexRun = false;
-        boolean complex = false;
-        boolean feature = false;
-
-        boolean checkComplex = true;
-        boolean checkBidi = true;
-        if ((flags & FLAGS_ANALYSIS_VALID) != 0) {
-            /* Avoid work when it is known neither complex
-             * text nor bidi are not present. */
-            checkComplex = (flags & FLAGS_HAS_COMPLEX) != 0;
-            checkBidi = (flags & FLAGS_HAS_BIDI) != 0;
-        }
-
-        TextRun run = null;
-        Bidi bidi = null;
-        byte bidiLevel = 0;
-        int bidiEnd = length;
-        int bidiIndex = 0;
-        int spanIndex = 0;
-        TextSpan span = null;
-        int spanEnd = length;
-        PGFont font = null;
-        TextSpan[] spans = layout.getTextSpans();
-        if (spans != null) {
-            if (spans.length > 0) {
-                span = spans[spanIndex];
-                spanEnd = span.getText().length();
-                font = (PGFont)span.getFont();
-                if (font == null) {
-                    flags |= FLAGS_HAS_EMBEDDED;
-                }
-            }
-        } else {
-            font = layout.getFont();
-        }
-        if (font != null) {
-            FontResource fr = font.getFontResource();
-            int requestedFeatures = font.getFeatures();
-            int supportedFeatures = fr.getFeatures();
-            feature = (requestedFeatures & supportedFeatures) != 0;
-        }
-        if (checkBidi && length > 0) {
-            int direction = layout.getDirection();
-            bidi = new Bidi(chars, 0, null, 0, length, direction);
-            /* Temporary Code: See RT-26997 */
-//            bidiLevel = (byte)bidi.getRunLevel(bidiIndex);
-            bidiLevel = (byte)bidi.getLevelAt(bidi.getRunStart(bidiIndex));
-            bidiEnd = bidi.getRunLimit(bidiIndex);
-            if ((bidiLevel & 1) != 0) {
-                flags |= FLAGS_HAS_BIDI;
-            }
-        }
-
-        int start = 0;
-        int i = 0;
-        while (i < length) {
-            char ch = chars[i];
-            int codePoint = ch;
-
-            boolean delimiterChanged = ch == '\t' || ch == '\n' || ch == '\r';
-            boolean spanChanged = i >= spanEnd;
-            boolean levelChanged = i >= bidiEnd;
-            boolean complexChanged = false;
-
-            if (checkComplex) {
-                if (Character.isHighSurrogate(ch)) {
-                    /* Only merge surrogate when the pair is in the same span. */
-                    if (i + 1 < spanEnd && Character.isLowSurrogate(chars[i + 1])) {
-                        codePoint = Character.toCodePoint(ch, chars[++i]);
-                    }
-                }
-                if (Character.isWhitespace(codePoint)) {
-                    complex = feature || complexRun;
-                } else {
-                    complex = feature || ScriptMapper.isComplexCharCode(codePoint);
-                }
-                complexChanged = complex != complexRun;
-            }
-
-            if (delimiterChanged || spanChanged || levelChanged || complexChanged) {
-
-                /* Create text run */
-                if (i != start) {
-                    run = addTextRun(layout, chars, start, i - start,
-                                     font, span, bidiLevel, complexRun);
-                    if (complexRun) {
-                        flags |= FLAGS_HAS_COMPLEX;
-                    }
-                    start = i;
-                }
-
-                if (delimiterChanged) {
-                    i++;
-                    /* Only merge \r\n when the are in the same text span */
-                    if (ch == '\r' && i < spanEnd && chars[i] == '\n') {
-                        i++;
-                    }
-
-                    /* Create delimiter run */
-                    run = new TextRun(start, i - start, bidiLevel, false,
-                                      ScriptMapper.COMMON, span, 0, false);
-                    if (ch == '\t') {
-                        run.setTab();
-                        flags |= FLAGS_HAS_TABS;
-                    } else {
-                        run.setLinebreak();
-                    }
-                    layout.addTextRun(run);
-
-                    start = i;
-                    if (i == length) break;
-                    spanChanged = i >= spanEnd;
-                    levelChanged = i >= bidiEnd;
-                }
-                if (spanChanged) {
-                    /* Only true for rich text (spans != null) */
-                    span = spans[++spanIndex];
-                    spanEnd += span.getText().length();
-                    font = (PGFont)span.getFont();
-                    if (font == null) {
-                        flags |= FLAGS_HAS_EMBEDDED;
-                    } else {
-                        FontResource fr = font.getFontResource();
-                        int requestedFeatures = font.getFeatures();
-                        int supportedFeatures = fr.getFeatures();
-                        feature = (requestedFeatures & supportedFeatures) != 0;
-                    }
-                }
-                if (levelChanged) {
-                    bidiIndex++;
-                    /* Temporary Code: See RT-26997 */
-//                    bidiLevel = (byte)bidi.getRunLevel(bidiIndex);
-                    bidiLevel = (byte)bidi.getLevelAt(bidi.getRunStart(bidiIndex));
-                    bidiEnd = bidi.getRunLimit(bidiIndex);
-                    if ((bidiLevel & 1) != 0) {
-                        flags |= FLAGS_HAS_BIDI;
-                    }
-                }
-
-                if (complexChanged) {
-                    if (delimiterChanged) {
-                        ch = chars[i]; /* update ch because of delimiterChanged */
-                        if (Character.isHighSurrogate(ch)) {
-                            /* Only merge surrogate when the pair is in the same span */
-                            if (i + 1 < spanEnd && Character.isLowSurrogate(chars[i + 1])) {
-                                codePoint = Character.toCodePoint(ch, chars[++i]);
-                            }
-                        }
-                        if (Character.isWhitespace(codePoint)) {
-                            complex = feature || complexRun;
-                        } else {
-                            complex = feature || ScriptMapper.isComplexCharCode(codePoint);
-                        }
-                    }
-                    complexRun = complex;
-                }
-            }
-            if (!delimiterChanged) i++;
-        }
-
-        /* Create final text run */
-        if (start < length) {
-            addTextRun(layout, chars, start, length - start,
-                       font, span, bidiLevel, complexRun);
-            if (complexRun) {
-                flags |= FLAGS_HAS_COMPLEX;
-            }
-        } else {
-            /* Ensure every lines has at least one run */
-            if (run == null || run.isLinebreak()) {
-                run = new TextRun(start, 0, (byte)0, false,
-                                  ScriptMapper.COMMON, span, 0, false);
-                layout.addTextRun(run);
-            }
-        }
-        if (bidi != null) {
-            if (!bidi.baseIsLeftToRight()) {
-                flags |= FLAGS_RTL_BASE;
-            }
-        }
-        flags |= FLAGS_ANALYSIS_VALID;
-        return flags;
-    }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/text/GlyphLayout.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/text/GlyphLayout.java	Tue Jul 09 16:04:06 2013 +0200
@@ -56,9 +56,20 @@
  */
 package com.sun.javafx.text;
 
+import static com.sun.javafx.scene.text.TextLayout.FLAGS_ANALYSIS_VALID;
+import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_BIDI;
+import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_COMPLEX;
+import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_EMBEDDED;
+import static com.sun.javafx.scene.text.TextLayout.FLAGS_HAS_TABS;
+import static com.sun.javafx.scene.text.TextLayout.FLAGS_RTL_BASE;
+
+import java.text.Bidi;
+
+import com.sun.javafx.font.FontResource;
 import com.sun.javafx.font.FontStrike;
 import com.sun.javafx.font.PGFont;
 import com.sun.javafx.font.PrismFontFactory;
+import com.sun.javafx.scene.text.TextSpan;
 
 public abstract class GlyphLayout {
 
@@ -84,7 +95,211 @@
 
     public static final int HINTING = 1 << 4;
 
-    public abstract int breakRuns(PrismTextLayout layout, char[] text, int flags);
+    protected TextRun addTextRun(PrismTextLayout layout, char[] chars,
+                                 int start, int length,
+                                 PGFont font, TextSpan span, byte level) {
+        /* subclass can overwrite this method in order to handle complex text */
+        TextRun run = new TextRun(start, length, level, false, 0, span, 0, false);
+        layout.addTextRun(run);
+        return run;
+    }
+
+    private TextRun addTextRun(PrismTextLayout layout, char[] chars,
+                               int start, int length, PGFont font,
+                               TextSpan span, byte level, boolean complex) {
+        if (complex) {
+            return addTextRun(layout, chars, start, length, font, span, level);
+        }
+        TextRun run = new TextRun(start, length, level, false, 0, span, 0, false);
+        layout.addTextRun(run);
+        return run;
+    }
+
+    public int breakRuns(PrismTextLayout layout, char[] chars, int flags) {
+        int length = chars.length;
+        boolean complexRun = false;
+        boolean complex = false;
+        boolean feature = false;
+
+        boolean checkComplex = true;
+        boolean checkBidi = true;
+        if ((flags & FLAGS_ANALYSIS_VALID) != 0) {
+            /* Avoid work when it is known neither complex
+             * text nor bidi are not present. */
+            checkComplex = (flags & FLAGS_HAS_COMPLEX) != 0;
+            checkBidi = (flags & FLAGS_HAS_BIDI) != 0;
+        }
+
+        TextRun run = null;
+        Bidi bidi = null;
+        byte bidiLevel = 0;
+        int bidiEnd = length;
+        int bidiIndex = 0;
+        int spanIndex = 0;
+        TextSpan span = null;
+        int spanEnd = length;
+        PGFont font = null;
+        TextSpan[] spans = layout.getTextSpans();
+        if (spans != null) {
+            if (spans.length > 0) {
+                span = spans[spanIndex];
+                spanEnd = span.getText().length();
+                font = (PGFont)span.getFont();
+                if (font == null) {
+                    flags |= FLAGS_HAS_EMBEDDED;
+                }
+            }
+        } else {
+            font = layout.getFont();
+        }
+        if (font != null) {
+            FontResource fr = font.getFontResource();
+            int requestedFeatures = font.getFeatures();
+            int supportedFeatures = fr.getFeatures();
+            feature = (requestedFeatures & supportedFeatures) != 0;
+        }
+        if (checkBidi && length > 0) {
+            int direction = layout.getDirection();
+            bidi = new Bidi(chars, 0, null, 0, length, direction);
+            /* Temporary Code: See RT-26997 */
+//            bidiLevel = (byte)bidi.getRunLevel(bidiIndex);
+            bidiLevel = (byte)bidi.getLevelAt(bidi.getRunStart(bidiIndex));
+            bidiEnd = bidi.getRunLimit(bidiIndex);
+            if ((bidiLevel & 1) != 0) {
+                flags |= FLAGS_HAS_BIDI;
+            }
+        }
+
+        int start = 0;
+        int i = 0;
+        while (i < length) {
+            char ch = chars[i];
+            int codePoint = ch;
+
+            boolean delimiterChanged = ch == '\t' || ch == '\n' || ch == '\r';
+            boolean spanChanged = i >= spanEnd;
+            boolean levelChanged = i >= bidiEnd;
+            boolean complexChanged = false;
+
+            if (checkComplex) {
+                if (Character.isHighSurrogate(ch)) {
+                    /* Only merge surrogate when the pair is in the same span. */
+                    if (i + 1 < spanEnd && Character.isLowSurrogate(chars[i + 1])) {
+                        codePoint = Character.toCodePoint(ch, chars[++i]);
+                    }
+                }
+                if (Character.isWhitespace(codePoint)) {
+                    complex = feature || complexRun;
+                } else {
+                    complex = feature || ScriptMapper.isComplexCharCode(codePoint);
+                }
+                complexChanged = complex != complexRun;
+            }
+
+            if (delimiterChanged || spanChanged || levelChanged || complexChanged) {
+
+                /* Create text run */
+                if (i != start) {
+                    run = addTextRun(layout, chars, start, i - start,
+                                     font, span, bidiLevel, complexRun);
+                    if (complexRun) {
+                        flags |= FLAGS_HAS_COMPLEX;
+                    }
+                    start = i;
+                }
+
+                if (delimiterChanged) {
+                    i++;
+                    /* Only merge \r\n when the are in the same text span */
+                    if (ch == '\r' && i < spanEnd && chars[i] == '\n') {
+                        i++;
+                    }
+
+                    /* Create delimiter run */
+                    run = new TextRun(start, i - start, bidiLevel, false,
+                                      ScriptMapper.COMMON, span, 0, false);
+                    if (ch == '\t') {
+                        run.setTab();
+                        flags |= FLAGS_HAS_TABS;
+                    } else {
+                        run.setLinebreak();
+                    }
+                    layout.addTextRun(run);
+
+                    start = i;
+                    if (i == length) break;
+                    spanChanged = i >= spanEnd;
+                    levelChanged = i >= bidiEnd;
+                }
+                if (spanChanged) {
+                    /* Only true for rich text (spans != null) */
+                    span = spans[++spanIndex];
+                    spanEnd += span.getText().length();
+                    font = (PGFont)span.getFont();
+                    if (font == null) {
+                        flags |= FLAGS_HAS_EMBEDDED;
+                    } else {
+                        FontResource fr = font.getFontResource();
+                        int requestedFeatures = font.getFeatures();
+                        int supportedFeatures = fr.getFeatures();
+                        feature = (requestedFeatures & supportedFeatures) != 0;
+                    }
+                }
+                if (levelChanged) {
+                    bidiIndex++;
+                    /* Temporary Code: See RT-26997 */
+//                    bidiLevel = (byte)bidi.getRunLevel(bidiIndex);
+                    bidiLevel = (byte)bidi.getLevelAt(bidi.getRunStart(bidiIndex));
+                    bidiEnd = bidi.getRunLimit(bidiIndex);
+                    if ((bidiLevel & 1) != 0) {
+                        flags |= FLAGS_HAS_BIDI;
+                    }
+                }
+
+                if (complexChanged) {
+                    if (delimiterChanged) {
+                        ch = chars[i]; /* update ch because of delimiterChanged */
+                        if (Character.isHighSurrogate(ch)) {
+                            /* Only merge surrogate when the pair is in the same span */
+                            if (i + 1 < spanEnd && Character.isLowSurrogate(chars[i + 1])) {
+                                codePoint = Character.toCodePoint(ch, chars[++i]);
+                            }
+                        }
+                        if (Character.isWhitespace(codePoint)) {
+                            complex = feature || complexRun;
+                        } else {
+                            complex = feature || ScriptMapper.isComplexCharCode(codePoint);
+                        }
+                    }
+                    complexRun = complex;
+                }
+            }
+            if (!delimiterChanged) i++;
+        }
+
+        /* Create final text run */
+        if (start < length) {
+            addTextRun(layout, chars, start, length - start,
+                       font, span, bidiLevel, complexRun);
+            if (complexRun) {
+                flags |= FLAGS_HAS_COMPLEX;
+            }
+        } else {
+            /* Ensure every lines has at least one run */
+            if (run == null || run.isLinebreak()) {
+                run = new TextRun(start, 0, (byte)0, false,
+                                  ScriptMapper.COMMON, span, 0, false);
+                layout.addTextRun(run);
+            }
+        }
+        if (bidi != null) {
+            if (!bidi.baseIsLeftToRight()) {
+                flags |= FLAGS_RTL_BASE;
+            }
+        }
+        flags |= FLAGS_ANALYSIS_VALID;
+        return flags;
+    }
 
     public abstract void layout(TextRun run, PGFont font,
                                 FontStrike strike, char[] text);
--- a/modules/graphics/src/main/java/javafx/stage/FileChooser.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/graphics/src/main/java/javafx/stage/FileChooser.java	Tue Jul 09 16:04:06 2013 +0200
@@ -251,7 +251,7 @@
      * file open dialogs.
      * </p>
      *
-     * @since JavaFX 8.0
+     * @since JavaFX 2.2.40
      */
     private ObjectProperty<String> initialFileName;
 
--- a/modules/swing/src/main/java/javafx/embed/swing/SwingNode.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/swing/src/main/java/javafx/embed/swing/SwingNode.java	Tue Jul 09 16:04:06 2013 +0200
@@ -535,7 +535,10 @@
             Platform.runLater(new Runnable() {
                 @Override
                 public void run() {
-                    if (getScene() != null && getScene().getWindow() != null) {
+                    if (getScene() != null &&
+                        getScene().getWindow() != null &&
+                        getScene().getWindow().impl_getPeer() != null)
+                    {
                         getScene().getWindow().impl_getPeer().grabFocus();
                         grabbed = true;
                     }
@@ -555,7 +558,9 @@
 
     private void ungrabFocus(boolean postUngrabEvent) {
         if (grabbed &&
-            getScene() != null && getScene().getWindow() != null)
+            getScene() != null &&
+            getScene().getWindow() != null &&
+            getScene().getWindow().impl_getPeer() != null)
         {
             skipBackwardUnrgabNotification = !postUngrabEvent;
             getScene().getWindow().impl_getPeer().ungrabFocus();
--- a/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java	Tue Jul 09 16:04:06 2013 +0200
@@ -937,8 +937,12 @@
     }
 
     @Override
-    public void drawWidget(RenderTheme theme, Ref widget, int x, int y) {
-        theme.drawWidget(this, widget, x, y);
+    public void drawWidget(final RenderTheme theme, final Ref widget, final int x, final int y) {
+        new Composite() {
+            @Override void doPaint(Graphics g) {
+                theme.drawWidget(WCGraphicsPrismContext.this, widget, x, y);
+            }
+        }.paint();
     }
 
     @Override
--- a/modules/web/src/test/java/javafx/scene/web/MiscellaneousTest.java	Tue Jul 09 16:00:44 2013 +0200
+++ b/modules/web/src/test/java/javafx/scene/web/MiscellaneousTest.java	Tue Jul 09 16:04:06 2013 +0200
@@ -50,6 +50,7 @@
         private static int dummyField;
     }
 
+    @org.junit.Ignore
     @Test public void testRT30835() throws Exception {
         class Record {
             private final Document document;