001/* ============
002 * FXGraphics2D
003 * ============
004 * 
005 * (C)opyright 2014-2022, by David Gilbert.
006 * 
007 * https://github.com/jfree/fxgraphics2d
008 *
009 * The FXGraphics2D class has been developed by David Gilbert for
010 * use in Orson Charts (https://github.com/jfree/orson-charts) and
011 * JFreeChart (http://www.jfree.org/jfreechart).  It may be useful for other
012 * code that uses the Graphics2D API provided by Java2D.
013 * 
014 * Redistribution and use in source and binary forms, with or without
015 * modification, are permitted provided that the following conditions are met:
016 *   - Redistributions of source code must retain the above copyright
017 *     notice, this list of conditions and the following disclaimer.
018 *   - Redistributions in binary form must reproduce the above copyright
019 *     notice, this list of conditions and the following disclaimer in the
020 *     documentation and/or other materials provided with the distribution.
021 *   - Neither the name of JFree.org nor the names of its contributors may
022 *     be used to endorse or promote products derived from this software
023 *     without specific prior written permission.
024 *
025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
028 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
029 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
030 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
031 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
032 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
033 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
034 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
035 * THE POSSIBILITY OF SUCH DAMAGE.
036 * 
037 */
038
039package org.jfree.fx;
040
041import java.awt.*;
042import java.awt.geom.AffineTransform;
043import java.awt.image.BufferedImage;
044import java.awt.image.ColorModel;
045import java.awt.image.DirectColorModel;
046import java.awt.image.VolatileImage;
047
048/**
049 * A graphics configuration for the {@link FXGraphics2D} class.
050 */
051public class FXGraphicsConfiguration extends GraphicsConfiguration {
052
053    private GraphicsDevice device;
054    
055    private final int width, height;
056    
057    /**
058     * Creates a new instance.
059     * 
060     * @param width  the width of the bounds.
061     * @param height  the height of the bounds.
062     */
063    public FXGraphicsConfiguration(int width, int height) {
064      super(); 
065      this.width = width;
066      this.height = height;
067    }
068    
069    /**
070     * Returns the graphics device that this configuration is associated with.
071     * 
072     * @return The graphics device (never {@code null}).
073     */
074    @Override
075    public GraphicsDevice getDevice() {
076        if (this.device == null) {
077            this.device = new FXGraphicsDevice("FXGraphicsDevice", this);
078        }
079        return this.device;
080    }
081
082    /**
083     * Returns the color model for this configuration.
084     * 
085     * @return The color model.
086     */
087    @Override
088    public ColorModel getColorModel() {
089        return getColorModel(Transparency.TRANSLUCENT);
090    }
091
092    /**
093     * Returns the color model for the specified transparency type, or 
094     * {@code null}.
095     * 
096     * @param transparency  the transparency type.
097     * 
098     * @return A color model (possibly {@code null}).
099     */
100    @Override
101    public ColorModel getColorModel(int transparency) {
102        if (transparency == Transparency.TRANSLUCENT) {
103            return ColorModel.getRGBdefault();
104        } else if (transparency == Transparency.OPAQUE) {
105            return new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff);
106        } else {
107            return null;
108        }
109    }
110
111    /**
112     * Returns the default transform.
113     * 
114     * @return The default transform. 
115     */
116    @Override
117    public AffineTransform getDefaultTransform() {
118        return new AffineTransform();
119    }
120
121    /**
122     * Returns the normalizing transform.
123     * 
124     * @return The normalizing transform. 
125     */
126    @Override
127    public AffineTransform getNormalizingTransform() {
128        return new AffineTransform();
129    }
130    
131    /**
132     * Returns the bounds for this configuration.
133     * 
134     * @return The bounds. 
135     */
136    @Override
137    public Rectangle getBounds() {
138        return new Rectangle(this.width, this.height);
139    }
140
141    private BufferedImage img;
142    private GraphicsConfiguration gc;
143
144    /**
145     * Returns a volatile image.  This method is a workaround for a
146     * ClassCastException that occurs on MacOSX when exporting a Swing UI
147     * that uses the Nimbus Look and Feel.
148     *
149     * @param width  the image width.
150     * @param height  the image height.
151     * @param caps  the image capabilities.
152     * @param transparency  the transparency.
153     *
154     * @return The volatile image.
155     *
156     * @throws AWTException if there is a problem creating the image.
157     */
158    @Override
159    public VolatileImage createCompatibleVolatileImage(int width, int height,
160                                                       ImageCapabilities caps, int transparency) throws AWTException {
161        if (img == null) {
162            img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
163            gc = img.createGraphics().getDeviceConfiguration();
164        }
165        return gc.createCompatibleVolatileImage(width, height, caps,
166                transparency);
167    }
168
169}