2011-05-12 Simon Fraser <simon.fraser@apple.com>

        Reviewed by Dan Bernstein.

        Mismatched multiple box-shadows do not transition as expected
        https://bugs.webkit.org/show_bug.cgi?id=60137

        When animating between two sets of shadows of different lengths, we need
        to walk the ShadowData list backwards, since it stores the shadows in
        reverse order relative to the CSS (so that painting is back-to-front).

        This progresses the behavior of the transitions/multiple-shadow-transitions.html
        test, which is given new expected results.

        Test: transitions/mismatched-shadow-transitions.html

        * page/animation/AnimationBase.cpp:
        (WebCore::shadowListLength): Utility to walk the list of ShadowData and count the number
        of shadows.
        (WebCore::shadowForBlending): Return a ShadowData* that is useful as a blending target,
        based on the shadow type, and whether it's a -webkit-box-shadow.
        (WebCore::PropertyWrapperShadow::blend): Call one of the specialized blend methods.
        (WebCore::PropertyWrapperShadow::blendSimpleOrMatchedShadowLists): Fast path
        for shadow blending, when the list lengths match, or both are single or null shadows.
        (WebCore::PropertyWrapperShadow::blendMismatchedShadowLists): Slower path that builds
        vectors for each list to reverse them.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@86351 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6f82bb95
