diff --git a/bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/SVGRasterizer.java b/bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/SVGRasterizer.java new file mode 100644 index 00000000000..6d919780dd8 --- /dev/null +++ b/bundles/org.eclipse.swt.svg/src/org/eclipse/swt/svg/SVGRasterizer.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2023 Vector Informatik GmbH and others. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Vector Informatik GmbH - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.svg; + +import static java.awt.RenderingHints.*; + +import java.awt.*; +import java.awt.image.*; +import java.io.*; +import java.util.*; +import org.eclipse.swt.graphics.ISVGRasterizer; +import org.eclipse.swt.graphics.SVGRasterizerRegistry; +import org.eclipse.swt.graphics.SVGUtil; + +import com.github.weisj.jsvg.*; +import com.github.weisj.jsvg.geometry.size.*; +import com.github.weisj.jsvg.parser.*; + +/** + * A rasterizer implementation for converting SVG data into rasterized images. + * This class implements the {@code ISVGRasterizer} interface. + * + * @since 1.0.0 + */ +public class SVGRasterizer implements ISVGRasterizer { + + private SVGLoader svgLoader; + + /** + * Initializes the SVG rasterizer by registering an instance of this rasterizer + * with the {@link SVGRasterizerRegistry}. + */ + public static void intializeSVGRasterizer() { + SVGRasterizerRegistry.register(new SVGRasterizer()); + } + + private final static Map RENDERING_HINTS = Map.of(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON, // + KEY_ALPHA_INTERPOLATION, VALUE_ALPHA_INTERPOLATION_QUALITY, // + KEY_COLOR_RENDERING, VALUE_COLOR_RENDER_QUALITY, // + KEY_DITHERING, VALUE_DITHER_DISABLE, // + KEY_FRACTIONALMETRICS, VALUE_FRACTIONALMETRICS_ON, // + KEY_INTERPOLATION, VALUE_INTERPOLATION_BICUBIC, // + KEY_RENDERING, VALUE_RENDER_QUALITY, // + KEY_STROKE_CONTROL, VALUE_STROKE_PURE, // + KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON // + ); + + @Override + public BufferedImage rasterizeSVG(byte[] bytes, float scalingFactor) throws IOException { + if(svgLoader == null) { + svgLoader = new SVGLoader(); + } + SVGDocument svgDocument = null; + if (SVGUtil.isSVGFile(bytes)) { + try (InputStream stream = new ByteArrayInputStream(bytes)) { + svgDocument = svgLoader.load(stream, null, LoaderContext.createDefault()); + } + if (svgDocument != null) { + FloatSize size = svgDocument.size(); + double originalWidth = size.getWidth(); + double originalHeight = size.getHeight(); + int scaledWidth = (int) Math.round(originalWidth * scalingFactor); + int scaledHeight = (int) Math.round(originalHeight * scalingFactor); + BufferedImage image = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = image.createGraphics(); + g.setRenderingHints(RENDERING_HINTS); + g.scale(scalingFactor, scalingFactor); + svgDocument.render(null, g); + g.dispose(); + return image; + } + } + return null; + } +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ISVGRasterizer.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ISVGRasterizer.java new file mode 100644 index 00000000000..64ea6d17677 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ISVGRasterizer.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2024 Vector Informatik GmbH and others. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Vector Informatik GmbH - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.graphics; + +import java.awt.image.*; +import java.io.*; + +/** + * Defines the interface for an SVG rasterizer, responsible for converting SVG + * data into rasterized images. + * + * @since 3.129 + */ +public interface ISVGRasterizer { + + /** + * Rasterizes an SVG image from the provided byte array, using the specified + * zoom factor. + * + * @param bytes the SVG image as a byte array. + * @param scalingFactor the scaling ratio e.g. 2.0 for doubled size. + * @return a {@link BufferedImage} containing the rasterized image, or + * {@code null} if the input is not a valid SVG file or cannot be + * processed. + * @throws IOException if an error occurs while reading the SVG data. + */ + public BufferedImage rasterizeSVG(byte[] bytes, float scalingFactor) throws IOException; + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/SVGUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/SVGUtil.java new file mode 100644 index 00000000000..f3245d44a13 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/SVGUtil.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2023 Vector Informatik GmbH and others. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: Vector Informatik GmbH - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.graphics; + +import java.io.*; +import java.nio.charset.*; + +/** + * Utility class for handling SVG-related operations. + * + * @since 3.129 + */ +public class SVGUtil { + + /** + * Determines whether the given {@link InputStream} contains a SVG file. + * + * @param data byte array to check. + * @return {@code true} if the input stream contains SVG content; {@code false} + * otherwise. + * @throws IOException if an error occurs while reading the stream. + * @throws IllegalArgumentException if the input stream is {@code null}. + */ + public static boolean isSVGFile(byte[] data) throws IOException { + String content = new String(data, 0, Math.min(data.length, 512), StandardCharsets.UTF_8); + return content.contains("