From 29fe87541e0f9fa30a2b8536736d3552c5ff0d5f Mon Sep 17 00:00:00 2001 From: weisj <31143295+weisJ@users.noreply.github.com> Date: Mon, 1 Mar 2021 23:09:45 +0100 Subject: [PATCH] Tooltip: Make use of BufferedImage#getSubImage. Also decrease the shadow opacity for light themes. --- .../components/border/DropShadowBorder.java | 63 +++++++++++-------- .../intellij/intellij_defaults.properties | 4 +- .../solarized_light_defaults.properties | 4 +- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/core/src/main/java/com/github/weisj/darklaf/components/border/DropShadowBorder.java b/core/src/main/java/com/github/weisj/darklaf/components/border/DropShadowBorder.java index 6abf079d..4c4debbb 100644 --- a/core/src/main/java/com/github/weisj/darklaf/components/border/DropShadowBorder.java +++ b/core/src/main/java/com/github/weisj/darklaf/components/border/DropShadowBorder.java @@ -25,6 +25,7 @@ import java.awt.*; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.awt.image.ConvolveOp; +import java.awt.image.ImageObserver; import java.awt.image.Kernel; import java.io.Serializable; import java.util.Arrays; @@ -158,51 +159,52 @@ public class DropShadowBorder implements Border, Serializable { if (showLeftShadow) { assert topLeftShadowPoint != null && bottomLeftShadowPoint != null; drawImage(g2, images[Position.LEFT.ordinal()], x, topLeftShadowPoint.y + shadowSize, shadowSize, - bottomLeftShadowPoint.y - topLeftShadowPoint.y - shadowSize); + bottomLeftShadowPoint.y - topLeftShadowPoint.y - shadowSize, c); } if (showBottomShadow) { assert bottomLeftShadowPoint != null && bottomRightShadowPoint != null; drawImage(g2, images[Position.BOTTOM.ordinal()], bottomLeftShadowPoint.x + shadowSize, y + height - shadowSize, bottomRightShadowPoint.x - bottomLeftShadowPoint.x - shadowSize, - shadowSize); + shadowSize, c); } if (showRightShadow) { assert topRightShadowPoint != null && bottomRightShadowPoint != null; drawImage(g2, images[Position.RIGHT.ordinal()], x + width - shadowSize, topRightShadowPoint.y + shadowSize, shadowSize, - bottomRightShadowPoint.y - topRightShadowPoint.y - shadowSize); + bottomRightShadowPoint.y - topRightShadowPoint.y - shadowSize, c); } if (showTopShadow) { assert topLeftShadowPoint != null && topRightShadowPoint != null; drawImage(g2, images[Position.TOP.ordinal()], topLeftShadowPoint.x + shadowSize, y, - topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize, shadowSize); + topRightShadowPoint.x - topLeftShadowPoint.x - shadowSize, shadowSize, c); } if (showLeftShadow || showTopShadow) { - drawImage(g2, images[Position.TOP_LEFT.ordinal()], topLeftShadowPoint); + drawImage(g2, images[Position.TOP_LEFT.ordinal()], topLeftShadowPoint, c); } if (showLeftShadow || showBottomShadow) { - drawImage(g2, images[Position.BOTTOM_LEFT.ordinal()], bottomLeftShadowPoint); + drawImage(g2, images[Position.BOTTOM_LEFT.ordinal()], bottomLeftShadowPoint, c); } if (showRightShadow || showBottomShadow) { - drawImage(g2, images[Position.BOTTOM_RIGHT.ordinal()], bottomRightShadowPoint); + drawImage(g2, images[Position.BOTTOM_RIGHT.ordinal()], bottomRightShadowPoint, c); } if (showRightShadow || showTopShadow) { - drawImage(g2, images[Position.TOP_RIGHT.ordinal()], topRightShadowPoint); + drawImage(g2, images[Position.TOP_RIGHT.ordinal()], topRightShadowPoint, c); } } } - protected void drawImage(final Graphics g, final Image image, final Point p) { + protected void drawImage(final Graphics g, final Image image, final Point p, final ImageObserver observer) { if (p == null) return; - g.drawImage(image, p.x, p.y, null); + g.drawImage(image, p.x, p.y, observer); } - 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); + protected void drawImage(final Graphics g, final Image image, final int x, final int y, final int w, final int h, + final ImageObserver observer) { + g.drawImage(image, x, y, w, h, observer); } @SuppressWarnings("SuspiciousNameCombination") @@ -214,12 +216,23 @@ public class DropShadowBorder implements Border, Serializable { images = new BufferedImage[Position.count()]; /* - * To draw a drop shadow, I have to: 1) Create a rounded rectangle 2) Create a BufferedImage to draw - * the rounded rect in 3) Translate the graphics for the image, so that the rectangle is centered in - * the drawn space. The border around the rectangle needs to be shadowWidth wide, so that there is - * space for the shadow to be drawn. 4) Draw the rounded rect as shadowColor, with an opacity of - * shadowOpacity 5) Create the BLUR_KERNEL 6) Blur the image 7) copy off the corners, sides, etc - * into images to be used for drawing the Border + * To draw a drop shadow, I have to: + * + * 1) Create a rounded rectangle + * + * 2) Create a BufferedImage to draw the rounded rect in + * + * 3) Translate the graphics for the image, so that the rectangle is centered in the drawn space. + * The border around the rectangle needs to be shadowWidth wide, so that there is space for the + * shadow to be drawn. + * + * 4) Draw the rounded rect as shadowColor, with an opacity of shadowOpacity + * + * 5) Create the BLUR_KERNEL + * + * 6) Blur the image + * + * 7) copy off the corners, sides, etc. into images to be used for drawing the Border */ int rectWidth = cornerSize + 1; RoundRectangle2D rect = new RoundRectangle2D.Double(0, 0, rectWidth, rectWidth, cornerSize, cornerSize); @@ -239,7 +252,10 @@ public class DropShadowBorder implements Border, Serializable { Arrays.fill(blurKernel, blurry); ConvolveOp blur = new ConvolveOp(new Kernel(shadowSize, shadowSize, blurKernel)); BufferedImage targetImage = ImageUtil.createCompatibleTranslucentImage(imageWidth, imageWidth); - ((Graphics2D) targetImage.getGraphics()).drawImage(image, blur, -(shadowSize / 2), -(shadowSize / 2)); + Graphics2D targetGraphics = (Graphics2D) targetImage.getGraphics(); + try (Disposable d = targetGraphics::dispose) { + targetGraphics.drawImage(image, blur, -(shadowSize / 2), -(shadowSize / 2)); + } int x = 1; int y = 1; @@ -301,14 +317,7 @@ public class DropShadowBorder implements Border, Serializable { * strategies on later JDKs.) */ private BufferedImage getSubImage(final BufferedImage img, final int x, final int y, final int w, final int h) { - BufferedImage ret = ImageUtil.createCompatibleTranslucentImage(w, h); - Graphics2D g2 = ret.createGraphics(); - - try (Disposable d = g2::dispose) { - g2.drawImage(img, 0, 0, w, h, x, y, x + w, y + h, null); - } - - return ret; + return img.getSubimage(x, y, w, h); } /** {@inheritDoc} */ diff --git a/theme/src/main/resources/com/github/weisj/darklaf/theme/intellij/intellij_defaults.properties b/theme/src/main/resources/com/github/weisj/darklaf/theme/intellij/intellij_defaults.properties index 03e95116..756ebc6c 100644 --- a/theme/src/main/resources/com/github/weisj/darklaf/theme/intellij/intellij_defaults.properties +++ b/theme/src/main/resources/com/github/weisj/darklaf/theme/intellij/intellij_defaults.properties @@ -159,8 +159,8 @@ Theme.highContrast = false %glowOpacity = 50 %dropOpacity = 80 -%shadowOpacityLight = 10 -%shadowOpacityStrong = 20 +%shadowOpacityLight = 5 +%shadowOpacityStrong = 10 %glowFocus = #3d94f2 %glowFocusInactive = #3d94f2 diff --git a/theme/src/main/resources/com/github/weisj/darklaf/theme/solarized_light/solarized_light_defaults.properties b/theme/src/main/resources/com/github/weisj/darklaf/theme/solarized_light/solarized_light_defaults.properties index 6c2142bb..514063b6 100644 --- a/theme/src/main/resources/com/github/weisj/darklaf/theme/solarized_light/solarized_light_defaults.properties +++ b/theme/src/main/resources/com/github/weisj/darklaf/theme/solarized_light/solarized_light_defaults.properties @@ -139,8 +139,8 @@ Theme.highContrast = false %glowOpacity = 50 %dropOpacity = 80 -%shadowOpacityLight = 10 -%shadowOpacityStrong = 20 +%shadowOpacityLight = 5 +%shadowOpacityStrong = 10 %glowFocus = #3b93eb %glowFocusInactive = #3b93eb