/src/3rdparty/webkit/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm
https://bitbucket.org/ultra_iter/qt-vtl · Objective C++ · 563 lines · 426 code · 106 blank · 31 comment · 68 complexity · ca9d5060d7ad51af2416c80d824119f0 MD5 · raw file
- /*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "config.h"
- #if USE(ACCELERATED_COMPOSITING)
- #import "PlatformCAAnimation.h"
- #import "FloatConversion.h"
- #import "PlatformString.h"
- #import "TimingFunction.h"
- #import <QuartzCore/QuartzCore.h>
- #import <wtf/UnusedParam.h>
- #define HAVE_MODERN_QUARTZCORE (!defined(BUILDING_ON_LEOPARD))
- using namespace WebCore;
- // This value must be the same as in PlatformCALayerMac.mm
- static NSString * const WKNonZeroBeginTimeFlag = @"WKPlatformCAAnimationNonZeroBeginTimeFlag";
- static bool hasNonZeroBeginTimeFlag(const PlatformCAAnimation* animation)
- {
- return [[animation->platformAnimation() valueForKey:WKNonZeroBeginTimeFlag] boolValue];
- }
- static void setNonZeroBeginTimeFlag(PlatformCAAnimation* animation, bool value)
- {
- [animation->platformAnimation() setValue:[NSNumber numberWithBool:value] forKey:WKNonZeroBeginTimeFlag];
- }
-
- static NSString* toCAFillModeType(PlatformCAAnimation::FillModeType type)
- {
- switch (type) {
- case PlatformCAAnimation::NoFillMode:
- case PlatformCAAnimation::Forwards: return kCAFillModeForwards;
- case PlatformCAAnimation::Backwards: return kCAFillModeBackwards;
- case PlatformCAAnimation::Both: return kCAFillModeBoth;
- }
- return @"";
- }
- static PlatformCAAnimation::FillModeType fromCAFillModeType(NSString* string)
- {
- if ([string isEqualToString:kCAFillModeBackwards])
- return PlatformCAAnimation::Backwards;
- if ([string isEqualToString:kCAFillModeBoth])
- return PlatformCAAnimation::Both;
- return PlatformCAAnimation::Forwards;
- }
- #if HAVE_MODERN_QUARTZCORE
- static NSString* toCAValueFunctionType(PlatformCAAnimation::ValueFunctionType type)
- {
- switch (type) {
- case PlatformCAAnimation::NoValueFunction: return @"";
- case PlatformCAAnimation::RotateX: return kCAValueFunctionRotateX;
- case PlatformCAAnimation::RotateY: return kCAValueFunctionRotateY;
- case PlatformCAAnimation::RotateZ: return kCAValueFunctionRotateZ;
- case PlatformCAAnimation::ScaleX: return kCAValueFunctionScaleX;
- case PlatformCAAnimation::ScaleY: return kCAValueFunctionScaleY;
- case PlatformCAAnimation::ScaleZ: return kCAValueFunctionScaleZ;
- case PlatformCAAnimation::Scale: return kCAValueFunctionScale;
- case PlatformCAAnimation::TranslateX: return kCAValueFunctionTranslateX;
- case PlatformCAAnimation::TranslateY: return kCAValueFunctionTranslateY;
- case PlatformCAAnimation::TranslateZ: return kCAValueFunctionTranslateZ;
- case PlatformCAAnimation::Translate: return kCAValueFunctionTranslate;
- }
- return @"";
- }
- static PlatformCAAnimation::ValueFunctionType fromCAValueFunctionType(NSString* string)
- {
- if ([string isEqualToString:kCAValueFunctionRotateX])
- return PlatformCAAnimation::RotateX;
- if ([string isEqualToString:kCAValueFunctionRotateY])
- return PlatformCAAnimation::RotateY;
- if ([string isEqualToString:kCAValueFunctionRotateZ])
- return PlatformCAAnimation::RotateZ;
- if ([string isEqualToString:kCAValueFunctionScaleX])
- return PlatformCAAnimation::ScaleX;
- if ([string isEqualToString:kCAValueFunctionScaleY])
- return PlatformCAAnimation::ScaleY;
- if ([string isEqualToString:kCAValueFunctionScaleZ])
- return PlatformCAAnimation::ScaleZ;
- if ([string isEqualToString:kCAValueFunctionScale])
- return PlatformCAAnimation::Scale;
- if ([string isEqualToString:kCAValueFunctionTranslateX])
- return PlatformCAAnimation::TranslateX;
- if ([string isEqualToString:kCAValueFunctionTranslateY])
- return PlatformCAAnimation::TranslateY;
- if ([string isEqualToString:kCAValueFunctionTranslateZ])
- return PlatformCAAnimation::TranslateZ;
- if ([string isEqualToString:kCAValueFunctionTranslate])
- return PlatformCAAnimation::Translate;
- return PlatformCAAnimation::NoValueFunction;
- }
- #endif
- static CAMediaTimingFunction* toCAMediaTimingFunction(const TimingFunction* timingFunction)
- {
- ASSERT(timingFunction);
- if (timingFunction->isCubicBezierTimingFunction()) {
- const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
- return [CAMediaTimingFunction functionWithControlPoints:static_cast<float>(ctf->x1()) :static_cast<float>(ctf->y1())
- :static_cast<float>(ctf->x2()) :static_cast<float>(ctf->y2())];
- }
-
- return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
- }
- PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(AnimationType type, const String& keyPath)
- {
- return adoptRef(new PlatformCAAnimation(type, keyPath));
- }
- PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(PlatformAnimationRef animation)
- {
- return adoptRef(new PlatformCAAnimation(animation));
- }
- PlatformCAAnimation::PlatformCAAnimation(AnimationType type, const String& keyPath)
- : m_type(type)
- {
- if (type == Basic)
- m_animation.adoptNS([[CABasicAnimation animationWithKeyPath:keyPath] retain]);
- else
- m_animation.adoptNS([[CAKeyframeAnimation animationWithKeyPath:keyPath] retain]);
- }
- PlatformCAAnimation::PlatformCAAnimation(PlatformAnimationRef animation)
- {
- if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CABasicAnimation class]])
- m_type = Basic;
- else if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CAKeyframeAnimation class]])
- m_type = Keyframe;
- else {
- ASSERT(0);
- return;
- }
-
- m_animation = static_cast<CAPropertyAnimation*>(animation);
- }
- PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::copy() const
- {
- RefPtr<PlatformCAAnimation> animation = create(animationType(), keyPath());
-
- animation->setBeginTime(beginTime());
- animation->setDuration(duration());
- animation->setSpeed(speed());
- animation->setTimeOffset(timeOffset());
- animation->setRepeatCount(repeatCount());
- animation->setAutoreverses(autoreverses());
- animation->setFillMode(fillMode());
- animation->setRemovedOnCompletion(isRemovedOnCompletion());
- animation->setAdditive(isAdditive());
- animation->copyTimingFunctionFrom(this);
- animation->setValueFunction(valueFunction());
- setNonZeroBeginTimeFlag(animation.get(), hasNonZeroBeginTimeFlag(this));
-
- // Copy the specific Basic or Keyframe values
- if (animationType() == Keyframe) {
- animation->copyValuesFrom(this);
- animation->copyKeyTimesFrom(this);
- animation->copyTimingFunctionsFrom(this);
- } else {
- animation->copyFromValueFrom(this);
- animation->copyToValueFrom(this);
- }
-
- return animation;
- }
- PlatformCAAnimation::~PlatformCAAnimation()
- {
- }
- bool PlatformCAAnimation::supportsValueFunction()
- {
- static bool sHaveValueFunction = [CAPropertyAnimation instancesRespondToSelector:@selector(setValueFunction:)];
- return sHaveValueFunction;
- }
- PlatformAnimationRef PlatformCAAnimation::platformAnimation() const
- {
- return m_animation.get();
- }
- String PlatformCAAnimation::keyPath() const
- {
- return [m_animation.get() keyPath];
- }
- CFTimeInterval PlatformCAAnimation::beginTime() const
- {
- return [m_animation.get() beginTime];
- }
- void PlatformCAAnimation::setBeginTime(CFTimeInterval value)
- {
- [m_animation.get() setBeginTime:value];
-
- // Also set a flag to tell us if we've passed in a 0 value.
- // The flag is needed because later beginTime will get changed
- // to the time at which it fired and we need to know whether
- // or not it was 0 to begin with.
- if (value)
- setNonZeroBeginTimeFlag(this, true);
- }
- CFTimeInterval PlatformCAAnimation::duration() const
- {
- return [m_animation.get() duration];
- }
- void PlatformCAAnimation::setDuration(CFTimeInterval value)
- {
- [m_animation.get() setDuration:value];
- }
- float PlatformCAAnimation::speed() const
- {
- return [m_animation.get() speed];
- }
- void PlatformCAAnimation::setSpeed(float value)
- {
- [m_animation.get() setSpeed:value];
- }
- CFTimeInterval PlatformCAAnimation::timeOffset() const
- {
- return [m_animation.get() timeOffset];
- }
- void PlatformCAAnimation::setTimeOffset(CFTimeInterval value)
- {
- [m_animation.get() setTimeOffset:value];
- }
- float PlatformCAAnimation::repeatCount() const
- {
- return [m_animation.get() repeatCount];
- }
- void PlatformCAAnimation::setRepeatCount(float value)
- {
- [m_animation.get() setRepeatCount:value];
- }
- bool PlatformCAAnimation::autoreverses() const
- {
- return [m_animation.get() autoreverses];
- }
- void PlatformCAAnimation::setAutoreverses(bool value)
- {
- [m_animation.get() setAutoreverses:value];
- }
- PlatformCAAnimation::FillModeType PlatformCAAnimation::fillMode() const
- {
- return fromCAFillModeType([m_animation.get() fillMode]);
- }
- void PlatformCAAnimation::setFillMode(FillModeType value)
- {
- [m_animation.get() setFillMode:toCAFillModeType(value)];
- }
- void PlatformCAAnimation::setTimingFunction(const TimingFunction* value)
- {
- [m_animation.get() setTimingFunction:toCAMediaTimingFunction(value)];
- }
- void PlatformCAAnimation::copyTimingFunctionFrom(const PlatformCAAnimation* value)
- {
- [m_animation.get() setTimingFunction:[value->m_animation.get() timingFunction]];
- }
- bool PlatformCAAnimation::isRemovedOnCompletion() const
- {
- return [m_animation.get() isRemovedOnCompletion];
- }
- void PlatformCAAnimation::setRemovedOnCompletion(bool value)
- {
- [m_animation.get() setRemovedOnCompletion:value];
- }
- bool PlatformCAAnimation::isAdditive() const
- {
- return [m_animation.get() isAdditive];
- }
- void PlatformCAAnimation::setAdditive(bool value)
- {
- [m_animation.get() setAdditive:value];
- }
- PlatformCAAnimation::ValueFunctionType PlatformCAAnimation::valueFunction() const
- {
- #if HAVE_MODERN_QUARTZCORE
- CAValueFunction* vf = [m_animation.get() valueFunction];
- return fromCAValueFunctionType([vf name]);
- #else
- return NoValueFunction;
- #endif
- }
- void PlatformCAAnimation::setValueFunction(ValueFunctionType value)
- {
- #if HAVE_MODERN_QUARTZCORE
- [m_animation.get() setValueFunction:[CAValueFunction functionWithName:toCAValueFunctionType(value)]];
- #else
- UNUSED_PARAM(value);
- #endif
- }
- void PlatformCAAnimation::setFromValue(float value)
- {
- if (animationType() != Basic)
- return;
- [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:[NSNumber numberWithDouble:value]];
- }
- void PlatformCAAnimation::setFromValue(const WebCore::TransformationMatrix& value)
- {
- if (animationType() != Basic)
- return;
-
- [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:[NSValue valueWithCATransform3D:value]];
- }
- void PlatformCAAnimation::setFromValue(const FloatPoint3D& value)
- {
- if (animationType() != Basic)
- return;
- NSArray* array = [NSArray arrayWithObjects:
- [NSNumber numberWithDouble:value.x()],
- [NSNumber numberWithDouble:value.y()],
- [NSNumber numberWithDouble:value.z()],
- nil];
- [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:array];
- }
- void PlatformCAAnimation::setFromValue(const WebCore::Color& value)
- {
- if (animationType() != Basic)
- return;
- NSArray* array = [NSArray arrayWithObjects:
- [NSNumber numberWithDouble:value.red()],
- [NSNumber numberWithDouble:value.green()],
- [NSNumber numberWithDouble:value.blue()],
- [NSNumber numberWithDouble:value.alpha()],
- nil];
- [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:array];
- }
- void PlatformCAAnimation::copyFromValueFrom(const PlatformCAAnimation* value)
- {
- if (animationType() != Basic || value->animationType() != Basic)
- return;
-
- CABasicAnimation* otherAnimation = static_cast<CABasicAnimation*>(value->m_animation.get());
- [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:[otherAnimation fromValue]];
- }
- void PlatformCAAnimation::setToValue(float value)
- {
- if (animationType() != Basic)
- return;
- [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:[NSNumber numberWithDouble:value]];
- }
- void PlatformCAAnimation::setToValue(const WebCore::TransformationMatrix& value)
- {
- if (animationType() != Basic)
- return;
- [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:[NSValue valueWithCATransform3D:value]];
- }
- void PlatformCAAnimation::setToValue(const FloatPoint3D& value)
- {
- if (animationType() != Basic)
- return;
- NSArray* array = [NSArray arrayWithObjects:
- [NSNumber numberWithDouble:value.x()],
- [NSNumber numberWithDouble:value.y()],
- [NSNumber numberWithDouble:value.z()],
- nil];
- [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:array];
- }
- void PlatformCAAnimation::setToValue(const WebCore::Color& value)
- {
- if (animationType() != Basic)
- return;
- NSArray* array = [NSArray arrayWithObjects:
- [NSNumber numberWithDouble:value.red()],
- [NSNumber numberWithDouble:value.green()],
- [NSNumber numberWithDouble:value.blue()],
- [NSNumber numberWithDouble:value.alpha()],
- nil];
- [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:array];
- }
- void PlatformCAAnimation::copyToValueFrom(const PlatformCAAnimation* value)
- {
- if (animationType() != Basic || value->animationType() != Basic)
- return;
-
- CABasicAnimation* otherAnimation = static_cast<CABasicAnimation*>(value->m_animation.get());
- [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:[otherAnimation toValue]];
- }
- // Keyframe-animation properties.
- void PlatformCAAnimation::setValues(const Vector<float>& value)
- {
- if (animationType() != Keyframe)
- return;
-
- NSMutableArray* array = [NSMutableArray array];
- for (size_t i = 0; i < value.size(); ++i)
- [array addObject:[NSNumber numberWithDouble:value[i]]];
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:array];
- }
- void PlatformCAAnimation::setValues(const Vector<WebCore::TransformationMatrix>& value)
- {
- if (animationType() != Keyframe)
- return;
-
- NSMutableArray* array = [NSMutableArray array];
- for (size_t i = 0; i < value.size(); ++i)
- [array addObject:[NSValue valueWithCATransform3D:value[i]]];
-
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:array];
- }
- void PlatformCAAnimation::setValues(const Vector<FloatPoint3D>& value)
- {
- if (animationType() != Keyframe)
- return;
-
- NSMutableArray* array = [NSMutableArray array];
- for (size_t i = 0; i < value.size(); ++i) {
- NSArray* object = [NSArray arrayWithObjects:
- [NSNumber numberWithDouble:value[i].x()],
- [NSNumber numberWithDouble:value[i].y()],
- [NSNumber numberWithDouble:value[i].z()],
- nil];
- [array addObject:object];
- }
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:array];
- }
- void PlatformCAAnimation::setValues(const Vector<WebCore::Color>& value)
- {
- if (animationType() != Keyframe)
- return;
-
- NSMutableArray* array = [NSMutableArray array];
- for (size_t i = 0; i < value.size(); ++i) {
- NSArray* object = [NSArray arrayWithObjects:
- [NSNumber numberWithDouble:value[i].red()],
- [NSNumber numberWithDouble:value[i].green()],
- [NSNumber numberWithDouble:value[i].blue()],
- [NSNumber numberWithDouble:value[i].alpha()],
- nil];
- [array addObject:object];
- }
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:array];
- }
- void PlatformCAAnimation::copyValuesFrom(const PlatformCAAnimation* value)
- {
- if (animationType() != Keyframe || value->animationType() != Keyframe)
- return;
-
- CAKeyframeAnimation* otherAnimation = static_cast<CAKeyframeAnimation*>(value->m_animation.get());
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:[otherAnimation values]];
- }
- void PlatformCAAnimation::setKeyTimes(const Vector<float>& value)
- {
- NSMutableArray* array = [NSMutableArray array];
- for (size_t i = 0; i < value.size(); ++i)
- [array addObject:[NSNumber numberWithFloat:value[i]]];
-
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setKeyTimes:array];
- }
- void PlatformCAAnimation::copyKeyTimesFrom(const PlatformCAAnimation* value)
- {
- CAKeyframeAnimation* other = static_cast<CAKeyframeAnimation*>(value->m_animation.get());
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setKeyTimes:[other keyTimes]];
- }
- void PlatformCAAnimation::setTimingFunctions(const Vector<const TimingFunction*>& value)
- {
- NSMutableArray* array = [NSMutableArray array];
- for (size_t i = 0; i < value.size(); ++i)
- [array addObject:toCAMediaTimingFunction(value[i])];
-
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setTimingFunctions:array];
- }
- void PlatformCAAnimation::copyTimingFunctionsFrom(const PlatformCAAnimation* value)
- {
- CAKeyframeAnimation* other = static_cast<CAKeyframeAnimation*>(value->m_animation.get());
- [static_cast<CAKeyframeAnimation*>(m_animation.get()) setTimingFunctions:[other timingFunctions]];
- }
- #endif // USE(ACCELERATED_COMPOSITING)