Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2007, 2010 Rob Buis <buis (at) kde.org>
      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 "SVGViewSpec.h"
     24 
     25 #include "Document.h"
     26 #include "SVGNames.h"
     27 #include "SVGParserUtilities.h"
     28 #include "SVGSVGElement.h"
     29 #include "SVGTransformable.h"
     30 
     31 namespace WebCore {
     32 
     33 // Animated property definitions
     34 DEFINE_ANIMATED_RECT(SVGViewSpec, SVGNames::viewBoxAttr, ViewBox, viewBox)
     35 DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGViewSpec, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
     36 
     37 SVGViewSpec::SVGViewSpec(SVGElement* contextElement)
     38     : m_contextElement(contextElement)
     39 {
     40 }
     41 
     42 void SVGViewSpec::setTransform(const String& transform)
     43 {
     44     SVGTransformable::parseTransformAttribute(m_transform, transform);
     45 }
     46 
     47 void SVGViewSpec::setViewBoxString(const String& viewBoxStr)
     48 {
     49     FloatRect viewBox;
     50     const UChar* c = viewBoxStr.characters();
     51     const UChar* end = c + viewBoxStr.length();
     52     if (!parseViewBox(m_contextElement->document(), c, end, viewBox, false))
     53          return;
     54     setViewBoxBaseValue(viewBox);
     55 }
     56 
     57 void SVGViewSpec::setPreserveAspectRatioString(const String& preserve)
     58 {
     59     SVGPreserveAspectRatio::parsePreserveAspectRatio(this, preserve);
     60 }
     61 
     62 void SVGViewSpec::setViewTargetString(const String& viewTargetString)
     63 {
     64     m_viewTargetString = viewTargetString;
     65 }
     66 
     67 SVGElement* SVGViewSpec::viewTarget() const
     68 {
     69     return static_cast<SVGElement*>(m_contextElement->document()->getElementById(m_viewTargetString));
     70 }
     71 
     72 static const UChar svgViewSpec[] = {'s', 'v', 'g', 'V', 'i', 'e', 'w'};
     73 static const UChar viewBoxSpec[] = {'v', 'i', 'e', 'w', 'B', 'o', 'x'};
     74 static const UChar preserveAspectRatioSpec[] = {'p', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'A', 's', 'p', 'e', 'c', 't', 'R', 'a', 't', 'i', 'o'};
     75 static const UChar transformSpec[] = {'t', 'r', 'a', 'n', 's', 'f', 'o', 'r', 'm'};
     76 static const UChar zoomAndPanSpec[] = {'z', 'o', 'o', 'm', 'A', 'n', 'd', 'P', 'a', 'n'};
     77 static const UChar viewTargetSpec[] =  {'v', 'i', 'e', 'w', 'T', 'a', 'r', 'g', 'e', 't'};
     78 
     79 bool SVGViewSpec::parseViewSpec(const String& viewSpec)
     80 {
     81     const UChar* currViewSpec = viewSpec.characters();
     82     const UChar* end = currViewSpec + viewSpec.length();
     83 
     84     if (currViewSpec >= end)
     85         return false;
     86 
     87     if (!skipString(currViewSpec, end, svgViewSpec, WTF_ARRAY_LENGTH(svgViewSpec)))
     88         return false;
     89 
     90     if (currViewSpec >= end || *currViewSpec != '(')
     91         return false;
     92     currViewSpec++;
     93 
     94     while (currViewSpec < end && *currViewSpec != ')') {
     95         if (*currViewSpec == 'v') {
     96             if (skipString(currViewSpec, end, viewBoxSpec, WTF_ARRAY_LENGTH(viewBoxSpec))) {
     97                 if (currViewSpec >= end || *currViewSpec != '(')
     98                     return false;
     99                 currViewSpec++;
    100                 FloatRect viewBox;
    101                 if (!parseViewBox(m_contextElement->document(), currViewSpec, end, viewBox, false))
    102                     return false;
    103                 setViewBoxBaseValue(viewBox);
    104                 if (currViewSpec >= end || *currViewSpec != ')')
    105                     return false;
    106                 currViewSpec++;
    107             } else if (skipString(currViewSpec, end, viewTargetSpec, WTF_ARRAY_LENGTH(viewTargetSpec))) {
    108                 if (currViewSpec >= end || *currViewSpec != '(')
    109                     return false;
    110                 const UChar* viewTargetStart = ++currViewSpec;
    111                 while (currViewSpec < end && *currViewSpec != ')')
    112                     currViewSpec++;
    113                 if (currViewSpec >= end)
    114                     return false;
    115                 setViewTargetString(String(viewTargetStart, currViewSpec - viewTargetStart));
    116                 currViewSpec++;
    117             } else
    118                 return false;
    119         } else if (*currViewSpec == 'z') {
    120             if (!skipString(currViewSpec, end, zoomAndPanSpec, WTF_ARRAY_LENGTH(zoomAndPanSpec)))
    121                 return false;
    122             if (currViewSpec >= end || *currViewSpec != '(')
    123                 return false;
    124             currViewSpec++;
    125             if (!parseZoomAndPan(currViewSpec, end))
    126                 return false;
    127             if (currViewSpec >= end || *currViewSpec != ')')
    128                 return false;
    129             currViewSpec++;
    130         } else if (*currViewSpec == 'p') {
    131             if (!skipString(currViewSpec, end, preserveAspectRatioSpec, WTF_ARRAY_LENGTH(preserveAspectRatioSpec)))
    132                 return false;
    133             if (currViewSpec >= end || *currViewSpec != '(')
    134                 return false;
    135             currViewSpec++;
    136             bool result = false;
    137             setPreserveAspectRatioBaseValue(SVGPreserveAspectRatio::parsePreserveAspectRatio(currViewSpec, end, false, result));
    138             if (!result)
    139                 return false;
    140             if (currViewSpec >= end || *currViewSpec != ')')
    141                 return false;
    142             currViewSpec++;
    143         } else if (*currViewSpec == 't') {
    144             if (!skipString(currViewSpec, end, transformSpec, WTF_ARRAY_LENGTH(transformSpec)))
    145                 return false;
    146             if (currViewSpec >= end || *currViewSpec != '(')
    147                 return false;
    148             currViewSpec++;
    149             SVGTransformable::parseTransformAttribute(m_transform, currViewSpec, end, SVGTransformable::DoNotClearList);
    150             if (currViewSpec >= end || *currViewSpec != ')')
    151                 return false;
    152             currViewSpec++;
    153         } else
    154             return false;
    155 
    156         if (currViewSpec < end && *currViewSpec == ';')
    157             currViewSpec++;
    158     }
    159 
    160     if (currViewSpec >= end || *currViewSpec != ')')
    161         return false;
    162 
    163     return true;
    164 }
    165 
    166 }
    167 
    168 #endif // ENABLE(SVG)
    169