Skip to content

Commit 1d8eb8c

Browse files
committed
Add internal API in SVGrasterizer to rasterize images at given height and width
Adding internal API to SVGRasterizer and simple tests to see if the svgs are loaded at right sizes by the rasterizer
1 parent 35119f0 commit 1d8eb8c

File tree

4 files changed

+162
-28
lines changed

4 files changed

+162
-28
lines changed

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

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import java.awt.RenderingHints.Key;
3636
import java.awt.image.BufferedImage;
3737
import java.awt.image.DataBufferInt;
38-
import java.io.IOException;
3938
import java.io.InputStream;
4039
import java.util.Map;
4140

@@ -71,35 +70,48 @@ public class JSVGRasterizer implements SVGRasterizer {
7170
);
7271

7372
@Override
74-
public ImageData rasterizeSVG(InputStream inputStream, int zoom) throws IOException {
75-
SVGDocument svgDocument = loadSVG(inputStream);
76-
if (svgDocument == null) {
77-
SWT.error(SWT.ERROR_INVALID_IMAGE);
78-
}
73+
public ImageData rasterizeSVG(InputStream inputStream, int zoom){
74+
SVGDocument svgDocument = loadAndValidateSVG(inputStream);
7975
BufferedImage rasterizedImage = renderSVG(svgDocument, zoom);
8076
return convertToSWTImageData(rasterizedImage);
8177
}
82-
83-
private SVGDocument loadSVG(InputStream inputStream) {
84-
return SVG_LOADER.load(inputStream, null, LoaderContext.createDefault());
78+
79+
@Override
80+
public ImageData rasterizeSVG(InputStream inputStream, int width, int height){
81+
SVGDocument svgDocument = loadAndValidateSVG(inputStream);
82+
BufferedImage rasterizedImage = renderSVG(svgDocument, width, height);
83+
return convertToSWTImageData(rasterizedImage);
84+
}
85+
86+
private SVGDocument loadAndValidateSVG(InputStream inputStream) {
87+
SVGDocument svgDocument = SVG_LOADER.load(inputStream, null, LoaderContext.createDefault());
88+
if (svgDocument == null) {
89+
SWT.error(SWT.ERROR_INVALID_IMAGE);
90+
}
91+
return svgDocument;
8592
}
8693

8794
private BufferedImage renderSVG(SVGDocument svgDocument, int zoom) {
95+
FloatSize sourceImageSize = svgDocument.size();
8896
float scalingFactor = zoom / 100.0f;
89-
BufferedImage image = createImageBase(svgDocument, scalingFactor);
90-
Graphics2D g = configureRenderingOptions(scalingFactor, image);
97+
int targetImageWidth = calculateTargetWidth(scalingFactor, sourceImageSize);
98+
int targetImageHeight = calculateTargetHeight(scalingFactor, sourceImageSize);
99+
return renderSVG(svgDocument, targetImageWidth, targetImageHeight);
100+
}
101+
102+
private BufferedImage renderSVG(SVGDocument svgDocument, int width, int height) {
103+
if (width <= 0 || height <= 0) {
104+
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
105+
}
106+
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
107+
float widthScalingFactor = width / svgDocument.size().width;
108+
float heightScalingFactor = height / svgDocument.size().height;
109+
Graphics2D g = configureRenderingOptions(widthScalingFactor, heightScalingFactor, image);
91110
svgDocument.render(null, g);
92111
g.dispose();
93112
return image;
94113
}
95114

96-
private BufferedImage createImageBase(SVGDocument svgDocument, float scalingFactor) {
97-
FloatSize sourceImageSize = svgDocument.size();
98-
int targetImageWidth = calculateTargetWidth(scalingFactor, sourceImageSize);
99-
int targetImageHeight = calculateTargetHeight(scalingFactor, sourceImageSize);
100-
return new BufferedImage(targetImageWidth, targetImageHeight, BufferedImage.TYPE_INT_ARGB);
101-
}
102-
103115
private int calculateTargetWidth(float scalingFactor, FloatSize sourceImageSize) {
104116
double sourceImageWidth = sourceImageSize.getWidth();
105117
return (int) Math.round(sourceImageWidth * scalingFactor);
@@ -110,10 +122,10 @@ private int calculateTargetHeight(float scalingFactor, FloatSize sourceImageSize
110122
return (int) Math.round(sourceImageHeight * scalingFactor);
111123
}
112124

113-
private Graphics2D configureRenderingOptions(float scalingFactor, BufferedImage image) {
125+
private Graphics2D configureRenderingOptions(float widthScalingFactor, float heightScalingFactor, BufferedImage image) {
114126
Graphics2D g = image.createGraphics();
115127
g.setRenderingHints(RENDERING_HINTS);
116-
g.scale(scalingFactor, scalingFactor);
128+
g.scale(widthScalingFactor, heightScalingFactor);
117129
return g;
118130
}
119131

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,8 @@ List<ElementAtZoom<ImageData>> loadFromByteStream(int fileZoom, int targetZoom)
5151
if (targetZoom <= 0) {
5252
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, " [Cannot rasterize SVG for zoom <= 0]");
5353
}
54-
try {
55-
ImageData rasterizedImageData = RASTERIZER.rasterizeSVG(inputStream, 100 * targetZoom / fileZoom);
56-
return List.of(new ElementAtZoom<>(rasterizedImageData, targetZoom));
57-
} catch (IOException e) {
58-
SWT.error(SWT.ERROR_INVALID_IMAGE, e);
59-
return List.of();
60-
}
54+
ImageData rasterizedImageData = RASTERIZER.rasterizeSVG(inputStream, 100 * targetZoom / fileZoom);
55+
return List.of(new ElementAtZoom<>(rasterizedImageData, targetZoom));
6156
}
6257

6358
@Override

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

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import java.io.*;
1616

17+
import org.eclipse.swt.*;
1718
import org.eclipse.swt.graphics.*;
1819

1920
/**
@@ -30,6 +31,39 @@ public interface SVGRasterizer {
3031
* size. This value must be greater zero.
3132
* @return the {@link ImageData} for the rasterized image, or {@code null} if
3233
* the input is not a valid SVG file or cannot be processed.
34+
*
35+
* @exception SWTException
36+
*<ul>
37+
* <li>ERROR_INVALID_IMAGE - if the SVG cannot be rasterized</li>
38+
*</ul>
39+
* @exception SWTException
40+
*<ul>
41+
* <li>ERROR_INVALID_IMAGE - if the zoom is less than zero</li>
42+
*</ul>
43+
*/
44+
public ImageData rasterizeSVG(InputStream stream, int zoom);
45+
46+
/**
47+
* Rasterizes an SVG image from the provided {@code InputStream} into a raster
48+
* image of the specified width and height.
49+
*
50+
* If {@code width} or {@code height} is zero or negative, this method throws an
51+
* {@link SWT#ERROR_INVALID_ARGUMENT}.
52+
*
53+
* @param stream the SVG image as an {@link InputStream}.
54+
* @param width the width of the rasterized image in pixels (must be positive).
55+
* @param height the height of the rasterized image in pixels (must be
56+
* positive).
57+
* @return the {@link ImageData} for the rasterized image.
58+
*
59+
* @exception SWTException
60+
*<ul>
61+
* <li>ERROR_INVALID_IMAGE - if the SVG cannot be rasterized</li>
62+
*</ul>
63+
* @exception SWTException
64+
*<ul>
65+
* <li>ERROR_INVALID_IMAGE - if the width or height is less than zero</li>
66+
*</ul>
3367
*/
34-
public ImageData rasterizeSVG(InputStream stream, int zoom) throws IOException;
68+
public ImageData rasterizeSVG(InputStream stream, int width, int height);
3569
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Yatta Solutions and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Yatta Solutions - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.swt.tests.junit;
15+
import static org.junit.Assert.assertThrows;
16+
import static org.junit.jupiter.api.Assertions.assertEquals;
17+
18+
import java.io.ByteArrayInputStream;
19+
import java.nio.charset.StandardCharsets;
20+
21+
import org.eclipse.swt.SWT;
22+
import org.eclipse.swt.SWTException;
23+
import org.eclipse.swt.graphics.ImageData;
24+
import org.eclipse.swt.svg.JSVGRasterizer;
25+
import org.junit.jupiter.api.Test;
26+
27+
class JSVGRasterizerTest {
28+
29+
private final JSVGRasterizer rasterizer = new JSVGRasterizer();
30+
private String svgString = """
31+
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
32+
<rect width="100%" height="100%"/>
33+
</svg>
34+
""";
35+
private ByteArrayInputStream svgStream(String svg) {
36+
return new ByteArrayInputStream(svg.getBytes(StandardCharsets.UTF_8));
37+
}
38+
private ByteArrayInputStream invalidSvg = new ByteArrayInputStream(new byte[0]);
39+
40+
@Test
41+
void testRasterizeWithZoom(){
42+
ImageData data = rasterizer.rasterizeSVG(svgStream(svgString), 200);
43+
assertEquals(200, data.width);
44+
assertEquals(200, data.height);
45+
}
46+
47+
@Test
48+
void testRasterizeWithZoomNegative(){
49+
assertThrows(IllegalArgumentException.class, () -> {
50+
rasterizer.rasterizeSVG(svgStream(svgString), -100);
51+
});
52+
}
53+
54+
@Test
55+
void testRasterizeWithZoomWithInvalidSVG() {
56+
57+
SWTException exception = assertThrows(SWTException.class, () -> {
58+
rasterizer.rasterizeSVG(invalidSvg, 100);
59+
});
60+
assertEquals(SWT.ERROR_INVALID_IMAGE, exception.code);
61+
}
62+
63+
@Test
64+
void testRasterizeWithTargetSize(){
65+
ImageData data = rasterizer.rasterizeSVG(svgStream(svgString), 300, 150);
66+
assertEquals(300, data.width);
67+
assertEquals(150, data.height);
68+
}
69+
70+
@Test
71+
void testRasterizeWithTargetSizeHavingInvalidHeight() {
72+
assertThrows(IllegalArgumentException.class, () -> {
73+
rasterizer.rasterizeSVG(svgStream(svgString), -1, 150);
74+
});
75+
}
76+
77+
@Test
78+
void testRasterizeWithTargetSizeHavingInvalidWidth() {
79+
assertThrows(IllegalArgumentException.class, () -> {
80+
rasterizer.rasterizeSVG(svgStream(svgString), 150, -1);
81+
});
82+
}
83+
84+
@Test
85+
void testRasterizeWithTargetSizeWithInvalidSVG() {
86+
SWTException exception = assertThrows(SWTException.class, () -> {
87+
rasterizer.rasterizeSVG(invalidSvg, 150, 150);
88+
});
89+
assertEquals(SWT.ERROR_INVALID_IMAGE, exception.code);
90+
}
91+
92+
93+
}

0 commit comments

Comments
 (0)