001    /*
002     * LinearGradient.java
003     *
004     *
005     *  The Salamander Project - 2D and 3D graphics libraries in Java
006     *  Copyright (C) 2004 Mark McKay
007     *
008     *  This library is free software; you can redistribute it and/or
009     *  modify it under the terms of the GNU Lesser General Public
010     *  License as published by the Free Software Foundation; either
011     *  version 2.1 of the License, or (at your option) any later version.
012     *
013     *  This library is distributed in the hope that it will be useful,
014     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
015     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016     *  Lesser General Public License for more details.
017     *
018     *  You should have received a copy of the GNU Lesser General Public
019     *  License along with this library; if not, write to the Free Software
020     *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021     *
022     *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
023     *  projects can be found at http://www.kitfox.com
024     *
025     * Created on January 26, 2004, 1:54 AM
026     */
027    
028    package com.kitfox.svg;
029    
030    import com.kitfox.svg.xml.StyleAttribute;
031    import java.awt.Graphics2D;
032    import java.awt.Shape;
033    import java.awt.geom.AffineTransform;
034    import java.awt.geom.Rectangle2D;
035    import java.net.URI;
036    
037    /**
038     * @author Mark McKay
039     * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
040     */
041    public class Use extends ShapeElement {
042    
043        float x = 0f;
044        float y = 0f;
045        float width = 1f;
046        float height = 1f;
047    
048        SVGElement href = null;
049    
050        AffineTransform refXform;
051    
052        /** Creates a new instance of LinearGradient */
053        public Use() {
054        }
055    /*
056        public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent)
057        {
058                    //Load style string
059            super.loaderStartElement(helper, attrs, parent);
060    
061            String x = attrs.getValue("x");
062            String y = attrs.getValue("y");
063            String width = attrs.getValue("width");
064            String height = attrs.getValue("height");
065            String href = attrs.getValue("xlink:href");
066    
067            if (x != null) this.x = (float)XMLParseUtil.parseRatio(x);
068            if (y != null) this.y = (float)XMLParseUtil.parseRatio(y);
069            if (width != null) this.width = (float)XMLParseUtil.parseRatio(width);
070            if (height != null) this.height = (float)XMLParseUtil.parseRatio(height);
071    
072    
073            if (href != null)
074            {
075                try {
076                    URI src = getXMLBase().resolve(href);
077                    this.href = helper.universe.getElement(src);
078                }
079                catch (Exception e)
080                {
081                    e.printStackTrace();
082                }
083            }
084    
085            //Determine use offset/scale
086            refXform = new AffineTransform();
087            refXform.translate(this.x, this.y);
088            refXform.scale(this.width, this.height);
089        }
090    */
091        protected void build() throws SVGException
092        {
093            super.build();
094            
095            StyleAttribute sty = new StyleAttribute();
096            
097            if (getPres(sty.setName("x"))) x = sty.getFloatValueWithUnits();
098    
099            if (getPres(sty.setName("y"))) y = sty.getFloatValueWithUnits();
100    
101            if (getPres(sty.setName("width"))) width = sty.getFloatValueWithUnits();
102    
103            if (getPres(sty.setName("height"))) height = sty.getFloatValueWithUnits();
104    
105            if (getPres(sty.setName("xlink:href")))
106            {
107                URI src = sty.getURIValue(getXMLBase());
108                href = diagram.getUniverse().getElement(src);
109            }
110            
111            //Determine use offset/scale
112            refXform = new AffineTransform();
113            refXform.translate(this.x, this.y);
114        }
115        
116        public void render(Graphics2D g) throws SVGException
117        {
118            beginLayer(g);
119    
120            //AffineTransform oldXform = g.getTransform();
121            AffineTransform oldXform = g.getTransform();
122            g.transform(refXform);
123    
124            if (href == null || !(href instanceof RenderableElement)) return;
125    
126            RenderableElement rendEle = (RenderableElement)href;
127            rendEle.pushParentContext(this);
128            rendEle.render(g);
129            rendEle.popParentContext();
130    
131            g.setTransform(oldXform);
132    
133            finishLayer(g);
134        }
135    
136        public Shape getShape()
137        {
138            if (href instanceof ShapeElement)
139            {
140                Shape shape = ((ShapeElement)href).getShape();
141                shape = refXform.createTransformedShape(shape);
142                shape = shapeToParent(shape);
143                return shape;
144            }
145    
146            return null;
147        }
148    
149        public Rectangle2D getBoundingBox() throws SVGException
150        {
151            if (href instanceof ShapeElement)
152            {
153                ShapeElement shapeEle = (ShapeElement)href;
154                shapeEle.pushParentContext(this);
155                Rectangle2D bounds = shapeEle.getBoundingBox();
156                shapeEle.popParentContext();
157                
158                bounds = refXform.createTransformedShape(bounds).getBounds2D();
159                bounds = boundsToParent(bounds);
160    
161                return bounds;
162            }
163    
164            return null;
165        }
166    
167        /**
168         * Updates all attributes in this diagram associated with a time event.
169         * Ie, all attributes with track information.
170         * @return - true if this node has changed state as a result of the time
171         * update
172         */
173        public boolean updateTime(double curTime) throws SVGException
174        {
175    //        if (trackManager.getNumTracks() == 0) return false;
176            boolean changeState = super.updateTime(curTime);
177    
178            //Get current values for parameters
179            StyleAttribute sty = new StyleAttribute();
180            boolean shapeChange = false;
181            
182            if (getPres(sty.setName("x")))
183            {
184                float newVal = sty.getFloatValueWithUnits();
185                if (newVal != x)
186                {
187                    x = newVal;
188                    shapeChange = true;
189                }
190            }
191    
192            if (getPres(sty.setName("y")))
193            {
194                float newVal = sty.getFloatValueWithUnits();
195                if (newVal != y)
196                {
197                    y = newVal;
198                    shapeChange = true;
199                }
200            }
201    
202            if (getPres(sty.setName("width")))
203            {
204                float newVal = sty.getFloatValueWithUnits();
205                if (newVal != width)
206                {
207                    width = newVal;
208                    shapeChange = true;
209                }
210            }
211    
212            if (getPres(sty.setName("height")))
213            {
214                float newVal = sty.getFloatValueWithUnits();
215                if (newVal != height)
216                {
217                    height = newVal;
218                    shapeChange = true;
219                }
220            }
221            
222            if (getPres(sty.setName("xlink:href")))
223            {
224                URI src = sty.getURIValue(getXMLBase());
225                SVGElement newVal = diagram.getUniverse().getElement(src);
226                if (newVal != href)
227                {
228                    href = newVal;
229                    shapeChange = true;
230                }
231            }
232    /*
233            if (getPres(sty.setName("xlink:href")))
234            {
235                URI src = sty.getURIValue(getXMLBase());
236                href = diagram.getUniverse().getElement(src);
237            }
238            
239            //Determine use offset/scale
240            refXform = new AffineTransform();
241            refXform.translate(this.x, this.y);
242            refXform.scale(this.width, this.height);
243    */        
244            if (shapeChange)
245            {
246                build();
247                //Determine use offset/scale
248    //            refXform.setToTranslation(this.x, this.y);
249    //            refXform.scale(this.width, this.height);
250    //            return true;
251            }
252            
253            return changeState || shapeChange;
254        }
255    }