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; } }