/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" #define ENABLE_BYTESTRING_STREAM_OPERATORS #include #include #include #include #include #include #include #include DBG_NAME( Animation ) // ----------- // - Defines - // ----------- #define MIN_TIMEOUT 2L #define INC_TIMEOUT 0L // ----------- // - statics - // ----------- sal_uLong Animation::mnAnimCount = 0UL; // ------------------- // - AnimationBitmap - // ------------------- sal_uLong AnimationBitmap::GetChecksum() const { sal_uInt32 nCrc = aBmpEx.GetChecksum(); SVBT32 aBT32; UInt32ToSVBT32( aPosPix.X(), aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( aPosPix.Y(), aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( aSizePix.Width(), aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( aSizePix.Height(), aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( (long) nWait, aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( (long) eDisposal, aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( (long) bUserInput, aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); return nCrc; } // ------------- // - Animation - // ------------- Animation::Animation() : mnLoopCount ( 0 ), mnLoops ( 0 ), mnPos ( 0 ), meCycleMode ( CYCLE_NORMAL ), mbIsInAnimation ( sal_False ), mbLoopTerminated ( sal_False ), mbIsWaiting ( sal_False ) { DBG_CTOR( Animation, NULL ); maTimer.SetTimeoutHdl( LINK( this, Animation, ImplTimeoutHdl ) ); mpViewList = new List; } // ----------------------------------------------------------------------- Animation::Animation( const Animation& rAnimation ) : maBitmapEx ( rAnimation.maBitmapEx ), maGlobalSize ( rAnimation.maGlobalSize ), mnLoopCount ( rAnimation.mnLoopCount ), mnPos ( rAnimation.mnPos ), meCycleMode ( rAnimation.meCycleMode ), mbIsInAnimation ( sal_False ), mbLoopTerminated ( rAnimation.mbLoopTerminated ), mbIsWaiting ( rAnimation.mbIsWaiting ) { DBG_CTOR( Animation, NULL ); for( long i = 0, nCount = rAnimation.maList.Count(); i < nCount; i++ ) maList.Insert( new AnimationBitmap( *(AnimationBitmap*) rAnimation.maList.GetObject( i ) ), LIST_APPEND ); maTimer.SetTimeoutHdl( LINK( this, Animation, ImplTimeoutHdl ) ); mpViewList = new List; mnLoops = mbLoopTerminated ? 0 : mnLoopCount; } // ----------------------------------------------------------------------- Animation::~Animation() { DBG_DTOR( Animation, NULL ); if( mbIsInAnimation ) Stop(); for( void* pStepBmp = maList.First(); pStepBmp; pStepBmp = maList.Next() ) delete (AnimationBitmap*) pStepBmp; for( void* pView = mpViewList->First(); pView; pView = mpViewList->Next() ) delete (ImplAnimView*) pView; delete mpViewList; } // ----------------------------------------------------------------------- Animation& Animation::operator=( const Animation& rAnimation ) { Clear(); for( long i = 0, nCount = rAnimation.maList.Count(); i < nCount; i++ ) maList.Insert( new AnimationBitmap( *(AnimationBitmap*) rAnimation.maList.GetObject( i ) ), LIST_APPEND ); maGlobalSize = rAnimation.maGlobalSize; maBitmapEx = rAnimation.maBitmapEx; meCycleMode = rAnimation.meCycleMode; mnLoopCount = rAnimation.mnLoopCount; mnPos = rAnimation.mnPos; mbLoopTerminated = rAnimation.mbLoopTerminated; mbIsWaiting = rAnimation.mbIsWaiting; mnLoops = mbLoopTerminated ? 0 : mnLoopCount; return *this; } // ----------------------------------------------------------------------- sal_Bool Animation::operator==( const Animation& rAnimation ) const { const sal_uLong nCount = maList.Count(); sal_Bool bRet = sal_False; if( rAnimation.maList.Count() == nCount && rAnimation.maBitmapEx == maBitmapEx && rAnimation.maGlobalSize == maGlobalSize && rAnimation.meCycleMode == meCycleMode ) { bRet = sal_True; for( sal_uLong n = 0; n < nCount; n++ ) { if( ( *(AnimationBitmap*) maList.GetObject( n ) ) != ( *(AnimationBitmap*) rAnimation.maList.GetObject( n ) ) ) { bRet = sal_False; break; } } } return bRet; } // ------------------------------------------------------------------ sal_Bool Animation::IsEqual( const Animation& rAnimation ) const { const sal_uLong nCount = maList.Count(); sal_Bool bRet = sal_False; if( rAnimation.maList.Count() == nCount && rAnimation.maBitmapEx.IsEqual( maBitmapEx ) && rAnimation.maGlobalSize == maGlobalSize && rAnimation.meCycleMode == meCycleMode ) { for( sal_uLong n = 0; ( n < nCount ) && !bRet; n++ ) if( ( (AnimationBitmap*) maList.GetObject( n ) )->IsEqual( *(AnimationBitmap*) rAnimation.maList.GetObject( n ) ) ) bRet = sal_True; } return bRet; } // ------------------------------------------------------------------ sal_Bool Animation::IsEmpty() const { return( maBitmapEx.IsEmpty() && !maList.Count() ); } // ------------------------------------------------------------------ void Animation::SetEmpty() { maTimer.Stop(); mbIsInAnimation = sal_False; maGlobalSize = Size(); maBitmapEx.SetEmpty(); for( void* pStepBmp = maList.First(); pStepBmp; pStepBmp = maList.Next() ) delete (AnimationBitmap*) pStepBmp; maList.Clear(); for( void* pView = mpViewList->First(); pView; pView = mpViewList->Next() ) delete (ImplAnimView*) pView; mpViewList->Clear(); } // ----------------------------------------------------------------------- void Animation::Clear() { SetEmpty(); } // ----------------------------------------------------------------------- sal_Bool Animation::IsTransparent() const { Point aPoint; Rectangle aRect( aPoint, maGlobalSize ); sal_Bool bRet = sal_False; // Falls irgendein 'kleines' Bildchen durch den Hintergrund // ersetzt werden soll, muessen wir 'transparent' sein, um // richtig dargestellt zu werden, da die Appl. aus Optimierungsgruenden // kein Invalidate auf nicht-transp. Grafiken ausfuehren for( long i = 0, nCount = maList.Count(); i < nCount; i++ ) { const AnimationBitmap* pAnimBmp = (AnimationBitmap*) maList.GetObject( i ); if( DISPOSE_BACK == pAnimBmp->eDisposal && Rectangle( pAnimBmp->aPosPix, pAnimBmp->aSizePix ) != aRect ) { bRet = sal_True; break; } } if( !bRet ) bRet = maBitmapEx.IsTransparent(); return bRet; } // ----------------------------------------------------------------------- sal_uLong Animation::GetSizeBytes() const { sal_uLong nSizeBytes = GetBitmapEx().GetSizeBytes(); for( long i = 0, nCount = maList.Count(); i < nCount; i++ ) { const AnimationBitmap* pAnimBmp = (AnimationBitmap*) maList.GetObject( i ); nSizeBytes += pAnimBmp->aBmpEx.GetSizeBytes(); } return nSizeBytes; } // ----------------------------------------------------------------------- sal_uLong Animation::GetChecksum() const { SVBT32 aBT32; sal_uInt32 nCrc = GetBitmapEx().GetChecksum(); UInt32ToSVBT32( maList.Count(), aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( maGlobalSize.Width(), aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( maGlobalSize.Height(), aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); UInt32ToSVBT32( (long) meCycleMode, aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); for( long i = 0, nCount = maList.Count(); i < nCount; i++ ) { UInt32ToSVBT32( ( (AnimationBitmap*) maList.GetObject( i ) )->GetChecksum(), aBT32 ); nCrc = rtl_crc32( nCrc, aBT32, 4 ); } return nCrc; } // ----------------------------------------------------------------------- sal_Bool Animation::Start( OutputDevice* pOut, const Point& rDestPt, long nExtraData, OutputDevice* pFirstFrameOutDev ) { return Start( pOut, rDestPt, pOut->PixelToLogic( maGlobalSize ), nExtraData, pFirstFrameOutDev ); } // ----------------------------------------------------------------------- sal_Bool Animation::Start( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz, long nExtraData, OutputDevice* pFirstFrameOutDev ) { sal_Bool bRet = sal_False; if( maList.Count() ) { if( ( pOut->GetOutDevType() == OUTDEV_WINDOW ) && !mbLoopTerminated && ( ANIMATION_TIMEOUT_ON_CLICK != ( (AnimationBitmap*) maList.GetObject( mnPos ) )->nWait ) ) { ImplAnimView* pView; ImplAnimView* pMatch = NULL; for( pView = (ImplAnimView*) mpViewList->First(); pView; pView = (ImplAnimView*) mpViewList->Next() ) { if( pView->ImplMatches( pOut, nExtraData ) ) { if( pView->ImplGetOutPos() == rDestPt && pView->ImplGetOutSizePix() == pOut->LogicToPixel( rDestSz ) ) { pView->ImplRepaint(); pMatch = pView; } else { delete (ImplAnimView*) mpViewList->Remove( pView ); pView = NULL; } break; } } if( !mpViewList->Count() ) { maTimer.Stop(); mbIsInAnimation = sal_False; mnPos = 0UL; } if( !pMatch ) mpViewList->Insert( new ImplAnimView( this, pOut, rDestPt, rDestSz, nExtraData, pFirstFrameOutDev ), LIST_APPEND ); if( !mbIsInAnimation ) { ImplRestartTimer( ( (AnimationBitmap*) maList.GetObject( mnPos ) )->nWait ); mbIsInAnimation = sal_True; } } else Draw( pOut, rDestPt, rDestSz ); bRet = sal_True; } return bRet; } // ----------------------------------------------------------------------- void Animation::Stop( OutputDevice* pOut, long nExtraData ) { ImplAnimView* pView = (ImplAnimView*) mpViewList->First(); while( pView ) { if( pView->ImplMatches( pOut, nExtraData ) ) { delete (ImplAnimView*) mpViewList->Remove( pView ); pView = (ImplAnimView*) mpViewList->GetCurObject(); } else pView = (ImplAnimView*) mpViewList->Next(); } if( !mpViewList->Count() ) { maTimer.Stop(); mbIsInAnimation = sal_False; } } // ----------------------------------------------------------------------- void Animation::Draw( OutputDevice* pOut, const Point& rDestPt ) const { Draw( pOut, rDestPt, pOut->PixelToLogic( maGlobalSize ) ); } // ----------------------------------------------------------------------- void Animation::Draw( OutputDevice* pOut, const Point& rDestPt, const Size& rDestSz ) const { const sal_uLong nCount = maList.Count(); if( nCount ) { AnimationBitmap* pObj = (AnimationBitmap*) maList.GetObject( Min( mnPos, (long) nCount - 1L ) ); if( pOut->GetConnectMetaFile() || ( pOut->GetOutDevType() == OUTDEV_PRINTER ) ) ( (AnimationBitmap*) maList.GetObject( 0 ) )->aBmpEx.Draw( pOut, rDestPt, rDestSz ); else if( ANIMATION_TIMEOUT_ON_CLICK == pObj->nWait ) pObj->aBmpEx.Draw( pOut, rDestPt, rDestSz ); else { const sal_uLong nOldPos = mnPos; ( (Animation*) this )->mnPos = mbLoopTerminated ? ( nCount - 1UL ) : mnPos; delete new ImplAnimView( (Animation*) this, pOut, rDestPt, rDestSz, 0 ); ( (Animation*) this )->mnPos = nOldPos; } } } // ----------------------------------------------------------------------- void Animation::ImplRestartTimer( sal_uLong nTimeout ) { maTimer.SetTimeout( Max( nTimeout, (sal_uLong)(MIN_TIMEOUT + ( mnAnimCount - 1 ) * INC_TIMEOUT) ) * 10L ); maTimer.Start(); } // ----------------------------------------------------------------------- IMPL_LINK( Animation, ImplTimeoutHdl, Timer*, EMPTYARG ) { const sal_uLong nAnimCount = maList.Count(); if( nAnimCount ) { ImplAnimView* pView; sal_Bool bGlobalPause = sal_True; if( maNotifyLink.IsSet() ) { AInfo* pAInfo; // create AInfo-List for( pView = (ImplAnimView*) mpViewList->First(); pView; pView = (ImplAnimView*) mpViewList->Next() ) maAInfoList.Insert( pView->ImplCreateAInfo() ); maNotifyLink.Call( this ); // set view state from AInfo structure for( pAInfo = (AInfo*) maAInfoList.First(); pAInfo; pAInfo = (AInfo*) maAInfoList.Next() ) { if( !pAInfo->pViewData ) { pView = new ImplAnimView( this, pAInfo->pOutDev, pAInfo->aStartOrg, pAInfo->aStartSize, pAInfo->nExtraData ); mpViewList->Insert( pView, LIST_APPEND ); } else pView = (ImplAnimView*) pAInfo->pViewData; pView->ImplPause( pAInfo->bPause ); pView->ImplSetMarked( sal_True ); } // delete AInfo structures for( pAInfo = (AInfo*) maAInfoList.First(); pAInfo; pAInfo = (AInfo*) maAInfoList.Next() ) delete (AInfo*) pAInfo; maAInfoList.Clear(); // delete all unmarked views and reset marked state pView = (ImplAnimView*) mpViewList->First(); while( pView ) { if( !pView->ImplIsMarked() ) { delete (ImplAnimView*) mpViewList->Remove( pView ); pView = (ImplAnimView*) mpViewList->GetCurObject(); } else { if( !pView->ImplIsPause() ) bGlobalPause = sal_False; pView->ImplSetMarked( sal_False ); pView = (ImplAnimView*) mpViewList->Next(); } } } else bGlobalPause = sal_False; if( !mpViewList->Count() ) Stop(); else if( bGlobalPause ) ImplRestartTimer( 10 ); else { AnimationBitmap* pStepBmp = (AnimationBitmap*) maList.GetObject( ++mnPos ); if( !pStepBmp ) { if( mnLoops == 1 ) { Stop(); mbLoopTerminated = sal_True; mnPos = nAnimCount - 1UL; maBitmapEx = ( (AnimationBitmap*) maList.GetObject( mnPos ) )->aBmpEx; return 0L; } else { if( mnLoops ) mnLoops--; mnPos = 0; pStepBmp = (AnimationBitmap*) maList.GetObject( mnPos ); } } // Paint all views; after painting check, if view is // marked; in this case remove view, because area of output // lies out of display area of window; mark state is // set from view itself pView = (ImplAnimView*) mpViewList->First(); while( pView ) { pView->ImplDraw( mnPos ); if( pView->ImplIsMarked() ) { delete (ImplAnimView*) mpViewList->Remove( pView ); pView = (ImplAnimView*) mpViewList->GetCurObject(); } else pView = (ImplAnimView*) mpViewList->Next(); } // stop or restart timer if( !mpViewList->Count() ) Stop(); else ImplRestartTimer( pStepBmp->nWait ); } } else Stop(); return 0L; } // ----------------------------------------------------------------------- sal_Bool Animation::Insert( const AnimationBitmap& rStepBmp ) { sal_Bool bRet = sal_False; if( !IsInAnimation() ) { Point aPoint; Rectangle aGlobalRect( aPoint, maGlobalSize ); maGlobalSize = aGlobalRect.Union( Rectangle( rStepBmp.aPosPix, rStepBmp.aSizePix ) ).GetSize(); maList.Insert( new AnimationBitmap( rStepBmp ), LIST_APPEND ); // zunaechst nehmen wir die erste BitmapEx als Ersatz-BitmapEx if( maList.Count() == 1 ) maBitmapEx = rStepBmp.aBmpEx; bRet = sal_True; } return bRet; } // ----------------------------------------------------------------------- const AnimationBitmap& Animation::Get( sal_uInt16 nAnimation ) const { DBG_ASSERT( ( nAnimation < maList.Count() ), "No object at this position" ); return *(AnimationBitmap*) maList.GetObject( nAnimation ); } // ----------------------------------------------------------------------- void Animation::Replace( const AnimationBitmap& rNewAnimationBitmap, sal_uInt16 nAnimation ) { DBG_ASSERT( ( nAnimation < maList.Count() ), "No object at this position" ); delete (AnimationBitmap*) maList.Replace( new AnimationBitmap( rNewAnimationBitmap ), nAnimation ); // Falls wir an erster Stelle einfuegen, // muessen wir natuerlich auch, // auch die Ersatzdarstellungs-BitmapEx // aktualisieren; if ( ( !nAnimation && ( !mbLoopTerminated || ( maList.Count() == 1 ) ) ) || ( ( nAnimation == maList.Count() - 1 ) && mbLoopTerminated ) ) { maBitmapEx = rNewAnimationBitmap.aBmpEx; } } // ----------------------------------------------------------------------- void Animation::SetLoopCount( const sal_uLong nLoopCount ) { mnLoopCount = nLoopCount; ResetLoopCount(); } // ----------------------------------------------------------------------- void Animation::ResetLoopCount() { mnLoops = mnLoopCount; mbLoopTerminated = sal_False; } // ----------------------------------------------------------------------- sal_Bool Animation::Convert( BmpConversion eConversion ) { DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); sal_Bool bRet; if( !IsInAnimation() && maList.Count() ) { bRet = sal_True; for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Convert( eConversion ); maBitmapEx.Convert( eConversion ); } else bRet = sal_False; return bRet; } // ----------------------------------------------------------------------- sal_Bool Animation::ReduceColors( sal_uInt16 nNewColorCount, BmpReduce eReduce ) { DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); sal_Bool bRet; if( !IsInAnimation() && maList.Count() ) { bRet = sal_True; for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.ReduceColors( nNewColorCount, eReduce ); maBitmapEx.ReduceColors( nNewColorCount, eReduce ); } else bRet = sal_False; return bRet; } // ----------------------------------------------------------------------- sal_Bool Animation::Invert() { DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); sal_Bool bRet; if( !IsInAnimation() && maList.Count() ) { bRet = sal_True; for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Invert(); maBitmapEx.Invert(); } else bRet = sal_False; return bRet; } // ----------------------------------------------------------------------- sal_Bool Animation::Mirror( sal_uLong nMirrorFlags ) { DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); sal_Bool bRet; if( !IsInAnimation() && maList.Count() ) { bRet = sal_True; if( nMirrorFlags ) { for( AnimationBitmap* pStepBmp = (AnimationBitmap*) maList.First(); pStepBmp && bRet; pStepBmp = (AnimationBitmap*) maList.Next() ) { if( ( bRet = pStepBmp->aBmpEx.Mirror( nMirrorFlags ) ) == sal_True ) { if( nMirrorFlags & BMP_MIRROR_HORZ ) pStepBmp->aPosPix.X() = maGlobalSize.Width() - pStepBmp->aPosPix.X() - pStepBmp->aSizePix.Width(); if( nMirrorFlags & BMP_MIRROR_VERT ) pStepBmp->aPosPix.Y() = maGlobalSize.Height() - pStepBmp->aPosPix.Y() - pStepBmp->aSizePix.Height(); } } maBitmapEx.Mirror( nMirrorFlags ); } } else bRet = sal_False; return bRet; } // ----------------------------------------------------------------------- sal_Bool Animation::Dither( sal_uLong nDitherFlags ) { DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); sal_Bool bRet; if( !IsInAnimation() && maList.Count() ) { bRet = sal_True; for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Dither( nDitherFlags ); maBitmapEx.Dither( nDitherFlags ); } else bRet = sal_False; return bRet; } // ----------------------------------------------------------------------- sal_Bool Animation::Adjust( short nLuminancePercent, short nContrastPercent, short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, double fGamma, sal_Bool bInvert ) { DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); sal_Bool bRet; if( !IsInAnimation() && maList.Count() ) { bRet = sal_True; for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) { bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Adjust( nLuminancePercent, nContrastPercent, nChannelRPercent, nChannelGPercent, nChannelBPercent, fGamma, bInvert ); } maBitmapEx.Adjust( nLuminancePercent, nContrastPercent, nChannelRPercent, nChannelGPercent, nChannelBPercent, fGamma, bInvert ); } else bRet = sal_False; return bRet; } // ----------------------------------------------------------------------- sal_Bool Animation::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress ) { DBG_ASSERT( !IsInAnimation(), "Animation modified while it is animated" ); sal_Bool bRet; if( !IsInAnimation() && maList.Count() ) { bRet = sal_True; for( void* pStepBmp = maList.First(); pStepBmp && bRet; pStepBmp = maList.Next() ) bRet = ( ( AnimationBitmap*) pStepBmp )->aBmpEx.Filter( eFilter, pFilterParam, pProgress ); maBitmapEx.Filter( eFilter, pFilterParam, pProgress ); } else bRet = sal_False; return bRet; } // ----------------------------------------------------------------------- SvStream& operator<<( SvStream& rOStm, const Animation& rAnimation ) { const sal_uInt16 nCount = rAnimation.Count(); if( nCount ) { const ByteString aDummyStr; const sal_uInt32 nDummy32 = 0UL; // Falls keine BitmapEx gesetzt wurde, schreiben wir // einfach die erste Bitmap der Animation if( !rAnimation.GetBitmapEx().GetBitmap() ) WriteDIBBitmapEx(rAnimation.Get( 0 ).aBmpEx, rOStm); else WriteDIBBitmapEx(rAnimation.GetBitmapEx(), rOStm); // Kennung schreiben ( SDANIMA1 ) rOStm << (sal_uInt32) 0x5344414e << (sal_uInt32) 0x494d4931; for( sal_uInt16 i = 0; i < nCount; i++ ) { const AnimationBitmap& rAnimBmp = rAnimation.Get( i ); const sal_uInt16 nRest = nCount - i - 1; // AnimationBitmap schreiben WriteDIBBitmapEx(rAnimBmp.aBmpEx, rOStm); rOStm << rAnimBmp.aPosPix; rOStm << rAnimBmp.aSizePix; rOStm << rAnimation.maGlobalSize; rOStm << (sal_uInt16) ( ( ANIMATION_TIMEOUT_ON_CLICK == rAnimBmp.nWait ) ? 65535 : rAnimBmp.nWait ); rOStm << (sal_uInt16) rAnimBmp.eDisposal; rOStm << (sal_uInt8) rAnimBmp.bUserInput; rOStm << (sal_uInt32) rAnimation.mnLoopCount; rOStm << nDummy32; // unbenutzt rOStm << nDummy32; // unbenutzt rOStm << nDummy32; // unbenutzt rOStm << aDummyStr; // unbenutzt rOStm << nRest; // Anzahl der Strukturen, die noch _folgen_ } } return rOStm; } // ----------------------------------------------------------------------- SvStream& operator>>( SvStream& rIStm, Animation& rAnimation ) { Bitmap aBmp; sal_uLong nStmPos = rIStm.Tell(); sal_uInt32 nAnimMagic1, nAnimMagic2; sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt(); sal_Bool bReadAnimations = sal_False; rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); nStmPos = rIStm.Tell(); rIStm >> nAnimMagic1 >> nAnimMagic2; rAnimation.Clear(); // Wenn die BitmapEx am Anfang schon gelesen // wurde ( von Graphic ), koennen wir direkt die Animationsbitmaps einlesen if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() ) bReadAnimations = sal_True; // ansonsten versuchen wir erstmal die Bitmap(-Ex) zu lesen else { rIStm.Seek( nStmPos ); ReadDIBBitmapEx(rAnimation.maBitmapEx, rIStm); nStmPos = rIStm.Tell(); rIStm >> nAnimMagic1 >> nAnimMagic2; if( ( nAnimMagic1 == 0x5344414e ) && ( nAnimMagic2 == 0x494d4931 ) && !rIStm.GetError() ) bReadAnimations = sal_True; else rIStm.Seek( nStmPos ); } // ggf. Animationsbitmaps lesen if( bReadAnimations ) { AnimationBitmap aAnimBmp; BitmapEx aBmpEx; ByteString aDummyStr; sal_uInt32 nTmp32; sal_uInt16 nTmp16; sal_uInt8 cTmp; do { ReadDIBBitmapEx(aAnimBmp.aBmpEx, rIStm); rIStm >> aAnimBmp.aPosPix; rIStm >> aAnimBmp.aSizePix; rIStm >> rAnimation.maGlobalSize; rIStm >> nTmp16; aAnimBmp.nWait = ( ( 65535 == nTmp16 ) ? ANIMATION_TIMEOUT_ON_CLICK : nTmp16 ); rIStm >> nTmp16; aAnimBmp.eDisposal = ( Disposal) nTmp16; rIStm >> cTmp; aAnimBmp.bUserInput = (sal_Bool) cTmp; rIStm >> nTmp32; rAnimation.mnLoopCount = (sal_uInt16) nTmp32; rIStm >> nTmp32; // unbenutzt rIStm >> nTmp32; // unbenutzt rIStm >> nTmp32; // unbenutzt rIStm >> aDummyStr; // unbenutzt rIStm >> nTmp16; // Rest zu lesen rAnimation.Insert( aAnimBmp ); } while( nTmp16 && !rIStm.GetError() ); rAnimation.ResetLoopCount(); } rIStm.SetNumberFormatInt( nOldFormat ); return rIStm; }