fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / khtml / svg / SVGPreserveAspectRatio.cpp
blob554ccf9fa2fd488de885f18666ffd21235032bde
1 /*
2 Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
5 This file is part of the KDE project
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.
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.
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., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
23 #include "config.h"
24 #include "wtf/Platform.h"
26 #if ENABLE(SVG)
27 #include "SVGPreserveAspectRatio.h"
29 #include "SVGParserUtilities.h"
30 #include "SVGSVGElement.h"
32 namespace WebCore {
34 SVGPreserveAspectRatio::SVGPreserveAspectRatio()
35 : m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID)
36 , m_meetOrSlice(SVG_MEETORSLICE_MEET)
38 // FIXME: Should the two values default to UNKNOWN instead?
41 SVGPreserveAspectRatio::~SVGPreserveAspectRatio()
45 void SVGPreserveAspectRatio::setAlign(unsigned short align)
47 m_align = align;
50 unsigned short SVGPreserveAspectRatio::align() const
52 return m_align;
55 void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice)
57 m_meetOrSlice = meetOrSlice;
60 unsigned short SVGPreserveAspectRatio::meetOrSlice() const
62 return m_meetOrSlice;
65 bool SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate)
67 SVGPreserveAspectRatioType align = SVG_PRESERVEASPECTRATIO_NONE;
68 SVGMeetOrSliceType meetOrSlice = SVG_MEETORSLICE_MEET;
69 bool ret = false;
71 if (!skipOptionalSpaces(currParam, end))
72 goto bail_out;
74 if (*currParam == 'd') {
75 /*if (!skipString(currParam, end, "defer"))
76 goto bail_out;
77 // FIXME: We just ignore the "defer" here.
78 if (!skipOptionalSpaces(currParam, end))
79 goto bail_out;*/
82 if (*currParam == 'n') {
83 /*if (!skipString(currParam, end, "none"))
84 goto bail_out;*/
85 skipOptionalSpaces(currParam, end);
86 } else if (*currParam == 'x') {
87 if ((end - currParam) < 8)
88 goto bail_out;
89 if (currParam[1] != 'M' || currParam[4] != 'Y' || currParam[5] != 'M')
90 goto bail_out;
91 if (currParam[2] == 'i') {
92 if (currParam[3] == 'n') {
93 if (currParam[6] == 'i') {
94 if (currParam[7] == 'n')
95 align = SVG_PRESERVEASPECTRATIO_XMINYMIN;
96 else if (currParam[7] == 'd')
97 align = SVG_PRESERVEASPECTRATIO_XMINYMID;
98 else
99 goto bail_out;
100 } else if (currParam[6] == 'a' && currParam[7] == 'x')
101 align = SVG_PRESERVEASPECTRATIO_XMINYMAX;
102 else
103 goto bail_out;
104 } else if (currParam[3] == 'd') {
105 if (currParam[6] == 'i') {
106 if (currParam[7] == 'n')
107 align = SVG_PRESERVEASPECTRATIO_XMIDYMIN;
108 else if (currParam[7] == 'd')
109 align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
110 else
111 goto bail_out;
112 } else if (currParam[6] == 'a' && currParam[7] == 'x')
113 align = SVG_PRESERVEASPECTRATIO_XMIDYMAX;
114 else
115 goto bail_out;
116 } else
117 goto bail_out;
118 } else if (currParam[2] == 'a' && currParam[3] == 'x') {
119 if (currParam[6] == 'i') {
120 if (currParam[7] == 'n')
121 align = SVG_PRESERVEASPECTRATIO_XMAXYMIN;
122 else if (currParam[7] == 'd')
123 align = SVG_PRESERVEASPECTRATIO_XMAXYMID;
124 else
125 goto bail_out;
126 } else if (currParam[6] == 'a' && currParam[7] == 'x')
127 align = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
128 else
129 goto bail_out;
130 } else
131 goto bail_out;
132 currParam += 8;
133 skipOptionalSpaces(currParam, end);
134 } else
135 goto bail_out;
137 if (currParam < end) {
138 if (*currParam == 'm') {
139 /*if (!skipString(currParam, end, "meet"))
140 goto bail_out;
141 skipOptionalSpaces(currParam, end);*/
142 } else if (*currParam == 's') {
143 /*if (!skipString(currParam, end, "slice"))
144 goto bail_out;
145 skipOptionalSpaces(currParam, end);
146 if (align != SVG_PRESERVEASPECTRATIO_NONE)
147 meetOrSlice = SVG_MEETORSLICE_SLICE;*/
151 if (end != currParam && validate) {
152 bail_out:
153 // FIXME: Should the two values be set to UNKNOWN instead?
154 align = SVG_PRESERVEASPECTRATIO_NONE;
155 meetOrSlice = SVG_MEETORSLICE_MEET;
156 } else
157 ret = true;
159 if (m_align == align && m_meetOrSlice == meetOrSlice)
160 return ret;
162 m_align = align;
163 m_meetOrSlice = meetOrSlice;
164 return ret;
167 AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY,
168 double logicWidth, double logicHeight,
169 double /*physX*/, double /*physY*/,
170 double physWidth, double physHeight)
172 AffineTransform temp;
174 if (align() == SVG_PRESERVEASPECTRATIO_UNKNOWN)
175 return temp;
177 double vpar = logicWidth / logicHeight;
178 double svgar = physWidth / physHeight;
180 if (align() == SVG_PRESERVEASPECTRATIO_NONE) {
181 temp.scale(physWidth / logicWidth, physHeight / logicHeight);
182 temp.translate(-logicX, -logicY);
183 } else if (vpar < svgar && (meetOrSlice() == SVG_MEETORSLICE_MEET) || vpar >= svgar && (meetOrSlice() == SVG_MEETORSLICE_SLICE)) {
184 temp.scale(physHeight / logicHeight, physHeight / logicHeight);
186 if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMINYMAX)
187 temp.translate(-logicX, -logicY);
188 else if (align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMAX)
189 temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight) / 2, -logicY);
190 else
191 temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
192 } else {
193 temp.scale(physWidth / logicWidth, physWidth / logicWidth);
195 if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMAXYMIN)
196 temp.translate(-logicX, -logicY);
197 else if (align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMAXYMID)
198 temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth) / 2);
199 else
200 temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth));
203 return temp;
208 #endif // ENABLE(SVG)