1 /* 2 * Copyright (c) 1997, 2019, 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 26 package sun.awt.image; 27 28 import java.awt.Component; 29 import java.awt.Graphics2D; 30 import java.awt.GraphicsConfiguration; 31 import java.awt.GraphicsDevice; 32 import java.awt.Rectangle; 33 import java.awt.Transparency; 34 import java.awt.geom.AffineTransform; 35 import java.awt.image.BufferedImage; 36 import java.awt.image.ColorModel; 37 import java.awt.image.DirectColorModel; 38 import java.awt.image.Raster; 39 import java.awt.image.WritableRaster; 40 41 public final class BufferedImageGraphicsConfig extends GraphicsConfiguration { 42 43 private static final int numconfigs = BufferedImage.TYPE_BYTE_BINARY; 44 private static BufferedImageGraphicsConfig[] standardConfigs = 45 new BufferedImageGraphicsConfig[numconfigs]; 46 private static BufferedImageGraphicsConfig[] scaledConfigs = 47 new BufferedImageGraphicsConfig[numconfigs]; 48 getConfig(BufferedImage bImg)49 public static BufferedImageGraphicsConfig getConfig(BufferedImage bImg) { 50 return getConfig(bImg, 1, 1); 51 } 52 getConfig(BufferedImage bImg, double scaleX, double scaleY)53 public static BufferedImageGraphicsConfig getConfig(BufferedImage bImg, 54 double scaleX, 55 double scaleY) 56 { 57 BufferedImageGraphicsConfig ret; 58 int type = bImg.getType(); 59 60 BufferedImageGraphicsConfig[] configs = (scaleX == 1 && scaleY == 1) 61 ? standardConfigs : scaledConfigs; 62 63 if (type > 0 && type < numconfigs) { 64 ret = configs[type]; 65 if (ret != null && ret.scaleX == scaleX && ret.scaleY == scaleY) { 66 return ret; 67 } 68 } 69 ret = new BufferedImageGraphicsConfig(bImg, null, scaleX, scaleY); 70 if (type > 0 && type < numconfigs) { 71 configs[type] = ret; 72 } 73 return ret; 74 } 75 76 private final GraphicsDevice device; 77 private final ColorModel model; 78 private final Raster raster; 79 private final double scaleX; 80 private final double scaleY; 81 BufferedImageGraphicsConfig(BufferedImage bufImg, Component comp, double scaleX, double scaleY)82 public BufferedImageGraphicsConfig(BufferedImage bufImg, Component comp, 83 double scaleX, double scaleY) 84 { 85 if (comp == null) { 86 device = new BufferedImageDevice(this); 87 } else { 88 Graphics2D g2d = (Graphics2D)comp.getGraphics(); 89 device = g2d.getDeviceConfiguration().getDevice(); 90 } 91 this.model = bufImg.getColorModel(); 92 this.raster = bufImg.getRaster().createCompatibleWritableRaster(1, 1); 93 this.scaleX = scaleX; 94 this.scaleY = scaleY; 95 } 96 97 /** 98 * Return the graphics device associated with this configuration. 99 */ 100 @Override getDevice()101 public GraphicsDevice getDevice() { 102 return device; 103 } 104 105 /** 106 * Returns a BufferedImage with channel layout and color model 107 * compatible with this graphics configuration. This method 108 * has nothing to do with memory-mapping 109 * a device. This BufferedImage has 110 * a layout and color model 111 * that is closest to this native device configuration and thus 112 * can be optimally blitted to this device. 113 */ 114 @Override createCompatibleImage(int width, int height)115 public BufferedImage createCompatibleImage(int width, int height) { 116 WritableRaster wr = raster.createCompatibleWritableRaster(width, height); 117 return new BufferedImage(model, wr, model.isAlphaPremultiplied(), null); 118 } 119 120 /** 121 * Returns the color model associated with this configuration. 122 */ 123 @Override getColorModel()124 public ColorModel getColorModel() { 125 return model; 126 } 127 128 /** 129 * Returns the color model associated with this configuration that 130 * supports the specified transparency. 131 */ 132 @Override getColorModel(int transparency)133 public ColorModel getColorModel(int transparency) { 134 135 if (model.getTransparency() == transparency) { 136 return model; 137 } 138 switch (transparency) { 139 case Transparency.OPAQUE: 140 return new DirectColorModel(24, 0xff0000, 0xff00, 0xff); 141 case Transparency.BITMASK: 142 return new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000); 143 case Transparency.TRANSLUCENT: 144 return ColorModel.getRGBdefault(); 145 default: 146 return null; 147 } 148 } 149 150 /** 151 * Returns the default Transform for this configuration. This 152 * Transform is typically the Identity transform for most normal 153 * screens. Device coordinates for screen and printer devices will 154 * have the origin in the upper left-hand corner of the target region of 155 * the device, with X coordinates 156 * increasing to the right and Y coordinates increasing downwards. 157 * For image buffers, this Transform will be the Identity transform. 158 */ 159 @Override getDefaultTransform()160 public AffineTransform getDefaultTransform() { 161 return AffineTransform.getScaleInstance(scaleX, scaleY); 162 } 163 164 /** 165 * 166 * Returns a Transform that can be composed with the default Transform 167 * of a Graphics2D so that 72 units in user space will equal 1 inch 168 * in device space. 169 * Given a Graphics2D, g, one can reset the transformation to create 170 * such a mapping by using the following pseudocode: 171 * <pre> 172 * GraphicsConfiguration gc = g.getGraphicsConfiguration(); 173 * 174 * g.setTransform(gc.getDefaultTransform()); 175 * g.transform(gc.getNormalizingTransform()); 176 * </pre> 177 * Note that sometimes this Transform will be identity (e.g. for 178 * printers or metafile output) and that this Transform is only 179 * as accurate as the information supplied by the underlying system. 180 * For image buffers, this Transform will be the Identity transform, 181 * since there is no valid distance measurement. 182 */ 183 @Override getNormalizingTransform()184 public AffineTransform getNormalizingTransform() { 185 return new AffineTransform(); 186 } 187 188 @Override getBounds()189 public Rectangle getBounds() { 190 return new Rectangle(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); 191 } 192 } 193