1 /*
   2  * Copyright (c) 1997, 2009, 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</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,&nbsp;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 abstract BufferedImage createCompatibleImage(int width, int height);
 148 
 149     /**
 150      * Returns a <code>BufferedImage</code> that supports the specified
 151      * transparency and has a data layout and color model
 152      * compatible with this <code>GraphicsConfiguration</code>.  This
 153      * method has nothing to do with memory-mapping
 154      * a device. The returned <code>BufferedImage</code> has a layout and
 155      * color model that can be optimally blitted to a device
 156      * with this <code>GraphicsConfiguration</code>.
 157      * @param width the width of the returned <code>BufferedImage</code>
 158      * @param height the height of the returned <code>BufferedImage</code>
 159      * @param transparency the specified transparency mode
 160      * @return a <code>BufferedImage</code> whose data layout and color
 161      * model is compatible with this <code>GraphicsConfiguration</code>
 162      * and also supports the specified transparency.
 163      * @throws IllegalArgumentException if the transparency is not a valid value
 164      * @see Transparency#OPAQUE
 165      * @see Transparency#BITMASK
 166      * @see Transparency#TRANSLUCENT
 167      */
 168     public BufferedImage createCompatibleImage(int width, int height,
 169                                                int transparency)
 170     {
 171         if (getColorModel().getTransparency() == transparency) {
 172             return createCompatibleImage(width, height);
 173         }
 174 
 175         ColorModel cm = getColorModel(transparency);
 176         if (cm == null) {
 177             throw new IllegalArgumentException("Unknown transparency: " +
 178                                                transparency);
 179         }
 180         WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
 181         return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
 182     }
 183 
 184 
 185     /**
 186      * Returns a {@link VolatileImage} with a data layout and color model
 187      * compatible with this <code>GraphicsConfiguration</code>.
 188      * The returned <code>VolatileImage</code>
 189      * may have data that is stored optimally for the underlying graphics
 190      * device and may therefore benefit from platform-specific rendering
 191      * acceleration.
 192      * @param width the width of the returned <code>VolatileImage</code>
 193      * @param height the height of the returned <code>VolatileImage</code>
 194      * @return a <code>VolatileImage</code> whose data layout and color
 195      * model is compatible with this <code>GraphicsConfiguration</code>.
 196      * @see Component#createVolatileImage(int, int)
 197      * @since 1.4
 198      */
 199     public VolatileImage createCompatibleVolatileImage(int width, int height) {
 200         VolatileImage vi = null;
 201         try {
 202             vi = createCompatibleVolatileImage(width, height,
 203                                                null, Transparency.OPAQUE);
 204         } catch (AWTException e) {
 205             // shouldn't happen: we're passing in null caps
 206             assert false;
 207         }
 208         return vi;
 209     }
 210 
 211     /**
 212      * Returns a {@link VolatileImage} with a data layout and color model
 213      * compatible with this <code>GraphicsConfiguration</code>.
 214      * The returned <code>VolatileImage</code>
 215      * may have data that is stored optimally for the underlying graphics
 216      * device and may therefore benefit from platform-specific rendering
 217      * acceleration.
 218      * @param width the width of the returned <code>VolatileImage</code>
 219      * @param height the height of the returned <code>VolatileImage</code>
 220      * @param transparency the specified transparency mode
 221      * @return a <code>VolatileImage</code> whose data layout and color
 222      * model is compatible with this <code>GraphicsConfiguration</code>.
 223      * @throws IllegalArgumentException if the transparency is not a valid value
 224      * @see Transparency#OPAQUE
 225      * @see Transparency#BITMASK
 226      * @see Transparency#TRANSLUCENT
 227      * @see Component#createVolatileImage(int, int)
 228      * @since 1.5
 229      */
 230     public VolatileImage createCompatibleVolatileImage(int width, int height,
 231                                                        int transparency)
 232     {
 233         VolatileImage vi = null;
 234         try {
 235             vi = createCompatibleVolatileImage(width, height, null, transparency);
 236         } catch (AWTException e) {
 237             // shouldn't happen: we're passing in null caps
 238             assert false;
 239         }
 240         return vi;
 241     }
 242 
 243     /**
 244      * Returns a {@link VolatileImage} with a data layout and color model
 245      * compatible with this <code>GraphicsConfiguration</code>, using
 246      * the specified image capabilities.
 247      * If the <code>caps</code> parameter is null, it is effectively ignored
 248      * and this method will create a VolatileImage without regard to
 249      * <code>ImageCapabilities</code> constraints.
 250      *
 251      * The returned <code>VolatileImage</code> has
 252      * a layout and color model that is closest to this native device
 253      * configuration and can therefore be optimally blitted to this
 254      * device.
 255      * @return a <code>VolatileImage</code> whose data layout and color
 256      * model is compatible with this <code>GraphicsConfiguration</code>.
 257      * @param width the width of the returned <code>VolatileImage</code>
 258      * @param height the height of the returned <code>VolatileImage</code>
 259      * @param caps the image capabilities
 260      * @exception AWTException if the supplied image capabilities could not
 261      * be met by this graphics configuration
 262      * @since 1.4
 263      */
 264     public VolatileImage createCompatibleVolatileImage(int width, int height,
 265         ImageCapabilities caps) throws AWTException
 266     {
 267         return createCompatibleVolatileImage(width, height, caps,
 268                                              Transparency.OPAQUE);
 269     }
 270 
 271     /**
 272      * Returns a {@link VolatileImage} with a data layout and color model
 273      * compatible with this <code>GraphicsConfiguration</code>, using
 274      * the specified image capabilities and transparency value.
 275      * If the <code>caps</code> parameter is null, it is effectively ignored
 276      * and this method will create a VolatileImage without regard to
 277      * <code>ImageCapabilities</code> constraints.
 278      *
 279      * The returned <code>VolatileImage</code> has
 280      * a layout and color model that is closest to this native device
 281      * configuration and can therefore be optimally blitted to this
 282      * device.
 283      * @param width the width of the returned <code>VolatileImage</code>
 284      * @param height the height of the returned <code>VolatileImage</code>
 285      * @param caps the image capabilities
 286      * @param transparency the specified transparency mode
 287      * @return a <code>VolatileImage</code> whose data layout and color
 288      * model is compatible with this <code>GraphicsConfiguration</code>.
 289      * @see Transparency#OPAQUE
 290      * @see Transparency#BITMASK
 291      * @see Transparency#TRANSLUCENT
 292      * @throws IllegalArgumentException if the transparency is not a valid value
 293      * @exception AWTException if the supplied image capabilities could not
 294      * be met by this graphics configuration
 295      * @see Component#createVolatileImage(int, int)
 296      * @since 1.5
 297      */
 298     public VolatileImage createCompatibleVolatileImage(int width, int height,
 299         ImageCapabilities caps, int transparency) throws AWTException
 300     {
 301         VolatileImage vi =
 302             new SunVolatileImage(this, width, height, transparency, caps);
 303         if (caps != null && caps.isAccelerated() &&
 304             !vi.getCapabilities().isAccelerated())
 305         {
 306             throw new AWTException("Supplied image capabilities could not " +
 307                                    "be met by this graphics configuration.");
 308         }
 309         return vi;
 310     }
 311 
 312     /**
 313      * Returns the {@link ColorModel} associated with this
 314      * <code>GraphicsConfiguration</code>.
 315      * @return a <code>ColorModel</code> object that is associated with
 316      * this <code>GraphicsConfiguration</code>.
 317      */
 318     public abstract ColorModel getColorModel();
 319 
 320     /**
 321      * Returns the <code>ColorModel</code> associated with this
 322      * <code>GraphicsConfiguration</code> that supports the specified
 323      * transparency.
 324      * @param transparency the specified transparency mode
 325      * @return a <code>ColorModel</code> object that is associated with
 326      * this <code>GraphicsConfiguration</code> and supports the
 327      * specified transparency or null if the transparency is not a valid
 328      * value.
 329      * @see Transparency#OPAQUE
 330      * @see Transparency#BITMASK
 331      * @see Transparency#TRANSLUCENT
 332      */
 333     public abstract ColorModel getColorModel(int transparency);
 334 
 335     /**
 336      * Returns the default {@link AffineTransform} for this
 337      * <code>GraphicsConfiguration</code>. This
 338      * <code>AffineTransform</code> is typically the Identity transform
 339      * for most normal screens.  The default <code>AffineTransform</code>
 340      * maps coordinates onto the device such that 72 user space
 341      * coordinate units measure approximately 1 inch in device
 342      * space.  The normalizing transform can be used to make
 343      * this mapping more exact.  Coordinates in the coordinate space
 344      * defined by the default <code>AffineTransform</code> for screen and
 345      * printer devices have the origin in the upper left-hand corner of
 346      * the target region of the device, with X coordinates
 347      * increasing to the right and Y coordinates increasing downwards.
 348      * For image buffers not associated with a device, such as those not
 349      * created by <code>createCompatibleImage</code>,
 350      * this <code>AffineTransform</code> is the Identity transform.
 351      * @return the default <code>AffineTransform</code> for this
 352      * <code>GraphicsConfiguration</code>.
 353      */
 354     public abstract AffineTransform getDefaultTransform();
 355 
 356     /**
 357      *
 358      * Returns a <code>AffineTransform</code> that can be concatenated
 359      * with the default <code>AffineTransform</code>
 360      * of a <code>GraphicsConfiguration</code> so that 72 units in user
 361      * space equals 1 inch in device space.
 362      * <p>
 363      * For a particular {@link Graphics2D}, g, one
 364      * can reset the transformation to create
 365      * such a mapping by using the following pseudocode:
 366      * <pre>
 367      *      GraphicsConfiguration gc = g.getDeviceConfiguration();
 368      *
 369      *      g.setTransform(gc.getDefaultTransform());
 370      *      g.transform(gc.getNormalizingTransform());
 371      * </pre>
 372      * Note that sometimes this <code>AffineTransform</code> is identity,
 373      * such as for printers or metafile output, and that this
 374      * <code>AffineTransform</code> is only as accurate as the information
 375      * supplied by the underlying system.  For image buffers not
 376      * associated with a device, such as those not created by
 377      * <code>createCompatibleImage</code>, this
 378      * <code>AffineTransform</code> is the Identity transform
 379      * since there is no valid distance measurement.
 380      * @return an <code>AffineTransform</code> to concatenate to the
 381      * default <code>AffineTransform</code> so that 72 units in user
 382      * space is mapped to 1 inch in device space.
 383      */
 384     public abstract AffineTransform getNormalizingTransform();
 385 
 386     /**
 387      * Returns the bounds of the <code>GraphicsConfiguration</code>
 388      * in the device coordinates. In a multi-screen environment
 389      * with a virtual device, the bounds can have negative X
 390      * or Y origins.
 391      * @return the bounds of the area covered by this
 392      * <code>GraphicsConfiguration</code>.
 393      * @since 1.3
 394      */
 395     public abstract Rectangle getBounds();
 396 
 397     private static class DefaultBufferCapabilities extends BufferCapabilities {
 398         public DefaultBufferCapabilities(ImageCapabilities imageCaps) {
 399             super(imageCaps, imageCaps, null);
 400         }
 401     }
 402 
 403     /**
 404      * Returns the buffering capabilities of this
 405      * <code>GraphicsConfiguration</code>.
 406      * @return the buffering capabilities of this graphics
 407      * configuration object
 408      * @since 1.4
 409      */
 410     public BufferCapabilities getBufferCapabilities() {
 411         if (defaultBufferCaps == null) {
 412             defaultBufferCaps = new DefaultBufferCapabilities(
 413                 getImageCapabilities());
 414         }
 415         return defaultBufferCaps;
 416     }
 417 
 418     /**
 419      * Returns the image capabilities of this
 420      * <code>GraphicsConfiguration</code>.
 421      * @return the image capabilities of this graphics
 422      * configuration object
 423      * @since 1.4
 424      */
 425     public ImageCapabilities getImageCapabilities() {
 426         if (defaultImageCaps == null) {
 427             defaultImageCaps = new ImageCapabilities(false);
 428         }
 429         return defaultImageCaps;
 430     }
 431 
 432     /**
 433      * Returns whether this {@code GraphicsConfiguration} supports
 434      * the {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
 435      * PERPIXEL_TRANSLUCENT} kind of translucency.
 436      *
 437      * @param gc GraphicsConfiguration
 438      * @throws NullPointerException if the gc argument is null
 439      * @return whether the given GraphicsConfiguration supports
 440      *         the translucency effects.
 441      * @see Window#setBackground(Color)
 442      */
 443     /*public */boolean isTranslucencyCapable() {
 444         // Overridden in subclasses
 445         return false;
 446     }
 447 }