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

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

reverse patches, so they are easier to use in quilt

File size: 200.6 KB
  • new file core/src/com/kitfox/svg/animation/Animate.java

    Patch 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.
    - +  
     1/*
     2 * Animate.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 2:51 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.SVGElement;
     30import com.kitfox.svg.SVGException;
     31import com.kitfox.svg.SVGLoaderHelper;
     32import com.kitfox.svg.animation.parser.AnimTimeParser;
     33import com.kitfox.svg.xml.ColorTable;
     34import com.kitfox.svg.xml.StyleAttribute;
     35import com.kitfox.svg.xml.XMLParseUtil;
     36import java.awt.Color;
     37import java.awt.geom.AffineTransform;
     38import java.awt.geom.GeneralPath;
     39import java.awt.geom.PathIterator;
     40import org.xml.sax.Attributes;
     41import org.xml.sax.SAXException;
     42
     43
     44/**
     45 * Animate is a really annoying morphic tag that could represent a real value,
     46 * a color or a path
     47 *
     48 * @author Mark McKay
     49 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     50 */
     51public class Animate extends AnimateBase implements AnimateColorIface
     52{
     53//    StyleAttribute retAttrib = new StyleAttribute
     54    public static final int DT_REAL = 0;
     55    public static final int DT_COLOR = 1;
     56    public static final int DT_PATH = 2;
     57    int dataType = DT_REAL;
     58   
     59    protected double fromValue = Double.NaN;
     60    protected double toValue = Double.NaN;
     61    protected double byValue = Double.NaN;
     62    protected double[] valuesValue;
     63   
     64    protected Color fromColor = null;
     65    protected Color toColor = null;
     66
     67    protected GeneralPath fromPath = null;
     68    protected GeneralPath toPath = null;
     69
     70    /** Creates a new instance of Animate */
     71    public Animate()
     72    {
     73    }
     74   
     75    public int getDataType()
     76    {
     77        return dataType;
     78    }
     79   
     80    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     81    {
     82                //Load style string
     83        super.loaderStartElement(helper, attrs, parent);
     84
     85        String strn = attrs.getValue("from");
     86        if (strn != null)
     87        {
     88            if (XMLParseUtil.isDouble(strn))
     89            {
     90                fromValue = XMLParseUtil.parseDouble(strn);
     91            }
     92//            else if (attrs.getValue("attributeName").equals("d"))
     93//            {
     94//                fromPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
     95//                dataType = DT_PATH;
     96//            }
     97            else
     98            {
     99                fromColor = ColorTable.parseColor(strn);
     100                if (fromColor == null)
     101                {
     102                    //Try path
     103                    fromPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
     104                    dataType = DT_PATH;
     105                }
     106                else dataType = DT_COLOR;
     107            }
     108        }
     109
     110        strn = attrs.getValue("to");
     111        if (strn != null)
     112        {
     113            if (XMLParseUtil.isDouble(strn))
     114            {
     115                toValue = XMLParseUtil.parseDouble(strn);
     116            }
     117            else
     118            {
     119                toColor = ColorTable.parseColor(strn);
     120                if (toColor == null)
     121                {
     122                    //Try path
     123                    toPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
     124                    dataType = DT_PATH;
     125                }
     126                else dataType = DT_COLOR;
     127            }
     128        }
     129
     130        strn = attrs.getValue("by");
     131        try
     132        {
     133            if (strn != null) byValue = XMLParseUtil.parseDouble(strn);
     134        } catch (Exception e) {}
     135
     136        strn = attrs.getValue("values");
     137        try
     138        {
     139            if (strn != null) valuesValue = XMLParseUtil.parseDoubleList(strn);
     140        } catch (Exception e) {}
     141    }
     142   
     143    /**
     144     * Evaluates this animation element for the passed interpolation time.  Interp
     145     * must be on [0..1].
     146     */
     147    public double eval(double interp)
     148    {
     149        boolean fromExists = !Double.isNaN(fromValue);
     150        boolean toExists = !Double.isNaN(toValue);
     151        boolean byExists = !Double.isNaN(byValue);
     152        boolean valuesExists = valuesValue != null;
     153       
     154        if (valuesExists)
     155        {
     156            double sp = interp * valuesValue.length;
     157            int ip = (int)sp;
     158            double fp = sp - ip;
     159           
     160            int i0 = ip;
     161            int i1 = ip + 1;
     162           
     163            if (i0 < 0) return valuesValue[0];
     164            if (i1 >= valuesValue.length) return valuesValue[valuesValue.length - 1];
     165            return valuesValue[i0] * (1 - fp) + valuesValue[i1] * fp;
     166        }
     167        else if (fromExists && toExists)
     168        {
     169            return toValue * interp + fromValue * (1.0 - interp);
     170        }
     171        else if (fromExists && byExists)
     172        {
     173            return fromValue + byValue * interp;
     174        }
     175        else if (toExists && byExists)
     176        {
     177            return toValue - byValue * (1.0 - interp);
     178        }
     179        else if (byExists)
     180        {
     181            return byValue * interp;
     182        }
     183 
     184        //Should not reach this line
     185        throw new RuntimeException("Animate tag could not be evalutated - insufficient arguements");
     186    }
     187
     188    public Color evalColor(double interp)
     189    {
     190        if (fromColor == null && toColor != null)
     191        {
     192            float[] toCol = new float[3];
     193            toColor.getColorComponents(toCol);
     194            return new Color(toCol[0] * (float)interp,
     195                toCol[1] * (float)interp,
     196                toCol[2] * (float)interp);
     197        }
     198        else if (fromColor != null && toColor != null)
     199        {
     200            float nInterp = 1 - (float)interp;
     201           
     202            float[] fromCol = new float[3];
     203            float[] toCol = new float[3];
     204            fromColor.getColorComponents(fromCol);
     205            toColor.getColorComponents(toCol);
     206            return new Color(fromCol[0] * nInterp + toCol[0] * (float)interp,
     207                fromCol[1] * nInterp + toCol[1] * (float)interp,
     208                fromCol[2] * nInterp + toCol[2] * (float)interp);
     209        }
     210       
     211        throw new RuntimeException("Animate tag could not be evalutated - insufficient arguements");
     212    }
     213
     214    public GeneralPath evalPath(double interp)
     215    {
     216        if (fromPath == null && toPath != null)
     217        {
     218            PathIterator itTo = toPath.getPathIterator(new AffineTransform());
     219           
     220            GeneralPath midPath = new GeneralPath();
     221            float[] coordsTo = new float[6];
     222           
     223            for (; !itTo.isDone(); itTo.next())
     224            {
     225                int segTo = itTo.currentSegment(coordsTo);
     226               
     227                switch (segTo)
     228                {
     229                    case PathIterator.SEG_CLOSE:
     230                        midPath.closePath();
     231                        break;
     232                    case PathIterator.SEG_CUBICTO:
     233                        midPath.curveTo(
     234                                (float)(coordsTo[0] * interp),
     235                                (float)(coordsTo[1] * interp),
     236                                (float)(coordsTo[2] * interp),
     237                                (float)(coordsTo[3] * interp),
     238                                (float)(coordsTo[4] * interp),
     239                                (float)(coordsTo[5] * interp)
     240                                );
     241                        break;
     242                    case PathIterator.SEG_LINETO:
     243                        midPath.lineTo(
     244                                (float)(coordsTo[0] * interp),
     245                                (float)(coordsTo[1] * interp)
     246                                );
     247                        break;
     248                    case PathIterator.SEG_MOVETO:
     249                        midPath.moveTo(
     250                                (float)(coordsTo[0] * interp),
     251                                (float)(coordsTo[1] * interp)
     252                                );
     253                        break;
     254                    case PathIterator.SEG_QUADTO:
     255                        midPath.quadTo(
     256                                (float)(coordsTo[0] * interp),
     257                                (float)(coordsTo[1] * interp),
     258                                (float)(coordsTo[2] * interp),
     259                                (float)(coordsTo[3] * interp)
     260                                );
     261                        break;
     262                }
     263            }
     264           
     265            return midPath;
     266        }
     267        else if (toPath != null)
     268        {
     269            PathIterator itFrom = fromPath.getPathIterator(new AffineTransform());
     270            PathIterator itTo = toPath.getPathIterator(new AffineTransform());
     271           
     272            GeneralPath midPath = new GeneralPath();
     273            float[] coordsFrom = new float[6];
     274            float[] coordsTo = new float[6];
     275           
     276            for (; !itFrom.isDone(); itFrom.next())
     277            {
     278                int segFrom = itFrom.currentSegment(coordsFrom);
     279                int segTo = itTo.currentSegment(coordsTo);
     280               
     281                if (segFrom != segTo)
     282                {
     283                    throw new RuntimeException("Path shape mismatch");
     284                }
     285               
     286                switch (segFrom)
     287                {
     288                    case PathIterator.SEG_CLOSE:
     289                        midPath.closePath();
     290                        break;
     291                    case PathIterator.SEG_CUBICTO:
     292                        midPath.curveTo(
     293                                (float)(coordsFrom[0] * (1 - interp) + coordsTo[0] * interp),
     294                                (float)(coordsFrom[1] * (1 - interp) + coordsTo[1] * interp),
     295                                (float)(coordsFrom[2] * (1 - interp) + coordsTo[2] * interp),
     296                                (float)(coordsFrom[3] * (1 - interp) + coordsTo[3] * interp),
     297                                (float)(coordsFrom[4] * (1 - interp) + coordsTo[4] * interp),
     298                                (float)(coordsFrom[5] * (1 - interp) + coordsTo[5] * interp)
     299                                );
     300                        break;
     301                    case PathIterator.SEG_LINETO:
     302                        midPath.lineTo(
     303                                (float)(coordsFrom[0] * (1 - interp) + coordsTo[0] * interp),
     304                                (float)(coordsFrom[1] * (1 - interp) + coordsTo[1] * interp)
     305                                );
     306                        break;
     307                    case PathIterator.SEG_MOVETO:
     308                        midPath.moveTo(
     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_QUADTO:
     314                        midPath.quadTo(
     315                                (float)(coordsFrom[0] * (1 - interp) + coordsTo[0] * interp),
     316                                (float)(coordsFrom[1] * (1 - interp) + coordsTo[1] * interp),
     317                                (float)(coordsFrom[2] * (1 - interp) + coordsTo[2] * interp),
     318                                (float)(coordsFrom[3] * (1 - interp) + coordsTo[3] * interp)
     319                                );
     320                        break;
     321                }
     322            }
     323           
     324            return midPath;
     325        }
     326       
     327        throw new RuntimeException("Animate tag could not be evalutated - insufficient arguements");
     328    }
     329   
     330    /**
     331     * If this element is being accumulated, detemine the delta to accumulate by
     332     */
     333    public double repeatSkipSize(int reps)
     334    {
     335        boolean fromExists = !Double.isNaN(fromValue);
     336        boolean toExists = !Double.isNaN(toValue);
     337        boolean byExists = !Double.isNaN(byValue);
     338       
     339        if (fromExists && toExists)
     340        {
     341            return (toValue - fromValue) * reps;
     342        }
     343        else if (fromExists && byExists)
     344        {
     345            return (fromValue + byValue) * reps;
     346        }
     347        else if (toExists && byExists)
     348        {
     349            return toValue * reps;
     350        }
     351        else if (byExists)
     352        {
     353            return byValue * reps;
     354        }
     355
     356        //Should not reach this line
     357        return 0;
     358    }
     359
     360    protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
     361    {
     362        super.rebuild(animTimeParser);
     363
     364        StyleAttribute sty = new StyleAttribute();
     365
     366        if (getPres(sty.setName("from")))
     367        {
     368            String strn = sty.getStringValue();
     369            if (XMLParseUtil.isDouble(strn))
     370            {
     371                fromValue = XMLParseUtil.parseDouble(strn);
     372            }
     373            else
     374            {
     375                fromColor = ColorTable.parseColor(strn);
     376                if (fromColor == null)
     377                {
     378                    //Try path
     379                    fromPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
     380                    dataType = DT_PATH;
     381                }
     382                else dataType = DT_COLOR;
     383            }
     384        }
     385
     386        if (getPres(sty.setName("to")))
     387        {
     388            String strn = sty.getStringValue();
     389            if (XMLParseUtil.isDouble(strn))
     390            {
     391                toValue = XMLParseUtil.parseDouble(strn);
     392            }
     393            else
     394            {
     395                toColor = ColorTable.parseColor(strn);
     396                if (toColor == null)
     397                {
     398                    //Try path
     399                    toPath = this.buildPath(strn, GeneralPath.WIND_EVEN_ODD);
     400                    dataType = DT_PATH;
     401                }
     402                else dataType = DT_COLOR;
     403            }
     404        }
     405
     406        if (getPres(sty.setName("by")))
     407        {
     408            String strn = sty.getStringValue();
     409            if (strn != null) byValue = XMLParseUtil.parseDouble(strn);
     410        }
     411
     412        if (getPres(sty.setName("values")))
     413        {
     414            String strn = sty.getStringValue();
     415            if (strn != null) valuesValue = XMLParseUtil.parseDoubleList(strn);
     416        }
     417    }
     418   
     419}
  • new file core/src/com/kitfox/svg/animation/AnimateBase.java

    - +  
     1/*
     2 * Animate.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 2:51 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.SVGElement;
     30import com.kitfox.svg.SVGException;
     31import com.kitfox.svg.SVGLoaderHelper;
     32import com.kitfox.svg.animation.parser.AnimTimeParser;
     33import com.kitfox.svg.animation.parser.ParseException;
     34import com.kitfox.svg.xml.StyleAttribute;
     35import java.io.StringReader;
     36import org.xml.sax.Attributes;
     37import org.xml.sax.SAXException;
     38
     39/**
     40 * @author Mark McKay
     41 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     42 */
     43abstract public class AnimateBase extends AnimationElement
     44{
     45    protected double repeatCount = Double.NaN;
     46    protected TimeBase repeatDur;
     47   
     48    /** Creates a new instance of Animate */
     49    public AnimateBase()
     50    {
     51    }
     52   
     53    public void evalParametric(AnimationTimeEval state, double curTime)
     54    {
     55        evalParametric(state, curTime, repeatCount, repeatDur == null ? Double.NaN : repeatDur.evalTime());
     56    }
     57   
     58    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     59    {
     60                //Load style string
     61        super.loaderStartElement(helper, attrs, parent);
     62
     63        String repeatDurTime = attrs.getValue("repeatDur");
     64
     65        try
     66        {
     67            if (repeatDurTime != null)
     68            {
     69                helper.animTimeParser.ReInit(new StringReader(repeatDurTime));
     70                this.repeatDur = helper.animTimeParser.Expr();
     71                this.repeatDur.setParentElement(this);
     72            }
     73        }
     74        catch (Exception e)
     75        {
     76            throw new SAXException(e);
     77        }
     78       
     79        String strn = attrs.getValue("repeatCount");
     80        if (strn == null)
     81        {
     82            repeatCount = 1;
     83        }
     84        else if ("indefinite".equals(strn))
     85        {
     86            repeatCount = Double.POSITIVE_INFINITY;
     87        }
     88        else
     89        {
     90            try { repeatCount = Double.parseDouble(strn); }
     91            catch (Exception e) { repeatCount = Double.NaN; }
     92        }
     93    }
     94
     95    protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
     96    {
     97        super.rebuild(animTimeParser);
     98
     99        StyleAttribute sty = new StyleAttribute();
     100
     101        if (getPres(sty.setName("repeatDur")))
     102        {
     103            String strn = sty.getStringValue();
     104            if (strn != null)
     105            {
     106                animTimeParser.ReInit(new StringReader(strn));
     107                try {
     108                    this.repeatDur = animTimeParser.Expr();
     109                } catch (ParseException ex) {
     110                    ex.printStackTrace();
     111                }
     112            }
     113        }
     114
     115        if (getPres(sty.setName("repeatCount")))
     116        {
     117            String strn = sty.getStringValue();
     118            if (strn == null)
     119            {
     120                repeatCount = 1;
     121            }
     122            else if ("indefinite".equals(strn))
     123            {
     124                repeatCount = Double.POSITIVE_INFINITY;
     125            }
     126            else
     127            {
     128                try { repeatCount = Double.parseDouble(strn); }
     129                catch (Exception e) { repeatCount = Double.NaN; }
     130            }
     131        }
     132    }
     133}
  • new file core/src/com/kitfox/svg/animation/AnimateColor.java

    - +  
     1/*
     2 * Animate.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 2:51 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.SVGElement;
     30import com.kitfox.svg.SVGException;
     31import com.kitfox.svg.SVGLoaderHelper;
     32import com.kitfox.svg.animation.parser.AnimTimeParser;
     33import com.kitfox.svg.xml.ColorTable;
     34import com.kitfox.svg.xml.StyleAttribute;
     35import java.awt.Color;
     36import org.xml.sax.Attributes;
     37import org.xml.sax.SAXException;
     38
     39
     40/**
     41 * @author Mark McKay
     42 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     43 */
     44public class AnimateColor extends AnimateBase implements AnimateColorIface
     45{
     46   
     47    protected Color fromValue;
     48    protected Color toValue;
     49   
     50    /** Creates a new instance of Animate */
     51    public AnimateColor()
     52    {
     53    }
     54   
     55    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     56    {
     57                //Load style string
     58        super.loaderStartElement(helper, attrs, parent);
     59
     60        String strn = attrs.getValue("from");
     61        fromValue = ColorTable.parseColor(strn);
     62
     63        strn = attrs.getValue("to");
     64        toValue = ColorTable.parseColor(strn);
     65    }
     66
     67   
     68    /**
     69     * Evaluates this animation element for the passed interpolation time.  Interp
     70     * must be on [0..1].
     71     */
     72    public Color evalColor(double interp)
     73    {
     74        int r1 = fromValue.getRed();
     75        int g1 = fromValue.getGreen();
     76        int b1 = fromValue.getBlue();
     77        int r2 = toValue.getRed();
     78        int g2 = toValue.getGreen();
     79        int b2 = toValue.getBlue();
     80        double invInterp = 1.0 - interp;
     81       
     82        return new Color((int)(r1 * invInterp + r2 * interp),
     83            (int)(g1 * invInterp + g2 * interp),
     84            (int)(b1 * invInterp + b2 * interp));
     85    }
     86
     87    protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
     88    {
     89        super.rebuild(animTimeParser);
     90
     91        StyleAttribute sty = new StyleAttribute();
     92
     93        if (getPres(sty.setName("from")))
     94        {
     95            String strn = sty.getStringValue();
     96            fromValue = ColorTable.parseColor(strn);
     97        }
     98
     99        if (getPres(sty.setName("to")))
     100        {
     101            String strn = sty.getStringValue();
     102            toValue = ColorTable.parseColor(strn);
     103        }
     104    }
     105}
  • new file core/src/com/kitfox/svg/animation/AnimateColorIface.java

    - +  
     1/*
     2 * AnimateColorIface.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on January 16, 2005, 6:24 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import java.awt.*;
     30
     31/**
     32 *
     33 * @author kitfox
     34 */
     35public interface AnimateColorIface
     36{
     37    public Color evalColor(double interp);
     38}
  • new file core/src/com/kitfox/svg/animation/AnimateMotion.java

    - +  
     1/*
     2 * Animate.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 2:51 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.SVGElement;
     30import com.kitfox.svg.SVGException;
     31import com.kitfox.svg.SVGLoaderHelper;
     32import com.kitfox.svg.animation.parser.AnimTimeParser;
     33import com.kitfox.svg.xml.StyleAttribute;
     34import java.awt.geom.AffineTransform;
     35import java.awt.geom.GeneralPath;
     36import java.awt.geom.PathIterator;
     37import java.awt.geom.Point2D;
     38import java.util.ArrayList;
     39import java.util.Iterator;
     40import java.util.regex.Matcher;
     41import java.util.regex.Pattern;
     42import org.xml.sax.Attributes;
     43import org.xml.sax.SAXException;
     44
     45
     46/**
     47 * @author Mark McKay
     48 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     49 */
     50public class AnimateMotion extends AnimateXform
     51{
     52    static final Matcher matchPoint = Pattern.compile("\\s*(\\d+)[^\\d]+(\\d+)\\s*").matcher("");
     53   
     54//    protected double fromValue;
     55//    protected double toValue;
     56    GeneralPath path;
     57    int rotateType = RT_ANGLE;
     58    double rotate;  //Static angle to rotate by
     59   
     60    public static final int RT_ANGLE = 0;  //Rotate by constant 'rotate' degrees
     61    public static final int RT_AUTO = 1;  //Rotate to reflect tangent of position on path
     62   
     63    final ArrayList bezierSegs = new ArrayList();
     64    double curveLength;
     65   
     66    /** Creates a new instance of Animate */
     67    public AnimateMotion()
     68    {
     69    }
     70   
     71    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     72    {
     73                //Load style string
     74        super.loaderStartElement(helper, attrs, parent);
     75       
     76        //Motion element implies animating the transform element
     77        if (attribName == null)
     78        {
     79            attribName = "transform";
     80            attribType = AT_AUTO;
     81            additiveType = AD_SUM;
     82        }
     83       
     84
     85        String path = attrs.getValue("path");
     86        if (path != null)
     87        {
     88            this.path = buildPath(path, GeneralPath.WIND_NON_ZERO);
     89        }
     90       
     91        //Now parse rotation style
     92        String rotate = attrs.getValue("rotate");
     93        if (rotate != null)
     94        {
     95            if (rotate.equals("auto"))
     96            {
     97                this.rotateType = RT_AUTO;
     98            }
     99            else
     100            {
     101                try { this.rotate = Math.toRadians(Float.parseFloat(rotate)); } catch (Exception e) {}
     102            }
     103        }
     104
     105        //Determine path
     106        String from = attrs.getValue("from");
     107        String to = attrs.getValue("to");
     108
     109        buildPath(from, to);
     110    }
     111   
     112    protected static void setPoint(Point2D.Float pt, String x, String y)
     113    {
     114        try { pt.x = Float.parseFloat(x); } catch (Exception e) {};
     115       
     116        try { pt.y = Float.parseFloat(y); } catch (Exception e) {};
     117    }
     118
     119    private void buildPath(String from, String to)
     120    {
     121        if (from != null && to != null)
     122        {
     123            Point2D.Float ptFrom = new Point2D.Float(), ptTo = new Point2D.Float();
     124
     125            matchPoint.reset(from);
     126            if (matchPoint.matches())
     127            {
     128                setPoint(ptFrom, matchPoint.group(1), matchPoint.group(2));
     129            }
     130
     131            matchPoint.reset(to);
     132            if (matchPoint.matches())
     133            {
     134                setPoint(ptFrom, matchPoint.group(1), matchPoint.group(2));
     135            }
     136
     137            if (ptFrom != null && ptTo != null)
     138            {
     139                path = new GeneralPath();
     140                path.moveTo(ptFrom.x, ptFrom.y);
     141                path.lineTo(ptTo.x, ptTo.y);
     142            }
     143        }
     144
     145        paramaterizePath();
     146    }
     147   
     148    private void paramaterizePath()
     149    {
     150        bezierSegs.clear();
     151        curveLength = 0;
     152       
     153        double[] coords = new double[6];
     154        double sx = 0, sy = 0;
     155       
     156        for (PathIterator pathIt = path.getPathIterator(new AffineTransform()); !pathIt.isDone(); pathIt.next())
     157        {
     158            Bezier bezier = null;
     159                   
     160            int segType = pathIt.currentSegment(coords);
     161           
     162            switch (segType)
     163            {
     164                case PathIterator.SEG_LINETO:
     165                {
     166                    bezier = new Bezier(sx, sy, coords, 1);
     167                    sx = coords[0];
     168                    sy = coords[1];
     169                    break;
     170                }
     171                case PathIterator.SEG_QUADTO:
     172                {
     173                    bezier = new Bezier(sx, sy, coords, 2);
     174                    sx = coords[2];
     175                    sy = coords[3];
     176                    break;
     177                }
     178                case PathIterator.SEG_CUBICTO:
     179                {
     180                    bezier = new Bezier(sx, sy, coords, 3);
     181                    sx = coords[4];
     182                    sy = coords[5];
     183                    break;
     184                }
     185                case PathIterator.SEG_MOVETO:
     186                {
     187                    sx = coords[0];
     188                    sy = coords[1];
     189                    break;
     190                }
     191                case PathIterator.SEG_CLOSE:
     192                    //Do nothing
     193                    break;
     194               
     195            }
     196
     197            if (bezier != null)
     198            {
     199                bezierSegs.add(bezier);
     200                curveLength += bezier.getLength();
     201            }
     202        }
     203    }
     204   
     205    /**
     206     * Evaluates this animation element for the passed interpolation time.  Interp
     207     * must be on [0..1].
     208     */
     209    public AffineTransform eval(AffineTransform xform, double interp)
     210    {
     211        Point2D.Double point = new Point2D.Double();
     212       
     213        if (interp >= 1)
     214        {
     215            Bezier last = (Bezier)bezierSegs.get(bezierSegs.size() - 1);
     216            last.getFinalPoint(point);
     217            xform.setToTranslation(point.x, point.y);
     218            return xform;
     219        }
     220       
     221        double curLength = curveLength * interp;
     222        for (Iterator it = bezierSegs.iterator(); it.hasNext();)
     223        {
     224            Bezier bez = (Bezier)it.next();
     225           
     226            double bezLength = bez.getLength();
     227            if (curLength < bezLength)
     228            {
     229                double param = curLength / bezLength;
     230                bez.eval(param, point);
     231                break;
     232            }
     233           
     234            curLength -= bezLength;
     235        }
     236       
     237        xform.setToTranslation(point.x, point.y);
     238       
     239        return xform;
     240    }
     241   
     242
     243    protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
     244    {
     245        super.rebuild(animTimeParser);
     246
     247        StyleAttribute sty = new StyleAttribute();
     248
     249        if (getPres(sty.setName("path")))
     250        {
     251            String strn = sty.getStringValue();
     252            this.path = buildPath(strn, GeneralPath.WIND_NON_ZERO);
     253        }
     254
     255        if (getPres(sty.setName("rotate")))
     256        {
     257            String strn = sty.getStringValue();
     258            if (strn.equals("auto"))
     259            {
     260                this.rotateType = RT_AUTO;
     261            }
     262            else
     263            {
     264                try { this.rotate = Math.toRadians(Float.parseFloat(strn)); } catch (Exception e) {}
     265            }
     266        }
     267
     268        String from = null;
     269        if (getPres(sty.setName("from")))
     270        {
     271            from = sty.getStringValue();
     272        }
     273
     274        String to = null;
     275        if (getPres(sty.setName("to")))
     276        {
     277            to = sty.getStringValue();
     278        }
     279       
     280        buildPath(from, to);
     281    }
     282}
  • new file core/src/com/kitfox/svg/animation/AnimateTransform.java

    - +  
     1/*
     2 * Animate.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 2:51 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.SVGElement;
     30import com.kitfox.svg.SVGException;
     31import com.kitfox.svg.SVGLoaderHelper;
     32import com.kitfox.svg.animation.parser.AnimTimeParser;
     33import com.kitfox.svg.xml.StyleAttribute;
     34import com.kitfox.svg.xml.XMLParseUtil;
     35import java.awt.geom.AffineTransform;
     36import java.util.regex.Pattern;
     37import org.xml.sax.Attributes;
     38import org.xml.sax.SAXException;
     39
     40
     41/**
     42 * @author Mark McKay
     43 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     44 */
     45public class AnimateTransform extends AnimateXform
     46{
     47//    protected AffineTransform fromValue;
     48//    protected AffineTransform toValue;
     49//    protected double[] fromValue;  //Transform parameters
     50//    protected double[] toValue;
     51    protected double[][] values;
     52    protected double[] keyTimes;
     53
     54    public static final int AT_REPLACE = 0;
     55    public static final int AT_SUM = 1;
     56
     57    protected int additive = AT_REPLACE;
     58
     59    public static final int TR_TRANSLATE = 0;
     60    public static final int TR_ROTATE = 1;
     61    public static final int TR_SCALE = 2;
     62    public static final int TR_SKEWY = 3;
     63    public static final int TR_SKEWX = 4;
     64    public static final int TR_INVALID = 5;
     65
     66    protected int xformType = TR_INVALID;
     67
     68    /** Creates a new instance of Animate */
     69    public AnimateTransform()
     70    {
     71    }
     72
     73    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     74    {
     75                //Load style string
     76        super.loaderStartElement(helper, attrs, parent);
     77
     78        //Type of matrix of transform.  Should be one of the known names used to
     79        // define matrix transforms
     80        // valid types: translate, scale, rotate, skewX, skewY
     81        // 'matrix' not valid for animation
     82        String type = attrs.getValue("type").toLowerCase();
     83        if (type.equals("translate")) xformType = TR_TRANSLATE;
     84        if (type.equals("rotate")) xformType = TR_ROTATE;
     85        if (type.equals("scale")) xformType = TR_SCALE;
     86        if (type.equals("skewx")) xformType = TR_SKEWX;
     87        if (type.equals("skewy")) xformType = TR_SKEWY;
     88
     89        String fromStrn = attrs.getValue("from");
     90        String toStrn = attrs.getValue("to");
     91        if (fromStrn != null && toStrn != null)
     92        {
     93            //fromValue = parseSingleTransform(type + "(" + strn + ")");
     94            double[] fromValue = XMLParseUtil.parseDoubleList(fromStrn);
     95            fromValue = validate(fromValue);
     96
     97    //        toValue = parseSingleTransform(type + "(" + strn + ")");
     98            double[] toValue = XMLParseUtil.parseDoubleList(toStrn);
     99            toValue = validate(toValue);
     100           
     101            values = new double[][]{fromValue, toValue};
     102            keyTimes = new double[]{0, 1};
     103        }
     104
     105        String keyTimeStrn = attrs.getValue("keyTimes");
     106        String valuesStrn = attrs.getValue("values");
     107        if (keyTimeStrn != null && valuesStrn != null)
     108        {
     109            keyTimes = XMLParseUtil.parseDoubleList(keyTimeStrn);
     110           
     111            String[] valueList = Pattern.compile(";").split(valuesStrn);
     112            values = new double[valueList.length][];
     113            for (int i = 0; i < valueList.length; i++)
     114            {
     115                double[] list = XMLParseUtil.parseDoubleList(valueList[i]);
     116                values[i] = validate(list);
     117            }
     118        }
     119       
     120        //Check our additive state
     121        String additive = attrs.getValue("additive");
     122        if (additive != null)
     123        {
     124            if (additive.equals("sum")) this.additive = AT_SUM;
     125        }
     126    }
     127
     128    /**
     129     * Check list size against current xform type and ensure list
     130     * is expanded to a standard list size
     131     */
     132    private double[] validate(double[] paramList)
     133    {
     134        switch (xformType)
     135        {
     136            case TR_SCALE:
     137            {
     138                if (paramList == null)
     139                {
     140                    paramList = new double[]{1, 1};
     141                }
     142                else if (paramList.length == 1)
     143                {
     144                    paramList = new double[]{paramList[0], paramList[0]};
     145                   
     146//                    double[] tmp = paramList;
     147//                    paramList = new double[2];
     148//                    paramList[0] = paramList[1] = tmp[0];
     149                }
     150            }
     151        }
     152
     153        return paramList;
     154    }
     155
     156    /**
     157     * Evaluates this animation element for the passed interpolation time.  Interp
     158     * must be on [0..1].
     159     */
     160    public AffineTransform eval(AffineTransform xform, double interp)
     161    {
     162        int idx = 0;
     163        for (; idx < keyTimes.length - 1; idx++)
     164        {
     165            if (interp >= keyTimes[idx])
     166            {
     167                idx--;
     168                if (idx < 0) idx = 0;
     169                break;
     170            }
     171        }
     172       
     173        double spanStartTime = keyTimes[idx];
     174        double spanEndTime = keyTimes[idx + 1];
     175//        double span = spanStartTime - spanEndTime;
     176       
     177        interp = (interp - spanStartTime) / (spanEndTime - spanStartTime);
     178        double[] fromValue = values[idx];
     179        double[] toValue = values[idx + 1];
     180       
     181        switch (xformType)
     182        {
     183            case TR_TRANSLATE:
     184            {
     185                double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
     186                double y = (1.0 - interp) * fromValue[1] + interp * toValue[1];
     187                xform.setToTranslation(x, y);
     188                break;
     189            }
     190            case TR_ROTATE:
     191            {
     192                double x1 = fromValue.length == 3 ? fromValue[1] : 0;
     193                double y1 = fromValue.length == 3 ? fromValue[2] : 0;
     194                double x2 = toValue.length == 3 ? toValue[1] : 0;
     195                double y2 = toValue.length == 3 ? toValue[2] : 0;
     196               
     197                double theta = (1.0 - interp) * fromValue[0] + interp * toValue[0];
     198                double x = (1.0 - interp) * x1 + interp * x2;
     199                double y = (1.0 - interp) * y1 + interp * y2;
     200                xform.setToRotation(Math.toRadians(theta), x, y);
     201                break;
     202            }
     203            case TR_SCALE:
     204            {
     205                double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
     206                double y = (1.0 - interp) * fromValue[1] + interp * toValue[1];
     207                xform.setToScale(x, y);
     208                break;
     209            }
     210            case TR_SKEWX:
     211            {
     212                double x = (1.0 - interp) * fromValue[0] + interp * toValue[0];
     213                xform.setToShear(Math.toRadians(x), 0.0);
     214                break;
     215            }
     216            case TR_SKEWY:
     217            {
     218                double y = (1.0 - interp) * fromValue[0] + interp * toValue[0];
     219                xform.setToShear(0.0, Math.toRadians(y));
     220                break;
     221            }
     222            default:
     223                xform.setToIdentity();
     224                break;
     225        }
     226
     227        return xform;
     228    }
     229
     230    protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
     231    {
     232        super.rebuild(animTimeParser);
     233
     234        StyleAttribute sty = new StyleAttribute();
     235
     236        if (getPres(sty.setName("type")))
     237        {
     238            String strn = sty.getStringValue().toLowerCase();
     239            if (strn.equals("translate")) xformType = TR_TRANSLATE;
     240            if (strn.equals("rotate")) xformType = TR_ROTATE;
     241            if (strn.equals("scale")) xformType = TR_SCALE;
     242            if (strn.equals("skewx")) xformType = TR_SKEWX;
     243            if (strn.equals("skewy")) xformType = TR_SKEWY;
     244        }
     245
     246        String fromStrn = null;
     247        if (getPres(sty.setName("from")))
     248        {
     249            fromStrn = sty.getStringValue();
     250        }
     251
     252        String toStrn = null;
     253        if (getPres(sty.setName("to")))
     254        {
     255            toStrn = sty.getStringValue();
     256        }
     257
     258        if (fromStrn != null && toStrn != null)
     259        {
     260            double[] fromValue = XMLParseUtil.parseDoubleList(fromStrn);
     261            fromValue = validate(fromValue);
     262
     263            double[] toValue = XMLParseUtil.parseDoubleList(toStrn);
     264            toValue = validate(toValue);
     265
     266            values = new double[][]{fromValue, toValue};
     267        }
     268
     269        String keyTimeStrn = null;
     270        if (getPres(sty.setName("keyTimes")))
     271        {
     272            keyTimeStrn = sty.getStringValue();
     273        }
     274
     275        String valuesStrn = null;
     276        if (getPres(sty.setName("values")))
     277        {
     278            valuesStrn = sty.getStringValue();
     279        }
     280
     281        if (keyTimeStrn != null && valuesStrn != null)
     282        {
     283            keyTimes = XMLParseUtil.parseDoubleList(keyTimeStrn);
     284
     285            String[] valueList = Pattern.compile(";").split(valuesStrn);
     286            values = new double[valueList.length][];
     287            for (int i = 0; i < valueList.length; i++)
     288            {
     289                double[] list = XMLParseUtil.parseDoubleList(valueList[i]);
     290                values[i] = validate(list);
     291            }
     292        }
     293
     294        //Check our additive state
     295
     296        if (getPres(sty.setName("additive")))
     297        {
     298            String strn = sty.getStringValue().toLowerCase();
     299            if (strn.equals("sum")) this.additive = AT_SUM;
     300        }
     301    }
     302}
  • new file core/src/com/kitfox/svg/animation/AnimateXform.java

    - +  
     1/*
     2 * AnimateXform.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on January 14, 2005, 6:46 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.SVGElement;
     30import com.kitfox.svg.SVGLoaderHelper;
     31import java.awt.geom.AffineTransform;
     32import org.xml.sax.Attributes;
     33import org.xml.sax.SAXException;
     34
     35
     36
     37/**
     38 *
     39 * @author kitfox
     40 */
     41abstract public class AnimateXform extends AnimateBase
     42{
     43    public AnimateXform()
     44    {
     45    }
     46   
     47    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     48    {
     49        super.loaderStartElement(helper, attrs, parent);
     50    }
     51   
     52    abstract public AffineTransform eval(AffineTransform xform, double interp);
     53   
     54}
  • new file core/src/com/kitfox/svg/animation/AnimationElement.java

    - +  
     1/*
     2 * AnimateEle.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 2:52 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.SVGElement;
     30import com.kitfox.svg.SVGException;
     31import com.kitfox.svg.SVGLoaderHelper;
     32import com.kitfox.svg.animation.parser.AnimTimeParser;
     33import com.kitfox.svg.animation.parser.ParseException;
     34import com.kitfox.svg.xml.StyleAttribute;
     35import java.io.StringReader;
     36import org.xml.sax.Attributes;
     37import org.xml.sax.SAXException;
     38
     39
     40/**
     41 * @author Mark McKay
     42 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     43 */
     44public abstract class AnimationElement extends SVGElement
     45{
     46    protected String attribName;
     47//    protected String attribType;
     48    protected int attribType = AT_AUTO;
     49
     50    public static final int AT_CSS = 0;
     51    public static final int AT_XML = 1;
     52    public static final int AT_AUTO = 2;  //Check CSS first, then XML
     53
     54    protected TimeBase beginTime;
     55    protected TimeBase durTime;
     56    protected TimeBase endTime;
     57    protected int fillType = FT_AUTO;
     58
     59    /** <a href="http://www.w3.org/TR/smil20/smil-timing.html#adef-fill">More about the <b>fill</b> attribute</a> */
     60    public static final int FT_REMOVE = 0;
     61    public static final int FT_FREEZE = 1;
     62    public static final int FT_HOLD = 2;
     63    public static final int FT_TRANSITION = 3;
     64    public static final int FT_AUTO = 4;
     65    public static final int FT_DEFAULT = 5;
     66
     67    /** Additive state of track */
     68    public static final int AD_REPLACE = 0;
     69    public static final int AD_SUM = 1;
     70
     71    int additiveType = AD_REPLACE;
     72   
     73    /** Accumlative state */
     74    public static final int AC_REPLACE = 0;
     75    public static final int AC_SUM = 1;
     76
     77    int accumulateType = AC_REPLACE;
     78
     79    /** Creates a new instance of AnimateEle */
     80    public AnimationElement()
     81    {
     82    }
     83
     84    public static String animationElementToString(int attrValue)
     85    {
     86        switch (attrValue)
     87        {
     88            case AT_CSS:
     89                return "CSS";
     90            case AT_XML:
     91                return "XML";
     92            case AT_AUTO:
     93                return "AUTO";
     94            default:
     95                throw new RuntimeException("Unknown element type");
     96        }
     97    }
     98   
     99    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     100    {
     101                //Load style string
     102        super.loaderStartElement(helper, attrs, parent);
     103
     104        attribName = attrs.getValue("attributeName");
     105        String attribType = attrs.getValue("attributeType");
     106        if (attribType != null)
     107        {
     108            attribType = attribType.toLowerCase();
     109            if (attribType.equals("css")) this.attribType = AT_CSS;
     110            else if (attribType.equals("xml")) this.attribType = AT_XML;
     111        }
     112
     113        String beginTime = attrs.getValue("begin");
     114        String durTime = attrs.getValue("dur");
     115        String endTime = attrs.getValue("end");
     116
     117        try
     118        {
     119            if (beginTime != null)
     120            {
     121                helper.animTimeParser.ReInit(new StringReader(beginTime));
     122                this.beginTime = helper.animTimeParser.Expr();
     123                this.beginTime.setParentElement(this);
     124            }
     125
     126            if (durTime != null)
     127            {
     128                helper.animTimeParser.ReInit(new StringReader(durTime));
     129                this.durTime = helper.animTimeParser.Expr();
     130                this.durTime.setParentElement(this);
     131            }
     132
     133            if (endTime != null)
     134            {
     135                helper.animTimeParser.ReInit(new StringReader(endTime));
     136                this.endTime = helper.animTimeParser.Expr();
     137                this.endTime.setParentElement(this);
     138            }
     139        }
     140        catch (Exception e)
     141        {
     142            throw new SAXException(e);
     143        }
     144       
     145//        this.beginTime = TimeBase.parseTime(beginTime);
     146//        this.durTime = TimeBase.parseTime(durTime);
     147//        this.endTime = TimeBase.parseTime(endTime);
     148
     149        String fill = attrs.getValue("fill");
     150
     151        if (fill != null)
     152        {
     153            if (fill.equals("remove")) this.fillType = FT_REMOVE;
     154            if (fill.equals("freeze")) this.fillType = FT_FREEZE;
     155            if (fill.equals("hold")) this.fillType = FT_HOLD;
     156            if (fill.equals("transiton")) this.fillType = FT_TRANSITION;
     157            if (fill.equals("auto")) this.fillType = FT_AUTO;
     158            if (fill.equals("default")) this.fillType = FT_DEFAULT;
     159        }
     160       
     161        String additiveStrn = attrs.getValue("additive");
     162       
     163        if (additiveStrn != null)
     164        {
     165            if (additiveStrn.equals("replace")) this.additiveType = AD_REPLACE;
     166            if (additiveStrn.equals("sum")) this.additiveType = AD_SUM;
     167        }
     168       
     169        String accumulateStrn = attrs.getValue("accumulate");
     170       
     171        if (accumulateStrn != null)
     172        {
     173            if (accumulateStrn.equals("replace")) this.accumulateType = AC_REPLACE;
     174            if (accumulateStrn.equals("sum")) this.accumulateType = AC_SUM;
     175        }
     176    }
     177
     178    public String getAttribName() { return attribName; }
     179    public int getAttribType() { return attribType; }
     180    public int getAdditiveType() { return additiveType; }
     181    public int getAccumulateType() { return accumulateType; }
     182
     183    public void evalParametric(AnimationTimeEval state, double curTime)
     184    {
     185        evalParametric(state, curTime, Double.NaN, Double.NaN);
     186    }
     187
     188    /**
     189     * Compares current time to start and end times and determines what degree
     190     * of time interpolation this track currently represents.  Returns
     191     * Float.NaN if this track cannot be evaluated at the passed time (ie,
     192     * it is before or past the end of the track, or it depends upon
     193     * an unknown event)
     194     * @param state - A structure that will be filled with information
     195     * regarding the applicability of this animatoin element at the passed
     196     * time.
     197     * @param curTime - Current time in seconds
     198     * @param repeatCount - Optional number of repetitions of length 'dur' to
     199     * do.  Set to Double.NaN to not consider this in the calculation.
     200     * @param repeatDur - Optional amoun tof time to repeat the animaiton.
     201     * Set to Double.NaN to not consider this in the calculation.
     202     */
     203    protected void evalParametric(AnimationTimeEval state, double curTime, double repeatCount, double repeatDur)
     204    {
     205        double begin = (beginTime == null) ? 0 : beginTime.evalTime();
     206        if (Double.isNaN(begin) || begin > curTime)
     207        {
     208            state.set(Double.NaN, 0);
     209            return;
     210        }
     211
     212        double dur = (durTime == null) ? Double.NaN : durTime.evalTime();
     213        if (Double.isNaN(dur))
     214        {
     215            state.set(Double.NaN, 0);
     216            return;
     217        }
     218
     219        //Determine end point of this animation
     220        double end = (endTime == null) ? Double.NaN : endTime.evalTime();
     221        double repeat;
     222//        if (Double.isNaN(repeatDur))
     223//        {
     224//            repeatDur = dur;
     225//        }
     226        if (Double.isNaN(repeatCount) && Double.isNaN(repeatDur))
     227        {
     228            repeat = Double.NaN;
     229        }
     230        else
     231        {
     232            repeat = Math.min(
     233                Double.isNaN(repeatCount) ? Double.POSITIVE_INFINITY : dur * repeatCount,
     234                Double.isNaN(repeatDur) ? Double.POSITIVE_INFINITY : repeatDur);
     235        }
     236        if (Double.isNaN(repeat) && Double.isNaN(end))
     237        {
     238            //If neither and end point nor a repeat is specified, end point is
     239            // implied by duration.
     240            end = begin + dur;
     241        }
     242
     243        double finishTime;
     244        if (Double.isNaN(end))
     245        {
     246            finishTime = begin + repeat;
     247        }
     248        else if (Double.isNaN(repeat))
     249        {
     250            finishTime = end;
     251        }
     252        else
     253        {
     254            finishTime = Math.min(end, repeat);
     255        }
     256       
     257        double evalTime = Math.min(curTime, finishTime);
     258//        if (curTime > finishTime) evalTime = finishTime;
     259       
     260       
     261//        double evalTime = curTime;
     262
     263//        boolean pastEnd = curTime > evalTime;
     264       
     265//        if (!Double.isNaN(end) && curTime > end) { pastEnd = true; evalTime = Math.min(evalTime, end); }
     266//        if (!Double.isNaN(repeat) && curTime > repeat) { pastEnd = true; evalTime = Math.min(evalTime, repeat); }
     267       
     268        double ratio = (evalTime - begin) / dur;
     269        int rep = (int)ratio;
     270        double interp = ratio - rep;
     271       
     272        //Adjust for roundoff
     273        if (interp < 0.00001) interp = 0;
     274
     275//        state.set(interp, rep);
     276//        if (!pastEnd)
     277//        {
     278//            state.set(interp, rep, false);
     279//            return;
     280//        }
     281
     282        //If we are still within the clip, return value
     283        if (curTime == evalTime)
     284        {
     285            state.set(interp, rep);
     286            return;
     287        }
     288       
     289        //We are past end of clip.  Determine to clamp or ignore.
     290        switch (fillType)
     291        {
     292            default:
     293            case FT_REMOVE:
     294            case FT_AUTO:
     295            case FT_DEFAULT:
     296                state.set(Double.NaN, rep);
     297                return;
     298            case FT_FREEZE:
     299            case FT_HOLD:
     300            case FT_TRANSITION:
     301                state.set(interp == 0 ? 1 : interp, rep);
     302                return;
     303        }
     304
     305    }
     306
     307    double evalStartTime()
     308    {
     309        return beginTime == null ? Double.NaN : beginTime.evalTime();
     310    }
     311
     312    double evalDurTime()
     313    {
     314        return durTime == null ? Double.NaN : durTime.evalTime();
     315    }
     316
     317    /**
     318     * Evaluates the ending time of this element.  Returns 0 if not specified.
     319     *
     320     * @see hasEndTime
     321     */
     322    double evalEndTime()
     323    {
     324        return endTime == null ? Double.NaN : endTime.evalTime();
     325    }
     326
     327    /**
     328     * Checks to see if an end time has been specified for this element.
     329     */
     330    boolean hasEndTime() { return endTime != null; }
     331
     332    /**
     333     * Updates all attributes in this diagram associated with a time event.
     334     * Ie, all attributes with track information.
     335     * @return - true if this node has changed state as a result of the time
     336     * update
     337     */
     338    public boolean updateTime(double curTime)
     339    {
     340        //Animation elements to not change with time
     341        return false;
     342    }
     343
     344    public void rebuild() throws SVGException
     345    {
     346        AnimTimeParser animTimeParser = new AnimTimeParser(new StringReader(""));
     347
     348        rebuild(animTimeParser);
     349    }
     350
     351    protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
     352    {
     353        StyleAttribute sty = new StyleAttribute();
     354
     355        if (getPres(sty.setName("begin")))
     356        {
     357            String newVal = sty.getStringValue();
     358            animTimeParser.ReInit(new StringReader(newVal));
     359            try {
     360                this.beginTime = animTimeParser.Expr();
     361            } catch (ParseException ex) {
     362                ex.printStackTrace();
     363            }
     364        }
     365
     366        if (getPres(sty.setName("dur")))
     367        {
     368            String newVal = sty.getStringValue();
     369            animTimeParser.ReInit(new StringReader(newVal));
     370            try {
     371                this.durTime = animTimeParser.Expr();
     372            } catch (ParseException ex) {
     373                ex.printStackTrace();
     374            }
     375        }
     376
     377        if (getPres(sty.setName("end")))
     378        {
     379            String newVal = sty.getStringValue();
     380            animTimeParser.ReInit(new StringReader(newVal));
     381            try {
     382                this.endTime = animTimeParser.Expr();
     383            } catch (ParseException ex) {
     384                ex.printStackTrace();
     385            }
     386        }
     387
     388        if (getPres(sty.setName("fill")))
     389        {
     390            String newVal = sty.getStringValue();
     391            if (newVal.equals("remove")) this.fillType = FT_REMOVE;
     392            if (newVal.equals("freeze")) this.fillType = FT_FREEZE;
     393            if (newVal.equals("hold")) this.fillType = FT_HOLD;
     394            if (newVal.equals("transiton")) this.fillType = FT_TRANSITION;
     395            if (newVal.equals("auto")) this.fillType = FT_AUTO;
     396            if (newVal.equals("default")) this.fillType = FT_DEFAULT;
     397        }
     398
     399        if (getPres(sty.setName("additive")))
     400        {
     401            String newVal = sty.getStringValue();
     402            if (newVal.equals("replace")) this.additiveType = AD_REPLACE;
     403            if (newVal.equals("sum")) this.additiveType = AD_SUM;
     404        }
     405
     406        if (getPres(sty.setName("accumulate")))
     407        {
     408            String newVal = sty.getStringValue();
     409            if (newVal.equals("replace")) this.accumulateType = AC_REPLACE;
     410            if (newVal.equals("sum")) this.accumulateType = AC_SUM;
     411        }
     412
     413    }
     414}
  • new file core/src/com/kitfox/svg/animation/AnimationTimeEval.java

    - +  
     1/*
     2 * AnimateTimeEval.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 *
     25 * Created on September 21, 2004, 1:31 PM
     26 */
     27
     28package com.kitfox.svg.animation;
     29
     30/**
     31 *
     32 * @author  kitfox
     33 */
     34public class AnimationTimeEval
     35{
     36    /**
     37     * Value on [0..1] representing the interpolation value of queried animation
     38     * element, or Double.NaN if element does not provide a valid evalutaion
     39     */
     40    public double interp;
     41   
     42    /**
     43     * Number of completed repetitions
     44     */
     45    public int rep;
     46   
     47    /**
     48     * True if this evaluation is in a frozen state; ie, past the end of the
     49     * track and held in the "freeze" state.
     50     */
     51//    public boolean pastEnd;
     52   
     53    /** Creates a new instance of AnimateTimeEval */
     54    public AnimationTimeEval()
     55    {
     56    }
     57   
     58//    public void set(double interp, int rep, boolean pastEnd)
     59    public void set(double interp, int rep)
     60    {
     61        this.interp = interp;
     62        this.rep = rep;
     63//        this.pastEnd = pastEnd;
     64    }
     65}
  • new file core/src/com/kitfox/svg/animation/Bezier.java

    - +  
     1/*
     2 * Bezier.java
     3 *
     4
     5 *  The Salamander Project - 2D and 3D graphics libraries in Java
     6 *  Copyright (C) 2004 Mark McKay
     7 *
     8 *  This library is free software; you can redistribute it and/or
     9 *  modify it under the terms of the GNU Lesser General Public
     10 *  License as published by the Free Software Foundation; either
     11 *  version 2.1 of the License, or (at your option) any later version.
     12 *
     13 *  This library is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     16 *  Lesser General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU Lesser General Public
     19 *  License along with this library; if not, write to the Free Software
     20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     21 *
     22 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     23 *  projects can be found at http://www.kitfox.com
     24 *
     25 * Created on January 14, 2005, 4:08 AM
     26 */
     27
     28package com.kitfox.svg.animation;
     29
     30import java.awt.geom.*;
     31
     32/**
     33 * http://mathworld.wolfram.com/BezierCurve.html
     34 * @author kitfox
     35 */
     36public class Bezier
     37{
     38    double length;
     39    double[] coord;
     40
     41    public Bezier(double sx, double sy, double[] coords, int numCoords)
     42    {
     43        setCoords(sx, sy, coords, numCoords);
     44    }
     45   
     46    public void setCoords(double sx, double sy, double[] coords, int numCoords)
     47    {
     48        coord = new double[numCoords * 2 + 2];
     49        coord[0] = sx;
     50        coord[1] = sy;
     51        for (int i = 0; i < numCoords; i++)
     52        {
     53            coord[i * 2 + 2] = coords[i * 2];
     54            coord[i * 2 + 3] = coords[i * 2 + 1];
     55        }
     56       
     57        calcLength();       
     58    }
     59   
     60    /**
     61     * Retuns aproximation of the length of the bezier
     62     */
     63    public double getLength()
     64    {
     65        return length;
     66    }
     67   
     68    private void calcLength()
     69    {
     70        length = 0;
     71        for (int i = 2; i < coord.length; i += 2)
     72        {
     73            length += lineLength(coord[i - 2], coord[i - 1], coord[i], coord[i + 1]);
     74        }
     75    }
     76   
     77    private double lineLength(double x1, double y1, double x2, double y2)
     78    {
     79        double dx = x2 - x1, dy = y2 - y1;
     80        return Math.sqrt(dx * dx + dy * dy);
     81    }
     82   
     83    public Point2D.Double getFinalPoint(Point2D.Double point)
     84    {
     85        point.x = coord[coord.length - 2];
     86        point.y = coord[coord.length - 1];
     87        return point;
     88    }
     89   
     90    public Point2D.Double eval(double param, Point2D.Double point)
     91    {
     92        point.x = 0;
     93        point.y = 0;
     94        int numKnots = coord.length / 2;
     95       
     96        for (int i = 0; i < numKnots; i++)
     97        {
     98            double scale = bernstein(numKnots - 1, i, param);
     99            point.x += coord[i * 2] * scale;
     100            point.y += coord[i * 2 + 1] * scale;
     101        }
     102       
     103        return point;
     104    }
     105   
     106    /**
     107     * Calculates the bernstein polynomial for evaluating parametric bezier
     108     * @param numKnots - one less than number of knots in this curve hull
     109     * @param knotNo - knot we are evaluating Bernstein for
     110     * @param param - Parametric value we are evaluating at
     111     */
     112    private double bernstein(int numKnots, int knotNo, double param)
     113    {
     114        double iParam = 1 - param;
     115        //Faster evaluation for easy cases:
     116        switch (numKnots)
     117        {
     118            case 0:
     119                return 1;
     120            case 1:
     121            {
     122                switch (knotNo)
     123                {
     124                    case 0:
     125                        return iParam;
     126                    case 1:
     127                        return param;
     128                }
     129                break;
     130            }
     131            case 2:
     132            {
     133                switch (knotNo)
     134                {
     135                    case 0:
     136                        return iParam * iParam;
     137                    case 1:
     138                        return 2 * iParam * param;
     139                    case 2:
     140                        return param * param;
     141                }
     142                break;
     143            }
     144            case 3:
     145            {
     146                switch (knotNo)
     147                {
     148                    case 0:
     149                        return iParam * iParam * iParam;
     150                    case 1:
     151                        return 3 * iParam * iParam * param;
     152                    case 2:
     153                        return 3 * iParam * param * param;
     154                    case 3:
     155                        return param * param * param;
     156                }
     157                break;
     158            }
     159        }
     160       
     161        //If this bezier has more than four points, calculate bernstein the hard way
     162        double retVal = 1;
     163        for (int i = 0; i < knotNo; i++)
     164        {
     165            retVal *= param;
     166        }
     167        for (int i = 0; i < numKnots - knotNo; i++)
     168        {
     169            retVal *= iParam;
     170        }
     171        retVal *= choose(numKnots, knotNo);
     172       
     173        return retVal;
     174    }
     175   
     176   
     177   
     178    private int choose(int num, int denom)
     179    {
     180        int denom2 = num - denom;
     181        if (denom < denom2)
     182        {
     183            int tmp = denom;
     184            denom = denom2;
     185            denom2 = tmp;
     186        }
     187       
     188        int prod = 1;
     189        for (int i = num; i > denom; i--)
     190        {
     191            prod *= num;
     192        }
     193       
     194        for (int i = 2; i <= denom2; i++)
     195        {
     196            prod /= i;
     197        }
     198       
     199        return prod;
     200    }
     201}
  • new file core/src/com/kitfox/svg/animation/SetSmil.java

    - +  
     1/*
     2 * Set.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 2:51 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.SVGElement;
     30import com.kitfox.svg.SVGException;
     31import com.kitfox.svg.SVGLoaderHelper;
     32import com.kitfox.svg.animation.parser.AnimTimeParser;
     33import com.kitfox.svg.xml.StyleAttribute;
     34import org.xml.sax.Attributes;
     35import org.xml.sax.SAXException;
     36
     37
     38/**
     39 * Set is used to set a textual value; most likely for a style element.
     40 *
     41 * @author Mark McKay
     42 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     43 */
     44public class SetSmil extends AnimationElement
     45{
     46    String toValue;
     47   
     48    /** Creates a new instance of Set */
     49    public SetSmil()
     50    {
     51    }
     52   
     53    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     54    {
     55                //Load style string
     56        super.loaderStartElement(helper, attrs, parent);
     57
     58        toValue = attrs.getValue("to");
     59    }
     60
     61    protected void rebuild(AnimTimeParser animTimeParser) throws SVGException
     62    {
     63        super.rebuild(animTimeParser);
     64
     65        StyleAttribute sty = new StyleAttribute();
     66
     67        if (getPres(sty.setName("to")))
     68        {
     69            String newVal = sty.getStringValue();
     70            toValue = newVal;
     71        }
     72    }
     73}
  • new file core/src/com/kitfox/svg/animation/TimeBase.java

    - +  
     1/*
     2 * TimeBase.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 3:31 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import java.util.regex.*;
     30
     31/**
     32 * SVG has a complicated way of specifying time.  Potentially, a time could
     33 * be represened as a summation of discrete times and times of other animation
     34 * events.  This provides a root for the many elements we will need to define
     35 * time.
     36 *
     37 * @author Mark McKay
     38 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     39 */
     40abstract public class TimeBase
     41{
     42    static final Matcher matchIndefinite = Pattern.compile("\\s*indefinite\\s*").matcher("");
     43    static final Matcher matchUnitTime = Pattern.compile("\\s*([-+]?((\\d*\\.\\d+)|(\\d+))([-+]?[eE]\\d+)?)\\s*(h|min|s|ms)?\\s*").matcher("");
     44   
     45    /*
     46    public static TimeBase parseTime(String text)
     47    {
     48        if (text == null) return null;
     49       
     50        if (text.indexOf('+') == -1)
     51        {
     52            return parseTimeComponent(text);
     53        }
     54       
     55        return new TimeCompound(text);
     56    }
     57     */
     58   
     59    protected static TimeBase parseTimeComponent(String text)
     60    {
     61        matchIndefinite.reset(text);
     62        if (matchIndefinite.matches()) return new TimeIndefinite();
     63       
     64        matchUnitTime.reset(text);
     65        if (matchUnitTime.matches())
     66        {
     67            String val = matchUnitTime.group(1);
     68            String units = matchUnitTime.group(6);
     69           
     70            double time = 0;
     71            try { time = Double.parseDouble(val); }
     72            catch (Exception e) {}
     73           
     74            if (units.equals("ms")) time *= .001;
     75            else if (units.equals("min")) time *= 60;
     76            else if (units.equals("h")) time *= 3600;
     77           
     78            return new TimeDiscrete(time);
     79        }
     80       
     81        return null;
     82    }
     83   
     84    /**
     85     * Calculates the (greater than or equal to 0) time in seconds this
     86     * time represents.  If the time cannot be determined, returns
     87     * Double.NaN.  If this represents an infinte amount of time, returns
     88     * Double.POSITIVE_INFINITY.
     89     */
     90    abstract public double evalTime();
     91   
     92    /**
     93     * Some time elements need to refer to the animation element that contains
     94     * them to evaluate correctly
     95     */
     96    public void setParentElement(AnimationElement ele)
     97    {
     98    }
     99}
  • new file core/src/com/kitfox/svg/animation/TimeCompound.java

    - +  
     1/*
     2 * TimeDiscrete.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 3:33 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import java.util.Collections;
     30import java.util.Iterator;
     31import java.util.List;
     32import java.util.regex.Pattern;
     33
     34
     35/**
     36 * This represents a summation of other time elements.  It is used for complex
     37 * timing events with offsets.
     38 *
     39 * @author Mark McKay
     40 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     41 */
     42public class TimeCompound extends TimeBase
     43{
     44    static final Pattern patPlus = Pattern.compile("\\+");
     45   
     46    /**
     47     * This is a list of times.  This element's time is calculated as the greatest
     48     * member that is less than the current time.
     49    */
     50    final List componentTimes;
     51
     52    private AnimationElement parent;
     53   
     54    /** Creates a new instance of TimeDiscrete */
     55    public TimeCompound(List timeBases)
     56    {
     57        componentTimes = Collections.unmodifiableList(timeBases);
     58    }
     59   
     60    public double evalTime()
     61    {
     62        double agg = 0.0;
     63       
     64        for (Iterator it = componentTimes.iterator(); it.hasNext();)
     65        {
     66            TimeBase timeEle = (TimeBase)it.next();
     67            double time = timeEle.evalTime();
     68            agg += time;
     69        }
     70       
     71        return agg;
     72    }
     73   
     74    public void setParentElement(AnimationElement ele)
     75    {
     76        this.parent = ele;
     77       
     78        for (Iterator it = componentTimes.iterator(); it.hasNext();)
     79        {
     80            TimeBase timeEle = (TimeBase)it.next();
     81            timeEle.setParentElement(ele);
     82        }
     83    }
     84}
  • new file core/src/com/kitfox/svg/animation/TimeDiscrete.java

    - +  
     1/*
     2 * TimeDiscrete.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 3:33 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29/**
     30 * This is a time that represents a specific number of milliseconds
     31 *
     32 * @author Mark McKay
     33 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     34 */
     35public class TimeDiscrete extends TimeBase
     36{
     37    //Milliseconds of delay
     38    double secs;
     39   
     40    /** Creates a new instance of TimeDiscrete */
     41    public TimeDiscrete(double secs)
     42    {
     43        this.secs = secs;
     44    }
     45   
     46    public double evalTime()
     47    {
     48        return secs;
     49    }
     50   
     51}
  • new file core/src/com/kitfox/svg/animation/TimeIndefinite.java

    - +  
     1/*
     2 * TimeDiscrete.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 3:33 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29/**
     30 * This represents the indefinite (infinite) amount of time.
     31 *
     32 * @author Mark McKay
     33 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     34 */
     35public class TimeIndefinite extends TimeBase
     36{
     37   
     38    /** Creates a new instance of TimeDiscrete */
     39    public TimeIndefinite()
     40    {
     41    }
     42   
     43    public double evalTime()
     44    {
     45        return Double.POSITIVE_INFINITY;
     46    }
     47   
     48}
  • new file core/src/com/kitfox/svg/animation/TimeLookup.java

    - +  
     1/*
     2 * TimeDiscrete.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 3:33 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29/**
     30 * This is a time that represents a specific number of milliseconds
     31 *
     32 * @author Mark McKay
     33 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     34 */
     35public class TimeLookup extends TimeBase
     36{
     37    /**
     38     * This time can only be resolved in relation to it's parent
     39     */
     40    private AnimationElement parent;
     41   
     42    /**
     43     * Node this lookup acts upon
     44     */
     45    String node;
     46   
     47    /**
     48     * Event to evalutae on this node
     49     */
     50    String event;
     51   
     52    /**
     53     * Optional parameter used by some events
     54     */
     55    String paramList;
     56   
     57    /** Creates a new instance of TimeDiscrete */
     58    public TimeLookup(AnimationElement parent, String node, String event, String paramList)
     59    {
     60        this.parent = parent;
     61        this.node = node;
     62        this.event = event;
     63        this.paramList = paramList;
     64    }
     65   
     66    public double evalTime()
     67    {
     68        return 0.0;
     69    }
     70   
     71    public void setParentElement(AnimationElement ele)
     72    {
     73        parent = ele;
     74    }
     75}
  • new file core/src/com/kitfox/svg/animation/TimeSum.java

    - +  
     1/*
     2 * TimeDiscrete.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 3:33 AM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29/**
     30 * This is a time that represents a specific number of milliseconds
     31 *
     32 * @author Mark McKay
     33 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     34 */
     35public class TimeSum extends TimeBase
     36{
     37    //Milliseconds of delay
     38    TimeBase t1;
     39    TimeBase t2;
     40    boolean add;
     41   
     42    /** Creates a new instance of TimeDiscrete */
     43    public TimeSum(TimeBase t1, TimeBase t2, boolean add)
     44    {
     45        this.t1 = t1;
     46        this.t2 = t2;
     47        this.add = add;
     48    }
     49   
     50    public double evalTime()
     51    {
     52        return add ? t1.evalTime() + t2.evalTime() : t1.evalTime() - t2.evalTime();
     53    }
     54   
     55    public void setParentElement(AnimationElement ele)
     56    {
     57        t1.setParentElement(ele);
     58        t2.setParentElement(ele);
     59    }
     60}
  • new file core/src/com/kitfox/svg/animation/TrackBase.java

    - +  
     1/*
     2 * TrackManager.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 11:34 PM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import java.util.*;
     30
     31import com.kitfox.svg.xml.*;
     32import com.kitfox.svg.*;
     33
     34/**
     35 * A track holds the animation events for a single parameter of a single SVG
     36 * element.  It also contains the default value for the element, should the
     37 * user want to see the 'unanimated' value.
     38 *
     39 * @author Mark McKay
     40 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     41 */
     42abstract public class TrackBase
     43{
     44    protected final String attribName;
     45    protected final int attribType;  //AnimationElement.AT_*
     46 
     47    /** Element we're animating */
     48    protected final SVGElement parent;
     49   
     50    //It doesn't make sense to sort this, since some events will depend on
     51    // other events - in many cases, there will be no meaningful sorted order.
     52    final ArrayList animEvents = new ArrayList();
     53   
     54    /** Creates a new instance of TrackManager */
     55//    public TrackBase(SVGElement parent)
     56//    {
     57//        this(parent, "", AnimationElement.AT_AUTO);
     58//    }
     59   
     60    /**
     61     * Creates a track that would be valid for the name and type of element
     62     * passed in.  Does not actually add this elemnt to the track.
     63     */
     64    public TrackBase(SVGElement parent, AnimationElement ele) throws SVGElementException
     65    {
     66        this(parent, ele.getAttribName(), ele.getAttribType());
     67    }
     68   
     69    public TrackBase(SVGElement parent, String attribName, int attribType) throws SVGElementException
     70    {
     71        this.parent = parent;
     72        this.attribName = attribName;
     73        this.attribType = attribType;
     74       
     75        //Make sure parent has an attribute we will write to
     76        if (attribType == AnimationElement.AT_AUTO
     77            && !parent.hasAttribute(attribName, AnimationElement.AT_CSS)
     78            && !parent.hasAttribute(attribName, AnimationElement.AT_XML))
     79        {
     80            parent.addAttribute(attribName, AnimationElement.AT_CSS, "");
     81        }
     82        else if (!parent.hasAttribute(attribName, attribType))
     83        {
     84            parent.addAttribute(attribName, attribType, "");
     85        }
     86    }
     87   
     88    public String getAttribName() { return attribName; }
     89    public int getAttribType() { return attribType; }
     90   
     91    public void addElement(AnimationElement ele)
     92    {
     93        animEvents.add(ele);
     94    }
     95   
     96    /**
     97     * Returns a StyleAttribute representing the value of this track at the
     98     * passed time.  If this track does not apply, returns null.
     99     * @return - True if successful, false if a value could not be obtained
     100     */
     101    abstract public boolean getValue(StyleAttribute attrib, double curTime) throws SVGException;
     102   
     103}
  • new file core/src/com/kitfox/svg/animation/TrackColor.java

    - +  
     1/*
     2 * TrackManager.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on September 21, 2004, 11:34 PM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.xml.StyleAttribute;
     30import java.awt.*;
     31import java.util.*;
     32
     33import com.kitfox.svg.*;
     34import com.kitfox.svg.xml.*;
     35
     36/**
     37 * A track holds the animation events for a single parameter of a single SVG
     38 * element.  It also contains the default value for the element, should the
     39 * user want to see the 'unanimated' value.
     40 *
     41 * @author Mark McKay
     42 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     43 */
     44public class TrackColor extends TrackBase
     45{
     46
     47    public TrackColor(AnimationElement ele) throws SVGElementException
     48    {
     49        super(ele.getParent(), ele);
     50    }
     51
     52    public boolean getValue(StyleAttribute attrib, double curTime)
     53    {
     54        Color col = getValue(curTime);
     55        if (col == null) return false;
     56
     57        attrib.setStringValue("#" + Integer.toHexString(col.getRGB()));
     58        return true;
     59    }
     60
     61    public Color getValue(double curTime)
     62    {
     63        Color retVal = null;
     64        AnimationTimeEval state = new AnimationTimeEval();
     65
     66        for (Iterator it = animEvents.iterator(); it.hasNext();)
     67        {
     68            AnimateBase ele = (AnimateBase)it.next();
     69            AnimateColorIface eleColor = (AnimateColorIface)ele;
     70            ele.evalParametric(state, curTime);
     71
     72            //Reject value if it is in the invalid state
     73            if (Double.isNaN(state.interp)) continue;
     74
     75            if (retVal == null)
     76            {
     77                retVal = eleColor.evalColor(state.interp);
     78                continue;
     79            }
     80           
     81            Color curCol = eleColor.evalColor(state.interp);
     82            switch (ele.getAdditiveType())
     83            {
     84                case AnimationElement.AD_REPLACE:
     85                    retVal = curCol;
     86                    break;
     87                case AnimationElement.AD_SUM:
     88                    retVal = new Color(curCol.getRed() + retVal.getRed(), curCol.getGreen() + retVal.getGreen(), curCol.getBlue() + retVal.getBlue());
     89                    break;
     90            }
     91        }
     92
     93        return retVal;
     94    }
     95}
  • new file core/src/com/kitfox/svg/animation/TrackDouble.java

    - +  
     1/*
     2 * TrackManager.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 11:34 PM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.xml.StyleAttribute;
     30import java.util.*;
     31
     32import com.kitfox.svg.*;
     33import com.kitfox.svg.xml.*;
     34
     35/**
     36 * A track holds the animation events for a single parameter of a single SVG
     37 * element.  It also contains the default value for the element, should the
     38 * user want to see the 'unanimated' value.
     39 *
     40 * @author Mark McKay
     41 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     42 */
     43public class TrackDouble extends TrackBase
     44{
     45    public TrackDouble(AnimationElement ele) throws SVGElementException
     46    {
     47        super(ele.getParent(), ele);
     48    }
     49
     50    public boolean getValue(StyleAttribute attrib, double curTime)
     51    {
     52        double val = getValue(curTime);
     53        if (Double.isNaN(val)) return false;
     54
     55        attrib.setStringValue("" + val);
     56        return true;
     57    }
     58
     59    public double getValue(double curTime)
     60    {
     61        double retVal = Double.NaN;
     62       
     63        StyleAttribute attr = null;
     64        switch (attribType)
     65        {
     66            case AnimationElement.AT_CSS:
     67                attr = parent.getStyleAbsolute(attribName);
     68                retVal = attr.getDoubleValue();
     69                break;
     70            case AnimationElement.AT_XML:
     71                attr = parent.getPresAbsolute(attribName);
     72                retVal = attr.getDoubleValue();
     73                break;
     74            case AnimationElement.AT_AUTO:
     75                attr = parent.getStyleAbsolute(attribName);
     76                if (attr == null) attr = parent.getPresAbsolute(attribName);
     77                retVal = attr.getDoubleValue();
     78                break;
     79        }
     80       
     81       
     82       
     83        AnimationTimeEval state = new AnimationTimeEval();
     84//        boolean pastEnd = true;
     85
     86        for (Iterator it = animEvents.iterator(); it.hasNext();)
     87        {
     88            Animate ele = (Animate)it.next();
     89            ele.evalParametric(state, curTime);
     90
     91            //Go to next element if this one does not affect processing
     92            if (Double.isNaN(state.interp)) continue;
     93
     94            switch (ele.getAdditiveType())
     95            {
     96                case AnimationElement.AD_SUM:
     97                    retVal += ele.eval(state.interp);
     98                    break;
     99                case AnimationElement.AD_REPLACE:
     100                    retVal = ele.eval(state.interp);
     101                    break;
     102            }
     103           
     104            //Evalutae accumulation if applicable
     105            if (state.rep > 0)
     106            {
     107                switch (ele.getAccumulateType())
     108                {
     109                    case AnimationElement.AC_SUM:
     110                        retVal += ele.repeatSkipSize(state.rep);
     111                        break;
     112                }
     113               
     114            }
     115        }
     116
     117        return retVal;
     118    }
     119}
  • new file core/src/com/kitfox/svg/animation/TrackManager.java

    - +  
     1/*
     2 * TrackManager.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on August 15, 2004, 11:34 PM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import java.util.*;
     30
     31import com.kitfox.svg.*;
     32import java.io.Serializable;
     33
     34/**
     35 * Every element contains tracks, which manage the animation.  There is one track
     36 * for every parameter with animation, and each track in turn is composed of
     37 * many events.
     38 *
     39 * @author Mark McKay
     40 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     41 */
     42public class TrackManager implements Serializable
     43{
     44    public static final long serialVersionUID = 0;
     45   
     46    static class TrackKey
     47    {
     48        String name;
     49        int type;
     50       
     51        TrackKey(AnimationElement base)
     52        {
     53            this(base.getAttribName(), base.getAttribType());
     54        }
     55       
     56        TrackKey(String name, int type)
     57        {
     58            this.name = name;
     59            this.type = type;
     60        }
     61       
     62        public int hashCode() { return name.hashCode() ^ type; }
     63        public boolean equals(Object obj)
     64        {
     65            if (!(obj instanceof TrackKey)) return false;
     66            TrackKey key = (TrackKey)obj;
     67            return key.type == type && key.name.equals(name);
     68        }
     69    }
     70   
     71    HashMap tracks = new HashMap();
     72   
     73    /** Creates a new instance of TrackManager */
     74    public TrackManager()
     75    {
     76    }
     77   
     78    /**
     79     * Adds a new animation element to this track
     80     */
     81    public void addTrackElement(AnimationElement element) throws SVGElementException
     82    {
     83        TrackKey key = new TrackKey(element);
     84       
     85        TrackBase track = (TrackBase)tracks.get(key);
     86       
     87        if (track == null)
     88        {
     89            //Create a track for this element
     90            if (element instanceof Animate)
     91            {
     92                switch (((Animate)element).getDataType())
     93                {
     94                    case Animate.DT_REAL:
     95                        track = new TrackDouble(element);
     96                        break;
     97                    case Animate.DT_COLOR:
     98                        track = new TrackColor(element);
     99                        break;
     100                    case Animate.DT_PATH:
     101                        track = new TrackPath(element);
     102                        break;
     103                    default:
     104                        throw new RuntimeException("");
     105                }
     106            }
     107            else if (element instanceof AnimateColor)
     108            {
     109                track = new TrackColor(element);
     110            }
     111            else if (element instanceof AnimateTransform || element instanceof AnimateMotion)
     112            {
     113                track = new TrackTransform(element);
     114            }
     115           
     116            tracks.put(key, track);
     117        }
     118 
     119        track.addElement(element);
     120    }
     121   
     122    public TrackBase getTrack(String name, int type)
     123    {
     124        //Handle AUTO, which will match either CSS or XML (in that order)
     125        if (type == AnimationElement.AT_AUTO)
     126        {
     127            TrackBase t = getTrack(name, AnimationElement.AT_CSS);
     128            if (t != null) return t;
     129            t = getTrack(name, AnimationElement.AT_XML);
     130            if (t != null) return t;
     131            return null;
     132        }
     133       
     134        //Get requested attribute
     135        TrackKey key = new TrackKey(name, type);
     136        TrackBase t = (TrackBase)tracks.get(key);
     137        if (t != null) return t;
     138       
     139        //If that didn't exist, see if one exists of type AUTO
     140        key = new TrackKey(name, AnimationElement.AT_AUTO);
     141        return (TrackBase)tracks.get(key);
     142    }
     143   
     144    public int getNumTracks()
     145    {
     146        return tracks.size();
     147    }
     148   
     149    public Iterator iterator()
     150    {
     151        return tracks.values().iterator();
     152    }
     153}
  • new file core/src/com/kitfox/svg/animation/TrackMotion.java

    - +  
     1/*
     2 * TrackManager.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on September 21, 2004, 11:34 PM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.xml.StyleAttribute;
     30import java.awt.geom.*;
     31import java.util.*;
     32
     33import com.kitfox.svg.*;
     34import com.kitfox.svg.xml.*;
     35
     36/**
     37 * A track holds the animation events for a single parameter of a single SVG
     38 * element.  It also contains the default value for the element, should the
     39 * user want to see the 'unanimated' value.
     40 *
     41 * @author Mark McKay
     42 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     43 */
     44public class TrackMotion extends TrackBase
     45{
     46    public TrackMotion(AnimationElement ele) throws SVGElementException
     47    {
     48        //The motion element implies a CSS attribute of transform
     49//        super(ele.getParent(), "transform", AnimationElement.AT_CSS);
     50        super(ele.getParent(), ele);
     51    }
     52
     53    public boolean getValue(StyleAttribute attrib, double curTime) throws SVGException
     54    {
     55        AffineTransform retVal = new AffineTransform();
     56        retVal = getValue(retVal, curTime);
     57//        AffineTransform val = getValue(curTime);
     58//        if (val == null) return false;
     59
     60        double[] mat = new double[6];
     61        retVal.getMatrix(mat);
     62        attrib.setStringValue("matrix(" + mat[0] + " " + mat[1] + " " + mat[2] + " " + mat[3] + " " + mat[4] + " " + mat[5] + ")");
     63        return true;
     64    }
     65
     66    public AffineTransform getValue(AffineTransform retVal, double curTime) throws SVGException
     67    {
     68        //Init transform with default state
     69        StyleAttribute attr = null;
     70        switch (attribType)
     71        {
     72            case AnimationElement.AT_CSS:
     73                attr = parent.getStyleAbsolute(attribName);
     74                retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
     75                break;
     76            case AnimationElement.AT_XML:
     77                attr = parent.getPresAbsolute(attribName);
     78                retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
     79                break;
     80            case AnimationElement.AT_AUTO:
     81                attr = parent.getStyleAbsolute(attribName);
     82                if (attr == null) attr = parent.getPresAbsolute(attribName);
     83                retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
     84                break;
     85        }
     86
     87
     88        //Update transform with time based information
     89        AnimationTimeEval state = new AnimationTimeEval();
     90        AffineTransform xform = new AffineTransform();
     91//        boolean pastEnd = true;
     92
     93        for (Iterator it = animEvents.iterator(); it.hasNext();)
     94        {
     95            AnimateMotion ele = (AnimateMotion)it.next();
     96            ele.evalParametric(state, curTime);
     97
     98            //Go to next element if this one does not affect processing
     99            if (Double.isNaN(state.interp)) continue;
     100
     101            switch (ele.getAdditiveType())
     102            {
     103                case AnimationElement.AD_SUM:
     104                    retVal.concatenate(ele.eval(xform, state.interp));
     105                    break;
     106                case AnimationElement.AD_REPLACE:
     107                    retVal.setTransform(ele.eval(xform, state.interp));
     108                    break;
     109            }
     110
     111            //Evaluate accumulation if applicable
     112/*
     113            if (state.rep > 0)
     114            {
     115                switch (ele.getAccumulateType())
     116                {
     117                    case AnimationElement.AC_SUM:
     118                        retVal += ele.repeatSkipSize(state.rep);
     119                        break;
     120                }
     121
     122            }
     123*/
     124        }
     125
     126        return retVal;
     127    }
     128}
  • new file core/src/com/kitfox/svg/animation/TrackPath.java

    - +  
     1/*
     2 * TrackManager.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on September 21, 2004, 11:34 PM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.xml.StyleAttribute;
     30import java.awt.*;
     31import java.awt.geom.*;
     32import java.util.*;
     33
     34import com.kitfox.svg.pathcmd.*;
     35import com.kitfox.svg.*;
     36import com.kitfox.svg.xml.*;
     37
     38/**
     39 * A track holds the animation events for a single parameter of a single SVG
     40 * element.  It also contains the default value for the element, should the
     41 * user want to see the 'unanimated' value.
     42 *
     43 * @author Mark McKay
     44 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     45 */
     46public class TrackPath extends TrackBase
     47{
     48
     49    public TrackPath(AnimationElement ele) throws SVGElementException
     50    {
     51        super(ele.getParent(), ele);
     52    }
     53
     54    public boolean getValue(StyleAttribute attrib, double curTime)
     55    {
     56        GeneralPath path = getValue(curTime);
     57        if (path == null) return false;
     58
     59        attrib.setStringValue(PathUtil.buildPathString(path));
     60        return true;
     61    }
     62
     63    public GeneralPath getValue(double curTime)
     64    {
     65        GeneralPath retVal = null;
     66        AnimationTimeEval state = new AnimationTimeEval();
     67
     68        for (Iterator it = animEvents.iterator(); it.hasNext();)
     69        {
     70            AnimateBase ele = (AnimateBase)it.next();
     71            Animate eleAnim = (Animate)ele;
     72            ele.evalParametric(state, curTime);
     73
     74            //Reject value if it is in the invalid state
     75            if (Double.isNaN(state.interp)) continue;
     76
     77            if (retVal == null)
     78            {
     79                retVal = eleAnim.evalPath(state.interp);
     80                continue;
     81            }
     82           
     83            GeneralPath curPath = eleAnim.evalPath(state.interp);
     84            switch (ele.getAdditiveType())
     85            {
     86                case AnimationElement.AD_REPLACE:
     87                    retVal = curPath;
     88                    break;
     89                case AnimationElement.AD_SUM:
     90                    throw new RuntimeException("Not implemented");
     91//                    retVal = new Color(curCol.getRed() + retVal.getRed(), curCol.getGreen() + retVal.getGreen(), curCol.getBlue() + retVal.getBlue());
     92//                    break;
     93                default:
     94                    throw new RuntimeException();
     95            }
     96        }
     97
     98        return retVal;
     99    }
     100}
  • new file core/src/com/kitfox/svg/animation/TrackTransform.java

    - +  
     1/*
     2 * TrackManager.java
     3 *
     4 *  The Salamander Project - 2D and 3D graphics libraries in Java
     5 *  Copyright (C) 2004 Mark McKay
     6 *
     7 *  This library is free software; you can redistribute it and/or
     8 *  modify it under the terms of the GNU Lesser General Public
     9 *  License as published by the Free Software Foundation; either
     10 *  version 2.1 of the License, or (at your option) any later version.
     11 *
     12 *  This library is distributed in the hope that it will be useful,
     13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     15 *  Lesser General Public License for more details.
     16 *
     17 *  You should have received a copy of the GNU Lesser General Public
     18 *  License along with this library; if not, write to the Free Software
     19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20 *
     21 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     22 *  projects can be found at http://www.kitfox.com
     23 *
     24 * Created on September 21, 2004, 11:34 PM
     25 */
     26
     27package com.kitfox.svg.animation;
     28
     29import com.kitfox.svg.xml.StyleAttribute;
     30import java.awt.geom.*;
     31import java.util.*;
     32
     33import com.kitfox.svg.*;
     34import com.kitfox.svg.xml.*;
     35
     36/**
     37 * A track holds the animation events for a single parameter of a single SVG
     38 * element.  It also contains the default value for the element, should the
     39 * user want to see the 'unanimated' value.
     40 *
     41 * @author Mark McKay
     42 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     43 */
     44public class TrackTransform extends TrackBase
     45{
     46    public TrackTransform(AnimationElement ele) throws SVGElementException
     47    {
     48        super(ele.getParent(), ele);
     49    }
     50
     51    public boolean getValue(StyleAttribute attrib, double curTime) throws SVGException
     52    {
     53        AffineTransform retVal = new AffineTransform();
     54        retVal = getValue(retVal, curTime);
     55//        AffineTransform val = getValue(curTime);
     56//        if (val == null) return false;
     57
     58        double[] mat = new double[6];
     59        retVal.getMatrix(mat);
     60        attrib.setStringValue("matrix(" + mat[0] + " " + mat[1] + " " + mat[2] + " " + mat[3] + " " + mat[4] + " " + mat[5] + ")");
     61        return true;
     62    }
     63
     64    public AffineTransform getValue(AffineTransform retVal, double curTime) throws SVGException
     65    {
     66        //Init transform with default state
     67        StyleAttribute attr = null;
     68        switch (attribType)
     69        {
     70            case AnimationElement.AT_CSS:
     71                attr = parent.getStyleAbsolute(attribName);
     72                retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
     73                break;
     74            case AnimationElement.AT_XML:
     75                attr = parent.getPresAbsolute(attribName);
     76                retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
     77                break;
     78            case AnimationElement.AT_AUTO:
     79                attr = parent.getStyleAbsolute(attribName);
     80                if (attr == null) attr = parent.getPresAbsolute(attribName);
     81                retVal.setTransform(SVGElement.parseSingleTransform(attr.getStringValue()));
     82                break;
     83        }
     84
     85
     86        //Update transform with time based information
     87        AnimationTimeEval state = new AnimationTimeEval();
     88        AffineTransform xform = new AffineTransform();
     89
     90        for (Iterator it = animEvents.iterator(); it.hasNext();)
     91        {
     92            AnimateXform ele = (AnimateXform)it.next();
     93            ele.evalParametric(state, curTime);
     94
     95            //Go to next element if this one does not affect processing
     96            if (Double.isNaN(state.interp)) continue;
     97
     98            switch (ele.getAdditiveType())
     99            {
     100                case AnimationElement.AD_SUM:
     101                    retVal.concatenate(ele.eval(xform, state.interp));
     102                    break;
     103                case AnimationElement.AD_REPLACE:
     104                    retVal.setTransform(ele.eval(xform, state.interp));
     105                    break;
     106            }
     107
     108        }
     109
     110        return retVal;
     111    }
     112}
  • src/com/kitfox/svg/SVGElement.java

    old new  
    3333import java.awt.geom.*;
    3434
    3535import org.xml.sax.*;
     36import com.kitfox.svg.animation.*;
    3637import com.kitfox.svg.pathcmd.*;
    3738import com.kitfox.svg.xml.*;
    3839import java.io.Serializable;
     
    100101     */
    101102//    protected SVGUniverse universe;
    102103   
     104    protected final TrackManager trackManager = new TrackManager();
     105
    103106    boolean dirty = true;
    104107
    105108//    public static final Matcher adobeId = Pattern.compile("(.*)_1_").matcher("");
     
    265268        }
    266269    }
    267270   
     271    public void addAttribute(String name, int attribType, String value) throws SVGElementException
     272    {
     273        if (hasAttribute(name, attribType)) throw new SVGElementException(this, "Attribute " + name + "(" + AnimationElement.animationElementToString(attribType) + ") already exists");
     274       
     275        //Alter layout for id attribute
     276        if ("id".equals(name) && diagram != null)
     277        {
     278            diagram.removeElement(this.id);
     279            this.id = name;
     280            diagram.setElement(this.id, this);
     281        }
     282       
     283        switch (attribType)
     284        {
     285            case AnimationElement.AT_CSS:
     286                inlineStyles.put(name, new StyleAttribute(name, value));
     287                return;
     288            case AnimationElement.AT_XML:
     289                presAttribs.put(name, new StyleAttribute(name, value));
     290                return;
     291        }
     292       
     293        throw new SVGElementException(this, "Invalid attribute type " + attribType);
     294    }
     295   
     296    public boolean hasAttribute(String name, int attribType) throws SVGElementException
     297    {
     298        switch (attribType)
     299        {
     300            case AnimationElement.AT_CSS:
     301                return inlineStyles.containsKey(name);
     302            case AnimationElement.AT_XML:
     303                return presAttribs.containsKey(name);
     304            case AnimationElement.AT_AUTO:
     305                return inlineStyles.containsKey(name) || presAttribs.containsKey(name);
     306        }
     307       
     308        throw new SVGElementException(this, "Invalid attribute type " + attribType);
     309    }
     310   
    268311    /**
    269312     * @return a set of Strings that corespond to CSS attributes on this element
    270313     */
     
    290333        children.add(child);
    291334        child.parent = this;
    292335        child.setDiagram(diagram);
     336       
     337        //Add info to track if we've scanned animation element
     338        if (child instanceof AnimationElement)
     339        {
     340            trackManager.addTrackElement((AnimationElement)child);
     341        }
    293342    }
    294343   
    295344    private void setDiagram(SVGDiagram diagram)
     
    408457        return getStyle(attrib, true);
    409458    }
    410459   
     460   
     461    public void setAttribute(String name, int attribType, String value) throws SVGElementException
     462    {
     463        StyleAttribute styAttr;
     464       
     465       
     466        switch (attribType)
     467        {
     468            case AnimationElement.AT_CSS:
     469            {
     470                styAttr = (StyleAttribute)inlineStyles.get(name);
     471                break;
     472            }
     473            case AnimationElement.AT_XML:
     474            {
     475                styAttr = (StyleAttribute)presAttribs.get(name);
     476                break;
     477            }
     478            case AnimationElement.AT_AUTO:
     479            {
     480                styAttr = (StyleAttribute)inlineStyles.get(name);
     481               
     482                if (styAttr == null)
     483                {
     484                    styAttr = (StyleAttribute)presAttribs.get(name);
     485                }
     486                break;
     487            }
     488            default:
     489                throw new SVGElementException(this, "Invalid attribute type " + attribType);
     490        }
     491       
     492        if (styAttr == null)
     493        {
     494            throw new SVGElementException(this, "Could not find attribute " + name + "(" + AnimationElement.animationElementToString(attribType) + ").  Make sure to create attribute before setting it.");
     495        }
     496       
     497        //Alter layout for relevant attributes
     498        if ("id".equals(styAttr.getName()))
     499        {
     500            diagram.removeElement(this.id);
     501            this.id = name;
     502            diagram.setElement(this.id, this);
     503        }
     504       
     505        styAttr.setStringValue(value);
     506    }
     507   
    411508    /**
    412509     * Copies the current style into the passed style attribute.  Checks for
    413510     * inline styles first, then internal and extranal style sheets, and
     
    427524       
    428525        attrib.setStringValue(styAttr == null ? "" : styAttr.getStringValue());
    429526       
     527        //Evalutate coresponding track, if one exists
     528        TrackBase track = trackManager.getTrack(styName, AnimationElement.AT_CSS);
     529        if (track != null)
     530        {
     531            track.getValue(attrib, diagram.getUniverse().getCurTime());
     532            return true;
     533        }
     534       
    430535        //Return if we've found a non animated style
    431536        if (styAttr != null) return true;
    432537       
     
    439544       
    440545        attrib.setStringValue(presAttr == null ? "" : presAttr.getStringValue());
    441546       
     547        //Evalutate coresponding track, if one exists
     548        track = trackManager.getTrack(styName, AnimationElement.AT_XML);
     549        if (track != null)
     550        {
     551            track.getValue(attrib, diagram.getUniverse().getCurTime());
     552            return true;
     553        }
     554       
    442555        //Return if we've found a presentation attribute instead
    443556        if (presAttr != null) return true;
    444557       
     
    480593        //Copy presentation value directly
    481594        attrib.setStringValue(presAttr == null ? "" : presAttr.getStringValue());
    482595       
     596        //Evalutate coresponding track, if one exists
     597        TrackBase track = trackManager.getTrack(presName, AnimationElement.AT_XML);
     598        if (track != null)
     599        {
     600            track.getValue(attrib, diagram.getUniverse().getCurTime());
     601            return true;
     602        }
     603       
    483604        //Return if we found presentation attribute
    484605        if (presAttr != null) return true;
    485606       
  • src/com/kitfox/svg/SVGLoader.java

    old new  
    3333import org.xml.sax.*;
    3434import org.xml.sax.helpers.DefaultHandler;
    3535
     36import com.kitfox.svg.animation.*;
     37
    3638/**
    3739 * @author Mark McKay
    3840 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     
    7577
    7678        //Compile a list of important builder classes
    7779        nodeClasses.put("a", A.class);
     80        nodeClasses.put("animate", Animate.class);
     81        nodeClasses.put("animatecolor", AnimateColor.class);
     82        nodeClasses.put("animatemotion", AnimateMotion.class);
     83        nodeClasses.put("animatetransform", AnimateTransform.class);
    7884        nodeClasses.put("circle", Circle.class);
    7985        nodeClasses.put("clippath", ClipPath.class);
    8086        nodeClasses.put("defs", Defs.class);
     
    98104        nodeClasses.put("polyline", Polyline.class);
    99105        nodeClasses.put("radialgradient", RadialGradient.class);
    100106        nodeClasses.put("rect", Rect.class);
     107        nodeClasses.put("set", SetSmil.class);
    101108        nodeClasses.put("shape", ShapeElement.class);
    102109        nodeClasses.put("stop", Stop.class);
    103110        nodeClasses.put("style", Style.class);
  • src/com/kitfox/svg/SVGLoaderHelper.java

    old new  
    2828package com.kitfox.svg;
    2929
    3030import java.net.*;
     31import java.io.*;
     32
     33import com.kitfox.svg.animation.parser.*;
    3134
    3235/**
    3336 * @author Mark McKay
     
    4750
    4851    public final URI xmlBase;
    4952
     53    /**
     54     * Animate nodes use this to parse their time strings
     55     */
     56    public final AnimTimeParser animTimeParser = new AnimTimeParser(new StringReader(""));
     57   
    5058    /** Creates a new instance of SVGLoaderHelper */
    5159    public SVGLoaderHelper(URI xmlBase, SVGUniverse universe, SVGDiagram diagram)
    5260    {
  • new file core/src/com/kitfox/svg/app/MainFrame.java

    - +  
     1/*
     2 * MainFrame.java
     3 *
     4 * Created on September 6, 2004, 1:19 AM
     5 */
     6
     7package com.kitfox.svg.app;
     8
     9/**
     10 *
     11 * @author  kitfox
     12 */
     13public class MainFrame extends javax.swing.JFrame
     14{
     15    public static final long serialVersionUID = 1;
     16   
     17    /** Creates new form MainFrame */
     18    public MainFrame()
     19    {
     20        initComponents();
     21    }
     22   
     23    /** This method is called from within the constructor to
     24     * initialize the form.
     25     * WARNING: Do NOT modify this code. The content of this method is
     26     * always regenerated by the Form Editor.
     27     */
     28    private void initComponents()//GEN-BEGIN:initComponents
     29    {
     30        jPanel1 = new javax.swing.JPanel();
     31        bn_svgViewer = new javax.swing.JButton();
     32        bn_svgViewer1 = new javax.swing.JButton();
     33        jPanel2 = new javax.swing.JPanel();
     34        bn_quit = new javax.swing.JButton();
     35
     36        setTitle("SVG Salamander - Application Launcher");
     37        addWindowListener(new java.awt.event.WindowAdapter()
     38        {
     39            public void windowClosing(java.awt.event.WindowEvent evt)
     40            {
     41                exitForm(evt);
     42            }
     43        });
     44
     45        jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS));
     46
     47        bn_svgViewer.setText("SVG Viewer (No animation)");
     48        bn_svgViewer.addActionListener(new java.awt.event.ActionListener()
     49        {
     50            public void actionPerformed(java.awt.event.ActionEvent evt)
     51            {
     52                bn_svgViewerActionPerformed(evt);
     53            }
     54        });
     55
     56        jPanel1.add(bn_svgViewer);
     57
     58        bn_svgViewer1.setText("SVG Player (Animation)");
     59        bn_svgViewer1.addActionListener(new java.awt.event.ActionListener()
     60        {
     61            public void actionPerformed(java.awt.event.ActionEvent evt)
     62            {
     63                bn_svgViewer1ActionPerformed(evt);
     64            }
     65        });
     66
     67        jPanel1.add(bn_svgViewer1);
     68
     69        getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
     70
     71        bn_quit.setText("Quit");
     72        bn_quit.addActionListener(new java.awt.event.ActionListener()
     73        {
     74            public void actionPerformed(java.awt.event.ActionEvent evt)
     75            {
     76                bn_quitActionPerformed(evt);
     77            }
     78        });
     79
     80        jPanel2.add(bn_quit);
     81
     82        getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);
     83
     84        pack();
     85    }//GEN-END:initComponents
     86
     87    private void bn_svgViewer1ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_svgViewer1ActionPerformed
     88    {//GEN-HEADEREND:event_bn_svgViewer1ActionPerformed
     89        SVGPlayer.main(null);
     90
     91        close();
     92    }//GEN-LAST:event_bn_svgViewer1ActionPerformed
     93
     94    private void bn_svgViewerActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_svgViewerActionPerformed
     95    {//GEN-HEADEREND:event_bn_svgViewerActionPerformed
     96        SVGViewer.main(null);
     97
     98        close();
     99    }//GEN-LAST:event_bn_svgViewerActionPerformed
     100
     101    private void bn_quitActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_quitActionPerformed
     102    {//GEN-HEADEREND:event_bn_quitActionPerformed
     103        exitForm(null);
     104    }//GEN-LAST:event_bn_quitActionPerformed
     105   
     106    /** Exit the Application */
     107    private void exitForm(java.awt.event.WindowEvent evt)//GEN-FIRST:event_exitForm
     108    {
     109        System.exit(0);
     110    }//GEN-LAST:event_exitForm
     111   
     112    private void close()
     113    {
     114        this.setVisible(false);
     115        this.dispose();
     116    }
     117   
     118    /**
     119     * @param args the command line arguments
     120     */
     121    public static void main(String args[])
     122    {
     123        new MainFrame().setVisible(true);
     124    }
     125   
     126    // Variables declaration - do not modify//GEN-BEGIN:variables
     127    private javax.swing.JButton bn_quit;
     128    private javax.swing.JButton bn_svgViewer;
     129    private javax.swing.JButton bn_svgViewer1;
     130    private javax.swing.JPanel jPanel1;
     131    private javax.swing.JPanel jPanel2;
     132    // End of variables declaration//GEN-END:variables
     133   
     134}
  • new file core/src/com/kitfox/svg/app/PlayerDialog.java

    - +  
     1/*
     2 * PlayerDialog.java
     3 *
     4 *
     5 *  The Salamander Project - 2D and 3D graphics libraries in Java
     6 *  Copyright (C) 2004 Mark McKay
     7 *
     8 *  This library is free software; you can redistribute it and/or
     9 *  modify it under the terms of the GNU Lesser General Public
     10 *  License as published by the Free Software Foundation; either
     11 *  version 2.1 of the License, or (at your option) any later version.
     12 *
     13 *  This library is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     16 *  Lesser General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU Lesser General Public
     19 *  License along with this library; if not, write to the Free Software
     20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     21 *
     22 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     23 *  projects can be found at http://www.kitfox.com
     24 *
     25 * Created on September 28, 2004, 9:56 PM
     26 */
     27
     28package com.kitfox.svg.app;
     29
     30/**
     31 *
     32 * @author  kitfox
     33 */
     34public class PlayerDialog extends javax.swing.JDialog implements PlayerThreadListener
     35{
     36    public static final long serialVersionUID = 1;
     37   
     38    PlayerThread thread;
     39   
     40    final SVGPlayer parent;
     41   
     42    /** Creates new form PlayerDialog */
     43    public PlayerDialog(SVGPlayer parent)
     44    {
     45        super(parent, false);
     46        initComponents();
     47       
     48        this.parent = parent;
     49       
     50        thread = new PlayerThread();
     51        thread.addListener(this);
     52       
     53        text_timeStepActionPerformed(null);
     54    }
     55   
     56    public void updateTime(double curTime, double timeStep, int playState)
     57    {
     58        if (playState == PlayerThread.PS_STOP) return;
     59       
     60        text_curTime.setText("" + (float)curTime);
     61        parent.updateTime(curTime);
     62//        text_timeStep.setText("" + (int)(1.0 / timeStep));
     63    }
     64   
     65    /** This method is called from within the constructor to
     66     * initialize the form.
     67     * WARNING: Do NOT modify this code. The content of this method is
     68     * always regenerated by the Form Editor.
     69     */
     70    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
     71    private void initComponents()
     72    {
     73        jPanel1 = new javax.swing.JPanel();
     74        bn_playBack = new javax.swing.JButton();
     75        bn_stop = new javax.swing.JButton();
     76        bn_playFwd = new javax.swing.JButton();
     77        jPanel2 = new javax.swing.JPanel();
     78        jPanel3 = new javax.swing.JPanel();
     79        jLabel1 = new javax.swing.JLabel();
     80        text_curTime = new javax.swing.JTextField();
     81        bn_time0 = new javax.swing.JButton();
     82        jPanel4 = new javax.swing.JPanel();
     83        jLabel2 = new javax.swing.JLabel();
     84        text_timeStep = new javax.swing.JTextField();
     85
     86        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
     87        setTitle("Player");
     88        addWindowListener(new java.awt.event.WindowAdapter()
     89        {
     90            public void windowClosed(java.awt.event.WindowEvent evt)
     91            {
     92                formWindowClosed(evt);
     93            }
     94        });
     95
     96        bn_playBack.setText("<");
     97        bn_playBack.setToolTipText("Play backwards");
     98        bn_playBack.addActionListener(new java.awt.event.ActionListener()
     99        {
     100            public void actionPerformed(java.awt.event.ActionEvent evt)
     101            {
     102                bn_playBackActionPerformed(evt);
     103            }
     104        });
     105
     106        jPanel1.add(bn_playBack);
     107
     108        bn_stop.setText("||");
     109        bn_stop.setToolTipText("Stop playback");
     110        bn_stop.addActionListener(new java.awt.event.ActionListener()
     111        {
     112            public void actionPerformed(java.awt.event.ActionEvent evt)
     113            {
     114                bn_stopActionPerformed(evt);
     115            }
     116        });
     117
     118        jPanel1.add(bn_stop);
     119
     120        bn_playFwd.setText(">");
     121        bn_playFwd.setToolTipText("Play Forwards");
     122        bn_playFwd.addActionListener(new java.awt.event.ActionListener()
     123        {
     124            public void actionPerformed(java.awt.event.ActionEvent evt)
     125            {
     126                bn_playFwdActionPerformed(evt);
     127            }
     128        });
     129
     130        jPanel1.add(bn_playFwd);
     131
     132        getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);
     133
     134        jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.Y_AXIS));
     135
     136        jLabel1.setText("Cur Time");
     137        jPanel3.add(jLabel1);
     138
     139        text_curTime.setHorizontalAlignment(javax.swing.JTextField.LEFT);
     140        text_curTime.setText("0");
     141        text_curTime.setPreferredSize(new java.awt.Dimension(100, 21));
     142        text_curTime.addActionListener(new java.awt.event.ActionListener()
     143        {
     144            public void actionPerformed(java.awt.event.ActionEvent evt)
     145            {
     146                text_curTimeActionPerformed(evt);
     147            }
     148        });
     149        text_curTime.addFocusListener(new java.awt.event.FocusAdapter()
     150        {
     151            public void focusLost(java.awt.event.FocusEvent evt)
     152            {
     153                text_curTimeFocusLost(evt);
     154            }
     155        });
     156
     157        jPanel3.add(text_curTime);
     158
     159        bn_time0.setText("Time 0");
     160        bn_time0.setToolTipText("Reset time to first frame");
     161        bn_time0.addActionListener(new java.awt.event.ActionListener()
     162        {
     163            public void actionPerformed(java.awt.event.ActionEvent evt)
     164            {
     165                bn_time0ActionPerformed(evt);
     166            }
     167        });
     168
     169        jPanel3.add(bn_time0);
     170
     171        jPanel2.add(jPanel3);
     172
     173        jLabel2.setText("Frames Per Second");
     174        jPanel4.add(jLabel2);
     175
     176        text_timeStep.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
     177        text_timeStep.setText("60");
     178        text_timeStep.setPreferredSize(new java.awt.Dimension(100, 21));
     179        text_timeStep.addActionListener(new java.awt.event.ActionListener()
     180        {
     181            public void actionPerformed(java.awt.event.ActionEvent evt)
     182            {
     183                text_timeStepActionPerformed(evt);
     184            }
     185        });
     186        text_timeStep.addFocusListener(new java.awt.event.FocusAdapter()
     187        {
     188            public void focusLost(java.awt.event.FocusEvent evt)
     189            {
     190                text_timeStepFocusLost(evt);
     191            }
     192        });
     193
     194        jPanel4.add(text_timeStep);
     195
     196        jPanel2.add(jPanel4);
     197
     198        getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);
     199
     200        pack();
     201    }// </editor-fold>//GEN-END:initComponents
     202
     203    private void bn_time0ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_time0ActionPerformed
     204    {//GEN-HEADEREND:event_bn_time0ActionPerformed
     205        thread.setCurTime(0);
     206    }//GEN-LAST:event_bn_time0ActionPerformed
     207
     208    private void bn_playFwdActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_playFwdActionPerformed
     209    {//GEN-HEADEREND:event_bn_playFwdActionPerformed
     210        thread.setPlayState(PlayerThread.PS_PLAY_FWD);
     211    }//GEN-LAST:event_bn_playFwdActionPerformed
     212
     213    private void bn_stopActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_stopActionPerformed
     214    {//GEN-HEADEREND:event_bn_stopActionPerformed
     215        thread.setPlayState(PlayerThread.PS_STOP);
     216    }//GEN-LAST:event_bn_stopActionPerformed
     217
     218    private void bn_playBackActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_playBackActionPerformed
     219    {//GEN-HEADEREND:event_bn_playBackActionPerformed
     220        thread.setPlayState(PlayerThread.PS_PLAY_BACK);
     221    }//GEN-LAST:event_bn_playBackActionPerformed
     222
     223    private void formWindowClosed(java.awt.event.WindowEvent evt)//GEN-FIRST:event_formWindowClosed
     224    {//GEN-HEADEREND:event_formWindowClosed
     225//        thread.exit();
     226    }//GEN-LAST:event_formWindowClosed
     227
     228    private void text_timeStepFocusLost(java.awt.event.FocusEvent evt)//GEN-FIRST:event_text_timeStepFocusLost
     229    {//GEN-HEADEREND:event_text_timeStepFocusLost
     230        text_timeStepActionPerformed(null);
     231    }//GEN-LAST:event_text_timeStepFocusLost
     232
     233    private void text_timeStepActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_text_timeStepActionPerformed
     234    {//GEN-HEADEREND:event_text_timeStepActionPerformed
     235        try
     236        {
     237            int val = Integer.parseInt(text_timeStep.getText());
     238            thread.setTimeStep(1.0 / val);
     239        }
     240        catch (Exception e)
     241        {
     242        }
     243       
     244        double d = thread.getTimeStep();
     245        String newStrn = "" + (int)(1f / d);
     246        if (newStrn.equals(text_timeStep.getText())) return;
     247        text_timeStep.setText(newStrn);
     248       
     249//        text_timeStepActionPerformed(null);
     250    }//GEN-LAST:event_text_timeStepActionPerformed
     251
     252    private void text_curTimeActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_text_curTimeActionPerformed
     253    {//GEN-HEADEREND:event_text_curTimeActionPerformed
     254        try
     255        {
     256            double val = Double.parseDouble(text_curTime.getText());
     257            thread.setCurTime(val);
     258        }
     259        catch (Exception e)
     260        {
     261        }
     262       
     263        double d = thread.getCurTime();
     264        text_curTime.setText("" + (float)d);
     265       
     266        text_timeStepActionPerformed(null);
     267    }//GEN-LAST:event_text_curTimeActionPerformed
     268
     269    private void text_curTimeFocusLost(java.awt.event.FocusEvent evt)//GEN-FIRST:event_text_curTimeFocusLost
     270    {//GEN-HEADEREND:event_text_curTimeFocusLost
     271        text_curTimeActionPerformed(null);
     272    }//GEN-LAST:event_text_curTimeFocusLost
     273   
     274    // Variables declaration - do not modify//GEN-BEGIN:variables
     275    private javax.swing.JButton bn_playBack;
     276    private javax.swing.JButton bn_playFwd;
     277    private javax.swing.JButton bn_stop;
     278    private javax.swing.JButton bn_time0;
     279    private javax.swing.JLabel jLabel1;
     280    private javax.swing.JLabel jLabel2;
     281    private javax.swing.JPanel jPanel1;
     282    private javax.swing.JPanel jPanel2;
     283    private javax.swing.JPanel jPanel3;
     284    private javax.swing.JPanel jPanel4;
     285    private javax.swing.JTextField text_curTime;
     286    private javax.swing.JTextField text_timeStep;
     287    // End of variables declaration//GEN-END:variables
     288   
     289}
  • new file core/src/com/kitfox/svg/app/PlayerThread.java

    - +  
     1/*
     2 * PlayerThread.java
     3 *
     4 *
     5 *  The Salamander Project - 2D and 3D graphics libraries in Java
     6 *  Copyright (C) 2004 Mark McKay
     7 *
     8 *  This library is free software; you can redistribute it and/or
     9 *  modify it under the terms of the GNU Lesser General Public
     10 *  License as published by the Free Software Foundation; either
     11 *  version 2.1 of the License, or (at your option) any later version.
     12 *
     13 *  This library is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     16 *  Lesser General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU Lesser General Public
     19 *  License along with this library; if not, write to the Free Software
     20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     21 *
     22 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     23 *  projects can be found at http://www.kitfox.com
     24 *
     25 * Created on September 28, 2004, 10:07 PM
     26 */
     27
     28
     29package com.kitfox.svg.app;
     30
     31import java.util.*;
     32
     33/**
     34 *
     35 * @author  kitfox
     36 */
     37public class PlayerThread implements Runnable
     38{
     39    HashSet listeners = new HashSet();
     40   
     41    double curTime = 0;
     42    double timeStep = .2;
     43   
     44    public static final int PS_STOP = 0;
     45    public static final int PS_PLAY_FWD = 1;
     46    public static final int PS_PLAY_BACK = 2;
     47   
     48    int playState = PS_STOP;
     49   
     50    Thread thread;
     51   
     52    /** Creates a new instance of PlayerThread */
     53    public PlayerThread()
     54    {
     55        thread = new Thread(this);
     56        thread.start();
     57    }
     58   
     59    public void run()
     60    {
     61        while (thread != null)
     62        {
     63            synchronized (this)
     64            {
     65                switch (playState)
     66                {
     67                    case PS_PLAY_FWD:
     68                        curTime += timeStep;
     69                        break;
     70                    case PS_PLAY_BACK:
     71                        curTime -= timeStep;
     72                        if (curTime < 0) curTime = 0;
     73                        break;
     74                    default:
     75                    case PS_STOP:
     76                        break;
     77                }
     78               
     79                fireTimeUpdateEvent();
     80            }
     81           
     82            try
     83            {
     84                Thread.sleep((long)(timeStep * 1000));
     85            }
     86            catch (Exception e)
     87            {
     88                throw new RuntimeException(e);
     89            }
     90        }
     91    }
     92   
     93    public void exit() { thread = null; }
     94    public synchronized void addListener(PlayerThreadListener listener)
     95    {
     96        listeners.add(listener);
     97    }
     98   
     99    public synchronized double getCurTime() { return curTime; }
     100   
     101    public synchronized void setCurTime(double time)
     102    {
     103        curTime = time;
     104    }
     105   
     106    public synchronized double getTimeStep() { return timeStep; }
     107   
     108    public synchronized void setTimeStep(double time)
     109    {
     110        timeStep = time;
     111        if (timeStep < .01) timeStep = .01;
     112    }
     113   
     114    public synchronized int getPlayState() { return playState; }
     115   
     116    public synchronized void setPlayState(int playState)
     117    {
     118        this.playState = playState;
     119    }
     120   
     121    private void fireTimeUpdateEvent()
     122    {
     123        for (Iterator it = listeners.iterator(); it.hasNext();)
     124        {
     125            PlayerThreadListener listener = (PlayerThreadListener)it.next();
     126            listener.updateTime(curTime, timeStep, playState);
     127        }
     128    }
     129}
  • new file core/src/com/kitfox/svg/app/PlayerThreadListener.java

    - +  
     1/*
     2 * PlayerThreadListener.java
     3 *
     4 *
     5 *  The Salamander Project - 2D and 3D graphics libraries in Java
     6 *  Copyright (C) 2004 Mark McKay
     7 *
     8 *  This library is free software; you can redistribute it and/or
     9 *  modify it under the terms of the GNU Lesser General Public
     10 *  License as published by the Free Software Foundation; either
     11 *  version 2.1 of the License, or (at your option) any later version.
     12 *
     13 *  This library is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     16 *  Lesser General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU Lesser General Public
     19 *  License along with this library; if not, write to the Free Software
     20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     21 *
     22 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     23 *  projects can be found at http://www.kitfox.com
     24 *
     25 * Created on September 28, 2004, 10:15 PM
     26 */
     27
     28package com.kitfox.svg.app;
     29
     30/**
     31 *
     32 * @author  kitfox
     33 */
     34public interface PlayerThreadListener
     35{
     36    public void updateTime(double curTime, double timeStep, int playState);
     37}
  • new file core/src/com/kitfox/svg/app/SVGPlayer.java

    - +  
     1/*
     2 * SVGViewer.java
     3 *
     4 *
     5 *  The Salamander Project - 2D and 3D graphics libraries in Java
     6 *  Copyright (C) 2004 Mark McKay
     7 *
     8 *  This library is free software; you can redistribute it and/or
     9 *  modify it under the terms of the GNU Lesser General Public
     10 *  License as published by the Free Software Foundation; either
     11 *  version 2.1 of the License, or (at your option) any later version.
     12 *
     13 *  This library is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     16 *  Lesser General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU Lesser General Public
     19 *  License along with this library; if not, write to the Free Software
     20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     21 *
     22 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     23 *  projects can be found at http://www.kitfox.com
     24 *
     25 * Created on April 3, 2004, 5:28 PM
     26 */
     27
     28package com.kitfox.svg.app;
     29
     30
     31import com.kitfox.svg.SVGDiagram;
     32import com.kitfox.svg.SVGDisplayPanel;
     33import com.kitfox.svg.SVGElement;
     34import com.kitfox.svg.SVGException;
     35import com.kitfox.svg.SVGUniverse;
     36import java.awt.Color;
     37import java.awt.event.MouseAdapter;
     38import java.awt.event.MouseEvent;
     39import java.awt.geom.Point2D;
     40import java.io.File;
     41import java.io.InputStream;
     42import java.net.URI;
     43import java.net.URL;
     44import java.net.URLEncoder;
     45import java.security.AccessControlException;
     46import java.util.ArrayList;
     47import java.util.List;
     48import java.util.Vector;
     49import java.util.regex.Matcher;
     50import java.util.regex.Pattern;
     51import javax.swing.JFileChooser;
     52import javax.swing.JOptionPane;
     53
     54/**
     55 * @author Mark McKay
     56 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     57 */
     58public class SVGPlayer extends javax.swing.JFrame
     59{
     60    public static final long serialVersionUID = 1;
     61
     62    SVGDisplayPanel svgDisplayPanel = new SVGDisplayPanel();
     63
     64    final PlayerDialog playerDialog;
     65   
     66    SVGUniverse universe;
     67   
     68    /** FileChooser for running in trusted environments */
     69    final JFileChooser fileChooser;
     70    {
     71//        fileChooser = new JFileChooser(new File("."));
     72        JFileChooser fc = null;
     73        try
     74        {
     75            fc = new JFileChooser();
     76            fc.setFileFilter(
     77                new javax.swing.filechooser.FileFilter() {
     78                    final Matcher matchLevelFile = Pattern.compile(".*\\.svg[z]?").matcher("");
     79
     80                    public boolean accept(File file)
     81                    {
     82                        if (file.isDirectory()) return true;
     83
     84                        matchLevelFile.reset(file.getName());
     85                        return matchLevelFile.matches();
     86                    }
     87
     88                    public String getDescription() { return "SVG file (*.svg, *.svgz)"; }
     89                }
     90            );
     91        }
     92        catch (AccessControlException ex)
     93        {
     94            //Do not create file chooser if webstart refuses permissions
     95        }
     96        fileChooser = fc;
     97    }
     98
     99    /** Backup file service for opening files in WebStart situations */
     100    /*
     101    final FileOpenService fileOpenService;
     102    {
     103        try
     104        {
     105            fileOpenService = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
     106        }
     107        catch (UnavailableServiceException e)
     108        {
     109            fileOpenService = null;
     110        }
     111    }
     112     */
     113   
     114    /** Creates new form SVGViewer */
     115    public SVGPlayer() {
     116        initComponents();
     117
     118        setSize(800, 600);
     119
     120        svgDisplayPanel.setBgColor(Color.white);
     121        svgDisplayPanel.addMouseListener(new MouseAdapter()
     122        {
     123            public void mouseClicked(MouseEvent evt)
     124            {
     125                SVGDiagram diagram = svgDisplayPanel.getDiagram();
     126                if (diagram == null) return;
     127               
     128                System.out.println("Picking at cursor (" + evt.getX() + ", " + evt.getY() + ")");
     129                try
     130                {
     131                    List paths = diagram.pick(new Point2D.Float(evt.getX(), evt.getY()), null);
     132                    for (int i = 0; i < paths.size(); i++)
     133                    {
     134                        ArrayList path = (ArrayList)paths.get(i);
     135                        System.out.println(pathToString(path));
     136                    }
     137                }
     138                catch (SVGException ex)
     139                {
     140                    ex.printStackTrace();
     141                }
     142            }
     143        }
     144        );
     145       
     146        svgDisplayPanel.setPreferredSize(getSize());
     147        scrollPane_svgArea.setViewportView(svgDisplayPanel);
     148       
     149        playerDialog = new PlayerDialog(this);
     150    }
     151   
     152    private String pathToString(List path)
     153    {
     154        if (path.size() == 0) return "";
     155       
     156        StringBuffer sb = new StringBuffer();
     157        sb.append(path.get(0));
     158        for (int i = 1; i < path.size(); i++)
     159        {
     160            sb.append("/");
     161            sb.append(((SVGElement)path.get(i)).getId());
     162        }
     163        return sb.toString();
     164    }
     165   
     166    public void updateTime(double curTime)
     167    {
     168        try
     169        {
     170            if (universe != null)
     171            {
     172                universe.setCurTime(curTime);
     173                universe.updateTime();
     174    //            svgDisplayPanel.updateTime(curTime);
     175                repaint();
     176            }
     177        }
     178        catch (Exception e)
     179        {
     180            e.printStackTrace();
     181        }
     182    }
     183
     184    private void loadURL(URL url)
     185    {
     186        boolean verbose = cmCheck_verbose.isSelected();
     187
     188        universe = new SVGUniverse();
     189        universe.setVerbose(verbose);
     190        SVGDiagram diagram = null;
     191
     192        if (!CheckBoxMenuItem_anonInputStream.isSelected())
     193        {
     194            //Load from a disk with a valid URL
     195            URI uri = universe.loadSVG(url);
     196
     197            if (verbose) System.err.println(uri.toString());
     198
     199            diagram = universe.getDiagram(uri);
     200        }
     201        else
     202        {
     203            //Load from a stream with no particular valid URL
     204            try
     205            {
     206                InputStream is = url.openStream();
     207                URI uri = universe.loadSVG(is, "defaultName");
     208
     209                if (verbose) System.err.println(uri.toString());
     210
     211                diagram = universe.getDiagram(uri);
     212            }
     213            catch (Exception e)
     214            {
     215                e.printStackTrace();
     216            }
     217        }
     218
     219        svgDisplayPanel.setDiagram(diagram);
     220        repaint();
     221    }
     222   
     223    /** This method is called from within the constructor to
     224     * initialize the form.
     225     * WARNING: Do NOT modify this code. The content of this method is
     226     * always regenerated by the Form Editor.
     227     */
     228    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
     229    private void initComponents()
     230    {
     231        scrollPane_svgArea = new javax.swing.JScrollPane();
     232        jMenuBar1 = new javax.swing.JMenuBar();
     233        menu_file = new javax.swing.JMenu();
     234        cm_loadFile = new javax.swing.JMenuItem();
     235        cm_loadUrl = new javax.swing.JMenuItem();
     236        menu_window = new javax.swing.JMenu();
     237        cm_player = new javax.swing.JMenuItem();
     238        jSeparator2 = new javax.swing.JSeparator();
     239        cm_800x600 = new javax.swing.JMenuItem();
     240        CheckBoxMenuItem_anonInputStream = new javax.swing.JCheckBoxMenuItem();
     241        cmCheck_verbose = new javax.swing.JCheckBoxMenuItem();
     242        menu_help = new javax.swing.JMenu();
     243        cm_about = new javax.swing.JMenuItem();
     244
     245        setTitle("SVG Player - Salamander Project");
     246        addWindowListener(new java.awt.event.WindowAdapter()
     247        {
     248            public void windowClosing(java.awt.event.WindowEvent evt)
     249            {
     250                exitForm(evt);
     251            }
     252        });
     253
     254        getContentPane().add(scrollPane_svgArea, java.awt.BorderLayout.CENTER);
     255
     256        menu_file.setMnemonic('f');
     257        menu_file.setText("File");
     258        cm_loadFile.setMnemonic('l');
     259        cm_loadFile.setText("Load File...");
     260        cm_loadFile.addActionListener(new java.awt.event.ActionListener()
     261        {
     262            public void actionPerformed(java.awt.event.ActionEvent evt)
     263            {
     264                cm_loadFileActionPerformed(evt);
     265            }
     266        });
     267
     268        menu_file.add(cm_loadFile);
     269
     270        cm_loadUrl.setText("Load URL...");
     271        cm_loadUrl.addActionListener(new java.awt.event.ActionListener()
     272        {
     273            public void actionPerformed(java.awt.event.ActionEvent evt)
     274            {
     275                cm_loadUrlActionPerformed(evt);
     276            }
     277        });
     278
     279        menu_file.add(cm_loadUrl);
     280
     281        jMenuBar1.add(menu_file);
     282
     283        menu_window.setText("Window");
     284        cm_player.setText("Player");
     285        cm_player.addActionListener(new java.awt.event.ActionListener()
     286        {
     287            public void actionPerformed(java.awt.event.ActionEvent evt)
     288            {
     289                cm_playerActionPerformed(evt);
     290            }
     291        });
     292
     293        menu_window.add(cm_player);
     294
     295        menu_window.add(jSeparator2);
     296
     297        cm_800x600.setText("800 x 600");
     298        cm_800x600.addActionListener(new java.awt.event.ActionListener()
     299        {
     300            public void actionPerformed(java.awt.event.ActionEvent evt)
     301            {
     302                cm_800x600ActionPerformed(evt);
     303            }
     304        });
     305
     306        menu_window.add(cm_800x600);
     307
     308        CheckBoxMenuItem_anonInputStream.setText("Anonymous Input Stream");
     309        menu_window.add(CheckBoxMenuItem_anonInputStream);
     310
     311        cmCheck_verbose.setText("Verbose");
     312        cmCheck_verbose.addActionListener(new java.awt.event.ActionListener()
     313        {
     314            public void actionPerformed(java.awt.event.ActionEvent evt)
     315            {
     316                cmCheck_verboseActionPerformed(evt);
     317            }
     318        });
     319
     320        menu_window.add(cmCheck_verbose);
     321
     322        jMenuBar1.add(menu_window);
     323
     324        menu_help.setText("Help");
     325        cm_about.setText("About...");
     326        cm_about.addActionListener(new java.awt.event.ActionListener()
     327        {
     328            public void actionPerformed(java.awt.event.ActionEvent evt)
     329            {
     330                cm_aboutActionPerformed(evt);
     331            }
     332        });
     333
     334        menu_help.add(cm_about);
     335
     336        jMenuBar1.add(menu_help);
     337
     338        setJMenuBar(jMenuBar1);
     339
     340        pack();
     341    }// </editor-fold>//GEN-END:initComponents
     342
     343    private void cm_loadUrlActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadUrlActionPerformed
     344    {//GEN-HEADEREND:event_cm_loadUrlActionPerformed
     345        String urlStrn = JOptionPane.showInputDialog(this, "Enter URL of SVG file");
     346        if (urlStrn == null) return;
     347       
     348        try
     349        {
     350            URL url = new URL(URLEncoder.encode(urlStrn, "UTF-8"));
     351            loadURL(url);
     352        }
     353        catch (Exception e)
     354        {
     355            e.printStackTrace();
     356        }
     357
     358    }//GEN-LAST:event_cm_loadUrlActionPerformed
     359
     360    private void cmCheck_verboseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cmCheck_verboseActionPerformed
     361    {//GEN-HEADEREND:event_cmCheck_verboseActionPerformed
     362// TODO add your handling code here:
     363    }//GEN-LAST:event_cmCheck_verboseActionPerformed
     364
     365    private void cm_playerActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_playerActionPerformed
     366    {//GEN-HEADEREND:event_cm_playerActionPerformed
     367        playerDialog.setVisible(true);
     368    }//GEN-LAST:event_cm_playerActionPerformed
     369
     370    private void cm_aboutActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_aboutActionPerformed
     371    {//GEN-HEADEREND:event_cm_aboutActionPerformed
     372        VersionDialog dia = new VersionDialog(this, true, cmCheck_verbose.isSelected());
     373        dia.setVisible(true);
     374//        JOptionPane.showMessageDialog(this, "Salamander SVG - Created by Mark McKay\nhttp://www.kitfox.com");
     375    }//GEN-LAST:event_cm_aboutActionPerformed
     376
     377    private void cm_800x600ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cm_800x600ActionPerformed
     378        setSize(800, 600);
     379    }//GEN-LAST:event_cm_800x600ActionPerformed
     380   
     381    private void cm_loadFileActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadFileActionPerformed
     382    {//GEN-HEADEREND:event_cm_loadFileActionPerformed
     383        boolean verbose = cmCheck_verbose.isSelected();
     384       
     385        try
     386        {
     387            int retVal = fileChooser.showOpenDialog(this);
     388            if (retVal == JFileChooser.APPROVE_OPTION)
     389            {
     390                File chosenFile = fileChooser.getSelectedFile();
     391
     392                URL url = chosenFile.toURI().toURL();
     393
     394                loadURL(url);
     395            }
     396        }
     397        catch (Exception e)
     398        {
     399            e.printStackTrace();
     400        }
     401
     402    }//GEN-LAST:event_cm_loadFileActionPerformed
     403
     404    /** Exit the Application */
     405    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
     406        System.exit(0);
     407    }//GEN-LAST:event_exitForm
     408
     409    /**
     410     * @param args the command line arguments
     411     */
     412    public static void main(String args[]) {
     413        new SVGPlayer().setVisible(true);
     414    }
     415
     416    public void updateTime(double curTime, double timeStep, int playState)
     417    {
     418    }
     419   
     420    // Variables declaration - do not modify//GEN-BEGIN:variables
     421    private javax.swing.JCheckBoxMenuItem CheckBoxMenuItem_anonInputStream;
     422    private javax.swing.JCheckBoxMenuItem cmCheck_verbose;
     423    private javax.swing.JMenuItem cm_800x600;
     424    private javax.swing.JMenuItem cm_about;
     425    private javax.swing.JMenuItem cm_loadFile;
     426    private javax.swing.JMenuItem cm_loadUrl;
     427    private javax.swing.JMenuItem cm_player;
     428    private javax.swing.JMenuBar jMenuBar1;
     429    private javax.swing.JSeparator jSeparator2;
     430    private javax.swing.JMenu menu_file;
     431    private javax.swing.JMenu menu_help;
     432    private javax.swing.JMenu menu_window;
     433    private javax.swing.JScrollPane scrollPane_svgArea;
     434    // End of variables declaration//GEN-END:variables
     435
     436}
  • new file core/src/com/kitfox/svg/app/SVGViewer.java

    - +  
     1/*
     2 * SVGViewer.java
     3 *
     4 *
     5 *  The Salamander Project - 2D and 3D graphics libraries in Java
     6 *  Copyright (C) 2004 Mark McKay
     7 *
     8 *  This library is free software; you can redistribute it and/or
     9 *  modify it under the terms of the GNU Lesser General Public
     10 *  License as published by the Free Software Foundation; either
     11 *  version 2.1 of the License, or (at your option) any later version.
     12 *
     13 *  This library is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     16 *  Lesser General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU Lesser General Public
     19 *  License along with this library; if not, write to the Free Software
     20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     21 *
     22 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     23 *  projects can be found at http://www.kitfox.com
     24 *
     25 * Created on April 3, 2004, 5:28 PM
     26 */
     27
     28package com.kitfox.svg.app;
     29
     30import com.kitfox.svg.SVGCache;
     31import com.kitfox.svg.SVGDiagram;
     32import com.kitfox.svg.SVGDisplayPanel;
     33import com.kitfox.svg.SVGElement;
     34import com.kitfox.svg.SVGException;
     35import com.kitfox.svg.SVGUniverse;
     36import java.awt.BorderLayout;
     37import java.awt.Color;
     38import java.awt.Point;
     39import java.io.File;
     40import java.io.InputStream;
     41import java.net.URI;
     42import java.net.URL;
     43import java.net.URLEncoder;
     44import java.security.AccessControlException;
     45import java.util.ArrayList;
     46import java.util.Iterator;
     47import java.util.List;
     48import java.util.regex.Matcher;
     49import java.util.regex.Pattern;
     50import javax.swing.JFileChooser;
     51import javax.swing.JOptionPane;
     52
     53
     54/**
     55 * @author Mark McKay
     56 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
     57 */
     58public class SVGViewer extends javax.swing.JFrame
     59{
     60    public static final long serialVersionUID = 1;
     61
     62    SVGDisplayPanel svgDisplayPanel = new SVGDisplayPanel();
     63
     64    /** FileChooser for running in trusted environments */
     65    final JFileChooser fileChooser;
     66    {
     67//        fileChooser = new JFileChooser(new File("."));
     68        JFileChooser fc = null;
     69        try
     70        {
     71            fc = new JFileChooser();
     72            fc.setFileFilter(
     73                new javax.swing.filechooser.FileFilter() {
     74                    final Matcher matchLevelFile = Pattern.compile(".*\\.svg[z]?").matcher("");
     75
     76                    public boolean accept(File file)
     77                    {
     78                        if (file.isDirectory()) return true;
     79
     80                        matchLevelFile.reset(file.getName());
     81                        return matchLevelFile.matches();
     82                    }
     83
     84                    public String getDescription() { return "SVG file (*.svg, *.svgz)"; }
     85                }
     86            );
     87        }
     88        catch (AccessControlException ex)
     89        {
     90            //Do not create file chooser if webstart refuses permissions
     91        }
     92        fileChooser = fc;
     93    }
     94
     95    /** Backup file service for opening files in WebStart situations */
     96    /*
     97    final FileOpenService fileOpenService;
     98    {
     99        try
     100        {
     101            fileOpenService = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
     102        }
     103        catch (UnavailableServiceException e)
     104        {
     105            fileOpenService = null;
     106        }
     107    }
     108     */
     109   
     110    /** Creates new form SVGViewer */
     111    public SVGViewer() {
     112        initComponents();
     113
     114        setSize(800, 600);
     115
     116        svgDisplayPanel.setBgColor(Color.white);
     117
     118        svgDisplayPanel.setPreferredSize(getSize());
     119        panel_svgArea.add(svgDisplayPanel, BorderLayout.CENTER);
     120//        scrollPane_svgArea.setViewportView(svgDisplayPanel);
     121    }
     122
     123    private void loadURL(URL url)
     124    {
     125        boolean verbose = cmCheck_verbose.isSelected();
     126       
     127//                SVGUniverse universe = new SVGUniverse();
     128        SVGUniverse universe = SVGCache.getSVGUniverse();
     129        SVGDiagram diagram = null;
     130        URI uri;
     131
     132        if (!CheckBoxMenuItem_anonInputStream.isSelected())
     133        {
     134            //Load from a disk with a valid URL
     135            uri = universe.loadSVG(url);
     136
     137            if (verbose) System.err.println("Loading document " + uri.toString());
     138
     139            diagram = universe.getDiagram(uri);
     140        }
     141        else
     142        {
     143            //Load from a stream with no particular valid URL
     144            try
     145            {
     146                InputStream is = url.openStream();
     147                uri = universe.loadSVG(is, "defaultName");
     148
     149                if (verbose) System.err.println("Loading document " + uri.toString());
     150            }
     151            catch (Exception e)
     152            {
     153                e.printStackTrace();
     154                return;
     155            }
     156        }
     157/*
     158ByteArrayOutputStream bs = new ByteArrayOutputStream();
     159ObjectOutputStream os = new ObjectOutputStream(bs);
     160os.writeObject(universe);
     161os.close();
     162
     163ByteArrayInputStream bin = new ByteArrayInputStream(bs.toByteArray());
     164ObjectInputStream is = new ObjectInputStream(bin);
     165universe = (SVGUniverse)is.readObject();
     166is.close();
     167*/
     168
     169        diagram = universe.getDiagram(uri);
     170
     171        svgDisplayPanel.setDiagram(diagram);
     172        repaint();
     173    }
     174   
     175    /** This method is called from within the constructor to
     176     * initialize the form.
     177     * WARNING: Do NOT modify this code. The content of this method is
     178     * always regenerated by the Form Editor.
     179     */
     180    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
     181    private void initComponents()
     182    {
     183        scrollPane_svgArea = new javax.swing.JScrollPane();
     184        panel_svgArea = new javax.swing.JPanel();
     185        jMenuBar1 = new javax.swing.JMenuBar();
     186        menu_file = new javax.swing.JMenu();
     187        cm_loadFile = new javax.swing.JMenuItem();
     188        cm_loadUrl = new javax.swing.JMenuItem();
     189        menu_window = new javax.swing.JMenu();
     190        cm_800x600 = new javax.swing.JMenuItem();
     191        CheckBoxMenuItem_anonInputStream = new javax.swing.JCheckBoxMenuItem();
     192        cmCheck_verbose = new javax.swing.JCheckBoxMenuItem();
     193        menu_help = new javax.swing.JMenu();
     194        cm_about = new javax.swing.JMenuItem();
     195
     196        setTitle("SVG Viewer - Salamander Project");
     197        addWindowListener(new java.awt.event.WindowAdapter()
     198        {
     199            public void windowClosing(java.awt.event.WindowEvent evt)
     200            {
     201                exitForm(evt);
     202            }
     203        });
     204
     205        panel_svgArea.setLayout(new java.awt.BorderLayout());
     206
     207        panel_svgArea.addMouseListener(new java.awt.event.MouseAdapter()
     208        {
     209            public void mousePressed(java.awt.event.MouseEvent evt)
     210            {
     211                panel_svgAreaMousePressed(evt);
     212            }
     213            public void mouseReleased(java.awt.event.MouseEvent evt)
     214            {
     215                panel_svgAreaMouseReleased(evt);
     216            }
     217        });
     218
     219        scrollPane_svgArea.setViewportView(panel_svgArea);
     220
     221        getContentPane().add(scrollPane_svgArea, java.awt.BorderLayout.CENTER);
     222
     223        menu_file.setMnemonic('f');
     224        menu_file.setText("File");
     225        cm_loadFile.setMnemonic('l');
     226        cm_loadFile.setText("Load File...");
     227        cm_loadFile.addActionListener(new java.awt.event.ActionListener()
     228        {
     229            public void actionPerformed(java.awt.event.ActionEvent evt)
     230            {
     231                cm_loadFileActionPerformed(evt);
     232            }
     233        });
     234
     235        menu_file.add(cm_loadFile);
     236
     237        cm_loadUrl.setText("Load URL...");
     238        cm_loadUrl.addActionListener(new java.awt.event.ActionListener()
     239        {
     240            public void actionPerformed(java.awt.event.ActionEvent evt)
     241            {
     242                cm_loadUrlActionPerformed(evt);
     243            }
     244        });
     245
     246        menu_file.add(cm_loadUrl);
     247
     248        jMenuBar1.add(menu_file);
     249
     250        menu_window.setText("Window");
     251        cm_800x600.setText("800 x 600");
     252        cm_800x600.addActionListener(new java.awt.event.ActionListener()
     253        {
     254            public void actionPerformed(java.awt.event.ActionEvent evt)
     255            {
     256                cm_800x600ActionPerformed(evt);
     257            }
     258        });
     259
     260        menu_window.add(cm_800x600);
     261
     262        CheckBoxMenuItem_anonInputStream.setText("Anonymous Input Stream");
     263        menu_window.add(CheckBoxMenuItem_anonInputStream);
     264
     265        cmCheck_verbose.setText("Verbose");
     266        cmCheck_verbose.addActionListener(new java.awt.event.ActionListener()
     267        {
     268            public void actionPerformed(java.awt.event.ActionEvent evt)
     269            {
     270                cmCheck_verboseActionPerformed(evt);
     271            }
     272        });
     273
     274        menu_window.add(cmCheck_verbose);
     275
     276        jMenuBar1.add(menu_window);
     277
     278        menu_help.setText("Help");
     279        cm_about.setText("About...");
     280        cm_about.addActionListener(new java.awt.event.ActionListener()
     281        {
     282            public void actionPerformed(java.awt.event.ActionEvent evt)
     283            {
     284                cm_aboutActionPerformed(evt);
     285            }
     286        });
     287
     288        menu_help.add(cm_about);
     289
     290        jMenuBar1.add(menu_help);
     291
     292        setJMenuBar(jMenuBar1);
     293
     294        pack();
     295    }// </editor-fold>//GEN-END:initComponents
     296
     297    private void cm_loadUrlActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadUrlActionPerformed
     298    {//GEN-HEADEREND:event_cm_loadUrlActionPerformed
     299        String urlStrn = JOptionPane.showInputDialog(this, "Enter URL of SVG file");
     300        if (urlStrn == null) return;
     301       
     302        try
     303        {
     304            URL url = new URL(URLEncoder.encode(urlStrn, "UTF-8"));
     305            loadURL(url);
     306        }
     307        catch (Exception e)
     308        {
     309            e.printStackTrace();
     310        }
     311
     312    }//GEN-LAST:event_cm_loadUrlActionPerformed
     313
     314    private void panel_svgAreaMouseReleased(java.awt.event.MouseEvent evt)//GEN-FIRST:event_panel_svgAreaMouseReleased
     315    {//GEN-HEADEREND:event_panel_svgAreaMouseReleased
     316        SVGDiagram diagram = svgDisplayPanel.getDiagram();
     317        List pickedElements;
     318        try
     319        {
     320            pickedElements = diagram.pick(new Point(evt.getX(), evt.getY()), null);
     321        }
     322        catch (SVGException ex)
     323        {
     324            ex.printStackTrace();
     325            return;
     326        }
     327       
     328        System.out.println("Pick results:");
     329        for (Iterator it = pickedElements.iterator(); it.hasNext();)
     330        {
     331            ArrayList path = (ArrayList)it.next();
     332           
     333            System.out.print("  Path: ");
     334           
     335            for (Iterator it2 = path.iterator(); it2.hasNext();)
     336            {
     337                SVGElement ele = (SVGElement)it2.next();
     338
     339                System.out.print("" + ele.getId() + "(" + ele.getClass().getName() + ") ");
     340            }
     341            System.out.println();
     342        }
     343    }//GEN-LAST:event_panel_svgAreaMouseReleased
     344
     345    private void panel_svgAreaMousePressed(java.awt.event.MouseEvent evt)//GEN-FIRST:event_panel_svgAreaMousePressed
     346    {//GEN-HEADEREND:event_panel_svgAreaMousePressed
     347
     348    }//GEN-LAST:event_panel_svgAreaMousePressed
     349
     350    private void cmCheck_verboseActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cmCheck_verboseActionPerformed
     351    {//GEN-HEADEREND:event_cmCheck_verboseActionPerformed
     352        SVGCache.getSVGUniverse().setVerbose(cmCheck_verbose.isSelected());
     353    }//GEN-LAST:event_cmCheck_verboseActionPerformed
     354
     355    private void cm_aboutActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_aboutActionPerformed
     356    {//GEN-HEADEREND:event_cm_aboutActionPerformed
     357        //JOptionPane.showMessageDialog(this, "Salamander SVG - Created by Mark McKay\nhttp://www.kitfox.com");
     358        VersionDialog dlg = new VersionDialog(this, true, cmCheck_verbose.isSelected());
     359        dlg.setVisible(true);
     360    }//GEN-LAST:event_cm_aboutActionPerformed
     361
     362    private void cm_800x600ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cm_800x600ActionPerformed
     363        setSize(800, 600);
     364    }//GEN-LAST:event_cm_800x600ActionPerformed
     365   
     366    private void cm_loadFileActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cm_loadFileActionPerformed
     367    {//GEN-HEADEREND:event_cm_loadFileActionPerformed
     368        try
     369        {
     370            int retVal = fileChooser.showOpenDialog(this);
     371            if (retVal == JFileChooser.APPROVE_OPTION)
     372            {
     373                File chosenFile = fileChooser.getSelectedFile();
     374
     375                URL url = chosenFile.toURI().toURL();
     376
     377                loadURL(url);
     378            }
     379        }
     380        /*
     381        catch (IOException ioe)
     382        {
     383            try
     384            {
     385                //We may be in a WebStart app.  Try again with a FileOpenService
     386                FileContents fc = fileOpenService.openFileDialog(null, new String[]{"svg"});
     387                InputStream is = fc.getInputStream();
     388                String name = fc.getName();
     389            }
     390            catch (Exception e)
     391            {
     392                e.printStackTrace();
     393            }
     394        }
     395         */
     396        catch (Exception e)
     397        {
     398            e.printStackTrace();
     399        }
     400
     401    }//GEN-LAST:event_cm_loadFileActionPerformed
     402
     403    /** Exit the Application */
     404    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
     405//        setVisible(false);
     406//        dispose();
     407        System.exit(0);
     408    }//GEN-LAST:event_exitForm
     409
     410    /**
     411     * @param args the command line arguments
     412     */
     413    public static void main(String args[]) {
     414        new SVGViewer().setVisible(true);
     415    }
     416
     417    // Variables declaration - do not modify//GEN-BEGIN:variables
     418    private javax.swing.JCheckBoxMenuItem CheckBoxMenuItem_anonInputStream;
     419    private javax.swing.JCheckBoxMenuItem cmCheck_verbose;
     420    private javax.swing.JMenuItem cm_800x600;
     421    private javax.swing.JMenuItem cm_about;
     422    private javax.swing.JMenuItem cm_loadFile;
     423    private javax.swing.JMenuItem cm_loadUrl;
     424    private javax.swing.JMenuBar jMenuBar1;
     425    private javax.swing.JMenu menu_file;
     426    private javax.swing.JMenu menu_help;
     427    private javax.swing.JMenu menu_window;
     428    private javax.swing.JPanel panel_svgArea;
     429    private javax.swing.JScrollPane scrollPane_svgArea;
     430    // End of variables declaration//GEN-END:variables
     431
     432}
  • new file core/src/com/kitfox/svg/app/VersionDialog.java

    - +  
     1/*
     2 * VersionDialog.java
     3 *
     4 *
     5 *  The Salamander Project - 2D and 3D graphics libraries in Java
     6 *  Copyright (C) 2004 Mark McKay
     7 *
     8 *  This library is free software; you can redistribute it and/or
     9 *  modify it under the terms of the GNU Lesser General Public
     10 *  License as published by the Free Software Foundation; either
     11 *  version 2.1 of the License, or (at your option) any later version.
     12 *
     13 *  This library is distributed in the hope that it will be useful,
     14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     16 *  Lesser General Public License for more details.
     17 *
     18 *  You should have received a copy of the GNU Lesser General Public
     19 *  License along with this library; if not, write to the Free Software
     20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     21 *
     22 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     23 *  projects can be found at http://www.kitfox.com
     24 *
     25 * Created on January 13, 2005, 7:23 AM
     26 */
     27
     28package com.kitfox.svg.app;
     29
     30import java.net.*;
     31import java.io.*;
     32import java.util.*;
     33import javax.swing.event.*;
     34import javax.swing.*;
     35import javax.swing.text.html.*;
     36
     37
     38/**
     39 *
     40 * @author  kitfox
     41 */
     42public class VersionDialog extends javax.swing.JDialog
     43{
     44    public static final long serialVersionUID = 1;
     45   
     46    final boolean verbose;
     47   
     48    /** Creates new form VersionDialog */
     49    public VersionDialog(java.awt.Frame parent, boolean modal, boolean verbose)
     50    {
     51        super(parent, modal);
     52        initComponents();
     53       
     54        this.verbose = verbose;
     55       
     56        textpane_text.setContentType("text/html");
     57       
     58        StringBuffer sb = new StringBuffer();
     59        try
     60        {
     61            URL url = getClass().getResource("/res/help/about/about.html");
     62            if (verbose)
     63            {
     64                System.err.println("" + getClass() + " trying to load about html " + url);
     65            }
     66           
     67            BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
     68            while (true)
     69            {
     70                String line = reader.readLine();
     71                if (line == null) break;
     72                sb.append(line);
     73            }
     74           
     75            textpane_text.setText(sb.toString());
     76        }
     77        catch (Exception e)
     78        {
     79            e.printStackTrace();
     80        }
     81       
     82    }
     83   
     84    /** This method is called from within the constructor to
     85     * initialize the form.
     86     * WARNING: Do NOT modify this code. The content of this method is
     87     * always regenerated by the Form Editor.
     88     */
     89    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
     90    private void initComponents()
     91    {
     92        jPanel1 = new javax.swing.JPanel();
     93        textpane_text = new javax.swing.JTextPane();
     94        jPanel2 = new javax.swing.JPanel();
     95        bn_close = new javax.swing.JButton();
     96
     97        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
     98        setTitle("About SVG Salamander");
     99        jPanel1.setLayout(new java.awt.BorderLayout());
     100
     101        textpane_text.setEditable(false);
     102        textpane_text.setPreferredSize(new java.awt.Dimension(400, 300));
     103        jPanel1.add(textpane_text, java.awt.BorderLayout.CENTER);
     104
     105        getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
     106
     107        bn_close.setText("Close");
     108        bn_close.addActionListener(new java.awt.event.ActionListener()
     109        {
     110            public void actionPerformed(java.awt.event.ActionEvent evt)
     111            {
     112                bn_closeActionPerformed(evt);
     113            }
     114        });
     115
     116        jPanel2.add(bn_close);
     117
     118        getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);
     119
     120        pack();
     121    }
     122    // </editor-fold>//GEN-END:initComponents
     123
     124    private void bn_closeActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bn_closeActionPerformed
     125    {//GEN-HEADEREND:event_bn_closeActionPerformed
     126        setVisible(false);
     127        dispose();
     128    }//GEN-LAST:event_bn_closeActionPerformed
     129   
     130    /**
     131     * @param args the command line arguments
     132     */
     133    public static void main(String args[])
     134    {
     135        java.awt.EventQueue.invokeLater(new Runnable()
     136        {
     137            public void run()
     138            {
     139                new VersionDialog(new javax.swing.JFrame(), true, true).setVisible(true);
     140            }
     141        });
     142    }
     143   
     144    // Variables declaration - do not modify//GEN-BEGIN:variables
     145    private javax.swing.JButton bn_close;
     146    private javax.swing.JPanel jPanel1;
     147    private javax.swing.JPanel jPanel2;
     148    private javax.swing.JTextPane textpane_text;
     149    // End of variables declaration//GEN-END:variables
     150   
     151}
  • new file core/src/com/kitfox/svg/app/ant/SVGToImageAntTask.java

    - +  
     1/*
     2 * IndexLoadObjectsAntTask.java
     3 *
     4 * Created on January 22, 2005, 10:30 AM
     5 */
     6
     7package com.kitfox.svg.app.ant;
     8
     9import java.awt.*;
     10import java.awt.image.*;
     11import java.util.*;
     12import java.util.regex.*;
     13import java.io.*;
     14import javax.imageio.*;
     15
     16//import com.kitfox.util.*;
     17//import com.kitfox.util.indexedObject.*;
     18
     19import org.apache.tools.ant.*;
     20import org.apache.tools.ant.types.*;
     21
     22import com.kitfox.svg.app.beans.*;
     23import com.kitfox.svg.*;
     24import com.kitfox.svg.xml.ColorTable;
     25
     26/**
     27 * <p>Translates a group of SVG files into images.</p>
     28 *
     29 * <p>Parameters:</p>
     30 * <p><ul>
     31 * <li/>destDir - If present, specifices a directory to write SVG files to.  Otherwise
     32 * writes images to directory SVG file was found in
     33 * verbose - If true, prints processing information to the console
     34 * <li/>format - File format for output images.  The java core javax.imageio.ImageIO
     35 * class is used for creating images, so format strings will depend on what
     36 * files your system is configured to handle.  By default, "gif", "jpg" and "png"
     37 * files are guaranteed to be present.  If omitted, "png" is used by default.
     38 * <li/>backgroundColor - Optional background color.  Color can be specified as a standard
     39 * HTML color.  That is, as the name of a standard color such as "blue" or
     40 * "limegreen", using the # notaion as in #ff00ff for magenta, or in rgb format
     41 * listing the components as in rgb(255, 192, 192) for pink.  If omitted,
     42 * background is transparent.
     43 * <li/>antiAlias - If set, shapes are drawn using antialiasing.  Defaults to true.
     44 * <li/>interpolation - String describing image interpolation alrogithm.  Can
     45 * be one of "nearest neighbor", "bilinear" or "bicubic".  Defaults to "bicubic".
     46 * <li/>width - If greater than 0, determines the width of the written image.  Otherwise,
     47 * the width is obtained from the SVG document.  Defaults to -1;
     48 * <li/>height - If greater than 0, determines the height of the written image.  Otherwise,
     49 * the height is obtained from the SVG document.  Defaults to -1.
     50 * <li/>sizeToFit - If true and the width and height of the output image differ
     51 * from that of the SVG image, the valid area of the SVG image will be resized
     52 * to fit the specified size.
     53 * <li/>verbose - IF true, prints out diagnostic infromation about processing. 
     54 * Defaults to false.
     55 * </ul></p>
     56 *
     57 * Example:
     58 * &lt;SVGToImage destDir="${index.java}" format="jpg" verbose="true"&gt;
     59 *    &lt;fileset dir="${dir1}"&gt;
     60 *        &lt;include name="*.svg"/&gt;
     61 *    &lt;/fileset&gt;
     62 *    &lt;fileset dir="${dir2}"&gt;
     63 *        &lt;include name="*.svg"/&gt;
     64 *    &lt;/fileset&gt;
     65 * &lt;/SVGToImage&gt;
     66 *
     67 *
     68 *
     69 * @author kitfox
     70 */
     71public class SVGToImageAntTask extends Task
     72{
     73    private ArrayList filesets = new ArrayList();
     74    boolean verbose = false;
     75    File destDir;
     76    private String format = "png";
     77    Color backgroundColor = null;
     78    int width = -1;
     79    int height = -1;
     80    boolean antiAlias = true;
     81    String interpolation = "bicubic";
     82    boolean clipToViewBox = false;
     83    boolean sizeToFit = true;
     84   
     85    /** Creates a new instance of IndexLoadObjectsAntTask */
     86    public SVGToImageAntTask()
     87    {
     88    }
     89   
     90   
     91    public String getFormat()
     92    {
     93        return format;
     94    }
     95   
     96    public void setFormat(String format)
     97    {
     98        this.format = format;
     99    }
     100   
     101    public void setBackgroundColor(String bgColor)
     102    {
     103        this.backgroundColor = ColorTable.parseColor(bgColor);
     104    }
     105   
     106    public void setHeight(int height)
     107    {
     108        this.height = height;
     109    }
     110   
     111    public void setWidth(int width)
     112    {
     113        this.width = width;
     114    }
     115   
     116    public void setAntiAlias(boolean antiAlias)
     117    {
     118        this.antiAlias = antiAlias;
     119    }
     120   
     121    public void setInterpolation(String interpolation)
     122    {
     123        this.interpolation = interpolation;
     124    }
     125   
     126    public void setSizeToFit(boolean sizeToFit)
     127    {
     128        this.sizeToFit = sizeToFit;
     129    }
     130   
     131    public void setClipToViewBox(boolean clipToViewBox)
     132    {
     133        this.clipToViewBox = clipToViewBox;
     134    }
     135   
     136    public void setVerbose(boolean verbose)
     137    {
     138        this.verbose = verbose;
     139    }
     140   
     141    public void setDestDir(File destDir)
     142    {
     143        this.destDir = destDir;
     144    }
     145   
     146    /**
     147     * Adds a set of files.
     148     */
     149    public void addFileset(FileSet set)
     150    {
     151        filesets.add(set);
     152    }
     153   
     154   
     155   
     156    public void execute()
     157    {
     158        if (verbose) log("Building SVG images");
     159       
     160        for (Iterator it = filesets.iterator(); it.hasNext();)
     161        {
     162            FileSet fs = (FileSet)it.next();
     163            FileScanner scanner = fs.getDirectoryScanner(getProject());
     164            String[] files = scanner.getIncludedFiles();
     165           
     166            try
     167            {
     168                File basedir = scanner.getBasedir();
     169               
     170                if (verbose) log("Scaning " + basedir);
     171               
     172                for (int i = 0; i < files.length; i++)
     173                {
     174//System.out.println("File " + files[i]);
     175//System.out.println("BaseDir " + basedir);
     176                    translate(basedir, files[i]);
     177                }
     178            }
     179            catch (Exception e)
     180            {
     181                throw new BuildException(e);
     182            }
     183        }
     184    }
     185   
     186    private void translate(File baseDir, String shortName) throws BuildException
     187    {
     188        File source = new File(baseDir, shortName);
     189       
     190        if (verbose) log("Reading file: " + source);
     191       
     192        Matcher matchName = Pattern.compile("(.*)\\.svg", Pattern.CASE_INSENSITIVE).matcher(shortName);
     193        if (matchName.matches())
     194        {
     195            shortName = matchName.group(1);
     196        }
     197        shortName += "." + format;
     198       
     199        SVGIcon icon = new SVGIcon();
     200        icon.setSvgURI(source.toURI());
     201        icon.setAntiAlias(antiAlias);
     202        if (interpolation.equals("nearest neighbor"))
     203        {
     204            icon.setInterpolation(SVGIcon.INTERP_NEAREST_NEIGHBOR);
     205        }
     206        else if (interpolation.equals("bilinear"))
     207        {
     208            icon.setInterpolation(SVGIcon.INTERP_BILINEAR);
     209        }
     210        else if (interpolation.equals("bicubic"))
     211        {
     212            icon.setInterpolation(SVGIcon.INTERP_BICUBIC);
     213        }
     214       
     215        int iconWidth = width > 0 ? width : icon.getIconWidth();
     216        int iconHeight = height > 0 ? height : icon.getIconHeight();
     217        icon.setClipToViewbox(clipToViewBox);
     218        icon.setPreferredSize(new Dimension(iconWidth, iconHeight));
     219        icon.setScaleToFit(sizeToFit);
     220        BufferedImage image = new BufferedImage(iconWidth, iconHeight, BufferedImage.TYPE_INT_ARGB);
     221        Graphics2D g = image.createGraphics();
     222       
     223        if (backgroundColor != null)
     224        {
     225            g.setColor(backgroundColor);
     226            g.fillRect(0, 0, iconWidth, iconHeight);
     227        }
     228       
     229        g.setClip(0, 0, iconWidth, iconHeight);
     230//        g.fillRect(10, 10, 100, 100);
     231        icon.paintIcon(null, g, 0, 0);
     232        g.dispose();
     233       
     234        File outFile = destDir == null ? new File(baseDir, shortName) : new File(destDir, shortName);
     235        if (verbose) log("Writing file: " + outFile);
     236       
     237        try
     238        {
     239            ImageIO.write(image, format, outFile);
     240        }
     241        catch (IOException e)
     242        {
     243            log("Error writing image: " + e.getMessage());
     244            throw new BuildException(e);
     245        }
     246       
     247       
     248        SVGCache.getSVGUniverse().clear();
     249    }
     250   
     251}
  • new file core/src/com/kitfox/svg/app/beans/ProportionalLayoutPanel.java

    - +  
     1/*
     2 * ProportionalLayoutPanel.java
     3 *
     4 * Created on May 7, 2005, 4:15 AM
     5 */
     6
     7package com.kitfox.svg.app.beans;
     8
     9import java.awt.*;
     10import java.util.*;
     11import javax.swing.*;
     12
     13/**
     14 * Panel based on the null layout.  Allows editing with absolute layout.  When
     15 * instanced, records layout dimensions of all subcomponents.  Then, if the
     16 * panel is ever resized, scales all children to fit new size.
     17 *
     18 * @author  kitfox
     19 */
     20public class ProportionalLayoutPanel extends javax.swing.JPanel
     21{
     22    public static final long serialVersionUID = 1;
     23
     24    //Margins to leave on sides of panel, expressed in fractions [0 1]
     25    float topMargin;
     26    float bottomMargin;
     27    float leftMargin;
     28    float rightMargin;
     29   
     30    /** Creates new form ProportionalLayoutPanel */
     31    public ProportionalLayoutPanel()
     32    {
     33        initComponents();
     34    }
     35   
     36    public void addNotify()
     37    {
     38        super.addNotify();
     39       
     40        Rectangle rect = this.getBounds();
     41        JOptionPane.showMessageDialog(this, "" + rect);
     42    }
     43   
     44   
     45    /** This method is called from within the constructor to
     46     * initialize the form.
     47     * WARNING: Do NOT modify this code. The content of this method is
     48     * always regenerated by the Form Editor.
     49     */
     50    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
     51    private void initComponents()
     52    {
     53        jPanel1 = new javax.swing.JPanel();
     54
     55        setLayout(null);
     56
     57        addComponentListener(new java.awt.event.ComponentAdapter()
     58        {
     59            public void componentResized(java.awt.event.ComponentEvent evt)
     60            {
     61                formComponentResized(evt);
     62            }
     63            public void componentShown(java.awt.event.ComponentEvent evt)
     64            {
     65                formComponentShown(evt);
     66            }
     67        });
     68
     69        add(jPanel1);
     70        jPanel1.setBounds(80, 90, 280, 160);
     71
     72    }
     73    // </editor-fold>//GEN-END:initComponents
     74
     75    private void formComponentShown(java.awt.event.ComponentEvent evt)//GEN-FIRST:event_formComponentShown
     76    {//GEN-HEADEREND:event_formComponentShown
     77        JOptionPane.showMessageDialog(this, "" + getWidth() + ", " + getHeight());
     78
     79    }//GEN-LAST:event_formComponentShown
     80
     81    private void formComponentResized(java.awt.event.ComponentEvent evt)//GEN-FIRST:event_formComponentResized
     82    {//GEN-HEADEREND:event_formComponentResized
     83// TODO add your handling code here:
     84    }//GEN-LAST:event_formComponentResized
     85   
     86   
     87    // Variables declaration - do not modify//GEN-BEGIN:variables
     88    private javax.swing.JPanel jPanel1;
     89    // End of variables declaration//GEN-END:variables
     90   
     91}
  • new file core/src/com/kitfox/svg/app/beans/SVGPanel.java

    - +  
     1/*
     2 * SVGIcon.java
     3 *
     4 * Created on April 21, 2005, 10:43 AM
     5 */
     6
     7package com.kitfox.svg.app.beans;
     8
     9import javax.swing.*;
     10import java.awt.*;
     11import java.awt.geom.*;
     12import java.net.*;
     13import java.beans.*;
     14
     15import com.kitfox.svg.*;
     16
     17/**
     18 *
     19 * @author  kitfox
     20 */
     21public class SVGPanel extends JPanel
     22{
     23    public static final long serialVersionUID = 1;
     24
     25
     26    SVGUniverse svgUniverse = SVGCache.getSVGUniverse();
     27   
     28    private boolean antiAlias;
     29   
     30//    private String svgPath;
     31    URI svgURI;
     32
     33    private boolean scaleToFit;
     34    AffineTransform scaleXform = new AffineTransform();
     35   
     36    /** Creates new form SVGIcon */
     37    public SVGPanel()
     38    {
     39        initComponents();
     40    }
     41       
     42    public int getSVGHeight()
     43    {
     44        if (scaleToFit) return getPreferredSize().height;
     45       
     46        SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
     47        if (diagram == null) return 0;
     48        return (int)diagram.getHeight();
     49    }
     50   
     51    public int getSVGWidth()
     52    {
     53        if (scaleToFit) return getPreferredSize().width;
     54       
     55        SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
     56        if (diagram == null) return 0;
     57        return (int)diagram.getWidth();
     58    }
     59   
     60//          Draw the icon at the specified location.
     61    public void paintComponent(Graphics gg)
     62    {
     63        super.paintComponent(gg);
     64       
     65        Graphics2D g = (Graphics2D)gg;
     66       
     67        Object oldAliasHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
     68        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
     69
     70       
     71        SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
     72        if (diagram == null) return;
     73       
     74        if (!scaleToFit)
     75        {
     76            try
     77            {
     78                diagram.render(g);
     79                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
     80            }
     81            catch (SVGException e)
     82            {
     83                throw new RuntimeException(e);
     84            }
     85            return;
     86        }
     87       
     88        Dimension dim = getSize();
     89        final int width = dim.width;
     90        final int height = dim.height;
     91//        int width = getWidth();
     92//        int height = getHeight();
     93       
     94//        if (width == 0 || height == 0)
     95//        {
     96//           //Chances are we're rendering offscreen
     97//            Dimension dim = getSize();
     98//            width = dim.width;
     99//            height = dim.height;
     100//            return;
     101//        }
     102       
     103//        g.setClip(0, 0, dim.width, dim.height);
     104
     105           
     106        final Rectangle2D.Double rect = new Rectangle2D.Double();
     107        diagram.getViewRect(rect);
     108       
     109        scaleXform.setToScale(width / rect.width, height / rect.height);
     110       
     111        AffineTransform oldXform = g.getTransform();
     112        g.transform(scaleXform);
     113
     114        try
     115        {
     116            diagram.render(g);
     117        }
     118        catch (SVGException e)
     119        {
     120            throw new RuntimeException(e);
     121        }
     122       
     123        g.setTransform(oldXform);
     124       
     125        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAliasHint);
     126    }
     127   
     128    public SVGUniverse getSvgUniverse()
     129    {
     130        return svgUniverse;
     131    }
     132
     133    public void setSvgUniverse(SVGUniverse svgUniverse)
     134    {
     135        SVGUniverse old = this.svgUniverse;
     136        this.svgUniverse = svgUniverse;
     137        firePropertyChange("svgUniverse", old, svgUniverse);
     138    }
     139
     140    public URI getSvgURI()
     141    {
     142        return svgURI;
     143    }
     144
     145    public void setSvgURI(URI svgURI)
     146    {
     147        URI old = this.svgURI;
     148        this.svgURI = svgURI;
     149        firePropertyChange("svgURI", old, svgURI);
     150    }
     151   
     152    /**
     153     * Most resources your component will want to access will be resources on your classpath. 
     154     * This method will interpret the passed string as a path in the classpath and use
     155     * Class.getResource() to determine the URI of the SVG.
     156     */
     157    public void setSvgResourcePath(String resourcePath) throws SVGException
     158    {
     159        URI old = this.svgURI;
     160       
     161        try
     162        {
     163            svgURI = new URI(getClass().getResource(resourcePath).toString());
     164//System.err.println("SVGPanel: new URI " + svgURI + " from path " + resourcePath);
     165           
     166            firePropertyChange("svgURI", old, svgURI);
     167           
     168            repaint();
     169        }
     170        catch (Exception e)
     171        {
     172            throw new SVGException("Could not resolve path " + resourcePath, e);
     173//            svgURI = old;
     174        }
     175    }
     176   
     177    public boolean isScaleToFit()
     178    {
     179        return scaleToFit;
     180    }
     181
     182    public void setScaleToFit(boolean scaleToFit)
     183    {
     184        boolean old = this.scaleToFit;
     185        this.scaleToFit = scaleToFit;
     186        firePropertyChange("scaleToFit", old, scaleToFit);
     187    }
     188   
     189    /**
     190     * @return true if antiAliasing is turned on.
     191     * @deprecated
     192     */
     193    public boolean getUseAntiAlias()
     194    {
     195        return getAntiAlias();
     196    }
     197
     198    /**
     199     * @param antiAlias true to use antiAliasing.
     200     * @deprecated
     201     */
     202    public void setUseAntiAlias(boolean antiAlias)
     203    {
     204        setAntiAlias(antiAlias);
     205    }
     206   
     207    /**
     208     * @return true if antiAliasing is turned on.
     209     */
     210    public boolean getAntiAlias()
     211    {
     212        return antiAlias;
     213    }
     214
     215    /**
     216     * @param antiAlias true to use antiAliasing.
     217     */
     218    public void setAntiAlias(boolean antiAlias)
     219    {
     220        boolean old = this.antiAlias;
     221        this.antiAlias = antiAlias;
     222        firePropertyChange("antiAlias", old, antiAlias);
     223    }
     224   
     225    /** This method is called from within the constructor to
     226     * initialize the form.
     227     * WARNING: Do NOT modify this code. The content of this method is
     228     * always regenerated by the Form Editor.
     229     */
     230    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
     231    private void initComponents()
     232    {
     233
     234        setLayout(new java.awt.BorderLayout());
     235
     236    }
     237    // </editor-fold>//GEN-END:initComponents
     238   
     239   
     240    // Variables declaration - do not modify//GEN-BEGIN:variables
     241    // End of variables declaration//GEN-END:variables
     242   
     243}
  • new file core/src/com/kitfox/svg/app/data/HandlerFactory.java

    - +  
     1/*
     2 * To change this template, choose Tools | Templates
     3 * and open the template in the editor.
     4 */
     5
     6package com.kitfox.svg.app.data;
     7
     8import java.net.URLStreamHandler;
     9import java.net.URLStreamHandlerFactory;
     10
     11/**
     12 *
     13 * @author kitfox
     14 */
     15public class HandlerFactory implements URLStreamHandlerFactory
     16{
     17    static Handler handler = new Handler();
     18
     19    public URLStreamHandler createURLStreamHandler(String protocol)
     20    {
     21        if ("data".equals(protocol))
     22        {
     23            return handler;
     24        }
     25        return null;
     26    }
     27}
Note: See TracBrowser for help on using the repository browser.