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 "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 PassRefPtr<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 0; 46 } 47 } 48 49 static PassRefPtr<CSSValue> strokeDashArrayToCSSValueList(const Vector<SVGLength>& dashes) 50 { 51 if (dashes.isEmpty()) 52 return CSSPrimitiveValue::createIdentifier(CSSValueNone); 53 54 RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); 55 const Vector<SVGLength>::const_iterator end = dashes.end(); 56 for (Vector<SVGLength>::const_iterator it = dashes.begin(); it != end; ++it) 57 list->append(SVGLength::toCSSPrimitiveValue(*it)); 58 59 return list.release(); 60 } 61 62 PassRefPtr<SVGPaint> CSSComputedStyleDeclaration::adjustSVGPaintForCurrentColor(PassRefPtr<SVGPaint> newPaint, RenderStyle* style) const 63 { 64 RefPtr<SVGPaint> paint = newPaint; 65 if (paint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR || paint->paintType() == SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR) { 66 // SVG handles currentColor itself, style->color() is guaranteed not to be currentColor. 67 ASSERT(!style->color().isCurrentColor()); 68 paint->setColor(style->color().color()); 69 } 70 return paint.release(); 71 } 72 73 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const 74 { 75 Node* node = m_node.get(); 76 if (!node) 77 return 0; 78 79 // Make sure our layout is up to date before we allow a query on these attributes. 80 if (updateLayout) 81 node->document()->updateLayout(); 82 83 RenderStyle* style = node->computedStyle(); 84 if (!style) 85 return 0; 86 87 const SVGRenderStyle* svgStyle = style->svgStyle(); 88 if (!svgStyle) 89 return 0; 90 91 switch (propertyID) { 92 case CSSPropertyClipRule: 93 return CSSPrimitiveValue::create(svgStyle->clipRule()); 94 case CSSPropertyFloodOpacity: 95 return CSSPrimitiveValue::create(svgStyle->floodOpacity(), CSSPrimitiveValue::CSS_NUMBER); 96 case CSSPropertyStopOpacity: 97 return CSSPrimitiveValue::create(svgStyle->stopOpacity(), CSSPrimitiveValue::CSS_NUMBER); 98 case CSSPropertyColorInterpolation: 99 return CSSPrimitiveValue::create(svgStyle->colorInterpolation()); 100 case CSSPropertyColorInterpolationFilters: 101 return CSSPrimitiveValue::create(svgStyle->colorInterpolationFilters()); 102 case CSSPropertyFillOpacity: 103 return CSSPrimitiveValue::create(svgStyle->fillOpacity(), CSSPrimitiveValue::CSS_NUMBER); 104 case CSSPropertyFillRule: 105 return CSSPrimitiveValue::create(svgStyle->fillRule()); 106 case CSSPropertyColorRendering: 107 return CSSPrimitiveValue::create(svgStyle->colorRendering()); 108 case CSSPropertyShapeRendering: 109 return CSSPrimitiveValue::create(svgStyle->shapeRendering()); 110 case CSSPropertyStrokeLinecap: 111 return CSSPrimitiveValue::create(svgStyle->capStyle()); 112 case CSSPropertyStrokeLinejoin: 113 return CSSPrimitiveValue::create(svgStyle->joinStyle()); 114 case CSSPropertyStrokeMiterlimit: 115 return CSSPrimitiveValue::create(svgStyle->strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER); 116 case CSSPropertyStrokeOpacity: 117 return CSSPrimitiveValue::create(svgStyle->strokeOpacity(), CSSPrimitiveValue::CSS_NUMBER); 118 case CSSPropertyAlignmentBaseline: 119 return CSSPrimitiveValue::create(svgStyle->alignmentBaseline()); 120 case CSSPropertyDominantBaseline: 121 return CSSPrimitiveValue::create(svgStyle->dominantBaseline()); 122 case CSSPropertyTextAnchor: 123 return CSSPrimitiveValue::create(svgStyle->textAnchor()); 124 case CSSPropertyWritingMode: 125 return CSSPrimitiveValue::create(svgStyle->writingMode()); 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 CSSPropertyFilter: 135 if (!svgStyle->filterResource().isEmpty()) 136 return CSSPrimitiveValue::create(svgStyle->filterResource(), CSSPrimitiveValue::CSS_URI); 137 return CSSPrimitiveValue::createIdentifier(CSSValueNone); 138 case CSSPropertyFloodColor: 139 return currentColorOrValidColor(style, svgStyle->floodColor()); 140 case CSSPropertyLightingColor: 141 return currentColorOrValidColor(style, svgStyle->lightingColor()); 142 case CSSPropertyStopColor: 143 return currentColorOrValidColor(style, svgStyle->stopColor()); 144 case CSSPropertyFill: 145 return adjustSVGPaintForCurrentColor(SVGPaint::create(svgStyle->fillPaintType(), svgStyle->fillPaintUri(), svgStyle->fillPaintColor()), style); 146 case CSSPropertyKerning: 147 return SVGLength::toCSSPrimitiveValue(svgStyle->kerning()); 148 case CSSPropertyMarkerEnd: 149 if (!svgStyle->markerEndResource().isEmpty()) 150 return CSSPrimitiveValue::create(svgStyle->markerEndResource(), CSSPrimitiveValue::CSS_URI); 151 return CSSPrimitiveValue::createIdentifier(CSSValueNone); 152 case CSSPropertyMarkerMid: 153 if (!svgStyle->markerMidResource().isEmpty()) 154 return CSSPrimitiveValue::create(svgStyle->markerMidResource(), CSSPrimitiveValue::CSS_URI); 155 return CSSPrimitiveValue::createIdentifier(CSSValueNone); 156 case CSSPropertyMarkerStart: 157 if (!svgStyle->markerStartResource().isEmpty()) 158 return CSSPrimitiveValue::create(svgStyle->markerStartResource(), CSSPrimitiveValue::CSS_URI); 159 return CSSPrimitiveValue::createIdentifier(CSSValueNone); 160 case CSSPropertyStroke: 161 return adjustSVGPaintForCurrentColor(SVGPaint::create(svgStyle->strokePaintType(), svgStyle->strokePaintUri(), svgStyle->strokePaintColor()), style); 162 case CSSPropertyStrokeDasharray: 163 return strokeDashArrayToCSSValueList(svgStyle->strokeDashArray()); 164 case CSSPropertyStrokeDashoffset: 165 return SVGLength::toCSSPrimitiveValue(svgStyle->strokeDashOffset()); 166 case CSSPropertyStrokeWidth: 167 return SVGLength::toCSSPrimitiveValue(svgStyle->strokeWidth()); 168 case CSSPropertyBaselineShift: { 169 switch (svgStyle->baselineShift()) { 170 case BS_BASELINE: 171 return CSSPrimitiveValue::createIdentifier(CSSValueBaseline); 172 case BS_SUPER: 173 return CSSPrimitiveValue::createIdentifier(CSSValueSuper); 174 case BS_SUB: 175 return CSSPrimitiveValue::createIdentifier(CSSValueSub); 176 case BS_LENGTH: 177 return SVGLength::toCSSPrimitiveValue(svgStyle->baselineShiftValue()); 178 } 179 ASSERT_NOT_REACHED(); 180 return 0; 181 } 182 case CSSPropertyBufferedRendering: 183 return CSSPrimitiveValue::create(svgStyle->bufferedRendering()); 184 case CSSPropertyGlyphOrientationHorizontal: 185 return glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationHorizontal()); 186 case CSSPropertyGlyphOrientationVertical: { 187 if (RefPtr<CSSPrimitiveValue> value = glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationVertical())) 188 return value.release(); 189 190 if (svgStyle->glyphOrientationVertical() == GO_AUTO) 191 return CSSPrimitiveValue::createIdentifier(CSSValueAuto); 192 193 return 0; 194 } 195 case CSSPropertyVectorEffect: 196 return CSSPrimitiveValue::create(svgStyle->vectorEffect()); 197 case CSSPropertyMaskType: 198 return CSSPrimitiveValue::create(svgStyle->maskType()); 199 case CSSPropertyMarker: 200 case CSSPropertyEnableBackground: 201 case CSSPropertyColorProfile: 202 // the above properties are not yet implemented in the engine 203 break; 204 default: 205 // If you crash here, it's because you added a css property and are not handling it 206 // in either this switch statement or the one in CSSComputedStyleDelcaration::getPropertyCSSValue 207 ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propertyID); 208 } 209 LOG_ERROR("unimplemented propertyID: %d", propertyID); 210 return 0; 211 } 212 213 } 214