fix logic
[personal-kdelibs.git] / khtml / css / SVGCSSParser.cpp
blob5f52c532e784750cc64a79d82c81aec91be44a45
1 /*
2 Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 2004, 2005, 2007 Rob Buis <buis@kde.org>
4 Copyright (C) 2005, 2006 Apple Computer, Inc.
6 This file is part of the KDE project
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
24 #include "cssparser.h"
25 #include "cssproperties.h"
26 #include "cssvalues.h"
27 #include "Color.h"
29 /*#include "CSSInheritedValue.h"
30 #include "CSSInitialValue.h"
31 #include "CSSParser.h"
32 #include "CSSProperty.h"
33 #include "CSSPropertyNames.h"
34 #include "CSSQuirkPrimitiveValue.h"
35 #include "CSSValueKeywords.h"
36 #include "CSSValueList.h"*/
37 #include "wtf/Platform.h"
38 #include "SVGPaint.h"
40 using namespace std;
41 using WebCore::SVGPaint;
42 using WebCore::SVGColor;
43 using WebCore::Color;
45 namespace DOM
48 bool CSSParser::parseSVGValue(int propId, bool important)
50 Value* value = valueList->current();
51 if (!value)
52 return false;
54 int id = value->id;
56 bool valid_primitive = false;
57 CSSValueImpl *parsedValue = 0;
59 switch (propId) {
60 /* The comment to the right defines all valid value of these
61 * properties as defined in SVG 1.1, Appendix N. Property index */
62 /*case CSSPropertyAlignmentBaseline:
63 // auto | baseline | before-edge | text-before-edge | middle |
64 // central | after-edge | text-after-edge | ideographic | alphabetic |
65 // hanging | mathematical | inherit
66 if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle ||
67 (id >= CSSValueBeforeEdge && id <= CSSValueMathematical))
68 valid_primitive = true;
69 break;
71 case CSSPropertyBaselineShift:
72 // baseline | super | sub | <percentage> | <length> | inherit
73 if (id == CSSValueBaseline || id == CSSValueSub ||
74 id >= CSSValueSuper)
75 valid_primitive = true;
76 else
77 valid_primitive = validUnit(value, FLength|FPercent, false);
78 break;
80 case CSSPropertyDominantBaseline:
81 // auto | use-script | no-change | reset-size | ideographic |
82 // alphabetic | hanging | mathematical | central | middle |
83 // text-after-edge | text-before-edge | inherit
84 if (id == CSSValueAuto || id == CSSValueMiddle ||
85 (id >= CSSValueUseScript && id <= CSSValueResetSize) ||
86 (id >= CSSValueCentral && id <= CSSValueMathematical))
87 valid_primitive = true;
88 break;
90 case CSSPropertyEnableBackground:
91 // accumulate | new [x] [y] [width] [height] | inherit
92 if (id == CSSValueAccumulate) // TODO : new
93 valid_primitive = true;
94 break;
96 case CSSPropertyMarkerStart:
97 case CSSPropertyMarkerMid:
98 case CSSPropertyMarkerEnd:
99 case CSSPropertyMask:
100 if (id == CSSValueNone)
101 valid_primitive = true;
102 else if (value->unit == CSSPrimitiveValue::CSS_URI) {
103 parsedValue = new CSSPrimitiveValue(value->string, CSSPrimitiveValue::CSS_URI);
104 if (parsedValue)
105 valueList->next();
107 break;*/
109 case CSS_PROP_CLIP_RULE: // nonzero | evenodd | inherit
110 case CSS_PROP_FILL_RULE:
111 if (id == CSS_VAL_NONZERO || id == CSS_VAL_EVENODD)
112 valid_primitive = true;
113 break;
115 /*case CSSPropertyStrokeMiterlimit: // <miterlimit> | inherit
116 valid_primitive = validUnit(value, FNumber|FNonNeg, false);
117 break;
119 case CSSPropertyStrokeLinejoin: // miter | round | bevel | inherit
120 if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel)
121 valid_primitive = true;
122 break;
124 case CSSPropertyStrokeLinecap: // butt | round | square | inherit
125 if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare)
126 valid_primitive = true;
127 break;*/
129 case CSS_PROP_STROKE_OPACITY: // <opacity-value> | inherit
130 case CSS_PROP_FILL_OPACITY:
131 case CSS_PROP_STOP_OPACITY:
132 //case CSSPropertyFloodOpacity:
133 valid_primitive = (!id && validUnit(value, FNumber|FPercent, false));
134 break;
136 /*case CSSPropertyShapeRendering:
137 // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
138 if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
139 id == CSSValueCrispedges || id == CSSValueGeometricprecision)
140 valid_primitive = true;
141 break;
143 case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit
144 if (id == CSSValueAuto || id == CSSValueOptimizespeed || id == CSSValueOptimizelegibility ||
145 id == CSSValueGeometricprecision)
146 valid_primitive = true;
147 break;
149 case CSSPropertyImageRendering: // auto | optimizeSpeed |
150 case CSSPropertyColorRendering: // optimizeQuality | inherit
151 if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
152 id == CSSValueOptimizequality)
153 valid_primitive = true;
154 break;
156 case CSSPropertyColorProfile: // auto | sRGB | <name> | <uri> inherit
157 if (id == CSSValueAuto || id == CSSValueSrgb)
158 valid_primitive = true;
159 break;
161 case CSSPropertyColorInterpolation: // auto | sRGB | linearRGB | inherit
162 case CSSPropertyColorInterpolationFilters:
163 if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb)
164 valid_primitive = true;
165 break;*/
167 /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
168 * correctly and allows optimization in applyRule(..)
171 /*case CSSPropertyPointerEvents:
172 // none | visiblePainted | visibleFill | visibleStroke | visible |
173 // painted | fill | stroke | none | all | inherit
174 if (id == CSSValueVisible || id == CSSValueNone ||
175 (id >= CSSValueVisiblepainted && id <= CSSValueAll))
176 valid_primitive = true;
177 break;
179 case CSSPropertyTextAnchor: // start | middle | end | inherit
180 if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd)
181 valid_primitive = true;
182 break;
184 case CSSPropertyGlyphOrientationVertical: // auto | <angle> | inherit
185 if (id == CSSValueAuto) {
186 valid_primitive = true;
187 break;
189 /* fallthrough intentional */
190 /*case CSSPropertyGlyphOrientationHorizontal: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit
191 if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) {
192 parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_DEG);
194 if (parsedValue)
195 valueList->next();
197 break;*/
199 case CSS_PROP_FILL: // <paint> | inherit
200 case CSS_PROP_STROKE: // <paint> | inherit
202 if (id == CSS_VAL_NONE)
203 parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_NONE);
204 else /*if (id == CSSValueCurrentcolor)
205 parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR);
206 else */if (value->unit == CSSPrimitiveValue::CSS_URI) {
207 CSSPrimitiveValueImpl* val;
208 // khtml FIXME memory leak here
209 if (valueList->next() && (val = parseColorFromValue(valueList->current()/*, c, true*/))) {
210 parsedValue = new SVGPaint(domString(value->string), val->getRGBColorValue());
211 } else
212 parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_URI, domString(value->string));
213 } else
214 parsedValue = parseSVGPaint();
216 if (parsedValue)
217 valueList->next();
219 break;
221 /*case CSSPropertyColor: // <color> | inherit
222 if ((id >= CSSValueAqua && id <= CSSValueWindowtext) ||
223 (id >= CSSValueAliceblue && id <= CSSValueYellowgreen))
224 parsedValue = new SVGColor(value->string);
225 else
226 parsedValue = parseSVGColor();
228 if (parsedValue)
229 valueList->next();
230 break;*/
232 case CSS_PROP_STOP_COLOR: // TODO : icccolor
233 //case CSSPropertyFloodColor:
234 //case CSSPropertyLightingColor:
235 if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT)/* ||
236 (id >= CSSValueAliceblue && id <= CSSValueYellowgreen)*/)
237 parsedValue = new SVGColor(domString(value->string));
238 else /*if (id == CSSValueCurrentcolor)
239 parsedValue = new SVGColor(SVGColor::SVG_COLORTYPE_CURRENTCOLOR);
240 else*/ // TODO : svgcolor (iccColor)
241 parsedValue = parseSVGColor();
243 if (parsedValue)
244 valueList->next();
246 break;
248 /*case CSSPropertyWritingMode:
249 // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
250 if (id >= CSSValueLrTb && id <= CSSValueTb)
251 valid_primitive = true;
252 break;*/
254 case CSS_PROP_STROKE_WIDTH: // <length> | inherit
255 //case CSSPropertyStrokeDashoffset:
256 valid_primitive = validUnit(value, FLength | FPercent, false);
257 break;
258 /*case CSSPropertyStrokeDasharray: // none | <dasharray> | inherit
259 if (id == CSSValueNone)
260 valid_primitive = true;
261 else
262 parsedValue = parseSVGStrokeDasharray();
264 break;
266 case CSSPropertyKerning: // auto | normal | <length> | inherit
267 if (id == CSSValueAuto || id == CSSValueNormal)
268 valid_primitive = true;
269 else
270 valid_primitive = validUnit(value, FLength, false);
271 break;*/
273 case CSS_PROP_CLIP_PATH: // <uri> | none | inherit
274 //case CSSPropertyFilter:
275 if (id == CSS_VAL_NONE)
276 valid_primitive = true;
277 else if (value->unit == CSSPrimitiveValue::CSS_URI) {
278 parsedValue = new CSSPrimitiveValueImpl(domString(value->string), (CSSPrimitiveValue::UnitTypes) value->unit);
279 if (parsedValue)
280 valueList->next();
282 break;
284 /* shorthand properties */
285 /*case CSSPropertyMarker:
287 ShorthandScope scope(this, propId);
288 m_implicitShorthand = true;
289 if (!parseValue(CSSPropertyMarkerStart, important))
290 return false;
291 if (valueList->current()) {
292 rollbackLastProperties(1);
293 return false;
295 CSSValue *value = parsedProperties[numParsedProperties - 1]->value();
296 addProperty(CSSPropertyMarkerMid, value, important);
297 addProperty(CSSPropertyMarkerEnd, value, important);
298 m_implicitShorthand = false;
299 return true;
301 default:
302 // If you crash here, it's because you added a css property and are not handling it
303 // in either this switch statement or the one in CSSParser::parseValue
304 //ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
305 //return false;
306 break;
309 if (valid_primitive) {
310 if (id != 0)
311 parsedValue = new CSSPrimitiveValueImpl(id);
312 else if (value->unit == CSSPrimitiveValue::CSS_STRING)
313 parsedValue = new CSSPrimitiveValueImpl(domString(value->string), (CSSPrimitiveValue::UnitTypes)value->unit);
314 else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
315 parsedValue = new CSSPrimitiveValueImpl(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
316 else if (value->unit >= Value::Q_EMS)
317 parsedValue = new CSSQuirkPrimitiveValueImpl(value->fValue, CSSPrimitiveValue::CSS_EMS);
318 valueList->next();
320 if (!parsedValue || (valueList->current() && !inShorthand())) {
321 if (parsedValue)
322 delete parsedValue; // khtml: we should delete here, right?
323 return false;
326 addProperty(propId, parsedValue, important);
327 return true;
329 #if 0
330 PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray()
332 CSSValueList* ret = new CSSValueList;
333 Value* value = valueList->current();
334 bool valid_primitive = true;
335 while (value) {
336 valid_primitive = validUnit(value, FLength | FPercent |FNonNeg, false);
337 if (!valid_primitive)
338 break;
339 if (value->id != 0)
340 ret->append(new CSSPrimitiveValue(value->id));
341 else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
342 ret->append(new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
343 value = valueList->next();
344 if (value && value->unit == Value::Operator && value->iValue == ',')
345 value = valueList->next();
347 if (!valid_primitive) {
348 delete ret;
349 ret = 0;
352 return ret;
354 #endif
355 CSSValueImpl* CSSParser::parseSVGPaint()
357 CSSPrimitiveValueImpl* val;
358 if (!(val = parseColorFromValue(valueList->current()/*, c, true*/)))
359 return new SVGPaint();
360 // khtml FIXME memory leak
361 return new SVGPaint(QColor(val->getRGBColorValue()));
364 CSSValueImpl* CSSParser::parseSVGColor()
366 CSSPrimitiveValueImpl* val;
367 if (!(val = parseColorFromValue(valueList->current()/*, c, true*/)))
368 return 0;
369 // khtml FIXME memory leak
370 return new SVGColor(Color(val->getRGBColorValue()));