bump product version to 5.0.4.1
[LibreOffice.git] / slideshow / source / engine / transitions / slidetransitionfactory.cxx
blob754e4f060a508777d2af2865491753cf93755c5f
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 .
20 #include <canvas/debug.hxx>
21 #include <tools/diagnose_ex.h>
23 #include <basegfx/matrix/b2dhommatrix.hxx>
24 #include <basegfx/tools/canvastools.hxx>
25 #include <basegfx/polygon/b2dpolygontools.hxx>
26 #include <basegfx/polygon/b2dpolypolygontools.hxx>
28 #include <cppcanvas/basegfxfactory.hxx>
30 #include <comphelper/optional.hxx>
31 #include <comphelper/make_shared_from_uno.hxx>
33 #include <com/sun/star/rendering/XIntegerBitmap.hpp>
34 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
35 #include <com/sun/star/animations/TransitionType.hpp>
36 #include <com/sun/star/animations/TransitionSubType.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include "slidechangebase.hxx"
40 #include "transitionfactory.hxx"
41 #include "transitionfactorytab.hxx"
42 #include "transitiontools.hxx"
43 #include "parametricpolypolygonfactory.hxx"
44 #include "animationfactory.hxx"
45 #include "clippingfunctor.hxx"
46 #include "combtransition.hxx"
47 #include "tools.hxx"
49 #include <boost/bind.hpp>
52 /***************************************************
53 *** ***
54 *** Slide Transition Effects ***
55 *** ***
56 ***************************************************/
58 using namespace com::sun::star;
60 namespace slideshow {
61 namespace internal {
63 namespace {
65 // helper methods
66 // =============================================
68 void fillPage( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
69 const ::basegfx::B2DSize& rPageSizePixel,
70 const RGBColor& rFillColor )
72 // need to render without any transformation (we
73 // assume rPageSizePixel to represent device units)
74 const ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas(
75 rDestinationCanvas->clone() );
76 pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
78 // TODO(F2): Properly respect clip here.
79 // Might have to be transformed, too.
80 const ::basegfx::B2DHomMatrix aViewTransform(
81 rDestinationCanvas->getTransformation() );
82 const ::basegfx::B2DPoint aOutputPosPixel(
83 aViewTransform * ::basegfx::B2DPoint() );
85 fillRect( pDevicePixelCanvas,
86 ::basegfx::B2DRectangle(
87 aOutputPosPixel.getX(),
88 aOutputPosPixel.getY(),
89 aOutputPosPixel.getX() + rPageSizePixel.getX(),
90 aOutputPosPixel.getY() + rPageSizePixel.getY() ),
91 rFillColor.getIntegerColor() );
94 class PluginSlideChange: public SlideChangeBase
96 struct TransitionViewPair {
97 uno::Reference<presentation::XTransition> mxTransition;
98 UnoViewSharedPtr mpView;
100 TransitionViewPair( uno::Reference<presentation::XTransition> xTransition, const UnoViewSharedPtr& rView )
102 mxTransition = xTransition;
103 mpView = rView;
106 ~TransitionViewPair()
108 mxTransition.clear();
109 mpView.reset();
112 void update( double t )
114 mxTransition->update( t );
118 public:
119 /** Create a new SlideChanger, for the given leaving and
120 entering slide bitmaps, which uses super secret OpenGL
121 stuff.
123 PluginSlideChange( sal_Int16 nTransitionType,
124 sal_Int16 nTransitionSubType,
125 boost::optional<SlideSharedPtr> const& leavingSlide_,
126 const SlideSharedPtr& pEnteringSlide,
127 const UnoViewContainer& rViewContainer,
128 ScreenUpdater& rScreenUpdater,
129 const uno::Reference<
130 presentation::XTransitionFactory>& xFactory,
131 const SoundPlayerSharedPtr& pSoundPlayer,
132 EventMultiplexer& rEventMultiplexer) :
133 SlideChangeBase( leavingSlide_,
134 pEnteringSlide,
135 pSoundPlayer,
136 rViewContainer,
137 rScreenUpdater,
138 rEventMultiplexer ),
139 maTransitions(),
140 mbSuccess( false ),
141 mnTransitionType( nTransitionType ),
142 mnTransitionSubType( nTransitionSubType ),
143 mxFactory( xFactory )
145 // create one transition per view
146 UnoViewVector::const_iterator aCurrView (rViewContainer.begin());
147 const UnoViewVector::const_iterator aEnd(rViewContainer.end());
148 while( aCurrView != aEnd )
150 if(! addTransition( *aCurrView ) )
151 return;
153 ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(),
154 "Failed to create plugin transition");
155 ++aCurrView;
157 mbSuccess = true;
160 virtual ~PluginSlideChange()
162 mxFactory.clear();
164 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
165 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
166 while( aCurrView != aEnd )
168 delete (*aCurrView);
169 ++aCurrView;
171 maTransitions.clear();
174 bool addTransition( const UnoViewSharedPtr& rView )
176 uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition(
177 mnTransitionType,
178 mnTransitionSubType,
179 rView->getUnoView(),
180 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
181 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
183 if( rTransition.is() )
184 maTransitions.push_back( new TransitionViewPair( rTransition, rView ) );
185 else
186 return false;
188 return true;
191 virtual bool operator()( double t ) SAL_OVERRIDE
193 std::for_each(maTransitions.begin(),
194 maTransitions.end(),
195 boost::bind( &TransitionViewPair::update,
196 _1, t) );
197 return true;
200 bool Success()
202 return mbSuccess;
205 // ViewEventHandler
206 virtual void viewAdded( const UnoViewSharedPtr& rView ) SAL_OVERRIDE
208 OSL_TRACE("PluginSlideChange viewAdded");
209 SlideChangeBase::viewAdded( rView );
211 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
212 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
213 bool bKnown = false;
214 while( aCurrView != aEnd )
216 if( (*aCurrView)->mpView == rView )
218 bKnown = true;
219 break;
221 ++aCurrView;
224 if( !bKnown )
226 OSL_TRACE("need to be added");
227 addTransition( rView );
231 virtual void viewRemoved( const UnoViewSharedPtr& rView ) SAL_OVERRIDE
233 OSL_TRACE("PluginSlideChange viewRemoved");
234 SlideChangeBase::viewRemoved( rView );
236 ::std::vector< TransitionViewPair* >::iterator aCurrView (maTransitions.begin());
237 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
238 while( aCurrView != aEnd )
240 if( (*aCurrView)->mpView == rView )
242 OSL_TRACE( "view removed" );
243 delete (*aCurrView);
244 maTransitions.erase( aCurrView );
245 break;
247 ++aCurrView;
251 virtual void viewChanged( const UnoViewSharedPtr& rView ) SAL_OVERRIDE
253 OSL_TRACE("PluginSlideChange viewChanged");
254 SlideChangeBase::viewChanged( rView );
256 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
257 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
258 while( aCurrView != aEnd )
260 if( (*aCurrView)->mpView == rView )
262 OSL_TRACE( "view changed" );
263 (*aCurrView)->mxTransition->viewChanged( rView->getUnoView(),
264 getLeavingBitmap(ViewEntry(rView))->getXBitmap(),
265 getEnteringBitmap(ViewEntry(rView))->getXBitmap() );
267 else
268 OSL_TRACE( "view did not changed" );
270 ++aCurrView;
274 virtual void viewsChanged() SAL_OVERRIDE
276 OSL_TRACE("PluginSlideChange viewsChanged");
277 SlideChangeBase::viewsChanged();
279 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin());
280 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end());
281 while( aCurrView != aEnd )
283 OSL_TRACE( "view changed" );
284 (*aCurrView)->mxTransition->viewChanged( (*aCurrView)->mpView->getUnoView(),
285 getLeavingBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap(),
286 getEnteringBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap() );
287 ++aCurrView;
291 private:
292 // One transition object per view
293 std::vector< TransitionViewPair* > maTransitions;
295 // bool
296 bool mbSuccess;
298 sal_Int16 mnTransitionType;
299 sal_Int16 mnTransitionSubType;
301 uno::Reference<presentation::XTransitionFactory> mxFactory;
304 class ClippedSlideChange : public SlideChangeBase
306 public:
307 /** Create a new SlideChanger, for the given leaving and
308 entering slide bitmaps, which applies the given clip
309 polygon.
311 ClippedSlideChange(
312 const SlideSharedPtr& pEnteringSlide,
313 const ParametricPolyPolygonSharedPtr& rPolygon,
314 const TransitionInfo& rTransitionInfo,
315 const UnoViewContainer& rViewContainer,
316 ScreenUpdater& rScreenUpdater,
317 EventMultiplexer& rEventMultiplexer,
318 bool bDirectionForward,
319 const SoundPlayerSharedPtr& pSoundPlayer ) :
320 SlideChangeBase(
321 // leaving bitmap is empty, we're leveraging the fact that the
322 // old slide is still displayed in the background:
323 boost::optional<SlideSharedPtr>(),
324 pEnteringSlide,
325 pSoundPlayer,
326 rViewContainer,
327 rScreenUpdater,
328 rEventMultiplexer ),
329 maClippingFunctor( rPolygon,
330 rTransitionInfo,
331 bDirectionForward,
332 true )
335 virtual void performIn(
336 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
337 const ViewEntry& rViewEntry,
338 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
339 double t ) SAL_OVERRIDE;
341 virtual void performOut(
342 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
343 const ViewEntry& rViewEntry,
344 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
345 double t ) SAL_OVERRIDE;
347 private:
348 ClippingFunctor maClippingFunctor;
351 void ClippedSlideChange::performIn(
352 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
353 const ViewEntry& rViewEntry,
354 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
355 double t )
357 // #i46602# Better work in device coordinate space here,
358 // otherwise, we too easily suffer from roundoffs. Apart from
359 // that, getEnteringSizePixel() _guarantees_ to cover the whole
360 // slide bitmap. There's a catch, though: this removes any effect
361 // of the view transformation (e.g. rotation) from the transition.
362 rSprite->setClipPixel(
363 maClippingFunctor( t,
364 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) ) );
367 void ClippedSlideChange::performOut(
368 const ::cppcanvas::CustomSpriteSharedPtr& /*rSprite*/,
369 const ViewEntry& /*rViewEntry*/,
370 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
371 double /*t*/ )
373 // not needed here
377 class FadingSlideChange : public SlideChangeBase
379 public:
380 /** Create a new SlideChanger, for the given leaving and
381 entering slides, which applies a fade effect.
383 FadingSlideChange(
384 boost::optional<SlideSharedPtr> const & leavingSlide,
385 const SlideSharedPtr& pEnteringSlide,
386 boost::optional<RGBColor> const& rFadeColor,
387 const SoundPlayerSharedPtr& pSoundPlayer,
388 const UnoViewContainer& rViewContainer,
389 ScreenUpdater& rScreenUpdater,
390 EventMultiplexer& rEventMultiplexer )
391 : SlideChangeBase( leavingSlide,
392 pEnteringSlide,
393 pSoundPlayer,
394 rViewContainer,
395 rScreenUpdater,
396 rEventMultiplexer ),
397 maFadeColor( rFadeColor )
400 virtual void prepareForRun(
401 const ViewEntry& rViewEntry,
402 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) SAL_OVERRIDE;
404 virtual void performIn(
405 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
406 const ViewEntry& rViewEntry,
407 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
408 double t ) SAL_OVERRIDE;
410 virtual void performOut(
411 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
412 const ViewEntry& rViewEntry,
413 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
414 double t ) SAL_OVERRIDE;
416 private:
417 const boost::optional< RGBColor > maFadeColor;
420 void FadingSlideChange::prepareForRun(
421 const ViewEntry& rViewEntry,
422 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
424 if ( maFadeColor )
426 // clear page to given fade color. 'Leaving' slide is
427 // painted atop of that, but slowly fading out.
428 fillPage( rDestinationCanvas,
429 ::basegfx::B2DSize( getEnteringSlideSizePixel( rViewEntry.mpView ) ),
430 *maFadeColor );
434 void FadingSlideChange::performIn(
435 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
436 const ViewEntry& /*rViewEntry*/,
437 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
438 double t )
440 ENSURE_OR_THROW(
441 rSprite,
442 "FadingSlideChange::performIn(): Invalid sprite" );
444 if( maFadeColor )
445 // After half of the active time, fade in new slide
446 rSprite->setAlpha( t > 0.5 ? 2.0*(t-0.5) : 0.0 );
447 else
448 // Fade in new slide over full active time
449 rSprite->setAlpha( t );
452 void FadingSlideChange::performOut(
453 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
454 const ViewEntry& /* rViewEntry */,
455 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
456 double t )
458 ENSURE_OR_THROW(
459 rSprite,
460 "FadingSlideChange::performOut(): Invalid sprite" );
461 ENSURE_OR_THROW(
462 rDestinationCanvas,
463 "FadingSlideChange::performOut(): Invalid dest canvas" );
465 // only needed for color fades
466 if( maFadeColor )
468 // Until half of the active time, fade out old
469 // slide. After half of the active time, old slide
470 // will be invisible.
471 rSprite->setAlpha( t > 0.5 ? 0.0 : 2.0*(0.5-t) );
475 class CutSlideChange : public SlideChangeBase
477 public:
478 /** Create a new SlideChanger, for the given leaving and
479 entering slides, which applies a cut effect.
481 CutSlideChange(
482 boost::optional<SlideSharedPtr> const & leavingSlide,
483 const SlideSharedPtr& pEnteringSlide,
484 const RGBColor& rFadeColor,
485 const SoundPlayerSharedPtr& pSoundPlayer,
486 const UnoViewContainer& rViewContainer,
487 ScreenUpdater& rScreenUpdater,
488 EventMultiplexer& rEventMultiplexer )
489 : SlideChangeBase( leavingSlide,
490 pEnteringSlide,
491 pSoundPlayer,
492 rViewContainer,
493 rScreenUpdater,
494 rEventMultiplexer ),
495 maFadeColor( rFadeColor )
498 virtual void prepareForRun(
499 const ViewEntry& rViewEntry,
500 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) SAL_OVERRIDE;
502 virtual void performIn(
503 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
504 const ViewEntry& rViewEntry,
505 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
506 double t ) SAL_OVERRIDE;
508 virtual void performOut(
509 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
510 const ViewEntry& rViewEntry,
511 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
512 double t ) SAL_OVERRIDE;
514 private:
515 RGBColor maFadeColor;
518 void CutSlideChange::prepareForRun(
519 const ViewEntry& rViewEntry,
520 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
522 // clear page to given fade color. 'Leaving' slide is
523 // painted atop of that
524 fillPage( rDestinationCanvas,
525 ::basegfx::B2DSize( getEnteringSlideSizePixel( rViewEntry.mpView ) ),
526 maFadeColor );
529 void CutSlideChange::performIn(
530 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
531 const ViewEntry& /*rViewEntry*/,
532 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/,
533 double t )
535 ENSURE_OR_THROW(
536 rSprite,
537 "CutSlideChange::performIn(): Invalid sprite" );
539 // After 2/3rd of the active time, display new slide
540 rSprite->setAlpha( t > 2/3.0 ? 1.0 : 0.0 );
543 void CutSlideChange::performOut(
544 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
545 const ViewEntry& /* rViewEntry */,
546 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
547 double t )
549 ENSURE_OR_THROW(
550 rSprite,
551 "CutSlideChange::performOut(): Invalid sprite" );
552 ENSURE_OR_THROW(
553 rDestinationCanvas,
554 "CutSlideChange::performOut(): Invalid dest canvas" );
556 // Until 1/3rd of the active time, display old slide.
557 rSprite->setAlpha( t > 1/3.0 ? 0.0 : 1.0 );
560 class MovingSlideChange : public SlideChangeBase
562 /// Direction vector for leaving slide,
563 const ::basegfx::B2DVector maLeavingDirection;
565 /// Direction vector for entering slide,
566 const ::basegfx::B2DVector maEnteringDirection;
568 public:
569 /** Create a new SlideChanger, for the given entering slide
570 bitmaps, which performs a moving slide change effect
572 @param rLeavingDirection
573 Direction vector. The move is performed along this
574 direction vector, starting at a position where the leaving
575 slide is fully visible, and ending at a position where the
576 leaving slide is just not visible. The vector must have
577 unit length.
579 @param rEnteringDirection
580 Direction vector. The move is performed along this
581 direction vector, starting at a position where the
582 entering slide is just not visible, and ending at the
583 final slide position. The vector must have unit length.
585 MovingSlideChange(
586 const boost::optional<SlideSharedPtr>& leavingSlide,
587 const SlideSharedPtr& pEnteringSlide,
588 const SoundPlayerSharedPtr& pSoundPlayer,
589 const UnoViewContainer& rViewContainer,
590 ScreenUpdater& rScreenUpdater,
591 EventMultiplexer& rEventMultiplexer,
592 const ::basegfx::B2DVector& rLeavingDirection,
593 const ::basegfx::B2DVector& rEnteringDirection )
594 : SlideChangeBase(
595 leavingSlide, pEnteringSlide, pSoundPlayer,
596 rViewContainer, rScreenUpdater, rEventMultiplexer,
597 // Optimization: when leaving bitmap is given,
598 // but it does not move, don't create sprites for it,
599 // we simply paint it once at startup:
600 !rLeavingDirection.equalZero() /* bCreateLeavingSprites */,
601 !rEnteringDirection.equalZero() /* bCreateEnteringSprites */ ),
602 // TODO(F1): calc correct length of direction
603 // vector. Directions not strictly horizontal or vertical
604 // must travel a longer distance.
605 maLeavingDirection( rLeavingDirection ),
606 // TODO(F1): calc correct length of direction
607 // vector. Directions not strictly horizontal or vertical
608 // must travel a longer distance.
609 maEnteringDirection( rEnteringDirection )
612 virtual void prepareForRun(
613 const ViewEntry& rViewEntry,
614 const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) SAL_OVERRIDE;
616 virtual void performIn(
617 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
618 const ViewEntry& rViewEntry,
619 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
620 double t ) SAL_OVERRIDE;
622 virtual void performOut(
623 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
624 const ViewEntry& rViewEntry,
625 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
626 double t ) SAL_OVERRIDE;
629 void MovingSlideChange::prepareForRun(
630 const ViewEntry& rViewEntry,
631 const cppcanvas::CanvasSharedPtr& rDestinationCanvas )
633 if ( maLeavingDirection.equalZero() )
634 renderBitmap( getLeavingBitmap( rViewEntry ), rDestinationCanvas );
635 else if ( maEnteringDirection.equalZero() )
636 renderBitmap( getEnteringBitmap( rViewEntry ), rDestinationCanvas );
639 void MovingSlideChange::performIn(
640 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
641 const ViewEntry& rViewEntry,
642 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
643 double t )
645 // intro sprite moves:
647 ENSURE_OR_THROW(
648 rSprite,
649 "MovingSlideChange::performIn(): Invalid sprite" );
650 ENSURE_OR_THROW(
651 rDestinationCanvas,
652 "MovingSlideChange::performIn(): Invalid dest canvas" );
654 // TODO(F1): This does not account for non-translational
655 // transformations! If the canvas is rotated, we still
656 // move the sprite unrotated (which might or might not
657 // produce the intended effect).
658 const basegfx::B2DHomMatrix aViewTransform(
659 rDestinationCanvas->getTransformation() );
660 const basegfx::B2DPoint aPageOrigin(
661 aViewTransform * basegfx::B2DPoint() );
663 // move sprite
664 rSprite->movePixel(
665 aPageOrigin +
666 ((t - 1.0) *
667 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) *
668 maEnteringDirection) );
671 void MovingSlideChange::performOut(
672 const ::cppcanvas::CustomSpriteSharedPtr& rSprite,
673 const ViewEntry& rViewEntry,
674 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
675 double t )
677 // outro sprite moves:
679 ENSURE_OR_THROW(
680 rSprite,
681 "MovingSlideChange::performOut(): Invalid sprite" );
682 ENSURE_OR_THROW(
683 rDestinationCanvas,
684 "MovingSlideChange::performOut(): Invalid dest canvas" );
686 // TODO(F1): This does not account for non-translational
687 // transformations! If the canvas is rotated, we still
688 // move the sprite unrotated (which might or might not
689 // produce the intended effect).
690 const basegfx::B2DHomMatrix aViewTransform(
691 rDestinationCanvas->getTransformation() );
692 const basegfx::B2DPoint aPageOrigin(
693 aViewTransform * basegfx::B2DPoint() );
695 // move sprite
696 rSprite->movePixel(
697 aPageOrigin + (t *
698 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) *
699 maLeavingDirection) );
703 NumberAnimationSharedPtr createPushWipeTransition(
704 boost::optional<SlideSharedPtr> const & leavingSlide_,
705 const SlideSharedPtr& pEnteringSlide,
706 const UnoViewContainer& rViewContainer,
707 ScreenUpdater& rScreenUpdater,
708 EventMultiplexer& rEventMultiplexer,
709 sal_Int16 /*nTransitionType*/,
710 sal_Int16 nTransitionSubType,
711 bool /*bTransitionDirection*/,
712 const SoundPlayerSharedPtr& pSoundPlayer )
714 boost::optional<SlideSharedPtr> leavingSlide; // no bitmap
715 if (leavingSlide_ && (*leavingSlide_).get() != 0)
717 // opt: only page, if we've an
718 // actual slide to move out here. We
719 // _don't_ need a fake black background
720 // bitmap, neither for push nor for comb
721 // wipes.
722 leavingSlide = leavingSlide_;
725 // setup direction vector
726 bool bComb( false );
727 ::basegfx::B2DVector aDirection;
728 switch( nTransitionSubType )
730 default:
731 OSL_FAIL(
732 "createPushWipeTransition(): Unexpected transition "
733 "subtype for animations::TransitionType::PUSHWIPE "
734 "transitions" );
735 return NumberAnimationSharedPtr();
737 case animations::TransitionSubType::FROMTOP:
738 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
739 break;
741 case animations::TransitionSubType::FROMBOTTOM:
742 aDirection = ::basegfx::B2DVector( 0.0, -1.0 );
743 break;
745 case animations::TransitionSubType::FROMLEFT:
746 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
747 break;
749 case animations::TransitionSubType::FROMRIGHT:
750 aDirection = ::basegfx::B2DVector( -1.0, 0.0 );
751 break;
753 case animations::TransitionSubType::FROMBOTTOMRIGHT:
754 aDirection = ::basegfx::B2DVector( -1.0, -1.0 );
755 break;
757 case animations::TransitionSubType::FROMBOTTOMLEFT:
758 aDirection = ::basegfx::B2DVector( 1.0, -1.0 );
759 break;
761 case animations::TransitionSubType::FROMTOPRIGHT:
762 aDirection = ::basegfx::B2DVector( -1.0, 1.0 );
763 break;
765 case animations::TransitionSubType::FROMTOPLEFT:
766 aDirection = ::basegfx::B2DVector( 1.0, 1.0 );
767 break;
769 case animations::TransitionSubType::COMBHORIZONTAL:
770 aDirection = ::basegfx::B2DVector( 1.0, 0.0 );
771 bComb = true;
772 break;
774 case animations::TransitionSubType::COMBVERTICAL:
775 aDirection = ::basegfx::B2DVector( 0.0, 1.0 );
776 bComb = true;
777 break;
780 if( bComb )
782 return NumberAnimationSharedPtr(
783 new CombTransition( leavingSlide,
784 pEnteringSlide,
785 pSoundPlayer,
786 rViewContainer,
787 rScreenUpdater,
788 rEventMultiplexer,
789 aDirection,
790 24 /* comb with 12 stripes */ ));
792 else
794 return NumberAnimationSharedPtr(
795 new MovingSlideChange( leavingSlide,
796 pEnteringSlide,
797 pSoundPlayer,
798 rViewContainer,
799 rScreenUpdater,
800 rEventMultiplexer,
801 aDirection,
802 aDirection ));
806 NumberAnimationSharedPtr createSlideWipeTransition(
807 boost::optional<SlideSharedPtr> const & leavingSlide,
808 const SlideSharedPtr& pEnteringSlide,
809 const UnoViewContainer& rViewContainer,
810 ScreenUpdater& rScreenUpdater,
811 EventMultiplexer& rEventMultiplexer,
812 sal_Int16 /*nTransitionType*/,
813 sal_Int16 nTransitionSubType,
814 bool bTransitionDirection,
815 const SoundPlayerSharedPtr& pSoundPlayer )
817 // setup 'in' direction vector
818 ::basegfx::B2DVector aInDirection;
819 switch( nTransitionSubType )
821 default:
822 OSL_FAIL(
823 "createSlideWipeTransition(): Unexpected transition "
824 "subtype for animations::TransitionType::SLIDEWIPE "
825 "transitions" );
826 return NumberAnimationSharedPtr();
828 case animations::TransitionSubType::FROMTOP:
829 aInDirection = ::basegfx::B2DVector( 0.0, 1.0 );
830 break;
832 case animations::TransitionSubType::FROMRIGHT:
833 aInDirection = ::basegfx::B2DVector( -1.0, 0.0 );
834 break;
836 case animations::TransitionSubType::FROMLEFT:
837 aInDirection = ::basegfx::B2DVector( 1.0, 0.0 );
838 break;
840 case animations::TransitionSubType::FROMBOTTOM:
841 aInDirection = ::basegfx::B2DVector( 0.0, -1.0 );
842 break;
844 case animations::TransitionSubType::FROMBOTTOMRIGHT:
845 aInDirection = ::basegfx::B2DVector( -1.0, -1.0 );
846 break;
848 case animations::TransitionSubType::FROMBOTTOMLEFT:
849 aInDirection = ::basegfx::B2DVector( 1.0, -1.0 );
850 break;
852 case animations::TransitionSubType::FROMTOPRIGHT:
853 aInDirection = ::basegfx::B2DVector( -1.0, 1.0 );
854 break;
856 case animations::TransitionSubType::FROMTOPLEFT:
857 aInDirection = ::basegfx::B2DVector( 1.0, 1.0 );
858 break;
861 if( bTransitionDirection )
863 // normal, 'forward' slide wipe effect. Since the old
864 // content is still on screen (and does not move), we omit
865 // the 'leaving' slide.
868 return NumberAnimationSharedPtr(
869 new MovingSlideChange(
870 boost::optional<SlideSharedPtr>() /* no slide */,
871 pEnteringSlide,
872 pSoundPlayer,
873 rViewContainer,
874 rScreenUpdater,
875 rEventMultiplexer,
876 basegfx::B2DVector(),
877 aInDirection ));
879 else
881 // 'reversed' slide wipe effect. Reverse for slide wipes
882 // means, that the new slide is in the back, statically,
883 // and the old one is moving off in the foreground.
886 return NumberAnimationSharedPtr(
887 new MovingSlideChange( leavingSlide,
888 pEnteringSlide,
889 pSoundPlayer,
890 rViewContainer,
891 rScreenUpdater,
892 rEventMultiplexer,
893 aInDirection,
894 basegfx::B2DVector() ));
898 NumberAnimationSharedPtr createPluginTransition(
899 sal_Int16 nTransitionType,
900 sal_Int16 nTransitionSubType,
901 boost::optional<SlideSharedPtr> const& pLeavingSlide,
902 const SlideSharedPtr& pEnteringSlide,
903 const UnoViewContainer& rViewContainer,
904 ScreenUpdater& rScreenUpdater,
905 const uno::Reference<
906 presentation::XTransitionFactory>& xFactory,
907 const SoundPlayerSharedPtr& pSoundPlayer,
908 EventMultiplexer& rEventMultiplexer)
910 PluginSlideChange* pTransition =
911 new PluginSlideChange(
912 nTransitionType,
913 nTransitionSubType,
914 pLeavingSlide,
915 pEnteringSlide,
916 rViewContainer,
917 rScreenUpdater,
918 xFactory,
919 pSoundPlayer,
920 rEventMultiplexer );
922 if( pTransition->Success() )
923 return NumberAnimationSharedPtr( pTransition );
924 else
926 delete pTransition;
927 return NumberAnimationSharedPtr();
931 } // anon namespace
934 NumberAnimationSharedPtr TransitionFactory::createSlideTransition(
935 const SlideSharedPtr& pLeavingSlide,
936 const SlideSharedPtr& pEnteringSlide,
937 const UnoViewContainer& rViewContainer,
938 ScreenUpdater& rScreenUpdater,
939 EventMultiplexer& rEventMultiplexer,
940 const uno::Reference<presentation::XTransitionFactory>& xOptionalFactory,
941 sal_Int16 nTransitionType,
942 sal_Int16 nTransitionSubType,
943 bool bTransitionDirection,
944 const RGBColor& rTransitionFadeColor,
945 const SoundPlayerSharedPtr& pSoundPlayer )
947 // xxx todo: change to TransitionType::NONE, TransitionSubType::NONE:
948 if (nTransitionType == 0 && nTransitionSubType == 0) {
949 // just play sound, no slide transition:
950 if (pSoundPlayer) {
951 pSoundPlayer->startPlayback();
952 // xxx todo: for now, presentation.cxx takes care about the slide
953 // #i50492# transition sound object, so just release it here
955 return NumberAnimationSharedPtr();
958 ENSURE_OR_THROW(
959 pEnteringSlide,
960 "TransitionFactory::createSlideTransition(): Invalid entering slide" );
962 if( xOptionalFactory.is() &&
963 xOptionalFactory->hasTransition(nTransitionType, nTransitionSubType) )
965 // #i82460# - optional plugin factory claims this transition. delegate.
966 NumberAnimationSharedPtr pTransition(
967 createPluginTransition(
968 nTransitionType,
969 nTransitionSubType,
970 comphelper::make_optional(pLeavingSlide),
971 pEnteringSlide,
972 rViewContainer,
973 rScreenUpdater,
974 xOptionalFactory,
975 pSoundPlayer,
976 rEventMultiplexer ));
978 if( pTransition.get() )
979 return pTransition;
982 const TransitionInfo* pTransitionInfo(
983 getTransitionInfo( nTransitionType, nTransitionSubType ) );
985 if( pTransitionInfo != NULL )
987 switch( pTransitionInfo->meTransitionClass )
989 default:
990 case TransitionInfo::TRANSITION_INVALID:
991 OSL_TRACE(
992 "TransitionFactory::createSlideTransition(): "
993 "Invalid type/subtype (%d/%d) combination encountered.",
994 nTransitionType,
995 nTransitionSubType );
996 return NumberAnimationSharedPtr();
999 case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON:
1001 // generate parametric poly-polygon
1002 ParametricPolyPolygonSharedPtr pPoly(
1003 ParametricPolyPolygonFactory::createClipPolyPolygon(
1004 nTransitionType, nTransitionSubType ) );
1006 // create a clip transition from that
1007 return NumberAnimationSharedPtr(
1008 new ClippedSlideChange( pEnteringSlide,
1009 pPoly,
1010 *pTransitionInfo,
1011 rViewContainer,
1012 rScreenUpdater,
1013 rEventMultiplexer,
1014 bTransitionDirection,
1015 pSoundPlayer ));
1018 case TransitionInfo::TRANSITION_SPECIAL:
1020 switch( nTransitionType )
1022 default:
1023 OSL_FAIL(
1024 "TransitionFactory::createSlideTransition(): "
1025 "Unexpected transition type for "
1026 "TRANSITION_SPECIAL transitions" );
1027 return NumberAnimationSharedPtr();
1029 case animations::TransitionType::RANDOM:
1031 // select randomly one of the effects from the
1032 // TransitionFactoryTable
1034 const TransitionInfo* pRandomTransitionInfo(
1035 getRandomTransitionInfo() );
1037 ENSURE_OR_THROW(
1038 pRandomTransitionInfo != NULL,
1039 "TransitionFactory::createSlideTransition(): "
1040 "Got invalid random transition info" );
1042 ENSURE_OR_THROW(
1043 pRandomTransitionInfo->mnTransitionType !=
1044 animations::TransitionType::RANDOM,
1045 "TransitionFactory::createSlideTransition(): "
1046 "Got random again for random input!" );
1048 // and recurse
1049 return createSlideTransition(
1050 pLeavingSlide,
1051 pEnteringSlide,
1052 rViewContainer,
1053 rScreenUpdater,
1054 rEventMultiplexer,
1055 xOptionalFactory,
1056 pRandomTransitionInfo->mnTransitionType,
1057 pRandomTransitionInfo->mnTransitionSubType,
1058 bTransitionDirection,
1059 rTransitionFadeColor,
1060 pSoundPlayer );
1063 case animations::TransitionType::PUSHWIPE:
1065 return createPushWipeTransition(
1066 comphelper::make_optional(pLeavingSlide),
1067 pEnteringSlide,
1068 rViewContainer,
1069 rScreenUpdater,
1070 rEventMultiplexer,
1071 nTransitionType,
1072 nTransitionSubType,
1073 bTransitionDirection,
1074 pSoundPlayer );
1077 case animations::TransitionType::SLIDEWIPE:
1079 return createSlideWipeTransition(
1080 comphelper::make_optional(pLeavingSlide),
1081 pEnteringSlide,
1082 rViewContainer,
1083 rScreenUpdater,
1084 rEventMultiplexer,
1085 nTransitionType,
1086 nTransitionSubType,
1087 bTransitionDirection,
1088 pSoundPlayer );
1091 case animations::TransitionType::BARWIPE:
1092 case animations::TransitionType::FADE:
1094 // black page:
1095 boost::optional<SlideSharedPtr> leavingSlide;
1096 boost::optional<RGBColor> aFadeColor;
1098 switch( nTransitionSubType )
1100 case animations::TransitionSubType::CROSSFADE:
1101 // crossfade needs no further setup,
1102 // just blend new slide over current
1103 // slide.
1104 break;
1106 // TODO(F1): Implement toColor/fromColor fades
1107 case animations::TransitionSubType::FADETOCOLOR:
1108 // FALLTHROUGH intended
1109 case animations::TransitionSubType::FADEFROMCOLOR:
1110 // FALLTHROUGH intended
1111 case animations::TransitionSubType::FADEOVERCOLOR:
1112 if (pLeavingSlide) {
1113 // only generate, if fade
1114 // effect really needs it.
1115 leavingSlide.reset( pLeavingSlide );
1117 aFadeColor = rTransitionFadeColor;
1118 break;
1120 default:
1121 ENSURE_OR_THROW( false,
1122 "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" );
1125 if( nTransitionType == animations::TransitionType::FADE )
1126 return NumberAnimationSharedPtr(
1127 new FadingSlideChange(
1128 leavingSlide,
1129 pEnteringSlide,
1130 aFadeColor,
1131 pSoundPlayer,
1132 rViewContainer,
1133 rScreenUpdater,
1134 rEventMultiplexer ));
1135 else
1136 return NumberAnimationSharedPtr(
1137 new CutSlideChange(
1138 leavingSlide,
1139 pEnteringSlide,
1140 rTransitionFadeColor,
1141 pSoundPlayer,
1142 rViewContainer,
1143 rScreenUpdater,
1144 rEventMultiplexer ));
1148 break;
1152 // No animation generated, maybe no table entry for given
1153 // transition?
1154 OSL_TRACE(
1155 "TransitionFactory::createSlideTransition(): "
1156 "Unknown type/subtype (%d/%d) combination encountered",
1157 nTransitionType,
1158 nTransitionSubType );
1159 OSL_FAIL(
1160 "TransitionFactory::createSlideTransition(): "
1161 "Unknown type/subtype combination encountered" );
1163 return NumberAnimationSharedPtr();
1166 } // namespace internal
1167 } // namespace presentation
1169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */