1 /* 2 Copyright (C) 2007 Eric Seidel <eric (at) webkit.org> 3 Copyright (C) 2007 Alexey Proskuryakov <ap (at) 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 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 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 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 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 106 static inline String serializeAsFragmentIdentifier(const AtomicString& resource) 107 { 108 return "#" + resource; 109 } 110 111 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