--- old/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2013-11-11 19:47:22.000000000 +0400 +++ new/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java 2013-11-11 19:47:21.000000000 +0400 @@ -35,14 +35,19 @@ import java.awt.im.InputMethodHighlight; import java.awt.peer.*; import java.lang.reflect.*; +import java.io.File; +import java.io.InputStream; +import java.net.URL; import java.security.*; import java.util.*; import java.util.concurrent.Callable; import sun.awt.*; +import sun.awt.image.ToolkitImage; import sun.lwawt.*; import sun.lwawt.LWWindowPeer.PeerType; import sun.security.action.GetBooleanAction; +import com.sun.awt.MultiResolutionImage; import sun.util.CoreResourceBundleControl; @@ -489,9 +494,37 @@ @Override public Image getImage(final String filename) { final Image nsImage = checkForNSImage(filename); - if (nsImage != null) return nsImage; + if (nsImage != null) { + return nsImage; + } + + Image image = super.getImage(filename); + Image scalableImage = ScalableToolkitImage.toScalableImage(image, filename); + if (image != scalableImage) { + putImageToCache(filename, (ToolkitImage) scalableImage); + } + return scalableImage; + } - return super.getImage(filename); + @Override + public Image getImage(URL url) { + Image image = super.getImage(url); + Image scalableImage = ScalableToolkitImage.toScalableImage(image, url); + if (image != scalableImage) { + putImageToCache(url, (ToolkitImage) scalableImage); + } + return scalableImage; + } + + @Override + public Image createImage(String filename) { + return ScalableToolkitImage.toScalableImage( + super.createImage(filename), filename); + } + + @Override + public Image createImage(URL url) { + return ScalableToolkitImage.toScalableImage(super.createImage(url), url); } static final String nsImagePrefix = "NSImage://"; @@ -781,4 +814,75 @@ public boolean enableInputMethodsForTextComponent() { return true; } + + public static final class ScalableToolkitImage extends ToolkitImage implements MultiResolutionImage { + + Image highResolutionImage; + + public ScalableToolkitImage(Image lowResolutionImage, Image highResolutionImage) { + super(lowResolutionImage.getSource()); + this.highResolutionImage = highResolutionImage; + } + + @Override + public Image getResolutionVariant(int width, int height) { + return ((width <= getWidth() && height <= getHeight())) + ? this : highResolutionImage; + } + + static Image toScalableImage(Image image, String fileName) { + + if (fileName != null && !fileName.contains("@2x") + && !(image instanceof ScalableToolkitImage)) { + String filename2x = getScaledImageName(fileName); + if (filename2x != null && new File(filename2x).exists()) { + return new ScalableToolkitImage(image, getDefaultToolkit().getImage(filename2x)); + } + } + return image; + } + + static Image toScalableImage(Image image, URL url) { + + if (url != null && !url.toString().contains("@2x") + && !(image instanceof ScalableToolkitImage)) { + try { + URL url2x = getScaledImageURL(url); + + if (url2x != null) { + try (InputStream is = url2x.openStream()) { + return new ScalableToolkitImage(image, + getDefaultToolkit().getImage(url2x)); + } + } + } catch (Exception ignore) { + } + } + return image; + } + + private static URL getScaledImageURL(URL url) throws Exception { + String scaledImagePath = getScaledImageName(url.getPath()); + return scaledImagePath == null ? null : new URL(url.getProtocol(), + url.getHost(), url.getPort(), scaledImagePath); + } + + private static String getScaledImageName(String path) { + if (!isValidPath(path)) { + return null; + } + int slash = path.lastIndexOf('/'); + String name = (slash < 0) ? path : path.substring(slash + 1); + + int dot = name.lastIndexOf('.'); + String name2x = (dot < 0) ? name + "@2x" + : name.substring(0, dot) + "@2x" + name.substring(dot); + return (slash < 0) ? name2x : path.substring(0, slash + 1) + name2x; + } + + private static boolean isValidPath(String path) { + return !path.isEmpty() && !path.endsWith("/") && !path.endsWith("."); + } + + } }