OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/LengthBoxStyleInterpolation.h" | 6 #include "core/animation/LengthBoxStyleInterpolation.h" |
7 | 7 |
8 #include "core/css/Rect.h" | |
9 #include "core/css/resolver/StyleBuilder.h" | 8 #include "core/css/resolver/StyleBuilder.h" |
10 | 9 |
11 namespace blink { | 10 namespace blink { |
12 | 11 |
13 bool LengthBoxStyleInterpolation::canCreateFrom(const CSSValue& value) | 12 namespace { |
13 | |
14 bool onlyLengthToAuto(Rect* startRect, Rect* endRect) | |
dstockwell
2015/02/13 02:30:35
Not sure what this name means, is there a more des
evemj (not active)
2015/02/13 04:04:00
Done.
| |
14 { | 15 { |
15 return value.isPrimitiveValue() && toCSSPrimitiveValue(value).isRect(); | 16 return (startRect->left()->isLength() == endRect->left()->isValueID() || end Rect->left()->isLength() == startRect->left()->isValueID()) |
17 && (startRect->right()->isLength() == endRect->right()->isValueID() || e ndRect->right()->isLength() == startRect->right()->isValueID()) | |
18 && (startRect->top()->isLength() == endRect->top()->isValueID() || endRe ct->top()->isLength() == startRect->top()->isValueID()) | |
19 && (startRect->bottom()->isLength() == endRect->bottom()->isValueID() || endRect->bottom()->isLength() == startRect->bottom()->isValueID()); | |
16 } | 20 } |
17 | 21 |
18 PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::lengthBox toInterpolableValue(const CSSValue& lengthBox) | 22 } // namespace |
23 | |
24 PassRefPtrWillBeRawPtr<LengthBoxStyleInterpolation> LengthBoxStyleInterpolation: :maybeCreateFrom(CSSValue* start, CSSValue* end, CSSPropertyID id) | |
25 { | |
26 bool startRect = start->isPrimitiveValue() && toCSSPrimitiveValue(start)->is Rect(); | |
27 bool endRect = end->isPrimitiveValue() && toCSSPrimitiveValue(end)->isRect() ; | |
28 bool startAuto = start->isPrimitiveValue() && toCSSPrimitiveValue(start)->is ValueID() && toCSSPrimitiveValue(start)->getValueID() == CSSValueAuto; | |
29 bool endAuto = end->isPrimitiveValue() && toCSSPrimitiveValue(end)->isValueI D() && toCSSPrimitiveValue(end)->getValueID() == CSSValueAuto; | |
30 | |
31 if (startAuto || endAuto) { | |
32 return adoptRefWillBeNoop(new LengthBoxStyleInterpolation(InterpolableBo ol::create(false), InterpolableBool::create(true), id, false, start, end)); | |
33 } | |
34 if (startRect && endRect) { | |
35 Rect* startRectValue = toCSSPrimitiveValue(start)->getRectValue(); | |
36 Rect* endRectValue = toCSSPrimitiveValue(end)->getRectValue(); | |
37 | |
38 if (onlyLengthToAuto(startRectValue, endRectValue)) | |
39 return adoptRefWillBeNoop(new LengthBoxStyleInterpolation(Interpolab leBool::create(false), InterpolableBool::create(true), id, false, start, end)); | |
dstockwell
2015/02/13 02:30:35
Is this different from a default interpolation (re
evemj (not active)
2015/02/13 04:04:00
Moved to using DefaultStyleInterpolation in String
| |
40 return adoptRefWillBeNoop(new LengthBoxStyleInterpolation(lengthBoxtoInt erpolableValue(*start, *end, false), lengthBoxtoInterpolableValue(*end, *start, true), id, false, start, end)); | |
41 } | |
42 if (start->isBorderImageSliceValue() && toCSSBorderImageSliceValue(start)->s lices() | |
dstockwell
2015/02/13 02:30:35
BorderImageSlice doesn't work the same way with 'a
| |
43 && end->isBorderImageSliceValue() && toCSSBorderImageSliceValue(end)->sl ices() | |
44 && toCSSBorderImageSliceValue(start)->m_fill == toCSSBorderImageSliceVal ue(end)->m_fill) | |
45 return adoptRefWillBeNoop(new LengthBoxStyleInterpolation(borderImageSli cetoInterpolableValue(*start), borderImageSlicetoInterpolableValue(*end), id, to CSSBorderImageSliceValue(start)->m_fill, start, end)); | |
46 return nullptr; | |
47 } | |
48 | |
49 PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::lengthBox toInterpolableValue(const CSSValue& lengthBox, const CSSValue& matchingValue, bo ol isEndInterpolation) | |
19 { | 50 { |
20 const int numberOfSides = 4; | 51 const int numberOfSides = 4; |
21 OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(numbe rOfSides); | 52 OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(numbe rOfSides); |
22 Rect* rect = toCSSPrimitiveValue(lengthBox).getRectValue(); | 53 Rect* rect = toCSSPrimitiveValue(lengthBox).getRectValue(); |
54 Rect* matchingRect = toCSSPrimitiveValue(matchingValue).getRectValue(); | |
23 CSSPrimitiveValue* side[numberOfSides] = { rect->left(), rect->right(), rect ->top(), rect->bottom() }; | 55 CSSPrimitiveValue* side[numberOfSides] = { rect->left(), rect->right(), rect ->top(), rect->bottom() }; |
56 CSSPrimitiveValue* matchingSide[numberOfSides] = { matchingRect->left(), mat chingRect->right(), matchingRect->top(), matchingRect->bottom() }; | |
24 | 57 |
25 for (size_t i = 0; i < numberOfSides; i++) { | 58 for (size_t i = 0; i < numberOfSides; i++) { |
26 result->set(i, LengthStyleInterpolation::toInterpolableValue(*side[i])); | 59 if (side[i]->isValueID() || matchingSide[i]->isValueID()) { |
60 result->set(i, InterpolableBool::create(isEndInterpolation)); | |
61 } else { | |
62 ASSERT(LengthStyleInterpolation::canCreateFrom(*side[i])); | |
63 result->set(i, LengthStyleInterpolation::toInterpolableValue(*side[i ])); | |
64 } | |
27 } | 65 } |
28 return result.release(); | 66 return result.release(); |
29 } | 67 } |
30 | 68 |
31 PassRefPtrWillBeRawPtr<CSSValue> LengthBoxStyleInterpolation::interpolableValueT oLengthBox(InterpolableValue* value, InterpolationRange range) | 69 namespace { |
70 | |
71 PassRefPtr<CSSPrimitiveValue> findValue(InterpolableList* lengthBox, size_t i, C SSPrimitiveValue* start[], CSSPrimitiveValue* end[]) | |
dstockwell
2015/02/13 02:30:35
findValue is a bit vague, is indexedValueToLength
evemj (not active)
2015/02/13 04:04:00
Done.
sof
2015/02/13 08:40:37
Intentionally kept as findValue()? (This helper di
| |
72 { | |
73 if (lengthBox->get(i)->isBool()) { | |
74 if (toInterpolableBool(lengthBox->get(i))->value()) | |
75 return end[i]; | |
76 return start[i]; | |
77 } | |
78 return LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(i), R angeAll); | |
79 } | |
80 | |
81 } | |
82 | |
83 PassRefPtrWillBeRawPtr<CSSValue> LengthBoxStyleInterpolation::interpolableValueT oLengthBox(InterpolableValue* value, const CSSValue& originalStart, const CSSVal ue& originalEnd) | |
32 { | 84 { |
33 InterpolableList* lengthBox = toInterpolableList(value); | 85 InterpolableList* lengthBox = toInterpolableList(value); |
86 Rect* startRect = toCSSPrimitiveValue(originalStart).getRectValue(); | |
87 Rect* endRect = toCSSPrimitiveValue(originalEnd).getRectValue(); | |
88 CSSPrimitiveValue* startSides[4] = { startRect->left(), startRect->right(), startRect->top(), startRect->bottom() }; | |
89 CSSPrimitiveValue* endSides[4] = { endRect->left(), endRect->right(), endRec t->top(), endRect->bottom() }; | |
34 RefPtrWillBeRawPtr<Rect> result = Rect::create(); | 90 RefPtrWillBeRawPtr<Rect> result = Rect::create(); |
35 | 91 |
36 result->setLeft(LengthStyleInterpolation::fromInterpolableValue(*lengthBox-> get(0), RangeNonNegative)); | 92 result->setLeft(findValue(lengthBox, 0, startSides, endSides)); |
37 result->setRight(LengthStyleInterpolation::fromInterpolableValue(*lengthBox- >get(1), RangeNonNegative)); | 93 result->setRight(findValue(lengthBox, 1, startSides, endSides)); |
38 result->setTop(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->g et(2), RangeNonNegative)); | 94 result->setTop(findValue(lengthBox, 2, startSides, endSides)); |
39 result->setBottom(LengthStyleInterpolation::fromInterpolableValue(*lengthBox ->get(3), RangeNonNegative)); | 95 result->setBottom(findValue(lengthBox, 3, startSides, endSides)); |
40 | 96 |
41 return CSSPrimitiveValue::create(result.release()); | 97 return CSSPrimitiveValue::create(result.release()); |
42 } | 98 } |
43 | 99 |
44 void LengthBoxStyleInterpolation::apply(StyleResolverState& state) const | 100 PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::borderIma geSlicetoInterpolableValue(const CSSValue& value) |
45 { | |
46 if (m_id == CSSPropertyWebkitMaskBoxImageSlice) | |
47 StyleBuilder::applyProperty(m_id, state, interpolableValueToBorderImageS lice(m_cachedValue.get(), m_fill).get()); | |
48 else | |
49 StyleBuilder::applyProperty(m_id, state, interpolableValueToLengthBox(m_ cachedValue.get()).get()); | |
50 } | |
51 | |
52 void LengthBoxStyleInterpolation::trace(Visitor* visitor) | |
53 { | |
54 StyleInterpolation::trace(visitor); | |
55 } | |
56 | |
57 bool LengthBoxStyleInterpolation::matchingFill(CSSValue& start, CSSValue& end) | |
58 { | |
59 return toCSSBorderImageSliceValue(start).m_fill == toCSSBorderImageSliceValu e(end).m_fill; | |
60 } | |
61 | |
62 bool LengthBoxStyleInterpolation::canCreateFromBorderImageSlice(CSSValue& value) | |
63 { | |
64 return value.isBorderImageSliceValue() && toCSSBorderImageSliceValue(value). slices(); | |
65 } | |
66 | |
67 PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::borderIma geSlicetoInterpolableValue(CSSValue& value) | |
68 { | 101 { |
69 const int numberOfSides = 4; | 102 const int numberOfSides = 4; |
70 OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(numbe rOfSides); | 103 OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(numbe rOfSides); |
71 Quad* quad = toCSSBorderImageSliceValue(value).slices(); | 104 Quad* quad = toCSSBorderImageSliceValue(value).slices(); |
72 CSSPrimitiveValue* side[numberOfSides] = { quad->left(), quad->right(), quad ->top(), quad->bottom() }; | 105 CSSPrimitiveValue* side[numberOfSides] = { quad->left(), quad->right(), quad ->top(), quad->bottom() }; |
73 | 106 |
74 for (size_t i = 0; i < numberOfSides; i++) { | 107 for (size_t i = 0; i < numberOfSides; i++) { |
75 result->set(i, LengthStyleInterpolation::toInterpolableValue(*side[i])); | 108 result->set(i, LengthStyleInterpolation::toInterpolableValue(*side[i])); |
76 } | 109 } |
77 return result.release(); | 110 return result.release(); |
78 } | 111 } |
79 | 112 |
80 static inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> toPrimitiveValue(PassRef PtrWillBeRawPtr<CSSValue> value) | |
81 { | |
82 return adoptRefWillBeNoop(toCSSPrimitiveValue(value.leakRef())); | |
83 } | |
84 | |
85 PassRefPtrWillBeRawPtr<CSSValue> LengthBoxStyleInterpolation::interpolableValueT oBorderImageSlice(InterpolableValue* value, bool fill) | 113 PassRefPtrWillBeRawPtr<CSSValue> LengthBoxStyleInterpolation::interpolableValueT oBorderImageSlice(InterpolableValue* value, bool fill) |
86 { | 114 { |
87 InterpolableList* lengthBox = toInterpolableList(value); | 115 InterpolableList* lengthBox = toInterpolableList(value); |
88 RefPtrWillBeRawPtr<Quad> quad = Quad::create(); | 116 RefPtrWillBeRawPtr<Quad> quad = Quad::create(); |
89 | 117 |
90 quad->setLeft(toPrimitiveValue(LengthStyleInterpolation::fromInterpolableVal ue(*lengthBox->get(0), RangeNonNegative))); | 118 quad->setLeft(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->ge t(0), RangeNonNegative)); |
91 quad->setRight(toPrimitiveValue(LengthStyleInterpolation::fromInterpolableVa lue(*lengthBox->get(1), RangeNonNegative))); | 119 quad->setRight(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->g et(1), RangeNonNegative)); |
92 quad->setTop(toPrimitiveValue(LengthStyleInterpolation::fromInterpolableValu e(*lengthBox->get(2), RangeNonNegative))); | 120 quad->setTop(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get (2), RangeNonNegative)); |
93 quad->setBottom(toPrimitiveValue(LengthStyleInterpolation::fromInterpolableV alue(*lengthBox->get(3), RangeNonNegative))); | 121 quad->setBottom(LengthStyleInterpolation::fromInterpolableValue(*lengthBox-> get(3), RangeNonNegative)); |
94 | 122 |
95 return CSSBorderImageSliceValue::create(CSSPrimitiveValue::create(quad.relea se()), fill); | 123 return CSSBorderImageSliceValue::create(CSSPrimitiveValue::create(quad.relea se()), fill); |
96 } | 124 } |
97 | 125 |
126 void LengthBoxStyleInterpolation::apply(StyleResolverState& state) const | |
127 { | |
128 if (m_id == CSSPropertyWebkitMaskBoxImageSlice || m_id == CSSPropertyBorderI mageSlice) { | |
129 StyleBuilder::applyProperty(m_id, state, interpolableValueToBorderImageS lice(m_cachedValue.get(), m_fill).get()); | |
130 } else if (m_cachedValue.get()->isBool()) { | |
131 StyleBuilder::applyProperty(m_id, state, toInterpolableBool(m_cachedValu e.get())->value() ? m_endCSSValue.get() : m_startCSSValue.get()); | |
132 } else { | |
133 StyleBuilder::applyProperty(m_id, state, interpolableValueToLengthBox(m_ cachedValue.get(), *m_startCSSValue, *m_endCSSValue).get()); | |
134 } | |
98 } | 135 } |
136 | |
137 void LengthBoxStyleInterpolation::trace(Visitor* visitor) | |
138 { | |
139 StyleInterpolation::trace(visitor); | |
140 visitor->trace(m_startCSSValue); | |
141 visitor->trace(m_endCSSValue); | |
142 } | |
143 | |
144 } | |
OLD | NEW |