1 /* 2 * Copyright (c) 2006, 2018, 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; 26 import java.awt.*; 27 import java.awt.color.*; 28 import java.awt.geom.AffineTransform; 29 import java.awt.image.*; 30 import sun.awt.image.ToolkitImage; 31 import sun.awt.image.ImageRepresentation; 32 import java.util.Arrays; 33 import sun.java2d.pipe.Region; 34 35 public class IconInfo { 36 /** 37 * Representation of image as an int array. 38 * It's used on platforms where icon data 39 * is expected to be in 32-bit format. 40 */ 41 private int[] intIconData; 42 /** 43 * Representation of image as an long array. 44 * It's used on platforms where icon data 45 * is expected to be in 64-bit format. 46 */ 47 private long[] longIconData; 48 /** 49 * Icon image. 50 */ 51 private Image image; 52 /** 53 * Width of icon image. Being set in constructor. 54 */ 55 private final int width; 56 /** 57 * Height of icon image. Being set in constructor. 58 */ 59 private final int height; 60 /** 61 * Width of scaled icon image. Can be set in setScaledDimension. 62 */ 63 private int scaledWidth; 64 /** 65 * Height of scaled icon image. Can be set in setScaledDimension. 66 */ 67 private int scaledHeight; 68 /** 69 * Length of raw data. Being set in constructor / setScaledDimension. 70 */ 71 private int rawLength; 72 IconInfo(int[] intIconData)73 public IconInfo(int[] intIconData) { 74 this.intIconData = 75 (null == intIconData) ? null : Arrays.copyOf(intIconData, intIconData.length); 76 this.width = intIconData[0]; 77 this.height = intIconData[1]; 78 this.scaledWidth = width; 79 this.scaledHeight = height; 80 this.rawLength = width * height + 2; 81 } 82 IconInfo(long[] longIconData)83 public IconInfo(long[] longIconData) { 84 this.longIconData = 85 (null == longIconData) ? null : Arrays.copyOf(longIconData, longIconData.length); 86 this.width = (int)longIconData[0]; 87 this.height = (int)longIconData[1]; 88 this.scaledWidth = width; 89 this.scaledHeight = height; 90 this.rawLength = width * height + 2; 91 } 92 IconInfo(Image image)93 public IconInfo(Image image) { 94 this.image = image; 95 if (image instanceof ToolkitImage) { 96 ImageRepresentation ir = ((ToolkitImage)image).getImageRep(); 97 ir.reconstruct(ImageObserver.ALLBITS); 98 this.width = ir.getWidth(); 99 this.height = ir.getHeight(); 100 } else { 101 this.width = image.getWidth(null); 102 this.height = image.getHeight(null); 103 } 104 this.scaledWidth = width; 105 this.scaledHeight = height; 106 this.rawLength = getScaledRawLength(width, height); 107 } 108 109 /* 110 * It sets size of scaled icon. 111 */ setScaledSize(int width, int height)112 public void setScaledSize(int width, int height) { 113 this.scaledWidth = width; 114 this.scaledHeight = height; 115 this.rawLength = getScaledRawLength(width, height); 116 } 117 118 /* 119 * returns scaled raw length. 120 */ getScaledRawLength(int w, int h)121 private int getScaledRawLength(int w, int h) { 122 int[] scaledWidthAndHeight = getScaledWidthAndHeight(w, h); 123 return scaledWidthAndHeight[0] * scaledWidthAndHeight[1] + 2; 124 } 125 126 /* 127 * returns the scaled width and height. 128 */ getScaledWidthAndHeight(int width, int height)129 private static int[] getScaledWidthAndHeight(int width, int height) { 130 AffineTransform tx = GraphicsEnvironment.getLocalGraphicsEnvironment(). 131 getDefaultScreenDevice().getDefaultConfiguration(). 132 getDefaultTransform(); 133 int w = Region.clipScale(width, tx.getScaleX()); 134 int h = Region.clipScale(height, tx.getScaleY()); 135 return new int[]{w, h}; 136 } 137 isValid()138 public boolean isValid() { 139 return (width > 0 && height > 0); 140 } 141 getWidth()142 public int getWidth() { 143 return width; 144 } 145 getHeight()146 public int getHeight() { 147 return height; 148 } 149 toString()150 public String toString() { 151 return "IconInfo[w=" + width + ",h=" + height + ",sw=" + scaledWidth + ",sh=" + scaledHeight + "]"; 152 } 153 getRawLength()154 public int getRawLength() { 155 return rawLength; 156 } 157 getIntData()158 public int[] getIntData() { 159 if (this.intIconData == null) { 160 if (this.longIconData != null) { 161 this.intIconData = longArrayToIntArray(longIconData); 162 } else if (this.image != null) { 163 this.intIconData = imageToIntArray(this.image, scaledWidth, scaledHeight); 164 } 165 } 166 return this.intIconData; 167 } 168 getLongData()169 public long[] getLongData() { 170 if (this.longIconData == null) { 171 if (this.intIconData != null) { 172 this.longIconData = intArrayToLongArray(this.intIconData); 173 } else if (this.image != null) { 174 int[] intIconData = imageToIntArray(this.image, scaledWidth, scaledHeight); 175 this.longIconData = intArrayToLongArray(intIconData); 176 } 177 } 178 return this.longIconData; 179 } 180 getImage()181 public Image getImage() { 182 if (this.image == null) { 183 if (this.intIconData != null) { 184 this.image = intArrayToImage(this.intIconData); 185 } else if (this.longIconData != null) { 186 int[] intIconData = longArrayToIntArray(this.longIconData); 187 this.image = intArrayToImage(intIconData); 188 } 189 } 190 return this.image; 191 } 192 longArrayToIntArray(long[] longData)193 private static int[] longArrayToIntArray(long[] longData) { 194 int[] intData = new int[longData.length]; 195 for (int i = 0; i < longData.length; i++) { 196 // Such a conversion is valid since the 197 // original data (see 198 // make/sun/xawt/ToBin.java) were ints 199 intData[i] = (int)longData[i]; 200 } 201 return intData; 202 } 203 intArrayToLongArray(int[] intData)204 private static long[] intArrayToLongArray(int[] intData) { 205 long[] longData = new long[intData.length]; 206 for (int i = 0; i < intData.length; i++) { 207 longData[i] = intData[i]; 208 } 209 return longData; 210 } 211 intArrayToImage(int[] raw)212 static Image intArrayToImage(int[] raw) { 213 ColorModel cm = 214 new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32, 215 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, 216 false, DataBuffer.TYPE_INT); 217 DataBuffer buffer = new DataBufferInt(raw, raw.length-2, 2); 218 WritableRaster raster = 219 Raster.createPackedRaster(buffer, raw[0], raw[1], 220 raw[0], 221 new int[] {0x00ff0000, 0x0000ff00, 222 0x000000ff, 0xff000000}, 223 null); 224 BufferedImage im = new BufferedImage(cm, raster, false, null); 225 return im; 226 } 227 228 /* 229 * Returns array of integers which holds data for the image. 230 * It scales the image if necessary. 231 */ imageToIntArray(Image image, int width, int height)232 static int[] imageToIntArray(Image image, int width, int height) { 233 if (width <= 0 || height <= 0) { 234 return null; 235 } 236 ColorModel cm = 237 new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32, 238 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, 239 false, DataBuffer.TYPE_INT); 240 int[] scaledWidthAndHeight = getScaledWidthAndHeight(width, height); 241 width = scaledWidthAndHeight[0]; 242 height = scaledWidthAndHeight[1]; 243 DataBufferInt buffer = new DataBufferInt(width * height); 244 WritableRaster raster = 245 Raster.createPackedRaster(buffer, width, height, 246 width, 247 new int[] {0x00ff0000, 0x0000ff00, 248 0x000000ff, 0xff000000}, 249 null); 250 BufferedImage im = new BufferedImage(cm, raster, false, null); 251 Graphics g = im.getGraphics(); 252 g.drawImage(image, 0, 0, width, height, null); 253 g.dispose(); 254 int[] data = buffer.getData(); 255 int[] raw = new int[width * height + 2]; 256 raw[0] = width; 257 raw[1] = height; 258 System.arraycopy(data, 0, raw, 2, width * height); 259 return raw; 260 } 261 262 } 263