diff options
author | Ben Murdoch <benm@google.com> | 2009-08-18 15:36:45 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2009-08-18 19:20:06 +0100 |
commit | d227fc870c7a697500a3c900c31baf05fb9a8524 (patch) | |
tree | a3fa109aa5bf52fef562ac49d97a2f723889cc71 /WebCore/page/animation | |
parent | f2c627513266faa73f7669058d98c60769fb3524 (diff) | |
download | external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.zip external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.tar.gz external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.tar.bz2 |
Merge WebKit r47420
Diffstat (limited to 'WebCore/page/animation')
-rw-r--r-- | WebCore/page/animation/AnimationBase.cpp | 169 |
1 files changed, 154 insertions, 15 deletions
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp index 7503f0a..f85d8e4 100644 --- a/WebCore/page/animation/AnimationBase.cpp +++ b/WebCore/page/animation/AnimationBase.cpp @@ -302,11 +302,21 @@ public: { ShadowData* shadowA = (a->*m_getter)(); ShadowData* shadowB = (b->*m_getter)(); + + while (true) { + if (!shadowA && !shadowB) // end of both lists + return true; + + if (!shadowA || !shadowB) // end of just one of the lists + return false; + + if (*shadowA != *shadowB) + return false; + + shadowA = shadowA->next; + shadowB = shadowB->next; + } - if ((!shadowA && shadowB) || (shadowA && !shadowB)) - return false; - if (shadowA && shadowB && (*shadowA != *shadowB)) - return false; return true; } @@ -316,12 +326,22 @@ public: ShadowData* shadowB = (b->*m_getter)(); ShadowData defaultShadowData(0, 0, 0, 0, Normal, Color::transparent); - if (!shadowA) - shadowA = &defaultShadowData; - if (!shadowB) - shadowB = &defaultShadowData; + ShadowData* newShadowData = 0; + + while (shadowA || shadowB) { + ShadowData* srcShadow = shadowA ? shadowA : &defaultShadowData; + ShadowData* dstShadow = shadowB ? shadowB : &defaultShadowData; + + if (!newShadowData) + newShadowData = blendFunc(anim, srcShadow, dstShadow, progress); + else + newShadowData->next = blendFunc(anim, srcShadow, dstShadow, progress); - (dst->*m_setter)(blendFunc(anim, shadowA, shadowB, progress), false); + shadowA = shadowA ? shadowA->next : 0; + shadowB = shadowB ? shadowB->next : 0; + } + + (dst->*m_setter)(newShadowData, false); } private: @@ -365,6 +385,124 @@ private: void (RenderStyle::*m_setter)(const Color&); }; +// Wrapper base class for an animatable property in a FillLayer +class FillLayerPropertyWrapperBase { +public: + FillLayerPropertyWrapperBase() + { + } + + virtual ~FillLayerPropertyWrapperBase() { } + + virtual bool equals(const FillLayer* a, const FillLayer* b) const = 0; + virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const = 0; +}; + +template <typename T> +class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase { +public: + FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const) + : m_getter(getter) + { + } + + virtual bool equals(const FillLayer* a, const FillLayer* b) const + { + // If the style pointers are the same, don't bother doing the test. + // If either is null, return false. If both are null, return true. + if ((!a && !b) || a == b) + return true; + if (!a || !b) + return false; + return (a->*m_getter)() == (b->*m_getter)(); + } + +protected: + T (FillLayer::*m_getter)() const; +}; + +template <typename T> +class FillLayerPropertyWrapper : public FillLayerPropertyWrapperGetter<T> { +public: + FillLayerPropertyWrapper(T (FillLayer::*getter)() const, void (FillLayer::*setter)(T)) + : FillLayerPropertyWrapperGetter<T>(getter) + , m_setter(setter) + { + } + + virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const + { + (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<T>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<T>::m_getter)(), progress)); + } + +protected: + void (FillLayer::*m_setter)(T); +}; + + +class FillLayersPropertyWrapper : public PropertyWrapperBase { +public: + typedef const FillLayer* (RenderStyle::*LayersGetter)() const; + typedef FillLayer* (RenderStyle::*LayersAccessor)(); + + FillLayersPropertyWrapper(int prop, LayersGetter getter, LayersAccessor accessor) + : PropertyWrapperBase(prop) + , m_layersGetter(getter) + , m_layersAccessor(accessor) + { + switch (prop) { + case CSSPropertyBackgroundPositionX: + case CSSPropertyWebkitMaskPositionX: + m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::xPosition, &FillLayer::setXPosition); + break; + case CSSPropertyBackgroundPositionY: + case CSSPropertyWebkitMaskPositionY: + m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::yPosition, &FillLayer::setYPosition); + break; + case CSSPropertyWebkitBackgroundSize: + case CSSPropertyWebkitMaskSize: + m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<LengthSize>(&FillLayer::size, &FillLayer::setSize); + break; + } + } + + virtual bool equals(const RenderStyle* a, const RenderStyle* b) const + { + const FillLayer* fromLayer = (a->*m_layersGetter)(); + const FillLayer* toLayer = (b->*m_layersGetter)(); + + while (fromLayer && toLayer) { + if (!m_fillLayerPropertyWrapper->equals(fromLayer, toLayer)) + return false; + + fromLayer = fromLayer->next(); + toLayer = toLayer->next(); + } + + return true; + } + + virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const + { + const FillLayer* aLayer = (a->*m_layersGetter)(); + const FillLayer* bLayer = (b->*m_layersGetter)(); + FillLayer* dstLayer = (dst->*m_layersAccessor)(); + + while (aLayer && bLayer && dstLayer) { + m_fillLayerPropertyWrapper->blend(anim, dstLayer, aLayer, bLayer, progress); + aLayer = aLayer->next(); + bLayer = bLayer->next(); + dstLayer = dstLayer->next(); + } + } + +private: + FillLayerPropertyWrapperBase* m_fillLayerPropertyWrapper; + + LayersGetter m_layersGetter; + LayersAccessor m_layersAccessor; +}; + class ShorthandPropertyWrapper : public PropertyWrapperBase { public: ShorthandPropertyWrapper(int property, const CSSPropertyLonghand& longhand) @@ -442,13 +580,14 @@ static void ensurePropertyMap() gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor)); gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundXPosition, &RenderStyle::setBackgroundXPosition)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundYPosition, &RenderStyle::setBackgroundYPosition)); - gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundSize, &RenderStyle::setBackgroundSize)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskXPosition, &RenderStyle::setMaskXPosition)); - gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskYPosition, &RenderStyle::setMaskYPosition)); - gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyWebkitMaskSize, &RenderStyle::maskSize, &RenderStyle::setMaskSize)); + gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers)); + gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers)); + gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers)); + + gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers)); + gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers)); + gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers)); gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyFontSize, &RenderStyle::fontSize, &RenderStyle::setBlendedFontSize)); gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth)); |