1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: animate.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #define ENABLE_BYTESTRING_STREAM_OPERATORS
35 #include <vcl/animate.hxx>
36 #include <tools/debug.hxx>
37 #include <tools/stream.hxx>
39 #include <vcl/virdev.hxx>
40 #include <vcl/window.hxx>
41 #include <impanmvw.hxx>
48 #define MIN_TIMEOUT 2L
49 #define INC_TIMEOUT 0L
55 ULONG
Animation::mnAnimCount
= 0UL;
57 // -------------------
58 // - AnimationBitmap -
59 // -------------------
61 ULONG
AnimationBitmap::GetChecksum() const
63 sal_uInt32 nCrc
= aBmpEx
.GetChecksum();
66 UInt32ToSVBT32( aPosPix
.X(), aBT32
);
67 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
69 UInt32ToSVBT32( aPosPix
.Y(), aBT32
);
70 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
72 UInt32ToSVBT32( aSizePix
.Width(), aBT32
);
73 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
75 UInt32ToSVBT32( aSizePix
.Height(), aBT32
);
76 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
78 UInt32ToSVBT32( (long) nWait
, aBT32
);
79 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
81 UInt32ToSVBT32( (long) eDisposal
, aBT32
);
82 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
84 UInt32ToSVBT32( (long) bUserInput
, aBT32
);
85 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
94 Animation::Animation() :
98 meCycleMode ( CYCLE_NORMAL
),
99 mbIsInAnimation ( FALSE
),
100 mbLoopTerminated ( FALSE
),
101 mbIsWaiting ( FALSE
)
103 DBG_CTOR( Animation
, NULL
);
104 maTimer
.SetTimeoutHdl( LINK( this, Animation
, ImplTimeoutHdl
) );
105 mpViewList
= new List
;
108 // -----------------------------------------------------------------------
110 Animation::Animation( const Animation
& rAnimation
) :
111 maBitmapEx ( rAnimation
.maBitmapEx
),
112 maGlobalSize ( rAnimation
.maGlobalSize
),
113 mnLoopCount ( rAnimation
.mnLoopCount
),
114 mnPos ( rAnimation
.mnPos
),
115 meCycleMode ( rAnimation
.meCycleMode
),
116 mbIsInAnimation ( FALSE
),
117 mbLoopTerminated ( rAnimation
.mbLoopTerminated
),
118 mbIsWaiting ( rAnimation
.mbIsWaiting
)
120 DBG_CTOR( Animation
, NULL
);
122 for( long i
= 0, nCount
= rAnimation
.maList
.Count(); i
< nCount
; i
++ )
123 maList
.Insert( new AnimationBitmap( *(AnimationBitmap
*) rAnimation
.maList
.GetObject( i
) ), LIST_APPEND
);
125 maTimer
.SetTimeoutHdl( LINK( this, Animation
, ImplTimeoutHdl
) );
126 mpViewList
= new List
;
127 mnLoops
= mbLoopTerminated
? 0 : mnLoopCount
;
130 // -----------------------------------------------------------------------
132 Animation::~Animation()
134 DBG_DTOR( Animation
, NULL
);
136 if( mbIsInAnimation
)
139 for( void* pStepBmp
= maList
.First(); pStepBmp
; pStepBmp
= maList
.Next() )
140 delete (AnimationBitmap
*) pStepBmp
;
142 for( void* pView
= mpViewList
->First(); pView
; pView
= mpViewList
->Next() )
143 delete (ImplAnimView
*) pView
;
148 // -----------------------------------------------------------------------
150 Animation
& Animation::operator=( const Animation
& rAnimation
)
154 for( long i
= 0, nCount
= rAnimation
.maList
.Count(); i
< nCount
; i
++ )
155 maList
.Insert( new AnimationBitmap( *(AnimationBitmap
*) rAnimation
.maList
.GetObject( i
) ), LIST_APPEND
);
157 maGlobalSize
= rAnimation
.maGlobalSize
;
158 maBitmapEx
= rAnimation
.maBitmapEx
;
159 meCycleMode
= rAnimation
.meCycleMode
;
160 mnLoopCount
= rAnimation
.mnLoopCount
;
161 mnPos
= rAnimation
.mnPos
;
162 mbLoopTerminated
= rAnimation
.mbLoopTerminated
;
163 mbIsWaiting
= rAnimation
.mbIsWaiting
;
164 mnLoops
= mbLoopTerminated
? 0 : mnLoopCount
;
169 // -----------------------------------------------------------------------
171 BOOL
Animation::operator==( const Animation
& rAnimation
) const
173 const ULONG nCount
= maList
.Count();
176 if( rAnimation
.maList
.Count() == nCount
&&
177 rAnimation
.maBitmapEx
== maBitmapEx
&&
178 rAnimation
.maGlobalSize
== maGlobalSize
&&
179 rAnimation
.meCycleMode
== meCycleMode
)
183 for( ULONG n
= 0; n
< nCount
; n
++ )
185 if( ( *(AnimationBitmap
*) maList
.GetObject( n
) ) !=
186 ( *(AnimationBitmap
*) rAnimation
.maList
.GetObject( n
) ) )
197 // ------------------------------------------------------------------
199 BOOL
Animation::IsEqual( const Animation
& rAnimation
) const
201 const ULONG nCount
= maList
.Count();
204 if( rAnimation
.maList
.Count() == nCount
&&
205 rAnimation
.maBitmapEx
.IsEqual( maBitmapEx
) &&
206 rAnimation
.maGlobalSize
== maGlobalSize
&&
207 rAnimation
.meCycleMode
== meCycleMode
)
209 for( ULONG n
= 0; ( n
< nCount
) && !bRet
; n
++ )
210 if( ( (AnimationBitmap
*) maList
.GetObject( n
) )->IsEqual( *(AnimationBitmap
*) rAnimation
.maList
.GetObject( n
) ) )
217 // ------------------------------------------------------------------
219 BOOL
Animation::IsEmpty() const
221 return( maBitmapEx
.IsEmpty() && !maList
.Count() );
224 // ------------------------------------------------------------------
226 void Animation::SetEmpty()
229 mbIsInAnimation
= FALSE
;
230 maGlobalSize
= Size();
231 maBitmapEx
.SetEmpty();
233 for( void* pStepBmp
= maList
.First(); pStepBmp
; pStepBmp
= maList
.Next() )
234 delete (AnimationBitmap
*) pStepBmp
;
237 for( void* pView
= mpViewList
->First(); pView
; pView
= mpViewList
->Next() )
238 delete (ImplAnimView
*) pView
;
242 // -----------------------------------------------------------------------
244 void Animation::Clear()
249 // -----------------------------------------------------------------------
251 BOOL
Animation::IsTransparent() const
254 Rectangle
aRect( aPoint
, maGlobalSize
);
257 // Falls irgendein 'kleines' Bildchen durch den Hintergrund
258 // ersetzt werden soll, muessen wir 'transparent' sein, um
259 // richtig dargestellt zu werden, da die Appl. aus Optimierungsgruenden
260 // kein Invalidate auf nicht-transp. Grafiken ausfuehren
261 for( long i
= 0, nCount
= maList
.Count(); i
< nCount
; i
++ )
263 const AnimationBitmap
* pAnimBmp
= (AnimationBitmap
*) maList
.GetObject( i
);
265 if( DISPOSE_BACK
== pAnimBmp
->eDisposal
&& Rectangle( pAnimBmp
->aPosPix
, pAnimBmp
->aSizePix
) != aRect
)
273 bRet
= maBitmapEx
.IsTransparent();
278 // -----------------------------------------------------------------------
280 ULONG
Animation::GetSizeBytes() const
282 ULONG nSizeBytes
= GetBitmapEx().GetSizeBytes();
284 for( long i
= 0, nCount
= maList
.Count(); i
< nCount
; i
++ )
286 const AnimationBitmap
* pAnimBmp
= (AnimationBitmap
*) maList
.GetObject( i
);
287 nSizeBytes
+= pAnimBmp
->aBmpEx
.GetSizeBytes();
293 // -----------------------------------------------------------------------
295 ULONG
Animation::GetChecksum() const
298 sal_uInt32 nCrc
= GetBitmapEx().GetChecksum();
300 UInt32ToSVBT32( maList
.Count(), aBT32
);
301 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
303 UInt32ToSVBT32( maGlobalSize
.Width(), aBT32
);
304 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
306 UInt32ToSVBT32( maGlobalSize
.Height(), aBT32
);
307 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
309 UInt32ToSVBT32( (long) meCycleMode
, aBT32
);
310 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
312 for( long i
= 0, nCount
= maList
.Count(); i
< nCount
; i
++ )
314 UInt32ToSVBT32( ( (AnimationBitmap
*) maList
.GetObject( i
) )->GetChecksum(), aBT32
);
315 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
321 // -----------------------------------------------------------------------
323 BOOL
Animation::Start( OutputDevice
* pOut
, const Point
& rDestPt
, long nExtraData
,
324 OutputDevice
* pFirstFrameOutDev
)
326 return Start( pOut
, rDestPt
, pOut
->PixelToLogic( maGlobalSize
), nExtraData
, pFirstFrameOutDev
);
329 // -----------------------------------------------------------------------
331 BOOL
Animation::Start( OutputDevice
* pOut
, const Point
& rDestPt
, const Size
& rDestSz
, long nExtraData
,
332 OutputDevice
* pFirstFrameOutDev
)
338 if( ( pOut
->GetOutDevType() == OUTDEV_WINDOW
) && !mbLoopTerminated
&&
339 ( ANIMATION_TIMEOUT_ON_CLICK
!= ( (AnimationBitmap
*) maList
.GetObject( mnPos
) )->nWait
) )
342 ImplAnimView
* pMatch
= NULL
;
344 for( pView
= (ImplAnimView
*) mpViewList
->First(); pView
; pView
= (ImplAnimView
*) mpViewList
->Next() )
346 if( pView
->ImplMatches( pOut
, nExtraData
) )
348 if( pView
->ImplGetOutPos() == rDestPt
&&
349 pView
->ImplGetOutSizePix() == pOut
->LogicToPixel( rDestSz
) )
351 pView
->ImplRepaint();
356 delete (ImplAnimView
*) mpViewList
->Remove( pView
);
364 if( !mpViewList
->Count() )
367 mbIsInAnimation
= FALSE
;
372 mpViewList
->Insert( new ImplAnimView( this, pOut
, rDestPt
, rDestSz
, nExtraData
, pFirstFrameOutDev
), LIST_APPEND
);
374 if( !mbIsInAnimation
)
376 ImplRestartTimer( ( (AnimationBitmap
*) maList
.GetObject( mnPos
) )->nWait
);
377 mbIsInAnimation
= TRUE
;
381 Draw( pOut
, rDestPt
, rDestSz
);
389 // -----------------------------------------------------------------------
391 void Animation::Stop( OutputDevice
* pOut
, long nExtraData
)
393 ImplAnimView
* pView
= (ImplAnimView
*) mpViewList
->First();
397 if( pView
->ImplMatches( pOut
, nExtraData
) )
399 delete (ImplAnimView
*) mpViewList
->Remove( pView
);
400 pView
= (ImplAnimView
*) mpViewList
->GetCurObject();
403 pView
= (ImplAnimView
*) mpViewList
->Next();
406 if( !mpViewList
->Count() )
409 mbIsInAnimation
= FALSE
;
413 // -----------------------------------------------------------------------
415 void Animation::Draw( OutputDevice
* pOut
, const Point
& rDestPt
) const
417 Draw( pOut
, rDestPt
, pOut
->PixelToLogic( maGlobalSize
) );
420 // -----------------------------------------------------------------------
422 void Animation::Draw( OutputDevice
* pOut
, const Point
& rDestPt
, const Size
& rDestSz
) const
424 const ULONG nCount
= maList
.Count();
428 AnimationBitmap
* pObj
= (AnimationBitmap
*) maList
.GetObject( Min( mnPos
, (long) nCount
- 1L ) );
430 if( pOut
->GetConnectMetaFile() || ( pOut
->GetOutDevType() == OUTDEV_PRINTER
) )
431 ( (AnimationBitmap
*) maList
.GetObject( 0 ) )->aBmpEx
.Draw( pOut
, rDestPt
, rDestSz
);
432 else if( ANIMATION_TIMEOUT_ON_CLICK
== pObj
->nWait
)
433 pObj
->aBmpEx
.Draw( pOut
, rDestPt
, rDestSz
);
436 const ULONG nOldPos
= mnPos
;
437 ( (Animation
*) this )->mnPos
= mbLoopTerminated
? ( nCount
- 1UL ) : mnPos
;
438 delete new ImplAnimView( (Animation
*) this, pOut
, rDestPt
, rDestSz
, 0 );
439 ( (Animation
*) this )->mnPos
= nOldPos
;
444 // -----------------------------------------------------------------------
446 void Animation::ImplRestartTimer( ULONG nTimeout
)
448 maTimer
.SetTimeout( Max( nTimeout
, (ULONG
)(MIN_TIMEOUT
+ ( mnAnimCount
- 1 ) * INC_TIMEOUT
) ) * 10L );
452 // -----------------------------------------------------------------------
454 IMPL_LINK( Animation
, ImplTimeoutHdl
, Timer
*, EMPTYARG
)
456 const ULONG nAnimCount
= maList
.Count();
461 BOOL bGlobalPause
= TRUE
;
463 if( maNotifyLink
.IsSet() )
468 for( pView
= (ImplAnimView
*) mpViewList
->First(); pView
; pView
= (ImplAnimView
*) mpViewList
->Next() )
469 maAInfoList
.Insert( pView
->ImplCreateAInfo() );
471 maNotifyLink
.Call( this );
473 // set view state from AInfo structure
474 for( pAInfo
= (AInfo
*) maAInfoList
.First(); pAInfo
; pAInfo
= (AInfo
*) maAInfoList
.Next() )
476 if( !pAInfo
->pViewData
)
478 pView
= new ImplAnimView( this, pAInfo
->pOutDev
,
479 pAInfo
->aStartOrg
, pAInfo
->aStartSize
, pAInfo
->nExtraData
);
481 mpViewList
->Insert( pView
, LIST_APPEND
);
484 pView
= (ImplAnimView
*) pAInfo
->pViewData
;
486 pView
->ImplPause( pAInfo
->bPause
);
487 pView
->ImplSetMarked( TRUE
);
490 // delete AInfo structures
491 for( pAInfo
= (AInfo
*) maAInfoList
.First(); pAInfo
; pAInfo
= (AInfo
*) maAInfoList
.Next() )
492 delete (AInfo
*) pAInfo
;
495 // delete all unmarked views and reset marked state
496 pView
= (ImplAnimView
*) mpViewList
->First();
499 if( !pView
->ImplIsMarked() )
501 delete (ImplAnimView
*) mpViewList
->Remove( pView
);
502 pView
= (ImplAnimView
*) mpViewList
->GetCurObject();
506 if( !pView
->ImplIsPause() )
507 bGlobalPause
= FALSE
;
509 pView
->ImplSetMarked( FALSE
);
510 pView
= (ImplAnimView
*) mpViewList
->Next();
515 bGlobalPause
= FALSE
;
517 if( !mpViewList
->Count() )
519 else if( bGlobalPause
)
520 ImplRestartTimer( 10 );
523 AnimationBitmap
* pStepBmp
= (AnimationBitmap
*) maList
.GetObject( ++mnPos
);
530 mbLoopTerminated
= TRUE
;
531 mnPos
= nAnimCount
- 1UL;
532 maBitmapEx
= ( (AnimationBitmap
*) maList
.GetObject( mnPos
) )->aBmpEx
;
541 pStepBmp
= (AnimationBitmap
*) maList
.GetObject( mnPos
);
545 // Paint all views; after painting check, if view is
546 // marked; in this case remove view, because area of output
547 // lies out of display area of window; mark state is
548 // set from view itself
549 pView
= (ImplAnimView
*) mpViewList
->First();
552 pView
->ImplDraw( mnPos
);
554 if( pView
->ImplIsMarked() )
556 delete (ImplAnimView
*) mpViewList
->Remove( pView
);
557 pView
= (ImplAnimView
*) mpViewList
->GetCurObject();
560 pView
= (ImplAnimView
*) mpViewList
->Next();
563 // stop or restart timer
564 if( !mpViewList
->Count() )
567 ImplRestartTimer( pStepBmp
->nWait
);
576 // -----------------------------------------------------------------------
578 BOOL
Animation::Insert( const AnimationBitmap
& rStepBmp
)
582 if( !IsInAnimation() )
585 Rectangle
aGlobalRect( aPoint
, maGlobalSize
);
587 maGlobalSize
= aGlobalRect
.Union( Rectangle( rStepBmp
.aPosPix
, rStepBmp
.aSizePix
) ).GetSize();
588 maList
.Insert( new AnimationBitmap( rStepBmp
), LIST_APPEND
);
590 // zunaechst nehmen wir die erste BitmapEx als Ersatz-BitmapEx
591 if( maList
.Count() == 1 )
592 maBitmapEx
= rStepBmp
.aBmpEx
;
600 // -----------------------------------------------------------------------
602 const AnimationBitmap
& Animation::Get( USHORT nAnimation
) const
604 DBG_ASSERT( ( nAnimation
< maList
.Count() ), "No object at this position" );
605 return *(AnimationBitmap
*) maList
.GetObject( nAnimation
);
608 // -----------------------------------------------------------------------
610 void Animation::Replace( const AnimationBitmap
& rNewAnimationBitmap
, USHORT nAnimation
)
612 DBG_ASSERT( ( nAnimation
< maList
.Count() ), "No object at this position" );
614 delete (AnimationBitmap
*) maList
.Replace( new AnimationBitmap( rNewAnimationBitmap
), nAnimation
);
616 // Falls wir an erster Stelle einfuegen,
617 // muessen wir natuerlich auch,
618 // auch die Ersatzdarstellungs-BitmapEx
620 if ( ( !nAnimation
&& ( !mbLoopTerminated
|| ( maList
.Count() == 1 ) ) ) ||
621 ( ( nAnimation
== maList
.Count() - 1 ) && mbLoopTerminated
) )
623 maBitmapEx
= rNewAnimationBitmap
.aBmpEx
;
627 // -----------------------------------------------------------------------
629 void Animation::SetLoopCount( const ULONG nLoopCount
)
631 mnLoopCount
= nLoopCount
;
635 // -----------------------------------------------------------------------
637 void Animation::ResetLoopCount()
639 mnLoops
= mnLoopCount
;
640 mbLoopTerminated
= FALSE
;
643 // -----------------------------------------------------------------------
645 BOOL
Animation::Convert( BmpConversion eConversion
)
647 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
651 if( !IsInAnimation() && maList
.Count() )
655 for( void* pStepBmp
= maList
.First(); pStepBmp
&& bRet
; pStepBmp
= maList
.Next() )
656 bRet
= ( ( AnimationBitmap
*) pStepBmp
)->aBmpEx
.Convert( eConversion
);
658 maBitmapEx
.Convert( eConversion
);
666 // -----------------------------------------------------------------------
668 BOOL
Animation::ReduceColors( USHORT nNewColorCount
, BmpReduce eReduce
)
670 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
674 if( !IsInAnimation() && maList
.Count() )
678 for( void* pStepBmp
= maList
.First(); pStepBmp
&& bRet
; pStepBmp
= maList
.Next() )
679 bRet
= ( ( AnimationBitmap
*) pStepBmp
)->aBmpEx
.ReduceColors( nNewColorCount
, eReduce
);
681 maBitmapEx
.ReduceColors( nNewColorCount
, eReduce
);
689 // -----------------------------------------------------------------------
691 BOOL
Animation::Invert()
693 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
697 if( !IsInAnimation() && maList
.Count() )
701 for( void* pStepBmp
= maList
.First(); pStepBmp
&& bRet
; pStepBmp
= maList
.Next() )
702 bRet
= ( ( AnimationBitmap
*) pStepBmp
)->aBmpEx
.Invert();
712 // -----------------------------------------------------------------------
714 BOOL
Animation::Mirror( ULONG nMirrorFlags
)
716 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
720 if( !IsInAnimation() && maList
.Count() )
726 for( AnimationBitmap
* pStepBmp
= (AnimationBitmap
*) maList
.First();
728 pStepBmp
= (AnimationBitmap
*) maList
.Next() )
730 if( ( bRet
= pStepBmp
->aBmpEx
.Mirror( nMirrorFlags
) ) == TRUE
)
732 if( nMirrorFlags
& BMP_MIRROR_HORZ
)
733 pStepBmp
->aPosPix
.X() = maGlobalSize
.Width() - pStepBmp
->aPosPix
.X() - pStepBmp
->aSizePix
.Width();
735 if( nMirrorFlags
& BMP_MIRROR_VERT
)
736 pStepBmp
->aPosPix
.Y() = maGlobalSize
.Height() - pStepBmp
->aPosPix
.Y() - pStepBmp
->aSizePix
.Height();
740 maBitmapEx
.Mirror( nMirrorFlags
);
749 // -----------------------------------------------------------------------
751 BOOL
Animation::Dither( ULONG nDitherFlags
)
753 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
757 if( !IsInAnimation() && maList
.Count() )
761 for( void* pStepBmp
= maList
.First(); pStepBmp
&& bRet
; pStepBmp
= maList
.Next() )
762 bRet
= ( ( AnimationBitmap
*) pStepBmp
)->aBmpEx
.Dither( nDitherFlags
);
764 maBitmapEx
.Dither( nDitherFlags
);
772 // -----------------------------------------------------------------------
774 BOOL
Animation::Adjust( short nLuminancePercent
, short nContrastPercent
,
775 short nChannelRPercent
, short nChannelGPercent
, short nChannelBPercent
,
776 double fGamma
, BOOL bInvert
)
778 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
782 if( !IsInAnimation() && maList
.Count() )
786 for( void* pStepBmp
= maList
.First(); pStepBmp
&& bRet
; pStepBmp
= maList
.Next() )
788 bRet
= ( ( AnimationBitmap
*) pStepBmp
)->aBmpEx
.Adjust( nLuminancePercent
, nContrastPercent
,
789 nChannelRPercent
, nChannelGPercent
, nChannelBPercent
,
793 maBitmapEx
.Adjust( nLuminancePercent
, nContrastPercent
,
794 nChannelRPercent
, nChannelGPercent
, nChannelBPercent
,
803 // -----------------------------------------------------------------------
805 BOOL
Animation::Filter( BmpFilter eFilter
, const BmpFilterParam
* pFilterParam
, const Link
* pProgress
)
807 DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" );
811 if( !IsInAnimation() && maList
.Count() )
815 for( void* pStepBmp
= maList
.First(); pStepBmp
&& bRet
; pStepBmp
= maList
.Next() )
816 bRet
= ( ( AnimationBitmap
*) pStepBmp
)->aBmpEx
.Filter( eFilter
, pFilterParam
, pProgress
);
818 maBitmapEx
.Filter( eFilter
, pFilterParam
, pProgress
);
826 // -----------------------------------------------------------------------
828 SvStream
& operator<<( SvStream
& rOStm
, const Animation
& rAnimation
)
830 const USHORT nCount
= rAnimation
.Count();
834 const ByteString aDummyStr
;
835 const UINT32 nDummy32
= 0UL;
837 // Falls keine BitmapEx gesetzt wurde, schreiben wir
838 // einfach die erste Bitmap der Animation
839 if( !rAnimation
.GetBitmapEx().GetBitmap() )
840 rOStm
<< rAnimation
.Get( 0 ).aBmpEx
;
842 rOStm
<< rAnimation
.GetBitmapEx();
844 // Kennung schreiben ( SDANIMA1 )
845 rOStm
<< (UINT32
) 0x5344414e << (UINT32
) 0x494d4931;
847 for( USHORT i
= 0; i
< nCount
; i
++ )
849 const AnimationBitmap
& rAnimBmp
= rAnimation
.Get( i
);
850 const UINT16 nRest
= nCount
- i
- 1;
852 // AnimationBitmap schreiben
853 rOStm
<< rAnimBmp
.aBmpEx
;
854 rOStm
<< rAnimBmp
.aPosPix
;
855 rOStm
<< rAnimBmp
.aSizePix
;
856 rOStm
<< rAnimation
.maGlobalSize
;
857 rOStm
<< (UINT16
) ( ( ANIMATION_TIMEOUT_ON_CLICK
== rAnimBmp
.nWait
) ? 65535 : rAnimBmp
.nWait
);
858 rOStm
<< (UINT16
) rAnimBmp
.eDisposal
;
859 rOStm
<< (BYTE
) rAnimBmp
.bUserInput
;
860 rOStm
<< (UINT32
) rAnimation
.mnLoopCount
;
861 rOStm
<< nDummy32
; // unbenutzt
862 rOStm
<< nDummy32
; // unbenutzt
863 rOStm
<< nDummy32
; // unbenutzt
864 rOStm
<< aDummyStr
; // unbenutzt
865 rOStm
<< nRest
; // Anzahl der Strukturen, die noch _folgen_
872 // -----------------------------------------------------------------------
874 SvStream
& operator>>( SvStream
& rIStm
, Animation
& rAnimation
)
877 ULONG nStmPos
= rIStm
.Tell();
878 UINT32 nAnimMagic1
, nAnimMagic2
;
879 USHORT nOldFormat
= rIStm
.GetNumberFormatInt();
880 BOOL bReadAnimations
= FALSE
;
882 rIStm
.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
883 nStmPos
= rIStm
.Tell();
884 rIStm
>> nAnimMagic1
>> nAnimMagic2
;
888 // Wenn die BitmapEx am Anfang schon gelesen
889 // wurde ( von Graphic ), koennen wir direkt die Animationsbitmaps einlesen
890 if( ( nAnimMagic1
== 0x5344414e ) && ( nAnimMagic2
== 0x494d4931 ) && !rIStm
.GetError() )
891 bReadAnimations
= TRUE
;
892 // ansonsten versuchen wir erstmal die Bitmap(-Ex) zu lesen
895 rIStm
.Seek( nStmPos
);
896 rIStm
>> rAnimation
.maBitmapEx
;
897 nStmPos
= rIStm
.Tell();
898 rIStm
>> nAnimMagic1
>> nAnimMagic2
;
900 if( ( nAnimMagic1
== 0x5344414e ) && ( nAnimMagic2
== 0x494d4931 ) && !rIStm
.GetError() )
901 bReadAnimations
= TRUE
;
903 rIStm
.Seek( nStmPos
);
906 // ggf. Animationsbitmaps lesen
907 if( bReadAnimations
)
909 AnimationBitmap aAnimBmp
;
911 ByteString aDummyStr
;
918 rIStm
>> aAnimBmp
.aBmpEx
;
919 rIStm
>> aAnimBmp
.aPosPix
;
920 rIStm
>> aAnimBmp
.aSizePix
;
921 rIStm
>> rAnimation
.maGlobalSize
;
922 rIStm
>> nTmp16
; aAnimBmp
.nWait
= ( ( 65535 == nTmp16
) ? ANIMATION_TIMEOUT_ON_CLICK
: nTmp16
);
923 rIStm
>> nTmp16
; aAnimBmp
.eDisposal
= ( Disposal
) nTmp16
;
924 rIStm
>> cTmp
; aAnimBmp
.bUserInput
= (BOOL
) cTmp
;
925 rIStm
>> nTmp32
; rAnimation
.mnLoopCount
= (USHORT
) nTmp32
;
926 rIStm
>> nTmp32
; // unbenutzt
927 rIStm
>> nTmp32
; // unbenutzt
928 rIStm
>> nTmp32
; // unbenutzt
929 rIStm
>> aDummyStr
; // unbenutzt
930 rIStm
>> nTmp16
; // Rest zu lesen
932 rAnimation
.Insert( aAnimBmp
);
934 while( nTmp16
&& !rIStm
.GetError() );
936 rAnimation
.ResetLoopCount();
939 rIStm
.SetNumberFormatInt( nOldFormat
);