diff options
Diffstat (limited to 'slideshow/source/engine/animationfactory.cxx')
-rw-r--r-- | slideshow/source/engine/animationfactory.cxx | 1386 |
1 files changed, 1386 insertions, 0 deletions
diff --git a/slideshow/source/engine/animationfactory.cxx b/slideshow/source/engine/animationfactory.cxx new file mode 100644 index 000000000000..358029e08590 --- /dev/null +++ b/slideshow/source/engine/animationfactory.cxx @@ -0,0 +1,1386 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_slideshow.hxx" + +// must be first +#include <canvas/debug.hxx> +#include <tools/diagnose_ex.h> +#include <canvas/verbosetrace.hxx> + +#include <animationfactory.hxx> +#include <attributemap.hxx> + +#include <com/sun/star/animations/AnimationAdditiveMode.hpp> +#include <com/sun/star/animations/AnimationTransformType.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/drawing/FillStyle.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/FontWeight.hpp> + +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> + +#include <functional> + + +using namespace ::com::sun::star; + + +namespace slideshow +{ + namespace internal + { + namespace + { + // attention, there is a similar implementation of Animation in + // transitions/transitionfactory.cxx + + template< typename ValueT > class TupleAnimation : public PairAnimation + { + public: + TupleAnimation( const ShapeManagerSharedPtr& rShapeManager, + int nFlags, + bool (ShapeAttributeLayer::*pIs1stValid)() const, + bool (ShapeAttributeLayer::*pIs2ndValid)() const, + const ValueT& rDefaultValue, + const ::basegfx::B2DSize& rReferenceSize, + double (ShapeAttributeLayer::*pGet1stValue)() const, + double (ShapeAttributeLayer::*pGet2ndValue)() const, + void (ShapeAttributeLayer::*pSetValue)( const ValueT& ) ) : + mpShape(), + mpAttrLayer(), + mpShapeManager( rShapeManager ), + mpIs1stValidFunc(pIs1stValid), + mpIs2ndValidFunc(pIs2ndValid), + mpGet1stValueFunc(pGet1stValue), + mpGet2ndValueFunc(pGet2ndValue), + mpSetValueFunc(pSetValue), + mnFlags( nFlags ), + maReferenceSize( rReferenceSize ), + maDefaultValue( rDefaultValue ), + mbAnimationStarted( false ) + { + ENSURE_OR_THROW( rShapeManager, + "TupleAnimation::TupleAnimation(): Invalid ShapeManager" ); + ENSURE_OR_THROW( pIs1stValid && pIs2ndValid && pGet1stValue && pGet2ndValue && pSetValue, + "TupleAnimation::TupleAnimation(): One of the method pointers is NULL" ); + } + + ~TupleAnimation() + { + end_(); + } + + // Animation interface + // ------------------- + virtual void prefetch( const AnimatableShapeSharedPtr&, + const ShapeAttributeLayerSharedPtr& ) + {} + + virtual void start( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) + { + OSL_ENSURE( !mpShape, + "TupleAnimation::start(): Shape already set" ); + OSL_ENSURE( !mpAttrLayer, + "TupleAnimation::start(): Attribute layer already set" ); + + mpShape = rShape; + mpAttrLayer = rAttrLayer; + + ENSURE_OR_THROW( rShape, + "TupleAnimation::start(): Invalid shape" ); + ENSURE_OR_THROW( rAttrLayer, + "TupleAnimation::start(): Invalid attribute layer" ); + + if( !mbAnimationStarted ) + { + mbAnimationStarted = true; + + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) + mpShapeManager->enterAnimationMode( mpShape ); + } + } + + virtual void end() { end_(); } + void end_() + { + if( mbAnimationStarted ) + { + mbAnimationStarted = false; + + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) + mpShapeManager->leaveAnimationMode( mpShape ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + } + } + + // PairAnimation interface + // ----------------------- + + virtual bool operator()( const ::basegfx::B2DTuple& rValue ) + { + ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape, + "TupleAnimation::operator(): Invalid ShapeAttributeLayer" ); + + ValueT aValue( rValue.getX(), + rValue.getY() ); + + // Activitis get values from the expression parser, + // which returns _relative_ sizes/positions. + // Convert back relative to reference coordinate system + aValue *= maReferenceSize; + + ((*mpAttrLayer).*mpSetValueFunc)( aValue ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + + return true; + } + + virtual ::basegfx::B2DTuple getUnderlyingValue() const + { + ENSURE_OR_THROW( mpAttrLayer, + "TupleAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" ); + + ::basegfx::B2DTuple aRetVal; + + // deviated from the (*shared_ptr).*mpFuncPtr + // notation here, since gcc does not seem to parse + // that as a member function call anymore. + aRetVal.setX( (mpAttrLayer.get()->*mpIs1stValidFunc)() ? + (mpAttrLayer.get()->*mpGet1stValueFunc)() : + maDefaultValue.getX() ); + aRetVal.setY( (mpAttrLayer.get()->*mpIs2ndValidFunc)() ? + (mpAttrLayer.get()->*mpGet2ndValueFunc)() : + maDefaultValue.getY() ); + + // Activities get values from the expression + // parser, which returns _relative_ + // sizes/positions. Convert start value to the + // same coordinate space (i.e. relative to given + // reference size). + aRetVal /= maReferenceSize; + + return aRetVal; + } + + private: + AnimatableShapeSharedPtr mpShape; + ShapeAttributeLayerSharedPtr mpAttrLayer; + ShapeManagerSharedPtr mpShapeManager; + bool (ShapeAttributeLayer::*mpIs1stValidFunc)() const; + bool (ShapeAttributeLayer::*mpIs2ndValidFunc)() const; + double (ShapeAttributeLayer::*mpGet1stValueFunc)() const; + double (ShapeAttributeLayer::*mpGet2ndValueFunc)() const; + void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& ); + + const int mnFlags; + + const ::basegfx::B2DSize maReferenceSize; + const ValueT maDefaultValue; + bool mbAnimationStarted; + }; + + + class PathAnimation : public NumberAnimation + { + public: + PathAnimation( const ::rtl::OUString& rSVGDPath, + sal_Int16 nAdditive, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + int nFlags ) : + maPathPoly(), + mpShape(), + mpAttrLayer(), + mpShapeManager( rShapeManager ), + maPageSize( rSlideSize ), + maShapeOrig(), + mnFlags( nFlags ), + mbAnimationStarted( false ), + mnAdditive( nAdditive ) + { + ENSURE_OR_THROW( rShapeManager, + "PathAnimation::PathAnimation(): Invalid ShapeManager" ); + + ::basegfx::B2DPolyPolygon aPolyPoly; + + ENSURE_OR_THROW( ::basegfx::tools::importFromSvgD( aPolyPoly, rSVGDPath ), + "PathAnimation::PathAnimation(): failed to parse SVG:d path" ); + ENSURE_OR_THROW( aPolyPoly.count() == 1, + "PathAnimation::PathAnimation(): motion path consists of multiple/zero polygon(s)" ); + + // TODO(F2): Since getPositionRelative() currently + // cannot handle beziers, have to subdivide. + // AW: Should be no longer necessary; getPositionRelative is now bezier-safe + maPathPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly.getB2DPolygon(0) ); + } + + ~PathAnimation() + { + end_(); + } + + // Animation interface + // ------------------- + virtual void prefetch( const AnimatableShapeSharedPtr&, + const ShapeAttributeLayerSharedPtr& ) + {} + + virtual void start( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) + { + OSL_ENSURE( !mpShape, + "PathAnimation::start(): Shape already set" ); + OSL_ENSURE( !mpAttrLayer, + "PathAnimation::start(): Attribute layer already set" ); + + mpShape = rShape; + mpAttrLayer = rAttrLayer; + + ENSURE_OR_THROW( rShape, + "PathAnimation::start(): Invalid shape" ); + ENSURE_OR_THROW( rAttrLayer, + "PathAnimation::start(): Invalid attribute layer" ); + + // TODO(F1): Check whether _shape_ bounds are correct here. + // Theoretically, our AttrLayer is way down the stack, and + // we only have to consider _that_ value, not the one from + // the top of the stack as returned by Shape::getBounds() + if( mnAdditive == animations::AnimationAdditiveMode::SUM ) + maShapeOrig = mpShape->getBounds().getCenter(); + else + maShapeOrig = mpShape->getDomBounds().getCenter(); + + if( !mbAnimationStarted ) + { + mbAnimationStarted = true; + + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) + mpShapeManager->enterAnimationMode( mpShape ); + } + } + + virtual void end() { end_(); } + void end_() + { + if( mbAnimationStarted ) + { + mbAnimationStarted = false; + + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) + mpShapeManager->leaveAnimationMode( mpShape ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + } + } + + // NumberAnimation interface + // ----------------------- + + virtual bool operator()( double nValue ) + { + ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape, + "PathAnimation::operator(): Invalid ShapeAttributeLayer" ); + + ::basegfx::B2DPoint rOutPos = ::basegfx::tools::getPositionRelative( maPathPoly, + nValue ); + + // TODO(F1): Determine whether the path is + // absolute, or shape-relative. + + // interpret path as page-relative. Scale up with page size + rOutPos *= maPageSize; + + // TODO(F1): Determine whether the path origin is + // absolute, or shape-relative. + + // interpret path as shape-originated. Offset to shape position + + rOutPos += maShapeOrig; + + mpAttrLayer->setPosition( rOutPos ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + + return true; + } + + virtual double getUnderlyingValue() const + { + ENSURE_OR_THROW( mpAttrLayer, + "PathAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" ); + + return 0.0; // though this should be used in concert with + // ActivitiesFactory::createSimpleActivity, better + // explicitely name our start value. + // Permissible range for operator() above is [0,1] + } + + private: + ::basegfx::B2DPolygon maPathPoly; + AnimatableShapeSharedPtr mpShape; + ShapeAttributeLayerSharedPtr mpAttrLayer; + ShapeManagerSharedPtr mpShapeManager; + const ::basegfx::B2DSize maPageSize; + ::basegfx::B2DPoint maShapeOrig; + const int mnFlags; + bool mbAnimationStarted; + sal_Int16 mnAdditive; + }; + + + /** GenericAnimation template + + This template makes heavy use of SFINAE, only one of + the operator()() methods will compile for each of the + base classes. + + Note that we omit the virtual keyword on the + operator()() overrides and getUnderlyingValue() methods on + purpose; those that actually do override baseclass + virtual methods inherit the property, and the others + won't increase our vtable. What's more, having all + those methods in the vtable actually creates POIs for + them, which breaks the whole SFINAE concept (IOW, this + template won't compile any longer). + + @tpl AnimationBase + Type of animation to generate (determines the + interface GenericAnimation will implement). Must be + one of NumberAnimation, ColorAnimation, + StringAnimation, PairAnimation or BoolAnimation. + + @tpl ModifierFunctor + Type of a functor object, which can optionally be used to + modify the getter/setter values. + */ + template< typename AnimationBase, typename ModifierFunctor > class GenericAnimation : public AnimationBase + { + public: + typedef typename AnimationBase::ValueType ValueT; + + /** Create generic animation + + @param pIsValid + Function pointer to one of the is*Valid + methods. Used to either take the given getter + method, or the given default value for the start value. + + @param rDefaultValue + Default value, to take as the start value if + is*Valid returns false. + + @param pGetValue + Getter method, to fetch start value if valid. + + @param pSetValue + Setter method. This one puts the current animation + value to the ShapeAttributeLayer. + + @param rGetterModifier + Modifies up values retrieved from the pGetValue method. + Must provide operator()( const ValueT& ) method. + + @param rSetterModifier + Modifies up values before passing them to the pSetValue method. + Must provide operator()( const ValueT& ) method. + */ + GenericAnimation( const ShapeManagerSharedPtr& rShapeManager, + int nFlags, + bool (ShapeAttributeLayer::*pIsValid)() const, + const ValueT& rDefaultValue, + ValueT (ShapeAttributeLayer::*pGetValue)() const, + void (ShapeAttributeLayer::*pSetValue)( const ValueT& ), + const ModifierFunctor& rGetterModifier, + const ModifierFunctor& rSetterModifier ) : + mpShape(), + mpAttrLayer(), + mpShapeManager( rShapeManager ), + mpIsValidFunc(pIsValid), + mpGetValueFunc(pGetValue), + mpSetValueFunc(pSetValue), + maGetterModifier( rGetterModifier ), + maSetterModifier( rSetterModifier ), + mnFlags( nFlags ), + maDefaultValue(rDefaultValue), + mbAnimationStarted( false ) + { + ENSURE_OR_THROW( rShapeManager, + "GenericAnimation::GenericAnimation(): Invalid ShapeManager" ); + ENSURE_OR_THROW( pIsValid && pGetValue && pSetValue, + "GenericAnimation::GenericAnimation(): One of the method pointers is NULL" ); + } + + ~GenericAnimation() + { + end_(); + } + + // Animation interface + // ------------------- + virtual void prefetch( const AnimatableShapeSharedPtr&, + const ShapeAttributeLayerSharedPtr& ) + {} + + virtual void start( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) + { + OSL_ENSURE( !mpShape, + "GenericAnimation::start(): Shape already set" ); + OSL_ENSURE( !mpAttrLayer, + "GenericAnimation::start(): Attribute layer already set" ); + + mpShape = rShape; + mpAttrLayer = rAttrLayer; + + ENSURE_OR_THROW( rShape, + "GenericAnimation::start(): Invalid shape" ); + ENSURE_OR_THROW( rAttrLayer, + "GenericAnimation::start(): Invalid attribute layer" ); + + // only start animation once per repeated start() call, + // and only if sprites should be used for display + if( !mbAnimationStarted ) + { + mbAnimationStarted = true; + + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) + mpShapeManager->enterAnimationMode( mpShape ); + } + } + + virtual void end() { end_(); } + void end_() + { + // TODO(Q2): Factor out common code (most + // prominently start() and end()) into base class + + // only stop animation once per repeated end() call, + // and only if sprites are used for display + if( mbAnimationStarted ) + { + mbAnimationStarted = false; + + if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) ) + mpShapeManager->leaveAnimationMode( mpShape ); + + // Attention, this notifyShapeUpdate() is + // somewhat delicate here. Calling it + // unconditional (i.e. not guarded by + // mbAnimationStarted) will lead to shapes + // snapping back to their original state just + // before the slide ends. Not calling it at + // all might swallow final animation + // states. The current implementation relies + // on the fact that end() is either called by + // the Activity (then, the last animation + // state has been set, and corresponds to the + // shape's hold state), or by the animation + // node (then, it's a forced end, and we + // _have_ to snap back). + // + // To reiterate: normally, we're called from + // the Activity first, thus the + // notifyShapeUpdate() below will update to + // the last activity value. + + // force shape update, activity might have changed + // state in the last round. + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + } + } + + // Derived Animation interface + // --------------------------- + + /** For by-reference interfaces (B2DTuple, OUString) + */ + bool operator()( const ValueT& x ) + { + ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape, + "GenericAnimation::operator(): Invalid ShapeAttributeLayer" ); + + ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + + return true; + } + + /** For by-value interfaces (bool, double) + */ + bool operator()( ValueT x ) + { + ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape, + "GenericAnimation::operator(): Invalid ShapeAttributeLayer" ); + + ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + + return true; + } + + ValueT getUnderlyingValue() const + { + ENSURE_OR_THROW( mpAttrLayer, + "GenericAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" ); + + // deviated from the (*shared_ptr).*mpFuncPtr + // notation here, since gcc does not seem to parse + // that as a member function call anymore. + if( (mpAttrLayer.get()->*mpIsValidFunc)() ) + return maGetterModifier( ((*mpAttrLayer).*mpGetValueFunc)() ); + else + return maDefaultValue; + } + + private: + AnimatableShapeSharedPtr mpShape; + ShapeAttributeLayerSharedPtr mpAttrLayer; + ShapeManagerSharedPtr mpShapeManager; + bool (ShapeAttributeLayer::*mpIsValidFunc)() const; + ValueT (ShapeAttributeLayer::*mpGetValueFunc)() const; + void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& ); + + ModifierFunctor maGetterModifier; + ModifierFunctor maSetterModifier; + + const int mnFlags; + + const ValueT maDefaultValue; + bool mbAnimationStarted; + }; + + /** Function template wrapper around GenericAnimation template + + @tpl AnimationBase + Type of animation to generate (determines the + interface GenericAnimation will implement). + */ + template< typename AnimationBase > ::boost::shared_ptr< AnimationBase > + makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager, + int nFlags, + bool (ShapeAttributeLayer::*pIsValid)() const, + const typename AnimationBase::ValueType& rDefaultValue, + typename AnimationBase::ValueType (ShapeAttributeLayer::*pGetValue)() const, + void (ShapeAttributeLayer::*pSetValue)( const typename AnimationBase::ValueType& ) ) + { + return ::boost::shared_ptr< AnimationBase >( + new GenericAnimation< AnimationBase, + ::std::identity< typename AnimationBase::ValueType > >( + rShapeManager, + nFlags, + pIsValid, + rDefaultValue, + pGetValue, + pSetValue, + // no modification necessary, use identity functor here + ::std::identity< typename AnimationBase::ValueType >(), + ::std::identity< typename AnimationBase::ValueType >() ) ); + } + + class Scaler + { + public: + Scaler( double nScale ) : + mnScale( nScale ) + { + } + + double operator()( double nVal ) const + { + return mnScale * nVal; + } + + private: + double mnScale; + }; + + /** Overload for NumberAnimations which need scaling (width,height,x,y currently) + */ + NumberAnimationSharedPtr makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager, + int nFlags, + bool (ShapeAttributeLayer::*pIsValid)() const, + double nDefaultValue, + double (ShapeAttributeLayer::*pGetValue)() const, + void (ShapeAttributeLayer::*pSetValue)( const double& ), + double nScaleValue ) + { + return NumberAnimationSharedPtr( + new GenericAnimation< NumberAnimation, Scaler >( rShapeManager, + nFlags, + pIsValid, + nDefaultValue / nScaleValue, + pGetValue, + pSetValue, + Scaler( 1.0/nScaleValue ), + Scaler( nScaleValue ) ) ); + } + + + uno::Any getShapeDefault( const AnimatableShapeSharedPtr& rShape, + const ::rtl::OUString& rPropertyName ) + { + uno::Reference< drawing::XShape > xShape( rShape->getXShape() ); + + if( !xShape.is() ) + return uno::Any(); // no regular shape, no defaults available + + + // extract relevant value from XShape's PropertySet + uno::Reference< beans::XPropertySet > xPropSet( xShape, + uno::UNO_QUERY ); + + ENSURE_OR_THROW( xPropSet.is(), + "getShapeDefault(): Cannot query property set from shape" ); + + return xPropSet->getPropertyValue( rPropertyName ); + } + + template< typename ValueType > ValueType getDefault( const AnimatableShapeSharedPtr& rShape, + const ::rtl::OUString& rPropertyName ) + { + const uno::Any& rAny( getShapeDefault( rShape, + rPropertyName ) ); + + if( !rAny.hasValue() ) + { + OSL_ENSURE( false, "getDefault(): cannot get requested shape property" ); + OSL_TRACE( "getDefault(): cannot get '%s' shape property", + ::rtl::OUStringToOString( rPropertyName, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + return ValueType(); + } + else + { + ValueType aValue = ValueType(); + + if( !(rAny >>= aValue) ) + { + OSL_ENSURE( false, "getDefault(): cannot extract requested shape property" ); + OSL_TRACE( "getDefault(): cannot extract '%s' shape property", + ::rtl::OUStringToOString( rPropertyName, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + return ValueType(); + } + + return aValue; + } + } + + template<> RGBColor getDefault< RGBColor >( const AnimatableShapeSharedPtr& rShape, + const ::rtl::OUString& rPropertyName ) + { + const uno::Any& rAny( getShapeDefault( rShape, + rPropertyName ) ); + + if( !rAny.hasValue() ) + { + OSL_ENSURE( false, "getDefault(): cannot get requested shape color property" ); + OSL_TRACE( "getDefault(): cannot get '%s' shape color property", + ::rtl::OUStringToOString( rPropertyName, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + return RGBColor(); + } + else + { + sal_Int32 nValue = 0; + + if( !(rAny >>= nValue) ) + { + OSL_ENSURE( false, "getDefault(): cannot extract requested shape color property" ); + OSL_TRACE( "getDefault(): cannot extract '%s' shape color property", + ::rtl::OUStringToOString( rPropertyName, + RTL_TEXTENCODING_ASCII_US ).getStr() ); + return RGBColor(); + } + + // convert from 0xAARRGGBB API color to 0xRRGGBB00 + // canvas color + return RGBColor( (nValue << 8U) & 0xFFFFFF00U ); + } + } + } + + AnimationFactory::AttributeClass AnimationFactory::classifyAttributeName( const ::rtl::OUString& rAttrName ) + { + // ATTENTION: When changing this map, also the create*PropertyAnimation() methods must + // be checked and possibly adapted in their switch statements + + // TODO(Q2): Since this map must be coherent with the various switch statements + // in the create*PropertyAnimation methods, try to unify into a single method or table + switch( mapAttributeName( rAttrName ) ) + { + default: + // FALLTHROUGH intended + case ATTRIBUTE_INVALID: + return CLASS_UNKNOWN_PROPERTY; + + case ATTRIBUTE_CHAR_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_DIMCOLOR: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_COLOR: + return CLASS_COLOR_PROPERTY; + + case ATTRIBUTE_CHAR_FONT_NAME: + return CLASS_STRING_PROPERTY; + + case ATTRIBUTE_VISIBILITY: + return CLASS_BOOL_PROPERTY; + + case ATTRIBUTE_CHAR_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_WEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_ROTATION: + // FALLTHROUGH intended + case ATTRIBUTE_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_OPACITY: + // FALLTHROUGH intended + case ATTRIBUTE_ROTATE: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_X: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_Y: + // FALLTHROUGH intended + case ATTRIBUTE_WIDTH: + // FALLTHROUGH intended + case ATTRIBUTE_POS_X: + // FALLTHROUGH intended + case ATTRIBUTE_POS_Y: + return CLASS_NUMBER_PROPERTY; + + case ATTRIBUTE_CHAR_UNDERLINE: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_POSTURE: + return CLASS_ENUM_PROPERTY; + } + } + + NumberAnimationSharedPtr AnimationFactory::createNumberPropertyAnimation( const ::rtl::OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + int nFlags ) + { + // ATTENTION: When changing this map, also the classifyAttributeName() method must + // be checked and possibly adapted in their switch statement + switch( mapAttributeName( rAttrName ) ) + { + default: + // FALLTHROUGH intended + case ATTRIBUTE_INVALID: + ENSURE_OR_THROW( false, + "AnimationFactory::createNumberPropertyAnimation(): Unknown attribute" ); + break; + + case ATTRIBUTE_CHAR_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_FONT_NAME: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_POSTURE: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_UNDERLINE: + // FALLTHROUGH intended + case ATTRIBUTE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_DIMCOLOR: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_VISIBILITY: + ENSURE_OR_THROW( false, + "AnimationFactory::createNumberPropertyAnimation(): Attribute type mismatch" ); + break; + + case ATTRIBUTE_CHAR_HEIGHT: + return makeGenericAnimation<NumberAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isCharScaleValid, + 1.0, // CharHeight is a relative attribute, thus + // default is 1.0 + &ShapeAttributeLayer::getCharScale, + &ShapeAttributeLayer::setCharScale ); + + case ATTRIBUTE_CHAR_WEIGHT: + return makeGenericAnimation<NumberAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isCharWeightValid, + getDefault<double>( rShape, rAttrName ), + &ShapeAttributeLayer::getCharWeight, + &ShapeAttributeLayer::setCharWeight ); + + case ATTRIBUTE_CHAR_ROTATION: + return makeGenericAnimation<NumberAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isCharRotationAngleValid, + getDefault<double>( rShape, rAttrName ), + &ShapeAttributeLayer::getCharRotationAngle, + &ShapeAttributeLayer::setCharRotationAngle ); + + case ATTRIBUTE_HEIGHT: + return makeGenericAnimation( rShapeManager, + nFlags, + &ShapeAttributeLayer::isHeightValid, + // TODO(F1): Check whether _shape_ bounds are correct here. + // Theoretically, our AttrLayer is way down the stack, and + // we only have to consider _that_ value, not the one from + // the top of the stack as returned by Shape::getBounds() + rShape->getBounds().getHeight(), + &ShapeAttributeLayer::getHeight, + &ShapeAttributeLayer::setHeight, + // convert expression parser value from relative page size + rSlideSize.getY() ); + + case ATTRIBUTE_OPACITY: + return makeGenericAnimation<NumberAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isAlphaValid, + // TODO(F1): Provide shape default here (FillTransparency?) + 1.0, + &ShapeAttributeLayer::getAlpha, + &ShapeAttributeLayer::setAlpha ); + + case ATTRIBUTE_ROTATE: + return makeGenericAnimation<NumberAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isRotationAngleValid, + // NOTE: Since we paint the shape as-is from metafile, + // rotation angle is always 0.0, even for rotated shapes + 0.0, + &ShapeAttributeLayer::getRotationAngle, + &ShapeAttributeLayer::setRotationAngle ); + + case ATTRIBUTE_SKEW_X: + return makeGenericAnimation<NumberAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isShearXAngleValid, + // TODO(F1): Is there any shape property for skew? + 0.0, + &ShapeAttributeLayer::getShearXAngle, + &ShapeAttributeLayer::setShearXAngle ); + + case ATTRIBUTE_SKEW_Y: + return makeGenericAnimation<NumberAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isShearYAngleValid, + // TODO(F1): Is there any shape property for skew? + 0.0, + &ShapeAttributeLayer::getShearYAngle, + &ShapeAttributeLayer::setShearYAngle ); + + case ATTRIBUTE_WIDTH: + return makeGenericAnimation( rShapeManager, + nFlags, + &ShapeAttributeLayer::isWidthValid, + // TODO(F1): Check whether _shape_ bounds are correct here. + // Theoretically, our AttrLayer is way down the stack, and + // we only have to consider _that_ value, not the one from + // the top of the stack as returned by Shape::getBounds() + rShape->getBounds().getWidth(), + &ShapeAttributeLayer::getWidth, + &ShapeAttributeLayer::setWidth, + // convert expression parser value from relative page size + rSlideSize.getX() ); + + case ATTRIBUTE_POS_X: + return makeGenericAnimation( rShapeManager, + nFlags, + &ShapeAttributeLayer::isPosXValid, + // TODO(F1): Check whether _shape_ bounds are correct here. + // Theoretically, our AttrLayer is way down the stack, and + // we only have to consider _that_ value, not the one from + // the top of the stack as returned by Shape::getBounds() + rShape->getBounds().getCenterX(), + &ShapeAttributeLayer::getPosX, + &ShapeAttributeLayer::setPosX, + // convert expression parser value from relative page size + rSlideSize.getX() ); + + case ATTRIBUTE_POS_Y: + return makeGenericAnimation( rShapeManager, + nFlags, + &ShapeAttributeLayer::isPosYValid, + // TODO(F1): Check whether _shape_ bounds are correct here. + // Theoretically, our AttrLayer is way down the stack, and + // we only have to consider _that_ value, not the one from + // the top of the stack as returned by Shape::getBounds() + rShape->getBounds().getCenterY(), + &ShapeAttributeLayer::getPosY, + &ShapeAttributeLayer::setPosY, + // convert expression parser value from relative page size + rSlideSize.getY() ); + } + + return NumberAnimationSharedPtr(); + } + + EnumAnimationSharedPtr AnimationFactory::createEnumPropertyAnimation( const ::rtl::OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& /*rSlideSize*/, + int nFlags ) + { + // ATTENTION: When changing this map, also the classifyAttributeName() method must + // be checked and possibly adapted in their switch statement + switch( mapAttributeName( rAttrName ) ) + { + default: + // FALLTHROUGH intended + case ATTRIBUTE_INVALID: + ENSURE_OR_THROW( false, + "AnimationFactory::createEnumPropertyAnimation(): Unknown attribute" ); + break; + + case ATTRIBUTE_CHAR_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_FONT_NAME: + // FALLTHROUGH intended + case ATTRIBUTE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_DIMCOLOR: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_VISIBILITY: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_WEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_ROTATION: + // FALLTHROUGH intended + case ATTRIBUTE_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_OPACITY: + // FALLTHROUGH intended + case ATTRIBUTE_ROTATE: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_X: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_Y: + // FALLTHROUGH intended + case ATTRIBUTE_WIDTH: + // FALLTHROUGH intended + case ATTRIBUTE_POS_X: + // FALLTHROUGH intended + case ATTRIBUTE_POS_Y: + ENSURE_OR_THROW( false, + "AnimationFactory::createEnumPropertyAnimation(): Attribute type mismatch" ); + break; + + + case ATTRIBUTE_FILL_STYLE: + return makeGenericAnimation<EnumAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isFillStyleValid, + sal::static_int_cast<sal_Int16>( + getDefault<drawing::FillStyle>( rShape, rAttrName )), + &ShapeAttributeLayer::getFillStyle, + &ShapeAttributeLayer::setFillStyle ); + + case ATTRIBUTE_LINE_STYLE: + return makeGenericAnimation<EnumAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isLineStyleValid, + sal::static_int_cast<sal_Int16>( + getDefault<drawing::LineStyle>( rShape, rAttrName )), + &ShapeAttributeLayer::getLineStyle, + &ShapeAttributeLayer::setLineStyle ); + + case ATTRIBUTE_CHAR_POSTURE: + return makeGenericAnimation<EnumAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isCharPostureValid, + sal::static_int_cast<sal_Int16>( + getDefault<awt::FontSlant>( rShape, rAttrName )), + &ShapeAttributeLayer::getCharPosture, + &ShapeAttributeLayer::setCharPosture ); + + case ATTRIBUTE_CHAR_UNDERLINE: + return makeGenericAnimation<EnumAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isUnderlineModeValid, + getDefault<sal_Int16>( rShape, rAttrName ), + &ShapeAttributeLayer::getUnderlineMode, + &ShapeAttributeLayer::setUnderlineMode ); + } + + return EnumAnimationSharedPtr(); + } + + ColorAnimationSharedPtr AnimationFactory::createColorPropertyAnimation( const ::rtl::OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& /*rSlideSize*/, + int nFlags ) + { + // ATTENTION: When changing this map, also the classifyAttributeName() method must + // be checked and possibly adapted in their switch statement + switch( mapAttributeName( rAttrName ) ) + { + default: + // FALLTHROUGH intended + case ATTRIBUTE_INVALID: + ENSURE_OR_THROW( false, + "AnimationFactory::createColorPropertyAnimation(): Unknown attribute" ); + break; + + case ATTRIBUTE_CHAR_FONT_NAME: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_POSTURE: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_ROTATION: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_UNDERLINE: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_WEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_OPACITY: + // FALLTHROUGH intended + case ATTRIBUTE_ROTATE: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_X: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_Y: + // FALLTHROUGH intended + case ATTRIBUTE_VISIBILITY: + // FALLTHROUGH intended + case ATTRIBUTE_WIDTH: + // FALLTHROUGH intended + case ATTRIBUTE_POS_X: + // FALLTHROUGH intended + case ATTRIBUTE_POS_Y: + ENSURE_OR_THROW( false, + "AnimationFactory::createColorPropertyAnimation(): Attribute type mismatch" ); + break; + + case ATTRIBUTE_CHAR_COLOR: + return makeGenericAnimation<ColorAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isCharColorValid, + getDefault<RGBColor>( rShape, rAttrName ), + &ShapeAttributeLayer::getCharColor, + &ShapeAttributeLayer::setCharColor ); + + case ATTRIBUTE_COLOR: + // TODO(F2): This is just mapped to fill color to make it work + return makeGenericAnimation<ColorAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isFillColorValid, + getDefault<RGBColor>( rShape, rAttrName ), + &ShapeAttributeLayer::getFillColor, + &ShapeAttributeLayer::setFillColor ); + + case ATTRIBUTE_DIMCOLOR: + return makeGenericAnimation<ColorAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isDimColorValid, + getDefault<RGBColor>( rShape, rAttrName ), + &ShapeAttributeLayer::getDimColor, + &ShapeAttributeLayer::setDimColor ); + + case ATTRIBUTE_FILL_COLOR: + return makeGenericAnimation<ColorAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isFillColorValid, + getDefault<RGBColor>( rShape, rAttrName ), + &ShapeAttributeLayer::getFillColor, + &ShapeAttributeLayer::setFillColor ); + + case ATTRIBUTE_LINE_COLOR: + return makeGenericAnimation<ColorAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isLineColorValid, + getDefault<RGBColor>( rShape, rAttrName ), + &ShapeAttributeLayer::getLineColor, + &ShapeAttributeLayer::setLineColor ); + } + + return ColorAnimationSharedPtr(); + } + + PairAnimationSharedPtr AnimationFactory::createPairPropertyAnimation( const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + sal_Int16 nTransformType, + int nFlags ) + { + const ::basegfx::B2DRectangle& rBounds( rShape->getBounds() ); + + switch( nTransformType ) + { + case animations::AnimationTransformType::SCALE: + return PairAnimationSharedPtr( + new TupleAnimation< ::basegfx::B2DSize >( + rShapeManager, + nFlags, + &ShapeAttributeLayer::isWidthValid, + &ShapeAttributeLayer::isHeightValid, + // TODO(F1): Check whether _shape_ bounds are correct here. + // Theoretically, our AttrLayer is way down the stack, and + // we only have to consider _that_ value, not the one from + // the top of the stack as returned by Shape::getBounds() + rBounds.getRange(), + rBounds.getRange(), + &ShapeAttributeLayer::getWidth, + &ShapeAttributeLayer::getHeight, + &ShapeAttributeLayer::setSize ) ); + + case animations::AnimationTransformType::TRANSLATE: + return PairAnimationSharedPtr( + new TupleAnimation< ::basegfx::B2DPoint >( + rShapeManager, + nFlags, + &ShapeAttributeLayer::isPosXValid, + &ShapeAttributeLayer::isPosYValid, + // TODO(F1): Check whether _shape_ bounds are correct here. + // Theoretically, our AttrLayer is way down the stack, and + // we only have to consider _that_ value, not the one from + // the top of the stack as returned by Shape::getBounds() + rBounds.getCenter(), + rSlideSize, + &ShapeAttributeLayer::getPosX, + &ShapeAttributeLayer::getPosY, + &ShapeAttributeLayer::setPosition ) ); + + default: + ENSURE_OR_THROW( false, + "AnimationFactory::createPairPropertyAnimation(): Attribute type mismatch" ); + break; + } + + return PairAnimationSharedPtr(); + } + + StringAnimationSharedPtr AnimationFactory::createStringPropertyAnimation( const ::rtl::OUString& rAttrName, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& /*rSlideSize*/, + int nFlags ) + { + // ATTENTION: When changing this map, also the classifyAttributeName() method must + // be checked and possibly adapted in their switch statement + switch( mapAttributeName( rAttrName ) ) + { + default: + // FALLTHROUGH intended + case ATTRIBUTE_INVALID: + ENSURE_OR_THROW( false, + "AnimationFactory::createStringPropertyAnimation(): Unknown attribute" ); + break; + + case ATTRIBUTE_CHAR_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_ROTATION: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_UNDERLINE: + // FALLTHROUGH intended + case ATTRIBUTE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_DIMCOLOR: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_OPACITY: + // FALLTHROUGH intended + case ATTRIBUTE_ROTATE: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_X: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_Y: + // FALLTHROUGH intended + case ATTRIBUTE_VISIBILITY: + // FALLTHROUGH intended + case ATTRIBUTE_WIDTH: + // FALLTHROUGH intended + case ATTRIBUTE_POS_X: + // FALLTHROUGH intended + case ATTRIBUTE_POS_Y: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_POSTURE: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_WEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_STYLE: + ENSURE_OR_THROW( false, + "AnimationFactory::createStringPropertyAnimation(): Attribute type mismatch" ); + break; + + case ATTRIBUTE_CHAR_FONT_NAME: + return makeGenericAnimation<StringAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isFontFamilyValid, + getDefault< ::rtl::OUString >( rShape, rAttrName ), + &ShapeAttributeLayer::getFontFamily, + &ShapeAttributeLayer::setFontFamily ); + } + + return StringAnimationSharedPtr(); + } + + BoolAnimationSharedPtr AnimationFactory::createBoolPropertyAnimation( const ::rtl::OUString& rAttrName, + const AnimatableShapeSharedPtr& /*rShape*/, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& /*rSlideSize*/, + int nFlags ) + { + // ATTENTION: When changing this map, also the classifyAttributeName() method must + // be checked and possibly adapted in their switch statement + switch( mapAttributeName( rAttrName ) ) + { + default: + // FALLTHROUGH intended + case ATTRIBUTE_INVALID: + ENSURE_OR_THROW( false, + "AnimationFactory::createBoolPropertyAnimation(): Unknown attribute" ); + break; + + case ATTRIBUTE_CHAR_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_FONT_NAME: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_POSTURE: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_ROTATION: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_WEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_DIMCOLOR: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_FILL_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_HEIGHT: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_COLOR: + // FALLTHROUGH intended + case ATTRIBUTE_LINE_STYLE: + // FALLTHROUGH intended + case ATTRIBUTE_OPACITY: + // FALLTHROUGH intended + case ATTRIBUTE_ROTATE: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_X: + // FALLTHROUGH intended + case ATTRIBUTE_SKEW_Y: + // FALLTHROUGH intended + case ATTRIBUTE_WIDTH: + // FALLTHROUGH intended + case ATTRIBUTE_POS_X: + // FALLTHROUGH intended + case ATTRIBUTE_POS_Y: + // FALLTHROUGH intended + case ATTRIBUTE_CHAR_UNDERLINE: + ENSURE_OR_THROW( false, + "AnimationFactory::createBoolPropertyAnimation(): Attribute type mismatch" ); + break; + + case ATTRIBUTE_VISIBILITY: + return makeGenericAnimation<BoolAnimation>( rShapeManager, + nFlags, + &ShapeAttributeLayer::isVisibilityValid, + // TODO(F1): Is there a corresponding shape property? + true, + &ShapeAttributeLayer::getVisibility, + &ShapeAttributeLayer::setVisibility ); + } + + return BoolAnimationSharedPtr(); + } + + NumberAnimationSharedPtr AnimationFactory::createPathMotionAnimation( const ::rtl::OUString& rSVGDPath, + sal_Int16 nAdditive, + const AnimatableShapeSharedPtr& /*rShape*/, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + int nFlags ) + { + return NumberAnimationSharedPtr( + new PathAnimation( rSVGDPath, nAdditive, + rShapeManager, + rSlideSize, + nFlags ) ); + } + + } +} |