src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java
Print this page
@@ -24,48 +24,112 @@
*/
package sun.awt.image;
import java.awt.Image;
import java.awt.Graphics;
+import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
+import java.util.stream.Collectors;
public class MultiResolutionBufferedImage extends BufferedImage
implements MultiResolutionImage {
- Image[] resolutionVariants;
- int baseIndex;
+ private final MultiResolutionImageMapper mapper;
+ private final Dimension2D[] sizes;
- public MultiResolutionBufferedImage(int imageType, int baseIndex, Image... images) {
- super(images[baseIndex].getWidth(null), images[baseIndex].getHeight(null),
- imageType);
- this.baseIndex = baseIndex;
- this.resolutionVariants = images;
+ public MultiResolutionBufferedImage(Image baseImage,
+ Dimension2D[] sizes, MultiResolutionImageMapper mapper) {
+ super(baseImage.getWidth(null), baseImage.getHeight(null),
+ BufferedImage.TYPE_INT_ARGB_PRE);
+ this.sizes = sizes;
+ this.mapper = mapper;
Graphics g = getGraphics();
- g.drawImage(images[baseIndex], 0, 0, null);
+ g.drawImage(baseImage, 0, 0, null);
g.dispose();
- images[baseIndex] = this;
}
@Override
public Image getResolutionVariant(int width, int height) {
- for (Image image : resolutionVariants) {
- if (width <= image.getWidth(null) && height <= image.getHeight(null)) {
- return image;
+ 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);
}
- return this;
+
+ return resolutionVariant;
}
@Override
public List<Image> getResolutionVariants() {
- return Arrays.asList(resolutionVariants);
+ return Arrays.stream(sizes).map((Function<Dimension2D, Image>) size
+ -> getResolutionVariant((int) size.getWidth(),
+ (int) size.getHeight())).collect(Collectors.toList());
}
public MultiResolutionBufferedImage map(Function<Image, Image> mapper) {
- return new MultiResolutionBufferedImage(getType(), baseIndex,
- Arrays.stream(resolutionVariants).map(mapper)
- .toArray(length -> new Image[length]));
+ return new MultiResolutionBufferedImage(mapper.apply(this), sizes,
+ (width, height) ->
+ mapper.apply(getResolutionVariant(width, height)));
+ }
+
+ public interface MultiResolutionImageMapper {
+
+ Image apply(int width, int height);
+ }
+
+ private static class ImageCacheKey implements ImageCache.PixelsKey {
+
+ private final int pixelCount;
+ private final int hash;
+
+ private final int w;
+ private final int h;
+ private final Image baseImage;
+
+ ImageCacheKey(final Image baseImage,
+ final int w, final int h) {
+ this.baseImage = baseImage;
+ this.w = w;
+ this.h = h;
+ this.pixelCount = w * h;
+ hash = hash();
+ }
+
+ @Override
+ public int getPixelCount() {
+ return pixelCount;
+ }
+
+ private int hash() {
+ int hash = baseImage.hashCode();
+ hash = 31 * hash + w;
+ hash = 31 * hash + h;
+ return hash;
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ImageCacheKey) {
+ ImageCacheKey key = (ImageCacheKey) obj;
+ return baseImage == key.baseImage && w == key.w && h == key.h;
+ }
+ return false;
+ }
}
}