Home | History | Annotate | Download | only in css
      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