1 /* 2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package sun.awt.image; 26 27 import java.awt.Image; 28 import java.awt.image.ImageObserver; 29 import java.awt.image.MultiResolutionImage; 30 import java.util.Arrays; 31 import java.util.List; 32 import java.util.function.Function; 33 import sun.awt.SoftCache; 34 35 public class MultiResolutionToolkitImage extends ToolkitImage implements MultiResolutionImage { 36 37 Image resolutionVariant; 38 39 public MultiResolutionToolkitImage(Image lowResolutionImage, Image resolutionVariant) { 40 super(lowResolutionImage.getSource()); 41 this.resolutionVariant = resolutionVariant; 42 } 43 44 @Override 45 public Image getResolutionVariant(double destWidth, double destHeight) { 46 checkSize(destWidth, destHeight); 47 return ((destWidth <= getWidth() && destHeight <= getHeight())) 48 ? this : resolutionVariant; 49 } 50 51 public static Image map(MultiResolutionToolkitImage mrImage, 52 Function<Image, Image> mapper) { 53 Image baseImage = mapper.apply(mrImage); 54 Image rvImage = mapper.apply(mrImage.resolutionVariant); 55 return new MultiResolutionToolkitImage(baseImage, rvImage); 56 } 57 58 private static void checkSize(double width, double height) { 59 if (width <= 0 || height <= 0) { 60 throw new IllegalArgumentException(String.format( 61 "Width (%s) or height (%s) cannot be <= 0", width, height)); 62 } 63 64 if (!Double.isFinite(width) || !Double.isFinite(height)) { 65 throw new IllegalArgumentException(String.format( 66 "Width (%s) or height (%s) is not finite", width, height)); 67 } 68 } 69 70 public Image getResolutionVariant() { 71 return resolutionVariant; 72 } 73 74 @Override 75 public List<Image> getResolutionVariants() { 76 return Arrays.<Image>asList(this, resolutionVariant); 77 } 78 79 private static final int BITS_INFO = ImageObserver.SOMEBITS 80 | ImageObserver.FRAMEBITS | ImageObserver.ALLBITS; 81 82 private static class ObserverCache { 83 84 @SuppressWarnings("deprecation") 85 static final SoftCache INSTANCE = new SoftCache(); 86 } 87 88 public static ImageObserver getResolutionVariantObserver( 89 final Image image, final ImageObserver observer, 90 final int imgWidth, final int imgHeight, 91 final int rvWidth, final int rvHeight) { 92 return getResolutionVariantObserver(image, observer, 93 imgWidth, imgHeight, rvWidth, rvHeight, false); 94 } 95 96 public static ImageObserver getResolutionVariantObserver( 97 final Image image, final ImageObserver observer, 98 final int imgWidth, final int imgHeight, 99 final int rvWidth, final int rvHeight, boolean concatenateInfo) { 100 101 if (observer == null) { 102 return null; 103 } 104 105 synchronized (ObserverCache.INSTANCE) { 106 ImageObserver o = (ImageObserver) ObserverCache.INSTANCE.get(observer); 107 108 if (o == null) { 109 110 o = (Image resolutionVariant, int flags, 111 int x, int y, int width, int height) -> { 112 113 if ((flags & (ImageObserver.WIDTH | BITS_INFO)) != 0) { 114 width = (width + 1) / 2; 115 } 116 117 if ((flags & (ImageObserver.HEIGHT | BITS_INFO)) != 0) { 118 height = (height + 1) / 2; 119 } 120 121 if ((flags & BITS_INFO) != 0) { 122 x /= 2; 123 y /= 2; 124 } 125 126 if(concatenateInfo){ 127 flags &= ((ToolkitImage) image). 128 getImageRep().check(null); 129 } 130 131 return observer.imageUpdate( 132 image, flags, x, y, width, height); 133 }; 134 135 ObserverCache.INSTANCE.put(observer, o); 136 } 137 return o; 138 } 139 } 140 }