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