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 #include "core/css/CSSComputedStyleDeclaration.h"
24
25 #include "core/CSSPropertyNames.h"
26 #include "core/css/CSSPrimitiveValueMappings.h"
27 #include "core/dom/Document.h"
28 #include "core/rendering/style/RenderStyle.h"
29
30 namespace blink {
31
glyphOrientationToCSSPrimitiveValue(EGlyphOrientation orientation)32 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> glyphOrientationToCSSPrimitiveValue(EGlyphOrientation orientation)
33 {
34 switch (orientation) {
35 case GO_0DEG:
36 return CSSPrimitiveValue::create(0.0f, CSSPrimitiveValue::CSS_DEG);
37 case GO_90DEG:
38 return CSSPrimitiveValue::create(90.0f, CSSPrimitiveValue::CSS_DEG);
39 case GO_180DEG:
40 return CSSPrimitiveValue::create(180.0f, CSSPrimitiveValue::CSS_DEG);
41 case GO_270DEG:
42 return CSSPrimitiveValue::create(270.0f, CSSPrimitiveValue::CSS_DEG);
43 default:
44 return nullptr;
45 }
46 }
47
strokeDashArrayToCSSValueList(PassRefPtr<SVGLengthList> passDashes)48 static PassRefPtrWillBeRawPtr<CSSValue> strokeDashArrayToCSSValueList(PassRefPtr<SVGLengthList> passDashes)
49 {
50 RefPtr<SVGLengthList> dashes = passDashes;
51
52 if (dashes->isEmpty())
53 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
54
55 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
56 SVGLengthList::ConstIterator it = dashes->begin();
57 SVGLengthList::ConstIterator itEnd = dashes->end();
58 for (; it != itEnd; ++it)
59 list->append(SVGLength::toCSSPrimitiveValue(*it));
60
61 return list.release();
62 }
63
paintOrderToCSSValueList(EPaintOrder paintorder)64 static PassRefPtrWillBeRawPtr<CSSValue> paintOrderToCSSValueList(EPaintOrder paintorder)
65 {
66 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
67 do {
68 EPaintOrderType paintOrderType = (EPaintOrderType)(paintorder & ((1 << kPaintOrderBitwidth) - 1));
69 switch (paintOrderType) {
70 case PT_FILL:
71 case PT_STROKE:
72 case PT_MARKERS:
73 list->append(CSSPrimitiveValue::create(paintOrderType));
74 break;
75 case PT_NONE:
76 default:
77 ASSERT_NOT_REACHED();
78 break;
79 }
80 } while (paintorder >>= kPaintOrderBitwidth);
81
82 return list.release();
83 }
84
adjustSVGPaintForCurrentColor(SVGPaintType paintType,const String & url,const Color & color,const Color & currentColor)85 static PassRefPtrWillBeRawPtr<CSSValue> adjustSVGPaintForCurrentColor(SVGPaintType paintType, const String& url, const Color& color, const Color& currentColor)
86 {
87 if (paintType >= SVG_PAINTTYPE_URI_NONE) {
88 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
89 values->append(CSSPrimitiveValue::create(url, CSSPrimitiveValue::CSS_URI));
90 if (paintType == SVG_PAINTTYPE_URI_NONE)
91 values->append(CSSPrimitiveValue::create(CSSValueNone));
92 else if (paintType == SVG_PAINTTYPE_URI_CURRENTCOLOR)
93 values->append(CSSPrimitiveValue::createColor(currentColor.rgb()));
94 else if (paintType == SVG_PAINTTYPE_URI_RGBCOLOR)
95 values->append(CSSPrimitiveValue::createColor(color.rgb()));
96 return values.release();
97 }
98 if (paintType == SVG_PAINTTYPE_NONE)
99 return CSSPrimitiveValue::create(CSSValueNone);
100 if (paintType == SVG_PAINTTYPE_CURRENTCOLOR)
101 return CSSPrimitiveValue::createColor(currentColor.rgb());
102
103 return CSSPrimitiveValue::createColor(color.rgb());
104 }
105
serializeAsFragmentIdentifier(const AtomicString & resource)106 static inline String serializeAsFragmentIdentifier(const AtomicString& resource)
107 {
108 return "#" + resource;
109 }
110
getSVGPropertyCSSValue(CSSPropertyID propertyID,EUpdateLayout updateLayout) const111 PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
112 {
113 Node* node = m_node.get();
114 if (!node)
115 return nullptr;
116
117 // Make sure our layout is up to date before we allow a query on these attributes.
118 if (updateLayout)
119 node->document().updateLayout();
120
121 RenderStyle* style = node->computedStyle();
122 if (!style)
123 return nullptr;
124
125 const SVGRenderStyle& svgStyle = style->svgStyle();
126
127 switch (propertyID) {
128 case CSSPropertyClipRule:
129 return CSSPrimitiveValue::create(svgStyle.clipRule());
130 case CSSPropertyFloodOpacity:
131 return CSSPrimitiveValue::create(svgStyle.floodOpacity(), CSSPrimitiveValue::CSS_NUMBER);
132 case CSSPropertyStopOpacity:
133 return CSSPrimitiveValue::create(svgStyle.stopOpacity(), CSSPrimitiveValue::CSS_NUMBER);
134 case CSSPropertyColorInterpolation:
135 return CSSPrimitiveValue::create(svgStyle.colorInterpolation());
136 case CSSPropertyColorInterpolationFilters:
137 return CSSPrimitiveValue::create(svgStyle.colorInterpolationFilters());
138 case CSSPropertyFillOpacity:
139 return CSSPrimitiveValue::create(svgStyle.fillOpacity(), CSSPrimitiveValue::CSS_NUMBER);
140 case CSSPropertyFillRule:
141 return CSSPrimitiveValue::create(svgStyle.fillRule());
142 case CSSPropertyColorRendering:
143 return CSSPrimitiveValue::create(svgStyle.colorRendering());
144 case CSSPropertyShapeRendering:
145 return CSSPrimitiveValue::create(svgStyle.shapeRendering());
146 case CSSPropertyStrokeLinecap:
147 return CSSPrimitiveValue::create(svgStyle.capStyle());
148 case CSSPropertyStrokeLinejoin:
149 return CSSPrimitiveValue::create(svgStyle.joinStyle());
150 case CSSPropertyStrokeMiterlimit:
151 return CSSPrimitiveValue::create(svgStyle.strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER);
152 case CSSPropertyStrokeOpacity:
153 return CSSPrimitiveValue::create(svgStyle.strokeOpacity(), CSSPrimitiveValue::CSS_NUMBER);
154 case CSSPropertyAlignmentBaseline:
155 return CSSPrimitiveValue::create(svgStyle.alignmentBaseline());
156 case CSSPropertyDominantBaseline:
157 return CSSPrimitiveValue::create(svgStyle.dominantBaseline());
158 case CSSPropertyTextAnchor:
159 return CSSPrimitiveValue::create(svgStyle.textAnchor());
160 case CSSPropertyWritingMode:
161 return CSSPrimitiveValue::create(svgStyle.writingMode());
162 case CSSPropertyClipPath:
163 if (!svgStyle.clipperResource().isEmpty())
164 return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle.clipperResource()), CSSPrimitiveValue::CSS_URI);
165 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
166 case CSSPropertyMask:
167 if (!svgStyle.maskerResource().isEmpty())
168 return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle.maskerResource()), CSSPrimitiveValue::CSS_URI);
169 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
170 case CSSPropertyFilter:
171 if (!svgStyle.filterResource().isEmpty())
172 return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle.filterResource()), CSSPrimitiveValue::CSS_URI);
173 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
174 case CSSPropertyFloodColor:
175 return currentColorOrValidColor(*style, svgStyle.floodColor());
176 case CSSPropertyLightingColor:
177 return currentColorOrValidColor(*style, svgStyle.lightingColor());
178 case CSSPropertyStopColor:
179 return currentColorOrValidColor(*style, svgStyle.stopColor());
180 case CSSPropertyFill:
181 return adjustSVGPaintForCurrentColor(svgStyle.fillPaintType(), svgStyle.fillPaintUri(), svgStyle.fillPaintColor(), style->color());
182 case CSSPropertyMarkerEnd:
183 if (!svgStyle.markerEndResource().isEmpty())
184 return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle.markerEndResource()), CSSPrimitiveValue::CSS_URI);
185 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
186 case CSSPropertyMarkerMid:
187 if (!svgStyle.markerMidResource().isEmpty())
188 return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle.markerMidResource()), CSSPrimitiveValue::CSS_URI);
189 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
190 case CSSPropertyMarkerStart:
191 if (!svgStyle.markerStartResource().isEmpty())
192 return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle.markerStartResource()), CSSPrimitiveValue::CSS_URI);
193 return CSSPrimitiveValue::createIdentifier(CSSValueNone);
194 case CSSPropertyStroke:
195 return adjustSVGPaintForCurrentColor(svgStyle.strokePaintType(), svgStyle.strokePaintUri(), svgStyle.strokePaintColor(), style->color());
196 case CSSPropertyStrokeDasharray:
197 return strokeDashArrayToCSSValueList(svgStyle.strokeDashArray());
198 case CSSPropertyStrokeDashoffset:
199 return SVGLength::toCSSPrimitiveValue(svgStyle.strokeDashOffset());
200 case CSSPropertyStrokeWidth:
201 return SVGLength::toCSSPrimitiveValue(svgStyle.strokeWidth());
202 case CSSPropertyBaselineShift: {
203 switch (svgStyle.baselineShift()) {
204 case BS_BASELINE:
205 return CSSPrimitiveValue::createIdentifier(CSSValueBaseline);
206 case BS_SUPER:
207 return CSSPrimitiveValue::createIdentifier(CSSValueSuper);
208 case BS_SUB:
209 return CSSPrimitiveValue::createIdentifier(CSSValueSub);
210 case BS_LENGTH:
211 return SVGLength::toCSSPrimitiveValue(svgStyle.baselineShiftValue());
212 }
213 ASSERT_NOT_REACHED();
214 return nullptr;
215 }
216 case CSSPropertyBufferedRendering:
217 return CSSPrimitiveValue::create(svgStyle.bufferedRendering());
218 case CSSPropertyGlyphOrientationHorizontal:
219 return glyphOrientationToCSSPrimitiveValue(svgStyle.glyphOrientationHorizontal());
220 case CSSPropertyGlyphOrientationVertical: {
221 if (RefPtrWillBeRawPtr<CSSPrimitiveValue> value = glyphOrientationToCSSPrimitiveValue(svgStyle.glyphOrientationVertical()))
222 return value.release();
223
224 if (svgStyle.glyphOrientationVertical() == GO_AUTO)
225 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
226
227 return nullptr;
228 }
229 case CSSPropertyPaintOrder:
230 return paintOrderToCSSValueList(svgStyle.paintOrder());
231 case CSSPropertyVectorEffect:
232 return CSSPrimitiveValue::create(svgStyle.vectorEffect());
233 case CSSPropertyMaskType:
234 return CSSPrimitiveValue::create(svgStyle.maskType());
235 case CSSPropertyMarker:
236 case CSSPropertyEnableBackground:
237 // the above properties are not yet implemented in the engine
238 break;
239 default:
240 // If you crash here, it's because you added a css property and are not handling it
241 // in either this switch statement or the one in CSSComputedStyleDelcaration::getPropertyCSSValue
242 ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propertyID);
243 }
244 WTF_LOG_ERROR("unimplemented propertyID: %d", propertyID);
245 return nullptr;
246 }
247
248 }
249