001package com.hfg.svg;
002
003import com.hfg.css.CSSProperty;
004import com.hfg.css.CssUtil;
005import com.hfg.graphics.Graphics2DState;
006import com.hfg.graphics.ColorUtil;
007import com.hfg.util.StringUtil;
008import com.hfg.xml.XMLTag;
009
010import java.awt.*;
011import java.awt.geom.Ellipse2D;
012import java.awt.geom.Point2D;
013
014//------------------------------------------------------------------------------
015/**
016 * Object representation of an SVG (Scalable Vector Graphics) 'circle' tag.
017 * <div>
018 * @author J. Alex Taylor, hairyfatguy.com
019 * </div>
020 */
021//------------------------------------------------------------------------------
022// com.hfg XML/HTML Coding Library
023//
024// This library is free software; you can redistribute it and/or
025// modify it under the terms of the GNU Lesser General Public
026// License as published by the Free Software Foundation; either
027// version 2.1 of the License, or (at your option) any later version.
028//
029// This library is distributed in the hope that it will be useful,
030// but WITHOUT ANY WARRANTY; without even the implied warranty of
031// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
032// Lesser General Public License for more details.
033//
034// You should have received a copy of the GNU Lesser General Public
035// License along with this library; if not, write to the Free Software
036// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
037//
038// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
039// jataylor@hairyfatguy.com
040//------------------------------------------------------------------------------
041
042public class SvgCircle extends AbstractSvgNode implements SvgNode
043{
044
045   //##########################################################################
046   // CONSTRUCTORS
047   //##########################################################################
048
049   //---------------------------------------------------------------------------
050   public SvgCircle()
051   {
052      super(SVG.circle);
053   }
054
055   //---------------------------------------------------------------------------
056   public SvgCircle(Point2D inCenter, int inRadius)
057   {
058      super(SVG.circle);
059      setCenter(inCenter);
060      setR(inRadius);
061   }
062
063   //---------------------------------------------------------------------------
064   public SvgCircle(XMLTag inXMLTag)
065   {
066      this();
067      initFromXMLTag(inXMLTag);
068   }
069
070   //##########################################################################
071   // PUBLIC METHODS
072   //##########################################################################
073
074
075   //---------------------------------------------------------------------------
076   @Override
077   public SvgCircle setId(String inValue)
078   {
079      return (SvgCircle) super.setId(inValue);
080   }
081
082   //---------------------------------------------------------------------------
083   public SvgCircle setR(int inValue)
084   {
085      setAttribute(SvgAttr.r, inValue);
086      return this;
087   }
088
089   //---------------------------------------------------------------------------
090   public SvgCircle setR(float inValue)
091   {
092      setAttribute(SvgAttr.r, SVG.formatCoordinate(inValue));
093      return this;
094   }
095
096   //---------------------------------------------------------------------------
097   public SvgCircle setR(double inValue)
098   {
099      setAttribute(SvgAttr.r, SVG.formatCoordinate(inValue));
100      return this;
101   }
102
103   //---------------------------------------------------------------------------
104   public int getR()
105   {
106      int r = 0;
107      String stringValue = getAttributeValue(SvgAttr.r);
108      if (StringUtil.isSet(stringValue))
109      {
110         r = (int) Float.parseFloat(stringValue);
111      }
112
113      return r;
114   }
115
116   //---------------------------------------------------------------------------
117   public SvgCircle setCx(int inValue)
118   {
119      setAttribute(SvgAttr.cx, inValue);
120      return this;
121   }
122
123   //---------------------------------------------------------------------------
124   public SvgCircle setCx(float inValue)
125   {
126      setAttribute(SvgAttr.cx, SVG.formatCoordinate(inValue));
127      return this;
128   }
129
130   //---------------------------------------------------------------------------
131   public SvgCircle setCx(double inValue)
132   {
133      setAttribute(SvgAttr.cx, SVG.formatCoordinate(inValue));
134      return this;
135   }
136
137   //---------------------------------------------------------------------------
138   public SvgCircle setCy(int inValue)
139   {
140      setAttribute(SvgAttr.cy, inValue);
141      return this;
142   }
143
144   //---------------------------------------------------------------------------
145   public SvgCircle setCy(float inValue)
146   {
147      setAttribute(SvgAttr.cy, SVG.formatCoordinate(inValue));
148      return this;
149   }
150
151   //---------------------------------------------------------------------------
152   public SvgCircle setCy(double inValue)
153   {
154      setAttribute(SvgAttr.cy, SVG.formatCoordinate(inValue));
155      return this;
156   }
157
158   //---------------------------------------------------------------------------
159   public SvgCircle setCenter(Point2D inValue)
160   {
161      setCx((int) inValue.getX());
162      setCy((int) inValue.getY());
163
164      return this;
165   }
166
167   //---------------------------------------------------------------------------
168   /**
169    Specifies the upper left corner of the bounding rectangle.
170    */
171   public SvgCircle setPosition(Point2D inValue)
172   {
173      setCx((int) inValue.getX() + getR());
174      setCy((int) inValue.getY() + getR());
175      return this;
176   }
177
178   //--------------------------------------------------------------------------
179   @Override
180   public SvgCircle addStyle(String inValue)
181   {
182      return (SvgCircle) super.addStyle(inValue);
183   }
184
185   //---------------------------------------------------------------------------
186   @Override
187   public SvgCircle setStyle(String inValue)
188   {
189      return (SvgCircle) super.setStyle(inValue);
190   }
191
192   //---------------------------------------------------------------------------
193   public SvgCircle setFill(Color inColor)
194   {
195      setAttribute(SvgAttr.fill, (inColor != null ? "#" + ColorUtil.colorToHex(inColor) : SvgAttr.Value.none));
196      return this;
197   }
198
199   //---------------------------------------------------------------------------
200   public SvgCircle setOpacity(int inPctOpacity)
201   {
202      addStyle(CSSProperty.opacity + ":" + inPctOpacity / 100f);
203      return this;
204   }
205
206   //---------------------------------------------------------------------------
207   public SvgCircle setFillOpacity(int inPctOpacity)
208   {
209      setAttribute(SvgAttr.fillOpacity, inPctOpacity);
210      return this;
211   }
212
213   //---------------------------------------------------------------------------
214   public SvgCircle setStroke(Color inColor)
215   {
216      addStyle(SvgAttr.stroke + ":" + (inColor != null ? CssUtil.colorToCssValue(inColor) : SvgAttr.Value.none));
217      return this;
218   }
219
220   //---------------------------------------------------------------------------
221   public SvgCircle setStrokeWidth(int inValue)
222   {
223      setAttribute(SvgAttr.strokeWidth, inValue);
224      return this;
225   }
226
227   //---------------------------------------------------------------------------
228   @Override
229   public Rectangle getBoundsBox()
230   {
231      float cx = (getAttributeValue(SvgAttr.cx) != null ? Float.parseFloat(getAttributeValue(SvgAttr.cx)) : 0);
232      float cy = (getAttributeValue(SvgAttr.cy) != null ? Float.parseFloat(getAttributeValue(SvgAttr.cy)) : 0);
233      float radius =  (getAttributeValue(SvgAttr.r) != null ? Float.parseFloat(getAttributeValue(SvgAttr.r)) : 0);
234
235      Ellipse2D ellipse = new Ellipse2D.Float(cx - radius, cy - radius, radius * 2, radius * 2);
236      Rectangle boundsBox = ellipse.getBounds();
237      adjustBoundsForTransform(boundsBox);
238
239      return boundsBox;
240   }
241
242   //--------------------------------------------------------------------------
243   @Override
244   public void draw(Graphics2D g2)
245   {
246      // Save settings
247      Graphics2DState origState = new Graphics2DState(g2);
248
249      float cx = (getAttributeValue(SvgAttr.cx) != null ? Float.parseFloat(getAttributeValue(SvgAttr.cx)) : 0);
250      float cy = (getAttributeValue(SvgAttr.cy) != null ? Float.parseFloat(getAttributeValue(SvgAttr.cy)) : 0);
251      float radius =  (getAttributeValue(SvgAttr.r) != null ? Float.parseFloat(getAttributeValue(SvgAttr.r)) : 0);
252
253      applyTransforms(g2);
254
255      Ellipse2D ellipse = new Ellipse2D.Float(cx - radius, cy - radius, radius * 2, radius * 2);
256
257      // Fill the circle
258      Paint paint = getG2Paint();
259      if (paint != null)
260      {
261         g2.setPaint(paint);
262         g2.fill(ellipse);
263      }
264
265      // Outline the circle
266      paint = getG2StrokeColor();
267      if (paint != null)
268      {
269         Stroke stroke = getG2Stroke();
270         if (stroke != null)
271         {
272            g2.setStroke(stroke);
273         }
274
275         g2.setPaint(paint);
276         g2.draw(ellipse);
277      }
278
279      // Restore settings
280      origState.applyTo(g2);
281   }
282
283}