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}