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 March 18, 2004, 6:52 AM
035 */
036package com.kitfox.svg;
037
038import com.kitfox.svg.xml.StyleAttribute;
039import java.awt.geom.Point2D;
040import java.net.URI;
041import java.net.URL;
042import java.util.ArrayList;
043
044/**
045 * @author Mark McKay
046 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
047 */
048public class Filter extends SVGElement
049{
050
051    public static final String TAG_NAME = "filter";
052    public static final int FU_OBJECT_BOUNDING_BOX = 0;
053    public static final int FU_USER_SPACE_ON_USE = 1;
054    protected int filterUnits = FU_OBJECT_BOUNDING_BOX;
055    public static final int PU_OBJECT_BOUNDING_BOX = 0;
056    public static final int PU_USER_SPACE_ON_USE = 1;
057    protected int primitiveUnits = PU_OBJECT_BOUNDING_BOX;
058    float x = 0f;
059    float y = 0f;
060    float width = 1f;
061    float height = 1f;
062    Point2D filterRes = new Point2D.Double();
063    URL href = null;
064    final ArrayList<SVGElement> filterEffects = new ArrayList<SVGElement>();
065
066    /**
067     * Creates a new instance of FillElement
068     */
069    public Filter()
070    {
071    }
072
073    @Override
074    public String getTagName()
075    {
076        return TAG_NAME;
077    }
078
079    /**
080     * Called after the start element but before the end element to indicate
081     * each child tag that has been processed
082     */
083    @Override
084    public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException
085    {
086        super.loaderAddChild(helper, child);
087
088        if (child instanceof FilterEffects)
089        {
090            filterEffects.add(child);
091        }
092    }
093
094    @Override
095    protected void build() throws SVGException
096    {
097        super.build();
098
099        StyleAttribute sty = new StyleAttribute();
100        String strn;
101
102        if (getPres(sty.setName("filterUnits")))
103        {
104            strn = sty.getStringValue().toLowerCase();
105            if (strn.equals("userspaceonuse"))
106            {
107                filterUnits = FU_USER_SPACE_ON_USE;
108            } else
109            {
110                filterUnits = FU_OBJECT_BOUNDING_BOX;
111            }
112        }
113
114        if (getPres(sty.setName("primitiveUnits")))
115        {
116            strn = sty.getStringValue().toLowerCase();
117            if (strn.equals("userspaceonuse"))
118            {
119                primitiveUnits = PU_USER_SPACE_ON_USE;
120            } else
121            {
122                primitiveUnits = PU_OBJECT_BOUNDING_BOX;
123            }
124        }
125
126        if (getPres(sty.setName("x")))
127        {
128            x = sty.getFloatValueWithUnits();
129        }
130
131        if (getPres(sty.setName("y")))
132        {
133            y = sty.getFloatValueWithUnits();
134        }
135
136        if (getPres(sty.setName("width")))
137        {
138            width = sty.getFloatValueWithUnits();
139        }
140
141        if (getPres(sty.setName("height")))
142        {
143            height = sty.getFloatValueWithUnits();
144        }
145
146        try
147        {
148            if (getPres(sty.setName("xlink:href")))
149            {
150                URI src = sty.getURIValue(getXMLBase());
151                href = src.toURL();
152            }
153        } catch (Exception e)
154        {
155            throw new SVGException(e);
156        }
157
158    }
159
160    public float getX()
161    {
162        return x;
163    }
164
165    public float getY()
166    {
167        return y;
168    }
169
170    public float getWidth()
171    {
172        return width;
173    }
174
175    public float getHeight()
176    {
177        return height;
178    }
179
180    @Override
181    public boolean updateTime(double curTime) throws SVGException
182    {
183//        if (trackManager.getNumTracks() == 0) return false;
184
185        //Get current values for parameters
186        StyleAttribute sty = new StyleAttribute();
187        boolean stateChange = false;
188
189        if (getPres(sty.setName("x")))
190        {
191            float newVal = sty.getFloatValueWithUnits();
192            if (newVal != x)
193            {
194                x = newVal;
195                stateChange = true;
196            }
197        }
198
199        if (getPres(sty.setName("y")))
200        {
201            float newVal = sty.getFloatValueWithUnits();
202            if (newVal != y)
203            {
204                y = newVal;
205                stateChange = true;
206            }
207        }
208
209        if (getPres(sty.setName("width")))
210        {
211            float newVal = sty.getFloatValueWithUnits();
212            if (newVal != width)
213            {
214                width = newVal;
215                stateChange = true;
216            }
217        }
218
219        if (getPres(sty.setName("height")))
220        {
221            float newVal = sty.getFloatValueWithUnits();
222            if (newVal != height)
223            {
224                height = newVal;
225                stateChange = true;
226            }
227        }
228
229        try
230        {
231            if (getPres(sty.setName("xlink:href")))
232            {
233                URI src = sty.getURIValue(getXMLBase());
234                URL newVal = src.toURL();
235
236                if (!newVal.equals(href))
237                {
238                    href = newVal;
239                    stateChange = true;
240                }
241            }
242        } catch (Exception e)
243        {
244            throw new SVGException(e);
245        }
246
247        if (getPres(sty.setName("filterUnits")))
248        {
249            int newVal;
250            String strn = sty.getStringValue().toLowerCase();
251            if (strn.equals("userspaceonuse"))
252            {
253                newVal = FU_USER_SPACE_ON_USE;
254            } else
255            {
256                newVal = FU_OBJECT_BOUNDING_BOX;
257            }
258            if (newVal != filterUnits)
259            {
260                filterUnits = newVal;
261                stateChange = true;
262            }
263        }
264
265        if (getPres(sty.setName("primitiveUnits")))
266        {
267            int newVal;
268            String strn = sty.getStringValue().toLowerCase();
269            if (strn.equals("userspaceonuse"))
270            {
271                newVal = PU_USER_SPACE_ON_USE;
272            } else
273            {
274                newVal = PU_OBJECT_BOUNDING_BOX;
275            }
276            if (newVal != filterUnits)
277            {
278                primitiveUnits = newVal;
279                stateChange = true;
280            }
281        }
282
283
284
285        return stateChange;
286    }
287}