source: josm/trunk/src/com/kitfox/svg/ImageSVG.java@ 16643

Last change on this file since 16643 was 14334, checked in by Don-vip, 6 years ago

see #14319, see #16838 - svgSalamander fix for CVE-2017-5617 was incomplete

See https://github.com/blackears/svgSalamander/issues/11

  • Property svn:eol-style set to native
File size: 10.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 February 20, 2004, 10:00 PM
35 */
36package com.kitfox.svg;
37
38import com.kitfox.svg.app.data.Handler;
39import com.kitfox.svg.xml.StyleAttribute;
40import java.awt.AlphaComposite;
41import java.awt.Composite;
42import java.awt.Graphics2D;
43import java.awt.geom.AffineTransform;
44import java.awt.geom.Point2D;
45import java.awt.geom.Rectangle2D;
46import java.awt.image.BufferedImage;
47import java.net.URI;
48import java.net.URL;
49import java.util.List;
50import java.util.logging.Level;
51import java.util.logging.Logger;
52
53/**
54 * Implements an image.
55 *
56 * @author Mark McKay
57 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
58 */
59public class ImageSVG extends RenderableElement
60{
61 public static final String TAG_NAME = "image";
62
63 float x = 0f;
64 float y = 0f;
65 float width = 0f;
66 float height = 0f;
67// BufferedImage href = null;
68 URL imageSrc = null;
69 AffineTransform xform;
70 Rectangle2D bounds;
71
72 /**
73 * Creates a new instance of Font
74 */
75 public ImageSVG()
76 {
77 }
78
79 @Override
80 public String getTagName()
81 {
82 return TAG_NAME;
83 }
84
85 @Override
86 protected void build() throws SVGException
87 {
88 super.build();
89
90 StyleAttribute sty = new StyleAttribute();
91
92 if (getPres(sty.setName("x")))
93 {
94 x = sty.getFloatValueWithUnits();
95 }
96
97 if (getPres(sty.setName("y")))
98 {
99 y = sty.getFloatValueWithUnits();
100 }
101
102 if (getPres(sty.setName("width")))
103 {
104 width = sty.getFloatValueWithUnits();
105 }
106
107 if (getPres(sty.setName("height")))
108 {
109 height = sty.getFloatValueWithUnits();
110 }
111
112 try
113 {
114 if (getPres(sty.setName("xlink:href")))
115 {
116 URI src = sty.getURIValue(getXMLBase());
117 if ("data".equals(src.getScheme()))
118 {
119 imageSrc = new URL(null, src.toASCIIString(), new Handler());
120 }
121 else if (!diagram.getUniverse().isImageDataInlineOnly())
122 {
123 try
124 {
125 imageSrc = src.toURL();
126 } catch (Exception e)
127 {
128 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
129 "Could not parse xlink:href " + src, e);
130 imageSrc = null;
131 }
132 }
133 }
134 } catch (Exception e)
135 {
136 throw new SVGException(e);
137 }
138
139 if (imageSrc != null)
140 {
141 diagram.getUniverse().registerImage(imageSrc);
142
143 //Set widths if not set
144 BufferedImage img = diagram.getUniverse().getImage(imageSrc);
145 if (img == null)
146 {
147 xform = new AffineTransform();
148 bounds = new Rectangle2D.Float();
149 return;
150 }
151
152 if (width == 0)
153 {
154 width = img.getWidth();
155 }
156 if (height == 0)
157 {
158 height = img.getHeight();
159 }
160
161 //Determine image xform
162 xform = new AffineTransform();
163 xform.translate(this.x, this.y);
164 xform.scale(this.width / img.getWidth(), this.height / img.getHeight());
165 }
166 bounds = new Rectangle2D.Float(this.x, this.y, this.width, this.height);
167 }
168
169 public float getX()
170 {
171 return x;
172 }
173
174 public float getY()
175 {
176 return y;
177 }
178
179 public float getWidth()
180 {
181 return width;
182 }
183
184 public float getHeight()
185 {
186 return height;
187 }
188
189 @Override
190 void pick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException
191 {
192 if (getBoundingBox().contains(point))
193 {
194 retVec.add(getPath(null));
195 }
196 }
197
198 @Override
199 void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException
200 {
201 if (ltw.createTransformedShape(getBoundingBox()).intersects(pickArea))
202 {
203 retVec.add(getPath(null));
204 }
205 }
206
207 @Override
208 public void render(Graphics2D g) throws SVGException
209 {
210 StyleAttribute styleAttrib = new StyleAttribute();
211 if (getStyle(styleAttrib.setName("visibility")))
212 {
213 if (!styleAttrib.getStringValue().equals("visible"))
214 {
215 return;
216 }
217 }
218
219 if (getStyle(styleAttrib.setName("display")))
220 {
221 if (styleAttrib.getStringValue().equals("none"))
222 {
223 return;
224 }
225 }
226
227 beginLayer(g);
228
229 float opacity = 1f;
230 if (getStyle(styleAttrib.setName("opacity")))
231 {
232 opacity = styleAttrib.getRatioValue();
233 }
234
235 if (opacity <= 0)
236 {
237 return;
238 }
239
240 Composite oldComp = null;
241
242 if (opacity < 1)
243 {
244 oldComp = g.getComposite();
245 Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);
246 g.setComposite(comp);
247 }
248
249 BufferedImage img = diagram.getUniverse().getImage(imageSrc);
250 if (img == null)
251 {
252 return;
253 }
254
255 AffineTransform curXform = g.getTransform();
256 g.transform(xform);
257
258 g.drawImage(img, 0, 0, null);
259
260 g.setTransform(curXform);
261 if (oldComp != null)
262 {
263 g.setComposite(oldComp);
264 }
265
266 finishLayer(g);
267 }
268
269 @Override
270 public Rectangle2D getBoundingBox()
271 {
272 return boundsToParent(bounds);
273 }
274
275 /**
276 * Updates all attributes in this diagram associated with a time event. Ie,
277 * all attributes with track information.
278 *
279 * @return - true if this node has changed state as a result of the time
280 * update
281 */
282 @Override
283 public boolean updateTime(double curTime) throws SVGException
284 {
285// if (trackManager.getNumTracks() == 0) return false;
286 boolean changeState = super.updateTime(curTime);
287
288 //Get current values for parameters
289 StyleAttribute sty = new StyleAttribute();
290 boolean shapeChange = false;
291
292 if (getPres(sty.setName("x")))
293 {
294 float newVal = sty.getFloatValueWithUnits();
295 if (newVal != x)
296 {
297 x = newVal;
298 shapeChange = true;
299 }
300 }
301
302 if (getPres(sty.setName("y")))
303 {
304 float newVal = sty.getFloatValueWithUnits();
305 if (newVal != y)
306 {
307 y = newVal;
308 shapeChange = true;
309 }
310 }
311
312 if (getPres(sty.setName("width")))
313 {
314 float newVal = sty.getFloatValueWithUnits();
315 if (newVal != width)
316 {
317 width = newVal;
318 shapeChange = true;
319 }
320 }
321
322 if (getPres(sty.setName("height")))
323 {
324 float newVal = sty.getFloatValueWithUnits();
325 if (newVal != height)
326 {
327 height = newVal;
328 shapeChange = true;
329 }
330 }
331
332 try
333 {
334 if (getPres(sty.setName("xlink:href")))
335 {
336 URI src = sty.getURIValue(getXMLBase());
337
338 URL newVal = null;
339 if ("data".equals(src.getScheme()))
340 {
341 newVal = new URL(null, src.toASCIIString(), new Handler());
342 } else if (!diagram.getUniverse().isImageDataInlineOnly())
343 {
344 newVal = src.toURL();
345 }
346
347 if (newVal != null && !newVal.equals(imageSrc))
348 {
349 imageSrc = newVal;
350 shapeChange = true;
351 }
352 }
353 } catch (IllegalArgumentException ie)
354 {
355 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
356 "Image provided with illegal value for href: \""
357 + sty.getStringValue() + '"', ie);
358 } catch (Exception e)
359 {
360 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
361 "Could not parse xlink:href", e);
362 }
363
364
365 if (shapeChange)
366 {
367 build();
368// diagram.getUniverse().registerImage(imageSrc);
369//
370// //Set widths if not set
371// BufferedImage img = diagram.getUniverse().getImage(imageSrc);
372// if (img == null)
373// {
374// xform = new AffineTransform();
375// bounds = new Rectangle2D.Float();
376// }
377// else
378// {
379// if (width == 0) width = img.getWidth();
380// if (height == 0) height = img.getHeight();
381//
382// //Determine image xform
383// xform = new AffineTransform();
384//// xform.setToScale(this.width / img.getWidth(), this.height / img.getHeight());
385//// xform.translate(this.x, this.y);
386// xform.translate(this.x, this.y);
387// xform.scale(this.width / img.getWidth(), this.height / img.getHeight());
388//
389// bounds = new Rectangle2D.Float(this.x, this.y, this.width, this.height);
390// }
391//
392// return true;
393 }
394
395 return changeState || shapeChange;
396 }
397}
Note: See TracBrowser for help on using the repository browser.