--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/startupservices/startupanimation/sanimsvgplugin/src/sanimmifplugin.cpp Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,428 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation of CSAnimMifPlugin class
+*
+*/
+
+
+#include <SVGEngineInterfaceImpl.h>
+
+#include "sanimmifplugin.h"
+#include "assert.h"
+#include "trace.h"
+
+/** MIF header contents. */
+class TMifHeader
+ {
+public:
+ TInt32 iUID;
+ TInt32 iVersion;
+ TInt32 iArrayOffset;
+ TInt32 iArrayLength;
+ };
+
+typedef TPckgBuf<TMifHeader> TMifHeaderPckg;
+
+/** Icon offset element from MIF file. */
+class TIconOffsetElement
+ {
+public:
+ TInt32 iOffset;
+ TInt32 iLength;
+ };
+
+typedef TPckgBuf<TIconOffsetElement> TIconOffsetElementPckg;
+
+/** Icon header contents. */
+class TIconHeader
+ {
+public:
+ TInt32 iUID;
+ TInt32 iVersion;
+ TInt32 iDataOffset;
+ TInt32 iDataLength;
+ TInt32 iType;
+ TInt32 iDepth;
+ TInt32 iAnimated;
+ TInt32 iMaskDepth;
+ };
+
+typedef TPckgBuf<TIconHeader> TIconHeaderPckg;
+
+/** Type identifier for SVG. */
+const TInt KSvgType = 1;
+
+/** Number of array elements one frame occupies (bitmap & mask = 2). */
+const TInt KArrElementsPerFrame = 2;
+
+/** Step through icon array with this granularity. */
+const TInt KIconArrStep = 2;
+
+// ======== LOCAL FUNCTIONS ========
+
+static TInt TimerCallBack( TAny* aPtr )
+ {
+ FUNC_LOG;
+
+ static_cast<CSAnimMifPlugin*>( aPtr )->TimerExpired();
+ return KErrNone;
+ }
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::NewL
+//
+// ---------------------------------------------------------------------------
+//
+CSAnimMifPlugin* CSAnimMifPlugin::NewL( TAny* aConstructionParameters )
+ {
+ FUNC_LOG;
+
+ CSAnimMifPlugin* self =
+ new( ELeave ) CSAnimMifPlugin( aConstructionParameters );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::~CSAnimMifPlugin
+//
+// ---------------------------------------------------------------------------
+//
+CSAnimMifPlugin::~CSAnimMifPlugin()
+ {
+ FUNC_LOG;
+
+ delete iDummy;
+ delete iTimer;
+ iFrames.ResetAndDestroy();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::TimerExpired
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::TimerExpired()
+ {
+ FUNC_LOG;
+
+ if ( iCurrentFrame < iFrames.Count() - KArrElementsPerFrame )
+ {
+ iCurrentFrame += KArrElementsPerFrame; // Each other array element is a mask
+ RefreshView();
+ }
+ else
+ {
+ iTimer->Cancel();
+ CompleteClientRequest( KErrNone );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::Load
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::Load(
+ RFs& aFs,
+ const TDesC& aFileName,
+ TRequestStatus& aStatus )
+ {
+ FUNC_LOG;
+ INFO_1( "File name: %S", &aFileName );
+
+ iTimer->Cancel();
+ iFrames.ResetAndDestroy();
+ iCurrentFrame = -1;
+
+ TRAPD( errorCode, LoadL( aFs, aFileName ) );
+ ERROR( errorCode, "Failed to load image file" );
+ SetClientRequest( aStatus );
+ CompleteClientRequest( errorCode );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::Start
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::Start( TRequestStatus& aStatus )
+ {
+ FUNC_LOG;
+ ASSERT_TRACE( iEngine, SAnimPanic::ENotInitialized );
+ ASSERT_TRACE( !( iTimer->IsActive() ), SAnimPanic::EInternalError );
+
+ SetClientRequest( aStatus );
+
+ iCurrentFrame = 0;
+ if ( iCurrentFrame < iFrames.Count() - 1 ) // Last one is a mask
+ {
+ RefreshView();
+ iTimer->Start(
+ iFrameDelay, iFrameDelay, TCallBack( TimerCallBack, this ) );
+ }
+ else
+ {
+ CompleteClientRequest( KErrNone );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::Cancel
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::Cancel()
+ {
+ FUNC_LOG;
+
+ CompleteClientRequest( KErrCancel );
+
+ iTimer->Cancel();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::BackroundColour
+//
+// ---------------------------------------------------------------------------
+//
+TRgb CSAnimMifPlugin::BackroundColour() const
+ {
+ FUNC_LOG;
+
+ return KRgbWhite;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::UpdateScreen
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::UpdateScreen()
+ {
+ FUNC_LOG;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::CSAnimMifPlugin
+//
+// ---------------------------------------------------------------------------
+//
+CSAnimMifPlugin::CSAnimMifPlugin( TAny* aConstructionParameters )
+ : CSAnimSvgPluginBase( aConstructionParameters ),
+ iCurrentFrame( -1 )
+ {
+ FUNC_LOG;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::ConstructL
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::ConstructL()
+ {
+ FUNC_LOG;
+
+ iTimer = CPeriodic::NewL( CActive::EPriorityHigh );
+ iDummy = new ( ELeave ) CFbsBitmap();
+ User::LeaveIfError( iDummy->Create( TSize( 0, 0 ), EGray256 ) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::LoadL
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::LoadL( RFs& aFs, const TDesC& aFileName )
+ {
+ FUNC_LOG;
+
+ delete iEngine;
+ iEngine = NULL;
+ iEngine = CSvgEngineInterfaceImpl::NewL( iDummy, this, iFontSpec );
+ iEngine->SetBackgroundColor( KRgbWhite.Internal() );
+ iEngine->SetDRMMode( EFalse );
+
+ RFile file;
+ CleanupClosePushL( file );
+ User::LeaveIfError( file.Open(
+ aFs, aFileName, EFileRead | EFileShareReadersOnly ) );
+
+ TMifHeaderPckg header;
+ TInt errorCode = file.Read( header );
+ ERROR( errorCode, "CSAnimMifPlugin::LoadL: failed to read file" );
+ INFO_2( "CSAnimMifPlugin::LoadL: arr pos %d, arr length %d",
+ header().iArrayOffset, header().iArrayLength );
+ User::LeaveIfError( errorCode );
+ TInt fileSize( 0 );
+ errorCode = file.Size( fileSize );
+ ERROR( errorCode, "CSAnimMifPlugin::LoadL: failed to read file size" );
+ User::LeaveIfError( errorCode );
+
+ if ( header().iArrayOffset < 0 || header().iArrayLength <= 0 ||
+ header().iArrayOffset + header().iArrayLength <= 0 ||
+ header().iArrayOffset + header().iArrayLength > fileSize )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ ReadIconArrayL( file, header().iArrayOffset, header().iArrayLength );
+
+ CleanupStack::PopAndDestroy( &file );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::ReadIconArrayL
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::ReadIconArrayL(
+ RFile& aFile,
+ const TInt32 aPosition,
+ const TInt32 aLength )
+ {
+ FUNC_LOG;
+
+ const TInt elementSize = sizeof( TIconOffsetElementPckg ) / 2;
+ INFO_1( "Reserving %d bytes", aLength * elementSize );
+
+ HBufC8* iconArray = HBufC8::NewLC( aLength * elementSize );
+ TPtr8 iconArrayPtr = iconArray->Des();
+ TInt errorCode = aFile.Read( aPosition, iconArrayPtr, aLength * elementSize );
+ ERROR( errorCode, "CSAnimMifPlugin::ReadIconArrayL failed to read from file" );
+ User::LeaveIfError( errorCode );
+
+ INFO_1( "Read %d bytes", iconArrayPtr.Length() );
+
+ for ( TInt i = 0; i < ( iconArrayPtr.Length() / elementSize ); i += KIconArrStep )
+ {
+ INFO_1( "Read icon %d", i );
+
+ ReadIconOffsetElementL(
+ aFile, iconArrayPtr.MidTPtr( i * elementSize, elementSize ) );
+ }
+
+ CleanupStack::PopAndDestroy( iconArray );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::ReadIconOffsetElementL
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::ReadIconOffsetElementL(
+ RFile& aFile,
+ const TDesC8& aData )
+ {
+ FUNC_LOG;
+
+ TIconOffsetElementPckg element;
+ element.Copy( aData );
+ INFO_2( "Offset %d, length %d", element().iOffset, element().iLength );
+
+ TIconHeaderPckg header;
+ TInt errorCode = aFile.Read( element().iOffset, header );
+ ERROR( errorCode, "CSAnimMifPlugin::ReadIconOffsetElementL failed to read from file" );
+ User::LeaveIfError( errorCode );
+
+ INFO_2( "Data pos %d, data length %d", header().iDataOffset, header().iDataLength );
+ INFO_3( "Type %d, depth %d, mask depth %d", header().iType, header().iDepth, header().iMaskDepth );
+
+ if ( header().iType != KSvgType )
+ {
+ ERROR_1( KErrNotSupported, "Unsupported file type: %d", header().iType );
+
+ User::Leave( KErrNotSupported );
+ }
+
+ HBufC8* data = HBufC8::NewLC( header().iDataLength );
+ TPtr8 dataPtr = data->Des();
+ errorCode = aFile.Read( element().iOffset + header().iDataOffset, dataPtr );
+ ERROR( errorCode, "CSAnimMifPlugin::ReadIconOffsetElementL failed to read from file" );
+ User::LeaveIfError( errorCode );
+
+ CFbsBitmap* mask = new ( ELeave ) CFbsBitmap();
+ CleanupStack::PushL( mask );
+ User::LeaveIfError( mask->Create( iSize, EGray256 ) );
+
+ CFbsBitmap* bmp = new ( ELeave ) CFbsBitmap();
+ CleanupStack::PushL( bmp );
+ User::LeaveIfError(
+ bmp->Create( iSize, static_cast<TDisplayMode>( header().iDepth ) ) );
+
+ TInt handle( 0 );
+ errorCode = SvgToSymbianErr( iEngine->PrepareDom( dataPtr, handle ) );
+ ERROR( errorCode, "Failed to prepare DOM" );
+ User::LeaveIfError( errorCode );
+
+ errorCode = SvgToSymbianErr( iEngine->UseDom( handle, bmp, mask ) );
+ ERROR( errorCode, "Failed to use DOM" );
+ User::LeaveIfError( errorCode );
+
+ iEngine->SetPreserveAspectRatio(
+ NULL, ESvgPreserveAspectRatio_XmidYmid, ESvgMeetOrSlice_Meet, ETrue );
+
+ MSvgError* error = NULL;
+ iEngine->Start( error );
+ errorCode = SvgToSymbianErr( error );
+ ERROR( errorCode, "Failed to start engine" );
+ User::LeaveIfError( errorCode );
+
+ errorCode = SvgToSymbianErr( iEngine->UseDom( handle, NULL, NULL ) );
+ ERROR( errorCode, "Failed to use DOM (empty)" );
+ User::LeaveIfError( errorCode );
+
+ iEngine->DeleteDom( handle );
+
+ iFrames.AppendL( bmp );
+ CleanupStack::Pop( bmp ); // It's now in the array.
+
+ iFrames.AppendL( mask );
+ CleanupStack::Pop( mask ); // It's now in the array.
+
+ CleanupStack::PopAndDestroy( data );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSAnimMifPlugin::RefreshView
+//
+// ---------------------------------------------------------------------------
+//
+void CSAnimMifPlugin::RefreshView()
+ {
+ FUNC_LOG;
+ ASSERT_TRACE( iCurrentFrame < iFrames.Count() - 1, SAnimPanic::EInternalError );
+
+ iObserver.UpdateScreen(
+ *( iFrames[iCurrentFrame] ), *( iFrames[iCurrentFrame + 1] ) );
+ }