startupservices/startupanimation/sanimsvgplugin/src/sanimmifplugin.cpp
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of CSAnimMifPlugin class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <SVGEngineInterfaceImpl.h>
       
    20 
       
    21 #include "sanimmifplugin.h"
       
    22 #include "assert.h"
       
    23 #include "trace.h"
       
    24 
       
    25 /** MIF header contents. */
       
    26 class TMifHeader
       
    27     {
       
    28 public:
       
    29     TInt32 iUID;
       
    30     TInt32 iVersion;
       
    31     TInt32 iArrayOffset;
       
    32     TInt32 iArrayLength;
       
    33     };
       
    34 
       
    35 typedef TPckgBuf<TMifHeader> TMifHeaderPckg;
       
    36 
       
    37 /** Icon offset element from MIF file. */
       
    38 class TIconOffsetElement
       
    39     {
       
    40 public:
       
    41     TInt32 iOffset;
       
    42     TInt32 iLength;
       
    43     };
       
    44 
       
    45 typedef TPckgBuf<TIconOffsetElement> TIconOffsetElementPckg;
       
    46 
       
    47 /** Icon header contents. */
       
    48 class TIconHeader
       
    49     {
       
    50 public:
       
    51     TInt32 iUID;
       
    52     TInt32 iVersion;
       
    53     TInt32 iDataOffset;
       
    54     TInt32 iDataLength;
       
    55     TInt32 iType;
       
    56     TInt32 iDepth;
       
    57     TInt32 iAnimated;
       
    58     TInt32 iMaskDepth;
       
    59     };
       
    60 
       
    61 typedef TPckgBuf<TIconHeader> TIconHeaderPckg;
       
    62 
       
    63 /** Type identifier for SVG. */
       
    64 const TInt KSvgType = 1;
       
    65 
       
    66 /** Number of array elements one frame occupies (bitmap & mask = 2). */
       
    67 const TInt KArrElementsPerFrame = 2;
       
    68 
       
    69 /** Step through icon array with this granularity. */
       
    70 const TInt KIconArrStep = 2;
       
    71 
       
    72 // ======== LOCAL FUNCTIONS ========
       
    73 
       
    74 static TInt TimerCallBack( TAny* aPtr )
       
    75     {
       
    76     FUNC_LOG;
       
    77 
       
    78     static_cast<CSAnimMifPlugin*>( aPtr )->TimerExpired();
       
    79     return KErrNone;
       
    80     }
       
    81 
       
    82 
       
    83 // ======== MEMBER FUNCTIONS ========
       
    84 
       
    85 // ---------------------------------------------------------------------------
       
    86 // CSAnimMifPlugin::NewL
       
    87 //
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 CSAnimMifPlugin* CSAnimMifPlugin::NewL( TAny* aConstructionParameters )
       
    91     {
       
    92     FUNC_LOG;
       
    93 
       
    94     CSAnimMifPlugin* self =
       
    95         new( ELeave ) CSAnimMifPlugin( aConstructionParameters );
       
    96     CleanupStack::PushL( self );
       
    97     self->ConstructL();
       
    98     CleanupStack::Pop( self );
       
    99     return self;
       
   100     }
       
   101 
       
   102 
       
   103 // ---------------------------------------------------------------------------
       
   104 // CSAnimMifPlugin::~CSAnimMifPlugin
       
   105 //
       
   106 // ---------------------------------------------------------------------------
       
   107 //
       
   108 CSAnimMifPlugin::~CSAnimMifPlugin()
       
   109     {
       
   110     FUNC_LOG;
       
   111 
       
   112     delete iDummy;
       
   113     delete iTimer;
       
   114     iFrames.ResetAndDestroy();
       
   115     }
       
   116 
       
   117 
       
   118 // ---------------------------------------------------------------------------
       
   119 // CSAnimMifPlugin::TimerExpired
       
   120 //
       
   121 // ---------------------------------------------------------------------------
       
   122 //
       
   123 void CSAnimMifPlugin::TimerExpired()
       
   124     {
       
   125     FUNC_LOG;
       
   126 
       
   127     if ( iCurrentFrame < iFrames.Count() - KArrElementsPerFrame )
       
   128         {
       
   129         iCurrentFrame += KArrElementsPerFrame; // Each other array element is a mask
       
   130         RefreshView();
       
   131         }
       
   132     else
       
   133         {
       
   134         iTimer->Cancel();
       
   135         CompleteClientRequest( KErrNone );
       
   136         }
       
   137     }
       
   138 
       
   139 
       
   140 // ---------------------------------------------------------------------------
       
   141 // CSAnimMifPlugin::Load
       
   142 //
       
   143 // ---------------------------------------------------------------------------
       
   144 //
       
   145 void CSAnimMifPlugin::Load(
       
   146     RFs& aFs,
       
   147     const TDesC& aFileName,
       
   148     TRequestStatus& aStatus )
       
   149     {
       
   150     FUNC_LOG;
       
   151     INFO_1( "File name: %S", &aFileName );
       
   152 
       
   153     iTimer->Cancel();
       
   154     iFrames.ResetAndDestroy();
       
   155     iCurrentFrame = -1;
       
   156 
       
   157     TRAPD( errorCode, LoadL( aFs, aFileName ) );
       
   158     ERROR( errorCode, "Failed to load image file" );
       
   159     SetClientRequest( aStatus );
       
   160     CompleteClientRequest( errorCode );
       
   161     }
       
   162 
       
   163 
       
   164 // ---------------------------------------------------------------------------
       
   165 // CSAnimMifPlugin::Start
       
   166 //
       
   167 // ---------------------------------------------------------------------------
       
   168 //
       
   169 void CSAnimMifPlugin::Start( TRequestStatus& aStatus )
       
   170     {
       
   171     FUNC_LOG;
       
   172     ASSERT_TRACE( iEngine, SAnimPanic::ENotInitialized );
       
   173     ASSERT_TRACE( !( iTimer->IsActive() ), SAnimPanic::EInternalError );
       
   174 
       
   175     SetClientRequest( aStatus );
       
   176 
       
   177     iCurrentFrame = 0;
       
   178     if ( iCurrentFrame < iFrames.Count() - 1 ) // Last one is a mask
       
   179         {
       
   180         RefreshView();
       
   181         iTimer->Start(
       
   182             iFrameDelay, iFrameDelay, TCallBack( TimerCallBack, this ) );
       
   183         }
       
   184     else
       
   185         {
       
   186         CompleteClientRequest( KErrNone );
       
   187         }
       
   188     }
       
   189 
       
   190 
       
   191 // ---------------------------------------------------------------------------
       
   192 // CSAnimMifPlugin::Cancel
       
   193 //
       
   194 // ---------------------------------------------------------------------------
       
   195 //
       
   196 void CSAnimMifPlugin::Cancel()
       
   197     {
       
   198     FUNC_LOG;
       
   199 
       
   200     CompleteClientRequest( KErrCancel );
       
   201 
       
   202     iTimer->Cancel();
       
   203     }
       
   204 
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 // CSAnimMifPlugin::BackroundColour
       
   208 //
       
   209 // ---------------------------------------------------------------------------
       
   210 //
       
   211 TRgb CSAnimMifPlugin::BackroundColour() const
       
   212     {
       
   213     FUNC_LOG;
       
   214 
       
   215     return KRgbWhite;
       
   216     }
       
   217 
       
   218 
       
   219 // ---------------------------------------------------------------------------
       
   220 // CSAnimMifPlugin::UpdateScreen
       
   221 //
       
   222 // ---------------------------------------------------------------------------
       
   223 //
       
   224 void CSAnimMifPlugin::UpdateScreen()
       
   225     {
       
   226     FUNC_LOG;
       
   227     }
       
   228 
       
   229 
       
   230 // ---------------------------------------------------------------------------
       
   231 // CSAnimMifPlugin::CSAnimMifPlugin
       
   232 //
       
   233 // ---------------------------------------------------------------------------
       
   234 //
       
   235 CSAnimMifPlugin::CSAnimMifPlugin( TAny* aConstructionParameters )
       
   236   : CSAnimSvgPluginBase( aConstructionParameters ),
       
   237     iCurrentFrame( -1 )
       
   238     {
       
   239     FUNC_LOG;
       
   240     }
       
   241 
       
   242 
       
   243 // ---------------------------------------------------------------------------
       
   244 // CSAnimMifPlugin::ConstructL
       
   245 //
       
   246 // ---------------------------------------------------------------------------
       
   247 //
       
   248 void CSAnimMifPlugin::ConstructL()
       
   249     {
       
   250     FUNC_LOG;
       
   251 
       
   252     iTimer = CPeriodic::NewL( CActive::EPriorityHigh );
       
   253     iDummy = new ( ELeave ) CFbsBitmap();
       
   254     User::LeaveIfError( iDummy->Create( TSize( 0, 0 ), EGray256 ) );
       
   255     }
       
   256 
       
   257 
       
   258 // ---------------------------------------------------------------------------
       
   259 // CSAnimMifPlugin::LoadL
       
   260 //
       
   261 // ---------------------------------------------------------------------------
       
   262 //
       
   263 void CSAnimMifPlugin::LoadL( RFs& aFs, const TDesC& aFileName )
       
   264     {
       
   265     FUNC_LOG;
       
   266 
       
   267     delete iEngine;
       
   268     iEngine = NULL;
       
   269     iEngine = CSvgEngineInterfaceImpl::NewL( iDummy, this, iFontSpec );
       
   270     iEngine->SetBackgroundColor( KRgbWhite.Internal() );
       
   271     iEngine->SetDRMMode( EFalse );
       
   272 
       
   273     RFile file;
       
   274     CleanupClosePushL( file );
       
   275     User::LeaveIfError( file.Open(
       
   276         aFs, aFileName, EFileRead | EFileShareReadersOnly ) );
       
   277 
       
   278     TMifHeaderPckg header;
       
   279     TInt errorCode = file.Read( header );
       
   280     ERROR( errorCode, "CSAnimMifPlugin::LoadL: failed to read file" );
       
   281     INFO_2( "CSAnimMifPlugin::LoadL: arr pos %d, arr length %d",
       
   282              header().iArrayOffset, header().iArrayLength );
       
   283     User::LeaveIfError( errorCode );
       
   284     TInt fileSize( 0 );
       
   285     errorCode = file.Size( fileSize );
       
   286     ERROR( errorCode, "CSAnimMifPlugin::LoadL: failed to read file size" );
       
   287     User::LeaveIfError( errorCode );
       
   288 
       
   289     if ( header().iArrayOffset < 0 || header().iArrayLength <= 0 ||
       
   290          header().iArrayOffset + header().iArrayLength <= 0 ||
       
   291          header().iArrayOffset + header().iArrayLength > fileSize )
       
   292         {
       
   293         User::Leave( KErrCorrupt );
       
   294         }
       
   295 
       
   296     ReadIconArrayL( file, header().iArrayOffset, header().iArrayLength );
       
   297 
       
   298     CleanupStack::PopAndDestroy( &file );
       
   299     }
       
   300 
       
   301 
       
   302 // ---------------------------------------------------------------------------
       
   303 // CSAnimMifPlugin::ReadIconArrayL
       
   304 //
       
   305 // ---------------------------------------------------------------------------
       
   306 //
       
   307 void CSAnimMifPlugin::ReadIconArrayL(
       
   308     RFile& aFile,
       
   309     const TInt32 aPosition,
       
   310     const TInt32 aLength )
       
   311     {
       
   312     FUNC_LOG;
       
   313 
       
   314     const TInt elementSize = sizeof( TIconOffsetElementPckg ) / 2;
       
   315     INFO_1( "Reserving %d bytes", aLength * elementSize );
       
   316 
       
   317     HBufC8* iconArray = HBufC8::NewLC( aLength * elementSize );
       
   318     TPtr8 iconArrayPtr = iconArray->Des();
       
   319     TInt errorCode = aFile.Read( aPosition, iconArrayPtr, aLength * elementSize );
       
   320     ERROR( errorCode, "CSAnimMifPlugin::ReadIconArrayL failed to read from file" );
       
   321     User::LeaveIfError( errorCode );
       
   322 
       
   323     INFO_1( "Read %d bytes", iconArrayPtr.Length() );
       
   324 
       
   325     for ( TInt i = 0; i < ( iconArrayPtr.Length() / elementSize ); i += KIconArrStep )
       
   326         {
       
   327         INFO_1( "Read icon %d", i );
       
   328 
       
   329         ReadIconOffsetElementL(
       
   330             aFile, iconArrayPtr.MidTPtr( i * elementSize, elementSize ) );
       
   331         }
       
   332 
       
   333     CleanupStack::PopAndDestroy( iconArray );
       
   334     }
       
   335 
       
   336 
       
   337 // ---------------------------------------------------------------------------
       
   338 // CSAnimMifPlugin::ReadIconOffsetElementL
       
   339 //
       
   340 // ---------------------------------------------------------------------------
       
   341 //
       
   342 void CSAnimMifPlugin::ReadIconOffsetElementL(
       
   343     RFile& aFile,
       
   344     const TDesC8& aData )
       
   345     {
       
   346     FUNC_LOG;
       
   347 
       
   348     TIconOffsetElementPckg element;
       
   349     element.Copy( aData );
       
   350     INFO_2( "Offset %d, length %d", element().iOffset, element().iLength );
       
   351 
       
   352     TIconHeaderPckg header;
       
   353     TInt errorCode = aFile.Read( element().iOffset, header );
       
   354     ERROR( errorCode, "CSAnimMifPlugin::ReadIconOffsetElementL failed to read from file" );
       
   355     User::LeaveIfError( errorCode );
       
   356 
       
   357     INFO_2( "Data pos %d, data length %d", header().iDataOffset, header().iDataLength );
       
   358     INFO_3( "Type %d, depth %d, mask depth %d", header().iType, header().iDepth, header().iMaskDepth );
       
   359 
       
   360     if ( header().iType != KSvgType )
       
   361         {
       
   362         ERROR_1( KErrNotSupported, "Unsupported file type: %d", header().iType );
       
   363 
       
   364         User::Leave( KErrNotSupported );
       
   365         }
       
   366 
       
   367     HBufC8* data = HBufC8::NewLC( header().iDataLength );
       
   368     TPtr8 dataPtr = data->Des();
       
   369     errorCode = aFile.Read( element().iOffset + header().iDataOffset, dataPtr );
       
   370     ERROR( errorCode, "CSAnimMifPlugin::ReadIconOffsetElementL failed to read from file" );
       
   371     User::LeaveIfError( errorCode );
       
   372 
       
   373     CFbsBitmap* mask = new ( ELeave ) CFbsBitmap();
       
   374     CleanupStack::PushL( mask );
       
   375     User::LeaveIfError( mask->Create( iSize, EGray256 ) );
       
   376 
       
   377     CFbsBitmap* bmp = new ( ELeave ) CFbsBitmap();
       
   378     CleanupStack::PushL( bmp );
       
   379     User::LeaveIfError(
       
   380         bmp->Create( iSize, static_cast<TDisplayMode>( header().iDepth ) ) );
       
   381 
       
   382     TInt handle( 0 );
       
   383     errorCode = SvgToSymbianErr( iEngine->PrepareDom( dataPtr, handle ) );
       
   384     ERROR( errorCode, "Failed to prepare DOM" );
       
   385     User::LeaveIfError( errorCode );
       
   386 
       
   387     errorCode = SvgToSymbianErr( iEngine->UseDom( handle, bmp, mask ) );
       
   388     ERROR( errorCode, "Failed to use DOM" );
       
   389     User::LeaveIfError( errorCode );
       
   390 
       
   391     iEngine->SetPreserveAspectRatio(
       
   392         NULL, ESvgPreserveAspectRatio_XmidYmid, ESvgMeetOrSlice_Meet, ETrue );
       
   393 
       
   394     MSvgError* error = NULL;
       
   395     iEngine->Start( error );
       
   396     errorCode = SvgToSymbianErr( error );
       
   397     ERROR( errorCode, "Failed to start engine" );
       
   398     User::LeaveIfError( errorCode );
       
   399 
       
   400     errorCode = SvgToSymbianErr( iEngine->UseDom( handle, NULL, NULL ) );
       
   401     ERROR( errorCode, "Failed to use DOM (empty)" );
       
   402     User::LeaveIfError( errorCode );
       
   403 
       
   404     iEngine->DeleteDom( handle );
       
   405 
       
   406     iFrames.AppendL( bmp );
       
   407     CleanupStack::Pop( bmp ); // It's now in the array.
       
   408 
       
   409     iFrames.AppendL( mask );
       
   410     CleanupStack::Pop( mask ); // It's now in the array.
       
   411 
       
   412     CleanupStack::PopAndDestroy( data );
       
   413     }
       
   414 
       
   415 
       
   416 // ---------------------------------------------------------------------------
       
   417 // CSAnimMifPlugin::RefreshView
       
   418 //
       
   419 // ---------------------------------------------------------------------------
       
   420 //
       
   421 void CSAnimMifPlugin::RefreshView()
       
   422     {
       
   423     FUNC_LOG;
       
   424     ASSERT_TRACE( iCurrentFrame < iFrames.Count() - 1, SAnimPanic::EInternalError );
       
   425 
       
   426     iObserver.UpdateScreen(
       
   427         *( iFrames[iCurrentFrame] ), *( iFrames[iCurrentFrame + 1] ) );
       
   428     }