Skip to content

Commit ffa17e4

Browse files
committed
Refactor names of SVGRasterizer and ISVGRasterizer
1 parent 0266fb9 commit ffa17e4

File tree

5 files changed

+179
-115
lines changed

5 files changed

+179
-115
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2023 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: Vector Informatik GmbH - initial API and implementation
11+
*******************************************************************************/
12+
package org.eclipse.swt.svg;
13+
14+
import static java.awt.RenderingHints.*;
15+
16+
import java.awt.*;
17+
import java.awt.image.*;
18+
import java.io.*;
19+
import java.util.*;
20+
import org.eclipse.swt.graphics.SVGRasterizer;
21+
import org.eclipse.swt.graphics.ImageData;
22+
import org.eclipse.swt.graphics.PaletteData;
23+
import org.eclipse.swt.graphics.RGB;
24+
import org.eclipse.swt.graphics.SVGRasterizerRegistry;
25+
import org.eclipse.swt.graphics.SVGUtil;
26+
27+
import com.github.weisj.jsvg.*;
28+
import com.github.weisj.jsvg.geometry.size.*;
29+
import com.github.weisj.jsvg.parser.*;
30+
31+
/**
32+
* A rasterizer implementation for converting SVG data into rasterized images.
33+
* This class implements the {@code ISVGRasterizer} interface.
34+
*
35+
* @since 1.0.0
36+
*/
37+
public class JSVGRasterizer implements SVGRasterizer {
38+
39+
private SVGLoader svgLoader;
40+
41+
/**
42+
* Initializes the SVG rasterizer by registering an instance of this rasterizer
43+
* with the {@link SVGRasterizerRegistry}.
44+
*/
45+
public static void intializeJSVGRasterizer() {
46+
SVGRasterizerRegistry.register(new JSVGRasterizer());
47+
}
48+
49+
private final static Map<Key, Object> RENDERING_HINTS = Map.of(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON, //
50+
KEY_ALPHA_INTERPOLATION, VALUE_ALPHA_INTERPOLATION_QUALITY, //
51+
KEY_COLOR_RENDERING, VALUE_COLOR_RENDER_QUALITY, //
52+
KEY_DITHERING, VALUE_DITHER_DISABLE, //
53+
KEY_FRACTIONALMETRICS, VALUE_FRACTIONALMETRICS_ON, //
54+
KEY_INTERPOLATION, VALUE_INTERPOLATION_BICUBIC, //
55+
KEY_RENDERING, VALUE_RENDER_QUALITY, //
56+
KEY_STROKE_CONTROL, VALUE_STROKE_PURE, //
57+
KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON //
58+
);
59+
60+
@Override
61+
public ImageData rasterizeSVG(byte[] bytes, float scalingFactor) throws IOException {
62+
if(svgLoader == null) {
63+
svgLoader = new SVGLoader();
64+
}
65+
SVGDocument svgDocument = null;
66+
if (SVGUtil.isSVGFile(bytes)) {
67+
try (InputStream stream = new ByteArrayInputStream(bytes)) {
68+
svgDocument = svgLoader.load(stream, null, LoaderContext.createDefault());
69+
}
70+
if (svgDocument != null) {
71+
FloatSize size = svgDocument.size();
72+
double originalWidth = size.getWidth();
73+
double originalHeight = size.getHeight();
74+
int scaledWidth = (int) Math.round(originalWidth * scalingFactor);
75+
int scaledHeight = (int) Math.round(originalHeight * scalingFactor);
76+
BufferedImage image = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
77+
Graphics2D g = image.createGraphics();
78+
g.setRenderingHints(RENDERING_HINTS);
79+
g.scale(scalingFactor, scalingFactor);
80+
svgDocument.render(null, g);
81+
g.dispose();
82+
return convertToSWT(image);
83+
}
84+
}
85+
return null;
86+
}
87+
88+
private ImageData convertToSWT(BufferedImage bufferedImage) {
89+
if (bufferedImage.getColorModel() instanceof DirectColorModel) {
90+
DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel();
91+
PaletteData palette = new PaletteData(
92+
colorModel.getRedMask(),
93+
colorModel.getGreenMask(),
94+
colorModel.getBlueMask());
95+
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
96+
colorModel.getPixelSize(), palette);
97+
for (int y = 0; y < data.height; y++) {
98+
for (int x = 0; x < data.width; x++) {
99+
int rgb = bufferedImage.getRGB(x, y);
100+
int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
101+
data.setPixel(x, y, pixel);
102+
if (colorModel.hasAlpha()) {
103+
data.setAlpha(x, y, (rgb >> 24) & 0xFF);
104+
}
105+
}
106+
}
107+
return data;
108+
}
109+
else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
110+
IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel();
111+
int size = colorModel.getMapSize();
112+
byte[] reds = new byte[size];
113+
byte[] greens = new byte[size];
114+
byte[] blues = new byte[size];
115+
colorModel.getReds(reds);
116+
colorModel.getGreens(greens);
117+
colorModel.getBlues(blues);
118+
RGB[] rgbs = new RGB[size];
119+
for (int i = 0; i < rgbs.length; i++) {
120+
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
121+
}
122+
PaletteData palette = new PaletteData(rgbs);
123+
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
124+
colorModel.getPixelSize(), palette);
125+
data.transparentPixel = colorModel.getTransparentPixel();
126+
WritableRaster raster = bufferedImage.getRaster();
127+
int[] pixelArray = new int[1];
128+
for (int y = 0; y < data.height; y++) {
129+
for (int x = 0; x < data.width; x++) {
130+
raster.getPixel(x, y, pixelArray);
131+
data.setPixel(x, y, pixelArray[0]);
132+
}
133+
}
134+
return data;
135+
}
136+
else if (bufferedImage.getColorModel() instanceof ComponentColorModel) {
137+
ComponentColorModel colorModel = (ComponentColorModel)bufferedImage.getColorModel();
138+
//ASSUMES: 3 BYTE BGR IMAGE TYPE
139+
PaletteData palette = new PaletteData(0x0000FF, 0x00FF00,0xFF0000);
140+
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
141+
colorModel.getPixelSize(), palette);
142+
//This is valid because we are using a 3-byte Data model with no transparent pixels
143+
data.transparentPixel = -1;
144+
WritableRaster raster = bufferedImage.getRaster();
145+
int[] pixelArray = new int[3];
146+
for (int y = 0; y < data.height; y++) {
147+
for (int x = 0; x < data.width; x++) {
148+
raster.getPixel(x, y, pixelArray);
149+
int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
150+
data.setPixel(x, y, pixel);
151+
}
152+
}
153+
return data;
154+
}
155+
return null;
156+
}
157+
}

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

