Tue, 05 Nov 2013 13:09:40 +0400
8027708: NASHORN TEST: Create Nashorn test that draws image step-by-step using JavaFX canvas.
Reviewed-by: jlaskey, lagergren
1.1 --- a/make/build.xml Tue Nov 05 09:13:41 2013 +0530 1.2 +++ b/make/build.xml Tue Nov 05 13:09:40 2013 +0400 1.3 @@ -372,6 +372,12 @@ 1.4 1.5 <copy file="${file.reference.jfxrt.jar}" todir="dist"/> 1.6 1.7 + <condition property="jfx.prism.order" value="-Dprism.order=j2d" else=" "> 1.8 + <not> 1.9 + <os family="mac"/> 1.10 + </not> 1.11 + </condition> 1.12 + 1.13 <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes" 1.14 verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}"> 1.15 <jvmarg line="${ext.class.path}"/> 1.16 @@ -380,6 +386,7 @@ 1.17 <propertyref prefix="testjfx-test-sys-prop."/> 1.18 <mapper from="testjfx-test-sys-prop.*" to="*" type="glob"/> 1.19 </propertyset> 1.20 + <sysproperty key="test.fork.jvm.options" value="${testjfx-test-sys-prop.test.fork.jvm.options} ${jfx.prism.order}"/> 1.21 <classpath> 1.22 <pathelement path="${testjfx.run.test.classpath}"/> 1.23 </classpath>
2.1 --- a/make/project.properties Tue Nov 05 09:13:41 2013 +0530 2.2 +++ b/make/project.properties Tue Nov 05 13:09:40 2013 +0400 2.3 @@ -230,7 +230,7 @@ 2.4 ${file.reference.jemmyawtinput.jar}${path.separator}\ 2.5 ${file.reference.testng.jar}${path.separator}\ 2.6 ${nashorn.internal.tests.jar}${path.separator}\ 2.7 - ${nashorn.api.tests.jar} 2.8 + ${nashorn.api.tests.jar} 2.9 2.10 # testjfx VM options for script tests with @fork option 2.11 testjfx-test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} -cp ${testjfx.run.test.classpath}
3.1 --- a/test/script/jfx.js Tue Nov 05 09:13:41 2013 +0530 3.2 +++ b/test/script/jfx.js Tue Nov 05 13:09:40 2013 +0400 3.3 @@ -37,13 +37,24 @@ 3.4 var Scene = Java.type("javafx.scene.Scene"); 3.5 var Stage = Java.type("javafx.stage.Stage"); 3.6 var File = Java.type("java.io.File"); 3.7 -var Timer = Java.type("java.util.Timer"); 3.8 -var TimerTask = Java.type("java.util.TimerTask"); 3.9 var OSInfo = Java.type("sun.awt.OSInfo"); 3.10 var OSType = Java.type("sun.awt.OSInfo.OSType"); 3.11 var StringBuffer = Java.type("java.lang.StringBuffer"); 3.12 +var Paint = Java.type("javafx.scene.paint.Paint"); 3.13 +var Color = Java.type("javafx.scene.paint.Color"); 3.14 +var Image = Java.type("javafx.scene.image.Image"); 3.15 +var Canvas = Java.type("javafx.scene.canvas.Canvas"); 3.16 +var BorderPane = Java.type("javafx.scene.layout.BorderPane"); 3.17 +var StackPane = Java.type("javafx.scene.layout.StackPane"); 3.18 +var StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); 3.19 +var Platform = Java.type("javafx.application.Platform"); 3.20 +var Runnable = Java.type("java.lang.Runnable"); 3.21 +var RunnableExtend = Java.extend(Runnable); 3.22 +var AnimationTimer = Java.type("javafx.animation.AnimationTimer"); 3.23 +var AnimationTimerExtend = Java.extend(AnimationTimer); 3.24 +var Timer = Java.type("java.util.Timer"); 3.25 +var TimerTask = Java.type("java.util.TimerTask"); 3.26 3.27 -var WAIT = 2000; 3.28 var TESTNAME = "test"; 3.29 var fsep = System.getProperty("file.separator"); 3.30 3.31 @@ -53,14 +64,16 @@ 3.32 run: function run() { 3.33 var tmpdir = System.getProperty("java.io.tmpdir"); 3.34 var timenow = (new Date()).getTime(); 3.35 - makeScreenShot(tmpdir + fsep + "screenshot" + timenow +".png"); 3.36 - var dupImg = isDuplicateImages(tmpdir + fsep + "screenshot" + timenow +".png", __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden"); 3.37 - (new File(mpdir + fsep + "screenshot" + timenow +".png")).delete(); 3.38 - if (!dupImg) System.err.println("ERROR: screenshot does not match golden image"); 3.39 + var scrShotTmp = tmpdir + fsep + "screenshot" + timenow +".png"; 3.40 + var goldenImageDir = __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden"; 3.41 + makeScreenShot(scrShotTmp); 3.42 + var dupImg = isDuplicateImages(scrShotTmp, goldenImageDir); 3.43 + (new File(scrShotTmp)).delete(); 3.44 + if (!dupImg) System.err.println("ERROR: screenshot does not match the golden image"); 3.45 exit(0); 3.46 } 3.47 }; 3.48 - raceTimer.schedule(timerTask, WAIT); 3.49 + raceTimer.schedule(timerTask, 100); 3.50 } 3.51 3.52 function makeScreenShot(shootToImg) { 3.53 @@ -70,10 +83,10 @@ 3.54 imageJemmy.save(shootToImg); 3.55 } 3.56 3.57 -function isDuplicateImages(file1, file2) { 3.58 - var f1 = new File(file1); 3.59 +function isDuplicateImages(screenShot, goldenDir) { 3.60 + var f1 = new File(screenShot); 3.61 var f2; 3.62 - var sb = new StringBuffer(file2); 3.63 + var sb = new StringBuffer(goldenDir); 3.64 if (OSInfo.getOSType() == OSType.WINDOWS) { 3.65 f2 = new File(sb.append(fsep + "windows.png").toString()); 3.66 } else if (OSInfo.getOSType() == OSType.LINUX) { 3.67 @@ -81,8 +94,6 @@ 3.68 } else if (OSInfo.getOSType() == OSType.MACOSX) { 3.69 f2 = new File(sb.append(fsep + "macosx.png").toString()); 3.70 } 3.71 - print(f1.getAbsolutePath()); 3.72 - print(f2.getAbsolutePath()); 3.73 if (f1.exists() && f2.exists()) { 3.74 var image1 = new AWTImage(PNGDecoder.decode(f1.getAbsolutePath())); 3.75 var image2 = new AWTImage(PNGDecoder.decode(f2.getAbsolutePath()));
4.1 --- a/test/script/jfx/flyingimage.js Tue Nov 05 09:13:41 2013 +0530 4.2 +++ b/test/script/jfx/flyingimage.js Tue Nov 05 13:09:40 2013 +0400 4.3 @@ -31,15 +31,6 @@ 4.4 4.5 TESTNAME = "flyingimage"; 4.6 4.7 -var Image = Java.type("javafx.scene.image.Image"); 4.8 -var Color = Java.type("javafx.scene.paint.Color"); 4.9 -var Canvas = Java.type("javafx.scene.canvas.Canvas"); 4.10 -var BorderPane = Java.type("javafx.scene.layout.BorderPane"); 4.11 -var StackPane = Java.type("javafx.scene.layout.StackPane"); 4.12 -var Font = Java.type("javafx.scene.text.Font"); 4.13 -var FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType"); 4.14 -var Text = Java.type("javafx.scene.text.Text"); 4.15 - 4.16 var WIDTH = 800; 4.17 var HEIGHT = 600; 4.18 var canvas = new Canvas(WIDTH, HEIGHT); 4.19 @@ -48,10 +39,9 @@ 4.20 } 4.21 var imageUrl = fileToURL(__DIR__ + "flyingimage/flyingimage.png"); 4.22 var img = new Image(imageUrl); 4.23 -var font = new Font("Arial", 16); 4.24 -var t = 0; 4.25 var isFrameRendered = false; 4.26 function renderFrame() { 4.27 + var t = frame; 4.28 var gc = canvas.graphicsContext2D; 4.29 gc.setFill(Color.web("#cccccc")); 4.30 gc.fillRect(0, 0, WIDTH, HEIGHT); 4.31 @@ -61,7 +51,7 @@ 4.32 var c = 200; 4.33 var msc= 0.5 * HEIGHT / img.height; 4.34 var sp0 = 0.003; 4.35 - for (var h = 0; h < c; h++, t++) { 4.36 + for (var h = 0; h < c; h++) { 4.37 gc.setTransform(1, 0, 0, 1, 0, 0); 4.38 var yh = h / (c - 1); 4.39 gc.translate((0.5 + Math.sin(t * sp0 + h * 0.1) / 3) * WIDTH, 25 + (HEIGHT * 3 / 4 - 40) * (yh * yh)); 4.40 @@ -69,15 +59,26 @@ 4.41 gc.rotate(90 * Math.sin(t * sp0 + h * 0.1 + Math.PI)); 4.42 gc.scale(sc, sc); 4.43 gc.drawImage(img, -img.width / 2, -img.height / 2); 4.44 - } 4.45 + } 4.46 gc.setTransform(1, 0, 0, 1, 0, 0); 4.47 isFrameRendered = true; 4.48 } 4.49 var stack = new StackPane(); 4.50 var pane = new BorderPane(); 4.51 - 4.52 pane.setCenter(canvas); 4.53 stack.getChildren().add(pane); 4.54 $STAGE.scene = new Scene(stack); 4.55 -renderFrame(); 4.56 -checkImageAndExit(); 4.57 +var frame = 0; 4.58 +var timer = new AnimationTimerExtend() { 4.59 + handle: function handle(now) { 4.60 + if (frame < 200) { 4.61 + renderFrame(); 4.62 + frame++; 4.63 + } else { 4.64 + checkImageAndExit(); 4.65 + timer.stop(); 4.66 + } 4.67 + } 4.68 +}; 4.69 +timer.start(); 4.70 +
5.1 Binary file test/script/jfx/flyingimage/flyingimage.png has changed
6.1 Binary file test/script/jfx/flyingimage/golden/linux.png has changed
7.1 Binary file test/script/jfx/flyingimage/golden/macosx.png has changed
8.1 Binary file test/script/jfx/flyingimage/golden/windows.png has changed
9.1 --- a/test/script/jfx/kaleidoscope.js Tue Nov 05 09:13:41 2013 +0530 9.2 +++ b/test/script/jfx/kaleidoscope.js Tue Nov 05 13:09:40 2013 +0400 9.3 @@ -30,13 +30,6 @@ 9.4 */ 9.5 9.6 TESTNAME = "kaleidoscope"; 9.7 -WAIT = 4000; 9.8 - 9.9 -var Paint = Java.type("javafx.scene.paint.Paint"); 9.10 -var Canvas = Java.type("javafx.scene.canvas.Canvas"); 9.11 -var BorderPane = Java.type("javafx.scene.layout.BorderPane"); 9.12 -var StackPane = Java.type("javafx.scene.layout.StackPane"); 9.13 -var StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); 9.14 9.15 var WIDTH = 800; 9.16 var HEIGHT = 600; 9.17 @@ -56,26 +49,28 @@ 9.18 var r,e; 9.19 var fade; 9.20 var prv_x,prv_y,prv_x2,prv_y2; 9.21 +var isFrameRendered = false; 9.22 9.23 function renderFrame() { 9.24 - a=0.2*angle; 9.25 - b=0.7*angle; 9.26 - r=0; 9.27 - fade=32; 9.28 - for(var i=0;i<6;i++) 9.29 - { 9.30 - c[i]=1.0/(i+1)/2; 9.31 - d[i]=1.0/(i+1)/2; 9.32 - } 9.33 - radius=Math.round((WIDTH+HEIGHT)/8); 9.34 - e=radius*0.2; 9.35 - p_x=Math.round(WIDTH/2); 9.36 - p_y=Math.round(HEIGHT/2); 9.37 - x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]); 9.38 - y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]); 9.39 - for (i = 0; i < 800; i++) { 9.40 - anim(); 9.41 + if (!isFrameRendered) { 9.42 + a=0.2*angle; 9.43 + b=0.7*angle; 9.44 + r=0; 9.45 + fade=32; 9.46 + for(var i=0;i<6;i++) 9.47 + { 9.48 + c[i]=1.0/(i+1)/2; 9.49 + d[i]=1.0/(i+1)/2; 9.50 + } 9.51 + radius=Math.round((WIDTH+HEIGHT)/8); 9.52 + e=radius*0.2; 9.53 + p_x=Math.round(WIDTH/2); 9.54 + p_y=Math.round(HEIGHT/2); 9.55 + x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]); 9.56 + y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]); 9.57 + isFrameRendered = true; 9.58 } 9.59 + anim(); 9.60 } 9.61 9.62 function anim() { 9.63 @@ -154,9 +149,19 @@ 9.64 9.65 var stack = new StackPane(); 9.66 var pane = new BorderPane(); 9.67 - 9.68 pane.setCenter(canvas); 9.69 stack.getChildren().add(pane); 9.70 $STAGE.scene = new Scene(stack); 9.71 -renderFrame(); 9.72 -checkImageAndExit(); 9.73 \ No newline at end of file 9.74 +var frame = 0; 9.75 +var timer = new AnimationTimerExtend() { 9.76 + handle: function handle(now) { 9.77 + if (frame < 800) { 9.78 + renderFrame(); 9.79 + frame++; 9.80 + } else { 9.81 + checkImageAndExit(); 9.82 + timer.stop(); 9.83 + } 9.84 + } 9.85 +}; 9.86 +timer.start();
10.1 Binary file test/script/jfx/kaleidoscope/golden/linux.png has changed
11.1 Binary file test/script/jfx/kaleidoscope/golden/macosx.png has changed
12.1 Binary file test/script/jfx/kaleidoscope/golden/windows.png has changed
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/test/script/jfx/spread.js Tue Nov 05 13:09:40 2013 +0400 13.3 @@ -0,0 +1,222 @@ 13.4 +/* 13.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.7 + * 13.8 + * This code is free software; you can redistribute it and/or modify it 13.9 + * under the terms of the GNU General Public License version 2 only, as 13.10 + * published by the Free Software Foundation. 13.11 + * 13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13.15 + * version 2 for more details (a copy is included in the LICENSE file that 13.16 + * accompanied this code). 13.17 + * 13.18 + * You should have received a copy of the GNU General Public License version 13.19 + * 2 along with this work; if not, write to the Free Software Foundation, 13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 13.21 + * 13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 13.23 + * or visit www.oracle.com if you need additional information or have any 13.24 + * questions. 13.25 + */ 13.26 + 13.27 +/** 13.28 + * Testing JavaFX canvas run by Nashorn. 13.29 + * 13.30 + * @test/nocompare 13.31 + * @run 13.32 + * @fork 13.33 + */ 13.34 + 13.35 +TESTNAME = "spread"; 13.36 + 13.37 +var WIDTH = 800; 13.38 +var HEIGHT = 600; 13.39 +var canvas = new Canvas(WIDTH, HEIGHT); 13.40 +var context = canvas.graphicsContext2D; 13.41 + 13.42 +/* "Spread" tech demo of canvas by Tom Theisen 13.43 + * 13.44 + * This will animate a sequence of branch structures in a canvas element. 13.45 + * Each frame, a new direction is calculated, similar to the last frame. 13.46 + */ 13.47 + 13.48 +var start_width = 20; // starting width of each branch 13.49 +var frame_time = 30; // milliseconds per frame 13.50 +var straighten_factor = 0.95; // value from 0 to 1, factor applied to direction_offset every frame 13.51 +var curviness = 0.2; // amount of random direction change each frame 13.52 + 13.53 +var color_speed = 0.03; // speed at which colors change when cycling is enabled 13.54 +var branch_shrink = 0.95; // factor by which branches shrink every frame 13.55 +var min_width = 1; // minimum WIDTH for branch, after which they are discontinued 13.56 +var branch_opacity = 0.4; // opacity of lines drawn 13.57 +var branch_count = 3; // branch count per tree 13.58 +var branch_bud_size = 0.5; // ratio of original branch size at which branch will split 13.59 +var branch_bud_angle = 1; // angle offset for split branch; 13.60 + 13.61 +var paper; // reference to graphics context 13.62 +var branches = Object(); // linked list of active branches 13.63 +var color_styles = []; // pre-computed list of colors as styles. format: (r,g,b,a) 13.64 +var direction_offset = 0; // current direction offset in radians. this is applied to all branches. 13.65 +var frame = 0; // frame counter 13.66 +var timespent = 0; // total time spent so far, used to calculate average frame render duration 13.67 +var frameratespan; // html span element for updating performance number 13.68 + 13.69 +// preferences object, contains an attribute for each user setting 13.70 +var prefs = { 13.71 + wrap: true, // causes branches reaching edge of viewable area to appear on opposite side 13.72 + fade: false, // fade existing graphics on each frame 13.73 + cycle: true, // gradually change colors each frame 13.74 + new_branch_frames: 20 // number of frames elapsed between each auto-generated tree 13.75 +}; 13.76 + 13.77 +// create tree at the specified position with number of branches 13.78 +function create_tree(branches, start_width, position, branch_count) { 13.79 + var angle_offset = Math.PI * 2 / branch_count; 13.80 + for (var i = 0; i < branch_count; ++i) { 13.81 + branch_add(branches, new Branch(position, angle_offset * i, start_width)); 13.82 + } 13.83 +} 13.84 + 13.85 +// add branch to collection 13.86 +function branch_add(branches, branch) { 13.87 + branch.next = branches.next; 13.88 + branches.next = branch; 13.89 +} 13.90 + 13.91 +// get the coordinates for the position of a new tree 13.92 +// use the center of the canvas 13.93 +function get_new_tree_center(width, height) { 13.94 + return { 13.95 + x: 0.5 * width, 13.96 + y: 0.5 * height 13.97 + }; 13.98 +} 13.99 + 13.100 +// Branch constructor 13.101 +// position has x and y properties 13.102 +// direction is in radians 13.103 +function Branch(position, direction, width) { 13.104 + this.x = position.x; 13.105 + this.y = position.y; 13.106 + this.width = width; 13.107 + this.original_width = width; 13.108 + this.direction = direction; 13.109 +} 13.110 + 13.111 +// update position, direction and width of a particular branch 13.112 +function branch_update(branches, branch, paper) { 13.113 + paper.beginPath(); 13.114 + paper.lineWidth = branch.width; 13.115 + paper.moveTo(branch.x, branch.y); 13.116 + 13.117 + branch.width *= branch_shrink; 13.118 + branch.direction += direction_offset; 13.119 + branch.x += Math.cos(branch.direction) * branch.width; 13.120 + branch.y += Math.sin(branch.direction) * branch.width; 13.121 + 13.122 + paper.lineTo(branch.x, branch.y); 13.123 + paper.stroke(); 13.124 + 13.125 + if (prefs.wrap) wrap_branch(branch, WIDTH, HEIGHT); 13.126 + 13.127 + if (branch.width < branch.original_width * branch_bud_size) { 13.128 + branch.original_width *= branch_bud_size; 13.129 + branch_add(branches, new Branch(branch, branch.direction + 1, branch.original_width)); 13.130 + } 13.131 +} 13.132 + 13.133 +function draw_frame() { 13.134 + if (prefs.fade) { 13.135 + paper.fillRect(0, 0, WIDTH, HEIGHT); 13.136 + } 13.137 + 13.138 + if (prefs.cycle) { 13.139 + paper.setStroke(Paint.valueOf(color_styles[frame % color_styles.length])); 13.140 + } 13.141 + 13.142 + if (frame++ % prefs.new_branch_frames == 0) { 13.143 + create_tree(branches, start_width, get_new_tree_center(WIDTH, HEIGHT), branch_count); 13.144 + } 13.145 + 13.146 + direction_offset += (0.35 + (frame % 200) * 0.0015) * curviness - curviness / 2; 13.147 + direction_offset *= straighten_factor; 13.148 + 13.149 + var branch = branches; 13.150 + var prev_branch = branches; 13.151 + while (branch = branch.next) { 13.152 + branch_update(branches, branch, paper); 13.153 + 13.154 + if (branch.width < min_width) { 13.155 + // remove branch from list 13.156 + prev_branch.next = branch.next; 13.157 + } 13.158 + 13.159 + prev_branch = branch; 13.160 + } 13.161 +} 13.162 + 13.163 +// constrain branch position to visible area by "wrapping" from edge to edge 13.164 +function wrap_branch(branch, WIDTH, HEIGHT) { 13.165 + branch.x = positive_mod(branch.x, WIDTH); 13.166 + branch.y = positive_mod(branch.y, HEIGHT); 13.167 +} 13.168 + 13.169 +// for a < 0, b > 0, javascript returns a negative number for a % b 13.170 +// this is a variant of the % operator that adds b to the result in this case 13.171 +function positive_mod(a, b) { 13.172 + // ECMA 262 11.5.3: Applying the % Operator 13.173 + // remainder operator does not convert operands to integers, 13.174 + // although negative results are possible 13.175 + 13.176 + return ((a % b) + b) % b; 13.177 +} 13.178 + 13.179 +// pre-compute color styles that will be used for color cycling 13.180 +function populate_colors(color_speed, color_styles, branch_opacity) { 13.181 + // used in calculation of RGB values 13.182 + var two_thirds_pi = Math.PI * 2 / 3; 13.183 + var four_thirds_pi = Math.PI * 4 / 3; 13.184 + var two_pi = Math.PI * 2; 13.185 + 13.186 + // hue does represent hue, but not in the conventional HSL scheme 13.187 + for(var hue = 0; hue < two_pi; hue += color_speed) { 13.188 + var r = Math.floor(Math.sin(hue) * 128 + 128); 13.189 + var g = Math.floor(Math.sin(hue + two_thirds_pi) * 128 + 128); 13.190 + var b = Math.floor(Math.sin(hue + four_thirds_pi) * 128 + 128); 13.191 + color = "rgba(" + [r, g, b, branch_opacity].join() + ")"; 13.192 + 13.193 + color_styles.push(color); 13.194 + } 13.195 +} 13.196 + 13.197 +// apply initial settings to canvas object 13.198 +function setup_canvas() { 13.199 + paper = canvas.graphicsContext2D; 13.200 + paper.setFill(Paint.valueOf('rgb(0, 0, 0)')); 13.201 + paper.fillRect(0, 0, WIDTH, HEIGHT); 13.202 + paper.setFill(Paint.valueOf("rgba(0, 0, 0, 0.005)")); 13.203 + paper.setStroke(Paint.valueOf("rgba(128, 128, 64, " + String(branch_opacity) + ")")); 13.204 +} 13.205 + 13.206 +populate_colors(color_speed, color_styles, branch_opacity); 13.207 +setup_canvas(); 13.208 + 13.209 +var stack = new StackPane(); 13.210 +var pane = new BorderPane(); 13.211 +pane.setCenter(canvas); 13.212 +stack.getChildren().add(pane); 13.213 +$STAGE.scene = new Scene(stack); 13.214 +var timer = new AnimationTimerExtend() { 13.215 + handle: function handle(now) { 13.216 + if (frame < 200) { 13.217 + draw_frame(); 13.218 + } else { 13.219 + checkImageAndExit(); 13.220 + timer.stop(); 13.221 + } 13.222 + } 13.223 +}; 13.224 +timer.start(); 13.225 +
14.1 Binary file test/script/jfx/spread/golden/linux.png has changed
15.1 Binary file test/script/jfx/spread/golden/macosx.png has changed
16.1 Binary file test/script/jfx/spread/golden/windows.png has changed