001package com.hfg.svg;
002
003import com.hfg.graphics.Graphics2DState;
004import com.hfg.graphics.ColorUtil;
005import com.hfg.util.StringBuilderPlus;
006import com.hfg.util.StringUtil;
007import com.hfg.util.collection.CollectionUtil;
008import com.hfg.xml.XMLTag;
009
010import java.awt.*;
011import java.awt.geom.Point2D;
012import java.util.ArrayList;
013import java.util.List;
014
015//------------------------------------------------------------------------------
016/**
017 * Object representation of an SVG (Scalable Vector Graphics) polyline tag.
018 *
019 * @author J. Alex Taylor, hairyfatguy.com
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 SvgPolyline extends AbstractSvgNode implements SvgNode
043{
044   //###########################################################################
045   // CONSTRUCTORS
046   //###########################################################################
047
048   //---------------------------------------------------------------------------
049   public SvgPolyline()
050   {
051      super(SVG.polyline);
052   }
053
054   //---------------------------------------------------------------------------
055   public SvgPolyline(List<? extends Point2D> inPoints)
056   {
057      this();
058      setPoints(inPoints);
059   }
060
061   //---------------------------------------------------------------------------
062   public SvgPolyline(XMLTag inXMLTag)
063   {
064      this();
065      initFromXMLTag(inXMLTag);
066   }
067
068
069   //###########################################################################
070   // PUBLIC METHODS
071   //###########################################################################
072
073   //---------------------------------------------------------------------------
074   public SvgPolyline setFill(Color inColor)
075   {
076      setAttribute(SvgAttr.fill, (inColor != null ? "#" + ColorUtil.colorToHex(inColor) : SvgAttr.Value.none));
077      return this;
078   }
079
080   //---------------------------------------------------------------------------
081   public SvgPolyline setOpacity(int inPctOpacity)
082   {
083      setAttribute(SvgAttr.opacity, inPctOpacity);
084      return this;
085   }
086
087   //---------------------------------------------------------------------------
088   public SvgPolyline setFillOpacity(int inPctOpacity)
089   {
090      setAttribute(SvgAttr.fillOpacity, inPctOpacity);
091      return this;
092   }
093
094   //---------------------------------------------------------------------------
095   public SvgPolyline setStroke(Color inColor)
096   {
097      setAttribute(SvgAttr.stroke, inColor != null ? "#" + ColorUtil.colorToHex(inColor) : SvgAttr.Value.none);
098      return this;
099   }
100
101   //---------------------------------------------------------------------------
102   public SvgPolyline setStrokeWidth(int inValue)
103   {
104      setAttribute(SvgAttr.strokeWidth, inValue);
105      return this;
106   }
107
108   //--------------------------------------------------------------------------
109   @Override
110   public SvgPolyline addStyle(String inValue)
111   {
112      return (SvgPolyline) super.addStyle(inValue);
113   }
114
115   //---------------------------------------------------------------------------
116   @Override
117   public SvgPolyline setStyle(String inValue)
118   {
119      return (SvgPolyline) super.setStyle(inValue);
120   }
121
122   //---------------------------------------------------------------------------
123   @Override
124   public SvgPolyline setTransform(String inValue)
125   {
126      return (SvgPolyline) super.setTransform(inValue);
127   }
128
129
130
131   //---------------------------------------------------------------------------
132   public SvgPolyline setPoints(List<? extends Point2D> inPoints)
133   {
134      StringBuilderPlus points = new StringBuilderPlus().setDelimiter(" ");
135      if (CollectionUtil.hasValues(inPoints))
136      {
137         for (Point2D point : inPoints)
138         {
139            points.delimitedAppend((int) point.getX() + "," + (int) point.getY());
140         }
141      }
142
143      return setPoints(points.toString());
144   }
145
146   //---------------------------------------------------------------------------
147   public SvgPolyline setPoints(String inValue)
148   {
149      setAttribute(SvgAttr.points, inValue);
150      return this;
151   }
152
153   //---------------------------------------------------------------------------
154   public String getPoints()
155   {
156      return getAttributeValue(SvgAttr.points);
157   }
158
159   //---------------------------------------------------------------------------
160   public List<Point2D.Float> getPointList()
161   {
162      List<Point2D.Float> points = null;
163      String pointsString = getPoints();
164      if (StringUtil.isSet(pointsString))
165      {
166         String[] pieces = pointsString.trim().split("[\\s,]+");
167         if (pieces.length%2 != 0)
168         {
169            throw new RuntimeException("Odd number of numbers in the polyline's points attribute!");
170         }
171
172         points = new ArrayList<>();
173         int index = 0;
174         while (index < pieces.length)
175         {
176            points.add(new Point2D.Float(Float.parseFloat(pieces[index++]), Float.parseFloat(pieces[index++])));
177         }
178      }
179
180      return points;
181   }
182
183   //--------------------------------------------------------------------------
184   @Override
185   public String toString()
186   {
187      return toXML();
188   }
189
190   //---------------------------------------------------------------------------
191   @Override
192   public Rectangle getBoundsBox()
193   {
194      Rectangle boundsBox = generatePolygon().getBounds();
195      adjustBoundsForTransform(boundsBox);
196
197      return boundsBox;
198   }
199
200   //--------------------------------------------------------------------------
201   @Override
202   public void draw(Graphics2D g2)
203   {
204      // Save settings
205      Graphics2DState origState = new Graphics2DState(g2);
206
207      applyTransforms(g2);
208
209      Polygon polygon = generatePolygon();
210
211      // Fill the polygon
212      Paint paint = getG2Paint();
213      if (paint != null)
214      {
215         g2.setPaint(paint);
216         g2.fill(polygon);
217      }
218
219      // Outline the polygon
220      paint = getG2StrokeColor();
221      if (paint != null)
222      {
223         g2.setPaint(paint);
224
225         Stroke stroke = getG2Stroke();
226         if (stroke != null)
227         {
228            g2.setStroke(stroke);
229         }
230
231         g2.draw(polygon);
232      }
233
234      // Restore settings
235      origState.applyTo(g2);
236   }
237
238   //--------------------------------------------------------------------------
239   private Polygon generatePolygon()
240   {
241      Polygon polygon = new Polygon();
242
243      List<Point2D.Float> pointList = getPointList();
244      if (CollectionUtil.hasValues(pointList))
245      {
246         for (Point2D.Float point : pointList)
247         {
248            polygon.addPoint((int) point.getX(), (int) point.getY());
249         }
250      }
251
252      return polygon;
253   }
254}