-84
This file was deleted.

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ISVGRasterizer.java renamed to bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/SVGRasterizer.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
*******************************************************************************/
1212
package org.eclipse.swt.graphics;
1313

14-
import java.awt.image.*;
1514
import java.io.*;
1615

1716
/**
@@ -20,19 +19,19 @@
2019
*
2120
* @since 3.129
2221
*/
23-
public interface ISVGRasterizer {
22+
public interface SVGRasterizer {
2423

2524
/**
2625
* Rasterizes an SVG image from the provided byte array, using the specified
2726
* zoom factor.
2827
*
2928
* @param bytes the SVG image as a byte array.
3029
* @param scalingFactor the scaling ratio e.g. 2.0 for doubled size.
31-
* @return a {@link BufferedImage} containing the rasterized image, or
30+
* @return the {@link ImageData} for the rasterized image, or
3231
* {@code null} if the input is not a valid SVG file or cannot be
3332
* processed.
3433
* @throws IOException if an error occurs while reading the SVG data.
3534
*/
36-
public BufferedImage rasterizeSVG(byte[] bytes, float scalingFactor) throws IOException;
35+
public ImageData rasterizeSVG(byte[] bytes, float scalingFactor) throws IOException;
3736

3837
}

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

+9-9
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,38 @@
1212
package org.eclipse.swt.graphics;
1313

1414
/**
15-
* A registry for managing the instance of an {@link ISVGRasterizer} implementation.
15+
* A registry for managing the instance of an {@link SVGRasterizer} implementation.
1616
* This allows for the registration and retrieval of a single rasterizer instance.
1717
*
1818
* @since 3.129
1919
*/
2020
public class SVGRasterizerRegistry {
2121

2222
/**
23-
* The instance of the registered {@link ISVGRasterizer}.
23+
* The instance of the registered {@link SVGRasterizer}.
2424
*/
25-
private static ISVGRasterizer rasterizer;
25+
private static SVGRasterizer rasterizer;
2626

2727
/**
28-
* Registers the provided implementation of {@link ISVGRasterizer}.
28+
* Registers the provided implementation of {@link SVGRasterizer}.
2929
* If a rasterizer has already been registered, subsequent calls to this method
3030
* will have no effect.
3131
*
32-
* @param implementation the {@link ISVGRasterizer} implementation to register.
32+
* @param implementation the {@link SVGRasterizer} implementation to register.
3333
*/
34-
public static void register(ISVGRasterizer implementation) {
34+
public static void register(SVGRasterizer implementation) {
3535
if (rasterizer == null) {
3636
rasterizer = implementation;
3737
}
3838
}
3939

4040
/**
41-
* Retrieves the currently registered {@link ISVGRasterizer} implementation.
41+
* Retrieves the currently registered {@link SVGRasterizer} implementation.
4242
*
43-
* @return the registered {@link ISVGRasterizer}, or {@code null} if no implementation
43+
* @return the registered {@link SVGRasterizer}, or {@code null} if no implementation
4444
* has been registered.
4545
*/
46-
public static ISVGRasterizer getRasterizer() {
46+
public static SVGRasterizer getRasterizer() {
4747
return rasterizer;
4848
}
4949
}

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/ImageLoader.java

+10-18
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,9 @@
1414
package org.eclipse.swt.graphics;
1515

1616

17-
import java.awt.image.*;
1817
import java.io.*;
1918
import java.util.*;
2019

21-
import javax.imageio.*;
22-
2320
import org.eclipse.swt.*;
2421
import org.eclipse.swt.internal.image.*;
2522

@@ -187,23 +184,18 @@ public ImageData[] load(InputStream stream, int zoom) {
187184
} catch (IOException e) {
188185
SWT.error(SWT.ERROR_IO, e);
189186
}
190-
ISVGRasterizer rasterizer = SVGRasterizerRegistry.getRasterizer();
187+
SVGRasterizer rasterizer = SVGRasterizerRegistry.getRasterizer();
191188
if (rasterizer != null && zoom != 0) {
192-
try {
193189
float scalingFactor = zoom / 100.0f;
194-
BufferedImage image = rasterizer.rasterizeSVG(bytes, scalingFactor);
195-
if(image != null) {
196-
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
197-
ImageIO.write(image, "png", baos);
198-
try (InputStream in = new ByteArrayInputStream(baos.toByteArray())) {
199-
data = FileFormat.load(in, this);
200-
return data;
201-
}
202-
}
203-
}
204-
} catch (IOException e) {
205-
// try standard method
206-
}
190+
try {
191+
ImageData rasterizedData = rasterizer.rasterizeSVG(bytes, scalingFactor);
192+
if (rasterizedData != null) {
193+
data = new ImageData[]{rasterizedData};
194+
return data;
195+
}
196+
} catch (IOException e) {
197+
//ignore.
198+
}
207199
}
208200
try (InputStream fallbackStream = new ByteArrayInputStream(bytes)) {
209201
return loadDefault(fallbackStream);

0 commit comments

Comments
 (0)