Bump version to 6.0-36
[LibreOffice.git] / slideshow / source / engine / animationfactory.cxx
blob1d666629302c02085775d5a67cf5ad38bd1689fe
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <tools/diagnose_ex.h>
23 #include <animationfactory.hxx>
24 #include <attributemap.hxx>
26 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
27 #include <com/sun/star/animations/AnimationTransformType.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/drawing/FillStyle.hpp>
30 #include <com/sun/star/drawing/LineStyle.hpp>
31 #include <com/sun/star/awt/FontSlant.hpp>
32 #include <com/sun/star/awt/FontUnderline.hpp>
33 #include <com/sun/star/awt/FontWeight.hpp>
35 #include <basegfx/polygon/b2dpolygon.hxx>
36 #include <basegfx/polygon/b2dpolygontools.hxx>
37 #include <basegfx/polygon/b2dpolypolygontools.hxx>
40 using namespace ::com::sun::star;
43 namespace slideshow
45 namespace internal
47 namespace
49 // attention, there is a similar implementation of Animation in
50 // transitions/transitionfactory.cxx
52 template< typename ValueT > class TupleAnimation : public PairAnimation
54 public:
55 TupleAnimation( const ShapeManagerSharedPtr& rShapeManager,
56 int nFlags,
57 bool (ShapeAttributeLayer::*pIs1stValid)() const,
58 bool (ShapeAttributeLayer::*pIs2ndValid)() const,
59 const ValueT& rDefaultValue,
60 const ::basegfx::B2DSize& rReferenceSize,
61 double (ShapeAttributeLayer::*pGet1stValue)() const,
62 double (ShapeAttributeLayer::*pGet2ndValue)() const,
63 void (ShapeAttributeLayer::*pSetValue)( const ValueT& ) ) :
64 mpShape(),
65 mpAttrLayer(),
66 mpShapeManager( rShapeManager ),
67 mpIs1stValidFunc(pIs1stValid),
68 mpIs2ndValidFunc(pIs2ndValid),
69 mpGet1stValueFunc(pGet1stValue),
70 mpGet2ndValueFunc(pGet2ndValue),
71 mpSetValueFunc(pSetValue),
72 mnFlags( nFlags ),
73 maReferenceSize( rReferenceSize ),
74 maDefaultValue( rDefaultValue ),
75 mbAnimationStarted( false )
77 ENSURE_OR_THROW( rShapeManager,
78 "TupleAnimation::TupleAnimation(): Invalid ShapeManager" );
79 ENSURE_OR_THROW( pIs1stValid && pIs2ndValid && pGet1stValue && pGet2ndValue && pSetValue,
80 "TupleAnimation::TupleAnimation(): One of the method pointers is NULL" );
83 virtual ~TupleAnimation() override
85 end_();
88 // Animation interface
90 virtual void prefetch( const AnimatableShapeSharedPtr&,
91 const ShapeAttributeLayerSharedPtr& ) override
94 virtual void start( const AnimatableShapeSharedPtr& rShape,
95 const ShapeAttributeLayerSharedPtr& rAttrLayer ) override
97 OSL_ENSURE( !mpShape,
98 "TupleAnimation::start(): Shape already set" );
99 OSL_ENSURE( !mpAttrLayer,
100 "TupleAnimation::start(): Attribute layer already set" );
102 mpShape = rShape;
103 mpAttrLayer = rAttrLayer;
105 ENSURE_OR_THROW( rShape,
106 "TupleAnimation::start(): Invalid shape" );
107 ENSURE_OR_THROW( rAttrLayer,
108 "TupleAnimation::start(): Invalid attribute layer" );
110 if( !mbAnimationStarted )
112 mbAnimationStarted = true;
114 if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
115 mpShapeManager->enterAnimationMode( mpShape );
119 virtual void end() override { end_(); }
120 void end_()
122 if( mbAnimationStarted )
124 mbAnimationStarted = false;
126 if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
127 mpShapeManager->leaveAnimationMode( mpShape );
129 if( mpShape->isContentChanged() )
130 mpShapeManager->notifyShapeUpdate( mpShape );
134 // PairAnimation interface
137 virtual bool operator()( const ::basegfx::B2DTuple& rValue ) override
139 ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
140 "TupleAnimation::operator(): Invalid ShapeAttributeLayer" );
142 ValueT aValue( rValue.getX(),
143 rValue.getY() );
145 // Activities get values from the expression parser,
146 // which returns _relative_ sizes/positions.
147 // Convert back relative to reference coordinate system
148 aValue *= maReferenceSize;
150 ((*mpAttrLayer).*mpSetValueFunc)( aValue );
152 if( mpShape->isContentChanged() )
153 mpShapeManager->notifyShapeUpdate( mpShape );
155 return true;
158 virtual ::basegfx::B2DTuple getUnderlyingValue() const override
160 ENSURE_OR_THROW( mpAttrLayer,
161 "TupleAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
163 ::basegfx::B2DTuple aRetVal;
165 // deviated from the (*shared_ptr).*mpFuncPtr
166 // notation here, since gcc does not seem to parse
167 // that as a member function call anymore.
168 aRetVal.setX( (mpAttrLayer.get()->*mpIs1stValidFunc)() ?
169 (mpAttrLayer.get()->*mpGet1stValueFunc)() :
170 maDefaultValue.getX() );
171 aRetVal.setY( (mpAttrLayer.get()->*mpIs2ndValidFunc)() ?
172 (mpAttrLayer.get()->*mpGet2ndValueFunc)() :
173 maDefaultValue.getY() );
175 // Activities get values from the expression
176 // parser, which returns _relative_
177 // sizes/positions. Convert start value to the
178 // same coordinate space (i.e. relative to given
179 // reference size).
180 aRetVal /= maReferenceSize;
182 return aRetVal;
185 private:
186 AnimatableShapeSharedPtr mpShape;
187 ShapeAttributeLayerSharedPtr mpAttrLayer;
188 ShapeManagerSharedPtr mpShapeManager;
189 bool (ShapeAttributeLayer::*mpIs1stValidFunc)() const;
190 bool (ShapeAttributeLayer::*mpIs2ndValidFunc)() const;
191 double (ShapeAttributeLayer::*mpGet1stValueFunc)() const;
192 double (ShapeAttributeLayer::*mpGet2ndValueFunc)() const;
193 void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );
195 const int mnFlags;
197 const ::basegfx::B2DSize maReferenceSize;
198 const ValueT maDefaultValue;
199 bool mbAnimationStarted;
203 class PathAnimation : public NumberAnimation
205 public:
206 PathAnimation( const OUString& rSVGDPath,
207 sal_Int16 nAdditive,
208 const ShapeManagerSharedPtr& rShapeManager,
209 const ::basegfx::B2DVector& rSlideSize,
210 int nFlags ) :
211 maPathPoly(),
212 mpShape(),
213 mpAttrLayer(),
214 mpShapeManager( rShapeManager ),
215 maPageSize( rSlideSize ),
216 maShapeOrig(),
217 mnFlags( nFlags ),
218 mbAnimationStarted( false ),
219 mnAdditive( nAdditive )
221 ENSURE_OR_THROW( rShapeManager,
222 "PathAnimation::PathAnimation(): Invalid ShapeManager" );
224 ::basegfx::B2DPolyPolygon aPolyPoly;
226 ENSURE_OR_THROW( ::basegfx::utils::importFromSvgD( aPolyPoly, rSVGDPath, false, nullptr ),
227 "PathAnimation::PathAnimation(): failed to parse SVG:d path" );
228 ENSURE_OR_THROW( aPolyPoly.count() == 1,
229 "PathAnimation::PathAnimation(): motion path consists of multiple/zero polygon(s)" );
231 // TODO(F2): Since getPositionRelative() currently
232 // cannot handle beziers, have to subdivide.
233 // AW: Should be no longer necessary; getPositionRelative is now bezier-safe
234 maPathPoly = ::basegfx::utils::adaptiveSubdivideByAngle(aPolyPoly.getB2DPolygon(0) );
237 virtual ~PathAnimation() override
239 end_();
242 // Animation interface
244 virtual void prefetch( const AnimatableShapeSharedPtr&,
245 const ShapeAttributeLayerSharedPtr& ) override
248 virtual void start( const AnimatableShapeSharedPtr& rShape,
249 const ShapeAttributeLayerSharedPtr& rAttrLayer ) override
251 OSL_ENSURE( !mpShape,
252 "PathAnimation::start(): Shape already set" );
253 OSL_ENSURE( !mpAttrLayer,
254 "PathAnimation::start(): Attribute layer already set" );
256 mpShape = rShape;
257 mpAttrLayer = rAttrLayer;
259 ENSURE_OR_THROW( rShape,
260 "PathAnimation::start(): Invalid shape" );
261 ENSURE_OR_THROW( rAttrLayer,
262 "PathAnimation::start(): Invalid attribute layer" );
264 // TODO(F1): Check whether _shape_ bounds are correct here.
265 // Theoretically, our AttrLayer is way down the stack, and
266 // we only have to consider _that_ value, not the one from
267 // the top of the stack as returned by Shape::getBounds()
268 if( mnAdditive == animations::AnimationAdditiveMode::SUM )
269 maShapeOrig = mpShape->getBounds().getCenter();
270 else
271 maShapeOrig = mpShape->getDomBounds().getCenter();
273 if( !mbAnimationStarted )
275 mbAnimationStarted = true;
277 if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
278 mpShapeManager->enterAnimationMode( mpShape );
282 virtual void end() override { end_(); }
283 void end_()
285 if( mbAnimationStarted )
287 mbAnimationStarted = false;
289 if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
290 mpShapeManager->leaveAnimationMode( mpShape );
292 if( mpShape->isContentChanged() )
293 mpShapeManager->notifyShapeUpdate( mpShape );
297 // NumberAnimation interface
300 virtual bool operator()( double nValue ) override
302 ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
303 "PathAnimation::operator(): Invalid ShapeAttributeLayer" );
305 ::basegfx::B2DPoint rOutPos = ::basegfx::utils::getPositionRelative( maPathPoly,
306 nValue );
308 // TODO(F1): Determine whether the path is
309 // absolute, or shape-relative.
311 // interpret path as page-relative. Scale up with page size
312 rOutPos *= maPageSize;
314 // TODO(F1): Determine whether the path origin is
315 // absolute, or shape-relative.
317 // interpret path as shape-originated. Offset to shape position
319 rOutPos += maShapeOrig;
321 mpAttrLayer->setPosition( rOutPos );
323 if( mpShape->isContentChanged() )
324 mpShapeManager->notifyShapeUpdate( mpShape );
326 return true;
329 virtual double getUnderlyingValue() const override
331 ENSURE_OR_THROW( mpAttrLayer,
332 "PathAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
334 return 0.0; // though this should be used in concert with
335 // ActivitiesFactory::createSimpleActivity, better
336 // explicitly name our start value.
337 // Permissible range for operator() above is [0,1]
340 private:
341 ::basegfx::B2DPolygon maPathPoly;
342 AnimatableShapeSharedPtr mpShape;
343 ShapeAttributeLayerSharedPtr mpAttrLayer;
344 ShapeManagerSharedPtr mpShapeManager;
345 const ::basegfx::B2DSize maPageSize;
346 ::basegfx::B2DPoint maShapeOrig;
347 const int mnFlags;
348 bool mbAnimationStarted;
349 sal_Int16 mnAdditive;
353 /** GenericAnimation template
355 This template makes heavy use of SFINAE, only one of
356 the operator()() methods will compile for each of the
357 base classes.
359 Note that we omit the virtual keyword on the
360 operator()() overrides and getUnderlyingValue() methods on
361 purpose; those that actually do override baseclass
362 virtual methods inherit the property, and the others
363 won't increase our vtable. What's more, having all
364 those methods in the vtable actually creates POIs for
365 them, which breaks the whole SFINAE concept (IOW, this
366 template won't compile any longer).
368 @tpl AnimationBase
369 Type of animation to generate (determines the
370 interface GenericAnimation will implement). Must be
371 one of NumberAnimation, ColorAnimation,
372 StringAnimation, PairAnimation or BoolAnimation.
374 @tpl ModifierFunctor
375 Type of a functor object, which can optionally be used to
376 modify the getter/setter values.
378 template< typename AnimationBase, typename ModifierFunctor > class GenericAnimation : public AnimationBase
380 public:
381 typedef typename AnimationBase::ValueType ValueT;
383 /** Create generic animation
385 @param pIsValid
386 Function pointer to one of the is*Valid
387 methods. Used to either take the given getter
388 method, or the given default value for the start value.
390 @param rDefaultValue
391 Default value, to take as the start value if
392 is*Valid returns false.
394 @param pGetValue
395 Getter method, to fetch start value if valid.
397 @param pSetValue
398 Setter method. This one puts the current animation
399 value to the ShapeAttributeLayer.
401 @param rGetterModifier
402 Modifies up values retrieved from the pGetValue method.
403 Must provide operator()( const ValueT& ) method.
405 @param rSetterModifier
406 Modifies up values before passing them to the pSetValue method.
407 Must provide operator()( const ValueT& ) method.
409 GenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
410 int nFlags,
411 bool (ShapeAttributeLayer::*pIsValid)() const,
412 const ValueT& rDefaultValue,
413 ValueT (ShapeAttributeLayer::*pGetValue)() const,
414 void (ShapeAttributeLayer::*pSetValue)( const ValueT& ),
415 const ModifierFunctor& rGetterModifier,
416 const ModifierFunctor& rSetterModifier ) :
417 mpShape(),
418 mpAttrLayer(),
419 mpShapeManager( rShapeManager ),
420 mpIsValidFunc(pIsValid),
421 mpGetValueFunc(pGetValue),
422 mpSetValueFunc(pSetValue),
423 maGetterModifier( rGetterModifier ),
424 maSetterModifier( rSetterModifier ),
425 mnFlags( nFlags ),
426 maDefaultValue(rDefaultValue),
427 mbAnimationStarted( false )
429 ENSURE_OR_THROW( rShapeManager,
430 "GenericAnimation::GenericAnimation(): Invalid ShapeManager" );
431 ENSURE_OR_THROW( pIsValid && pGetValue && pSetValue,
432 "GenericAnimation::GenericAnimation(): One of the method pointers is NULL" );
435 ~GenericAnimation()
437 end();
440 // Animation interface
442 virtual void prefetch( const AnimatableShapeSharedPtr&,
443 const ShapeAttributeLayerSharedPtr& )
446 virtual void start( const AnimatableShapeSharedPtr& rShape,
447 const ShapeAttributeLayerSharedPtr& rAttrLayer )
449 OSL_ENSURE( !mpShape,
450 "GenericAnimation::start(): Shape already set" );
451 OSL_ENSURE( !mpAttrLayer,
452 "GenericAnimation::start(): Attribute layer already set" );
454 mpShape = rShape;
455 mpAttrLayer = rAttrLayer;
457 ENSURE_OR_THROW( rShape,
458 "GenericAnimation::start(): Invalid shape" );
459 ENSURE_OR_THROW( rAttrLayer,
460 "GenericAnimation::start(): Invalid attribute layer" );
462 // only start animation once per repeated start() call,
463 // and only if sprites should be used for display
464 if( !mbAnimationStarted )
466 mbAnimationStarted = true;
468 if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
469 mpShapeManager->enterAnimationMode( mpShape );
473 void end()
475 // TODO(Q2): Factor out common code (most
476 // prominently start() and end()) into base class
478 // only stop animation once per repeated end() call,
479 // and only if sprites are used for display
480 if( mbAnimationStarted )
482 mbAnimationStarted = false;
484 if( !(mnFlags & AnimationFactory::FLAG_NO_SPRITE) )
485 mpShapeManager->leaveAnimationMode( mpShape );
487 // Attention, this notifyShapeUpdate() is
488 // somewhat delicate here. Calling it
489 // unconditional (i.e. not guarded by
490 // mbAnimationStarted) will lead to shapes
491 // snapping back to their original state just
492 // before the slide ends. Not calling it at
493 // all might swallow final animation
494 // states. The current implementation relies
495 // on the fact that end() is either called by
496 // the Activity (then, the last animation
497 // state has been set, and corresponds to the
498 // shape's hold state), or by the animation
499 // node (then, it's a forced end, and we
500 // _have_ to snap back).
502 // To reiterate: normally, we're called from
503 // the Activity first, thus the
504 // notifyShapeUpdate() below will update to
505 // the last activity value.
507 // force shape update, activity might have changed
508 // state in the last round.
509 if( mpShape->isContentChanged() )
510 mpShapeManager->notifyShapeUpdate( mpShape );
514 // Derived Animation interface
517 /** For by-reference interfaces (B2DTuple, OUString)
519 bool operator()( const ValueT& x )
521 ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
522 "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
524 ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
526 if( mpShape->isContentChanged() )
527 mpShapeManager->notifyShapeUpdate( mpShape );
529 return true;
532 /** For by-value interfaces (bool, double)
534 bool operator()( ValueT x )
536 ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape,
537 "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
539 ((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
541 if( mpShape->isContentChanged() )
542 mpShapeManager->notifyShapeUpdate( mpShape );
544 return true;
547 ValueT getUnderlyingValue() const
549 ENSURE_OR_THROW( mpAttrLayer,
550 "GenericAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" );
552 // deviated from the (*shared_ptr).*mpFuncPtr
553 // notation here, since gcc does not seem to parse
554 // that as a member function call anymore.
555 if( (mpAttrLayer.get()->*mpIsValidFunc)() )
556 return maGetterModifier( ((*mpAttrLayer).*mpGetValueFunc)() );
557 else
558 return maDefaultValue;
561 private:
562 AnimatableShapeSharedPtr mpShape;
563 ShapeAttributeLayerSharedPtr mpAttrLayer;
564 ShapeManagerSharedPtr mpShapeManager;
565 bool (ShapeAttributeLayer::*mpIsValidFunc)() const;
566 ValueT (ShapeAttributeLayer::*mpGetValueFunc)() const;
567 void (ShapeAttributeLayer::*mpSetValueFunc)( const ValueT& );
569 ModifierFunctor maGetterModifier;
570 ModifierFunctor maSetterModifier;
572 const int mnFlags;
574 const ValueT maDefaultValue;
575 bool mbAnimationStarted;
578 //Current c++0x draft (apparently) has std::identity, but not operator()
579 template<typename T> struct SGI_identity
581 T& operator()(T& x) const { return x; }
582 const T& operator()(const T& x) const { return x; }
585 /** Function template wrapper around GenericAnimation template
587 @tpl AnimationBase
588 Type of animation to generate (determines the
589 interface GenericAnimation will implement).
591 template< typename AnimationBase > ::std::shared_ptr< AnimationBase >
592 makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
593 int nFlags,
594 bool (ShapeAttributeLayer::*pIsValid)() const,
595 const typename AnimationBase::ValueType& rDefaultValue,
596 typename AnimationBase::ValueType (ShapeAttributeLayer::*pGetValue)() const,
597 void (ShapeAttributeLayer::*pSetValue)( const typename AnimationBase::ValueType& ) )
599 return ::std::shared_ptr< AnimationBase >(
600 new GenericAnimation< AnimationBase,
601 SGI_identity< typename AnimationBase::ValueType > >(
602 rShapeManager,
603 nFlags,
604 pIsValid,
605 rDefaultValue,
606 pGetValue,
607 pSetValue,
608 // no modification necessary, use identity functor here
609 SGI_identity< typename AnimationBase::ValueType >(),
610 SGI_identity< typename AnimationBase::ValueType >() ) );
613 class Scaler
615 public:
616 explicit Scaler( double nScale ) :
617 mnScale( nScale )
621 double operator()( double nVal ) const
623 return mnScale * nVal;
626 private:
627 double mnScale;
630 /** Overload for NumberAnimations which need scaling (width,height,x,y currently)
632 NumberAnimationSharedPtr makeGenericAnimation( const ShapeManagerSharedPtr& rShapeManager,
633 int nFlags,
634 bool (ShapeAttributeLayer::*pIsValid)() const,
635 double nDefaultValue,
636 double (ShapeAttributeLayer::*pGetValue)() const,
637 void (ShapeAttributeLayer::*pSetValue)( const double& ),
638 double nScaleValue )
640 return NumberAnimationSharedPtr(
641 new GenericAnimation< NumberAnimation, Scaler >( rShapeManager,
642 nFlags,
643 pIsValid,
644 nDefaultValue / nScaleValue,
645 pGetValue,
646 pSetValue,
647 Scaler( 1.0/nScaleValue ),
648 Scaler( nScaleValue ) ) );
652 uno::Any getShapeDefault( const AnimatableShapeSharedPtr& rShape,
653 const OUString& rPropertyName )
655 uno::Reference< drawing::XShape > xShape( rShape->getXShape() );
657 if( !xShape.is() )
658 return uno::Any(); // no regular shape, no defaults available
661 // extract relevant value from XShape's PropertySet
662 uno::Reference< beans::XPropertySet > xPropSet( xShape,
663 uno::UNO_QUERY );
665 ENSURE_OR_THROW( xPropSet.is(),
666 "getShapeDefault(): Cannot query property set from shape" );
668 return xPropSet->getPropertyValue( rPropertyName );
671 template< typename ValueType > ValueType getDefault( const AnimatableShapeSharedPtr& rShape,
672 const OUString& rPropertyName )
674 const uno::Any& rAny( getShapeDefault( rShape,
675 rPropertyName ) );
677 if( !rAny.hasValue() )
679 SAL_WARN("slideshow", "getDefault(): cannot get shape property " << rPropertyName );
680 return ValueType();
682 else
684 ValueType aValue = ValueType();
686 if( !(rAny >>= aValue) )
688 SAL_WARN("slideshow", "getDefault(): cannot extract shape property " << rPropertyName);
689 return ValueType();
692 return aValue;
696 template<> RGBColor getDefault< RGBColor >( const AnimatableShapeSharedPtr& rShape,
697 const OUString& rPropertyName )
699 const uno::Any& rAny( getShapeDefault( rShape,
700 rPropertyName ) );
702 if( !rAny.hasValue() )
704 SAL_WARN("slideshow", "getDefault(): cannot get shape color property " << rPropertyName);
705 return RGBColor();
707 else
709 sal_Int32 nValue = 0;
711 if( !(rAny >>= nValue) )
713 SAL_INFO("slideshow", "getDefault(): cannot extract shape color property " << rPropertyName);
714 return RGBColor();
717 // convert from 0xAARRGGBB API color to 0xRRGGBB00
718 // canvas color
719 return RGBColor( (nValue << 8U) & 0xFFFFFF00U );
724 AnimationFactory::AttributeClass AnimationFactory::classifyAttributeName( const OUString& rAttrName )
726 // ATTENTION: When changing this map, also the create*PropertyAnimation() methods must
727 // be checked and possibly adapted in their switch statements
729 // TODO(Q2): Since this map must be coherent with the various switch statements
730 // in the create*PropertyAnimation methods, try to unify into a single method or table
731 switch( mapAttributeName( rAttrName ) )
733 default:
734 // FALLTHROUGH intended
735 case AttributeType::Invalid:
736 return CLASS_UNKNOWN_PROPERTY;
738 case AttributeType::CharColor:
739 // FALLTHROUGH intended
740 case AttributeType::Color:
741 // FALLTHROUGH intended
742 case AttributeType::DimColor:
743 // FALLTHROUGH intended
744 case AttributeType::FillColor:
745 // FALLTHROUGH intended
746 case AttributeType::LineColor:
747 return CLASS_COLOR_PROPERTY;
749 case AttributeType::CharFontName:
750 return CLASS_STRING_PROPERTY;
752 case AttributeType::Visibility:
753 return CLASS_BOOL_PROPERTY;
755 case AttributeType::CharHeight:
756 // FALLTHROUGH intended
757 case AttributeType::CharWeight:
758 // FALLTHROUGH intended
759 case AttributeType::Height:
760 // FALLTHROUGH intended
761 case AttributeType::Opacity:
762 // FALLTHROUGH intended
763 case AttributeType::Rotate:
764 // FALLTHROUGH intended
765 case AttributeType::SkewX:
766 // FALLTHROUGH intended
767 case AttributeType::SkewY:
768 // FALLTHROUGH intended
769 case AttributeType::Width:
770 // FALLTHROUGH intended
771 case AttributeType::PosX:
772 // FALLTHROUGH intended
773 case AttributeType::PosY:
774 return CLASS_NUMBER_PROPERTY;
776 case AttributeType::CharUnderline:
777 // FALLTHROUGH intended
778 case AttributeType::FillStyle:
779 // FALLTHROUGH intended
780 case AttributeType::LineStyle:
781 // FALLTHROUGH intended
782 case AttributeType::CharPosture:
783 return CLASS_ENUM_PROPERTY;
787 NumberAnimationSharedPtr AnimationFactory::createNumberPropertyAnimation( const OUString& rAttrName,
788 const AnimatableShapeSharedPtr& rShape,
789 const ShapeManagerSharedPtr& rShapeManager,
790 const ::basegfx::B2DVector& rSlideSize,
791 int nFlags )
793 // ATTENTION: When changing this map, also the classifyAttributeName() method must
794 // be checked and possibly adapted in their switch statement
795 switch( mapAttributeName( rAttrName ) )
797 default:
798 // FALLTHROUGH intended
799 case AttributeType::Invalid:
800 ENSURE_OR_THROW( false,
801 "AnimationFactory::createNumberPropertyAnimation(): Unknown attribute" );
802 break;
804 case AttributeType::CharColor:
805 // FALLTHROUGH intended
806 case AttributeType::CharFontName:
807 // FALLTHROUGH intended
808 case AttributeType::CharPosture:
809 // FALLTHROUGH intended
810 case AttributeType::CharUnderline:
811 // FALLTHROUGH intended
812 case AttributeType::Color:
813 // FALLTHROUGH intended
814 case AttributeType::DimColor:
815 // FALLTHROUGH intended
816 case AttributeType::FillColor:
817 // FALLTHROUGH intended
818 case AttributeType::FillStyle:
819 // FALLTHROUGH intended
820 case AttributeType::LineColor:
821 // FALLTHROUGH intended
822 case AttributeType::LineStyle:
823 // FALLTHROUGH intended
824 case AttributeType::Visibility:
825 ENSURE_OR_THROW( false,
826 "AnimationFactory::createNumberPropertyAnimation(): Attribute type mismatch" );
827 break;
829 case AttributeType::CharHeight:
830 return makeGenericAnimation<NumberAnimation>( rShapeManager,
831 nFlags,
832 &ShapeAttributeLayer::isCharScaleValid,
833 1.0, // CharHeight is a relative attribute, thus
834 // default is 1.0
835 &ShapeAttributeLayer::getCharScale,
836 &ShapeAttributeLayer::setCharScale );
838 case AttributeType::CharWeight:
839 return makeGenericAnimation<NumberAnimation>( rShapeManager,
840 nFlags,
841 &ShapeAttributeLayer::isCharWeightValid,
842 getDefault<double>( rShape, rAttrName ),
843 &ShapeAttributeLayer::getCharWeight,
844 &ShapeAttributeLayer::setCharWeight );
846 case AttributeType::Height:
847 return makeGenericAnimation( rShapeManager,
848 nFlags,
849 &ShapeAttributeLayer::isHeightValid,
850 // TODO(F1): Check whether _shape_ bounds are correct here.
851 // Theoretically, our AttrLayer is way down the stack, and
852 // we only have to consider _that_ value, not the one from
853 // the top of the stack as returned by Shape::getBounds()
854 rShape->getBounds().getHeight(),
855 &ShapeAttributeLayer::getHeight,
856 &ShapeAttributeLayer::setHeight,
857 // convert expression parser value from relative page size
858 rSlideSize.getY() );
860 case AttributeType::Opacity:
861 return makeGenericAnimation<NumberAnimation>( rShapeManager,
862 nFlags,
863 &ShapeAttributeLayer::isAlphaValid,
864 // TODO(F1): Provide shape default here (FillTransparency?)
865 1.0,
866 &ShapeAttributeLayer::getAlpha,
867 &ShapeAttributeLayer::setAlpha );
869 case AttributeType::Rotate:
870 return makeGenericAnimation<NumberAnimation>( rShapeManager,
871 nFlags,
872 &ShapeAttributeLayer::isRotationAngleValid,
873 // NOTE: Since we paint the shape as-is from metafile,
874 // rotation angle is always 0.0, even for rotated shapes
875 0.0,
876 &ShapeAttributeLayer::getRotationAngle,
877 &ShapeAttributeLayer::setRotationAngle );
879 case AttributeType::SkewX:
880 return makeGenericAnimation<NumberAnimation>( rShapeManager,
881 nFlags,
882 &ShapeAttributeLayer::isShearXAngleValid,
883 // TODO(F1): Is there any shape property for skew?
884 0.0,
885 &ShapeAttributeLayer::getShearXAngle,
886 &ShapeAttributeLayer::setShearXAngle );
888 case AttributeType::SkewY:
889 return makeGenericAnimation<NumberAnimation>( rShapeManager,
890 nFlags,
891 &ShapeAttributeLayer::isShearYAngleValid,
892 // TODO(F1): Is there any shape property for skew?
893 0.0,
894 &ShapeAttributeLayer::getShearYAngle,
895 &ShapeAttributeLayer::setShearYAngle );
897 case AttributeType::Width:
898 return makeGenericAnimation( rShapeManager,
899 nFlags,
900 &ShapeAttributeLayer::isWidthValid,
901 // TODO(F1): Check whether _shape_ bounds are correct here.
902 // Theoretically, our AttrLayer is way down the stack, and
903 // we only have to consider _that_ value, not the one from
904 // the top of the stack as returned by Shape::getBounds()
905 rShape->getBounds().getWidth(),
906 &ShapeAttributeLayer::getWidth,
907 &ShapeAttributeLayer::setWidth,
908 // convert expression parser value from relative page size
909 rSlideSize.getX() );
911 case AttributeType::PosX:
912 return makeGenericAnimation( rShapeManager,
913 nFlags,
914 &ShapeAttributeLayer::isPosXValid,
915 // TODO(F1): Check whether _shape_ bounds are correct here.
916 // Theoretically, our AttrLayer is way down the stack, and
917 // we only have to consider _that_ value, not the one from
918 // the top of the stack as returned by Shape::getBounds()
919 rShape->getBounds().getCenterX(),
920 &ShapeAttributeLayer::getPosX,
921 &ShapeAttributeLayer::setPosX,
922 // convert expression parser value from relative page size
923 rSlideSize.getX() );
925 case AttributeType::PosY:
926 return makeGenericAnimation( rShapeManager,
927 nFlags,
928 &ShapeAttributeLayer::isPosYValid,
929 // TODO(F1): Check whether _shape_ bounds are correct here.
930 // Theoretically, our AttrLayer is way down the stack, and
931 // we only have to consider _that_ value, not the one from
932 // the top of the stack as returned by Shape::getBounds()
933 rShape->getBounds().getCenterY(),
934 &ShapeAttributeLayer::getPosY,
935 &ShapeAttributeLayer::setPosY,
936 // convert expression parser value from relative page size
937 rSlideSize.getY() );
940 return NumberAnimationSharedPtr();
943 EnumAnimationSharedPtr AnimationFactory::createEnumPropertyAnimation( const OUString& rAttrName,
944 const AnimatableShapeSharedPtr& rShape,
945 const ShapeManagerSharedPtr& rShapeManager,
946 const ::basegfx::B2DVector& /*rSlideSize*/,
947 int nFlags )
949 // ATTENTION: When changing this map, also the classifyAttributeName() method must
950 // be checked and possibly adapted in their switch statement
951 switch( mapAttributeName( rAttrName ) )
953 default:
954 // FALLTHROUGH intended
955 case AttributeType::Invalid:
956 ENSURE_OR_THROW( false,
957 "AnimationFactory::createEnumPropertyAnimation(): Unknown attribute" );
958 break;
960 case AttributeType::CharColor:
961 // FALLTHROUGH intended
962 case AttributeType::CharFontName:
963 // FALLTHROUGH intended
964 case AttributeType::Color:
965 // FALLTHROUGH intended
966 case AttributeType::DimColor:
967 // FALLTHROUGH intended
968 case AttributeType::FillColor:
969 // FALLTHROUGH intended
970 case AttributeType::LineColor:
971 // FALLTHROUGH intended
972 case AttributeType::Visibility:
973 // FALLTHROUGH intended
974 case AttributeType::CharHeight:
975 // FALLTHROUGH intended
976 case AttributeType::CharWeight:
977 // FALLTHROUGH intended
978 case AttributeType::Height:
979 // FALLTHROUGH intended
980 case AttributeType::Opacity:
981 // FALLTHROUGH intended
982 case AttributeType::Rotate:
983 // FALLTHROUGH intended
984 case AttributeType::SkewX:
985 // FALLTHROUGH intended
986 case AttributeType::SkewY:
987 // FALLTHROUGH intended
988 case AttributeType::Width:
989 // FALLTHROUGH intended
990 case AttributeType::PosX:
991 // FALLTHROUGH intended
992 case AttributeType::PosY:
993 ENSURE_OR_THROW( false,
994 "AnimationFactory::createEnumPropertyAnimation(): Attribute type mismatch" );
995 break;
998 case AttributeType::FillStyle:
999 return makeGenericAnimation<EnumAnimation>( rShapeManager,
1000 nFlags,
1001 &ShapeAttributeLayer::isFillStyleValid,
1002 sal::static_int_cast<sal_Int16>(
1003 getDefault<drawing::FillStyle>( rShape, rAttrName )),
1004 &ShapeAttributeLayer::getFillStyle,
1005 &ShapeAttributeLayer::setFillStyle );
1007 case AttributeType::LineStyle:
1008 return makeGenericAnimation<EnumAnimation>( rShapeManager,
1009 nFlags,
1010 &ShapeAttributeLayer::isLineStyleValid,
1011 sal::static_int_cast<sal_Int16>(
1012 getDefault<drawing::LineStyle>( rShape, rAttrName )),
1013 &ShapeAttributeLayer::getLineStyle,
1014 &ShapeAttributeLayer::setLineStyle );
1016 case AttributeType::CharPosture:
1017 return makeGenericAnimation<EnumAnimation>( rShapeManager,
1018 nFlags,
1019 &ShapeAttributeLayer::isCharPostureValid,
1020 sal::static_int_cast<sal_Int16>(
1021 getDefault<awt::FontSlant>( rShape, rAttrName )),
1022 &ShapeAttributeLayer::getCharPosture,
1023 &ShapeAttributeLayer::setCharPosture );
1025 case AttributeType::CharUnderline:
1026 return makeGenericAnimation<EnumAnimation>( rShapeManager,
1027 nFlags,
1028 &ShapeAttributeLayer::isUnderlineModeValid,
1029 getDefault<sal_Int16>( rShape, rAttrName ),
1030 &ShapeAttributeLayer::getUnderlineMode,
1031 &ShapeAttributeLayer::setUnderlineMode );
1034 return EnumAnimationSharedPtr();
1037 ColorAnimationSharedPtr AnimationFactory::createColorPropertyAnimation( const OUString& rAttrName,
1038 const AnimatableShapeSharedPtr& rShape,
1039 const ShapeManagerSharedPtr& rShapeManager,
1040 const ::basegfx::B2DVector& /*rSlideSize*/,
1041 int nFlags )
1043 // ATTENTION: When changing this map, also the classifyAttributeName() method must
1044 // be checked and possibly adapted in their switch statement
1045 switch( mapAttributeName( rAttrName ) )
1047 default:
1048 // FALLTHROUGH intended
1049 case AttributeType::Invalid:
1050 ENSURE_OR_THROW( false,
1051 "AnimationFactory::createColorPropertyAnimation(): Unknown attribute" );
1052 break;
1054 case AttributeType::CharFontName:
1055 // FALLTHROUGH intended
1056 case AttributeType::CharHeight:
1057 // FALLTHROUGH intended
1058 case AttributeType::CharPosture:
1059 // FALLTHROUGH intended
1060 case AttributeType::CharUnderline:
1061 // FALLTHROUGH intended
1062 case AttributeType::CharWeight:
1063 // FALLTHROUGH intended
1064 case AttributeType::FillStyle:
1065 // FALLTHROUGH intended
1066 case AttributeType::Height:
1067 // FALLTHROUGH intended
1068 case AttributeType::LineStyle:
1069 // FALLTHROUGH intended
1070 case AttributeType::Opacity:
1071 // FALLTHROUGH intended
1072 case AttributeType::Rotate:
1073 // FALLTHROUGH intended
1074 case AttributeType::SkewX:
1075 // FALLTHROUGH intended
1076 case AttributeType::SkewY:
1077 // FALLTHROUGH intended
1078 case AttributeType::Visibility:
1079 // FALLTHROUGH intended
1080 case AttributeType::Width:
1081 // FALLTHROUGH intended
1082 case AttributeType::PosX:
1083 // FALLTHROUGH intended
1084 case AttributeType::PosY:
1085 ENSURE_OR_THROW( false,
1086 "AnimationFactory::createColorPropertyAnimation(): Attribute type mismatch" );
1087 break;
1089 case AttributeType::CharColor:
1090 return makeGenericAnimation<ColorAnimation>( rShapeManager,
1091 nFlags,
1092 &ShapeAttributeLayer::isCharColorValid,
1093 getDefault<RGBColor>( rShape, rAttrName ),
1094 &ShapeAttributeLayer::getCharColor,
1095 &ShapeAttributeLayer::setCharColor );
1097 case AttributeType::Color:
1098 // TODO(F2): This is just mapped to fill color to make it work
1099 return makeGenericAnimation<ColorAnimation>( rShapeManager,
1100 nFlags,
1101 &ShapeAttributeLayer::isFillColorValid,
1102 getDefault<RGBColor>( rShape, rAttrName ),
1103 &ShapeAttributeLayer::getFillColor,
1104 &ShapeAttributeLayer::setFillColor );
1106 case AttributeType::DimColor:
1107 return makeGenericAnimation<ColorAnimation>( rShapeManager,
1108 nFlags,
1109 &ShapeAttributeLayer::isDimColorValid,
1110 getDefault<RGBColor>( rShape, rAttrName ),
1111 &ShapeAttributeLayer::getDimColor,
1112 &ShapeAttributeLayer::setDimColor );
1114 case AttributeType::FillColor:
1115 return makeGenericAnimation<ColorAnimation>( rShapeManager,
1116 nFlags,
1117 &ShapeAttributeLayer::isFillColorValid,
1118 getDefault<RGBColor>( rShape, rAttrName ),
1119 &ShapeAttributeLayer::getFillColor,
1120 &ShapeAttributeLayer::setFillColor );
1122 case AttributeType::LineColor:
1123 return makeGenericAnimation<ColorAnimation>( rShapeManager,
1124 nFlags,
1125 &ShapeAttributeLayer::isLineColorValid,
1126 getDefault<RGBColor>( rShape, rAttrName ),
1127 &ShapeAttributeLayer::getLineColor,
1128 &ShapeAttributeLayer::setLineColor );
1131 return ColorAnimationSharedPtr();
1134 PairAnimationSharedPtr AnimationFactory::createPairPropertyAnimation( const AnimatableShapeSharedPtr& rShape,
1135 const ShapeManagerSharedPtr& rShapeManager,
1136 const ::basegfx::B2DVector& rSlideSize,
1137 sal_Int16 nTransformType,
1138 int nFlags )
1140 const ::basegfx::B2DRectangle& rBounds( rShape->getBounds() );
1142 switch( nTransformType )
1144 case animations::AnimationTransformType::SCALE:
1145 return PairAnimationSharedPtr(
1146 new TupleAnimation< ::basegfx::B2DSize >(
1147 rShapeManager,
1148 nFlags,
1149 &ShapeAttributeLayer::isWidthValid,
1150 &ShapeAttributeLayer::isHeightValid,
1151 // TODO(F1): Check whether _shape_ bounds are correct here.
1152 // Theoretically, our AttrLayer is way down the stack, and
1153 // we only have to consider _that_ value, not the one from
1154 // the top of the stack as returned by Shape::getBounds()
1155 rBounds.getRange(),
1156 rBounds.getRange(),
1157 &ShapeAttributeLayer::getWidth,
1158 &ShapeAttributeLayer::getHeight,
1159 &ShapeAttributeLayer::setSize ) );
1161 case animations::AnimationTransformType::TRANSLATE:
1162 return PairAnimationSharedPtr(
1163 new TupleAnimation< ::basegfx::B2DPoint >(
1164 rShapeManager,
1165 nFlags,
1166 &ShapeAttributeLayer::isPosXValid,
1167 &ShapeAttributeLayer::isPosYValid,
1168 // TODO(F1): Check whether _shape_ bounds are correct here.
1169 // Theoretically, our AttrLayer is way down the stack, and
1170 // we only have to consider _that_ value, not the one from
1171 // the top of the stack as returned by Shape::getBounds()
1172 rBounds.getCenter(),
1173 rSlideSize,
1174 &ShapeAttributeLayer::getPosX,
1175 &ShapeAttributeLayer::getPosY,
1176 &ShapeAttributeLayer::setPosition ) );
1178 default:
1179 ENSURE_OR_THROW( false,
1180 "AnimationFactory::createPairPropertyAnimation(): Attribute type mismatch" );
1181 break;
1184 return PairAnimationSharedPtr();
1187 StringAnimationSharedPtr AnimationFactory::createStringPropertyAnimation( const OUString& rAttrName,
1188 const AnimatableShapeSharedPtr& rShape,
1189 const ShapeManagerSharedPtr& rShapeManager,
1190 const ::basegfx::B2DVector& /*rSlideSize*/,
1191 int nFlags )
1193 // ATTENTION: When changing this map, also the classifyAttributeName() method must
1194 // be checked and possibly adapted in their switch statement
1195 switch( mapAttributeName( rAttrName ) )
1197 default:
1198 // FALLTHROUGH intended
1199 case AttributeType::Invalid:
1200 ENSURE_OR_THROW( false,
1201 "AnimationFactory::createStringPropertyAnimation(): Unknown attribute" );
1202 break;
1204 case AttributeType::CharColor:
1205 // FALLTHROUGH intended
1206 case AttributeType::CharHeight:
1207 // FALLTHROUGH intended
1208 case AttributeType::CharUnderline:
1209 // FALLTHROUGH intended
1210 case AttributeType::Color:
1211 // FALLTHROUGH intended
1212 case AttributeType::DimColor:
1213 // FALLTHROUGH intended
1214 case AttributeType::FillColor:
1215 // FALLTHROUGH intended
1216 case AttributeType::Height:
1217 // FALLTHROUGH intended
1218 case AttributeType::LineColor:
1219 // FALLTHROUGH intended
1220 case AttributeType::Opacity:
1221 // FALLTHROUGH intended
1222 case AttributeType::Rotate:
1223 // FALLTHROUGH intended
1224 case AttributeType::SkewX:
1225 // FALLTHROUGH intended
1226 case AttributeType::SkewY:
1227 // FALLTHROUGH intended
1228 case AttributeType::Visibility:
1229 // FALLTHROUGH intended
1230 case AttributeType::Width:
1231 // FALLTHROUGH intended
1232 case AttributeType::PosX:
1233 // FALLTHROUGH intended
1234 case AttributeType::PosY:
1235 // FALLTHROUGH intended
1236 case AttributeType::CharPosture:
1237 // FALLTHROUGH intended
1238 case AttributeType::CharWeight:
1239 // FALLTHROUGH intended
1240 case AttributeType::FillStyle:
1241 // FALLTHROUGH intended
1242 case AttributeType::LineStyle:
1243 ENSURE_OR_THROW( false,
1244 "AnimationFactory::createStringPropertyAnimation(): Attribute type mismatch" );
1245 break;
1247 case AttributeType::CharFontName:
1248 return makeGenericAnimation<StringAnimation>( rShapeManager,
1249 nFlags,
1250 &ShapeAttributeLayer::isFontFamilyValid,
1251 getDefault< OUString >( rShape, rAttrName ),
1252 &ShapeAttributeLayer::getFontFamily,
1253 &ShapeAttributeLayer::setFontFamily );
1256 return StringAnimationSharedPtr();
1259 BoolAnimationSharedPtr AnimationFactory::createBoolPropertyAnimation( const OUString& rAttrName,
1260 const AnimatableShapeSharedPtr& /*rShape*/,
1261 const ShapeManagerSharedPtr& rShapeManager,
1262 const ::basegfx::B2DVector& /*rSlideSize*/,
1263 int nFlags )
1265 // ATTENTION: When changing this map, also the classifyAttributeName() method must
1266 // be checked and possibly adapted in their switch statement
1267 switch( mapAttributeName( rAttrName ) )
1269 default:
1270 // FALLTHROUGH intended
1271 case AttributeType::Invalid:
1272 ENSURE_OR_THROW( false,
1273 "AnimationFactory::createBoolPropertyAnimation(): Unknown attribute" );
1274 break;
1276 case AttributeType::CharColor:
1277 // FALLTHROUGH intended
1278 case AttributeType::CharFontName:
1279 // FALLTHROUGH intended
1280 case AttributeType::CharHeight:
1281 // FALLTHROUGH intended
1282 case AttributeType::CharPosture:
1283 // FALLTHROUGH intended
1284 case AttributeType::CharWeight:
1285 // FALLTHROUGH intended
1286 case AttributeType::Color:
1287 // FALLTHROUGH intended
1288 case AttributeType::DimColor:
1289 // FALLTHROUGH intended
1290 case AttributeType::FillColor:
1291 // FALLTHROUGH intended
1292 case AttributeType::FillStyle:
1293 // FALLTHROUGH intended
1294 case AttributeType::Height:
1295 // FALLTHROUGH intended
1296 case AttributeType::LineColor:
1297 // FALLTHROUGH intended
1298 case AttributeType::LineStyle:
1299 // FALLTHROUGH intended
1300 case AttributeType::Opacity:
1301 // FALLTHROUGH intended
1302 case AttributeType::Rotate:
1303 // FALLTHROUGH intended
1304 case AttributeType::SkewX:
1305 // FALLTHROUGH intended
1306 case AttributeType::SkewY:
1307 // FALLTHROUGH intended
1308 case AttributeType::Width:
1309 // FALLTHROUGH intended
1310 case AttributeType::PosX:
1311 // FALLTHROUGH intended
1312 case AttributeType::PosY:
1313 // FALLTHROUGH intended
1314 case AttributeType::CharUnderline:
1315 ENSURE_OR_THROW( false,
1316 "AnimationFactory::createBoolPropertyAnimation(): Attribute type mismatch" );
1317 break;
1319 case AttributeType::Visibility:
1320 return makeGenericAnimation<BoolAnimation>( rShapeManager,
1321 nFlags,
1322 &ShapeAttributeLayer::isVisibilityValid,
1323 // TODO(F1): Is there a corresponding shape property?
1324 true,
1325 &ShapeAttributeLayer::getVisibility,
1326 &ShapeAttributeLayer::setVisibility );
1329 return BoolAnimationSharedPtr();
1332 NumberAnimationSharedPtr AnimationFactory::createPathMotionAnimation( const OUString& rSVGDPath,
1333 sal_Int16 nAdditive,
1334 const AnimatableShapeSharedPtr& /*rShape*/,
1335 const ShapeManagerSharedPtr& rShapeManager,
1336 const ::basegfx::B2DVector& rSlideSize,
1337 int nFlags )
1339 return NumberAnimationSharedPtr(
1340 new PathAnimation( rSVGDPath, nAdditive,
1341 rShapeManager,
1342 rSlideSize,
1343 nFlags ) );
1349 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */