8027708: NASHORN TEST: Create Nashorn test that draws image step-by-step using JavaFX canvas.

Tue, 05 Nov 2013 13:09:40 +0400

author
kshefov
date
Tue, 05 Nov 2013 13:09:40 +0400
changeset 667
bda654c6d59c
parent 666
b0d4ef6fb2db
child 669
3b794f364c77

8027708: NASHORN TEST: Create Nashorn test that draws image step-by-step using JavaFX canvas.
Reviewed-by: jlaskey, lagergren

make/build.xml file | annotate | diff | comparison | revisions
make/project.properties file | annotate | diff | comparison | revisions
test/script/jfx.js file | annotate | diff | comparison | revisions
test/script/jfx/flyingimage.js file | annotate | diff | comparison | revisions
test/script/jfx/flyingimage/flyingimage.png file | annotate | diff | comparison | revisions
test/script/jfx/flyingimage/golden/linux.png file | annotate | diff | comparison | revisions
test/script/jfx/flyingimage/golden/macosx.png file | annotate | diff | comparison | revisions
test/script/jfx/flyingimage/golden/windows.png file | annotate | diff | comparison | revisions
test/script/jfx/kaleidoscope.js file | annotate | diff | comparison | revisions
test/script/jfx/kaleidoscope/golden/linux.png file | annotate | diff | comparison | revisions
test/script/jfx/kaleidoscope/golden/macosx.png file | annotate | diff | comparison | revisions
test/script/jfx/kaleidoscope/golden/windows.png file | annotate | diff | comparison | revisions
test/script/jfx/spread.js file | annotate | diff | comparison | revisions
test/script/jfx/spread/golden/linux.png file | annotate | diff | comparison | revisions
test/script/jfx/spread/golden/macosx.png file | annotate | diff | comparison | revisions
test/script/jfx/spread/golden/windows.png file | annotate | diff | comparison | revisions
     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

mercurial