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 
SunVolatileImage(Component comp, GraphicsConfiguration graphicsConfig, int width, int height, Object context, int transparency, ImageCapabilities caps, int accType)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 
SunVolatileImage(Component comp, GraphicsConfiguration graphicsConfig, int width, int height, Object context, ImageCapabilities caps)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 
SunVolatileImage(Component comp, int width, int height)107     public SunVolatileImage(Component comp, int width, int height) {
108         this(comp, width, height, null);
109     }
110 
SunVolatileImage(Component comp, int width, int height, Object context)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 
SunVolatileImage(GraphicsConfiguration graphicsConfig, int width, int height, int transparency, ImageCapabilities caps)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 
getWidth()126     public int getWidth() {
127         return width;
128     }
129 
getHeight()130     public int getHeight() {
131         return height;
132     }
133 
getGraphicsConfig()134     public GraphicsConfiguration getGraphicsConfig() {
135         return graphicsConfig;
136     }
137 
updateGraphicsConfig()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 
getComponent()153     public Component getComponent() {
154         return comp;
155     }
156 
getForcedAccelSurfaceType()157     public int getForcedAccelSurfaceType() {
158         return forcedAccelSurfaceType;
159     }
160 
createSurfaceManager(Object context, ImageCapabilities caps)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 
getForeground()186     private Color getForeground() {
187         if (comp != null) {
188             return comp.getForeground();
189         } else {
190             return Color.black;
191         }
192     }
193 
getBackground()194     private Color getBackground() {
195         if (comp != null) {
196             return comp.getBackground();
197         } else {
198             return Color.white;
199         }
200     }
201 
getFont()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 
createGraphics()213     public Graphics2D createGraphics() {
214         return new SunGraphics2D(volSurfaceManager.getPrimarySurfaceData(),
215                                  getForeground(),
216                                  getBackground(),
217                                  getFont());
218     }
219 
220     // Image method implementations
getProperty(String name, ImageObserver observer)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 
getWidth(ImageObserver observer)228     public int getWidth(ImageObserver observer) {
229         return getWidth();
230     }
231 
getHeight(ImageObserver observer)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      */
getBackupImage()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      */
getBackupImage(double scaleX, double scaleY)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 
getSnapshot()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 
validate(GraphicsConfiguration gc)263     public int validate(GraphicsConfiguration gc) {
264         return volSurfaceManager.validate(gc);
265     }
266 
contentsLost()267     public boolean contentsLost() {
268         return volSurfaceManager.contentsLost();
269     }
270 
getCapabilities()271     public ImageCapabilities getCapabilities() {
272         return volSurfaceManager.getCapabilities(graphicsConfig);
273     }
274 
275     /**
276      * {@inheritDoc}
277      *
278      * @see sun.java2d.DestSurfaceProvider#getDestSurface
279      */
280     @Override
getDestSurface()281     public Surface getDestSurface() {
282         return volSurfaceManager.getPrimarySurfaceData();
283     }
284 }
285