Skip to content

Commit a94cab6

Browse files
committed
refactor class JSVGRasterizer
1 parent 0459b4b commit a94cab6

File tree

2 files changed

+124
-77
lines changed

2 files changed

+124
-77
lines changed

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

Lines changed: 120 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,134 @@ 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+
return transformToSWTImageData(rasterizedImage);
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+
return new BufferedImage(targetImageWidth, targetImageHeight, BufferedImage.TYPE_INT_ARGB);
114+
}
115+
116+
private int calculateTargetWidth(float scalingFactor, FloatSize sourceImageSize) {
117+
double sourceImageWidth = sourceImageSize.getWidth();
118+
return (int) Math.round(sourceImageWidth * scalingFactor);
119+
}
120+
121+
private int calculateTargetHeight(float scalingFactor, FloatSize sourceImageSize) {
122+
double sourceImageHeight = sourceImageSize.getHeight();
123+
return (int) Math.round(sourceImageHeight * scalingFactor);
124+
}
125+
126+
private Graphics2D configureRenderingOptions(float scalingFactor, BufferedImage image) {
127+
Graphics2D g = image.createGraphics();
128+
g.setRenderingHints(RENDERING_HINTS);
129+
g.scale(scalingFactor, scalingFactor);
130+
return g;
131+
}
132+
133+
private ImageData[] transformToSWTImageData(BufferedImage bufferedImage) {
134+
ColorModel colorModel = bufferedImage.getColorModel();
135+
if (colorModel instanceof DirectColorModel directColorModel) {
136+
return generateSWTImageData(bufferedImage, directColorModel);
137+
} else if (colorModel instanceof IndexColorModel indexColorModel) {
138+
return generateSWTImageData(bufferedImage, indexColorModel);
139+
} else if (colorModel instanceof ComponentColorModel componentColorModel) {
140+
return generateSWTImageData(bufferedImage, componentColorModel);
141+
}
142+
return null;
143+
}
144+
145+
private ImageData[] generateSWTImageData(BufferedImage bufferedImage, DirectColorModel colorModel) {
146+
PaletteData paletteData = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(),
147+
colorModel.getBlueMask());
148+
ImageData imageData = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
149+
colorModel.getPixelSize(), paletteData);
150+
for (int y = 0; y < imageData.height; y++) {
151+
for (int x = 0; x < imageData.width; x++) {
152+
int rgb = bufferedImage.getRGB(x, y);
153+
int pixel = paletteData.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
154+
imageData.setPixel(x, y, pixel);
155+
if (colorModel.hasAlpha()) {
156+
imageData.setAlpha(x, y, (rgb >> 24) & 0xFF);
117157
}
118158
}
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-
}
159+
}
160+
return new ImageData[] { imageData };
161+
}
162+
163+
private ImageData[] generateSWTImageData(BufferedImage bufferedImage, IndexColorModel indexColorModel) {
164+
RGB[] colors = calculateColors(indexColorModel);
165+
PaletteData paletteData = new PaletteData(colors);
166+
ImageData imageData = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
167+
indexColorModel.getPixelSize(), paletteData);
168+
imageData.transparentPixel = indexColorModel.getTransparentPixel();
169+
WritableRaster raster = bufferedImage.getRaster();
170+
int[] pixelArray = new int[1];
171+
for (int y = 0; y < imageData.height; y++) {
172+
for (int x = 0; x < imageData.width; x++) {
173+
raster.getPixel(x, y, pixelArray);
174+
imageData.setPixel(x, y, pixelArray[0]);
144175
}
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-
}
176+
}
177+
return new ImageData[] { imageData };
178+
}
179+
180+
private RGB[] calculateColors(IndexColorModel indexColorModel) {
181+
int size = indexColorModel.getMapSize();
182+
byte[] reds = new byte[size];
183+
byte[] greens = new byte[size];
184+
byte[] blues = new byte[size];
185+
indexColorModel.getReds(reds);
186+
indexColorModel.getGreens(greens);
187+
indexColorModel.getBlues(blues);
188+
RGB[] rgbs = new RGB[size];
189+
for (int i = 0; i < rgbs.length; i++) {
190+
rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
191+
}
192+
return rgbs;
193+
}
194+
195+
private ImageData[] generateSWTImageData(BufferedImage bufferedImage, ComponentColorModel componentColorModel) {
196+
PaletteData paletteData = new PaletteData(0x0000FF, 0x00FF00, 0xFF0000);
197+
ImageData imageData = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(),
198+
componentColorModel.getPixelSize(), paletteData);
199+
imageData.transparentPixel = -1;
200+
WritableRaster raster = bufferedImage.getRaster();
201+
int[] pixelArray = new int[3];
202+
for (int y = 0; y < imageData.height; y++) {
203+
for (int x = 0; x < imageData.width; x++) {
204+
raster.getPixel(x, y, pixelArray);
205+
int pixel = paletteData.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
206+
imageData.setPixel(x, y, pixel);
160207
}
161-
return data;
162208
}
163-
return null;
209+
return new ImageData[] { imageData };
164210
}
165211
}

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)