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