001/* ===================================================
002 * JFreeSVG : an SVG library for the Java(tm) platform
003 * ===================================================
004 * 
005 * (C)opyright 2013-2021, by Object Refinery Limited.  All rights reserved.
006 *
007 * Project Info:  http://www.jfree.org/jfreesvg/index.html
008 * 
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as published by
011 * the Free Software Foundation, either version 3 of the License, or
012 * (at your option) any later version.
013 *
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 *
019 * You should have received a copy of the GNU General Public License
020 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
021 * 
022 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
023 * Other names may be trademarks of their respective owners.]
024 * 
025 * If you do not wish to be bound by the terms of the GPL, an alternative
026 * commercial license can be purchased.  For details, please see visit the
027 * JFreeSVG home page:
028 * 
029 * http://www.jfree.org/jfreesvg
030 * 
031 */
032
033package org.jfree.svg;
034
035import java.awt.AWTException;
036import java.awt.GraphicsConfiguration;
037import java.awt.GraphicsDevice;
038import java.awt.ImageCapabilities;
039import java.awt.Rectangle;
040import java.awt.Transparency;
041import java.awt.geom.AffineTransform;
042import java.awt.image.BufferedImage;
043import java.awt.image.ColorModel;
044import java.awt.image.DirectColorModel;
045import java.awt.image.VolatileImage;
046import java.awt.image.WritableRaster;
047
048/**
049 * A graphics configuration for the {@link SVGGraphics2D} class.
050 */
051public class SVGGraphicsConfiguration extends GraphicsConfiguration {
052
053    private GraphicsDevice device;
054    
055    private final int width;
056    private final int height;
057    
058    /**
059     * Creates a new instance.
060     * 
061     * @param width  the width of the bounds.
062     * @param height  the height of the bounds.
063     */
064    public SVGGraphicsConfiguration(int width, int height) {
065      super(); 
066      this.width = width;
067      this.height = height;
068    }
069    
070    /**
071     * Returns the graphics device that this configuration is associated with.
072     * 
073     * @return The graphics device (never {@code null}).
074     */
075    @Override
076    public GraphicsDevice getDevice() {
077        if (this.device == null) {
078            this.device = new SVGGraphicsDevice("JFreeSVG-GraphicsDevice", this);
079        }
080        return this.device;
081    }
082
083    /**
084     * Returns the color model for this configuration.
085     * 
086     * @return The color model.
087     */
088    @Override
089    public ColorModel getColorModel() {
090        return getColorModel(Transparency.TRANSLUCENT);
091    }
092
093    /**
094     * Returns the color model for the specified transparency type, or 
095     * {@code null}.
096     * 
097     * @param transparency  the transparency type.
098     * 
099     * @return A color model (possibly {@code null}).
100     */
101    @Override
102    public ColorModel getColorModel(int transparency) {
103        switch (transparency) {
104            case Transparency.TRANSLUCENT:
105                return ColorModel.getRGBdefault();
106            case Transparency.OPAQUE:
107                return new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff);
108            default:
109                return null;
110        }
111    }
112
113    /**
114     * Returns the default transform.
115     * 
116     * @return The default transform. 
117     */
118    @Override
119    public AffineTransform getDefaultTransform() {
120        return new AffineTransform();
121    }
122
123    /**
124     * Returns the normalizing transform.
125     * 
126     * @return The normalizing transform. 
127     */
128    @Override
129    public AffineTransform getNormalizingTransform() {
130        return new AffineTransform();
131    }
132    
133    /**
134     * Returns the bounds for this configuration.
135     * 
136     * @return The bounds. 
137     */
138    @Override
139    public Rectangle getBounds() {
140        return new Rectangle(this.width, this.height);
141    }
142
143    /**
144     * Creates a compatible image. This override is only here to provide
145     * support for Java 6 because from Java 7 onwards the super class has a
146     * non-abstract implementation for this method.
147     * 
148     * @param width  the width.
149     * @param height  the height.
150     * 
151     * @return A compatible image. 
152     */
153    @Override
154    public BufferedImage createCompatibleImage(int width, int height) {
155        ColorModel model = getColorModel();
156        WritableRaster raster = model.createCompatibleWritableRaster(width, 
157                height);
158        return new BufferedImage(model, raster, model.isAlphaPremultiplied(), 
159                null);
160    }
161
162    private BufferedImage img;
163    private GraphicsConfiguration gc;
164    
165    /**
166     * Returns a volatile image.  This method is a workaround for a
167     * ClassCastException that occurs on MacOSX when exporting a Swing UI
168     * that uses the Nimbus Look and Feel to SVG.
169     * 
170     * @param width  the image width.
171     * @param height  the image height.
172     * @param caps  the image capabilities.
173     * @param transparency  the transparency.
174     * 
175     * @return The volatile image.
176     * 
177     * @throws AWTException if there is a problem creating the image.
178     */
179    @Override
180    public VolatileImage createCompatibleVolatileImage(int width, int height, 
181            ImageCapabilities caps, int transparency) throws AWTException {
182        if (img == null) {
183            img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
184            gc = img.createGraphics().getDeviceConfiguration();
185        }
186        return gc.createCompatibleVolatileImage(width, height, caps, 
187                transparency);
188    }
189
190}