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    public String getTagName()
072    {
073        return TAG_NAME;
074    }
075
076    private void writeObject(ObjectOutputStream out) throws IOException
077    {
078        out.writeFloat(x);
079        out.writeFloat(y);
080        out.writeFloat(width);
081        out.writeFloat(height);
082        out.writeFloat(rx);
083        out.writeFloat(ry);
084    }
085
086    private void readObject(ObjectInputStream in) throws IOException
087    {
088        x = in.readFloat();
089        y = in.readFloat();
090        width = in.readFloat();
091        height = in.readFloat();
092        rx = in.readFloat();
093        ry = in.readFloat();
094
095        if (rx == 0f && ry == 0f)
096        {
097            rect = new Rectangle2D.Float(x, y, width, height);
098        } else
099        {
100            rect = new RoundRectangle2D.Float(x, y, width, height, rx * 2, ry * 2);
101        }
102    }
103
104    /*
105     public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent)
106     {
107     //Load style string
108     super.loaderStartElement(helper, attrs, parent);
109
110     String x = attrs.getValue("x");
111     String y = attrs.getValue("y");
112     String width = attrs.getValue("width");
113     String height = attrs.getValue("height");
114     String rx = attrs.getValue("rx");
115     String ry = attrs.getValue("ry");
116
117     if (rx == null) rx = ry;
118     if (ry == null) ry = rx;
119
120     this.x = XMLParseUtil.parseFloat(x);
121     this.y = XMLParseUtil.parseFloat(y);
122     this.width = XMLParseUtil.parseFloat(width);
123     this.height = XMLParseUtil.parseFloat(height);
124     if (rx != null)
125     {
126     this.rx = XMLParseUtil.parseFloat(rx);
127     this.ry = XMLParseUtil.parseFloat(ry);
128     }
129
130     build();
131     //        setBounds(this.x, this.y, this.width, this.height);
132     }
133     */
134    protected void build() throws SVGException
135    {
136        super.build();
137
138        StyleAttribute sty = new StyleAttribute();
139
140//        SVGElement parent = this.getParent();
141//        if (parent instanceof RenderableElement)
142//        {
143//            RenderableElement re = (RenderableElement)parent;
144//            Rectangle2D bounds = re.getBoundingBox();
145//            bounds = null;
146//        }
147
148
149        if (getPres(sty.setName("x")))
150        {
151            x = sty.getFloatValueWithUnits();
152        }
153
154        if (getPres(sty.setName("y")))
155        {
156            y = sty.getFloatValueWithUnits();
157        }
158
159        if (getPres(sty.setName("width")))
160        {
161            width = sty.getFloatValueWithUnits();
162        }
163
164        if (getPres(sty.setName("height")))
165        {
166            height = sty.getFloatValueWithUnits();
167        }
168
169        boolean rxSet = false;
170        if (getPres(sty.setName("rx")))
171        {
172            rx = sty.getFloatValueWithUnits();
173            rxSet = true;
174        }
175
176        boolean rySet = false;
177        if (getPres(sty.setName("ry")))
178        {
179            ry = sty.getFloatValueWithUnits();
180            rySet = true;
181        }
182
183        if (!rxSet)
184        {
185            rx = ry;
186        }
187        if (!rySet)
188        {
189            ry = rx;
190        }
191
192
193        if (rx == 0f && ry == 0f)
194        {
195            rect = new Rectangle2D.Float(x, y, width, height);
196        } else
197        {
198            rect = new RoundRectangle2D.Float(x, y, width, height, rx * 2, ry * 2);
199        }
200    }
201
202    public void render(Graphics2D g) throws SVGException
203    {
204        beginLayer(g);
205        renderShape(g, rect);
206        finishLayer(g);
207    }
208
209    public Shape getShape()
210    {
211        return shapeToParent(rect);
212    }
213
214    public Rectangle2D getBoundingBox() throws SVGException
215    {
216        return boundsToParent(includeStrokeInBounds(rect.getBounds2D()));
217    }
218
219    /**
220     * Updates all attributes in this diagram associated with a time event. Ie,
221     * all attributes with track information.
222     *
223     * @return - true if this node has changed state as a result of the time
224     * update
225     */
226    public boolean updateTime(double curTime) throws SVGException
227    {
228//        if (trackManager.getNumTracks() == 0) return false;
229        boolean changeState = super.updateTime(curTime);
230
231        //Get current values for parameters
232        StyleAttribute sty = new StyleAttribute();
233        boolean shapeChange = false;
234
235        if (getPres(sty.setName("x")))
236        {
237            float newVal = sty.getFloatValueWithUnits();
238            if (newVal != x)
239            {
240                x = newVal;
241                shapeChange = true;
242            }
243        }
244
245        if (getPres(sty.setName("y")))
246        {
247            float newVal = sty.getFloatValueWithUnits();
248            if (newVal != y)
249            {
250                y = newVal;
251                shapeChange = true;
252            }
253        }
254
255        if (getPres(sty.setName("width")))
256        {
257            float newVal = sty.getFloatValueWithUnits();
258            if (newVal != width)
259            {
260                width = newVal;
261                shapeChange = true;
262            }
263        }
264
265        if (getPres(sty.setName("height")))
266        {
267            float newVal = sty.getFloatValueWithUnits();
268            if (newVal != height)
269            {
270                height = newVal;
271                shapeChange = true;
272            }
273        }
274
275        if (getPres(sty.setName("rx")))
276        {
277            float newVal = sty.getFloatValueWithUnits();
278            if (newVal != rx)
279            {
280                rx = newVal;
281                shapeChange = true;
282            }
283        }
284
285        if (getPres(sty.setName("ry")))
286        {
287            float newVal = sty.getFloatValueWithUnits();
288            if (newVal != ry)
289            {
290                ry = newVal;
291                shapeChange = true;
292            }
293        }
294
295        if (shapeChange)
296        {
297            build();
298//            if (rx == 0f && ry == 0f)
299//            {
300//                rect = new Rectangle2D.Float(x, y, width, height);
301//            }
302//            else
303//            {
304//                rect = new RoundRectangle2D.Float(x, y, width, height, rx * 2, ry * 2);
305//            }
306//            return true;
307        }
308
309        return changeState || shapeChange;
310    }
311}