update credits
[LibreOffice.git] / vcl / source / gdi / impanmvw.cxx
blob40b86b4fb91ffc4203736f84f5f75f7deddda41e
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 "impanmvw.hxx"
22 #include <vcl/virdev.hxx>
23 #include <vcl/window.hxx>
24 #include <tools/helpers.hxx>
26 ImplAnimView::ImplAnimView( Animation* pParent, OutputDevice* pOut,
27 const Point& rPt, const Size& rSz,
28 sal_uLong nExtraData,
29 OutputDevice* pFirstFrameOutDev ) :
30 mpParent ( pParent ),
31 mpOut ( pFirstFrameOutDev ? pFirstFrameOutDev : pOut ),
32 mnExtraData ( nExtraData ),
33 maPt ( rPt ),
34 maSz ( rSz ),
35 maSzPix ( mpOut->LogicToPixel( maSz ) ),
36 maClip ( mpOut->GetClipRegion() ),
37 mpBackground ( new VirtualDevice ),
38 mpRestore ( new VirtualDevice ),
39 meLastDisposal ( DISPOSE_BACK ),
40 mbPause ( sal_False ),
41 mbMarked ( sal_False ),
42 mbHMirr ( maSz.Width() < 0L ),
43 mbVMirr ( maSz.Height() < 0L )
45 mpParent->ImplIncAnimCount();
47 // Mirrored horizontally?
48 if( mbHMirr )
50 maDispPt.X() = maPt.X() + maSz.Width() + 1L;
51 maDispSz.Width() = -maSz.Width();
52 maSzPix.Width() = -maSzPix.Width();
54 else
56 maDispPt.X() = maPt.X();
57 maDispSz.Width() = maSz.Width();
60 // Mirrored vertically?
61 if( mbVMirr )
63 maDispPt.Y() = maPt.Y() + maSz.Height() + 1L;
64 maDispSz.Height() = -maSz.Height();
65 maSzPix.Height() = -maSzPix.Height();
67 else
69 maDispPt.Y() = maPt.Y();
70 maDispSz.Height() = maSz.Height();
73 // save background
74 mpBackground->SetOutputSizePixel( maSzPix );
76 if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
78 MapMode aTempMap( mpOut->GetMapMode() );
79 aTempMap.SetOrigin( Point() );
80 mpBackground->SetMapMode( aTempMap );
81 ( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
82 mpBackground->SetMapMode( MapMode() );
84 else
85 mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
87 // Initialize drawing to actual position
88 ImplDrawToPos( mpParent->ImplGetCurPos() );
90 // If first frame OutputDevice is set, update variables now for real OutputDevice
91 if( pFirstFrameOutDev )
92 maClip = ( mpOut = pOut )->GetClipRegion();
95 ImplAnimView::~ImplAnimView()
97 delete mpBackground;
98 delete mpRestore;
100 mpParent->ImplDecAnimCount();
103 sal_Bool ImplAnimView::ImplMatches( OutputDevice* pOut, long nExtraData ) const
105 sal_Bool bRet = sal_False;
107 if( nExtraData )
109 if( ( mnExtraData == nExtraData ) && ( !pOut || ( pOut == mpOut ) ) )
110 bRet = sal_True;
112 else if( !pOut || ( pOut == mpOut ) )
113 bRet = sal_True;
115 return bRet;
118 void ImplAnimView::ImplGetPosSize( const AnimationBitmap& rAnm, Point& rPosPix, Size& rSizePix )
120 const Size& rAnmSize = mpParent->GetDisplaySizePixel();
121 Point aPt2( rAnm.aPosPix.X() + rAnm.aSizePix.Width() - 1L,
122 rAnm.aPosPix.Y() + rAnm.aSizePix.Height() - 1L );
123 double fFactX, fFactY;
125 // calculate x scaling
126 if( rAnmSize.Width() > 1L )
127 fFactX = (double) ( maSzPix.Width() - 1L ) / ( rAnmSize.Width() - 1L );
128 else
129 fFactX = 1.0;
131 // calculate y scaling
132 if( rAnmSize.Height() > 1L )
133 fFactY = (double) ( maSzPix.Height() - 1L ) / ( rAnmSize.Height() - 1L );
134 else
135 fFactY = 1.0;
137 rPosPix.X() = FRound( rAnm.aPosPix.X() * fFactX );
138 rPosPix.Y() = FRound( rAnm.aPosPix.Y() * fFactY );
140 aPt2.X() = FRound( aPt2.X() * fFactX );
141 aPt2.Y() = FRound( aPt2.Y() * fFactY );
143 rSizePix.Width() = aPt2.X() - rPosPix.X() + 1L;
144 rSizePix.Height() = aPt2.Y() - rPosPix.Y() + 1L;
146 // Mirrored horizontally?
147 if( mbHMirr )
148 rPosPix.X() = maSzPix.Width() - 1L - aPt2.X();
150 // Mirrored vertically?
151 if( mbVMirr )
152 rPosPix.Y() = maSzPix.Height() - 1L - aPt2.Y();
155 void ImplAnimView::ImplDrawToPos( sal_uLong nPos )
157 VirtualDevice aVDev;
158 Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
160 aVDev.SetOutputSizePixel( maSzPix, sal_False );
161 nPos = std::min( nPos, (sal_uLong) mpParent->Count() - 1UL );
163 for( sal_uLong i = 0UL; i <= nPos; i++ )
164 ImplDraw( i, &aVDev );
166 if( pOldClip )
167 mpOut->SetClipRegion( maClip );
169 mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, aVDev );
171 if( pOldClip )
173 mpOut->SetClipRegion( *pOldClip );
174 delete pOldClip;
178 void ImplAnimView::ImplDraw( sal_uLong nPos )
180 ImplDraw( nPos, NULL );
183 void ImplAnimView::ImplDraw( sal_uLong nPos, VirtualDevice* pVDev )
185 Rectangle aOutRect( mpOut->PixelToLogic( Point() ), mpOut->GetOutputSize() );
187 // check, if output lies out of display
188 if( aOutRect.Intersection( Rectangle( maDispPt, maDispSz ) ).IsEmpty() )
189 ImplSetMarked( sal_True );
190 else if( !mbPause )
192 VirtualDevice* pDev;
193 Point aPosPix;
194 Point aBmpPosPix;
195 Size aSizePix;
196 Size aBmpSizePix;
197 const sal_uLong nLastPos = mpParent->Count() - 1;
198 const AnimationBitmap& rAnm = mpParent->Get( (sal_uInt16) ( mnActPos = std::min( nPos, nLastPos ) ) );
200 ImplGetPosSize( rAnm, aPosPix, aSizePix );
202 // Mirrored horizontally?
203 if( mbHMirr )
205 aBmpPosPix.X() = aPosPix.X() + aSizePix.Width() - 1L;
206 aBmpSizePix.Width() = -aSizePix.Width();
208 else
210 aBmpPosPix.X() = aPosPix.X();
211 aBmpSizePix.Width() = aSizePix.Width();
214 // Mirrored vertically?
215 if( mbVMirr )
217 aBmpPosPix.Y() = aPosPix.Y() + aSizePix.Height() - 1L;
218 aBmpSizePix.Height() = -aSizePix.Height();
220 else
222 aBmpPosPix.Y() = aPosPix.Y();
223 aBmpSizePix.Height() = aSizePix.Height();
226 // get output device
227 if( !pVDev )
229 pDev = new VirtualDevice;
230 pDev->SetOutputSizePixel( maSzPix, sal_False );
231 pDev->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
233 else
234 pDev = pVDev;
236 // restore background after each run
237 if( !nPos )
239 meLastDisposal = DISPOSE_BACK;
240 maRestPt = Point();
241 maRestSz = maSzPix;
244 // restore
245 if( ( DISPOSE_NOT != meLastDisposal ) && maRestSz.Width() && maRestSz.Height() )
247 if( DISPOSE_BACK == meLastDisposal )
248 pDev->DrawOutDev( maRestPt, maRestSz, maRestPt, maRestSz, *mpBackground );
249 else
250 pDev->DrawOutDev( maRestPt, maRestSz, Point(), maRestSz, *mpRestore );
253 meLastDisposal = rAnm.eDisposal;
254 maRestPt = aPosPix;
255 maRestSz = aSizePix;
257 // What do we need to restore the next time?
258 // Put it into a bitmap if needed, else delete
259 // SaveBitmap to conserve memory
260 if( ( meLastDisposal == DISPOSE_BACK ) || ( meLastDisposal == DISPOSE_NOT ) )
261 mpRestore->SetOutputSizePixel( Size( 1, 1 ), sal_False );
262 else
264 mpRestore->SetOutputSizePixel( maRestSz, sal_False );
265 mpRestore->DrawOutDev( Point(), maRestSz, aPosPix, aSizePix, *pDev );
268 pDev->DrawBitmapEx( aBmpPosPix, aBmpSizePix, rAnm.aBmpEx );
270 if( !pVDev )
272 Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
274 if( pOldClip )
275 mpOut->SetClipRegion( maClip );
277 mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, *pDev );
279 if( pOldClip )
281 mpOut->SetClipRegion( *pOldClip );
282 delete pOldClip;
285 delete pDev;
287 if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
288 ( (Window*) mpOut )->Sync();
293 void ImplAnimView::ImplRepaint()
295 const sal_Bool bOldPause = mbPause;
297 if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
299 MapMode aTempMap( mpOut->GetMapMode() );
300 aTempMap.SetOrigin( Point() );
301 mpBackground->SetMapMode( aTempMap );
302 ( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
303 mpBackground->SetMapMode( MapMode() );
305 else
306 mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
308 mbPause = sal_False;
309 ImplDrawToPos( mnActPos );
310 mbPause = bOldPause;
313 AInfo* ImplAnimView::ImplCreateAInfo() const
315 AInfo* pAInfo = new AInfo;
317 pAInfo->aStartOrg = maPt;
318 pAInfo->aStartSize = maSz;
319 pAInfo->pOutDev = mpOut;
320 pAInfo->pViewData = (void*) this;
321 pAInfo->nExtraData = mnExtraData;
322 pAInfo->bPause = mbPause;
324 return pAInfo;
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */