LibreOffice Module slideshow (master) 1
combtransition.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
25
26#include "combtransition.hxx"
27
28namespace slideshow::internal {
29
30namespace {
31
32basegfx::B2DPolyPolygon createClipPolygon(
33 const ::basegfx::B2DVector& rDirection,
34 const ::basegfx::B2DSize& rSlideSize,
35 int nNumStrips, int nOffset )
36{
37 // create clip polygon in standard orientation (will later
38 // be rotated to match direction vector)
40
41 // create nNumStrips/2 vertical strips
42 for( int i=nOffset; i<nNumStrips; i+=2 )
43 {
44 aClipPoly.append(
45 ::basegfx::utils::createPolygonFromRect(
46 ::basegfx::B2DRectangle( double(i)/nNumStrips, 0.0,
47 double(i+1)/nNumStrips, 1.0) ) );
48
49 }
50
51 // rotate polygons, such that the strips are parallel to
52 // the given direction vector
53 const ::basegfx::B2DVector aUpVec(0.0, 1.0);
54 basegfx::B2DHomMatrix aMatrix(basegfx::utils::createRotateAroundPoint(0.5, 0.5, aUpVec.angle( rDirection )));
55
56 // blow up clip polygon to slide size
57 aMatrix.scale(rSlideSize.getWidth(), rSlideSize.getHeight());
58
59 aClipPoly.transform( aMatrix );
60
61 return aClipPoly;
62}
63
64}
65
67 std::optional<SlideSharedPtr> const & leavingSlide,
68 const SlideSharedPtr& pEnteringSlide,
69 const SoundPlayerSharedPtr& pSoundPlayer,
70 const UnoViewContainer& rViewContainer,
71 ScreenUpdater& rScreenUpdater,
72 EventMultiplexer& rEventMultiplexer,
73 const ::basegfx::B2DVector& rPushDirection,
74 sal_Int32 nNumStripes )
75 : SlideChangeBase( leavingSlide, pEnteringSlide, pSoundPlayer,
76 rViewContainer, rScreenUpdater, rEventMultiplexer,
77 false /* no leaving sprite */,
78 false /* no entering sprite */ ),
79 maPushDirectionUnit( rPushDirection ),
80 mnNumStripes( nNumStripes )
81{
82}
83
85 const ViewEntry& rViewEntry ) const
86{
87 const SlideBitmapSharedPtr& pEnteringBitmap = getEnteringBitmap(rViewEntry);
88 const cppcanvas::CanvasSharedPtr pCanvas_ = rViewEntry.mpView->getCanvas();
89
90 if( !pEnteringBitmap || !pCanvas_ )
91 return;
92
93 // calc bitmap offsets. The enter/leaving bitmaps are only
94 // as large as the actual slides. For scaled-down
95 // presentations, we have to move the left, top edge of
96 // those bitmaps to the actual position, governed by the
97 // given view transform. The aBitmapPosPixel local
98 // variable is already in device coordinate space
99 // (i.e. pixel).
100
101 // TODO(F2): Properly respect clip here. Might have to be transformed, too.
102 const basegfx::B2DHomMatrix viewTransform( rViewEntry.mpView->getTransformation() );
103 const basegfx::B2DPoint pageOrigin( viewTransform * basegfx::B2DPoint() );
104
105 // change transformation on cloned canvas to be in
106 // device pixel
107 cppcanvas::CanvasSharedPtr pCanvas( pCanvas_->clone() );
109
110 // TODO(Q2): Use basegfx bitmaps here
111 // TODO(F1): SlideBitmap is not fully portable between different canvases!
112
113 auto aSlideSizePixel = getEnteringSlideSizePixel(rViewEntry.mpView);
114 const basegfx::B2DVector enteringSizePixel(aSlideSizePixel.getWidth(), aSlideSizePixel.getHeight());
115
116 const basegfx::B2DVector aPushDirection(
117 enteringSizePixel * maPushDirectionUnit );
118 const basegfx::B2DPolyPolygon aClipPolygon1 =
119 createClipPolygon( maPushDirectionUnit,
120 basegfx::B2DSize(enteringSizePixel.getX(), enteringSizePixel.getY()),
121 mnNumStripes, 0 );
122 const basegfx::B2DPolyPolygon aClipPolygon2 =
123 createClipPolygon( maPushDirectionUnit,
124 basegfx::B2DSize(enteringSizePixel.getX(), enteringSizePixel.getY()),
125 mnNumStripes, 1 );
126
127 SlideBitmapSharedPtr const & pLeavingBitmap = getLeavingBitmap(rViewEntry);
128 if( pLeavingBitmap )
129 {
130 // render odd strips:
131 pLeavingBitmap->clip( aClipPolygon1 );
132 // don't modify bitmap object (no move!):
133 p = basegfx::B2DPoint( pageOrigin + (t * aPushDirection) );
134 pCanvas->setTransformation(basegfx::utils::createTranslateB2DHomMatrix(p.getX(), p.getY()));
135 pLeavingBitmap->draw( pCanvas );
136
137 // render even strips:
138 pLeavingBitmap->clip( aClipPolygon2 );
139 // don't modify bitmap object (no move!):
140 p = basegfx::B2DPoint( pageOrigin - (t * aPushDirection) );
141 pCanvas->setTransformation(basegfx::utils::createTranslateB2DHomMatrix(p.getX(), p.getY()));
142 pLeavingBitmap->draw( pCanvas );
143 }
144
145 // TODO(Q2): Use basegfx bitmaps here
146 // TODO(F1): SlideBitmap is not fully portable between different canvases!
147
148 // render odd strips:
149 pEnteringBitmap->clip( aClipPolygon1 );
150 // don't modify bitmap object (no move!):
151 p = basegfx::B2DPoint( pageOrigin + ((t - 1.0) * aPushDirection) );
152 pCanvas->setTransformation(basegfx::utils::createTranslateB2DHomMatrix(p.getX(), p.getY()));
153 pEnteringBitmap->draw( pCanvas );
154
155 // render even strips:
156 pEnteringBitmap->clip( aClipPolygon2 );
157 // don't modify bitmap object (no move!):
158 p = basegfx::B2DPoint( pageOrigin + ((1.0 - t) * aPushDirection) );
159 pCanvas->setTransformation(basegfx::utils::createTranslateB2DHomMatrix(p.getX(), p.getY()));
160 pEnteringBitmap->draw( pCanvas );
161}
162
164{
165 std::for_each( beginViews(),
166 endViews(),
167 [this, &t]( const ViewEntry& rViewEntry )
168 { return this->renderComb( t, rViewEntry ); } );
169
171
172 return true;
173}
174
175} // namespace slideshow::internal
176
177/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
void transform(const basegfx::B2DHomMatrix &rMatrix)
TYPE getX() const
TYPE getY() const
CombTransition(::std::optional< SlideSharedPtr > const &leavingSlide, const SlideSharedPtr &pEnteringSlide, const SoundPlayerSharedPtr &pSoundPlayer, const UnoViewContainer &rViewContainer, ScreenUpdater &rScreenUpdater, EventMultiplexer &rEventMultiplexer, const ::basegfx::B2DVector &rPushDirection, sal_Int32 nNumStripes)
Create the comb transition effect.
virtual bool operator()(double x) override
Set the animation to value x.
const ::basegfx::B2DVector maPushDirectionUnit
void renderComb(double t, const ViewEntry &rViewEntry) const
This class multiplexes user-activated and slide-show global events.
void notifyUpdate()
Notify screen update.
Base class for all slide change effects.
ViewsVecT::const_iterator endViews()
::basegfx::B2ISize getEnteringSlideSizePixel(const UnoViewSharedPtr &pView) const
SlideBitmapSharedPtr getEnteringBitmap(const ViewEntry &rViewEntry) const
ScreenUpdater & getScreenUpdater() const
SlideBitmapSharedPtr getLeavingBitmap(const ViewEntry &rViewEntry) const
ViewsVecT::const_iterator beginViews()
void * p
B2DHomMatrix createRotateAroundPoint(double fPointX, double fPointY, double fRadiant)
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
std::shared_ptr< Canvas > CanvasSharedPtr
int i
::std::shared_ptr< SoundPlayer > SoundPlayerSharedPtr
::std::shared_ptr< SlideBitmap > SlideBitmapSharedPtr
Definition: slidebitmap.hxx:76
::std::shared_ptr< Slide > SlideSharedPtr
Definition: slide.hxx:148
UnoViewSharedPtr mpView
The view this entry is for.