7fb137e17182a814ff45af622ad0b887f4d24829
[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 #include "CSSComputedStyleDeclaration.h"
23
24 #include "CSSPrimitiveValueMappings.h"
25 #include "CSSPropertyNames.h"
26 #include "CSSValueList.h"
27 #include "Document.h"
28 #include "Element.h"
29 #include "RenderStyle.h"
30
31 namespace WebCore {
32
33 static RefPtr<CSSPrimitiveValue> glyphOrientationToCSSPrimitiveValue(GlyphOrientation orientation)
34 {
35     switch (orientation) {
36     case GlyphOrientation::Degrees0:
37         return CSSPrimitiveValue::create(0.0f, CSSPrimitiveValue::CSS_DEG);
38     case GlyphOrientation::Degrees90:
39         return CSSPrimitiveValue::create(90.0f, CSSPrimitiveValue::CSS_DEG);
40     case GlyphOrientation::Degrees180:
41         return CSSPrimitiveValue::create(180.0f, CSSPrimitiveValue::CSS_DEG);
42     case GlyphOrientation::Degrees270:
43         return CSSPrimitiveValue::create(270.0f, CSSPrimitiveValue::CSS_DEG);
44     case GlyphOrientation::Auto:
45         return nullptr;
46     }
47
48     RELEASE_ASSERT_NOT_REACHED();
49 }
50
51 static Ref<CSSValue> strokeDashArrayToCSSValueList(const Vector<SVGLengthValue>& dashes)
52 {
53     if (dashes.isEmpty())
54         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
55
56     auto list = CSSValueList::createCommaSeparated();
57     for (auto& length : dashes)
58         list->append(SVGLengthValue::toCSSPrimitiveValue(length));
59
60     return list;
61 }
62
63 Ref<CSSValue> ComputedStyleExtractor::adjustSVGPaintForCurrentColor(SVGPaintType paintType, const String& url, const Color& color, const Color& currentColor) const
64 {
65     if (paintType >= SVGPaintType::URINone) {
66         auto values = CSSValueList::createSpaceSeparated();
67         values->append(CSSPrimitiveValue::create(url, CSSPrimitiveValue::UnitType::CSS_URI));
68         if (paintType == SVGPaintType::URINone)
69             values->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
70         else if (paintType == SVGPaintType::URICurrentColor)
71             values->append(CSSPrimitiveValue::create(currentColor));
72         else if (paintType == SVGPaintType::URIRGBColor)
73             values->append(CSSPrimitiveValue::create(color));
74         return values;
75     }
76     if (paintType == SVGPaintType::None)
77         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
78     if (paintType == SVGPaintType::CurrentColor)
79         return CSSPrimitiveValue::create(currentColor);
80     
81     return CSSPrimitiveValue::create(color);
82 }
83
84 RefPtr<CSSValue> ComputedStyleExtractor::svgPropertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout)
85 {
86     if (!m_element)
87         return nullptr;
88
89     // Make sure our layout is up to date before we allow a query on these attributes.
90     if (updateLayout)
91         m_element->document().updateLayout();
92
93     auto* style = m_element->computedStyle();
94     if (!style)
95         return nullptr;
96
97     const SVGRenderStyle& svgStyle = style->svgStyle();
98
99     switch (propertyID) {
100     case CSSPropertyClipRule:
101         return CSSPrimitiveValue::create(svgStyle.clipRule());
102     case CSSPropertyFloodOpacity:
103         return CSSPrimitiveValue::create(svgStyle.floodOpacity(), CSSPrimitiveValue::CSS_NUMBER);
104     case CSSPropertyStopOpacity:
105         return CSSPrimitiveValue::create(svgStyle.stopOpacity(), CSSPrimitiveValue::CSS_NUMBER);
106     case CSSPropertyColorInterpolation:
107         return CSSPrimitiveValue::create(svgStyle.colorInterpolation());
108     case CSSPropertyColorInterpolationFilters:
109         return CSSPrimitiveValue::create(svgStyle.colorInterpolationFilters());
110     case CSSPropertyFillOpacity:
111         return CSSPrimitiveValue::create(svgStyle.fillOpacity(), CSSPrimitiveValue::CSS_NUMBER);
112     case CSSPropertyFillRule:
113         return CSSPrimitiveValue::create(svgStyle.fillRule());
114     case CSSPropertyColorRendering:
115         return CSSPrimitiveValue::create(svgStyle.colorRendering());
116     case CSSPropertyShapeRendering:
117         return CSSPrimitiveValue::create(svgStyle.shapeRendering());
118     case CSSPropertyStrokeOpacity:
119         return CSSPrimitiveValue::create(svgStyle.strokeOpacity(), CSSPrimitiveValue::CSS_NUMBER);
120     case CSSPropertyAlignmentBaseline:
121         return CSSPrimitiveValue::create(svgStyle.alignmentBaseline());
122     case CSSPropertyDominantBaseline:
123         return CSSPrimitiveValue::create(svgStyle.dominantBaseline());
124     case CSSPropertyTextAnchor:
125         return CSSPrimitiveValue::create(svgStyle.textAnchor());
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 CSSPropertyFloodColor:
135         return currentColorOrValidColor(style, svgStyle.floodColor());
136     case CSSPropertyLightingColor:
137         return currentColorOrValidColor(style, svgStyle.lightingColor());
138     case CSSPropertyStopColor:
139         return currentColorOrValidColor(style, svgStyle.stopColor());
140     case CSSPropertyFill:
141         return adjustSVGPaintForCurrentColor(svgStyle.fillPaintType(), svgStyle.fillPaintUri(), svgStyle.fillPaintColor(), style->color());
142     case CSSPropertyKerning:
143         return SVGLengthValue::toCSSPrimitiveValue(svgStyle.kerning());
144     case CSSPropertyMarkerEnd:
145         if (!svgStyle.markerEndResource().isEmpty())
146             return CSSPrimitiveValue::create(svgStyle.markerEndResource(), CSSPrimitiveValue::CSS_URI);
147         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
148     case CSSPropertyMarkerMid:
149         if (!svgStyle.markerMidResource().isEmpty())
150             return CSSPrimitiveValue::create(svgStyle.markerMidResource(), CSSPrimitiveValue::CSS_URI);
151         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
152     case CSSPropertyMarkerStart:
153         if (!svgStyle.markerStartResource().isEmpty())
154             return CSSPrimitiveValue::create(svgStyle.markerStartResource(), CSSPrimitiveValue::CSS_URI);
155         return CSSPrimitiveValue::createIdentifier(CSSValueNone);
156     case CSSPropertyStroke:
157         return adjustSVGPaintForCurrentColor(svgStyle.strokePaintType(), svgStyle.strokePaintUri(), svgStyle.strokePaintColor(), style->color());
158     case CSSPropertyStrokeDasharray:
159         return strokeDashArrayToCSSValueList(svgStyle.strokeDashArray());
160     case CSSPropertyBaselineShift: {
161         switch (svgStyle.baselineShift()) {
162         case BaselineShift::Baseline:
163             return CSSPrimitiveValue::createIdentifier(CSSValueBaseline);
164         case BaselineShift::Super:
165             return CSSPrimitiveValue::createIdentifier(CSSValueSuper);
166         case BaselineShift::Sub:
167             return CSSPrimitiveValue::createIdentifier(CSSValueSub);
168         case BaselineShift::Length:
169             return SVGLengthValue::toCSSPrimitiveValue(svgStyle.baselineShiftValue());
170         }
171         ASSERT_NOT_REACHED();
172         return nullptr;
173     }
174     case CSSPropertyBufferedRendering:
175         return CSSPrimitiveValue::create(svgStyle.bufferedRendering());
176     case CSSPropertyGlyphOrientationHorizontal:
177         return glyphOrientationToCSSPrimitiveValue(svgStyle.glyphOrientationHorizontal());
178     case CSSPropertyGlyphOrientationVertical: {
179         if (RefPtr<CSSPrimitiveValue> value = glyphOrientationToCSSPrimitiveValue(svgStyle.glyphOrientationVertical()))
180             return value;
181
182         if (svgStyle.glyphOrientationVertical() == GlyphOrientation::Auto)
183             return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
184
185         return nullptr;
186     }
187     case CSSPropertyVectorEffect:
188         return CSSPrimitiveValue::create(svgStyle.vectorEffect());
189     case CSSPropertyMaskType:
190         return CSSPrimitiveValue::create(svgStyle.maskType());
191     case CSSPropertyMarker:
192     case CSSPropertyEnableBackground:
193     case CSSPropertyColorProfile:
194         // the above properties are not yet implemented in the engine
195         break;
196     default:
197         // If you crash here, it's because you added a css property and are not handling it
198         // in either this switch statement or the one in CSSComputedStyleDelcaration::getPropertyCSSValue
199         ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propertyID);
200     }
201     LOG_ERROR("unimplemented propertyID: %d", propertyID);
202     return nullptr;
203 }
204
205 }