Home | History | Annotate | Download | only in resolver
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "core/css/resolver/AnimatedStyleBuilder.h"
     33 
     34 #include "core/animation/animatable/AnimatableClipPathOperation.h"
     35 #include "core/animation/animatable/AnimatableColor.h"
     36 #include "core/animation/animatable/AnimatableDouble.h"
     37 #include "core/animation/animatable/AnimatableFilterOperations.h"
     38 #include "core/animation/animatable/AnimatableImage.h"
     39 #include "core/animation/animatable/AnimatableLength.h"
     40 #include "core/animation/animatable/AnimatableLengthBox.h"
     41 #include "core/animation/animatable/AnimatableLengthBoxAndBool.h"
     42 #include "core/animation/animatable/AnimatableLengthPoint.h"
     43 #include "core/animation/animatable/AnimatableLengthPoint3D.h"
     44 #include "core/animation/animatable/AnimatableLengthSize.h"
     45 #include "core/animation/animatable/AnimatableRepeatable.h"
     46 #include "core/animation/animatable/AnimatableSVGLength.h"
     47 #include "core/animation/animatable/AnimatableSVGPaint.h"
     48 #include "core/animation/animatable/AnimatableShadow.h"
     49 #include "core/animation/animatable/AnimatableShapeValue.h"
     50 #include "core/animation/animatable/AnimatableStrokeDasharrayList.h"
     51 #include "core/animation/animatable/AnimatableTransform.h"
     52 #include "core/animation/animatable/AnimatableUnknown.h"
     53 #include "core/animation/animatable/AnimatableValue.h"
     54 #include "core/animation/animatable/AnimatableVisibility.h"
     55 #include "core/css/CSSPrimitiveValueMappings.h"
     56 #include "core/css/CSSPropertyMetadata.h"
     57 #include "core/css/resolver/StyleBuilder.h"
     58 #include "core/css/resolver/StyleResolverState.h"
     59 #include "core/rendering/style/RenderStyle.h"
     60 #include "wtf/MathExtras.h"
     61 #include "wtf/TypeTraits.h"
     62 
     63 namespace blink {
     64 
     65 namespace {
     66 
     67 Length animatableValueToLength(const AnimatableValue* value, const StyleResolverState& state, ValueRange range = ValueRangeAll)
     68 {
     69     if (value->isLength())
     70         return toAnimatableLength(value)->length(state.style()->effectiveZoom(), range);
     71     RefPtrWillBeRawPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
     72     CSSPrimitiveValue* cssPrimitiveValue = toCSSPrimitiveValue(cssValue.get());
     73     return cssPrimitiveValue->convertToLength<AnyConversion>(state.cssToLengthConversionData());
     74 }
     75 
     76 BorderImageLength animatableValueToBorderImageLength(const AnimatableValue* value, const StyleResolverState& state)
     77 {
     78     if (value->isLength())
     79         return BorderImageLength(toAnimatableLength(value)->length(state.style()->effectiveZoom(), ValueRangeNonNegative));
     80     if (value->isDouble())
     81         return BorderImageLength(clampTo<double>(toAnimatableDouble(value)->toDouble(), 0));
     82     RefPtrWillBeRawPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
     83     CSSPrimitiveValue* cssPrimitiveValue = toCSSPrimitiveValue(cssValue.get());
     84     return BorderImageLength(cssPrimitiveValue->convertToLength<AnyConversion>(state.cssToLengthConversionData()));
     85 }
     86 
     87 template<typename T> T animatableValueRoundClampTo(const AnimatableValue* value, T min = defaultMinimumForClamp<T>(), T max = defaultMaximumForClamp<T>())
     88 {
     89     COMPILE_ASSERT(WTF::IsInteger<T>::value, ShouldUseIntegralTypeTWhenRoundingValues);
     90     return clampTo<T>(round(toAnimatableDouble(value)->toDouble()), min, max);
     91 }
     92 
     93 LengthBox animatableValueToLengthBox(const AnimatableValue* value, const StyleResolverState& state, ValueRange range = ValueRangeAll)
     94 {
     95     const AnimatableLengthBox* animatableLengthBox = toAnimatableLengthBox(value);
     96     return LengthBox(
     97         animatableValueToLength(animatableLengthBox->top(), state, range),
     98         animatableValueToLength(animatableLengthBox->right(), state, range),
     99         animatableValueToLength(animatableLengthBox->bottom(), state, range),
    100         animatableValueToLength(animatableLengthBox->left(), state, range));
    101 }
    102 
    103 BorderImageLengthBox animatableValueToBorderImageLengthBox(const AnimatableValue* value, const StyleResolverState& state)
    104 {
    105     const AnimatableLengthBox* animatableLengthBox = toAnimatableLengthBox(value);
    106     return BorderImageLengthBox(
    107         animatableValueToBorderImageLength(animatableLengthBox->top(), state),
    108         animatableValueToBorderImageLength(animatableLengthBox->right(), state),
    109         animatableValueToBorderImageLength(animatableLengthBox->bottom(), state),
    110         animatableValueToBorderImageLength(animatableLengthBox->left(), state));
    111 }
    112 
    113 LengthPoint animatableValueToLengthPoint(const AnimatableValue* value, const StyleResolverState& state, ValueRange range = ValueRangeAll)
    114 {
    115     const AnimatableLengthPoint* animatableLengthPoint = toAnimatableLengthPoint(value);
    116     return LengthPoint(
    117         animatableValueToLength(animatableLengthPoint->x(), state, range),
    118         animatableValueToLength(animatableLengthPoint->y(), state, range));
    119 }
    120 
    121 LengthSize animatableValueToLengthSize(const AnimatableValue* value, const StyleResolverState& state, ValueRange range)
    122 {
    123     const AnimatableLengthSize* animatableLengthSize = toAnimatableLengthSize(value);
    124     return LengthSize(
    125         animatableValueToLength(animatableLengthSize->width(), state, range),
    126         animatableValueToLength(animatableLengthSize->height(), state, range));
    127 }
    128 
    129 void setFillSize(FillLayer* fillLayer, const AnimatableValue* value, const StyleResolverState& state)
    130 {
    131     if (value->isLengthSize())
    132         fillLayer->setSize(FillSize(SizeLength, animatableValueToLengthSize(value, state, ValueRangeNonNegative)));
    133     else
    134         state.styleMap().mapFillSize(fillLayer, toAnimatableUnknown(value)->toCSSValue().get());
    135 }
    136 
    137 PassRefPtr<SVGLength> animatableValueToNonNegativeSVGLength(const AnimatableValue* value)
    138 {
    139     RefPtr<SVGLength> length = toAnimatableSVGLength(value)->toSVGLength();
    140     if (length->valueInSpecifiedUnits() < 0)
    141         length->setValueInSpecifiedUnits(0);
    142     return length.release();
    143 }
    144 
    145 template <CSSPropertyID property>
    146 void setOnFillLayers(FillLayer& fillLayers, const AnimatableValue* value, StyleResolverState& state)
    147 {
    148     const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& values = toAnimatableRepeatable(value)->values();
    149     ASSERT(!values.isEmpty());
    150     FillLayer* fillLayer = &fillLayers;
    151     FillLayer* prev = 0;
    152     for (size_t i = 0; i < values.size(); ++i) {
    153         if (!fillLayer)
    154             fillLayer = prev->ensureNext();
    155         const AnimatableValue* layerValue = values[i].get();
    156         switch (property) {
    157         case CSSPropertyBackgroundImage:
    158         case CSSPropertyWebkitMaskImage:
    159             if (layerValue->isImage()) {
    160                 fillLayer->setImage(state.styleImage(property, toAnimatableImage(layerValue)->toCSSValue()));
    161             } else {
    162                 ASSERT(toAnimatableUnknown(layerValue)->toCSSValueID() == CSSValueNone);
    163                 fillLayer->setImage(nullptr);
    164             }
    165             break;
    166         case CSSPropertyBackgroundPositionX:
    167         case CSSPropertyWebkitMaskPositionX:
    168             fillLayer->setXPosition(animatableValueToLength(layerValue, state));
    169             break;
    170         case CSSPropertyBackgroundPositionY:
    171         case CSSPropertyWebkitMaskPositionY:
    172             fillLayer->setYPosition(animatableValueToLength(layerValue, state));
    173             break;
    174         case CSSPropertyBackgroundSize:
    175         case CSSPropertyWebkitBackgroundSize:
    176         case CSSPropertyWebkitMaskSize:
    177             setFillSize(fillLayer, layerValue, state);
    178             break;
    179         default:
    180             ASSERT_NOT_REACHED();
    181         }
    182         prev = fillLayer;
    183         fillLayer = fillLayer->next();
    184     }
    185     while (fillLayer) {
    186         switch (property) {
    187         case CSSPropertyBackgroundImage:
    188         case CSSPropertyWebkitMaskImage:
    189             fillLayer->clearImage();
    190             break;
    191         case CSSPropertyBackgroundPositionX:
    192         case CSSPropertyWebkitMaskPositionX:
    193             fillLayer->clearXPosition();
    194             break;
    195         case CSSPropertyBackgroundPositionY:
    196         case CSSPropertyWebkitMaskPositionY:
    197             fillLayer->clearYPosition();
    198             break;
    199         case CSSPropertyBackgroundSize:
    200         case CSSPropertyWebkitBackgroundSize:
    201         case CSSPropertyWebkitMaskSize:
    202             fillLayer->clearSize();
    203             break;
    204         default:
    205             ASSERT_NOT_REACHED();
    206         }
    207         fillLayer = fillLayer->next();
    208     }
    209 }
    210 
    211 FontStretch animatableValueToFontStretch(const AnimatableValue* value)
    212 {
    213     ASSERT(FontStretchUltraCondensed == 1 && FontStretchUltraExpanded == 9);
    214     unsigned index = round(toAnimatableDouble(value)->toDouble()) - 1;
    215     static const FontStretch stretchValues[] = {
    216         FontStretchUltraCondensed,
    217         FontStretchExtraCondensed,
    218         FontStretchCondensed,
    219         FontStretchSemiCondensed,
    220         FontStretchNormal,
    221         FontStretchSemiExpanded,
    222         FontStretchExpanded,
    223         FontStretchExtraExpanded,
    224         FontStretchUltraExpanded
    225     };
    226 
    227     index = clampTo<unsigned>(index, 0, WTF_ARRAY_LENGTH(stretchValues) - 1);
    228     return stretchValues[index];
    229 }
    230 
    231 FontWeight animatableValueToFontWeight(const AnimatableValue* value)
    232 {
    233     int index = round(toAnimatableDouble(value)->toDouble() / 100) - 1;
    234 
    235     static const FontWeight weights[] = {
    236         FontWeight100,
    237         FontWeight200,
    238         FontWeight300,
    239         FontWeight400,
    240         FontWeight500,
    241         FontWeight600,
    242         FontWeight700,
    243         FontWeight800,
    244         FontWeight900
    245     };
    246 
    247     index = clampTo<int>(index, 0, WTF_ARRAY_LENGTH(weights) - 1);
    248 
    249     return weights[index];
    250 }
    251 
    252 } // namespace
    253 
    254 // FIXME: Generate this function.
    255 void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverState& state, const AnimatableValue* value)
    256 {
    257     ASSERT(CSSPropertyMetadata::isAnimatableProperty(property));
    258     if (value->isUnknown()) {
    259         StyleBuilder::applyProperty(property, state, toAnimatableUnknown(value)->toCSSValue().get());
    260         return;
    261     }
    262     RenderStyle* style = state.style();
    263     switch (property) {
    264     case CSSPropertyBackgroundColor:
    265         style->setBackgroundColor(toAnimatableColor(value)->color());
    266         style->setVisitedLinkBackgroundColor(toAnimatableColor(value)->visitedLinkColor());
    267         return;
    268     case CSSPropertyBackgroundImage:
    269         setOnFillLayers<CSSPropertyBackgroundImage>(style->accessBackgroundLayers(), value, state);
    270         return;
    271     case CSSPropertyBackgroundPositionX:
    272         setOnFillLayers<CSSPropertyBackgroundPositionX>(style->accessBackgroundLayers(), value, state);
    273         return;
    274     case CSSPropertyBackgroundPositionY:
    275         setOnFillLayers<CSSPropertyBackgroundPositionY>(style->accessBackgroundLayers(), value, state);
    276         return;
    277     case CSSPropertyBackgroundSize:
    278         setOnFillLayers<CSSPropertyBackgroundSize>(style->accessBackgroundLayers(), value, state);
    279         return;
    280     case CSSPropertyBaselineShift:
    281         style->setBaselineShiftValue(toAnimatableSVGLength(value)->toSVGLength());
    282         return;
    283     case CSSPropertyBorderBottomColor:
    284         style->setBorderBottomColor(toAnimatableColor(value)->color());
    285         style->setVisitedLinkBorderBottomColor(toAnimatableColor(value)->visitedLinkColor());
    286         return;
    287     case CSSPropertyBorderBottomLeftRadius:
    288         style->setBorderBottomLeftRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
    289         return;
    290     case CSSPropertyBorderBottomRightRadius:
    291         style->setBorderBottomRightRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
    292         return;
    293     case CSSPropertyBorderBottomWidth:
    294         style->setBorderBottomWidth(animatableValueRoundClampTo<unsigned>(value));
    295         return;
    296     case CSSPropertyBorderImageOutset:
    297         style->setBorderImageOutset(animatableValueToBorderImageLengthBox(value, state));
    298         return;
    299     case CSSPropertyBorderImageSlice:
    300         style->setBorderImageSlices(animatableValueToLengthBox(value, state, ValueRangeNonNegative));
    301         return;
    302     case CSSPropertyBorderImageSource:
    303         style->setBorderImageSource(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
    304         return;
    305     case CSSPropertyBorderImageWidth:
    306         style->setBorderImageWidth(animatableValueToBorderImageLengthBox(value, state));
    307         return;
    308     case CSSPropertyBorderLeftColor:
    309         style->setBorderLeftColor(toAnimatableColor(value)->color());
    310         style->setVisitedLinkBorderLeftColor(toAnimatableColor(value)->visitedLinkColor());
    311         return;
    312     case CSSPropertyBorderLeftWidth:
    313         style->setBorderLeftWidth(animatableValueRoundClampTo<unsigned>(value));
    314         return;
    315     case CSSPropertyBorderRightColor:
    316         style->setBorderRightColor(toAnimatableColor(value)->color());
    317         style->setVisitedLinkBorderRightColor(toAnimatableColor(value)->visitedLinkColor());
    318         return;
    319     case CSSPropertyBorderRightWidth:
    320         style->setBorderRightWidth(animatableValueRoundClampTo<unsigned>(value));
    321         return;
    322     case CSSPropertyBorderTopColor:
    323         style->setBorderTopColor(toAnimatableColor(value)->color());
    324         style->setVisitedLinkBorderTopColor(toAnimatableColor(value)->visitedLinkColor());
    325         return;
    326     case CSSPropertyBorderTopLeftRadius:
    327         style->setBorderTopLeftRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
    328         return;
    329     case CSSPropertyBorderTopRightRadius:
    330         style->setBorderTopRightRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
    331         return;
    332     case CSSPropertyBorderTopWidth:
    333         style->setBorderTopWidth(animatableValueRoundClampTo<unsigned>(value));
    334         return;
    335     case CSSPropertyBottom:
    336         style->setBottom(animatableValueToLength(value, state));
    337         return;
    338     case CSSPropertyBoxShadow:
    339     case CSSPropertyWebkitBoxShadow:
    340         style->setBoxShadow(toAnimatableShadow(value)->shadowList());
    341         return;
    342     case CSSPropertyClip:
    343         style->setClip(animatableValueToLengthBox(value, state));
    344         return;
    345     case CSSPropertyColor:
    346         style->setColor(toAnimatableColor(value)->color());
    347         style->setVisitedLinkColor(toAnimatableColor(value)->visitedLinkColor());
    348         return;
    349     case CSSPropertyFillOpacity:
    350         style->setFillOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
    351         return;
    352     case CSSPropertyFill:
    353         {
    354             const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
    355             style->accessSVGStyle().setFillPaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri(), true, false);
    356             style->accessSVGStyle().setFillPaint(svgPaint->visitedLinkPaintType(), svgPaint->visitedLinkColor(), svgPaint->visitedLinkURI(), false, true);
    357         }
    358         return;
    359     case CSSPropertyFlexGrow:
    360         style->setFlexGrow(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
    361         return;
    362     case CSSPropertyFlexShrink:
    363         style->setFlexShrink(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
    364         return;
    365     case CSSPropertyFlexBasis:
    366         style->setFlexBasis(animatableValueToLength(value, state, ValueRangeNonNegative));
    367         return;
    368     case CSSPropertyFloodColor:
    369         style->setFloodColor(toAnimatableColor(value)->color());
    370         return;
    371     case CSSPropertyFloodOpacity:
    372         style->setFloodOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
    373         return;
    374     case CSSPropertyFontSize:
    375         style->setFontSize(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
    376         return;
    377     case CSSPropertyFontStretch:
    378         style->setFontStretch(animatableValueToFontStretch(value));
    379         return;
    380     case CSSPropertyFontWeight:
    381         style->setFontWeight(animatableValueToFontWeight(value));
    382         return;
    383     case CSSPropertyHeight:
    384         style->setHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
    385         return;
    386     case CSSPropertyLeft:
    387         style->setLeft(animatableValueToLength(value, state));
    388         return;
    389     case CSSPropertyLightingColor:
    390         style->setLightingColor(toAnimatableColor(value)->color());
    391         return;
    392     case CSSPropertyLineHeight:
    393         if (value->isLength())
    394             style->setLineHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
    395         else
    396             style->setLineHeight(Length(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0), Percent));
    397         return;
    398     case CSSPropertyListStyleImage:
    399         style->setListStyleImage(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
    400         return;
    401     case CSSPropertyLetterSpacing:
    402         style->setLetterSpacing(clampTo<float>(toAnimatableDouble(value)->toDouble()));
    403         return;
    404     case CSSPropertyMarginBottom:
    405         style->setMarginBottom(animatableValueToLength(value, state));
    406         return;
    407     case CSSPropertyMarginLeft:
    408         style->setMarginLeft(animatableValueToLength(value, state));
    409         return;
    410     case CSSPropertyMarginRight:
    411         style->setMarginRight(animatableValueToLength(value, state));
    412         return;
    413     case CSSPropertyMarginTop:
    414         style->setMarginTop(animatableValueToLength(value, state));
    415         return;
    416     case CSSPropertyMaxHeight:
    417         style->setMaxHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
    418         return;
    419     case CSSPropertyMaxWidth:
    420         style->setMaxWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
    421         return;
    422     case CSSPropertyMinHeight:
    423         style->setMinHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
    424         return;
    425     case CSSPropertyMinWidth:
    426         style->setMinWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
    427         return;
    428     case CSSPropertyObjectPosition:
    429         style->setObjectPosition(animatableValueToLengthPoint(value, state));
    430         return;
    431     case CSSPropertyOpacity:
    432         // Avoiding a value of 1 forces a layer to be created.
    433         style->setOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, nextafterf(1, 0)));
    434         return;
    435     case CSSPropertyOrphans:
    436         style->setOrphans(animatableValueRoundClampTo<unsigned short>(value, 1));
    437         return;
    438     case CSSPropertyOutlineColor:
    439         style->setOutlineColor(toAnimatableColor(value)->color());
    440         style->setVisitedLinkOutlineColor(toAnimatableColor(value)->visitedLinkColor());
    441         return;
    442     case CSSPropertyOutlineOffset:
    443         style->setOutlineOffset(animatableValueRoundClampTo<int>(value));
    444         return;
    445     case CSSPropertyOutlineWidth:
    446         style->setOutlineWidth(animatableValueRoundClampTo<unsigned short>(value));
    447         return;
    448     case CSSPropertyPaddingBottom:
    449         style->setPaddingBottom(animatableValueToLength(value, state, ValueRangeNonNegative));
    450         return;
    451     case CSSPropertyPaddingLeft:
    452         style->setPaddingLeft(animatableValueToLength(value, state, ValueRangeNonNegative));
    453         return;
    454     case CSSPropertyPaddingRight:
    455         style->setPaddingRight(animatableValueToLength(value, state, ValueRangeNonNegative));
    456         return;
    457     case CSSPropertyPaddingTop:
    458         style->setPaddingTop(animatableValueToLength(value, state, ValueRangeNonNegative));
    459         return;
    460     case CSSPropertyRight:
    461         style->setRight(animatableValueToLength(value, state));
    462         return;
    463     case CSSPropertyStrokeWidth:
    464         style->setStrokeWidth(animatableValueToNonNegativeSVGLength(value));
    465         return;
    466     case CSSPropertyStopColor:
    467         style->setStopColor(toAnimatableColor(value)->color());
    468         return;
    469     case CSSPropertyStopOpacity:
    470         style->setStopOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
    471         return;
    472     case CSSPropertyStrokeDasharray:
    473         style->setStrokeDashArray(toAnimatableStrokeDasharrayList(value)->toSVGLengthList());
    474         return;
    475     case CSSPropertyStrokeDashoffset:
    476         style->setStrokeDashOffset(toAnimatableSVGLength(value)->toSVGLength());
    477         return;
    478     case CSSPropertyStrokeMiterlimit:
    479         style->setStrokeMiterLimit(clampTo<float>(toAnimatableDouble(value)->toDouble(), 1));
    480         return;
    481     case CSSPropertyStrokeOpacity:
    482         style->setStrokeOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
    483         return;
    484     case CSSPropertyStroke:
    485         {
    486             const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
    487             style->accessSVGStyle().setStrokePaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri(), true, false);
    488             style->accessSVGStyle().setStrokePaint(svgPaint->visitedLinkPaintType(), svgPaint->visitedLinkColor(), svgPaint->visitedLinkURI(), false, true);
    489         }
    490         return;
    491     case CSSPropertyTextDecorationColor:
    492         style->setTextDecorationColor(toAnimatableColor(value)->color());
    493         style->setVisitedLinkTextDecorationColor(toAnimatableColor(value)->visitedLinkColor());
    494         return;
    495     case CSSPropertyTextIndent:
    496         style->setTextIndent(animatableValueToLength(value, state));
    497         return;
    498     case CSSPropertyTextShadow:
    499         style->setTextShadow(toAnimatableShadow(value)->shadowList());
    500         return;
    501     case CSSPropertyTop:
    502         style->setTop(animatableValueToLength(value, state));
    503         return;
    504     case CSSPropertyWebkitBackgroundSize:
    505         setOnFillLayers<CSSPropertyWebkitBackgroundSize>(style->accessBackgroundLayers(), value, state);
    506         return;
    507     case CSSPropertyWebkitBorderHorizontalSpacing:
    508         style->setHorizontalBorderSpacing(animatableValueRoundClampTo<unsigned short>(value));
    509         return;
    510     case CSSPropertyWebkitBorderVerticalSpacing:
    511         style->setVerticalBorderSpacing(animatableValueRoundClampTo<unsigned short>(value));
    512         return;
    513     case CSSPropertyWebkitClipPath:
    514         style->setClipPath(toAnimatableClipPathOperation(value)->clipPathOperation());
    515         return;
    516     case CSSPropertyWebkitColumnCount:
    517         style->setColumnCount(animatableValueRoundClampTo<unsigned short>(value, 1));
    518         return;
    519     case CSSPropertyWebkitColumnGap:
    520         style->setColumnGap(clampTo(toAnimatableDouble(value)->toDouble(), 0));
    521         return;
    522     case CSSPropertyWebkitColumnRuleColor:
    523         style->setColumnRuleColor(toAnimatableColor(value)->color());
    524         style->setVisitedLinkColumnRuleColor(toAnimatableColor(value)->visitedLinkColor());
    525         return;
    526     case CSSPropertyWebkitColumnWidth:
    527         style->setColumnWidth(clampTo(toAnimatableDouble(value)->toDouble(), std::numeric_limits<float>::epsilon()));
    528         return;
    529     case CSSPropertyWebkitColumnRuleWidth:
    530         style->setColumnRuleWidth(animatableValueRoundClampTo<unsigned short>(value));
    531         return;
    532     case CSSPropertyWebkitFilter:
    533         style->setFilter(toAnimatableFilterOperations(value)->operations());
    534         return;
    535     case CSSPropertyWebkitMaskBoxImageOutset:
    536         style->setMaskBoxImageOutset(animatableValueToBorderImageLengthBox(value, state));
    537         return;
    538     case CSSPropertyWebkitMaskBoxImageSlice:
    539         style->setMaskBoxImageSlices(animatableValueToLengthBox(toAnimatableLengthBoxAndBool(value)->box(), state, ValueRangeNonNegative));
    540         style->setMaskBoxImageSlicesFill(toAnimatableLengthBoxAndBool(value)->flag());
    541         return;
    542     case CSSPropertyWebkitMaskBoxImageSource:
    543         style->setMaskBoxImageSource(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
    544         return;
    545     case CSSPropertyWebkitMaskBoxImageWidth:
    546         style->setMaskBoxImageWidth(animatableValueToBorderImageLengthBox(value, state));
    547         return;
    548     case CSSPropertyWebkitMaskImage:
    549         setOnFillLayers<CSSPropertyWebkitMaskImage>(style->accessMaskLayers(), value, state);
    550         return;
    551     case CSSPropertyWebkitMaskPositionX:
    552         setOnFillLayers<CSSPropertyWebkitMaskPositionX>(style->accessMaskLayers(), value, state);
    553         return;
    554     case CSSPropertyWebkitMaskPositionY:
    555         setOnFillLayers<CSSPropertyWebkitMaskPositionY>(style->accessMaskLayers(), value, state);
    556         return;
    557     case CSSPropertyWebkitMaskSize:
    558         setOnFillLayers<CSSPropertyWebkitMaskSize>(style->accessMaskLayers(), value, state);
    559         return;
    560     case CSSPropertyPerspective:
    561         style->setPerspective(clampTo<float>(toAnimatableDouble(value)->toDouble()));
    562         return;
    563     case CSSPropertyPerspectiveOrigin: {
    564         const AnimatableLengthPoint* animatableLengthPoint = toAnimatableLengthPoint(value);
    565         style->setPerspectiveOriginX(animatableValueToLength(animatableLengthPoint->x(), state));
    566         style->setPerspectiveOriginY(animatableValueToLength(animatableLengthPoint->y(), state));
    567         return;
    568     }
    569     case CSSPropertyShapeOutside:
    570         style->setShapeOutside(toAnimatableShapeValue(value)->shapeValue());
    571         return;
    572     case CSSPropertyShapeMargin:
    573         style->setShapeMargin(animatableValueToLength(value, state, ValueRangeNonNegative));
    574         return;
    575     case CSSPropertyShapeImageThreshold:
    576         style->setShapeImageThreshold(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
    577         return;
    578     case CSSPropertyWebkitTextStrokeColor:
    579         style->setTextStrokeColor(toAnimatableColor(value)->color());
    580         style->setVisitedLinkTextStrokeColor(toAnimatableColor(value)->visitedLinkColor());
    581         return;
    582     case CSSPropertyTransform: {
    583         const TransformOperations& operations = toAnimatableTransform(value)->transformOperations();
    584         // FIXME: This normalization (handling of 'none') should be performed at input in AnimatableValueFactory.
    585         style->setTransform(operations.size() ? operations : TransformOperations(true));
    586         return;
    587     }
    588     case CSSPropertyTransformOrigin: {
    589         const AnimatableLengthPoint3D* animatableLengthPoint3D = toAnimatableLengthPoint3D(value);
    590         style->setTransformOriginX(animatableValueToLength(animatableLengthPoint3D->x(), state));
    591         style->setTransformOriginY(animatableValueToLength(animatableLengthPoint3D->y(), state));
    592         style->setTransformOriginZ(clampTo<float>(toAnimatableDouble(animatableLengthPoint3D->z())->toDouble()));
    593         return;
    594     }
    595     case CSSPropertyWidows:
    596         style->setWidows(animatableValueRoundClampTo<unsigned short>(value, 1));
    597         return;
    598     case CSSPropertyWidth:
    599         style->setWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
    600         return;
    601     case CSSPropertyWordSpacing:
    602         style->setWordSpacing(clampTo<float>(toAnimatableDouble(value)->toDouble()));
    603         return;
    604     case CSSPropertyVerticalAlign:
    605         style->setVerticalAlignLength(animatableValueToLength(value, state));
    606         return;
    607     case CSSPropertyVisibility:
    608         style->setVisibility(toAnimatableVisibility(value)->visibility());
    609         return;
    610     case CSSPropertyZIndex:
    611         style->setZIndex(animatableValueRoundClampTo<int>(value));
    612         return;
    613     case CSSPropertyZoom:
    614         style->setZoom(clampTo<float>(toAnimatableDouble(value)->toDouble(), std::numeric_limits<float>::denorm_min()));
    615         return;
    616     default:
    617         ASSERT_NOT_REACHED();
    618     }
    619 }
    620 
    621 } // namespace blink
    622