source: josm/trunk/src/com/kitfox/svg/app/beans/SVGIcon.java@ 6002

Last change on this file since 6002 was 6002, checked in by Don-vip, 11 years ago

fix #8742 - update svgsalamander to release 0.1.18+patch (fix bug SVGSALAMANDER-26) -> allow to open more SVG files

File size: 12.8 KB
Line 
1/*
2 * SVG Salamander
3 * Copyright (c) 2004, Mark McKay
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
9 *
10 * - Redistributions of source code must retain the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
32 * projects can be found at http://www.kitfox.com
33 *
34 * Created on April 21, 2005, 10:45 AM
35 */
36
37package com.kitfox.svg.app.beans;
38
39import com.kitfox.svg.*;
40import java.awt.*;
41import java.awt.geom.*;
42import java.beans.*;
43import java.net.*;
44import javax.swing.*;
45
46/**
47 *
48 * @author kitfox
49 */
50public class SVGIcon implements Icon
51{
52 public static final long serialVersionUID = 1;
53
54 private PropertyChangeSupport changes = new PropertyChangeSupport(this);
55
56 SVGUniverse svgUniverse = SVGCache.getSVGUniverse();
57 public static final int INTERP_NEAREST_NEIGHBOR = 0;
58 public static final int INTERP_BILINEAR = 1;
59 public static final int INTERP_BICUBIC = 2;
60
61 private boolean antiAlias;
62 private int interpolation = INTERP_NEAREST_NEIGHBOR;
63 private boolean clipToViewbox;
64
65// private String svgPath;
66 URI svgURI;
67
68 private boolean scaleToFit;
69 AffineTransform scaleXform = new AffineTransform();
70
71// Dimension preferredSize = new Dimension(100, 100);
72 Dimension preferredSize;
73
74 /** Creates a new instance of SVGIcon */
75 public SVGIcon()
76 {
77 }
78
79 public void addPropertyChangeListener(PropertyChangeListener p)
80 {
81 changes.addPropertyChangeListener(p);
82 }
83
84 public void removePropertyChangeListener(PropertyChangeListener p)
85 {
86 changes.removePropertyChangeListener(p);
87 }
88
89 /**
90 * @return height of this icon
91 */
92 public int getIconHeight()
93 {
94 if (scaleToFit && preferredSize != null)
95 {
96 return preferredSize.height;
97 }
98
99 SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
100 if (diagram == null)
101 {
102 return 0;
103 }
104 return (int)diagram.getHeight();
105 }
106
107 /**
108 * @return width of this icon
109 */
110 public int getIconWidth()
111 {
112 if (scaleToFit && preferredSize != null)
113 {
114 return preferredSize.width;
115 }
116
117 SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
118 if (diagram == null)
119 {
120 return 0;
121 }
122 return (int)diagram.getWidth();
123 }
124
125 /**
126 * Draws the icon to the specified component.
127 * @param comp - Component to draw icon to. This is ignored by SVGIcon, and can be set to null; only gg is used for drawing the icon
128 * @param gg - Graphics context to render SVG content to
129 * @param x - X coordinate to draw icon
130 * @param y - Y coordinate to draw icon
131 */
132 public void paintIcon(Component comp, Graphics gg, int x, int y)
133 {
134 //Copy graphics object so that
135 Graphics2D g = (Graphics2D)gg.create();
136 paintIcon(comp, g, x, y);
137 g.dispose();
138 }
139
140 private void paintIcon(Component comp, Graphics2D g, int x, int y)
141 {
142 Object oldAliasHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
143 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
144
145 Object oldInterpolationHint = g.getRenderingHint(RenderingHints.KEY_INTERPOLATION);
146 switch (interpolation)
147 {
148 case INTERP_NEAREST_NEIGHBOR:
149 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
150 break;
151 case INTERP_BILINEAR:
152 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
153 break;
154 case INTERP_BICUBIC:
155 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
156 break;
157 }
158
159
160 SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
161 if (diagram == null)
162 {
163 return;
164 }
165
166 g.translate(x, y);
167 diagram.setIgnoringClipHeuristic(!clipToViewbox);
168 if (clipToViewbox)
169 {
170 g.setClip(new Rectangle2D.Float(0, 0, diagram.getWidth(), diagram.getHeight()));
171 }
172
173
174
175 if (!scaleToFit)
176 {
177 try
178 {
179 diagram.render(g);
180 g.translate(-x, -y);
181 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
182 }
183 catch (Exception e)
184 {
185 throw new RuntimeException(e);
186 }
187 return;
188 }
189
190 final int width = getIconWidth();
191 final int height = getIconHeight();
192// int width = getWidth();
193// int height = getHeight();
194
195 if (width == 0 || height == 0)
196 {
197 return;
198 }
199
200// if (width == 0 || height == 0)
201// {
202// //Chances are we're rendering offscreen
203// Dimension dim = getSize();
204// width = dim.width;
205// height = dim.height;
206// return;
207// }
208
209// g.setClip(0, 0, width, height);
210
211
212 final Rectangle2D.Double rect = new Rectangle2D.Double();
213 diagram.getViewRect(rect);
214
215 scaleXform.setToScale(width / rect.width, height / rect.height);
216
217 AffineTransform oldXform = g.getTransform();
218 g.transform(scaleXform);
219
220 try
221 {
222 diagram.render(g);
223 }
224 catch (SVGException e)
225 {
226 throw new RuntimeException(e);
227 }
228
229 g.setTransform(oldXform);
230
231
232 g.translate(-x, -y);
233
234 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
235 if (oldInterpolationHint != null)
236 {
237 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, oldInterpolationHint);
238 }
239 }
240
241 /**
242 * @return the universe this icon draws it's SVGDiagrams from
243 */
244 public SVGUniverse getSvgUniverse()
245 {
246 return svgUniverse;
247 }
248
249 public void setSvgUniverse(SVGUniverse svgUniverse)
250 {
251 SVGUniverse old = this.svgUniverse;
252 this.svgUniverse = svgUniverse;
253 changes.firePropertyChange("svgUniverse", old, svgUniverse);
254 }
255
256 /**
257 * @return the uni of the document being displayed by this icon
258 */
259 public URI getSvgURI()
260 {
261 return svgURI;
262 }
263
264 /**
265 * Loads an SVG document from a URI.
266 * @param svgURI - URI to load document from
267 */
268 public void setSvgURI(URI svgURI)
269 {
270 URI old = this.svgURI;
271 this.svgURI = svgURI;
272
273 SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
274 if (diagram != null)
275 {
276 Dimension size = getPreferredSize();
277 if (size == null)
278 {
279 size = new Dimension((int)diagram.getRoot().getDeviceWidth(), (int)diagram.getRoot().getDeviceHeight());
280 }
281 diagram.setDeviceViewport(new Rectangle(0, 0, size.width, size.height));
282 }
283
284 changes.firePropertyChange("svgURI", old, svgURI);
285 }
286
287 /**
288 * Loads an SVG document from the classpath. This function is equivilant to
289 * setSvgURI(new URI(getClass().getResource(resourcePath).toString());
290 * @param resourcePath - resource to load
291 */
292 public void setSvgResourcePath(String resourcePath)
293 {
294 URI old = this.svgURI;
295
296 try
297 {
298 svgURI = new URI(getClass().getResource(resourcePath).toString());
299 changes.firePropertyChange("svgURI", old, svgURI);
300
301 SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
302 if (diagram != null)
303 {
304 diagram.setDeviceViewport(new Rectangle(0, 0, preferredSize.width, preferredSize.height));
305 }
306
307 }
308 catch (Exception e)
309 {
310 svgURI = old;
311 }
312 }
313
314 /**
315 * If this SVG document has a viewbox, if scaleToFit is set, will scale the viewbox to match the
316 * preferred size of this icon
317 */
318 public boolean isScaleToFit()
319 {
320 return scaleToFit;
321 }
322
323 public void setScaleToFit(boolean scaleToFit)
324 {
325 boolean old = this.scaleToFit;
326 this.scaleToFit = scaleToFit;
327 changes.firePropertyChange("scaleToFit", old, scaleToFit);
328 }
329
330 public Dimension getPreferredSize()
331 {
332 if (preferredSize == null)
333 {
334 SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
335 if (diagram != null)
336 {
337 //preferredSize = new Dimension((int)diagram.getWidth(), (int)diagram.getHeight());
338 setPreferredSize(new Dimension((int)diagram.getWidth(), (int)diagram.getHeight()));
339 }
340 }
341
342 return new Dimension(preferredSize);
343 }
344
345 public void setPreferredSize(Dimension preferredSize)
346 {
347 Dimension old = this.preferredSize;
348 this.preferredSize = preferredSize;
349
350 SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
351 if (diagram != null)
352 {
353 diagram.setDeviceViewport(new Rectangle(0, 0, preferredSize.width, preferredSize.height));
354 }
355
356 changes.firePropertyChange("preferredSize", old, preferredSize);
357 }
358
359
360 /**
361 * @return true if antiAliasing is turned on.
362 * @deprecated
363 */
364 public boolean getUseAntiAlias()
365 {
366 return getAntiAlias();
367 }
368
369 /**
370 * @param antiAlias true to use antiAliasing.
371 * @deprecated
372 */
373 public void setUseAntiAlias(boolean antiAlias)
374 {
375 setAntiAlias(antiAlias);
376 }
377
378 /**
379 * @return true if antiAliasing is turned on.
380 */
381 public boolean getAntiAlias()
382 {
383 return antiAlias;
384 }
385
386 /**
387 * @param antiAlias true to use antiAliasing.
388 */
389 public void setAntiAlias(boolean antiAlias)
390 {
391 boolean old = this.antiAlias;
392 this.antiAlias = antiAlias;
393 changes.firePropertyChange("antiAlias", old, antiAlias);
394 }
395
396 /**
397 * @return interpolation used in rescaling images
398 */
399 public int getInterpolation()
400 {
401 return interpolation;
402 }
403
404 /**
405 * @param interpolation Interpolation value used in rescaling images.
406 * Should be one of
407 * INTERP_NEAREST_NEIGHBOR - Fastest, one pixel resampling, poor quality
408 * INTERP_BILINEAR - four pixel resampling
409 * INTERP_BICUBIC - Slowest, nine pixel resampling, best quality
410 */
411 public void setInterpolation(int interpolation)
412 {
413 int old = this.interpolation;
414 this.interpolation = interpolation;
415 changes.firePropertyChange("interpolation", old, interpolation);
416 }
417
418 /**
419 * clipToViewbox will set a clip box equivilant to the SVG's viewbox before
420 * rendering.
421 */
422 public boolean isClipToViewbox()
423 {
424 return clipToViewbox;
425 }
426
427 public void setClipToViewbox(boolean clipToViewbox)
428 {
429 this.clipToViewbox = clipToViewbox;
430 }
431
432}
Note: See TracBrowser for help on using the repository browser.