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
63namespace blink {
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
129void 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
137PassRefPtr<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
145template <CSSPropertyID property>
146void 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
211FontStretch 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
231FontWeight 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.
255void 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