Build configuration files changed to generate SVG icons and skins.
/*
* 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: Pictograph drawer
*
*/
// INCLUDE FILES
#include <fbs.h>
#include <gdi.h>
#include <bitdev.h>
#include <mmfcontrollerpluginresolver.h> // For CleanupResetAndDestroyPushL
#include "BitmapBuilder.h"
#include "aknpictographconfig.h" // KBitmapDisplayMode, KMaskDisplayMode
// KBitmapTag, KMaskTag
// CONSTANTS
// The root is mapped to parent of dir AknPictograph
_LIT( KDefaultPath, "a:\\" );
// This should be carefully selected beacuse adding support
// for new height will need about 40 KB more
TUint KBufferSizeForHeaderGeneration = 300000;
// WINC platform - paths mapped directly in PC file system
// on EKA2 drive a: is mapped to the PC file system
_LIT( KConfigPathEpoc, "\\AknPictograph\\config\\" );
_LIT( KConfigFile, "picto%u.ini" );
_LIT( KGeneratedPathEpoc, "\\AknPictograph\\generated\\" );
// String for inserting in batch files
_LIT( KGeneratedPath, "..\\generated\\" );
_LIT( KBmconvFile, "bmconv%u.txt" );
_LIT( KMultiBitmapFile, "AknPictograph_multi%u.mbm" );
_LIT( KBitmapFile, "AknPictograph%u.mbm" );
_LIT( KMaskFile, "AknPictographMask%u.mbm" );
_LIT( KDefinitionsFile, "AknPictographDefinitions.h" );
_LIT( KRangeFile, "AknPictographRange.h" );
_LIT( KBuildBitmapsFile, "BuildBitmaps.cmd" );
_LIT8( KGeneratedInfo, "// This file is generated by AknPictoBitmapBuilder.\r\n\r\n" );
// Bmconv command file strings
_LIT8( KBmconvParameters, "/q " );
_LIT8( KBmpDefaultPath, "..\\..\\AknPictographBitmaps\\data\\" );
// Definition header strings
_LIT8( KDefinitionHeaderStart,
"#include <e32std.h>\r\n"
"#include \"AknPictographDrawerInterface.h\"\r\n"
"#include \"AknPictographConstants.h\"\r\n\r\n" );
// TAknPictographSupportedHeights array
_LIT8( KAknPictographSupportedHeightsStart,
"const TAknPictographHeight TAknPictographSupportedHeights[] =\r\n" );
_LIT8( KAknPictographSupportedHeightsArrayRow,
" EHeight%u,\r\n" );
// TAknPictographSupportedHeightsNumbers array
_LIT8( KAknPictographSupportedHeightsNumbersStart,
"const TUint TAknPictographSupportedHeightsNumbers[] =\r\n" );
_LIT8( KAknPictographSupportedHeightsNumbersArrayRow,
" %u,\r\n" );
// KAknPictographSupportedHeightsCount row
_LIT8( KAknPictographSupportedHeightsCount,
"const TInt KAknPictographSupportedHeightsCount = sizeof(TAknPictographSupportedHeights)/sizeof(TAknPictographHeight);\r\n\r\n" );
// Animation definitions
_LIT8( KAnimationDefinitionStart,
"const TAknPictographMetrics P_%x_%u[] =\r\n" );
_LIT8( KAnimationFrame,
" {%u, %u, %u},\r\n" );
// Animation frames definitions
_LIT8( KAnimationFramesDefinitionStart,
"const TAknAnimatedPictographFramesDefinition Frames_%x[] =\r\n" );
_LIT8( KAnimationFramesDefinitionRow,
" {%u, P_%x_%u},\r\n" );
// Animated pictograph table
_LIT8( KAnimatedTableStart,
"const TAknAnimatedPictographDefinition TheAnimatedPictographDefinitions[] =\r\n" );
_LIT8( KAnimatedTableRow,
" { 0x%x, %u, Frames_%x },\r\n" );
_LIT8( KAnimatedTableDummyRow,
" { 0x0000, 0, NULL }\r\n" );
// KAknPictographAnimatedPictographsCount row
_LIT8( KAknPictographAnimatedPictographsCount,
"const TInt KAknPictographAnimatedPictographsCount = sizeof(TheAnimatedPictographDefinitions)/sizeof(TAknAnimatedPictographDefinition) - %u;\r\n\r\n" );
// Static definitions
_LIT8( KStaticDefinitionStart,
"const TAknPictographMetrics Static_%x[] =\r\n" );
_LIT8( KStaticDefinitionRow,
" {%u, %u, %u},\r\n" );
// Static pictograph table
_LIT8( KStaticTableStart,
"const TAknStaticPictographDefinition TheStaticPictographDefinitions[] =\r\n" );
_LIT8( KStaticTableRow,
" { 0x%x, Static_%x },\r\n" );
_LIT8( KStaticTableDummyRow,
" { 0x0000, NULL }\r\n" );
// KAknPictographAnimatedPictographsCount row
_LIT8( KAknPictographStaticPictographsCount,
"const TInt KAknPictographStaticPictographsCount = sizeof(TheStaticPictographDefinitions)/sizeof(TAknStaticPictographDefinition) - %u;\r\n\r\n" );
// Range header strings
_LIT8( KRangeHeaderStart,
"#ifndef AKN_PICTOGRAPH_RANGE_H\r\n"
"#define AKN_PICTOGRAPH_RANGE_H\r\n\r\n"
"#include <e32std.h>\r\n\r\n" );
_LIT8( KRangeStart,
"const TText KPictographRangeStart = 0x%x;\r\n" );
_LIT8( KRangeEnd,
"const TText KPictographRangeEnd = 0x%x;\r\n\r\n" );
_LIT8( KEndIf, "#endif\r\n\r\n" );
// Common for all arrays
_LIT8( KArrayStart, " {\r\n" );
_LIT8( KArrayEnd, " };\r\n\r\n" );
_LIT8( KHeaderEnd, "// End of File" );
// BuildBitmaps.cmd strings
_LIT8( KBuildBitmapsFileStart,
"@echo off\r\n"
"rem\r\n"
"rem This file is generated by AknPictoBitmapBuilder.\r\n"
"rem\r\n\r\n"
"if %1==xip goto xip_rom\r\n"
"if %1==XIP goto xip_rom\r\n\r\n"
"set bmconv_params=/q\r\n"
"goto main\r\n\r\n"
":xip_rom\r\n"
"set bmconv_params=/q /r\r\n\r\n"
":main\r\n\r\n");
_LIT8( KBuildBitmapsRow,
"bmconv ..\\generated\\bmconv%u.txt&&^\r\n");
_LIT8( KBuildFinalBitmaps,
"\\epoc32\\release\\winscw\\urel\\AknPictoBitmapBuilder.exe -Dnogui -D_epoc_drive_a=%~pd2 -- 2&&^\r\n"
"cd ..\\generated&&^\r\n");
_LIT8( KCompressFinalBitmapsRow,
"bmconv %%bmconv_params%% AknPictograph%u_rom.mbm /mAknPictograph%u.mbm&&^\r\n"
"bmconv %%bmconv_params%% AknPictographMask%u_rom.mbm /mAknPictographMask%u.mbm&&^\r\n");
_LIT8( KMoveFinalBitmapsRow,
"move AknPictograph%u_rom.mbm %%3\\AknPictograph%u.mbm&&^\r\n"
"move AknPictographMask%u_rom.mbm %%3\\AknPictographMask%u.mbm&&^\r\n");
_LIT8( KBuildBitmapsFileEnd,
"cd ..\\group\r\n");
_LIT8( KLongCommandLineSeparator,
"rem\r\n");
// ============================ MEMBER FUNCTIONS ===============================
CPictographIniData* CPictographIniData::NewLC()
{
CPictographIniData* self = new( ELeave ) CPictographIniData;
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
void CPictographIniData::ConstructL()
{
}
CPictographIniFileData* CPictographIniFileData::NewLC()
{
CPictographIniFileData* self = new( ELeave ) CPictographIniFileData;
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
void CPictographIniFileData::ConstructL()
{
}
CPictographBitmapsData* CPictographBitmapsData::NewLC(TInt aBitmapSizesGranularity)
{
CPictographBitmapsData* self = new( ELeave ) CPictographBitmapsData(aBitmapSizesGranularity);
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
CPictographBitmapsData::CPictographBitmapsData(TInt aBitmapSizesGranularity):
iBitmapSizes(aBitmapSizesGranularity)
{
}
CPictographBitmapsData::~CPictographBitmapsData()
{
iBitmapSizes.Reset();
delete iOffsets;
}
void CPictographBitmapsData::ConstructL()
{
iOffsets = new( ELeave ) CArrayFixFlat<TInt>( 32 );
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::CBitmapBuilder
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CBitmapBuilder::CBitmapBuilder()
{
}
CBitmapBuilder* CBitmapBuilder::NewLC()
{
CBitmapBuilder* self = new( ELeave ) CBitmapBuilder;
CleanupStack::PushL( self );
self->ConstructL();
return self;
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::ConstructL()
{
User::LeaveIfError( iFs.Connect() );
User::LeaveIfError( iFs.SetSessionPath(KDefaultPath) );
User::LeaveIfError( iFs.ShareProtected() );
}
// Destructor
CBitmapBuilder::~CBitmapBuilder()
{
iBitmapsData.ResetAndDestroy();
iIniFilesData.ResetAndDestroy();
iFs.Close();
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::EnsurePathsL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::EnsurePathsL()
{
iFs.MkDirAll( KGeneratedPathEpoc );
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::ParseIniFilesL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::ParseIniFilesL()
{
TFileName name;
TFileName temp;
for (TInt i = 0; i < KAknPictographMaxSetOfSupportedHeightsCount; i++)
{
// prepare ini file name
temp.Zero();
temp.Format( KConfigFile, TAknPictographMaxSetOfSupportedHeights[i] );
name = KConfigPathEpoc;
name.Append( temp );
CPictographIniFileData* iniFileData = NULL;
TRAPD(err, ParseIniFileL( name, iniFileData ));
if (err != KErrNotFound)
{
// Leave if the reason of leave in ParseIniFileL is not because
// of the ini file was not found
User::LeaveIfError(err);
}
if (iniFileData)
{
CleanupStack::PushL( iniFileData );
// The parsing was successful
iniFileData->iHeightIndex = i;
User::LeaveIfError( iIniFilesData.Append(iniFileData));
CleanupStack::Pop( iniFileData );
}
}
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::ParseIniFileL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::ParseIniFileL(
const TDesC& aFilename,
CPictographIniFileData*& aIniFileData )
{
RFile file;
User::LeaveIfError( file.Open( iFs, aFilename, EFileRead ) );
CleanupClosePushL( file );
aIniFileData = CPictographIniFileData::NewLC();
TInt pos = 0;
// go in the beginning of the file
User::LeaveIfError( file.Seek( ESeekStart, pos ) );
TInt size = 0;
file.Size( size );
HBufC8* buffer = HBufC8::NewMaxLC( size );
TPtr8 ptr = buffer->Des();
file.Read( ptr );
TLex8 lex( ptr );
TPtrC8 token( lex.NextToken() );
while ( token.Length() )
{
// code tag first
if ( token.Length() != 8 ||
token[0] != '[' ||
token[1] != '0' ||
( token[2] != 'x' && token[2] != 'X' ) ||
token[7] != ']' )
{
User::Leave( KErrCorrupt );
}
CPictographIniData* data = CPictographIniData::NewLC();
TLex8 codeLex( token.Mid( 3, 4 ) );
User::LeaveIfError( codeLex.Val( data->iCode, EHex ) );
// filename parameters then
for ( token.Set( lex.NextToken() ) ;
token.Length() && token[0] != '[' ;
token.Set( lex.NextToken() ) )
{
HBufC8* filename = token.AllocLC();
User::LeaveIfError( data->iFilenameArray.Append( filename ) );
CleanupStack::Pop( filename );
aIniFileData->iBmps++;
}
// Must be even number because each bitmap must have mask
if ( data->iFilenameArray.Count() % 2 != 0 )
{
User::Leave( KErrCorrupt );
}
User::LeaveIfError( aIniFileData->iIniData.Append( data ) );
CleanupStack::Pop( data );
}
CleanupStack::PopAndDestroy( buffer );
CleanupStack::Pop( aIniFileData );
CleanupStack::PopAndDestroy(); // file
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateBmconvCommandFilesL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateBmconvCommandFilesL()
{
TFileName cmdFile;
TFileName bitmapFile;
TFileName temp;
for (TInt i = 0; i < iIniFilesData.Count(); i++)
{
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[i]->iHeightIndex];
// prepare cmdFile name
temp.Zero();
temp.Format( KBmconvFile, height );
cmdFile = KGeneratedPathEpoc;
cmdFile.Append( temp );
// prepare bitmapFile name
temp.Zero();
temp.Format( KMultiBitmapFile, height );
bitmapFile = KGeneratedPath;
bitmapFile.Append( temp );
GenerateBmconvCommandFileL( cmdFile, bitmapFile, iIniFilesData[i]->iIniData );
}
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateBmconvCommandFilesL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateBuildBitmapsCommandFileL()
{
TFileName aCmdFileName;
TBuf8<256> temp;
// prepare cmdFile name
aCmdFileName = KGeneratedPathEpoc;
aCmdFileName.Append( KBuildBitmapsFile );
RFile file;
User::LeaveIfError( file.Replace( iFs, aCmdFileName, EFileWrite ) );
CleanupClosePushL( file );
TInt pos = 0;
// go in the beginning of the file
User::LeaveIfError( file.Seek( ESeekStart, pos ) );
file.Write( KBuildBitmapsFileStart );
// generate bitmaps building section
for (TInt i = 0; i < iIniFilesData.Count(); i++)
{
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[i]->iHeightIndex];
temp.Zero();
temp.Format( KBuildBitmapsRow, height );
file.Write( temp );
}
file.Write( KLongCommandLineSeparator );
file.Write( KBuildFinalBitmaps );
// generate compress final bitmaps section
for (TInt j = 0; j < iIniFilesData.Count(); j++)
{
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[j]->iHeightIndex];
temp.Zero();
temp.Format( KCompressFinalBitmapsRow, height, height, height, height );
file.Write( temp );
}
file.Write( KLongCommandLineSeparator );
// generate move final bitmaps section
for (TInt k = 0; k < iIniFilesData.Count(); k++)
{
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[k]->iHeightIndex];
temp.Zero();
temp.Format( KMoveFinalBitmapsRow, height, height, height, height );
file.Write( temp );
}
file.Write( KLongCommandLineSeparator );
file.Write( KBuildBitmapsFileEnd );
CleanupStack::PopAndDestroy(); // file
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateBmconvCommandFileL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateBmconvCommandFileL(
const TDesC& aCmdFileName,
const TDesC& aBitmapFileName,
RPointerArray<CPictographIniData>& aArray )
{
RFile file;
User::LeaveIfError( file.Replace( iFs, aCmdFileName, EFileWrite ) );
CleanupClosePushL( file );
TInt pos = 0;
// go in the beginning of the file
User::LeaveIfError( file.Seek( ESeekStart, pos ) );
file.Write( KGeneratedInfo );
file.Write( KBmconvParameters );
TBuf8<400> buf8;
buf8.Copy( aBitmapFileName );
buf8.Append( _L8("\r\n\r\n") );
file.Write( buf8 );
// write bmp parameters
for ( TInt i = 0 ; i < aArray.Count() ; i++ )
{
CPictographIniData* data = aArray[i];
for ( TInt ii = 0 ; ii < data->iFilenameArray.Count() ; ii += 2 )
{
// bitmap
buf8.Zero();
buf8.Append( KBitmapTag );
TFileName filename;
// 8-bit to 16-bit copy
filename.Copy( *(data->iFilenameArray[ii]) );
TParse parse;
parse.Set( filename, NULL, NULL );
if ( !parse.PathPresent() )
{
buf8.Append( KBmpDefaultPath );
}
// 16-bit to 8-bit append
buf8.Append( parse.FullName() );
buf8.Append( _L8("\r\n") );
file.Write( buf8 );
// mask
buf8.Zero();
buf8.Append( KMaskTag );
// 8-bit to 16-bit copy
filename.Copy( *(data->iFilenameArray[ii + 1]) );
parse.Set( filename, NULL, NULL );
if ( !parse.PathPresent() )
{
buf8.Append( KBmpDefaultPath );
}
// 16-bit to 8-bit append
buf8.Append( parse.FullName() );
buf8.Append( _L8("\r\n") );
file.Write( buf8 );
}
}
CleanupStack::PopAndDestroy(); // file
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::BuildFinalBitmapsL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::BuildFinalBitmapsL()
{
TFileName* multiBitmapFile = new( ELeave ) TFileName;
CleanupStack::PushL( multiBitmapFile );
TFileName* finalBitmapFile = new( ELeave ) TFileName;
CleanupStack::PushL( finalBitmapFile );
TFileName* finalMaskFile = new( ELeave ) TFileName;
CleanupStack::PushL( finalMaskFile );
TFileName* temp = new( ELeave ) TFileName;
CleanupStack::PushL( temp );
for (TInt i = 0; i < iIniFilesData.Count(); i++)
{
// set proper value for granularity
CPictographBitmapsData* bitmapsData = CPictographBitmapsData::NewLC(iIniFilesData[i]->iBmps/2);
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[i]->iHeightIndex];
// prepare multiBitmapFile name
temp->Zero();
temp->Format( KMultiBitmapFile, height );
multiBitmapFile->Copy( KGeneratedPathEpoc );
multiBitmapFile->Append( *temp );
// prepare finalBitmapFile name
temp->Zero();
temp->Format( KBitmapFile, height );
finalBitmapFile->Copy( KGeneratedPathEpoc );
finalBitmapFile->Append( *temp );
// prepare finalMaskFile name
temp->Zero();
temp->Format( KMaskFile, height );
finalMaskFile->Copy( KGeneratedPathEpoc );
finalMaskFile->Append( *temp );
BuildFinalBitmapL(
*multiBitmapFile,
*finalBitmapFile,
*finalMaskFile,
iIniFilesData[i]->iBmps,
*bitmapsData);
User::LeaveIfError( iBitmapsData.Append(bitmapsData) );
CleanupStack::Pop(bitmapsData);
}
// multiBitmapFile, finalBitmapFile, finalMaskFile, temp
CleanupStack::PopAndDestroy( 4 );
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::BuildFinalBitmapL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::BuildFinalBitmapL(
const TDesC& aMultiBitmapFile,
const TDesC& aFinalBitmapFile,
const TDesC& aFinalMaskFile,
TInt aBmps,
CPictographBitmapsData& aBitmapsData )
{
TInt totalWidth = 0;
TInt maxHeight = 0;
// set proper granularity values
RPointerArray<CFbsBitmap> bitmaps(aBmps/2);
RPointerArray<CFbsBitmap> masks(aBmps/2);
CleanupResetAndDestroyPushL(bitmaps);
CleanupResetAndDestroyPushL(masks);
// First bitmap has x-offset 0
aBitmapsData.iOffsets->AppendL( 0 );
RFile multiBitmapfile;
User::LeaveIfError( multiBitmapfile.Open( iFs, aMultiBitmapFile, EFileRead ) );
CleanupClosePushL( multiBitmapfile );
// Load bitmaps and masks in arrays
for ( TInt i = 0 ; i < aBmps ; i += 2 )
{
CFbsBitmap* bitmap = new( ELeave ) CFbsBitmap;
CleanupStack::PushL( bitmap );
User::LeaveIfError( bitmap->Load( multiBitmapfile, i ) );
User::LeaveIfError( bitmaps.Append( bitmap ) );
CleanupStack::Pop( bitmap );
// Update total width and max height
TSize size = bitmap->SizeInPixels();
User::LeaveIfError( aBitmapsData.iBitmapSizes.Append( size ) );
totalWidth += size.iWidth;
aBitmapsData.iOffsets->AppendL( totalWidth );
if ( size.iHeight > maxHeight )
{
maxHeight = size.iHeight;
}
CFbsBitmap* mask = new( ELeave ) CFbsBitmap;
CleanupStack::PushL( mask );
User::LeaveIfError( mask->Load( multiBitmapfile, i + 1 ) );
User::LeaveIfError( masks.Append( mask ) );
CleanupStack::Pop( mask );
}
// new size for one large bitmap
TSize newSize( totalWidth, maxHeight );
// bitgdi objects for large bitmap
CFbsBitmap* largeBitmap = new( ELeave ) CFbsBitmap;
CleanupStack::PushL( largeBitmap );
User::LeaveIfError( largeBitmap->Create( newSize, KBitmapDisplayMode ) );
CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( largeBitmap );
CleanupStack::PushL( bitmapDevice );
CFbsBitGc* bitmapGc = NULL;
User::LeaveIfError( bitmapDevice->CreateContext( bitmapGc ) );
CleanupStack::PushL( bitmapGc );
// bitgdi objects for large mask
CFbsBitmap* largeMask = new( ELeave ) CFbsBitmap;
CleanupStack::PushL( largeMask );
User::LeaveIfError( largeMask->Create( newSize, KMaskDisplayMode ) );
CFbsBitmapDevice* maskDevice = CFbsBitmapDevice::NewL( largeMask );
CleanupStack::PushL( maskDevice );
CFbsBitGc* maskGc = NULL;
User::LeaveIfError( maskDevice->CreateContext( maskGc ) );
CleanupStack::PushL( maskGc );
// fill with black color
bitmapGc->SetBrushColor( KRgbBlack );
bitmapGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
bitmapGc->Clear();
maskGc->SetBrushColor( KRgbBlack );
maskGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
maskGc->Clear();
TPoint point( 0, 0 );
for ( TInt j = 0 ; j < aBmps / 2 ; j++ )
{
// bitmap
bitmapGc->BitBlt( point, bitmaps[j] );
// mask
maskGc->BitBlt( point, masks[j] );
point.iX += bitmaps[j]->SizeInPixels().iWidth;
// Mask must be same size as the corresponding bitmap!
__ASSERT_ALWAYS( aBitmapsData.iBitmapSizes[j] == masks[j]->SizeInPixels(),
User::Invariant() );
}
RFile finalBitmapFile;
User::LeaveIfError( finalBitmapFile.Replace( iFs, aFinalBitmapFile, EFileWrite ) );
CleanupClosePushL( finalBitmapFile );
User::LeaveIfError( largeBitmap->Save( finalBitmapFile ) );
RFile finalMaskFile;
User::LeaveIfError( finalMaskFile.Replace( iFs, aFinalMaskFile, EFileWrite ) );
CleanupClosePushL( finalMaskFile );
User::LeaveIfError( largeMask->Save( finalMaskFile ) );
// bitmaps, masks, multiBitmapfile, largeBitmap, largeMask, bitmapDevice, bitmapGc, maskDevice, maskGc,
// finalBitmapFile, finalMaskFile
CleanupStack::PopAndDestroy( 11 );
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GeneratePictographDefinitionsL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GeneratePictographDefinitionsL()
{
TFileName name;
name = KGeneratedPathEpoc;
name.Append( KDefinitionsFile );
RFile file;
User::LeaveIfError( file.Replace( iFs, name, EFileWrite ) );
CleanupClosePushL( file );
TInt pos = 0;
// go in the beginning of the file
User::LeaveIfError( file.Seek( ESeekStart, pos ) );
HBufC8* buffer = HBufC8::NewLC( KBufferSizeForHeaderGeneration );
TPtr8 data = buffer->Des();
data.Append( KGeneratedInfo );
data.Append( KDefinitionHeaderStart );
// TAknPictographSupportedHeights array
GenerateTAknPictographSupportedHeightsArrayL( data );
// TAknPictographSupportedHeightsNumbers array
GenerateTAknPictographSupportedHeightsNumbersArrayL( data );
data.Append( KAknPictographSupportedHeightsCount );
// Animation definitions
GenerateAnimationDefinitionsL( data );
// Animation frames definitions
GenerateAnimationFramesDefinitionsL( data );
// Animated pictograph table
GenerateAnimatedPictographTableL( data );
// Static definitions
GenerateStaticDefinitionsL( data );
// Static pictorah table
GenerateStaticPictographTableL( data );
data.Append( KHeaderEnd );
User::LeaveIfError( file.Write( data ) );
CleanupStack::PopAndDestroy( 2 ); // file, buffer
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateTAknPictographSupportedHeightsArrayL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateTAknPictographSupportedHeightsArrayL(TPtr8& aData)
{
TBuf8<128> temp;
// TAknPictographSupportedHeights array
aData.Append( KAknPictographSupportedHeightsStart );
aData.Append( KArrayStart );
// any rows added in the array?
TBool rowsAdded = EFalse;
for (TInt i = 0; i < iIniFilesData.Count(); i++)
{
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[i]->iHeightIndex];
// prepare and append array row
temp.Zero();
temp.Format( KAknPictographSupportedHeightsArrayRow, height );
aData.Append( temp );
rowsAdded = ETrue;
}
if ( !rowsAdded )
{
// At least one height must be supported
User::Leave( KErrGeneral );
}
else
{
aData.Delete( aData.Length() - 3, 1 ); // remove last comma
aData.Append( KArrayEnd );
}
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateTAknPictographSupportedHeightsNumbersArrayL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::
GenerateTAknPictographSupportedHeightsNumbersArrayL(TPtr8& aData)
{
TBuf8<128> temp;
// TAknPictographSupportedHeights array
aData.Append( KAknPictographSupportedHeightsNumbersStart );
aData.Append( KArrayStart );
// any rows added in the array?
TBool rowsAdded = EFalse;
for (TInt i = 0; i < iIniFilesData.Count(); i++)
{
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[i]->iHeightIndex];
// prepare and append array row
temp.Zero();
temp.Format( KAknPictographSupportedHeightsNumbersArrayRow, height );
aData.Append( temp );
rowsAdded = ETrue;
}
if ( !rowsAdded )
{
// At least one height must be supported
User::Leave( KErrGeneral );
}
else
{
aData.Delete( aData.Length() - 3, 1 ); // remove last comma
aData.Append( KArrayEnd );
}
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateAnimationDefinitionsL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateAnimationDefinitionsL(TPtr8& aData)
{
TBuf8<128> temp;
// Generate Animation definitions for each supported height
for (TInt z = 0; z < iIniFilesData.Count(); z++)
{
TInt index = 0;
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[z]->iHeightIndex];
for ( TInt i = 0 ; i < iIniFilesData[z]->iIniData.Count() ; i++ )
{
RPointerArray<HBufC8>& filenameArray =
iIniFilesData[z]->iIniData[i]->iFilenameArray;
// if more than 2 bmps (bitmap and mask), it is animated
if ( filenameArray.Count() > 2 )
{
temp.Zero();
temp.Format( KAnimationDefinitionStart, iIniFilesData[z]->iIniData[i]->iCode, height);
aData.Append( temp );
aData.Append( KArrayStart );
for ( TInt ii = 0 ; ii < filenameArray.Count() ; ii += 2 )
{
TSize size = iBitmapsData[z]->iBitmapSizes[index + ii/2];
TInt offset = (*iBitmapsData[z]->iOffsets)[index + ii/2];
temp.Zero();
temp.Format( KAnimationFrame, offset, size.iWidth, size.iHeight );
aData.Append( temp );
}
aData.Delete( aData.Length() - 3, 1 ); // remove last comma
aData.Append( KArrayEnd );
}
index += filenameArray.Count() / 2;
}
}
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateAnimationFramesDefinitionsL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateAnimationFramesDefinitionsL(TPtr8& aData)
{
TBuf8<128> temp;
// Generate Animation Frames definitions for each for each
// animated pictograph
if (iIniFilesData.Count())
{
for ( TInt i = 0 ; i < iIniFilesData[0]->iIniData.Count() ; i++ )
{
// Check if the pictograph is animated and
// if yes it must be animated for all supported heights
TInt rowCount = 0;
for (TInt z = 0; z < iIniFilesData.Count(); z++)
{
RPointerArray<HBufC8>& array =
iIniFilesData[z]->iIniData[i]->iFilenameArray;
// If more than 2 bmps (bitmap and mask), it is animated
if ( array.Count() > 2 )
{
if (!rowCount)
{
// Only insert table header before the first row
// Animation Frames definition table
temp.Zero();
temp.Format( KAnimationFramesDefinitionStart,
iIniFilesData[0]->iIniData[i]->iCode);
aData.Append( temp );
aData.Append( KArrayStart );
}
// get current height
TInt height = TAknPictographMaxSetOfSupportedHeights[iIniFilesData[z]->iHeightIndex];
temp.Zero();
temp.Format( KAnimationFramesDefinitionRow,
array.Count() / 2,
iIniFilesData[0]->iIniData[i]->iCode,
height);
aData.Append( temp );
rowCount++;
}
}
if ( rowCount > 0 )
{
if ( rowCount != iIniFilesData.Count() )
{
// If it is animated pictograph then it must be for all heights
User::Leave( KErrGeneral );
}
else
{
aData.Delete( aData.Length() - 3, 1 ); // remove last comma
aData.Append( KArrayEnd );
}
}
}
}
else
{
// At least one height must be supported
User::Leave( KErrGeneral );
}
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateAnimatedPictographTableL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateAnimatedPictographTableL(TPtr8& aData)
{
TBuf8<256> temp;
if (iIniFilesData.Count())
{
aData.Append( KAnimatedTableStart );
aData.Append( KArrayStart );
// any rows added in the array?
TBool rowsAdded = EFalse;
for ( TInt i = 0 ; i < iIniFilesData[0]->iIniData.Count() ; i++ )
{
RPointerArray<HBufC8>& array =
iIniFilesData[0]->iIniData[i]->iFilenameArray;
// if more than 2 bmps (bitmap and mask), it is animated
if ( array.Count() > 2 )
{
// Checking if the pictograph is animated for all heights
// is done in function GenerateAnimationFramesDefinitionsL.
// It is enough to be done in one place.
temp.Zero();
temp.Format( KAnimatedTableRow,
iIniFilesData[0]->iIniData[i]->iCode,
/*rate*/1,
iIniFilesData[0]->iIniData[i]->iCode);
aData.Append( temp );
rowsAdded = ETrue;
}
}
TInt decCount = 0;
if ( !rowsAdded )
{
aData.Append( KAnimatedTableDummyRow );
decCount = 1; // This will adjust the real animated pictograph count to 0
}
else
{
aData.Delete( aData.Length() - 3, 1 ); // remove last comma
}
aData.Append( KArrayEnd );
// Append KAknPictographAnimatedPictographsCount row
temp.Zero();
temp.Format( KAknPictographAnimatedPictographsCount, decCount );
aData.Append( temp );
}
else
{
// At least one height must be supported
User::Leave( KErrGeneral );
}
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateStaticDefinitionsL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateStaticDefinitionsL(TPtr8& aData)
{
TBuf8<128> temp;
// Generate Static definitions for each static pictograph
if (iIniFilesData.Count())
{
RArray<TUint> indexArray = RArray<TUint>(iIniFilesData.Count());
CleanupClosePushL( indexArray );
// Init indexes for each supported height
for (TInt k = 0; k < iIniFilesData.Count(); k++)
{
indexArray.Append(0);
}
for ( TInt i = 0 ; i < iIniFilesData[0]->iIniData.Count() ; i++ )
{
// Check if the pictograph is static and
// if yes it must be static for all supported heights
TInt rowCount = 0;
for (TInt z = 0; z < iIniFilesData.Count(); z++)
{
RPointerArray<HBufC8>& array =
iIniFilesData[z]->iIniData[i]->iFilenameArray;
// if only 2 bmps (bitmap and mask), it is static
if ( array.Count() == 2 )
{
if (!rowCount)
{
// Only insert table header before the first row
// Static definition table
temp.Zero();
temp.Format( KStaticDefinitionStart,
iIniFilesData[0]->iIniData[i]->iCode);
aData.Append( temp );
aData.Append( KArrayStart );
}
TSize size = iBitmapsData[z]->iBitmapSizes[indexArray[z]];
TInt offset = (*iBitmapsData[z]->iOffsets)[indexArray[z]];
temp.Zero();
temp.Format( KStaticDefinitionRow, offset, size.iWidth, size.iHeight );
aData.Append( temp );
rowCount++;
}
indexArray[z] += array.Count() / 2;
}
if ( rowCount > 0 )
{
if ( rowCount != iIniFilesData.Count() )
{
// If it is static pictograph then it must be for all heights
User::Leave( KErrGeneral );
}
else
{
aData.Delete( aData.Length() - 3, 1 ); // remove last comma
aData.Append( KArrayEnd );
}
}
}
CleanupStack::PopAndDestroy(); // indexArray
}
else
{
// At least one height must be supported
User::Leave( KErrGeneral );
}
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GenerateStaticPictographTableL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GenerateStaticPictographTableL( TPtr8& aData )
{
TBuf8<256> temp;
aData.Append( KStaticTableStart );
aData.Append( KArrayStart );
// any rows added in the array?
TBool rowsAdded = EFalse;
for ( TInt i = 0 ; i < iIniFilesData[0]->iIniData.Count() ; i++ )
{
RPointerArray<HBufC8>& array =
iIniFilesData[0]->iIniData[i]->iFilenameArray;
// if only 2 bmps (bitmap and mask), it is static
if ( array.Count() == 2 )
{
// Checking if the pictograph is static for all heights
// is done in function GenerateStaticDefinitionsL.
// It is enough to be done in one place.
temp.Zero();
temp.Format( KStaticTableRow,
iIniFilesData[0]->iIniData[i]->iCode,
iIniFilesData[0]->iIniData[i]->iCode );
aData.Append( temp );
rowsAdded = ETrue;
}
}
TInt decCount = 0;
if ( !rowsAdded )
{
aData.Append( KStaticTableDummyRow );
decCount = 1; // This will adjust the real static pictograph count to 0
}
else
{
aData.Delete( aData.Length() - 3, 1 ); // remove last comma
}
aData.Append( KArrayEnd );
// Append KAknPictographStaticPictographsCount row
temp.Zero();
temp.Format( KAknPictographStaticPictographsCount, decCount );
aData.Append( temp );
}
// -----------------------------------------------------------------------------
// CBitmapBuilder::GeneratePictographRangeL
// -----------------------------------------------------------------------------
//
void CBitmapBuilder::GeneratePictographRangeL()
{
if (iIniFilesData.Count() && iIniFilesData[0]->iIniData.Count())
{
TFileName name;
name = KGeneratedPathEpoc;
name.Append( KRangeFile );
RFile file;
User::LeaveIfError( file.Replace( iFs, name, EFileWrite ) );
CleanupClosePushL( file );
TInt pos = 0;
// go in the beginning of the file
User::LeaveIfError( file.Seek( ESeekStart, pos ) );
HBufC8* buffer = HBufC8::NewLC( 4000 );
TPtr8 data = buffer->Des();
TBuf8<128> temp;
data.Append( KGeneratedInfo );
data.Append( KRangeHeaderStart );
temp.Format( KRangeStart, iIniFilesData[0]->iIniData[0]->iCode );
data.Append( temp );
temp.Format( KRangeEnd, iIniFilesData[0]->iIniData[iIniFilesData[0]->iIniData.Count() - 1]->iCode );
data.Append( temp );
data.Append( KEndIf );
data.Append( KHeaderEnd );
User::LeaveIfError( file.Write( data ) );
CleanupStack::PopAndDestroy( 2 ); // file, buffer
}
else
{
// At least one height and one pictograph must be supported
User::Leave( KErrGeneral );
}
}
// End of File