001/*
002 * SVG Salamander
003 * Copyright (c) 2004, Mark McKay
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or 
007 * without modification, are permitted provided that the following
008 * conditions are met:
009 *
010 *   - Redistributions of source code must retain the above 
011 *     copyright notice, this list of conditions and the following
012 *     disclaimer.
013 *   - Redistributions in binary form must reproduce the above
014 *     copyright notice, this list of conditions and the following
015 *     disclaimer in the documentation and/or other materials 
016 *     provided with the distribution.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
021 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
022 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
023 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
026 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
027 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
029 * OF THE POSSIBILITY OF SUCH DAMAGE. 
030 * 
031 * Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
032 * projects can be found at http://www.kitfox.com
033 *
034 * Created on January 26, 2004, 5:25 PM
035 */
036package com.kitfox.svg;
037
038import com.kitfox.svg.xml.StyleAttribute;
039import java.awt.Graphics2D;
040import java.awt.Shape;
041import java.awt.geom.Rectangle2D;
042import java.awt.geom.RectangularShape;
043import java.awt.geom.RoundRectangle2D;
044import java.io.IOException;
045import java.io.ObjectInputStream;
046import java.io.ObjectOutputStream;
047
048/**
049 * @author Mark McKay
050 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
051 */
052public class Rect extends ShapeElement
053{
054    public static final String TAG_NAME = "rect";
055
056    float x = 0f;
057    float y = 0f;
058    float width = 0f;
059    float height = 0f;
060    float rx = 0f;
061    float ry = 0f;
062    RectangularShape rect;
063
064    /**
065     * Creates a new instance of Rect
066     */
067    public Rect()
068    {
069    }
070
071    @Override
072    public String getTagName()
073    {
074        return TAG_NAME;
075    }
076
077    private void writeObject(ObjectOutputStream out) throws IOException
078    {
079        out.writeFloat(x);
080        out.writeFloat(y);
081        out.writeFloat(width);
082        out.writeFloat(height);
083        out.writeFloat(rx);
084        out.writeFloat(ry);
085    }
086
087    private void readObject(ObjectInputStream in) throws IOException
088    {
089        x = in.readFloat();
090        y = in.readFloat();
091        width = in.readFloat();
092        height = in.readFloat();
093        rx = in.readFloat();
094        ry = in.readFloat();
095
096        if (rx == 0f && ry == 0f)
097        {
098            rect = new Rectangle2D.Float(x, y, width, height);
099        } else
100        {
101            rect = new RoundRectangle2D.Float(x, y, width, height, rx * 2, ry * 2);
102        }
103    }
104
105    /*
106     public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent)
107     {
108     //Load style string
109     super.loaderStartElement(helper, attrs, parent);
110
111     String x = attrs.getValue("x");
112     String y = attrs.getValue("y");
113     String width = attrs.getValue("width");
114     String height = attrs.getValue("height");
115     String rx = attrs.getValue("rx");
116     String ry = attrs.getValue("ry");
117
118     if (rx == null) rx = ry;
119     if (ry == null) ry = rx;
120
121     this.x = XMLParseUtil.parseFloat(x);
122     this.y = XMLParseUtil.parseFloat(y);
123     this.width = XMLParseUtil.parseFloat(width);
124     this.height = XMLParseUtil.parseFloat(height);
125     if (rx != null)
126     {
127     this.rx = XMLParseUtil.parseFloat(rx);
128     this.ry = XMLParseUtil.parseFloat(ry);
129     }
130
131     build();
132     //        setBounds(this.x, this.y, this.width, this.height);
133     }
134     */
135    @Override
136    protected void build() throws SVGException
137    {
138        super.build();
139
140        StyleAttribute sty = new StyleAttribute();
141
142//        SVGElement parent = this.getParent();
143//        if (parent instanceof RenderableElement)
144//        {
145//            RenderableElement re = (RenderableElement)parent;
146//            Rectangle2D bounds = re.getBoundingBox();
147//            bounds = null;
148//        }
149
150
151        if (getPres(sty.setName("x")))
152        {
153            x = sty.getFloatValueWithUnits();
154        }
155
156        if (getPres(sty.setName("y")))
157        {
158            y = sty.getFloatValueWithUnits();
159        }
160
161        if (getPres(sty.setName("width")))
162        {
163            width = sty.getFloatValueWithUnits();
164        }
165
166        if (getPres(sty.setName("height")))
167        {
168            height = sty.getFloatValueWithUnits();
169        }
170
171        boolean rxSet = false;
172        if (getPres(sty.setName("rx")))
173        {
174            rx = sty.getFloatValueWithUnits();
175            rxSet = true;
176        }
177
178        boolean rySet = false;
179        if (getPres(sty.setName("ry")))
180        {
181            ry = sty.getFloatValueWithUnits();
182            rySet = true;
183        }
184
185        if (!rxSet)
186        {
187            rx = ry;
188        }
189        if (!rySet)
190        {
191            ry = rx;
192        }
193
194
195        if (rx == 0f && ry == 0f)
196        {
197            rect = new Rectangle2D.Float(x, y, width, height);
198        } else
199        {
200            rect = new RoundRectangle2D.Float(x, y, width, height, rx * 2, ry * 2);
201        }
202    }
203
204    @Override
205    public void render(Graphics2D g) throws SVGException
206    {
207        beginLayer(g);
208        renderShape(g, rect);
209        finishLayer(g);
210    }
211
212    @Override
213    public Shape getShape()
214    {
215        return shapeToParent(rect);
216    }
217
218    @Override
219    public Rectangle2D getBoundingBox() throws SVGException
220    {
221        return boundsToParent(includeStrokeInBounds(rect.getBounds2D()));
222    }
223
224    /**
225     * Updates all attributes in this diagram associated with a time event. Ie,
226     * all attributes with track information.
227     *
228     * @return - true if this node has changed state as a result of the time
229     * update
230     */
231    @Override
232    public boolean updateTime(double curTime) throws SVGException
233    {
234//        if (trackManager.getNumTracks() == 0) return false;
235        boolean changeState = super.updateTime(curTime);
236
237        //Get current values for parameters
238        StyleAttribute sty = new StyleAttribute();
239        boolean shapeChange = false;
240
241        if (getPres(sty.setName("x")))
242        {
243            float newVal = sty.getFloatValueWithUnits();
244            if (newVal != x)
245            {
246                x = newVal;
247                shapeChange = true;
248            }
249        }
250
251        if (getPres(sty.setName("y")))
252        {
253            float newVal = sty.getFloatValueWithUnits();
254            if (newVal != y)
255            {
256                y = newVal;
257                shapeChange = true;
258            }
259        }
260
261        if (getPres(sty.setName("width")))
262        {
263            float newVal = sty.getFloatValueWithUnits();
264            if (newVal != width)
265            {
266                width = newVal;
267                shapeChange = true;
268            }
269        }
270
271        if (getPres(sty.setName("height")))
272        {
273            float newVal = sty.getFloatValueWithUnits();
274            if (newVal != height)
275            {
276                height = newVal;
277                shapeChange = true;
278            }
279        }
280
281        if (getPres(sty.setName("rx")))
282        {
283            float newVal = sty.getFloatValueWithUnits();
284            if (newVal != rx)
285            {
286                rx = newVal;
287                shapeChange = true;
288            }
289        }
290
291        if (getPres(sty.setName("ry")))
292        {
293            float newVal = sty.getFloatValueWithUnits();
294            if (newVal != ry)
295            {
296                ry = newVal;
297                shapeChange = true;
298            }
299        }
300
301        if (shapeChange)
302        {
303            build();
304//            if (rx == 0f && ry == 0f)
305//            {
306//                rect = new Rectangle2D.Float(x, y, width, height);
307//            }
308//            else
309//            {
310//                rect = new RoundRectangle2D.Float(x, y, width, height, rx * 2, ry * 2);
311//            }
312//            return true;
313        }
314
315        return changeState || shapeChange;
316    }
317}