Branch data Line data Source code
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 : :
21 : : #include "impanmvw.hxx"
22 : : #include <vcl/virdev.hxx>
23 : : #include <vcl/window.hxx>
24 : : #include <tools/helpers.hxx>
25 : :
26 : : // ----------------
27 : : // - ImplAnimView -
28 : : // ----------------
29 : :
30 : 0 : ImplAnimView::ImplAnimView( Animation* pParent, OutputDevice* pOut,
31 : : const Point& rPt, const Size& rSz,
32 : : sal_uLong nExtraData,
33 : : OutputDevice* pFirstFrameOutDev ) :
34 : : mpParent ( pParent ),
35 : : mpOut ( pFirstFrameOutDev ? pFirstFrameOutDev : pOut ),
36 : : mnExtraData ( nExtraData ),
37 : : maPt ( rPt ),
38 : : maSz ( rSz ),
39 : 0 : maSzPix ( mpOut->LogicToPixel( maSz ) ),
40 : : maClip ( mpOut->GetClipRegion() ),
41 [ # # ]: 0 : mpBackground ( new VirtualDevice ),
42 [ # # ]: 0 : mpRestore ( new VirtualDevice ),
43 : : meLastDisposal ( DISPOSE_BACK ),
44 : : mbPause ( sal_False ),
45 : : mbMarked ( sal_False ),
46 : 0 : mbHMirr ( maSz.Width() < 0L ),
47 [ # # ][ # # ]: 0 : mbVMirr ( maSz.Height() < 0L )
[ # # ][ # # ]
48 : : {
49 : 0 : mpParent->ImplIncAnimCount();
50 : :
51 : : // mirrored horizontically?
52 [ # # ]: 0 : if( mbHMirr )
53 : : {
54 : 0 : maDispPt.X() = maPt.X() + maSz.Width() + 1L;
55 : 0 : maDispSz.Width() = -maSz.Width();
56 : 0 : maSzPix.Width() = -maSzPix.Width();
57 : : }
58 : : else
59 : : {
60 : 0 : maDispPt.X() = maPt.X();
61 : 0 : maDispSz.Width() = maSz.Width();
62 : : }
63 : :
64 : : // mirrored vertically?
65 [ # # ]: 0 : if( mbVMirr )
66 : : {
67 : 0 : maDispPt.Y() = maPt.Y() + maSz.Height() + 1L;
68 : 0 : maDispSz.Height() = -maSz.Height();
69 : 0 : maSzPix.Height() = -maSzPix.Height();
70 : : }
71 : : else
72 : : {
73 : 0 : maDispPt.Y() = maPt.Y();
74 : 0 : maDispSz.Height() = maSz.Height();
75 : : }
76 : :
77 : : // save background
78 [ # # ]: 0 : mpBackground->SetOutputSizePixel( maSzPix );
79 : :
80 [ # # ]: 0 : if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
81 : : {
82 [ # # ]: 0 : MapMode aTempMap( mpOut->GetMapMode() );
83 [ # # ]: 0 : aTempMap.SetOrigin( Point() );
84 [ # # ]: 0 : mpBackground->SetMapMode( aTempMap );
85 [ # # ]: 0 : ( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
86 [ # # ][ # # ]: 0 : mpBackground->SetMapMode( MapMode() );
[ # # ][ # # ]
87 : : }
88 : : else
89 [ # # ]: 0 : mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
90 : :
91 : : // initial drawing to actual position
92 [ # # ]: 0 : ImplDrawToPos( mpParent->ImplGetCurPos() );
93 : :
94 : : // if first frame OutputDevice is set, update variables now for real OutputDevice
95 [ # # ]: 0 : if( pFirstFrameOutDev )
96 [ # # ][ # # ]: 0 : maClip = ( mpOut = pOut )->GetClipRegion();
[ # # ]
97 : 0 : }
98 : :
99 : : // ------------------------------------------------------------------------
100 : :
101 [ # # ]: 0 : ImplAnimView::~ImplAnimView()
102 : : {
103 [ # # ][ # # ]: 0 : delete mpBackground;
104 [ # # ][ # # ]: 0 : delete mpRestore;
105 : :
106 : 0 : mpParent->ImplDecAnimCount();
107 : 0 : }
108 : :
109 : : // ------------------------------------------------------------------------
110 : :
111 : 0 : sal_Bool ImplAnimView::ImplMatches( OutputDevice* pOut, long nExtraData ) const
112 : : {
113 : 0 : sal_Bool bRet = sal_False;
114 : :
115 [ # # ]: 0 : if( nExtraData )
116 : : {
117 [ # # ][ # # ]: 0 : if( ( mnExtraData == nExtraData ) && ( !pOut || ( pOut == mpOut ) ) )
[ # # ]
118 : 0 : bRet = sal_True;
119 : : }
120 [ # # ][ # # ]: 0 : else if( !pOut || ( pOut == mpOut ) )
121 : 0 : bRet = sal_True;
122 : :
123 : 0 : return bRet;
124 : : }
125 : :
126 : : // ------------------------------------------------------------------------
127 : :
128 : 0 : void ImplAnimView::ImplGetPosSize( const AnimationBitmap& rAnm, Point& rPosPix, Size& rSizePix )
129 : : {
130 : 0 : const Size& rAnmSize = mpParent->GetDisplaySizePixel();
131 : 0 : Point aPt2( rAnm.aPosPix.X() + rAnm.aSizePix.Width() - 1L,
132 : 0 : rAnm.aPosPix.Y() + rAnm.aSizePix.Height() - 1L );
133 : : double fFactX, fFactY;
134 : :
135 : : // calculate x scaling
136 [ # # ]: 0 : if( rAnmSize.Width() > 1L )
137 : 0 : fFactX = (double) ( maSzPix.Width() - 1L ) / ( rAnmSize.Width() - 1L );
138 : : else
139 : 0 : fFactX = 1.0;
140 : :
141 : : // calculate y scaling
142 [ # # ]: 0 : if( rAnmSize.Height() > 1L )
143 : 0 : fFactY = (double) ( maSzPix.Height() - 1L ) / ( rAnmSize.Height() - 1L );
144 : : else
145 : 0 : fFactY = 1.0;
146 : :
147 : 0 : rPosPix.X() = FRound( rAnm.aPosPix.X() * fFactX );
148 : 0 : rPosPix.Y() = FRound( rAnm.aPosPix.Y() * fFactY );
149 : :
150 : 0 : aPt2.X() = FRound( aPt2.X() * fFactX );
151 : 0 : aPt2.Y() = FRound( aPt2.Y() * fFactY );
152 : :
153 : 0 : rSizePix.Width() = aPt2.X() - rPosPix.X() + 1L;
154 : 0 : rSizePix.Height() = aPt2.Y() - rPosPix.Y() + 1L;
155 : :
156 : : // mirrored horizontically?
157 [ # # ]: 0 : if( mbHMirr )
158 : 0 : rPosPix.X() = maSzPix.Width() - 1L - aPt2.X();
159 : :
160 : : // mirrored vertically?
161 [ # # ]: 0 : if( mbVMirr )
162 : 0 : rPosPix.Y() = maSzPix.Height() - 1L - aPt2.Y();
163 : 0 : }
164 : :
165 : : // ------------------------------------------------------------------------
166 : :
167 : 0 : void ImplAnimView::ImplDrawToPos( sal_uLong nPos )
168 : : {
169 [ # # ]: 0 : VirtualDevice aVDev;
170 [ # # ][ # # ]: 0 : Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
[ # # ][ # # ]
171 : :
172 [ # # ]: 0 : aVDev.SetOutputSizePixel( maSzPix, sal_False );
173 : 0 : nPos = Min( nPos, (sal_uLong) mpParent->Count() - 1UL );
174 : :
175 [ # # ]: 0 : for( sal_uLong i = 0UL; i <= nPos; i++ )
176 [ # # ]: 0 : ImplDraw( i, &aVDev );
177 : :
178 [ # # ]: 0 : if( pOldClip )
179 [ # # ]: 0 : mpOut->SetClipRegion( maClip );
180 : :
181 [ # # ]: 0 : mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, aVDev );
182 : :
183 [ # # ]: 0 : if( pOldClip )
184 : : {
185 [ # # ]: 0 : mpOut->SetClipRegion( *pOldClip );
186 [ # # ][ # # ]: 0 : delete pOldClip;
187 [ # # ]: 0 : }
188 : 0 : }
189 : :
190 : : // ------------------------------------------------------------------------
191 : :
192 : 0 : void ImplAnimView::ImplDraw( sal_uLong nPos )
193 : : {
194 : 0 : ImplDraw( nPos, NULL );
195 : 0 : }
196 : :
197 : : // ------------------------------------------------------------------------
198 : :
199 : 0 : void ImplAnimView::ImplDraw( sal_uLong nPos, VirtualDevice* pVDev )
200 : : {
201 [ # # ][ # # ]: 0 : Rectangle aOutRect( mpOut->PixelToLogic( Point() ), mpOut->GetOutputSize() );
[ # # ]
202 : :
203 : : // check, if output lies out of display
204 [ # # ][ # # ]: 0 : if( aOutRect.Intersection( Rectangle( maDispPt, maDispSz ) ).IsEmpty() )
[ # # ][ # # ]
205 : 0 : ImplSetMarked( sal_True );
206 [ # # ]: 0 : else if( !mbPause )
207 : : {
208 : : VirtualDevice* pDev;
209 : 0 : Point aPosPix;
210 : 0 : Point aBmpPosPix;
211 : 0 : Size aSizePix;
212 : 0 : Size aBmpSizePix;
213 : 0 : const sal_uLong nLastPos = mpParent->Count() - 1;
214 [ # # ]: 0 : const AnimationBitmap& rAnm = mpParent->Get( (sal_uInt16) ( mnActPos = Min( nPos, nLastPos ) ) );
215 : :
216 : 0 : ImplGetPosSize( rAnm, aPosPix, aSizePix );
217 : :
218 : : // mirrored horizontically?
219 [ # # ]: 0 : if( mbHMirr )
220 : : {
221 : 0 : aBmpPosPix.X() = aPosPix.X() + aSizePix.Width() - 1L;
222 : 0 : aBmpSizePix.Width() = -aSizePix.Width();
223 : : }
224 : : else
225 : : {
226 : 0 : aBmpPosPix.X() = aPosPix.X();
227 : 0 : aBmpSizePix.Width() = aSizePix.Width();
228 : : }
229 : :
230 : : // mirrored vertically?
231 [ # # ]: 0 : if( mbVMirr )
232 : : {
233 : 0 : aBmpPosPix.Y() = aPosPix.Y() + aSizePix.Height() - 1L;
234 : 0 : aBmpSizePix.Height() = -aSizePix.Height();
235 : : }
236 : : else
237 : : {
238 : 0 : aBmpPosPix.Y() = aPosPix.Y();
239 : 0 : aBmpSizePix.Height() = aSizePix.Height();
240 : : }
241 : :
242 : : // get output device
243 [ # # ]: 0 : if( !pVDev )
244 : : {
245 [ # # ][ # # ]: 0 : pDev = new VirtualDevice;
246 [ # # ]: 0 : pDev->SetOutputSizePixel( maSzPix, sal_False );
247 [ # # ]: 0 : pDev->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
248 : : }
249 : : else
250 : 0 : pDev = pVDev;
251 : :
252 : : // restore background after each run
253 [ # # ]: 0 : if( !nPos )
254 : : {
255 : 0 : meLastDisposal = DISPOSE_BACK;
256 : 0 : maRestPt = Point();
257 : 0 : maRestSz = maSzPix;
258 : : }
259 : :
260 : : // restore
261 [ # # ][ # # ]: 0 : if( ( DISPOSE_NOT != meLastDisposal ) && maRestSz.Width() && maRestSz.Height() )
[ # # ][ # # ]
262 : : {
263 [ # # ]: 0 : if( DISPOSE_BACK == meLastDisposal )
264 [ # # ]: 0 : pDev->DrawOutDev( maRestPt, maRestSz, maRestPt, maRestSz, *mpBackground );
265 : : else
266 [ # # ]: 0 : pDev->DrawOutDev( maRestPt, maRestSz, Point(), maRestSz, *mpRestore );
267 : : }
268 : :
269 : 0 : meLastDisposal = rAnm.eDisposal;
270 : 0 : maRestPt = aPosPix;
271 : 0 : maRestSz = aSizePix;
272 : :
273 : : // Was muessen wir beim naechsten Mal restaurieren ?
274 : : // ==> ggf. in eine Bitmap stecken, ansonsten SaveBitmap
275 : : // aus Speichergruenden loeschen
276 [ # # ][ # # ]: 0 : if( ( meLastDisposal == DISPOSE_BACK ) || ( meLastDisposal == DISPOSE_NOT ) )
277 [ # # ]: 0 : mpRestore->SetOutputSizePixel( Size( 1, 1 ), sal_False );
278 : : else
279 : : {
280 [ # # ]: 0 : mpRestore->SetOutputSizePixel( maRestSz, sal_False );
281 [ # # ]: 0 : mpRestore->DrawOutDev( Point(), maRestSz, aPosPix, aSizePix, *pDev );
282 : : }
283 : :
284 [ # # ]: 0 : pDev->DrawBitmapEx( aBmpPosPix, aBmpSizePix, rAnm.aBmpEx );
285 : :
286 [ # # ]: 0 : if( !pVDev )
287 : : {
288 [ # # ][ # # ]: 0 : Region* pOldClip = !maClip.IsNull() ? new Region( mpOut->GetClipRegion() ) : NULL;
[ # # ][ # # ]
289 : :
290 [ # # ]: 0 : if( pOldClip )
291 [ # # ]: 0 : mpOut->SetClipRegion( maClip );
292 : :
293 [ # # ]: 0 : mpOut->DrawOutDev( maDispPt, maDispSz, Point(), maSzPix, *pDev );
294 : :
295 [ # # ]: 0 : if( pOldClip )
296 : : {
297 [ # # ]: 0 : mpOut->SetClipRegion( *pOldClip );
298 [ # # ][ # # ]: 0 : delete pOldClip;
299 : : }
300 : :
301 [ # # ][ # # ]: 0 : delete pDev;
302 : :
303 [ # # ]: 0 : if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
304 [ # # ]: 0 : ( (Window*) mpOut )->Sync();
305 : : }
306 : : }
307 : 0 : }
308 : :
309 : : // ------------------------------------------------------------------------
310 : :
311 : 0 : void ImplAnimView::ImplRepaint()
312 : : {
313 : 0 : const sal_Bool bOldPause = mbPause;
314 : :
315 [ # # ]: 0 : if( mpOut->GetOutDevType() == OUTDEV_WINDOW )
316 : : {
317 [ # # ]: 0 : MapMode aTempMap( mpOut->GetMapMode() );
318 [ # # ]: 0 : aTempMap.SetOrigin( Point() );
319 [ # # ]: 0 : mpBackground->SetMapMode( aTempMap );
320 [ # # ]: 0 : ( (Window*) mpOut )->SaveBackground( maDispPt, maDispSz, Point(), *mpBackground );
321 [ # # ][ # # ]: 0 : mpBackground->SetMapMode( MapMode() );
[ # # ][ # # ]
322 : : }
323 : : else
324 [ # # ]: 0 : mpBackground->DrawOutDev( Point(), maSzPix, maDispPt, maDispSz, *mpOut );
325 : :
326 : 0 : mbPause = sal_False;
327 : 0 : ImplDrawToPos( mnActPos );
328 : 0 : mbPause = bOldPause;
329 : 0 : }
330 : :
331 : : // ------------------------------------------------------------------------
332 : :
333 : 0 : AInfo* ImplAnimView::ImplCreateAInfo() const
334 : : {
335 [ # # ]: 0 : AInfo* pAInfo = new AInfo;
336 : :
337 : 0 : pAInfo->aStartOrg = maPt;
338 : 0 : pAInfo->aStartSize = maSz;
339 : 0 : pAInfo->pOutDev = mpOut;
340 : 0 : pAInfo->pViewData = (void*) this;
341 : 0 : pAInfo->nExtraData = mnExtraData;
342 : 0 : pAInfo->bPause = mbPause;
343 : :
344 : 0 : return pAInfo;
345 : : }
346 : :
347 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|