Skip to content

Commit cd56672

Browse files
committed
refactor class JSVGRasterizer
1 parent 3cc85a7 commit cd56672

File tree

2 files changed

+128
-77
lines changed

2 files changed

+128
-77
lines changed

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

Lines changed: 124 additions & 74 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,7 +56,8 @@
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
*/
@@ -76,90 +78,138 @@ public class JSVGRasterizer implements SVGRasterizer {
7678
);
7779

7880
@Override
79-
public ImageData[] rasterizeSVG(InputStream stream, int zoom) throws IOException {
80-
SVGDocument svgDocument = null;
81-
svgDocument = SVG_LOADER.load(stream, null, LoaderContext.createDefault());
81+
public ImageData[] rasterizeSVG(InputStream inputStream, int zoom) throws IOException {
82+
SVGDocument svgDocument = loadSVG(inputStream);
8283
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) };
84+
return generateRasterizedImageData(svgDocument, zoom);
9685
} else {
9786
SWT.error(SWT.ERROR_INVALID_IMAGE);
9887
}
9988
return null;
10089
}
10190

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-
}
91+
private SVGDocument loadSVG(InputStream inputStream) {
92+
return SVG_LOADER.load(inputStream, null, LoaderContext.createDefault());
93+
}
94+
95+
private ImageData[] generateRasterizedImageData(SVGDocument svgDocument, int zoom) {
96+
BufferedImage rasterizedImage = renderSVG(svgDocument, zoom);
97+
ImageData[] rasterizedImageData = transformtoSWTImageData(rasterizedImage);
98+
return rasterizedImageData;
99+
}
100+
101+
private BufferedImage renderSVG(SVGDocument svgDocument, int zoom) {
102+
float scalingFactor = zoom / 100.0f;
103+
BufferedImage image = createImageBase(svgDocument, scalingFactor);
104+
Graphics2D g = configureRenderingOptions(scalingFactor, image);
105+
svgDocument.render(null, g);
106+
g.dispose();
107+
return image;
108+
}
109+
110+
private BufferedImage createImageBase(SVGDocument svgDocument, float scalingFactor) {
111+
FloatSize sourceImageSize = svgDocument.size();
112+
int targetImageWidth = calculateTargetWidth(scalingFactor, sourceImageSize);
113+
int targetImageHeight = calculateTargetHeight(scalingFactor, sourceImageSize);
114+
BufferedImage image = new BufferedImage(targetImageWidth, targetImageHeight, BufferedImage.TYPE_INT_ARGB);
115+
return image;
116+
}
117+
118+
private int calculateTargetWidth(float scalingFactor, FloatSize sourceImageSize) {
119+
double sourceImageWidth = sourceImageSize.getWidth();
120+
int targetImageWidth = (int) Math.round(sourceImageWidth * scalingFactor);
121+
return targetImageWidth;
122+
}
123+
124+
private int calculateTargetHeight(float scalingFactor, FloatSize sourceImageSize) {
125+
double sourceImageHeight = sourceImageSize.getHeight();
126+
int targetImageHeight = (int) Math.round(sourceImageHeight * scalingFactor);
127+
return targetImageHeight;
128+
}
129+
130+
private Graphics2D configureRenderingOptions(float scalingFactor, BufferedImage image) {
131+
Graphics2D g = image.createGraphics();
132+
g.setRenderingHints(RENDERING_HINTS);
133+
g.scale(scalingFactor, scalingFactor);
134+
return g;
135+
}
136+
137+
private ImageData[] transformtoSWTImageData(BufferedImage bufferedImage) {
138+
ColorModel colorModel = bufferedImage.getColorModel();
139+
if (colorModel instanceof DirectColorModel directColorModel) {
140+
return generateSWTImageData(bufferedImage, directColorModel);
141+
} else if (colorModel instanceof IndexColorModel indexColorModel) {
142+
return generateSWTImageData(bufferedImage, indexColorModel);
143+
} else if (colorModel instanceof ComponentColorModel componentColorModel) {
144+
return generateSWTImageData(bufferedImage, componentColorModel);
145+
}
146+
return null;
147+
}
148+
149+
private ImageData[] generateSWTImageData(BufferedImage bufferedImage, DirectColorModel colorModel) {
150+
PaletteData paletteData = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(),
151+
colorModel.getBlueMask());
152+
ImageData imageData = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
153+
colorModel.getPixelSize(), paletteData);
154+
for (int y = 0; y < imageData.height; y++) {
155+
for (int x = 0; x < imageData.width; x++) {
156+
int rgb = bufferedImage.getRGB(x, y);
157+
int pixel = paletteData.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
158+
imageData.setPixel(x, y, pixel);
159+
if (colorModel.hasAlpha()) {
160+
imageData.setAlpha(x, y, (rgb >> 24) & 0xFF);
117161
}
118162
}
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-
}
163+
}
164+
return new ImageData[] { imageData };
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)