2323import org .eclipse .swt .graphics .PaletteData ;
2424import org .eclipse .swt .graphics .RGB ;
2525import org .eclipse .swt .internal .SVGRasterizer ;
26-
2726import com .github .weisj .jsvg .*;
2827import com .github .weisj .jsvg .geometry .size .*;
2928import com .github .weisj .jsvg .parser .*;
3534 * @since 1.0.0
3635 */
3736public class JSVGRasterizer implements SVGRasterizer {
38-
37+
3938 private SVGLoader svgLoader ;
4039
4140 private final static Map <Key , Object > RENDERING_HINTS = Map .of (KEY_ANTIALIASING , VALUE_ANTIALIAS_ON , //
@@ -50,120 +49,123 @@ public class JSVGRasterizer implements SVGRasterizer {
5049 );
5150
5251 @ Override
53- public ImageData rasterizeSVG (InputStream stream , float scalingFactor ) throws IOException {
52+ public ImageData [] rasterizeSVG (InputStream stream , int zoom ) throws IOException {
5453 if (stream == null ) {
55- throw new IllegalArgumentException ("InputStream cannot be null" );
56- }
57- stream .mark (Integer .MAX_VALUE );
58- if (svgLoader == null ) {
59- svgLoader = new SVGLoader ();
54+ throw new IllegalArgumentException ("InputStream cannot be null" );
55+ }
56+ if (!stream .markSupported ()) {
57+ stream = new BufferedInputStream (stream );
6058 }
61- SVGDocument svgDocument = null ;
62- InputStream nonClosingStream = new FilterInputStream (stream ) {
63- @ Override
64- public void close () throws IOException {
65- // Do nothing to prevent closing the underlying stream
66- }
67- };
68- svgDocument = svgLoader .load (nonClosingStream , null , LoaderContext .createDefault ());
69- stream .reset ();
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- } else {
84- SWT .error (SWT .ERROR_INVALID_IMAGE );
85- return null ;
59+ if (isSVGFile (stream )) {
60+ stream .mark (Integer .MAX_VALUE );
61+ if (svgLoader == null ) {
62+ svgLoader = new SVGLoader ();
63+ }
64+ SVGDocument svgDocument = null ;
65+ InputStream nonClosingStream = new FilterInputStream (stream ) {
66+ @ Override
67+ public void close () throws IOException {
68+ // Do nothing to prevent closing the underlying stream
69+ }
70+ };
71+ svgDocument = svgLoader .load (nonClosingStream , null , LoaderContext .createDefault ());
72+ stream .reset ();
73+ if (svgDocument != null ) {
74+ float scalingFactor = zoom / 100.0f ;
75+ FloatSize size = svgDocument .size ();
76+ double originalWidth = size .getWidth ();
77+ double originalHeight = size .getHeight ();
78+ int scaledWidth = (int ) Math .round (originalWidth * scalingFactor );
79+ int scaledHeight = (int ) Math .round (originalHeight * scalingFactor );
80+ BufferedImage image = new BufferedImage (scaledWidth , scaledHeight , BufferedImage .TYPE_INT_ARGB );
81+ Graphics2D g = image .createGraphics ();
82+ g .setRenderingHints (RENDERING_HINTS );
83+ g .scale (scalingFactor , scalingFactor );
84+ svgDocument .render (null , g );
85+ g .dispose ();
86+ return new ImageData [] { convertToSWT (image ) };
87+ } else {
88+ SWT .error (SWT .ERROR_INVALID_IMAGE );
89+ }
8690 }
91+ return null ;
8792 }
88-
93+
8994 private ImageData convertToSWT (BufferedImage bufferedImage ) {
90- if (bufferedImage .getColorModel () instanceof DirectColorModel ) {
91- DirectColorModel colorModel = (DirectColorModel )bufferedImage .getColorModel ();
92- PaletteData palette = new PaletteData (
93- colorModel .getRedMask (),
94- colorModel .getGreenMask (),
95- colorModel .getBlueMask ());
96- ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
97- colorModel .getPixelSize (), palette );
98- for (int y = 0 ; y < data .height ; y ++) {
99- for (int x = 0 ; x < data .width ; x ++) {
100- int rgb = bufferedImage .getRGB (x , y );
101- int pixel = palette .getPixel (new RGB ((rgb >> 16 ) & 0xFF , (rgb >> 8 ) & 0xFF , rgb & 0xFF ));
102- data .setPixel (x , y , pixel );
103- if (colorModel .hasAlpha ()) {
104- data .setAlpha (x , y , (rgb >> 24 ) & 0xFF );
105- }
106- }
107- }
108- return data ;
109- }
110- else if (bufferedImage .getColorModel () instanceof IndexColorModel ) {
111- IndexColorModel colorModel = (IndexColorModel )bufferedImage .getColorModel ();
112- int size = colorModel .getMapSize ();
113- byte [] reds = new byte [size ];
114- byte [] greens = new byte [size ];
115- byte [] blues = new byte [size ];
116- colorModel .getReds (reds );
117- colorModel .getGreens (greens );
118- colorModel .getBlues (blues );
119- RGB [] rgbs = new RGB [size ];
120- for (int i = 0 ; i < rgbs .length ; i ++) {
121- rgbs [i ] = new RGB (reds [i ] & 0xFF , greens [i ] & 0xFF , blues [i ] & 0xFF );
122- }
123- PaletteData palette = new PaletteData (rgbs );
124- ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
125- colorModel .getPixelSize (), palette );
126- data .transparentPixel = colorModel .getTransparentPixel ();
127- WritableRaster raster = bufferedImage .getRaster ();
128- int [] pixelArray = new int [1 ];
129- for (int y = 0 ; y < data .height ; y ++) {
130- for (int x = 0 ; x < data .width ; x ++) {
131- raster .getPixel (x , y , pixelArray );
132- data .setPixel (x , y , pixelArray [0 ]);
133- }
134- }
135- return data ;
136- }
137- else if (bufferedImage .getColorModel () instanceof ComponentColorModel ) {
138- ComponentColorModel colorModel = (ComponentColorModel )bufferedImage .getColorModel ();
139- //ASSUMES: 3 BYTE BGR IMAGE TYPE
140- PaletteData palette = new PaletteData (0x0000FF , 0x00FF00 ,0xFF0000 );
141- ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
142- colorModel .getPixelSize (), palette );
143- //This is valid because we are using a 3-byte Data model with no transparent pixels
144- data .transparentPixel = -1 ;
145- WritableRaster raster = bufferedImage .getRaster ();
146- int [] pixelArray = new int [3 ];
147- for (int y = 0 ; y < data .height ; y ++) {
148- for (int x = 0 ; x < data .width ; x ++) {
149- raster .getPixel (x , y , pixelArray );
150- int pixel = palette .getPixel (new RGB (pixelArray [0 ], pixelArray [1 ], pixelArray [2 ]));
151- data .setPixel (x , y , pixel );
152- }
153- }
154- return data ;
155- }
156- return null ;
95+ if (bufferedImage .getColorModel () instanceof DirectColorModel ) {
96+ DirectColorModel colorModel = (DirectColorModel ) bufferedImage .getColorModel ();
97+ PaletteData palette = new PaletteData (colorModel .getRedMask (), colorModel .getGreenMask (),
98+ colorModel .getBlueMask ());
99+ ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
100+ colorModel .getPixelSize (), palette );
101+ for (int y = 0 ; y < data .height ; y ++) {
102+ for (int x = 0 ; x < data .width ; x ++) {
103+ int rgb = bufferedImage .getRGB (x , y );
104+ int pixel = palette .getPixel (new RGB ((rgb >> 16 ) & 0xFF , (rgb >> 8 ) & 0xFF , rgb & 0xFF ));
105+ data .setPixel (x , y , pixel );
106+ if (colorModel .hasAlpha ()) {
107+ data .setAlpha (x , y , (rgb >> 24 ) & 0xFF );
108+ }
109+ }
110+ }
111+ return data ;
112+ } else if (bufferedImage .getColorModel () instanceof IndexColorModel ) {
113+ IndexColorModel colorModel = (IndexColorModel ) bufferedImage .getColorModel ();
114+ int size = colorModel .getMapSize ();
115+ byte [] reds = new byte [size ];
116+ byte [] greens = new byte [size ];
117+ byte [] blues = new byte [size ];
118+ colorModel .getReds (reds );
119+ colorModel .getGreens (greens );
120+ colorModel .getBlues (blues );
121+ RGB [] rgbs = new RGB [size ];
122+ for (int i = 0 ; i < rgbs .length ; i ++) {
123+ rgbs [i ] = new RGB (reds [i ] & 0xFF , greens [i ] & 0xFF , blues [i ] & 0xFF );
124+ }
125+ PaletteData palette = new PaletteData (rgbs );
126+ ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
127+ colorModel .getPixelSize (), palette );
128+ data .transparentPixel = colorModel .getTransparentPixel ();
129+ WritableRaster raster = bufferedImage .getRaster ();
130+ int [] pixelArray = new int [1 ];
131+ for (int y = 0 ; y < data .height ; y ++) {
132+ for (int x = 0 ; x < data .width ; x ++) {
133+ raster .getPixel (x , y , pixelArray );
134+ data .setPixel (x , y , pixelArray [0 ]);
135+ }
136+ }
137+ return data ;
138+ } else if (bufferedImage .getColorModel () instanceof ComponentColorModel ) {
139+ ComponentColorModel colorModel = (ComponentColorModel ) bufferedImage .getColorModel ();
140+ // ASSUMES: 3 BYTE BGR IMAGE TYPE
141+ PaletteData palette = new PaletteData (0x0000FF , 0x00FF00 , 0xFF0000 );
142+ ImageData data = new ImageData (bufferedImage .getWidth (), bufferedImage .getHeight (),
143+ colorModel .getPixelSize (), palette );
144+ // This is valid because we are using a 3-byte Data model with no transparent
145+ // pixels
146+ data .transparentPixel = -1 ;
147+ WritableRaster raster = bufferedImage .getRaster ();
148+ int [] pixelArray = new int [3 ];
149+ for (int y = 0 ; y < data .height ; y ++) {
150+ for (int x = 0 ; x < data .width ; x ++) {
151+ raster .getPixel (x , y , pixelArray );
152+ int pixel = palette .getPixel (new RGB (pixelArray [0 ], pixelArray [1 ], pixelArray [2 ]));
153+ data .setPixel (x , y , pixel );
154+ }
155+ }
156+ return data ;
157+ }
158+ return null ;
157159 }
158160
159- public boolean isSVGFile (InputStream stream ) throws IOException {
161+ private boolean isSVGFile (InputStream stream ) throws IOException {
160162 if (stream == null ) {
161- throw new IllegalArgumentException ("InputStream cannot be null" );
162- }
163+ throw new IllegalArgumentException ("InputStream cannot be null" );
164+ }
163165 stream .mark (Integer .MAX_VALUE );
164166 try {
165- int firstByte = stream .read ();
166- return firstByte == '<' ;
167+ int firstByte = stream .read ();
168+ return firstByte == '<' ;
167169 } finally {
168170 stream .reset ();
169171 }
0 commit comments