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 static sun.java2d.pipe.hw.AccelSurface.*;
  44 
  45 /**
  46  * This class is the base implementation of the VolatileImage
  47  * abstract class.  The class implements most of the standard Image
  48  * methods (width, height, etc.) but delegates all surface management
  49  * issues to a platform-specific VolatileSurfaceManager.  When a new instance
  50  * of SunVolatileImage is created, it automatically creates an
  51  * appropriate VolatileSurfaceManager for the GraphicsConfiguration
  52  * under which this SunVolatileImage was created.
  53  */
  54 public class SunVolatileImage extends VolatileImage
  55     implements DestSurfaceProvider
  56 {
  57 
  58     protected VolatileSurfaceManager volSurfaceManager;
  59     protected Component comp;
  60     private GraphicsConfiguration graphicsConfig;
  61     private Font defaultFont;
  62     private int width, height;
  63     private int forcedAccelSurfaceType;
  64 
  65     protected SunVolatileImage(Component comp,
  66                                GraphicsConfiguration graphicsConfig,
  67                                int width, int height, Object context,
  68                                int transparency, ImageCapabilities caps,
  69                                int accType)
  70     {
  71         this.comp = comp;
  72         this.graphicsConfig = graphicsConfig;
  73         this.width = width;
  74         this.height = height;
  75         this.forcedAccelSurfaceType = accType;
  76         if (!(transparency == Transparency.OPAQUE ||
  77             transparency == Transparency.BITMASK ||
  78             transparency == Transparency.TRANSLUCENT))
  79         {
  80             throw new IllegalArgumentException("Unknown transparency type:" +
  81                                                transparency);
  82         }
  83         this.transparency = transparency;
  84         this.volSurfaceManager = createSurfaceManager(context, caps);
  85         SurfaceManager.setManager(this, volSurfaceManager);
  86 
  87         // post-construction initialization of the surface manager
  88         volSurfaceManager.initialize();
  89         // clear the background
  90         volSurfaceManager.initContents();
  91     }
  92 
  93     private SunVolatileImage(Component comp,
  94                              GraphicsConfiguration graphicsConfig,
  95                              int width, int height, Object context,
  96                              ImageCapabilities caps)
  97     {
  98         this(comp, graphicsConfig,
  99              width, height, context, Transparency.OPAQUE, caps, UNDEFINED);
 100     }
 101 
 102     public SunVolatileImage(Component comp, int width, int height) {
 103         this(comp, width, height, null);
 104     }
 105 
 106     public SunVolatileImage(Component comp,
 107                             int width, int height, Object context)
 108     {
 109         this(comp, comp.getGraphicsConfiguration(),
 110              width, height, context, null);
 111     }
 112 
 113     public SunVolatileImage(GraphicsConfiguration graphicsConfig,
 114                             int width, int height, int transparency,
 115                             ImageCapabilities caps)
 116     {
 117         this(null, graphicsConfig, width, height, null, transparency,
 118              caps, UNDEFINED);
 119     }
 120 
 121     public int getWidth() {
 122         return width;
 123     }
 124 
 125     public int getHeight() {
 126         return height;
 127     }
 128 
 129     public GraphicsConfiguration getGraphicsConfig() {
 130         return graphicsConfig;
 131     }
 132 
 133     public void updateGraphicsConfig() {
 134         // If this VImage is associated with a Component, get an updated
 135         // graphicsConfig from that component.  Otherwise, keep the one
 136         // that we were created with
 137         if (comp != null) {
 138             GraphicsConfiguration gc = comp.getGraphicsConfiguration();
 139             if (gc != null) {
 140                 // Could potentially be null in some failure situations;
 141                 // better to keep the old non-null value around than to
 142                 // set graphicsConfig to null
 143                 graphicsConfig = gc;
 144             }
 145         }
 146     }
 147 
 148     public Component getComponent() {
 149         return comp;
 150     }
 151 
 152     public int getForcedAccelSurfaceType() {
 153         return forcedAccelSurfaceType;
 154     }
 155 
 156     protected VolatileSurfaceManager createSurfaceManager(Object context,
 157                                                           ImageCapabilities caps)
 158     {
 159         /**
 160          * Platform-specific SurfaceManagerFactories will return a
 161          * manager suited to acceleration on each platform.  But if
 162          * the user is asking for a VolatileImage from a BufferedImageGC,
 163          * then we need to return the appropriate unaccelerated manager.
 164          * Note: this could change in the future; if some platform would
 165          * like to accelerate BIGC volatile images, then this special-casing
 166          * of the BIGC graphicsConfig should live in platform-specific
 167          * code instead.
 168          * We do the same for a Printer Device, and if user requested an
 169          * unaccelerated VolatileImage by passing the capabilities object.
 170          */
 171         if (graphicsConfig instanceof BufferedImageGraphicsConfig ||
 172             graphicsConfig instanceof sun.print.PrinterGraphicsConfig ||
 173             (caps != null && !caps.isAccelerated()))
 174         {
 175             return new BufImgVolatileSurfaceManager(this, context);
 176         }
 177         SurfaceManagerFactory smf = SurfaceManagerFactory.getInstance();
 178         return smf.createVolatileManager(this, context);
 179     }
 180 
 181     private Color getForeground() {
 182         if (comp != null) {
 183             return comp.getForeground();
 184         } else {
 185             return Color.black;
 186         }
 187     }
 188 
 189     private Color getBackground() {
 190         if (comp != null) {
 191             return comp.getBackground();
 192         } else {
 193             return Color.white;
 194         }
 195     }
 196 
 197     private Font getFont() {
 198         if (comp != null) {
 199             return comp.getFont();
 200         } else {
 201             if (defaultFont == null) {
 202                 defaultFont = new Font("Dialog", Font.PLAIN, 12);
 203             }
 204             return defaultFont;
 205         }
 206     }
 207 
 208     public Graphics2D createGraphics() {
 209         return new SunGraphics2D(volSurfaceManager.getPrimarySurfaceData(),
 210                                  getForeground(),
 211                                  getBackground(),
 212                                  getFont());
 213     }
 214 
 215     // Image method implementations
 216     public Object getProperty(String name, ImageObserver observer) {
 217         if (name == null) {
 218             throw new NullPointerException("null property name is not allowed");
 219         }
 220         return java.awt.Image.UndefinedProperty;
 221     }
 222 
 223     public int getWidth(ImageObserver observer) {
 224         return getWidth();
 225     }
 226 
 227     public int getHeight(ImageObserver observer) {
 228         return getHeight();
 229     }
 230 
 231     /**
 232      * This method creates a BufferedImage intended for use as a "snapshot"
 233      * or a backup surface.
 234      */
 235     public BufferedImage getBackupImage() {
 236         return getBackupImage(1, 1);
 237     }
 238 
 239     /**
 240      * This method creates a BufferedImage intended for use as a "snapshot"
 241      * or a backup surface with the given horizontal and vertical scale factors.
 242      */
 243     public BufferedImage getBackupImage(double scaleX, double scaleY) {
 244         int w = (int) Math.ceil(getWidth() * scaleX);
 245         int h = (int) Math.ceil(getHeight() * scaleY);
 246         return graphicsConfig.createCompatibleImage(w, h, getTransparency());
 247     }
 248 
 249     public BufferedImage getSnapshot() {
 250         BufferedImage bi = getBackupImage();
 251         Graphics2D g = bi.createGraphics();
 252         g.setComposite(AlphaComposite.Src);
 253         g.drawImage(this, 0, 0, null);
 254         g.dispose();
 255         return bi;
 256     }
 257 
 258     public int validate(GraphicsConfiguration gc) {
 259         return volSurfaceManager.validate(gc);
 260     }
 261 
 262     public boolean contentsLost() {
 263         return volSurfaceManager.contentsLost();
 264     }
 265 
 266     public ImageCapabilities getCapabilities() {
 267         return volSurfaceManager.getCapabilities(graphicsConfig);
 268     }
 269 
 270     /**
 271      * {@inheritDoc}
 272      *
 273      * @see sun.java2d.DestSurfaceProvider#getDestSurface
 274      */
 275     @Override
 276     public Surface getDestSurface() {
 277         return volSurfaceManager.getPrimarySurfaceData();
 278     }
 279 }