diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java index 8fb2f842..3db69935 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java @@ -16,10 +16,13 @@ package com.formdev.flatlaf.extras; +import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; +import java.awt.Rectangle; +import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.net.URISyntaxException; import java.net.URL; @@ -29,7 +32,9 @@ import javax.swing.UIManager; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.util.UIScale; -import com.kitfox.svg.app.beans.SVGIcon; +import com.kitfox.svg.SVGDiagram; +import com.kitfox.svg.SVGException; +import com.kitfox.svg.SVGUniverse; /** * @author Karl Tauber @@ -37,19 +42,19 @@ import com.kitfox.svg.app.beans.SVGIcon; public class FlatSVGIcon extends ImageIcon { + // use own SVG universe so that it can not be cleared from anywhere + private static final SVGUniverse svgUniverse = new SVGUniverse(); + private final String name; - private final SVGIcon svgIcon; + private SVGDiagram diagram; private boolean dark; public FlatSVGIcon( String name ) { this.name = name; - - svgIcon = new SVGIcon(); - svgIcon.setAntiAlias( true ); } private void update() { - if( dark == isDarkLaf() && svgIcon.getSvgURI() != null ) + if( dark == isDarkLaf() && diagram != null ) return; dark = isDarkLaf(); @@ -57,8 +62,9 @@ public class FlatSVGIcon if( url == null & dark ) url = getIconURL( name, false ); + // load/get image try { - svgIcon.setSvgURI( url.toURI() ); + diagram = svgUniverse.getDiagram( url.toURI() ); } catch( URISyntaxException ex ) { ex.printStackTrace(); } @@ -75,32 +81,59 @@ public class FlatSVGIcon @Override public int getIconWidth() { update(); - return UIScale.scale( svgIcon.getIconWidth() ); + return (int) UIScale.scale( (diagram != null) ? diagram.getWidth() : 16 ); } @Override public int getIconHeight() { update(); - return UIScale.scale( svgIcon.getIconHeight() ); + return (int) UIScale.scale( (diagram != null) ? diagram.getHeight() : 16 ); } @Override public void paintIcon( Component c, Graphics g, int x, int y ) { update(); + Rectangle clipBounds = g.getClipBounds(); + if( clipBounds != null && !clipBounds.intersects( new Rectangle( x, y, getIconWidth(), getIconHeight() ) ) ) + return; + Graphics2D g2 = (Graphics2D) g.create(); try { FlatUIUtils.setRenderingHints( g2 ); + g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR ); - g2.translate( x, y ); - UIScale.scaleGraphics( g2 ); - - svgIcon.paintIcon( c, g2, 0, 0 ); + paintSvg( g2, x, y ); } finally { g2.dispose(); } } + private void paintSvg( Graphics2D g, int x, int y ) { + if( diagram == null ) { + paintSvgError( g, x, y ); + return; + } + + g.translate( x, y ); + g.clipRect( 0, 0, getIconWidth(), getIconHeight() ); + + UIScale.scaleGraphics( g ); + + diagram.setIgnoringClipHeuristic( true ); + + try { + diagram.render( g ); + } catch( SVGException ex ) { + paintSvgError( g, 0, 0 ); + } + } + + private void paintSvgError( Graphics2D g, int x, int y ) { + g.setColor( Color.red ); + g.fillRect( x, y, getIconWidth(), getIconHeight() ); + } + @Override public Image getImage() { update();