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