55import jakarta .annotation .Nonnull ;
66import jakarta .annotation .Nullable ;
77import javafx .scene .Node ;
8- import javafx .scene .image .* ;
8+ import javafx .scene .image .ImageView ;
99import software .coley .recaf .ui .control .IconView ;
1010
11- import java .awt .*;
11+ import java .awt .Graphics2D ;
12+ import java .awt .RenderingHints ;
1213import java .awt .image .BufferedImage ;
1314import java .io .ByteArrayInputStream ;
1415import java .io .InputStream ;
16+ import java .lang .reflect .Method ;
1517import java .nio .charset .StandardCharsets ;
1618import java .util .Map ;
1719import java .util .concurrent .ConcurrentHashMap ;
@@ -31,9 +33,7 @@ public class SVG {
3133 private static final Map <String , SVGDocument > DOCUMENT_CACHE = new ConcurrentHashMap <>();
3234
3335 static {
34- EMPTY_DOCUMENT = new SVGLoader ()
35- .load (new ByteArrayInputStream (("<svg width=\" 0\" height=\" 0\" xmlns=\" http://www.w3.org/2000/svg\" >" +
36- "</svg>" ).getBytes (StandardCharsets .UTF_8 )));
36+ EMPTY_DOCUMENT = read (new ByteArrayInputStream (("<svg width=\" 0\" height=\" 0\" xmlns=\" http://www.w3.org/2000/svg\" ></svg>" ).getBytes (StandardCharsets .UTF_8 )));
3737 }
3838
3939 /**
@@ -108,14 +108,7 @@ public static Node ofFile(@Nonnull String path, int width, int height) {
108108 @ Nonnull
109109 public static Node ofFile (@ Nonnull String path , int width , int height ,
110110 @ Nullable Map <RenderingHints .Key , Object > renderingHints ) {
111- SVGDocument document = DOCUMENT_CACHE .computeIfAbsent (path , p -> {
112- try (InputStream is = ResourceUtil .resource (path )) {
113- SVGLoader loader = new SVGLoader ();
114- return loader .load (is );
115- } catch (Exception ex ) {
116- return EMPTY_DOCUMENT ;
117- }
118- });
111+ SVGDocument document = DOCUMENT_CACHE .computeIfAbsent (path , SVG ::read );
119112
120113 // Render to image
121114 BufferedImage image = new BufferedImage (width , height , BufferedImage .TYPE_INT_ARGB );
@@ -128,4 +121,35 @@ public static Node ofFile(@Nonnull String path, int width, int height,
128121 // Convert to FX compatible image
129122 return new ImageView (Icons .convertToFxImage (image ));
130123 }
124+
125+ @ Nonnull
126+ private static SVGDocument read (@ Nonnull String path ) {
127+ try (InputStream is = ResourceUtil .resource (path )) {
128+ return read (is );
129+ } catch (Exception ex ) {
130+ return EMPTY_DOCUMENT ;
131+ }
132+ }
133+
134+ @ Nonnull
135+ private static SVGDocument read (@ Nullable InputStream is ) {
136+ if (is == null )
137+ throw new IllegalStateException ();
138+
139+ // The optimal code for this is:
140+ // return new SVGLoader().load(is);
141+ // But JDK 24+ complains that @NotNull from THEIR CODE is missing in OUR classpath
142+ // even though it is not directly referenced in OUR CODE. What I really don't get
143+ // is that this is only a problem HERE with JSVG, despite this annotation being used
144+ // in other libraries without issue.
145+ // This is slower, but we also cache the results, so I don't care.
146+ // See: https://github.com/Col-E/Recaf/issues/933
147+ try {
148+ SVGLoader loader = new SVGLoader ();
149+ Method m = SVGLoader .class .getDeclaredMethod ("load" , InputStream .class );
150+ return (SVGDocument ) m .invoke (loader , is );
151+ } catch (Throwable t ) {
152+ throw new IllegalStateException (t );
153+ }
154+ }
131155}
0 commit comments