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