1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_slideshow.hxx" 26 27 #include <canvas/debug.hxx> 28 #include <tools/diagnose_ex.h> 29 30 #include <basegfx/matrix/b2dhommatrix.hxx> 31 #include <basegfx/tools/canvastools.hxx> 32 #include <basegfx/polygon/b2dpolygontools.hxx> 33 #include <basegfx/polygon/b2dpolypolygontools.hxx> 34 35 #include <cppcanvas/basegfxfactory.hxx> 36 37 #include <comphelper/optional.hxx> 38 #include <comphelper/make_shared_from_uno.hxx> 39 40 #include <com/sun/star/rendering/XIntegerBitmap.hpp> 41 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp> 42 #include <com/sun/star/animations/TransitionType.hpp> 43 #include <com/sun/star/animations/TransitionSubType.hpp> 44 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 45 46 #include "slidechangebase.hxx" 47 #include "transitionfactory.hxx" 48 #include "transitiontools.hxx" 49 #include "parametricpolypolygonfactory.hxx" 50 #include "animationfactory.hxx" 51 #include "clippingfunctor.hxx" 52 #include "combtransition.hxx" 53 #include "tools.hxx" 54 55 #include <boost/bind.hpp> 56 57 58 /*************************************************** 59 *** *** 60 *** Slide Transition Effects *** 61 *** *** 62 ***************************************************/ 63 64 using namespace com::sun::star; 65 66 namespace slideshow { 67 namespace internal { 68 69 namespace { 70 71 // helper methods 72 // ============================================= 73 74 void fillPage( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 75 const ::basegfx::B2DSize& rPageSizePixel, 76 const RGBColor& rFillColor ) 77 { 78 // need to render without any transformation (we 79 // assume rPageSizePixel to represent device units) 80 const ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( 81 rDestinationCanvas->clone() ); 82 pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() ); 83 84 // TODO(F2): Properly respect clip here. 85 // Might have to be transformed, too. 86 const ::basegfx::B2DHomMatrix aViewTransform( 87 rDestinationCanvas->getTransformation() ); 88 const ::basegfx::B2DPoint aOutputPosPixel( 89 aViewTransform * ::basegfx::B2DPoint() ); 90 91 fillRect( pDevicePixelCanvas, 92 ::basegfx::B2DRectangle( 93 aOutputPosPixel.getX(), 94 aOutputPosPixel.getY(), 95 aOutputPosPixel.getX() + rPageSizePixel.getX(), 96 aOutputPosPixel.getY() + rPageSizePixel.getY() ), 97 rFillColor.getIntegerColor() ); 98 } 99 100 class PluginSlideChange: public SlideChangeBase 101 { 102 struct TransitionViewPair { 103 uno::Reference<presentation::XTransition> mxTransition; 104 UnoViewSharedPtr mpView; 105 106 TransitionViewPair( uno::Reference<presentation::XTransition> xTransition, const UnoViewSharedPtr pView ) 107 { 108 mxTransition = xTransition; 109 mpView = pView; 110 } 111 112 ~TransitionViewPair() 113 { 114 mxTransition.clear(); 115 mpView.reset();; 116 } 117 118 void update( double t ) 119 { 120 mxTransition->update( t ); 121 } 122 }; 123 124 public: 125 /** Create a new SlideChanger, for the given leaving and 126 entering slide bitmaps, which uses super secret OpenGL 127 stuff. 128 */ 129 PluginSlideChange( sal_Int16 nTransitionType, 130 sal_Int16 nTransitionSubType, 131 boost::optional<SlideSharedPtr> const& leavingSlide_, 132 const SlideSharedPtr& pEnteringSlide, 133 const UnoViewContainer& rViewContainer, 134 ScreenUpdater& rScreenUpdater, 135 const uno::Reference< 136 presentation::XTransitionFactory>& xFactory, 137 const SoundPlayerSharedPtr& pSoundPlayer, 138 EventMultiplexer& rEventMultiplexer) : 139 SlideChangeBase( leavingSlide_, 140 pEnteringSlide, 141 pSoundPlayer, 142 rViewContainer, 143 rScreenUpdater, 144 rEventMultiplexer ), 145 maTransitions(), 146 mbSuccess( false ), 147 mnTransitionType( nTransitionType ), 148 mnTransitionSubType( nTransitionSubType ), 149 mxFactory( xFactory ) 150 { 151 // create one transition per view 152 UnoViewVector::const_iterator aCurrView (rViewContainer.begin()); 153 const UnoViewVector::const_iterator aEnd(rViewContainer.end()); 154 while( aCurrView != aEnd ) 155 { 156 if(! addTransition( *aCurrView ) ) 157 return; 158 159 ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(), 160 "Failed to create plugin transition"); 161 ++aCurrView; 162 } 163 mbSuccess = true; 164 } 165 166 ~PluginSlideChange() 167 { 168 mxFactory.clear(); 169 170 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin()); 171 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end()); 172 while( aCurrView != aEnd ) 173 { 174 delete (*aCurrView); 175 ++aCurrView; 176 } 177 maTransitions.clear(); 178 } 179 180 bool addTransition( const UnoViewSharedPtr& rView ) 181 { 182 uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition( 183 mnTransitionType, 184 mnTransitionSubType, 185 rView->getUnoView(), 186 getLeavingBitmap(ViewEntry(rView))->getXBitmap(), 187 getEnteringBitmap(ViewEntry(rView))->getXBitmap() ); 188 189 if( rTransition.is() ) 190 maTransitions.push_back( new TransitionViewPair( rTransition, rView ) ); 191 else 192 return false; 193 194 return true; 195 } 196 197 virtual bool operator()( double t ) 198 { 199 std::for_each(maTransitions.begin(), 200 maTransitions.end(), 201 boost::bind( &TransitionViewPair::update, 202 _1, t) ); 203 return true; 204 } 205 206 bool Success() 207 { 208 return mbSuccess; 209 } 210 211 // ViewEventHandler 212 virtual void viewAdded( const UnoViewSharedPtr& rView ) 213 { 214 OSL_TRACE("PluginSlideChange viewAdded"); 215 SlideChangeBase::viewAdded( rView ); 216 217 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin()); 218 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end()); 219 bool bKnown = false; 220 while( aCurrView != aEnd ) 221 { 222 if( (*aCurrView)->mpView == rView ) { 223 bKnown = true; 224 break; 225 } 226 ++aCurrView; 227 } 228 229 if( !bKnown ) { 230 OSL_TRACE("need to be added"); 231 232 addTransition( rView ); 233 } 234 } 235 236 virtual void viewRemoved( const UnoViewSharedPtr& rView ) 237 { 238 OSL_TRACE("PluginSlideChange viewRemoved"); 239 SlideChangeBase::viewRemoved( rView ); 240 241 ::std::vector< TransitionViewPair* >::iterator aCurrView (maTransitions.begin()); 242 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end()); 243 while( aCurrView != aEnd ) 244 { 245 if( (*aCurrView)->mpView == rView ) { 246 OSL_TRACE( "view removed" ); 247 delete (*aCurrView); 248 maTransitions.erase( aCurrView ); 249 break; 250 } 251 ++aCurrView; 252 } 253 } 254 255 virtual void viewChanged( const UnoViewSharedPtr& rView ) 256 { 257 OSL_TRACE("PluginSlideChange viewChanged"); 258 SlideChangeBase::viewChanged( rView ); 259 260 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin()); 261 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end()); 262 while( aCurrView != aEnd ) 263 { 264 if( (*aCurrView)->mpView == rView ) { 265 OSL_TRACE( "view changed" ); 266 (*aCurrView)->mxTransition->viewChanged( rView->getUnoView(), 267 getLeavingBitmap(ViewEntry(rView))->getXBitmap(), 268 getEnteringBitmap(ViewEntry(rView))->getXBitmap() ); 269 } else 270 OSL_TRACE( "view did not changed" ); 271 272 ++aCurrView; 273 } 274 } 275 276 virtual void viewsChanged() 277 { 278 OSL_TRACE("PluginSlideChange viewsChanged"); 279 SlideChangeBase::viewsChanged(); 280 281 ::std::vector< TransitionViewPair* >::const_iterator aCurrView (maTransitions.begin()); 282 ::std::vector< TransitionViewPair* >::const_iterator aEnd(maTransitions.end()); 283 while( aCurrView != aEnd ) 284 { 285 OSL_TRACE( "view changed" ); 286 (*aCurrView)->mxTransition->viewChanged( (*aCurrView)->mpView->getUnoView(), 287 getLeavingBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap(), 288 getEnteringBitmap(ViewEntry((*aCurrView)->mpView))->getXBitmap() ); 289 ++aCurrView; 290 } 291 } 292 293 private: 294 // One transition object per view 295 std::vector< TransitionViewPair* > maTransitions; 296 297 // bool 298 bool mbSuccess; 299 300 sal_Int16 mnTransitionType; 301 sal_Int16 mnTransitionSubType; 302 303 uno::Reference<presentation::XTransitionFactory> mxFactory; 304 }; 305 306 class ClippedSlideChange : public SlideChangeBase 307 { 308 public: 309 /** Create a new SlideChanger, for the given leaving and 310 entering slide bitmaps, which applies the given clip 311 polygon. 312 */ 313 ClippedSlideChange( 314 const SlideSharedPtr& pEnteringSlide, 315 const ParametricPolyPolygonSharedPtr& rPolygon, 316 const TransitionInfo& rTransitionInfo, 317 const UnoViewContainer& rViewContainer, 318 ScreenUpdater& rScreenUpdater, 319 EventMultiplexer& rEventMultiplexer, 320 bool bDirectionForward, 321 const SoundPlayerSharedPtr& pSoundPlayer ) : 322 SlideChangeBase( 323 // leaving bitmap is empty, we're leveraging the fact that the 324 // old slide is still displayed in the background: 325 boost::optional<SlideSharedPtr>(), 326 pEnteringSlide, 327 pSoundPlayer, 328 rViewContainer, 329 rScreenUpdater, 330 rEventMultiplexer ), 331 maClippingFunctor( rPolygon, 332 rTransitionInfo, 333 bDirectionForward, 334 true ) 335 {} 336 337 virtual void performIn( 338 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 339 const ViewEntry& rViewEntry, 340 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 341 double t ); 342 343 virtual void performOut( 344 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 345 const ViewEntry& rViewEntry, 346 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 347 double t ); 348 349 private: 350 ClippingFunctor maClippingFunctor; 351 }; 352 353 void ClippedSlideChange::performIn( 354 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 355 const ViewEntry& rViewEntry, 356 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, 357 double t ) 358 { 359 // #i46602# Better work in device coordinate space here, 360 // otherwise, we too easily suffer from roundoffs. Apart from 361 // that, getEnteringSizePixel() _guarantees_ to cover the whole 362 // slide bitmap. There's a catch, though: this removes any effect 363 // of the view transformation (e.g. rotation) from the transition. 364 rSprite->setClipPixel( 365 maClippingFunctor( t, 366 getEnteringSlideSizePixel(rViewEntry.mpView) ) ); 367 } 368 369 void ClippedSlideChange::performOut( 370 const ::cppcanvas::CustomSpriteSharedPtr& /*rSprite*/, 371 const ViewEntry& /*rViewEntry*/, 372 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, 373 double /*t*/ ) 374 { 375 // not needed here 376 } 377 378 379 class FadingSlideChange : public SlideChangeBase 380 { 381 public: 382 /** Create a new SlideChanger, for the given leaving and 383 entering slides, which applies a fade effect. 384 */ 385 FadingSlideChange( 386 boost::optional<SlideSharedPtr> const & leavingSlide, 387 const SlideSharedPtr& pEnteringSlide, 388 boost::optional<RGBColor> const& rFadeColor, 389 const SoundPlayerSharedPtr& pSoundPlayer, 390 const UnoViewContainer& rViewContainer, 391 ScreenUpdater& rScreenUpdater, 392 EventMultiplexer& rEventMultiplexer ) 393 : SlideChangeBase( leavingSlide, 394 pEnteringSlide, 395 pSoundPlayer, 396 rViewContainer, 397 rScreenUpdater, 398 rEventMultiplexer ), 399 maFadeColor( rFadeColor ), 400 mbFirstTurn( true ) 401 {} 402 403 virtual void performIn( 404 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 405 const ViewEntry& rViewEntry, 406 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 407 double t ); 408 409 virtual void performOut( 410 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 411 const ViewEntry& rViewEntry, 412 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 413 double t ); 414 415 private: 416 const boost::optional< RGBColor > maFadeColor; 417 bool mbFirstTurn; 418 }; 419 420 void FadingSlideChange::performIn( 421 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 422 const ViewEntry& /*rViewEntry*/, 423 const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, 424 double t ) 425 { 426 ENSURE_OR_THROW( 427 rSprite, 428 "FadingSlideChange::performIn(): Invalid sprite" ); 429 430 if( maFadeColor ) 431 // After half of the active time, fade in new slide 432 rSprite->setAlpha( t > 0.5 ? 2.0*(t-0.5) : 0.0 ); 433 else 434 // Fade in new slide over full active time 435 rSprite->setAlpha( t ); 436 } 437 438 void FadingSlideChange::performOut( 439 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 440 const ViewEntry& rViewEntry, 441 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 442 double t ) 443 { 444 ENSURE_OR_THROW( 445 rSprite, 446 "FadingSlideChange::performOut(): Invalid sprite" ); 447 ENSURE_OR_THROW( 448 rDestinationCanvas, 449 "FadingSlideChange::performOut(): Invalid dest canvas" ); 450 451 // only needed for color fades 452 if( maFadeColor ) 453 { 454 if( mbFirstTurn ) 455 { 456 mbFirstTurn = false; 457 458 // clear page to given fade color. 'Leaving' slide is 459 // painted atop of that, but slowly fading out. 460 fillPage( rDestinationCanvas, 461 getEnteringSlideSizePixel( rViewEntry.mpView ), 462 *maFadeColor ); 463 } 464 465 // Until half of the active time, fade out old 466 // slide. After half of the active time, old slide 467 // will be invisible. 468 rSprite->setAlpha( t > 0.5 ? 0.0 : 2.0*(0.5-t) ); 469 } 470 } 471 472 class MovingSlideChange : public SlideChangeBase 473 { 474 /// Direction vector for leaving slide, 475 const ::basegfx::B2DVector maLeavingDirection; 476 477 /// Direction vector for entering slide, 478 const ::basegfx::B2DVector maEnteringDirection; 479 480 bool mbFirstPerformCall; 481 482 public: 483 /** Create a new SlideChanger, for the given entering slide 484 bitmaps, which performes a moving slide change effect 485 486 @param rLeavingDirection 487 Direction vector. The move is performed along this 488 direction vector, starting at a position where the leaving 489 slide is fully visible, and ending at a position where the 490 leaving slide is just not visible. The vector must have 491 unit length. 492 493 @param rEnteringDirection 494 Direction vector. The move is performed along this 495 direction vector, starting at a position where the 496 entering slide is just not visible, and ending at the 497 final slide position. The vector must have unit length. 498 */ 499 MovingSlideChange( 500 const boost::optional<SlideSharedPtr>& leavingSlide, 501 const SlideSharedPtr& pEnteringSlide, 502 const SoundPlayerSharedPtr& pSoundPlayer, 503 const UnoViewContainer& rViewContainer, 504 ScreenUpdater& rScreenUpdater, 505 EventMultiplexer& rEventMultiplexer, 506 const ::basegfx::B2DVector& rLeavingDirection, 507 const ::basegfx::B2DVector& rEnteringDirection ) 508 : SlideChangeBase( 509 leavingSlide, pEnteringSlide, pSoundPlayer, 510 rViewContainer, rScreenUpdater, rEventMultiplexer, 511 // Optimization: when leaving bitmap is given, 512 // but it does not move, don't create sprites for it, 513 // we simply paint it once at startup: 514 !rLeavingDirection.equalZero() /* bCreateLeavingSprites */, 515 !rEnteringDirection.equalZero() /* bCreateEnteringSprites */ ), 516 // TODO(F1): calc correct length of direction 517 // vector. Directions not strictly horizontal or vertical 518 // must travel a longer distance. 519 maLeavingDirection( rLeavingDirection ), 520 // TODO(F1): calc correct length of direction 521 // vector. Directions not strictly horizontal or vertical 522 // must travel a longer distance. 523 maEnteringDirection( rEnteringDirection ), 524 mbFirstPerformCall( true ) 525 {} 526 527 virtual void performIn( 528 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 529 const ViewEntry& rViewEntry, 530 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 531 double t ); 532 533 virtual void performOut( 534 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 535 const ViewEntry& rViewEntry, 536 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 537 double t ); 538 }; 539 540 void MovingSlideChange::performIn( 541 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 542 const ViewEntry& rViewEntry, 543 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 544 double t ) 545 { 546 // intro sprite moves: 547 548 ENSURE_OR_THROW( 549 rSprite, 550 "MovingSlideChange::performIn(): Invalid sprite" ); 551 ENSURE_OR_THROW( 552 rDestinationCanvas, 553 "MovingSlideChange::performIn(): Invalid dest canvas" ); 554 555 if (mbFirstPerformCall && maLeavingDirection.equalZero()) 556 { 557 mbFirstPerformCall = false; 558 renderBitmap( getLeavingBitmap(rViewEntry), rDestinationCanvas ); 559 } 560 561 // TODO(F1): This does not account for non-translational 562 // transformations! If the canvas is rotated, we still 563 // move the sprite unrotated (which might or might not 564 // produce the intended effect). 565 const basegfx::B2DHomMatrix aViewTransform( 566 rDestinationCanvas->getTransformation() ); 567 const basegfx::B2DPoint aPageOrigin( 568 aViewTransform * basegfx::B2DPoint() ); 569 570 // move sprite 571 rSprite->movePixel( 572 aPageOrigin + 573 ((t - 1.0) * 574 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) * 575 maEnteringDirection) ); 576 } 577 578 void MovingSlideChange::performOut( 579 const ::cppcanvas::CustomSpriteSharedPtr& rSprite, 580 const ViewEntry& rViewEntry, 581 const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, 582 double t ) 583 { 584 // outro sprite moves: 585 586 ENSURE_OR_THROW( 587 rSprite, 588 "MovingSlideChange::performOut(): Invalid sprite" ); 589 ENSURE_OR_THROW( 590 rDestinationCanvas, 591 "MovingSlideChange::performOut(): Invalid dest canvas" ); 592 593 if (mbFirstPerformCall && maEnteringDirection.equalZero()) 594 { 595 mbFirstPerformCall = false; 596 renderBitmap( getEnteringBitmap(rViewEntry), rDestinationCanvas ); 597 } 598 599 // TODO(F1): This does not account for non-translational 600 // transformations! If the canvas is rotated, we still 601 // move the sprite unrotated (which might or might not 602 // produce the intended effect). 603 const basegfx::B2DHomMatrix aViewTransform( 604 rDestinationCanvas->getTransformation() ); 605 const basegfx::B2DPoint aPageOrigin( 606 aViewTransform * basegfx::B2DPoint() ); 607 608 // move sprite 609 rSprite->movePixel( 610 aPageOrigin + (t * 611 ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) * 612 maLeavingDirection) ); 613 } 614 615 616 NumberAnimationSharedPtr createPushWipeTransition( 617 boost::optional<SlideSharedPtr> const & leavingSlide_, 618 const SlideSharedPtr& pEnteringSlide, 619 const UnoViewContainer& rViewContainer, 620 ScreenUpdater& rScreenUpdater, 621 EventMultiplexer& rEventMultiplexer, 622 sal_Int16 /*nTransitionType*/, 623 sal_Int16 nTransitionSubType, 624 bool /*bTransitionDirection*/, 625 const SoundPlayerSharedPtr& pSoundPlayer ) 626 { 627 boost::optional<SlideSharedPtr> leavingSlide; // no bitmap 628 if (leavingSlide_ && (*leavingSlide_).get() != 0) 629 { 630 // opt: only page, if we've an 631 // actual slide to move out here. We 632 // _don't_ need a fake black background 633 // bitmap, neither for push nor for comb 634 // wipes. 635 leavingSlide = leavingSlide_; 636 } 637 638 // setup direction vector 639 bool bComb( false ); 640 ::basegfx::B2DVector aDirection; 641 switch( nTransitionSubType ) 642 { 643 default: 644 OSL_ENSURE( 645 false, 646 "createPushWipeTransition(): Unexpected transition " 647 "subtype for animations::TransitionType::PUSHWIPE " 648 "transitions" ); 649 return NumberAnimationSharedPtr(); 650 651 case animations::TransitionSubType::FROMTOP: 652 aDirection = ::basegfx::B2DVector( 0.0, 1.0 ); 653 break; 654 655 case animations::TransitionSubType::FROMBOTTOM: 656 aDirection = ::basegfx::B2DVector( 0.0, -1.0 ); 657 break; 658 659 case animations::TransitionSubType::FROMLEFT: 660 aDirection = ::basegfx::B2DVector( 1.0, 0.0 ); 661 break; 662 663 case animations::TransitionSubType::FROMRIGHT: 664 aDirection = ::basegfx::B2DVector( -1.0, 0.0 ); 665 break; 666 667 case animations::TransitionSubType::FROMBOTTOMRIGHT: 668 aDirection = ::basegfx::B2DVector( -1.0, -1.0 ); 669 break; 670 671 case animations::TransitionSubType::FROMBOTTOMLEFT: 672 aDirection = ::basegfx::B2DVector( 1.0, -1.0 ); 673 break; 674 675 case animations::TransitionSubType::FROMTOPRIGHT: 676 aDirection = ::basegfx::B2DVector( -1.0, 1.0 ); 677 break; 678 679 case animations::TransitionSubType::FROMTOPLEFT: 680 aDirection = ::basegfx::B2DVector( 1.0, 1.0 ); 681 break; 682 683 case animations::TransitionSubType::COMBHORIZONTAL: 684 aDirection = ::basegfx::B2DVector( 1.0, 0.0 ); 685 bComb = true; 686 break; 687 688 case animations::TransitionSubType::COMBVERTICAL: 689 aDirection = ::basegfx::B2DVector( 0.0, 1.0 ); 690 bComb = true; 691 break; 692 } 693 694 if( bComb ) 695 { 696 return NumberAnimationSharedPtr( 697 new CombTransition( leavingSlide, 698 pEnteringSlide, 699 pSoundPlayer, 700 rViewContainer, 701 rScreenUpdater, 702 rEventMultiplexer, 703 aDirection, 704 24 /* comb with 12 stripes */ )); 705 } 706 else 707 { 708 return NumberAnimationSharedPtr( 709 new MovingSlideChange( leavingSlide, 710 pEnteringSlide, 711 pSoundPlayer, 712 rViewContainer, 713 rScreenUpdater, 714 rEventMultiplexer, 715 aDirection, 716 aDirection )); 717 } 718 } 719 720 NumberAnimationSharedPtr createSlideWipeTransition( 721 boost::optional<SlideSharedPtr> const & leavingSlide, 722 const SlideSharedPtr& pEnteringSlide, 723 const UnoViewContainer& rViewContainer, 724 ScreenUpdater& rScreenUpdater, 725 EventMultiplexer& rEventMultiplexer, 726 sal_Int16 /*nTransitionType*/, 727 sal_Int16 nTransitionSubType, 728 bool bTransitionDirection, 729 const SoundPlayerSharedPtr& pSoundPlayer ) 730 { 731 // setup 'in' direction vector 732 ::basegfx::B2DVector aInDirection; 733 switch( nTransitionSubType ) 734 { 735 default: 736 OSL_ENSURE( 737 false, 738 "createSlideWipeTransition(): Unexpected transition " 739 "subtype for animations::TransitionType::SLIDEWIPE " 740 "transitions" ); 741 return NumberAnimationSharedPtr(); 742 743 case animations::TransitionSubType::FROMTOP: 744 aInDirection = ::basegfx::B2DVector( 0.0, 1.0 ); 745 break; 746 747 case animations::TransitionSubType::FROMRIGHT: 748 aInDirection = ::basegfx::B2DVector( -1.0, 0.0 ); 749 break; 750 751 case animations::TransitionSubType::FROMLEFT: 752 aInDirection = ::basegfx::B2DVector( 1.0, 0.0 ); 753 break; 754 755 case animations::TransitionSubType::FROMBOTTOM: 756 aInDirection = ::basegfx::B2DVector( 0.0, -1.0 ); 757 break; 758 759 case animations::TransitionSubType::FROMBOTTOMRIGHT: 760 aInDirection = ::basegfx::B2DVector( -1.0, -1.0 ); 761 break; 762 763 case animations::TransitionSubType::FROMBOTTOMLEFT: 764 aInDirection = ::basegfx::B2DVector( 1.0, -1.0 ); 765 break; 766 767 case animations::TransitionSubType::FROMTOPRIGHT: 768 aInDirection = ::basegfx::B2DVector( -1.0, 1.0 ); 769 break; 770 771 case animations::TransitionSubType::FROMTOPLEFT: 772 aInDirection = ::basegfx::B2DVector( 1.0, 1.0 ); 773 break; 774 } 775 776 if( bTransitionDirection ) 777 { 778 // normal, 'forward' slide wipe effect. Since the old 779 // content is still on screen (and does not move), we omit 780 // the 'leaving' slide. 781 // ======================================================= 782 783 return NumberAnimationSharedPtr( 784 new MovingSlideChange( 785 boost::optional<SlideSharedPtr>() /* no slide */, 786 pEnteringSlide, 787 pSoundPlayer, 788 rViewContainer, 789 rScreenUpdater, 790 rEventMultiplexer, 791 basegfx::B2DVector(), 792 aInDirection )); 793 } 794 else 795 { 796 // 'reversed' slide wipe effect. Reverse for slide wipes 797 // means, that the new slide is in the back, statically, 798 // and the old one is moving off in the foreground. 799 // ======================================================= 800 801 return NumberAnimationSharedPtr( 802 new MovingSlideChange( leavingSlide, 803 pEnteringSlide, 804 pSoundPlayer, 805 rViewContainer, 806 rScreenUpdater, 807 rEventMultiplexer, 808 aInDirection, 809 basegfx::B2DVector() )); 810 } 811 } 812 813 NumberAnimationSharedPtr createPluginTransition( 814 sal_Int16 nTransitionType, 815 sal_Int16 nTransitionSubType, 816 boost::optional<SlideSharedPtr> const& pLeavingSlide, 817 const SlideSharedPtr& pEnteringSlide, 818 const UnoViewContainer& rViewContainer, 819 ScreenUpdater& rScreenUpdater, 820 const uno::Reference< 821 presentation::XTransitionFactory>& xFactory, 822 const SoundPlayerSharedPtr& pSoundPlayer, 823 EventMultiplexer& rEventMultiplexer) 824 { 825 PluginSlideChange* pTransition = 826 new PluginSlideChange( 827 nTransitionType, 828 nTransitionSubType, 829 pLeavingSlide, 830 pEnteringSlide, 831 rViewContainer, 832 rScreenUpdater, 833 xFactory, 834 pSoundPlayer, 835 rEventMultiplexer ); 836 837 if( pTransition->Success() ) 838 return NumberAnimationSharedPtr( pTransition ); 839 else { 840 delete pTransition; 841 return NumberAnimationSharedPtr(); 842 } 843 } 844 845 } // anon namespace 846 847 848 NumberAnimationSharedPtr TransitionFactory::createSlideTransition( 849 const SlideSharedPtr& pLeavingSlide, 850 const SlideSharedPtr& pEnteringSlide, 851 const UnoViewContainer& rViewContainer, 852 ScreenUpdater& rScreenUpdater, 853 EventMultiplexer& rEventMultiplexer, 854 const uno::Reference<presentation::XTransitionFactory>& xOptionalFactory, 855 sal_Int16 nTransitionType, 856 sal_Int16 nTransitionSubType, 857 bool bTransitionDirection, 858 const RGBColor& rTransitionFadeColor, 859 const SoundPlayerSharedPtr& pSoundPlayer ) 860 { 861 // xxx todo: change to TransitionType::NONE, TransitionSubType::NONE: 862 if (nTransitionType == 0 && nTransitionSubType == 0) { 863 // just play sound, no slide transition: 864 if (pSoundPlayer) { 865 pSoundPlayer->startPlayback(); 866 // xxx todo: for now, presentation.cxx takes care about the slide 867 // #i50492# transition sound object, so just release it here 868 } 869 return NumberAnimationSharedPtr(); 870 } 871 872 ENSURE_OR_THROW( 873 pEnteringSlide, 874 "TransitionFactory::createSlideTransition(): Invalid entering slide" ); 875 876 if( xOptionalFactory.is() && 877 xOptionalFactory->hasTransition(nTransitionType, nTransitionSubType) ) 878 { 879 // #i82460# - optional plugin factory claims this transition. delegate. 880 NumberAnimationSharedPtr pTransition( 881 createPluginTransition( 882 nTransitionType, 883 nTransitionSubType, 884 comphelper::make_optional(pLeavingSlide), 885 pEnteringSlide, 886 rViewContainer, 887 rScreenUpdater, 888 xOptionalFactory, 889 pSoundPlayer, 890 rEventMultiplexer )); 891 892 if( pTransition.get() ) 893 return pTransition; 894 } 895 896 const TransitionInfo* pTransitionInfo( 897 getTransitionInfo( nTransitionType, nTransitionSubType ) ); 898 899 if( pTransitionInfo != NULL ) 900 { 901 switch( pTransitionInfo->meTransitionClass ) 902 { 903 default: 904 case TransitionInfo::TRANSITION_INVALID: 905 OSL_TRACE( 906 "TransitionFactory::createSlideTransition(): " 907 "Invalid type/subtype (%d/%d) combination encountered.", 908 nTransitionType, 909 nTransitionSubType ); 910 return NumberAnimationSharedPtr(); 911 912 913 case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON: 914 { 915 // generate parametric poly-polygon 916 ParametricPolyPolygonSharedPtr pPoly( 917 ParametricPolyPolygonFactory::createClipPolyPolygon( 918 nTransitionType, nTransitionSubType ) ); 919 920 // create a clip transition from that 921 return NumberAnimationSharedPtr( 922 new ClippedSlideChange( pEnteringSlide, 923 pPoly, 924 *pTransitionInfo, 925 rViewContainer, 926 rScreenUpdater, 927 rEventMultiplexer, 928 bTransitionDirection, 929 pSoundPlayer )); 930 } 931 932 case TransitionInfo::TRANSITION_SPECIAL: 933 { 934 switch( nTransitionType ) 935 { 936 default: 937 OSL_ENSURE( 938 false, 939 "TransitionFactory::createSlideTransition(): " 940 "Unexpected transition type for " 941 "TRANSITION_SPECIAL transitions" ); 942 return NumberAnimationSharedPtr(); 943 944 case animations::TransitionType::RANDOM: 945 { 946 // select randomly one of the effects from the 947 // TransitionFactoryTable 948 949 const TransitionInfo* pRandomTransitionInfo( 950 getRandomTransitionInfo() ); 951 952 ENSURE_OR_THROW( 953 pRandomTransitionInfo != NULL, 954 "TransitionFactory::createSlideTransition(): " 955 "Got invalid random transition info" ); 956 957 ENSURE_OR_THROW( 958 pRandomTransitionInfo->mnTransitionType != 959 animations::TransitionType::RANDOM, 960 "TransitionFactory::createSlideTransition(): " 961 "Got random again for random input!" ); 962 963 // and recurse 964 return createSlideTransition( 965 pLeavingSlide, 966 pEnteringSlide, 967 rViewContainer, 968 rScreenUpdater, 969 rEventMultiplexer, 970 xOptionalFactory, 971 pRandomTransitionInfo->mnTransitionType, 972 pRandomTransitionInfo->mnTransitionSubType, 973 bTransitionDirection, 974 rTransitionFadeColor, 975 pSoundPlayer ); 976 } 977 978 case animations::TransitionType::PUSHWIPE: 979 { 980 return createPushWipeTransition( 981 comphelper::make_optional(pLeavingSlide), 982 pEnteringSlide, 983 rViewContainer, 984 rScreenUpdater, 985 rEventMultiplexer, 986 nTransitionType, 987 nTransitionSubType, 988 bTransitionDirection, 989 pSoundPlayer ); 990 } 991 992 case animations::TransitionType::SLIDEWIPE: 993 { 994 return createSlideWipeTransition( 995 comphelper::make_optional(pLeavingSlide), 996 pEnteringSlide, 997 rViewContainer, 998 rScreenUpdater, 999 rEventMultiplexer, 1000 nTransitionType, 1001 nTransitionSubType, 1002 bTransitionDirection, 1003 pSoundPlayer ); 1004 } 1005 1006 case animations::TransitionType::FADE: 1007 { 1008 // black page: 1009 boost::optional<SlideSharedPtr> leavingSlide; 1010 1011 switch( nTransitionSubType ) 1012 { 1013 case animations::TransitionSubType::CROSSFADE: 1014 // crossfade needs no further setup, 1015 // just blend new slide over existing 1016 // background. 1017 break; 1018 1019 // TODO(F1): Implement toColor/fromColor fades 1020 case animations::TransitionSubType::FADETOCOLOR: 1021 // FALLTHROUGH intended 1022 case animations::TransitionSubType::FADEFROMCOLOR: 1023 // FALLTHROUGH intended 1024 case animations::TransitionSubType::FADEOVERCOLOR: 1025 if (pLeavingSlide) { 1026 // only generate, if fade 1027 // effect really needs it. 1028 leavingSlide.reset( pLeavingSlide ); 1029 } 1030 break; 1031 1032 default: 1033 ENSURE_OR_THROW( false, 1034 "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" ); 1035 } 1036 1037 return NumberAnimationSharedPtr( 1038 new FadingSlideChange( 1039 leavingSlide, 1040 pEnteringSlide, 1041 comphelper::make_optional( 1042 rTransitionFadeColor), 1043 pSoundPlayer, 1044 rViewContainer, 1045 rScreenUpdater, 1046 rEventMultiplexer )); 1047 } 1048 } 1049 } 1050 break; 1051 } 1052 } 1053 1054 // No animation generated, maybe no table entry for given 1055 // transition? 1056 OSL_TRACE( 1057 "TransitionFactory::createSlideTransition(): " 1058 "Unknown type/subtype (%d/%d) combination encountered", 1059 nTransitionType, 1060 nTransitionSubType ); 1061 OSL_ENSURE( 1062 false, 1063 "TransitionFactory::createSlideTransition(): " 1064 "Unknown type/subtype combination encountered" ); 1065 1066 return NumberAnimationSharedPtr(); 1067 } 1068 1069 } // namespace internal 1070 } // namespace presentation 1071