001package com.hfg.svg;
002
003import java.awt.Color;
004import java.awt.Composite;
005import java.awt.Graphics2D;
006import java.awt.Paint;
007import java.awt.Rectangle;
008import java.awt.Stroke;
009import java.awt.geom.Point2D;
010import java.awt.geom.Rectangle2D;
011
012import com.hfg.graphics.Graphics2DState;
013import com.hfg.graphics.ColorUtil;
014import com.hfg.util.StringUtil;
015import com.hfg.xml.XMLTag;
016import com.hfg.xml.XMLizable;
017
018//------------------------------------------------------------------------------
019/**
020 * Object representation of an SVG (Scalable Vector Graphics) rect tag.
021 *
022 * @author J. Alex Taylor, hairyfatguy.com
023 */
024//------------------------------------------------------------------------------
025// com.hfg XML/HTML Coding Library
026//
027// This library is free software; you can redistribute it and/or
028// modify it under the terms of the GNU Lesser General Public
029// License as published by the Free Software Foundation; either
030// version 2.1 of the License, or (at your option) any later version.
031//
032// This library is distributed in the hope that it will be useful,
033// but WITHOUT ANY WARRANTY; without even the implied warranty of
034// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
035// Lesser General Public License for more details.
036//
037// You should have received a copy of the GNU Lesser General Public
038// License along with this library; if not, write to the Free Software
039// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
040//
041// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
042// jataylor@hairyfatguy.com
043//------------------------------------------------------------------------------
044
045public class SvgRect extends AbstractSvgNode implements SvgNode
046{
047   //###########################################################################
048   // CONSTRUCTORS
049   //###########################################################################
050
051   //---------------------------------------------------------------------------
052   public SvgRect()
053   {
054      super(SVG.rect);
055   }
056
057   //---------------------------------------------------------------------------
058   public SvgRect(Rectangle inRect)
059   {
060      this();
061      setAttribute(SvgAttr.x, SVG.formatCoordinate(inRect.getX()));
062      setAttribute(SvgAttr.y, SVG.formatCoordinate(inRect.getY()));
063      setWidth(inRect.getWidth());
064      setHeight(inRect.getHeight());
065//      setStyle(DEFAULT_STYLE);
066   }
067
068   //---------------------------------------------------------------------------
069   public SvgRect(Rectangle2D inRect)
070   {
071      this();
072      setAttribute(SvgAttr.x, SVG.formatCoordinate(inRect.getX()));
073      setAttribute(SvgAttr.y, SVG.formatCoordinate(inRect.getY()));
074      setWidth(inRect.getWidth());
075      setHeight(inRect.getHeight());
076//      setStyle(DEFAULT_STYLE);
077   }
078
079   //---------------------------------------------------------------------------
080   public SvgRect(XMLTag inXMLTag)
081   {
082      this();
083      initFromXMLTag(inXMLTag);
084   }
085
086   //###########################################################################
087   // PUBLIC METHODS
088   //###########################################################################
089
090   //---------------------------------------------------------------------------
091   public SvgRect setFill(Color inColor)
092   {
093      setAttribute(SvgAttr.fill, (inColor != null ? "#" + ColorUtil.colorToHex(inColor) : SvgAttr.Value.none));
094      return this;
095   }
096
097   //---------------------------------------------------------------------------
098   /**
099    * Specifies a value for the opacity of this rectangle (both its fill and stroke).
100    * @param inOpacity A numeric value between 0.0 (completely transparent) and 1.0 (completely opaque).
101    * @return this object to allow for method chaining
102    */
103   public SvgRect setOpacity(float inOpacity)
104   {
105      rangeCheckOpacityValue(inOpacity);
106
107      setAttribute(SvgAttr.opacity, inOpacity);
108      return this;
109   }
110
111   //---------------------------------------------------------------------------
112   /**
113    * Specifies a value for the fill opacity of this rectangle.
114    * @param inOpacity A numeric value between 0.0 (completely transparent) and 1.0 (completely opaque).
115    * @return this object to allow for method chaining
116    */
117   public SvgRect setFillOpacity(float inOpacity)
118   {
119      rangeCheckOpacityValue(inOpacity);
120
121      setAttribute(SvgAttr.fillOpacity, inOpacity);
122      return this;
123   }
124
125   //---------------------------------------------------------------------------
126   /**
127    * Specifies a value for the stroke opacity of this rectangle.
128    * @param inOpacity A numeric value between 0.0 (completely transparent) and 1.0 (completely opaque).
129    * @return this object to allow for method chaining
130    */
131   public SvgRect setStrokeOpacity(float inOpacity)
132   {
133      rangeCheckOpacityValue(inOpacity);
134
135      setAttribute(SvgAttr.strokeOpacity, inOpacity);
136      return this;
137   }
138
139   //---------------------------------------------------------------------------
140   public SvgRect setStroke(Color inColor)
141   {
142      setAttribute(SvgAttr.stroke, inColor != null ? "#" + ColorUtil.colorToHex(inColor) : SvgAttr.Value.none);
143      return this;
144   }
145
146   //---------------------------------------------------------------------------
147   public SvgRect setStrokeWidth(int inValue)
148   {
149      setAttribute(SvgAttr.strokeWidth, inValue);
150      return this;
151   }
152
153   //--------------------------------------------------------------------------
154   @Override
155   public SvgRect addStyle(String inValue)
156   {
157      return (SvgRect) super.addStyle(inValue);
158   }
159
160   //---------------------------------------------------------------------------
161   @Override
162   public SvgRect setStyle(String inValue)
163   {
164      return (SvgRect) super.setStyle(inValue);
165   }
166
167   //---------------------------------------------------------------------------
168   @Override
169   public SvgRect setTransform(String inValue)
170   {
171      return (SvgRect) super.setTransform(inValue);
172   }
173
174   //---------------------------------------------------------------------------
175   public SvgRect setOnMouseOver(String inValue)
176   {
177      setAttribute(SvgAttr.onmouseover, inValue);
178      return this;
179   }
180
181   //---------------------------------------------------------------------------
182   public SvgRect setOnMouseOut(String inValue)
183   {
184      setAttribute(SvgAttr.onmouseout, inValue);
185      return this;
186   }
187
188   //---------------------------------------------------------------------------
189   public SvgRect setOnMouseDown(String inValue)
190   {
191      setAttribute(SvgAttr.onmousedown, inValue);
192      return this;
193   }
194
195
196   //---------------------------------------------------------------------------
197   public SvgRect setPosition(Point2D inValue)
198   {
199      setAttribute(SvgAttr.x, (int) inValue.getX());
200      setAttribute(SvgAttr.y, (int) inValue.getY());
201      return this;
202   }
203
204   //---------------------------------------------------------------------------
205   public Float getX()
206   {
207      String xAttr = getAttributeValue(SvgAttr.x);
208      return (StringUtil.isSet(xAttr) ? Float.parseFloat(xAttr) : null);
209   }
210
211   //---------------------------------------------------------------------------
212   public Float getY()
213   {
214      String yAttr = getAttributeValue(SvgAttr.y);
215      return (StringUtil.isSet(yAttr) ? Float.parseFloat(yAttr) : null);
216   }
217
218
219   //---------------------------------------------------------------------------
220   public SvgRect setRx(int inValue)
221   {
222      setAttribute(SvgAttr.rx, inValue);
223      return this;
224   }
225
226   //---------------------------------------------------------------------------
227   public Integer getRx()
228   {
229      String attr = getAttributeValue(SvgAttr.rx);
230      return (StringUtil.isSet(attr) ? (int) Float.parseFloat(attr) : null);
231   }
232
233
234   //---------------------------------------------------------------------------
235   public SvgRect setRy(int inValue)
236   {
237      setAttribute(SvgAttr.ry, inValue);
238      return this;
239   }
240
241   //---------------------------------------------------------------------------
242   public Integer getRy()
243   {
244      String attr = getAttributeValue(SvgAttr.ry);
245      return (StringUtil.isSet(attr) ? (int) Float.parseFloat(attr) : null);
246   }
247
248
249   //---------------------------------------------------------------------------
250   public SvgRect setWidth(int inValue)
251   {
252      setAttribute(SvgAttr.width, inValue);
253      return this;
254   }
255
256   //---------------------------------------------------------------------------
257   public SvgRect setWidth(float inValue)
258   {
259      setAttribute(SvgAttr.width, SVG.formatCoordinate(inValue));
260      return this;
261   }
262
263   //---------------------------------------------------------------------------
264   public SvgRect setWidth(double inValue)
265   {
266      setAttribute(SvgAttr.width, SVG.formatCoordinate(inValue));
267      return this;
268   }
269
270   //---------------------------------------------------------------------------
271   public Float getWidth()
272   {
273      String attr = getAttributeValue(SvgAttr.width);
274      return (StringUtil.isSet(attr) ? Float.parseFloat(attr) : null);
275   }
276
277
278   //---------------------------------------------------------------------------
279   public SvgRect setHeight(int inValue)
280   {
281      setAttribute(SvgAttr.height, inValue);
282      return this;
283   }
284
285   //---------------------------------------------------------------------------
286   public SvgRect setHeight(float inValue)
287   {
288      setAttribute(SvgAttr.height, SVG.formatCoordinate(inValue));
289      return this;
290   }
291
292   //---------------------------------------------------------------------------
293   public SvgRect setHeight(double inValue)
294   {
295      setAttribute(SvgAttr.height, SVG.formatCoordinate(inValue));
296      return this;
297   }
298
299   //---------------------------------------------------------------------------
300   public Float getHeight()
301   {
302      String attr = getAttributeValue(SvgAttr.height);
303      return (StringUtil.isSet(attr) ? Float.parseFloat(attr) : null);
304   }
305
306   //---------------------------------------------------------------------------
307   @Override
308   public Rectangle2D getBoundsBox()
309   {
310      float minX = (getAttributeValue(SvgAttr.x) != null ? Float.parseFloat(getAttributeValue(SvgAttr.x)) : 0);
311      float minY = (getAttributeValue(SvgAttr.y) != null ? Float.parseFloat(getAttributeValue(SvgAttr.y)) : 0);
312      float maxX = minX + (getAttributeValue(SvgAttr.width) != null ? Float.parseFloat(getAttributeValue(SvgAttr.width)) : 0);
313      float maxY = minY + (getAttributeValue(SvgAttr.height) != null ? Float.parseFloat(getAttributeValue(SvgAttr.height)) : 0);
314
315      for (XMLizable node : getSubtags())
316      {
317         if (node instanceof SvgNode)
318         {
319            Rectangle2D rect = ((SvgNode)node).getBoundsBox();
320            if (rect.getX() < minX) minX = (int) rect.getX();
321            if (rect.getY() < minY) minY = (int) rect.getY();
322            if (rect.getMaxX() > maxX) maxX = (int) rect.getMaxX();
323            if (rect.getMaxY() > maxY) maxY = (int) rect.getMaxY();
324         }
325      }
326
327      Rectangle2D boundsBox = new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY).getBounds();
328      adjustBoundsForTransform(boundsBox);
329
330      return boundsBox;
331   }
332
333   //--------------------------------------------------------------------------
334   @Override
335   public String toString()
336   {
337      return toXML();
338   }
339
340   //--------------------------------------------------------------------------
341   @Override
342   public void draw(Graphics2D g2)
343   {
344      // Save settings
345      Graphics2DState origState = new Graphics2DState(g2);
346
347      // Java2D uses int instead of float
348      int x1 = getX().intValue();
349      int y1 = getY().intValue();
350      int width = getWidth().intValue();
351      int height = getHeight().intValue();
352
353      Stroke stroke = getG2Stroke();
354      if (stroke != null) g2.setStroke(stroke);
355
356      Composite composite = getG2Composite();
357      if (composite != null)
358      {
359         g2.setComposite(composite);
360      }
361
362      applyTransforms(g2);
363
364      // Fill the rect.
365      Paint paint = getG2Paint();
366      if (paint != null)
367      {
368         g2.setPaint(paint);
369         g2.fillRect(x1, y1, width, height);
370      }
371
372      // Outline the rect.
373      paint = getG2StrokeColor();
374      if (paint != null)
375      {
376         g2.setPaint(paint);
377         g2.drawRect(x1, y1, width, height);
378      }
379
380      // Restore settings
381      origState.applyTo(g2);
382   }
383
384}