--- old/src/java.desktop/share/classes/sun/awt/image/MultiResolutionToolkitImage.java 2016-04-05 17:09:47.000000000 +0400 +++ new/src/java.desktop/share/classes/sun/awt/image/MultiResolutionToolkitImage.java 2016-04-05 17:09:46.000000000 +0400 @@ -25,28 +25,59 @@ package sun.awt.image; import java.awt.Image; +import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; import java.awt.image.MultiResolutionImage; -import java.util.Arrays; +import java.awt.image.ResolutionVariantItem; import java.util.List; +import java.util.stream.Collectors; import sun.misc.SoftCache; public class MultiResolutionToolkitImage extends ToolkitImage implements MultiResolutionImage { - Image resolutionVariant; + List> resolutionVariants; - public MultiResolutionToolkitImage(Image lowResolutionImage, Image resolutionVariant) { - super(lowResolutionImage.getSource()); - this.resolutionVariant = resolutionVariant; + public MultiResolutionToolkitImage(ImageProducer mriProducer) { + super(mriProducer); + this.resolutionVariants = mriProducer.getResolutionVariantItems().stream() + .map((item) -> new ResolutionVariantItem( + new ToolkitImage(item.getValue()), + item.getScaleX(), + item.getScaleY())) + .collect(Collectors.toList()); + } + + public MultiResolutionToolkitImage( + List> resolutionVariants) { + super(resolutionVariants.get(0).getValue().getSource()); + this.resolutionVariants = resolutionVariants; } + @Override public Image getResolutionVariant(double destWidth, double destHeight) { + return getResolutionVariantItem(destWidth, destHeight).getValue(); + } + + public ResolutionVariantItem getResolutionVariantItem( + double destWidth, double destHeight) { checkSize(destWidth, destHeight); - return ((destWidth <= getWidth() && destHeight <= getHeight())) - ? this : resolutionVariant; + int baseWidth = getWidth(); + int baseHeight = getHeight(); + + for (ResolutionVariantItem rvItem : resolutionVariants) { + double sx = rvItem.getScaleX(); + double sy = rvItem.getScaleY(); + if (destWidth <= baseWidth * sx && destHeight <= baseHeight * sy) { + return rvItem; + } + } + + return resolutionVariants.get(resolutionVariants.size() - 1); } + private static void checkSize(double width, double height) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException(String.format( @@ -59,13 +90,25 @@ } } - public Image getResolutionVariant() { - return resolutionVariant; + @Override + public List getResolutionVariants() { + return resolutionVariants.stream() + .map(rvItem -> rvItem.getValue()) + .collect(Collectors.toList()); + } + + public List> getResolutionVariantItems() { + return resolutionVariants; } @Override - public List getResolutionVariants() { - return Arrays.asList(this, resolutionVariant); + public ImageProducer getSource() { + return new MultiResolutionImageProducer(resolutionVariants.stream() + .map(rvItem -> new ResolutionVariantItem<>( + rvItem.getValue().getSource(), + rvItem.getScaleX(), + rvItem.getScaleY())) + .collect(Collectors.toList())); } private static final int BITS_INFO = ImageObserver.SOMEBITS @@ -79,23 +122,17 @@ public static ImageObserver getResolutionVariantObserver( final Image image, final ImageObserver observer, - final int imgWidth, final int imgHeight, - final int rvWidth, final int rvHeight) { - return getResolutionVariantObserver(image, observer, - imgWidth, imgHeight, rvWidth, rvHeight, false); - } - - public static ImageObserver getResolutionVariantObserver( - final Image image, final ImageObserver observer, - final int imgWidth, final int imgHeight, - final int rvWidth, final int rvHeight, boolean concatenateInfo) { + final double scaleX, final double scaleY, + boolean concatenateInfo) { if (observer == null) { return null; } synchronized (ObserverCache.INSTANCE) { - ImageObserver o = (ImageObserver) ObserverCache.INSTANCE.get(observer); + + Object key = new ResolutionVariantItem<>(observer, scaleX, scaleY); + ImageObserver o = (ImageObserver) ObserverCache.INSTANCE.get(key); if (o == null) { @@ -103,16 +140,16 @@ int x, int y, int width, int height) -> { if ((flags & (ImageObserver.WIDTH | BITS_INFO)) != 0) { - width = (width + 1) / 2; + width = (int) Math.floor(width / scaleX); } if ((flags & (ImageObserver.HEIGHT | BITS_INFO)) != 0) { - height = (height + 1) / 2; + height = (int) Math.floor(height / scaleY); } if ((flags & BITS_INFO) != 0) { - x /= 2; - y /= 2; + x = (int) Math.ceil(x / scaleX); + y = (int) Math.ceil(y / scaleY); } if(concatenateInfo){ @@ -124,9 +161,61 @@ image, flags, x, y, width, height); }; - ObserverCache.INSTANCE.put(observer, o); + ObserverCache.INSTANCE.put(key, o); } return o; } } + + public static class MultiResolutionImageProducer implements ImageProducer { + + private final ImageProducer baseImageProducer; + private final List> rvProducers; + + public MultiResolutionImageProducer( + List> rvProducers) + { + this.baseImageProducer = rvProducers.get(0).getValue(); + this.rvProducers = rvProducers; + } + + @Override + public void addConsumer(ImageConsumer ic) { + getBaseImageProducer().addConsumer(ic); + } + + @Override + public boolean isConsumer(ImageConsumer ic) { + return getBaseImageProducer().isConsumer(ic); + } + + @Override + public void removeConsumer(ImageConsumer ic) { + getBaseImageProducer().removeConsumer(ic); + } + + @Override + public void startProduction(ImageConsumer ic) { + getBaseImageProducer().startProduction(ic); + } + + @Override + public void requestTopDownLeftRightResend(ImageConsumer ic) { + getBaseImageProducer().requestTopDownLeftRightResend(ic); + } + + private ImageProducer getBaseImageProducer() { + return baseImageProducer; + } + + @Override + public boolean isMultiResolutionImageProducer() { + return true; + } + + @Override + public List> getResolutionVariantItems() { + return rvProducers; + } + } }