Reviewed by Adele.
[WebKit-https.git] / WebCore / ksvg2 / svg / SVGTransformable.cpp
1 /*
2     Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
3                   2004, 2005 Rob Buis <buis@kde.org>
4
5     This file is part of the KDE project
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20     Boston, MA 02111-1307, USA.
21 */
22
23 #include "config.h"
24 #ifdef SVG_SUPPORT
25 #include "RegularExpression.h"
26 #include "DeprecatedStringList.h"
27 #include <wtf/RefPtr.h>
28
29 #include "Attr.h"
30
31 #include <kcanvas/RenderPath.h>
32
33 #include "SVGNames.h"
34 #include "SVGHelper.h"
35 #include "SVGMatrix.h"
36 #include "SVGTransformable.h"
37 #include "SVGStyledElement.h"
38 #include "SVGAnimatedTransformList.h"
39 #include "ksvg.h"
40
41 using namespace WebCore;
42
43 SVGTransformable::SVGTransformable() : SVGLocatable()
44 {
45 }
46
47 SVGTransformable::~SVGTransformable()
48 {
49 }
50
51 void SVGTransformable::parseTransformAttribute(SVGTransformList *list, const AtomicString& transform)
52 {
53     // Split string for handling 1 transform statement at a time
54     DeprecatedStringList subtransforms = DeprecatedStringList::split(')', transform.deprecatedString().simplifyWhiteSpace());
55     DeprecatedStringList::ConstIterator it = subtransforms.begin();
56     DeprecatedStringList::ConstIterator end = subtransforms.end();
57     for (; it != end; ++it) {
58         DeprecatedStringList subtransform = DeprecatedStringList::split('(', (*it));
59         
60         if (subtransform.count() < 2)
61             break; // invalid transform, ignore.
62
63         subtransform[0] = subtransform[0].stripWhiteSpace().lower();
64         subtransform[1] = subtransform[1].simplifyWhiteSpace();
65         RegularExpression reg("([-]?\\d*\\.?\\d+(?:e[-]?\\d+)?)");
66
67         int pos = 0;
68         DeprecatedStringList params;
69         
70         while (pos >= 0) {
71             pos = reg.search(subtransform[1], pos);
72             if (pos != -1) {
73                 params += reg.cap(1);
74                 pos += reg.matchedLength();
75             }
76         }
77         
78         if (params.count() < 1)
79             break;
80
81         if (subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
82             subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
83
84         RefPtr<SVGTransform> t(new SVGTransform());
85
86         if (subtransform[0] == "rotate") {
87             if (params.count() == 3)
88                 t->setRotate(params[0].toDouble(),
89                              params[1].toDouble(),
90                               params[2].toDouble());
91             else if (params.count() == 1)
92                 t->setRotate(params[0].toDouble(), 0, 0);
93         } else if (subtransform[0] == "translate") {
94             if (params.count() == 2)
95                 t->setTranslate(params[0].toDouble(), params[1].toDouble());
96             else if (params.count() == 1) // Spec: if only one param given, assume 2nd param to be 0
97                 t->setTranslate(params[0].toDouble(), 0);
98         } else if (subtransform[0] == "scale") {
99             if (params.count() == 2)
100                 t->setScale(params[0].toDouble(), params[1].toDouble());
101             else if (params.count() == 1) // Spec: if only one param given, assume uniform scaling
102                 t->setScale(params[0].toDouble(), params[0].toDouble());
103         } else if (subtransform[0] == "skewx" && (params.count() == 1))
104             t->setSkewX(params[0].toDouble());
105         else if (subtransform[0] == "skewy" && (params.count() == 1))
106             t->setSkewY(params[0].toDouble());
107         else if (subtransform[0] == "matrix" && (params.count() == 6)) {
108             SVGMatrix *ret = new SVGMatrix(params[0].toDouble(),
109                                                    params[1].toDouble(),
110                                                    params[2].toDouble(),
111                                                    params[3].toDouble(),
112                                                    params[4].toDouble(),
113                                                    params[5].toDouble());
114             t->setMatrix(ret);
115         }
116         
117         if (t->type() == SVG_TRANSFORM_UNKNOWN)
118             break; // failed to parse a valid transform, abort.
119         
120         list->appendItem(t.release().release());
121     }
122 }
123
124 // vim:ts=4:noet
125 #endif // SVG_SUPPORT
126