1 /* 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene; 27 28 import java.util.ArrayList; 29 import java.util.Collection; 30 import javafx.geometry.Rectangle2D; 31 import javafx.scene.image.WritableImage; 32 import javafx.scene.shape.Rectangle; 33 import javafx.scene.transform.Transform; 34 import javafx.util.Callback; 35 import org.junit.After; 36 import org.junit.AfterClass; 37 import org.junit.Before; 38 import org.junit.BeforeClass; 39 import org.junit.Ignore; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 import org.junit.runners.Parameterized; 43 import org.junit.runners.Parameterized.Parameters; 44 import util.Util; 45 46 import static org.junit.Assert.*; 47 48 /** 49 * Test program for showAndWait functionality. 50 */ 51 @RunWith(Parameterized.class) 52 public class Snapshot2Test extends SnapshotCommon { 53 54 @BeforeClass 55 public static void setupOnce() { 56 doSetupOnce(); 57 } 58 59 @AfterClass 60 public static void teardownOnce() { 61 doTeardownOnce(); 62 } 63 64 // Flag indicating snapshot should be taken on a live scene, that is a 65 // scene attached to the primary stage 66 private final boolean live; 67 68 // Flag indicating to use an existing image 69 private final boolean useImage; 70 71 // Temporary stage, scene, and node used for testing 72 private TestStage tmpStage = null; 73 private Scene tmpScene = null; 74 private Node tmpNode = null; 75 76 private static Collection params = null; 77 78 private static final Object[] pLive = { Boolean.FALSE, Boolean.TRUE }; 79 private static final Object[] pUseImage = { Boolean.FALSE, Boolean.TRUE }; 80 81 @Parameters 82 public static Collection getParams() { 83 if (params == null) { 84 params = new ArrayList(); 85 for (Object o0 : pLive) { 86 for (Object o1 : pUseImage) { 87 params.add(new Object[] { o0, o1 }); 88 } 89 } 90 } 91 return params; 92 } 93 94 public Snapshot2Test(Boolean live, Boolean useImage) { 95 this.live = live; 96 this.useImage = useImage; 97 } 98 99 @Before 100 public void setupEach() { 101 assertNotNull(myApp); 102 assertNotNull(myApp.primaryStage); 103 assertTrue(myApp.primaryStage.isShowing()); 104 } 105 106 @After 107 public void teardownEach() { 108 Util.runAndWait(() -> { 109 if (tmpStage != null && tmpStage.isShowing()) { 110 tmpStage.hide(); 111 } 112 }); 113 } 114 115 // ========================== TEST CASES ========================== 116 117 private void setupEmptyScene() { 118 Util.runAndWait(() -> { 119 Group root = new Group(); 120 tmpScene = new Scene(root); 121 if (live) { 122 tmpStage = new TestStage(tmpScene); 123 assertNotNull(tmpScene.getWindow()); 124 tmpStage.show(); 125 } else { 126 assertNull(tmpScene.getWindow()); 127 } 128 }); 129 } 130 131 // Verify a snapshot of an empty scene / root node 132 @Test 133 public void testSnapshotEmptySceneImm() { 134 setupEmptyScene(); 135 136 final WritableImage img = useImage ? new WritableImage(1, 1) : null; 137 Util.runAndWait(() -> { 138 WritableImage wimg = tmpScene.snapshot(img); 139 assertNotNull(wimg); 140 if (img != null) { 141 assertSame(img, wimg); 142 } 143 144 assertEquals(1, (int)wimg.getWidth()); 145 assertEquals(1, (int)wimg.getHeight()); 146 }); 147 } 148 149 @Test 150 public void testSnapshotEmptySceneDefer() { 151 setupEmptyScene(); 152 final WritableImage img = useImage ? new WritableImage(1, 1) : null; 153 runDeferredSnapshotWait(tmpScene, result -> { 154 assertSame(tmpScene, result.getSource()); 155 assertNull(result.getSnapshotParameters()); 156 assertNotNull(result.getImage()); 157 if (img != null) { 158 assertSame(img, result.getImage()); 159 } 160 161 assertEquals(1, (int)result.getImage().getWidth()); 162 assertEquals(1, (int)result.getImage().getHeight()); 163 164 return null; 165 }, img); 166 } 167 168 private void doTestSnapshotEmptyNodeImm(final SnapshotParameters snapshotParams) { 169 setupEmptyScene(); 170 final WritableImage img = useImage ? new WritableImage(1, 1) : null; 171 Util.runAndWait(() -> { 172 WritableImage wimg = tmpScene.getRoot().snapshot(snapshotParams, img); 173 assertNotNull(wimg); 174 if (img != null) { 175 assertSame(img, wimg); 176 } 177 178 assertEquals(1, (int)wimg.getWidth()); 179 assertEquals(1, (int)wimg.getHeight()); 180 }); 181 } 182 183 @Test 184 public void testSnapshotEmptyNodeImmNoParams() { 185 doTestSnapshotEmptyNodeDefer(null); 186 } 187 188 @Test 189 public void testSnapshotEmptyNodeImm() { 190 doTestSnapshotEmptyNodeDefer(new SnapshotParameters()); 191 } 192 193 private void doTestSnapshotEmptyNodeDefer(final SnapshotParameters snapshotParams) { 194 setupEmptyScene(); 195 final WritableImage img = useImage ? new WritableImage(1, 1) : null; 196 runDeferredSnapshotWait(tmpScene.getRoot(), result -> { 197 assertSame(tmpScene.getRoot(), result.getSource()); 198 assertNotNull(result.getSnapshotParameters()); 199 assertNotNull(result.getImage()); 200 if (img != null) { 201 assertSame(img, result.getImage()); 202 } 203 204 assertEquals(1, (int)result.getImage().getWidth()); 205 assertEquals(1, (int)result.getImage().getHeight()); 206 207 return null; 208 }, snapshotParams, img); 209 } 210 211 @Test 212 public void testSnapshotEmptyNodeDeferNoParams() { 213 doTestSnapshotEmptyNodeImm(null); 214 } 215 216 @Test 217 public void testSnapshotEmptyNodeDefer() { 218 doTestSnapshotEmptyNodeImm(new SnapshotParameters()); 219 } 220 221 private static final int SCENE_W = 200; 222 private static final int SCENE_H = 100; 223 private static final int NODE_W = SCENE_W - 2*10; 224 private static final int NODE_H = SCENE_H - 2*5; 225 226 private void setupSimpleScene() { 227 Util.runAndWait(() -> { 228 tmpNode = new Rectangle(10, 5, NODE_W, NODE_H); 229 Group root = new Group(); 230 tmpScene = new Scene(root, SCENE_W, SCENE_H); 231 root.getChildren().add(tmpNode); 232 if (live) { 233 tmpStage = new TestStage(tmpScene); 234 assertNotNull(tmpScene.getWindow()); 235 tmpStage.show(); 236 } else { 237 assertNull(tmpScene.getWindow()); 238 } 239 }); 240 } 241 242 // Test snapshot of a simple scene 243 244 @Test 245 public void testSnapshotSimpleSceneImm() { 246 setupSimpleScene(); 247 248 final WritableImage img = useImage ? new WritableImage(SCENE_W, SCENE_H) : null; 249 Util.runAndWait(() -> { 250 WritableImage wimg = tmpScene.snapshot(img); 251 assertNotNull(wimg); 252 if (img != null) { 253 assertSame(img, wimg); 254 } 255 256 assertEquals(SCENE_W, (int)wimg.getWidth()); 257 assertEquals(SCENE_H, (int)wimg.getHeight()); 258 }); 259 } 260 261 @Test 262 public void testSnapshotSimpleSceneDefer() { 263 setupSimpleScene(); 264 265 final WritableImage img = useImage ? new WritableImage(SCENE_W, SCENE_H) : null; 266 runDeferredSnapshotWait(tmpScene, result -> { 267 assertSame(tmpScene, result.getSource()); 268 assertNull(result.getSnapshotParameters()); 269 assertNotNull(result.getImage()); 270 if (img != null) { 271 assertSame(img, result.getImage()); 272 } 273 274 assertEquals(SCENE_W, (int)result.getImage().getWidth()); 275 assertEquals(SCENE_H, (int)result.getImage().getHeight()); 276 277 return null; 278 }, img); 279 } 280 281 @Test 282 public void testSnapshotSimpleNodeImm() { 283 setupSimpleScene(); 284 final SnapshotParameters snapshotParams = new SnapshotParameters(); 285 final WritableImage img = useImage ? new WritableImage(NODE_W, NODE_H) : null; 286 Util.runAndWait(() -> { 287 WritableImage wimg = tmpScene.getRoot().snapshot(snapshotParams, img); 288 assertNotNull(wimg); 289 if (img != null) { 290 assertSame(img, wimg); 291 } 292 293 assertEquals(NODE_W, (int)wimg.getWidth()); 294 assertEquals(NODE_H, (int)wimg.getHeight()); 295 }); 296 } 297 298 @Test 299 public void testSnapshotSimpleNodeDefer() { 300 setupSimpleScene(); 301 final SnapshotParameters snapshotParams = new SnapshotParameters(); 302 final WritableImage img = useImage ? new WritableImage(NODE_W, NODE_H) : null; 303 runDeferredSnapshotWait(tmpScene.getRoot(), result -> { 304 assertSame(tmpScene.getRoot(), result.getSource()); 305 assertNotNull(result.getSnapshotParameters()); 306 assertNotNull(result.getImage()); 307 if (img != null) { 308 assertSame(img, result.getImage()); 309 } 310 311 assertEquals(NODE_W, (int)result.getImage().getWidth()); 312 assertEquals(NODE_H, (int)result.getImage().getHeight()); 313 314 return null; 315 }, snapshotParams, img); 316 } 317 318 // Test node snapshot with a scale transform 319 320 private void doTestSnapshotScaleNodeImm(int xScale, int yScale) { 321 setupSimpleScene(); 322 final SnapshotParameters snapshotParams = new SnapshotParameters(); 323 snapshotParams.setTransform(Transform.scale(xScale, yScale)); 324 final int WIDTH = NODE_W * xScale; 325 final int HEIGHT = NODE_H * yScale; 326 final WritableImage img = useImage ? new WritableImage(WIDTH, HEIGHT) : null; 327 Util.runAndWait(() -> { 328 WritableImage wimg = tmpScene.getRoot().snapshot(snapshotParams, img); 329 assertNotNull(wimg); 330 if (img != null) { 331 assertSame(img, wimg); 332 } 333 334 assertEquals(WIDTH, (int)wimg.getWidth()); 335 assertEquals(HEIGHT, (int)wimg.getHeight()); 336 }); 337 } 338 339 private void doTestSnapshotScaleNodeDefer(int xScale, int yScale) { 340 setupSimpleScene(); 341 final SnapshotParameters snapshotParams = new SnapshotParameters(); 342 snapshotParams.setTransform(Transform.scale(xScale, yScale)); 343 final int WIDTH = NODE_W * xScale; 344 final int HEIGHT = NODE_H * yScale; 345 final WritableImage img = useImage ? new WritableImage(WIDTH, HEIGHT) : null; 346 runDeferredSnapshotWait(tmpScene.getRoot(), result -> { 347 assertSame(tmpScene.getRoot(), result.getSource()); 348 assertNotNull(result.getSnapshotParameters()); 349 assertNotNull(result.getImage()); 350 if (img != null) { 351 assertSame(img, result.getImage()); 352 } 353 354 assertEquals(WIDTH, (int)result.getImage().getWidth()); 355 assertEquals(HEIGHT, (int)result.getImage().getHeight()); 356 357 return null; 358 }, snapshotParams, img); 359 } 360 361 @Test 362 public void testSnapshotScaleNodeImm() { 363 doTestSnapshotScaleNodeImm(3, 3); 364 } 365 366 @Test 367 public void testSnapshotScaleNodeDefer() { 368 doTestSnapshotScaleNodeDefer(3, 3); 369 } 370 371 // TODO: Re-enable this test when RT-22073 is fixed 372 @Ignore @Test 373 public void testSnapshotBigXScaleNodeImm() { 374 doTestSnapshotScaleNodeImm(100, 1); 375 } 376 377 // TODO: Re-enable this test when RT-22073 is fixed 378 @Ignore @Test 379 public void testSnapshotBigXScaleNodeDefer() { 380 doTestSnapshotScaleNodeDefer(100, 1); 381 } 382 383 // TODO: Re-enable this test when RT-22073 is fixed 384 @Ignore @Test 385 public void testSnapshotBigYScaleNodeImm() { 386 doTestSnapshotScaleNodeImm(1, 200); 387 } 388 389 // TODO: Re-enable this test when RT-22073 is fixed 390 @Ignore @Test 391 public void testSnapshotBigYScaleNodeDefer() { 392 doTestSnapshotScaleNodeDefer(1, 200); 393 } 394 395 // Test node snapshot with a 90 degree rotate transform 396 397 @Test 398 public void testSnapshotRotateNodeImm() { 399 setupSimpleScene(); 400 final SnapshotParameters snapshotParams = new SnapshotParameters(); 401 // Rotate by 90 degrees, which will swap width and height 402 snapshotParams.setTransform(Transform.rotate(90, 0, 0)); 403 final int WIDTH = NODE_H; 404 final int HEIGHT = NODE_W; 405 final WritableImage img = useImage ? new WritableImage(WIDTH, HEIGHT) : null; 406 Util.runAndWait(() -> { 407 WritableImage wimg = tmpScene.getRoot().snapshot(snapshotParams, img); 408 assertNotNull(wimg); 409 if (img != null) { 410 assertSame(img, wimg); 411 } 412 413 assertEquals(WIDTH, (int)wimg.getWidth()); 414 assertEquals(HEIGHT, (int)wimg.getHeight()); 415 }); 416 } 417 418 @Test 419 public void testSnapshotRotateNodeDefer() { 420 setupSimpleScene(); 421 final SnapshotParameters snapshotParams = new SnapshotParameters(); 422 // Rotate by 90 degrees, which will swap width and height 423 snapshotParams.setTransform(Transform.rotate(90, 0, 0)); 424 final int WIDTH = NODE_H; 425 final int HEIGHT = NODE_W; 426 final WritableImage img = useImage ? new WritableImage(WIDTH, HEIGHT) : null; 427 runDeferredSnapshotWait(tmpScene.getRoot(), result -> { 428 assertSame(tmpScene.getRoot(), result.getSource()); 429 assertNotNull(result.getSnapshotParameters()); 430 assertNotNull(result.getImage()); 431 if (img != null) { 432 assertSame(img, result.getImage()); 433 } 434 435 assertEquals(WIDTH, (int)result.getImage().getWidth()); 436 assertEquals(HEIGHT, (int)result.getImage().getHeight()); 437 438 return null; 439 }, snapshotParams, img); 440 } 441 442 // Test viewport 443 private static final int VP_X = 105; 444 private static final int VP_Y = 20; 445 private static final int VP_WIDTH = 160; 446 private static final int VP_HEIGHT = 100; 447 448 @Test 449 public void testSnapshotViewportNodeImm() { 450 setupSimpleScene(); 451 final SnapshotParameters snapshotParams = new SnapshotParameters(); 452 snapshotParams.setViewport(new Rectangle2D(VP_X, VP_Y, VP_WIDTH, VP_HEIGHT)); 453 final WritableImage img = useImage ? new WritableImage(NODE_W, NODE_H) : null; 454 final int WIDTH = useImage ? NODE_W : VP_WIDTH; 455 final int HEIGHT = useImage ? NODE_H : VP_HEIGHT; 456 Util.runAndWait(() -> { 457 WritableImage wimg = tmpScene.getRoot().snapshot(snapshotParams, img); 458 assertNotNull(wimg); 459 if (img != null) { 460 assertSame(img, wimg); 461 } 462 463 assertEquals(WIDTH, (int)wimg.getWidth()); 464 assertEquals(HEIGHT, (int)wimg.getHeight()); 465 }); 466 } 467 468 @Test 469 public void testSnapshotViewportNodeDefer() { 470 setupSimpleScene(); 471 final SnapshotParameters snapshotParams = new SnapshotParameters(); 472 snapshotParams.setViewport(new Rectangle2D(VP_X, VP_Y, VP_WIDTH, VP_HEIGHT)); 473 final WritableImage img = useImage ? new WritableImage(NODE_W, NODE_H) : null; 474 final int WIDTH = useImage ? NODE_W : VP_WIDTH; 475 final int HEIGHT = useImage ? NODE_H : VP_HEIGHT; 476 runDeferredSnapshotWait(tmpScene.getRoot(), result -> { 477 assertSame(tmpScene.getRoot(), result.getSource()); 478 assertNotNull(result.getSnapshotParameters()); 479 assertNotNull(result.getImage()); 480 if (img != null) { 481 assertSame(img, result.getImage()); 482 } 483 484 assertEquals(WIDTH, (int)result.getImage().getWidth()); 485 assertEquals(HEIGHT, (int)result.getImage().getHeight()); 486 487 return null; 488 }, snapshotParams, img); 489 } 490 491 // Test updating the node after the call to a deferred snapshot, in 492 // the same runLater call. Verify that the change to the node is 493 // reflected in the result 494 495 private static final int NEW_WIDTH = 70; 496 private static final int NEW_HEIGHT = 35; 497 498 @Test 499 public void testSnapshotUpdateNodeDefer() { 500 setupSimpleScene(); 501 final SnapshotParameters snapshotParams = new SnapshotParameters(); 502 final WritableImage img = useImage ? new WritableImage(NODE_W, NODE_H) : null; 503 final int WIDTH = useImage ? NODE_W : NEW_WIDTH; 504 final int HEIGHT = useImage ? NODE_H : NEW_HEIGHT; 505 Callback<SnapshotResult, Void> cb = result -> { 506 assertSame(tmpScene.getRoot(), result.getSource()); 507 assertNotNull(result.getSnapshotParameters()); 508 assertNotNull(result.getImage()); 509 if (img != null) { 510 assertSame(img, result.getImage()); 511 } 512 513 assertEquals(WIDTH, (int)result.getImage().getWidth()); 514 assertEquals(HEIGHT, (int)result.getImage().getHeight()); 515 516 return null; 517 }; 518 Runnable runAfter = () -> { 519 assertTrue(tmpNode instanceof Rectangle); 520 Rectangle rect = (Rectangle)tmpNode; 521 rect.setWidth(NEW_WIDTH); 522 rect.setHeight(NEW_HEIGHT); 523 }; 524 525 runDeferredSnapshotWait(tmpScene.getRoot(), cb, snapshotParams, img, runAfter); 526 } 527 528 }