diff -r 000000000000 -r 05e9090e2422 uigraphics/AknIcon/src/AknIconLoader.cpp --- /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 +#include "AknIconLoader.h" +#include "AknIconLocationInfo.h" +#include + +// CONSTANTS + +// ============================ GLOBAL FUNCTIONS =============================== + +GLDEF_C void CleanupFreeIcon( TAny* aObj ) + { + static_cast( 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 v1(iHeader.iV1); + User::LeaveIfError( iFile.Read( 0, v1, sizeof( TMifFileHeaderV1 ) ) ); + + if (iHeader.iV1.iVersion >= 3) + { + TPckg 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