From 6f8a7471c205af4dc10a4b4458bc7e7399f70dfb Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 26 Oct 2020 15:09:44 +0100 Subject: [PATCH] SVGUtils: support creating window images from SVG files that are not 16x16 (issue #196) --- .../com/formdev/flatlaf/extras/SVGUtils.java | 86 +++++++++++++++---- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/SVGUtils.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/SVGUtils.java index 3a123865..9f698d48 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/SVGUtils.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/SVGUtils.java @@ -30,46 +30,84 @@ import com.kitfox.svg.SVGDiagram; import com.kitfox.svg.SVGException; /** + * Utility methods for SVG. + * * @author Karl Tauber */ public class SVGUtils { /** * Creates from the given SVG a list of icon images with different sizes that - * can be used for windows headers. The SVG should have a size of 16 x 16. + * can be used for windows headers. The SVG should have a size of 16x16, + * otherwise it is scaled. * + * @param svgName the name of the SVG resource (a '/'-separated path) + * @return list of icon images with different sizes (16x16, 24x24, 32x32, 48x48 and 64x64) + * @throws RuntimeException if failed to load or render SVG file * @see JWindow#setIconImages(List) */ public static List createWindowIconImages( String svgName ) { + SVGDiagram diagram = loadSVG( svgName ); + return Arrays.asList( - svg2image( svgName, 1f ), // 16 x 16 - svg2image( svgName, 1.5f ), // 24 x 24 - svg2image( svgName, 2f ), // 32 x 32 - svg2image( svgName, 3f ), // 48 x 48 - svg2image( svgName, 4f ) // 64 x 64 + svg2image( diagram, 16, 16 ), + svg2image( diagram, 24, 24 ), + svg2image( diagram, 32, 32 ), + svg2image( diagram, 48, 48 ), + svg2image( diagram, 64, 64 ) ); } /** * Creates a buffered image and renders the given SVG into it. + * + * @param svgName the name of the SVG resource (a '/'-separated path) + * @param width the width of the image + * @param height the height of the image + * @return the image + * @throws RuntimeException if failed to load or render SVG file + */ + public static BufferedImage svg2image( String svgName, int width, int height ) { + return svg2image( loadSVG( svgName ), width, height ); + } + + /** + * Creates a buffered image and renders the given SVG into it. + * + * @param svgName the name of the SVG resource (a '/'-separated path) + * @param scaleFactor the amount by which the SVG size is scaled + * @return the image + * @throws RuntimeException if failed to load or render SVG file */ public static BufferedImage svg2image( String svgName, float scaleFactor ) { - try { - URL url = SVGUtils.class.getResource( svgName ); - SVGDiagram diagram = SVGCache.getSVGUniverse().getDiagram( url.toURI() ); + SVGDiagram diagram = loadSVG( svgName ); + int width = (int) (diagram.getWidth() * scaleFactor); + int height = (int) (diagram.getHeight() * scaleFactor); + return svg2image( diagram, width, height ); + } - BufferedImage image = new BufferedImage( - (int) (diagram.getWidth() * scaleFactor), - (int) (diagram.getHeight() * scaleFactor), - BufferedImage.TYPE_INT_ARGB ); + /** + * Creates a buffered image and renders the given SVGDiagram into it. + * + * @param diagram the SVG diagram + * @param width the width of the image + * @param height the height of the image + * @return the image + * @throws RuntimeException if failed to render SVG file + */ + public static BufferedImage svg2image( SVGDiagram diagram, int width, int height ) { + try { + BufferedImage image = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB ); Graphics2D g = image.createGraphics(); try { g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR ); - if( scaleFactor != 1f ) - g.scale( scaleFactor, scaleFactor ); + double sx = width / diagram.getWidth(); + double sy = height / diagram.getHeight(); + if( sx != 1 || sy != 1 ) + g.scale( sx, sy ); diagram.setIgnoringClipHeuristic( true ); @@ -79,7 +117,23 @@ public class SVGUtils } return image; - } catch( URISyntaxException | SVGException ex ) { + } catch( SVGException ex ) { + throw new RuntimeException( ex ); + } + } + + /** + * Loads a SVG file. + * + * @param svgName the name of the SVG resource (a '/'-separated path) + * @return the SVG diagram + * @throws RuntimeException if failed to load SVG file + */ + private static SVGDiagram loadSVG( String svgName ) { + try { + URL url = SVGUtils.class.getResource( svgName ); + return SVGCache.getSVGUniverse().getDiagram( url.toURI() ); + } catch( URISyntaxException ex ) { throw new RuntimeException( ex ); } }