pictographs/AknPictograph/src/AknPictographFactory.cpp
changeset 0 05e9090e2422
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pictographs/AknPictograph/src/AknPictographFactory.cpp	Thu Dec 17 09:14:12 2009 +0200
@@ -0,0 +1,345 @@
+/*
+* 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 "AknPictographFactory.h"
+#include "AknPictographConstants.h"
+#include "AknPictographDefinitions.h"
+#include "AknStaticPictographDefKey.h"
+#include "AknAnimatedPictographDefKey.h"
+
+#include <fbs.h>
+#include <gdi.h>
+#include <bitdev.h>
+
+
+
+
+// CONSTANTS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::SupportedPictographCodesL
+// -----------------------------------------------------------------------------
+//
+HBufC* AknPictographFactory::SupportedPictographCodesL()
+    {
+    // static pictographs
+    const TAknStaticPictographDefinition* staticTable = 
+        TheStaticPictographDefinitions;
+
+    // animated pictographs
+    const TAknAnimatedPictographDefinition* animatedTable = 
+        TheAnimatedPictographDefinitions;
+
+    TInt numPictographs = KAknPictographStaticPictographsCount +
+                          KAknPictographAnimatedPictographsCount;
+
+    RArray<TUint> array( numPictographs );
+    CleanupClosePushL( array );
+
+    // append static pictograph codes
+    for ( TInt i = 0 ; i < KAknPictographStaticPictographsCount ; i++ )
+        {
+        User::LeaveIfError( array.Append( staticTable[i].iCode ) );
+        }
+
+    // append animated pictograph codes
+    for ( TInt j = 0 ; j < KAknPictographAnimatedPictographsCount ; j++ )
+        {
+        User::LeaveIfError( array.Append( animatedTable[j].iCode ) );
+        }
+
+    // sort
+    array.Sort();
+
+    // copy to descriptor
+    HBufC* buf = HBufC::NewMaxL( numPictographs );
+    TText* codes = const_cast<TText*>( buf->Ptr() );
+
+    for ( TInt k = 0 ; k < numPictographs ; k++ )
+        {
+        codes[k] = static_cast<TText>( array[k] );
+        }
+
+    CleanupStack::PopAndDestroy(); // array
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::StaticPictographData
+// -----------------------------------------------------------------------------
+//
+TInt AknPictographFactory::StaticPictographData( 
+    TText aCode, TAknPictographHeight aHeight, TAknPictographData& aData )
+    {
+    // Search static pictograph table.
+    TAknStaticPictographDefKey staticDefKey;
+    staticDefKey.SetPtr( &aCode );
+    TInt pos;
+
+    TInt ret = User::BinarySearch( KAknPictographStaticPictographsCount,
+                                   staticDefKey,
+                                   pos );
+
+    const TAknStaticPictographDefinition* def = NULL;
+
+    if ( ret == KErrNone )
+        {
+        def = &( TheStaticPictographDefinitions[pos] );
+
+        TUint index = 0;
+        ret = GetArrayIndexForHeight(aHeight,index);
+
+        if ( ret == KErrNone )
+            {
+            aData.iOffset = def->iMetrics[index].iX;
+            aData.iSize.iWidth = def->iMetrics[index].iWidth;
+            aData.iSize.iHeight = def->iMetrics[index].iHeight;
+            aData.iAnimated = EFalse;
+            }
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::AnimatedPictographData
+// -----------------------------------------------------------------------------
+//
+TInt AknPictographFactory::AnimatedPictographData(
+    TText aCode,
+    TAknPictographHeight aHeight,
+    TUint aCounter,
+    TAknPictographData& aData )
+    {
+    // Search animated pictograph table.
+    TAknAnimatedPictographDefKey animatedDefKey;
+    animatedDefKey.SetPtr( &aCode );
+    TInt pos;
+
+    TInt ret = User::BinarySearch( KAknPictographAnimatedPictographsCount,
+                                   animatedDefKey,
+                                   pos );
+
+    const TAknAnimatedPictographDefinition* def = NULL;
+
+    if ( ret == KErrNone )
+        {
+        def = &( TheAnimatedPictographDefinitions[pos] );
+
+
+        TUint index = 0;
+        ret = GetArrayIndexForHeight(aHeight,index);
+
+        if ( ret == KErrNone )
+            {
+            TInt frame = aCounter % def->iFramesDefinitions[index].iFrames;
+
+            const TAknPictographMetrics* metrics = def->iFramesDefinitions[index].iMetrics;
+            aData.iOffset = metrics[frame].iX;
+            aData.iSize.iWidth = metrics[frame].iWidth;
+            aData.iSize.iHeight = metrics[frame].iHeight;
+            aData.iAnimated = ETrue;
+            }
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::StaticPictographTable
+// -----------------------------------------------------------------------------
+//
+const TAknStaticPictographDefinition* 
+    AknPictographFactory::StaticPictographTable()
+    {
+    return TheStaticPictographDefinitions;
+    }
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::AnimatedPictographTable
+// -----------------------------------------------------------------------------
+//
+const TAknAnimatedPictographDefinition* 
+    AknPictographFactory::AnimatedPictographTable()
+    {
+    return TheAnimatedPictographDefinitions;
+    }
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::LoadBitmapsL
+// -----------------------------------------------------------------------------
+//
+void AknPictographFactory::LoadBitmapsL(
+            RPointerArray<CFbsBitmap>*& aBitmaps,
+            RPointerArray<CFbsBitmap>*& aMasks
+            )
+    {
+    // Allocates array object and sets proper granularity values
+    aBitmaps = new(ELeave) RPointerArray<CFbsBitmap>(KAknPictographSupportedHeightsCount);
+    aMasks = new(ELeave) RPointerArray<CFbsBitmap>(KAknPictographSupportedHeightsCount);
+
+    TFileName filename;
+    CFbsBitmap* bitmap = NULL;
+
+    // Loads supported bitamps and masks
+    for (TInt i = 0; i < KAknPictographSupportedHeightsCount; i++)
+        {
+        // Load bitmap and append to aBitmaps
+        filename = KBitmapFileNameBase;
+        filename.AppendNum( TAknPictographSupportedHeightsNumbers[i] );
+        filename.Append( KExtension );
+        bitmap = new( ELeave ) CFbsBitmap;
+        CleanupStack::PushL( bitmap );
+        User::LeaveIfError( aBitmaps->Append(bitmap) );
+        CleanupStack::Pop( bitmap );
+        User::LeaveIfError( bitmap->Load( filename ) );
+
+        // Load bitmap mask and append to aBitmaps
+        filename = KMaskFileNameBase;
+        filename.AppendNum( TAknPictographSupportedHeightsNumbers[i] );
+        filename.Append( KExtension );
+        bitmap = new( ELeave ) CFbsBitmap;
+        CleanupStack::PushL( bitmap );
+        User::LeaveIfError( aMasks->Append(bitmap) );
+        CleanupStack::Pop( bitmap );
+        User::LeaveIfError( bitmap->Load( filename ) );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::CreateWhiteBitmapsL
+// -----------------------------------------------------------------------------
+//
+void AknPictographFactory::CreateWhiteBitmapsL(
+            CFbsBitmap*& aBitmap,
+            CFbsBitmap*& aMask,
+            CFbsBitmapDevice*& aMaskBitmapDevice,
+            CFbsBitGc*& aMaskGc
+            )
+    {
+    __ASSERT_DEBUG( KAknPictographSupportedHeightsCount > 0, User::Invariant() );
+    // Note: TAknPictographSupportedHeightsNumbers should contain height numbers
+    // ascending order
+    // The size estimate below is derived from the heights of the biggest supported pictograph
+    const TInt sideLenght = TAknPictographSupportedHeightsNumbers[KAknPictographSupportedHeightsCount-1]*2;
+    const TSize whiteBitmapSize(sideLenght,sideLenght);
+
+    // create white bitmap
+    CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
+    CleanupStack::PushL(bitmap);
+    User::LeaveIfError( bitmap->Create( whiteBitmapSize, EGray2 ) );
+    CFbsBitmapDevice* bitmapDev = CFbsBitmapDevice::NewL( bitmap );
+    CleanupStack::PushL( bitmapDev );
+    CFbsBitGc* bitmapGc = NULL;
+    User::LeaveIfError( bitmapDev->CreateContext( bitmapGc ) );
+    CleanupStack::PushL( bitmapGc );
+
+    // fill the whole bitmap with white color
+    bitmapGc->SetBrushColor(KRgbWhite);
+    bitmapGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+    bitmapGc->Clear();
+    CleanupStack::PopAndDestroy(2); // bitmapDev, bitmapGc
+
+    // create the mask (to be filled later)
+    CFbsBitmap* mask = new (ELeave) CFbsBitmap();
+    CleanupStack::PushL(mask);
+    User::LeaveIfError( mask->Create( whiteBitmapSize, EGray2 ) );
+    CFbsBitmapDevice* maskDev = CFbsBitmapDevice::NewL( mask );
+    CleanupStack::PushL( maskDev );
+    CFbsBitGc* maskGc = NULL;
+    User::LeaveIfError( maskDev->CreateContext( maskGc ) );
+
+    // fill the whole are of mask with white color
+    maskGc->SetBrushColor(KRgbWhite);
+    maskGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+    maskGc->Clear();
+
+    CleanupStack::Pop(3); // bitmap, mask, maskDev
+    aBitmap = bitmap;
+    aMask = mask;
+    aMaskBitmapDevice = maskDev;
+    aMaskGc = maskGc;
+    }
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::GetArrayIndexForHeight
+// -----------------------------------------------------------------------------
+//
+TInt AknPictographFactory::GetArrayIndexForHeight(
+            TAknPictographHeight aHeight,
+            TUint& aIndex
+            )
+    {
+    TInt ret = KErrNotSupported;
+
+    for (TInt i = 0; i < KAknPictographSupportedHeightsCount; i++)
+        {
+        if (TAknPictographSupportedHeights[i] == aHeight)
+            {
+            aIndex = i;
+            ret = KErrNone;
+            break;
+            }
+        }
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// AknPictographFactory::SelectPictographHeightForFont
+// -----------------------------------------------------------------------------
+//
+TInt AknPictographFactory::SelectPictographHeightForFont(
+            const CFont& aFont,
+            TAknPictographHeight& aHeight
+            )
+    {
+    TInt ret = KErrNotSupported;
+    TInt fontHeight = aFont.HeightInPixels();
+    TInt i;
+
+    // Search for the first height that is bigger
+    // Note: TAknPictographSupportedHeightsNumbers should contain height numbers
+    // ascending order
+    for (i = 0; i < KAknPictographSupportedHeightsCount; i++)
+        {
+        if ((TUint)fontHeight < TAknPictographSupportedHeightsNumbers[i])
+            {
+            break;
+            }
+        }
+
+    // The previous height should be the best match
+    // Use the biggest supported pictograph height in case the font height is
+    // bigger
+    TInt index = i-1;
+    if (index >= 0)
+        {
+        aHeight = TAknPictographSupportedHeights[index];
+        ret = KErrNone;
+        }
+
+    return ret;
+    }
+
+
+
+//  End of File