diff --git a/bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/JSVGRasterizer.java b/bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/JSVGRasterizer.java index fed3f63db94..5769e9afe0d 100644 --- a/bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/JSVGRasterizer.java +++ b/bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/JSVGRasterizer.java @@ -74,34 +74,47 @@ public ImageData rasterizeSVG(InputStream inputStream, int zoom) { if (zoom < 0) { SWT.error(SWT.ERROR_INVALID_ARGUMENT); } - SVGDocument svgDocument = loadSVG(inputStream); - if (svgDocument == null) { - SWT.error(SWT.ERROR_INVALID_IMAGE); - } + SVGDocument svgDocument = loadAndValidateSVG(inputStream); BufferedImage rasterizedImage = renderSVG(svgDocument, zoom); return convertToSWTImageData(rasterizedImage); } - private SVGDocument loadSVG(InputStream inputStream) { - return SVG_LOADER.load(inputStream, null, LoaderContext.createDefault()); + @Override + public ImageData rasterizeSVG(InputStream inputStream, int width, int height) { + SVGDocument svgDocument = loadAndValidateSVG(inputStream); + BufferedImage rasterizedImage = renderSVG(svgDocument, width, height); + return convertToSWTImageData(rasterizedImage); + } + + private SVGDocument loadAndValidateSVG(InputStream inputStream) { + SVGDocument svgDocument = SVG_LOADER.load(inputStream, null, LoaderContext.createDefault()); + if (svgDocument == null) { + SWT.error(SWT.ERROR_INVALID_IMAGE); + } + return svgDocument; } private BufferedImage renderSVG(SVGDocument svgDocument, int zoom) { + FloatSize sourceImageSize = svgDocument.size(); float scalingFactor = zoom / 100.0f; - BufferedImage image = createImageBase(svgDocument, scalingFactor); - Graphics2D g = configureRenderingOptions(scalingFactor, image); + int targetImageWidth = calculateTargetWidth(scalingFactor, sourceImageSize); + int targetImageHeight = calculateTargetHeight(scalingFactor, sourceImageSize); + return renderSVG(svgDocument, targetImageWidth, targetImageHeight); + } + + private BufferedImage renderSVG(SVGDocument svgDocument, int width, int height) { + if (width <= 0 || height <= 0) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + float widthScalingFactor = width / svgDocument.size().width; + float heightScalingFactor = height / svgDocument.size().height; + Graphics2D g = configureRenderingOptions(widthScalingFactor, heightScalingFactor, image); svgDocument.render(null, g); g.dispose(); return image; } - private BufferedImage createImageBase(SVGDocument svgDocument, float scalingFactor) { - FloatSize sourceImageSize = svgDocument.size(); - int targetImageWidth = calculateTargetWidth(scalingFactor, sourceImageSize); - int targetImageHeight = calculateTargetHeight(scalingFactor, sourceImageSize); - return new BufferedImage(targetImageWidth, targetImageHeight, BufferedImage.TYPE_INT_ARGB); - } - private int calculateTargetWidth(float scalingFactor, FloatSize sourceImageSize) { double sourceImageWidth = sourceImageSize.getWidth(); return (int) Math.round(sourceImageWidth * scalingFactor); @@ -112,10 +125,11 @@ private int calculateTargetHeight(float scalingFactor, FloatSize sourceImageSize return (int) Math.round(sourceImageHeight * scalingFactor); } - private Graphics2D configureRenderingOptions(float scalingFactor, BufferedImage image) { + private Graphics2D configureRenderingOptions(float widthScalingFactor, float heightScalingFactor, + BufferedImage image) { Graphics2D g = image.createGraphics(); g.setRenderingHints(RENDERING_HINTS); - g.scale(scalingFactor, scalingFactor); + g.scale(widthScalingFactor, heightScalingFactor); return g; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGRasterizer.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGRasterizer.java index bc9531c7fba..c99413dbd9e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGRasterizer.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGRasterizer.java @@ -41,4 +41,24 @@ public interface SVGRasterizer { * */ public ImageData rasterizeSVG(InputStream stream, int zoom); + + /** + * Rasterizes an SVG image from the provided {@code InputStream} into a raster + * image of the specified width and height. + * + * @param stream the SVG image as an {@link InputStream}. + * @param width the width of the rasterized image in pixels (must be positive). + * @param height the height of the rasterized image in pixels (must be positive). + * @return the {@link ImageData} for the rasterized image. + * + * @exception SWTException + * + * @exception IllegalArgumentException + * + */ + public ImageData rasterizeSVG(InputStream stream, int width, int height); } diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/JSVGRasterizerTest.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/JSVGRasterizerTest.java index 44bf1b57090..dd8478cd8b7 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/JSVGRasterizerTest.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/JSVGRasterizerTest.java @@ -68,4 +68,33 @@ void testRasterizeWithZoomWithInvalidSVG() { assertEquals(SWT.ERROR_INVALID_IMAGE, exception.code); } + @Test + void testRasterizeWithTargetSize() { + ImageData data = rasterizer.rasterizeSVG(svgStream(svgString), 300, 150); + assertEquals(300, data.width); + assertEquals(150, data.height); + } + + @Test + void testRasterizeWithTargetSizeHavingInvalidHeight() { + assertThrows(IllegalArgumentException.class, () -> { + rasterizer.rasterizeSVG(svgStream(svgString), -1, 150); + }); + } + + @Test + void testRasterizeWithTargetSizeHavingInvalidWidth() { + assertThrows(IllegalArgumentException.class, () -> { + rasterizer.rasterizeSVG(svgStream(svgString), 150, -1); + }); + } + + @Test + void testRasterizeWithTargetSizeWithInvalidSVG() { + SWTException exception = assertThrows(SWTException.class, () -> { + rasterizer.rasterizeSVG(invalidSvg, 150, 150); + }); + assertEquals(SWT.ERROR_INVALID_IMAGE, exception.code); + } + }