1 /*
2  * Copyright (c) 1997, 2013, 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 java.awt;
27 
28 import java.awt.geom.AffineTransform;
29 import java.awt.image.BufferedImage;
30 import java.awt.image.ColorModel;
31 import java.awt.image.VolatileImage;
32 import java.awt.image.WritableRaster;
33 
34 import sun.awt.image.SunVolatileImage;
35 
36 /**
37  * The {@code GraphicsConfiguration} class describes the
38  * characteristics of a graphics destination such as a printer or monitor.
39  * There can be many {@code GraphicsConfiguration} objects associated
40  * with a single graphics device, representing different drawing modes or
41  * capabilities.  The corresponding native structure will vary from platform
42  * to platform.  For example, on X11 windowing systems,
43  * each visual is a different {@code GraphicsConfiguration}.
44  * On Microsoft Windows, {@code GraphicsConfiguration}s represent
45  * PixelFormats available in the current resolution and color depth.
46  * <p>
47  * In a virtual device multi-screen environment in which the desktop
48  * area could span multiple physical screen devices, the bounds of the
49  * {@code GraphicsConfiguration} objects are relative to the
50  * virtual coordinate system.  When setting the location of a
51  * component, use {@link #getBounds() getBounds} to get the bounds of
52  * the desired {@code GraphicsConfiguration} and offset the location
53  * with the coordinates of the {@code GraphicsConfiguration},
54  * as the following code sample illustrates:
55  * </p>
56  *
57  * <pre>
58  *      Frame f = new Frame(gc);  // where gc is a GraphicsConfiguration
59  *      Rectangle bounds = gc.getBounds();
60  *      f.setLocation(10 + bounds.x, 10 + bounds.y); </pre>
61  *
62  * <p>
63  * To determine if your environment is a virtual device
64  * environment, call {@code getBounds} on all of the
65  * {@code GraphicsConfiguration} objects in your system.  If
66  * any of the origins of the returned bounds is not (0,&nbsp;0),
67  * your environment is a virtual device environment.
68  *
69  * <p>
70  * You can also use {@code getBounds} to determine the bounds
71  * of the virtual device.  To do this, first call {@code getBounds} on all
72  * of the {@code GraphicsConfiguration} objects in your
73  * system.  Then calculate the union of all of the bounds returned
74  * from the calls to {@code getBounds}.  The union is the
75  * bounds of the virtual device.  The following code sample
76  * calculates the bounds of the virtual device.
77  *
78  * <pre>{@code
79  *      Rectangle virtualBounds = new Rectangle();
80  *      GraphicsEnvironment ge = GraphicsEnvironment.
81  *              getLocalGraphicsEnvironment();
82  *      GraphicsDevice[] gs =
83  *              ge.getScreenDevices();
84  *      for (int j = 0; j < gs.length; j++) {
85  *          GraphicsDevice gd = gs[j];
86  *          GraphicsConfiguration[] gc =
87  *              gd.getConfigurations();
88  *          for (int i=0; i < gc.length; i++) {
89  *              virtualBounds =
90  *                  virtualBounds.union(gc[i].getBounds());
91  *          }
92  *      } }</pre>
93  *
94  * @see Window
95  * @see Frame
96  * @see GraphicsEnvironment
97  * @see GraphicsDevice
98  */
99 /*
100  * REMIND:  What to do about capabilities?
101  * The
102  * capabilities of the device can be determined by enumerating the possible
103  * capabilities and checking if the GraphicsConfiguration
104  * implements the interface for that capability.
105  *
106  */
107 public abstract class GraphicsConfiguration {
108 
109     private static BufferCapabilities defaultBufferCaps;
110     private static ImageCapabilities defaultImageCaps;
111 
112     /**
113      * This is an abstract class that cannot be instantiated directly.
114      * Instances must be obtained from a suitable factory or query method.
115      *
116      * @see GraphicsDevice#getConfigurations
117      * @see GraphicsDevice#getDefaultConfiguration
118      * @see GraphicsDevice#getBestConfiguration
119      * @see Graphics2D#getDeviceConfiguration
120      */
GraphicsConfiguration()121     protected GraphicsConfiguration() {
122     }
123 
124     /**
125      * Returns the {@link GraphicsDevice} associated with this
126      * {@code GraphicsConfiguration}.
127      * @return a {@code GraphicsDevice} object that is
128      * associated with this {@code GraphicsConfiguration}.
129      */
getDevice()130     public abstract GraphicsDevice getDevice();
131 
132     /**
133      * Returns a {@link BufferedImage} with a data layout and color model
134      * compatible with this {@code GraphicsConfiguration}.  This
135      * method has nothing to do with memory-mapping
136      * a device.  The returned {@code BufferedImage} has
137      * a layout and color model that is closest to this native device
138      * configuration and can therefore be optimally blitted to this
139      * device.
140      * @param width the width of the returned {@code BufferedImage}
141      * @param height the height of the returned {@code BufferedImage}
142      * @return a {@code BufferedImage} whose data layout and color
143      * model is compatible with this {@code GraphicsConfiguration}.
144      */
createCompatibleImage(int width, int height)145     public BufferedImage createCompatibleImage(int width, int height) {
146         ColorModel model = getColorModel();
147         WritableRaster raster =
148             model.createCompatibleWritableRaster(width, height);
149         return new BufferedImage(model, raster,
150                                  model.isAlphaPremultiplied(), null);
151     }
152 
153     /**
154      * Returns a {@code BufferedImage} that supports the specified
155      * transparency and has a data layout and color model
156      * compatible with this {@code GraphicsConfiguration}.  This
157      * method has nothing to do with memory-mapping
158      * a device. The returned {@code BufferedImage} has a layout and
159      * color model that can be optimally blitted to a device
160      * with this {@code GraphicsConfiguration}.
161      * @param width the width of the returned {@code BufferedImage}
162      * @param height the height of the returned {@code BufferedImage}
163      * @param transparency the specified transparency mode
164      * @return a {@code BufferedImage} whose data layout and color
165      * model is compatible with this {@code GraphicsConfiguration}
166      * and also supports the specified transparency.
167      * @throws IllegalArgumentException if the transparency is not a valid value
168      * @see Transparency#OPAQUE
169      * @see Transparency#BITMASK
170      * @see Transparency#TRANSLUCENT
171      */
createCompatibleImage(int width, int height, int transparency)172     public BufferedImage createCompatibleImage(int width, int height,
173                                                int transparency)
174     {
175         if (getColorModel().getTransparency() == transparency) {
176             return createCompatibleImage(width, height);
177         }
178 
179         ColorModel cm = getColorModel(transparency);
180         if (cm == null) {
181             throw new IllegalArgumentException("Unknown transparency: " +
182                                                transparency);
183         }
184         WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
185         return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
186     }
187 
188 
189     /**
190      * Returns a {@link VolatileImage} with a data layout and color model
191      * compatible with this {@code GraphicsConfiguration}.
192      * The returned {@code VolatileImage}
193      * may have data that is stored optimally for the underlying graphics
194      * device and may therefore benefit from platform-specific rendering
195      * acceleration.
196      * @param width the width of the returned {@code VolatileImage}
197      * @param height the height of the returned {@code VolatileImage}
198      * @return a {@code VolatileImage} whose data layout and color
199      * model is compatible with this {@code GraphicsConfiguration}.
200      * @see Component#createVolatileImage(int, int)
201      * @since 1.4
202      */
createCompatibleVolatileImage(int width, int height)203     public VolatileImage createCompatibleVolatileImage(int width, int height) {
204         VolatileImage vi = null;
205         try {
206             vi = createCompatibleVolatileImage(width, height,
207                                                null, Transparency.OPAQUE);
208         } catch (AWTException e) {
209             // shouldn't happen: we're passing in null caps
210             assert false;
211         }
212         return vi;
213     }
214 
215     /**
216      * Returns a {@link VolatileImage} with a data layout and color model
217      * compatible with this {@code GraphicsConfiguration}.
218      * The returned {@code VolatileImage}
219      * may have data that is stored optimally for the underlying graphics
220      * device and may therefore benefit from platform-specific rendering
221      * acceleration.
222      * @param width the width of the returned {@code VolatileImage}
223      * @param height the height of the returned {@code VolatileImage}
224      * @param transparency the specified transparency mode
225      * @return a {@code VolatileImage} whose data layout and color
226      * model is compatible with this {@code GraphicsConfiguration}.
227      * @throws IllegalArgumentException if the transparency is not a valid value
228      * @see Transparency#OPAQUE
229      * @see Transparency#BITMASK
230      * @see Transparency#TRANSLUCENT
231      * @see Component#createVolatileImage(int, int)
232      * @since 1.5
233      */
createCompatibleVolatileImage(int width, int height, int transparency)234     public VolatileImage createCompatibleVolatileImage(int width, int height,
235                                                        int transparency)
236     {
237         VolatileImage vi = null;
238         try {
239             vi = createCompatibleVolatileImage(width, height, null, transparency);
240         } catch (AWTException e) {
241             // shouldn't happen: we're passing in null caps
242             assert false;
243         }
244         return vi;
245     }
246 
247     /**
248      * Returns a {@link VolatileImage} with a data layout and color model
249      * compatible with this {@code GraphicsConfiguration}, using
250      * the specified image capabilities.
251      * If the {@code caps} parameter is null, it is effectively ignored
252      * and this method will create a VolatileImage without regard to
253      * {@code ImageCapabilities} constraints.
254      *
255      * The returned {@code VolatileImage} has
256      * a layout and color model that is closest to this native device
257      * configuration and can therefore be optimally blitted to this
258      * device.
259      * @return a {@code VolatileImage} whose data layout and color
260      * model is compatible with this {@code GraphicsConfiguration}.
261      * @param width the width of the returned {@code VolatileImage}
262      * @param height the height of the returned {@code VolatileImage}
263      * @param caps the image capabilities
264      * @exception AWTException if the supplied image capabilities could not
265      * be met by this graphics configuration
266      * @since 1.4
267      */
createCompatibleVolatileImage(int width, int height, ImageCapabilities caps)268     public VolatileImage createCompatibleVolatileImage(int width, int height,
269         ImageCapabilities caps) throws AWTException
270     {
271         return createCompatibleVolatileImage(width, height, caps,
272                                              Transparency.OPAQUE);
273     }
274 
275     /**
276      * Returns a {@link VolatileImage} with a data layout and color model
277      * compatible with this {@code GraphicsConfiguration}, using
278      * the specified image capabilities and transparency value.
279      * If the {@code caps} parameter is null, it is effectively ignored
280      * and this method will create a VolatileImage without regard to
281      * {@code ImageCapabilities} constraints.
282      *
283      * The returned {@code VolatileImage} has
284      * a layout and color model that is closest to this native device
285      * configuration and can therefore be optimally blitted to this
286      * device.
287      * @param width the width of the returned {@code VolatileImage}
288      * @param height the height of the returned {@code VolatileImage}
289      * @param caps the image capabilities
290      * @param transparency the specified transparency mode
291      * @return a {@code VolatileImage} whose data layout and color
292      * model is compatible with this {@code GraphicsConfiguration}.
293      * @see Transparency#OPAQUE
294      * @see Transparency#BITMASK
295      * @see Transparency#TRANSLUCENT
296      * @throws IllegalArgumentException if the transparency is not a valid value
297      * @exception AWTException if the supplied image capabilities could not
298      * be met by this graphics configuration
299      * @see Component#createVolatileImage(int, int)
300      * @since 1.5
301      */
createCompatibleVolatileImage(int width, int height, ImageCapabilities caps, int transparency)302     public VolatileImage createCompatibleVolatileImage(int width, int height,
303         ImageCapabilities caps, int transparency) throws AWTException
304     {
305         VolatileImage vi =
306             new SunVolatileImage(this, width, height, transparency, caps);
307         if (caps != null && caps.isAccelerated() &&
308             !vi.getCapabilities().isAccelerated())
309         {
310             throw new AWTException("Supplied image capabilities could not " +
311                                    "be met by this graphics configuration.");
312         }
313         return vi;
314     }
315 
316     /**
317      * Returns the {@link ColorModel} associated with this
318      * {@code GraphicsConfiguration}.
319      * @return a {@code ColorModel} object that is associated with
320      * this {@code GraphicsConfiguration}.
321      */
getColorModel()322     public abstract ColorModel getColorModel();
323 
324     /**
325      * Returns the {@code ColorModel} associated with this
326      * {@code GraphicsConfiguration} that supports the specified
327      * transparency.
328      * @param transparency the specified transparency mode
329      * @return a {@code ColorModel} object that is associated with
330      * this {@code GraphicsConfiguration} and supports the
331      * specified transparency or null if the transparency is not a valid
332      * value.
333      * @see Transparency#OPAQUE
334      * @see Transparency#BITMASK
335      * @see Transparency#TRANSLUCENT
336      */
getColorModel(int transparency)337     public abstract ColorModel getColorModel(int transparency);
338 
339     /**
340      * Returns the default {@link AffineTransform} for this
341      * {@code GraphicsConfiguration}. This
342      * {@code AffineTransform} is typically the Identity transform
343      * for most normal screens.  The default {@code AffineTransform}
344      * maps coordinates onto the device such that 72 user space
345      * coordinate units measure approximately 1 inch in device
346      * space.  The normalizing transform can be used to make
347      * this mapping more exact.  Coordinates in the coordinate space
348      * defined by the default {@code AffineTransform} for screen and
349      * printer devices have the origin in the upper left-hand corner of
350      * the target region of the device, with X coordinates
351      * increasing to the right and Y coordinates increasing downwards.
352      * For image buffers not associated with a device, such as those not
353      * created by {@code createCompatibleImage},
354      * this {@code AffineTransform} is the Identity transform.
355      * @return the default {@code AffineTransform} for this
356      * {@code GraphicsConfiguration}.
357      */
getDefaultTransform()358     public abstract AffineTransform getDefaultTransform();
359 
360     /**
361      * Returns an {@code AffineTransform} that can be concatenated
362      * with the default {@code AffineTransform}
363      * of a {@code GraphicsConfiguration} so that 72 units in user
364      * space equals 1 inch in device space.
365      * <p>
366      * For a particular {@link Graphics2D}, g, one
367      * can reset the transformation to create
368      * such a mapping by using the following pseudocode:
369      * <pre>
370      *      GraphicsConfiguration gc = g.getDeviceConfiguration();
371      *
372      *      g.setTransform(gc.getDefaultTransform());
373      *      g.transform(gc.getNormalizingTransform());
374      * </pre>
375      * Note that sometimes this {@code AffineTransform} is identity,
376      * such as for printers or metafile output, and that this
377      * {@code AffineTransform} is only as accurate as the information
378      * supplied by the underlying system.  For image buffers not
379      * associated with a device, such as those not created by
380      * {@code createCompatibleImage}, this
381      * {@code AffineTransform} is the Identity transform
382      * since there is no valid distance measurement.
383      * @return an {@code AffineTransform} to concatenate to the
384      * default {@code AffineTransform} so that 72 units in user
385      * space is mapped to 1 inch in device space.
386      */
getNormalizingTransform()387     public abstract AffineTransform getNormalizingTransform();
388 
389     /**
390      * Returns the bounds of the {@code GraphicsConfiguration}
391      * in the device coordinates. In a multi-screen environment
392      * with a virtual device, the bounds can have negative X
393      * or Y origins.
394      * @return the bounds of the area covered by this
395      * {@code GraphicsConfiguration}.
396      * @since 1.3
397      */
getBounds()398     public abstract Rectangle getBounds();
399 
400     private static class DefaultBufferCapabilities extends BufferCapabilities {
DefaultBufferCapabilities(ImageCapabilities imageCaps)401         public DefaultBufferCapabilities(ImageCapabilities imageCaps) {
402             super(imageCaps, imageCaps, null);
403         }
404     }
405 
406     /**
407      * Returns the buffering capabilities of this
408      * {@code GraphicsConfiguration}.
409      * @return the buffering capabilities of this graphics
410      * configuration object
411      * @since 1.4
412      */
getBufferCapabilities()413     public BufferCapabilities getBufferCapabilities() {
414         if (defaultBufferCaps == null) {
415             defaultBufferCaps = new DefaultBufferCapabilities(
416                 getImageCapabilities());
417         }
418         return defaultBufferCaps;
419     }
420 
421     /**
422      * Returns the image capabilities of this
423      * {@code GraphicsConfiguration}.
424      * @return the image capabilities of this graphics
425      * configuration object
426      * @since 1.4
427      */
getImageCapabilities()428     public ImageCapabilities getImageCapabilities() {
429         if (defaultImageCaps == null) {
430             defaultImageCaps = new ImageCapabilities(false);
431         }
432         return defaultImageCaps;
433     }
434 
435     /**
436      * Returns whether this {@code GraphicsConfiguration} supports
437      * the {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
438      * PERPIXEL_TRANSLUCENT} kind of translucency.
439      *
440      * @return whether the given GraphicsConfiguration supports
441      *         the translucency effects.
442      *
443      * @see Window#setBackground(Color)
444      *
445      * @since 1.7
446      */
isTranslucencyCapable()447     public boolean isTranslucencyCapable() {
448         // Overridden in subclasses
449         return false;
450     }
451 }
452