fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / slideshow / source / engine / slide / slideimpl.cxx
blob07913937772066830ccc925f9b18c631134d98a0
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 <osl/diagnose.hxx>
22 #include <canvas/debug.hxx>
23 #include <tools/diagnose_ex.h>
24 #include <canvas/canvastools.hxx>
25 #include <cppcanvas/basegfxfactory.hxx>
27 #include <basegfx/matrix/b2dhommatrix.hxx>
28 #include <basegfx/point/b2dpoint.hxx>
29 #include <basegfx/polygon/b2dpolygon.hxx>
30 #include <basegfx/polygon/b2dpolygontools.hxx>
31 #include <basegfx/numeric/ftools.hxx>
33 #include <com/sun/star/awt/SystemPointer.hpp>
34 #include <com/sun/star/container/XIndexAccess.hpp>
35 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/container/XEnumerationAccess.hpp>
38 #include <com/sun/star/awt/Rectangle.hpp>
39 #include <com/sun/star/presentation/ParagraphTarget.hpp>
40 #include <com/sun/star/presentation/EffectNodeType.hpp>
41 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
42 #include <com/sun/star/drawing/TextAnimationKind.hpp>
44 #include <cppuhelper/exc_hlp.hxx>
45 #include <comphelper/anytostring.hxx>
47 #include "slide.hxx"
48 #include "slideshowcontext.hxx"
49 #include "slideanimations.hxx"
50 #include "doctreenode.hxx"
51 #include "screenupdater.hxx"
52 #include "cursormanager.hxx"
53 #include "shapeimporter.hxx"
54 #include "slideshowexceptions.hxx"
55 #include "eventqueue.hxx"
56 #include "activitiesqueue.hxx"
57 #include "layermanager.hxx"
58 #include "shapemanagerimpl.hxx"
59 #include "usereventqueue.hxx"
60 #include "userpaintoverlay.hxx"
61 #include "event.hxx"
62 #include "targetpropertiescreator.hxx"
63 #include "tools.hxx"
65 #include <o3tl/compat_functional.hxx>
67 #include <boost/bind.hpp>
68 #include <iterator>
69 #include <algorithm>
70 #include <functional>
71 #include <iostream>
73 using namespace ::com::sun::star;
77 namespace slideshow
79 namespace internal
81 namespace
84 class SlideImpl : public Slide,
85 public CursorManager,
86 public ViewEventHandler,
87 public ::osl::DebugBase<SlideImpl>
89 public:
90 SlideImpl( const uno::Reference<drawing::XDrawPage>& xDrawPage,
91 const uno::Reference<drawing::XDrawPagesSupplier>& xDrawPages,
92 const uno::Reference<animations::XAnimationNode>& xRootNode,
93 EventQueue& rEventQueue,
94 EventMultiplexer& rEventMultiplexer,
95 ScreenUpdater& rScreenUpdater,
96 ActivitiesQueue& rActivitiesQueue,
97 UserEventQueue& rUserEventQueue,
98 CursorManager& rCursorManager,
99 const UnoViewContainer& rViewContainer,
100 const uno::Reference<uno::XComponentContext>& xContext,
101 const ShapeEventListenerMap& rShapeListenerMap,
102 const ShapeCursorMap& rShapeCursorMap,
103 const PolyPolygonVector& rPolyPolygonVector,
104 RGBColor const& rUserPaintColor,
105 double dUserPaintStrokeWidth,
106 bool bUserPaintEnabled,
107 bool bIntrinsicAnimationsAllowed,
108 bool bDisableAnimationZOrder );
110 virtual ~SlideImpl();
113 // Slide interface
116 virtual bool prefetch() SAL_OVERRIDE;
117 virtual bool show( bool ) SAL_OVERRIDE;
118 virtual void hide() SAL_OVERRIDE;
120 virtual basegfx::B2ISize getSlideSize() const SAL_OVERRIDE;
121 virtual uno::Reference<drawing::XDrawPage > getXDrawPage() const SAL_OVERRIDE;
122 virtual uno::Reference<animations::XAnimationNode> getXAnimationNode() const SAL_OVERRIDE;
123 virtual PolyPolygonVector getPolygons() SAL_OVERRIDE;
124 virtual void drawPolygons() const SAL_OVERRIDE;
125 virtual bool isPaintOverlayActive() const SAL_OVERRIDE;
126 virtual void enablePaintOverlay() SAL_OVERRIDE;
127 virtual void disablePaintOverlay() SAL_OVERRIDE;
128 virtual void update_settings( bool bUserPaintEnabled, RGBColor const& aUserPaintColor, double dUserPaintStrokeWidth ) SAL_OVERRIDE;
131 // TODO(F2): Rework SlideBitmap to no longer be based on XBitmap,
132 // but on canvas-independent basegfx bitmaps
133 virtual SlideBitmapSharedPtr getCurrentSlideBitmap( const UnoViewSharedPtr& rView ) const SAL_OVERRIDE;
136 private:
137 // ViewEventHandler
138 virtual void viewAdded( const UnoViewSharedPtr& rView ) SAL_OVERRIDE;
139 virtual void viewRemoved( const UnoViewSharedPtr& rView ) SAL_OVERRIDE;
140 virtual void viewChanged( const UnoViewSharedPtr& rView ) SAL_OVERRIDE;
141 virtual void viewsChanged() SAL_OVERRIDE;
143 // CursorManager
144 virtual bool requestCursor( sal_Int16 nCursorShape ) SAL_OVERRIDE;
145 virtual void resetCursor() SAL_OVERRIDE;
147 void activatePaintOverlay();
148 void deactivatePaintOverlay();
150 /** Query whether the slide has animations at all
152 If the slide doesn't have animations, show() displays
153 only static content. If an event is registered with
154 registerSlideEndEvent(), this event will be
155 immediately activated at the end of the show() method.
157 @return true, if this slide has animations, false
158 otherwise
160 bool isAnimated();
162 /// Set all Shapes to their initial attributes for slideshow
163 bool applyInitialShapeAttributes( const ::com::sun::star::uno::Reference<
164 ::com::sun::star::animations::XAnimationNode >& xRootAnimationNode );
166 /// Renders current slide content to bitmap
167 SlideBitmapSharedPtr createCurrentSlideBitmap(
168 const UnoViewSharedPtr& rView,
169 ::basegfx::B2ISize const & rSlideSize ) const;
171 /// Prefetch all shapes (not the animations)
172 bool loadShapes();
174 /// Retrieve slide size from XDrawPage
175 basegfx::B2ISize getSlideSizeImpl() const;
177 /// Prefetch show, but don't call applyInitialShapeAttributes()
178 bool implPrefetchShow();
180 /// Query the rectangle covered by the slide
181 ::basegfx::B2DRectangle getSlideRect() const;
183 /// Start GIF and other intrinsic shape animations
184 void endIntrinsicAnimations();
186 /// End GIF and other intrinsic shape animations
187 void startIntrinsicAnimations();
189 /// Add Polygons to the member maPolygons
190 void addPolygons(const PolyPolygonVector& rPolygons);
192 // Types
193 // =====
195 enum SlideAnimationState
197 CONSTRUCTING_STATE=0,
198 INITIAL_STATE=1,
199 SHOWING_STATE=2,
200 FINAL_STATE=3,
201 SlideAnimationState_NUM_ENTRIES=4
204 typedef std::vector< SlideBitmapSharedPtr > VectorOfSlideBitmaps;
205 /** Vector of slide bitmaps.
207 Since the bitmap content is sensitive to animation
208 effects, we have an inner vector containing a distinct
209 bitmap for each of the SlideAnimationStates.
211 typedef ::std::vector< std::pair< UnoViewSharedPtr,
212 VectorOfSlideBitmaps > > VectorOfVectorOfSlideBitmaps;
215 // Member variables
216 // ================
218 /// The page model object
219 uno::Reference< drawing::XDrawPage > mxDrawPage;
220 uno::Reference< drawing::XDrawPagesSupplier > mxDrawPagesSupplier;
221 uno::Reference< animations::XAnimationNode > mxRootNode;
223 LayerManagerSharedPtr mpLayerManager;
224 boost::shared_ptr<ShapeManagerImpl> mpShapeManager;
225 boost::shared_ptr<SubsettableShapeManager> mpSubsettableShapeManager;
227 /// Contains common objects needed throughout the slideshow
228 SlideShowContext maContext;
230 /// parent cursor manager
231 CursorManager& mrCursorManager;
233 /// Handles the animation and event generation for us
234 SlideAnimations maAnimations;
235 PolyPolygonVector maPolygons;
237 RGBColor maUserPaintColor;
238 double mdUserPaintStrokeWidth;
239 UserPaintOverlaySharedPtr mpPaintOverlay;
241 /// Bitmaps with slide content at various states
242 mutable VectorOfVectorOfSlideBitmaps maSlideBitmaps;
244 SlideAnimationState meAnimationState;
246 const basegfx::B2ISize maSlideSize;
248 sal_Int16 mnCurrentCursor;
250 /// True, when intrinsic shape animations are allowed
251 bool mbIntrinsicAnimationsAllowed;
253 /// True, when user paint overlay is enabled
254 bool mbUserPaintOverlayEnabled;
256 /// True, if initial load of all page shapes succeeded
257 bool mbShapesLoaded;
259 /// True, if initial load of all animation info succeeded
260 bool mbShowLoaded;
262 /** True, if this slide is not static.
264 If this slide has animated content, this variable will
265 be true, and false otherwise.
267 bool mbHaveAnimations;
269 /** True, if this slide has a main animation sequence.
271 If this slide has animation content, which in turn has
272 a main animation sequence (which must be fully run
273 before EventMultiplexer::notifySlideAnimationsEnd() is
274 called), this member is true.
276 bool mbMainSequenceFound;
278 /// When true, show() was called. Slide hidden oherwise.
279 bool mbActive;
281 ///When true, enablePaintOverlay was called and mbUserPaintOverlay = true
282 bool mbPaintOverlayActive;
289 class SlideRenderer
291 public:
292 explicit SlideRenderer( SlideImpl& rSlide ) :
293 mrSlide( rSlide )
297 void operator()( const UnoViewSharedPtr& rView )
299 // fully clear view content to background color
300 rView->clearAll();
302 SlideBitmapSharedPtr pBitmap( mrSlide.getCurrentSlideBitmap( rView ) );
303 ::cppcanvas::CanvasSharedPtr pCanvas( rView->getCanvas() );
305 const ::basegfx::B2DHomMatrix aViewTransform( rView->getTransformation() );
306 const ::basegfx::B2DPoint aOutPosPixel( aViewTransform * ::basegfx::B2DPoint() );
308 // setup a canvas with device coordinate space, the slide
309 // bitmap already has the correct dimension.
310 ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( pCanvas->clone() );
311 pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
313 // render at given output position
314 pBitmap->move( aOutPosPixel );
316 // clear clip (might have been changed, e.g. from comb
317 // transition)
318 pBitmap->clip( ::basegfx::B2DPolyPolygon() );
319 pBitmap->draw( pDevicePixelCanvas );
322 private:
323 SlideImpl& mrSlide;
330 SlideImpl::SlideImpl( const uno::Reference< drawing::XDrawPage >& xDrawPage,
331 const uno::Reference<drawing::XDrawPagesSupplier>& xDrawPages,
332 const uno::Reference< animations::XAnimationNode >& xRootNode,
333 EventQueue& rEventQueue,
334 EventMultiplexer& rEventMultiplexer,
335 ScreenUpdater& rScreenUpdater,
336 ActivitiesQueue& rActivitiesQueue,
337 UserEventQueue& rUserEventQueue,
338 CursorManager& rCursorManager,
339 const UnoViewContainer& rViewContainer,
340 const uno::Reference< uno::XComponentContext >& xComponentContext,
341 const ShapeEventListenerMap& rShapeListenerMap,
342 const ShapeCursorMap& rShapeCursorMap,
343 const PolyPolygonVector& rPolyPolygonVector,
344 RGBColor const& aUserPaintColor,
345 double dUserPaintStrokeWidth,
346 bool bUserPaintEnabled,
347 bool bIntrinsicAnimationsAllowed,
348 bool bDisableAnimationZOrder ) :
349 mxDrawPage( xDrawPage ),
350 mxDrawPagesSupplier( xDrawPages ),
351 mxRootNode( xRootNode ),
352 mpLayerManager( new LayerManager(
353 rViewContainer,
354 getSlideRect(),
355 bDisableAnimationZOrder) ),
356 mpShapeManager( new ShapeManagerImpl(
357 rEventMultiplexer,
358 mpLayerManager,
359 rCursorManager,
360 rShapeListenerMap,
361 rShapeCursorMap)),
362 mpSubsettableShapeManager( mpShapeManager ),
363 maContext( mpSubsettableShapeManager,
364 rEventQueue,
365 rEventMultiplexer,
366 rScreenUpdater,
367 rActivitiesQueue,
368 rUserEventQueue,
369 *this,
370 rViewContainer,
371 xComponentContext ),
372 mrCursorManager( rCursorManager ),
373 maAnimations( maContext,
374 basegfx::B2DSize( getSlideSizeImpl() ) ),
375 maPolygons(rPolyPolygonVector),
376 maUserPaintColor(aUserPaintColor),
377 mdUserPaintStrokeWidth(dUserPaintStrokeWidth),
378 mpPaintOverlay(),
379 maSlideBitmaps(),
380 meAnimationState( CONSTRUCTING_STATE ),
381 maSlideSize(getSlideSizeImpl()),
382 mnCurrentCursor( awt::SystemPointer::ARROW ),
383 mbIntrinsicAnimationsAllowed( bIntrinsicAnimationsAllowed ),
384 mbUserPaintOverlayEnabled(bUserPaintEnabled),
385 mbShapesLoaded( false ),
386 mbShowLoaded( false ),
387 mbHaveAnimations( false ),
388 mbMainSequenceFound( false ),
389 mbActive( false ),
390 mbPaintOverlayActive( false )
392 // clone already existing views for slide bitmaps
393 std::for_each( rViewContainer.begin(),
394 rViewContainer.end(),
395 boost::bind( &SlideImpl::viewAdded,
396 this,
397 _1 ));
399 // register screen update (LayerManager needs to signal pending
400 // updates)
401 maContext.mrScreenUpdater.addViewUpdate(mpShapeManager);
404 void SlideImpl::update_settings( bool bUserPaintEnabled, RGBColor const& aUserPaintColor, double dUserPaintStrokeWidth )
406 maUserPaintColor = aUserPaintColor;
407 mdUserPaintStrokeWidth = dUserPaintStrokeWidth;
408 mbUserPaintOverlayEnabled = bUserPaintEnabled;
411 SlideImpl::~SlideImpl()
413 if( mpShapeManager )
415 maContext.mrScreenUpdater.removeViewUpdate(mpShapeManager);
416 mpShapeManager->dispose();
418 // TODO(Q3): Make sure LayerManager (and thus Shapes) dies
419 // first, because SlideShowContext has SubsettableShapeManager
420 // as reference member.
421 mpLayerManager.reset();
425 bool SlideImpl::prefetch()
427 if( !mxRootNode.is() )
428 return false;
430 return applyInitialShapeAttributes(mxRootNode);
433 bool SlideImpl::show( bool bSlideBackgoundPainted )
437 if( mbActive )
438 return true; // already active
440 if( !mpShapeManager || !mpLayerManager )
441 return false; // disposed
445 // set initial shape attributes (e.g. hide shapes that have
446 // 'appear' effect set)
447 if( !applyInitialShapeAttributes(mxRootNode) )
448 return false;
452 // activate and take over view - clears view, if necessary
453 mbActive = true;
454 requestCursor( mnCurrentCursor );
456 // enable shape management & event broadcasting for shapes of this
457 // slide. Also enables LayerManager to record updates. Currently,
458 // never let LayerManager render initial slide content, use
459 // buffered slide bitmaps instead.
460 mpShapeManager->activate( true );
464 // render slide to screen, if requested
465 if( !bSlideBackgoundPainted )
467 std::for_each(maContext.mrViewContainer.begin(),
468 maContext.mrViewContainer.end(),
469 boost::mem_fn(&View::clearAll));
471 std::for_each( maContext.mrViewContainer.begin(),
472 maContext.mrViewContainer.end(),
473 SlideRenderer(*this) );
474 maContext.mrScreenUpdater.notifyUpdate();
479 // fire up animations
480 const bool bIsAnimated( isAnimated() );
481 if( bIsAnimated )
482 maAnimations.start(); // feeds initial events into queue
484 // NOTE: this looks slightly weird, but is indeed correct:
485 // as isAnimated() might return false, _although_ there is
486 // a main sequence (because the animation nodes don't
487 // contain any executable effects), we gotta check both
488 // conditions here.
489 if( !bIsAnimated || !mbMainSequenceFound )
491 // manually trigger a slide animation end event (we don't have
492 // animations at all, or we don't have a main animation
493 // sequence, but if we had, it'd end now). Note that having
494 // animations alone does not matter here, as only main
495 // sequence animations prevents showing the next slide on
496 // nextEvent().
497 maContext.mrEventMultiplexer.notifySlideAnimationsEnd();
500 // enable shape-intrinsic animations (drawing layer animations or
501 // GIF animations)
502 if( mbIntrinsicAnimationsAllowed )
503 startIntrinsicAnimations();
507 // enable paint overlay, if maUserPaintColor is valid
508 activatePaintOverlay();
512 // from now on, animations might be showing
513 meAnimationState = SHOWING_STATE;
515 return true;
518 void SlideImpl::hide()
520 if( !mbActive || !mpShapeManager )
521 return; // already hidden/disposed
525 // from now on, all animations are stopped
526 meAnimationState = FINAL_STATE;
530 // disable user paint overlay under all circumstances,
531 // this slide now ceases to be active.
532 deactivatePaintOverlay();
536 // switch off all shape-intrinsic animations.
537 endIntrinsicAnimations();
539 // force-end all SMIL animations, too
540 maAnimations.end();
544 // disable shape management & event broadcasting for shapes of this
545 // slide. Also disables LayerManager.
546 mpShapeManager->deactivate();
548 // vanish from view
549 resetCursor();
550 mbActive = false;
555 basegfx::B2ISize SlideImpl::getSlideSize() const
557 return maSlideSize;
560 uno::Reference<drawing::XDrawPage > SlideImpl::getXDrawPage() const
562 return mxDrawPage;
565 uno::Reference<animations::XAnimationNode> SlideImpl::getXAnimationNode() const
567 return mxRootNode;
570 PolyPolygonVector SlideImpl::getPolygons()
572 if(mbPaintOverlayActive)
573 maPolygons = mpPaintOverlay->getPolygons();
574 return maPolygons;
577 SlideBitmapSharedPtr SlideImpl::getCurrentSlideBitmap( const UnoViewSharedPtr& rView ) const
579 // search corresponding entry in maSlideBitmaps (which
580 // contains the views as the key)
581 VectorOfVectorOfSlideBitmaps::iterator aIter;
582 const VectorOfVectorOfSlideBitmaps::iterator aEnd( maSlideBitmaps.end() );
583 if( (aIter=std::find_if( maSlideBitmaps.begin(),
584 aEnd,
585 boost::bind(
586 std::equal_to<UnoViewSharedPtr>(),
587 rView,
588 // select view:
589 boost::bind(
590 o3tl::select1st<VectorOfVectorOfSlideBitmaps::value_type>(),
591 _1 )))) == aEnd )
593 // corresponding view not found - maybe view was not
594 // added to Slide?
595 ENSURE_OR_THROW( false,
596 "SlideImpl::getInitialSlideBitmap(): view does not "
597 "match any of the added ones" );
600 // ensure that the show is loaded
601 if( !mbShowLoaded )
603 // only prefetch and init shapes when not done already
604 // (otherwise, at least applyInitialShapeAttributes() will be
605 // called twice for initial slide rendering). Furthermore,
606 // applyInitialShapeAttributes() _always_ performs
607 // initializations, which would be highly unwanted during a
608 // running show. OTOH, a slide whose mbShowLoaded is false is
609 // guaranteed not be running a show.
611 // set initial shape attributes (e.g. hide 'appear' effect
612 // shapes)
613 if( !const_cast<SlideImpl*>(this)->applyInitialShapeAttributes( mxRootNode ) )
614 ENSURE_OR_THROW(false,
615 "SlideImpl::getCurrentSlideBitmap(): Cannot "
616 "apply initial attributes");
619 SlideBitmapSharedPtr& rBitmap( aIter->second.at( meAnimationState ));
620 const ::basegfx::B2ISize& rSlideSize(
621 getSlideSizePixel( ::basegfx::B2DSize( getSlideSize() ),
622 rView ));
624 // is the bitmap valid (actually existent, and of correct
625 // size)?
626 if( !rBitmap || rBitmap->getSize() != rSlideSize )
628 // no bitmap there yet, or wrong size - create one
629 rBitmap = createCurrentSlideBitmap(rView, rSlideSize);
632 return rBitmap;
636 // private methods
640 void SlideImpl::viewAdded( const UnoViewSharedPtr& rView )
642 maSlideBitmaps.push_back(
643 std::make_pair( rView,
644 VectorOfSlideBitmaps(SlideAnimationState_NUM_ENTRIES) ));
646 if( mpLayerManager )
647 mpLayerManager->viewAdded( rView );
650 void SlideImpl::viewRemoved( const UnoViewSharedPtr& rView )
652 if( mpLayerManager )
653 mpLayerManager->viewRemoved( rView );
655 const VectorOfVectorOfSlideBitmaps::iterator aEnd( maSlideBitmaps.end() );
656 maSlideBitmaps.erase(
657 std::remove_if( maSlideBitmaps.begin(),
658 aEnd,
659 boost::bind(
660 std::equal_to<UnoViewSharedPtr>(),
661 rView,
662 // select view:
663 boost::bind(
664 o3tl::select1st<VectorOfVectorOfSlideBitmaps::value_type>(),
665 _1 ))),
666 aEnd );
669 void SlideImpl::viewChanged( const UnoViewSharedPtr& rView )
671 // nothing to do for the Slide - getCurrentSlideBitmap() lazily
672 // handles bitmap resizes
673 if( mbActive && mpLayerManager )
674 mpLayerManager->viewChanged(rView);
677 void SlideImpl::viewsChanged()
679 // nothing to do for the Slide - getCurrentSlideBitmap() lazily
680 // handles bitmap resizes
681 if( mbActive && mpLayerManager )
682 mpLayerManager->viewsChanged();
685 bool SlideImpl::requestCursor( sal_Int16 nCursorShape )
687 mnCurrentCursor = nCursorShape;
688 return mrCursorManager.requestCursor(mnCurrentCursor);
691 void SlideImpl::resetCursor()
693 mnCurrentCursor = awt::SystemPointer::ARROW;
694 mrCursorManager.resetCursor();
697 bool SlideImpl::isAnimated()
699 // prefetch, but don't apply initial shape attributes
700 if( !implPrefetchShow() )
701 return false;
703 return mbHaveAnimations && maAnimations.isAnimated();
706 SlideBitmapSharedPtr SlideImpl::createCurrentSlideBitmap( const UnoViewSharedPtr& rView,
707 const ::basegfx::B2ISize& rBmpSize ) const
709 ENSURE_OR_THROW( rView && rView->getCanvas(),
710 "SlideImpl::createCurrentSlideBitmap(): Invalid view" );
711 ENSURE_OR_THROW( mpLayerManager,
712 "SlideImpl::createCurrentSlideBitmap(): Invalid layer manager" );
713 ENSURE_OR_THROW( mbShowLoaded,
714 "SlideImpl::createCurrentSlideBitmap(): No show loaded" );
716 ::cppcanvas::CanvasSharedPtr pCanvas( rView->getCanvas() );
718 // create a bitmap of appropriate size
719 ::cppcanvas::BitmapSharedPtr pBitmap(
720 ::cppcanvas::BaseGfxFactory::createBitmap(
721 pCanvas,
722 rBmpSize ) );
724 ENSURE_OR_THROW( pBitmap,
725 "SlideImpl::createCurrentSlideBitmap(): Cannot create page bitmap" );
727 ::cppcanvas::BitmapCanvasSharedPtr pBitmapCanvas( pBitmap->getBitmapCanvas() );
729 ENSURE_OR_THROW( pBitmapCanvas,
730 "SlideImpl::createCurrentSlideBitmap(): Cannot create page bitmap canvas" );
732 // apply linear part of destination canvas transformation (linear means in this context:
733 // transformation without any translational components)
734 ::basegfx::B2DHomMatrix aLinearTransform( rView->getTransformation() );
735 aLinearTransform.set( 0, 2, 0.0 );
736 aLinearTransform.set( 1, 2, 0.0 );
737 pBitmapCanvas->setTransformation( aLinearTransform );
739 // output all shapes to bitmap
740 initSlideBackground( pBitmapCanvas, rBmpSize );
741 mpLayerManager->renderTo( pBitmapCanvas );
743 return SlideBitmapSharedPtr( new SlideBitmap( pBitmap ) );
746 namespace
748 class MainSequenceSearcher
750 public:
751 MainSequenceSearcher()
753 maSearchKey.Name = "node-type";
754 maSearchKey.Value <<= presentation::EffectNodeType::MAIN_SEQUENCE;
757 void operator()( const uno::Reference< animations::XAnimationNode >& xChildNode )
759 uno::Sequence< beans::NamedValue > aUserData( xChildNode->getUserData() );
761 if( findNamedValue( aUserData, maSearchKey ) )
763 maMainSequence = xChildNode;
767 uno::Reference< animations::XAnimationNode > getMainSequence() const
769 return maMainSequence;
772 private:
773 beans::NamedValue maSearchKey;
774 uno::Reference< animations::XAnimationNode > maMainSequence;
778 bool SlideImpl::implPrefetchShow()
780 if( mbShowLoaded )
781 return true;
783 ENSURE_OR_RETURN_FALSE( mxDrawPage.is(),
784 "SlideImpl::implPrefetchShow(): Invalid draw page" );
785 ENSURE_OR_RETURN_FALSE( mpLayerManager,
786 "SlideImpl::implPrefetchShow(): Invalid layer manager" );
788 // fetch desired page content
789 // ==========================
791 if( !loadShapes() )
792 return false;
794 // New animations framework: import the shape effect info
795 // ======================================================
799 if( mxRootNode.is() )
801 if( !maAnimations.importAnimations( mxRootNode ) )
803 OSL_FAIL( "SlideImpl::implPrefetchShow(): have animation nodes, "
804 "but import animations failed." );
806 // could not import animation framework,
807 // _although_ some animation nodes are there -
808 // this is an error (not finding animations at
809 // all is okay - might be a static slide)
810 return false;
813 // now check whether we've got a main sequence (if
814 // not, we must manually call
815 // EventMultiplexer::notifySlideAnimationsEnd()
816 // above, as e.g. interactive sequences alone
817 // don't block nextEvent() from issuing the next
818 // slide)
819 MainSequenceSearcher aSearcher;
820 if( for_each_childNode( mxRootNode, aSearcher ) )
821 mbMainSequenceFound = aSearcher.getMainSequence().is();
823 // import successfully done
824 mbHaveAnimations = true;
827 catch( uno::RuntimeException& )
829 throw;
831 catch( uno::Exception& )
833 OSL_FAIL(
834 OUStringToOString(
835 comphelper::anyToString(cppu::getCaughtException()),
836 RTL_TEXTENCODING_UTF8).getStr() );
837 // TODO(E2): Error handling. For now, bail out
840 mbShowLoaded = true;
842 return true;
845 void SlideImpl::enablePaintOverlay()
847 if( !mbUserPaintOverlayEnabled || !mbPaintOverlayActive )
849 mbUserPaintOverlayEnabled = true;
850 activatePaintOverlay();
854 void SlideImpl::disablePaintOverlay()
858 void SlideImpl::activatePaintOverlay()
860 if( mbUserPaintOverlayEnabled || !maPolygons.empty() )
862 mpPaintOverlay = UserPaintOverlay::create( maUserPaintColor,
863 mdUserPaintStrokeWidth,
864 maContext,
865 maPolygons,
866 mbUserPaintOverlayEnabled );
867 mbPaintOverlayActive = true;
871 void SlideImpl::drawPolygons() const
873 if( mpPaintOverlay )
874 mpPaintOverlay->drawPolygons();
877 void SlideImpl::addPolygons(const PolyPolygonVector& rPolygons)
879 if(!rPolygons.empty())
881 for( PolyPolygonVector::const_iterator aIter = rPolygons.begin(),
882 aEnd = rPolygons.end();
883 aIter!=aEnd;
884 ++aIter )
886 maPolygons.push_back(*aIter);
891 bool SlideImpl::isPaintOverlayActive() const
893 return mbPaintOverlayActive;
896 void SlideImpl::deactivatePaintOverlay()
898 if(mbPaintOverlayActive)
899 maPolygons = mpPaintOverlay->getPolygons();
901 mpPaintOverlay.reset();
902 mbPaintOverlayActive = false;
905 ::basegfx::B2DRectangle SlideImpl::getSlideRect() const
907 const basegfx::B2ISize slideSize( getSlideSizeImpl() );
908 return ::basegfx::B2DRectangle(0.0,0.0,
909 slideSize.getX(),
910 slideSize.getY());
913 void SlideImpl::endIntrinsicAnimations()
915 mpSubsettableShapeManager->notifyIntrinsicAnimationsDisabled();
918 void SlideImpl::startIntrinsicAnimations()
920 mpSubsettableShapeManager->notifyIntrinsicAnimationsEnabled();
923 bool SlideImpl::applyInitialShapeAttributes(
924 const uno::Reference< animations::XAnimationNode >& xRootAnimationNode )
926 if( !implPrefetchShow() )
927 return false;
929 if( !xRootAnimationNode.is() )
931 meAnimationState = INITIAL_STATE;
933 return true; // no animations - no attributes to apply -
934 // succeeded
937 uno::Sequence< animations::TargetProperties > aProps(
938 TargetPropertiesCreator::createInitialTargetProperties( xRootAnimationNode ) );
940 // apply extracted values to our shapes
941 const ::std::size_t nSize( aProps.getLength() );
942 for( ::std::size_t i=0; i<nSize; ++i )
944 sal_Int16 nParaIndex( -1 );
945 uno::Reference< drawing::XShape > xShape( aProps[i].Target,
946 uno::UNO_QUERY );
948 if( !xShape.is() )
950 // not a shape target. Maybe a ParagraphTarget?
951 presentation::ParagraphTarget aParaTarget;
953 if( (aProps[i].Target >>= aParaTarget) )
955 // yep, ParagraphTarget found - extract shape
956 // and index
957 xShape = aParaTarget.Shape;
958 nParaIndex = aParaTarget.Paragraph;
962 if( xShape.is() )
964 ShapeSharedPtr pShape( mpLayerManager->lookupShape( xShape ) );
966 if( !pShape )
968 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): no shape found for given target" );
969 continue;
972 AttributableShapeSharedPtr pAttrShape(
973 ::boost::dynamic_pointer_cast< AttributableShape >( pShape ) );
975 if( !pAttrShape )
977 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): shape found does not "
978 "implement AttributableShape interface" );
979 continue;
982 if( nParaIndex != -1 )
984 // our target is a paragraph subset, thus look
985 // this up first.
986 const DocTreeNodeSupplier& rNodeSupplier( pAttrShape->getTreeNodeSupplier() );
988 if( rNodeSupplier.getNumberOfTreeNodes(
989 DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ) <= nParaIndex )
991 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): shape found does not "
992 "provide a subset for requested paragraph index" );
993 continue;
996 pAttrShape = pAttrShape->getSubset(
997 rNodeSupplier.getTreeNode(
998 nParaIndex,
999 DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH ) );
1001 if( !pAttrShape )
1003 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): shape found does not "
1004 "provide a subset for requested paragraph index" );
1005 continue;
1009 const uno::Sequence< beans::NamedValue >& rShapeProps( aProps[i].Properties );
1010 const ::std::size_t nShapePropSize( rShapeProps.getLength() );
1011 for( ::std::size_t j=0; j<nShapePropSize; ++j )
1013 bool bVisible=false;
1014 if( rShapeProps[j].Name.equalsIgnoreAsciiCase("visibility") &&
1015 extractValue( bVisible,
1016 rShapeProps[j].Value,
1017 pShape,
1018 ::basegfx::B2DSize( getSlideSize() ) ))
1020 pAttrShape->setVisibility( bVisible );
1022 else
1024 OSL_FAIL( "SlideImpl::applyInitialShapeAttributes(): Unexpected "
1025 "(and unimplemented) property encountered" );
1031 meAnimationState = INITIAL_STATE;
1033 return true;
1036 bool SlideImpl::loadShapes()
1038 if( mbShapesLoaded )
1039 return true;
1041 ENSURE_OR_RETURN_FALSE( mxDrawPage.is(),
1042 "SlideImpl::loadShapes(): Invalid draw page" );
1043 ENSURE_OR_RETURN_FALSE( mpLayerManager,
1044 "SlideImpl::loadShapes(): Invalid layer manager" );
1046 // fetch desired page content
1047 // ==========================
1049 // also take master page content
1050 uno::Reference< drawing::XDrawPage > xMasterPage;
1051 uno::Reference< drawing::XShapes > xMasterPageShapes;
1052 sal_Int32 nCurrCount(0);
1054 uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( mxDrawPage,
1055 uno::UNO_QUERY );
1056 if( xMasterPageTarget.is() )
1058 xMasterPage = xMasterPageTarget->getMasterPage();
1059 xMasterPageShapes.set( xMasterPage,
1060 uno::UNO_QUERY );
1062 if( xMasterPage.is() && xMasterPageShapes.is() )
1064 // TODO(P2): maybe cache master pages here (or treat the
1065 // masterpage as a single metafile. At least currently,
1066 // masterpages do not contain animation effects)
1069 // load the masterpage shapes
1071 ShapeImporter aMPShapesFunctor( xMasterPage,
1072 mxDrawPage,
1073 mxDrawPagesSupplier,
1074 maContext,
1075 0, /* shape num starts at 0 */
1076 true );
1078 mpLayerManager->addShape(
1079 aMPShapesFunctor.importBackgroundShape() );
1081 while( !aMPShapesFunctor.isImportDone() )
1083 ShapeSharedPtr const& rShape(
1084 aMPShapesFunctor.importShape() );
1085 if( rShape )
1086 mpLayerManager->addShape( rShape );
1088 addPolygons(aMPShapesFunctor.getPolygons());
1090 nCurrCount = static_cast<sal_Int32>(aMPShapesFunctor.getImportedShapesCount());
1092 catch( uno::RuntimeException& )
1094 throw;
1096 catch( ShapeLoadFailedException& )
1098 // TODO(E2): Error handling. For now, bail out
1099 OSL_FAIL( "SlideImpl::loadShapes(): caught ShapeLoadFailedException" );
1100 return false;
1103 catch( uno::Exception& )
1105 OSL_FAIL( OUStringToOString(
1106 comphelper::anyToString( cppu::getCaughtException() ),
1107 RTL_TEXTENCODING_UTF8 ).getStr() );
1109 return false;
1116 // load the normal page shapes
1119 ShapeImporter aShapesFunctor( mxDrawPage,
1120 mxDrawPage,
1121 mxDrawPagesSupplier,
1122 maContext,
1123 nCurrCount,
1124 false );
1126 while( !aShapesFunctor.isImportDone() )
1128 ShapeSharedPtr const& rShape(
1129 aShapesFunctor.importShape() );
1130 if( rShape )
1131 mpLayerManager->addShape( rShape );
1133 addPolygons(aShapesFunctor.getPolygons());
1135 catch( uno::RuntimeException& )
1137 throw;
1139 catch( ShapeLoadFailedException& )
1141 // TODO(E2): Error handling. For now, bail out
1142 OSL_FAIL( "SlideImpl::loadShapes(): caught ShapeLoadFailedException" );
1143 return false;
1145 catch( uno::Exception& )
1147 OSL_FAIL( OUStringToOString(
1148 comphelper::anyToString( cppu::getCaughtException() ),
1149 RTL_TEXTENCODING_UTF8 ).getStr() );
1151 return false;
1154 mbShapesLoaded = true;
1156 return true;
1159 basegfx::B2ISize SlideImpl::getSlideSizeImpl() const
1161 uno::Reference< beans::XPropertySet > xPropSet(
1162 mxDrawPage, uno::UNO_QUERY_THROW );
1164 sal_Int32 nDocWidth = 0;
1165 sal_Int32 nDocHeight = 0;
1166 xPropSet->getPropertyValue("Width") >>= nDocWidth;
1167 xPropSet->getPropertyValue("Height") >>= nDocHeight;
1169 return basegfx::B2ISize( nDocWidth, nDocHeight );
1172 } // namespace
1175 SlideSharedPtr createSlide( const uno::Reference< drawing::XDrawPage >& xDrawPage,
1176 const uno::Reference<drawing::XDrawPagesSupplier>& xDrawPages,
1177 const uno::Reference< animations::XAnimationNode >& xRootNode,
1178 EventQueue& rEventQueue,
1179 EventMultiplexer& rEventMultiplexer,
1180 ScreenUpdater& rScreenUpdater,
1181 ActivitiesQueue& rActivitiesQueue,
1182 UserEventQueue& rUserEventQueue,
1183 CursorManager& rCursorManager,
1184 const UnoViewContainer& rViewContainer,
1185 const uno::Reference< uno::XComponentContext >& xComponentContext,
1186 const ShapeEventListenerMap& rShapeListenerMap,
1187 const ShapeCursorMap& rShapeCursorMap,
1188 const PolyPolygonVector& rPolyPolygonVector,
1189 RGBColor const& rUserPaintColor,
1190 double dUserPaintStrokeWidth,
1191 bool bUserPaintEnabled,
1192 bool bIntrinsicAnimationsAllowed,
1193 bool bDisableAnimationZOrder )
1195 boost::shared_ptr<SlideImpl> pRet( new SlideImpl( xDrawPage, xDrawPages, xRootNode, rEventQueue,
1196 rEventMultiplexer, rScreenUpdater,
1197 rActivitiesQueue, rUserEventQueue,
1198 rCursorManager, rViewContainer,
1199 xComponentContext, rShapeListenerMap,
1200 rShapeCursorMap, rPolyPolygonVector, rUserPaintColor,
1201 dUserPaintStrokeWidth, bUserPaintEnabled,
1202 bIntrinsicAnimationsAllowed,
1203 bDisableAnimationZOrder ));
1205 rEventMultiplexer.addViewHandler( pRet );
1207 return pRet;
1210 } // namespace internal
1211 } // namespace slideshow
1213 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */