Ignore:
Timestamp:
2013-06-11T01:01:28+02:00 (13 years ago)
Author:
Don-vip
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/com/kitfox/svg/SVGElement.java

    r4256 r6002  
    11/*
    2  * SVGElement.java
     2 * SVG Salamander
     3 * Copyright (c) 2004, Mark McKay
     4 * All rights reserved.
    35 *
     6 * Redistribution and use in source and binary forms, with or
     7 * without modification, are permitted provided that the following
     8 * conditions are met:
    49 *
    5  *  The Salamander Project - 2D and 3D graphics libraries in Java
    6  *  Copyright (C) 2004 Mark McKay
     10 *   - Redistributions of source code must retain the above
     11 *     copyright notice, this list of conditions and the following
     12 *     disclaimer.
     13 *   - Redistributions in binary form must reproduce the above
     14 *     copyright notice, this list of conditions and the following
     15 *     disclaimer in the documentation and/or other materials
     16 *     provided with the distribution.
    717 *
    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
     18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     29 * OF THE POSSIBILITY OF SUCH DAMAGE.
     30 *
     31 * Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
     32 * projects can be found at http://www.kitfox.com
    2433 *
    2534 * Created on January 26, 2004, 1:59 AM
    2635 */
    27 
    2836package com.kitfox.svg;
    2937
    30 import java.util.*;
    31 import java.util.regex.*;
    32 import java.net.*;
    33 import java.awt.geom.*;
    34 
    35 import org.xml.sax.*;
    36 import com.kitfox.svg.pathcmd.*;
    37 import com.kitfox.svg.xml.*;
     38import com.kitfox.svg.pathcmd.Arc;
     39import com.kitfox.svg.pathcmd.BuildHistory;
     40import com.kitfox.svg.pathcmd.Cubic;
     41import com.kitfox.svg.pathcmd.CubicSmooth;
     42import com.kitfox.svg.pathcmd.Horizontal;
     43import com.kitfox.svg.pathcmd.LineTo;
     44import com.kitfox.svg.pathcmd.MoveTo;
     45import com.kitfox.svg.pathcmd.PathCommand;
     46import com.kitfox.svg.pathcmd.Quadratic;
     47import com.kitfox.svg.pathcmd.QuadraticSmooth;
     48import com.kitfox.svg.pathcmd.Terminal;
     49import com.kitfox.svg.pathcmd.Vertical;
     50import com.kitfox.svg.xml.StyleAttribute;
     51import com.kitfox.svg.xml.StyleSheet;
     52import com.kitfox.svg.xml.XMLParseUtil;
     53import java.awt.geom.AffineTransform;
     54import java.awt.geom.GeneralPath;
    3855import java.io.Serializable;
     56import java.net.URI;
     57import java.util.ArrayList;
     58import java.util.Collections;
     59import java.util.HashMap;
     60import java.util.HashSet;
     61import java.util.Iterator;
     62import java.util.LinkedList;
     63import java.util.List;
     64import java.util.Set;
     65import java.util.regex.Matcher;
     66import java.util.regex.Pattern;
     67import org.xml.sax.Attributes;
     68import org.xml.sax.SAXException;
     69
    3970
    4071/**
     
    4475abstract public class SVGElement implements Serializable
    4576{
     77
    4678    public static final long serialVersionUID = 0;
    47    
    4879    public static final String SVG_NS = "http://www.w3.org/2000/svg";
    49    
    5080    protected SVGElement parent = null;
    51    
    5281    protected final ArrayList children = new ArrayList();
    53    
    5482    protected String id = null;
    5583    /**
    56      * CSS class.  Used for applying style sheet information.
     84     * CSS class. Used for applying style sheet information.
    5785     */
    5886    protected String cssClass = null;
    59    
    6087    /**
    6188     * Styles defined for this elemnt via the <b>style</b> attribute.
    6289     */
    6390    protected final HashMap inlineStyles = new HashMap();
    64    
    65     /**
    66      * Presentation attributes set for this element.  Ie, any attribute other
     91    /**
     92     * Presentation attributes set for this element. Ie, any attribute other
    6793     * than the <b>style</b> attribute.
    6894     */
    6995    protected final HashMap presAttribs = new HashMap();
    70    
    7196    /**
    7297     * A list of presentation attributes to not include in the presentation
     
    7499     */
    75100    protected static final Set ignorePresAttrib;
     101
    76102    static
    77103    {
     
    81107//        set.add("style");
    82108//        set.add("xml:base");
    83        
     109
    84110        ignorePresAttrib = Collections.unmodifiableSet(set);
    85111    }
    86    
    87     /**
    88      * This element may override the URI we resolve against with an
    89      * xml:base attribute.  If so, a copy is placed here.  Otherwise, we defer
    90      * to our parent for the reolution base
     112    /**
     113     * This element may override the URI we resolve against with an xml:base
     114     * attribute. If so, a copy is placed here. Otherwise, we defer to our
     115     * parent for the reolution base
    91116     */
    92117    protected URI xmlBase = null;
    93    
    94118    /**
    95119     * The diagram this element belongs to
    96120     */
    97121    protected SVGDiagram diagram;
    98     /**
    99      * Link to the universe we reside in
    100      */
    101 //    protected SVGUniverse universe;
    102    
    103122    boolean dirty = true;
    104123
    105 //    public static final Matcher adobeId = Pattern.compile("(.*)_1_").matcher("");
    106 //    static final String fpNumRe = "[-+]?((\\d+)|(\\d*\\.\\d+))([-+]?[eE]\\d+)?";
    107    
    108     /** Creates a new instance of SVGElement */
     124    /**
     125     * Creates a new instance of SVGElement
     126     */
    109127    public SVGElement()
    110128    {
    111129        this(null, null, null);
    112130    }
    113    
     131
    114132    public SVGElement(String id, SVGElement parent)
    115133    {
    116134        this(id, null, parent);
    117135    }
    118    
     136
    119137    public SVGElement(String id, String cssClass, SVGElement parent)
    120138    {
     
    123141        this.parent = parent;
    124142    }
    125    
     143
     144    abstract public String getTagName();
     145
    126146    public SVGElement getParent()
    127147    {
    128148        return parent;
    129149    }
    130    
     150
    131151    void setParent(SVGElement parent)
    132152    {
    133153        this.parent = parent;
    134154    }
    135    
     155
    136156    /**
    137157     * @return an ordered list of nodes from the root of the tree to this node
     
    139159    public List getPath(List retVec)
    140160    {
    141         if (retVec == null) retVec = new ArrayList();
    142        
     161        if (retVec == null)
     162        {
     163            retVec = new ArrayList();
     164        }
     165
    143166        if (parent != null)
    144167        {
     
    146169        }
    147170        retVec.add(this);
    148        
     171
    149172        return retVec;
    150173    }
    151    
    152     /**
    153      * @param retVec - A list to add all children to.  If null, a new list is
     174
     175    /**
     176     * @param retVec - A list to add all children to. If null, a new list is
    154177     * created and children of this group are added.
    155178     *
     
    158181    public List getChildren(List retVec)
    159182    {
    160         if (retVec == null) retVec = new ArrayList();
    161        
     183        if (retVec == null)
     184        {
     185            retVec = new ArrayList();
     186        }
     187
    162188        retVec.addAll(children);
    163        
     189
    164190        return retVec;
    165191    }
    166    
     192
    167193    /**
    168194     * @param id - Id of svg element to return
     
    173199        for (Iterator it = children.iterator(); it.hasNext();)
    174200        {
    175             SVGElement ele = (SVGElement)it.next();
     201            SVGElement ele = (SVGElement) it.next();
    176202            String eleId = ele.getId();
    177             if (eleId != null && eleId.equals(id)) return ele;
    178         }
    179        
     203            if (eleId != null && eleId.equals(id))
     204            {
     205                return ele;
     206            }
     207        }
     208
    180209        return null;
    181210    }
    182    
    183     /**
    184      * Searches children for given element.  If found, returns index of child.
     211
     212    /**
     213     * Searches children for given element. If found, returns index of child.
    185214     * Otherwise returns -1.
    186215     */
     
    189218        return children.indexOf(child);
    190219    }
    191    
     220
    192221    /**
    193222     * Swaps 2 elements in children.
     223     *
    194224     * @i index of first
    195225     * @j index of second
     
    203233            return;
    204234        }
    205        
     235
    206236        Object temp = children.get(i);
    207237        children.set(i, children.get(j));
     
    209239        build();
    210240    }
    211    
    212     /**
    213      * Called during SAX load process to notify that this tag has begun the process
    214      * of being loaded
     241
     242    /**
     243     * Called during SAX load process to notify that this tag has begun the
     244     * process of being loaded
     245     *
    215246     * @param attrs - Attributes of this tag
    216      * @param helper - An object passed to all SVG elements involved in this build
    217      * process to aid in sharing information.
     247     * @param helper - An object passed to all SVG elements involved in this
     248     * build process to aid in sharing information.
    218249     */
    219250    public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent) throws SAXException
     
    222253        this.parent = parent;
    223254        this.diagram = helper.diagram;
    224        
     255
    225256        this.id = attrs.getValue("id");
    226257        if (this.id != null && !this.id.equals(""))
     
    228259            diagram.setElement(this.id, this);
    229260        }
    230        
     261
    231262        String className = attrs.getValue("class");
    232263        this.cssClass = (className == null || className.equals("")) ? null : className;
    233264        //docRoot = helper.docRoot;
    234265        //universe = helper.universe;
    235        
     266
    236267        //Parse style string, if any
    237268        String style = attrs.getValue("style");
     
    240271            HashMap map = XMLParseUtil.parseStyle(style, inlineStyles);
    241272        }
    242        
     273
    243274        String base = attrs.getValue("xml:base");
    244275        if (base != null && !base.equals(""))
     
    247278            {
    248279                xmlBase = new URI(base);
    249             }
    250             catch (Exception e)
     280            } catch (Exception e)
    251281            {
    252282                throw new SAXException(e);
    253283            }
    254284        }
    255        
     285
    256286        //Place all other attributes into the presentation attribute list
    257287        int numAttrs = attrs.getLength();
     
    259289        {
    260290            String name = attrs.getQName(i);
    261             if (ignorePresAttrib.contains(name)) continue;
     291            if (ignorePresAttrib.contains(name))
     292            {
     293                continue;
     294            }
    262295            String value = attrs.getValue(i);
    263            
     296
    264297            presAttribs.put(name, new StyleAttribute(name, value));
    265298        }
    266299    }
    267    
     300
    268301    /**
    269302     * @return a set of Strings that corespond to CSS attributes on this element
     
    273306        return inlineStyles.keySet();
    274307    }
    275    
     308
    276309    /**
    277310     * @return a set of Strings that corespond to XML attributes on this element
     
    281314        return presAttribs.keySet();
    282315    }
    283    
     316
    284317    /**
    285318     * Called after the start element but before the end element to indicate
     
    292325        child.setDiagram(diagram);
    293326    }
    294    
    295     private void setDiagram(SVGDiagram diagram)
     327
     328    protected void setDiagram(SVGDiagram diagram)
    296329    {
    297330        this.diagram = diagram;
     
    299332        for (Iterator it = children.iterator(); it.hasNext();)
    300333        {
    301             SVGElement ele = (SVGElement)it.next();
     334            SVGElement ele = (SVGElement) it.next();
    302335            ele.setDiagram(diagram);
    303336        }
    304337    }
    305    
     338
    306339    public void removeChild(SVGElement child) throws SVGElementException
    307340    {
     
    310343            throw new SVGElementException(this, "Element does not contain child " + child);
    311344        }
    312        
     345
    313346        children.remove(child);
    314347    }
    315    
     348
    316349    /**
    317350     * Called during load process to add text scanned within a tag
     
    320353    {
    321354    }
    322    
    323     /**
    324      * Called to indicate that this tag and the tags it contains have been completely
    325      * processed, and that it should finish any load processes.
     355
     356    /**
     357     * Called to indicate that this tag and the tags it contains have been
     358     * completely processed, and that it should finish any load processes.
    326359     */
    327360    public void loaderEndElement(SVGLoaderHelper helper) throws SVGParseException
    328361    {
    329         try
    330         {
    331             build();
    332         }
    333         catch (SVGException se)
    334         {
    335             throw new SVGParseException(se);
    336         }
    337     }
    338    
    339     /**
    340      * Called by internal processes to rebuild the geometry of this node
    341      * from it's presentation attributes, style attributes and animated tracks.
     362//        try
     363//        {
     364//            build();
     365//        }
     366//        catch (SVGException se)
     367//        {
     368//            throw new SVGParseException(se);
     369//        }
     370    }
     371
     372    /**
     373     * Called by internal processes to rebuild the geometry of this node from
     374     * it's presentation attributes, style attributes and animated tracks.
    342375     */
    343376    protected void build() throws SVGException
    344377    {
    345378        StyleAttribute sty = new StyleAttribute();
    346        
     379
    347380        if (getPres(sty.setName("id")))
    348381        {
     
    355388            }
    356389        }
    357         if (getPres(sty.setName("class"))) cssClass = sty.getStringValue();
    358         if (getPres(sty.setName("xml:base"))) xmlBase = sty.getURIValue();
    359     }
    360    
     390        if (getPres(sty.setName("class")))
     391        {
     392            cssClass = sty.getStringValue();
     393        }
     394        if (getPres(sty.setName("xml:base")))
     395        {
     396            xmlBase = sty.getURIValue();
     397        }
     398
     399        //Build children
     400        for (int i = 0; i < children.size(); ++i)
     401        {
     402            SVGElement ele = (SVGElement) children.get(i);
     403            ele.build();
     404        }
     405    }
     406
    361407    public URI getXMLBase()
    362408    {
    363         return xmlBase != null ? xmlBase :
    364             (parent != null ? parent.getXMLBase() : diagram.getXMLBase());
    365     }
    366 
    367     /**
    368      * @return the id assigned to this node.  Null if no id explicitly set.
     409        return xmlBase != null ? xmlBase
     410            : (parent != null ? parent.getXMLBase() : diagram.getXMLBase());
     411    }
     412
     413    /**
     414     * @return the id assigned to this node. Null if no id explicitly set.
    369415     */
    370416    public String getId()
    371417    {
    372         return id;
    373     }
    374    
    375    
     418        return id;
     419    }
    376420    LinkedList contexts = new LinkedList();
    377    
    378     /**
    379      * Hack to allow nodes to temporarily change their parents.  The Use tag will
     421
     422    /**
     423     * Hack to allow nodes to temporarily change their parents. The Use tag will
    380424     * need this so it can alter the attributes that a particular node uses.
    381425     */
     
    387431    protected SVGElement popParentContext()
    388432    {
    389         return (SVGElement)contexts.removeLast();
    390     }
    391    
     433        return (SVGElement) contexts.removeLast();
     434    }
     435
    392436    protected SVGElement getParentContext()
    393437    {
    394         return contexts.isEmpty() ? null : (SVGElement)contexts.getLast();
    395     }
    396    
     438        return contexts.isEmpty() ? null : (SVGElement) contexts.getLast();
     439    }
     440
     441    public SVGRoot getRoot()
     442    {
     443        return parent == null ? null : parent.getRoot();
     444    }
     445
    397446    /*
    398447     * Returns the named style attribute.  Checks for inline styles first, then
     
    408457        return getStyle(attrib, true);
    409458    }
    410    
    411     /**
    412      * Copies the current style into the passed style attribute.  Checks for
    413      * inline styles first, then internal and extranal style sheets, and
    414      * finally checks for presentation attributes.  Recursively checks parents.
    415      * @param attrib - Attribute to write style data to.  Must have it's name
    416      * set to the name of the style being queried.
    417      * @param recursive - If true and this object does not contain the
    418      * named style attribute, checks attributes of parents abck to root until
    419      * one found.
     459
     460    /**
     461     * Copies the current style into the passed style attribute. Checks for
     462     * inline styles first, then internal and extranal style sheets, and finally
     463     * checks for presentation attributes. Recursively checks parents.
     464     *
     465     * @param attrib - Attribute to write style data to. Must have it's name set
     466     * to the name of the style being queried.
     467     * @param recursive - If true and this object does not contain the named
     468     * style attribute, checks attributes of parents back to root until one
     469     * found.
    420470     */
    421471    public boolean getStyle(StyleAttribute attrib, boolean recursive) throws SVGException
    422472    {
    423473        String styName = attrib.getName();
    424        
     474
    425475        //Check for local inline styles
    426476        StyleAttribute styAttr = (StyleAttribute)inlineStyles.get(styName);
    427        
     477
    428478        attrib.setStringValue(styAttr == null ? "" : styAttr.getStringValue());
    429        
     479
    430480        //Return if we've found a non animated style
    431         if (styAttr != null) return true;
    432        
    433        
    434        
    435         //Implement style sheet lookup later
    436        
     481        if (styAttr != null)
     482        {
     483            return true;
     484        }
     485
     486
    437487        //Check for presentation attribute
    438488        StyleAttribute presAttr = (StyleAttribute)presAttribs.get(styName);
    439        
     489
    440490        attrib.setStringValue(presAttr == null ? "" : presAttr.getStringValue());
    441        
     491
    442492        //Return if we've found a presentation attribute instead
    443         if (presAttr != null) return true;
    444        
    445        
     493        if (presAttr != null)
     494        {
     495            return true;
     496        }
     497
     498        //Check for style sheet
     499        SVGRoot root = getRoot();
     500        if (root != null)
     501        {
     502            StyleSheet ss = root.getStyleSheet();
     503            if (ss != null)
     504            {
     505                return ss.getStyle(attrib, getTagName(), cssClass);
     506            }
     507        }
     508
    446509        //If we're recursive, check parents
    447510        if (recursive)
    448511        {
    449512            SVGElement parentContext = getParentContext();
    450             if (parentContext != null) return parentContext.getStyle(attrib, true);
    451             if (parent != null) return parent.getStyle(attrib, true);
    452         }
    453        
     513            if (parentContext != null)
     514            {
     515                return parentContext.getStyle(attrib, true);
     516            }
     517            if (parent != null)
     518            {
     519                return parent.getStyle(attrib, true);
     520            }
     521        }
     522
    454523        //Unsuccessful reading style attribute
    455524        return false;
    456525    }
    457    
    458     /**
    459      * @return the raw style value of this attribute.  Does not take the 
    460      * presentation value or animation into consideration.  Used by animations
    461      * to determine the base to animate from.
     526
     527    /**
     528     * @return the raw style value of this attribute. Does not take the
     529     * presentation value or animation into consideration. Used by animations to
     530     * determine the base to animate from.
    462531     */
    463532    public StyleAttribute getStyleAbsolute(String styName)
    464533    {
    465534        //Check for local inline styles
    466         return (StyleAttribute)inlineStyles.get(styName);
    467     }
    468    
     535        return (StyleAttribute) inlineStyles.get(styName);
     536    }
     537
    469538    /**
    470539     * Copies the presentation attribute into the passed one.
     540     *
    471541     * @return - True if attribute was read successfully
    472542     */
     
    474544    {
    475545        String presName = attrib.getName();
    476        
     546
    477547        //Make sure we have a coresponding presentation attribute
    478         StyleAttribute presAttr = (StyleAttribute)presAttribs.get(presName);
    479        
     548        StyleAttribute presAttr = (StyleAttribute) presAttribs.get(presName);
     549
    480550        //Copy presentation value directly
    481551        attrib.setStringValue(presAttr == null ? "" : presAttr.getStringValue());
    482        
     552
    483553        //Return if we found presentation attribute
    484         if (presAttr != null) return true;
    485        
     554        if (presAttr != null)
     555        {
     556            return true;
     557        }
     558
    486559        return false;
    487560    }
    488    
    489     /**
    490      * @return the raw presentation value of this attribute.  Ignores any 
    491      * modifications applied by style attributes or animation.  Used by
     561
     562    /**
     563     * @return the raw presentation value of this attribute. Ignores any
     564     * modifications applied by style attributes or animation. Used by
    492565     * animations to determine the starting point to animate from
    493566     */
     
    495568    {
    496569        //Check for local inline styles
    497         return (StyleAttribute)presAttribs.get(styName);
    498     }
    499    
     570        return (StyleAttribute) presAttribs.get(styName);
     571    }
     572
    500573    static protected AffineTransform parseTransform(String val) throws SVGException
    501574    {
    502575        final Matcher matchExpression = Pattern.compile("\\w+\\([^)]*\\)").matcher("");
    503        
     576
    504577        AffineTransform retXform = new AffineTransform();
    505        
     578
    506579        matchExpression.reset(val);
    507580        while (matchExpression.find())
     
    509582            retXform.concatenate(parseSingleTransform(matchExpression.group()));
    510583        }
    511        
     584
    512585        return retXform;
    513586    }
    514    
     587
    515588    static public AffineTransform parseSingleTransform(String val) throws SVGException
    516589    {
    517590        final Matcher matchWord = Pattern.compile("[-.\\w]+").matcher("");
    518        
     591
    519592        AffineTransform retXform = new AffineTransform();
    520        
     593
    521594        matchWord.reset(val);
    522595        if (!matchWord.find())
     
    525598            return retXform;
    526599        }
    527        
     600
    528601        String function = matchWord.group().toLowerCase();
    529        
     602
    530603        LinkedList termList = new LinkedList();
    531604        while (matchWord.find())
     
    533606            termList.add(matchWord.group());
    534607        }
    535        
    536        
     608
     609
    537610        double[] terms = new double[termList.size()];
    538611        Iterator it = termList.iterator();
     
    540613        while (it.hasNext())
    541614        {
    542             terms[count++] = XMLParseUtil.parseDouble((String)it.next());
    543         }
    544        
     615            terms[count++] = XMLParseUtil.parseDouble((String) it.next());
     616        }
     617
    545618        //Calculate transformation
    546619        if (function.equals("matrix"))
    547620        {
    548621            retXform.setTransform(terms[0], terms[1], terms[2], terms[3], terms[4], terms[5]);
    549         }
    550         else if (function.equals("translate"))
    551         {
    552             retXform.setToTranslation(terms[0], terms[1]);
    553         }
    554         else if (function.equals("scale"))
     622        } else if (function.equals("translate"))
     623        {
     624            if (terms.length == 1)
     625            {
     626                retXform.setToTranslation(terms[0], 0);
     627            } else
     628            {
     629                retXform.setToTranslation(terms[0], terms[1]);
     630            }
     631        } else if (function.equals("scale"))
    555632        {
    556633            if (terms.length > 1)
     634            {
    557635                retXform.setToScale(terms[0], terms[1]);
    558             else
     636            } else
     637            {
    559638                retXform.setToScale(terms[0], terms[0]);
    560         }
    561         else if (function.equals("rotate"))
     639            }
     640        } else if (function.equals("rotate"))
    562641        {
    563642            if (terms.length > 2)
     643            {
    564644                retXform.setToRotation(Math.toRadians(terms[0]), terms[1], terms[2]);
    565             else
     645            } else
     646            {
    566647                retXform.setToRotation(Math.toRadians(terms[0]));
    567         }
    568         else if (function.equals("skewx"))
     648            }
     649        } else if (function.equals("skewx"))
    569650        {
    570651            retXform.setToShear(Math.toRadians(terms[0]), 0.0);
    571         }
    572         else if (function.equals("skewy"))
     652        } else if (function.equals("skewy"))
    573653        {
    574654            retXform.setToShear(0.0, Math.toRadians(terms[0]));
    575         }
    576         else
     655        } else
    577656        {
    578657            throw new SVGException("Unknown transform type");
    579658        }
    580        
     659
    581660        return retXform;
    582661    }
    583    
     662
    584663    static protected float nextFloat(LinkedList l)
    585664    {
    586         String s = (String)l.removeFirst();
     665        String s = (String) l.removeFirst();
    587666        return Float.parseFloat(s);
    588667    }
    589    
     668
    590669    static protected PathCommand[] parsePathList(String list)
    591670    {
    592671        final Matcher matchPathCmd = Pattern.compile("([MmLlHhVvAaQqTtCcSsZz])|([-+]?((\\d*\\.\\d+)|(\\d+))([eE][-+]?\\d+)?)").matcher(list);
    593        
     672
    594673        //Tokenize
    595674        LinkedList tokens = new LinkedList();
     
    598677            tokens.addLast(matchPathCmd.group());
    599678        }
    600        
    601        
     679
     680
    602681        boolean defaultRelative = false;
    603682        LinkedList cmdList = new LinkedList();
     
    605684        while (tokens.size() != 0)
    606685        {
    607             String curToken = (String)tokens.removeFirst();
     686            String curToken = (String) tokens.removeFirst();
    608687            char initChar = curToken.charAt(0);
    609             if ((initChar >= 'A' && initChar <='Z') || (initChar >= 'a' && initChar <='z'))
     688            if ((initChar >= 'A' && initChar <= 'Z') || (initChar >= 'a' && initChar <= 'z'))
    610689            {
    611690                curCmd = initChar;
    612             }
    613             else
     691            } else
    614692            {
    615693                tokens.addFirst(curToken);
    616694            }
    617            
     695
    618696            PathCommand cmd = null;
    619            
     697
    620698            switch (curCmd)
    621699            {
     
    648726                case 'A':
    649727                    cmd = new Arc(false, nextFloat(tokens), nextFloat(tokens),
    650                             nextFloat(tokens),
    651                             nextFloat(tokens) == 1f, nextFloat(tokens) == 1f,
    652                             nextFloat(tokens), nextFloat(tokens));
     728                        nextFloat(tokens),
     729                        nextFloat(tokens) == 1f, nextFloat(tokens) == 1f,
     730                        nextFloat(tokens), nextFloat(tokens));
    653731                    break;
    654732                case 'a':
    655733                    cmd = new Arc(true, nextFloat(tokens), nextFloat(tokens),
    656                             nextFloat(tokens),
    657                             nextFloat(tokens) == 1f, nextFloat(tokens) == 1f,
    658                             nextFloat(tokens), nextFloat(tokens));
     734                        nextFloat(tokens),
     735                        nextFloat(tokens) == 1f, nextFloat(tokens) == 1f,
     736                        nextFloat(tokens), nextFloat(tokens));
    659737                    break;
    660738                case 'Q':
    661739                    cmd = new Quadratic(false, nextFloat(tokens), nextFloat(tokens),
    662                             nextFloat(tokens), nextFloat(tokens));
     740                        nextFloat(tokens), nextFloat(tokens));
    663741                    break;
    664742                case 'q':
    665743                    cmd = new Quadratic(true, nextFloat(tokens), nextFloat(tokens),
    666                             nextFloat(tokens), nextFloat(tokens));
     744                        nextFloat(tokens), nextFloat(tokens));
    667745                    break;
    668746                case 'T':
     
    674752                case 'C':
    675753                    cmd = new Cubic(false, nextFloat(tokens), nextFloat(tokens),
    676                             nextFloat(tokens), nextFloat(tokens),
    677                             nextFloat(tokens), nextFloat(tokens));
     754                        nextFloat(tokens), nextFloat(tokens),
     755                        nextFloat(tokens), nextFloat(tokens));
    678756                    break;
    679757                case 'c':
    680758                    cmd = new Cubic(true, nextFloat(tokens), nextFloat(tokens),
    681                             nextFloat(tokens), nextFloat(tokens),
    682                             nextFloat(tokens), nextFloat(tokens));
     759                        nextFloat(tokens), nextFloat(tokens),
     760                        nextFloat(tokens), nextFloat(tokens));
    683761                    break;
    684762                case 'S':
    685763                    cmd = new CubicSmooth(false, nextFloat(tokens), nextFloat(tokens),
    686                             nextFloat(tokens), nextFloat(tokens));
     764                        nextFloat(tokens), nextFloat(tokens));
    687765                    break;
    688766                case 's':
    689767                    cmd = new CubicSmooth(true, nextFloat(tokens), nextFloat(tokens),
    690                             nextFloat(tokens), nextFloat(tokens));
     768                        nextFloat(tokens), nextFloat(tokens));
    691769                    break;
    692770                case 'Z':
     
    697775                    throw new RuntimeException("Invalid path element");
    698776            }
    699            
     777
    700778            cmdList.add(cmd);
    701779            defaultRelative = cmd.isRelative;
    702780        }
    703        
     781
    704782        PathCommand[] retArr = new PathCommand[cmdList.size()];
    705783        cmdList.toArray(retArr);
    706784        return retArr;
    707785    }
    708    
     786
    709787    static protected GeneralPath buildPath(String text, int windingRule)
    710788    {
    711789        PathCommand[] commands = parsePathList(text);
    712        
     790
    713791        int numKnots = 2;
    714792        for (int i = 0; i < commands.length; i++)
     
    716794            numKnots += commands[i].getNumKnotsAdded();
    717795        }
    718        
    719        
     796
     797
    720798        GeneralPath path = new GeneralPath(windingRule, numKnots);
    721        
     799
    722800        BuildHistory hist = new BuildHistory();
    723        
     801
    724802        for (int i = 0; i < commands.length; i++)
    725803        {
     
    727805            cmd.appendPath(path, hist);
    728806        }
    729        
     807
    730808        return path;
    731809    }
    732    
    733    
    734    
    735     /**
    736      * Updates all attributes in this diagram associated with a time event.
    737      * Ie, all attributes with track information.
     810
     811    /**
     812     * Updates all attributes in this diagram associated with a time event. Ie,
     813     * all attributes with track information.
     814     *
    738815     * @return - true if this node has changed state as a result of the time
    739816     * update
     
    748825    public SVGElement getChild(int i)
    749826    {
    750         return (SVGElement)children.get(i);
    751     }
    752    
     827        return (SVGElement) children.get(i);
     828    }
     829
     830    public double lerp(double t0, double t1, double alpha)
     831    {
     832        return (1 - alpha) * t0 + alpha * t1;
     833    }
    753834}
Note: See TracChangeset for help on using the changeset viewer.