Skip to content

Commit 85141cd

Browse files
committed
Add support for SVG images
SWT currently loads icons exclusively as raster graphics (e.g., PNGs) without support for vector formats like SVG (except for Linux). A major drawback of raster graphics is their inability to scale without degrading image quality. Additionally, generating icons of different sizes requires manually rasterization of SVGs as a preparatory step, leading to unnecessary effort and many icon files. This change introduces support for vector graphics in images, enabling SVGs to be used for images. An SVG rasterizer can be provided via an SWT fragment. This change adds an according fragment based on the JSVG library. An according FileFormat implementation is added, which utilized a present SVG rasterization fragment to rasterize images for the desired zoom factor. Fixes eclipse-platform#1438
1 parent dc55c0e commit 85141cd

File tree

8 files changed

+35
-39
lines changed

8 files changed

+35
-39
lines changed

bundles/org.eclipse.swt.svg/META-INF/MANIFEST.MF

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
3-
Bundle-Name: SWT SVG Rendering Support
43
Bundle-SymbolicName: org.eclipse.swt.svg
54
Bundle-Version: 3.130.0.qualifier
65
Automatic-Module-Name: org.eclipse.swt.svg
6+
Bundle-Name: %fragmentName
7+
Bundle-Vendor: %providerName
78
Bundle-RequiredExecutionEnvironment: JavaSE-17
89
Fragment-Host: org.eclipse.swt
910
Import-Package: com.github.weisj.jsvg;version="[1.7.0,2.0.0)",

bundles/org.eclipse.swt.svg/build.properties

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
source.. = src/
22
output.. = bin/
33
bin.includes = META-INF/,\
4-
.
4+
.,\
5+
fragment.properties
6+
57
tycho.pomless.parent = ../../local-build/local-build-parent
68
jars.extra.classpath = platform:/plugin/org.eclipse.swt.cocoa.macosx.aarch64,\
79
platform:/plugin/org.eclipse.swt.cocoa.macosx.x86_64,\
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
###############################################################################
2+
# Copyright (c) 2025 Vector Informatik GmbH and others.
3+
#
4+
# This program and the accompanying materials are made available under the terms of the Eclipse
5+
# Public License 2.0 which accompanies this distribution, and is available at
6+
# https://www.eclipse.org/legal/epl-2.0/
7+
#
8+
# SPDX-License-Identifier: EPL-2.0
9+
#
10+
# Contributors:
11+
# Michael Bangas (Vector Informatik GmbH) - initial API and implementation
12+
###############################################################################
13+
fragmentName = SWT SVG Rendering Support
14+
providerName = Eclipse.org

bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/JSVGRasterizer.java

+3-9
Original file line numberDiff line numberDiff line change
@@ -100,23 +100,17 @@ public ImageData rasterizeSVG(InputStream inputStream, int zoom, int flag) throw
100100
SWT.error(SWT.ERROR_INVALID_IMAGE);
101101
}
102102
SVGDocument svgDocument = loadSVG(inputStream);
103-
if (svgDocument != null) {
104-
return generateRasterizedImageData(svgDocument, zoom);
105-
} else {
103+
if (svgDocument == null) {
106104
SWT.error(SWT.ERROR_INVALID_IMAGE);
107105
}
108-
return null;
106+
BufferedImage rasterizedImage = renderSVG(svgDocument, zoom);
107+
return convertToSWTImageData(rasterizedImage);
109108
}
110109

111110
private SVGDocument loadSVG(InputStream inputStream) {
112111
return SVG_LOADER.load(inputStream, null, LoaderContext.createDefault());
113112
}
114113