2011-05-12 Simon Fraser <simon.fraser@apple.com>
Reviewed by Dan Bernstein.
Mismatched multiple box-shadows do not transition as expected
https://bugs.webkit.org/show_bug.cgi?id=60137
New test for animating between mismatched lists of shadows.
Update the test and result for multiple-shadow-transition.html,
as this change fixes its behavior.
* transitions/mismatched-shadow-transitions-expected.txt: Added.
* transitions/mismatched-shadow-transitions.html: Added.
* transitions/multiple-shadow-transitions-expected.txt:
* transitions/multiple-shadow-transitions.html:
2011-05-12 Anton Muhin <antonnm@chromium.org>
Unreviewed.
BOX
PASS - "box-shadow" property for "box" element at 0.5s saw something close to: 15,15,5,5
<!DOCTYPE>
<html>
<head>
<style>
.box {
height: 100px;
width: 100px;
margin: 50px;
border: 1px solid black;
text-align: center;
padding: 20px;
background-repeat: no-repeat;
-webkit-transition-duration: 1s;
-webkit-transition-timing-function: linear;
-webkit-transition-property: box-shadow;
}
#box {
box-shadow: inset 10px 20px 4px gray;
}
#box.final {
box-shadow: inset 20px 10px 4px gray, 10px 10px 6px black;
}
</style>
<script src="resources/transition-test-helpers.js"></script>
<script type="text/javascript">
const expectedValues = [
// [time, element-id, property, expected-value, tolerance]
[0.5, 'box', 'box-shadow', [15, 15, 5, 5], 4],
];
function setupTest()
{
document.getElementById('box').className = 'box final';
}
runTransitionTest(expectedValues, setupTest, usePauseAPI);
</script>
</head>
<body>
<div id="box" class="box">BOX</div>
<div id="result"></div>
</body>
</html>
......@@ -2,6 +2,6 @@ BOX
BOX
BOX
PASS - "-webkit-box-shadow" property for "box" element at 0.5s saw something close to: 0,0,0,0
PASS - "-webkit-box-shadow" property for "box2" element at 0.5s saw something close to: 0,-10,0,0
PASS - "-webkit-box-shadow" property for "box3" element at 0.5s saw something close to: 0,-10,0,20
PASS - "-webkit-box-shadow" property for "box2" element at 0.5s saw something close to: 0,-20,0,10
PASS - "-webkit-box-shadow" property for "box3" element at 0.5s saw something close to: 0,0,0,10
......@@ -54,8 +54,8 @@
const expectedValues = [
// [time, element-id, property, expected-value, tolerance]
[0.5, 'box', '-webkit-box-shadow', [0, 0, 0, 0], 4],
[0.5, 'box2', '-webkit-box-shadow', [0, -10, 0, 0], 4],
[0.5, 'box3', '-webkit-box-shadow', [0, -10, 0, 20], 4],
[0.5, 'box2', '-webkit-box-shadow', [0, -20, 0, 10], 4],
[0.5, 'box3', '-webkit-box-shadow', [0, 0, 0, 10], 4],
];
function setupTest()
......
2011-05-12 Simon Fraser <simon.fraser@apple.com>
Reviewed by Dan Bernstein.
Mismatched multiple box-shadows do not transition as expected
https://bugs.webkit.org/show_bug.cgi?id=60137
When animating between two sets of shadows of different lengths, we need
to walk the ShadowData list backwards, since it stores the shadows in
reverse order relative to the CSS (so that painting is back-to-front).
This progresses the behavior of the transitions/multiple-shadow-transitions.html
test, which is given new expected results.
Test: transitions/mismatched-shadow-transitions.html
* page/animation/AnimationBase.cpp:
(WebCore::shadowListLength): Utility to walk the list of ShadowData and count the number
of shadows.
(WebCore::shadowForBlending): Return a ShadowData* that is useful as a blending target,
based on the shadow type, and whether it's a -webkit-box-shadow.
(WebCore::PropertyWrapperShadow::blend): Call one of the specialized blend methods.
(WebCore::PropertyWrapperShadow::blendSimpleOrMatchedShadowLists): Fast path
for shadow blending, when the list lengths match, or both are single or null shadows.
(WebCore::PropertyWrapperShadow::blendMismatchedShadowLists): Slower path that builds
vectors for each list to reverse them.
2011-05-12 Adam Roben <aroben@apple.com>
Attempted WinCairo build fix after r86169, part II
......@@ -327,6 +327,31 @@ public:
};
#endif // USE(ACCELERATED_COMPOSITING)
static inline size_t shadowListLength(const ShadowData* shadow)
{
size_t count;
for (count = 0; shadow; shadow = shadow->next())
++count;
return count;
}
static inline const ShadowData* shadowForBlending(const ShadowData* srcShadow, const ShadowData* otherShadow)
{
DEFINE_STATIC_LOCAL(ShadowData, defaultShadowData, (0, 0, 0, 0, Normal, false, Color::transparent));
DEFINE_STATIC_LOCAL(ShadowData, defaultInsetShadowData, (0, 0, 0, 0, Inset, false, Color::transparent));
DEFINE_STATIC_LOCAL(ShadowData, defaultWebKitBoxShadowData, (0, 0, 0, 0, Normal, true, Color::transparent));
DEFINE_STATIC_LOCAL(ShadowData, defaultInsetWebKitBoxShadowData, (0, 0, 0, 0, Inset, true, Color::transparent));
if (srcShadow)
return srcShadow;
if (otherShadow->style() == Inset)
return otherShadow->isWebkitBoxShadow() ? &defaultInsetWebKitBoxShadowData : &defaultInsetShadowData;
return otherShadow->isWebkitBoxShadow() ? &defaultWebKitBoxShadowData : &defaultShadowData;
}
class PropertyWrapperShadow : public PropertyWrapperBase {
public:
PropertyWrapperShadow(int prop, const ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassOwnPtr<ShadowData>, bool))
......@@ -362,15 +387,27 @@ public:
{
const ShadowData* shadowA = (a->*m_getter)();
const ShadowData* shadowB = (b->*m_getter)();
ShadowData defaultShadowData(0, 0, 0, 0, Normal, property() == CSSPropertyWebkitBoxShadow, Color::transparent);
ShadowData defaultInsetShadowData(0, 0, 0, 0, Inset, property() == CSSPropertyWebkitBoxShadow, Color::transparent);
int fromLength = shadowListLength(shadowA);
int toLength = shadowListLength(shadowB);
if (fromLength == toLength || (fromLength <= 1 && toLength <= 1)) {
(dst->*m_setter)(blendSimpleOrMatchedShadowLists(anim, progress, shadowA, shadowB), false);
return;
}
(dst->*m_setter)(blendMismatchedShadowLists(anim, progress, shadowA, shadowB, fromLength, toLength), false);
}
private:
PassOwnPtr<ShadowData*> blendSimpleOrMatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB) const
{
OwnPtr<ShadowData> newShadowData;
ShadowData* lastShadow = 0;
while (shadowA || shadowB) {
const ShadowData* srcShadow = shadowA ? shadowA : (shadowB->style() == Inset ? &defaultInsetShadowData : &defaultShadowData);
const ShadowData* dstShadow = shadowB ? shadowB : (shadowA->style() == Inset ? &defaultInsetShadowData : &defaultShadowData);
const ShadowData* srcShadow = shadowForBlending(shadowA, shadowB);
const ShadowData* dstShadow = shadowForBlending(shadowB, shadowA);
OwnPtr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress);
ShadowData* blendedShadowPtr = blendedShadow.get();
......@@ -386,10 +423,44 @@ public:
shadowB = shadowB ? shadowB->next() : 0;
}
(dst->*m_setter)(newShadowData.release(), false);
return newShadowData.release();
}
PassOwnPtr<ShadowData*> blendMismatchedShadowLists(const AnimationBase* anim, double progress, const ShadowData* shadowA, const ShadowData* shadowB, int fromLength, int toLength) const
{
// The shadows in ShadowData are stored in reverse order, so when animating mismatched lists,
// reverse them and match from the end.
Vector<const ShadowData*> fromShadows(fromLength);
for (int i = fromLength - 1; i >= 0; --i) {
fromShadows[i] = shadowA;
shadowA = shadowA->next();
}
Vector<const ShadowData*> toShadows(toLength);
for (int i = toLength - 1; i >= 0; --i) {
toShadows[i] = shadowB;
shadowB = shadowB->next();
}
OwnPtr<ShadowData> newShadowData;
int maxLength = max(fromLength, toLength);
for (int i = 0; i < maxLength; ++i) {
const ShadowData* fromShadow = i < fromLength ? fromShadows[i] : 0;
const ShadowData* toShadow = i < toLength ? toShadows[i] : 0;
const ShadowData* srcShadow = shadowForBlending(fromShadow, toShadow);
const ShadowData* dstShadow = shadowForBlending(toShadow, fromShadow);
OwnPtr<ShadowData> blendedShadow = blendFunc(anim, srcShadow, dstShadow, progress);
// Insert at the start of the list to preserve the order.
blendedShadow->setNext(newShadowData.release());
newShadowData = blendedShadow.release();
}
return newShadowData.release();
}
private:
const ShadowData* (RenderStyle::*m_getter)() const;
void (RenderStyle::*m_setter)(PassOwnPtr<ShadowData>, bool);
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment