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/AnimatableClipPathOperation.h"
35#include "core/animation/AnimatableColor.h"
36#include "core/animation/AnimatableDouble.h"
37#include "core/animation/AnimatableFilterOperations.h"
38#include "core/animation/AnimatableImage.h"
39#include "core/animation/AnimatableLength.h"
40#include "core/animation/AnimatableLengthBox.h"
41#include "core/animation/AnimatableLengthBoxAndBool.h"
42#include "core/animation/AnimatableLengthPoint.h"
43#include "core/animation/AnimatableLengthPoint3D.h"
44#include "core/animation/AnimatableLengthSize.h"
45#include "core/animation/AnimatableRepeatable.h"
46#include "core/animation/AnimatableSVGLength.h"
47#include "core/animation/AnimatableSVGPaint.h"
48#include "core/animation/AnimatableShadow.h"
49#include "core/animation/AnimatableShapeValue.h"
50#include "core/animation/AnimatableStrokeDasharrayList.h"
51#include "core/animation/AnimatableTransform.h"
52#include "core/animation/AnimatableUnknown.h"
53#include "core/animation/AnimatableValue.h"
54#include "core/animation/AnimatableVisibility.h"
55#include "core/animation/css/CSSAnimations.h"
56#include "core/css/CSSPrimitiveValueMappings.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
63namespace WebCore {
64
65namespace {
66
67Length 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
76BorderImageLength 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
87template<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
93LengthBox 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
103BorderImageLengthBox 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
113LengthPoint 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
121LengthSize 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
129template <CSSPropertyID property>
130void setFillSize(FillLayer* fillLayer, const AnimatableValue* value, const StyleResolverState& state)
131{
132    if (value->isLengthSize())
133        fillLayer->setSize(FillSize(SizeLength, animatableValueToLengthSize(value, state, ValueRangeNonNegative)));
134    else
135        state.styleMap().mapFillSize(property, fillLayer, toAnimatableUnknown(value)->toCSSValue().get());
136}
137
138PassRefPtr<SVGLength> animatableValueToNonNegativeSVGLength(const AnimatableValue* value)
139{
140    RefPtr<SVGLength> length = toAnimatableSVGLength(value)->toSVGLength();
141    if (length->valueInSpecifiedUnits() < 0)
142        length->setValueInSpecifiedUnits(0);
143    return length.release();
144}
145
146template <CSSPropertyID property>
147void setOnFillLayers(FillLayer* fillLayer, const AnimatableValue* value, StyleResolverState& state)
148{
149    const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& values = toAnimatableRepeatable(value)->values();
150    ASSERT(!values.isEmpty());
151    FillLayer* prev = 0;
152    for (size_t i = 0; i < values.size(); ++i) {
153        if (!fillLayer) {
154            switch (property) {
155            case CSSPropertyBackgroundImage:
156            case CSSPropertyBackgroundPositionX:
157            case CSSPropertyBackgroundPositionY:
158            case CSSPropertyBackgroundSize:
159            case CSSPropertyWebkitBackgroundSize:
160                fillLayer = new FillLayer(BackgroundFillLayer);
161                break;
162            case CSSPropertyWebkitMaskImage:
163            case CSSPropertyWebkitMaskPositionX:
164            case CSSPropertyWebkitMaskPositionY:
165            case CSSPropertyWebkitMaskSize:
166                fillLayer = new FillLayer(MaskFillLayer);
167                break;
168            default:
169                ASSERT_NOT_REACHED();
170            }
171            prev->setNext(fillLayer);
172        }
173        const AnimatableValue* layerValue = values[i].get();
174        switch (property) {
175        case CSSPropertyBackgroundImage:
176        case CSSPropertyWebkitMaskImage:
177            if (layerValue->isImage()) {
178                fillLayer->setImage(state.styleImage(property, toAnimatableImage(layerValue)->toCSSValue()));
179            } else {
180                ASSERT(toAnimatableUnknown(layerValue)->toCSSValueID() == CSSValueNone);
181                fillLayer->setImage(nullptr);
182            }
183            break;
184        case CSSPropertyBackgroundPositionX:
185        case CSSPropertyWebkitMaskPositionX:
186            fillLayer->setXPosition(animatableValueToLength(layerValue, state));
187            break;
188        case CSSPropertyBackgroundPositionY:
189        case CSSPropertyWebkitMaskPositionY:
190            fillLayer->setYPosition(animatableValueToLength(layerValue, state));
191            break;
192        case CSSPropertyBackgroundSize:
193        case CSSPropertyWebkitBackgroundSize:
194        case CSSPropertyWebkitMaskSize:
195            setFillSize<property>(fillLayer, layerValue, state);
196            break;
197        default:
198            ASSERT_NOT_REACHED();
199        }
200        prev = fillLayer;
201        fillLayer = fillLayer->next();
202    }
203    while (fillLayer) {
204        switch (property) {
205        case CSSPropertyBackgroundImage:
206        case CSSPropertyWebkitMaskImage:
207            fillLayer->clearImage();
208            break;
209        case CSSPropertyBackgroundPositionX:
210        case CSSPropertyWebkitMaskPositionX:
211            fillLayer->clearXPosition();
212            break;
213        case CSSPropertyBackgroundPositionY:
214        case CSSPropertyWebkitMaskPositionY:
215            fillLayer->clearYPosition();
216            break;
217        case CSSPropertyBackgroundSize:
218        case CSSPropertyWebkitBackgroundSize:
219        case CSSPropertyWebkitMaskSize:
220            fillLayer->clearSize();
221            break;
222        default:
223            ASSERT_NOT_REACHED();
224        }
225        fillLayer = fillLayer->next();
226    }
227}
228
229FontWeight animatableValueToFontWeight(const AnimatableValue* value)
230{
231    int index = round(toAnimatableDouble(value)->toDouble() / 100) - 1;
232
233    static const FontWeight weights[] = {
234        FontWeight100,
235        FontWeight200,
236        FontWeight300,
237        FontWeight400,
238        FontWeight500,
239        FontWeight600,
240        FontWeight700,
241        FontWeight800,
242        FontWeight900
243    };
244
245    index = clampTo<int>(index, 0, WTF_ARRAY_LENGTH(weights) - 1);
246
247    return weights[index];
248}
249
250} // namespace
251
252// FIXME: Generate this function.
253void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverState& state, const AnimatableValue* value)
254{
255    ASSERT(CSSAnimations::isAnimatableProperty(property));
256    if (value->isUnknown()) {
257        StyleBuilder::applyProperty(property, state, toAnimatableUnknown(value)->toCSSValue().get());
258        return;
259    }
260    RenderStyle* style = state.style();
261    switch (property) {
262    case CSSPropertyBackgroundColor:
263        style->setBackgroundColor(toAnimatableColor(value)->color());
264        style->setVisitedLinkBackgroundColor(toAnimatableColor(value)->visitedLinkColor());
265        return;
266    case CSSPropertyBackgroundImage:
267        setOnFillLayers<CSSPropertyBackgroundImage>(style->accessBackgroundLayers(), value, state);
268        return;
269    case CSSPropertyBackgroundPositionX:
270        setOnFillLayers<CSSPropertyBackgroundPositionX>(style->accessBackgroundLayers(), value, state);
271        return;
272    case CSSPropertyBackgroundPositionY:
273        setOnFillLayers<CSSPropertyBackgroundPositionY>(style->accessBackgroundLayers(), value, state);
274        return;
275    case CSSPropertyBackgroundSize:
276        setOnFillLayers<CSSPropertyBackgroundSize>(style->accessBackgroundLayers(), value, state);
277        return;
278    case CSSPropertyBaselineShift:
279        style->setBaselineShiftValue(toAnimatableSVGLength(value)->toSVGLength());
280        return;
281    case CSSPropertyBorderBottomColor:
282        style->setBorderBottomColor(toAnimatableColor(value)->color());
283        style->setVisitedLinkBorderBottomColor(toAnimatableColor(value)->visitedLinkColor());
284        return;
285    case CSSPropertyBorderBottomLeftRadius:
286        style->setBorderBottomLeftRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
287        return;
288    case CSSPropertyBorderBottomRightRadius:
289        style->setBorderBottomRightRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
290        return;
291    case CSSPropertyBorderBottomWidth:
292        style->setBorderBottomWidth(animatableValueRoundClampTo<unsigned>(value));
293        return;
294    case CSSPropertyBorderImageOutset:
295        style->setBorderImageOutset(animatableValueToBorderImageLengthBox(value, state));
296        return;
297    case CSSPropertyBorderImageSlice:
298        style->setBorderImageSlices(animatableValueToLengthBox(value, state, ValueRangeNonNegative));
299        return;
300    case CSSPropertyBorderImageSource:
301        style->setBorderImageSource(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
302        return;
303    case CSSPropertyBorderImageWidth:
304        style->setBorderImageWidth(animatableValueToBorderImageLengthBox(value, state));
305        return;
306    case CSSPropertyBorderLeftColor:
307        style->setBorderLeftColor(toAnimatableColor(value)->color());
308        style->setVisitedLinkBorderLeftColor(toAnimatableColor(value)->visitedLinkColor());
309        return;
310    case CSSPropertyBorderLeftWidth:
311        style->setBorderLeftWidth(animatableValueRoundClampTo<unsigned>(value));
312        return;
313    case CSSPropertyBorderRightColor:
314        style->setBorderRightColor(toAnimatableColor(value)->color());
315        style->setVisitedLinkBorderRightColor(toAnimatableColor(value)->visitedLinkColor());
316        return;
317    case CSSPropertyBorderRightWidth:
318        style->setBorderRightWidth(animatableValueRoundClampTo<unsigned>(value));
319        return;
320    case CSSPropertyBorderTopColor:
321        style->setBorderTopColor(toAnimatableColor(value)->color());
322        style->setVisitedLinkBorderTopColor(toAnimatableColor(value)->visitedLinkColor());
323        return;
324    case CSSPropertyBorderTopLeftRadius:
325        style->setBorderTopLeftRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
326        return;
327    case CSSPropertyBorderTopRightRadius:
328        style->setBorderTopRightRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
329        return;
330    case CSSPropertyBorderTopWidth:
331        style->setBorderTopWidth(animatableValueRoundClampTo<unsigned>(value));
332        return;
333    case CSSPropertyBottom:
334        style->setBottom(animatableValueToLength(value, state));
335        return;
336    case CSSPropertyBoxShadow:
337    case CSSPropertyWebkitBoxShadow:
338        style->setBoxShadow(toAnimatableShadow(value)->shadowList());
339        return;
340    case CSSPropertyClip:
341        style->setClip(animatableValueToLengthBox(value, state));
342        style->setHasClip(true);
343        return;
344    case CSSPropertyColor:
345        style->setColor(toAnimatableColor(value)->color());
346        style->setVisitedLinkColor(toAnimatableColor(value)->visitedLinkColor());
347        return;
348    case CSSPropertyFillOpacity:
349        style->setFillOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
350        return;
351    case CSSPropertyFill:
352        {
353            const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
354            style->accessSVGStyle()->setFillPaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri(), true, false);
355            style->accessSVGStyle()->setFillPaint(svgPaint->visitedLinkPaintType(), svgPaint->visitedLinkColor(), svgPaint->visitedLinkURI(), false, true);
356        }
357        return;
358    case CSSPropertyFlexGrow:
359        style->setFlexGrow(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
360        return;
361    case CSSPropertyFlexShrink:
362        style->setFlexShrink(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
363        return;
364    case CSSPropertyFlexBasis:
365        style->setFlexBasis(animatableValueToLength(value, state, ValueRangeNonNegative));
366        return;
367    case CSSPropertyFloodColor:
368        style->setFloodColor(toAnimatableColor(value)->color());
369        return;
370    case CSSPropertyFloodOpacity:
371        style->setFloodOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
372        return;
373    case CSSPropertyFontSize:
374        style->setFontSize(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
375        return;
376    case CSSPropertyFontWeight:
377        style->setFontWeight(animatableValueToFontWeight(value));
378        return;
379    case CSSPropertyHeight:
380        style->setHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
381        return;
382    case CSSPropertyLeft:
383        style->setLeft(animatableValueToLength(value, state));
384        return;
385    case CSSPropertyLightingColor:
386        style->setLightingColor(toAnimatableColor(value)->color());
387        return;
388    case CSSPropertyLineHeight:
389        if (value->isLength())
390            style->setLineHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
391        else
392            style->setLineHeight(Length(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0), Percent));
393        return;
394    case CSSPropertyListStyleImage:
395        style->setListStyleImage(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
396        return;
397    case CSSPropertyLetterSpacing:
398        style->setLetterSpacing(clampTo<float>(toAnimatableDouble(value)->toDouble()));
399        return;
400    case CSSPropertyMarginBottom:
401        style->setMarginBottom(animatableValueToLength(value, state));
402        return;
403    case CSSPropertyMarginLeft:
404        style->setMarginLeft(animatableValueToLength(value, state));
405        return;
406    case CSSPropertyMarginRight:
407        style->setMarginRight(animatableValueToLength(value, state));
408        return;
409    case CSSPropertyMarginTop:
410        style->setMarginTop(animatableValueToLength(value, state));
411        return;
412    case CSSPropertyMaxHeight:
413        style->setMaxHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
414        return;
415    case CSSPropertyMaxWidth:
416        style->setMaxWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
417        return;
418    case CSSPropertyMinHeight:
419        style->setMinHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
420        return;
421    case CSSPropertyMinWidth:
422        style->setMinWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
423        return;
424    case CSSPropertyObjectPosition:
425        style->setObjectPosition(animatableValueToLengthPoint(value, state));
426        return;
427    case CSSPropertyOpacity:
428        // Avoiding a value of 1 forces a layer to be created.
429        style->setOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, nextafterf(1, 0)));
430        return;
431    case CSSPropertyOrphans:
432        style->setOrphans(animatableValueRoundClampTo<unsigned short>(value, 1));
433        return;
434    case CSSPropertyOutlineColor:
435        style->setOutlineColor(toAnimatableColor(value)->color());
436        style->setVisitedLinkOutlineColor(toAnimatableColor(value)->visitedLinkColor());
437        return;
438    case CSSPropertyOutlineOffset:
439        style->setOutlineOffset(animatableValueRoundClampTo<int>(value));
440        return;
441    case CSSPropertyOutlineWidth:
442        style->setOutlineWidth(animatableValueRoundClampTo<unsigned short>(value));
443        return;
444    case CSSPropertyPaddingBottom:
445        style->setPaddingBottom(animatableValueToLength(value, state, ValueRangeNonNegative));
446        return;
447    case CSSPropertyPaddingLeft:
448        style->setPaddingLeft(animatableValueToLength(value, state, ValueRangeNonNegative));
449        return;
450    case CSSPropertyPaddingRight:
451        style->setPaddingRight(animatableValueToLength(value, state, ValueRangeNonNegative));
452        return;
453    case CSSPropertyPaddingTop:
454        style->setPaddingTop(animatableValueToLength(value, state, ValueRangeNonNegative));
455        return;
456    case CSSPropertyRight:
457        style->setRight(animatableValueToLength(value, state));
458        return;
459    case CSSPropertyStrokeWidth:
460        style->setStrokeWidth(animatableValueToNonNegativeSVGLength(value));
461        return;
462    case CSSPropertyStopColor:
463        style->setStopColor(toAnimatableColor(value)->color());
464        return;
465    case CSSPropertyStopOpacity:
466        style->setStopOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
467        return;
468    case CSSPropertyStrokeDasharray:
469        style->setStrokeDashArray(toAnimatableStrokeDasharrayList(value)->toSVGLengthList());
470        return;
471    case CSSPropertyStrokeDashoffset:
472        style->setStrokeDashOffset(toAnimatableSVGLength(value)->toSVGLength());
473        return;
474    case CSSPropertyStrokeMiterlimit:
475        style->setStrokeMiterLimit(clampTo<float>(toAnimatableDouble(value)->toDouble(), 1));
476        return;
477    case CSSPropertyStrokeOpacity:
478        style->setStrokeOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
479        return;
480    case CSSPropertyStroke:
481        {
482            const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
483            style->accessSVGStyle()->setStrokePaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri(), true, false);
484            style->accessSVGStyle()->setStrokePaint(svgPaint->visitedLinkPaintType(), svgPaint->visitedLinkColor(), svgPaint->visitedLinkURI(), false, true);
485        }
486        return;
487    case CSSPropertyTextDecorationColor:
488        style->setTextDecorationColor(toAnimatableColor(value)->color());
489        style->setVisitedLinkTextDecorationColor(toAnimatableColor(value)->visitedLinkColor());
490        return;
491    case CSSPropertyTextIndent:
492        style->setTextIndent(animatableValueToLength(value, state));
493        return;
494    case CSSPropertyTextShadow:
495        style->setTextShadow(toAnimatableShadow(value)->shadowList());
496        return;
497    case CSSPropertyTop:
498        style->setTop(animatableValueToLength(value, state));
499        return;
500    case CSSPropertyWebkitBackgroundSize:
501        setOnFillLayers<CSSPropertyWebkitBackgroundSize>(style->accessBackgroundLayers(), value, state);
502        return;
503    case CSSPropertyWebkitBorderHorizontalSpacing:
504        style->setHorizontalBorderSpacing(animatableValueRoundClampTo<unsigned short>(value));
505        return;
506    case CSSPropertyWebkitBorderVerticalSpacing:
507        style->setVerticalBorderSpacing(animatableValueRoundClampTo<unsigned short>(value));
508        return;
509    case CSSPropertyWebkitClipPath:
510        style->setClipPath(toAnimatableClipPathOperation(value)->clipPathOperation());
511        return;
512    case CSSPropertyWebkitColumnCount:
513        style->setColumnCount(animatableValueRoundClampTo<unsigned short>(value, 1));
514        return;
515    case CSSPropertyWebkitColumnGap:
516        style->setColumnGap(clampTo(toAnimatableDouble(value)->toDouble(), 0));
517        return;
518    case CSSPropertyWebkitColumnRuleColor:
519        style->setColumnRuleColor(toAnimatableColor(value)->color());
520        style->setVisitedLinkColumnRuleColor(toAnimatableColor(value)->visitedLinkColor());
521        return;
522    case CSSPropertyWebkitColumnWidth:
523        style->setColumnWidth(clampTo(toAnimatableDouble(value)->toDouble(), std::numeric_limits<float>::epsilon()));
524        return;
525    case CSSPropertyWebkitColumnRuleWidth:
526        style->setColumnRuleWidth(animatableValueRoundClampTo<unsigned short>(value));
527        return;
528    case CSSPropertyWebkitFilter:
529        style->setFilter(toAnimatableFilterOperations(value)->operations());
530        return;
531    case CSSPropertyWebkitMaskBoxImageOutset:
532        style->setMaskBoxImageOutset(animatableValueToBorderImageLengthBox(value, state));
533        return;
534    case CSSPropertyWebkitMaskBoxImageSlice:
535        style->setMaskBoxImageSlices(animatableValueToLengthBox(toAnimatableLengthBoxAndBool(value)->box(), state, ValueRangeNonNegative));
536        style->setMaskBoxImageSlicesFill(toAnimatableLengthBoxAndBool(value)->flag());
537        return;
538    case CSSPropertyWebkitMaskBoxImageSource:
539        style->setMaskBoxImageSource(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
540        return;
541    case CSSPropertyWebkitMaskBoxImageWidth:
542        style->setMaskBoxImageWidth(animatableValueToBorderImageLengthBox(value, state));
543        return;
544    case CSSPropertyWebkitMaskImage:
545        setOnFillLayers<CSSPropertyWebkitMaskImage>(style->accessMaskLayers(), value, state);
546        return;
547    case CSSPropertyWebkitMaskPositionX:
548        setOnFillLayers<CSSPropertyWebkitMaskPositionX>(style->accessMaskLayers(), value, state);
549        return;
550    case CSSPropertyWebkitMaskPositionY:
551        setOnFillLayers<CSSPropertyWebkitMaskPositionY>(style->accessMaskLayers(), value, state);
552        return;
553    case CSSPropertyWebkitMaskSize:
554        setOnFillLayers<CSSPropertyWebkitMaskSize>(style->accessMaskLayers(), value, state);
555        return;
556    case CSSPropertyPerspective:
557        style->setPerspective(clampTo<float>(toAnimatableDouble(value)->toDouble()));
558        return;
559    case CSSPropertyPerspectiveOrigin: {
560        ASSERT(RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
561        const AnimatableLengthPoint* animatableLengthPoint = toAnimatableLengthPoint(value);
562        style->setPerspectiveOriginX(animatableValueToLength(animatableLengthPoint->x(), state));
563        style->setPerspectiveOriginY(animatableValueToLength(animatableLengthPoint->y(), state));
564        return;
565    }
566    case CSSPropertyWebkitPerspectiveOriginX:
567        ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
568        style->setPerspectiveOriginX(animatableValueToLength(value, state));
569        return;
570    case CSSPropertyWebkitPerspectiveOriginY:
571        ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
572        style->setPerspectiveOriginY(animatableValueToLength(value, state));
573        return;
574    case CSSPropertyShapeOutside:
575        style->setShapeOutside(toAnimatableShapeValue(value)->shapeValue());
576        return;
577    case CSSPropertyShapeMargin:
578        style->setShapeMargin(animatableValueToLength(value, state, ValueRangeNonNegative));
579        return;
580    case CSSPropertyShapeImageThreshold:
581        style->setShapeImageThreshold(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
582        return;
583    case CSSPropertyWebkitTextStrokeColor:
584        style->setTextStrokeColor(toAnimatableColor(value)->color());
585        style->setVisitedLinkTextStrokeColor(toAnimatableColor(value)->visitedLinkColor());
586        return;
587    case CSSPropertyTransform: {
588        const TransformOperations& operations = toAnimatableTransform(value)->transformOperations();
589        // FIXME: This normalization (handling of 'none') should be performed at input in AnimatableValueFactory.
590        style->setTransform(operations.size() ? operations : TransformOperations(true));
591        return;
592    }
593    case CSSPropertyTransformOrigin: {
594        ASSERT(RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
595        const AnimatableLengthPoint3D* animatableLengthPoint3D = toAnimatableLengthPoint3D(value);
596        style->setTransformOriginX(animatableValueToLength(animatableLengthPoint3D->x(), state));
597        style->setTransformOriginY(animatableValueToLength(animatableLengthPoint3D->y(), state));
598        style->setTransformOriginZ(clampTo<float>(toAnimatableDouble(animatableLengthPoint3D->z())->toDouble()));
599        return;
600    }
601    case CSSPropertyWebkitTransformOriginX:
602        ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
603        style->setTransformOriginX(animatableValueToLength(value, state));
604        return;
605    case CSSPropertyWebkitTransformOriginY:
606        ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
607        style->setTransformOriginY(animatableValueToLength(value, state));
608        return;
609    case CSSPropertyWebkitTransformOriginZ:
610        ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
611        style->setTransformOriginZ(toAnimatableDouble(value)->toDouble());
612        return;
613    case CSSPropertyWidows:
614        style->setWidows(animatableValueRoundClampTo<unsigned short>(value, 1));
615        return;
616    case CSSPropertyWidth:
617        style->setWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
618        return;
619    case CSSPropertyWordSpacing:
620        style->setWordSpacing(clampTo<float>(toAnimatableDouble(value)->toDouble()));
621        return;
622    case CSSPropertyVerticalAlign:
623        style->setVerticalAlignLength(animatableValueToLength(value, state));
624        return;
625    case CSSPropertyVisibility:
626        style->setVisibility(toAnimatableVisibility(value)->visibility());
627        return;
628    case CSSPropertyZIndex:
629        style->setZIndex(animatableValueRoundClampTo<int>(value));
630        return;
631    case CSSPropertyZoom:
632        style->setZoom(clampTo<float>(toAnimatableDouble(value)->toDouble(), std::numeric_limits<float>::denorm_min()));
633        return;
634    default:
635        ASSERT_NOT_REACHED();
636    }
637}
638
639} // namespace WebCore
640