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