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
31namespace WebCore {
32
33static 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
51static 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
63Ref<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
84RefPtr<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}
206