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 com.apple.laf;
27
28 import java.awt.*;
29 import java.awt.image.*;
30 import java.util.HashMap;
31
32 import com.apple.laf.AquaImageFactory.RecyclableSlicedImageControl;
33 import com.apple.laf.AquaImageFactory.NineSliceMetrics;
34 import com.apple.laf.AquaImageFactory.SlicedImageControl;
35
36 import sun.awt.image.*;
37 import sun.java2d.*;
38 import sun.print.*;
39 import apple.laf.*;
40 import apple.laf.JRSUIUtils.NineSliceMetricsProvider;
41
42 abstract class AquaPainter <T extends JRSUIState> {
43 static <T extends JRSUIState> AquaPainter<T> create(final T state) {
44 return new AquaSingleImagePainter<>(state);
45 }
46
47 static <T extends JRSUIState> AquaPainter<T> create(final T state, final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut) {
48 return create(state, minWidth, minHeight, westCut, eastCut, northCut, southCut, true);
49 }
50
51 static <T extends JRSUIState> AquaPainter<T> create(final T state, final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle) {
52 return create(state, minWidth, minHeight, westCut, eastCut, northCut, southCut, useMiddle, true, true);
53 }
54
55 static <T extends JRSUIState> AquaPainter<T> create(final T state, final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle, final boolean stretchHorizontally, final boolean stretchVertically) {
56 return create(state, new NineSliceMetricsProvider() {
57 @Override
58 public NineSliceMetrics getNineSliceMetricsForState(JRSUIState state) {
59 return new NineSliceMetrics(minWidth, minHeight, westCut, eastCut, northCut, southCut, useMiddle, stretchHorizontally, stretchVertically);
60 }
138 @Override
139 void paint(final Graphics2D g, final T stateToPaint) {
140 paintFromSingleCachedImage(g, control, stateToPaint, boundsRect);
141 }
142
143 static void paintFromSingleCachedImage(final Graphics2D g,
144 final JRSUIControl control, final JRSUIState controlState,
145 final Rectangle bounds) {
146 if (bounds.width <= 0 || bounds.height <= 0) {
147 return;
148 }
149
150 int scale = 1;
151 if (g instanceof SunGraphics2D) {
152 scale = ((SunGraphics2D) g).surfaceData.getDefaultScale();
153 }
154 final GraphicsConfiguration config = g.getDeviceConfiguration();
155 final ImageCache cache = ImageCache.getInstance();
156 final int imgW = bounds.width * scale;
157 final int imgH = bounds.height * scale;
158 BufferedImage img = (BufferedImage) cache.getImage(config, imgW, imgH, scale, controlState);
159 if (img == null) {
160 img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB_PRE);
161 cache.setImage(img, config, imgW, imgH, scale, controlState);
162 final WritableRaster raster = img.getRaster();
163 final DataBufferInt buffer = (DataBufferInt) raster.getDataBuffer();
164
165 control.set(controlState);
166 control.paint(SunWritableRaster.stealData(buffer, 0),
167 imgW, imgH, 0, 0, bounds.width, bounds.height);
168 SunWritableRaster.markDirty(buffer);
169 }
170
171 g.drawImage(img, bounds.x, bounds.y, bounds.width, bounds.height, null);
172 }
173 }
174
175 private static class RecyclableJRSUISlicedImageControl
176 extends RecyclableSlicedImageControl {
177
178 private final JRSUIControl control;
179 private final JRSUIState state;
180
181 RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) {
182 super(metrics);
183 this.control = control;
184 this.state = state;
185 }
186
187 @Override
188 protected Image createTemplateImage(int width, int height) {
189 BufferedImage image = new BufferedImage(metrics.minW, metrics.minH, BufferedImage.TYPE_INT_ARGB_PRE);
190
191 final WritableRaster raster = image.getRaster();
192 final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer();
193
194 control.set(state);
|
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 com.apple.laf;
27
28 import java.awt.*;
29 import java.awt.image.*;
30 import java.util.HashMap;
31
32 import com.apple.laf.AquaImageFactory.RecyclableSlicedImageControl;
33 import com.apple.laf.AquaImageFactory.NineSliceMetrics;
34 import com.apple.laf.AquaImageFactory.SlicedImageControl;
35
36 import sun.awt.image.*;
37 import sun.java2d.*;
38 import sun.print.*;
39 import apple.laf.*;
40 import apple.laf.JRSUIUtils.NineSliceMetricsProvider;
41 import sun.awt.image.ImageCache;
42
43 abstract class AquaPainter <T extends JRSUIState> {
44 static <T extends JRSUIState> AquaPainter<T> create(final T state) {
45 return new AquaSingleImagePainter<>(state);
46 }
47
48 static <T extends JRSUIState> AquaPainter<T> create(final T state, final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut) {
49 return create(state, minWidth, minHeight, westCut, eastCut, northCut, southCut, true);
50 }
51
52 static <T extends JRSUIState> AquaPainter<T> create(final T state, final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle) {
53 return create(state, minWidth, minHeight, westCut, eastCut, northCut, southCut, useMiddle, true, true);
54 }
55
56 static <T extends JRSUIState> AquaPainter<T> create(final T state, final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle, final boolean stretchHorizontally, final boolean stretchVertically) {
57 return create(state, new NineSliceMetricsProvider() {
58 @Override
59 public NineSliceMetrics getNineSliceMetricsForState(JRSUIState state) {
60 return new NineSliceMetrics(minWidth, minHeight, westCut, eastCut, northCut, southCut, useMiddle, stretchHorizontally, stretchVertically);
61 }
139 @Override
140 void paint(final Graphics2D g, final T stateToPaint) {
141 paintFromSingleCachedImage(g, control, stateToPaint, boundsRect);
142 }
143
144 static void paintFromSingleCachedImage(final Graphics2D g,
145 final JRSUIControl control, final JRSUIState controlState,
146 final Rectangle bounds) {
147 if (bounds.width <= 0 || bounds.height <= 0) {
148 return;
149 }
150
151 int scale = 1;
152 if (g instanceof SunGraphics2D) {
153 scale = ((SunGraphics2D) g).surfaceData.getDefaultScale();
154 }
155 final GraphicsConfiguration config = g.getDeviceConfiguration();
156 final ImageCache cache = ImageCache.getInstance();
157 final int imgW = bounds.width * scale;
158 final int imgH = bounds.height * scale;
159 AquaPixelsKey key = new AquaPixelsKey(config,
160 imgW, imgH, scale, controlState);
161 BufferedImage img = (BufferedImage) cache.getImage(key);
162 if (img == null) {
163 img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB_PRE);
164 if (!controlState.is(JRSUIConstants.Animating.YES)) {
165 cache.setImage(key, img);
166 }
167
168 final WritableRaster raster = img.getRaster();
169 final DataBufferInt buffer = (DataBufferInt) raster.getDataBuffer();
170
171 control.set(controlState);
172 control.paint(SunWritableRaster.stealData(buffer, 0),
173 imgW, imgH, 0, 0, bounds.width, bounds.height);
174 SunWritableRaster.markDirty(buffer);
175 }
176
177 g.drawImage(img, bounds.x, bounds.y, bounds.width, bounds.height, null);
178 }
179 }
180
181 private static class AquaPixelsKey implements ImageCache.PixelsKey {
182
183 private final int pixelCount;
184 private final int hash;
185
186 // key parts
187 private final GraphicsConfiguration config;
188 private final int w;
189 private final int h;
190 private final int scale;
191 private final JRSUIState state;
192
193 AquaPixelsKey(final GraphicsConfiguration config,
194 final int w, final int h, final int scale,
195 final JRSUIState state) {
196 this.pixelCount = w * h;
197 this.config = config;
198 this.w = w;
199 this.h = h;
200 this.scale = scale;
201 this.state = state;
202 this.hash = hash();
203 }
204
205 public int getPixelCount() {
206 return pixelCount;
207 }
208
209 private int hash() {
210 int hash = config != null ? config.hashCode() : 0;
211 hash = 31 * hash + w;
212 hash = 31 * hash + h;
213 hash = 31 * hash + scale;
214 hash = 31 * hash + state.hashCode();
215 return hash;
216 }
217
218 @Override
219 public int hashCode() {
220 return hash;
221 }
222
223 @Override
224 public boolean equals(Object obj) {
225 if (obj instanceof AquaPixelsKey) {
226 AquaPixelsKey key = (AquaPixelsKey) obj;
227 return config == key.config && w == key.w && h == key.h
228 && scale == key.scale && state.equals(key.state);
229 }
230 return false;
231 }
232 }
233
234 private static class RecyclableJRSUISlicedImageControl
235 extends RecyclableSlicedImageControl {
236
237 private final JRSUIControl control;
238 private final JRSUIState state;
239
240 RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) {
241 super(metrics);
242 this.control = control;
243 this.state = state;
244 }
245
246 @Override
247 protected Image createTemplateImage(int width, int height) {
248 BufferedImage image = new BufferedImage(metrics.minW, metrics.minH, BufferedImage.TYPE_INT_ARGB_PRE);
249
250 final WritableRaster raster = image.getRaster();
251 final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer();
252
253 control.set(state);
|