00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "wtf/Platform.h"
00024 #if ENABLE(SVG)
00025 #include "SVGViewSpec.h"
00026
00027 #include "PlatformString.h"
00028 #include "SVGParserUtilities.h"
00029 #include "SVGPreserveAspectRatio.h"
00030 #include "SVGSVGElement.h"
00031 #include "SVGTransformList.h"
00032 #include "SVGTransformable.h"
00033
00034 namespace WebCore {
00035
00036 SVGViewSpec::SVGViewSpec(const SVGSVGElement* contextElement)
00037 : SVGFitToViewBox()
00038 , SVGZoomAndPan()
00039 , m_transform(SVGTransformList::create(SVGNames::transformAttr))
00040 , m_contextElement(contextElement)
00041 {
00042 }
00043
00044 SVGViewSpec::~SVGViewSpec()
00045 {
00046 }
00047
00048 void SVGViewSpec::setTransform(const String& transform)
00049 {
00050 SVGTransformable::parseTransformAttribute(m_transform.get(), transform);
00051 }
00052
00053 void SVGViewSpec::setViewBoxString(const String& viewBox)
00054 {
00055 float x, y, w, h;
00056 const UChar* c = viewBox.characters();
00057 const UChar* end = c + viewBox.length();
00058 if (!parseViewBox(c, end, x, y, w, h, false))
00059 return;
00060 setViewBoxBaseValue(FloatRect(x, y, w, h));
00061 }
00062
00063 void SVGViewSpec::setPreserveAspectRatioString(const String& preserve)
00064 {
00065 const UChar* c = preserve.characters();
00066 const UChar* end = c + preserve.length();
00067 preserveAspectRatioBaseValue()->parsePreserveAspectRatio(c, end);
00068 }
00069
00070 void SVGViewSpec::setViewTargetString(const String& viewTargetString)
00071 {
00072 m_viewTargetString = viewTargetString;
00073 }
00074
00075 SVGElement* SVGViewSpec::viewTarget() const
00076 {
00077 return static_cast<SVGElement*>(m_contextElement->ownerDocument()->getElementById(m_viewTargetString));
00078 }
00079
00080 const SVGElement* SVGViewSpec::contextElement() const
00081 {
00082 return m_contextElement;
00083 }
00084
00085 static const UChar svgViewSpec[] = {'s','v','g','V', 'i', 'e', 'w'};
00086 static const UChar viewBoxSpec[] = {'v', 'i', 'e', 'w', 'B', 'o', 'x'};
00087 static const UChar preserveAspectRatioSpec[] = {'p', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'A', 's', 'p', 'e', 'c', 't', 'R', 'a', 't', 'i', 'o'};
00088 static const UChar transformSpec[] = {'t', 'r', 'a', 'n', 's', 'f', 'o', 'r', 'm'};
00089 static const UChar zoomAndPanSpec[] = {'z', 'o', 'o', 'm', 'A', 'n', 'd', 'P', 'a', 'n'};
00090 static const UChar viewTargetSpec[] = {'v', 'i', 'e', 'w', 'T', 'a', 'r', 'g', 'e', 't'};
00091
00092 bool SVGViewSpec::parseViewSpec(const String& viewSpec)
00093 {
00094 const UChar* currViewSpec = viewSpec.characters();
00095 const UChar* end = currViewSpec + viewSpec.length();
00096
00097 if (currViewSpec >= end)
00098 return false;
00099
00100 if (!skipString(currViewSpec, end, svgViewSpec, sizeof(svgViewSpec) / sizeof(UChar)))
00101 return false;
00102
00103 if (currViewSpec >= end || *currViewSpec != '(' )
00104 return false;
00105 currViewSpec++;
00106
00107 while (currViewSpec < end && *currViewSpec != ')') {
00108 if (*currViewSpec == 'v') {
00109 if (skipString(currViewSpec, end, viewBoxSpec, sizeof(viewBoxSpec) / sizeof(UChar))) {
00110 if (currViewSpec >= end || *currViewSpec != '(')
00111 return false;
00112 currViewSpec++;
00113 float x, y, w, h;
00114 if (!parseViewBox(currViewSpec, end, x, y, w, h, false))
00115 return false;
00116 setViewBoxBaseValue(FloatRect(x, y, w, h));
00117 if (currViewSpec >= end || *currViewSpec != ')')
00118 return false;
00119 currViewSpec++;
00120 } else if (skipString(currViewSpec, end, viewTargetSpec, sizeof(viewTargetSpec) / sizeof(UChar))) {
00121 if (currViewSpec >= end || *currViewSpec != '(')
00122 return false;
00123 const UChar* viewTargetStart = ++currViewSpec;
00124 while (currViewSpec < end && *currViewSpec != ')')
00125 currViewSpec++;
00126 if (currViewSpec >= end)
00127 return false;
00128 setViewTargetString(String(viewTargetStart, currViewSpec - viewTargetStart));
00129 currViewSpec++;
00130 } else
00131 return false;
00132 } else if (*currViewSpec == 'z') {
00133 if (!skipString(currViewSpec, end, zoomAndPanSpec, sizeof(zoomAndPanSpec) / sizeof(UChar)))
00134 return false;
00135 if (currViewSpec >= end || *currViewSpec != '(')
00136 return false;
00137 currViewSpec++;
00138 if (!parseZoomAndPan(currViewSpec, end))
00139 return false;
00140 if (currViewSpec >= end || *currViewSpec != ')')
00141 return false;
00142 currViewSpec++;
00143 } else if (*currViewSpec == 'p') {
00144 if (!skipString(currViewSpec, end, preserveAspectRatioSpec, sizeof(preserveAspectRatioSpec) / sizeof(UChar)))
00145 return false;
00146 if (currViewSpec >= end || *currViewSpec != '(')
00147 return false;
00148 currViewSpec++;
00149 if (!preserveAspectRatioBaseValue()->parsePreserveAspectRatio(currViewSpec, end, false))
00150 return false;
00151 if (currViewSpec >= end || *currViewSpec != ')')
00152 return false;
00153 currViewSpec++;
00154 } else if (*currViewSpec == 't') {
00155 if (!skipString(currViewSpec, end, transformSpec, sizeof(transformSpec) / sizeof(UChar)))
00156 return false;
00157 if (currViewSpec >= end || *currViewSpec != '(')
00158 return false;
00159 currViewSpec++;
00160 SVGTransformable::parseTransformAttribute(m_transform.get(), currViewSpec, end);
00161 if (currViewSpec >= end || *currViewSpec != ')')
00162 return false;
00163 currViewSpec++;
00164 } else
00165 return false;
00166
00167 if (currViewSpec < end && *currViewSpec == ';')
00168 currViewSpec++;
00169 }
00170
00171 if (currViewSpec >= end || *currViewSpec != ')')
00172 return false;
00173
00174 return true;
00175 }
00176
00177 }
00178
00179 #endif // ENABLE(SVG)