src/share/classes/sun/awt/image/MultiResolutionBufferedImage.java

Print this page

        

*** 24,71 **** */ package sun.awt.image; import java.awt.Image; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class MultiResolutionBufferedImage extends BufferedImage implements MultiResolutionImage { ! Image[] resolutionVariants; ! int baseIndex; ! ! public MultiResolutionBufferedImage(int imageType, int baseIndex, Image... images) { ! super(images[baseIndex].getWidth(null), images[baseIndex].getHeight(null), ! imageType); ! this.baseIndex = baseIndex; ! this.resolutionVariants = images; Graphics g = getGraphics(); ! g.drawImage(images[baseIndex], 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; } } ! return this; } @Override public List<Image> getResolutionVariants() { ! return Arrays.asList(resolutionVariants); } public MultiResolutionBufferedImage map(Function<Image, Image> mapper) { ! return new MultiResolutionBufferedImage(getType(), baseIndex, ! Arrays.stream(resolutionVariants).map(mapper) ! .toArray(length -> new Image[length])); } } --- 24,177 ---- */ package sun.awt.image; 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; import java.util.function.Function; + import java.util.function.BiFunction; + import java.util.stream.Collectors; public class MultiResolutionBufferedImage extends BufferedImage implements MultiResolutionImage { ! private final BiFunction<Integer, Integer, Image> mapper; ! private final Dimension2D[] sizes; ! private int availableInfo; ! ! public MultiResolutionBufferedImage(Image baseImage, ! Dimension2D[] sizes, BiFunction<Integer, Integer, Image> mapper) { ! super(baseImage.getWidth(null), baseImage.getHeight(null), ! BufferedImage.TYPE_INT_ARGB_PRE); ! 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); } ! ! return resolutionVariant; } @Override public List<Image> getResolutionVariants() { ! 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(mapper.apply(this), sizes, ! (width, height) -> ! mapper.apply(getResolutionVariant(width, height))); ! } ! ! @Override ! public int getWidth(ImageObserver observer) { ! availableInfo |= ImageObserver.WIDTH; ! return super.getWidth(observer); ! } ! ! @Override ! public int getHeight(ImageObserver observer) { ! availableInfo |= ImageObserver.HEIGHT; ! return super.getHeight(observer); ! } ! ! @Override ! public Object getProperty(String name, ImageObserver observer) { ! availableInfo |= ImageObserver.PROPERTIES; ! return super.getProperty(name, observer); ! } ! ! private static int getInfo(Image image) { ! if (image instanceof ToolkitImage) { ! return ((ToolkitImage) image).getImageRep().check( ! (img, infoflags, x, y, w, h) -> false); ! } ! return 0; ! } ! ! private static void preload(Image image, int availableInfo) { ! if (image instanceof ToolkitImage) { ! ((ToolkitImage) image).preload(new ImageObserver() { ! int flags = availableInfo; ! ! @Override ! public boolean imageUpdate(Image img, int infoflags, ! int x, int y, int width, int height) { ! flags &= ~infoflags; ! return (flags != 0) && ((infoflags ! & (ImageObserver.ERROR | ImageObserver.ABORT)) == 0); ! } ! }); ! } ! } ! ! 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; ! } } } \ No newline at end of file