001: /*
002: * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package java.awt;
027:
028: import java.awt.geom.AffineTransform;
029: import java.awt.image.BufferedImage;
030: import java.awt.image.ColorModel;
031: import java.awt.image.VolatileImage;
032: import java.awt.image.WritableRaster;
033:
034: import sun.awt.image.SunVolatileImage;
035:
036: /**
037: * The <code>GraphicsConfiguration</code> class describes the
038: * characteristics of a graphics destination such as a printer or monitor.
039: * There can be many <code>GraphicsConfiguration</code> objects associated
040: * with a single graphics device, representing different drawing modes or
041: * capabilities. The corresponding native structure will vary from platform
042: * to platform. For example, on X11 windowing systems,
043: * each visual is a different <code>GraphicsConfiguration</code>.
044: * On Microsoft Windows, <code>GraphicsConfiguration</code>s represent
045: * PixelFormats available in the current resolution and color depth.
046: * <p>
047: * In a virtual device multi-screen environment in which the desktop
048: * area could span multiple physical screen devices, the bounds of the
049: * <code>GraphicsConfiguration</code> objects are relative to the
050: * virtual coordinate system. When setting the location of a
051: * component, use {@link #getBounds() getBounds} to get the bounds of
052: * the desired <code>GraphicsConfiguration</code> and offset the location
053: * with the coordinates of the <code>GraphicsConfiguration</code>,
054: * as the following code sample illustrates:
055: * </p>
056: *
057: * <pre>
058: * Frame f = new Frame(gc); // where gc is a GraphicsConfiguration
059: * Rectangle bounds = gc.getBounds();
060: * f.setLocation(10 + bounds.x, 10 + bounds.y); </pre>
061: *
062: * <p>
063: * To determine if your environment is a virtual device
064: * environment, call <code>getBounds</code> on all of the
065: * <code>GraphicsConfiguration</code> objects in your system. If
066: * any of the origins of the returned bounds is not (0, 0),
067: * your environment is a virtual device environment.
068: *
069: * <p>
070: * You can also use <code>getBounds</code> to determine the bounds
071: * of the virtual device. To do this, first call <code>getBounds</code> on all
072: * of the <code>GraphicsConfiguration</code> objects in your
073: * system. Then calculate the union of all of the bounds returned
074: * from the calls to <code>getBounds</code>. The union is the
075: * bounds of the virtual device. The following code sample
076: * calculates the bounds of the virtual device.
077: *
078: * <pre>
079: * Rectangle virtualBounds = new Rectangle();
080: * GraphicsEnvironment ge = GraphicsEnvironment.
081: * getLocalGraphicsEnvironment();
082: * GraphicsDevice[] gs =
083: * ge.getScreenDevices();
084: * for (int j = 0; j < gs.length; j++) {
085: * GraphicsDevice gd = gs[j];
086: * GraphicsConfiguration[] gc =
087: * gd.getConfigurations();
088: * for (int i=0; i < gc.length; i++) {
089: * virtualBounds =
090: * virtualBounds.union(gc[i].getBounds());
091: * }
092: * } </pre>
093: *
094: * @see Window
095: * @see Frame
096: * @see GraphicsEnvironment
097: * @see GraphicsDevice
098: */
099: /*
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: * @version 1.48, 05/05/07
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 = model.createCompatibleWritableRaster(
150: width, height);
151: return new BufferedImage(model, raster, model
152: .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: if (getColorModel().getTransparency() == transparency) {
177: return createCompatibleImage(width, height);
178: }
179:
180: ColorModel cm = getColorModel(transparency);
181: if (cm == null) {
182: throw new IllegalArgumentException("Unknown transparency: "
183: + transparency);
184: }
185: WritableRaster wr = cm.createCompatibleWritableRaster(width,
186: height);
187: return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(),
188: null);
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,
206: int height) {
207: VolatileImage vi = null;
208: try {
209: vi = createCompatibleVolatileImage(width, height, null,
210: Transparency.OPAQUE);
211: } catch (AWTException e) {
212: // shouldn't happen: we're passing in null caps
213: assert false;
214: }
215: return vi;
216: }
217:
218: /**
219: * Returns a {@link VolatileImage} with a data layout and color model
220: * compatible with this <code>GraphicsConfiguration</code>.
221: * The returned <code>VolatileImage</code>
222: * may have data that is stored optimally for the underlying graphics
223: * device and may therefore benefit from platform-specific rendering
224: * acceleration.
225: * @param width the width of the returned <code>VolatileImage</code>
226: * @param height the height of the returned <code>VolatileImage</code>
227: * @param transparency the specified transparency mode
228: * @return a <code>VolatileImage</code> whose data layout and color
229: * model is compatible with this <code>GraphicsConfiguration</code>.
230: * @throws IllegalArgumentException if the transparency is not a valid value
231: * @see Transparency#OPAQUE
232: * @see Transparency#BITMASK
233: * @see Transparency#TRANSLUCENT
234: * @see Component#createVolatileImage(int, int)
235: * @since 1.5
236: */
237: public VolatileImage createCompatibleVolatileImage(int width,
238: int height, int transparency) {
239: VolatileImage vi = null;
240: try {
241: vi = createCompatibleVolatileImage(width, height, null,
242: transparency);
243: } catch (AWTException e) {
244: // shouldn't happen: we're passing in null caps
245: assert false;
246: }
247: return vi;
248: }
249:
250: /**
251: * Returns a {@link VolatileImage} with a data layout and color model
252: * compatible with this <code>GraphicsConfiguration</code>, using
253: * the specified image capabilities.
254: * If the <code>caps</code> parameter is null, it is effectively ignored
255: * and this method will create a VolatileImage without regard to
256: * <code>ImageCapabilities</code> constraints.
257: *
258: * The returned <code>VolatileImage</code> has
259: * a layout and color model that is closest to this native device
260: * configuration and can therefore be optimally blitted to this
261: * device.
262: * @return a <code>VolatileImage</code> whose data layout and color
263: * model is compatible with this <code>GraphicsConfiguration</code>.
264: * @param width the width of the returned <code>VolatileImage</code>
265: * @param height the height of the returned <code>VolatileImage</code>
266: * @param caps the image capabilities
267: * @exception AWTException if the supplied image capabilities could not
268: * be met by this graphics configuration
269: * @since 1.4
270: */
271: public VolatileImage createCompatibleVolatileImage(int width,
272: int height, ImageCapabilities caps) throws AWTException {
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,
305: int height, ImageCapabilities caps, int transparency)
306: throws AWTException {
307: VolatileImage vi = new SunVolatileImage(this , width, height,
308: transparency, caps);
309: if (caps != null && caps.isAccelerated()
310: && !vi.getCapabilities().isAccelerated()) {
311: throw new AWTException(
312: "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
404: BufferCapabilities {
405: public DefaultBufferCapabilities(ImageCapabilities imageCaps) {
406: super (imageCaps, imageCaps, null);
407: }
408: }
409:
410: /**
411: * Returns the buffering capabilities of this
412: * <code>GraphicsConfiguration</code>.
413: * @return the buffering capabilities of this graphics
414: * configuration object
415: * @since 1.4
416: */
417: public BufferCapabilities getBufferCapabilities() {
418: if (defaultBufferCaps == null) {
419: defaultBufferCaps = new DefaultBufferCapabilities(
420: getImageCapabilities());
421: }
422: return defaultBufferCaps;
423: }
424:
425: /**
426: * Returns the image capabilities of this
427: * <code>GraphicsConfiguration</code>.
428: * @return the image capabilities of this graphics
429: * configuration object
430: * @since 1.4
431: */
432: public ImageCapabilities getImageCapabilities() {
433: if (defaultImageCaps == null) {
434: defaultImageCaps = new ImageCapabilities(false);
435: }
436: return defaultImageCaps;
437: }
438: }
|