Reviewed by Darin.
[WebKit-https.git] / WebCore / ksvg2 / svg / SVGFitToViewBox.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 #if SVG_SUPPORT
25 #include "DeprecatedStringList.h"
26
27 #include "Attr.h"
28 #include "StringImpl.h"
29
30 #include "SVGNames.h"
31 #include "svgpathparser.h"
32 #include "SVGRect.h"
33 #include "SVGSVGElement.h"
34 #include "SVGAnimatedRect.h"
35 #include "SVGFitToViewBox.h"
36 #include "SVGPreserveAspectRatio.h"
37 #include "SVGAnimatedPreserveAspectRatio.h"
38
39 using namespace WebCore;
40
41 SVGFitToViewBox::SVGFitToViewBox()
42 {
43 }
44
45 SVGFitToViewBox::~SVGFitToViewBox()
46 {
47 }
48
49 SVGAnimatedRect *SVGFitToViewBox::viewBox() const
50 {
51     if(!m_viewBox)
52     {
53         //const SVGStyledElement *context = dynamic_cast<const SVGStyledElement *>(this);
54         m_viewBox = new SVGAnimatedRect(0); // FIXME: 0 is a hack
55     }
56
57     return m_viewBox.get();
58 }
59
60 SVGAnimatedPreserveAspectRatio *SVGFitToViewBox::preserveAspectRatio() const
61 {
62     if(!m_preserveAspectRatio)
63     {
64         //const SVGStyledElement *context = dynamic_cast<const SVGStyledElement *>(this);
65         m_preserveAspectRatio = new SVGAnimatedPreserveAspectRatio(0); // FIXME: 0 is a hack
66     }
67
68     return m_preserveAspectRatio.get();
69 }
70
71 void SVGFitToViewBox::parseViewBox(StringImpl *str)
72 {
73     double x = 0, y = 0, w = 0, h = 0;
74     DeprecatedString viewbox = String(str).deprecatedString();
75     const char *p = viewbox.latin1();
76     const char *end = p + viewbox.length();
77     const char *c = p;
78     p = parseCoord(c, x);
79     if (p == c)
80         goto bail_out;
81     if (*p == ',')
82         p++;
83     while (*p == ' ')
84         p++;
85
86     c = p;
87     p = parseCoord(c, y);
88     if (p == c)
89         goto bail_out;
90
91     if (*p == ',')
92         p++;
93     while (*p == ' ')
94         p++;
95
96     c = p;
97     p = parseCoord(c, w);
98     if(w < 0.0 || p == c) // check that width is positive
99         goto bail_out;
100     if (*p == ',')
101         p++;
102     while (*p == ' ')
103         p++;
104
105     c = p;
106     p = parseCoord(c, h);
107     if (h < 0.0 || p == c) // check that height is positive
108         goto bail_out;
109     if (*p == ',')
110         p++;
111     while (*p == ' ')
112         p++;
113
114     if (p < end) // nothing should come after the last, fourth number
115         goto bail_out;
116
117     viewBox()->baseVal()->setX(x);
118     viewBox()->baseVal()->setY(y);
119     viewBox()->baseVal()->setWidth(w);
120     viewBox()->baseVal()->setHeight(h);
121     return;
122
123 bail_out:
124         fprintf(stderr, "WARNING: Malformed viewbox string: %s (l: %i)", viewbox.ascii(), viewbox.length());
125 }
126
127 SVGMatrix *SVGFitToViewBox::viewBoxToViewTransform(float viewWidth, float viewHeight) const
128 {
129     SVGRect *viewBoxRect = viewBox()->baseVal();
130     if(viewBoxRect->width() == 0 || viewBoxRect->height() == 0)
131         return SVGSVGElement::createSVGMatrix();
132
133     return preserveAspectRatio()->baseVal()->getCTM(viewBoxRect->x(),
134             viewBoxRect->y(), viewBoxRect->width(), viewBoxRect->height(),
135             0, 0, viewWidth, viewHeight);
136 }
137
138 bool SVGFitToViewBox::parseMappedAttribute(MappedAttribute *attr)
139 {
140     if (attr->name() == SVGNames::viewBoxAttr)
141     {
142         parseViewBox(attr->value().impl());
143         return true;
144     }
145     else if (attr->name() == SVGNames::preserveAspectRatioAttr)
146     {
147         preserveAspectRatio()->baseVal()->parsePreserveAspectRatio(attr->value().impl());
148         return true;
149     }
150
151     return false;
152 }
153
154 // vim:ts=4:noet
155 #endif // SVG_SUPPORT
156