src/macosx/classes/com/apple/laf/AquaPainter.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 39,57 ****
import apple.laf.*;
import apple.laf.JRSUIUtils.NineSliceMetricsProvider;
abstract class AquaPainter <T extends JRSUIState> {
static <T extends JRSUIState> AquaPainter<T> create(final T state) {
! return new AquaSingleImagePainter<T>(state);
}
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) {
! return AquaPainter.create(state, minWidth, minHeight, westCut, eastCut, northCut, southCut, true);
}
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) {
! return AquaPainter.create(state, minWidth, minHeight, westCut, eastCut, northCut, southCut, useMiddle, true, true);
}
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) {
return create(state, new NineSliceMetricsProvider() {
@Override
--- 39,57 ----
import apple.laf.*;
import apple.laf.JRSUIUtils.NineSliceMetricsProvider;
abstract class AquaPainter <T extends JRSUIState> {
static <T extends JRSUIState> AquaPainter<T> create(final T state) {
! return new AquaSingleImagePainter<>(state);
}
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) {
! return create(state, minWidth, minHeight, westCut, eastCut, northCut, southCut, true);
}
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) {
! return create(state, minWidth, minHeight, westCut, eastCut, northCut, southCut, useMiddle, true, true);
}
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) {
return create(state, new NineSliceMetricsProvider() {
@Override
*** 63,99 ****
static <T extends JRSUIState> AquaPainter<T> create(final T state, final NineSliceMetricsProvider metricsProvider) {
return new AquaNineSlicingImagePainter<>(state, metricsProvider);
}
! abstract void paint(final Graphics2D g, final T stateToPaint, final Component c);
final Rectangle boundsRect = new Rectangle();
final JRSUIControl control;
T state;
AquaPainter(final JRSUIControl control, final T state) {
this.control = control;
this.state = state;
}
! JRSUIControl getControl() {
! control.set(state = (T)state.derive());
return control;
}
! void paint(final Graphics g, final Component c, final int x, final int y, final int w, final int h) {
boundsRect.setBounds(x, y, w, h);
! final T nextState = (T)state.derive();
final Graphics2D g2d = getGraphics2D(g);
! if (g2d != null) paint(g2d, nextState, c);
state = nextState;
}
! static class AquaNineSlicingImagePainter<T extends JRSUIState> extends AquaPainter<T> {
! protected final HashMap<T, RecyclableJRSUISlicedImageControl> slicedControlImages;
! protected final NineSliceMetricsProvider metricsProvider;
AquaNineSlicingImagePainter(final T state) {
this(state, null);
}
--- 63,102 ----
static <T extends JRSUIState> AquaPainter<T> create(final T state, final NineSliceMetricsProvider metricsProvider) {
return new AquaNineSlicingImagePainter<>(state, metricsProvider);
}
! abstract void paint(Graphics2D g, T stateToPaint);
final Rectangle boundsRect = new Rectangle();
final JRSUIControl control;
T state;
AquaPainter(final JRSUIControl control, final T state) {
this.control = control;
this.state = state;
}
! final JRSUIControl getControl() {
! control.set(state = state.derive());
return control;
}
! final void paint(final Graphics g, final Component c, final int x,
! final int y, final int w, final int h) {
boundsRect.setBounds(x, y, w, h);
! final T nextState = state.derive();
final Graphics2D g2d = getGraphics2D(g);
! if (g2d != null) paint(g2d, nextState);
state = nextState;
}
! private static class AquaNineSlicingImagePainter<T extends JRSUIState>
! extends AquaPainter<T> {
!
! private final HashMap<T, RecyclableJRSUISlicedImageControl> slicedControlImages;
! private final NineSliceMetricsProvider metricsProvider;
AquaNineSlicingImagePainter(final T state) {
this(state, null);
}
*** 102,173 ****
this.metricsProvider = metricsProvider;
slicedControlImages = new HashMap<>();
}
@Override
! void paint(final Graphics2D g, final T stateToPaint, final Component c) {
if (metricsProvider == null) {
! AquaSingleImagePainter.paintFromSingleCachedImage(g, control, stateToPaint, c, boundsRect);
return;
}
RecyclableJRSUISlicedImageControl slicesRef = slicedControlImages.get(stateToPaint);
if (slicesRef == null) {
final NineSliceMetrics metrics = metricsProvider.getNineSliceMetricsForState(stateToPaint);
if (metrics == null) {
! AquaSingleImagePainter.paintFromSingleCachedImage(g, control, stateToPaint, c, boundsRect);
return;
}
slicesRef = new RecyclableJRSUISlicedImageControl(control, stateToPaint, metrics);
slicedControlImages.put(stateToPaint, slicesRef);
}
final SlicedImageControl slices = slicesRef.get();
slices.paint(g, boundsRect.x, boundsRect.y, boundsRect.width, boundsRect.height);
}
}
! static class AquaSingleImagePainter<T extends JRSUIState> extends AquaPainter<T> {
AquaSingleImagePainter(final T state) {
super(new JRSUIControl(false), state);
}
@Override
! void paint(Graphics2D g, T stateToPaint, Component c) {
! paintFromSingleCachedImage(g, control, stateToPaint, c, boundsRect);
}
! static void paintFromSingleCachedImage(final Graphics2D g, final JRSUIControl control, final JRSUIState controlState, final Component c, final Rectangle boundsRect) {
! final Rectangle clipRect = g.getClipBounds();
! final Rectangle intersection = boundsRect.intersection(clipRect);
! if (intersection.width <= 0 || intersection.height <= 0) return;
!
! final int imgX1 = intersection.x - boundsRect.x;
! final int imgY1 = intersection.y - boundsRect.y;
final GraphicsConfiguration config = g.getDeviceConfiguration();
final ImageCache cache = ImageCache.getInstance();
! BufferedImage image = (BufferedImage)cache.getImage(config, boundsRect.width, boundsRect.height, controlState);
! if (image == null) {
! image = new BufferedImage(boundsRect.width, boundsRect.height, BufferedImage.TYPE_INT_ARGB_PRE);
! cache.setImage(image, config, boundsRect.width, boundsRect.height, controlState);
! final WritableRaster raster = image.getRaster();
! final DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer();
control.set(controlState);
control.paint(SunWritableRaster.stealData(buffer, 0),
! image.getWidth(), image.getHeight(), 0, 0, boundsRect.width, boundsRect.height);
SunWritableRaster.markDirty(buffer);
}
! g.drawImage(image, intersection.x, intersection.y, intersection.x + intersection.width, intersection.y + intersection.height,
! imgX1, imgY1, imgX1 + intersection.width, imgY1 + intersection.height, null);
}
}
! static class RecyclableJRSUISlicedImageControl extends RecyclableSlicedImageControl {
! final JRSUIControl control;
! final JRSUIState state;
RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) {
super(metrics);
this.control = control;
this.state = state;
--- 105,184 ----
this.metricsProvider = metricsProvider;
slicedControlImages = new HashMap<>();
}
@Override
! void paint(final Graphics2D g, final T stateToPaint) {
if (metricsProvider == null) {
! AquaSingleImagePainter.paintFromSingleCachedImage(g, control, stateToPaint, boundsRect);
return;
}
RecyclableJRSUISlicedImageControl slicesRef = slicedControlImages.get(stateToPaint);
if (slicesRef == null) {
final NineSliceMetrics metrics = metricsProvider.getNineSliceMetricsForState(stateToPaint);
if (metrics == null) {
! AquaSingleImagePainter.paintFromSingleCachedImage(g, control, stateToPaint, boundsRect);
return;
}
slicesRef = new RecyclableJRSUISlicedImageControl(control, stateToPaint, metrics);
slicedControlImages.put(stateToPaint, slicesRef);
}
final SlicedImageControl slices = slicesRef.get();
slices.paint(g, boundsRect.x, boundsRect.y, boundsRect.width, boundsRect.height);
}
}
! private static final class AquaSingleImagePainter<T extends JRSUIState>
! extends AquaPainter<T> {
!
AquaSingleImagePainter(final T state) {
super(new JRSUIControl(false), state);
}
@Override
! void paint(final Graphics2D g, final T stateToPaint) {
! paintFromSingleCachedImage(g, control, stateToPaint, boundsRect);
}
! static void paintFromSingleCachedImage(final Graphics2D g,
! final JRSUIControl control, final JRSUIState controlState,
! final Rectangle bounds) {
! if (bounds.width <= 0 || bounds.height <= 0) {
! return;
! }
+ int scale = 1;
+ if (g instanceof SunGraphics2D) {
+ scale = ((SunGraphics2D) g).surfaceData.getDefaultScale();
+ }
final GraphicsConfiguration config = g.getDeviceConfiguration();
final ImageCache cache = ImageCache.getInstance();
! final int imgW = bounds.width * scale;
! final int imgH = bounds.height * scale;
! BufferedImage img = (BufferedImage) cache.getImage(config, imgW, imgH, scale, controlState);
! if (img == null) {
! img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB_PRE);
! cache.setImage(img, config, imgW, imgH, scale, controlState);
! final WritableRaster raster = img.getRaster();
! final DataBufferInt buffer = (DataBufferInt) raster.getDataBuffer();
control.set(controlState);
control.paint(SunWritableRaster.stealData(buffer, 0),
! imgW, imgH, 0, 0, bounds.width, bounds.height);
SunWritableRaster.markDirty(buffer);
}
! g.drawImage(img, bounds.x, bounds.y, bounds.width, bounds.height, null);
}
}
! private static class RecyclableJRSUISlicedImageControl
! extends RecyclableSlicedImageControl {
!
! private final JRSUIControl control;
! private final JRSUIState state;
RecyclableJRSUISlicedImageControl(final JRSUIControl control, final JRSUIState state, final NineSliceMetrics metrics) {
super(metrics);
this.control = control;
this.state = state;
*** 187,207 ****
return image;
}
}
! protected Graphics2D getGraphics2D(final Graphics g) {
try {
return (SunGraphics2D)g; // doing a blind try is faster than checking instanceof
! } catch (Exception e) {
if (g instanceof PeekGraphics) {
// if it is a peek just dirty the region
g.fillRect(boundsRect.x, boundsRect.y, boundsRect.width, boundsRect.height);
} else if (g instanceof ProxyGraphics2D) {
final ProxyGraphics2D pg = (ProxyGraphics2D)g;
final Graphics2D g2d = pg.getDelegate();
! if (g2d instanceof SunGraphics2D) { return (SunGraphics2D)g2d; }
} else if (g instanceof Graphics2D) {
return (Graphics2D) g;
}
}
--- 198,220 ----
return image;
}
}
! private Graphics2D getGraphics2D(final Graphics g) {
try {
return (SunGraphics2D)g; // doing a blind try is faster than checking instanceof
! } catch (Exception ignored) {
if (g instanceof PeekGraphics) {
// if it is a peek just dirty the region
g.fillRect(boundsRect.x, boundsRect.y, boundsRect.width, boundsRect.height);
} else if (g instanceof ProxyGraphics2D) {
final ProxyGraphics2D pg = (ProxyGraphics2D)g;
final Graphics2D g2d = pg.getDelegate();
! if (g2d instanceof SunGraphics2D) {
! return g2d;
! }
} else if (g instanceof Graphics2D) {
return (Graphics2D) g;
}
}