1 /*
2 * Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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</code> class describes the
38 * characteristics of a graphics destination such as a printer or monitor.
39 * There can be many <code>GraphicsConfiguration</code> 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</code>.
44 * On Microsoft Windows, <code>GraphicsConfiguration</code>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</code> 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</code> and offset the location
53 * with the coordinates of the <code>GraphicsConfiguration</code>,
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</code> on all of the
65 * <code>GraphicsConfiguration</code> objects in your system. If
66 * any of the origins of the returned bounds is not (0, 0),
67 * your environment is a virtual device environment.
68 *
69 * <p>
70 * You can also use <code>getBounds</code> to determine the bounds
71 * of the virtual device. To do this, first call <code>getBounds</code> on all
72 * of the <code>GraphicsConfiguration</code> objects in your
73 * system. Then calculate the union of all of the bounds returned
74 * from the calls to <code>getBounds</code>. 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>
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
108
109 public abstract class GraphicsConfiguration {
110
111 private static BufferCapabilities defaultBufferCaps;
112 private static ImageCapabilities defaultImageCaps;
113
114 /**
115 * This is an abstract class that cannot be instantiated directly.
116 * Instances must be obtained from a suitable factory or query method.
117 *
118 * @see GraphicsDevice#getConfigurations
119 * @see GraphicsDevice#getDefaultConfiguration
120 * @see GraphicsDevice#getBestConfiguration
121 * @see Graphics2D#getDeviceConfiguration
122 */
123 protected GraphicsConfiguration() {
124 }
125
126 /**
127 * Returns the {@link GraphicsDevice} associated with this
128 * <code>GraphicsConfiguration</code>.
129 * @return a <code>GraphicsDevice</code> object that is
130 * associated with this <code>GraphicsConfiguration</code>.
131 */
132 public abstract GraphicsDevice getDevice();
133
134 /**
135 * Returns a {@link BufferedImage} with a data layout and color model
136 * compatible with this <code>GraphicsConfiguration</code>. This
137 * method has nothing to do with memory-mapping
138 * a device. The returned <code>BufferedImage</code> has
139 * a layout and color model that is closest to this native device
140 * configuration and can therefore be optimally blitted to this
141 * device.
142 * @param width the width of the returned <code>BufferedImage</code>
143 * @param height the height of the returned <code>BufferedImage</code>
144 * @return a <code>BufferedImage</code> whose data layout and color
145 * model is compatible with this <code>GraphicsConfiguration</code>.
146 */
147 public BufferedImage createCompatibleImage(int width, int height) {
148 ColorModel model = getColorModel();
149 WritableRaster raster =
150 model.createCompatibleWritableRaster(width, height);
151 return new BufferedImage(model, raster,
152 model.isAlphaPremultiplied(), null);
153 }
154
155 /**
156 * Returns a <code>BufferedImage</code> that supports the specified
157 * transparency and has a data layout and color model
158 * compatible with this <code>GraphicsConfiguration</code>. This
159 * method has nothing to do with memory-mapping
160 * a device. The returned <code>BufferedImage</code> has a layout and
161 * color model that can be optimally blitted to a device
162 * with this <code>GraphicsConfiguration</code>.
163 * @param width the width of the returned <code>BufferedImage</code>
164 * @param height the height of the returned <code>BufferedImage</code>
165 * @param transparency the specified transparency mode
166 * @return a <code>BufferedImage</code> whose data layout and color
167 * model is compatible with this <code>GraphicsConfiguration</code>
168 * and also supports the specified transparency.
169 * @throws IllegalArgumentException if the transparency is not a valid value
170 * @see Transparency#OPAQUE
171 * @see Transparency#BITMASK
172 * @see Transparency#TRANSLUCENT
173 */
174 public BufferedImage createCompatibleImage(int width, int height,
175 int transparency)
176 {
177 if (getColorModel().getTransparency() == transparency) {
178 return createCompatibleImage(width, height);
179 }
180
181 ColorModel cm = getColorModel(transparency);
182 if (cm == null) {
183 throw new IllegalArgumentException("Unknown transparency: " +
184 transparency);
185 }
186 WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
187 return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
188 }
189
190
191 /**
192 * Returns a {@link VolatileImage} with a data layout and color model
193 * compatible with this <code>GraphicsConfiguration</code>.
194 * The returned <code>VolatileImage</code>
195 * may have data that is stored optimally for the underlying graphics
196 * device and may therefore benefit from platform-specific rendering
197 * acceleration.
198 * @param width the width of the returned <code>VolatileImage</code>
199 * @param height the height of the returned <code>VolatileImage</code>
200 * @return a <code>VolatileImage</code> whose data layout and color
201 * model is compatible with this <code>GraphicsConfiguration</code>.
202 * @see Component#createVolatileImage(int, int)
203 * @since 1.4
204 */
205 public VolatileImage createCompatibleVolatileImage(int width, int height) {
206 VolatileImage vi = null;
207 try {
208 vi = createCompatibleVolatileImage(width, height,
209 null, Transparency.OPAQUE);
210 } catch (AWTException e) {
211 // shouldn't happen: we're passing in null caps
212 assert false;
213 }
214 return vi;
215 }
216
217 /**
218 * Returns a {@link VolatileImage} with a data layout and color model
219 * compatible with this <code>GraphicsConfiguration</code>.
220 * The returned <code>VolatileImage</code>
221 * may have data that is stored optimally for the underlying graphics
222 * device and may therefore benefit from platform-specific rendering
223 * acceleration.
224 * @param width the width of the returned <code>VolatileImage</code>
225 * @param height the height of the returned <code>VolatileImage</code>
226 * @param transparency the specified transparency mode
227 * @return a <code>VolatileImage</code> whose data layout and color
228 * model is compatible with this <code>GraphicsConfiguration</code>.
229 * @throws IllegalArgumentException if the transparency is not a valid value
230 * @see Transparency#OPAQUE
231 * @see Transparency#BITMASK
232 * @see Transparency#TRANSLUCENT
233 * @see Component#createVolatileImage(int, int)
234 * @since 1.5
235 */
236 public VolatileImage createCompatibleVolatileImage(int width, int height,
237 int transparency)
238 {
239 VolatileImage vi = null;
240 try {
241 vi = createCompatibleVolatileImage(width, height, null, transparency);
242 } catch (AWTException e) {
243 // shouldn't happen: we're passing in null caps
244 assert false;
245 }
246 return vi;
247 }
248
249 /**
250 * Returns a {@link VolatileImage} with a data layout and color model
251 * compatible with this <code>GraphicsConfiguration</code>, using
252 * the specified image capabilities.
253 * If the <code>caps</code> parameter is null, it is effectively ignored
254 * and this method will create a VolatileImage without regard to
255 * <code>ImageCapabilities</code> constraints.
256 *
257 * The returned <code>VolatileImage</code> has
258 * a layout and color model that is closest to this native device
259 * configuration and can therefore be optimally blitted to this
260 * device.
261 * @return a <code>VolatileImage</code> whose data layout and color
262 * model is compatible with this <code>GraphicsConfiguration</code>.
263 * @param width the width of the returned <code>VolatileImage</code>
264 * @param height the height of the returned <code>VolatileImage</code>
265 * @param caps the image capabilities
266 * @exception AWTException if the supplied image capabilities could not
267 * be met by this graphics configuration
268 * @since 1.4
269 */
270 public VolatileImage createCompatibleVolatileImage(int width, int height,
271 ImageCapabilities caps) throws AWTException
272 {
273 return createCompatibleVolatileImage(width, height, caps,
274 Transparency.OPAQUE);
275 }
276
277 /**
278 * Returns a {@link VolatileImage} with a data layout and color model
279 * compatible with this <code>GraphicsConfiguration</code>, using
280 * the specified image capabilities and transparency value.
281 * If the <code>caps</code> parameter is null, it is effectively ignored
282 * and this method will create a VolatileImage without regard to
283 * <code>ImageCapabilities</code> constraints.
284 *
285 * The returned <code>VolatileImage</code> has
286 * a layout and color model that is closest to this native device
287 * configuration and can therefore be optimally blitted to this
288 * device.
289 * @param width the width of the returned <code>VolatileImage</code>
290 * @param height the height of the returned <code>VolatileImage</code>
291 * @param caps the image capabilities
292 * @param transparency the specified transparency mode
293 * @return a <code>VolatileImage</code> whose data layout and color
294 * model is compatible with this <code>GraphicsConfiguration</code>.
295 * @see Transparency#OPAQUE
296 * @see Transparency#BITMASK
297 * @see Transparency#TRANSLUCENT
298 * @throws IllegalArgumentException if the transparency is not a valid value
299 * @exception AWTException if the supplied image capabilities could not
300 * be met by this graphics configuration
301 * @see Component#createVolatileImage(int, int)
302 * @since 1.5
303 */
304 public VolatileImage createCompatibleVolatileImage(int width, int height,
305 ImageCapabilities caps, int transparency) throws AWTException
306 {
307 VolatileImage vi =
308 new SunVolatileImage(this, width, height, transparency, caps);
309 if (caps != null && caps.isAccelerated() &&
310 !vi.getCapabilities().isAccelerated())
311 {
312 throw new AWTException("Supplied image capabilities could not " +
313 "be met by this graphics configuration.");
314 }
315 return vi;
316 }
317
318 /**
319 * Returns the {@link ColorModel} associated with this
320 * <code>GraphicsConfiguration</code>.
321 * @return a <code>ColorModel</code> object that is associated with
322 * this <code>GraphicsConfiguration</code>.
323 */
324 public abstract ColorModel getColorModel();
325
326 /**
327 * Returns the <code>ColorModel</code> associated with this
328 * <code>GraphicsConfiguration</code> that supports the specified
329 * transparency.
330 * @param transparency the specified transparency mode
331 * @return a <code>ColorModel</code> object that is associated with
332 * this <code>GraphicsConfiguration</code> and supports the
333 * specified transparency or null if the transparency is not a valid
334 * value.
335 * @see Transparency#OPAQUE
336 * @see Transparency#BITMASK
337 * @see Transparency#TRANSLUCENT
338 */
339 public abstract ColorModel getColorModel(int transparency);
340
341 /**
342 * Returns the default {@link AffineTransform} for this
343 * <code>GraphicsConfiguration</code>. This
344 * <code>AffineTransform</code> is typically the Identity transform
345 * for most normal screens. The default <code>AffineTransform</code>
346 * maps coordinates onto the device such that 72 user space
347 * coordinate units measure approximately 1 inch in device
348 * space. The normalizing transform can be used to make
349 * this mapping more exact. Coordinates in the coordinate space
350 * defined by the default <code>AffineTransform</code> for screen and
351 * printer devices have the origin in the upper left-hand corner of
352 * the target region of the device, with X coordinates
353 * increasing to the right and Y coordinates increasing downwards.
354 * For image buffers not associated with a device, such as those not
355 * created by <code>createCompatibleImage</code>,
356 * this <code>AffineTransform</code> is the Identity transform.
357 * @return the default <code>AffineTransform</code> for this
358 * <code>GraphicsConfiguration</code>.
359 */
360 public abstract AffineTransform getDefaultTransform();
361
362 /**
363 *
364 * Returns a <code>AffineTransform</code> that can be concatenated
365 * with the default <code>AffineTransform</code>
366 * of a <code>GraphicsConfiguration</code> so that 72 units in user
367 * space equals 1 inch in device space.
368 * <p>
369 * For a particular {@link Graphics2D}, g, one
370 * can reset the transformation to create
371 * such a mapping by using the following pseudocode:
372 * <pre>
373 * GraphicsConfiguration gc = g.getDeviceConfiguration();
374 *
375 * g.setTransform(gc.getDefaultTransform());
376 * g.transform(gc.getNormalizingTransform());
377 * </pre>
378 * Note that sometimes this <code>AffineTransform</code> is identity,
379 * such as for printers or metafile output, and that this
380 * <code>AffineTransform</code> is only as accurate as the information
381 * supplied by the underlying system. For image buffers not
382 * associated with a device, such as those not created by
383 * <code>createCompatibleImage</code>, this
384 * <code>AffineTransform</code> is the Identity transform
385 * since there is no valid distance measurement.
386 * @return an <code>AffineTransform</code> to concatenate to the
387 * default <code>AffineTransform</code> so that 72 units in user
388 * space is mapped to 1 inch in device space.
389 */
390 public abstract AffineTransform getNormalizingTransform();
391
392 /**
393 * Returns the bounds of the <code>GraphicsConfiguration</code>
394 * in the device coordinates. In a multi-screen environment
395 * with a virtual device, the bounds can have negative X
396 * or Y origins.
397 * @return the bounds of the area covered by this
398 * <code>GraphicsConfiguration</code>.
399 * @since 1.3
400 */
401 public abstract Rectangle getBounds();
402
403 private static class DefaultBufferCapabilities extends BufferCapabilities {
404 public DefaultBufferCapabilities(ImageCapabilities imageCaps) {
405 super(imageCaps, imageCaps, null);
406 }
407 }
408
409 /**
410 * Returns the buffering capabilities of this
411 * <code>GraphicsConfiguration</code>.
412 * @return the buffering capabilities of this graphics
413 * configuration object
414 * @since 1.4
415 */
416 public BufferCapabilities getBufferCapabilities() {
417 if (defaultBufferCaps == null) {
418 defaultBufferCaps = new DefaultBufferCapabilities(
419 getImageCapabilities());
420 }
421 return defaultBufferCaps;
422 }
423
424 /**
425 * Returns the image capabilities of this
426 * <code>GraphicsConfiguration</code>.
427 * @return the image capabilities of this graphics
428 * configuration object
429 * @since 1.4
430 */
431 public ImageCapabilities getImageCapabilities() {
432 if (defaultImageCaps == null) {
433 defaultImageCaps = new ImageCapabilities(false);
434 }
435 return defaultImageCaps;
436 }
437 }