Browse Source

Reduce interpolation quality for drop shadow border for faster paint speed.

pull/188/head
weisj 5 years ago
parent
commit
73face463d
  1. 96
      core/src/main/java/com/github/weisj/darklaf/components/border/DropShadowBorder.java
  2. 35
      utils/src/main/java/com/github/weisj/darklaf/util/Disposable.java

96
core/src/main/java/com/github/weisj/darklaf/components/border/DropShadowBorder.java

@ -37,6 +37,7 @@ import java.util.Map;
import javax.swing.border.Border; import javax.swing.border.Border;
import com.github.weisj.darklaf.graphics.ImageUtil; import com.github.weisj.darklaf.graphics.ImageUtil;
import com.github.weisj.darklaf.util.Disposable;
/** /**
* Implements a DropShadow for components. In general, the DropShadowBorder will work with any rectangular components * Implements a DropShadow for components. In general, the DropShadowBorder will work with any rectangular components
@ -93,15 +94,10 @@ public class DropShadowBorder implements Border, Serializable {
@Override @Override
public void paintBorder(final Component c, final Graphics graphics, public void paintBorder(final Component c, final Graphics graphics,
final int x, final int y, final int width, final int height) { final int x, final int y, final int width, final int height) {
/* final BufferedImage[] images = getImages();
* 1) Get images for this border final Graphics2D g2 = (Graphics2D) graphics.create();
* 2) Paint the images for each side of the border that should be painted
*/
BufferedImage[] images = getImages((Graphics2D) graphics);
Graphics2D g2 = (Graphics2D) graphics.create(); try (Disposable d = g2::dispose) {
try {
// The location and size of the shadows depends on which shadows are being // The location and size of the shadows depends on which shadows are being
// drawn. For instance, if the left & bottom shadows are being drawn, then // drawn. For instance, if the left & bottom shadows are being drawn, then
// the left shadow extends all the way down to the corner, a corner is drawn, // the left shadow extends all the way down to the corner, a corner is drawn,
@ -160,78 +156,72 @@ public class DropShadowBorder implements Border, Serializable {
} }
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC); RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_SPEED); RenderingHints.VALUE_RENDER_SPEED);
if (showLeftShadow) { if (showLeftShadow) {
assert topLeftShadowPoint != null && bottomLeftShadowPoint != null; assert topLeftShadowPoint != null && bottomLeftShadowPoint != null;
Rectangle leftShadowRect = new Rectangle(x, topLeftShadowPoint.y + shadowSize, shadowSize, drawImage(g2, images[Position.LEFT.ordinal()],
bottomLeftShadowPoint.y - topLeftShadowPoint.y - shadowSize); x,
g2.drawImage(images[Position.LEFT.ordinal()], topLeftShadowPoint.y + shadowSize,
leftShadowRect.x, leftShadowRect.y, shadowSize,
leftShadowRect.width, leftShadowRect.height, null); bottomLeftShadowPoint.y - topLeftShadowPoint.y - shadowSize);
} }
if (showBottomShadow) { if (showBottomShadow) {
assert bottomLeftShadowPoint != null && bottomRightShadowPoint != null; assert bottomLeftShadowPoint != null && bottomRightShadowPoint != null;
Rectangle bottomShadowRect = new Rectangle(bottomLeftShadowPoint.x + shadowSize, drawImage(g2, images[Position.BOTTOM.ordinal()],
y + height - shadowSize, bottomLeftShadowPoint.x + shadowSize,
bottomRightShadowPoint.x - bottomLeftShadowPoint.x y + height - shadowSize,
- shadowSize, bottomRightShadowPoint.x - bottomLeftShadowPoint.x - shadowSize,
shadowSize); shadowSize);
g2.drawImage(images[Position.BOTTOM.ordinal()],
bottomShadowRect.x, bottomShadowRect.y,
bottomShadowRect.width, bottomShadowRect.height, null);
} }
if (showRightShadow) { if (showRightShadow) {
assert topRightShadowPoint != null && bottomRightShadowPoint != null; assert topRightShadowPoint != null && bottomRightShadowPoint != null;
Rectangle rightShadowRect = new Rectangle(x + width - shadowSize, topRightShadowPoint.y + shadowSize, drawImage(g2, images[Position.RIGHT.ordinal()],
shadowSize, x + width - shadowSize,
bottomRightShadowPoint.y - topRightShadowPoint.y topRightShadowPoint.y + shadowSize,
- shadowSize); shadowSize,
g2.drawImage(images[Position.RIGHT.ordinal()], bottomRightShadowPoint.y - topRightShadowPoint.y - shadowSize);
rightShadowRect.x, rightShadowRect.y,
rightShadowRect.width, rightShadowRect.height, null);
} }
if (showTopShadow) { if (showTopShadow) {
assert topLeftShadowPoint != null && topRightShadowPoint != null; assert topLeftShadowPoint != null && topRightShadowPoint != null;
Rectangle topShadowRect = new Rectangle(topLeftShadowPoint.x + shadowSize, y, drawImage(g2, images[Position.TOP.ordinal()],
topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize, topLeftShadowPoint.x + shadowSize,
shadowSize); y,
g2.drawImage(images[Position.TOP.ordinal()], topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize,
topShadowRect.x, topShadowRect.y, shadowSize);
topShadowRect.width, topShadowRect.height, null);
} }
if (showLeftShadow || showTopShadow) { if (showLeftShadow || showTopShadow) {
assert topLeftShadowPoint != null; drawImage(g2, images[Position.TOP_LEFT.ordinal()], topLeftShadowPoint);
g2.drawImage(images[Position.TOP_LEFT.ordinal()], topLeftShadowPoint.x, topLeftShadowPoint.y, null);
} }
if (showLeftShadow || showBottomShadow) { if (showLeftShadow || showBottomShadow) {
assert bottomLeftShadowPoint != null; drawImage(g2, images[Position.BOTTOM_LEFT.ordinal()], bottomLeftShadowPoint);
g2.drawImage(images[Position.BOTTOM_LEFT.ordinal()], bottomLeftShadowPoint.x, bottomLeftShadowPoint.y,
null);
} }
if (showRightShadow || showBottomShadow) { if (showRightShadow || showBottomShadow) {
assert bottomRightShadowPoint != null; drawImage(g2, images[Position.BOTTOM_RIGHT.ordinal()], bottomRightShadowPoint);
g2.drawImage(images[Position.BOTTOM_RIGHT.ordinal()], bottomRightShadowPoint.x,
bottomRightShadowPoint.y, null);
} }
if (showRightShadow || showTopShadow) { if (showRightShadow || showTopShadow) {
assert topRightShadowPoint != null; drawImage(g2, images[Position.TOP_RIGHT.ordinal()], topRightShadowPoint);
g2.drawImage(images[Position.TOP_RIGHT.ordinal()], topRightShadowPoint.x, topRightShadowPoint.y, null);
} }
} finally {
g2.dispose();
} }
} }
@SuppressWarnings("SuspiciousNameCombination") protected void drawImage(final Graphics g, final Image image, final Point p) {
if (p == null) return;
g.drawImage(image, p.x, p.y, null);
}
private BufferedImage[] getImages(final Graphics2D g2) { protected void drawImage(final Graphics g, final Image image, final int x, final int y, final int w, final int h) {
g.drawImage(image, x, y, w, h, null);
}
@SuppressWarnings("SuspiciousNameCombination")
private BufferedImage[] getImages() {
// first, check to see if an image for this size has already been rendered // first, check to see if an image for this size has already been rendered
// if so, use the cache. Else, draw and save // if so, use the cache. Else, draw and save
BufferedImage[] images = CACHE.get(getBorderHash(shadowSize, shadowOpacity, shadowColor)); BufferedImage[] images = CACHE.get(getBorderHash(shadowSize, shadowOpacity, shadowColor));
@ -258,13 +248,11 @@ public class DropShadowBorder implements Border, Serializable {
BufferedImage image = ImageUtil.createCompatibleTranslucentImage(imageWidth, imageWidth); BufferedImage image = ImageUtil.createCompatibleTranslucentImage(imageWidth, imageWidth);
Graphics2D buffer = (Graphics2D) image.getGraphics(); Graphics2D buffer = (Graphics2D) image.getGraphics();
try { try (Disposable d = buffer::dispose) {
buffer.setPaint(new Color(shadowColor.getRed(), shadowColor.getGreen(), buffer.setPaint(new Color(shadowColor.getRed(), shadowColor.getGreen(),
shadowColor.getBlue(), (int) (shadowOpacity * 255))); shadowColor.getBlue(), (int) (shadowOpacity * 255)));
buffer.translate(shadowSize, shadowSize); buffer.translate(shadowSize, shadowSize);
buffer.fill(rect); buffer.fill(rect);
} finally {
buffer.dispose();
} }
float blurry = 1.0f / (float) (shadowSize * shadowSize); float blurry = 1.0f / (float) (shadowSize * shadowSize);
@ -336,10 +324,8 @@ public class DropShadowBorder implements Border, Serializable {
BufferedImage ret = ImageUtil.createCompatibleTranslucentImage(w, h); BufferedImage ret = ImageUtil.createCompatibleTranslucentImage(w, h);
Graphics2D g2 = ret.createGraphics(); Graphics2D g2 = ret.createGraphics();
try { try (Disposable d = g2::dispose) {
g2.drawImage(img, 0, 0, w, h, x, y, x + w, y + h, null); g2.drawImage(img, 0, 0, w, h, x, y, x + w, y + h, null);
} finally {
g2.dispose();
} }
return ret; return ret;

35
utils/src/main/java/com/github/weisj/darklaf/util/Disposable.java

@ -0,0 +1,35 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package com.github.weisj.darklaf.util;
public interface Disposable extends AutoCloseable {
void dispose();
@Override
default void close() {
dispose();
}
}
Loading…
Cancel
Save