• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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