5dfe03e03013ad5e1e7f1deb1dbbd93b224ec677
[WebKit-https.git] / Source / WebCore / css / SVGCSSComputedStyleDeclaration.cpp
1 /*
2     Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3     Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22
23 #if ENABLE(SVG)
24 #include "CSSComputedStyleDeclaration.h"
25
26 #include "CSSPrimitiveValueMappings.h"
27 #include "CSSPropertyNames.h"
28 #include "Document.h"
29 #include "RenderStyle.h"
30 #include "SVGPaint.h"
31
32 namespace WebCore {
33
34 static PassRefPtr<CSSPrimitiveValue> glyphOrientationToCSSPrimitiveValue(EGlyphOrientation orientation)
35 {
36     switch (orientation) {
37         case GO_0DEG:
38             return CSSPrimitiveValue::create(0.0f, CSSPrimitiveValue::CSS_DEG);
39         case GO_90DEG:
40             return CSSPrimitiveValue::create(90.0f, CSSPrimitiveValue::CSS_DEG);
41         case GO_180DEG:
42             return CSSPrimitiveValue::create(180.0f, CSSPrimitiveValue::CSS_DEG);
43         case GO_270DEG:
44             return CSSPrimitiveValue::create(270.0f, CSSPrimitiveValue::CSS_DEG);
45         default:
46             return 0;
47     }
48 }
49
50 static PassRefPtr<CSSValue> strokeDashArrayToCSSValueList(const Vector<SVGLength>& dashes)
51 {
52     if (dashes.isEmpty())
53         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
54
55     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
56     const Vector<SVGLength>::const_iterator end = dashes.end();
57     for (Vector<SVGLength>::const_iterator it = dashes.begin(); it != end; ++it)
58         list->append(SVGLength::toCSSPrimitiveValue(*it));
59
60     return list.release();
61 }
62
63 PassRefPtr<SVGPaint> CSSComputedStyleDeclaration::adjustSVGPaintForCurrentColor(PassRefPtr<SVGPaint> newPaint, RenderStyle* style) const
64 {
65     RefPtr<SVGPaint> paint = newPaint;
66     if (paint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR || paint->paintType() == SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR)
67         paint->setColor(style->color());
68     return paint.release();
69 }
70
71 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(int propertyID, EUpdateLayout updateLayout) const
72 {
73     Node* node = m_node.get();
74     if (!node)
75         return 0;
76     
77     // Make sure our layout is up to date before we allow a query on these attributes.
78     if (updateLayout)
79         node->document()->updateLayout();
80         
81     RenderStyle* style = node->computedStyle();
82     if (!style)
83         return 0;
84     
85     const SVGRenderStyle* svgStyle = style->svgStyle();
86     if (!svgStyle)
87         return 0;
88     
89     switch (static_cast<CSSPropertyID>(propertyID)) {
90         case CSSPropertyClipRule:
91             return CSSPrimitiveValue::create(svgStyle->clipRule());
92         case CSSPropertyFloodOpacity:
93             return CSSPrimitiveValue::create(svgStyle->floodOpacity(), CSSPrimitiveValue::CSS_NUMBER);
94         case CSSPropertyStopOpacity:
95             return CSSPrimitiveValue::create(svgStyle->stopOpacity(), CSSPrimitiveValue::CSS_NUMBER);
96         case CSSPropertyColorInterpolation:
97             return CSSPrimitiveValue::create(svgStyle->colorInterpolation());
98         case CSSPropertyColorInterpolationFilters:
99             return CSSPrimitiveValue::create(svgStyle->colorInterpolationFilters());
100         case CSSPropertyFillOpacity:
101             return CSSPrimitiveValue::create(svgStyle->fillOpacity(), CSSPrimitiveValue::CSS_NUMBER);
102         case CSSPropertyFillRule:
103             return CSSPrimitiveValue::create(svgStyle->fillRule());
104         case CSSPropertyColorRendering:
105             return CSSPrimitiveValue::create(svgStyle->colorRendering());
106         case CSSPropertyImageRendering:
107             return CSSPrimitiveValue::create(svgStyle->imageRendering());
108         case CSSPropertyShapeRendering:
109             return CSSPrimitiveValue::create(svgStyle->shapeRendering());
110         case CSSPropertyStrokeLinecap:
111             return CSSPrimitiveValue::create(svgStyle->capStyle());
112         case CSSPropertyStrokeLinejoin:
113             return CSSPrimitiveValue::create(svgStyle->joinStyle());
114         case CSSPropertyStrokeMiterlimit:
115             return CSSPrimitiveValue::create(svgStyle->strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER);
116         case CSSPropertyStrokeOpacity:
117             return CSSPrimitiveValue::create(svgStyle->strokeOpacity(), CSSPrimitiveValue::CSS_NUMBER);
118         case CSSPropertyAlignmentBaseline:
119             return CSSPrimitiveValue::create(svgStyle->alignmentBaseline());
120         case CSSPropertyDominantBaseline:
121             return CSSPrimitiveValue::create(svgStyle->dominantBaseline());
122         case CSSPropertyTextAnchor:
123             return CSSPrimitiveValue::create(svgStyle->textAnchor());
124         case CSSPropertyWritingMode:
125             return CSSPrimitiveValue::create(svgStyle->writingMode());
126         case CSSPropertyClipPath:
127             if (!svgStyle->clipperResource().isEmpty())
128                 return CSSPrimitiveValue::create(svgStyle->clipperResource(), CSSPrimitiveValue::CSS_URI);
129             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
130         case CSSPropertyMask:
131             if (!svgStyle->maskerResource().isEmpty())
132                 return CSSPrimitiveValue::create(svgStyle->maskerResource(), CSSPrimitiveValue::CSS_URI);
133             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
134         case CSSPropertyFilter:
135             if (!svgStyle->filterResource().isEmpty())
136                 return CSSPrimitiveValue::create(svgStyle->filterResource(), CSSPrimitiveValue::CSS_URI);
137             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
138         case CSSPropertyFloodColor:
139             return currentColorOrValidColor(style, svgStyle->floodColor());
140         case CSSPropertyLightingColor:
141             return currentColorOrValidColor(style, svgStyle->lightingColor());
142         case CSSPropertyStopColor:
143             return currentColorOrValidColor(style, svgStyle->stopColor());
144         case CSSPropertyFill:
145             return adjustSVGPaintForCurrentColor(SVGPaint::create(svgStyle->fillPaintType(), svgStyle->fillPaintUri(), svgStyle->fillPaintColor()), style);
146         case CSSPropertyKerning:
147             return SVGLength::toCSSPrimitiveValue(svgStyle->kerning());
148         case CSSPropertyMarkerEnd:
149             if (!svgStyle->markerEndResource().isEmpty())
150                 return CSSPrimitiveValue::create(svgStyle->markerEndResource(), CSSPrimitiveValue::CSS_URI);
151             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
152         case CSSPropertyMarkerMid:
153             if (!svgStyle->markerMidResource().isEmpty())
154                 return CSSPrimitiveValue::create(svgStyle->markerMidResource(), CSSPrimitiveValue::CSS_URI);
155             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
156         case CSSPropertyMarkerStart:
157             if (!svgStyle->markerStartResource().isEmpty())
158                 return CSSPrimitiveValue::create(svgStyle->markerStartResource(), CSSPrimitiveValue::CSS_URI);
159             return CSSPrimitiveValue::createIdentifier(CSSValueNone);
160         case CSSPropertyStroke:
161             return adjustSVGPaintForCurrentColor(SVGPaint::create(svgStyle->strokePaintType(), svgStyle->strokePaintUri(), svgStyle->strokePaintColor()), style);
162         case CSSPropertyStrokeDasharray:
163             return strokeDashArrayToCSSValueList(svgStyle->strokeDashArray());
164         case CSSPropertyStrokeDashoffset:
165             return SVGLength::toCSSPrimitiveValue(svgStyle->strokeDashOffset());
166         case CSSPropertyStrokeWidth:
167             return SVGLength::toCSSPrimitiveValue(svgStyle->strokeWidth());
168         case CSSPropertyBaselineShift: {
169             switch (svgStyle->baselineShift()) {
170                 case BS_BASELINE:
171                     return CSSPrimitiveValue::createIdentifier(CSSValueBaseline);
172                 case BS_SUPER:
173                     return CSSPrimitiveValue::createIdentifier(CSSValueSuper);
174                 case BS_SUB:
175                     return CSSPrimitiveValue::createIdentifier(CSSValueSub);
176                 case BS_LENGTH:
177                     return SVGLength::toCSSPrimitiveValue(svgStyle->baselineShiftValue());
178             }
179         }
180         case CSSPropertyGlyphOrientationHorizontal:
181             return glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationHorizontal());
182         case CSSPropertyGlyphOrientationVertical: {
183             if (RefPtr<CSSPrimitiveValue> value = glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationVertical()))
184                 return value.release();
185
186             if (svgStyle->glyphOrientationVertical() == GO_AUTO)
187                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
188
189             return 0;
190         }
191         case CSSPropertyWebkitSvgShadow:
192             return valueForShadow(svgStyle->shadow(), propertyID, style);
193         case CSSPropertyVectorEffect:
194             return CSSPrimitiveValue::create(svgStyle->vectorEffect());
195         case CSSPropertyMarker:
196         case CSSPropertyEnableBackground:
197         case CSSPropertyColorProfile:
198             // the above properties are not yet implemented in the engine
199             break;
200     default:
201         // If you crash here, it's because you added a css property and are not handling it
202         // in either this switch statement or the one in CSSComputedStyleDelcaration::getPropertyCSSValue
203         ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propertyID);
204     }
205     LOG_ERROR("unimplemented propertyID: %d", propertyID);
206     return 0;
207 }
208
209 }
210
211 #endif // ENABLE(SVG)
212
213 // vim:ts=4:noet