Skip to content

Commit 389a319

Browse files
committed
refactor class JSVGRasterizer
1 parent 3cc85a7 commit 389a319

File tree

2 files changed

+130
-79
lines changed

2 files changed

+130
-79
lines changed

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

Lines changed: 126 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.awt.Graphics2D;
3535
import java.awt.RenderingHints.Key;
3636
import java.awt.image.BufferedImage;
37+
import java.awt.image.ColorModel;
3738
import java.awt.image.ComponentColorModel;
3839
import java.awt.image.DirectColorModel;
3940
import java.awt.image.IndexColorModel;
@@ -55,16 +56,16 @@
5556

5657
/**
5758
* A rasterizer implementation for converting SVG data into rasterized images.
58-
* This class implements the {@code SVGRasterizer} interface.
59+
* This class uses the third party library JSVG for the raterization of SVG
60+
* images.
5961
*
6062
* @since 1.0.0
6163
*/
6264
public class JSVGRasterizer implements SVGRasterizer {
6365

6466
private static final SVGLoader SVG_LOADER = new SVGLoader();
6567

66-
private final static Map<Key, Object> RENDERING_HINTS = Map.of(
67-
KEY_ANTIALIASING, VALUE_ANTIALIAS_ON, //
68+
private final static Map<Key, Object> RENDERING_HINTS = Map.of(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON, //
6869
KEY_ALPHA_INTERPOLATION, VALUE_ALPHA_INTERPOLATION_QUALITY, //
6970
KEY_COLOR_RENDERING, VALUE_COLOR_RENDER_QUALITY, //
7071
KEY_DITHERING, VALUE_DITHER_DISABLE, //
@@ -76,90 +77,139 @@ public class JSVGRasterizer implements SVGRasterizer {
7677
);
7778

7879
@Override
79-
public ImageData[] rasterizeSVG(InputStream stream, int zoom) throws IOException {
80-
SVGDocument svgDocument = null;
81-
svgDocument = SVG_LOADER.load(stream, null, LoaderContext.createDefault());
80+
public ImageData[] rasterizeSVG(InputStream inputStream, int zoom) throws IOException {
81+
SVGDocument svgDocument = loadSVG(inputStream);
8282
if (svgDocument != null) {
83-
float scalingFactor = zoom / 100.0f;
84-
FloatSize size = svgDocument.size();
85-
double originalWidth = size.getWidth();
86-
double originalHeight = size.getHeight();
87-
int scaledWidth = (int) Math.round(originalWidth * scalingFactor);
88-
int scaledHeight = (int) Math.round(originalHeight * scalingFactor);
89-
BufferedImage image = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
90-
Graphics2D g = image.createGraphics();
91-
g.setRenderingHints(RENDERING_HINTS);
92-
g.scale(scalingFactor, scalingFactor);
93-
svgDocument.render(null, g);
94-
g.dispose();
95-
return new ImageData[] { convertToSWT(image) };
83+
return generateRasterizedImageData(svgDocument, zoom);
9684
} else {
9785
SWT.error(SWT.ERROR_INVALID_IMAGE);
9886
}
9987
return null;
10088
}
10189

102-
private ImageData convertToSWT(BufferedImage bufferedImage) {
103-
if (bufferedImage.getColorModel() instanceof DirectColorModel) {
104-
DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
105-
PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(),
106-
colorModel.getBlueMask());
107-
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
108-
colorModel.getPixelSize(), palette);
109-
for (int y = 0; y < data.height; y++) {
110-
for (int x = 0; x < data.width; x++) {
111-
int rgb = bufferedImage.getRGB(x, y);
112-
int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
113-
data.setPixel(x, y, pixel);
114-
if (colorModel.hasAlpha()) {
115-
data.setAlpha(x, y, (rgb >> 24) & 0xFF);
116-
}
90+
private SVGDocument loadSVG(InputStream inputStream) {
91+
return SVG_LOADER.load(inputStream, null, LoaderContext.createDefault());
92+
}
93+
94+
private ImageData[] generateRasterizedImageData(SVGDocument svgDocument, int zoom) {
95+
BufferedImage rasterizedImage = renderSVG(svgDocument, zoom);
96+
ImageData[] rasterizedImageData = transformtoSWTImageData(rasterizedImage);
97+
return rasterizedImageData;
98+
}
99+
100+
private BufferedImage renderSVG(SVGDocument svgDocument, int zoom) {
101+
float scalingFactor = zoom / 100.0f;
102+
BufferedImage image = createImageBase(svgDocument, scalingFactor);
103+
Graphics2D g = configureRenderingOptions(scalingFactor, image);
104+
svgDocument.render(null, g);
105+
g.dispose();
106+
return image;
107+
}
108+
109+
private BufferedImage createImageBase(SVGDocument svgDocument, float scalingFactor) {
110+
FloatSize sourceImageSize = svgDocument.size();
111+
int targetImageWidth = calculateTargetWidth(scalingFactor, sourceImageSize);
112+
int targetImageHeight = calculateTargetHeight(scalingFactor, sourceImageSize);
113+
BufferedImage image = new BufferedImage(targetImageWidth, targetImageHeight, BufferedImage.TYPE_INT_ARGB);
114+
return image;
115+
}
116+
117+
private int calculateTargetWidth(float scalingFactor, FloatSize sourceImageSize) {
118+
double sourceImageWidth = sourceImageSize.getWidth();
119+
int targetImageWidth = (int) Math.round(sourceImageWidth * scalingFactor);
120+
return targetImageWidth;
121+
}
122+
123+
private int calculateTargetHeight(float scalingFactor, FloatSize sourceImageSize) {
124+
double sourceImageHeight = sourceImageSize.getHeight();
125+
int targetImageHeight = (int) Math.round(sourceImageHeight * scalingFactor);
126+
return targetImageHeight;
127+
}
128+
129+
private Graphics2D configureRenderingOptions(float scalingFactor, BufferedImage image) {
130+
Graphics2D g = image.createGraphics();
131+
g.setRenderingHints(RENDERING_HINTS);
132+
g.scale(scalingFactor, scalingFactor);
133+
return g;
134+
}
135+
136+
private ImageData[] transformtoSWTImageData(BufferedImage bufferedImage) {
137+
ColorModel colorModel = bufferedImage.getColorModel();
138+
if (colorModel instanceof DirectColorModel directColorModel) {
139+
return generateSWTImageData(bufferedImage, directColorModel);
140+
} else if (colorModel instanceof IndexColorModel indexColorModel) {
141+
return generateSWTImageData(bufferedImage, indexColorModel);
142+
} else if (colorModel instanceof ComponentColorModel componentColorModel) {
143+
return generateSWTImageData(bufferedImage, componentColorModel);
144+
}
145+
return null;
146+
}
147+
148+
private ImageData[] generateSWTImageData(BufferedImage bufferedImage, DirectColorModel colorModel) {
149+
PaletteData paletteData = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(),
150+
colorModel.getBlueMask());
151+
ImageData imageData = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
152+
colorModel.getPixelSize(), paletteData);
153+
for (int y = 0; y < imageData.height; y++) {
154+
for (int x = 0; x < imageData.width; x++) {
155+
int rgb = bufferedImage.getRGB(x, y);
156+
int pixel = paletteData.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
157+
imageData.setPixel(x, y, pixel);
158+
if (colorModel.hasAlpha()) {
159+
imageData.setAlpha(x, y, (rgb >> 24) & 0xFF);
117160
}
118161
}
119-
return data;
120-
} else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
121-
IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
122-
int size = colorModel.getMapSize();
123-
byte[] reds = new byte[size];
124-
byte[] greens = new byte[size];
125-
byte[] blues = new byte[size];
126-
colorModel.getReds(reds);
127-
colorModel.getGreens(greens);
128-
colorModel.getBlues(blues);
129-
RGB[] rgbs = new RGB[size];
130-
for (int i = 0; i < rgbs.length; i++) {
131-
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
132-
}
133-
PaletteData palette = new PaletteData(rgbs);
134-
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
135-
colorModel.getPixelSize(), palette);
136-
data.transparentPixel = colorModel.getTransparentPixel();
137-
WritableRaster raster = bufferedImage.getRaster();
138-
int[] pixelArray = new int[1];
139-
for (int y = 0; y < data.height; y++) {
140-
for (int x = 0; x < data.width; x++) {
141-
raster.getPixel(x, y, pixelArray);
142-
data.setPixel(x, y, pixelArray[0]);
143-
}
162+
}
163+
return new ImageData[] { imageData };
164+
}
165+
166+
167+
private ImageData[] generateSWTImageData(BufferedImage bufferedImage, IndexColorModel indexColorModel) {
168+
RGB[] colors = calculateColors(indexColorModel);
169+
PaletteData paletteData = new PaletteData(colors);
170+
ImageData imageData = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
171+
indexColorModel.getPixelSize(), paletteData);
172+
imageData.transparentPixel = indexColorModel.getTransparentPixel();
173+
WritableRaster raster = bufferedImage.getRaster();
174+
int[] pixelArray = new int[1];
175+
for (int y = 0; y < imageData.height; y++) {
176+
for (int x = 0; x < imageData.width; x++) {
177+
raster.getPixel(x, y, pixelArray);
178+
imageData.setPixel(x, y, pixelArray[0]);
144179
}
145-
return data;
146-
} else if (bufferedImage.getColorModel() instanceof ComponentColorModel) {
147-
ComponentColorModel colorModel = (ComponentColorModel) bufferedImage.getColorModel();
148-
PaletteData palette = new PaletteData(0x0000FF, 0x00FF00, 0xFF0000);
149-
ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
150-
colorModel.getPixelSize(), palette);
151-
data.transparentPixel = -1;
152-
WritableRaster raster = bufferedImage.getRaster();
153-
int[] pixelArray = new int[3];
154-
for (int y = 0; y < data.height; y++) {
155-
for (int x = 0; x < data.width; x++) {
156-
raster.getPixel(x, y, pixelArray);
157-
int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
158-
data.setPixel(x, y, pixel);
159-
}
180+
}
181+
return new ImageData[] { imageData };
182+
}
183+
184+
private RGB[] calculateColors(IndexColorModel indexColorModel) {
185+
int size = indexColorModel.getMapSize();
186+
byte[] reds = new byte[size];
187+
byte[] greens = new byte[size];
188+
byte[] blues = new byte[size];
189+
indexColorModel.getReds(reds);
190+
indexColorModel.getGreens(greens);
191+
indexColorModel.getBlues(blues);
192+
RGB[] rgbs = new RGB[size];
193+
for (int i = 0; i < rgbs.length; i++) {
194+
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
195+
}
196+
return rgbs;
197+
}
198+
199+
private ImageData[] generateSWTImageData(BufferedImage bufferedImage, ComponentColorModel componentColorModel) {
200+
PaletteData paletteData = new PaletteData(0x0000FF, 0x00FF00, 0xFF0000);
201+
ImageData imageData = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
202+
componentColorModel.getPixelSize(), paletteData);
203+
imageData.transparentPixel = -1;
204+
WritableRaster raster = bufferedImage.getRaster();
205+
int[] pixelArray = new int[3];
206+
for (int y = 0; y < imageData.height; y++) {
207+
for (int x = 0; x < imageData.width; x++) {
208+
raster.getPixel(x, y, pixelArray);
209+
int pixel = paletteData.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
210+
imageData.setPixel(x, y, pixel);
160211
}
161-
return data;
162212
}
163-
return null;
213+
return new ImageData[] { imageData };
164214
}
165215
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@
2323
*/
2424
public interface SVGRasterizer {
2525
/**
26-
* Rasterizes an SVG image from the provided {@code InputStream} using the specified
27-
* zoom factor.
26+
* Rasterizes an SVG image from the provided {@code InputStream} using the
27+
* specified zoom factor.
2828
*
2929
* @param stream the SVG image as an {@link InputStream}.
30-
* @param zoom the scaling factor e.g. 200 for doubled size. This value must no be 0.
30+
* @param zoom the scaling factor e.g. 200 for doubled size. This value must
31+
* not be 0.
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.
3334
* @throws IOException if an error occurs while reading the SVG data.

0 commit comments

Comments
 (0)