| 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 "CSSValueList.h" |
| 27 | #include "Document.h" |
| 28 | #include "Element.h" |
| 29 | #include "RenderStyle.h" |
| 30 | |
| 31 | namespace WebCore { |
| 32 | |
| 33 | static RefPtr<CSSPrimitiveValue> glyphOrientationToCSSPrimitiveValue(GlyphOrientation orientation) |
| 34 | { |
| 35 | switch (orientation) { |
| 36 | case GlyphOrientation::Degrees0: |
| 37 | return CSSPrimitiveValue::create(0.0f, CSSPrimitiveValue::CSS_DEG); |
| 38 | case GlyphOrientation::Degrees90: |
| 39 | return CSSPrimitiveValue::create(90.0f, CSSPrimitiveValue::CSS_DEG); |
| 40 | case GlyphOrientation::Degrees180: |
| 41 | return CSSPrimitiveValue::create(180.0f, CSSPrimitiveValue::CSS_DEG); |
| 42 | case GlyphOrientation::Degrees270: |
| 43 | return CSSPrimitiveValue::create(270.0f, CSSPrimitiveValue::CSS_DEG); |
| 44 | case GlyphOrientation::Auto: |
| 45 | return nullptr; |
| 46 | } |
| 47 | |
| 48 | RELEASE_ASSERT_NOT_REACHED(); |
| 49 | } |
| 50 | |
| 51 | static Ref<CSSValue> strokeDashArrayToCSSValueList(const Vector<SVGLengthValue>& dashes) |
| 52 | { |
| 53 | if (dashes.isEmpty()) |
| 54 | return CSSPrimitiveValue::createIdentifier(CSSValueNone); |
| 55 | |
| 56 | auto list = CSSValueList::createCommaSeparated(); |
| 57 | for (auto& length : dashes) |
| 58 | list->append(SVGLengthValue::toCSSPrimitiveValue(length)); |
| 59 | |
| 60 | return list; |
| 61 | } |
| 62 | |
| 63 | Ref<CSSValue> ComputedStyleExtractor::(SVGPaintType paintType, const String& url, const Color& color, const Color& currentColor) const |
| 64 | { |
| 65 | if (paintType >= SVGPaintType::URINone) { |
| 66 | auto values = CSSValueList::createSpaceSeparated(); |
| 67 | values->append(CSSPrimitiveValue::create(url, CSSPrimitiveValue::UnitType::CSS_URI)); |
| 68 | if (paintType == SVGPaintType::URINone) |
| 69 | values->append(CSSPrimitiveValue::createIdentifier(CSSValueNone)); |
| 70 | else if (paintType == SVGPaintType::URICurrentColor) |
| 71 | values->append(CSSPrimitiveValue::create(currentColor)); |
| 72 | else if (paintType == SVGPaintType::URIRGBColor) |
| 73 | values->append(CSSPrimitiveValue::create(color)); |
| 74 | return values; |
| 75 | } |
| 76 | if (paintType == SVGPaintType::None) |
| 77 | return CSSPrimitiveValue::createIdentifier(CSSValueNone); |
| 78 | if (paintType == SVGPaintType::CurrentColor) |
| 79 | return CSSPrimitiveValue::create(currentColor); |
| 80 | |
| 81 | return CSSPrimitiveValue::create(color); |
| 82 | } |
| 83 | |
| 84 | RefPtr<CSSValue> ComputedStyleExtractor::(CSSPropertyID propertyID, EUpdateLayout updateLayout) |
| 85 | { |
| 86 | if (!m_element) |
| 87 | return nullptr; |
| 88 | |
| 89 | // Make sure our layout is up to date before we allow a query on these attributes. |
| 90 | if (updateLayout) |
| 91 | m_element->document().updateLayout(); |
| 92 | |
| 93 | auto* style = m_element->computedStyle(); |
| 94 | if (!style) |
| 95 | return nullptr; |
| 96 | |
| 97 | const SVGRenderStyle& svgStyle = style->svgStyle(); |
| 98 | |
| 99 | switch (propertyID) { |
| 100 | case CSSPropertyClipRule: |
| 101 | return CSSPrimitiveValue::create(svgStyle.clipRule()); |
| 102 | case CSSPropertyFloodOpacity: |
| 103 | return CSSPrimitiveValue::create(svgStyle.floodOpacity(), CSSPrimitiveValue::CSS_NUMBER); |
| 104 | case CSSPropertyStopOpacity: |
| 105 | return CSSPrimitiveValue::create(svgStyle.stopOpacity(), CSSPrimitiveValue::CSS_NUMBER); |
| 106 | case CSSPropertyColorInterpolation: |
| 107 | return CSSPrimitiveValue::create(svgStyle.colorInterpolation()); |
| 108 | case CSSPropertyColorInterpolationFilters: |
| 109 | return CSSPrimitiveValue::create(svgStyle.colorInterpolationFilters()); |
| 110 | case CSSPropertyFillOpacity: |
| 111 | return CSSPrimitiveValue::create(svgStyle.fillOpacity(), CSSPrimitiveValue::CSS_NUMBER); |
| 112 | case CSSPropertyFillRule: |
| 113 | return CSSPrimitiveValue::create(svgStyle.fillRule()); |
| 114 | case CSSPropertyColorRendering: |
| 115 | return CSSPrimitiveValue::create(svgStyle.colorRendering()); |
| 116 | case CSSPropertyShapeRendering: |
| 117 | return CSSPrimitiveValue::create(svgStyle.shapeRendering()); |
| 118 | case CSSPropertyStrokeOpacity: |
| 119 | return CSSPrimitiveValue::create(svgStyle.strokeOpacity(), CSSPrimitiveValue::CSS_NUMBER); |
| 120 | case CSSPropertyAlignmentBaseline: |
| 121 | return CSSPrimitiveValue::create(svgStyle.alignmentBaseline()); |
| 122 | case CSSPropertyDominantBaseline: |
| 123 | return CSSPrimitiveValue::create(svgStyle.dominantBaseline()); |
| 124 | case CSSPropertyTextAnchor: |
| 125 | return CSSPrimitiveValue::create(svgStyle.textAnchor()); |
| 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 CSSPropertyFloodColor: |
| 135 | return currentColorOrValidColor(style, svgStyle.floodColor()); |
| 136 | case CSSPropertyLightingColor: |
| 137 | return currentColorOrValidColor(style, svgStyle.lightingColor()); |
| 138 | case CSSPropertyStopColor: |
| 139 | return currentColorOrValidColor(style, svgStyle.stopColor()); |
| 140 | case CSSPropertyFill: |
| 141 | return adjustSVGPaintForCurrentColor(svgStyle.fillPaintType(), svgStyle.fillPaintUri(), svgStyle.fillPaintColor(), style->color()); |
| 142 | case CSSPropertyKerning: |
| 143 | return SVGLengthValue::toCSSPrimitiveValue(svgStyle.kerning()); |
| 144 | case CSSPropertyMarkerEnd: |
| 145 | if (!svgStyle.markerEndResource().isEmpty()) |
| 146 | return CSSPrimitiveValue::create(svgStyle.markerEndResource(), CSSPrimitiveValue::CSS_URI); |
| 147 | return CSSPrimitiveValue::createIdentifier(CSSValueNone); |
| 148 | case CSSPropertyMarkerMid: |
| 149 | if (!svgStyle.markerMidResource().isEmpty()) |
| 150 | return CSSPrimitiveValue::create(svgStyle.markerMidResource(), CSSPrimitiveValue::CSS_URI); |
| 151 | return CSSPrimitiveValue::createIdentifier(CSSValueNone); |
| 152 | case CSSPropertyMarkerStart: |
| 153 | if (!svgStyle.markerStartResource().isEmpty()) |
| 154 | return CSSPrimitiveValue::create(svgStyle.markerStartResource(), CSSPrimitiveValue::CSS_URI); |
| 155 | return CSSPrimitiveValue::createIdentifier(CSSValueNone); |
| 156 | case CSSPropertyStroke: |
| 157 | return adjustSVGPaintForCurrentColor(svgStyle.strokePaintType(), svgStyle.strokePaintUri(), svgStyle.strokePaintColor(), style->color()); |
| 158 | case CSSPropertyStrokeDasharray: |
| 159 | return strokeDashArrayToCSSValueList(svgStyle.strokeDashArray()); |
| 160 | case CSSPropertyBaselineShift: { |
| 161 | switch (svgStyle.baselineShift()) { |
| 162 | case BaselineShift::Baseline: |
| 163 | return CSSPrimitiveValue::createIdentifier(CSSValueBaseline); |
| 164 | case BaselineShift::Super: |
| 165 | return CSSPrimitiveValue::createIdentifier(CSSValueSuper); |
| 166 | case BaselineShift::Sub: |
| 167 | return CSSPrimitiveValue::createIdentifier(CSSValueSub); |
| 168 | case BaselineShift::Length: |
| 169 | return SVGLengthValue::toCSSPrimitiveValue(svgStyle.baselineShiftValue()); |
| 170 | } |
| 171 | ASSERT_NOT_REACHED(); |
| 172 | return nullptr; |
| 173 | } |
| 174 | case CSSPropertyBufferedRendering: |
| 175 | return CSSPrimitiveValue::create(svgStyle.bufferedRendering()); |
| 176 | case CSSPropertyGlyphOrientationHorizontal: |
| 177 | return glyphOrientationToCSSPrimitiveValue(svgStyle.glyphOrientationHorizontal()); |
| 178 | case CSSPropertyGlyphOrientationVertical: { |
| 179 | if (RefPtr<CSSPrimitiveValue> value = glyphOrientationToCSSPrimitiveValue(svgStyle.glyphOrientationVertical())) |
| 180 | return value; |
| 181 | |
| 182 | if (svgStyle.glyphOrientationVertical() == GlyphOrientation::Auto) |
| 183 | return CSSPrimitiveValue::createIdentifier(CSSValueAuto); |
| 184 | |
| 185 | return nullptr; |
| 186 | } |
| 187 | case CSSPropertyVectorEffect: |
| 188 | return CSSPrimitiveValue::create(svgStyle.vectorEffect()); |
| 189 | case CSSPropertyMaskType: |
| 190 | return CSSPrimitiveValue::create(svgStyle.maskType()); |
| 191 | case CSSPropertyMarker: |
| 192 | case CSSPropertyEnableBackground: |
| 193 | case CSSPropertyColorProfile: |
| 194 | // the above properties are not yet implemented in the engine |
| 195 | break; |
| 196 | default: |
| 197 | // If you crash here, it's because you added a css property and are not handling it |
| 198 | // in either this switch statement or the one in CSSComputedStyleDelcaration::getPropertyCSSValue |
| 199 | ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d" , propertyID); |
| 200 | } |
| 201 | LOG_ERROR("unimplemented propertyID: %d" , propertyID); |
| 202 | return nullptr; |
| 203 | } |
| 204 | |
| 205 | } |
| 206 | |