source: josm/trunk/patches/10trim_svgsalamander.patch@ 6101

Last change on this file since 6101 was 5284, checked in by bastiK, 12 years ago

reverse patches, so they are easier to use in quilt

File size: 200.6 KB
RevLine 
[4256]1Patch against rev 98 of https://svn.java.net/svn/svgsalamander~svn/trunk. It strips some classes, that aren't needed (basically animation and gui) and removes dependencies. The only purpose of this patch is to reduce binary download size for JOSM users.
[5284]2Index: core/src/com/kitfox/svg/animation/Animate.java
[4256]3===================================================================
[5284]4--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5+++ core/src/com/kitfox/svg/animation/Animate.java 2012-06-17 23:56:57.664545050 +0200
6@@ -0,0 +1,419 @@
7+/*
8+ * Animate.java
9+ *
10+ * The Salamander Project - 2D and 3D graphics libraries in Java
11+ * Copyright (C) 2004 Mark McKay
12+ *
13+ * This library is free software; you can redistribute it and/or
14+ * modify it under the terms of the GNU Lesser General Public
15+ * License as published by the Free Software Foundation; either
16+ * version 2.1 of the License, or (at your option) any later version.
17+ *
18+ * This library is distributed in the hope that it will be useful,
19+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21+ * Lesser General Public License for more details.
22+ *
23+ * You should have received a copy of the GNU Lesser General Public
24+ * License along with this library; if not, write to the Free Software
25+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26+ *
27+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
28+ * projects can be found at http://www.kitfox.com
29+ *
30+ * Created on August 15, 2004, 2:51 AM
31+ */
32+
33+package com.kitfox.svg.animation;
34+
35+import com.kitfox.svg.SVGElement;
36+import com.kitfox.svg.SVGException;
37+import com.kitfox.svg.SVGLoaderHelper;
38+import com.kitfox.svg.animation.parser.AnimTimeParser;
39+import com.kitfox.svg.xml.ColorTable;
40+import com.kitfox.svg.xml.StyleAttribute;
41+import com.kitfox.svg.xml.XMLParseUtil;
42+import java.awt.Color;
43+import java.awt.geom.AffineTransform;
44+import java.awt.geom.GeneralPath;
45+import java.awt.geom.PathIterator;
46+import org.xml.sax.Attributes;
47+import org.xml.sax.SAXException;
48+
49+
50+/**
51+ * Animate is a really annoying morphic tag that could represent a real value,
52+ * a color or a path
53+ *
54+ * @author Mark McKay
55+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
56+ */
57+public class Animate extends AnimateBase implements AnimateColorIface
58+{
59+// StyleAttribute retAttrib = new StyleAttribute
60+ public static final int DT_REAL = 0;
61+ public static final int DT_COLOR = 1;
62+ public static final int DT_PATH = 2;
63+ int dataType = DT_REAL;
64+
65+ protected double fromValue = Double.NaN;
66+ protected double toValue = Double.NaN;
67+ protected double byValue = Double.NaN;
68+ protected double[] valuesValue;
69+
70+ protected Color fromColor = null;
71+ protected Color toColor = null;
72+
73+ protected GeneralPath fromPath = null;
74+ protected GeneralPath toPath = null;
75+
76+ /** Creates a new instance of Animate */
77+ public Animate()
78+ {
79+ }
80+
81+ public int getDataType()
82+ {
83+ return dataType;
84+ }
85+
86+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
87+ {
88+ //Load style string
89+ super.loaderStartElement(helper, attrs, parent);
90+
91+ String strn = attrs.getValue("from");
92+ if (strn != null)
93+ {
94+ if (XMLParseUtil.isDouble(strn))
95+ {
96+ fromValue = XMLParseUtil.parseDouble(strn);
97+ }
98+// else if (attrs.getValue("attributeName").equals("d"))
99+// {
100+// fromPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
101+// dataType = DT_PATH;
102+// }
103+ else
104+ {
105+ fromColor = ColorTable.parseColor(strn);
106+ if (fromColor == null)
107+ {
108+ //Try path
109+ fromPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
110+ dataType = DT_PATH;
111+ }
112+ else dataType = DT_COLOR;
113+ }
114+ }
115+
116+ strn = attrs.getValue("to");
117+ if (strn != null)
118+ {
119+ if (XMLParseUtil.isDouble(strn))
120+ {
121+ toValue = XMLParseUtil.parseDouble(strn);
122+ }
123+ else
124+ {
125+ toColor = ColorTable.parseColor(strn);
126+ if (toColor == null)
127+ {
128+ //Try path
129+ toPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
130+ dataType = DT_PATH;
131+ }
132+ else dataType = DT_COLOR;
133+ }
134+ }
135+
136+ strn = attrs.getValue("by");
137+ try
138+ {
139+ if (strn != null) byValue = XMLParseUtil.parseDouble(strn);
140+ } catch (Exception e) {}
141+
142+ strn = attrs.getValue("values");
143+ try
144+ {
145+ if (strn != null) valuesValue = XMLParseUtil.parseDoubleList(strn);
146+ } catch (Exception e) {}
147+ }
148+
149+ /**
150+ * Evaluates this animation element for the passed interpolation time. Interp
151+ * must be on [0..1].
152+ */
153+ public double eval(double interp)
154+ {
155+ boolean fromExists = !Double.isNaN(fromValue);
156+ boolean toExists = !Double.isNaN(toValue);
157+ boolean byExists = !Double.isNaN(byValue);
158+ boolean valuesExists = valuesValue != null;
159+
160+ if (valuesExists)
161+ {
162+ double sp = interp * valuesValue.length;
163+ int ip = (int)sp;
164+ double fp = sp - ip;
165+
166+ int i0 = ip;
167+ int i1 = ip + 1;
168+
169+ if (i0 < 0) return valuesValue[0];
170+ if (i1 >= valuesValue.length) return valuesValue[valuesValue.length - 1];
171+ return valuesValue[i0] * (1 - fp) + valuesValue[i1] * fp;
172+ }
173+ else if (fromExists && toExists)
174+ {
175+ return toValue * interp + fromValue * (1.0 - interp);
176+ }
177+ else if (fromExists && byExists)
178+ {
179+ return fromValue + byValue * interp;
180+ }
181+ else if (toExists && byExists)
182+ {
183+ return toValue - byValue * (1.0 - interp);
184+ }
185+ else if (byExists)
186+ {
187+ return byValue * interp;
188+ }
189+
190+ //Should not reach this line
191+ throw new RuntimeException("Animate tag could not be evalutated - insufficient arguements");
192+ }
193+
194+ public Color evalColor(double interp)
195+ {
196+ if (fromColor == null && toColor != null)
197+ {
198+ float[] toCol = new float[3];
199+ toColor.getColorComponents(toCol);
200+ return new Color(toCol[0] * (float)interp,
201+ toCol[1] * (float)interp,
202+ toCol[2] * (float)interp);
203+ }
204+ else if (fromColor != null && toColor != null)
205+ {
206+ float nInterp = 1 - (float)interp;
207+
208+ float[] fromCol = new float[3];
209+ float[] toCol = new float[3];
210+ fromColor.getColorComponents(fromCol);
211+ toColor.getColorComponents(toCol);
212+ return new Color(fromCol[0] * nInterp + toCol[0] * (float)interp,
213+ fromCol[1] * nInterp + toCol[1] * (float)interp,
214+ fromCol[2] * nInterp + toCol[2] * (float)interp);
215+ }
216+
217+ throw new RuntimeException("Animate tag could not be evalutated - insufficient arguements");
218+ }
219+
220+ public GeneralPath evalPath(double interp)
221+ {
222+ if (fromPath == null && toPath != null)
223+ {
224+ PathIterator itTo = toPath.getPathIterator(new AffineTransform());
225+
226+ GeneralPath midPath = new GeneralPath();
227+ float[] coordsTo = new float[6];
228+
229+ for (; !itTo.isDone(); itTo.next())
230+ {
231+ int segTo = itTo.currentSegment(coordsTo);
232+
233+ switch (segTo)
234+ {
235+ case PathIterator.SEG_CLOSE:
236+ midPath.closePath();
237+ break;
238+ case PathIterator.SEG_CUBICTO:
239+ midPath.curveTo(
240+ (float)(coordsTo[0] * interp),
241+ (float)(coordsTo[1] * interp),
242+ (float)(coordsTo[2] * interp),
243+ (float)(coordsTo[3] * interp),
244+ (float)(coordsTo[4] * interp),
245+ (float)(coordsTo[5] * interp)
246+ );
247+ break;
248+ case PathIterator.SEG_LINETO:
249+ midPath.lineTo(
250+ (float)(coordsTo[0] * interp),
251+ (float)(coordsTo[1] * interp)
252+ );
253+ break;
254+ case PathIterator.SEG_MOVETO:
255+ midPath.moveTo(
256+ (float)(coordsTo[0] * interp),
257+ (float)(coordsTo[1] * interp)
258+ );
259+ break;
260+ case PathIterator.SEG_QUADTO:
261+ midPath.quadTo(
262+ (float)(coordsTo[0] * interp),
263+ (float)(coordsTo[1] * interp),
264+ (float)(coordsTo[2] * interp),
265+ (float)(coordsTo[3] * interp)
266+ );
267+ break;
268+ }
269+ }
270+
271+ return midPath;
272+ }
273+ else if (toPath != null)
274+ {
275+ PathIterator itFrom = fromPath.getPathIterator(new AffineTransform());
276+ PathIterator itTo = toPath.getPathIterator(new AffineTransform());
277+
278+ GeneralPath midPath = new GeneralPath();
279+ float[] coordsFrom = new float[6];
280+ float[] coordsTo = new float[6];
281+
282+ for (; !itFrom.isDone(); itFrom.next())
283+ {
284+ int segFrom = itFrom.currentSegment(coordsFrom);
285+ int segTo = itTo.currentSegment(coordsTo);
286+
287+ if (segFrom != segTo)
288+ {
289+ throw new RuntimeException("Path shape mismatch");
290+ }
291+
292+ switch (segFrom)
293+ {
294+ case PathIterator.SEG_CLOSE:
295+ midPath.closePath();
296+ break;
297+ case PathIterator.SEG_CUBICTO:
298+ midPath.curveTo(
299+ (float)(coordsFrom[0] * (1 - interp) + coordsTo[0] * interp),
300+ (float)(coordsFrom[1] * (1 - interp) + coordsTo[1] * interp),
301+ (float)(coordsFrom[2] * (1 - interp) + coordsTo[2] * interp),
302+ (float)(coordsFrom[3] * (1 - interp) + coordsTo[3] * interp),
303+ (float)(coordsFrom[4] * (1 - interp) + coordsTo[4] * interp),
304+ (float)(coordsFrom[5] * (1 - interp) + coordsTo[5] * interp)
305+ );
306+ break;
307+ case PathIterator.SEG_LINETO:
308+ midPath.lineTo(
309+ (float)(coordsFrom[0] * (1 - interp) + coordsTo[0] * interp),
310+ (float)(coordsFrom[1] * (1 - interp) + coordsTo[1] * interp)
311+ );
312+ break;
313+ case PathIterator.SEG_MOVETO:
314+ midPath.moveTo(
315+ (float)(coordsFrom[0] * (1 - interp) + coordsTo[0] * interp),
316+ (float)(coordsFrom[1] * (1 - interp) + coordsTo[1] * interp)
317+ );
318+ break;
319+ case PathIterator.SEG_QUADTO:
320+ midPath.quadTo(
321+ (float)(coordsFrom[0] * (1 - interp) + coordsTo[0] * interp),
322+ (float)(coordsFrom[1] * (1 - interp) + coordsTo[1] * interp),
323+ (float)(coordsFrom[2] * (1 - interp) + coordsTo[2] * interp),
324+ (float)(coordsFrom[3] * (1 - interp) + coordsTo[3] * interp)
325+ );
326+ break;
327+ }
328+ }
329+
330+ return midPath;
331+ }
332+
333+ throw new RuntimeException("Animate tag could not be evalutated - insufficient arguements");
334+ }
335+
336+ /**
337+ * If this element is being accumulated, detemine the delta to accumulate by
338+ */
339+ public double repeatSkipSize(int reps)
340+ {
341+ boolean fromExists = !Double.isNaN(fromValue);
342+ boolean toExists = !Double.isNaN(toValue);
343+ boolean byExists = !Double.isNaN(byValue);
344+
345+ if (fromExists && toExists)
346+ {
347+ return (toValue - fromValue) * reps;
348+ }
349+ else if (fromExists && byExists)
350+ {
351+ return (fromValue + byValue) * reps;
352+ }
353+ else if (toExists && byExists)
354+ {
355+ return toValue * reps;
356+ }
357+ else if (byExists)
358+ {
359+ return byValue * reps;
360+ }
361+
362+ //Should not reach this line
363+ return 0;
364+ }
365+
366+ protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
367+ {
368+ super.rebuild(animTimeParser);
369+
370+ StyleAttribute sty = new StyleAttribute();
371+
372+ if (getPres(sty.setName("from")))
373+ {
374+ String strn = sty.getStringValue();
375+ if (XMLParseUtil.isDouble(strn))
376+ {
377+ fromValue = XMLParseUtil.parseDouble(strn);
378+ }
379+ else
380+ {
381+ fromColor = ColorTable.parseColor(strn);
382+ if (fromColor == null)
383+ {
384+ //Try path
385+ fromPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
386+ dataType = DT_PATH;
387+ }
388+ else dataType = DT_COLOR;
389+ }
390+ }
391+
392+ if (getPres(sty.setName("to")))
393+ {
394+ String strn = sty.getStringValue();
395+ if (XMLParseUtil.isDouble(strn))
396+ {
397+ toValue = XMLParseUtil.parseDouble(strn);
398+ }
399+ else
400+ {
401+ toColor = ColorTable.parseColor(strn);
402+ if (toColor == null)
403+ {
404+ //Try path
405+ toPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
406+ dataType = DT_PATH;
407+ }
408+ else dataType = DT_COLOR;
409+ }
410+ }
411+
412+ if (getPres(sty.setName("by")))
413+ {
414+ String strn = sty.getStringValue();
415+ if (strn != null) byValue = XMLParseUtil.parseDouble(strn);
416+ }
417+
418+ if (getPres(sty.setName("values")))
419+ {
420+ String strn = sty.getStringValue();
421+ if (strn != null) valuesValue = XMLParseUtil.parseDoubleList(strn);
422+ }
423+ }
424+
425+}
426Index: core/src/com/kitfox/svg/animation/AnimateBase.java
[4256]427===================================================================
[5284]428--- /dev/null 1970-01-01 00:00:00.000000000 +0000
429+++ core/src/com/kitfox/svg/animation/AnimateBase.java 2012-06-17 23:56:57.664545050 +0200
430@@ -0,0 +1,133 @@
431+/*
432+ * Animate.java
433+ *
434+ * The Salamander Project - 2D and 3D graphics libraries in Java
435+ * Copyright (C) 2004 Mark McKay
436+ *
437+ * This library is free software; you can redistribute it and/or
438+ * modify it under the terms of the GNU Lesser General Public
439+ * License as published by the Free Software Foundation; either
440+ * version 2.1 of the License, or (at your option) any later version.
441+ *
442+ * This library is distributed in the hope that it will be useful,
443+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
444+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
445+ * Lesser General Public License for more details.
446+ *
447+ * You should have received a copy of the GNU Lesser General Public
448+ * License along with this library; if not, write to the Free Software
449+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
450+ *
451+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
452+ * projects can be found at http://www.kitfox.com
453+ *
454+ * Created on August 15, 2004, 2:51 AM
455+ */
456+
457+package com.kitfox.svg.animation;
458+
459+import com.kitfox.svg.SVGElement;
460+import com.kitfox.svg.SVGException;
461+import com.kitfox.svg.SVGLoaderHelper;
462+import com.kitfox.svg.animation.parser.AnimTimeParser;
463+import com.kitfox.svg.animation.parser.ParseException;
464+import com.kitfox.svg.xml.StyleAttribute;
465+import java.io.StringReader;
466+import org.xml.sax.Attributes;
467+import org.xml.sax.SAXException;
468+
469+/**
470+ * @author Mark McKay
471+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
472+ */
473+abstract public class AnimateBase extends AnimationElement
474+{
475+ protected double repeatCount = Double.NaN;
476+ protected TimeBase repeatDur;
477+
478+ /** Creates a new instance of Animate */
479+ public AnimateBase()
480+ {
481+ }
482+
483+ public void evalParametric(AnimationTimeEval state, double curTime)
484+ {
485+ evalParametric(state, curTime, repeatCount, repeatDur == null ? Double.NaN : repeatDur.evalTime());
486+ }
487+
488+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
489+ {
490+ //Load style string
491+ super.loaderStartElement(helper, attrs, parent);
492+
493+ String repeatDurTime = attrs.getValue("repeatDur");
494+
495+ try
496+ {
497+ if (repeatDurTime != null)
498+ {
499+ helper.animTimeParser.ReInit(new StringReader(repeatDurTime));
500+ this.repeatDur = helper.animTimeParser.Expr();
501+ this.repeatDur.setParentElement(this);
502+ }
503+ }
504+ catch (Exception e)
505+ {
506+ throw new SAXException(e);
507+ }
508+
509+ String strn = attrs.getValue("repeatCount");
510+ if (strn == null)
511+ {
512+ repeatCount = 1;
513+ }
514+ else if ("indefinite".equals(strn))
515+ {
516+ repeatCount = Double.POSITIVE_INFINITY;
517+ }
518+ else
519+ {
520+ try { repeatCount = Double.parseDouble(strn); }
521+ catch (Exception e) { repeatCount = Double.NaN; }
522+ }
523+ }
524+
525+ protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
526+ {
527+ super.rebuild(animTimeParser);
528+
529+ StyleAttribute sty = new StyleAttribute();
530+
531+ if (getPres(sty.setName("repeatDur")))
532+ {
533+ String strn = sty.getStringValue();
534+ if (strn != null)
535+ {
536+ animTimeParser.ReInit(new StringReader(strn));
537+ try {
538+ this.repeatDur = animTimeParser.Expr();
539+ } catch (ParseException ex) {
540+ ex.printStackTrace();
541+ }
542+ }
543+ }
544+
545+ if (getPres(sty.setName("repeatCount")))
546+ {
547+ String strn = sty.getStringValue();
548+ if (strn == null)
549+ {
550+ repeatCount = 1;
551+ }
552+ else if ("indefinite".equals(strn))
553+ {
554+ repeatCount = Double.POSITIVE_INFINITY;
555+ }
556+ else
557+ {
558+ try { repeatCount = Double.parseDouble(strn); }
559+ catch (Exception e) { repeatCount = Double.NaN; }
560+ }
561+ }
562+ }
563+}
564Index: core/src/com/kitfox/svg/animation/AnimateColor.java
[4256]565===================================================================
[5284]566--- /dev/null 1970-01-01 00:00:00.000000000 +0000
567+++ core/src/com/kitfox/svg/animation/AnimateColor.java 2012-06-17 23:56:57.672545050 +0200
568@@ -0,0 +1,105 @@
569+/*
570+ * Animate.java
571+ *
572+ * The Salamander Project - 2D and 3D graphics libraries in Java
573+ * Copyright (C) 2004 Mark McKay
574+ *
575+ * This library is free software; you can redistribute it and/or
576+ * modify it under the terms of the GNU Lesser General Public
577+ * License as published by the Free Software Foundation; either
578+ * version 2.1 of the License, or (at your option) any later version.
579+ *
580+ * This library is distributed in the hope that it will be useful,
581+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
582+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
583+ * Lesser General Public License for more details.
584+ *
585+ * You should have received a copy of the GNU Lesser General Public
586+ * License along with this library; if not, write to the Free Software
587+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
588+ *
589+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
590+ * projects can be found at http://www.kitfox.com
591+ *
592+ * Created on August 15, 2004, 2:51 AM
593+ */
594+
595+package com.kitfox.svg.animation;
596+
597+import com.kitfox.svg.SVGElement;
598+import com.kitfox.svg.SVGException;
599+import com.kitfox.svg.SVGLoaderHelper;
600+import com.kitfox.svg.animation.parser.AnimTimeParser;
601+import com.kitfox.svg.xml.ColorTable;
602+import com.kitfox.svg.xml.StyleAttribute;
603+import java.awt.Color;
604+import org.xml.sax.Attributes;
605+import org.xml.sax.SAXException;
606+
607+
608+/**
609+ * @author Mark McKay
610+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
611+ */
612+public class AnimateColor extends AnimateBase implements AnimateColorIface
613+{
614+
615+ protected Color fromValue;
616+ protected Color toValue;
617+
618+ /** Creates a new instance of Animate */
619+ public AnimateColor()
620+ {
621+ }
622+
623+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
624+ {
625+ //Load style string
626+ super.loaderStartElement(helper, attrs, parent);
627+
628+ String strn = attrs.getValue("from");
629+ fromValue = ColorTable.parseColor(strn);
630+
631+ strn = attrs.getValue("to");
632+ toValue = ColorTable.parseColor(strn);
633+ }
634+
635+
636+ /**
637+ * Evaluates this animation element for the passed interpolation time. Interp
638+ * must be on [0..1].
639+ */
640+ public Color evalColor(double interp)
641+ {
642+ int r1 = fromValue.getRed();
643+ int g1 = fromValue.getGreen();
644+ int b1 = fromValue.getBlue();
645+ int r2 = toValue.getRed();
646+ int g2 = toValue.getGreen();
647+ int b2 = toValue.getBlue();
648+ double invInterp = 1.0 - interp;
649+
650+ return new Color((int)(r1 * invInterp + r2 * interp),
651+ (int)(g1 * invInterp + g2 * interp),
652+ (int)(b1 * invInterp + b2 * interp));
653+ }
654+
655+ protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
656+ {
657+ super.rebuild(animTimeParser);
658+
659+ StyleAttribute sty = new StyleAttribute();
660+
661+ if (getPres(sty.setName("from")))
662+ {
663+ String strn = sty.getStringValue();
664+ fromValue = ColorTable.parseColor(strn);
665+ }
666+
667+ if (getPres(sty.setName("to")))
668+ {
669+ String strn = sty.getStringValue();
670+ toValue = ColorTable.parseColor(strn);
671+ }
672+ }
673+}
674Index: core/src/com/kitfox/svg/animation/AnimateColorIface.java
[4256]675===================================================================
[5284]676--- /dev/null 1970-01-01 00:00:00.000000000 +0000
677+++ core/src/com/kitfox/svg/animation/AnimateColorIface.java 2012-06-17 23:56:57.672545050 +0200
678@@ -0,0 +1,38 @@
679+/*
680+ * AnimateColorIface.java
681+ *
682+ * The Salamander Project - 2D and 3D graphics libraries in Java
683+ * Copyright (C) 2004 Mark McKay
684+ *
685+ * This library is free software; you can redistribute it and/or
686+ * modify it under the terms of the GNU Lesser General Public
687+ * License as published by the Free Software Foundation; either
688+ * version 2.1 of the License, or (at your option) any later version.
689+ *
690+ * This library is distributed in the hope that it will be useful,
691+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
692+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
693+ * Lesser General Public License for more details.
694+ *
695+ * You should have received a copy of the GNU Lesser General Public
696+ * License along with this library; if not, write to the Free Software
697+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
698+ *
699+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
700+ * projects can be found at http://www.kitfox.com
701+ *
702+ * Created on January 16, 2005, 6:24 AM
703+ */
704+
705+package com.kitfox.svg.animation;
706+
707+import java.awt.*;
708+
709+/**
710+ *
711+ * @author kitfox
712+ */
713+public interface AnimateColorIface
714+{
715+ public Color evalColor(double interp);
716+}
717Index: core/src/com/kitfox/svg/animation/AnimateMotion.java
[4256]718===================================================================
[5284]719--- /dev/null 1970-01-01 00:00:00.000000000 +0000
720+++ core/src/com/kitfox/svg/animation/AnimateMotion.java 2012-06-17 23:56:57.672545050 +0200
721@@ -0,0 +1,282 @@
722+/*
723+ * Animate.java
724+ *
725+ * The Salamander Project - 2D and 3D graphics libraries in Java
726+ * Copyright (C) 2004 Mark McKay
727+ *
728+ * This library is free software; you can redistribute it and/or
729+ * modify it under the terms of the GNU Lesser General Public
730+ * License as published by the Free Software Foundation; either
731+ * version 2.1 of the License, or (at your option) any later version.
732+ *
733+ * This library is distributed in the hope that it will be useful,
734+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
735+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
736+ * Lesser General Public License for more details.
737+ *
738+ * You should have received a copy of the GNU Lesser General Public
739+ * License along with this library; if not, write to the Free Software
740+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
741+ *
742+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
743+ * projects can be found at http://www.kitfox.com
744+ *
745+ * Created on August 15, 2004, 2:51 AM
746+ */
747+
748+package com.kitfox.svg.animation;
749+
750+import com.kitfox.svg.SVGElement;
751+import com.kitfox.svg.SVGException;
752+import com.kitfox.svg.SVGLoaderHelper;
753+import com.kitfox.svg.animation.parser.AnimTimeParser;
754+import com.kitfox.svg.xml.StyleAttribute;
755+import java.awt.geom.AffineTransform;
756+import java.awt.geom.GeneralPath;
757+import java.awt.geom.PathIterator;
758+import java.awt.geom.Point2D;
759+import java.util.ArrayList;
760+import java.util.Iterator;
761+import java.util.regex.Matcher;
762+import java.util.regex.Pattern;
763+import org.xml.sax.Attributes;
764+import org.xml.sax.SAXException;
765+
766+
767+/**
768+ * @author Mark McKay
769+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
770+ */
771+public class AnimateMotion extends AnimateXform
772+{
773+ static final Matcher matchPoint = Pattern.compile("\\s*(\\d+)[^\\d]+(\\d+)\\s*").matcher("");
774+
775+// protected double fromValue;
776+// protected double toValue;
777+ GeneralPath path;
778+ int rotateType = RT_ANGLE;
779+ double rotate; //Static angle to rotate by
780+
781+ public static final int RT_ANGLE = 0; //Rotate by constant 'rotate' degrees
782+ public static final int RT_AUTO = 1; //Rotate to reflect tangent of position on path
783+
784+ final ArrayList bezierSegs = new ArrayList();
785+ double curveLength;
786+
787+ /** Creates a new instance of Animate */
788+ public AnimateMotion()
789+ {
790+ }
791+
792+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
793+ {
794+ //Load style string
795+ super.loaderStartElement(helper, attrs, parent);
796+
797+ //Motion element implies animating the transform element
798+ if (attribName == null)
799+ {
800+ attribName = "transform";
801+ attribType = AT_AUTO;
802+ additiveType = AD_SUM;
803+ }
804+
805+
806+ String path = attrs.getValue("path");
807+ if (path != null)
808+ {
809+ this.path = buildPath(path, GeneralPath.WIND_NON_ZERO);
810+ }
811+
812+ //Now parse rotation style
813+ String rotate = attrs.getValue("rotate");
814+ if (rotate != null)
815+ {
816+ if (rotate.equals("auto"))
817+ {
818+ this.rotateType = RT_AUTO;
819+ }
820+ else
821+ {
822+ try { this.rotate = Math.toRadians(Float.parseFloat(rotate)); } catch (Exception e) {}
823+ }
824+ }
825+
826+ //Determine path
827+ String from = attrs.getValue("from");
828+ String to = attrs.getValue("to");
829+
830+ buildPath(from, to);
831+ }
832+
833+ protected static void setPoint(Point2D.Float pt, String x, String y)
834+ {
835+ try { pt.x = Float.parseFloat(x); } catch (Exception e) {};
836+
837+ try { pt.y = Float.parseFloat(y); } catch (Exception e) {};
838+ }
839+
840+ private void buildPath(String from, String to)
841+ {
842+ if (from != null && to != null)
843+ {
844+ Point2D.Float ptFrom = new Point2D.Float(), ptTo = new Point2D.Float();
845+
846+ matchPoint.reset(from);
847+ if (matchPoint.matches())
848+ {
849+ setPoint(ptFrom, matchPoint.group(1), matchPoint.group(2));
850+ }
851+
852+ matchPoint.reset(to);
853+ if (matchPoint.matches())
854+ {
855+ setPoint(ptFrom, matchPoint.group(1), matchPoint.group(2));
856+ }
857+
858+ if (ptFrom != null && ptTo != null)
859+ {
860+ path = new GeneralPath();
861+ path.moveTo(ptFrom.x, ptFrom.y);
862+ path.lineTo(ptTo.x, ptTo.y);
863+ }
864+ }
865+
866+ paramaterizePath();
867+ }
868+
869+ private void paramaterizePath()
870+ {
871+ bezierSegs.clear();
872+ curveLength = 0;
873+
874+ double[] coords = new double[6];
875+ double sx = 0, sy = 0;
876+
877+ for (PathIterator pathIt = path.getPathIterator(new AffineTransform()); !pathIt.isDone(); pathIt.next())
878+ {
879+ Bezier bezier = null;
880+
881+ int segType = pathIt.currentSegment(coords);
882+
883+ switch (segType)
884+ {
885+ case PathIterator.SEG_LINETO:
886+ {
887+ bezier = new Bezier(sx, sy, coords, 1);
888+ sx = coords[0];
889+ sy = coords[1];
890+ break;
891+ }
892+ case PathIterator.SEG_QUADTO:
893+ {
894+ bezier = new Bezier(sx, sy, coords, 2);
895+ sx = coords[2];
896+ sy = coords[3];
897+ break;
898+ }
899+ case PathIterator.SEG_CUBICTO:
900+ {
901+ bezier = new Bezier(sx, sy, coords, 3);
902+ sx = coords[4];
903+ sy = coords[5];
904+ break;
905+ }
906+ case PathIterator.SEG_MOVETO:
907+ {
908+ sx = coords[0];
909+ sy = coords[1];
910+ break;
911+ }
912+ case PathIterator.SEG_CLOSE:
913+ //Do nothing
914+ break;
915+
916+ }
917+
918+ if (bezier != null)
919+ {
920+ bezierSegs.add(bezier);
921+ curveLength += bezier.getLength();
922+ }
923+ }
924+ }
925+
926+ /**
927+ * Evaluates this animation element for the passed interpolation time. Interp
928+ * must be on [0..1].
929+ */
930+ public AffineTransform eval(AffineTransform xform, double interp)
931+ {
932+ Point2D.Double point = new Point2D.Double();
933+
934+ if (interp >= 1)
935+ {
936+ Bezier last = (Bezier)bezierSegs.get(bezierSegs.size() - 1);
937+ last.getFinalPoint(point);
938+ xform.setToTranslation(point.x, point.y);
939+ return xform;
940+ }
941+
942+ double curLength = curveLength * interp;
943+ for (Iterator it = bezierSegs.iterator(); it.hasNext();)
944+ {
945+ Bezier bez = (Bezier)it.next();
946+
947+ double bezLength = bez.getLength();
948+ if (curLength < bezLength)
949+ {
950+ double param = curLength / bezLength;
951+ bez.eval(param, point);
952+ break;
953+ }
954+
955+ curLength -= bezLength;
956+ }
957+
958+ xform.setToTranslation(point.x, point.y);
959+
960+ return xform;
961+ }
962+
963+
964+ protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
965+ {
966+ super.rebuild(animTimeParser);
967+
968+ StyleAttribute sty = new StyleAttribute();
969+
970+ if (getPres(sty.setName("path")))
971+ {
972+ String strn = sty.getStringValue();
973+ this.path = buildPath(strn, GeneralPath.WIND_NON_ZERO);
974+ }
975+
976+ if (getPres(sty.setName("rotate")))
977+ {
978+ String strn = sty.getStringValue();
979+ if (strn.equals("auto"))
980+ {
981+ this.rotateType = RT_AUTO;
982+ }
983+ else
984+ {
985+ try { this.rotate = Math.toRadians(Float.parseFloat(strn)); } catch (Exception e) {}
986+ }
987+ }
988+
989+ String from = null;
990+ if (getPres(sty.setName("from")))
991+ {
992+ from = sty.getStringValue();
993+ }
994+
995+ String to = null;
996+ if (getPres(sty.setName("to")))
997+ {
998+ to = sty.getStringValue();
999+ }
1000+
1001+ buildPath(from, to);
1002+ }
1003+}
1004Index: core/src/com/kitfox/svg/animation/AnimateTransform.java
[4256]1005===================================================================
[5284]1006--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1007+++ core/src/com/kitfox/svg/animation/AnimateTransform.java 2012-06-17 23:56:57.676545050 +0200
1008@@ -0,0 +1,302 @@
1009+/*
1010+ * Animate.java
1011+ *
1012+ * The Salamander Project - 2D and 3D graphics libraries in Java
1013+ * Copyright (C) 2004 Mark McKay
1014+ *
1015+ * This library is free software; you can redistribute it and/or
1016+ * modify it under the terms of the GNU Lesser General Public
1017+ * License as published by the Free Software Foundation; either
1018+ * version 2.1 of the License, or (at your option) any later version.
1019+ *
1020+ * This library is distributed in the hope that it will be useful,
1021+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1022+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1023+ * Lesser General Public License for more details.
1024+ *
1025+ * You should have received a copy of the GNU Lesser General Public
1026+ * License along with this library; if not, write to the Free Software
1027+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1028+ *
1029+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
1030+ * projects can be found at http://www.kitfox.com
1031+ *
1032+ * Created on August 15, 2004, 2:51 AM
1033+ */
1034+
1035+package com.kitfox.svg.animation;
1036+
1037+import com.kitfox.svg.SVGElement;
1038+import com.kitfox.svg.SVGException;
1039+import com.kitfox.svg.SVGLoaderHelper;
1040+import com.kitfox.svg.animation.parser.AnimTimeParser;
1041+import com.kitfox.svg.xml.StyleAttribute;
1042+import com.kitfox.svg.xml.XMLParseUtil;
1043+import java.awt.geom.AffineTransform;
1044+import java.util.regex.Pattern;
1045+import org.xml.sax.Attributes;
1046+import org.xml.sax.SAXException;
1047+
1048+
1049+/**
1050+ * @author Mark McKay
1051+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
1052+ */
1053+public class AnimateTransform extends AnimateXform
1054+{
1055+// protected AffineTransform fromValue;
1056+// protected AffineTransform toValue;
1057+// protected double[] fromValue; //Transform parameters
1058+// protected double[] toValue;
1059+ protected double[][] values;
1060+ protected double[] keyTimes;
1061+
1062+ public static final int AT_REPLACE = 0;
1063+ public static final int AT_SUM = 1;
1064+
1065+ protected int additive = AT_REPLACE;
1066+
1067+ public static final int TR_TRANSLATE = 0;
1068+ public static final int TR_ROTATE = 1;
1069+ public static final int TR_SCALE = 2;
1070+ public static final int TR_SKEWY = 3;
1071+ public static final int TR_SKEWX = 4;
1072+ public static final int TR_INVALID = 5;
1073+
1074+ protected int xformType = TR_INVALID;
1075+
1076+ /** Creates a new instance of Animate */
1077+ public AnimateTransform()
1078+ {
1079+ }
1080+
1081+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
1082+ {
1083+ //Load style string
1084+ super.loaderStartElement(helper, attrs, parent);
1085+
1086+ //Type of matrix of transform. Should be one of the known names used to
1087+ // define matrix transforms
1088+ // valid types: translate, scale, rotate, skewX, skewY
1089+ // 'matrix' not valid for animation
1090+ String type = attrs.getValue("type").toLowerCase();
1091+ if (type.equals("translate")) xformType = TR_TRANSLATE;
1092+ if (type.equals("rotate")) xformType = TR_ROTATE;
1093+ if (type.equals("scale")) xformType = TR_SCALE;
1094+ if (type.equals("skewx")) xformType = TR_SKEWX;
1095+ if (type.equals("skewy")) xformType = TR_SKEWY;
1096+
1097+ String fromStrn = attrs.getValue("from");
1098+ String toStrn = attrs.getValue("to");
1099+ if (fromStrn != null && toStrn != null)
1100+ {
1101+ //fromValue = parseSingleTransform(type + "(" + strn + ")");
1102+ double[] fromValue = XMLParseUtil.parseDoubleList(fromStrn);
1103+ fromValue = validate(fromValue);
1104+
1105+ // toValue = parseSingleTransform(type + "(" + strn + ")");
1106+ double[] toValue = XMLParseUtil.parseDoubleList(toStrn);
1107+ toValue = validate(toValue);
1108+
1109+ values = new double[][]{fromValue, toValue};
1110+ keyTimes = new double[]{0, 1};
1111+ }
1112+
1113+ String keyTimeStrn = attrs.getValue("keyTimes");
1114+ String valuesStrn = attrs.getValue("values");
1115+ if (keyTimeStrn != null && valuesStrn != null)
1116+ {
1117+ keyTimes = XMLParseUtil.parseDoubleList(keyTimeStrn);
1118+
1119+ String[] valueList = Pattern.compile(";").split(valuesStrn);
1120+ values = new double[valueList.length][];
1121+ for (int i = 0; i < valueList.length; i++)
1122+ {
1123+ double[] list = XMLParseUtil.parseDoubleList(valueList[i]);
1124+ values[i] = validate(list);
1125+ }
1126+ }
1127+
1128+ //Check our additive state
1129+ String additive = attrs.getValue("additive");
1130+ if (additive != null)
1131+ {
1132+ if (additive.equals("sum")) this.additive = AT_SUM;
1133+ }
1134+ }
1135+
1136+ /**
1137+ * Check list size against current xform type and ensure list
1138+ * is expanded to a standard list size
1139+ */
1140+ private double[] validate(double[] paramList)
1141+ {
1142+ switch (xformType)
1143+ {
1144+ case TR_SCALE:
1145+ {
1146+ if (paramList == null)
1147+ {
1148+ paramList = new double[]{1, 1};
1149+ }
1150+ else if (paramList.length == 1)
1151+ {
1152+ paramList = new double[]{paramList[0], paramList[0]};
1153+
1154+// double[] tmp = paramList;
1155+// paramList = new double[2];
1156+// paramList[0] = paramList[1] = tmp[0];
1157+ }
1158+ }
1159+ }
1160+
1161+ return paramList;
1162+ }
1163+
1164+ /**
1165+ * Evaluates this animation element for the passed interpolation time. Interp
1166+ * must be on [0..1].
1167+ */
1168+ public AffineTransform eval(AffineTransform xform, double interp)
1169+ {
1170+ int idx = 0;
1171+ for (; idx < keyTimes.length - 1; idx++)
1172+ {
1173+ if (interp >= keyTimes[idx])
1174+ {
1175+ idx--;
1176+ if (idx < 0) idx = 0;
1177+ break;
1178+ }
1179+ }
1180+
1181+ double spanStartTime = keyTimes[idx];
1182+ double spanEndTime = keyTimes[idx + 1];
1183+// double span = spanStartTime - spanEndTime;
1184+
1185+ interp = (interp - spanStartTime) / (spanEndTime - spanStartTime);
1186+ double[] fromValue = values[idx];
1187+ double[] toValue = values[idx + 1];
1188+
1189+ switch (xformType)
1190+ {
1191+ case TR_TRANSLATE:
1192+ {
1193+ double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
1194+ double y = (1.0 - interp) * fromValue[1] + interp * toValue[1];
1195+ xform.setToTranslation(x, y);
1196+ break;
1197+ }
1198+ case TR_ROTATE:
1199+ {
1200+ double x1 = fromValue.length == 3 ? fromValue[1] : 0;
1201+ double y1 = fromValue.length == 3 ? fromValue[2] : 0;
1202+ double x2 = toValue.length == 3 ? toValue[1] : 0;
1203+ double y2 = toValue.length == 3 ? toValue[2] : 0;
1204+
1205+ double theta = (1.0 - interp) * fromValue[0] + interp * toValue[0];
1206+ double x = (1.0 - interp) * x1 + interp * x2;
1207+ double y = (1.0 - interp) * y1 + interp * y2;
1208+ xform.setToRotation(Math.toRadians(theta), x, y);
1209+ break;
1210+ }
1211+ case TR_SCALE:
1212+ {
1213+ double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
1214+ double y = (1.0 - interp) * fromValue[1] + interp * toValue[1];
1215+ xform.setToScale(x, y);
1216+ break;
1217+ }
1218+ case TR_SKEWX:
1219+ {
1220+ double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
1221+ xform.setToShear(Math.toRadians(x), 0.0);
1222+ break;
1223+ }
1224+ case TR_SKEWY:
1225+ {
1226+ double y = (1.0 - interp) * fromValue[0] + interp * toValue[0];
1227+ xform.setToShear(0.0, Math.toRadians(y));
1228+ break;
1229+ }
1230+ default:
1231+ xform.setToIdentity();
1232+ break;
1233+ }
1234+
1235+ return xform;
1236+ }
1237+
1238+ protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
1239+ {
1240+ super.rebuild(animTimeParser);
1241+
1242+ StyleAttribute sty = new StyleAttribute();
1243+
1244+ if (getPres(sty.setName("type")))
1245+ {
1246+ String strn = sty.getStringValue().toLowerCase();
1247+ if (strn.equals("translate")) xformType = TR_TRANSLATE;
1248+ if (strn.equals("rotate")) xformType = TR_ROTATE;
1249+ if (strn.equals("scale")) xformType = TR_SCALE;
1250+ if (strn.equals("skewx")) xformType = TR_SKEWX;
1251+ if (strn.equals("skewy")) xformType = TR_SKEWY;
1252+ }
1253+
1254+ String fromStrn = null;
1255+ if (getPres(sty.setName("from")))
1256+ {
1257+ fromStrn = sty.getStringValue();
1258+ }
1259+
1260+ String toStrn = null;
1261+ if (getPres(sty.setName("to")))
1262+ {
1263+ toStrn = sty.getStringValue();
1264+ }
1265+
1266+ if (fromStrn != null && toStrn != null)
1267+ {
1268+ double[] fromValue = XMLParseUtil.parseDoubleList(fromStrn);
1269+ fromValue = validate(fromValue);
1270+
1271+ double[] toValue = XMLParseUtil.parseDoubleList(toStrn);
1272+ toValue = validate(toValue);
1273+
1274+ values = new double[][]{fromValue, toValue};
1275+ }
1276+
1277+ String keyTimeStrn = null;
1278+ if (getPres(sty.setName("keyTimes")))
1279+ {
1280+ keyTimeStrn = sty.getStringValue();
1281+ }
1282+
1283+ String valuesStrn = null;
1284+ if (getPres(sty.setName("values")))
1285+ {
1286+ valuesStrn = sty.getStringValue();
1287+ }
1288+
1289+ if (keyTimeStrn != null && valuesStrn != null)
1290+ {
1291+ keyTimes = XMLParseUtil.parseDoubleList(keyTimeStrn);
1292+
1293+ String[] valueList = Pattern.compile(";").split(valuesStrn);
1294+ values = new double[valueList.length][];
1295+ for (int i = 0; i < valueList.length; i++)
1296+ {
1297+ double[] list = XMLParseUtil.parseDoubleList(valueList[i]);
1298+ values[i] = validate(list);
1299+ }
1300+ }
1301+
1302+ //Check our additive state
1303+
1304+ if (getPres(sty.setName("additive")))
1305+ {
1306+ String strn = sty.getStringValue().toLowerCase();
1307+ if (strn.equals("sum")) this.additive = AT_SUM;
1308+ }
1309+ }
1310+}
1311Index: core/src/com/kitfox/svg/animation/AnimateXform.java
[4256]1312===================================================================
[5284]1313--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1314+++ core/src/com/kitfox/svg/animation/AnimateXform.java 2012-06-17 23:56:57.676545050 +0200
1315@@ -0,0 +1,54 @@
1316+/*
1317+ * AnimateXform.java
1318+ *
1319+ * The Salamander Project - 2D and 3D graphics libraries in Java
1320+ * Copyright (C) 2004 Mark McKay
1321+ *
1322+ * This library is free software; you can redistribute it and/or
1323+ * modify it under the terms of the GNU Lesser General Public
1324+ * License as published by the Free Software Foundation; either
1325+ * version 2.1 of the License, or (at your option) any later version.
1326+ *
1327+ * This library is distributed in the hope that it will be useful,
1328+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1329+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1330+ * Lesser General Public License for more details.
1331+ *
1332+ * You should have received a copy of the GNU Lesser General Public
1333+ * License along with this library; if not, write to the Free Software
1334+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1335+ *
1336+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
1337+ * projects can be found at http://www.kitfox.com
1338+ *
1339+ * Created on January 14, 2005, 6:46 AM
1340+ */
1341+
1342+package com.kitfox.svg.animation;
1343+
1344+import com.kitfox.svg.SVGElement;
1345+import com.kitfox.svg.SVGLoaderHelper;
1346+import java.awt.geom.AffineTransform;
1347+import org.xml.sax.Attributes;
1348+import org.xml.sax.SAXException;
1349+
1350+
1351+
1352+/**
1353+ *
1354+ * @author kitfox
1355+ */
1356+abstract public class AnimateXform extends AnimateBase
1357+{
1358+ public AnimateXform()
1359+ {
1360+ }
1361+
1362+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
1363+ {
1364+ super.loaderStartElement(helper, attrs, parent);
1365+ }
1366+
1367+ abstract public AffineTransform eval(AffineTransform xform, double interp);
1368+
1369+}
1370Index: core/src/com/kitfox/svg/animation/AnimationElement.java
[4256]1371===================================================================
[5284]1372--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1373+++ core/src/com/kitfox/svg/animation/AnimationElement.java 2012-06-17 23:56:57.676545050 +0200
1374@@ -0,0 +1,414 @@
1375+/*
1376+ * AnimateEle.java
1377+ *
1378+ * The Salamander Project - 2D and 3D graphics libraries in Java
1379+ * Copyright (C) 2004 Mark McKay
1380+ *
1381+ * This library is free software; you can redistribute it and/or
1382+ * modify it under the terms of the GNU Lesser General Public
1383+ * License as published by the Free Software Foundation; either
1384+ * version 2.1 of the License, or (at your option) any later version.
1385+ *
1386+ * This library is distributed in the hope that it will be useful,
1387+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1388+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1389+ * Lesser General Public License for more details.
1390+ *
1391+ * You should have received a copy of the GNU Lesser General Public
1392+ * License along with this library; if not, write to the Free Software
1393+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1394+ *
1395+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
1396+ * projects can be found at http://www.kitfox.com
1397+ *
1398+ * Created on August 15, 2004, 2:52 AM
1399+ */
1400+
1401+package com.kitfox.svg.animation;
1402+
1403+import com.kitfox.svg.SVGElement;
1404+import com.kitfox.svg.SVGException;
1405+import com.kitfox.svg.SVGLoaderHelper;
1406+import com.kitfox.svg.animation.parser.AnimTimeParser;
1407+import com.kitfox.svg.animation.parser.ParseException;
1408+import com.kitfox.svg.xml.StyleAttribute;
1409+import java.io.StringReader;
1410+import org.xml.sax.Attributes;
1411+import org.xml.sax.SAXException;
1412+
1413+
1414+/**
1415+ * @author Mark McKay
1416+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
1417+ */
1418+public abstract class AnimationElement extends SVGElement
1419+{
1420+ protected String attribName;
1421+// protected String attribType;
1422+ protected int attribType = AT_AUTO;
1423+
1424+ public static final int AT_CSS = 0;
1425+ public static final int AT_XML = 1;
1426+ public static final int AT_AUTO = 2; //Check CSS first, then XML
1427+
1428+ protected TimeBase beginTime;
1429+ protected TimeBase durTime;
1430+ protected TimeBase endTime;
1431+ protected int fillType = FT_AUTO;
1432+
1433+ /** <a href="http://www.w3.org/TR/smil20/smil-timing.html#adef-fill">More about the <b>fill</b> attribute</a> */
1434+ public static final int FT_REMOVE = 0;
1435+ public static final int FT_FREEZE = 1;
1436+ public static final int FT_HOLD = 2;
1437+ public static final int FT_TRANSITION = 3;
1438+ public static final int FT_AUTO = 4;
1439+ public static final int FT_DEFAULT = 5;
1440+
1441+ /** Additive state of track */
1442+ public static final int AD_REPLACE = 0;
1443+ public static final int AD_SUM = 1;
1444+
1445+ int additiveType = AD_REPLACE;
1446+
1447+ /** Accumlative state */
1448+ public static final int AC_REPLACE = 0;
1449+ public static final int AC_SUM = 1;
1450+
1451+ int accumulateType = AC_REPLACE;
1452+
1453+ /** Creates a new instance of AnimateEle */
1454+ public AnimationElement()
1455+ {
1456+ }
1457+
1458+ public static String animationElementToString(int attrValue)
1459+ {
1460+ switch (attrValue)
1461+ {
1462+ case AT_CSS:
1463+ return "CSS";
1464+ case AT_XML:
1465+ return "XML";
1466+ case AT_AUTO:
1467+ return "AUTO";
1468+ default:
1469+ throw new RuntimeException("Unknown element type");
1470+ }
1471+ }
1472+
1473+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
1474+ {
1475+ //Load style string
1476+ super.loaderStartElement(helper, attrs, parent);
1477+
1478+ attribName = attrs.getValue("attributeName");
1479+ String attribType = attrs.getValue("attributeType");
1480+ if (attribType != null)
1481+ {
1482+ attribType = attribType.toLowerCase();
1483+ if (attribType.equals("css")) this.attribType = AT_CSS;
1484+ else if (attribType.equals("xml")) this.attribType = AT_XML;
1485+ }
1486+
1487+ String beginTime = attrs.getValue("begin");
1488+ String durTime = attrs.getValue("dur");
1489+ String endTime = attrs.getValue("end");
1490+
1491+ try
1492+ {
1493+ if (beginTime != null)
1494+ {
1495+ helper.animTimeParser.ReInit(new StringReader(beginTime));
1496+ this.beginTime = helper.animTimeParser.Expr();
1497+ this.beginTime.setParentElement(this);
1498+ }
1499+
1500+ if (durTime != null)
1501+ {
1502+ helper.animTimeParser.ReInit(new StringReader(durTime));
1503+ this.durTime = helper.animTimeParser.Expr();
1504+ this.durTime.setParentElement(this);
1505+ }
1506+
1507+ if (endTime != null)
1508+ {
1509+ helper.animTimeParser.ReInit(new StringReader(endTime));
1510+ this.endTime = helper.animTimeParser.Expr();
1511+ this.endTime.setParentElement(this);
1512+ }
1513+ }
1514+ catch (Exception e)
1515+ {
1516+ throw new SAXException(e);
1517+ }
1518+
1519+// this.beginTime = TimeBase.parseTime(beginTime);
1520+// this.durTime = TimeBase.parseTime(durTime);
1521+// this.endTime = TimeBase.parseTime(endTime);
1522+
1523+ String fill = attrs.getValue("fill");
1524+
1525+ if (fill != null)
1526+ {
1527+ if (fill.equals("remove")) this.fillType = FT_REMOVE;
1528+ if (fill.equals("freeze")) this.fillType = FT_FREEZE;
1529+ if (fill.equals("hold")) this.fillType = FT_HOLD;
1530+ if (fill.equals("transiton")) this.fillType = FT_TRANSITION;
1531+ if (fill.equals("auto")) this.fillType = FT_AUTO;
1532+ if (fill.equals("default")) this.fillType = FT_DEFAULT;
1533+ }
1534+
1535+ String additiveStrn = attrs.getValue("additive");
1536+
1537+ if (additiveStrn != null)
1538+ {
1539+ if (additiveStrn.equals("replace")) this.additiveType = AD_REPLACE;
1540+ if (additiveStrn.equals("sum")) this.additiveType = AD_SUM;
1541+ }
1542+
1543+ String accumulateStrn = attrs.getValue("accumulate");
1544+
1545+ if (accumulateStrn != null)
1546+ {
1547+ if (accumulateStrn.equals("replace")) this.accumulateType = AC_REPLACE;
1548+ if (accumulateStrn.equals("sum")) this.accumulateType = AC_SUM;
1549+ }
1550+ }
1551+
1552+ public String getAttribName() { return attribName; }
1553+ public int getAttribType() { return attribType; }
1554+ public int getAdditiveType() { return additiveType; }
1555+ public int getAccumulateType() { return accumulateType; }
1556+
1557+ public void evalParametric(AnimationTimeEval state, double curTime)
1558+ {
1559+ evalParametric(state, curTime, Double.NaN, Double.NaN);
1560+ }
1561+
1562+ /**
1563+ * Compares current time to start and end times and determines what degree
1564+ * of time interpolation this track currently represents. Returns
1565+ * Float.NaN if this track cannot be evaluated at the passed time (ie,
1566+ * it is before or past the end of the track, or it depends upon
1567+ * an unknown event)
1568+ * @param state - A structure that will be filled with information
1569+ * regarding the applicability of this animatoin element at the passed
1570+ * time.
1571+ * @param curTime - Current time in seconds
1572+ * @param repeatCount - Optional number of repetitions of length 'dur' to
1573+ * do. Set to Double.NaN to not consider this in the calculation.
1574+ * @param repeatDur - Optional amoun tof time to repeat the animaiton.
1575+ * Set to Double.NaN to not consider this in the calculation.
1576+ */
1577+ protected void evalParametric(AnimationTimeEval state, double curTime, double repeatCount, double repeatDur)
1578+ {
1579+ double begin = (beginTime == null) ? 0 : beginTime.evalTime();
1580+ if (Double.isNaN(begin) || begin > curTime)
1581+ {
1582+ state.set(Double.NaN, 0);
1583+ return;
1584+ }
1585+
1586+ double dur = (durTime == null) ? Double.NaN : durTime.evalTime();
1587+ if (Double.isNaN(dur))
1588+ {
1589+ state.set(Double.NaN, 0);
1590+ return;
1591+ }
1592+
1593+ //Determine end point of this animation
1594+ double end = (endTime == null) ? Double.NaN : endTime.evalTime();
1595+ double repeat;
1596+// if (Double.isNaN(repeatDur))
1597+// {
1598+// repeatDur = dur;
1599+// }
1600+ if (Double.isNaN(repeatCount) && Double.isNaN(repeatDur))
1601+ {
1602+ repeat = Double.NaN;
1603+ }
1604+ else
1605+ {
1606+ repeat = Math.min(
1607+ Double.isNaN(repeatCount) ? Double.POSITIVE_INFINITY : dur * repeatCount,
1608+ Double.isNaN(repeatDur) ? Double.POSITIVE_INFINITY : repeatDur);
1609+ }
1610+ if (Double.isNaN(repeat) && Double.isNaN(end))
1611+ {
1612+ //If neither and end point nor a repeat is specified, end point is
1613+ // implied by duration.
1614+ end = begin + dur;
1615+ }
1616+
1617+ double finishTime;
1618+ if (Double.isNaN(end))
1619+ {
1620+ finishTime = begin + repeat;
1621+ }
1622+ else if (Double.isNaN(repeat))
1623+ {
1624+ finishTime = end;
1625+ }
1626+ else
1627+ {
1628+ finishTime = Math.min(end, repeat);
1629+ }
1630+
1631+ double evalTime = Math.min(curTime, finishTime);
1632+// if (curTime > finishTime) evalTime = finishTime;
1633+
1634+
1635+// double evalTime = curTime;
1636+
1637+// boolean pastEnd = curTime > evalTime;
1638+
1639+// if (!Double.isNaN(end) && curTime > end) { pastEnd = true; evalTime = Math.min(evalTime, end); }
1640+// if (!Double.isNaN(repeat) && curTime > repeat) { pastEnd = true; evalTime = Math.min(evalTime, repeat); }
1641+
1642+ double ratio = (evalTime - begin) / dur;
1643+ int rep = (int)ratio;
1644+ double interp = ratio - rep;
1645+
1646+ //Adjust for roundoff
1647+ if (interp < 0.00001) interp = 0;
1648+
1649+// state.set(interp, rep);
1650+// if (!pastEnd)
1651+// {
1652+// state.set(interp, rep, false);
1653+// return;
1654+// }
1655+
1656+ //If we are still within the clip, return value
1657+ if (curTime == evalTime)
1658+ {
1659+ state.set(interp, rep);
1660+ return;
1661+ }
1662+
1663+ //We are past end of clip. Determine to clamp or ignore.
1664+ switch (fillType)
1665+ {
1666+ default:
1667+ case FT_REMOVE:
1668+ case FT_AUTO:
1669+ case FT_DEFAULT:
1670+ state.set(Double.NaN, rep);
1671+ return;
1672+ case FT_FREEZE:
1673+ case FT_HOLD:
1674+ case FT_TRANSITION:
1675+ state.set(interp == 0 ? 1 : interp, rep);
1676+ return;
1677+ }
1678+
1679+ }
1680+
1681+ double evalStartTime()
1682+ {
1683+ return beginTime == null ? Double.NaN : beginTime.evalTime();
1684+ }
1685+
1686+ double evalDurTime()
1687+ {
1688+ return durTime == null ? Double.NaN : durTime.evalTime();
1689+ }
1690+
1691+ /**
1692+ * Evaluates the ending time of this element. Returns 0 if not specified.
1693+ *
1694+ * @see hasEndTime
1695+ */
1696+ double evalEndTime()
1697+ {
1698+ return endTime == null ? Double.NaN : endTime.evalTime();
1699+ }
1700+
1701+ /**
1702+ * Checks to see if an end time has been specified for this element.
1703+ */
1704+ boolean hasEndTime() { return endTime != null; }
1705+
1706+ /**
1707+ * Updates all attributes in this diagram associated with a time event.
1708+ * Ie, all attributes with track information.
1709+ * @return - true if this node has changed state as a result of the time
1710+ * update
1711+ */
1712+ public boolean updateTime(double curTime)
1713+ {
1714+ //Animation elements to not change with time
1715+ return false;
1716+ }
1717+
1718+ public void rebuild() throws SVGException
1719+ {
1720+ AnimTimeParser animTimeParser = new AnimTimeParser(new StringReader(""));
1721+
1722+ rebuild(animTimeParser);
1723+ }
1724+
1725+ protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
1726+ {
1727+ StyleAttribute sty = new StyleAttribute();
1728+
1729+ if (getPres(sty.setName("begin")))
1730+ {
1731+ String newVal = sty.getStringValue();
1732+ animTimeParser.ReInit(new StringReader(newVal));
1733+ try {
1734+ this.beginTime = animTimeParser.Expr();
1735+ } catch (ParseException ex) {
1736+ ex.printStackTrace();
1737+ }
1738+ }
1739+
1740+ if (getPres(sty.setName("dur")))
1741+ {
1742+ String newVal = sty.getStringValue();
1743+ animTimeParser.ReInit(new StringReader(newVal));
1744+ try {
1745+ this.durTime = animTimeParser.Expr();
1746+ } catch (ParseException ex) {
1747+ ex.printStackTrace();
1748+ }
1749+ }
1750+
1751+ if (getPres(sty.setName("end")))
1752+ {
1753+ String newVal = sty.getStringValue();
1754+ animTimeParser.ReInit(new StringReader(newVal));
1755+ try {
1756+ this.endTime = animTimeParser.Expr();
1757+ } catch (ParseException ex) {
1758+ ex.printStackTrace();
1759+ }
1760+ }
1761+
1762+ if (getPres(sty.setName("fill")))
1763+ {
1764+ String newVal = sty.getStringValue();
1765+ if (newVal.equals("remove")) this.fillType = FT_REMOVE;
1766+ if (newVal.equals("freeze")) this.fillType = FT_FREEZE;
1767+ if (newVal.equals("hold")) this.fillType = FT_HOLD;
1768+ if (newVal.equals("transiton")) this.fillType = FT_TRANSITION;
1769+ if (newVal.equals("auto")) this.fillType = FT_AUTO;
1770+ if (newVal.equals("default")) this.fillType = FT_DEFAULT;
1771+ }
1772+
1773+ if (getPres(sty.setName("additive")))
1774+ {
1775+ String newVal = sty.getStringValue();
1776+ if (newVal.equals("replace")) this.additiveType = AD_REPLACE;
1777+ if (newVal.equals("sum")) this.additiveType = AD_SUM;
1778+ }
1779+
1780+ if (getPres(sty.setName("accumulate")))
1781+ {
1782+ String newVal = sty.getStringValue();
1783+ if (newVal.equals("replace")) this.accumulateType = AC_REPLACE;
1784+ if (newVal.equals("sum")) this.accumulateType = AC_SUM;
1785+ }
1786+
1787+ }
1788+}
1789Index: core/src/com/kitfox/svg/animation/AnimationTimeEval.java
[4256]1790===================================================================
[5284]1791--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1792+++ core/src/com/kitfox/svg/animation/AnimationTimeEval.java 2012-06-17 23:56:57.676545050 +0200
1793@@ -0,0 +1,65 @@
1794+/*
1795+ * AnimateTimeEval.java
1796+ *
1797+ * The Salamander Project - 2D and 3D graphics libraries in Java
1798+ * Copyright (C) 2004 Mark McKay
1799+ *
1800+ * This library is free software; you can redistribute it and/or
1801+ * modify it under the terms of the GNU Lesser General Public
1802+ * License as published by the Free Software Foundation; either
1803+ * version 2.1 of the License, or (at your option) any later version.
1804+ *
1805+ * This library is distributed in the hope that it will be useful,
1806+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1807+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1808+ * Lesser General Public License for more details.
1809+ *
1810+ * You should have received a copy of the GNU Lesser General Public
1811+ * License along with this library; if not, write to the Free Software
1812+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1813+ *
1814+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
1815+ * projects can be found at http://www.kitfox.com
1816+ *
1817+ *
1818+ * Created on September 21, 2004, 1:31 PM
1819+ */
1820+
1821+package com.kitfox.svg.animation;
1822+
1823+/**
1824+ *
1825+ * @author kitfox
1826+ */
1827+public class AnimationTimeEval
1828+{
1829+ /**
1830+ * Value on [0..1] representing the interpolation value of queried animation
1831+ * element, or Double.NaN if element does not provide a valid evalutaion
1832+ */
1833+ public double interp;
1834+
1835+ /**
1836+ * Number of completed repetitions
1837+ */
1838+ public int rep;
1839+
1840+ /**
1841+ * True if this evaluation is in a frozen state; ie, past the end of the
1842+ * track and held in the "freeze" state.
1843+ */
1844+// public boolean pastEnd;
1845+
1846+ /** Creates a new instance of AnimateTimeEval */
1847+ public AnimationTimeEval()
1848+ {
1849+ }
1850+
1851+// public void set(double interp, int rep, boolean pastEnd)
1852+ public void set(double interp, int rep)
1853+ {
1854+ this.interp = interp;
1855+ this.rep = rep;
1856+// this.pastEnd = pastEnd;
1857+ }
1858+}
1859Index: core/src/com/kitfox/svg/animation/Bezier.java
[4256]1860===================================================================
[5284]1861--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1862+++ core/src/com/kitfox/svg/animation/Bezier.java 2012-06-17 23:56:57.680545050 +0200
1863@@ -0,0 +1,201 @@
1864+/*
1865+ * Bezier.java
1866+ *
1867+
1868+ * The Salamander Project - 2D and 3D graphics libraries in Java
1869+ * Copyright (C) 2004 Mark McKay
1870+ *
1871+ * This library is free software; you can redistribute it and/or
1872+ * modify it under the terms of the GNU Lesser General Public
1873+ * License as published by the Free Software Foundation; either
1874+ * version 2.1 of the License, or (at your option) any later version.
1875+ *
1876+ * This library is distributed in the hope that it will be useful,
1877+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1878+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1879+ * Lesser General Public License for more details.
1880+ *
1881+ * You should have received a copy of the GNU Lesser General Public
1882+ * License along with this library; if not, write to the Free Software
1883+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1884+ *
1885+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
1886+ * projects can be found at http://www.kitfox.com
1887+ *
1888+ * Created on January 14, 2005, 4:08 AM
1889+ */
1890+
1891+package com.kitfox.svg.animation;
1892+
1893+import java.awt.geom.*;
1894+
1895+/**
1896+ * http://mathworld.wolfram.com/BezierCurve.html
1897+ * @author kitfox
1898+ */
1899+public class Bezier
1900+{
1901+ double length;
1902+ double[] coord;
1903+
1904+ public Bezier(double sx, double sy, double[] coords, int numCoords)
1905+ {
1906+ setCoords(sx, sy, coords, numCoords);
1907+ }
1908+
1909+ public void setCoords(double sx, double sy, double[] coords, int numCoords)
1910+ {
1911+ coord = new double[numCoords * 2 + 2];
1912+ coord[0] = sx;
1913+ coord[1] = sy;
1914+ for (int i = 0; i < numCoords; i++)
1915+ {
1916+ coord[i * 2 + 2] = coords[i * 2];
1917+ coord[i * 2 + 3] = coords[i * 2 + 1];
1918+ }
1919+
1920+ calcLength();
1921+ }
1922+
1923+ /**
1924+ * Retuns aproximation of the length of the bezier
1925+ */
1926+ public double getLength()
1927+ {
1928+ return length;
1929+ }
1930+
1931+ private void calcLength()
1932+ {
1933+ length = 0;
1934+ for (int i = 2; i < coord.length; i += 2)
1935+ {
1936+ length += lineLength(coord[i - 2], coord[i - 1], coord[i], coord[i + 1]);
1937+ }
1938+ }
1939+
1940+ private double lineLength(double x1, double y1, double x2, double y2)
1941+ {
1942+ double dx = x2 - x1, dy = y2 - y1;
1943+ return Math.sqrt(dx * dx + dy * dy);
1944+ }
1945+
1946+ public Point2D.Double getFinalPoint(Point2D.Double point)
1947+ {
1948+ point.x = coord[coord.length - 2];
1949+ point.y = coord[coord.length - 1];
1950+ return point;
1951+ }
1952+
1953+ public Point2D.Double eval(double param, Point2D.Double point)
1954+ {
1955+ point.x = 0;
1956+ point.y = 0;
1957+ int numKnots = coord.length / 2;
1958+
1959+ for (int i = 0; i < numKnots; i++)
1960+ {
1961+ double scale = bernstein(numKnots - 1, i, param);
1962+ point.x += coord[i * 2] * scale;
1963+ point.y += coord[i * 2 + 1] * scale;
1964+ }
1965+
1966+ return point;
1967+ }
1968+
1969+ /**
1970+ * Calculates the bernstein polynomial for evaluating parametric bezier
1971+ * @param numKnots - one less than number of knots in this curve hull
1972+ * @param knotNo - knot we are evaluating Bernstein for
1973+ * @param param - Parametric value we are evaluating at
1974+ */
1975+ private double bernstein(int numKnots, int knotNo, double param)
1976+ {
1977+ double iParam = 1 - param;
1978+ //Faster evaluation for easy cases:
1979+ switch (numKnots)
1980+ {
1981+ case 0:
1982+ return 1;
1983+ case 1:
1984+ {
1985+ switch (knotNo)
1986+ {
1987+ case 0:
1988+ return iParam;
1989+ case 1:
1990+ return param;
1991+ }
1992+ break;
1993+ }
1994+ case 2:
1995+ {
1996+ switch (knotNo)
1997+ {
1998+ case 0:
1999+ return iParam * iParam;
2000+ case 1:
2001+ return 2 * iParam * param;
2002+ case 2:
2003+ return param * param;
2004+ }
2005+ break;
2006+ }
2007+ case 3:
2008+ {
2009+ switch (knotNo)
2010+ {
2011+ case 0:
2012+ return iParam * iParam * iParam;
2013+ case 1:
2014+ return 3 * iParam * iParam * param;
2015+ case 2:
2016+ return 3 * iParam * param * param;
2017+ case 3:
2018+ return param * param * param;
2019+ }
2020+ break;
2021+ }
2022+ }
2023+
2024+ //If this bezier has more than four points, calculate bernstein the hard way
2025+ double retVal = 1;
2026+ for (int i = 0; i < knotNo; i++)
2027+ {
2028+ retVal *= param;
2029+ }
2030+ for (int i = 0; i < numKnots - knotNo; i++)
2031+ {
2032+ retVal *= iParam;
2033+ }
2034+ retVal *= choose(numKnots, knotNo);
2035+
2036+ return retVal;
2037+ }
2038+
2039+
2040+
2041+ private int choose(int num, int denom)
2042+ {
2043+ int denom2 = num - denom;
2044+ if (denom < denom2)
2045+ {
2046+ int tmp = denom;
2047+ denom = denom2;
2048+ denom2 = tmp;
2049+ }
2050+
2051+ int prod = 1;
2052+ for (int i = num; i > denom; i--)
2053+ {
2054+ prod *= num;
2055+ }
2056+
2057+ for (int i = 2; i <= denom2; i++)
2058+ {
2059+ prod /= i;
2060+ }
2061+
2062+ return prod;
2063+ }
2064+}
2065Index: core/src/com/kitfox/svg/animation/SetSmil.java
[4256]2066===================================================================
[5284]2067--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2068+++ core/src/com/kitfox/svg/animation/SetSmil.java 2012-06-17 23:56:57.680545050 +0200
2069@@ -0,0 +1,73 @@
2070+/*
2071+ * Set.java
2072+ *
2073+ * The Salamander Project - 2D and 3D graphics libraries in Java
2074+ * Copyright (C) 2004 Mark McKay
2075+ *
2076+ * This library is free software; you can redistribute it and/or
2077+ * modify it under the terms of the GNU Lesser General Public
2078+ * License as published by the Free Software Foundation; either
2079+ * version 2.1 of the License, or (at your option) any later version.
2080+ *
2081+ * This library is distributed in the hope that it will be useful,
2082+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2083+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2084+ * Lesser General Public License for more details.
2085+ *
2086+ * You should have received a copy of the GNU Lesser General Public
2087+ * License along with this library; if not, write to the Free Software
2088+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2089+ *
2090+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2091+ * projects can be found at http://www.kitfox.com
2092+ *
2093+ * Created on August 15, 2004, 2:51 AM
2094+ */
2095+
2096+package com.kitfox.svg.animation;
2097+
2098+import com.kitfox.svg.SVGElement;
2099+import com.kitfox.svg.SVGException;
2100+import com.kitfox.svg.SVGLoaderHelper;
2101+import com.kitfox.svg.animation.parser.AnimTimeParser;
2102+import com.kitfox.svg.xml.StyleAttribute;
2103+import org.xml.sax.Attributes;
2104+import org.xml.sax.SAXException;
2105+
2106+
2107+/**
2108+ * Set is used to set a textual value; most likely for a style element.
2109+ *
2110+ * @author Mark McKay
2111+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2112+ */
2113+public class SetSmil extends AnimationElement
2114+{
2115+ String toValue;
2116+
2117+ /** Creates a new instance of Set */
2118+ public SetSmil()
2119+ {
2120+ }
2121+
2122+ public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
2123+ {
2124+ //Load style string
2125+ super.loaderStartElement(helper, attrs, parent);
2126+
2127+ toValue = attrs.getValue("to");
2128+ }
2129+
2130+ protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
2131+ {
2132+ super.rebuild(animTimeParser);
2133+
2134+ StyleAttribute sty = new StyleAttribute();
2135+
2136+ if (getPres(sty.setName("to")))
2137+ {
2138+ String newVal = sty.getStringValue();
2139+ toValue = newVal;
2140+ }
2141+ }
2142+}
2143Index: core/src/com/kitfox/svg/animation/TimeBase.java
[4256]2144===================================================================
[5284]2145--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2146+++ core/src/com/kitfox/svg/animation/TimeBase.java 2012-06-17 23:56:57.680545050 +0200
2147@@ -0,0 +1,99 @@
2148+/*
2149+ * TimeBase.java
2150+ *
2151+ * The Salamander Project - 2D and 3D graphics libraries in Java
2152+ * Copyright (C) 2004 Mark McKay
2153+ *
2154+ * This library is free software; you can redistribute it and/or
2155+ * modify it under the terms of the GNU Lesser General Public
2156+ * License as published by the Free Software Foundation; either
2157+ * version 2.1 of the License, or (at your option) any later version.
2158+ *
2159+ * This library is distributed in the hope that it will be useful,
2160+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2161+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2162+ * Lesser General Public License for more details.
2163+ *
2164+ * You should have received a copy of the GNU Lesser General Public
2165+ * License along with this library; if not, write to the Free Software
2166+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2167+ *
2168+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2169+ * projects can be found at http://www.kitfox.com
2170+ *
2171+ * Created on August 15, 2004, 3:31 AM
2172+ */
2173+
2174+package com.kitfox.svg.animation;
2175+
2176+import java.util.regex.*;
2177+
2178+/**
2179+ * SVG has a complicated way of specifying time. Potentially, a time could
2180+ * be represened as a summation of discrete times and times of other animation
2181+ * events. This provides a root for the many elements we will need to define
2182+ * time.
2183+ *
2184+ * @author Mark McKay
2185+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2186+ */
2187+abstract public class TimeBase
2188+{
2189+ static final Matcher matchIndefinite = Pattern.compile("\\s*indefinite\\s*").matcher("");
2190+ static final Matcher matchUnitTime = Pattern.compile("\\s*([-+]?((\\d*\\.\\d+)|(\\d+))([-+]?[eE]\\d+)?)\\s*(h|min|s|ms)?\\s*").matcher("");
2191+
2192+ /*
2193+ public static TimeBase parseTime(String text)
2194+ {
2195+ if (text == null) return null;
2196+
2197+ if (text.indexOf('+') == -1)
2198+ {
2199+ return parseTimeComponent(text);
2200+ }
2201+
2202+ return new TimeCompound(text);
2203+ }
2204+ */
2205+
2206+ protected static TimeBase parseTimeComponent(String text)
2207+ {
2208+ matchIndefinite.reset(text);
2209+ if (matchIndefinite.matches()) return new TimeIndefinite();
2210+
2211+ matchUnitTime.reset(text);
2212+ if (matchUnitTime.matches())
2213+ {
2214+ String val = matchUnitTime.group(1);
2215+ String units = matchUnitTime.group(6);
2216+
2217+ double time = 0;
2218+ try { time = Double.parseDouble(val); }
2219+ catch (Exception e) {}
2220+
2221+ if (units.equals("ms")) time *= .001;
2222+ else if (units.equals("min")) time *= 60;
2223+ else if (units.equals("h")) time *= 3600;
2224+
2225+ return new TimeDiscrete(time);
2226+ }
2227+
2228+ return null;
2229+ }
2230+
2231+ /**
2232+ * Calculates the (greater than or equal to 0) time in seconds this
2233+ * time represents. If the time cannot be determined, returns
2234+ * Double.NaN. If this represents an infinte amount of time, returns
2235+ * Double.POSITIVE_INFINITY.
2236+ */
2237+ abstract public double evalTime();
2238+
2239+ /**
2240+ * Some time elements need to refer to the animation element that contains
2241+ * them to evaluate correctly
2242+ */
2243+ public void setParentElement(AnimationElement ele)
2244+ {
2245+ }
2246+}
2247Index: core/src/com/kitfox/svg/animation/TimeCompound.java
[4256]2248===================================================================
[5284]2249--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2250+++ core/src/com/kitfox/svg/animation/TimeCompound.java 2012-06-17 23:56:57.680545050 +0200
2251@@ -0,0 +1,84 @@
2252+/*
2253+ * TimeDiscrete.java
2254+ *
2255+ * The Salamander Project - 2D and 3D graphics libraries in Java
2256+ * Copyright (C) 2004 Mark McKay
2257+ *
2258+ * This library is free software; you can redistribute it and/or
2259+ * modify it under the terms of the GNU Lesser General Public
2260+ * License as published by the Free Software Foundation; either
2261+ * version 2.1 of the License, or (at your option) any later version.
2262+ *
2263+ * This library is distributed in the hope that it will be useful,
2264+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2265+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2266+ * Lesser General Public License for more details.
2267+ *
2268+ * You should have received a copy of the GNU Lesser General Public
2269+ * License along with this library; if not, write to the Free Software
2270+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2271+ *
2272+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2273+ * projects can be found at http://www.kitfox.com
2274+ *
2275+ * Created on August 15, 2004, 3:33 AM
2276+ */
2277+
2278+package com.kitfox.svg.animation;
2279+
2280+import java.util.Collections;
2281+import java.util.Iterator;
2282+import java.util.List;
2283+import java.util.regex.Pattern;
2284+
2285+
2286+/**
2287+ * This represents a summation of other time elements. It is used for complex
2288+ * timing events with offsets.
2289+ *
2290+ * @author Mark McKay
2291+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2292+ */
2293+public class TimeCompound extends TimeBase
2294+{
2295+ static final Pattern patPlus = Pattern.compile("\\+");
2296+
2297+ /**
2298+ * This is a list of times. This element's time is calculated as the greatest
2299+ * member that is less than the current time.
2300+ */
2301+ final List componentTimes;
2302+
2303+ private AnimationElement parent;
2304+
2305+ /** Creates a new instance of TimeDiscrete */
2306+ public TimeCompound(List timeBases)
2307+ {
2308+ componentTimes = Collections.unmodifiableList(timeBases);
2309+ }
2310+
2311+ public double evalTime()
2312+ {
2313+ double agg = 0.0;
2314+
2315+ for (Iterator it = componentTimes.iterator(); it.hasNext();)
2316+ {
2317+ TimeBase timeEle = (TimeBase)it.next();
2318+ double time = timeEle.evalTime();
2319+ agg += time;
2320+ }
2321+
2322+ return agg;
2323+ }
2324+
2325+ public void setParentElement(AnimationElement ele)
2326+ {
2327+ this.parent = ele;
2328+
2329+ for (Iterator it = componentTimes.iterator(); it.hasNext();)
2330+ {
2331+ TimeBase timeEle = (TimeBase)it.next();
2332+ timeEle.setParentElement(ele);
2333+ }
2334+ }
2335+}
2336Index: core/src/com/kitfox/svg/animation/TimeDiscrete.java
[4256]2337===================================================================
[5284]2338--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2339+++ core/src/com/kitfox/svg/animation/TimeDiscrete.java 2012-06-17 23:56:57.680545050 +0200
2340@@ -0,0 +1,51 @@
2341+/*
2342+ * TimeDiscrete.java
2343+ *
2344+ * The Salamander Project - 2D and 3D graphics libraries in Java
2345+ * Copyright (C) 2004 Mark McKay
2346+ *
2347+ * This library is free software; you can redistribute it and/or
2348+ * modify it under the terms of the GNU Lesser General Public
2349+ * License as published by the Free Software Foundation; either
2350+ * version 2.1 of the License, or (at your option) any later version.
2351+ *
2352+ * This library is distributed in the hope that it will be useful,
2353+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2354+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2355+ * Lesser General Public License for more details.
2356+ *
2357+ * You should have received a copy of the GNU Lesser General Public
2358+ * License along with this library; if not, write to the Free Software
2359+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2360+ *
2361+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2362+ * projects can be found at http://www.kitfox.com
2363+ *
2364+ * Created on August 15, 2004, 3:33 AM
2365+ */
2366+
2367+package com.kitfox.svg.animation;
2368+
2369+/**
2370+ * This is a time that represents a specific number of milliseconds
2371+ *
2372+ * @author Mark McKay
2373+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2374+ */
2375+public class TimeDiscrete extends TimeBase
2376+{
2377+ //Milliseconds of delay
2378+ double secs;
2379+
2380+ /** Creates a new instance of TimeDiscrete */
2381+ public TimeDiscrete(double secs)
2382+ {
2383+ this.secs = secs;
2384+ }
2385+
2386+ public double evalTime()
2387+ {
2388+ return secs;
2389+ }
2390+
2391+}
2392Index: core/src/com/kitfox/svg/animation/TimeIndefinite.java
[4256]2393===================================================================
[5284]2394--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2395+++ core/src/com/kitfox/svg/animation/TimeIndefinite.java 2012-06-17 23:56:57.680545050 +0200
2396@@ -0,0 +1,48 @@
2397+/*
2398+ * TimeDiscrete.java
2399+ *
2400+ * The Salamander Project - 2D and 3D graphics libraries in Java
2401+ * Copyright (C) 2004 Mark McKay
2402+ *
2403+ * This library is free software; you can redistribute it and/or
2404+ * modify it under the terms of the GNU Lesser General Public
2405+ * License as published by the Free Software Foundation; either
2406+ * version 2.1 of the License, or (at your option) any later version.
2407+ *
2408+ * This library is distributed in the hope that it will be useful,
2409+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2410+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2411+ * Lesser General Public License for more details.
2412+ *
2413+ * You should have received a copy of the GNU Lesser General Public
2414+ * License along with this library; if not, write to the Free Software
2415+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2416+ *
2417+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2418+ * projects can be found at http://www.kitfox.com
2419+ *
2420+ * Created on August 15, 2004, 3:33 AM
2421+ */
2422+
2423+package com.kitfox.svg.animation;
2424+
2425+/**
2426+ * This represents the indefinite (infinite) amount of time.
2427+ *
2428+ * @author Mark McKay
2429+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2430+ */
2431+public class TimeIndefinite extends TimeBase
2432+{
2433+
2434+ /** Creates a new instance of TimeDiscrete */
2435+ public TimeIndefinite()
2436+ {
2437+ }
2438+
2439+ public double evalTime()
2440+ {
2441+ return Double.POSITIVE_INFINITY;
2442+ }
2443+
2444+}
2445Index: core/src/com/kitfox/svg/animation/TimeLookup.java
[4256]2446===================================================================
[5284]2447--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2448+++ core/src/com/kitfox/svg/animation/TimeLookup.java 2012-06-17 23:56:57.684545050 +0200
2449@@ -0,0 +1,75 @@
2450+/*
2451+ * TimeDiscrete.java
2452+ *
2453+ * The Salamander Project - 2D and 3D graphics libraries in Java
2454+ * Copyright (C) 2004 Mark McKay
2455+ *
2456+ * This library is free software; you can redistribute it and/or
2457+ * modify it under the terms of the GNU Lesser General Public
2458+ * License as published by the Free Software Foundation; either
2459+ * version 2.1 of the License, or (at your option) any later version.
2460+ *
2461+ * This library is distributed in the hope that it will be useful,
2462+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2463+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2464+ * Lesser General Public License for more details.
2465+ *
2466+ * You should have received a copy of the GNU Lesser General Public
2467+ * License along with this library; if not, write to the Free Software
2468+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2469+ *
2470+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2471+ * projects can be found at http://www.kitfox.com
2472+ *
2473+ * Created on August 15, 2004, 3:33 AM
2474+ */
2475+
2476+package com.kitfox.svg.animation;
2477+
2478+/**
2479+ * This is a time that represents a specific number of milliseconds
2480+ *
2481+ * @author Mark McKay
2482+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2483+ */
2484+public class TimeLookup extends TimeBase
2485+{
2486+ /**
2487+ * This time can only be resolved in relation to it's parent
2488+ */
2489+ private AnimationElement parent;
2490+
2491+ /**
2492+ * Node this lookup acts upon
2493+ */
2494+ String node;
2495+
2496+ /**
2497+ * Event to evalutae on this node
2498+ */
2499+ String event;
2500+
2501+ /**
2502+ * Optional parameter used by some events
2503+ */
2504+ String paramList;
2505+
2506+ /** Creates a new instance of TimeDiscrete */
2507+ public TimeLookup(AnimationElement parent, String node, String event, String paramList)
2508+ {
2509+ this.parent = parent;
2510+ this.node = node;
2511+ this.event = event;
2512+ this.paramList = paramList;
2513+ }
2514+
2515+ public double evalTime()
2516+ {
2517+ return 0.0;
2518+ }
2519+
2520+ public void setParentElement(AnimationElement ele)
2521+ {
2522+ parent = ele;
2523+ }
2524+}
2525Index: core/src/com/kitfox/svg/animation/TimeSum.java
[4256]2526===================================================================
[5284]2527--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2528+++ core/src/com/kitfox/svg/animation/TimeSum.java 2012-06-17 23:56:57.684545050 +0200
2529@@ -0,0 +1,60 @@
2530+/*
2531+ * TimeDiscrete.java
2532+ *
2533+ * The Salamander Project - 2D and 3D graphics libraries in Java
2534+ * Copyright (C) 2004 Mark McKay
2535+ *
2536+ * This library is free software; you can redistribute it and/or
2537+ * modify it under the terms of the GNU Lesser General Public
2538+ * License as published by the Free Software Foundation; either
2539+ * version 2.1 of the License, or (at your option) any later version.
2540+ *
2541+ * This library is distributed in the hope that it will be useful,
2542+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2543+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2544+ * Lesser General Public License for more details.
2545+ *
2546+ * You should have received a copy of the GNU Lesser General Public
2547+ * License along with this library; if not, write to the Free Software
2548+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2549+ *
2550+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2551+ * projects can be found at http://www.kitfox.com
2552+ *
2553+ * Created on August 15, 2004, 3:33 AM
2554+ */
2555+
2556+package com.kitfox.svg.animation;
2557+
2558+/**
2559+ * This is a time that represents a specific number of milliseconds
2560+ *
2561+ * @author Mark McKay
2562+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2563+ */
2564+public class TimeSum extends TimeBase
2565+{
2566+ //Milliseconds of delay
2567+ TimeBase t1;
2568+ TimeBase t2;
2569+ boolean add;
2570+
2571+ /** Creates a new instance of TimeDiscrete */
2572+ public TimeSum(TimeBase t1, TimeBase t2, boolean add)
2573+ {
2574+ this.t1 = t1;
2575+ this.t2 = t2;
2576+ this.add = add;
2577+ }
2578+
2579+ public double evalTime()
2580+ {
2581+ return add ? t1.evalTime() + t2.evalTime() : t1.evalTime() - t2.evalTime();
2582+ }
2583+
2584+ public void setParentElement(AnimationElement ele)
2585+ {
2586+ t1.setParentElement(ele);
2587+ t2.setParentElement(ele);
2588+ }
2589+}
2590Index: core/src/com/kitfox/svg/animation/TrackBase.java
[4256]2591===================================================================
[5284]2592--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2593+++ core/src/com/kitfox/svg/animation/TrackBase.java 2012-06-17 23:56:57.684545050 +0200
2594@@ -0,0 +1,103 @@
2595+/*
2596+ * TrackManager.java
2597+ *
2598+ * The Salamander Project - 2D and 3D graphics libraries in Java
2599+ * Copyright (C) 2004 Mark McKay
2600+ *
2601+ * This library is free software; you can redistribute it and/or
2602+ * modify it under the terms of the GNU Lesser General Public
2603+ * License as published by the Free Software Foundation; either
2604+ * version 2.1 of the License, or (at your option) any later version.
2605+ *
2606+ * This library is distributed in the hope that it will be useful,
2607+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2608+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2609+ * Lesser General Public License for more details.
2610+ *
2611+ * You should have received a copy of the GNU Lesser General Public
2612+ * License along with this library; if not, write to the Free Software
2613+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2614+ *
2615+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2616+ * projects can be found at http://www.kitfox.com
2617+ *
2618+ * Created on August 15, 2004, 11:34 PM
2619+ */
2620+
2621+package com.kitfox.svg.animation;
2622+
2623+import java.util.*;
2624+
2625+import com.kitfox.svg.xml.*;
2626+import com.kitfox.svg.*;
2627+
2628+/**
2629+ * A track holds the animation events for a single parameter of a single SVG
2630+ * element. It also contains the default value for the element, should the
2631+ * user want to see the 'unanimated' value.
2632+ *
2633+ * @author Mark McKay
2634+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2635+ */
2636+abstract public class TrackBase
2637+{
2638+ protected final String attribName;
2639+ protected final int attribType; //AnimationElement.AT_*
2640+
2641+ /** Element we're animating */
2642+ protected final SVGElement parent;
2643+
2644+ //It doesn't make sense to sort this, since some events will depend on
2645+ // other events - in many cases, there will be no meaningful sorted order.
2646+ final ArrayList animEvents = new ArrayList();
2647+
2648+ /** Creates a new instance of TrackManager */
2649+// public TrackBase(SVGElement parent)
2650+// {
2651+// this(parent, "", AnimationElement.AT_AUTO);
2652+// }
2653+
2654+ /**
2655+ * Creates a track that would be valid for the name and type of element
2656+ * passed in. Does not actually add this elemnt to the track.
2657+ */
2658+ public TrackBase(SVGElement parent, AnimationElement ele) throws SVGElementException
2659+ {
2660+ this(parent, ele.getAttribName(), ele.getAttribType());
2661+ }
2662+
2663+ public TrackBase(SVGElement parent, String attribName, int attribType) throws SVGElementException
2664+ {
2665+ this.parent = parent;
2666+ this.attribName = attribName;
2667+ this.attribType = attribType;
2668+
2669+ //Make sure parent has an attribute we will write to
2670+ if (attribType == AnimationElement.AT_AUTO
2671+ && !parent.hasAttribute(attribName, AnimationElement.AT_CSS)
2672+ && !parent.hasAttribute(attribName, AnimationElement.AT_XML))
2673+ {
2674+ parent.addAttribute(attribName, AnimationElement.AT_CSS, "");
2675+ }
2676+ else if (!parent.hasAttribute(attribName, attribType))
2677+ {
2678+ parent.addAttribute(attribName, attribType, "");
2679+ }
2680+ }
2681+
2682+ public String getAttribName() { return attribName; }
2683+ public int getAttribType() { return attribType; }
2684+
2685+ public void addElement(AnimationElement ele)
2686+ {
2687+ animEvents.add(ele);
2688+ }
2689+
2690+ /**
2691+ * Returns a StyleAttribute representing the value of this track at the
2692+ * passed time. If this track does not apply, returns null.
2693+ * @return - True if successful, false if a value could not be obtained
2694+ */
2695+ abstract public boolean getValue(StyleAttribute attrib, double curTime) throws SVGException;
2696+
2697+}
2698Index: core/src/com/kitfox/svg/animation/TrackColor.java
[4256]2699===================================================================
[5284]2700--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2701+++ core/src/com/kitfox/svg/animation/TrackColor.java 2012-06-17 23:56:57.684545050 +0200
2702@@ -0,0 +1,95 @@
2703+/*
2704+ * TrackManager.java
2705+ *
2706+ * The Salamander Project - 2D and 3D graphics libraries in Java
2707+ * Copyright (C) 2004 Mark McKay
2708+ *
2709+ * This library is free software; you can redistribute it and/or
2710+ * modify it under the terms of the GNU Lesser General Public
2711+ * License as published by the Free Software Foundation; either
2712+ * version 2.1 of the License, or (at your option) any later version.
2713+ *
2714+ * This library is distributed in the hope that it will be useful,
2715+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2716+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2717+ * Lesser General Public License for more details.
2718+ *
2719+ * You should have received a copy of the GNU Lesser General Public
2720+ * License along with this library; if not, write to the Free Software
2721+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2722+ *
2723+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2724+ * projects can be found at http://www.kitfox.com
2725+ *
2726+ * Created on September 21, 2004, 11:34 PM
2727+ */
2728+
2729+package com.kitfox.svg.animation;
2730+
2731+import com.kitfox.svg.xml.StyleAttribute;
2732+import java.awt.*;
2733+import java.util.*;
2734+
2735+import com.kitfox.svg.*;
2736+import com.kitfox.svg.xml.*;
2737+
2738+/**
2739+ * A track holds the animation events for a single parameter of a single SVG
2740+ * element. It also contains the default value for the element, should the
2741+ * user want to see the 'unanimated' value.
2742+ *
2743+ * @author Mark McKay
2744+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2745+ */
2746+public class TrackColor extends TrackBase
2747+{
2748+
2749+ public TrackColor(AnimationElement ele) throws SVGElementException
2750+ {
2751+ super(ele.getParent(), ele);
2752+ }
2753+
2754+ public boolean getValue(StyleAttribute attrib, double curTime)
2755+ {
2756+ Color col = getValue(curTime);
2757+ if (col == null) return false;
2758+
2759+ attrib.setStringValue("#" + Integer.toHexString(col.getRGB()));
2760+ return true;
2761+ }
2762+
2763+ public Color getValue(double curTime)
2764+ {
2765+ Color retVal = null;
2766+ AnimationTimeEval state = new AnimationTimeEval();
2767+
2768+ for (Iterator it = animEvents.iterator(); it.hasNext();)
2769+ {
2770+ AnimateBase ele = (AnimateBase)it.next();
2771+ AnimateColorIface eleColor = (AnimateColorIface)ele;
2772+ ele.evalParametric(state, curTime);
2773+
2774+ //Reject value if it is in the invalid state
2775+ if (Double.isNaN(state.interp)) continue;
2776+
2777+ if (retVal == null)
2778+ {
2779+ retVal = eleColor.evalColor(state.interp);
2780+ continue;
2781+ }
2782+
2783+ Color curCol = eleColor.evalColor(state.interp);
2784+ switch (ele.getAdditiveType())
2785+ {
2786+ case AnimationElement.AD_REPLACE:
2787+ retVal = curCol;
2788+ break;
2789+ case AnimationElement.AD_SUM:
2790+ retVal = new Color(curCol.getRed() + retVal.getRed(), curCol.getGreen() + retVal.getGreen(), curCol.getBlue() + retVal.getBlue());
2791+ break;
2792+ }
2793+ }
2794+
2795+ return retVal;
2796+ }
2797+}
2798Index: core/src/com/kitfox/svg/animation/TrackDouble.java
[4256]2799===================================================================
[5284]2800--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2801+++ core/src/com/kitfox/svg/animation/TrackDouble.java 2012-06-17 23:56:57.684545050 +0200
2802@@ -0,0 +1,119 @@
2803+/*
2804+ * TrackManager.java
2805+ *
2806+ * The Salamander Project - 2D and 3D graphics libraries in Java
2807+ * Copyright (C) 2004 Mark McKay
2808+ *
2809+ * This library is free software; you can redistribute it and/or
2810+ * modify it under the terms of the GNU Lesser General Public
2811+ * License as published by the Free Software Foundation; either
2812+ * version 2.1 of the License, or (at your option) any later version.
2813+ *
2814+ * This library is distributed in the hope that it will be useful,
2815+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2816+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2817+ * Lesser General Public License for more details.
2818+ *
2819+ * You should have received a copy of the GNU Lesser General Public
2820+ * License along with this library; if not, write to the Free Software
2821+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2822+ *
2823+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2824+ * projects can be found at http://www.kitfox.com
2825+ *
2826+ * Created on August 15, 2004, 11:34 PM
2827+ */
2828+
2829+package com.kitfox.svg.animation;
2830+
2831+import com.kitfox.svg.xml.StyleAttribute;
2832+import java.util.*;
2833+
2834+import com.kitfox.svg.*;
2835+import com.kitfox.svg.xml.*;
2836+
2837+/**
2838+ * A track holds the animation events for a single parameter of a single SVG
2839+ * element. It also contains the default value for the element, should the
2840+ * user want to see the 'unanimated' value.
2841+ *
2842+ * @author Mark McKay
2843+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2844+ */
2845+public class TrackDouble extends TrackBase
2846+{
2847+ public TrackDouble(AnimationElement ele) throws SVGElementException
2848+ {
2849+ super(ele.getParent(), ele);
2850+ }
2851+
2852+ public boolean getValue(StyleAttribute attrib, double curTime)
2853+ {
2854+ double val = getValue(curTime);
2855+ if (Double.isNaN(val)) return false;
2856+
2857+ attrib.setStringValue("" + val);
2858+ return true;
2859+ }
2860+
2861+ public double getValue(double curTime)
2862+ {
2863+ double retVal = Double.NaN;
2864+
2865+ StyleAttribute attr = null;
2866+ switch (attribType)
2867+ {
2868+ case AnimationElement.AT_CSS:
2869+ attr = parent.getStyleAbsolute(attribName);
2870+ retVal = attr.getDoubleValue();
2871+ break;
2872+ case AnimationElement.AT_XML:
2873+ attr = parent.getPresAbsolute(attribName);
2874+ retVal = attr.getDoubleValue();
2875+ break;
2876+ case AnimationElement.AT_AUTO:
2877+ attr = parent.getStyleAbsolute(attribName);
2878+ if (attr == null) attr = parent.getPresAbsolute(attribName);
2879+ retVal = attr.getDoubleValue();
2880+ break;
2881+ }
2882+
2883+
2884+
2885+ AnimationTimeEval state = new AnimationTimeEval();
2886+// boolean pastEnd = true;
2887+
2888+ for (Iterator it = animEvents.iterator(); it.hasNext();)
2889+ {
2890+ Animate ele = (Animate)it.next();
2891+ ele.evalParametric(state, curTime);
2892+
2893+ //Go to next element if this one does not affect processing
2894+ if (Double.isNaN(state.interp)) continue;
2895+
2896+ switch (ele.getAdditiveType())
2897+ {
2898+ case AnimationElement.AD_SUM:
2899+ retVal += ele.eval(state.interp);
2900+ break;
2901+ case AnimationElement.AD_REPLACE:
2902+ retVal = ele.eval(state.interp);
2903+ break;
2904+ }
2905+
2906+ //Evalutae accumulation if applicable
2907+ if (state.rep > 0)
2908+ {
2909+ switch (ele.getAccumulateType())
2910+ {
2911+ case AnimationElement.AC_SUM:
2912+ retVal += ele.repeatSkipSize(state.rep);
2913+ break;
2914+ }
2915+
2916+ }
2917+ }
2918+
2919+ return retVal;
2920+ }
2921+}
2922Index: core/src/com/kitfox/svg/animation/TrackManager.java
[4256]2923===================================================================
[5284]2924--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2925+++ core/src/com/kitfox/svg/animation/TrackManager.java 2012-06-17 23:56:57.684545050 +0200
2926@@ -0,0 +1,153 @@
2927+/*
2928+ * TrackManager.java
2929+ *
2930+ * The Salamander Project - 2D and 3D graphics libraries in Java
2931+ * Copyright (C) 2004 Mark McKay
2932+ *
2933+ * This library is free software; you can redistribute it and/or
2934+ * modify it under the terms of the GNU Lesser General Public
2935+ * License as published by the Free Software Foundation; either
2936+ * version 2.1 of the License, or (at your option) any later version.
2937+ *
2938+ * This library is distributed in the hope that it will be useful,
2939+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2940+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2941+ * Lesser General Public License for more details.
2942+ *
2943+ * You should have received a copy of the GNU Lesser General Public
2944+ * License along with this library; if not, write to the Free Software
2945+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2946+ *
2947+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
2948+ * projects can be found at http://www.kitfox.com
2949+ *
2950+ * Created on August 15, 2004, 11:34 PM
2951+ */
2952+
2953+package com.kitfox.svg.animation;
2954+
2955+import java.util.*;
2956+
2957+import com.kitfox.svg.*;
2958+import java.io.Serializable;
2959+
2960+/**
2961+ * Every element contains tracks, which manage the animation. There is one track
2962+ * for every parameter with animation, and each track in turn is composed of
2963+ * many events.
2964+ *
2965+ * @author Mark McKay
2966+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
2967+ */
2968+public class TrackManager implements Serializable
2969+{
2970+ public static final long serialVersionUID = 0;
2971+
2972+ static class TrackKey
2973+ {
2974+ String name;
2975+ int type;
2976+
2977+ TrackKey(AnimationElement base)
2978+ {
2979+ this(base.getAttribName(), base.getAttribType());
2980+ }
2981+
2982+ TrackKey(String name, int type)
2983+ {
2984+ this.name = name;
2985+ this.type = type;
2986+ }
2987+
2988+ public int hashCode() { return name.hashCode() ^ type; }
2989+ public boolean equals(Object obj)
2990+ {
2991+ if (!(obj instanceof TrackKey)) return false;
2992+ TrackKey key = (TrackKey)obj;
2993+ return key.type == type && key.name.equals(name);
2994+ }
2995+ }
2996+
2997+ HashMap tracks = new HashMap();
2998+
2999+ /** Creates a new instance of TrackManager */
3000+ public TrackManager()
3001+ {
3002+ }
3003+
3004+ /**
3005+ * Adds a new animation element to this track
3006+ */
3007+ public void addTrackElement(AnimationElement element) throws SVGElementException
3008+ {
3009+ TrackKey key = new TrackKey(element);
3010+
3011+ TrackBase track = (TrackBase)tracks.get(key);
3012+
3013+ if (track == null)
3014+ {
3015+ //Create a track for this element
3016+ if (element instanceof Animate)
3017+ {
3018+ switch (((Animate)element).getDataType())
3019+ {
3020+ case Animate.DT_REAL:
3021+ track = new TrackDouble(element);
3022+ break;
3023+ case Animate.DT_COLOR:
3024+ track = new TrackColor(element);
3025+ break;
3026+ case Animate.DT_PATH:
3027+ track = new TrackPath(element);
3028+ break;
3029+ default:
3030+ throw new RuntimeException("");
3031+ }
3032+ }
3033+ else if (element instanceof AnimateColor)
3034+ {
3035+ track = new TrackColor(element);
3036+ }
3037+ else if (element instanceof AnimateTransform || element instanceof AnimateMotion)
3038+ {
3039+ track = new TrackTransform(element);
3040+ }
3041+
3042+ tracks.put(key, track);
3043+ }
3044+
3045+ track.addElement(element);
3046+ }
3047+
3048+ public TrackBase getTrack(String name, int type)
3049+ {
3050+ //Handle AUTO, which will match either CSS or XML (in that order)
3051+ if (type == AnimationElement.AT_AUTO)
3052+ {
3053+ TrackBase t = getTrack(name, AnimationElement.AT_CSS);
3054+ if (t != null) return t;
3055+ t = getTrack(name, AnimationElement.AT_XML);
3056+ if (t != null) return t;
3057+ return null;
3058+ }
3059+
3060+ //Get requested attribute
3061+ TrackKey key = new TrackKey(name, type);
3062+ TrackBase t = (TrackBase)tracks.get(key);
3063+ if (t != null) return t;
3064+
3065+ //If that didn't exist, see if one exists of type AUTO
3066+ key = new TrackKey(name, AnimationElement.AT_AUTO);
3067+ return (TrackBase)tracks.get(key);
3068+ }
3069+
3070+ public int getNumTracks()
3071+ {
3072+ return tracks.size();
3073+ }
3074+
3075+ public Iterator iterator()
3076+ {
3077+ return tracks.values().iterator();
3078+ }
3079+}
3080Index: core/src/com/kitfox/svg/animation/TrackMotion.java
[4256]3081===================================================================
[5284]3082--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3083+++ core/src/com/kitfox/svg/animation/TrackMotion.java 2012-06-17 23:56:57.684545050 +0200
3084@@ -0,0 +1,128 @@
3085+/*
3086+ * TrackManager.java
3087+ *
3088+ * The Salamander Project - 2D and 3D graphics libraries in Java
3089+ * Copyright (C) 2004 Mark McKay
3090+ *
3091+ * This library is free software; you can redistribute it and/or
3092+ * modify it under the terms of the GNU Lesser General Public
3093+ * License as published by the Free Software Foundation; either
3094+ * version 2.1 of the License, or (at your option) any later version.
3095+ *
3096+ * This library is distributed in the hope that it will be useful,
3097+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3098+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3099+ * Lesser General Public License for more details.
3100+ *
3101+ * You should have received a copy of the GNU Lesser General Public
3102+ * License along with this library; if not, write to the Free Software
3103+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3104+ *
3105+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
3106+ * projects can be found at http://www.kitfox.com
3107+ *
3108+ * Created on September 21, 2004, 11:34 PM
3109+ */
3110+
3111+package com.kitfox.svg.animation;
3112+
3113+import com.kitfox.svg.xml.StyleAttribute;
3114+import java.awt.geom.*;
3115+import java.util.*;
3116+
3117+import com.kitfox.svg.*;
3118+import com.kitfox.svg.xml.*;
3119+
3120+/**
3121+ * A track holds the animation events for a single parameter of a single SVG
3122+ * element. It also contains the default value for the element, should the
3123+ * user want to see the 'unanimated' value.
3124+ *
3125+ * @author Mark McKay
3126+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
3127+ */
3128+public class TrackMotion extends TrackBase
3129+{
3130+ public TrackMotion(AnimationElement ele) throws SVGElementException
3131+ {
3132+ //The motion element implies a CSS attribute of transform
3133+// super(ele.getParent(), "transform", AnimationElement.AT_CSS);
3134+ super(ele.getParent(), ele);
3135+ }
3136+
3137+ public boolean getValue(StyleAttribute attrib, double curTime) throws SVGException
3138+ {
3139+ AffineTransform retVal = new AffineTransform();
3140+ retVal = getValue(retVal, curTime);
3141+// AffineTransform val = getValue(curTime);
3142+// if (val == null) return false;
3143+
3144+ double[] mat = new double[6];
3145+ retVal.getMatrix(mat);
3146+ attrib.setStringValue("matrix(" + mat[0] + " " + mat[1] + " " + mat[2] + " " + mat[3] + " " + mat[4] + " " + mat[5] + ")");
3147+ return true;
3148+ }
3149+
3150+ public AffineTransform getValue(AffineTransform retVal, double curTime) throws SVGException
3151+ {
3152+ //Init transform with default state
3153+ StyleAttribute attr = null;
3154+ switch (attribType)
3155+ {
3156+ case AnimationElement.AT_CSS:
3157+ attr = parent.getStyleAbsolute(attribName);
3158+ retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
3159+ break;
3160+ case AnimationElement.AT_XML:
3161+ attr = parent.getPresAbsolute(attribName);
3162+ retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
3163+ break;
3164+ case AnimationElement.AT_AUTO:
3165+ attr = parent.getStyleAbsolute(attribName);
3166+ if (attr == null) attr = parent.getPresAbsolute(attribName);
3167+ retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
3168+ break;
3169+ }
3170+
3171+
3172+ //Update transform with time based information
3173+ AnimationTimeEval state = new AnimationTimeEval();
3174+ AffineTransform xform = new AffineTransform();
3175+// boolean pastEnd = true;
3176+
3177+ for (Iterator it = animEvents.iterator(); it.hasNext();)
3178+ {
3179+ AnimateMotion ele = (AnimateMotion)it.next();
3180+ ele.evalParametric(state, curTime);
3181+
3182+ //Go to next element if this one does not affect processing
3183+ if (Double.isNaN(state.interp)) continue;
3184+
3185+ switch (ele.getAdditiveType())
3186+ {
3187+ case AnimationElement.AD_SUM:
3188+ retVal.concatenate(ele.eval(xform, state.interp));
3189+ break;
3190+ case AnimationElement.AD_REPLACE:
3191+ retVal.setTransform(ele.eval(xform, state.interp));
3192+ break;
3193+ }
3194+
3195+ //Evaluate accumulation if applicable
3196+/*
3197+ if (state.rep > 0)
3198+ {
3199+ switch (ele.getAccumulateType())
3200+ {
3201+ case AnimationElement.AC_SUM:
3202+ retVal += ele.repeatSkipSize(state.rep);
3203+ break;
3204+ }
3205+
3206+ }
3207+*/
3208+ }
3209+
3210+ return retVal;
3211+ }
3212+}
3213Index: core/src/com/kitfox/svg/animation/TrackPath.java
[4256]3214===================================================================
[5284]3215--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3216+++ core/src/com/kitfox/svg/animation/TrackPath.java 2012-06-17 23:56:57.684545050 +0200
3217@@ -0,0 +1,100 @@
3218+/*
3219+ * TrackManager.java
3220+ *
3221+ * The Salamander Project - 2D and 3D graphics libraries in Java
3222+ * Copyright (C) 2004 Mark McKay
3223+ *
3224+ * This library is free software; you can redistribute it and/or
3225+ * modify it under the terms of the GNU Lesser General Public
3226+ * License as published by the Free Software Foundation; either
3227+ * version 2.1 of the License, or (at your option) any later version.
3228+ *
3229+ * This library is distributed in the hope that it will be useful,
3230+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3231+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3232+ * Lesser General Public License for more details.
3233+ *
3234+ * You should have received a copy of the GNU Lesser General Public
3235+ * License along with this library; if not, write to the Free Software
3236+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3237+ *
3238+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
3239+ * projects can be found at http://www.kitfox.com
3240+ *
3241+ * Created on September 21, 2004, 11:34 PM
3242+ */
3243+
3244+package com.kitfox.svg.animation;
3245+
3246+import com.kitfox.svg.xml.StyleAttribute;
3247+import java.awt.*;
3248+import java.awt.geom.*;
3249+import java.util.*;
3250+
3251+import com.kitfox.svg.pathcmd.*;
3252+import com.kitfox.svg.*;
3253+import com.kitfox.svg.xml.*;
3254+
3255+/**
3256+ * A track holds the animation events for a single parameter of a single SVG
3257+ * element. It also contains the default value for the element, should the
3258+ * user want to see the 'unanimated' value.
3259+ *
3260+ * @author Mark McKay
3261+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
3262+ */
3263+public class TrackPath extends TrackBase
3264+{
3265+
3266+ public TrackPath(AnimationElement ele) throws SVGElementException
3267+ {
3268+ super(ele.getParent(), ele);
3269+ }
3270+
3271+ public boolean getValue(StyleAttribute attrib, double curTime)
3272+ {
3273+ GeneralPath path = getValue(curTime);
3274+ if (path == null) return false;
3275+
3276+ attrib.setStringValue(PathUtil.buildPathString(path));
3277+ return true;
3278+ }
3279+
3280+ public GeneralPath getValue(double curTime)
3281+ {
3282+ GeneralPath retVal = null;
3283+ AnimationTimeEval state = new AnimationTimeEval();
3284+
3285+ for (Iterator it = animEvents.iterator(); it.hasNext();)
3286+ {
3287+ AnimateBase ele = (AnimateBase)it.next();
3288+ Animate eleAnim = (Animate)ele;
3289+ ele.evalParametric(state, curTime);
3290+
3291+ //Reject value if it is in the invalid state
3292+ if (Double.isNaN(state.interp)) continue;
3293+
3294+ if (retVal == null)
3295+ {
3296+ retVal = eleAnim.evalPath(state.interp);
3297+ continue;
3298+ }
3299+
3300+ GeneralPath curPath = eleAnim.evalPath(state.interp);
3301+ switch (ele.getAdditiveType())
3302+ {
3303+ case AnimationElement.AD_REPLACE:
3304+ retVal = curPath;
3305+ break;
3306+ case AnimationElement.AD_SUM:
3307+ throw new RuntimeException("Not implemented");
3308+// retVal = new Color(curCol.getRed() + retVal.getRed(), curCol.getGreen() + retVal.getGreen(), curCol.getBlue() + retVal.getBlue());
3309+// break;
3310+ default:
3311+ throw new RuntimeException();
3312+ }
3313+ }
3314+
3315+ return retVal;
3316+ }
3317+}
3318Index: core/src/com/kitfox/svg/animation/TrackTransform.java
[4256]3319===================================================================
[5284]3320--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3321+++ core/src/com/kitfox/svg/animation/TrackTransform.java 2012-06-17 23:56:57.684545050 +0200
3322@@ -0,0 +1,112 @@
3323+/*
3324+ * TrackManager.java
3325+ *
3326+ * The Salamander Project - 2D and 3D graphics libraries in Java
3327+ * Copyright (C) 2004 Mark McKay
3328+ *
3329+ * This library is free software; you can redistribute it and/or
3330+ * modify it under the terms of the GNU Lesser General Public
3331+ * License as published by the Free Software Foundation; either
3332+ * version 2.1 of the License, or (at your option) any later version.
3333+ *
3334+ * This library is distributed in the hope that it will be useful,
3335+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3336+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3337+ * Lesser General Public License for more details.
3338+ *
3339+ * You should have received a copy of the GNU Lesser General Public
3340+ * License along with this library; if not, write to the Free Software
3341+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3342+ *
3343+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
3344+ * projects can be found at http://www.kitfox.com
3345+ *
3346+ * Created on September 21, 2004, 11:34 PM
3347+ */
3348+
3349+package com.kitfox.svg.animation;
3350+
3351+import com.kitfox.svg.xml.StyleAttribute;
3352+import java.awt.geom.*;
3353+import java.util.*;
3354+
3355+import com.kitfox.svg.*;
3356+import com.kitfox.svg.xml.*;
3357+
3358+/**
3359+ * A track holds the animation events for a single parameter of a single SVG
3360+ * element. It also contains the default value for the element, should the
3361+ * user want to see the 'unanimated' value.
3362+ *
3363+ * @author Mark McKay
3364+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
3365+ */
3366+public class TrackTransform extends TrackBase
3367+{
3368+ public TrackTransform(AnimationElement ele) throws SVGElementException
3369+ {
3370+ super(ele.getParent(), ele);
3371+ }
3372+
3373+ public boolean getValue(StyleAttribute attrib, double curTime) throws SVGException
3374+ {
3375+ AffineTransform retVal = new AffineTransform();
3376+ retVal = getValue(retVal, curTime);
3377+// AffineTransform val = getValue(curTime);
3378+// if (val == null) return false;
3379+
3380+ double[] mat = new double[6];
3381+ retVal.getMatrix(mat);
3382+ attrib.setStringValue("matrix(" + mat[0] + " " + mat[1] + " " + mat[2] + " " + mat[3] + " " + mat[4] + " " + mat[5] + ")");
3383+ return true;
3384+ }
3385+
3386+ public AffineTransform getValue(AffineTransform retVal, double curTime) throws SVGException
3387+ {
3388+ //Init transform with default state
3389+ StyleAttribute attr = null;
3390+ switch (attribType)
3391+ {
3392+ case AnimationElement.AT_CSS:
3393+ attr = parent.getStyleAbsolute(attribName);
3394+ retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
3395+ break;
3396+ case AnimationElement.AT_XML:
3397+ attr = parent.getPresAbsolute(attribName);
3398+ retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
3399+ break;
3400+ case AnimationElement.AT_AUTO:
3401+ attr = parent.getStyleAbsolute(attribName);
3402+ if (attr == null) attr = parent.getPresAbsolute(attribName);
3403+ retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
3404+ break;
3405+ }
3406+
3407+
3408+ //Update transform with time based information
3409+ AnimationTimeEval state = new AnimationTimeEval();
3410+ AffineTransform xform = new AffineTransform();
3411+
3412+ for (Iterator it = animEvents.iterator(); it.hasNext();)
3413+ {
3414+ AnimateXform ele = (AnimateXform)it.next();
3415+ ele.evalParametric(state, curTime);
3416+
3417+ //Go to next element if this one does not affect processing
3418+ if (Double.isNaN(state.interp)) continue;
3419+
3420+ switch (ele.getAdditiveType())
3421+ {
3422+ case AnimationElement.AD_SUM:
3423+ retVal.concatenate(ele.eval(xform, state.interp));
3424+ break;
3425+ case AnimationElement.AD_REPLACE:
3426+ retVal.setTransform(ele.eval(xform, state.interp));
3427+ break;
3428+ }
3429+
3430+ }
3431+
3432+ return retVal;
3433+ }
3434+}
3435Index: core/src/com/kitfox/svg/SVGElement.java
[4256]3436===================================================================
[5284]3437--- core.orig/src/com/kitfox/svg/SVGElement.java 2012-05-11 17:03:52.404311564 +0200
3438+++ core/src/com/kitfox/svg/SVGElement.java 2012-06-17 23:56:57.732545052 +0200
3439@@ -33,6 +33,7 @@
[4256]3440 import java.awt.geom.*;
3441
3442 import org.xml.sax.*;
[5284]3443+import com.kitfox.svg.animation.*;
[4256]3444 import com.kitfox.svg.pathcmd.*;
3445 import com.kitfox.svg.xml.*;
3446 import java.io.Serializable;
[5284]3447@@ -100,6 +101,8 @@
[4256]3448 */
3449 // protected SVGUniverse universe;
3450
[5284]3451+ protected final TrackManager trackManager = new TrackManager();
3452+
[4256]3453 boolean dirty = true;
3454
3455 // public static final Matcher adobeId = Pattern.compile("(.*)_1_").matcher("");
[5284]3456@@ -265,6 +268,46 @@
[4256]3457 }
3458 }
3459
[5284]3460+ public void addAttribute(String name, int attribType, String value) throws SVGElementException
3461+ {
3462+ if (hasAttribute(name, attribType)) throw new SVGElementException(this, "Attribute " + name + "(" + AnimationElement.animationElementToString(attribType) + ") already exists");
3463+
3464+ //Alter layout for id attribute
3465+ if ("id".equals(name) && diagram != null)
3466+ {
3467+ diagram.removeElement(this.id);
3468+ this.id = name;
3469+ diagram.setElement(this.id, this);
3470+ }
3471+
3472+ switch (attribType)
3473+ {
3474+ case AnimationElement.AT_CSS:
3475+ inlineStyles.put(name, new StyleAttribute(name, value));
3476+ return;
3477+ case AnimationElement.AT_XML:
3478+ presAttribs.put(name, new StyleAttribute(name, value));
3479+ return;
3480+ }
3481+
3482+ throw new SVGElementException(this, "Invalid attribute type " + attribType);
3483+ }
3484+
3485+ public boolean hasAttribute(String name, int attribType) throws SVGElementException
3486+ {
3487+ switch (attribType)
3488+ {
3489+ case AnimationElement.AT_CSS:
3490+ return inlineStyles.containsKey(name);
3491+ case AnimationElement.AT_XML:
3492+ return presAttribs.containsKey(name);
3493+ case AnimationElement.AT_AUTO:
3494+ return inlineStyles.containsKey(name) || presAttribs.containsKey(name);
3495+ }
3496+
3497+ throw new SVGElementException(this, "Invalid attribute type " + attribType);
3498+ }
3499+
[4256]3500 /**
3501 * @return a set of Strings that corespond to CSS attributes on this element
3502 */
[5284]3503@@ -290,6 +333,12 @@
[4256]3504 children.add(child);
3505 child.parent = this;
3506 child.setDiagram(diagram);
[5284]3507+
3508+ //Add info to track if we've scanned animation element
3509+ if (child instanceof AnimationElement)
3510+ {
3511+ trackManager.addTrackElement((AnimationElement)child);
3512+ }
[4256]3513 }
3514
3515 private void setDiagram(SVGDiagram diagram)
[5284]3516@@ -408,6 +457,54 @@
[4256]3517 return getStyle(attrib, true);
3518 }
3519
[5284]3520+
3521+ public void setAttribute(String name, int attribType, String value) throws SVGElementException
3522+ {
3523+ StyleAttribute styAttr;
3524+
3525+
3526+ switch (attribType)
3527+ {
3528+ case AnimationElement.AT_CSS:
3529+ {
3530+ styAttr = (StyleAttribute)inlineStyles.get(name);
3531+ break;
3532+ }
3533+ case AnimationElement.AT_XML:
3534+ {
3535+ styAttr = (StyleAttribute)presAttribs.get(name);
3536+ break;
3537+ }
3538+ case AnimationElement.AT_AUTO:
3539+ {
3540+ styAttr = (StyleAttribute)inlineStyles.get(name);
3541+
3542+ if (styAttr == null)
3543+ {
3544+ styAttr = (StyleAttribute)presAttribs.get(name);
3545+ }
3546+ break;
3547+ }
3548+ default:
3549+ throw new SVGElementException(this, "Invalid attribute type " + attribType);
3550+ }
3551+
3552+ if (styAttr == null)
3553+ {
3554+ throw new SVGElementException(this, "Could not find attribute " + name + "(" + AnimationElement.animationElementToString(attribType) + "). Make sure to create attribute before setting it.");
3555+ }
3556+
3557+ //Alter layout for relevant attributes
3558+ if ("id".equals(styAttr.getName()))
3559+ {
3560+ diagram.removeElement(this.id);
3561+ this.id = name;
3562+ diagram.setElement(this.id, this);
3563+ }
3564+
3565+ styAttr.setStringValue(value);
3566+ }
3567+
[4256]3568 /**
3569 * Copies the current style into the passed style attribute. Checks for
3570 * inline styles first, then internal and extranal style sheets, and
[5284]3571@@ -427,6 +524,14 @@
[4256]3572
3573 attrib.setStringValue(styAttr == null ? "" : styAttr.getStringValue());
3574
[5284]3575+ //Evalutate coresponding track, if one exists
3576+ TrackBase track = trackManager.getTrack(styName, AnimationElement.AT_CSS);
3577+ if (track != null)
3578+ {
3579+ track.getValue(attrib, diagram.getUniverse().getCurTime());
3580+ return true;
3581+ }
3582+
[4256]3583 //Return if we've found a non animated style
3584 if (styAttr != null) return true;
3585
[5284]3586@@ -439,6 +544,14 @@
[4256]3587
3588 attrib.setStringValue(presAttr == null ? "" : presAttr.getStringValue());
3589
[5284]3590+ //Evalutate coresponding track, if one exists
3591+ track = trackManager.getTrack(styName, AnimationElement.AT_XML);
3592+ if (track != null)
3593+ {
3594+ track.getValue(attrib, diagram.getUniverse().getCurTime());
3595+ return true;
3596+ }
3597+
[4256]3598 //Return if we've found a presentation attribute instead
3599 if (presAttr != null) return true;
3600
[5284]3601@@ -480,6 +593,14 @@
[4256]3602 //Copy presentation value directly
3603 attrib.setStringValue(presAttr == null ? "" : presAttr.getStringValue());
3604
[5284]3605+ //Evalutate coresponding track, if one exists
3606+ TrackBase track = trackManager.getTrack(presName, AnimationElement.AT_XML);
3607+ if (track != null)
3608+ {
3609+ track.getValue(attrib, diagram.getUniverse().getCurTime());
3610+ return true;
3611+ }
3612+
[4256]3613 //Return if we found presentation attribute
3614 if (presAttr != null) return true;
3615
[5284]3616Index: core/src/com/kitfox/svg/SVGLoader.java
[4256]3617===================================================================
[5284]3618--- core.orig/src/com/kitfox/svg/SVGLoader.java 2012-05-11 17:03:52.404311564 +0200
3619+++ core/src/com/kitfox/svg/SVGLoader.java 2012-06-17 23:56:57.732545052 +0200
3620@@ -33,6 +33,8 @@
[4256]3621 import org.xml.sax.*;
3622 import org.xml.sax.helpers.DefaultHandler;
3623
[5284]3624+import com.kitfox.svg.animation.*;
3625+
[4256]3626 /**
3627 * @author Mark McKay
3628 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
[5284]3629@@ -75,6 +77,10 @@
[4256]3630
3631 //Compile a list of important builder classes
3632 nodeClasses.put("a", A.class);
[5284]3633+ nodeClasses.put("animate", Animate.class);
3634+ nodeClasses.put("animatecolor", AnimateColor.class);
3635+ nodeClasses.put("animatemotion", AnimateMotion.class);
3636+ nodeClasses.put("animatetransform", AnimateTransform.class);
[4256]3637 nodeClasses.put("circle", Circle.class);
3638 nodeClasses.put("clippath", ClipPath.class);
3639 nodeClasses.put("defs", Defs.class);
[5284]3640@@ -98,6 +104,7 @@
[4256]3641 nodeClasses.put("polyline", Polyline.class);
3642 nodeClasses.put("radialgradient", RadialGradient.class);
3643 nodeClasses.put("rect", Rect.class);
[5284]3644+ nodeClasses.put("set", SetSmil.class);
[4256]3645 nodeClasses.put("shape", ShapeElement.class);
3646 nodeClasses.put("stop", Stop.class);
3647 nodeClasses.put("style", Style.class);
[5284]3648Index: core/src/com/kitfox/svg/SVGLoaderHelper.java
[4256]3649===================================================================
[5284]3650--- core.orig/src/com/kitfox/svg/SVGLoaderHelper.java 2012-05-11 17:03:52.404311564 +0200
3651+++ core/src/com/kitfox/svg/SVGLoaderHelper.java 2012-06-17 23:56:57.740545051 +0200
3652@@ -28,6 +28,9 @@
[4256]3653 package com.kitfox.svg;
3654
3655 import java.net.*;
[5284]3656+import java.io.*;
3657+
3658+import com.kitfox.svg.animation.parser.*;
[4256]3659
3660 /**
3661 * @author Mark McKay
[5284]3662@@ -47,6 +50,11 @@
[4256]3663
3664 public final URI xmlBase;
3665
[5284]3666+ /**
3667+ * Animate nodes use this to parse their time strings
3668+ */
3669+ public final AnimTimeParser animTimeParser = new AnimTimeParser(new StringReader(""));
3670+
[4256]3671 /** Creates a new instance of SVGLoaderHelper */
3672 public SVGLoaderHelper(URI xmlBase, SVGUniverse universe, SVGDiagram diagram)
3673 {
[5284]3674Index: core/src/com/kitfox/svg/app/MainFrame.java
[4256]3675===================================================================
[5284]3676--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3677+++ core/src/com/kitfox/svg/app/MainFrame.java 2012-06-17 23:56:57.748545052 +0200
3678@@ -0,0 +1,134 @@
3679+/*
3680+ * MainFrame.java
3681+ *
3682+ * Created on September 6, 2004, 1:19 AM
3683+ */
3684+
3685+package com.kitfox.svg.app;
3686+
3687+/**
3688+ *
3689+ * @author kitfox
3690+ */
3691+public class MainFrame extends javax.swing.JFrame
3692+{
3693+ public static final long serialVersionUID = 1;
3694+
3695+ /** Creates new form MainFrame */
3696+ public MainFrame()
3697+ {
3698+ initComponents();
3699+ }
3700+
3701+ /** This method is called from within the constructor to
3702+ * initialize the form.
3703+ * WARNING: Do NOT modify this code. The content of this method is
3704+ * always regenerated by the Form Editor.
3705+ */
3706+ private void initComponents()//GEN-BEGIN:initComponents
3707+ {
3708+ jPanel1 = new javax.swing.JPanel();
3709+ bn_svgViewer = new javax.swing.JButton();
3710+ bn_svgViewer1 = new javax.swing.JButton();
3711+ jPanel2 = new javax.swing.JPanel();
3712+ bn_quit = new javax.swing.JButton();
3713+
3714+ setTitle("SVG Salamander - Application Launcher");
3715+ addWindowListener(new java.awt.event.WindowAdapter()
3716+ {
3717+ public void windowClosing(java.awt.event.WindowEvent evt)
3718+ {
3719+ exitForm(evt);
3720+ }
3721+ });
3722+
3723+ jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS));
3724+
3725+ bn_svgViewer.setText("SVG Viewer (No animation)");
3726+ bn_svgViewer.addActionListener(new java.awt.event.ActionListener()
3727+ {
3728+ public void actionPerformed(java.awt.event.ActionEvent evt)
3729+ {
3730+ bn_svgViewerActionPerformed(evt);
3731+ }
3732+ });
3733+
3734+ jPanel1.add(bn_svgViewer);
3735+
3736+ bn_svgViewer1.setText("SVG Player (Animation)");
3737+ bn_svgViewer1.addActionListener(new java.awt.event.ActionListener()
3738+ {
3739+ public void actionPerformed(java.awt.event.ActionEvent evt)
3740+ {
3741+ bn_svgViewer1ActionPerformed(evt);
3742+ }
3743+ });
3744+
3745+ jPanel1.add(bn_svgViewer1);
3746+
3747+ getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
3748+
3749+ bn_quit.setText("Quit");
3750+ bn_quit.addActionListener(new java.awt.event.ActionListener()
3751+ {
3752+ public void actionPerformed(java.awt.event.ActionEvent evt)
3753+ {
3754+ bn_quitActionPerformed(evt);
3755+ }
3756+ });
3757+
3758+ jPanel2.add(bn_quit);
3759+
3760+ getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);
3761+
3762+ pack();
3763+ }//GEN-END:initComponents
3764+
3765+ private void bn_svgViewer1ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_svgViewer1ActionPerformed
3766+ {//GEN-HEADEREND:event_bn_svgViewer1ActionPerformed
3767+ SVGPlayer.main(null);
3768+
3769+ close();
3770+ }//GEN-LAST:event_bn_svgViewer1ActionPerformed
3771+
3772+ private void bn_svgViewerActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_svgViewerActionPerformed
3773+ {//GEN-HEADEREND:event_bn_svgViewerActionPerformed
3774+ SVGViewer.main(null);
3775+
3776+ close();
3777+ }//GEN-LAST:event_bn_svgViewerActionPerformed
3778+
3779+ private void bn_quitActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_quitActionPerformed
3780+ {//GEN-HEADEREND:event_bn_quitActionPerformed
3781+ exitForm(null);
3782+ }//GEN-LAST:event_bn_quitActionPerformed
3783+
3784+ /** Exit the Application */
3785+ private void exitForm(java.awt.event.WindowEvent evt)//GEN-FIRST:event_exitForm
3786+ {
3787+ System.exit(0);
3788+ }//GEN-LAST:event_exitForm
3789+
3790+ private void close()
3791+ {
3792+ this.setVisible(false);
3793+ this.dispose();
3794+ }
3795+
3796+ /**
3797+ * @param args the command line arguments
3798+ */
3799+ public static void main(String args[])
3800+ {
3801+ new MainFrame().setVisible(true);
3802+ }
3803+
3804+ // Variables declaration - do not modify//GEN-BEGIN:variables
3805+ private javax.swing.JButton bn_quit;
3806+ private javax.swing.JButton bn_svgViewer;
3807+ private javax.swing.JButton bn_svgViewer1;
3808+ private javax.swing.JPanel jPanel1;
3809+ private javax.swing.JPanel jPanel2;
3810+ // End of variables declaration//GEN-END:variables
3811+
3812+}
3813Index: core/src/com/kitfox/svg/app/PlayerDialog.java
[4256]3814===================================================================
[5284]3815--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3816+++ core/src/com/kitfox/svg/app/PlayerDialog.java 2012-06-17 23:56:57.748545052 +0200
3817@@ -0,0 +1,289 @@
3818+/*
3819+ * PlayerDialog.java
3820+ *
3821+ *
3822+ * The Salamander Project - 2D and 3D graphics libraries in Java
3823+ * Copyright (C) 2004 Mark McKay
3824+ *
3825+ * This library is free software; you can redistribute it and/or
3826+ * modify it under the terms of the GNU Lesser General Public
3827+ * License as published by the Free Software Foundation; either
3828+ * version 2.1 of the License, or (at your option) any later version.
3829+ *
3830+ * This library is distributed in the hope that it will be useful,
3831+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3832+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3833+ * Lesser General Public License for more details.
3834+ *
3835+ * You should have received a copy of the GNU Lesser General Public
3836+ * License along with this library; if not, write to the Free Software
3837+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3838+ *
3839+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
3840+ * projects can be found at http://www.kitfox.com
3841+ *
3842+ * Created on September 28, 2004, 9:56 PM
3843+ */
3844+
3845+package com.kitfox.svg.app;
3846+
3847+/**
3848+ *
3849+ * @author kitfox
3850+ */
3851+public class PlayerDialog extends javax.swing.JDialog implements PlayerThreadListener
3852+{
3853+ public static final long serialVersionUID = 1;
3854+
3855+ PlayerThread thread;
3856+
3857+ final SVGPlayer parent;
3858+
3859+ /** Creates new form PlayerDialog */
3860+ public PlayerDialog(SVGPlayer parent)
3861+ {
3862+ super(parent, false);
3863+ initComponents();
3864+
3865+ this.parent = parent;
3866+
3867+ thread = new PlayerThread();
3868+ thread.addListener(this);
3869+
3870+ text_timeStepActionPerformed(null);
3871+ }
3872+
3873+ public void updateTime(double curTime, double timeStep, int playState)
3874+ {
3875+ if (playState == PlayerThread.PS_STOP) return;
3876+
3877+ text_curTime.setText("" + (float)curTime);
3878+ parent.updateTime(curTime);
3879+// text_timeStep.setText("" + (int)(1.0 / timeStep));
3880+ }
3881+
3882+ /** This method is called from within the constructor to
3883+ * initialize the form.
3884+ * WARNING: Do NOT modify this code. The content of this method is
3885+ * always regenerated by the Form Editor.
3886+ */
3887+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
3888+ private void initComponents()
3889+ {
3890+ jPanel1 = new javax.swing.JPanel();
3891+ bn_playBack = new javax.swing.JButton();
3892+ bn_stop = new javax.swing.JButton();
3893+ bn_playFwd = new javax.swing.JButton();
3894+ jPanel2 = new javax.swing.JPanel();
3895+ jPanel3 = new javax.swing.JPanel();
3896+ jLabel1 = new javax.swing.JLabel();
3897+ text_curTime = new javax.swing.JTextField();
3898+ bn_time0 = new javax.swing.JButton();
3899+ jPanel4 = new javax.swing.JPanel();
3900+ jLabel2 = new javax.swing.JLabel();
3901+ text_timeStep = new javax.swing.JTextField();
3902+
3903+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
3904+ setTitle("Player");
3905+ addWindowListener(new java.awt.event.WindowAdapter()
3906+ {
3907+ public void windowClosed(java.awt.event.WindowEvent evt)
3908+ {
3909+ formWindowClosed(evt);
3910+ }
3911+ });
3912+
3913+ bn_playBack.setText("<");
3914+ bn_playBack.setToolTipText("Play backwards");
3915+ bn_playBack.addActionListener(new java.awt.event.ActionListener()
3916+ {
3917+ public void actionPerformed(java.awt.event.ActionEvent evt)
3918+ {
3919+ bn_playBackActionPerformed(evt);
3920+ }
3921+ });
3922+
3923+ jPanel1.add(bn_playBack);
3924+
3925+ bn_stop.setText("||");
3926+ bn_stop.setToolTipText("Stop playback");
3927+ bn_stop.addActionListener(new java.awt.event.ActionListener()
3928+ {
3929+ public void actionPerformed(java.awt.event.ActionEvent evt)
3930+ {
3931+ bn_stopActionPerformed(evt);
3932+ }
3933+ });
3934+
3935+ jPanel1.add(bn_stop);
3936+
3937+ bn_playFwd.setText(">");
3938+ bn_playFwd.setToolTipText("Play Forwards");
3939+ bn_playFwd.addActionListener(new java.awt.event.ActionListener()
3940+ {
3941+ public void actionPerformed(java.awt.event.ActionEvent evt)
3942+ {
3943+ bn_playFwdActionPerformed(evt);
3944+ }
3945+ });
3946+
3947+ jPanel1.add(bn_playFwd);
3948+
3949+ getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);
3950+
3951+ jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.Y_AXIS));
3952+
3953+ jLabel1.setText("Cur Time");
3954+ jPanel3.add(jLabel1);
3955+
3956+ text_curTime.setHorizontalAlignment(javax.swing.JTextField.LEFT);
3957+ text_curTime.setText("0");
3958+ text_curTime.setPreferredSize(new java.awt.Dimension(100, 21));
3959+ text_curTime.addActionListener(new java.awt.event.ActionListener()
3960+ {
3961+ public void actionPerformed(java.awt.event.ActionEvent evt)
3962+ {
3963+ text_curTimeActionPerformed(evt);
3964+ }
3965+ });
3966+ text_curTime.addFocusListener(new java.awt.event.FocusAdapter()
3967+ {
3968+ public void focusLost(java.awt.event.FocusEvent evt)
3969+ {
3970+ text_curTimeFocusLost(evt);
3971+ }
3972+ });
3973+
3974+ jPanel3.add(text_curTime);
3975+
3976+ bn_time0.setText("Time 0");
3977+ bn_time0.setToolTipText("Reset time to first frame");
3978+ bn_time0.addActionListener(new java.awt.event.ActionListener()
3979+ {
3980+ public void actionPerformed(java.awt.event.ActionEvent evt)
3981+ {
3982+ bn_time0ActionPerformed(evt);
3983+ }
3984+ });
3985+
3986+ jPanel3.add(bn_time0);
3987+
3988+ jPanel2.add(jPanel3);
3989+
3990+ jLabel2.setText("Frames Per Second");
3991+ jPanel4.add(jLabel2);
3992+
3993+ text_timeStep.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
3994+ text_timeStep.setText("60");
3995+ text_timeStep.setPreferredSize(new java.awt.Dimension(100, 21));
3996+ text_timeStep.addActionListener(new java.awt.event.ActionListener()
3997+ {
3998+ public void actionPerformed(java.awt.event.ActionEvent evt)
3999+ {
4000+ text_timeStepActionPerformed(evt);
4001+ }
4002+ });
4003+ text_timeStep.addFocusListener(new java.awt.event.FocusAdapter()
4004+ {
4005+ public void focusLost(java.awt.event.FocusEvent evt)
4006+ {
4007+ text_timeStepFocusLost(evt);
4008+ }
4009+ });
4010+
4011+ jPanel4.add(text_timeStep);
4012+
4013+ jPanel2.add(jPanel4);
4014+
4015+ getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);
4016+
4017+ pack();
4018+ }// </editor-fold>//GEN-END:initComponents
4019+
4020+ private void bn_time0ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_time0ActionPerformed
4021+ {//GEN-HEADEREND:event_bn_time0ActionPerformed
4022+ thread.setCurTime(0);
4023+ }//GEN-LAST:event_bn_time0ActionPerformed
4024+
4025+ private void bn_playFwdActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_playFwdActionPerformed
4026+ {//GEN-HEADEREND:event_bn_playFwdActionPerformed
4027+ thread.setPlayState(PlayerThread.PS_PLAY_FWD);
4028+ }//GEN-LAST:event_bn_playFwdActionPerformed
4029+
4030+ private void bn_stopActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_stopActionPerformed
4031+ {//GEN-HEADEREND:event_bn_stopActionPerformed
4032+ thread.setPlayState(PlayerThread.PS_STOP);
4033+ }//GEN-LAST:event_bn_stopActionPerformed
4034+
4035+ private void bn_playBackActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_playBackActionPerformed
4036+ {//GEN-HEADEREND:event_bn_playBackActionPerformed
4037+ thread.setPlayState(PlayerThread.PS_PLAY_BACK);
4038+ }//GEN-LAST:event_bn_playBackActionPerformed
4039+
4040+ private void formWindowClosed(java.awt.event.WindowEvent evt)//GEN-FIRST:event_formWindowClosed
4041+ {//GEN-HEADEREND:event_formWindowClosed
4042+// thread.exit();
4043+ }//GEN-LAST:event_formWindowClosed
4044+
4045+ private void text_timeStepFocusLost(java.awt.event.FocusEvent evt)//GEN-FIRST:event_text_timeStepFocusLost
4046+ {//GEN-HEADEREND:event_text_timeStepFocusLost
4047+ text_timeStepActionPerformed(null);
4048+ }//GEN-LAST:event_text_timeStepFocusLost
4049+
4050+ private void text_timeStepActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_text_timeStepActionPerformed
4051+ {//GEN-HEADEREND:event_text_timeStepActionPerformed
4052+ try
4053+ {
4054+ int val = Integer.parseInt(text_timeStep.getText());
4055+ thread.setTimeStep(1.0 / val);
4056+ }
4057+ catch (Exception e)
4058+ {
4059+ }
4060+
4061+ double d = thread.getTimeStep();
4062+ String newStrn = "" + (int)(1f / d);
4063+ if (newStrn.equals(text_timeStep.getText())) return;
4064+ text_timeStep.setText(newStrn);
4065+
4066+// text_timeStepActionPerformed(null);
4067+ }//GEN-LAST:event_text_timeStepActionPerformed
4068+
4069+ private void text_curTimeActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_text_curTimeActionPerformed
4070+ {//GEN-HEADEREND:event_text_curTimeActionPerformed
4071+ try
4072+ {
4073+ double val = Double.parseDouble(text_curTime.getText());
4074+ thread.setCurTime(val);
4075+ }
4076+ catch (Exception e)
4077+ {
4078+ }
4079+
4080+ double d = thread.getCurTime();
4081+ text_curTime.setText("" + (float)d);
4082+
4083+ text_timeStepActionPerformed(null);
4084+ }//GEN-LAST:event_text_curTimeActionPerformed
4085+
4086+ private void text_curTimeFocusLost(java.awt.event.FocusEvent evt)//GEN-FIRST:event_text_curTimeFocusLost
4087+ {//GEN-HEADEREND:event_text_curTimeFocusLost
4088+ text_curTimeActionPerformed(null);
4089+ }//GEN-LAST:event_text_curTimeFocusLost
4090+
4091+ // Variables declaration - do not modify//GEN-BEGIN:variables
4092+ private javax.swing.JButton bn_playBack;
4093+ private javax.swing.JButton bn_playFwd;
4094+ private javax.swing.JButton bn_stop;
4095+ private javax.swing.JButton bn_time0;
4096+ private javax.swing.JLabel jLabel1;
4097+ private javax.swing.JLabel jLabel2;
4098+ private javax.swing.JPanel jPanel1;
4099+ private javax.swing.JPanel jPanel2;
4100+ private javax.swing.JPanel jPanel3;
4101+ private javax.swing.JPanel jPanel4;
4102+ private javax.swing.JTextField text_curTime;
4103+ private javax.swing.JTextField text_timeStep;
4104+ // End of variables declaration//GEN-END:variables
4105+
4106+}
4107Index: core/src/com/kitfox/svg/app/PlayerThread.java
[4256]4108===================================================================
[5284]4109--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4110+++ core/src/com/kitfox/svg/app/PlayerThread.java 2012-06-17 23:56:57.748545052 +0200
4111@@ -0,0 +1,129 @@
4112+/*
4113+ * PlayerThread.java
4114+ *
4115+ *
4116+ * The Salamander Project - 2D and 3D graphics libraries in Java
4117+ * Copyright (C) 2004 Mark McKay
4118+ *
4119+ * This library is free software; you can redistribute it and/or
4120+ * modify it under the terms of the GNU Lesser General Public
4121+ * License as published by the Free Software Foundation; either
4122+ * version 2.1 of the License, or (at your option) any later version.
4123+ *
4124+ * This library is distributed in the hope that it will be useful,
4125+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4126+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4127+ * Lesser General Public License for more details.
4128+ *
4129+ * You should have received a copy of the GNU Lesser General Public
4130+ * License along with this library; if not, write to the Free Software
4131+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4132+ *
4133+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
4134+ * projects can be found at http://www.kitfox.com
4135+ *
4136+ * Created on September 28, 2004, 10:07 PM
4137+ */
4138+
4139+
4140+package com.kitfox.svg.app;
4141+
4142+import java.util.*;
4143+
4144+/**
4145+ *
4146+ * @author kitfox
4147+ */
4148+public class PlayerThread implements Runnable
4149+{
4150+ HashSet listeners = new HashSet();
4151+
4152+ double curTime = 0;
4153+ double timeStep = .2;
4154+
4155+ public static final int PS_STOP = 0;
4156+ public static final int PS_PLAY_FWD = 1;
4157+ public static final int PS_PLAY_BACK = 2;
4158+
4159+ int playState = PS_STOP;
4160+
4161+ Thread thread;
4162+
4163+ /** Creates a new instance of PlayerThread */
4164+ public PlayerThread()
4165+ {
4166+ thread = new Thread(this);
4167+ thread.start();
4168+ }
4169+
4170+ public void run()
4171+ {
4172+ while (thread != null)
4173+ {
4174+ synchronized (this)
4175+ {
4176+ switch (playState)
4177+ {
4178+ case PS_PLAY_FWD:
4179+ curTime += timeStep;
4180+ break;
4181+ case PS_PLAY_BACK:
4182+ curTime -= timeStep;
4183+ if (curTime < 0) curTime = 0;
4184+ break;
4185+ default:
4186+ case PS_STOP:
4187+ break;
4188+ }
4189+
4190+ fireTimeUpdateEvent();
4191+ }
4192+
4193+ try
4194+ {
4195+ Thread.sleep((long)(timeStep * 1000));
4196+ }
4197+ catch (Exception e)
4198+ {
4199+ throw new RuntimeException(e);
4200+ }
4201+ }
4202+ }
4203+
4204+ public void exit() { thread = null; }
4205+ public synchronized void addListener(PlayerThreadListener listener)
4206+ {
4207+ listeners.add(listener);
4208+ }
4209+
4210+ public synchronized double getCurTime() { return curTime; }
4211+
4212+ public synchronized void setCurTime(double time)
4213+ {
4214+ curTime = time;
4215+ }
4216+
4217+ public synchronized double getTimeStep() { return timeStep; }
4218+
4219+ public synchronized void setTimeStep(double time)
4220+ {
4221+ timeStep = time;
4222+ if (timeStep < .01) timeStep = .01;
4223+ }
4224+
4225+ public synchronized int getPlayState() { return playState; }
4226+
4227+ public synchronized void setPlayState(int playState)
4228+ {
4229+ this.playState = playState;
4230+ }
4231+
4232+ private void fireTimeUpdateEvent()
4233+ {
4234+ for (Iterator it = listeners.iterator(); it.hasNext();)
4235+ {
4236+ PlayerThreadListener listener = (PlayerThreadListener)it.next();
4237+ listener.updateTime(curTime, timeStep, playState);
4238+ }
4239+ }
4240+}
4241Index: core/src/com/kitfox/svg/app/PlayerThreadListener.java
[4256]4242===================================================================
[5284]4243--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4244+++ core/src/com/kitfox/svg/app/PlayerThreadListener.java 2012-06-17 23:56:57.748545052 +0200
4245@@ -0,0 +1,37 @@
4246+/*
4247+ * PlayerThreadListener.java
4248+ *
4249+ *
4250+ * The Salamander Project - 2D and 3D graphics libraries in Java
4251+ * Copyright (C) 2004 Mark McKay
4252+ *
4253+ * This library is free software; you can redistribute it and/or
4254+ * modify it under the terms of the GNU Lesser General Public
4255+ * License as published by the Free Software Foundation; either
4256+ * version 2.1 of the License, or (at your option) any later version.
4257+ *
4258+ * This library is distributed in the hope that it will be useful,
4259+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4260+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4261+ * Lesser General Public License for more details.
4262+ *
4263+ * You should have received a copy of the GNU Lesser General Public
4264+ * License along with this library; if not, write to the Free Software
4265+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4266+ *
4267+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
4268+ * projects can be found at http://www.kitfox.com
4269+ *
4270+ * Created on September 28, 2004, 10:15 PM
4271+ */
4272+
4273+package com.kitfox.svg.app;
4274+
4275+/**
4276+ *
4277+ * @author kitfox
4278+ */
4279+public interface PlayerThreadListener
4280+{
4281+ public void updateTime(double curTime, double timeStep, int playState);
4282+}
4283Index: core/src/com/kitfox/svg/app/SVGPlayer.java
[4256]4284===================================================================
[5284]4285--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4286+++ core/src/com/kitfox/svg/app/SVGPlayer.java 2012-06-17 23:56:57.748545052 +0200
4287@@ -0,0 +1,436 @@
4288+/*
4289+ * SVGViewer.java
4290+ *
4291+ *
4292+ * The Salamander Project - 2D and 3D graphics libraries in Java
4293+ * Copyright (C) 2004 Mark McKay
4294+ *
4295+ * This library is free software; you can redistribute it and/or
4296+ * modify it under the terms of the GNU Lesser General Public
4297+ * License as published by the Free Software Foundation; either
4298+ * version 2.1 of the License, or (at your option) any later version.
4299+ *
4300+ * This library is distributed in the hope that it will be useful,
4301+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4302+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4303+ * Lesser General Public License for more details.
4304+ *
4305+ * You should have received a copy of the GNU Lesser General Public
4306+ * License along with this library; if not, write to the Free Software
4307+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4308+ *
4309+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
4310+ * projects can be found at http://www.kitfox.com
4311+ *
4312+ * Created on April 3, 2004, 5:28 PM
4313+ */
4314+
4315+package com.kitfox.svg.app;
4316+
4317+
4318+import com.kitfox.svg.SVGDiagram;
4319+import com.kitfox.svg.SVGDisplayPanel;
4320+import com.kitfox.svg.SVGElement;
4321+import com.kitfox.svg.SVGException;
4322+import com.kitfox.svg.SVGUniverse;
4323+import java.awt.Color;
4324+import java.awt.event.MouseAdapter;
4325+import java.awt.event.MouseEvent;
4326+import java.awt.geom.Point2D;
4327+import java.io.File;
4328+import java.io.InputStream;
4329+import java.net.URI;
4330+import java.net.URL;
4331+import java.net.URLEncoder;
4332+import java.security.AccessControlException;
4333+import java.util.ArrayList;
4334+import java.util.List;
4335+import java.util.Vector;
4336+import java.util.regex.Matcher;
4337+import java.util.regex.Pattern;
4338+import javax.swing.JFileChooser;
4339+import javax.swing.JOptionPane;
4340+
4341+/**
4342+ * @author Mark McKay
4343+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
4344+ */
4345+public class SVGPlayer extends javax.swing.JFrame
4346+{
4347+ public static final long serialVersionUID = 1;
4348+
4349+ SVGDisplayPanel svgDisplayPanel = new SVGDisplayPanel();
4350+
4351+ final PlayerDialog playerDialog;
4352+
4353+ SVGUniverse universe;
4354+
4355+ /** FileChooser for running in trusted environments */
4356+ final JFileChooser fileChooser;
4357+ {
4358+// fileChooser = new JFileChooser(new File("."));
4359+ JFileChooser fc = null;
4360+ try
4361+ {
4362+ fc = new JFileChooser();
4363+ fc.setFileFilter(
4364+ new javax.swing.filechooser.FileFilter() {
4365+ final Matcher matchLevelFile = Pattern.compile(".*\\.svg[z]?").matcher("");
4366+
4367+ public boolean accept(File file)
4368+ {
4369+ if (file.isDirectory()) return true;
4370+
4371+ matchLevelFile.reset(file.getName());
4372+ return matchLevelFile.matches();
4373+ }
4374+
4375+ public String getDescription() { return "SVG file (*.svg, *.svgz)"; }
4376+ }
4377+ );
4378+ }
4379+ catch (AccessControlException ex)
4380+ {
4381+ //Do not create file chooser if webstart refuses permissions
4382+ }
4383+ fileChooser = fc;
4384+ }
4385+
4386+ /** Backup file service for opening files in WebStart situations */
4387+ /*
4388+ final FileOpenService fileOpenService;
4389+ {
4390+ try
4391+ {
4392+ fileOpenService = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
4393+ }
4394+ catch (UnavailableServiceException e)
4395+ {
4396+ fileOpenService = null;
4397+ }
4398+ }
4399+ */
4400+
4401+ /** Creates new form SVGViewer */
4402+ public SVGPlayer() {
4403+ initComponents();
4404+
4405+ setSize(800, 600);
4406+
4407+ svgDisplayPanel.setBgColor(Color.white);
4408+ svgDisplayPanel.addMouseListener(new MouseAdapter()
4409+ {
4410+ public void mouseClicked(MouseEvent evt)
4411+ {
4412+ SVGDiagram diagram = svgDisplayPanel.getDiagram();
4413+ if (diagram == null) return;
4414+
4415+ System.out.println("Picking at cursor (" + evt.getX() + ", " + evt.getY() + ")");
4416+ try
4417+ {
4418+ List paths = diagram.pick(new Point2D.Float(evt.getX(), evt.getY()), null);
4419+ for (int i = 0; i < paths.size(); i++)
4420+ {
4421+ ArrayList path = (ArrayList)paths.get(i);
4422+ System.out.println(pathToString(path));
4423+ }
4424+ }
4425+ catch (SVGException ex)
4426+ {
4427+ ex.printStackTrace();
4428+ }
4429+ }
4430+ }
4431+ );
4432+
4433+ svgDisplayPanel.setPreferredSize(getSize());
4434+ scrollPane_svgArea.setViewportView(svgDisplayPanel);
4435+
4436+ playerDialog = new PlayerDialog(this);
4437+ }
4438+
4439+ private String pathToString(List path)
4440+ {
4441+ if (path.size() == 0) return "";
4442+
4443+ StringBuffer sb = new StringBuffer();
4444+ sb.append(path.get(0));
4445+ for (int i = 1; i < path.size(); i++)
4446+ {
4447+ sb.append("/");
4448+ sb.append(((SVGElement)path.get(i)).getId());
4449+ }
4450+ return sb.toString();
4451+ }
4452+
4453+ public void updateTime(double curTime)
4454+ {
4455+ try
4456+ {
4457+ if (universe != null)
4458+ {
4459+ universe.setCurTime(curTime);
4460+ universe.updateTime();
4461+ // svgDisplayPanel.updateTime(curTime);
4462+ repaint();
4463+ }
4464+ }
4465+ catch (Exception e)
4466+ {
4467+ e.printStackTrace();
4468+ }
4469+ }
4470+
4471+ private void loadURL(URL url)
4472+ {
4473+ boolean verbose = cmCheck_verbose.isSelected();
4474+
4475+ universe = new SVGUniverse();
4476+ universe.setVerbose(verbose);
4477+ SVGDiagram diagram = null;
4478+
4479+ if (!CheckBoxMenuItem_anonInputStream.isSelected())
4480+ {
4481+ //Load from a disk with a valid URL
4482+ URI uri = universe.loadSVG(url);
4483+
4484+ if (verbose) System.err.println(uri.toString());
4485+
4486+ diagram = universe.getDiagram(uri);
4487+ }
4488+ else
4489+ {
4490+ //Load from a stream with no particular valid URL
4491+ try
4492+ {
4493+ InputStream is = url.openStream();
4494+ URI uri = universe.loadSVG(is, "defaultName");
4495+
4496+ if (verbose) System.err.println(uri.toString());
4497+
4498+ diagram = universe.getDiagram(uri);
4499+ }
4500+ catch (Exception e)
4501+ {
4502+ e.printStackTrace();
4503+ }
4504+ }
4505+
4506+ svgDisplayPanel.setDiagram(diagram);
4507+ repaint();
4508+ }
4509+
4510+ /** This method is called from within the constructor to
4511+ * initialize the form.
4512+ * WARNING: Do NOT modify this code. The content of this method is
4513+ * always regenerated by the Form Editor.
4514+ */
4515+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
4516+ private void initComponents()
4517+ {
4518+ scrollPane_svgArea = new javax.swing.JScrollPane();
4519+ jMenuBar1 = new javax.swing.JMenuBar();
4520+ menu_file = new javax.swing.JMenu();
4521+ cm_loadFile = new javax.swing.JMenuItem();
4522+ cm_loadUrl = new javax.swing.JMenuItem();
4523+ menu_window = new javax.swing.JMenu();
4524+ cm_player = new javax.swing.JMenuItem();
4525+ jSeparator2 = new javax.swing.JSeparator();
4526+ cm_800x600 = new javax.swing.JMenuItem();
4527+ CheckBoxMenuItem_anonInputStream = new javax.swing.JCheckBoxMenuItem();
4528+ cmCheck_verbose = new javax.swing.JCheckBoxMenuItem();
4529+ menu_help = new javax.swing.JMenu();
4530+ cm_about = new javax.swing.JMenuItem();
4531+
4532+ setTitle("SVG Player - Salamander Project");
4533+ addWindowListener(new java.awt.event.WindowAdapter()
4534+ {
4535+ public void windowClosing(java.awt.event.WindowEvent evt)
4536+ {
4537+ exitForm(evt);
4538+ }
4539+ });
4540+
4541+ getContentPane().add(scrollPane_svgArea, java.awt.BorderLayout.CENTER);
4542+
4543+ menu_file.setMnemonic('f');
4544+ menu_file.setText("File");
4545+ cm_loadFile.setMnemonic('l');
4546+ cm_loadFile.setText("Load File...");
4547+ cm_loadFile.addActionListener(new java.awt.event.ActionListener()
4548+ {
4549+ public void actionPerformed(java.awt.event.ActionEvent evt)
4550+ {
4551+ cm_loadFileActionPerformed(evt);
4552+ }
4553+ });
4554+
4555+ menu_file.add(cm_loadFile);
4556+
4557+ cm_loadUrl.setText("Load URL...");
4558+ cm_loadUrl.addActionListener(new java.awt.event.ActionListener()
4559+ {
4560+ public void actionPerformed(java.awt.event.ActionEvent evt)
4561+ {
4562+ cm_loadUrlActionPerformed(evt);
4563+ }
4564+ });
4565+
4566+ menu_file.add(cm_loadUrl);
4567+
4568+ jMenuBar1.add(menu_file);
4569+
4570+ menu_window.setText("Window");
4571+ cm_player.setText("Player");
4572+ cm_player.addActionListener(new java.awt.event.ActionListener()
4573+ {
4574+ public void actionPerformed(java.awt.event.ActionEvent evt)
4575+ {
4576+ cm_playerActionPerformed(evt);
4577+ }
4578+ });
4579+
4580+ menu_window.add(cm_player);
4581+
4582+ menu_window.add(jSeparator2);
4583+
4584+ cm_800x600.setText("800 x 600");
4585+ cm_800x600.addActionListener(new java.awt.event.ActionListener()
4586+ {
4587+ public void actionPerformed(java.awt.event.ActionEvent evt)
4588+ {
4589+ cm_800x600ActionPerformed(evt);
4590+ }
4591+ });
4592+
4593+ menu_window.add(cm_800x600);
4594+
4595+ CheckBoxMenuItem_anonInputStream.setText("Anonymous Input Stream");
4596+ menu_window.add(CheckBoxMenuItem_anonInputStream);
4597+
4598+ cmCheck_verbose.setText("Verbose");
4599+ cmCheck_verbose.addActionListener(new java.awt.event.ActionListener()
4600+ {
4601+ public void actionPerformed(java.awt.event.ActionEvent evt)
4602+ {
4603+ cmCheck_verboseActionPerformed(evt);
4604+ }
4605+ });
4606+
4607+ menu_window.add(cmCheck_verbose);
4608+
4609+ jMenuBar1.add(menu_window);
4610+
4611+ menu_help.setText("Help");
4612+ cm_about.setText("About...");
4613+ cm_about.addActionListener(new java.awt.event.ActionListener()
4614+ {
4615+ public void actionPerformed(java.awt.event.ActionEvent evt)
4616+ {
4617+ cm_aboutActionPerformed(evt);
4618+ }
4619+ });
4620+
4621+ menu_help.add(cm_about);
4622+
4623+ jMenuBar1.add(menu_help);
4624+
4625+ setJMenuBar(jMenuBar1);
4626+
4627+ pack();
4628+ }// </editor-fold>//GEN-END:initComponents
4629+
4630+ private void cm_loadUrlActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadUrlActionPerformed
4631+ {//GEN-HEADEREND:event_cm_loadUrlActionPerformed
4632+ String urlStrn = JOptionPane.showInputDialog(this, "Enter URL of SVG file");
4633+ if (urlStrn == null) return;
4634+
4635+ try
4636+ {
4637+ URL url = new URL(URLEncoder.encode(urlStrn, "UTF-8"));
4638+ loadURL(url);
4639+ }
4640+ catch (Exception e)
4641+ {
4642+ e.printStackTrace();
4643+ }
4644+
4645+ }//GEN-LAST:event_cm_loadUrlActionPerformed
4646+
4647+ private void cmCheck_verboseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cmCheck_verboseActionPerformed
4648+ {//GEN-HEADEREND:event_cmCheck_verboseActionPerformed
4649+// TODO add your handling code here:
4650+ }//GEN-LAST:event_cmCheck_verboseActionPerformed
4651+
4652+ private void cm_playerActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_playerActionPerformed
4653+ {//GEN-HEADEREND:event_cm_playerActionPerformed
4654+ playerDialog.setVisible(true);
4655+ }//GEN-LAST:event_cm_playerActionPerformed
4656+
4657+ private void cm_aboutActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_aboutActionPerformed
4658+ {//GEN-HEADEREND:event_cm_aboutActionPerformed
4659+ VersionDialog dia = new VersionDialog(this, true, cmCheck_verbose.isSelected());
4660+ dia.setVisible(true);
4661+// JOptionPane.showMessageDialog(this, "Salamander SVG - Created by Mark McKay\nhttp://www.kitfox.com");
4662+ }//GEN-LAST:event_cm_aboutActionPerformed
4663+
4664+ private void cm_800x600ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cm_800x600ActionPerformed
4665+ setSize(800, 600);
4666+ }//GEN-LAST:event_cm_800x600ActionPerformed
4667+
4668+ private void cm_loadFileActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadFileActionPerformed
4669+ {//GEN-HEADEREND:event_cm_loadFileActionPerformed
4670+ boolean verbose = cmCheck_verbose.isSelected();
4671+
4672+ try
4673+ {
4674+ int retVal = fileChooser.showOpenDialog(this);
4675+ if (retVal == JFileChooser.APPROVE_OPTION)
4676+ {
4677+ File chosenFile = fileChooser.getSelectedFile();
4678+
4679+ URL url = chosenFile.toURI().toURL();
4680+
4681+ loadURL(url);
4682+ }
4683+ }
4684+ catch (Exception e)
4685+ {
4686+ e.printStackTrace();
4687+ }
4688+
4689+ }//GEN-LAST:event_cm_loadFileActionPerformed
4690+
4691+ /** Exit the Application */
4692+ private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
4693+ System.exit(0);
4694+ }//GEN-LAST:event_exitForm
4695+
4696+ /**
4697+ * @param args the command line arguments
4698+ */
4699+ public static void main(String args[]) {
4700+ new SVGPlayer().setVisible(true);
4701+ }
4702+
4703+ public void updateTime(double curTime, double timeStep, int playState)
4704+ {
4705+ }
4706+
4707+ // Variables declaration - do not modify//GEN-BEGIN:variables
4708+ private javax.swing.JCheckBoxMenuItem CheckBoxMenuItem_anonInputStream;
4709+ private javax.swing.JCheckBoxMenuItem cmCheck_verbose;
4710+ private javax.swing.JMenuItem cm_800x600;
4711+ private javax.swing.JMenuItem cm_about;
4712+ private javax.swing.JMenuItem cm_loadFile;
4713+ private javax.swing.JMenuItem cm_loadUrl;
4714+ private javax.swing.JMenuItem cm_player;
4715+ private javax.swing.JMenuBar jMenuBar1;
4716+ private javax.swing.JSeparator jSeparator2;
4717+ private javax.swing.JMenu menu_file;
4718+ private javax.swing.JMenu menu_help;
4719+ private javax.swing.JMenu menu_window;
4720+ private javax.swing.JScrollPane scrollPane_svgArea;
4721+ // End of variables declaration//GEN-END:variables
4722+
4723+}
4724Index: core/src/com/kitfox/svg/app/SVGViewer.java
[4256]4725===================================================================
[5284]4726--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4727+++ core/src/com/kitfox/svg/app/SVGViewer.java 2012-06-17 23:56:57.752545052 +0200
4728@@ -0,0 +1,432 @@
4729+/*
4730+ * SVGViewer.java
4731+ *
4732+ *
4733+ * The Salamander Project - 2D and 3D graphics libraries in Java
4734+ * Copyright (C) 2004 Mark McKay
4735+ *
4736+ * This library is free software; you can redistribute it and/or
4737+ * modify it under the terms of the GNU Lesser General Public
4738+ * License as published by the Free Software Foundation; either
4739+ * version 2.1 of the License, or (at your option) any later version.
4740+ *
4741+ * This library is distributed in the hope that it will be useful,
4742+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4743+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4744+ * Lesser General Public License for more details.
4745+ *
4746+ * You should have received a copy of the GNU Lesser General Public
4747+ * License along with this library; if not, write to the Free Software
4748+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4749+ *
4750+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
4751+ * projects can be found at http://www.kitfox.com
4752+ *
4753+ * Created on April 3, 2004, 5:28 PM
4754+ */
4755+
4756+package com.kitfox.svg.app;
4757+
4758+import com.kitfox.svg.SVGCache;
4759+import com.kitfox.svg.SVGDiagram;
4760+import com.kitfox.svg.SVGDisplayPanel;
4761+import com.kitfox.svg.SVGElement;
4762+import com.kitfox.svg.SVGException;
4763+import com.kitfox.svg.SVGUniverse;
4764+import java.awt.BorderLayout;
4765+import java.awt.Color;
4766+import java.awt.Point;
4767+import java.io.File;
4768+import java.io.InputStream;
4769+import java.net.URI;
4770+import java.net.URL;
4771+import java.net.URLEncoder;
4772+import java.security.AccessControlException;
4773+import java.util.ArrayList;
4774+import java.util.Iterator;
4775+import java.util.List;
4776+import java.util.regex.Matcher;
4777+import java.util.regex.Pattern;
4778+import javax.swing.JFileChooser;
4779+import javax.swing.JOptionPane;
4780+
4781+
4782+/**
4783+ * @author Mark McKay
4784+ * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
4785+ */
4786+public class SVGViewer extends javax.swing.JFrame
4787+{
4788+ public static final long serialVersionUID = 1;
4789+
4790+ SVGDisplayPanel svgDisplayPanel = new SVGDisplayPanel();
4791+
4792+ /** FileChooser for running in trusted environments */
4793+ final JFileChooser fileChooser;
4794+ {
4795+// fileChooser = new JFileChooser(new File("."));
4796+ JFileChooser fc = null;
4797+ try
4798+ {
4799+ fc = new JFileChooser();
4800+ fc.setFileFilter(
4801+ new javax.swing.filechooser.FileFilter() {
4802+ final Matcher matchLevelFile = Pattern.compile(".*\\.svg[z]?").matcher("");
4803+
4804+ public boolean accept(File file)
4805+ {
4806+ if (file.isDirectory()) return true;
4807+
4808+ matchLevelFile.reset(file.getName());
4809+ return matchLevelFile.matches();
4810+ }
4811+
4812+ public String getDescription() { return "SVG file (*.svg, *.svgz)"; }
4813+ }
4814+ );
4815+ }
4816+ catch (AccessControlException ex)
4817+ {
4818+ //Do not create file chooser if webstart refuses permissions
4819+ }
4820+ fileChooser = fc;
4821+ }
4822+
4823+ /** Backup file service for opening files in WebStart situations */
4824+ /*
4825+ final FileOpenService fileOpenService;
4826+ {
4827+ try
4828+ {
4829+ fileOpenService = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
4830+ }
4831+ catch (UnavailableServiceException e)
4832+ {
4833+ fileOpenService = null;
4834+ }
4835+ }
4836+ */
4837+
4838+ /** Creates new form SVGViewer */
4839+ public SVGViewer() {
4840+ initComponents();
4841+
4842+ setSize(800, 600);
4843+
4844+ svgDisplayPanel.setBgColor(Color.white);
4845+
4846+ svgDisplayPanel.setPreferredSize(getSize());
4847+ panel_svgArea.add(svgDisplayPanel, BorderLayout.CENTER);
4848+// scrollPane_svgArea.setViewportView(svgDisplayPanel);
4849+ }
4850+
4851+ private void loadURL(URL url)
4852+ {
4853+ boolean verbose = cmCheck_verbose.isSelected();
4854+
4855+// SVGUniverse universe = new SVGUniverse();
4856+ SVGUniverse universe = SVGCache.getSVGUniverse();
4857+ SVGDiagram diagram = null;
4858+ URI uri;
4859+
4860+ if (!CheckBoxMenuItem_anonInputStream.isSelected())
4861+ {
4862+ //Load from a disk with a valid URL
4863+ uri = universe.loadSVG(url);
4864+
4865+ if (verbose) System.err.println("Loading document " + uri.toString());
4866+
4867+ diagram = universe.getDiagram(uri);
4868+ }
4869+ else
4870+ {
4871+ //Load from a stream with no particular valid URL
4872+ try
4873+ {
4874+ InputStream is = url.openStream();
4875+ uri = universe.loadSVG(is, "defaultName");
4876+
4877+ if (verbose) System.err.println("Loading document " + uri.toString());
4878+ }
4879+ catch (Exception e)
4880+ {
4881+ e.printStackTrace();
4882+ return;
4883+ }
4884+ }
4885+/*
4886+ByteArrayOutputStream bs = new ByteArrayOutputStream();
4887+ObjectOutputStream os = new ObjectOutputStream(bs);
4888+os.writeObject(universe);
4889+os.close();
4890+
4891+ByteArrayInputStream bin = new ByteArrayInputStream(bs.toByteArray());
4892+ObjectInputStream is = new ObjectInputStream(bin);
4893+universe = (SVGUniverse)is.readObject();
4894+is.close();
4895+*/
4896+
4897+ diagram = universe.getDiagram(uri);
4898+
4899+ svgDisplayPanel.setDiagram(diagram);
4900+ repaint();
4901+ }
4902+
4903+ /** This method is called from within the constructor to
4904+ * initialize the form.
4905+ * WARNING: Do NOT modify this code. The content of this method is
4906+ * always regenerated by the Form Editor.
4907+ */
4908+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
4909+ private void initComponents()
4910+ {
4911+ scrollPane_svgArea = new javax.swing.JScrollPane();
4912+ panel_svgArea = new javax.swing.JPanel();
4913+ jMenuBar1 = new javax.swing.JMenuBar();
4914+ menu_file = new javax.swing.JMenu();
4915+ cm_loadFile = new javax.swing.JMenuItem();
4916+ cm_loadUrl = new javax.swing.JMenuItem();
4917+ menu_window = new javax.swing.JMenu();
4918+ cm_800x600 = new javax.swing.JMenuItem();
4919+ CheckBoxMenuItem_anonInputStream = new javax.swing.JCheckBoxMenuItem();
4920+ cmCheck_verbose = new javax.swing.JCheckBoxMenuItem();
4921+ menu_help = new javax.swing.JMenu();
4922+ cm_about = new javax.swing.JMenuItem();
4923+
4924+ setTitle("SVG Viewer - Salamander Project");
4925+ addWindowListener(new java.awt.event.WindowAdapter()
4926+ {
4927+ public void windowClosing(java.awt.event.WindowEvent evt)
4928+ {
4929+ exitForm(evt);
4930+ }
4931+ });
4932+
4933+ panel_svgArea.setLayout(new java.awt.BorderLayout());
4934+
4935+ panel_svgArea.addMouseListener(new java.awt.event.MouseAdapter()
4936+ {
4937+ public void mousePressed(java.awt.event.MouseEvent evt)
4938+ {
4939+ panel_svgAreaMousePressed(evt);
4940+ }
4941+ public void mouseReleased(java.awt.event.MouseEvent evt)
4942+ {
4943+ panel_svgAreaMouseReleased(evt);
4944+ }
4945+ });
4946+
4947+ scrollPane_svgArea.setViewportView(panel_svgArea);
4948+
4949+ getContentPane().add(scrollPane_svgArea, java.awt.BorderLayout.CENTER);
4950+
4951+ menu_file.setMnemonic('f');
4952+ menu_file.setText("File");
4953+ cm_loadFile.setMnemonic('l');
4954+ cm_loadFile.setText("Load File...");
4955+ cm_loadFile.addActionListener(new java.awt.event.ActionListener()
4956+ {
4957+ public void actionPerformed(java.awt.event.ActionEvent evt)
4958+ {
4959+ cm_loadFileActionPerformed(evt);
4960+ }
4961+ });
4962+
4963+ menu_file.add(cm_loadFile);
4964+
4965+ cm_loadUrl.setText("Load URL...");
4966+ cm_loadUrl.addActionListener(new java.awt.event.ActionListener()
4967+ {
4968+ public void actionPerformed(java.awt.event.ActionEvent evt)
4969+ {
4970+ cm_loadUrlActionPerformed(evt);
4971+ }
4972+ });
4973+
4974+ menu_file.add(cm_loadUrl);
4975+
4976+ jMenuBar1.add(menu_file);
4977+
4978+ menu_window.setText("Window");
4979+ cm_800x600.setText("800 x 600");
4980+ cm_800x600.addActionListener(new java.awt.event.ActionListener()
4981+ {
4982+ public void actionPerformed(java.awt.event.ActionEvent evt)
4983+ {
4984+ cm_800x600ActionPerformed(evt);
4985+ }
4986+ });
4987+
4988+ menu_window.add(cm_800x600);
4989+
4990+ CheckBoxMenuItem_anonInputStream.setText("Anonymous Input Stream");
4991+ menu_window.add(CheckBoxMenuItem_anonInputStream);
4992+
4993+ cmCheck_verbose.setText("Verbose");
4994+ cmCheck_verbose.addActionListener(new java.awt.event.ActionListener()
4995+ {
4996+ public void actionPerformed(java.awt.event.ActionEvent evt)
4997+ {
4998+ cmCheck_verboseActionPerformed(evt);
4999+ }
5000+ });
5001+
5002+ menu_window.add(cmCheck_verbose);
5003+
5004+ jMenuBar1.add(menu_window);
5005+
5006+ menu_help.setText("Help");
5007+ cm_about.setText("About...");
5008+ cm_about.addActionListener(new java.awt.event.ActionListener()
5009+ {
5010+ public void actionPerformed(java.awt.event.ActionEvent evt)
5011+ {
5012+ cm_aboutActionPerformed(evt);
5013+ }
5014+ });
5015+
5016+ menu_help.add(cm_about);
5017+
5018+ jMenuBar1.add(menu_help);
5019+
5020+ setJMenuBar(jMenuBar1);
5021+
5022+ pack();
5023+ }// </editor-fold>//GEN-END:initComponents
5024+
5025+ private void cm_loadUrlActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadUrlActionPerformed
5026+ {//GEN-HEADEREND:event_cm_loadUrlActionPerformed
5027+ String urlStrn = JOptionPane.showInputDialog(this, "Enter URL of SVG file");
5028+ if (urlStrn == null) return;
5029+
5030+ try
5031+ {
5032+ URL url = new URL(URLEncoder.encode(urlStrn, "UTF-8"));
5033+ loadURL(url);
5034+ }
5035+ catch (Exception e)
5036+ {
5037+ e.printStackTrace();
5038+ }
5039+
5040+ }//GEN-LAST:event_cm_loadUrlActionPerformed
5041+
5042+ private void panel_svgAreaMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_panel_svgAreaMouseReleased
5043+ {//GEN-HEADEREND:event_panel_svgAreaMouseReleased
5044+ SVGDiagram diagram = svgDisplayPanel.getDiagram();
5045+ List pickedElements;
5046+ try
5047+ {
5048+ pickedElements = diagram.pick(new Point(evt.getX(), evt.getY()), null);
5049+ }
5050+ catch (SVGException ex)
5051+ {
5052+ ex.printStackTrace();
5053+ return;
5054+ }
5055+
5056+ System.out.println("Pick results:");
5057+ for (Iterator it = pickedElements.iterator(); it.hasNext();)
5058+ {
5059+ ArrayList path = (ArrayList)it.next();
5060+
5061+ System.out.print(" Path: ");
5062+
5063+ for (Iterator it2 = path.iterator(); it2.hasNext();)
5064+ {
5065+ SVGElement ele = (SVGElement)it2.next();
5066+
5067+ System.out.print("" + ele.getId() + "(" + ele.getClass().getName() + ") ");
5068+ }
5069+ System.out.println();
5070+ }
5071+ }//GEN-LAST:event_panel_svgAreaMouseReleased
5072+
5073+ private void panel_svgAreaMousePressed(java.awt.event.MouseEvent evt)//GEN-FIRST:event_panel_svgAreaMousePressed
5074+ {//GEN-HEADEREND:event_panel_svgAreaMousePressed
5075+
5076+ }//GEN-LAST:event_panel_svgAreaMousePressed
5077+
5078+ private void cmCheck_verboseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cmCheck_verboseActionPerformed
5079+ {//GEN-HEADEREND:event_cmCheck_verboseActionPerformed
5080+ SVGCache.getSVGUniverse().setVerbose(cmCheck_verbose.isSelected());
5081+ }//GEN-LAST:event_cmCheck_verboseActionPerformed
5082+
5083+ private void cm_aboutActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_aboutActionPerformed
5084+ {//GEN-HEADEREND:event_cm_aboutActionPerformed
5085+ //JOptionPane.showMessageDialog(this, "Salamander SVG - Created by Mark McKay\nhttp://www.kitfox.com");
5086+ VersionDialog dlg = new VersionDialog(this, true, cmCheck_verbose.isSelected());
5087+ dlg.setVisible(true);
5088+ }//GEN-LAST:event_cm_aboutActionPerformed
5089+
5090+ private void cm_800x600ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cm_800x600ActionPerformed
5091+ setSize(800, 600);
5092+ }//GEN-LAST:event_cm_800x600ActionPerformed
5093+
5094+ private void cm_loadFileActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadFileActionPerformed
5095+ {//GEN-HEADEREND:event_cm_loadFileActionPerformed
5096+ try
5097+ {
5098+ int retVal = fileChooser.showOpenDialog(this);
5099+ if (retVal == JFileChooser.APPROVE_OPTION)
5100+ {
5101+ File chosenFile = fileChooser.getSelectedFile();
5102+
5103+ URL url = chosenFile.toURI().toURL();
5104+
5105+ loadURL(url);
5106+ }
5107+ }
5108+ /*
5109+ catch (IOException ioe)
5110+ {
5111+ try
5112+ {
5113+ //We may be in a WebStart app. Try again with a FileOpenService
5114+ FileContents fc = fileOpenService.openFileDialog(null, new String[]{"svg"});
5115+ InputStream is = fc.getInputStream();
5116+ String name = fc.getName();
5117+ }
5118+ catch (Exception e)
5119+ {
5120+ e.printStackTrace();
5121+ }
5122+ }
5123+ */
5124+ catch (Exception e)
5125+ {
5126+ e.printStackTrace();
5127+ }
5128+
5129+ }//GEN-LAST:event_cm_loadFileActionPerformed
5130+
5131+ /** Exit the Application */
5132+ private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
5133+// setVisible(false);
5134+// dispose();
5135+ System.exit(0);
5136+ }//GEN-LAST:event_exitForm
5137+
5138+ /**
5139+ * @param args the command line arguments
5140+ */
5141+ public static void main(String args[]) {
5142+ new SVGViewer().setVisible(true);
5143+ }
5144+
5145+ // Variables declaration - do not modify//GEN-BEGIN:variables
5146+ private javax.swing.JCheckBoxMenuItem CheckBoxMenuItem_anonInputStream;
5147+ private javax.swing.JCheckBoxMenuItem cmCheck_verbose;
5148+ private javax.swing.JMenuItem cm_800x600;
5149+ private javax.swing.JMenuItem cm_about;
5150+ private javax.swing.JMenuItem cm_loadFile;
5151+ private javax.swing.JMenuItem cm_loadUrl;
5152+ private javax.swing.JMenuBar jMenuBar1;
5153+ private javax.swing.JMenu menu_file;
5154+ private javax.swing.JMenu menu_help;
5155+ private javax.swing.JMenu menu_window;
5156+ private javax.swing.JPanel panel_svgArea;
5157+ private javax.swing.JScrollPane scrollPane_svgArea;
5158+ // End of variables declaration//GEN-END:variables
5159+
5160+}
5161Index: core/src/com/kitfox/svg/app/VersionDialog.java
[4256]5162===================================================================
[5284]5163--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5164+++ core/src/com/kitfox/svg/app/VersionDialog.java 2012-06-17 23:56:57.752545052 +0200
5165@@ -0,0 +1,151 @@
5166+/*
5167+ * VersionDialog.java
5168+ *
5169+ *
5170+ * The Salamander Project - 2D and 3D graphics libraries in Java
5171+ * Copyright (C) 2004 Mark McKay
5172+ *
5173+ * This library is free software; you can redistribute it and/or
5174+ * modify it under the terms of the GNU Lesser General Public
5175+ * License as published by the Free Software Foundation; either
5176+ * version 2.1 of the License, or (at your option) any later version.
5177+ *
5178+ * This library is distributed in the hope that it will be useful,
5179+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5180+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5181+ * Lesser General Public License for more details.
5182+ *
5183+ * You should have received a copy of the GNU Lesser General Public
5184+ * License along with this library; if not, write to the Free Software
5185+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5186+ *
5187+ * Mark McKay can be contacted at mark@kitfox.com. Salamander and other
5188+ * projects can be found at http://www.kitfox.com
5189+ *
5190+ * Created on January 13, 2005, 7:23 AM
5191+ */
5192+
5193+package com.kitfox.svg.app;
5194+
5195+import java.net.*;
5196+import java.io.*;
5197+import java.util.*;
5198+import javax.swing.event.*;
5199+import javax.swing.*;
5200+import javax.swing.text.html.*;
5201+
5202+
5203+/**
5204+ *
5205+ * @author kitfox
5206+ */
5207+public class VersionDialog extends javax.swing.JDialog
5208+{
5209+ public static final long serialVersionUID = 1;
5210+
5211+ final boolean verbose;
5212+
5213+ /** Creates new form VersionDialog */
5214+ public VersionDialog(java.awt.Frame parent, boolean modal, boolean verbose)
5215+ {
5216+ super(parent, modal);
5217+ initComponents();
5218+
5219+ this.verbose = verbose;
5220+
5221+ textpane_text.setContentType("text/html");
5222+
5223+ StringBuffer sb = new StringBuffer();
5224+ try
5225+ {
5226+ URL url = getClass().getResource("/res/help/about/about.html");
5227+ if (verbose)
5228+ {
5229+ System.err.println("" + getClass() + " trying to load about html " + url);
5230+ }
5231+
5232+ BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
5233+ while (true)
5234+ {
5235+ String line = reader.readLine();
5236+ if (line == null) break;
5237+ sb.append(line);
5238+ }
5239+
5240+ textpane_text.setText(sb.toString());
5241+ }
5242+ catch (Exception e)
5243+ {
5244+ e.printStackTrace();
5245+ }
5246+
5247+ }
5248+
5249+ /** This method is called from within the constructor to
5250+ * initialize the form.
5251+ * WARNING: Do NOT modify this code. The content of this method is
5252+ * always regenerated by the Form Editor.
5253+ */
5254+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
5255+ private void initComponents()
5256+ {
5257+ jPanel1 = new javax.swing.JPanel();
5258+ textpane_text = new javax.swing.JTextPane();
5259+ jPanel2 = new javax.swing.JPanel();
5260+ bn_close = new javax.swing.JButton();
5261+
5262+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
5263+ setTitle("About SVG Salamander");
5264+ jPanel1.setLayout(new java.awt.BorderLayout());
5265+
5266+ textpane_text.setEditable(false);
5267+ textpane_text.setPreferredSize(new java.awt.Dimension(400, 300));
5268+ jPanel1.add(textpane_text, java.awt.BorderLayout.CENTER);
5269+
5270+ getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
5271+
5272+ bn_close.setText("Close");
5273+ bn_close.addActionListener(new java.awt.event.ActionListener()
5274+ {
5275+ public void actionPerformed(java.awt.event.ActionEvent evt)
5276+ {
5277+ bn_closeActionPerformed(evt);
5278+ }
5279+ });
5280+
5281+ jPanel2.add(bn_close);
5282+
5283+ getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);
5284+
5285+ pack();
5286+ }
5287+ // </editor-fold>//GEN-END:initComponents
5288+
5289+ private void bn_closeActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_closeActionPerformed
5290+ {//GEN-HEADEREND:event_bn_closeActionPerformed
5291+ setVisible(false);
5292+ dispose();
5293+ }//GEN-LAST:event_bn_closeActionPerformed
5294+
5295+ /**
5296+ * @param args the command line arguments
5297+ */
5298+ public static void main(String args[])
5299+ {
5300+ java.awt.EventQueue.invokeLater(new Runnable()
5301+ {
5302+ public void run()
5303+ {
5304+ new VersionDialog(new javax.swing.JFrame(), true, true).setVisible(true);
5305+ }
5306+ });
5307+ }
5308+
5309+ // Variables declaration - do not modify//GEN-BEGIN:variables
5310+ private javax.swing.JButton bn_close;
5311+ private javax.swing.JPanel jPanel1;
5312+ private javax.swing.JPanel jPanel2;
5313+ private javax.swing.JTextPane textpane_text;
5314+ // End of variables declaration//GEN-END:variables
5315+
5316+}
5317Index: core/src/com/kitfox/svg/app/ant/SVGToImageAntTask.java
[4256]5318===================================================================
[5284]5319--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5320+++ core/src/com/kitfox/svg/app/ant/SVGToImageAntTask.java 2012-06-17 23:56:57.752545052 +0200
5321@@ -0,0 +1,251 @@
5322+/*
5323+ * IndexLoadObjectsAntTask.java
5324+ *
5325+ * Created on January 22, 2005, 10:30 AM
5326+ */
5327+
5328+package com.kitfox.svg.app.ant;
5329+
5330+import java.awt.*;
5331+import java.awt.image.*;
5332+import java.util.*;
5333+import java.util.regex.*;
5334+import java.io.*;
5335+import javax.imageio.*;
5336+
5337+//import com.kitfox.util.*;
5338+//import com.kitfox.util.indexedObject.*;
5339+
5340+import org.apache.tools.ant.*;
5341+import org.apache.tools.ant.types.*;
5342+
5343+import com.kitfox.svg.app.beans.*;
5344+import com.kitfox.svg.*;
5345+import com.kitfox.svg.xml.ColorTable;
5346+
5347+/**
5348+ * <p>Translates a group of SVG files into images.</p>
5349+ *
5350+ * <p>Parameters:</p>
5351+ * <p><ul>
5352+ * <li/>destDir - If present, specifices a directory to write SVG files to. Otherwise
5353+ * writes images to directory SVG file was found in
5354+ * verbose - If true, prints processing information to the console
5355+ * <li/>format - File format for output images. The java core javax.imageio.ImageIO
5356+ * class is used for creating images, so format strings will depend on what
5357+ * files your system is configured to handle. By default, "gif", "jpg" and "png"
5358+ * files are guaranteed to be present. If omitted, "png" is used by default.
5359+ * <li/>backgroundColor - Optional background color. Color can be specified as a standard
5360+ * HTML color. That is, as the name of a standard color such as "blue" or
5361+ * "limegreen", using the # notaion as in #ff00ff for magenta, or in rgb format
5362+ * listing the components as in rgb(255, 192, 192) for pink. If omitted,
5363+ * background is transparent.
5364+ * <li/>antiAlias - If set, shapes are drawn using antialiasing. Defaults to true.
5365+ * <li/>interpolation - String describing image interpolation alrogithm. Can
5366+ * be one of "nearest neighbor", "bilinear" or "bicubic". Defaults to "bicubic".
5367+ * <li/>width - If greater than 0, determines the width of the written image. Otherwise,
5368+ * the width is obtained from the SVG document. Defaults to -1;
5369+ * <li/>height - If greater than 0, determines the height of the written image. Otherwise,
5370+ * the height is obtained from the SVG document. Defaults to -1.
5371+ * <li/>sizeToFit - If true and the width and height of the output image differ
5372+ * from that of the SVG image, the valid area of the SVG image will be resized
5373+ * to fit the specified size.
5374+ * <li/>verbose - IF true, prints out diagnostic infromation about processing.
5375+ * Defaults to false.
5376+ * </ul></p>
5377+ *
5378+ * Example:
5379+ * &lt;SVGToImage destDir="${index.java}" format="jpg" verbose="true"&gt;
5380+ * &lt;fileset dir="${dir1}"&gt;
5381+ * &lt;include name="*.svg"/&gt;
5382+ * &lt;/fileset&gt;
5383+ * &lt;fileset dir="${dir2}"&gt;
5384+ * &lt;include name="*.svg"/&gt;
5385+ * &lt;/fileset&gt;
5386+ * &lt;/SVGToImage&gt;
5387+ *
5388+ *
5389+ *
5390+ * @author kitfox
5391+ */
5392+public class SVGToImageAntTask extends Task
5393+{
5394+ private ArrayList filesets = new ArrayList();
5395+ boolean verbose = false;
5396+ File destDir;
5397+ private String format = "png";
5398+ Color backgroundColor = null;
5399+ int width = -1;
5400+ int height = -1;
5401+ boolean antiAlias = true;
5402+ String interpolation = "bicubic";
5403+ boolean clipToViewBox = false;
5404+ boolean sizeToFit = true;
5405+
5406+ /** Creates a new instance of IndexLoadObjectsAntTask */
5407+ public SVGToImageAntTask()
5408+ {
5409+ }
5410+
5411+
5412+ public String getFormat()
5413+ {
5414+ return format;
5415+ }
5416+
5417+ public void setFormat(String format)
5418+ {
5419+ this.format = format;
5420+ }
5421+
5422+ public void setBackgroundColor(String bgColor)
5423+ {
5424+ this.backgroundColor = ColorTable.parseColor(bgColor);
5425+ }
5426+
5427+ public void setHeight(int height)
5428+ {
5429+ this.height = height;
5430+ }
5431+
5432+ public void setWidth(int width)
5433+ {
5434+ this.width = width;
5435+ }
5436+
5437+ public void setAntiAlias(boolean antiAlias)
5438+ {
5439+ this.antiAlias = antiAlias;
5440+ }
5441+
5442+ public void setInterpolation(String interpolation)
5443+ {
5444+ this.interpolation = interpolation;
5445+ }
5446+
5447+ public void setSizeToFit(boolean sizeToFit)
5448+ {
5449+ this.sizeToFit = sizeToFit;
5450+ }
5451+
5452+ public void setClipToViewBox(boolean clipToViewBox)
5453+ {
5454+ this.clipToViewBox = clipToViewBox;
5455+ }
5456+
5457+ public void setVerbose(boolean verbose)
5458+ {
5459+ this.verbose = verbose;
5460+ }
5461+
5462+ public void setDestDir(File destDir)
5463+ {
5464+ this.destDir = destDir;
5465+ }
5466+
5467+ /**
5468+ * Adds a set of files.
5469+ */
5470+ public void addFileset(FileSet set)
5471+ {
5472+ filesets.add(set);
5473+ }
5474+
5475+
5476+
5477+ public void execute()
5478+ {
5479+ if (verbose) log("Building SVG images");
5480+
5481+ for (Iterator it = filesets.iterator(); it.hasNext();)
5482+ {
5483+ FileSet fs = (FileSet)it.next();
5484+ FileScanner scanner = fs.getDirectoryScanner(getProject());
5485+ String[] files = scanner.getIncludedFiles();
5486+
5487+ try
5488+ {
5489+ File basedir = scanner.getBasedir();
5490+
5491+ if (verbose) log("Scaning " + basedir);
5492+
5493+ for (int i = 0; i < files.length; i++)
5494+ {
5495+//System.out.println("File " + files[i]);
5496+//System.out.println("BaseDir " + basedir);
5497+ translate(basedir, files[i]);
5498+ }
5499+ }
5500+ catch (Exception e)
5501+ {
5502+ throw new BuildException(e);
5503+ }
5504+ }
5505+ }
5506+
5507+ private void translate(File baseDir, String shortName) throws BuildException
5508+ {
5509+ File source = new File(baseDir, shortName);
5510+
5511+ if (verbose) log("Reading file: " + source);
5512+
5513+ Matcher matchName = Pattern.compile("(.*)\\.svg", Pattern.CASE_INSENSITIVE).matcher(shortName);
5514+ if (matchName.matches())
5515+ {
5516+ shortName = matchName.group(1);
5517+ }
5518+ shortName += "." + format;
5519+
5520+ SVGIcon icon = new SVGIcon();
5521+ icon.setSvgURI(source.toURI());
5522+ icon.setAntiAlias(antiAlias);
5523+ if (interpolation.equals("nearest neighbor"))
5524+ {
5525+ icon.setInterpolation(SVGIcon.INTERP_NEAREST_NEIGHBOR);
5526+ }
5527+ else if (interpolation.equals("bilinear"))
5528+ {
5529+ icon.setInterpolation(SVGIcon.INTERP_BILINEAR);
5530+ }
5531+ else if (interpolation.equals("bicubic"))
5532+ {
5533+ icon.setInterpolation(SVGIcon.INTERP_BICUBIC);
5534+ }
5535+
5536+ int iconWidth = width > 0 ? width : icon.getIconWidth();
5537+ int iconHeight = height > 0 ? height : icon.getIconHeight();
5538+ icon.setClipToViewbox(clipToViewBox);
5539+ icon.setPreferredSize(new Dimension(iconWidth, iconHeight));
5540+ icon.setScaleToFit(sizeToFit);
5541+ BufferedImage image = new BufferedImage(iconWidth, iconHeight, BufferedImage.TYPE_INT_ARGB);
5542+ Graphics2D g = image.createGraphics();
5543+
5544+ if (backgroundColor != null)
5545+ {
5546+ g.setColor(backgroundColor);
5547+ g.fillRect(0, 0, iconWidth, iconHeight);
5548+ }
5549+
5550+ g.setClip(0, 0, iconWidth, iconHeight);
5551+// g.fillRect(10, 10, 100, 100);
5552+ icon.paintIcon(null, g, 0, 0);
5553+ g.dispose();
5554+
5555+ File outFile = destDir == null ? new File(baseDir, shortName) : new File(destDir, shortName);
5556+ if (verbose) log("Writing file: " + outFile);
5557+
5558+ try
5559+ {
5560+ ImageIO.write(image, format, outFile);
5561+ }
5562+ catch (IOException e)
5563+ {
5564+ log("Error writing image: " + e.getMessage());
5565+ throw new BuildException(e);
5566+ }
5567+
5568+
5569+ SVGCache.getSVGUniverse().clear();
5570+ }
5571+
5572+}
5573Index: core/src/com/kitfox/svg/app/beans/ProportionalLayoutPanel.java
[4256]5574===================================================================
[5284]5575--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5576+++ core/src/com/kitfox/svg/app/beans/ProportionalLayoutPanel.java 2012-06-17 23:56:57.784545052 +0200
5577@@ -0,0 +1,91 @@
5578+/*
5579+ * ProportionalLayoutPanel.java
5580+ *
5581+ * Created on May 7, 2005, 4:15 AM
5582+ */
5583+
5584+package com.kitfox.svg.app.beans;
5585+
5586+import java.awt.*;
5587+import java.util.*;
5588+import javax.swing.*;
5589+
5590+/**
5591+ * Panel based on the null layout. Allows editing with absolute layout. When
5592+ * instanced, records layout dimensions of all subcomponents. Then, if the
5593+ * panel is ever resized, scales all children to fit new size.
5594+ *
5595+ * @author kitfox
5596+ */
5597+public class ProportionalLayoutPanel extends javax.swing.JPanel
5598+{
5599+ public static final long serialVersionUID = 1;
5600+
5601+ //Margins to leave on sides of panel, expressed in fractions [0 1]
5602+ float topMargin;
5603+ float bottomMargin;
5604+ float leftMargin;
5605+ float rightMargin;
5606+
5607+ /** Creates new form ProportionalLayoutPanel */
5608+ public ProportionalLayoutPanel()
5609+ {
5610+ initComponents();
5611+ }
5612+
5613+ public void addNotify()
5614+ {
5615+ super.addNotify();
5616+
5617+ Rectangle rect = this.getBounds();
5618+ JOptionPane.showMessageDialog(this, "" + rect);
5619+ }
5620+
5621+
5622+ /** This method is called from within the constructor to
5623+ * initialize the form.
5624+ * WARNING: Do NOT modify this code. The content of this method is
5625+ * always regenerated by the Form Editor.
5626+ */
5627+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
5628+ private void initComponents()
5629+ {
5630+ jPanel1 = new javax.swing.JPanel();
5631+
5632+ setLayout(null);
5633+
5634+ addComponentListener(new java.awt.event.ComponentAdapter()
5635+ {
5636+ public void componentResized(java.awt.event.ComponentEvent evt)
5637+ {
5638+ formComponentResized(evt);
5639+ }
5640+ public void componentShown(java.awt.event.ComponentEvent evt)
5641+ {
5642+ formComponentShown(evt);
5643+ }
5644+ });
5645+
5646+ add(jPanel1);
5647+ jPanel1.setBounds(80, 90, 280, 160);
5648+
5649+ }
5650+ // </editor-fold>//GEN-END:initComponents
5651+
5652+ private void formComponentShown(java.awt.event.ComponentEvent evt)//GEN-FIRST:event_formComponentShown
5653+ {//GEN-HEADEREND:event_formComponentShown
5654+ JOptionPane.showMessageDialog(this, "" + getWidth() + ", " + getHeight());
5655+
5656+ }//GEN-LAST:event_formComponentShown
5657+
5658+ private void formComponentResized(java.awt.event.ComponentEvent evt)//GEN-FIRST:event_formComponentResized
5659+ {//GEN-HEADEREND:event_formComponentResized
5660+// TODO add your handling code here:
5661+ }//GEN-LAST:event_formComponentResized
5662+
5663+
5664+ // Variables declaration - do not modify//GEN-BEGIN:variables
5665+ private javax.swing.JPanel jPanel1;
5666+ // End of variables declaration//GEN-END:variables
5667+
5668+}
5669Index: core/src/com/kitfox/svg/app/beans/SVGPanel.java
[4256]5670===================================================================
[5284]5671--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5672+++ core/src/com/kitfox/svg/app/beans/SVGPanel.java 2012-06-17 23:56:57.784545052 +0200
5673@@ -0,0 +1,243 @@
5674+/*
5675+ * SVGIcon.java
5676+ *
5677+ * Created on April 21, 2005, 10:43 AM
5678+ */
5679+
5680+package com.kitfox.svg.app.beans;
5681+
5682+import javax.swing.*;
5683+import java.awt.*;
5684+import java.awt.geom.*;
5685+import java.net.*;
5686+import java.beans.*;
5687+
5688+import com.kitfox.svg.*;
5689+
5690+/**
5691+ *
5692+ * @author kitfox
5693+ */
5694+public class SVGPanel extends JPanel
5695+{
5696+ public static final long serialVersionUID = 1;
5697+
5698+
5699+ SVGUniverse svgUniverse = SVGCache.getSVGUniverse();
5700+
5701+ private boolean antiAlias;
5702+
5703+// private String svgPath;
5704+ URI svgURI;
5705+
5706+ private boolean scaleToFit;
5707+ AffineTransform scaleXform = new AffineTransform();
5708+
5709+ /** Creates new form SVGIcon */
5710+ public SVGPanel()
5711+ {
5712+ initComponents();
5713+ }
5714+
5715+ public int getSVGHeight()
5716+ {
5717+ if (scaleToFit) return getPreferredSize().height;
5718+
5719+ SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
5720+ if (diagram == null) return 0;
5721+ return (int)diagram.getHeight();
5722+ }
5723+
5724+ public int getSVGWidth()
5725+ {
5726+ if (scaleToFit) return getPreferredSize().width;
5727+
5728+ SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
5729+ if (diagram == null) return 0;
5730+ return (int)diagram.getWidth();
5731+ }
5732+
5733+// Draw the icon at the specified location.
5734+ public void paintComponent(Graphics gg)
5735+ {
5736+ super.paintComponent(gg);
5737+
5738+ Graphics2D g = (Graphics2D)gg;
5739+
5740+ Object oldAliasHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
5741+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
5742+
5743+
5744+ SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
5745+ if (diagram == null) return;
5746+
5747+ if (!scaleToFit)
5748+ {
5749+ try
5750+ {
5751+ diagram.render(g);
5752+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
5753+ }
5754+ catch (SVGException e)
5755+ {
5756+ throw new RuntimeException(e);
5757+ }
5758+ return;
5759+ }
5760+
5761+ Dimension dim = getSize();
5762+ final int width = dim.width;
5763+ final int height = dim.height;
5764+// int width = getWidth();
5765+// int height = getHeight();
5766+
5767+// if (width == 0 || height == 0)
5768+// {
5769+// //Chances are we're rendering offscreen
5770+// Dimension dim = getSize();
5771+// width = dim.width;
5772+// height = dim.height;
5773+// return;
5774+// }
5775+
5776+// g.setClip(0, 0, dim.width, dim.height);
5777+
5778+
5779+ final Rectangle2D.Double rect = new Rectangle2D.Double();
5780+ diagram.getViewRect(rect);
5781+
5782+ scaleXform.setToScale(width / rect.width, height / rect.height);
5783+
5784+ AffineTransform oldXform = g.getTransform();
5785+ g.transform(scaleXform);
5786+
5787+ try
5788+ {
5789+ diagram.render(g);
5790+ }
5791+ catch (SVGException e)
5792+ {
5793+ throw new RuntimeException(e);
5794+ }
5795+
5796+ g.setTransform(oldXform);
5797+
5798+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
5799+ }
5800+
5801+ public SVGUniverse getSvgUniverse()
5802+ {
5803+ return svgUniverse;
5804+ }
5805+
5806+ public void setSvgUniverse(SVGUniverse svgUniverse)
5807+ {
5808+ SVGUniverse old = this.svgUniverse;
5809+ this.svgUniverse = svgUniverse;
5810+ firePropertyChange("svgUniverse", old, svgUniverse);
5811+ }
5812+
5813+ public URI getSvgURI()
5814+ {
5815+ return svgURI;
5816+ }
5817+
5818+ public void setSvgURI(URI svgURI)
5819+ {
5820+ URI old = this.svgURI;
5821+ this.svgURI = svgURI;
5822+ firePropertyChange("svgURI", old, svgURI);
5823+ }
5824+
5825+ /**
5826+ * Most resources your component will want to access will be resources on your classpath.
5827+ * This method will interpret the passed string as a path in the classpath and use
5828+ * Class.getResource() to determine the URI of the SVG.
5829+ */
5830+ public void setSvgResourcePath(String resourcePath) throws SVGException
5831+ {
5832+ URI old = this.svgURI;
5833+
5834+ try
5835+ {
5836+ svgURI = new URI(getClass().getResource(resourcePath).toString());
5837+//System.err.println("SVGPanel: new URI " + svgURI + " from path " + resourcePath);
5838+
5839+ firePropertyChange("svgURI", old, svgURI);
5840+
5841+ repaint();
5842+ }
5843+ catch (Exception e)
5844+ {
5845+ throw new SVGException("Could not resolve path " + resourcePath, e);
5846+// svgURI = old;
5847+ }
5848+ }
5849+
5850+ public boolean isScaleToFit()
5851+ {
5852+ return scaleToFit;
5853+ }
5854+
5855+ public void setScaleToFit(boolean scaleToFit)
5856+ {
5857+ boolean old = this.scaleToFit;
5858+ this.scaleToFit = scaleToFit;
5859+ firePropertyChange("scaleToFit", old, scaleToFit);
5860+ }
5861+
5862+ /**
5863+ * @return true if antiAliasing is turned on.
5864+ * @deprecated
5865+ */
5866+ public boolean getUseAntiAlias()
5867+ {
5868+ return getAntiAlias();
5869+ }
5870+
5871+ /**
5872+ * @param antiAlias true to use antiAliasing.
5873+ * @deprecated
5874+ */
5875+ public void setUseAntiAlias(boolean antiAlias)
5876+ {
5877+ setAntiAlias(antiAlias);
5878+ }
5879+
5880+ /**
5881+ * @return true if antiAliasing is turned on.
5882+ */
5883+ public boolean getAntiAlias()
5884+ {
5885+ return antiAlias;
5886+ }
5887+
5888+ /**
5889+ * @param antiAlias true to use antiAliasing.
5890+ */
5891+ public void setAntiAlias(boolean antiAlias)
5892+ {
5893+ boolean old = this.antiAlias;
5894+ this.antiAlias = antiAlias;
5895+ firePropertyChange("antiAlias", old, antiAlias);
5896+ }
5897+
5898+ /** This method is called from within the constructor to
5899+ * initialize the form.
5900+ * WARNING: Do NOT modify this code. The content of this method is
5901+ * always regenerated by the Form Editor.
5902+ */
5903+ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
5904+ private void initComponents()
5905+ {
5906+
5907+ setLayout(new java.awt.BorderLayout());
5908+
5909+ }
5910+ // </editor-fold>//GEN-END:initComponents
5911+
5912+
5913+ // Variables declaration - do not modify//GEN-BEGIN:variables
5914+ // End of variables declaration//GEN-END:variables
5915+
5916+}
5917Index: core/src/com/kitfox/svg/app/data/HandlerFactory.java
[4256]5918===================================================================
[5284]5919--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5920+++ core/src/com/kitfox/svg/app/data/HandlerFactory.java 2012-06-17 23:56:57.784545052 +0200
5921@@ -0,0 +1,27 @@
5922+/*
5923+ * To change this template, choose Tools | Templates
5924+ * and open the template in the editor.
5925+ */
5926+
5927+package com.kitfox.svg.app.data;
5928+
5929+import java.net.URLStreamHandler;
5930+import java.net.URLStreamHandlerFactory;
5931+
5932+/**
5933+ *
5934+ * @author kitfox
5935+ */
5936+public class HandlerFactory implements URLStreamHandlerFactory
5937+{
5938+ static Handler handler = new Handler();
5939+
5940+ public URLStreamHandler createURLStreamHandler(String protocol)
5941+ {
5942+ if ("data".equals(protocol))
5943+ {
5944+ return handler;
5945+ }
5946+ return null;
5947+ }
5948+}
Note: See TracBrowser for help on using the repository browser.