OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/animation/ImageSliceStyleInterpolation.h" | 6 #include "core/animation/ImageSliceStyleInterpolation.h" |
7 | 7 |
8 #include "core/css/CSSBorderImageSliceValue.h" | 8 #include "core/css/CSSBorderImageSliceValue.h" |
9 #include "core/css/CSSPrimitiveValue.h" | 9 #include "core/css/CSSPrimitiveValue.h" |
10 #include "core/css/Rect.h" | 10 #include "core/css/Rect.h" |
11 #include "core/css/resolver/StyleBuilder.h" | 11 #include "core/css/resolver/StyleBuilder.h" |
12 | 12 |
13 namespace blink { | 13 namespace blink { |
14 | 14 |
15 bool ImageSliceStyleInterpolation::usesDefaultInterpolation(const CSSValue& star
t, const CSSValue& end) | 15 bool ImageSliceStyleInterpolation::usesDefaultInterpolation(const CSSValue& star
t, const CSSValue& end) |
16 { | 16 { |
17 if (!start.isBorderImageSliceValue() || !end.isBorderImageSliceValue()) | 17 if (!start.isBorderImageSliceValue() || !end.isBorderImageSliceValue()) |
18 return true; | 18 return true; |
19 const CSSBorderImageSliceValue& startSlice = toCSSBorderImageSliceValue(star
t); | 19 const CSSBorderImageSliceValue& startSlice = toCSSBorderImageSliceValue(star
t); |
20 const CSSBorderImageSliceValue& endSlice = toCSSBorderImageSliceValue(end); | 20 const CSSBorderImageSliceValue& endSlice = toCSSBorderImageSliceValue(end); |
21 return startSlice.slices()->top()->isPercentage() != endSlice.slices()->top(
)->isPercentage() | 21 return startSlice.slices()->top()->isPercentage() != endSlice.slices()->top(
)->isPercentage() |
22 || startSlice.m_fill != endSlice.m_fill; | 22 || startSlice.m_fill != endSlice.m_fill; |
23 } | 23 } |
24 | 24 |
25 // PassDecompositionResult is required because the Windows compiler fails to cal
l the OwnPtr(OwnPtr&&) constructor. | 25 namespace { |
26 struct PassDecompositionResult { | 26 |
27 PassOwnPtrWillBeRawPtr<InterpolableValue> interpolableValue; | 27 class Decomposition { |
| 28 STACK_ALLOCATED(); |
| 29 public: |
| 30 Decomposition(const CSSBorderImageSliceValue& value) |
| 31 { |
| 32 decompose(value); |
| 33 } |
| 34 |
| 35 OwnPtrWillBeMember<InterpolableValue> interpolableValue; |
28 ImageSliceStyleInterpolation::Metadata metadata; | 36 ImageSliceStyleInterpolation::Metadata metadata; |
| 37 |
| 38 private: |
| 39 void decompose(const CSSBorderImageSliceValue& value) |
| 40 { |
| 41 const size_t kQuadSides = 4; |
| 42 OwnPtrWillBeRawPtr<InterpolableList> interpolableList = InterpolableList
::create(kQuadSides); |
| 43 const Quad& quad = *value.slices(); |
| 44 interpolableList->set(0, InterpolableNumber::create(quad.top()->getDoubl
eValue())); |
| 45 interpolableList->set(1, InterpolableNumber::create(quad.right()->getDou
bleValue())); |
| 46 interpolableList->set(2, InterpolableNumber::create(quad.bottom()->getDo
ubleValue())); |
| 47 interpolableList->set(3, InterpolableNumber::create(quad.left()->getDoub
leValue())); |
| 48 bool isPercentage = quad.top()->isPercentage(); |
| 49 ASSERT(quad.bottom()->isPercentage() == isPercentage |
| 50 && quad.left()->isPercentage() == isPercentage |
| 51 && quad.right()->isPercentage() == isPercentage); |
| 52 |
| 53 interpolableValue = interpolableList.release(); |
| 54 metadata = ImageSliceStyleInterpolation::Metadata {isPercentage, value.m
_fill}; |
| 55 } |
29 }; | 56 }; |
30 | 57 |
31 struct DecompositionResult { | 58 PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> compose(const InterpolableValue
& value, const ImageSliceStyleInterpolation::Metadata& metadata) |
32 DecompositionResult(const PassDecompositionResult& o) | |
33 : interpolableValue(o.interpolableValue) | |
34 , metadata(o.metadata) | |
35 { } | |
36 OwnPtrWillBeRawPtr<InterpolableValue> interpolableValue; | |
37 ImageSliceStyleInterpolation::Metadata metadata; | |
38 }; | |
39 | |
40 static PassDecompositionResult decompose(const CSSBorderImageSliceValue& value) | |
41 { | |
42 const size_t kQuadSides = 4; | |
43 OwnPtrWillBeRawPtr<InterpolableList> interpolableList = InterpolableList::cr
eate(kQuadSides); | |
44 const Quad& quad = *value.slices(); | |
45 interpolableList->set(0, InterpolableNumber::create(quad.top()->getDoubleVal
ue())); | |
46 interpolableList->set(1, InterpolableNumber::create(quad.right()->getDoubleV
alue())); | |
47 interpolableList->set(2, InterpolableNumber::create(quad.bottom()->getDouble
Value())); | |
48 interpolableList->set(3, InterpolableNumber::create(quad.left()->getDoubleVa
lue())); | |
49 bool isPercentage = quad.top()->isPercentage(); | |
50 ASSERT(quad.bottom()->isPercentage() == isPercentage | |
51 && quad.left()->isPercentage() == isPercentage | |
52 && quad.right()->isPercentage() == isPercentage); | |
53 return PassDecompositionResult { | |
54 interpolableList.release(), | |
55 ImageSliceStyleInterpolation::Metadata {isPercentage, value.m_fill}, | |
56 }; | |
57 } | |
58 | |
59 static PassRefPtr<CSSBorderImageSliceValue> compose(const InterpolableValue& val
ue, const ImageSliceStyleInterpolation::Metadata& metadata) | |
60 { | 59 { |
61 const InterpolableList& interpolableList = toInterpolableList(value); | 60 const InterpolableList& interpolableList = toInterpolableList(value); |
62 CSSPrimitiveValue::UnitType type = metadata.isPercentage ? CSSPrimitiveValue
::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER; | 61 CSSPrimitiveValue::UnitType type = metadata.isPercentage ? CSSPrimitiveValue
::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER; |
63 RefPtrWillBeRawPtr<Quad> quad = Quad::create(); | 62 RefPtrWillBeRawPtr<Quad> quad = Quad::create(); |
64 quad->setTop(CSSPrimitiveValue::create(clampTo(toInterpolableNumber(interpol
ableList.get(0))->value(), 0), type)); | 63 quad->setTop(CSSPrimitiveValue::create(clampTo(toInterpolableNumber(interpol
ableList.get(0))->value(), 0), type)); |
65 quad->setRight(CSSPrimitiveValue::create(clampTo(toInterpolableNumber(interp
olableList.get(1))->value(), 0), type)); | 64 quad->setRight(CSSPrimitiveValue::create(clampTo(toInterpolableNumber(interp
olableList.get(1))->value(), 0), type)); |
66 quad->setBottom(CSSPrimitiveValue::create(clampTo(toInterpolableNumber(inter
polableList.get(2))->value(), 0), type)); | 65 quad->setBottom(CSSPrimitiveValue::create(clampTo(toInterpolableNumber(inter
polableList.get(2))->value(), 0), type)); |
67 quad->setLeft(CSSPrimitiveValue::create(clampTo(toInterpolableNumber(interpo
lableList.get(3))->value(), 0), type)); | 66 quad->setLeft(CSSPrimitiveValue::create(clampTo(toInterpolableNumber(interpo
lableList.get(3))->value(), 0), type)); |
68 return CSSBorderImageSliceValue::create(CSSPrimitiveValue::create(quad.relea
se()), metadata.fill); | 67 return CSSBorderImageSliceValue::create(CSSPrimitiveValue::create(quad.relea
se()), metadata.fill); |
69 } | 68 } |
70 | 69 |
| 70 } // namespace |
| 71 |
71 PassRefPtrWillBeRawPtr<ImageSliceStyleInterpolation> ImageSliceStyleInterpolatio
n::maybeCreate(const CSSValue& start, const CSSValue& end, CSSPropertyID propert
y) | 72 PassRefPtrWillBeRawPtr<ImageSliceStyleInterpolation> ImageSliceStyleInterpolatio
n::maybeCreate(const CSSValue& start, const CSSValue& end, CSSPropertyID propert
y) |
72 { | 73 { |
73 if (!start.isBorderImageSliceValue() || !end.isBorderImageSliceValue()) | 74 if (!start.isBorderImageSliceValue() || !end.isBorderImageSliceValue()) |
74 return nullptr; | 75 return nullptr; |
75 | 76 |
76 DecompositionResult startDecompose = decompose(toCSSBorderImageSliceValue(st
art)); | 77 Decomposition startDecompose(toCSSBorderImageSliceValue(start)); |
77 DecompositionResult endDecompose = decompose(toCSSBorderImageSliceValue(end)
); | 78 Decomposition endDecompose(toCSSBorderImageSliceValue(end)); |
78 if (!(startDecompose.metadata == endDecompose.metadata)) | 79 if (!(startDecompose.metadata == endDecompose.metadata)) |
79 return nullptr; | 80 return nullptr; |
80 | 81 |
81 return adoptRefWillBeNoop(new ImageSliceStyleInterpolation( | 82 return adoptRefWillBeNoop(new ImageSliceStyleInterpolation( |
82 startDecompose.interpolableValue.release(), | 83 startDecompose.interpolableValue.release(), |
83 endDecompose.interpolableValue.release(), | 84 endDecompose.interpolableValue.release(), |
84 property, | 85 property, |
85 startDecompose.metadata | 86 startDecompose.metadata |
86 )); | 87 )); |
87 } | 88 } |
88 | 89 |
89 void ImageSliceStyleInterpolation::apply(StyleResolverState& state) const | 90 void ImageSliceStyleInterpolation::apply(StyleResolverState& state) const |
90 { | 91 { |
91 StyleBuilder::applyProperty(m_id, state, compose(*m_cachedValue, m_metadata)
.get()); | 92 StyleBuilder::applyProperty(m_id, state, compose(*m_cachedValue, m_metadata)
.get()); |
92 } | 93 } |
93 | 94 |
94 DEFINE_TRACE(ImageSliceStyleInterpolation) | 95 DEFINE_TRACE(ImageSliceStyleInterpolation) |
95 { | 96 { |
96 StyleInterpolation::trace(visitor); | 97 StyleInterpolation::trace(visitor); |
97 } | 98 } |
98 | 99 |
99 } // namespace blink | 100 } // namespace blink |
OLD | NEW |