1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_slideshow.hxx" 30 31 #include <canvas/debug.hxx> 32 #include <basegfx/polygon/b2dpolygon.hxx> 33 #include <basegfx/polygon/b2dpolygontools.hxx> 34 #include <basegfx/matrix/b2dhommatrix.hxx> 35 #include <basegfx/matrix/b2dhommatrixtools.hxx> 36 37 #include <cppcanvas/spritecanvas.hxx> 38 39 #include "combtransition.hxx" 40 41 #include <boost/bind.hpp> 42 43 44 namespace slideshow { 45 namespace internal { 46 47 namespace { 48 49 basegfx::B2DPolyPolygon createClipPolygon( 50 const ::basegfx::B2DVector& rDirection, 51 const ::basegfx::B2DSize& rSlideSize, 52 int nNumStrips, int nOffset ) 53 { 54 // create clip polygon in standard orientation (will later 55 // be rotated to match direction vector) 56 ::basegfx::B2DPolyPolygon aClipPoly; 57 58 // create nNumStrips/2 vertical strips 59 for( int i=nOffset; i<nNumStrips; i+=2 ) 60 { 61 aClipPoly.append( 62 ::basegfx::tools::createPolygonFromRect( 63 ::basegfx::B2DRectangle( double(i)/nNumStrips, 0.0, 64 double(i+1)/nNumStrips, 1.0) ) ); 65 66 } 67 68 // rotate polygons, such that the strips are parallel to 69 // the given direction vector 70 const ::basegfx::B2DVector aUpVec(0.0, 1.0); 71 basegfx::B2DHomMatrix aMatrix(basegfx::tools::createRotateAroundPoint(0.5, 0.5, aUpVec.angle( rDirection ))); 72 73 // blow up clip polygon to slide size 74 aMatrix.scale( rSlideSize.getX(), 75 rSlideSize.getY() ); 76 77 aClipPoly.transform( aMatrix ); 78 79 return aClipPoly; 80 } 81 82 } 83 84 CombTransition::CombTransition( 85 boost::optional<SlideSharedPtr> const & leavingSlide, 86 const SlideSharedPtr& pEnteringSlide, 87 const SoundPlayerSharedPtr& pSoundPlayer, 88 const UnoViewContainer& rViewContainer, 89 ScreenUpdater& rScreenUpdater, 90 EventMultiplexer& rEventMultiplexer, 91 const ::basegfx::B2DVector& rPushDirection, 92 sal_Int32 nNumStripes ) 93 : SlideChangeBase( leavingSlide, pEnteringSlide, pSoundPlayer, 94 rViewContainer, rScreenUpdater, rEventMultiplexer, 95 false /* no leaving sprite */, 96 false /* no entering sprite */ ), 97 maPushDirectionUnit( rPushDirection ), 98 mnNumStripes( nNumStripes ) 99 { 100 } 101 102 void CombTransition::renderComb( double t, 103 const ViewEntry& rViewEntry ) const 104 { 105 const SlideBitmapSharedPtr& pEnteringBitmap = getEnteringBitmap(rViewEntry); 106 const cppcanvas::CanvasSharedPtr pCanvas_ = rViewEntry.mpView->getCanvas(); 107 108 if( !pEnteringBitmap || !pCanvas_ ) 109 return; 110 111 // calc bitmap offsets. The enter/leaving bitmaps are only 112 // as large as the actual slides. For scaled-down 113 // presentations, we have to move the left, top edge of 114 // those bitmaps to the actual position, governed by the 115 // given view transform. The aBitmapPosPixel local 116 // variable is already in device coordinate space 117 // (i.e. pixel). 118 119 // TODO(F2): Properly respect clip here. Might have to be transformed, too. 120 const basegfx::B2DHomMatrix viewTransform( rViewEntry.mpView->getTransformation() ); 121 const basegfx::B2DPoint pageOrigin( viewTransform * basegfx::B2DPoint() ); 122 123 // change transformation on cloned canvas to be in 124 // device pixel 125 cppcanvas::CanvasSharedPtr pCanvas( pCanvas_->clone() ); 126 basegfx::B2DPoint p; 127 128 // TODO(Q2): Use basegfx bitmaps here 129 // TODO(F1): SlideBitmap is not fully portable between different canvases! 130 131 const basegfx::B2DSize enteringSizePixel( 132 getEnteringSlideSizePixel( rViewEntry.mpView) ); 133 134 const basegfx::B2DVector aPushDirection = basegfx::B2DVector( 135 enteringSizePixel * maPushDirectionUnit ); 136 const basegfx::B2DPolyPolygon aClipPolygon1 = basegfx::B2DPolyPolygon( 137 createClipPolygon( maPushDirectionUnit, 138 enteringSizePixel, 139 mnNumStripes, 0 ) ); 140 const basegfx::B2DPolyPolygon aClipPolygon2 = basegfx::B2DPolyPolygon( 141 createClipPolygon( maPushDirectionUnit, 142 enteringSizePixel, 143 mnNumStripes, 1 ) ); 144 145 SlideBitmapSharedPtr const & pLeavingBitmap = getLeavingBitmap(rViewEntry); 146 if( pLeavingBitmap ) 147 { 148 // render odd strips: 149 pLeavingBitmap->clip( aClipPolygon1 ); 150 // don't modify bitmap object (no move!): 151 p = basegfx::B2DPoint( pageOrigin + (t * aPushDirection) ); 152 pCanvas->setTransformation(basegfx::tools::createTranslateB2DHomMatrix(p.getX(), p.getY())); 153 pLeavingBitmap->draw( pCanvas ); 154 155 // render even strips: 156 pLeavingBitmap->clip( aClipPolygon2 ); 157 // don't modify bitmap object (no move!): 158 p = basegfx::B2DPoint( pageOrigin - (t * aPushDirection) ); 159 pCanvas->setTransformation(basegfx::tools::createTranslateB2DHomMatrix(p.getX(), p.getY())); 160 pLeavingBitmap->draw( pCanvas ); 161 } 162 163 // TODO(Q2): Use basegfx bitmaps here 164 // TODO(F1): SlideBitmap is not fully portable between different canvases! 165 166 // render odd strips: 167 pEnteringBitmap->clip( aClipPolygon1 ); 168 // don't modify bitmap object (no move!): 169 p = basegfx::B2DPoint( pageOrigin + ((t - 1.0) * aPushDirection) ); 170 pCanvas->setTransformation(basegfx::tools::createTranslateB2DHomMatrix(p.getX(), p.getY())); 171 pEnteringBitmap->draw( pCanvas ); 172 173 // render even strips: 174 pEnteringBitmap->clip( aClipPolygon2 ); 175 // don't modify bitmap object (no move!): 176 p = basegfx::B2DPoint( pageOrigin + ((1.0 - t) * aPushDirection) ); 177 pCanvas->setTransformation(basegfx::tools::createTranslateB2DHomMatrix(p.getX(), p.getY())); 178 pEnteringBitmap->draw( pCanvas ); 179 } 180 181 bool CombTransition::operator()( double t ) 182 { 183 std::for_each( beginViews(), 184 endViews(), 185 boost::bind( &CombTransition::renderComb, 186 this, 187 t, 188 _1 )); 189 190 getScreenUpdater().notifyUpdate(); 191 192 return true; 193 } 194 195 } // namespace internal 196 } // namespace presentation 197