Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "config.h"
     21 
     22 #if ENABLE(SVG)
     23 #include "SVGPathStringSource.h"
     24 
     25 #include "SVGParserUtilities.h"
     26 
     27 namespace WebCore {
     28 
     29 SVGPathStringSource::SVGPathStringSource(const String& string)
     30     : m_string(string)
     31     , m_current(string.characters())
     32     , m_end(m_current + string.length())
     33 {
     34     ASSERT(!string.isEmpty());
     35 }
     36 
     37 bool SVGPathStringSource::hasMoreData() const
     38 {
     39     return m_current < m_end;
     40 }
     41 
     42 bool SVGPathStringSource::moveToNextToken()
     43 {
     44     return skipOptionalSpaces(m_current, m_end);
     45 }
     46 
     47 bool SVGPathStringSource::parseSVGSegmentType(SVGPathSegType& pathSegType)
     48 {
     49     switch (*(m_current++)) {
     50     case 'Z':
     51     case 'z':
     52         pathSegType = PathSegClosePath;
     53         break;
     54     case 'M':
     55         pathSegType = PathSegMoveToAbs;
     56         break;
     57     case 'm':
     58         pathSegType = PathSegMoveToRel;
     59         break;
     60     case 'L':
     61         pathSegType = PathSegLineToAbs;
     62         break;
     63     case 'l':
     64         pathSegType = PathSegLineToRel;
     65         break;
     66     case 'C':
     67         pathSegType = PathSegCurveToCubicAbs;
     68         break;
     69     case 'c':
     70         pathSegType = PathSegCurveToCubicRel;
     71         break;
     72     case 'Q':
     73         pathSegType = PathSegCurveToQuadraticAbs;
     74         break;
     75     case 'q':
     76         pathSegType = PathSegCurveToQuadraticRel;
     77         break;
     78     case 'A':
     79         pathSegType = PathSegArcAbs;
     80         break;
     81     case 'a':
     82         pathSegType = PathSegArcRel;
     83         break;
     84     case 'H':
     85         pathSegType = PathSegLineToHorizontalAbs;
     86         break;
     87     case 'h':
     88         pathSegType = PathSegLineToHorizontalRel;
     89         break;
     90     case 'V':
     91         pathSegType = PathSegLineToVerticalAbs;
     92         break;
     93     case 'v':
     94         pathSegType = PathSegLineToVerticalRel;
     95         break;
     96     case 'S':
     97         pathSegType = PathSegCurveToCubicSmoothAbs;
     98         break;
     99     case 's':
    100         pathSegType = PathSegCurveToCubicSmoothRel;
    101         break;
    102     case 'T':
    103         pathSegType = PathSegCurveToQuadraticSmoothAbs;
    104         break;
    105     case 't':
    106         pathSegType = PathSegCurveToQuadraticSmoothRel;
    107         break;
    108     default:
    109         pathSegType = PathSegUnknown;
    110     }
    111     return true;
    112 }
    113 
    114 SVGPathSegType SVGPathStringSource::nextCommand(SVGPathSegType previousCommand)
    115 {
    116     // Check for remaining coordinates in the current command.
    117     if ((*m_current == '+' || *m_current == '-' || *m_current == '.' || (*m_current >= '0' && *m_current <= '9'))
    118         && previousCommand != PathSegClosePath) {
    119         if (previousCommand == PathSegMoveToAbs)
    120             return PathSegLineToAbs;
    121         if (previousCommand == PathSegMoveToRel)
    122             return PathSegLineToRel;
    123         return previousCommand;
    124     }
    125     SVGPathSegType nextCommand;
    126     parseSVGSegmentType(nextCommand);
    127     return nextCommand;
    128 }
    129 
    130 bool SVGPathStringSource::parseMoveToSegment(FloatPoint& targetPoint)
    131 {
    132     float toX;
    133     float toY;
    134     if (!parseNumber(m_current, m_end, toX) || !parseNumber(m_current, m_end, toY))
    135         return false;
    136     targetPoint = FloatPoint(toX, toY);
    137     return true;
    138 }
    139 
    140 bool SVGPathStringSource::parseLineToSegment(FloatPoint& targetPoint)
    141 {
    142     float toX;
    143     float toY;
    144     if (!parseNumber(m_current, m_end, toX) || !parseNumber(m_current, m_end, toY))
    145         return false;
    146     targetPoint = FloatPoint(toX, toY);
    147     return true;
    148 }
    149 
    150 bool SVGPathStringSource::parseLineToHorizontalSegment(float& x)
    151 {
    152     return parseNumber(m_current, m_end, x);
    153 }
    154 
    155 bool SVGPathStringSource::parseLineToVerticalSegment(float& y)
    156 {
    157     return parseNumber(m_current, m_end, y);
    158 }
    159 
    160 bool SVGPathStringSource::parseCurveToCubicSegment(FloatPoint& point1, FloatPoint& point2, FloatPoint& targetPoint)
    161 {
    162     float x1;
    163     float y1;
    164     float x2;
    165     float y2;
    166     float toX;
    167     float toY;
    168     if (!parseNumber(m_current, m_end, x1)
    169         || !parseNumber(m_current, m_end, y1)
    170         || !parseNumber(m_current, m_end, x2)
    171         || !parseNumber(m_current, m_end, y2)
    172         || !parseNumber(m_current, m_end, toX)
    173         || !parseNumber(m_current, m_end, toY))
    174         return false;
    175     point1 = FloatPoint(x1, y1);
    176     point2 = FloatPoint(x2, y2);
    177     targetPoint = FloatPoint(toX, toY);
    178     return true;
    179 }
    180 
    181 bool SVGPathStringSource::parseCurveToCubicSmoothSegment(FloatPoint& point1, FloatPoint& targetPoint)
    182 {
    183     float x1;
    184     float y1;
    185     float toX;
    186     float toY;
    187     if (!parseNumber(m_current, m_end, x1)
    188         || !parseNumber(m_current, m_end, y1)
    189         || !parseNumber(m_current, m_end, toX)
    190         || !parseNumber(m_current, m_end, toY))
    191         return false;
    192     point1 = FloatPoint(x1, y1);
    193     targetPoint = FloatPoint(toX, toY);
    194     return true;
    195 }
    196 
    197 bool SVGPathStringSource::parseCurveToQuadraticSegment(FloatPoint& point2, FloatPoint& targetPoint)
    198 {
    199     float x2;
    200     float y2;
    201     float toX;
    202     float toY;
    203     if (!parseNumber(m_current, m_end, x2)
    204         || !parseNumber(m_current, m_end, y2)
    205         || !parseNumber(m_current, m_end, toX)
    206         || !parseNumber(m_current, m_end, toY))
    207         return false;
    208     point2 = FloatPoint(x2, y2);
    209     targetPoint = FloatPoint(toX, toY);
    210     return true;
    211 }
    212 
    213 bool SVGPathStringSource::parseCurveToQuadraticSmoothSegment(FloatPoint& targetPoint)
    214 {
    215     float toX;
    216     float toY;
    217     if (!parseNumber(m_current, m_end, toX)
    218         || !parseNumber(m_current, m_end, toY))
    219         return false;
    220     targetPoint = FloatPoint(toX, toY);
    221     return true;
    222 }
    223 
    224 bool SVGPathStringSource::parseArcToSegment(float& rx, float& ry, float& angle, bool& largeArc, bool& sweep, FloatPoint& targetPoint)
    225 {
    226     float toX;
    227     float toY;
    228     if (!parseNumber(m_current, m_end, rx)
    229         || !parseNumber(m_current, m_end, ry)
    230         || !parseNumber(m_current, m_end, angle)
    231         || !parseArcFlag(m_current, m_end, largeArc)
    232         || !parseArcFlag(m_current, m_end, sweep)
    233         || !parseNumber(m_current, m_end, toX)
    234         || !parseNumber(m_current, m_end, toY))
    235         return false;
    236     targetPoint = FloatPoint(toX, toY);
    237     return true;
    238 }
    239 
    240 
    241 }
    242 
    243 #endif // ENABLE(SVG)
    244