Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/animate.hxx>
31 : : #include <tools/debug.hxx>
32 : : #include <tools/stream.hxx>
33 : : #include <rtl/crc.h>
34 : : #include <vcl/virdev.hxx>
35 : : #include <vcl/window.hxx>
36 : : #include <impanmvw.hxx>
37 : : DBG_NAME( Animation )
38 : :
39 : : // -----------
40 : : // - Defines -
41 : : // -----------
42 : :
43 : : #define MIN_TIMEOUT 2L
44 : : #define INC_TIMEOUT 0L
45 : :
46 : : // -----------
47 : : // - statics -
48 : : // -----------
49 : :
50 : : sal_uLong Animation::mnAnimCount = 0UL;
51 : :
52 : : // -------------------
53 : : // - AnimationBitmap -
54 : : // -------------------
55 : :
56 : 0 : sal_uLong AnimationBitmap::GetChecksum() const
57 : : {
58 [ # # ]: 0 : sal_uInt32 nCrc = aBmpEx.GetChecksum();
59 : : SVBT32 aBT32;
60 : :
61 : 0 : UInt32ToSVBT32( aPosPix.X(), aBT32 );
62 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
63 : :
64 : 0 : UInt32ToSVBT32( aPosPix.Y(), aBT32 );
65 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
66 : :
67 : 0 : UInt32ToSVBT32( aSizePix.Width(), aBT32 );
68 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
69 : :
70 : 0 : UInt32ToSVBT32( aSizePix.Height(), aBT32 );
71 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
72 : :
73 : 0 : UInt32ToSVBT32( (long) nWait, aBT32 );
74 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
75 : :
76 : 0 : UInt32ToSVBT32( (long) eDisposal, aBT32 );
77 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
78 : :
79 : 0 : UInt32ToSVBT32( (long) bUserInput, aBT32 );
80 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
81 : :
82 : 0 : return nCrc;
83 : : }
84 : :
85 : : // -------------
86 : : // - Animation -
87 : : // -------------
88 : :
89 : 56 : Animation::Animation() :
90 : : mnLoopCount ( 0 ),
91 : : mnLoops ( 0 ),
92 : : mnPos ( 0 ),
93 : : meCycleMode ( CYCLE_NORMAL ),
94 : : mbIsInAnimation ( sal_False ),
95 : : mbLoopTerminated ( sal_False ),
96 [ + - ][ + - ]: 56 : mbIsWaiting ( sal_False )
[ + - ][ + - ]
97 : : {
98 : : DBG_CTOR( Animation, NULL );
99 [ + - ]: 56 : maTimer.SetTimeoutHdl( LINK( this, Animation, ImplTimeoutHdl ) );
100 : 56 : }
101 : :
102 : : // -----------------------------------------------------------------------
103 : :
104 : 36 : Animation::Animation( const Animation& rAnimation ) :
105 : : maBitmapEx ( rAnimation.maBitmapEx ),
106 : : maGlobalSize ( rAnimation.maGlobalSize ),
107 : : mnLoopCount ( rAnimation.mnLoopCount ),
108 : : mnPos ( rAnimation.mnPos ),
109 : : meCycleMode ( rAnimation.meCycleMode ),
110 : : mbIsInAnimation ( sal_False ),
111 : : mbLoopTerminated ( rAnimation.mbLoopTerminated ),
112 [ + - ][ + - ]: 36 : mbIsWaiting ( rAnimation.mbIsWaiting )
[ + - ][ + - ]
113 : : {
114 : : DBG_CTOR( Animation, NULL );
115 : :
116 [ + + ]: 360 : for( size_t i = 0, nCount = rAnimation.maList.size(); i < nCount; i++ )
117 [ + - ][ + - ]: 324 : maList.push_back( new AnimationBitmap( *rAnimation.maList[ i ] ) );
[ + - ][ + - ]
118 : :
119 [ + - ]: 36 : maTimer.SetTimeoutHdl( LINK( this, Animation, ImplTimeoutHdl ) );
120 [ + - ]: 36 : mnLoops = mbLoopTerminated ? 0 : mnLoopCount;
121 : 36 : }
122 : :
123 : : // -----------------------------------------------------------------------
124 : :
125 [ + - ][ + - ]: 92 : Animation::~Animation()
126 : : {
127 : : DBG_DTOR( Animation, NULL );
128 : :
129 [ - + ]: 92 : if( mbIsInAnimation )
130 [ # # ]: 0 : Stop();
131 : :
132 [ + + ]: 271 : for( size_t i = 0, n = maList.size(); i < n; ++i )
133 [ + - ][ + - ]: 179 : delete maList[ i ];
[ + - ]
134 : :
135 [ - + ]: 92 : for( size_t i = 0, n = maViewList.size(); i < n; ++i )
136 [ # # ][ # # ]: 0 : delete maViewList[ i ];
137 : 92 : }
138 : :
139 : : // -----------------------------------------------------------------------
140 : :
141 : 0 : Animation& Animation::operator=( const Animation& rAnimation )
142 : : {
143 : 0 : Clear();
144 : :
145 [ # # ]: 0 : for( size_t i = 0, nCount = rAnimation.maList.size(); i < nCount; i++ )
146 [ # # ][ # # ]: 0 : maList.push_back( new AnimationBitmap( *rAnimation.maList[ i ] ) );
147 : :
148 : 0 : maGlobalSize = rAnimation.maGlobalSize;
149 : 0 : maBitmapEx = rAnimation.maBitmapEx;
150 : 0 : meCycleMode = rAnimation.meCycleMode;
151 : 0 : mnLoopCount = rAnimation.mnLoopCount;
152 : 0 : mnPos = rAnimation.mnPos;
153 : 0 : mbLoopTerminated = rAnimation.mbLoopTerminated;
154 : 0 : mbIsWaiting = rAnimation.mbIsWaiting;
155 [ # # ]: 0 : mnLoops = mbLoopTerminated ? 0 : mnLoopCount;
156 : :
157 : 0 : return *this;
158 : : }
159 : :
160 : : // -----------------------------------------------------------------------
161 : :
162 : 0 : sal_Bool Animation::operator==( const Animation& rAnimation ) const
163 : : {
164 : 0 : const size_t nCount = maList.size();
165 : 0 : sal_Bool bRet = sal_False;
166 : :
167 [ # # ][ # # ]: 0 : if( rAnimation.maList.size() == nCount
[ # # # #
# # ]
168 : 0 : && rAnimation.maBitmapEx == maBitmapEx
169 : 0 : && rAnimation.maGlobalSize == maGlobalSize
170 : : && rAnimation.meCycleMode == meCycleMode
171 : : )
172 : : {
173 : 0 : bRet = sal_True;
174 : :
175 [ # # ]: 0 : for( size_t n = 0; n < nCount; n++ )
176 : : {
177 [ # # ]: 0 : if( ( *maList[ n ] ) != ( *rAnimation.maList[ n ] ) )
178 : : {
179 : 0 : bRet = sal_False;
180 : 0 : break;
181 : : }
182 : : }
183 : : }
184 : :
185 : 0 : return bRet;
186 : : }
187 : :
188 : 36 : void Animation::Clear()
189 : : {
190 : 36 : maTimer.Stop();
191 : 36 : mbIsInAnimation = sal_False;
192 : 36 : maGlobalSize = Size();
193 : 36 : maBitmapEx.SetEmpty();
194 : :
195 [ + + ]: 360 : for( size_t i = 0, n = maList.size(); i < n; ++i )
196 [ + - ]: 324 : delete maList[ i ];
197 : 36 : maList.clear();
198 : :
199 [ - + ]: 36 : for( size_t i = 0, n = maViewList.size(); i < n; ++i )
200 [ # # ]: 0 : delete maViewList[ i ];
201 : 36 : maViewList.clear();
202 : 36 : }
203 : :
204 : : // -----------------------------------------------------------------------
205 : :
206 : 0 : sal_Bool Animation::IsTransparent() const
207 : : {
208 : 0 : Point aPoint;
209 [ # # ]: 0 : Rectangle aRect( aPoint, maGlobalSize );
210 : 0 : sal_Bool bRet = sal_False;
211 : :
212 : : // Falls irgendein 'kleines' Bildchen durch den Hintergrund
213 : : // ersetzt werden soll, muessen wir 'transparent' sein, um
214 : : // richtig dargestellt zu werden, da die Appl. aus Optimierungsgruenden
215 : : // kein Invalidate auf nicht-transp. Grafiken ausfuehren
216 [ # # ]: 0 : for( size_t i = 0, nCount = maList.size(); i < nCount; i++ )
217 : : {
218 [ # # ]: 0 : const AnimationBitmap* pAnimBmp = maList[ i ];
219 : :
220 [ # # ][ # # ]: 0 : if( DISPOSE_BACK == pAnimBmp->eDisposal
[ # # ]
221 [ # # ][ # # ]: 0 : && Rectangle( pAnimBmp->aPosPix, pAnimBmp->aSizePix ) != aRect
[ # # ][ # # ]
222 : : )
223 : : {
224 : 0 : bRet = sal_True;
225 : 0 : break;
226 : : }
227 : : }
228 : :
229 [ # # ]: 0 : if( !bRet )
230 [ # # ]: 0 : bRet = maBitmapEx.IsTransparent();
231 : :
232 : 0 : return bRet;
233 : : }
234 : :
235 : : // -----------------------------------------------------------------------
236 : :
237 : 0 : sal_uLong Animation::GetSizeBytes() const
238 : : {
239 : 0 : sal_uLong nSizeBytes = GetBitmapEx().GetSizeBytes();
240 : :
241 [ # # ]: 0 : for( size_t i = 0, nCount = maList.size(); i < nCount; i++ )
242 : : {
243 : 0 : const AnimationBitmap* pAnimBmp = maList[ i ];
244 : 0 : nSizeBytes += pAnimBmp->aBmpEx.GetSizeBytes();
245 : : }
246 : :
247 : 0 : return nSizeBytes;
248 : : }
249 : :
250 : : // -----------------------------------------------------------------------
251 : :
252 : 0 : sal_uLong Animation::GetChecksum() const
253 : : {
254 : : SVBT32 aBT32;
255 [ # # ]: 0 : sal_uInt32 nCrc = GetBitmapEx().GetChecksum();
256 : :
257 : 0 : UInt32ToSVBT32( maList.size(), aBT32 );
258 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
259 : :
260 : 0 : UInt32ToSVBT32( maGlobalSize.Width(), aBT32 );
261 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
262 : :
263 : 0 : UInt32ToSVBT32( maGlobalSize.Height(), aBT32 );
264 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
265 : :
266 : 0 : UInt32ToSVBT32( (long) meCycleMode, aBT32 );
267 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
268 : :
269 [ # # ]: 0 : for( size_t i = 0, nCount = maList.size(); i < nCount; i++ )
270 : : {
271 [ # # ][ # # ]: 0 : UInt32ToSVBT32( maList[ i ]->GetChecksum(), aBT32 );
272 : 0 : nCrc = rtl_crc32( nCrc, aBT32, 4 );
273 : : }
274 : :
275 : 0 : return nCrc;
276 : : }
277 : :
278 : : // -----------------------------------------------------------------------
279 : :
280 : 0 : sal_Bool Animation::Start( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz, long nExtraData,
281 : : OutputDevice* pFirstFrameOutDev )
282 : : {
283 : 0 : sal_Bool bRet = sal_False;
284 : :
285 [ # # ]: 0 : if( !maList.empty() )
286 : : {
287 [ # # ]: 0 : if( ( pOut->GetOutDevType() == OUTDEV_WINDOW )
[ # # # # ]
[ # # ]
288 : 0 : && !mbLoopTerminated
289 : 0 : && ( ANIMATION_TIMEOUT_ON_CLICK != maList[ mnPos ]->nWait )
290 : : )
291 : : {
292 : : ImplAnimView* pView;
293 : 0 : ImplAnimView* pMatch = NULL;
294 : :
295 [ # # ]: 0 : for( size_t i = 0; i < maViewList.size(); ++i )
296 : : {
297 : 0 : pView = maViewList[ i ];
298 [ # # ]: 0 : if( pView->ImplMatches( pOut, nExtraData ) )
299 : : {
300 [ # # # # ]: 0 : if( pView->ImplGetOutPos() == rDestPt &&
[ # # ]
301 [ # # ][ # # ]: 0 : pView->ImplGetOutSizePix() == pOut->LogicToPixel( rDestSz ) )
[ # # ]
302 : : {
303 : 0 : pView->ImplRepaint();
304 : 0 : pMatch = pView;
305 : : }
306 : : else
307 : : {
308 [ # # ]: 0 : delete maViewList[ i ];
309 [ # # ][ # # ]: 0 : maViewList.erase( maViewList.begin() + i );
310 : 0 : pView = NULL;
311 : : }
312 : :
313 : 0 : break;
314 : : }
315 : : }
316 : :
317 [ # # ]: 0 : if( maViewList.empty() )
318 : : {
319 : 0 : maTimer.Stop();
320 : 0 : mbIsInAnimation = sal_False;
321 : 0 : mnPos = 0UL;
322 : : }
323 : :
324 [ # # ]: 0 : if( !pMatch )
325 [ # # ][ # # ]: 0 : maViewList.push_back( new ImplAnimView( this, pOut, rDestPt, rDestSz, nExtraData, pFirstFrameOutDev ) );
326 : :
327 [ # # ]: 0 : if( !mbIsInAnimation )
328 : : {
329 : 0 : ImplRestartTimer( maList[ mnPos ]->nWait );
330 : 0 : mbIsInAnimation = sal_True;
331 : : }
332 : : }
333 : : else
334 : 0 : Draw( pOut, rDestPt, rDestSz );
335 : :
336 : 0 : bRet = sal_True;
337 : : }
338 : :
339 : 0 : return bRet;
340 : : }
341 : :
342 : : // -----------------------------------------------------------------------
343 : :
344 : 0 : void Animation::Stop( OutputDevice* pOut, long nExtraData )
345 : : {
346 [ # # ]: 0 : for( size_t i = 0; i < maViewList.size(); )
347 : : {
348 : :
349 : :
350 : 0 : ImplAnimView* pView = maViewList[ i ];
351 [ # # ]: 0 : if( pView->ImplMatches( pOut, nExtraData ) )
352 : : {
353 [ # # ]: 0 : delete pView;
354 [ # # ][ # # ]: 0 : maViewList.erase( maViewList.begin() + i );
355 : : }
356 : : else
357 : 0 : i++;
358 : : }
359 : :
360 [ # # ]: 0 : if( maViewList.empty() )
361 : : {
362 : 0 : maTimer.Stop();
363 : 0 : mbIsInAnimation = sal_False;
364 : : }
365 : 0 : }
366 : :
367 : : // -----------------------------------------------------------------------
368 : :
369 : 0 : void Animation::Draw( OutputDevice* pOut, const Point& rDestPt ) const
370 : : {
371 [ # # ]: 0 : Draw( pOut, rDestPt, pOut->PixelToLogic( maGlobalSize ) );
372 : 0 : }
373 : :
374 : : // -----------------------------------------------------------------------
375 : :
376 : 0 : void Animation::Draw( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz ) const
377 : : {
378 : 0 : const size_t nCount = maList.size();
379 : :
380 [ # # ]: 0 : if( nCount )
381 : : {
382 : 0 : AnimationBitmap* pObj = maList[ Min( mnPos, nCount - 1 ) ];
383 : :
384 [ # # ]: 0 : if( pOut->GetConnectMetaFile()
[ # # # # ]
385 : 0 : || ( pOut->GetOutDevType() == OUTDEV_PRINTER )
386 : : )
387 : 0 : maList[ 0 ]->aBmpEx.Draw( pOut, rDestPt, rDestSz );
388 [ # # ]: 0 : else if( ANIMATION_TIMEOUT_ON_CLICK == pObj->nWait )
389 : 0 : pObj->aBmpEx.Draw( pOut, rDestPt, rDestSz );
390 : : else
391 : : {
392 : 0 : const size_t nOldPos = mnPos;
393 [ # # ]: 0 : ( (Animation*) this )->mnPos = mbLoopTerminated ? ( nCount - 1UL ) : mnPos;
394 [ # # ][ # # ]: 0 : delete new ImplAnimView( (Animation*) this, pOut, rDestPt, rDestSz, 0 );
395 : 0 : ( (Animation*) this )->mnPos = nOldPos;
396 : : }
397 : : }
398 : 0 : }
399 : :
400 : : // -----------------------------------------------------------------------
401 : :
402 : 0 : void Animation::ImplRestartTimer( sal_uLong nTimeout )
403 : : {
404 : 0 : maTimer.SetTimeout( Max( nTimeout, (sal_uLong)(MIN_TIMEOUT + ( mnAnimCount - 1 ) * INC_TIMEOUT) ) * 10L );
405 : 0 : maTimer.Start();
406 : 0 : }
407 : :
408 : : // -----------------------------------------------------------------------
409 : : typedef ::std::vector< AInfo* > AInfoList_impl;
410 : :
411 : 0 : IMPL_LINK_NOARG(Animation, ImplTimeoutHdl)
412 : : {
413 : 0 : const size_t nAnimCount = maList.size();
414 [ # # ]: 0 : AInfoList_impl aAInfoList;
415 : :
416 [ # # ]: 0 : if( nAnimCount )
417 : : {
418 : : ImplAnimView* pView;
419 : 0 : sal_Bool bGlobalPause = sal_True;
420 : :
421 [ # # ][ # # ]: 0 : if( maNotifyLink.IsSet() )
422 : : {
423 : : AInfo* pAInfo;
424 : :
425 : : // create AInfo-List
426 [ # # ]: 0 : for( size_t i = 0, n = maViewList.size(); i < n; ++i )
427 [ # # ][ # # ]: 0 : aAInfoList.push_back( maViewList[ i ]->ImplCreateAInfo() );
428 : :
429 [ # # ]: 0 : maNotifyLink.Call( this );
430 : :
431 : : // set view state from AInfo structure
432 [ # # ]: 0 : for( size_t i = 0, n = aAInfoList.size(); i < n; ++i )
433 : : {
434 : 0 : pAInfo = aAInfoList[ i ];
435 [ # # ]: 0 : if( !pAInfo->pViewData )
436 : : {
437 : : pView = new ImplAnimView( this, pAInfo->pOutDev,
438 [ # # ][ # # ]: 0 : pAInfo->aStartOrg, pAInfo->aStartSize, pAInfo->nExtraData );
439 : :
440 [ # # ]: 0 : maViewList.push_back( pView );
441 : : }
442 : : else
443 : 0 : pView = (ImplAnimView*) pAInfo->pViewData;
444 : :
445 : 0 : pView->ImplPause( pAInfo->bPause );
446 : 0 : pView->ImplSetMarked( sal_True );
447 : : }
448 : :
449 : : // delete AInfo structures
450 [ # # ]: 0 : for( size_t i = 0, n = aAInfoList.size(); i < n; ++i )
451 [ # # ][ # # ]: 0 : delete aAInfoList[ i ];
452 : 0 : aAInfoList.clear();
453 : :
454 : : // delete all unmarked views and reset marked state
455 [ # # ]: 0 : for( size_t i = 0; i < maViewList.size(); )
456 : : {
457 : 0 : pView = maViewList[ i ];
458 [ # # ]: 0 : if( !pView->ImplIsMarked() )
459 : : {
460 [ # # ][ # # ]: 0 : delete pView;
461 [ # # ][ # # ]: 0 : maViewList.erase( maViewList.begin() + i );
462 : : }
463 : : else
464 : : {
465 [ # # ]: 0 : if( !pView->ImplIsPause() )
466 : 0 : bGlobalPause = sal_False;
467 : :
468 : 0 : pView->ImplSetMarked( sal_False );
469 : 0 : i++;
470 : : }
471 : : }
472 : : }
473 : : else
474 : 0 : bGlobalPause = sal_False;
475 : :
476 [ # # ]: 0 : if( maViewList.empty() )
477 [ # # ]: 0 : Stop();
478 [ # # ]: 0 : else if( bGlobalPause )
479 [ # # ]: 0 : ImplRestartTimer( 10 );
480 : : else
481 : : {
482 [ # # ][ # # ]: 0 : AnimationBitmap* pStepBmp = (++mnPos < maList.size()) ? maList[ mnPos ] : NULL;
483 : :
484 [ # # ]: 0 : if( !pStepBmp )
485 : : {
486 [ # # ]: 0 : if( mnLoops == 1 )
487 : : {
488 [ # # ]: 0 : Stop();
489 : 0 : mbLoopTerminated = sal_True;
490 : 0 : mnPos = nAnimCount - 1UL;
491 [ # # ][ # # ]: 0 : maBitmapEx = maList[ mnPos ]->aBmpEx;
492 : 0 : return 0L;
493 : : }
494 : : else
495 : : {
496 [ # # ]: 0 : if( mnLoops )
497 : 0 : mnLoops--;
498 : :
499 : 0 : mnPos = 0;
500 [ # # ]: 0 : pStepBmp = maList[ mnPos ];
501 : : }
502 : : }
503 : :
504 : : // Paint all views; after painting check, if view is
505 : : // marked; in this case remove view, because area of output
506 : : // lies out of display area of window; mark state is
507 : : // set from view itself
508 [ # # ]: 0 : for( size_t i = 0; i < maViewList.size(); )
509 : : {
510 : 0 : pView = maViewList[ i ];
511 [ # # ]: 0 : pView->ImplDraw( mnPos );
512 : :
513 [ # # ]: 0 : if( pView->ImplIsMarked() )
514 : : {
515 [ # # ][ # # ]: 0 : delete pView;
516 [ # # ][ # # ]: 0 : maViewList.erase( maViewList.begin() + i );
517 : : }
518 : : else
519 : 0 : i++;
520 : : }
521 : :
522 : : // stop or restart timer
523 [ # # ]: 0 : if( maViewList.empty() )
524 [ # # ]: 0 : Stop();
525 : : else
526 [ # # ]: 0 : ImplRestartTimer( pStepBmp->nWait );
527 : : }
528 : : }
529 : : else
530 [ # # ]: 0 : Stop();
531 : :
532 : 0 : return 0L;
533 : : }
534 : :
535 : : // -----------------------------------------------------------------------
536 : :
537 : 179 : sal_Bool Animation::Insert( const AnimationBitmap& rStepBmp )
538 : : {
539 : 179 : sal_Bool bRet = sal_False;
540 : :
541 [ + - ]: 179 : if( !IsInAnimation() )
542 : : {
543 : 179 : Point aPoint;
544 [ + - ]: 179 : Rectangle aGlobalRect( aPoint, maGlobalSize );
545 : :
546 [ + - ][ + - ]: 179 : maGlobalSize = aGlobalRect.Union( Rectangle( rStepBmp.aPosPix, rStepBmp.aSizePix ) ).GetSize();
[ + - ]
547 [ + - ][ + - ]: 179 : maList.push_back( new AnimationBitmap( rStepBmp ) );
[ + - ]
548 : :
549 : : // zunaechst nehmen wir die erste BitmapEx als Ersatz-BitmapEx
550 [ + + ]: 179 : if( maList.size() == 1 )
551 [ + - ]: 26 : maBitmapEx = rStepBmp.aBmpEx;
552 : :
553 : 179 : bRet = sal_True;
554 : : }
555 : :
556 : 179 : return bRet;
557 : : }
558 : :
559 : : // -----------------------------------------------------------------------
560 : :
561 : 8 : const AnimationBitmap& Animation::Get( sal_uInt16 nAnimation ) const
562 : : {
563 : : DBG_ASSERT( ( nAnimation < maList.size() ), "No object at this position" );
564 : 8 : return *maList[ nAnimation ];
565 : : }
566 : :
567 : : // -----------------------------------------------------------------------
568 : :
569 : 0 : void Animation::Replace( const AnimationBitmap& rNewAnimationBitmap, sal_uInt16 nAnimation )
570 : : {
571 : : DBG_ASSERT( ( nAnimation < maList.size() ), "No object at this position" );
572 : :
573 [ # # ]: 0 : delete maList[ nAnimation ];
574 [ # # ]: 0 : maList[ nAnimation ] = new AnimationBitmap( rNewAnimationBitmap );
575 : :
576 : : // Falls wir an erster Stelle einfuegen,
577 : : // muessen wir natuerlich auch,
578 : : // auch die Ersatzdarstellungs-BitmapEx
579 : : // aktualisieren;
580 [ # # # # : 0 : if ( ( !nAnimation
# # ][ # # ]
[ # # ][ # # ]
581 : 0 : && ( !mbLoopTerminated
582 : 0 : || ( maList.size() == 1 )
583 : : )
584 : : )
585 : : ||
586 : 0 : ( ( nAnimation == maList.size() - 1 )
587 : : && mbLoopTerminated
588 : : )
589 : : )
590 : : {
591 : 0 : maBitmapEx = rNewAnimationBitmap.aBmpEx;
592 : : }
593 : 0 : }
594 : :
595 : : // -----------------------------------------------------------------------
596 : :
597 : 17 : void Animation::SetLoopCount( const sal_uLong nLoopCount )
598 : : {
599 : 17 : mnLoopCount = nLoopCount;
600 : 17 : ResetLoopCount();
601 : 17 : }
602 : :
603 : : // -----------------------------------------------------------------------
604 : :
605 : 17 : void Animation::ResetLoopCount()
606 : : {
607 : 17 : mnLoops = mnLoopCount;
608 : 17 : mbLoopTerminated = sal_False;
609 : 17 : }
610 : :
611 : : // -----------------------------------------------------------------------
612 : :
613 : 0 : sal_Bool Animation::Convert( BmpConversion eConversion )
614 : : {
615 : : DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
616 : :
617 : : sal_Bool bRet;
618 : :
619 [ # # ][ # # ]: 0 : if( !IsInAnimation() && !maList.empty() )
[ # # ]
620 : : {
621 : 0 : bRet = sal_True;
622 : :
623 [ # # ][ # # ]: 0 : for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
[ # # ]
624 : 0 : bRet = maList[ i ]->aBmpEx.Convert( eConversion );
625 : :
626 : 0 : maBitmapEx.Convert( eConversion );
627 : : }
628 : : else
629 : 0 : bRet = sal_False;
630 : :
631 : 0 : return bRet;
632 : : }
633 : :
634 : : // -----------------------------------------------------------------------
635 : :
636 : 0 : sal_Bool Animation::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce )
637 : : {
638 : : DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
639 : :
640 : : sal_Bool bRet;
641 : :
642 [ # # ][ # # ]: 0 : if( !IsInAnimation() && !maList.empty() )
[ # # ]
643 : : {
644 : 0 : bRet = sal_True;
645 : :
646 [ # # ][ # # ]: 0 : for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
[ # # ]
647 : 0 : bRet = maList[ i ]->aBmpEx.ReduceColors( nNewColorCount, eReduce );
648 : :
649 : 0 : maBitmapEx.ReduceColors( nNewColorCount, eReduce );
650 : : }
651 : : else
652 : 0 : bRet = sal_False;
653 : :
654 : 0 : return bRet;
655 : : }
656 : :
657 : : // -----------------------------------------------------------------------
658 : :
659 : 0 : sal_Bool Animation::Invert()
660 : : {
661 : : DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
662 : :
663 : : sal_Bool bRet;
664 : :
665 [ # # ][ # # ]: 0 : if( !IsInAnimation() && !maList.empty() )
[ # # ]
666 : : {
667 : 0 : bRet = sal_True;
668 : :
669 [ # # ][ # # ]: 0 : for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
[ # # ]
670 : 0 : bRet = maList[ i ]->aBmpEx.Invert();
671 : :
672 : 0 : maBitmapEx.Invert();
673 : : }
674 : : else
675 : 0 : bRet = sal_False;
676 : :
677 : 0 : return bRet;
678 : : }
679 : :
680 : : // -----------------------------------------------------------------------
681 : :
682 : 0 : sal_Bool Animation::Mirror( sal_uLong nMirrorFlags )
683 : : {
684 : : DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
685 : :
686 : : sal_Bool bRet;
687 : :
688 [ # # ][ # # ]: 0 : if( !IsInAnimation() && !maList.empty() )
[ # # ]
689 : : {
690 : 0 : bRet = sal_True;
691 : :
692 [ # # ]: 0 : if( nMirrorFlags )
693 : : {
694 [ # # ][ # # ]: 0 : for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
[ # # ]
695 : : {
696 : 0 : AnimationBitmap* pStepBmp = maList[ i ];
697 [ # # ]: 0 : if( ( bRet = pStepBmp->aBmpEx.Mirror( nMirrorFlags ) ) == sal_True )
698 : : {
699 [ # # ]: 0 : if( nMirrorFlags & BMP_MIRROR_HORZ )
700 : 0 : pStepBmp->aPosPix.X() = maGlobalSize.Width() - pStepBmp->aPosPix.X() - pStepBmp->aSizePix.Width();
701 : :
702 [ # # ]: 0 : if( nMirrorFlags & BMP_MIRROR_VERT )
703 : 0 : pStepBmp->aPosPix.Y() = maGlobalSize.Height() - pStepBmp->aPosPix.Y() - pStepBmp->aSizePix.Height();
704 : : }
705 : : }
706 : :
707 : 0 : maBitmapEx.Mirror( nMirrorFlags );
708 : : }
709 : : }
710 : : else
711 : 0 : bRet = sal_False;
712 : :
713 : 0 : return bRet;
714 : : }
715 : :
716 : : // -----------------------------------------------------------------------
717 : :
718 : 0 : sal_Bool Animation::Adjust( short nLuminancePercent, short nContrastPercent,
719 : : short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
720 : : double fGamma, sal_Bool bInvert )
721 : : {
722 : : DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
723 : :
724 : : sal_Bool bRet;
725 : :
726 [ # # ][ # # ]: 0 : if( !IsInAnimation() && !maList.empty() )
[ # # ]
727 : : {
728 : 0 : bRet = sal_True;
729 : :
730 [ # # ][ # # ]: 0 : for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
[ # # ]
731 : : {
732 : 0 : bRet = maList[ i ]->aBmpEx.Adjust( nLuminancePercent,
733 : : nContrastPercent,
734 : : nChannelRPercent,
735 : : nChannelGPercent,
736 : : nChannelBPercent,
737 : : fGamma, bInvert
738 : 0 : );
739 : : }
740 : :
741 : : maBitmapEx.Adjust( nLuminancePercent, nContrastPercent,
742 : : nChannelRPercent, nChannelGPercent, nChannelBPercent,
743 : 0 : fGamma, bInvert );
744 : : }
745 : : else
746 : 0 : bRet = sal_False;
747 : :
748 : 0 : return bRet;
749 : : }
750 : :
751 : : // -----------------------------------------------------------------------
752 : :
753 : 0 : sal_Bool Animation::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
754 : : {
755 : : DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
756 : :
757 : : sal_Bool bRet;
758 : :
759 [ # # ][ # # ]: 0 : if( !IsInAnimation() && !maList.empty() )
[ # # ]
760 : : {
761 : 0 : bRet = sal_True;
762 : :
763 [ # # ][ # # ]: 0 : for( size_t i = 0, n = maList.size(); ( i < n ) && bRet; ++i )
[ # # ]
764 : 0 : bRet = maList[ i ]->aBmpEx.Filter( eFilter, pFilterParam, pProgress );
765 : :
766 : 0 : maBitmapEx.Filter( eFilter, pFilterParam, pProgress );
767 : : }
768 : : else
769 : 0 : bRet = sal_False;
770 : :
771 : 0 : return bRet;
772 : : }
773 : :
774 : : // -----------------------------------------------------------------------
775 : :
776 : 0 : SvStream& operator<<( SvStream& rOStm, const Animation& rAnimation )
777 : : {
778 : 0 : const sal_uInt16 nCount = rAnimation.Count();
779 : :
780 [ # # ]: 0 : if( nCount )
781 : : {
782 : 0 : const sal_uInt32 nDummy32 = 0UL;
783 : :
784 : : // Falls keine BitmapEx gesetzt wurde, schreiben wir
785 : : // einfach die erste Bitmap der Animation
786 [ # # ]: 0 : if( !rAnimation.GetBitmapEx().GetBitmap() )
787 : 0 : rOStm << rAnimation.Get( 0 ).aBmpEx;
788 : : else
789 : 0 : rOStm << rAnimation.GetBitmapEx();
790 : :
791 : : // Kennung schreiben ( SDANIMA1 )
792 : 0 : rOStm << (sal_uInt32) 0x5344414e << (sal_uInt32) 0x494d4931;
793 : :
794 [ # # ]: 0 : for( sal_uInt16 i = 0; i < nCount; i++ )
795 : : {
796 : 0 : const AnimationBitmap& rAnimBmp = rAnimation.Get( i );
797 : 0 : const sal_uInt16 nRest = nCount - i - 1;
798 : :
799 : : // AnimationBitmap schreiben
800 : 0 : rOStm << rAnimBmp.aBmpEx;
801 : 0 : rOStm << rAnimBmp.aPosPix;
802 : 0 : rOStm << rAnimBmp.aSizePix;
803 : 0 : rOStm << rAnimation.maGlobalSize;
804 [ # # ]: 0 : rOStm << (sal_uInt16) ( ( ANIMATION_TIMEOUT_ON_CLICK == rAnimBmp.nWait ) ? 65535 : rAnimBmp.nWait );
805 : 0 : rOStm << (sal_uInt16) rAnimBmp.eDisposal;
806 : 0 : rOStm << (sal_uInt8) rAnimBmp.bUserInput;
807 : 0 : rOStm << (sal_uInt32) rAnimation.mnLoopCount;
808 : 0 : rOStm << nDummy32; // unbenutzt
809 : 0 : rOStm << nDummy32; // unbenutzt
810 : 0 : rOStm << nDummy32; // unbenutzt
811 [ # # ]: 0 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStm, rtl::OString()); // dummy
812 : 0 : rOStm << nRest; // Anzahl der Strukturen, die noch _folgen_
813 : : }
814 : : }
815 : :
816 : 0 : return rOStm;
817 : : }
818 : :
819 : : // -----------------------------------------------------------------------
820 : :
821 : 0 : SvStream& operator>>( SvStream& rIStm, Animation& rAnimation )
822 : : {
823 [ # # ]: 0 : Bitmap aBmp;
824 : 0 : sal_uLong nStmPos = rIStm.Tell();
825 : : sal_uInt32 nAnimMagic1, nAnimMagic2;
826 : 0 : sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt();
827 : 0 : sal_Bool bReadAnimations = sal_False;
828 : :
829 [ # # ]: 0 : rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
830 : 0 : nStmPos = rIStm.Tell();
831 [ # # ][ # # ]: 0 : rIStm >> nAnimMagic1 >> nAnimMagic2;
832 : :
833 [ # # ]: 0 : rAnimation.Clear();
834 : :
835 : : // Wenn die BitmapEx am Anfang schon gelesen
836 : : // wurde ( von Graphic ), koennen wir direkt die Animationsbitmaps einlesen
837 [ # # ][ # # ]: 0 : if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() )
[ # # ][ # # ]
838 : 0 : bReadAnimations = sal_True;
839 : : // ansonsten versuchen wir erstmal die Bitmap(-Ex) zu lesen
840 : : else
841 : : {
842 [ # # ]: 0 : rIStm.Seek( nStmPos );
843 [ # # ]: 0 : rIStm >> rAnimation.maBitmapEx;
844 : 0 : nStmPos = rIStm.Tell();
845 [ # # ][ # # ]: 0 : rIStm >> nAnimMagic1 >> nAnimMagic2;
846 : :
847 [ # # ][ # # ]: 0 : if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() )
[ # # ][ # # ]
848 : 0 : bReadAnimations = sal_True;
849 : : else
850 [ # # ]: 0 : rIStm.Seek( nStmPos );
851 : : }
852 : :
853 : : // ggf. Animationsbitmaps lesen
854 [ # # ]: 0 : if( bReadAnimations )
855 : : {
856 [ # # ]: 0 : AnimationBitmap aAnimBmp;
857 [ # # ]: 0 : BitmapEx aBmpEx;
858 : : sal_uInt32 nTmp32;
859 : : sal_uInt16 nTmp16;
860 : : sal_uInt8 cTmp;
861 : :
862 [ # # # # ]: 0 : do
[ # # ]
863 : : {
864 [ # # ]: 0 : rIStm >> aAnimBmp.aBmpEx;
865 [ # # ]: 0 : rIStm >> aAnimBmp.aPosPix;
866 [ # # ]: 0 : rIStm >> aAnimBmp.aSizePix;
867 [ # # ]: 0 : rIStm >> rAnimation.maGlobalSize;
868 [ # # ][ # # ]: 0 : rIStm >> nTmp16; aAnimBmp.nWait = ( ( 65535 == nTmp16 ) ? ANIMATION_TIMEOUT_ON_CLICK : nTmp16 );
869 [ # # ]: 0 : rIStm >> nTmp16; aAnimBmp.eDisposal = ( Disposal) nTmp16;
870 [ # # ]: 0 : rIStm >> cTmp; aAnimBmp.bUserInput = (sal_Bool) cTmp;
871 [ # # ]: 0 : rIStm >> nTmp32; rAnimation.mnLoopCount = (sal_uInt16) nTmp32;
872 [ # # ]: 0 : rIStm >> nTmp32; // unbenutzt
873 [ # # ]: 0 : rIStm >> nTmp32; // unbenutzt
874 [ # # ]: 0 : rIStm >> nTmp32; // unbenutzt
875 [ # # ]: 0 : read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(rIStm); // unbenutzt
876 [ # # ]: 0 : rIStm >> nTmp16; // Rest zu lesen
877 : :
878 [ # # ]: 0 : rAnimation.Insert( aAnimBmp );
879 : : }
880 : 0 : while( nTmp16 && !rIStm.GetError() );
881 : :
882 [ # # ][ # # ]: 0 : rAnimation.ResetLoopCount();
[ # # ]
883 : : }
884 : :
885 [ # # ]: 0 : rIStm.SetNumberFormatInt( nOldFormat );
886 : :
887 [ # # ]: 0 : return rIStm;
888 : : }
889 : :
890 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|