1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
,
29 OutputDevice
* pFirstFrameOutDev
) :
31 mpOut ( pFirstFrameOutDev
? pFirstFrameOutDev
: pOut
),
32 mnExtraData ( nExtraData
),
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?
50 maDispPt
.X() = maPt
.X() + maSz
.Width() + 1L;
51 maDispSz
.Width() = -maSz
.Width();
52 maSzPix
.Width() = -maSzPix
.Width();
56 maDispPt
.X() = maPt
.X();
57 maDispSz
.Width() = maSz
.Width();
60 // Mirrored vertically?
63 maDispPt
.Y() = maPt
.Y() + maSz
.Height() + 1L;
64 maDispSz
.Height() = -maSz
.Height();
65 maSzPix
.Height() = -maSzPix
.Height();
69 maDispPt
.Y() = maPt
.Y();
70 maDispSz
.Height() = maSz
.Height();
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() );
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()
100 mpParent
->ImplDecAnimCount();
103 sal_Bool
ImplAnimView::ImplMatches( OutputDevice
* pOut
, long nExtraData
) const
105 sal_Bool bRet
= sal_False
;
109 if( ( mnExtraData
== nExtraData
) && ( !pOut
|| ( pOut
== mpOut
) ) )
112 else if( !pOut
|| ( pOut
== mpOut
) )
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 );
131 // calculate y scaling
132 if( rAnmSize
.Height() > 1L )
133 fFactY
= (double) ( maSzPix
.Height() - 1L ) / ( rAnmSize
.Height() - 1L );
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?
148 rPosPix
.X() = maSzPix
.Width() - 1L - aPt2
.X();
150 // Mirrored vertically?
152 rPosPix
.Y() = maSzPix
.Height() - 1L - aPt2
.Y();
155 void ImplAnimView::ImplDrawToPos( sal_uLong nPos
)
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
);
167 mpOut
->SetClipRegion( maClip
);
169 mpOut
->DrawOutDev( maDispPt
, maDispSz
, Point(), maSzPix
, aVDev
);
173 mpOut
->SetClipRegion( *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
);
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?
205 aBmpPosPix
.X() = aPosPix
.X() + aSizePix
.Width() - 1L;
206 aBmpSizePix
.Width() = -aSizePix
.Width();
210 aBmpPosPix
.X() = aPosPix
.X();
211 aBmpSizePix
.Width() = aSizePix
.Width();
214 // Mirrored vertically?
217 aBmpPosPix
.Y() = aPosPix
.Y() + aSizePix
.Height() - 1L;
218 aBmpSizePix
.Height() = -aSizePix
.Height();
222 aBmpPosPix
.Y() = aPosPix
.Y();
223 aBmpSizePix
.Height() = aSizePix
.Height();
229 pDev
= new VirtualDevice
;
230 pDev
->SetOutputSizePixel( maSzPix
, sal_False
);
231 pDev
->DrawOutDev( Point(), maSzPix
, maDispPt
, maDispSz
, *mpOut
);
236 // restore background after each run
239 meLastDisposal
= DISPOSE_BACK
;
245 if( ( DISPOSE_NOT
!= meLastDisposal
) && maRestSz
.Width() && maRestSz
.Height() )
247 if( DISPOSE_BACK
== meLastDisposal
)
248 pDev
->DrawOutDev( maRestPt
, maRestSz
, maRestPt
, maRestSz
, *mpBackground
);
250 pDev
->DrawOutDev( maRestPt
, maRestSz
, Point(), maRestSz
, *mpRestore
);
253 meLastDisposal
= rAnm
.eDisposal
;
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
);
264 mpRestore
->SetOutputSizePixel( maRestSz
, sal_False
);
265 mpRestore
->DrawOutDev( Point(), maRestSz
, aPosPix
, aSizePix
, *pDev
);
268 pDev
->DrawBitmapEx( aBmpPosPix
, aBmpSizePix
, rAnm
.aBmpEx
);
272 Region
* pOldClip
= !maClip
.IsNull() ? new Region( mpOut
->GetClipRegion() ) : NULL
;
275 mpOut
->SetClipRegion( maClip
);
277 mpOut
->DrawOutDev( maDispPt
, maDispSz
, Point(), maSzPix
, *pDev
);
281 mpOut
->SetClipRegion( *pOldClip
);
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() );
306 mpBackground
->DrawOutDev( Point(), maSzPix
, maDispPt
, maDispSz
, *mpOut
);
309 ImplDrawToPos( mnActPos
);
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
;
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */