1 /* 2 * Copyright (c) 2000, 2008, 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.AlphaComposite; 29 import java.awt.Color; 30 import java.awt.Component; 31 import java.awt.Font; 32 import java.awt.Graphics2D; 33 import java.awt.GraphicsConfiguration; 34 import java.awt.ImageCapabilities; 35 import java.awt.Transparency; 36 import java.awt.image.BufferedImage; 37 import java.awt.image.ImageObserver; 38 import java.awt.image.VolatileImage; 39 import sun.java2d.SunGraphics2D; 40 import sun.java2d.SurfaceManagerFactory; 41 import sun.java2d.DestSurfaceProvider; 42 import sun.java2d.Surface; 43 import sun.java2d.pipe.Region; 44 import static sun.java2d.pipe.hw.AccelSurface.*; 45 46 /** 47 * This class is the base implementation of the VolatileImage 48 * abstract class. The class implements most of the standard Image 49 * methods (width, height, etc.) but delegates all surface management 50 * issues to a platform-specific VolatileSurfaceManager. When a new instance 51 * of SunVolatileImage is created, it automatically creates an 52 * appropriate VolatileSurfaceManager for the GraphicsConfiguration 53 * under which this SunVolatileImage was created. 54 */ 55 public class SunVolatileImage extends VolatileImage 56 implements DestSurfaceProvider 57 { 58 59 protected VolatileSurfaceManager volSurfaceManager; 60 protected Component comp; 61 private GraphicsConfiguration graphicsConfig; 62 private Font defaultFont; 63 private int width, height; 64 private int forcedAccelSurfaceType; 65 66 protected SunVolatileImage(Component comp, 67 GraphicsConfiguration graphicsConfig, 68 int width, int height, Object context, 69 int transparency, ImageCapabilities caps, 70 int accType) 71 { 72 this.comp = comp; 73 this.graphicsConfig = graphicsConfig; 74 if (width <= 0 || height <= 0) { 75 throw new IllegalArgumentException("Width (" + width + ")" + 76 " and height (" + height + ") cannot be <= 0"); 77 } 78 this.width = width; 79 this.height = height; 80 this.forcedAccelSurfaceType = accType; 81 if (!(transparency == Transparency.OPAQUE || 82 transparency == Transparency.BITMASK || 83 transparency == Transparency.TRANSLUCENT)) 84 { 85 throw new IllegalArgumentException("Unknown transparency type:" + 86 transparency); 87 } 88 this.transparency = transparency; 89 this.volSurfaceManager = createSurfaceManager(context, caps); 90 SurfaceManager.setManager(this, volSurfaceManager); 91 92 // post-construction initialization of the surface manager 93 volSurfaceManager.initialize(); 94 // clear the background 95 volSurfaceManager.initContents(); 96 } 97 98 private SunVolatileImage(Component comp, 99 GraphicsConfiguration graphicsConfig, 100 int width, int height, Object context, 101 ImageCapabilities caps) 102 { 103 this(comp, graphicsConfig, 104 width, height, context, Transparency.OPAQUE, caps, UNDEFINED); 105 } 106 107 public SunVolatileImage(Component comp, int width, int height) { 108 this(comp, width, height, null); 109 } 110 111 public SunVolatileImage(Component comp, 112 int width, int height, Object context) 113 { 114 this(comp, comp.getGraphicsConfiguration(), 115 width, height, context, null); 116 } 117 118 public SunVolatileImage(GraphicsConfiguration graphicsConfig, 119 int width, int height, int transparency, 120 ImageCapabilities caps) 121 { 122 this(null, graphicsConfig, width, height, null, transparency, 123 caps, UNDEFINED); 124 } 125 126 public int getWidth() { 127 return width; 128 } 129 130 public int getHeight() { 131 return height; 132 } 133 134 public GraphicsConfiguration getGraphicsConfig() { 135 return graphicsConfig; 136 } 137 138 public void updateGraphicsConfig() { 139 // If this VImage is associated with a Component, get an updated 140 // graphicsConfig from that component. Otherwise, keep the one 141 // that we were created with 142 if (comp != null) { 143 GraphicsConfiguration gc = comp.getGraphicsConfiguration(); 144 if (gc != null) { 145 // Could potentially be null in some failure situations; 146 // better to keep the old non-null value around than to 147 // set graphicsConfig to null 148 graphicsConfig = gc; 149 } 150 } 151 } 152 153 public Component getComponent() { 154 return comp; 155 } 156 157 public int getForcedAccelSurfaceType() { 158 return forcedAccelSurfaceType; 159 } 160 161 protected VolatileSurfaceManager createSurfaceManager(Object context, 162 ImageCapabilities caps) 163 { 164 /** 165 * Platform-specific SurfaceManagerFactories will return a 166 * manager suited to acceleration on each platform. But if 167 * the user is asking for a VolatileImage from a BufferedImageGC, 168 * then we need to return the appropriate unaccelerated manager. 169 * Note: this could change in the future; if some platform would 170 * like to accelerate BIGC volatile images, then this special-casing 171 * of the BIGC graphicsConfig should live in platform-specific 172 * code instead. 173 * We do the same for a Printer Device, and if user requested an 174 * unaccelerated VolatileImage by passing the capabilities object. 175 */ 176 if (graphicsConfig instanceof BufferedImageGraphicsConfig || 177 graphicsConfig instanceof sun.print.PrinterGraphicsConfig || 178 (caps != null && !caps.isAccelerated())) 179 { 180 return new BufImgVolatileSurfaceManager(this, context); 181 } 182 SurfaceManagerFactory smf = SurfaceManagerFactory.getInstance(); 183 return smf.createVolatileManager(this, context); 184 } 185 186 private Color getForeground() { 187 if (comp != null) { 188 return comp.getForeground(); 189 } else { 190 return Color.black; 191 } 192 } 193 194 private Color getBackground() { 195 if (comp != null) { 196 return comp.getBackground(); 197 } else { 198 return Color.white; 199 } 200 } 201 202 private Font getFont() { 203 if (comp != null) { 204 return comp.getFont(); 205 } else { 206 if (defaultFont == null) { 207 defaultFont = new Font("Dialog", Font.PLAIN, 12); 208 } 209 return defaultFont; 210 } 211 } 212 213 public Graphics2D createGraphics() { 214 return new SunGraphics2D(volSurfaceManager.getPrimarySurfaceData(), 215 getForeground(), 216 getBackground(), 217 getFont()); 218 } 219 220 // Image method implementations 221 public Object getProperty(String name, ImageObserver observer) { 222 if (name == null) { 223 throw new NullPointerException("null property name is not allowed"); 224 } 225 return java.awt.Image.UndefinedProperty; 226 } 227 228 public int getWidth(ImageObserver observer) { 229 return getWidth(); 230 } 231 232 public int getHeight(ImageObserver observer) { 233 return getHeight(); 234 } 235 236 /** 237 * This method creates a BufferedImage intended for use as a "snapshot" 238 * or a backup surface. 239 */ 240 public BufferedImage getBackupImage() { 241 return getBackupImage(1, 1); 242 } 243 244 /** 245 * This method creates a BufferedImage intended for use as a "snapshot" 246 * or a backup surface with the given horizontal and vertical scale factors. 247 */ 248 public BufferedImage getBackupImage(double scaleX, double scaleY) { 249 int w = Region.clipRound(getWidth() * scaleX); 250 int h = Region.clipRound(getHeight() * scaleY); 251 return graphicsConfig.createCompatibleImage(w, h, getTransparency()); 252 } 253 254 public BufferedImage getSnapshot() { 255 BufferedImage bi = getBackupImage(); 256 Graphics2D g = bi.createGraphics(); 257 g.setComposite(AlphaComposite.Src); 258 g.drawImage(this, 0, 0, null); 259 g.dispose(); 260 return bi; 261 } 262 263 public int validate(GraphicsConfiguration gc) { 264 return volSurfaceManager.validate(gc); 265 } 266 267 public boolean contentsLost() { 268 return volSurfaceManager.contentsLost(); 269 } 270 271 public ImageCapabilities getCapabilities() { 272 return volSurfaceManager.getCapabilities(graphicsConfig); 273 } 274 275 /** 276 * {@inheritDoc} 277 * 278 * @see sun.java2d.DestSurfaceProvider#getDestSurface 279 */ 280 @Override 281 public Surface getDestSurface() { 282 return volSurfaceManager.getPrimarySurfaceData(); 283 } 284 }