1 /* 2 * Copyright (c) 2013, 2015, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.awt.Color; 25 import java.awt.Graphics; 26 import java.awt.Graphics2D; 27 import java.awt.Image; 28 import java.awt.Toolkit; 29 import java.awt.image.BufferedImage; 30 import java.io.File; 31 import java.lang.reflect.Method; 32 import java.net.URL; 33 import javax.imageio.ImageIO; 34 import sun.awt.OSInfo; 35 import sun.awt.SunHints; 36 import java.awt.MediaTracker; 37 import java.awt.geom.AffineTransform; 38 import java.awt.image.ImageObserver; 39 import java.util.Arrays; 40 import java.util.List; 41 import javax.swing.JPanel; 42 import sun.awt.SunToolkit; 43 import sun.awt.image.MultiResolutionImage; 44 45 /** 46 * @test 47 * @bug 8011059 48 * @author Alexander Scherbatiy 49 * @summary [macosx] Make JDK demos look perfect on retina displays 50 * @requires (os.family == "mac") 51 * @modules java.desktop/sun.awt 52 * java.desktop/sun.awt.image 53 * java.desktop/sun.lwawt.macosx 54 * @run main MultiResolutionImageTest CUSTOM 55 * @run main MultiResolutionImageTest TOOLKIT_PREPARE 56 * @run main MultiResolutionImageTest TOOLKIT_LOAD 57 * @run main MultiResolutionImageTest TOOLKIT 58 */ 59 public class MultiResolutionImageTest { 60 61 private static final int IMAGE_WIDTH = 300; 62 private static final int IMAGE_HEIGHT = 200; 63 private static final Color COLOR_1X = Color.GREEN; 64 private static final Color COLOR_2X = Color.BLUE; 65 private static final String IMAGE_NAME_1X = "image.png"; 66 private static final String IMAGE_NAME_2X = "image@2x.png"; 67 68 public static void main(String[] args) throws Exception { 69 70 System.out.println("args: " + args.length); 71 72 if (args.length == 0) { 73 throw new RuntimeException("Not found a test"); 74 } 75 76 String test = args[0]; 77 78 System.out.println("TEST: " + test); 79 System.out.println("CHECK OS: " + checkOS()); 80 81 if ("CUSTOM".equals(test)) { 82 testCustomMultiResolutionImage(); 83 } else if (checkOS()) { 84 switch (test) { 85 case "CUSTOM": 86 break; 87 case "TOOLKIT_PREPARE": 88 testToolkitMultiResolutionImagePrepare(); 89 break; 90 case "TOOLKIT_LOAD": 91 testToolkitMultiResolutionImageLoad(); 92 break; 93 case "TOOLKIT": 94 testToolkitMultiResolutionImage(); 95 testImageNameTo2xParsing(); 96 break; 97 default: 98 throw new RuntimeException("Unknown test: " + test); 99 } 100 } 101 } 102 103 static boolean checkOS() { 104 return OSInfo.getOSType() == OSInfo.OSType.MACOSX; 105 } 106 107 public static void testCustomMultiResolutionImage() { 108 testCustomMultiResolutionImage(false); 109 testCustomMultiResolutionImage(true); 110 } 111 112 public static void testCustomMultiResolutionImage(boolean enableImageScaling) { 113 114 Image image = new MultiResolutionBufferedImage(); 115 116 // Same image size 117 BufferedImage bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, 118 BufferedImage.TYPE_INT_RGB); 119 Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics(); 120 setImageScalingHint(g2d, enableImageScaling); 121 g2d.drawImage(image, 0, 0, null); 122 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false); 123 124 // Twice image size 125 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 126 BufferedImage.TYPE_INT_RGB); 127 g2d = (Graphics2D) bufferedImage.getGraphics(); 128 setImageScalingHint(g2d, enableImageScaling); 129 g2d.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null); 130 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 131 132 // Scale 2x 133 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 134 g2d = (Graphics2D) bufferedImage.getGraphics(); 135 setImageScalingHint(g2d, enableImageScaling); 136 g2d.scale(2, 2); 137 g2d.drawImage(image, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null); 138 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 139 140 // Rotate 141 bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, 142 BufferedImage.TYPE_INT_RGB); 143 g2d = (Graphics2D) bufferedImage.getGraphics(); 144 setImageScalingHint(g2d, enableImageScaling); 145 g2d.drawImage(image, 0, 0, null); 146 g2d.rotate(Math.PI / 4); 147 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false); 148 149 // Scale 2x and Rotate 150 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 151 g2d = (Graphics2D) bufferedImage.getGraphics(); 152 setImageScalingHint(g2d, enableImageScaling); 153 g2d.scale(-2, 2); 154 g2d.rotate(-Math.PI / 10); 155 g2d.drawImage(image, -IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null); 156 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 157 158 // General Transform 159 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 160 g2d = (Graphics2D) bufferedImage.getGraphics(); 161 setImageScalingHint(g2d, enableImageScaling); 162 float delta = 0.05f; 163 float cos = 1 - delta * delta / 2; 164 float sin = 1 + delta; 165 AffineTransform transform = new AffineTransform(2 * cos, 0.1, 0.3, -2 * sin, 10, -5); 166 g2d.setTransform(transform); 167 g2d.drawImage(image, 0, -IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, null); 168 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 169 170 int D = 10; 171 // From Source to small Destination region 172 bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 173 g2d = (Graphics2D) bufferedImage.getGraphics(); 174 setImageScalingHint(g2d, enableImageScaling); 175 g2d.drawImage(image, IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, 176 D, D, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, null); 177 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false); 178 179 // From Source to large Destination region 180 bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 181 g2d = (Graphics2D) bufferedImage.getGraphics(); 182 setImageScalingHint(g2d, enableImageScaling); 183 g2d.drawImage(image, D, D, 2 * IMAGE_WIDTH - D, 2 * IMAGE_HEIGHT - D, 184 IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, null); 185 checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 186 } 187 188 static class MultiResolutionBufferedImage extends BufferedImage 189 implements MultiResolutionImage { 190 191 Image highResolutionImage; 192 193 public MultiResolutionBufferedImage() { 194 super(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 195 highResolutionImage = new BufferedImage( 196 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 197 draw(getGraphics(), 1); 198 draw(highResolutionImage.getGraphics(), 2); 199 } 200 201 void draw(Graphics graphics, float resolution) { 202 Graphics2D g2 = (Graphics2D) graphics; 203 g2.scale(resolution, resolution); 204 g2.setColor((resolution == 1) ? COLOR_1X : COLOR_2X); 205 g2.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); 206 } 207 208 @Override 209 public Image getResolutionVariant(int width, int height) { 210 return ((width <= getWidth() && height <= getHeight())) 211 ? this : highResolutionImage; 212 } 213 214 @Override 215 public List<Image> getResolutionVariants() { 216 return Arrays.asList(this, highResolutionImage); 217 } 218 } 219 220 static void testToolkitMultiResolutionImagePrepare() throws Exception { 221 222 generateImages(); 223 224 File imageFile = new File(IMAGE_NAME_1X); 225 String fileName = imageFile.getAbsolutePath(); 226 227 Image image = Toolkit.getDefaultToolkit().getImage(fileName); 228 229 SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); 230 toolkit.prepareImage(image, IMAGE_WIDTH, IMAGE_HEIGHT, new LoadImageObserver(image)); 231 232 testToolkitMultiResolutionImageLoad(image); 233 } 234 235 static void testToolkitMultiResolutionImageLoad() throws Exception { 236 237 generateImages(); 238 239 File imageFile = new File(IMAGE_NAME_1X); 240 String fileName = imageFile.getAbsolutePath(); 241 Image image = Toolkit.getDefaultToolkit().getImage(fileName); 242 testToolkitMultiResolutionImageLoad(image); 243 } 244 245 static void testToolkitMultiResolutionImageLoad(Image image) throws Exception { 246 247 MediaTracker tracker = new MediaTracker(new JPanel()); 248 tracker.addImage(image, 0); 249 tracker.waitForID(0); 250 if (tracker.isErrorAny()) { 251 throw new RuntimeException("Error during image loading"); 252 } 253 tracker.removeImage(image, 0); 254 255 testImageLoaded(image); 256 257 int w = image.getWidth(null); 258 int h = image.getHeight(null); 259 260 Image resolutionVariant = ((MultiResolutionImage) image) 261 .getResolutionVariant(2 * w, 2 * h); 262 263 if (image == resolutionVariant) { 264 throw new RuntimeException("Resolution variant is not loaded"); 265 } 266 267 testImageLoaded(resolutionVariant); 268 } 269 270 static void testImageLoaded(Image image) { 271 272 SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); 273 274 int flags = toolkit.checkImage(image, IMAGE_WIDTH, IMAGE_WIDTH, new SilentImageObserver()); 275 if ((flags & (ImageObserver.FRAMEBITS | ImageObserver.ALLBITS)) == 0) { 276 throw new RuntimeException("Image is not loaded!"); 277 } 278 } 279 280 static class SilentImageObserver implements ImageObserver { 281 282 @Override 283 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 284 throw new RuntimeException("Observer should not be called!"); 285 } 286 } 287 288 static class LoadImageObserver implements ImageObserver { 289 290 Image image; 291 292 public LoadImageObserver(Image image) { 293 this.image = image; 294 } 295 296 @Override 297 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 298 299 if (image != img) { 300 throw new RuntimeException("Original image is not passed to the observer"); 301 } 302 303 if ((infoflags & ImageObserver.WIDTH) != 0) { 304 if (width != IMAGE_WIDTH) { 305 throw new RuntimeException("Original width is not passed to the observer"); 306 } 307 } 308 309 if ((infoflags & ImageObserver.HEIGHT) != 0) { 310 if (height != IMAGE_HEIGHT) { 311 throw new RuntimeException("Original height is not passed to the observer"); 312 } 313 } 314 315 return (infoflags & ALLBITS) == 0; 316 } 317 318 } 319 320 static void testToolkitMultiResolutionImage() throws Exception { 321 322 generateImages(); 323 324 File imageFile = new File(IMAGE_NAME_1X); 325 String fileName = imageFile.getAbsolutePath(); 326 URL url = imageFile.toURI().toURL(); 327 testToolkitMultiResolutionImageChache(fileName, url); 328 329 Image image = Toolkit.getDefaultToolkit().getImage(fileName); 330 testToolkitImageObserver(image); 331 testToolkitMultiResolutionImage(image, false); 332 testToolkitMultiResolutionImage(image, true); 333 334 image = Toolkit.getDefaultToolkit().getImage(url); 335 testToolkitImageObserver(image); 336 testToolkitMultiResolutionImage(image, false); 337 testToolkitMultiResolutionImage(image, true); 338 } 339 340 static void testToolkitMultiResolutionImageChache(String fileName, URL url) { 341 342 Image img1 = Toolkit.getDefaultToolkit().getImage(fileName); 343 if (!(img1 instanceof MultiResolutionImage)) { 344 throw new RuntimeException("Not a MultiResolutionImage"); 345 } 346 347 Image img2 = Toolkit.getDefaultToolkit().getImage(fileName); 348 if (img1 != img2) { 349 throw new RuntimeException("Image is not cached"); 350 } 351 352 img1 = Toolkit.getDefaultToolkit().getImage(url); 353 if (!(img1 instanceof MultiResolutionImage)) { 354 throw new RuntimeException("Not a MultiResolutionImage"); 355 } 356 357 img2 = Toolkit.getDefaultToolkit().getImage(url); 358 if (img1 != img2) { 359 throw new RuntimeException("Image is not cached"); 360 } 361 } 362 363 static void testToolkitMultiResolutionImage(Image image, boolean enableImageScaling) 364 throws Exception { 365 366 MediaTracker tracker = new MediaTracker(new JPanel()); 367 tracker.addImage(image, 0); 368 tracker.waitForID(0); 369 if (tracker.isErrorAny()) { 370 throw new RuntimeException("Error during image loading"); 371 } 372 373 final BufferedImage bufferedImage1x = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, 374 BufferedImage.TYPE_INT_RGB); 375 Graphics2D g1x = (Graphics2D) bufferedImage1x.getGraphics(); 376 setImageScalingHint(g1x, false); 377 g1x.drawImage(image, 0, 0, null); 378 checkColor(bufferedImage1x.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false); 379 380 Image resolutionVariant = ((MultiResolutionImage) image). 381 getResolutionVariant(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT); 382 383 if (resolutionVariant == null) { 384 throw new RuntimeException("Resolution variant is null"); 385 } 386 387 MediaTracker tracker2x = new MediaTracker(new JPanel()); 388 tracker2x.addImage(resolutionVariant, 0); 389 tracker2x.waitForID(0); 390 if (tracker2x.isErrorAny()) { 391 throw new RuntimeException("Error during scalable image loading"); 392 } 393 394 final BufferedImage bufferedImage2x = new BufferedImage(2 * IMAGE_WIDTH, 395 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 396 Graphics2D g2x = (Graphics2D) bufferedImage2x.getGraphics(); 397 setImageScalingHint(g2x, enableImageScaling); 398 g2x.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null); 399 checkColor(bufferedImage2x.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling); 400 401 if (!(image instanceof MultiResolutionImage)) { 402 throw new RuntimeException("Not a MultiResolutionImage"); 403 } 404 405 MultiResolutionImage multiResolutionImage = (MultiResolutionImage) image; 406 407 Image image1x = multiResolutionImage.getResolutionVariant(IMAGE_WIDTH, IMAGE_HEIGHT); 408 Image image2x = multiResolutionImage.getResolutionVariant(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT); 409 410 if (image1x.getWidth(null) * 2 != image2x.getWidth(null) 411 || image1x.getHeight(null) * 2 != image2x.getHeight(null)) { 412 throw new RuntimeException("Wrong resolution variant size"); 413 } 414 } 415 416 static void testToolkitImageObserver(final Image image) { 417 418 ImageObserver observer = new ImageObserver() { 419 420 @Override 421 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 422 423 if (img != image) { 424 throw new RuntimeException("Wrong image in observer"); 425 } 426 427 if ((infoflags & (ImageObserver.ERROR | ImageObserver.ABORT)) != 0) { 428 throw new RuntimeException("Error during image loading"); 429 } 430 431 return (infoflags & ImageObserver.ALLBITS) == 0; 432 433 } 434 }; 435 436 final BufferedImage bufferedImage2x = new BufferedImage(2 * IMAGE_WIDTH, 437 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); 438 Graphics2D g2x = (Graphics2D) bufferedImage2x.getGraphics(); 439 setImageScalingHint(g2x, true); 440 441 g2x.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, observer); 442 443 } 444 445 static void setImageScalingHint(Graphics2D g2d, boolean enableImageScaling) { 446 g2d.setRenderingHint(SunHints.KEY_RESOLUTION_VARIANT, enableImageScaling 447 ? SunHints.VALUE_RESOLUTION_VARIANT_ON 448 : SunHints.VALUE_RESOLUTION_VARIANT_OFF); 449 } 450 451 static void checkColor(int rgb, boolean isImageScaled) { 452 453 if (!isImageScaled && COLOR_1X.getRGB() != rgb) { 454 throw new RuntimeException("Wrong 1x color: " + new Color(rgb)); 455 } 456 457 if (isImageScaled && COLOR_2X.getRGB() != rgb) { 458 throw new RuntimeException("Wrong 2x color" + new Color(rgb)); 459 } 460 } 461 462 static void generateImages() throws Exception { 463 if (!new File(IMAGE_NAME_1X).exists()) { 464 generateImage(1); 465 } 466 467 if (!new File(IMAGE_NAME_2X).exists()) { 468 generateImage(2); 469 } 470 } 471 472 static void generateImage(int scale) throws Exception { 473 BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT, 474 BufferedImage.TYPE_INT_RGB); 475 Graphics g = image.getGraphics(); 476 g.setColor(scale == 1 ? COLOR_1X : COLOR_2X); 477 g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT); 478 File file = new File(scale == 1 ? IMAGE_NAME_1X : IMAGE_NAME_2X); 479 ImageIO.write(image, "png", file); 480 } 481 482 static void testImageNameTo2xParsing() throws Exception { 483 484 for (String[] testNames : TEST_FILE_NAMES) { 485 String testName = testNames[0]; 486 String goldenName = testNames[1]; 487 String resultName = getTestScaledImageName(testName); 488 489 if (!isValidPath(testName) && resultName == null) { 490 continue; 491 } 492 493 if (goldenName.equals(resultName)) { 494 continue; 495 } 496 497 throw new RuntimeException("Test name " + testName 498 + ", result name: " + resultName); 499 } 500 501 for (URL[] testURLs : TEST_URLS) { 502 URL testURL = testURLs[0]; 503 URL goldenURL = testURLs[1]; 504 URL resultURL = getTestScaledImageURL(testURL); 505 506 if (!isValidPath(testURL.getPath()) && resultURL == null) { 507 continue; 508 } 509 510 if (goldenURL.equals(resultURL)) { 511 continue; 512 } 513 514 throw new RuntimeException("Test url: " + testURL 515 + ", result url: " + resultURL); 516 } 517 518 } 519 520 static URL getTestScaledImageURL(URL url) throws Exception { 521 Method method = getScalableImageMethod("getScaledImageURL", URL.class); 522 return (URL) method.invoke(null, url); 523 } 524 525 static String getTestScaledImageName(String name) throws Exception { 526 Method method = getScalableImageMethod("getScaledImageName", String.class); 527 return (String) method.invoke(null, name); 528 } 529 530 private static boolean isValidPath(String path) { 531 return !path.isEmpty() && !path.endsWith("/") && !path.endsWith(".") 532 && !path.contains("@2x"); 533 } 534 535 private static Method getScalableImageMethod(String name, 536 Class... parameterTypes) throws Exception { 537 Toolkit toolkit = Toolkit.getDefaultToolkit(); 538 Method method = toolkit.getClass().getDeclaredMethod(name, parameterTypes); 539 method.setAccessible(true); 540 return method; 541 } 542 private static final String[][] TEST_FILE_NAMES; 543 private static final URL[][] TEST_URLS; 544 545 static { 546 TEST_FILE_NAMES = new String[][]{ 547 {"", null}, 548 {".", null}, 549 {"..", null}, 550 {"/", null}, 551 {"/.", null}, 552 {"dir/", null}, 553 {"dir/.", null}, 554 {"aaa@2x.png", null}, 555 {"/dir/aaa@2x.png", null}, 556 {"image", "image@2x"}, 557 {"image.ext", "image@2x.ext"}, 558 {"image.aaa.ext", "image.aaa@2x.ext"}, 559 {"dir/image", "dir/image@2x"}, 560 {"dir/image.ext", "dir/image@2x.ext"}, 561 {"dir/image.aaa.ext", "dir/image.aaa@2x.ext"}, 562 {"dir/aaa.bbb/image", "dir/aaa.bbb/image@2x"}, 563 {"dir/aaa.bbb/image.ext", "dir/aaa.bbb/image@2x.ext"}, 564 {"dir/aaa.bbb/image.ccc.ext", "dir/aaa.bbb/image.ccc@2x.ext"}, 565 {"/dir/image", "/dir/image@2x"}, 566 {"/dir/image.ext", "/dir/image@2x.ext"}, 567 {"/dir/image.aaa.ext", "/dir/image.aaa@2x.ext"}, 568 {"/dir/aaa.bbb/image", "/dir/aaa.bbb/image@2x"}, 569 {"/dir/aaa.bbb/image.ext", "/dir/aaa.bbb/image@2x.ext"}, 570 {"/dir/aaa.bbb/image.ccc.ext", "/dir/aaa.bbb/image.ccc@2x.ext"} 571 }; 572 try { 573 TEST_URLS = new URL[][]{ 574 // file 575 {new URL("file:/aaa"), new URL("file:/aaa@2x")}, 576 {new URL("file:/aaa.ext"), new URL("file:/aaa@2x.ext")}, 577 {new URL("file:/aaa.bbb.ext"), new URL("file:/aaa.bbb@2x.ext")}, 578 {new URL("file:/ccc/aaa.bbb.ext"), 579 new URL("file:/ccc/aaa.bbb@2x.ext")}, 580 {new URL("file:/ccc.ddd/aaa.bbb.ext"), 581 new URL("file:/ccc.ddd/aaa.bbb@2x.ext")}, 582 {new URL("file:///~/image"), new URL("file:///~/image@2x")}, 583 {new URL("file:///~/image.ext"), 584 new URL("file:///~/image@2x.ext")}, 585 // http 586 {new URL("http://www.test.com"), null}, 587 {new URL("http://www.test.com/"), null}, 588 {new URL("http://www.test.com///"), null}, 589 {new URL("http://www.test.com/image"), 590 new URL("http://www.test.com/image@2x")}, 591 {new URL("http://www.test.com/image.ext"), 592 new URL("http://www.test.com/image@2x.ext")}, 593 {new URL("http://www.test.com/dir/image"), 594 new URL("http://www.test.com/dir/image@2x")}, 595 {new URL("http://www.test.com:80/dir/image.aaa.ext"), 596 new URL("http://www.test.com:80/dir/image.aaa@2x.ext")}, 597 {new URL("http://www.test.com:8080/dir/image.aaa.ext"), 598 new URL("http://www.test.com:8080/dir/image.aaa@2x.ext")}, 599 // jar 600 {new URL("jar:file:/dir/Java2D.jar!/image"), 601 new URL("jar:file:/dir/Java2D.jar!/image@2x")}, 602 {new URL("jar:file:/dir/Java2D.jar!/image.aaa.ext"), 603 new URL("jar:file:/dir/Java2D.jar!/image.aaa@2x.ext")}, 604 {new URL("jar:file:/dir/Java2D.jar!/images/image"), 605 new URL("jar:file:/dir/Java2D.jar!/images/image@2x")}, 606 {new URL("jar:file:/dir/Java2D.jar!/images/image.ext"), 607 new URL("jar:file:/dir/Java2D.jar!/images/image@2x.ext")}, 608 {new URL("jar:file:/aaa.bbb/Java2D.jar!/images/image.ext"), 609 new URL("jar:file:/aaa.bbb/Java2D.jar!/images/image@2x.ext")}, 610 {new URL("jar:file:/dir/Java2D.jar!/aaa.bbb/image.ext"), 611 new URL("jar:file:/dir/Java2D.jar!/aaa.bbb/image@2x.ext")},}; 612 } catch (Exception e) { 613 throw new RuntimeException(e); 614 } 615 } 616 617 static class PreloadedImageObserver implements ImageObserver { 618 619 @Override 620 public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { 621 throw new RuntimeException("Image should be already preloaded"); 622 } 623 } 624 }