Skip to content

Commit

Permalink
Refactor names of SVGRasterizer and ISVGRasterizer
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael5601 committed Dec 11, 2024
1 parent 0266fb9 commit ffa17e4
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 115 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*******************************************************************************
* 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.SVGRasterizer;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
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 JSVGRasterizer implements SVGRasterizer {

private SVGLoader svgLoader;

/**
* Initializes the SVG rasterizer by registering an instance of this rasterizer
* with the {@link SVGRasterizerRegistry}.
*/
public static void intializeJSVGRasterizer() {
SVGRasterizerRegistry.register(new JSVGRasterizer());
}

private final static Map<Key, Object> 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 ImageData 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 convertToSWT(image);
}
}
return null;
}

private ImageData convertToSWT(BufferedImage bufferedImage) {
if (bufferedImage.getColorModel() instanceof DirectColorModel) {
DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel();
PaletteData palette = new PaletteData(
colorModel.getRedMask(),
colorModel.getGreenMask(),
colorModel.getBlueMask());
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
colorModel.getPixelSize(), palette);
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
int rgb = bufferedImage.getRGB(x, y);
int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
data.setPixel(x, y, pixel);
if (colorModel.hasAlpha()) {
data.setAlpha(x, y, (rgb >> 24) & 0xFF);
}
}
}
return data;
}
else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel();
int size = colorModel.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
colorModel.getReds(reds);
colorModel.getGreens(greens);
colorModel.getBlues(blues);
RGB[] rgbs = new RGB[size];
for (int i = 0; i < rgbs.length; i++) {
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
}
PaletteData palette = new PaletteData(rgbs);
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
colorModel.getPixelSize(), palette);
data.transparentPixel = colorModel.getTransparentPixel();
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[1];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
data.setPixel(x, y, pixelArray[0]);
}
}
return data;
}
else if (bufferedImage.getColorModel() instanceof ComponentColorModel) {
ComponentColorModel colorModel = (ComponentColorModel)bufferedImage.getColorModel();
//ASSUMES: 3 BYTE BGR IMAGE TYPE
PaletteData palette = new PaletteData(0x0000FF, 0x00FF00,0xFF0000);
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
colorModel.getPixelSize(), palette);
//This is valid because we are using a 3-byte Data model with no transparent pixels
data.transparentPixel = -1;
WritableRaster raster = bufferedImage.getRaster();
int[] pixelArray = new int[3];
for (int y = 0; y < data.height; y++) {
for (int x = 0; x < data.width; x++) {
raster.getPixel(x, y, pixelArray);
int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
data.setPixel(x, y, pixel);
}
}
return data;
}
return null;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*******************************************************************************/
package org.eclipse.swt.graphics;

import java.awt.image.*;
import java.io.*;

/**
Expand All @@ -20,19 +19,19 @@
*
* @since 3.129
*/
public interface ISVGRasterizer {
public interface SVGRasterizer {

/**
* 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
* @return the {@link ImageData} for 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;
public ImageData rasterizeSVG(byte[] bytes, float scalingFactor) throws IOException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,38 @@
package org.eclipse.swt.graphics;

/**
* A registry for managing the instance of an {@link ISVGRasterizer} implementation.
* A registry for managing the instance of an {@link SVGRasterizer} implementation.
* This allows for the registration and retrieval of a single rasterizer instance.
*
* @since 3.129
*/
public class SVGRasterizerRegistry {

/**
* The instance of the registered {@link ISVGRasterizer}.
* The instance of the registered {@link SVGRasterizer}.
*/
private static ISVGRasterizer rasterizer;
private static SVGRasterizer rasterizer;

/**
* Registers the provided implementation of {@link ISVGRasterizer}.
* Registers the provided implementation of {@link SVGRasterizer}.
* If a rasterizer has already been registered, subsequent calls to this method
* will have no effect.
*
* @param implementation the {@link ISVGRasterizer} implementation to register.
* @param implementation the {@link SVGRasterizer} implementation to register.
*/
public static void register(ISVGRasterizer implementation) {
public static void register(SVGRasterizer implementation) {
if (rasterizer == null) {
rasterizer = implementation;
}
}

/**
* Retrieves the currently registered {@link ISVGRasterizer} implementation.
* Retrieves the currently registered {@link SVGRasterizer} implementation.
*
* @return the registered {@link ISVGRasterizer}, or {@code null} if no implementation
* @return the registered {@link SVGRasterizer}, or {@code null} if no implementation
* has been registered.
*/
public static ISVGRasterizer getRasterizer() {
public static SVGRasterizer getRasterizer() {
return rasterizer;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@
package org.eclipse.swt.graphics;


import java.awt.image.*;
import java.io.*;
import java.util.*;

import javax.imageio.*;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.image.*;

Expand Down Expand Up @@ -187,23 +184,18 @@ public ImageData[] load(InputStream stream, int zoom) {
} catch (IOException e) {
SWT.error(SWT.ERROR_IO, e);
}
ISVGRasterizer rasterizer = SVGRasterizerRegistry.getRasterizer();
SVGRasterizer rasterizer = SVGRasterizerRegistry.getRasterizer();
if (rasterizer != null && zoom != 0) {
try {
float scalingFactor = zoom / 100.0f;
BufferedImage image = rasterizer.rasterizeSVG(bytes, scalingFactor);
if(image != null) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ImageIO.write(image, "png", baos);
try (InputStream in = new ByteArrayInputStream(baos.toByteArray())) {
data = FileFormat.load(in, this);
return data;
}
}
}
} catch (IOException e) {
// try standard method
}
try {
ImageData rasterizedData = rasterizer.rasterizeSVG(bytes, scalingFactor);
if (rasterizedData != null) {
data = new ImageData[]{rasterizedData};
return data;
}
} catch (IOException e) {
//ignore.
}
}
try (InputStream fallbackStream = new ByteArrayInputStream(bytes)) {
return loadDefault(fallbackStream);
Expand Down

0 comments on commit ffa17e4

Please sign in to comment.