aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralexsch <none@none>2014-08-06 15:30:04 +0400
committeralexsch <none@none>2014-08-06 15:30:04 +0400
commit99621ec61bcc3e5d66d7d5a86e8f0d133edfb242 (patch)
tree5c6d5828c8d7f8e876f8f5d846f113adf1842728
parente7e170104c1dd55165c40c3627a51fc43681d6ce (diff)
8040279: [macosx] Do not use the base image in the MultiResolutionBufferedImage
Reviewed-by: serb, pchelko
-rw-r--r--src/macosx/classes/com/apple/laf/AquaImageFactory.java24
-rw-r--r--src/macosx/classes/com/apple/laf/AquaPainter.java6
-rw-r--r--src/macosx/classes/com/apple/laf/AquaUtils.java6
-rw-r--r--src/macosx/classes/sun/lwawt/macosx/CImage.java36
-rw-r--r--src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java122
-rw-r--r--src/share/classes/sun/awt/image/MultiResolutionCachedImage.java (renamed from src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java)56
-rw-r--r--test/javax/swing/JMenuItem/8031573/bug8031573.java2
-rw-r--r--test/javax/swing/JOptionPane/8024926/bug8024926.java2
8 files changed, 176 insertions, 78 deletions
diff --git a/src/macosx/classes/com/apple/laf/AquaImageFactory.java b/src/macosx/classes/com/apple/laf/AquaImageFactory.java
index 8fbc4c01a..d19486395 100644
--- a/src/macosx/classes/com/apple/laf/AquaImageFactory.java
+++ b/src/macosx/classes/com/apple/laf/AquaImageFactory.java
@@ -46,10 +46,8 @@ import com.apple.laf.AquaIcon.JRSUIControlSpec;
import com.apple.laf.AquaIcon.SystemIcon;
import com.apple.laf.AquaUtils.RecyclableObject;
import com.apple.laf.AquaUtils.RecyclableSingleton;
-import java.util.Arrays;
-import java.util.List;
-import sun.awt.image.MultiResolutionBufferedImage;
import sun.awt.image.MultiResolutionImage;
+import sun.awt.image.MultiResolutionCachedImage;
public class AquaImageFactory {
public static IconUIResource getConfirmImageIcon() {
@@ -107,9 +105,9 @@ public class AquaImageFactory {
private static final int kAlertIconSize = 64;
static IconUIResource getAppIconCompositedOn(final Image background) {
- if (background instanceof MultiResolutionBufferedImage) {
+ if (background instanceof MultiResolutionCachedImage) {
int width = background.getWidth(null);
- Image mrIconImage = ((MultiResolutionBufferedImage) background).map(
+ Image mrIconImage = ((MultiResolutionCachedImage) background).map(
rv -> getAppIconImageCompositedOn(rv, rv.getWidth(null) / width));
return new IconUIResource(new ImageIcon(mrIconImage));
}
@@ -287,21 +285,7 @@ public class AquaImageFactory {
private static Image getNSIcon(String imageName) {
Image icon = Toolkit.getDefaultToolkit()
.getImage("NSImage://" + imageName);
-
- if (icon instanceof MultiResolutionImage) {
- return icon;
- }
-
- int w = icon.getWidth(null);
- int h = icon.getHeight(null);
-
- Dimension[] sizes = new Dimension[]{
- new Dimension(w, h), new Dimension(2 * w, 2 * h)
- };
-
- return new MultiResolutionBufferedImage(icon, sizes, (width, height) ->
- AquaUtils.getCImageCreator().createImageFromName(
- imageName, width, height));
+ return icon;
}
public static class NineSliceMetrics {
diff --git a/src/macosx/classes/com/apple/laf/AquaPainter.java b/src/macosx/classes/com/apple/laf/AquaPainter.java
index ee4fcba1a..a2ebaf1c9 100644
--- a/src/macosx/classes/com/apple/laf/AquaPainter.java
+++ b/src/macosx/classes/com/apple/laf/AquaPainter.java
@@ -174,11 +174,7 @@ abstract class AquaPainter <T extends JRSUIState> {
bounds, controlState);
Image img = cache.getImage(key);
if (img == null) {
-
- Image baseImage = createImage(imgX, imgY, imgW, imgH, bounds,
- control, controlState);
-
- img = new MultiResolutionBufferedImage(baseImage,
+ img = new MultiResolutionCachedImage(imgW, imgH,
(rvWidth, rvHeight) -> createImage(imgX, imgY,
rvWidth, rvHeight, bounds, control, controlState));
diff --git a/src/macosx/classes/com/apple/laf/AquaUtils.java b/src/macosx/classes/com/apple/laf/AquaUtils.java
index a20897f7b..078435b16 100644
--- a/src/macosx/classes/com/apple/laf/AquaUtils.java
+++ b/src/macosx/classes/com/apple/laf/AquaUtils.java
@@ -48,7 +48,7 @@ import sun.security.action.GetPropertyAction;
import sun.swing.SwingUtilities2;
import com.apple.laf.AquaImageFactory.SlicedImageControl;
-import sun.awt.image.MultiResolutionBufferedImage;
+import sun.awt.image.MultiResolutionCachedImage;
final class AquaUtils {
@@ -124,8 +124,8 @@ final class AquaUtils {
static Image generateLightenedImage(final Image image, final int percent) {
final GrayFilter filter = new GrayFilter(true, percent);
- return (image instanceof MultiResolutionBufferedImage)
- ? ((MultiResolutionBufferedImage) image).map(
+ return (image instanceof MultiResolutionCachedImage)
+ ? ((MultiResolutionCachedImage) image).map(
rv -> generateLightenedImage(rv, filter))
: generateLightenedImage(image, filter);
}
diff --git a/src/macosx/classes/sun/lwawt/macosx/CImage.java b/src/macosx/classes/sun/lwawt/macosx/CImage.java
index 7b0c826e4..0cbd570ac 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CImage.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CImage.java
@@ -32,7 +32,7 @@ import java.awt.image.*;
import java.util.Arrays;
import java.util.List;
import sun.awt.image.MultiResolutionImage;
-import sun.awt.image.MultiResolutionBufferedImage;
+import sun.awt.image.MultiResolutionCachedImage;
import sun.awt.image.SunWritableRaster;
@@ -60,41 +60,41 @@ public class CImage extends CFRetainedResource {
// This is used to create a CImage with an NSImage pointer. It MUST be a CFRetained
// NSImage, and the CImage takes ownership of the non-GC retain. If callers need the
// NSImage themselves, they MUST call retain on the NSImage themselves.
- public BufferedImage createImageUsingNativeSize(final long image) {
+ public Image createImageUsingNativeSize(final long image) {
if (image == 0) return null;
final Dimension2D size = nativeGetNSImageSize(image);
- return createBufferedImage(image, size.getWidth(), size.getHeight());
+ return createImage(image, size.getWidth(), size.getHeight());
}
// the width and height passed in as a parameter could differ than the width and the height of the NSImage (image), in that case, the image will be scaled
- BufferedImage createBufferedImage(long image, double width, double height) {
+ Image createImage(long image, double width, double height) {
if (image == 0) throw new Error("Unable to instantiate CImage with null native image reference.");
return createImageWithSize(image, width, height);
}
- public BufferedImage createImageWithSize(final long image, final double width, final double height) {
+ public Image createImageWithSize(final long image, final double width, final double height) {
final CImage img = new CImage(image);
img.resize(width, height);
return img.toImage();
}
// This is used to create a CImage that represents the icon of the given file.
- public BufferedImage createImageOfFile(final String file, final int width, final int height) {
- return createBufferedImage(nativeCreateNSImageOfFileFromLaunchServices(file), width, height);
+ public Image createImageOfFile(final String file, final int width, final int height) {
+ return createImage(nativeCreateNSImageOfFileFromLaunchServices(file), width, height);
}
- public BufferedImage createImageFromFile(final String file, final double width, final double height) {
+ public Image createImageFromFile(final String file, final double width, final double height) {
final long image = nativeCreateNSImageFromFileContents(file);
nativeSetNSImageSize(image, width, height);
- return createBufferedImage(image, width, height);
+ return createImage(image, width, height);
}
- public BufferedImage createSystemImageFromSelector(final String iconSelector, final int width, final int height) {
- return createBufferedImage(nativeCreateNSImageFromIconSelector(getSelectorAsInt(iconSelector)), width, height);
+ public Image createSystemImageFromSelector(final String iconSelector, final int width, final int height) {
+ return createImage(nativeCreateNSImageFromIconSelector(getSelectorAsInt(iconSelector)), width, height);
}
public Image createImageFromName(final String name, final int width, final int height) {
- return createBufferedImage(nativeCreateNSImageFromImageName(name), width, height);
+ return createImage(nativeCreateNSImageFromImageName(name), width, height);
}
public Image createImageFromName(final String name) {
@@ -213,7 +213,7 @@ public class CImage extends CFRetainedResource {
}
/** @return A MultiResolution image created from nsImagePtr, or null. */
- private BufferedImage toImage() {
+ private Image toImage() {
if (ptr == 0) return null;
final Dimension2D size = nativeGetNSImageSize(ptr);
@@ -224,11 +224,11 @@ public class CImage extends CFRetainedResource {
= nativeGetNSImageRepresentationSizes(ptr,
size.getWidth(), size.getHeight());
- BufferedImage baseImage = toImage(w, h, w, h);
-
- return sizes == null || sizes.length < 2 ? baseImage
- : new MultiResolutionBufferedImage(baseImage, sizes,
- (width, height) -> toImage(w, h, width, height));
+ return sizes == null || sizes.length < 2 ?
+ new MultiResolutionCachedImage(w, h, (width, height)
+ -> toImage(w, h, width, height))
+ : new MultiResolutionCachedImage(w, h, sizes, (width, height)
+ -> toImage(w, h, width, height));
}
private BufferedImage toImage(int srcWidth, int srcHeight, int dstWidth, int dstHeight) {
diff --git a/src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java b/src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java
new file mode 100644
index 000000000..94c070916
--- /dev/null
+++ b/src/share/classes/sun/awt/image/AbstractMultiResolutionImage.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package sun.awt.image;
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.image.*;
+
+/**
+ * This class provides default implementations for the
+ * <code>MultiResolutionImage</code> interface. The developer needs only
+ * to subclass this abstract class and define the <code>getResolutionVariant</code>,
+ * <code>getResolutionVariants</code>, and <code>getBaseImage</code> methods.
+ *
+ *
+ * For example,
+ * {@code
+ * public class CustomMultiResolutionImage extends AbstractMultiResolutionImage {
+ *
+ * int baseImageIndex;
+ * Image[] resolutionVariants;
+ *
+ * public CustomMultiResolutionImage(int baseImageIndex,
+ * Image... resolutionVariants) {
+ * this.baseImageIndex = baseImageIndex;
+ * this.resolutionVariants = resolutionVariants;
+ * }
+ *
+ * @Override
+ * public Image getResolutionVariant(float logicalDPIX, float logicalDPIY,
+ * float baseImageWidth, float baseImageHeight,
+ * float destImageWidth, float destImageHeight) {
+ * // return a resolution variant based on the given logical DPI,
+ * // base image size, or destination image size
+ * }
+ *
+ * @Override
+ * public List<Image> getResolutionVariants() {
+ * return Arrays.asList(resolutionVariants);
+ * }
+ *
+ * protected Image getBaseImage() {
+ * return resolutionVariants[baseImageIndex];
+ * }
+ * }
+ * }
+ *
+ * @see java.awt.Image
+ * @see java.awt.image.MultiResolutionImage
+ *
+ */
+public abstract class AbstractMultiResolutionImage extends java.awt.Image
+ implements MultiResolutionImage {
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public int getWidth(ImageObserver observer) {
+ return getBaseImage().getWidth(null);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public int getHeight(ImageObserver observer) {
+ return getBaseImage().getHeight(null);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public ImageProducer getSource() {
+ return getBaseImage().getSource();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public Graphics getGraphics() {
+ return getBaseImage().getGraphics();
+
+ }
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public Object getProperty(String name, ImageObserver observer) {
+ return getBaseImage().getProperty(name, observer);
+ }
+
+ /**
+ * @return base image
+ */
+ protected abstract Image getBaseImage();
+}
diff --git a/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java b/src/share/classes/sun/awt/image/MultiResolutionCachedImage.java
index 74db82734..376827c08 100644
--- a/src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java
+++ b/src/share/classes/sun/awt/image/MultiResolutionCachedImage.java
@@ -26,9 +26,7 @@ package sun.awt.image;
import java.awt.Dimension;
import java.awt.Image;
-import java.awt.Graphics;
import java.awt.geom.Dimension2D;
-import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.util.Arrays;
import java.util.List;
@@ -36,50 +34,39 @@ import java.util.function.Function;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
-public class MultiResolutionBufferedImage extends BufferedImage
- implements MultiResolutionImage {
+public class MultiResolutionCachedImage extends AbstractMultiResolutionImage {
- private final BiFunction<Integer, Integer, Image> mapper;
+ private final int baseImageWidth;
+ private final int baseImageHeight;
private final Dimension2D[] sizes;
+ private final BiFunction<Integer, Integer, Image> mapper;
private int availableInfo;
- public MultiResolutionBufferedImage(Image baseImage,
+ public MultiResolutionCachedImage(int baseImageWidth, int baseImageHeight,
BiFunction<Integer, Integer, Image> mapper) {
- this(baseImage, new Dimension[]{new Dimension(
- baseImage.getWidth(null), baseImage.getHeight(null))
+ this(baseImageWidth, baseImageHeight, new Dimension[]{new Dimension(
+ baseImageWidth, baseImageHeight)
}, mapper);
}
- public MultiResolutionBufferedImage(Image baseImage,
+ public MultiResolutionCachedImage(int baseImageWidth, int baseImageHeight,
Dimension2D[] sizes, BiFunction<Integer, Integer, Image> mapper) {
- super(baseImage.getWidth(null), baseImage.getHeight(null),
- BufferedImage.TYPE_INT_ARGB_PRE);
+ this.baseImageWidth = baseImageWidth;
+ this.baseImageHeight = baseImageHeight;
this.sizes = sizes;
this.mapper = mapper;
- this.availableInfo = getInfo(baseImage);
- Graphics g = getGraphics();
- g.drawImage(baseImage, 0, 0, null);
- g.dispose();
}
@Override
public Image getResolutionVariant(int width, int height) {
- int baseWidth = getWidth();
- int baseHeight = getHeight();
-
- if (baseWidth == width && baseHeight == height) {
- return this;
- }
-
ImageCache cache = ImageCache.getInstance();
ImageCacheKey key = new ImageCacheKey(this, width, height);
Image resolutionVariant = cache.getImage(key);
if (resolutionVariant == null) {
resolutionVariant = mapper.apply(width, height);
cache.setImage(key, resolutionVariant);
- preload(resolutionVariant, availableInfo);
}
-
+ preload(resolutionVariant, availableInfo);
return resolutionVariant;
}
@@ -90,30 +77,39 @@ public class MultiResolutionBufferedImage extends BufferedImage
(int) size.getHeight())).collect(Collectors.toList());
}
- public MultiResolutionBufferedImage map(Function<Image, Image> mapper) {
- return new MultiResolutionBufferedImage(mapper.apply(this), sizes,
- (width, height) ->
+ public MultiResolutionCachedImage map(Function<Image, Image> mapper) {
+ return new MultiResolutionCachedImage(baseImageWidth, baseImageHeight,
+ sizes, (width, height) ->
mapper.apply(getResolutionVariant(width, height)));
}
@Override
public int getWidth(ImageObserver observer) {
- availableInfo |= ImageObserver.WIDTH;
+ updateInfo(observer, ImageObserver.WIDTH);
return super.getWidth(observer);
}
@Override
public int getHeight(ImageObserver observer) {
- availableInfo |= ImageObserver.HEIGHT;
+ updateInfo(observer, ImageObserver.HEIGHT);
return super.getHeight(observer);
}
@Override
public Object getProperty(String name, ImageObserver observer) {
- availableInfo |= ImageObserver.PROPERTIES;
+ updateInfo(observer, ImageObserver.PROPERTIES);
return super.getProperty(name, observer);
}
+ @Override
+ protected Image getBaseImage() {
+ return getResolutionVariant(baseImageWidth, baseImageHeight);
+ }
+
+ private void updateInfo(ImageObserver observer, int info) {
+ availableInfo |= (observer == null) ? ImageObserver.ALLBITS : info;
+ }
+
private static int getInfo(Image image) {
if (image instanceof ToolkitImage) {
return ((ToolkitImage) image).getImageRep().check(
diff --git a/test/javax/swing/JMenuItem/8031573/bug8031573.java b/test/javax/swing/JMenuItem/8031573/bug8031573.java
index 5cb1dc504..2d36db7a1 100644
--- a/test/javax/swing/JMenuItem/8031573/bug8031573.java
+++ b/test/javax/swing/JMenuItem/8031573/bug8031573.java
@@ -28,7 +28,7 @@ import javax.swing.JMenuBar;
import javax.swing.SwingUtilities;
/* @test
- * @bug 8031573
+ * @bug 8031573 8040279
* @summary [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered
* in high resolution on Retina
* @author Alexander Scherbatiy
diff --git a/test/javax/swing/JOptionPane/8024926/bug8024926.java b/test/javax/swing/JOptionPane/8024926/bug8024926.java
index 42f976b03..185537f3b 100644
--- a/test/javax/swing/JOptionPane/8024926/bug8024926.java
+++ b/test/javax/swing/JOptionPane/8024926/bug8024926.java
@@ -31,7 +31,7 @@ import sun.awt.OSInfo;
/**
* @test
- * @bug 8024926
+ * @bug 8024926 8040279
* @summary [macosx] AquaIcon HiDPI support
* @author Alexander Scherbatiy
* @run applet/manual=yesno bug8024926.html