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.
27 #include "CSSInheritedValue.h"
28 #include "CSSInitialValue.h"
29 #include "CSSParser.h"
30 #include "CSSProperty.h"
31 #include "CSSPropertyNames.h"
32 #include "CSSQuirkPrimitiveValue.h"
33 #include "CSSValueKeywords.h"
34 #include "CSSValueList.h"
36 #include "DeprecatedString.h"
42 bool CSSParser::parseSVGValue(int propId, bool important)
44 Value* value = valueList->current();
50 bool valid_primitive = false;
51 CSSValue* parsedValue = 0;
54 /* The comment to the right defines all valid value of these
55 * properties as defined in SVG 1.1, Appendix N. Property index */
56 case CSS_PROP_ALIGNMENT_BASELINE:
57 // auto | baseline | before-edge | text-before-edge | middle |
58 // central | after-edge | text-after-edge | ideographic | alphabetic |
59 // hanging | mathematical | inherit
60 if (id == CSS_VAL_AUTO || id == CSS_VAL_BASELINE || id == CSS_VAL_MIDDLE ||
61 (id >= CSS_VAL_BEFORE_EDGE && id <= CSS_VAL_MATHEMATICAL))
62 valid_primitive = true;
65 case CSS_PROP_BASELINE_SHIFT:
66 // baseline | super | sub | <percentage> | <length> | inherit
67 if (id == CSS_VAL_BASELINE || id == CSS_VAL_SUB ||
69 valid_primitive = true;
71 valid_primitive = validUnit(value, FLength|FPercent, false);
74 case CSS_PROP_DOMINANT_BASELINE:
75 // auto | use-script | no-change | reset-size | ideographic |
76 // alphabetic | hanging | mathematical | central | middle |
77 // text-after-edge | text-before-edge | inherit
78 if (id == CSS_VAL_AUTO || id == CSS_VAL_MIDDLE ||
79 (id >= CSS_VAL_USE_SCRIPT && id <= CSS_VAL_RESET_SIZE) ||
80 (id >= CSS_VAL_CENTRAL && id <= CSS_VAL_MATHEMATICAL))
81 valid_primitive = true;
84 case CSS_PROP_ENABLE_BACKGROUND:
85 // accumulate | new [x] [y] [width] [height] | inherit
86 if (id == CSS_VAL_ACCUMULATE) // TODO : new
87 valid_primitive = true;
90 case CSS_PROP_MARKER_START:
91 case CSS_PROP_MARKER_MID:
92 case CSS_PROP_MARKER_END:
94 if (id == CSS_VAL_NONE)
95 valid_primitive = true;
96 else if (value->unit == CSSPrimitiveValue::CSS_URI) {
97 parsedValue = new CSSPrimitiveValue(domString(value->string), CSSPrimitiveValue::CSS_URI);
103 case CSS_PROP_CLIP_RULE: // nonzero | evenodd | inherit
104 case CSS_PROP_FILL_RULE:
105 if (id == CSS_VAL_NONZERO || id == CSS_VAL_EVENODD)
106 valid_primitive = true;
109 case CSS_PROP_STROKE_MITERLIMIT: // <miterlimit> | inherit
110 valid_primitive = validUnit(value, FNumber|FNonNeg, false);
113 case CSS_PROP_STROKE_LINEJOIN: // miter | round | bevel | inherit
114 if (id == CSS_VAL_MITER || id == CSS_VAL_ROUND || id == CSS_VAL_BEVEL)
115 valid_primitive = true;
118 case CSS_PROP_STROKE_LINECAP: // butt | round | square | inherit
119 if (id == CSS_VAL_BUTT || id == CSS_VAL_ROUND || id == CSS_VAL_SQUARE)
120 valid_primitive = true;
123 case CSS_PROP_STROKE_OPACITY: // <opacity-value> | inherit
124 case CSS_PROP_FILL_OPACITY:
125 case CSS_PROP_STOP_OPACITY:
126 case CSS_PROP_FLOOD_OPACITY:
127 valid_primitive = (!id && validUnit(value, FNumber|FPercent, false));
130 case CSS_PROP_SHAPE_RENDERING:
131 // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
132 if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED ||
133 id == CSS_VAL_CRISPEDGES || id == CSS_VAL_GEOMETRICPRECISION)
134 valid_primitive = true;
137 case CSS_PROP_TEXT_RENDERING: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit
138 if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED || id == CSS_VAL_OPTIMIZELEGIBILITY ||
139 id == CSS_VAL_GEOMETRICPRECISION)
140 valid_primitive = true;
143 case CSS_PROP_IMAGE_RENDERING: // auto | optimizeSpeed |
144 case CSS_PROP_COLOR_RENDERING: // optimizeQuality | inherit
145 if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED ||
146 id == CSS_VAL_OPTIMIZEQUALITY)
147 valid_primitive = true;
150 case CSS_PROP_COLOR_PROFILE: // auto | sRGB | <name> | <uri> inherit
151 if (id == CSS_VAL_AUTO || id == CSS_VAL_SRGB)
152 valid_primitive = true;
155 case CSS_PROP_COLOR_INTERPOLATION: // auto | sRGB | linearRGB | inherit
156 case CSS_PROP_COLOR_INTERPOLATION_FILTERS:
157 if (id == CSS_VAL_AUTO || id == CSS_VAL_SRGB || id == CSS_VAL_LINEARRGB)
158 valid_primitive = true;
161 /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
162 * correctly and allows optimization in applyRule(..)
165 case CSS_PROP_POINTER_EVENTS:
166 // none | visiblePainted | visibleFill | visibleStroke | visible |
167 // painted | fill | stroke | none | all | inherit
168 if (id == CSS_VAL_VISIBLE || id == CSS_VAL_NONE ||
169 (id >= CSS_VAL_VISIBLEPAINTED && id <= CSS_VAL_ALL))
170 valid_primitive = true;
173 case CSS_PROP_TEXT_ANCHOR: // start | middle | end | inherit
174 if (id == CSS_VAL_START || id == CSS_VAL_MIDDLE || id == CSS_VAL_END)
175 valid_primitive = true;
178 case CSS_PROP_GLYPH_ORIENTATION_VERTICAL: // auto | <angle> | inherit
179 if (id == CSS_VAL_AUTO) {
180 valid_primitive = true;
183 /* fallthrough intentional */
184 case CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL: // <angle> | inherit
185 if (value->unit == CSSPrimitiveValue::CSS_DEG)
186 parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_DEG);
187 else if (value->unit == CSSPrimitiveValue::CSS_GRAD)
188 parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_GRAD);
189 else if (value->unit == CSSPrimitiveValue::CSS_RAD)
190 parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_RAD);
193 case CSS_PROP_FILL: // <paint> | inherit
194 case CSS_PROP_STROKE: // <paint> | inherit
196 if (id == CSS_VAL_NONE)
197 parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_NONE);
198 else if (id == CSS_VAL_CURRENTCOLOR)
199 parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR);
200 else if (value->unit == CSSPrimitiveValue::CSS_URI) {
201 RGBA32 c = Color::transparent;
202 if (valueList->next() && parseColorFromValue(valueList->current(), c, true)) {
203 parsedValue = new SVGPaint(domString(value->string), c);
205 parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_URI, domString(value->string));
207 parsedValue = parseSVGPaint();
214 case CSS_PROP_COLOR: // <color> | inherit
215 if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) ||
216 (id >= CSS_VAL_ALICEBLUE && id <= CSS_VAL_YELLOWGREEN))
217 parsedValue = new SVGColor(domString(value->string));
219 parsedValue = parseSVGColor();
225 case CSS_PROP_STOP_COLOR: // TODO : icccolor
226 case CSS_PROP_FLOOD_COLOR:
227 case CSS_PROP_LIGHTING_COLOR:
228 if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) ||
229 (id >= CSS_VAL_ALICEBLUE && id <= CSS_VAL_YELLOWGREEN))
230 parsedValue = new SVGColor(domString(value->string));
231 else if (id == CSS_VAL_CURRENTCOLOR)
232 parsedValue = new SVGColor(SVGColor::SVG_COLORTYPE_CURRENTCOLOR);
233 else // TODO : svgcolor (iccColor)
234 parsedValue = parseSVGColor();
241 case CSS_PROP_WRITING_MODE:
242 // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
243 if (id >= CSS_VAL_LR_TB && id <= CSS_VAL_TB)
244 valid_primitive = true;
247 case CSS_PROP_STROKE_WIDTH: // <length> | inherit
248 case CSS_PROP_STROKE_DASHOFFSET:
249 valid_primitive = validUnit(value, FLength | FPercent, false);
251 case CSS_PROP_STROKE_DASHARRAY: // none | <dasharray> | inherit
252 if (id == CSS_VAL_NONE)
253 valid_primitive = true;
255 parsedValue = parseSVGStrokeDasharray();
259 case CSS_PROP_KERNING: // auto | normal | <length> | inherit
260 if (id == CSS_VAL_AUTO || id == CSS_VAL_NORMAL)
261 valid_primitive = true;
263 valid_primitive = validUnit(value, FLength, false);
266 case CSS_PROP_CLIP_PATH: // <uri> | none | inherit
267 case CSS_PROP_FILTER:
268 if (id == CSS_VAL_NONE)
269 valid_primitive = true;
270 else if (value->unit == CSSPrimitiveValue::CSS_URI) {
271 parsedValue = new CSSPrimitiveValue(domString(value->string), (CSSPrimitiveValue::UnitTypes) value->unit);
277 /* shorthand properties */
278 case CSS_PROP_MARKER:
280 if (!parseValue(CSS_PROP_MARKER_START, important))
282 CSSValue *value = parsedProperties[numParsedProperties - 1]->value();
283 m_implicitShorthand = true;
284 addProperty(CSS_PROP_MARKER_MID, value, important);
285 addProperty(CSS_PROP_MARKER_END, value, important);
286 m_implicitShorthand = false;
290 // If you crash here, it's because you added a css property and are not handling it
291 // in either this switch statement or the one in CSSParser::parseValue
292 ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
296 if (valid_primitive) {
298 parsedValue = new CSSPrimitiveValue(id);
299 else if (value->unit == CSSPrimitiveValue::CSS_STRING)
300 parsedValue = new CSSPrimitiveValue(domString(value->string), (CSSPrimitiveValue::UnitTypes) value->unit);
301 else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
302 parsedValue = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
303 else if (value->unit >= Value::Q_EMS)
304 parsedValue = new CSSQuirkPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_EMS);
308 if (!valueList->current() || inShorthand()) {
309 addProperty(propId, parsedValue, important);
317 CSSValue* CSSParser::parseSVGStrokeDasharray()
319 CSSValueList* ret = new CSSValueList;
320 Value* value = valueList->current();
321 bool valid_primitive = true;
323 valid_primitive = validUnit(value, FLength | FPercent |FNonNeg, false);
324 if (!valid_primitive)
327 ret->append(new CSSPrimitiveValue(value->id));
328 else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
329 ret->append(new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
330 value = valueList->next();
331 if (value && value->unit == Value::Operator && value->iValue == ',')
332 value = valueList->next();
334 if (!valid_primitive) {
342 CSSValue* CSSParser::parseSVGPaint()
344 RGBA32 c = Color::transparent;
345 if (!parseColorFromValue(valueList->current(), c, true))
346 return new SVGPaint();
347 return new SVGPaint(Color(c));
350 CSSValue* CSSParser::parseSVGColor()
352 RGBA32 c = Color::transparent;
353 if (!parseColorFromValue(valueList->current(), c, true))
355 return new SVGColor(Color(c));
360 #endif // ENABLE(SVG)