summaryrefslogtreecommitdiffstats
path: root/WebCore/css/SVGCSSParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/css/SVGCSSParser.cpp')
-rw-r--r--WebCore/css/SVGCSSParser.cpp358
1 files changed, 358 insertions, 0 deletions
diff --git a/WebCore/css/SVGCSSParser.cpp b/WebCore/css/SVGCSSParser.cpp
new file mode 100644
index 0000000..4aca97d
--- /dev/null
+++ b/WebCore/css/SVGCSSParser.cpp
@@ -0,0 +1,358 @@
+/*
+ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ 2004, 2005, 2007 Rob Buis <buis@kde.org>
+ Copyright (C) 2005, 2006 Apple Computer, Inc.
+
+ This file is part of the KDE project
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "CSSInheritedValue.h"
+#include "CSSInitialValue.h"
+#include "CSSParser.h"
+#include "CSSProperty.h"
+#include "CSSPropertyNames.h"
+#include "CSSQuirkPrimitiveValue.h"
+#include "CSSValueKeywords.h"
+#include "CSSValueList.h"
+#include "SVGPaint.h"
+
+using namespace std;
+
+namespace WebCore {
+
+bool CSSParser::parseSVGValue(int propId, bool important)
+{
+ Value* value = valueList->current();
+ if (!value)
+ return false;
+
+ int id = value->id;
+
+ bool valid_primitive = false;
+ RefPtr<CSSValue> parsedValue;
+
+ switch (propId) {
+ /* The comment to the right defines all valid value of these
+ * properties as defined in SVG 1.1, Appendix N. Property index */
+ case CSS_PROP_ALIGNMENT_BASELINE:
+ // auto | baseline | before-edge | text-before-edge | middle |
+ // central | after-edge | text-after-edge | ideographic | alphabetic |
+ // hanging | mathematical | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_BASELINE || id == CSS_VAL_MIDDLE ||
+ (id >= CSS_VAL_BEFORE_EDGE && id <= CSS_VAL_MATHEMATICAL))
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_BASELINE_SHIFT:
+ // baseline | super | sub | <percentage> | <length> | inherit
+ if (id == CSS_VAL_BASELINE || id == CSS_VAL_SUB ||
+ id >= CSS_VAL_SUPER)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FLength|FPercent, false);
+ break;
+
+ case CSS_PROP_DOMINANT_BASELINE:
+ // auto | use-script | no-change | reset-size | ideographic |
+ // alphabetic | hanging | mathematical | central | middle |
+ // text-after-edge | text-before-edge | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_MIDDLE ||
+ (id >= CSS_VAL_USE_SCRIPT && id <= CSS_VAL_RESET_SIZE) ||
+ (id >= CSS_VAL_CENTRAL && id <= CSS_VAL_MATHEMATICAL))
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_ENABLE_BACKGROUND:
+ // accumulate | new [x] [y] [width] [height] | inherit
+ if (id == CSS_VAL_ACCUMULATE) // TODO : new
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_MARKER_START:
+ case CSS_PROP_MARKER_MID:
+ case CSS_PROP_MARKER_END:
+ case CSS_PROP_MASK:
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ parsedValue = new CSSPrimitiveValue(value->string, CSSPrimitiveValue::CSS_URI);
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ case CSS_PROP_CLIP_RULE: // nonzero | evenodd | inherit
+ case CSS_PROP_FILL_RULE:
+ if (id == CSS_VAL_NONZERO || id == CSS_VAL_EVENODD)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_STROKE_MITERLIMIT: // <miterlimit> | inherit
+ valid_primitive = validUnit(value, FNumber|FNonNeg, false);
+ break;
+
+ case CSS_PROP_STROKE_LINEJOIN: // miter | round | bevel | inherit
+ if (id == CSS_VAL_MITER || id == CSS_VAL_ROUND || id == CSS_VAL_BEVEL)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_STROKE_LINECAP: // butt | round | square | inherit
+ if (id == CSS_VAL_BUTT || id == CSS_VAL_ROUND || id == CSS_VAL_SQUARE)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_STROKE_OPACITY: // <opacity-value> | inherit
+ case CSS_PROP_FILL_OPACITY:
+ case CSS_PROP_STOP_OPACITY:
+ case CSS_PROP_FLOOD_OPACITY:
+ valid_primitive = (!id && validUnit(value, FNumber|FPercent, false));
+ break;
+
+ case CSS_PROP_SHAPE_RENDERING:
+ // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED ||
+ id == CSS_VAL_CRISPEDGES || id == CSS_VAL_GEOMETRICPRECISION)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_TEXT_RENDERING: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED || id == CSS_VAL_OPTIMIZELEGIBILITY ||
+ id == CSS_VAL_GEOMETRICPRECISION)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_IMAGE_RENDERING: // auto | optimizeSpeed |
+ case CSS_PROP_COLOR_RENDERING: // optimizeQuality | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED ||
+ id == CSS_VAL_OPTIMIZEQUALITY)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_COLOR_PROFILE: // auto | sRGB | <name> | <uri> inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_SRGB)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_COLOR_INTERPOLATION: // auto | sRGB | linearRGB | inherit
+ case CSS_PROP_COLOR_INTERPOLATION_FILTERS:
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_SRGB || id == CSS_VAL_LINEARRGB)
+ valid_primitive = true;
+ break;
+
+ /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
+ * correctly and allows optimization in applyRule(..)
+ */
+
+ case CSS_PROP_POINTER_EVENTS:
+ // none | visiblePainted | visibleFill | visibleStroke | visible |
+ // painted | fill | stroke | none | all | inherit
+ if (id == CSS_VAL_VISIBLE || id == CSS_VAL_NONE ||
+ (id >= CSS_VAL_VISIBLEPAINTED && id <= CSS_VAL_ALL))
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_TEXT_ANCHOR: // start | middle | end | inherit
+ if (id == CSS_VAL_START || id == CSS_VAL_MIDDLE || id == CSS_VAL_END)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_GLYPH_ORIENTATION_VERTICAL: // auto | <angle> | inherit
+ if (id == CSS_VAL_AUTO) {
+ valid_primitive = true;
+ break;
+ }
+ /* fallthrough intentional */
+ case CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit
+ if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+ parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_DEG);
+
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ case CSS_PROP_FILL: // <paint> | inherit
+ case CSS_PROP_STROKE: // <paint> | inherit
+ {
+ if (id == CSS_VAL_NONE)
+ parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_NONE);
+ else if (id == CSS_VAL_CURRENTCOLOR)
+ parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR);
+ else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ RGBA32 c = Color::transparent;
+ if (valueList->next() && parseColorFromValue(valueList->current(), c, true)) {
+ parsedValue = new SVGPaint(value->string, c);
+ } else
+ parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_URI, value->string);
+ } else
+ parsedValue = parseSVGPaint();
+
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ case CSS_PROP_COLOR: // <color> | inherit
+ if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) ||
+ (id >= CSS_VAL_ALICEBLUE && id <= CSS_VAL_YELLOWGREEN))
+ parsedValue = new SVGColor(value->string);
+ else
+ parsedValue = parseSVGColor();
+
+ if (parsedValue)
+ valueList->next();
+ break;
+
+ case CSS_PROP_STOP_COLOR: // TODO : icccolor
+ case CSS_PROP_FLOOD_COLOR:
+ case CSS_PROP_LIGHTING_COLOR:
+ if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) ||
+ (id >= CSS_VAL_ALICEBLUE && id <= CSS_VAL_YELLOWGREEN))
+ parsedValue = new SVGColor(value->string);
+ else if (id == CSS_VAL_CURRENTCOLOR)
+ parsedValue = new SVGColor(SVGColor::SVG_COLORTYPE_CURRENTCOLOR);
+ else // TODO : svgcolor (iccColor)
+ parsedValue = parseSVGColor();
+
+ if (parsedValue)
+ valueList->next();
+
+ break;
+
+ case CSS_PROP_WRITING_MODE:
+ // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
+ if (id >= CSS_VAL_LR_TB && id <= CSS_VAL_TB)
+ valid_primitive = true;
+ break;
+
+ case CSS_PROP_STROKE_WIDTH: // <length> | inherit
+ case CSS_PROP_STROKE_DASHOFFSET:
+ valid_primitive = validUnit(value, FLength | FPercent, false);
+ break;
+ case CSS_PROP_STROKE_DASHARRAY: // none | <dasharray> | inherit
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else
+ parsedValue = parseSVGStrokeDasharray();
+
+ break;
+
+ case CSS_PROP_KERNING: // auto | normal | <length> | inherit
+ if (id == CSS_VAL_AUTO || id == CSS_VAL_NORMAL)
+ valid_primitive = true;
+ else
+ valid_primitive = validUnit(value, FLength, false);
+ break;
+
+ case CSS_PROP_CLIP_PATH: // <uri> | none | inherit
+ case CSS_PROP_FILTER:
+ if (id == CSS_VAL_NONE)
+ valid_primitive = true;
+ else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ parsedValue = new CSSPrimitiveValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+ if (parsedValue)
+ valueList->next();
+ }
+ break;
+
+ /* shorthand properties */
+ case CSS_PROP_MARKER:
+ {
+ if (!parseValue(CSS_PROP_MARKER_START, important))
+ return false;
+ CSSValue *value = parsedProperties[numParsedProperties - 1]->value();
+ m_implicitShorthand = true;
+ addProperty(CSS_PROP_MARKER_MID, value, important);
+ addProperty(CSS_PROP_MARKER_END, value, important);
+ m_implicitShorthand = false;
+ return true;
+ }
+ default:
+ // If you crash here, it's because you added a css property and are not handling it
+ // in either this switch statement or the one in CSSParser::parseValue
+ ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
+ return false;
+ }
+
+ if (valid_primitive) {
+ if (id != 0)
+ parsedValue = new CSSPrimitiveValue(id);
+ else if (value->unit == CSSPrimitiveValue::CSS_STRING)
+ parsedValue = new CSSPrimitiveValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+ else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ parsedValue = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+ else if (value->unit >= Value::Q_EMS)
+ parsedValue = new CSSQuirkPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_EMS);
+ valueList->next();
+ }
+ if (!parsedValue || (valueList->current() && !inShorthand()))
+ return false;
+
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray()
+{
+ CSSValueList* ret = new CSSValueList;
+ Value* value = valueList->current();
+ bool valid_primitive = true;
+ while (value) {
+ valid_primitive = validUnit(value, FLength | FPercent |FNonNeg, false);
+ if (!valid_primitive)
+ break;
+ if (value->id != 0)
+ ret->append(new CSSPrimitiveValue(value->id));
+ else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ ret->append(new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
+ value = valueList->next();
+ if (value && value->unit == Value::Operator && value->iValue == ',')
+ value = valueList->next();
+ }
+ if (!valid_primitive) {
+ delete ret;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+PassRefPtr<CSSValue> CSSParser::parseSVGPaint()
+{
+ RGBA32 c = Color::transparent;
+ if (!parseColorFromValue(valueList->current(), c, true))
+ return new SVGPaint();
+ return new SVGPaint(Color(c));
+}
+
+PassRefPtr<CSSValue> CSSParser::parseSVGColor()
+{
+ RGBA32 c = Color::transparent;
+ if (!parseColorFromValue(valueList->current(), c, true))
+ return 0;
+ return new SVGColor(Color(c));
+}
+
+}
+
+#endif // ENABLE(SVG)
+
+// vim:ts=4:noet