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