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