author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Fri, 12 Mar 2010 15:46:37 +0200 | |
branch | RCL_3 |
changeset 5 | d3bac044e0f0 |
parent 3 | 41300fa6a67c |
child 30 | 5dc02b23752f |
permissions | -rw-r--r-- |
0 | 1 |
/* |
2 |
Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
|
3 |
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> |
|
4 |
2004, 2005, 2007 Rob Buis <buis@kde.org> |
|
5 |
Copyright (C) 2005, 2006 Apple Computer, Inc. |
|
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., 51 Franklin Street, Fifth Floor, |
|
20 |
Boston, MA 02110-1301, USA. |
|
21 |
*/ |
|
22 |
||
23 |
#include "config.h" |
|
24 |
||
25 |
#if ENABLE(SVG) |
|
26 |
#include "CSSInheritedValue.h" |
|
27 |
#include "CSSInitialValue.h" |
|
28 |
#include "CSSParser.h" |
|
29 |
#include "CSSProperty.h" |
|
30 |
#include "CSSPropertyNames.h" |
|
31 |
#include "CSSQuirkPrimitiveValue.h" |
|
32 |
#include "CSSValueKeywords.h" |
|
33 |
#include "CSSValueList.h" |
|
34 |
#include "SVGPaint.h" |
|
35 |
||
36 |
using namespace std; |
|
37 |
||
38 |
namespace WebCore { |
|
39 |
||
40 |
bool CSSParser::parseSVGValue(int propId, bool important) |
|
41 |
{ |
|
42 |
CSSParserValue* value = m_valueList->current(); |
|
43 |
if (!value) |
|
44 |
return false; |
|
45 |
||
46 |
int id = value->id; |
|
47 |
||
48 |
bool valid_primitive = false; |
|
49 |
RefPtr<CSSValue> parsedValue; |
|
50 |
||
51 |
switch (propId) { |
|
52 |
/* The comment to the right defines all valid value of these |
|
53 |
* properties as defined in SVG 1.1, Appendix N. Property index */ |
|
54 |
case CSSPropertyAlignmentBaseline: |
|
55 |
// auto | baseline | before-edge | text-before-edge | middle | |
|
56 |
// central | after-edge | text-after-edge | ideographic | alphabetic | |
|
57 |
// hanging | mathematical | inherit |
|
58 |
if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle || |
|
59 |
(id >= CSSValueBeforeEdge && id <= CSSValueMathematical)) |
|
60 |
valid_primitive = true; |
|
61 |
break; |
|
62 |
||
63 |
case CSSPropertyBaselineShift: |
|
64 |
// baseline | super | sub | <percentage> | <length> | inherit |
|
65 |
if (id == CSSValueBaseline || id == CSSValueSub || |
|
66 |
id >= CSSValueSuper) |
|
67 |
valid_primitive = true; |
|
68 |
else |
|
69 |
valid_primitive = validUnit(value, FLength|FPercent, false); |
|
70 |
break; |
|
71 |
||
72 |
case CSSPropertyDominantBaseline: |
|
73 |
// auto | use-script | no-change | reset-size | ideographic | |
|
74 |
// alphabetic | hanging | mathematical | central | middle | |
|
75 |
// text-after-edge | text-before-edge | inherit |
|
76 |
if (id == CSSValueAuto || id == CSSValueMiddle || |
|
77 |
(id >= CSSValueUseScript && id <= CSSValueResetSize) || |
|
78 |
(id >= CSSValueCentral && id <= CSSValueMathematical)) |
|
79 |
valid_primitive = true; |
|
80 |
break; |
|
81 |
||
82 |
case CSSPropertyEnableBackground: |
|
83 |
// accumulate | new [x] [y] [width] [height] | inherit |
|
84 |
if (id == CSSValueAccumulate) // TODO : new |
|
85 |
valid_primitive = true; |
|
86 |
break; |
|
87 |
||
88 |
case CSSPropertyMarkerStart: |
|
89 |
case CSSPropertyMarkerMid: |
|
90 |
case CSSPropertyMarkerEnd: |
|
91 |
case CSSPropertyMask: |
|
92 |
if (id == CSSValueNone) |
|
93 |
valid_primitive = true; |
|
94 |
else if (value->unit == CSSPrimitiveValue::CSS_URI) { |
|
95 |
parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI); |
|
96 |
if (parsedValue) |
|
97 |
m_valueList->next(); |
|
98 |
} |
|
99 |
break; |
|
100 |
||
101 |
case CSSPropertyClipRule: // nonzero | evenodd | inherit |
|
102 |
case CSSPropertyFillRule: |
|
103 |
if (id == CSSValueNonzero || id == CSSValueEvenodd) |
|
104 |
valid_primitive = true; |
|
105 |
break; |
|
106 |
||
107 |
case CSSPropertyStrokeMiterlimit: // <miterlimit> | inherit |
|
108 |
valid_primitive = validUnit(value, FNumber|FNonNeg, false); |
|
109 |
break; |
|
110 |
||
111 |
case CSSPropertyStrokeLinejoin: // miter | round | bevel | inherit |
|
112 |
if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel) |
|
113 |
valid_primitive = true; |
|
114 |
break; |
|
115 |
||
116 |
case CSSPropertyStrokeLinecap: // butt | round | square | inherit |
|
117 |
if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare) |
|
118 |
valid_primitive = true; |
|
119 |
break; |
|
120 |
||
121 |
case CSSPropertyStrokeOpacity: // <opacity-value> | inherit |
|
122 |
case CSSPropertyFillOpacity: |
|
123 |
case CSSPropertyStopOpacity: |
|
124 |
case CSSPropertyFloodOpacity: |
|
125 |
valid_primitive = (!id && validUnit(value, FNumber|FPercent, false)); |
|
126 |
break; |
|
127 |
||
128 |
case CSSPropertyShapeRendering: |
|
129 |
// auto | optimizeSpeed | crispEdges | geometricPrecision | inherit |
|
130 |
if (id == CSSValueAuto || id == CSSValueOptimizespeed || |
|
131 |
id == CSSValueCrispedges || id == CSSValueGeometricprecision) |
|
132 |
valid_primitive = true; |
|
133 |
break; |
|
134 |
||
135 |
case CSSPropertyImageRendering: // auto | optimizeSpeed | |
|
136 |
case CSSPropertyColorRendering: // optimizeQuality | inherit |
|
137 |
if (id == CSSValueAuto || id == CSSValueOptimizespeed || |
|
138 |
id == CSSValueOptimizequality) |
|
139 |
valid_primitive = true; |
|
140 |
break; |
|
141 |
||
142 |
case CSSPropertyColorProfile: // auto | sRGB | <name> | <uri> inherit |
|
143 |
if (id == CSSValueAuto || id == CSSValueSrgb) |
|
144 |
valid_primitive = true; |
|
145 |
break; |
|
146 |
||
147 |
case CSSPropertyColorInterpolation: // auto | sRGB | linearRGB | inherit |
|
148 |
case CSSPropertyColorInterpolationFilters: |
|
149 |
if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb) |
|
150 |
valid_primitive = true; |
|
151 |
break; |
|
152 |
||
153 |
/* Start of supported CSS properties with validation. This is needed for parseShortHand to work |
|
154 |
* correctly and allows optimization in applyRule(..) |
|
155 |
*/ |
|
156 |
||
157 |
case CSSPropertyTextAnchor: // start | middle | end | inherit |
|
158 |
if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd) |
|
159 |
valid_primitive = true; |
|
160 |
break; |
|
161 |
||
162 |
case CSSPropertyGlyphOrientationVertical: // auto | <angle> | inherit |
|
163 |
if (id == CSSValueAuto) { |
|
164 |
valid_primitive = true; |
|
165 |
break; |
|
166 |
} |
|
167 |
/* fallthrough intentional */ |
|
168 |
case CSSPropertyGlyphOrientationHorizontal: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit |
|
169 |
if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) { |
|
170 |
parsedValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_DEG); |
|
171 |
||
172 |
if (parsedValue) |
|
173 |
m_valueList->next(); |
|
174 |
} |
|
175 |
break; |
|
176 |
||
177 |
case CSSPropertyFill: // <paint> | inherit |
|
178 |
case CSSPropertyStroke: // <paint> | inherit |
|
179 |
{ |
|
180 |
if (id == CSSValueNone) |
|
181 |
parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_NONE); |
|
182 |
else if (id == CSSValueCurrentcolor) |
|
183 |
parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR); |
|
184 |
else if (value->unit == CSSPrimitiveValue::CSS_URI) { |
|
185 |
RGBA32 c = Color::transparent; |
|
186 |
if (m_valueList->next() && parseColorFromValue(m_valueList->current(), c, true)) { |
|
187 |
parsedValue = SVGPaint::create(value->string, c); |
|
188 |
} else |
|
189 |
parsedValue = SVGPaint::create(SVGPaint::SVG_PAINTTYPE_URI, value->string); |
|
190 |
} else |
|
191 |
parsedValue = parseSVGPaint(); |
|
192 |
||
193 |
if (parsedValue) |
|
194 |
m_valueList->next(); |
|
195 |
} |
|
196 |
break; |
|
197 |
||
198 |
case CSSPropertyColor: // <color> | inherit |
|
199 |
if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || |
|
200 |
(id >= CSSValueAliceblue && id <= CSSValueYellowgreen)) |
|
201 |
parsedValue = SVGColor::create(value->string); |
|
202 |
else |
|
203 |
parsedValue = parseSVGColor(); |
|
204 |
||
205 |
if (parsedValue) |
|
206 |
m_valueList->next(); |
|
207 |
break; |
|
208 |
||
209 |
case CSSPropertyStopColor: // TODO : icccolor |
|
210 |
case CSSPropertyFloodColor: |
|
211 |
case CSSPropertyLightingColor: |
|
212 |
if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || |
|
213 |
(id >= CSSValueAliceblue && id <= CSSValueYellowgreen)) |
|
214 |
parsedValue = SVGColor::create(value->string); |
|
215 |
else if (id == CSSValueCurrentcolor) |
|
216 |
parsedValue = SVGColor::createCurrentColor(); |
|
217 |
else // TODO : svgcolor (iccColor) |
|
218 |
parsedValue = parseSVGColor(); |
|
219 |
||
220 |
if (parsedValue) |
|
221 |
m_valueList->next(); |
|
222 |
||
223 |
break; |
|
224 |
||
225 |
case CSSPropertyWritingMode: |
|
226 |
// lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit |
|
227 |
if (id >= CSSValueLrTb && id <= CSSValueTb) |
|
228 |
valid_primitive = true; |
|
229 |
break; |
|
230 |
||
231 |
case CSSPropertyStrokeWidth: // <length> | inherit |
|
232 |
case CSSPropertyStrokeDashoffset: |
|
233 |
valid_primitive = validUnit(value, FLength | FPercent, false); |
|
234 |
break; |
|
235 |
case CSSPropertyStrokeDasharray: // none | <dasharray> | inherit |
|
236 |
if (id == CSSValueNone) |
|
237 |
valid_primitive = true; |
|
238 |
else |
|
239 |
parsedValue = parseSVGStrokeDasharray(); |
|
240 |
||
241 |
break; |
|
242 |
||
243 |
case CSSPropertyKerning: // auto | normal | <length> | inherit |
|
244 |
if (id == CSSValueAuto || id == CSSValueNormal) |
|
245 |
valid_primitive = true; |
|
246 |
else |
|
247 |
valid_primitive = validUnit(value, FLength, false); |
|
248 |
break; |
|
249 |
||
250 |
case CSSPropertyClipPath: // <uri> | none | inherit |
|
251 |
case CSSPropertyFilter: |
|
252 |
if (id == CSSValueNone) |
|
253 |
valid_primitive = true; |
|
254 |
else if (value->unit == CSSPrimitiveValue::CSS_URI) { |
|
255 |
parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); |
|
256 |
if (parsedValue) |
|
257 |
m_valueList->next(); |
|
258 |
} |
|
259 |
break; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
260 |
case CSSPropertyWebkitShadow: |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
261 |
if (id == CSSValueNone) |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
262 |
valid_primitive = true; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
263 |
else |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
264 |
return parseShadow(propId, important); |
0 | 265 |
|
266 |
/* shorthand properties */ |
|
267 |
case CSSPropertyMarker: |
|
268 |
{ |
|
269 |
ShorthandScope scope(this, propId); |
|
270 |
m_implicitShorthand = true; |
|
271 |
if (!parseValue(CSSPropertyMarkerStart, important)) |
|
272 |
return false; |
|
273 |
if (m_valueList->current()) { |
|
274 |
rollbackLastProperties(1); |
|
275 |
return false; |
|
276 |
} |
|
277 |
CSSValue* value = m_parsedProperties[m_numParsedProperties - 1]->value(); |
|
278 |
addProperty(CSSPropertyMarkerMid, value, important); |
|
279 |
addProperty(CSSPropertyMarkerEnd, value, important); |
|
280 |
m_implicitShorthand = false; |
|
281 |
return true; |
|
282 |
} |
|
283 |
default: |
|
284 |
// If you crash here, it's because you added a css property and are not handling it |
|
285 |
// in either this switch statement or the one in CSSParser::parseValue |
|
286 |
ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId); |
|
287 |
return false; |
|
288 |
} |
|
289 |
||
290 |
if (valid_primitive) { |
|
291 |
if (id != 0) |
|
292 |
parsedValue = CSSPrimitiveValue::createIdentifier(id); |
|
293 |
else if (value->unit == CSSPrimitiveValue::CSS_STRING) |
|
294 |
parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); |
|
295 |
else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) |
|
296 |
parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit); |
|
297 |
else if (value->unit >= CSSParserValue::Q_EMS) |
|
298 |
parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS); |
|
299 |
m_valueList->next(); |
|
300 |
} |
|
301 |
if (!parsedValue || (m_valueList->current() && !inShorthand())) |
|
302 |
return false; |
|
303 |
||
304 |
addProperty(propId, parsedValue.release(), important); |
|
305 |
return true; |
|
306 |
} |
|
307 |
||
308 |
PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray() |
|
309 |
{ |
|
310 |
RefPtr<CSSValueList> ret = CSSValueList::createCommaSeparated(); |
|
311 |
CSSParserValue* value = m_valueList->current(); |
|
312 |
bool valid_primitive = true; |
|
313 |
while (value) { |
|
314 |
valid_primitive = validUnit(value, FLength | FPercent |FNonNeg, false); |
|
315 |
if (!valid_primitive) |
|
316 |
break; |
|
317 |
if (value->id != 0) |
|
318 |
ret->append(CSSPrimitiveValue::createIdentifier(value->id)); |
|
319 |
else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) |
|
320 |
ret->append(CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit)); |
|
321 |
value = m_valueList->next(); |
|
322 |
if (value && value->unit == CSSParserValue::Operator && value->iValue == ',') |
|
323 |
value = m_valueList->next(); |
|
324 |
} |
|
325 |
if (!valid_primitive) |
|
326 |
return 0; |
|
327 |
return ret.release(); |
|
328 |
} |
|
329 |
||
330 |
PassRefPtr<CSSValue> CSSParser::parseSVGPaint() |
|
331 |
{ |
|
332 |
RGBA32 c = Color::transparent; |
|
333 |
if (!parseColorFromValue(m_valueList->current(), c, true)) |
|
334 |
return SVGPaint::create(); |
|
335 |
return SVGPaint::create(Color(c)); |
|
336 |
} |
|
337 |
||
338 |
PassRefPtr<CSSValue> CSSParser::parseSVGColor() |
|
339 |
{ |
|
340 |
RGBA32 c = Color::transparent; |
|
341 |
if (!parseColorFromValue(m_valueList->current(), c, true)) |
|
342 |
return 0; |
|
343 |
return SVGColor::create(Color(c)); |
|
344 |
} |
|
345 |
||
346 |
} |
|
347 |
||
348 |
#endif // ENABLE(SVG) |
|
349 |
||
350 |
// vim:ts=4:noet |