jsvg: simplified/fixed loading from input stream; replaced internal usage of URI with URL

This commit is contained in:
Karl Tauber
2023-07-10 13:41:54 +02:00
parent f6062e1ec4
commit 799f8efe22
2 changed files with 33 additions and 67 deletions

View File

@@ -32,7 +32,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@@ -64,9 +63,8 @@ public class FlatSVGIcon
implements DisabledIconProvider implements DisabledIconProvider
{ {
// cache that uses soft references for values, which allows freeing SVG documents if no longer used // cache that uses soft references for values, which allows freeing SVG documents if no longer used
private static final SoftCache<URI, SVGDocument> svgCache = new SoftCache<>(); private static final SoftCache<URL, SVGDocument> svgCache = new SoftCache<>();
private static final SVGLoader svgLoader = new SVGLoader(); private static final SVGLoader svgLoader = new SVGLoader();
private static int streamNumber;
private final String name; private final String name;
private final int width; private final int width;
@@ -74,7 +72,7 @@ public class FlatSVGIcon
private final float scale; private final float scale;
private final boolean disabled; private final boolean disabled;
private final ClassLoader classLoader; private final ClassLoader classLoader;
private final URI uri; private final URL url;
private ColorFilter colorFilter; private ColorFilter colorFilter;
@@ -219,7 +217,7 @@ public class FlatSVGIcon
* @since 2 * @since 2
*/ */
public FlatSVGIcon( URL url ) { public FlatSVGIcon( URL url ) {
this( null, -1, -1, 1, false, null, url2uri( url ) ); this( null, -1, -1, 1, false, null, url );
} }
/** /**
@@ -235,7 +233,7 @@ public class FlatSVGIcon
* @since 2 * @since 2
*/ */
public FlatSVGIcon( URI uri ) { public FlatSVGIcon( URI uri ) {
this( null, -1, -1, 1, false, null, uri ); this( null, -1, -1, 1, false, null, uri2url( uri ) );
} }
/** /**
@@ -250,7 +248,7 @@ public class FlatSVGIcon
* @since 2 * @since 2
*/ */
public FlatSVGIcon( File file ) { public FlatSVGIcon( File file ) {
this( null, -1, -1, 1, false, null, file.toURI() ); this( null, -1, -1, 1, false, null, uri2url( file.toURI() ) );
} }
/** /**
@@ -266,24 +264,15 @@ public class FlatSVGIcon
* @since 2 * @since 2
*/ */
public FlatSVGIcon( InputStream in ) throws IOException { public FlatSVGIcon( InputStream in ) throws IOException {
this( null, -1, -1, 1, false, null, loadFromStream( in ) ); this( null, -1, -1, 1, false, null, null );
// since the input stream is already loaded and parsed,
// get the document here and remove it from cache
update();
synchronized( FlatSVGIcon.class ) {
svgCache.remove( uri );
}
}
private static synchronized URI loadFromStream( InputStream in ) throws IOException {
try( InputStream in2 = in ) { try( InputStream in2 = in ) {
SVGDocument document = svgLoader.load( in2 ); document = svgLoader.load( in2 );
URI dummyUri = new URI( "inputStreamSVG", "/flatlaf-stream-" + streamNumber++, null );
svgCache.put( dummyUri, document ); if( document == null ) {
return dummyUri; loadFailed = true;
} catch( URISyntaxException e ) { LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load SVG icon from input stream", null );
throw new IllegalStateException( e ); }
} }
} }
@@ -295,14 +284,14 @@ public class FlatSVGIcon
* @since 2.0.1 * @since 2.0.1
*/ */
public FlatSVGIcon( FlatSVGIcon icon ) { public FlatSVGIcon( FlatSVGIcon icon ) {
this( icon.name, icon.width, icon.height, icon.scale, icon.disabled, icon.classLoader, icon.uri ); this( icon.name, icon.width, icon.height, icon.scale, icon.disabled, icon.classLoader, icon.url );
colorFilter = icon.colorFilter; colorFilter = icon.colorFilter;
document = icon.document; document = icon.document;
dark = icon.dark; dark = icon.dark;
} }
protected FlatSVGIcon( String name, int width, int height, float scale, boolean disabled, ClassLoader classLoader, protected FlatSVGIcon( String name, int width, int height, float scale,
URI uri ) boolean disabled, ClassLoader classLoader, URL url )
{ {
this.name = name; this.name = name;
this.width = width; this.width = width;
@@ -310,7 +299,7 @@ public class FlatSVGIcon
this.scale = scale; this.scale = scale;
this.disabled = disabled; this.disabled = disabled;
this.classLoader = classLoader; this.classLoader = classLoader;
this.uri = uri; this.url = url;
} }
/** /**
@@ -389,7 +378,7 @@ public class FlatSVGIcon
if( width == this.width && height == this.height ) if( width == this.width && height == this.height )
return this; return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, uri ); FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, url );
icon.colorFilter = colorFilter; icon.colorFilter = colorFilter;
icon.document = document; icon.document = document;
icon.dark = dark; icon.dark = dark;
@@ -408,7 +397,7 @@ public class FlatSVGIcon
if( scale == this.scale ) if( scale == this.scale )
return this; return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, uri ); FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, url );
icon.colorFilter = colorFilter; icon.colorFilter = colorFilter;
icon.document = document; icon.document = document;
icon.dark = dark; icon.dark = dark;
@@ -427,7 +416,7 @@ public class FlatSVGIcon
if( disabled ) if( disabled )
return this; return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, true, classLoader, uri ); FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, true, classLoader, url );
icon.colorFilter = colorFilter; icon.colorFilter = colorFilter;
icon.document = document; icon.document = document;
icon.dark = dark; icon.dark = dark;
@@ -473,13 +462,12 @@ public class FlatSVGIcon
dark = isDarkLaf(); dark = isDarkLaf();
// SVGs already loaded via url or input stream can not have light/dark variants // SVGs already loaded via url, file or input stream can not have light/dark variants
if( uri != null && document != null ) if( document != null && name == null )
return; return;
URI uri = this.uri; URL url = this.url;
URL url = null; if( url == null ) {
if( uri == null ) {
url = getIconURL( name, dark ); url = getIconURL( name, dark );
if( url == null && dark ) if( url == null && dark )
url = getIconURL( name, false ); url = getIconURL( name, false );
@@ -489,37 +477,27 @@ public class FlatSVGIcon
LoggingFacade.INSTANCE.logConfig( "FlatSVGIcon: resource '" + name + "' not found (if using Java modules, check whether icon package is opened in module-info.java)", null ); LoggingFacade.INSTANCE.logConfig( "FlatSVGIcon: resource '" + name + "' not found (if using Java modules, check whether icon package is opened in module-info.java)", null );
return; return;
} }
uri = url2uri( url );
} }
if( url == null ) { document = loadSVG( url );
url = uri2url( uri );
}
document = loadSVG( uri, url );
loadFailed = (document == null); loadFailed = (document == null);
} }
/* static synchronized SVGDocument loadSVG( URL url ) {
* The uri and url parameters should always match each other in the sense that they represent the same
* location. We pass both as most places
*/
static synchronized SVGDocument loadSVG( URI uri, URL url ) {
// get from our cache // get from our cache
SVGDocument document = svgCache.get( uri ); SVGDocument document = svgCache.get( url );
if( document != null ) if( document != null )
return document; return document;
// load/get SVG document // load SVG document
document = svgLoader.load( url ); document = svgLoader.load( url );
if( document == null ) { if( document == null ) {
LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load '" + uri + "'", null ); LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load '" + url + "'", null );
return null; return null;
} }
svgCache.put( uri, document ); svgCache.put( url, document );
return document; return document;
} }
@@ -674,14 +652,6 @@ public class FlatSVGIcon
return MultiResolutionImageSupport.create( 0, dimensions, producer ); return MultiResolutionImageSupport.create( 0, dimensions, producer );
} }
static URI url2uri( URL url ) {
try {
return url.toURI();
} catch( URISyntaxException ex ) {
throw new IllegalArgumentException( ex );
}
}
static URL uri2url( URI uri ) { static URL uri2url( URI uri ) {
try { try {
return uri.toURL(); return uri.toURL();

View File

@@ -83,7 +83,7 @@ public class FlatSVGUtils
* @since 2 * @since 2
*/ */
public static List<Image> createWindowIconImages( URL svgUrl ) { public static List<Image> createWindowIconImages( URL svgUrl ) {
SVGDocument document = loadSVG( svgUrl ); SVGDocument document = FlatSVGIcon.loadSVG( svgUrl );
if( SystemInfo.isWindows && MultiResolutionImageSupport.isAvailable() ) { if( SystemInfo.isWindows && MultiResolutionImageSupport.isAvailable() ) {
// use a multi-resolution image that creates images on demand for requested sizes // use a multi-resolution image that creates images on demand for requested sizes
@@ -148,7 +148,7 @@ public class FlatSVGUtils
* @since 2 * @since 2
*/ */
public static BufferedImage svg2image( URL svgUrl, int width, int height ) { public static BufferedImage svg2image( URL svgUrl, int width, int height ) {
return svg2image( loadSVG( svgUrl ), width, height ); return svg2image( FlatSVGIcon.loadSVG( svgUrl ), width, height );
} }
/** /**
@@ -180,7 +180,7 @@ public class FlatSVGUtils
* @since 2 * @since 2
*/ */
public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) { public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) {
SVGDocument document = loadSVG( svgUrl ); SVGDocument document = FlatSVGIcon.loadSVG( svgUrl );
FloatSize size = document.size(); FloatSize size = document.size();
int width = (int) (size.width * scaleFactor); int width = (int) (size.width * scaleFactor);
int height = (int) (size.height * scaleFactor); int height = (int) (size.height * scaleFactor);
@@ -196,7 +196,7 @@ public class FlatSVGUtils
* @return the image * @return the image
* @throws RuntimeException if failed to render SVG file * @throws RuntimeException if failed to render SVG file
*/ */
public static BufferedImage svg2image( SVGDocument document, int width, int height ) { private static BufferedImage svg2image( SVGDocument document, int width, int height ) {
BufferedImage image = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB ); BufferedImage image = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
Graphics2D g = image.createGraphics(); Graphics2D g = image.createGraphics();
@@ -220,8 +220,4 @@ public class FlatSVGUtils
private static URL getResource( String svgName ) { private static URL getResource( String svgName ) {
return FlatSVGUtils.class.getResource( svgName ); return FlatSVGUtils.class.getResource( svgName );
} }
private static SVGDocument loadSVG( URL url ) {
return FlatSVGIcon.loadSVG( FlatSVGIcon.url2uri( url ), url );
}
} }