/* Copyright (C) 2007 Eric Seidel Copyright (C) 2007 Alexey Proskuryakov This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "CSSComputedStyleDeclaration.h" #include "CSSPrimitiveValueMappings.h" #include "CSSPropertyNames.h" #include "CSSValueList.h" #include "Document.h" #include "Element.h" #include "RenderStyle.h" namespace WebCore { static RefPtr glyphOrientationToCSSPrimitiveValue(EGlyphOrientation orientation) { switch (orientation) { case GO_0DEG: return CSSPrimitiveValue::create(0.0f, CSSPrimitiveValue::CSS_DEG); case GO_90DEG: return CSSPrimitiveValue::create(90.0f, CSSPrimitiveValue::CSS_DEG); case GO_180DEG: return CSSPrimitiveValue::create(180.0f, CSSPrimitiveValue::CSS_DEG); case GO_270DEG: return CSSPrimitiveValue::create(270.0f, CSSPrimitiveValue::CSS_DEG); default: return nullptr; } } static RefPtr strokeDashArrayToCSSValueList(const Vector& dashes) { if (dashes.isEmpty()) return CSSPrimitiveValue::createIdentifier(CSSValueNone); auto list = CSSValueList::createCommaSeparated(); for (auto& length : dashes) list->append(SVGLengthValue::toCSSPrimitiveValue(length)); return WTFMove(list); } RefPtr ComputedStyleExtractor::adjustSVGPaintForCurrentColor(SVGPaintType paintType, const String& url, const Color& color, const Color& currentColor) const { if (paintType >= SVG_PAINTTYPE_URI_NONE) { RefPtr values = CSSValueList::createSpaceSeparated(); values->append(CSSPrimitiveValue::create(url, CSSPrimitiveValue::UnitType::CSS_URI)); if (paintType == SVG_PAINTTYPE_URI_NONE) values->append(CSSPrimitiveValue::createIdentifier(CSSValueNone)); else if (paintType == SVG_PAINTTYPE_URI_CURRENTCOLOR) values->append(CSSPrimitiveValue::create(currentColor)); else if (paintType == SVG_PAINTTYPE_URI_RGBCOLOR) values->append(CSSPrimitiveValue::create(color)); return values; } if (paintType == SVG_PAINTTYPE_NONE) return CSSPrimitiveValue::createIdentifier(CSSValueNone); if (paintType == SVG_PAINTTYPE_CURRENTCOLOR) return CSSPrimitiveValue::create(currentColor); return CSSPrimitiveValue::create(color); } RefPtr ComputedStyleExtractor::svgPropertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) { if (!m_element) return nullptr; // Make sure our layout is up to date before we allow a query on these attributes. if (updateLayout) m_element->document().updateLayout(); auto* style = m_element->computedStyle(); if (!style) return nullptr; const SVGRenderStyle& svgStyle = style->svgStyle(); switch (propertyID) { case CSSPropertyClipRule: return CSSPrimitiveValue::create(svgStyle.clipRule()); case CSSPropertyFloodOpacity: return CSSPrimitiveValue::create(svgStyle.floodOpacity(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyStopOpacity: return CSSPrimitiveValue::create(svgStyle.stopOpacity(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyColorInterpolation: return CSSPrimitiveValue::create(svgStyle.colorInterpolation()); case CSSPropertyColorInterpolationFilters: return CSSPrimitiveValue::create(svgStyle.colorInterpolationFilters()); case CSSPropertyFillOpacity: return CSSPrimitiveValue::create(svgStyle.fillOpacity(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyFillRule: return CSSPrimitiveValue::create(svgStyle.fillRule()); case CSSPropertyColorRendering: return CSSPrimitiveValue::create(svgStyle.colorRendering()); case CSSPropertyShapeRendering: return CSSPrimitiveValue::create(svgStyle.shapeRendering()); case CSSPropertyStrokeMiterlimit: return CSSPrimitiveValue::create(svgStyle.strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyStrokeOpacity: return CSSPrimitiveValue::create(svgStyle.strokeOpacity(), CSSPrimitiveValue::CSS_NUMBER); case CSSPropertyAlignmentBaseline: return CSSPrimitiveValue::create(svgStyle.alignmentBaseline()); case CSSPropertyDominantBaseline: return CSSPrimitiveValue::create(svgStyle.dominantBaseline()); case CSSPropertyTextAnchor: return CSSPrimitiveValue::create(svgStyle.textAnchor()); case CSSPropertyClipPath: if (!svgStyle.clipperResource().isEmpty()) return CSSPrimitiveValue::create(svgStyle.clipperResource(), CSSPrimitiveValue::CSS_URI); return CSSPrimitiveValue::createIdentifier(CSSValueNone); case CSSPropertyMask: if (!svgStyle.maskerResource().isEmpty()) return CSSPrimitiveValue::create(svgStyle.maskerResource(), CSSPrimitiveValue::CSS_URI); return CSSPrimitiveValue::createIdentifier(CSSValueNone); case CSSPropertyFloodColor: return currentColorOrValidColor(style, svgStyle.floodColor()); case CSSPropertyLightingColor: return currentColorOrValidColor(style, svgStyle.lightingColor()); case CSSPropertyStopColor: return currentColorOrValidColor(style, svgStyle.stopColor()); case CSSPropertyFill: return adjustSVGPaintForCurrentColor(svgStyle.fillPaintType(), svgStyle.fillPaintUri(), svgStyle.fillPaintColor(), style->color()); case CSSPropertyKerning: return SVGLengthValue::toCSSPrimitiveValue(svgStyle.kerning()); case CSSPropertyMarkerEnd: if (!svgStyle.markerEndResource().isEmpty()) return CSSPrimitiveValue::create(svgStyle.markerEndResource(), CSSPrimitiveValue::CSS_URI); return CSSPrimitiveValue::createIdentifier(CSSValueNone); case CSSPropertyMarkerMid: if (!svgStyle.markerMidResource().isEmpty()) return CSSPrimitiveValue::create(svgStyle.markerMidResource(), CSSPrimitiveValue::CSS_URI); return CSSPrimitiveValue::createIdentifier(CSSValueNone); case CSSPropertyMarkerStart: if (!svgStyle.markerStartResource().isEmpty()) return CSSPrimitiveValue::create(svgStyle.markerStartResource(), CSSPrimitiveValue::CSS_URI); return CSSPrimitiveValue::createIdentifier(CSSValueNone); case CSSPropertyStroke: return adjustSVGPaintForCurrentColor(svgStyle.strokePaintType(), svgStyle.strokePaintUri(), svgStyle.strokePaintColor(), style->color()); case CSSPropertyStrokeDasharray: return strokeDashArrayToCSSValueList(svgStyle.strokeDashArray()); case CSSPropertyBaselineShift: { switch (svgStyle.baselineShift()) { case BS_BASELINE: return CSSPrimitiveValue::createIdentifier(CSSValueBaseline); case BS_SUPER: return CSSPrimitiveValue::createIdentifier(CSSValueSuper); case BS_SUB: return CSSPrimitiveValue::createIdentifier(CSSValueSub); case BS_LENGTH: return SVGLengthValue::toCSSPrimitiveValue(svgStyle.baselineShiftValue()); } ASSERT_NOT_REACHED(); return nullptr; } case CSSPropertyBufferedRendering: return CSSPrimitiveValue::create(svgStyle.bufferedRendering()); case CSSPropertyGlyphOrientationHorizontal: return glyphOrientationToCSSPrimitiveValue(svgStyle.glyphOrientationHorizontal()); case CSSPropertyGlyphOrientationVertical: { if (RefPtr value = glyphOrientationToCSSPrimitiveValue(svgStyle.glyphOrientationVertical())) return value; if (svgStyle.glyphOrientationVertical() == GO_AUTO) return CSSPrimitiveValue::createIdentifier(CSSValueAuto); return nullptr; } case CSSPropertyWebkitSvgShadow: return valueForShadow(svgStyle.shadow(), propertyID, *style); case CSSPropertyVectorEffect: return CSSPrimitiveValue::create(svgStyle.vectorEffect()); case CSSPropertyMaskType: return CSSPrimitiveValue::create(svgStyle.maskType()); case CSSPropertyMarker: case CSSPropertyEnableBackground: case CSSPropertyColorProfile: // the above properties are not yet implemented in the engine break; default: // If you crash here, it's because you added a css property and are not handling it // in either this switch statement or the one in CSSComputedStyleDelcaration::getPropertyCSSValue ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propertyID); } LOG_ERROR("unimplemented propertyID: %d", propertyID); return nullptr; } }