001package com.hfg.svg.path; 002 003import java.awt.geom.GeneralPath; 004import java.awt.geom.Path2D; 005import java.awt.geom.Point2D; 006import java.util.List; 007 008//------------------------------------------------------------------------------ 009/** 010 * Object representation of an SVG (Scalable Vector Graphics) path curveTo ('C' or 'c') command. 011 * 012 * @author J. Alex Taylor, hairyfatguy.com 013 */ 014//------------------------------------------------------------------------------ 015// com.hfg XML/HTML Coding Library 016// 017// This library is free software; you can redistribute it and/or 018// modify it under the terms of the GNU Lesser General Public 019// License as published by the Free Software Foundation; either 020// version 2.1 of the License, or (at your option) any later version. 021// 022// This library is distributed in the hope that it will be useful, 023// but WITHOUT ANY WARRANTY; without even the implied warranty of 024// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 025// Lesser General Public License for more details. 026// 027// You should have received a copy of the GNU Lesser General Public 028// License along with this library; if not, write to the Free Software 029// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 030// 031// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 032// jataylor@hairyfatguy.com 033//------------------------------------------------------------------------------ 034 035public class SvgPathCurveToCmd extends SvgPathCmd 036{ 037 private Point2D.Float mSecondControlPoint; 038 039 //--------------------------------------------------------------------------- 040 public SvgPathCurveToCmd() 041 { 042 super('C'); 043 } 044 045 //--------------------------------------------------------------------------- 046 protected SvgPathCurveToCmd(char inCmdChar) 047 { 048 super(inCmdChar); 049 } 050 051 052 //--------------------------------------------------------------------------- 053 @Override 054 public SvgPathCurveToCmd setRawNumbers(List<Float> inValue) 055 { 056 if (inValue.size()%6 != 0) 057 { 058 throw new SvgPathDataException("6 numbers per command must be given to a curveTo path command!"); 059 } 060 061 setNumSteps(inValue.size()/6); 062 063 super.setRawNumbers(inValue); 064 return this; 065 } 066 067 068 //-------------------------------------------------------------------------- 069 public Point2D.Float getSecondControlPoint() 070 { 071 return mSecondControlPoint; 072 } 073 074 //-------------------------------------------------------------------------- 075 protected void setSecondControlPoint(Point2D.Float inValue) 076 { 077 mSecondControlPoint = inValue; 078 } 079 080 //-------------------------------------------------------------------------- 081 // From http://www.w3.org/TR/SVG/paths.html 082 // 083 // Draws a cubic Bézier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of 084 // the curve and (x2,y2) as the control point at the end of the curve. C (uppercase) indicates that absolute coordinates 085 // will follow; c (lowercase) indicates that relative coordinates will follow. Multiple sets of coordinates may be 086 // specified to draw a polybézier. At the end of the command, the new current point becomes the final (x,y) coordinate 087 // pair used in the polybézier. 088 public Point2D.Float draw(Path2D.Float inPolyline) 089 { 090 List<Float> rawNumbers = getRawNumbers(); 091 int numIndex = 0; 092 093 Point2D.Float currentPoint = getStartingPoint(); 094 095 while (numIndex < rawNumbers.size() - 1) 096 { 097 Point2D.Float point1 = new Point2D.Float(rawNumbers.get(numIndex++), rawNumbers.get(numIndex++)); 098 Point2D.Float point2 = new Point2D.Float(rawNumbers.get(numIndex++), rawNumbers.get(numIndex++)); 099 Point2D.Float point3 = new Point2D.Float(rawNumbers.get(numIndex++), rawNumbers.get(numIndex++)); 100 101 if (isRelative()) 102 { 103 point1.setLocation(point1.getX() + currentPoint.getX(), point1.getY() + currentPoint.getY()); 104 point2.setLocation(point2.getX() + currentPoint.getX(), point2.getY() + currentPoint.getY()); 105 point3.setLocation(point3.getX() + currentPoint.getX(), point3.getY() + currentPoint.getY()); 106 } 107 108 inPolyline.curveTo(point1.getX(), point1.getY(), point2.getX(), point2.getY(), point3.getX(), point3.getY()); 109 110 setSecondControlPoint(point2); 111 112 currentPoint = point3; 113 } 114 115 // Return the last point. 116 return currentPoint; 117 } 118}