summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/css/SVGCSSStyleSelector.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/css/SVGCSSStyleSelector.cpp
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/css/SVGCSSStyleSelector.cpp')
-rw-r--r--Source/WebCore/css/SVGCSSStyleSelector.cpp594
1 files changed, 594 insertions, 0 deletions
diff --git a/Source/WebCore/css/SVGCSSStyleSelector.cpp b/Source/WebCore/css/SVGCSSStyleSelector.cpp
new file mode 100644
index 0000000..64665d4
--- /dev/null
+++ b/Source/WebCore/css/SVGCSSStyleSelector.cpp
@@ -0,0 +1,594 @@
+/*
+ Copyright (C) 2005 Apple Computer, Inc.
+ Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ 2004, 2005, 2008 Rob Buis <buis@kde.org>
+ Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
+
+ Based on khtml css code by:
+ Copyright(C) 1999-2003 Lars Knoll(knoll@kde.org)
+ (C) 2003 Apple Computer, Inc.
+ (C) 2004 Allan Sandfeld Jensen(kde@carewolf.com)
+ (C) 2004 Germain Garand(germain@ebooksfrance.org)
+
+ 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 "CSSStyleSelector.h"
+
+#include "CSSPrimitiveValueMappings.h"
+#include "CSSPropertyNames.h"
+#include "CSSValueList.h"
+#include "Document.h"
+#include "ShadowValue.h"
+#include "SVGColor.h"
+#include "SVGNames.h"
+#include "SVGPaint.h"
+#include "SVGRenderStyle.h"
+#include "SVGRenderStyleDefs.h"
+#include "SVGStyledElement.h"
+#include "SVGURIReference.h"
+#include <stdlib.h>
+#include <wtf/MathExtras.h>
+
+#define HANDLE_INHERIT(prop, Prop) \
+if (isInherit) \
+{ \
+ svgstyle->set##Prop(m_parentStyle->svgStyle()->prop()); \
+ return; \
+}
+
+#define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
+HANDLE_INHERIT(prop, Prop) \
+if (isInitial) { \
+ svgstyle->set##Prop(SVGRenderStyle::initial##Prop()); \
+ return; \
+}
+
+namespace WebCore {
+
+static float roundToNearestGlyphOrientationAngle(float angle)
+{
+ angle = fabsf(fmodf(angle, 360.0f));
+
+ if (angle <= 45.0f || angle > 315.0f)
+ return 0.0f;
+ else if (angle > 45.0f && angle <= 135.0f)
+ return 90.0f;
+ else if (angle > 135.0f && angle <= 225.0f)
+ return 180.0f;
+
+ return 270.0f;
+}
+
+static int angleToGlyphOrientation(float angle)
+{
+ angle = roundToNearestGlyphOrientationAngle(angle);
+
+ if (angle == 0.0f)
+ return GO_0DEG;
+ else if (angle == 90.0f)
+ return GO_90DEG;
+ else if (angle == 180.0f)
+ return GO_180DEG;
+ else if (angle == 270.0f)
+ return GO_270DEG;
+
+ return -1;
+}
+
+static Color colorFromSVGColorCSSValue(SVGColor* svgColor, const Color& fgColor)
+{
+ Color color;
+ if (svgColor->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
+ color = fgColor;
+ else
+ color = svgColor->color();
+ return color;
+}
+
+void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
+{
+ ASSERT(value);
+ CSSPrimitiveValue* primitiveValue = 0;
+ if (value->isPrimitiveValue())
+ primitiveValue = static_cast<CSSPrimitiveValue*>(value);
+
+ SVGRenderStyle* svgstyle = m_style->accessSVGStyle();
+ unsigned short valueType = value->cssValueType();
+
+ bool isInherit = m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT;
+ bool isInitial = valueType == CSSPrimitiveValue::CSS_INITIAL || (!m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT);
+
+ // What follows is a list that maps the CSS properties into their
+ // corresponding front-end RenderStyle values. Shorthands(e.g. border,
+ // background) occur in this list as well and are only hit when mapping
+ // "inherit" or "initial" into front-end values.
+ switch (id)
+ {
+ // ident only properties
+ case CSSPropertyAlignmentBaseline:
+ {
+ HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline)
+ if (!primitiveValue)
+ break;
+
+ svgstyle->setAlignmentBaseline(*primitiveValue);
+ break;
+ }
+ case CSSPropertyBaselineShift:
+ {
+ HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
+ if (!primitiveValue)
+ break;
+
+ if (primitiveValue->getIdent()) {
+ switch (primitiveValue->getIdent()) {
+ case CSSValueBaseline:
+ svgstyle->setBaselineShift(BS_BASELINE);
+ break;
+ case CSSValueSub:
+ svgstyle->setBaselineShift(BS_SUB);
+ break;
+ case CSSValueSuper:
+ svgstyle->setBaselineShift(BS_SUPER);
+ break;
+ default:
+ break;
+ }
+ } else {
+ svgstyle->setBaselineShift(BS_LENGTH);
+ svgstyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
+ }
+
+ break;
+ }
+ case CSSPropertyKerning:
+ {
+ HANDLE_INHERIT_AND_INITIAL(kerning, Kerning);
+ if (primitiveValue)
+ svgstyle->setKerning(SVGLength::fromCSSPrimitiveValue(primitiveValue));
+ break;
+ }
+ case CSSPropertyDominantBaseline:
+ {
+ HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline)
+ if (primitiveValue)
+ svgstyle->setDominantBaseline(*primitiveValue);
+ break;
+ }
+ case CSSPropertyColorInterpolation:
+ {
+ HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation)
+ if (primitiveValue)
+ svgstyle->setColorInterpolation(*primitiveValue);
+ break;
+ }
+ case CSSPropertyColorInterpolationFilters:
+ {
+ HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters)
+ if (primitiveValue)
+ svgstyle->setColorInterpolationFilters(*primitiveValue);
+ break;
+ }
+ case CSSPropertyColorRendering:
+ {
+ HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering)
+ if (primitiveValue)
+ svgstyle->setColorRendering(*primitiveValue);
+ break;
+ }
+ case CSSPropertyClipRule:
+ {
+ HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule)
+ if (primitiveValue)
+ svgstyle->setClipRule(*primitiveValue);
+ break;
+ }
+ case CSSPropertyFillRule:
+ {
+ HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule)
+ if (primitiveValue)
+ svgstyle->setFillRule(*primitiveValue);
+ break;
+ }
+ case CSSPropertyStrokeLinejoin:
+ {
+ HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle)
+ if (primitiveValue)
+ svgstyle->setJoinStyle(*primitiveValue);
+ break;
+ }
+ case CSSPropertyImageRendering:
+ {
+ HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering)
+ if (primitiveValue)
+ svgstyle->setImageRendering(*primitiveValue);
+ break;
+ }
+ case CSSPropertyShapeRendering:
+ {
+ HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering)
+ if (primitiveValue)
+ svgstyle->setShapeRendering(*primitiveValue);
+ break;
+ }
+ // end of ident only properties
+ case CSSPropertyFill:
+ {
+ HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint)
+ if (value->isSVGPaint())
+ svgstyle->setFillPaint(static_cast<SVGPaint*>(value));
+ break;
+ }
+ case CSSPropertyStroke:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint)
+ if (value->isSVGPaint())
+ svgstyle->setStrokePaint(static_cast<SVGPaint*>(value));
+
+ break;
+ }
+ case CSSPropertyStrokeWidth:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
+ if (primitiveValue)
+ svgstyle->setStrokeWidth(SVGLength::fromCSSPrimitiveValue(primitiveValue));
+ break;
+ }
+ case CSSPropertyStrokeDasharray:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
+ if (!value->isValueList())
+ break;
+
+ CSSValueList* dashes = static_cast<CSSValueList*>(value);
+
+ Vector<SVGLength> array;
+ size_t length = dashes->length();
+ for (size_t i = 0; i < length; ++i) {
+ CSSValue* currValue = dashes->itemWithoutBoundsCheck(i);
+ if (!currValue->isPrimitiveValue())
+ continue;
+
+ CSSPrimitiveValue* dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i));
+ array.append(SVGLength::fromCSSPrimitiveValue(dash));
+ }
+
+ svgstyle->setStrokeDashArray(array);
+ break;
+ }
+ case CSSPropertyStrokeDashoffset:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
+ if (primitiveValue)
+ svgstyle->setStrokeDashOffset(SVGLength::fromCSSPrimitiveValue(primitiveValue));
+ break;
+ }
+ case CSSPropertyFillOpacity:
+ {
+ HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ f = primitiveValue->getFloatValue() / 100.0f;
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setFillOpacity(f);
+ break;
+ }
+ case CSSPropertyStrokeOpacity:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ f = primitiveValue->getFloatValue() / 100.0f;
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setStrokeOpacity(f);
+ break;
+ }
+ case CSSPropertyStopOpacity:
+ {
+ HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ f = primitiveValue->getFloatValue() / 100.0f;
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setStopOpacity(f);
+ break;
+ }
+ case CSSPropertyMarkerStart:
+ {
+ HANDLE_INHERIT_AND_INITIAL(markerStartResource, MarkerStartResource)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setMarkerStartResource(SVGURIReference::getTarget(s));
+ break;
+ }
+ case CSSPropertyMarkerMid:
+ {
+ HANDLE_INHERIT_AND_INITIAL(markerMidResource, MarkerMidResource)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setMarkerMidResource(SVGURIReference::getTarget(s));
+ break;
+ }
+ case CSSPropertyMarkerEnd:
+ {
+ HANDLE_INHERIT_AND_INITIAL(markerEndResource, MarkerEndResource)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setMarkerEndResource(SVGURIReference::getTarget(s));
+ break;
+ }
+ case CSSPropertyStrokeLinecap:
+ {
+ HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle)
+ if (primitiveValue)
+ svgstyle->setCapStyle(*primitiveValue);
+ break;
+ }
+ case CSSPropertyStrokeMiterlimit:
+ {
+ HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setStrokeMiterLimit(f);
+ break;
+ }
+ case CSSPropertyFilter:
+ {
+ HANDLE_INHERIT_AND_INITIAL(filterResource, FilterResource)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setFilterResource(SVGURIReference::getTarget(s));
+ break;
+ }
+ case CSSPropertyMask:
+ {
+ HANDLE_INHERIT_AND_INITIAL(maskerResource, MaskerResource)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setMaskerResource(SVGURIReference::getTarget(s));
+ break;
+ }
+ case CSSPropertyClipPath:
+ {
+ HANDLE_INHERIT_AND_INITIAL(clipperResource, ClipperResource)
+ if (!primitiveValue)
+ return;
+
+ String s;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_URI)
+ s = primitiveValue->getStringValue();
+ else
+ return;
+
+ svgstyle->setClipperResource(SVGURIReference::getTarget(s));
+ break;
+ }
+ case CSSPropertyTextAnchor:
+ {
+ HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor)
+ if (primitiveValue)
+ svgstyle->setTextAnchor(*primitiveValue);
+ break;
+ }
+ case CSSPropertyWritingMode:
+ {
+ HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode)
+ if (primitiveValue)
+ svgstyle->setWritingMode(*primitiveValue);
+ break;
+ }
+ case CSSPropertyStopColor:
+ {
+ HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
+ if (value->isSVGColor())
+ svgstyle->setStopColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), m_style->color()));
+ break;
+ }
+ case CSSPropertyLightingColor:
+ {
+ HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
+ if (value->isSVGColor())
+ svgstyle->setLightingColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), m_style->color()));
+ break;
+ }
+ case CSSPropertyFloodOpacity:
+ {
+ HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity)
+ if (!primitiveValue)
+ return;
+
+ float f = 0.0f;
+ int type = primitiveValue->primitiveType();
+ if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
+ f = primitiveValue->getFloatValue() / 100.0f;
+ else if (type == CSSPrimitiveValue::CSS_NUMBER)
+ f = primitiveValue->getFloatValue();
+ else
+ return;
+
+ svgstyle->setFloodOpacity(f);
+ break;
+ }
+ case CSSPropertyFloodColor:
+ {
+ HANDLE_INHERIT_AND_INITIAL(floodColor, FloodColor);
+ if (value->isSVGColor())
+ svgstyle->setFloodColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), m_style->color()));
+ break;
+ }
+ case CSSPropertyGlyphOrientationHorizontal:
+ {
+ HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal)
+ if (!primitiveValue)
+ return;
+
+ if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
+ int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
+ ASSERT(orientation != -1);
+
+ svgstyle->setGlyphOrientationHorizontal((EGlyphOrientation) orientation);
+ }
+
+ break;
+ }
+ case CSSPropertyGlyphOrientationVertical:
+ {
+ HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical)
+ if (!primitiveValue)
+ return;
+
+ if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
+ int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
+ ASSERT(orientation != -1);
+
+ svgstyle->setGlyphOrientationVertical((EGlyphOrientation) orientation);
+ } else if (primitiveValue->getIdent() == CSSValueAuto)
+ svgstyle->setGlyphOrientationVertical(GO_AUTO);
+
+ break;
+ }
+ case CSSPropertyEnableBackground:
+ // Silently ignoring this property for now
+ // http://bugs.webkit.org/show_bug.cgi?id=6022
+ break;
+ case CSSPropertyWebkitSvgShadow: {
+ if (isInherit)
+ return svgstyle->setShadow(m_parentStyle->svgStyle()->shadow() ? new ShadowData(*m_parentStyle->svgStyle()->shadow()) : 0);
+ if (isInitial || primitiveValue) // initial | none
+ return svgstyle->setShadow(0);
+
+ if (!value->isValueList())
+ return;
+
+ CSSValueList *list = static_cast<CSSValueList*>(value);
+ if (!list->length())
+ return;
+
+ CSSValue* firstValue = list->itemWithoutBoundsCheck(0);
+ if (!firstValue->isShadowValue())
+ return;
+ ShadowValue* item = static_cast<ShadowValue*>(firstValue);
+ int x = item->x->computeLengthInt(style(), m_rootElementStyle);
+ int y = item->y->computeLengthInt(style(), m_rootElementStyle);
+ int blur = item->blur ? item->blur->computeLengthInt(style(), m_rootElementStyle) : 0;
+ Color color;
+ if (item->color)
+ color = getColorFromPrimitiveValue(item->color.get());
+
+ // -webkit-svg-shadow does should not have a spread or style
+ ASSERT(!item->spread);
+ ASSERT(!item->style);
+
+ ShadowData* shadowData = new ShadowData(x, y, blur, 0, Normal, false, color.isValid() ? color : Color::transparent);
+ svgstyle->setShadow(shadowData);
+ return;
+ }
+ case CSSPropertyVectorEffect: {
+ HANDLE_INHERIT_AND_INITIAL(vectorEffect, VectorEffect)
+ if (!primitiveValue)
+ break;
+
+ svgstyle->setVectorEffect(*primitiveValue);
+ break;
+ }
+ 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 CSSStyleSelector::applyProperty
+ ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id);
+ return;
+ }
+}
+
+}
+
+#endif