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.geom.*;
032    import java.awt.*;
033    
034    import com.kitfox.svg.xml.*;
035    import org.xml.sax.*;
036    
037    //import org.apache.batik.ext.awt.*;
038    import com.kitfox.svg.batik.*;
039    
040    
041    /**
042     * @author Mark McKay
043     * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
044     */
045    public class LinearGradient extends Gradient {
046    
047        float x1 = 0f;
048        float y1 = 0f;
049        float x2 = 1f;
050        float y2 = 0f;
051    
052        /** Creates a new instance of LinearGradient */
053        public LinearGradient() {
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 x1 = attrs.getValue("x1");
062            String x2 = attrs.getValue("x2");
063            String y1 = attrs.getValue("y1");
064            String y2 = attrs.getValue("y2");
065    
066            if (x1 != null) this.x1 = (float)XMLParseUtil.parseRatio(x1);
067            if (y1 != null) this.y1 = (float)XMLParseUtil.parseRatio(y1);
068            if (x2 != null) this.x2 = (float)XMLParseUtil.parseRatio(x2);
069            if (y2 != null) this.y2 = (float)XMLParseUtil.parseRatio(y2);
070        }
071    */
072        /*
073        public void loaderEndElement(SVGLoaderHelper helper)
074        {
075            super.loaderEndElement(helper);
076            
077            build();
078        }
079        */
080        
081        protected void build() throws SVGException
082        {
083            super.build();
084            
085            StyleAttribute sty = new StyleAttribute();
086            
087            if (getPres(sty.setName("x1"))) x1 = sty.getFloatValueWithUnits();
088            
089            if (getPres(sty.setName("y1"))) y1 = sty.getFloatValueWithUnits();
090            
091            if (getPres(sty.setName("x2"))) x2 = sty.getFloatValueWithUnits();
092            
093            if (getPres(sty.setName("y2"))) y2 = sty.getFloatValueWithUnits();
094        }
095        
096        public Paint getPaint(Rectangle2D bounds, AffineTransform xform)
097        {
098            com.kitfox.svg.batik.MultipleGradientPaint.CycleMethodEnum method;
099            switch (spreadMethod)
100            {
101                default:
102                case SM_PAD:
103                    method = com.kitfox.svg.batik.MultipleGradientPaint.NO_CYCLE;
104                    break;
105                case SM_REPEAT:
106                    method = com.kitfox.svg.batik.MultipleGradientPaint.REPEAT;
107                    break;
108                case SM_REFLECT:
109                    method = com.kitfox.svg.batik.MultipleGradientPaint.REFLECT;
110                    break;
111            }
112    
113            com.kitfox.svg.batik.LinearGradientPaint paint;
114            if (gradientUnits == GU_USER_SPACE_ON_USE)
115            {
116    //            paint = new LinearGradientPaint(x1, y1, x2, y2, getStopFractions(), getStopColors(), method);
117                paint = new com.kitfox.svg.batik.LinearGradientPaint(
118                    new Point2D.Float(x1, y1),
119                    new Point2D.Float(x2, y2),
120                    getStopFractions(),
121                    getStopColors(),
122                    method,
123                    com.kitfox.svg.batik.MultipleGradientPaint.SRGB,
124                    gradientTransform);
125            }
126            else
127            {
128                AffineTransform viewXform = new AffineTransform();
129                viewXform.translate(bounds.getX(), bounds.getY());
130                
131                //This is a hack to get around shapes that have a width or height of 0.  Should be close enough to the true answer.
132                double width = bounds.getWidth();
133                double height = bounds.getHeight();
134                if (width == 0) width = 1;
135                if (height == 0) height = 1;
136                viewXform.scale(width, height);
137    
138                viewXform.concatenate(gradientTransform);
139    
140                paint = new com.kitfox.svg.batik.LinearGradientPaint(
141                    new Point2D.Float(x1, y1),
142                    new Point2D.Float(x2, y2),
143                    getStopFractions(),
144                    getStopColors(),
145                    method,
146                    com.kitfox.svg.batik.MultipleGradientPaint.SRGB,
147                    viewXform);
148            }
149    
150            return paint;
151        }
152        
153        /**
154         * Updates all attributes in this diagram associated with a time event.
155         * Ie, all attributes with track information.
156         * @return - true if this node has changed state as a result of the time
157         * update
158         */
159        public boolean updateTime(double curTime) throws SVGException
160        {
161    //        if (trackManager.getNumTracks() == 0) return stopChange;
162            boolean changeState = super.updateTime(curTime);
163    
164            //Get current values for parameters
165            StyleAttribute sty = new StyleAttribute();
166            boolean shapeChange = false;
167            
168            if (getPres(sty.setName("x1")))
169            {
170                float newVal = sty.getFloatValueWithUnits();
171                if (newVal != x1)
172                {
173                    x1 = newVal;
174                    shapeChange = true;
175                }
176            }
177    
178            if (getPres(sty.setName("y1")))
179            {
180                float newVal = sty.getFloatValueWithUnits();
181                if (newVal != y1)
182                {
183                    y1 = newVal;
184                    shapeChange = true;
185                }
186            }
187    
188            if (getPres(sty.setName("x2")))
189            {
190                float newVal = sty.getFloatValueWithUnits();
191                if (newVal != x2)
192                {
193                    x2 = newVal;
194                    shapeChange = true;
195                }
196            }
197    
198            if (getPres(sty.setName("y2")))
199            {
200                float newVal = sty.getFloatValueWithUnits();
201                if (newVal != y2)
202                {
203                    y2 = newVal;
204                    shapeChange = true;
205                }
206            }
207    
208            return changeState || shapeChange;
209        }
210    }