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