115-
private ImageData generateRasterizedImageData(SVGDocument svgDocument, int zoom) {
116-
BufferedImage rasterizedImage = renderSVG(svgDocument, zoom);
117-
return convertToSWTImageData(rasterizedImage);
118-
}
119-
120114
private BufferedImage renderSVG(SVGDocument svgDocument, int zoom) {
121115
float scalingFactor = zoom / 100.0f;
122116
BufferedImage image = createImageBase(svgDocument, scalingFactor);

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java

-1
Original file line numberDiff line numberDiff line change
@@ -4465,7 +4465,6 @@ public class SWT {
44654465

44664466
/**
44674467
* Image format constant indicating a SVG format image (value is 8).
4468-
* <br>Note that this is a <em>HINT</em> and is currently only supported on GTK.
44694468
*
44704469
* @since 3.113
44714470
*/

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGFileFormat.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ List<ElementAtZoom<ImageData>> loadFromByteStream(int fileZoom, int targetZoom,
5555
return List.of(new ElementAtZoom<>(rasterizedImageData, targetZoom));
5656
} catch (IOException e) {
5757
SWT.error(SWT.ERROR_INVALID_IMAGE, e);
58+
return List.of();
5859
}
59-
return Collections.emptyList();
6060
}
6161

6262
@Override

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGRasterizer.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,13 @@
2323
public interface SVGRasterizer {
2424
/**
2525
* Rasterizes an SVG image from the provided {@code InputStream} using the
26-
* specified zoom factor.
26+
* specified zoom.
2727
*
2828
* @param stream the SVG image as an {@link InputStream}.
29-
* @param zoom the scaling factor (in percent) e.g. 200 for doubled size. This
30-
* value must not be 0.
29+
* @param zoom the scaling factor (in percent) e.g. {@code 200} for doubled
30+
* size. This value must be greater zero.
3131
* @return the {@link ImageData} for the rasterized image, or {@code null} if
3232
* the input is not a valid SVG file or cannot be processed.
33-
* @throws IOException
3433
*/
3534
public ImageData rasterizeSVG(InputStream stream, int zoom, int flag) throws IOException;
3635
}

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java

+9-22
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import static org.eclipse.swt.tests.junit.SwtTestUtil.assertSWTProblem;
1616
import static org.junit.Assert.fail;
17+
import static org.junit.jupiter.api.Assertions.assertThrows;
1718
import static org.junit.jupiter.api.Assertions.assertTrue;
1819

1920
import java.io.File;
@@ -39,24 +40,14 @@ public class Test_org_eclipse_swt_internal_SVGRasterizer {
3940

4041
@Test
4142
public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageFileNameProvider() {
42-
ImageFileNameProvider validImageFileNameProvider = zoom -> {
43-
String fileName = "collapseall.svg";
44-
return getPath(fileName);
45-
};
43+
ImageFileNameProvider validImageFileNameProvider = zoom -> getPath("collapseall.svg");
4644
Image image = new Image(Display.getDefault(), validImageFileNameProvider);
4745
image.dispose();
4846

49-
ImageFileNameProvider corruptImageFileNameProvider = zoom -> {
50-
String fileName = "corrupt.svg";
51-
return getPath(fileName);
52-
};
53-
try {
54-
image = new Image(Display.getDefault(), corruptImageFileNameProvider);
55-
image.dispose();
56-
fail("No exception thrown for corrupt image file.");
57-
} catch (SWTException e) {
58-
assertSWTProblem("Incorrect exception thrown for provider with corrupt images", SWT.ERROR_INVALID_IMAGE, e);
59-
}
47+
ImageFileNameProvider corruptImageFileNameProvider = zoom -> getPath("corrupt.svg");
48+
SWTException e = assertThrows(SWTException.class,
49+
() -> new Image(Display.getDefault(), corruptImageFileNameProvider));
50+
assertSWTProblem("Incorrect exception thrown for provider with corrupt images", SWT.ERROR_INVALID_IMAGE, e);
6051
}
6152

6253
@Test
@@ -72,13 +63,9 @@ public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageDataProvider()
7263
String fileName = "corrupt.svg";
7364
return new ImageData(getPath(fileName));
7465
};
75-
try {
76-
image = new Image(Display.getDefault(), corruptImageDataProvider);
77-
image.dispose();
78-
fail("No exception thrown for corrupt image file.");
79-
} catch (SWTException e) {
80-
assertSWTProblem("Incorrect exception thrown for provider with corrupt images", SWT.ERROR_INVALID_IMAGE, e);
81-
}
66+
SWTException e = assertThrows(SWTException.class,
67+
() -> new Image(Display.getDefault(), corruptImageDataProvider));
68+
assertSWTProblem("Incorrect exception thrown for provider with corrupt images", SWT.ERROR_INVALID_IMAGE, e);
8269
}
8370

8471
String getPath(String fileName) {

0 commit comments

Comments
 (0)