--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/MultiResolutionImageTest.java Thu Jan 09 18:04:31 2014 +0400
@@ -0,0 +1,620 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URL;
+import javax.imageio.ImageIO;
+import sun.awt.OSInfo;
+import sun.awt.SunHints;
+import java.awt.MediaTracker;
+import java.awt.geom.AffineTransform;
+import java.awt.image.ImageObserver;
+import java.util.Arrays;
+import java.util.List;
+import javax.swing.JPanel;
+import sun.awt.SunToolkit;
+import sun.awt.image.MultiResolutionImage;
+
+/**
+ * @test
+ * @bug 8011059
+ * @author Alexander Scherbatiy
+ * @summary [macosx] Make JDK demos look perfect on retina displays
+ * @run main MultiResolutionImageTest CUSTOM
+ * @run main MultiResolutionImageTest TOOLKIT_PREPARE
+ * @run main MultiResolutionImageTest TOOLKIT_LOAD
+ * @run main MultiResolutionImageTest TOOLKIT
+ */
+public class MultiResolutionImageTest {
+
+ private static final int IMAGE_WIDTH = 300;
+ private static final int IMAGE_HEIGHT = 200;
+ private static final Color COLOR_1X = Color.GREEN;
+ private static final Color COLOR_2X = Color.BLUE;
+ private static final String IMAGE_NAME_1X = "image.png";
+ private static final String IMAGE_NAME_2X = "image@2x.png";
+
+ public static void main(String[] args) throws Exception {
+
+ System.out.println("args: " + args.length);
+
+ if (args.length == 0) {
+ throw new RuntimeException("Not found a test");
+ }
+
+ String test = args[0];
+
+ System.out.println("TEST: " + test);
+ System.out.println("CHECK OS: " + checkOS());
+
+ if ("CUSTOM".equals(test)) {
+ testCustomMultiResolutionImage();
+ } else if (checkOS()) {
+ switch (test) {
+ case "CUSTOM":
+ break;
+ case "TOOLKIT_PREPARE":
+ testToolkitMultiResolutionImagePrepare();
+ break;
+ case "TOOLKIT_LOAD":
+ testToolkitMultiResolutionImageLoad();
+ break;
+ case "TOOLKIT":
+ testToolkitMultiResolutionImage();
+ testImageNameTo2xParsing();
+ break;
+ default:
+ throw new RuntimeException("Unknown test: " + test);
+ }
+ }
+ }
+
+ static boolean checkOS() {
+ return OSInfo.getOSType() == OSInfo.OSType.MACOSX;
+ }
+
+ public static void testCustomMultiResolutionImage() {
+ testCustomMultiResolutionImage(false);
+ testCustomMultiResolutionImage(true);
+ }
+
+ public static void testCustomMultiResolutionImage(boolean enableImageScaling) {
+
+ Image image = new MultiResolutionBufferedImage();
+
+ // Same image size
+ BufferedImage bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
+ setImageScalingHint(g2d, enableImageScaling);
+ g2d.drawImage(image, 0, 0, null);
+ checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false);
+
+ // Twice image size
+ bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT,
+ BufferedImage.TYPE_INT_RGB);
+ g2d = (Graphics2D) bufferedImage.getGraphics();
+ setImageScalingHint(g2d, enableImageScaling);
+ g2d.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
+ checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
+
+ // Scale 2x
+ bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ g2d = (Graphics2D) bufferedImage.getGraphics();
+ setImageScalingHint(g2d, enableImageScaling);
+ g2d.scale(2, 2);
+ g2d.drawImage(image, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
+ checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
+
+ // Rotate
+ bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,
+ BufferedImage.TYPE_INT_RGB);
+ g2d = (Graphics2D) bufferedImage.getGraphics();
+ setImageScalingHint(g2d, enableImageScaling);
+ g2d.drawImage(image, 0, 0, null);
+ g2d.rotate(Math.PI / 4);
+ checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false);
+
+ // Scale 2x and Rotate
+ bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ g2d = (Graphics2D) bufferedImage.getGraphics();
+ setImageScalingHint(g2d, enableImageScaling);
+ g2d.scale(-2, 2);
+ g2d.rotate(-Math.PI / 10);
+ g2d.drawImage(image, -IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
+ checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
+
+ // General Transform
+ bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ g2d = (Graphics2D) bufferedImage.getGraphics();
+ setImageScalingHint(g2d, enableImageScaling);
+ float delta = 0.05f;
+ float cos = 1 - delta * delta / 2;
+ float sin = 1 + delta;
+ AffineTransform transform = new AffineTransform(2 * cos, 0.1, 0.3, -2 * sin, 10, -5);
+ g2d.setTransform(transform);
+ g2d.drawImage(image, 0, -IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, null);
+ checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
+
+ int D = 10;
+ // From Source to small Destination region
+ bufferedImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ g2d = (Graphics2D) bufferedImage.getGraphics();
+ setImageScalingHint(g2d, enableImageScaling);
+ g2d.drawImage(image, IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, IMAGE_WIDTH - D, IMAGE_HEIGHT - D,
+ D, D, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, null);
+ checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false);
+
+ // From Source to large Destination region
+ bufferedImage = new BufferedImage(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ g2d = (Graphics2D) bufferedImage.getGraphics();
+ setImageScalingHint(g2d, enableImageScaling);
+ g2d.drawImage(image, D, D, 2 * IMAGE_WIDTH - D, 2 * IMAGE_HEIGHT - D,
+ IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2, IMAGE_WIDTH - D, IMAGE_HEIGHT - D, null);
+ checkColor(bufferedImage.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
+ }
+
+ static class MultiResolutionBufferedImage extends BufferedImage
+ implements MultiResolutionImage {
+
+ Image highResolutionImage;
+
+ public MultiResolutionBufferedImage() {
+ super(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ highResolutionImage = new BufferedImage(
+ 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ draw(getGraphics(), 1);
+ draw(highResolutionImage.getGraphics(), 2);
+ }
+
+ void draw(Graphics graphics, float resolution) {
+ Graphics2D g2 = (Graphics2D) graphics;
+ g2.scale(resolution, resolution);
+ g2.setColor((resolution == 1) ? COLOR_1X : COLOR_2X);
+ g2.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+ }
+
+ @Override
+ public Image getResolutionVariant(int width, int height) {
+ return ((width <= getWidth() && height <= getHeight()))
+ ? this : highResolutionImage;
+ }
+
+ @Override
+ public List<Image> getResolutionVariants() {
+ return Arrays.asList(this, highResolutionImage);
+ }
+ }
+
+ static void testToolkitMultiResolutionImagePrepare() throws Exception {
+
+ generateImages();
+
+ File imageFile = new File(IMAGE_NAME_1X);
+ String fileName = imageFile.getAbsolutePath();
+
+ Image image = Toolkit.getDefaultToolkit().getImage(fileName);
+
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ toolkit.prepareImage(image, IMAGE_WIDTH, IMAGE_HEIGHT, new LoadImageObserver(image));
+
+ testToolkitMultiResolutionImageLoad(image);
+ }
+
+ static void testToolkitMultiResolutionImageLoad() throws Exception {
+
+ generateImages();
+
+ File imageFile = new File(IMAGE_NAME_1X);
+ String fileName = imageFile.getAbsolutePath();
+ Image image = Toolkit.getDefaultToolkit().getImage(fileName);
+ testToolkitMultiResolutionImageLoad(image);
+ }
+
+ static void testToolkitMultiResolutionImageLoad(Image image) throws Exception {
+
+ MediaTracker tracker = new MediaTracker(new JPanel());
+ tracker.addImage(image, 0);
+ tracker.waitForID(0);
+ if (tracker.isErrorAny()) {
+ throw new RuntimeException("Error during image loading");
+ }
+ tracker.removeImage(image, 0);
+
+ testImageLoaded(image);
+
+ int w = image.getWidth(null);
+ int h = image.getHeight(null);
+
+ Image resolutionVariant = ((MultiResolutionImage) image)
+ .getResolutionVariant(2 * w, 2 * h);
+
+ if (image == resolutionVariant) {
+ throw new RuntimeException("Resolution variant is not loaded");
+ }
+
+ testImageLoaded(resolutionVariant);
+ }
+
+ static void testImageLoaded(Image image) {
+
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+ int flags = toolkit.checkImage(image, IMAGE_WIDTH, IMAGE_WIDTH, new SilentImageObserver());
+ if ((flags & (ImageObserver.FRAMEBITS | ImageObserver.ALLBITS)) == 0) {
+ throw new RuntimeException("Image is not loaded!");
+ }
+ }
+
+ static class SilentImageObserver implements ImageObserver {
+
+ @Override
+ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
+ throw new RuntimeException("Observer should not be called!");
+ }
+ }
+
+ static class LoadImageObserver implements ImageObserver {
+
+ Image image;
+
+ public LoadImageObserver(Image image) {
+ this.image = image;
+ }
+
+ @Override
+ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
+
+ if (image != img) {
+ throw new RuntimeException("Original image is not passed to the observer");
+ }
+
+ if ((infoflags & ImageObserver.WIDTH) != 0) {
+ if (width != IMAGE_WIDTH) {
+ throw new RuntimeException("Original width is not passed to the observer");
+ }
+ }
+
+ if ((infoflags & ImageObserver.HEIGHT) != 0) {
+ if (height != IMAGE_HEIGHT) {
+ throw new RuntimeException("Original height is not passed to the observer");
+ }
+ }
+
+ return (infoflags & ALLBITS) == 0;
+ }
+
+ }
+
+ static void testToolkitMultiResolutionImage() throws Exception {
+
+ generateImages();
+
+ File imageFile = new File(IMAGE_NAME_1X);
+ String fileName = imageFile.getAbsolutePath();
+ URL url = imageFile.toURI().toURL();
+ testToolkitMultiResolutionImageChache(fileName, url);
+
+ Image image = Toolkit.getDefaultToolkit().getImage(fileName);
+ testToolkitImageObserver(image);
+ testToolkitMultiResolutionImage(image, false);
+ testToolkitMultiResolutionImage(image, true);
+
+ image = Toolkit.getDefaultToolkit().getImage(url);
+ testToolkitImageObserver(image);
+ testToolkitMultiResolutionImage(image, false);
+ testToolkitMultiResolutionImage(image, true);
+ }
+
+ static void testToolkitMultiResolutionImageChache(String fileName, URL url) {
+
+ Image img1 = Toolkit.getDefaultToolkit().getImage(fileName);
+ if (!(img1 instanceof MultiResolutionImage)) {
+ throw new RuntimeException("Not a MultiResolutionImage");
+ }
+
+ Image img2 = Toolkit.getDefaultToolkit().getImage(fileName);
+ if (img1 != img2) {
+ throw new RuntimeException("Image is not cached");
+ }
+
+ img1 = Toolkit.getDefaultToolkit().getImage(url);
+ if (!(img1 instanceof MultiResolutionImage)) {
+ throw new RuntimeException("Not a MultiResolutionImage");
+ }
+
+ img2 = Toolkit.getDefaultToolkit().getImage(url);
+ if (img1 != img2) {
+ throw new RuntimeException("Image is not cached");
+ }
+ }
+
+ static void testToolkitMultiResolutionImage(Image image, boolean enableImageScaling)
+ throws Exception {
+
+ MediaTracker tracker = new MediaTracker(new JPanel());
+ tracker.addImage(image, 0);
+ tracker.waitForID(0);
+ if (tracker.isErrorAny()) {
+ throw new RuntimeException("Error during image loading");
+ }
+
+ final BufferedImage bufferedImage1x = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics2D g1x = (Graphics2D) bufferedImage1x.getGraphics();
+ setImageScalingHint(g1x, false);
+ g1x.drawImage(image, 0, 0, null);
+ checkColor(bufferedImage1x.getRGB(3 * IMAGE_WIDTH / 4, 3 * IMAGE_HEIGHT / 4), false);
+
+ Image resolutionVariant = ((MultiResolutionImage) image).
+ getResolutionVariant(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT);
+
+ if (resolutionVariant == null) {
+ throw new RuntimeException("Resolution variant is null");
+ }
+
+ MediaTracker tracker2x = new MediaTracker(new JPanel());
+ tracker2x.addImage(resolutionVariant, 0);
+ tracker2x.waitForID(0);
+ if (tracker2x.isErrorAny()) {
+ throw new RuntimeException("Error during scalable image loading");
+ }
+
+ final BufferedImage bufferedImage2x = new BufferedImage(2 * IMAGE_WIDTH,
+ 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g2x = (Graphics2D) bufferedImage2x.getGraphics();
+ setImageScalingHint(g2x, enableImageScaling);
+ g2x.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
+ checkColor(bufferedImage2x.getRGB(3 * IMAGE_WIDTH / 2, 3 * IMAGE_HEIGHT / 2), enableImageScaling);
+
+ if (!(image instanceof MultiResolutionImage)) {
+ throw new RuntimeException("Not a MultiResolutionImage");
+ }
+
+ MultiResolutionImage multiResolutionImage = (MultiResolutionImage) image;
+
+ Image image1x = multiResolutionImage.getResolutionVariant(IMAGE_WIDTH, IMAGE_HEIGHT);
+ Image image2x = multiResolutionImage.getResolutionVariant(2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT);
+
+ if (image1x.getWidth(null) * 2 != image2x.getWidth(null)
+ || image1x.getHeight(null) * 2 != image2x.getHeight(null)) {
+ throw new RuntimeException("Wrong resolution variant size");
+ }
+ }
+
+ static void testToolkitImageObserver(final Image image) {
+
+ ImageObserver observer = new ImageObserver() {
+
+ @Override
+ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
+
+ if (img != image) {
+ throw new RuntimeException("Wrong image in observer");
+ }
+
+ if ((infoflags & (ImageObserver.ERROR | ImageObserver.ABORT)) != 0) {
+ throw new RuntimeException("Error during image loading");
+ }
+
+ return (infoflags & ImageObserver.ALLBITS) == 0;
+
+ }
+ };
+
+ final BufferedImage bufferedImage2x = new BufferedImage(2 * IMAGE_WIDTH,
+ 2 * IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g2x = (Graphics2D) bufferedImage2x.getGraphics();
+ setImageScalingHint(g2x, true);
+
+ g2x.drawImage(image, 0, 0, 2 * IMAGE_WIDTH, 2 * IMAGE_HEIGHT, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, observer);
+
+ }
+
+ static void setImageScalingHint(Graphics2D g2d, boolean enableImageScaling) {
+ g2d.setRenderingHint(SunHints.KEY_RESOLUTION_VARIANT, enableImageScaling
+ ? SunHints.VALUE_RESOLUTION_VARIANT_ON
+ : SunHints.VALUE_RESOLUTION_VARIANT_OFF);
+ }
+
+ static void checkColor(int rgb, boolean isImageScaled) {
+
+ if (!isImageScaled && COLOR_1X.getRGB() != rgb) {
+ throw new RuntimeException("Wrong 1x color: " + new Color(rgb));
+ }
+
+ if (isImageScaled && COLOR_2X.getRGB() != rgb) {
+ throw new RuntimeException("Wrong 2x color" + new Color(rgb));
+ }
+ }
+
+ static void generateImages() throws Exception {
+ if (!new File(IMAGE_NAME_1X).exists()) {
+ generateImage(1);
+ }
+
+ if (!new File(IMAGE_NAME_2X).exists()) {
+ generateImage(2);
+ }
+ }
+
+ static void generateImage(int scale) throws Exception {
+ BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics g = image.getGraphics();
+ g.setColor(scale == 1 ? COLOR_1X : COLOR_2X);
+ g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT);
+ File file = new File(scale == 1 ? IMAGE_NAME_1X : IMAGE_NAME_2X);
+ ImageIO.write(image, "png", file);
+ }
+
+ static void testImageNameTo2xParsing() throws Exception {
+
+ for (String[] testNames : TEST_FILE_NAMES) {
+ String testName = testNames[0];
+ String goldenName = testNames[1];
+ String resultName = getTestScaledImageName(testName);
+
+ if (!isValidPath(testName) && resultName == null) {
+ continue;
+ }
+
+ if (goldenName.equals(resultName)) {
+ continue;
+ }
+
+ throw new RuntimeException("Test name " + testName
+ + ", result name: " + resultName);
+ }
+
+ for (URL[] testURLs : TEST_URLS) {
+ URL testURL = testURLs[0];
+ URL goldenURL = testURLs[1];
+ URL resultURL = getTestScaledImageURL(testURL);
+
+ if (!isValidPath(testURL.getPath()) && resultURL == null) {
+ continue;
+ }
+
+ if (goldenURL.equals(resultURL)) {
+ continue;
+ }
+
+ throw new RuntimeException("Test url: " + testURL
+ + ", result url: " + resultURL);
+ }
+
+ }
+
+ static URL getTestScaledImageURL(URL url) throws Exception {
+ Method method = getScalableImageMethod("getScaledImageURL", URL.class);
+ return (URL) method.invoke(null, url);
+ }
+
+ static String getTestScaledImageName(String name) throws Exception {
+ Method method = getScalableImageMethod("getScaledImageName", String.class);
+ return (String) method.invoke(null, name);
+ }
+
+ private static boolean isValidPath(String path) {
+ return !path.isEmpty() && !path.endsWith("/") && !path.endsWith(".")
+ && !path.contains("@2x");
+ }
+
+ private static Method getScalableImageMethod(String name,
+ Class... parameterTypes) throws Exception {
+ Toolkit toolkit = Toolkit.getDefaultToolkit();
+ Method method = toolkit.getClass().getDeclaredMethod(name, parameterTypes);
+ method.setAccessible(true);
+ return method;
+ }
+ private static final String[][] TEST_FILE_NAMES;
+ private static final URL[][] TEST_URLS;
+
+ static {
+ TEST_FILE_NAMES = new String[][]{
+ {"", null},
+ {".", null},
+ {"..", null},
+ {"/", null},
+ {"/.", null},
+ {"dir/", null},
+ {"dir/.", null},
+ {"aaa@2x.png", null},
+ {"/dir/aaa@2x.png", null},
+ {"image", "image@2x"},
+ {"image.ext", "image@2x.ext"},
+ {"image.aaa.ext", "image.aaa@2x.ext"},
+ {"dir/image", "dir/image@2x"},
+ {"dir/image.ext", "dir/image@2x.ext"},
+ {"dir/image.aaa.ext", "dir/image.aaa@2x.ext"},
+ {"dir/aaa.bbb/image", "dir/aaa.bbb/image@2x"},
+ {"dir/aaa.bbb/image.ext", "dir/aaa.bbb/image@2x.ext"},
+ {"dir/aaa.bbb/image.ccc.ext", "dir/aaa.bbb/image.ccc@2x.ext"},
+ {"/dir/image", "/dir/image@2x"},
+ {"/dir/image.ext", "/dir/image@2x.ext"},
+ {"/dir/image.aaa.ext", "/dir/image.aaa@2x.ext"},
+ {"/dir/aaa.bbb/image", "/dir/aaa.bbb/image@2x"},
+ {"/dir/aaa.bbb/image.ext", "/dir/aaa.bbb/image@2x.ext"},
+ {"/dir/aaa.bbb/image.ccc.ext", "/dir/aaa.bbb/image.ccc@2x.ext"}
+ };
+ try {
+ TEST_URLS = new URL[][]{
+ // file
+ {new URL("file:/aaa"), new URL("file:/aaa@2x")},
+ {new URL("file:/aaa.ext"), new URL("file:/aaa@2x.ext")},
+ {new URL("file:/aaa.bbb.ext"), new URL("file:/aaa.bbb@2x.ext")},
+ {new URL("file:/ccc/aaa.bbb.ext"),
+ new URL("file:/ccc/aaa.bbb@2x.ext")},
+ {new URL("file:/ccc.ddd/aaa.bbb.ext"),
+ new URL("file:/ccc.ddd/aaa.bbb@2x.ext")},
+ {new URL("file:///~/image"), new URL("file:///~/image@2x")},
+ {new URL("file:///~/image.ext"),
+ new URL("file:///~/image@2x.ext")},
+ // http
+ {new URL("http://www.test.com"), null},
+ {new URL("http://www.test.com/"), null},
+ {new URL("http://www.test.com///"), null},
+ {new URL("http://www.test.com/image"),
+ new URL("http://www.test.com/image@2x")},
+ {new URL("http://www.test.com/image.ext"),
+ new URL("http://www.test.com/image@2x.ext")},
+ {new URL("http://www.test.com/dir/image"),
+ new URL("http://www.test.com/dir/image@2x")},
+ {new URL("http://www.test.com:80/dir/image.aaa.ext"),
+ new URL("http://www.test.com:80/dir/image.aaa@2x.ext")},
+ {new URL("http://www.test.com:8080/dir/image.aaa.ext"),
+ new URL("http://www.test.com:8080/dir/image.aaa@2x.ext")},
+ // jar
+ {new URL("jar:file:/dir/Java2D.jar!/image"),
+ new URL("jar:file:/dir/Java2D.jar!/image@2x")},
+ {new URL("jar:file:/dir/Java2D.jar!/image.aaa.ext"),
+ new URL("jar:file:/dir/Java2D.jar!/image.aaa@2x.ext")},
+ {new URL("jar:file:/dir/Java2D.jar!/images/image"),
+ new URL("jar:file:/dir/Java2D.jar!/images/image@2x")},
+ {new URL("jar:file:/dir/Java2D.jar!/images/image.ext"),
+ new URL("jar:file:/dir/Java2D.jar!/images/image@2x.ext")},
+ {new URL("jar:file:/aaa.bbb/Java2D.jar!/images/image.ext"),
+ new URL("jar:file:/aaa.bbb/Java2D.jar!/images/image@2x.ext")},
+ {new URL("jar:file:/dir/Java2D.jar!/aaa.bbb/image.ext"),
+ new URL("jar:file:/dir/Java2D.jar!/aaa.bbb/image@2x.ext")},};
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static class PreloadedImageObserver implements ImageObserver {
+
+ @Override
+ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
+ throw new RuntimeException("Image should be already preloaded");
+ }
+ }
+}