--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uigraphics/AknIcon/src/AknIconLoader.cpp Thu Dec 17 09:14:12 2009 +0200
@@ -0,0 +1,445 @@
+/*
+* Copyright (c) 2002 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: Icon loading from MIF files.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <gdi.h>
+#include "AknIconLoader.h"
+#include "AknIconLocationInfo.h"
+#include <mifconvdefs.h>
+
+// CONSTANTS
+
+// ============================ GLOBAL FUNCTIONS ===============================
+
+GLDEF_C void CleanupFreeIcon( TAny* aObj )
+ {
+ static_cast<CAknIconLoader*>( aObj )->FreeIcon();
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::CAknIconLoader
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CAknIconLoader::CAknIconLoader() : iIconId( -1 )
+ {
+#ifdef _NGATESTING
+ iConfigIconType = -1;
+#endif
+ }
+
+CAknIconLoader* CAknIconLoader::NewL( RFs& aFs, const TDesC& aFileName )
+ {
+ CAknIconLoader* self = new( ELeave ) CAknIconLoader;
+ CleanupStack::PushL( self );
+ self->ConstructL( aFs, aFileName );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// Opened file handle as parameter.
+CAknIconLoader* CAknIconLoader::NewL( RFile& aFile )
+ {
+ CAknIconLoader* self = new( ELeave ) CAknIconLoader;
+ CleanupStack::PushL( self );
+ self->ConstructL( aFile );
+ CleanupStack::Pop();
+ return self;
+ }
+
+void CAknIconLoader::ConstructL( RFs& aFs, const TDesC& aFileName )
+ {
+ OpenFileL( aFs, aFileName );
+ }
+
+void CAknIconLoader::ConstructL( RFile& aFile )
+ {
+ OpenFileL( aFile );
+ }
+
+// Destructor
+CAknIconLoader::~CAknIconLoader()
+ {
+ iFile.Close();
+ delete iOffsets;
+ delete iSharedOffsets;
+ delete iIcon;
+ delete iCdlEngine;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::OpenFileL
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::OpenFileL( RFs& aFs, const TDesC& aFileName )
+ {
+ iFile.Close();
+ User::LeaveIfError( iFile.Open( aFs, aFileName, EFileRead|EFileShareReadersOnly ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::OpenFileL
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::OpenFileL( RFile& aFile )
+ {
+ iFile.Close();
+ User::LeaveIfError( iFile.Duplicate( aFile ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::CloseFile
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::CloseFile()
+ {
+ iFile.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::FileHeaderStructL
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::LoadFileHeaderStructL()
+ {
+ if ( !iHeader.iV1.iUid )
+ {
+ TPckg<TMifFileHeaderV1> v1(iHeader.iV1);
+ User::LeaveIfError( iFile.Read( 0, v1, sizeof( TMifFileHeaderV1 ) ) );
+
+ if (iHeader.iV1.iVersion >= 3)
+ {
+ TPckg<TMifFileHeaderV3> v3(iHeader.iV3);
+ User::LeaveIfError( iFile.Read( v3, sizeof( TMifFileHeaderV3 ) ) );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::CheckFileL
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::CheckFileL()
+ {
+ LoadFileHeaderStructL();
+
+ if ( iHeader.iV1.iUid != KUidAvkonMultiIconFile ||
+ iHeader.iV1.iVersion < KMifFirstSupportedVersion ||
+ iHeader.iV1.iVersion > KMifLastSupportedVersion )
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("AknIconLoader: Icon file corrupt; file format error!"));
+ #endif
+
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::LoadSharedOffsetsL
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::LoadSharedOffsetsL()
+ {
+ if (!CdlEngine::IsCdlEngineCreated())
+ iCdlEngine = CdlEngine::CreateCdlEngineL();
+
+ TBuf<12> dllName;
+ _LIT(KDllNameFormat,"%08x.DLL");
+ dllName.Format(KDllNameFormat, iHeader.iV3.iIndexDllUid);
+ iSharedOffsets = MifHeader::CInstance::NewL(dllName, 0); // MifHeader DLLs only ever have one instance, and that has id 0
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::LoadOffsetsFromMifL
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::LoadOffsetsFromMifL()
+ {
+ TInt pos = iHeader.iV1.iArrayOffset;
+ TInt length = iHeader.iV1.iArrayLength;
+ HBufC8* offsets = HBufC8::NewL( sizeof( TMifBitmapOffsetElement ) * length );
+ CleanupStack::PushL( offsets );
+ TPtr8 ptr = offsets->Des();
+
+ User::LeaveIfError( iFile.Read(
+ pos, ptr, sizeof( TMifBitmapOffsetElement ) * length ) );
+
+ if ( TUint( ptr.Length() ) != sizeof( TMifBitmapOffsetElement ) * length )
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("AknIconLoader: Icon file corrupt; EOF at offsets!"));
+ #endif
+
+ User::Leave( KErrCorrupt );
+ }
+
+ CleanupStack::Pop(); // offsets
+ iOffsets = offsets;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::BitmapOffsetsL
+// -----------------------------------------------------------------------------
+//
+const TMifBitmapOffsetElement* CAknIconLoader::BitmapOffsetsL()
+ {
+ if ( !iOffsets && !iSharedOffsets )
+ {
+ CheckFileL();
+
+ LoadFileHeaderStructL();
+ if (iHeader.iV1.iVersion == 3)
+ LoadSharedOffsetsL();
+ else
+ LoadOffsetsFromMifL();
+ }
+
+ if (iOffsets)
+ return (TMifBitmapOffsetElement*)iOffsets->Ptr();
+ else
+ return &iSharedOffsets->indicies()[0];
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::BitmapOffsetsArrayL
+// -----------------------------------------------------------------------------
+//
+const TMifBitmapOffsetElement* CAknIconLoader::BitmapOffsetsArrayL()
+ {
+ return BitmapOffsetsL();
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::IconWithHeaderL
+// -----------------------------------------------------------------------------
+//
+TPtrC8 CAknIconLoader::IconWithHeaderL( TInt aId )
+ {
+ if ( iIconId == aId )
+ {
+ return iIcon->Des();
+ }
+
+ LoadFileHeaderStructL();
+
+ TInt usedId = iHeader.iV1.iVersion == 1 ? aId / 2 : aId;
+
+ if ( usedId < 0 || usedId >= iHeader.iV1.iArrayLength )
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("AknIconLoader: Icon ID not found!"));
+ #endif
+
+ // Consistent error code with MBM loading.
+ User::Leave( KErrEof );
+ }
+
+ const TMifBitmapOffsetElement* ptr = BitmapOffsetsArrayL();
+ TUint32 offset = ptr[usedId].iOffset;
+ if (((TInt32)offset) < 0)
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("AknIconLoader: Icon file corrupt; Negative offset!"));
+ #endif
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint32 length = ptr[usedId].iLength;
+
+ delete iIcon;
+ iIcon = NULL;
+ iIcon = HBufC8::NewL( length );
+
+ TPtr8 ptr2 = iIcon->Des();
+ User::LeaveIfError( iFile.Read( offset, ptr2, length ) );
+
+ if ( TUint( ptr2.Length() ) != length )
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("AknIconLoader: Icon file corrupt; EOF at icon!"));
+ #endif
+
+ User::Leave( KErrCorrupt );
+ }
+
+ iIconId = aId;
+ return iIcon->Des();
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::CheckIconL
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::CheckIconL( TInt aId )
+ {
+ TMifIconHeader* header = (TMifIconHeader*)IconWithHeaderL( aId ).Ptr();
+
+ if ( header->iUid != KUidAvkonMultiIcon ||
+ header->iVersion < KMifIconFirstSupportedVersion ||
+ header->iVersion > KMifIconLastSupportedVersion )
+ {
+ #ifdef _DEBUG
+ RDebug::Print(_L("AknIconLoader: Icon file corrupt; icon format error!"));
+ #endif
+
+ User::Leave( KErrCorrupt );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::IconHeaderL
+// -----------------------------------------------------------------------------
+//
+TMifIconHeader* CAknIconLoader::IconHeaderL( TInt aId )
+ {
+ CheckIconL( aId );
+
+ TPtrC8 icon = IconWithHeaderL( aId );
+ return (TMifIconHeader*)icon.Ptr();
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::IconL
+// -----------------------------------------------------------------------------
+//
+TPtrC8 CAknIconLoader::IconL( TInt aId )
+ {
+ CheckIconL( aId );
+
+ TPtrC8 icon = IconWithHeaderL( aId );
+ TMifIconHeader* header = IconHeaderL( aId );
+ icon.Set( icon.Mid( header->iDataOffset, header->iDataLength ) );
+ return icon;
+ }
+#ifdef _NGATESTING
+void CAknIconLoader::SetIconTypeConfig(TInt32 aConfigIconType, const TDesC & aNGATestDirectory)
+ {
+ iConfigIconType = aConfigIconType;
+ iNGADirectory.Copy(aNGATestDirectory);
+ }
+
+TInt32 CAknIconLoader::GetDerivedIconTypeL(TInt32 aType, const TDesC & aMifFileName)
+ {
+ if (aType != EIconFormatBMP &&
+ aType != EIconFormatNVG)
+ {
+ if (iConfigIconType != -1)
+ {
+ aType = iConfigIconType;
+ }
+
+ if (aType != EIconFormatNGA)
+ {
+ TInt NGADirectoryLength = iNGADirectory.Length();
+ if ( NGADirectoryLength > 0 &&
+ NGADirectoryLength < aMifFileName.Length() &&
+ aMifFileName.Left(NGADirectoryLength).CompareF(iNGADirectory) == 0 )
+ {
+ aType = EIconFormatNGA;
+ }
+ }
+ }
+
+ return aType;
+ }
+#endif
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::IconTypeL
+// -----------------------------------------------------------------------------
+//
+TInt32 CAknIconLoader::IconTypeL( TInt aId )
+ {
+ TMifIconHeader* header = IconHeaderL( aId );
+ return header->iType;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::IconDepthL
+// -----------------------------------------------------------------------------
+//
+TInt32 CAknIconLoader::IconDepthL( TInt aId )
+ {
+ TMifIconHeader* header = IconHeaderL( aId );
+ return header->iDepth;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::MaskDepthL
+// -----------------------------------------------------------------------------
+//
+TInt32 CAknIconLoader::MaskDepthL( TInt aId )
+ {
+ TMifIconHeader* header = IconHeaderL( aId );
+ return header->iMaskDepth;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::IconAnimatedL
+// -----------------------------------------------------------------------------
+//
+TInt32 CAknIconLoader::IconAnimatedL( TInt aId )
+ {
+ TMifIconHeader* header = IconHeaderL( aId );
+ return header->iAnimated;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::FreeIcon
+// -----------------------------------------------------------------------------
+//
+void CAknIconLoader::FreeIcon()
+ {
+ iIconId = -1;
+ delete iIcon;
+ iIcon = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknIconLoader::LoadIconLocationInfoL
+// -----------------------------------------------------------------------------
+//
+CAknIconLocationInfo* CAknIconLoader::LoadIconLocationInfoL(
+ const TDesC& aFileName )
+ {
+ CheckFileL();
+
+ // First check whether this is v1 or v2 MIF file.
+ LoadFileHeaderStructL();
+
+ if ( iHeader.iV1.iVersion == 1 )
+ {
+ // V1, no location info array as parameter.
+ return CAknIconLocationInfo::NewL( aFileName );
+ }
+
+ // V2+ MIF file, load the location info array.
+ BitmapOffsetsL();
+ if (iOffsets)
+ return CAknIconLocationInfo::NewL( aFileName, *iOffsets );
+ else
+ return CAknIconLocationInfo::NewL( aFileName, *iSharedOffsets );
+ }
+
+// End of File