/*
* 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: Format Handler for NGA(will create an extended bitmap)
*
*/
// INCLUDE FILES
#include <e32math.h>
#include <fbs.h>
#include <mifconvdefs.h> // For definition of EIconFormatSVG
#include "AknNGAFormatHandler.h"
#include "AknIconObserver.h"
#include "AknIconSrvPanic.h"
#include "AknIconTraces.h"
#include "AknBitmap.h"
#include "AknIconManager.h"
#include "AknIconHeader.h"
#include <SVGRendererId.h>
// CONSTANTS
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::CAknNGAFormatHandler
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CAknNGAFormatHandler::CAknNGAFormatHandler(TSize aBitmapSize,TDisplayMode aBitmapDspMode,TDisplayMode aMaskDspMode):iBitmapSize(aBitmapSize),
iBitmapDspMode(aBitmapDspMode),
iMaskDspMode(aMaskDspMode)
{
iData = 0;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::ConstructL(TInt /*aType*/)
{
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x Calling ConstructL - iSvgEngine: %x"), this, iSvgEngine);
#endif
}
CAknNGAFormatHandler* CAknNGAFormatHandler::NewL(TInt aType,TSize aBitmapSize,TDisplayMode aBitmapDspMode,TDisplayMode aMaskDspMode)
{
CAknNGAFormatHandler* self = new( ELeave ) CAknNGAFormatHandler(aBitmapSize,aBitmapDspMode,aMaskDspMode);
CleanupStack::PushL( self );
self->ConstructL(aType);
CleanupStack::Pop();
return self;
}
// Destructor
CAknNGAFormatHandler::~CAknNGAFormatHandler()
{
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x Calling ~CAknNGAFormatHandler - iSvgEngine: %x"), this, iSvgEngine);
#endif
delete iSvgEngine;
delete iDummyBitmap;
delete iData;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::SetScaleMode
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::SetScaleMode( TScaleMode aMode )
{
iMode = aMode;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::SetRotation
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::SetRotation( TInt aAngle )
{
iAngle = aAngle;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::GetContentDimensionsL
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::GetContentDimensionsL( TAknContentDimensions& aContentDimensions )
{
__ASSERT_DEBUG( iSvgEngine,
User::Panic( KAknIconSrvPanicCategory, ESrvPanicSvgEngineMissing ) );
CheckHandleActivatedL( NULL, NULL );
iSvgEngine->ContentDimensions(aContentDimensions.iWidth,aContentDimensions.iHeight);
if ( aContentDimensions.iWidth <= 0 || aContentDimensions.iHeight <= 0 )
{
User::Leave( KErrNotFound );
}
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::InitializeEngineL
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::InitializeEngineL()
{
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x Calling InitializeEngineL - iSvgEngine: %x"), this, iSvgEngine);
#endif
if ( !iSvgEngine )
{
TFontSpec spec;
if ( !iDummyBitmap )
{
// Have to give some bitmap to the engine in the constructor.
iDummyBitmap = new( ELeave ) CFbsBitmap;
}
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x In InitializeEngineL - iDummyBitmap: %x"), this, iDummyBitmap);
#endif
iSvgEngine = CSvgEngineInterfaceImpl::NewL( iDummyBitmap, this, spec,ESVGRendererTLV );
iSvgEngine->SetBackgroundColor( 0xFFFFFFFF );
// No DRM check needed.
iSvgEngine->SetDRMMode( EFalse );
}
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x InitializeEngineL called - iSvgEngine: %x"), this, iSvgEngine);
#endif
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::PrepareIconL
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::PrepareIconL( const TDesC8& aIconData, TInt& aHandle )
{
InitializeEngineL();
TInt handle = -1;
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x Calling PrepareDom"), this );
#endif
LeaveIfErrorL( iSvgEngine->PrepareDom( aIconData, handle ) );
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x PrepareDom called - handle = %d"), this, handle );
#endif
aHandle = handle;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::UsePreparedIconL
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::UsePreparedIconL( TInt aHandle )
{
__ASSERT_DEBUG( iSvgEngine,
User::Panic( KAknIconSrvPanicCategory, ESrvPanicSvgEngineMissing ) );
if ( aHandle != iHandle )
{
iHandle = aHandle;
iHandleActivationStatus = ENotActivated;
}
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::RenderPreparedIconL
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::RenderPreparedIconL(
CFbsBitmap* aBitmap,
CFbsBitmap* aMask,TSize Bitmapsize,TDisplayMode Bitmapdepth,TDisplayMode Maskdepth, TRgb aColor, TBool aMarginFlag )
{
__ASSERT_DEBUG( iSvgEngine,
User::Panic( KAknIconSrvPanicCategory, ESrvPanicSvgEngineMissing ) );
iMask = aMask;
iBitmapSize=Bitmapsize;
iBitmapDspMode=Bitmapdepth;
iMaskDspMode=Maskdepth;
// Make sure iMask is NULL'ed if a leave occurs so that an invalid pointer
// is not left there.
CleanupStack::PushL( TCleanupItem( CleanupNullMaskPointer, this ) );
CheckHandleActivatedL( aBitmap, aMask );
TReal32 angle = 0;
TSize size;
if ( iAngle && !iAnimated )
{
// SVG engine wants rotation angle as TReal32 and in radians.
angle = (TReal32)iAngle / (TReal32)(360 / 2 / (TReal32)KPi);
iSvgEngine->Rotate(angle, Bitmapsize.iWidth / 2, Bitmapsize.iHeight / 2);
}
else
{
iSvgEngine->Rotate(0.0f, Bitmapsize.iWidth / 2, Bitmapsize.iHeight / 2);
}
SetEngineScaleMode();
MSvgError* aError = NULL;
iSvgEngine->ChooseViewBoxIfNotSet( iHandle );
FormCommonHeader(aBitmap, EFalse, aColor, aMarginFlag);
TPtr8 lPtr( iData->Des() );
iSvgEngine->Start(aError,&lPtr);
TRAPD(err,LeaveIfErrorL(aError));
if ( err != KErrNone || !iAnimated )
{
// SVG engine cannot handle the situation, where the bitmap given in UseDom
// is deleted before next UseDom call, this is a workaround for it.
LeaveIfErrorL( iSvgEngine->UseDom( iHandle,aBitmap,aMask,iBitmapSize,iBitmapDspMode,iMaskDspMode) );
iHandleActivationStatus = EActivated;
// Undo any rotation, so that the situation is resetted for the
// next request with different parameters.
if ( iAngle )
{
iSvgEngine->Rotate( -angle, size.iWidth / 2, size.iHeight / 2 );
}
User::LeaveIfError(err);
CleanupStack::PopAndDestroy(); // CleanupNullMaskPointer
}
else
{
CleanupStack::Pop(); // Keep mask pointer if animated.
}
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::UnprepareIcon
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::UnprepareIcon( TInt aHandle )
{
__ASSERT_DEBUG( iSvgEngine,
User::Panic( KAknIconSrvPanicCategory, ESrvPanicSvgEngineMissing ) );
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x Calling DeleteDom - handle = %d"), this, aHandle );
#endif
iSvgEngine->DeleteDom( aHandle );
if ( aHandle == iHandle )
{
iHandleActivationStatus = ENotActivated;
}
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::SetAnimated
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::SetAnimated( TBool aAnimated )
{
iAnimated = aAnimated;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::IconFormatType
// -----------------------------------------------------------------------------
//
TInt CAknNGAFormatHandler::IconFormatType()
{
return EIconFormatNGA;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::SetObserver
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::SetObserver( MAknIconChangeObserver* aObserver )
{
#ifdef __AKNICON_TRACES
RDebug::Print( _L("AknIcon: %x Calling SetObserver - aObserver: %x"), this, aObserver);
#endif
iObserver = aObserver;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::CheckHandleActivatedL
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::CheckHandleActivatedL( CFbsBitmap* aBitmap, CFbsBitmap* aMask )
{
if ( !aBitmap )
{
if ( iHandleActivationStatus == ENotActivated )
{
#ifdef __AKNICON_TRACES
RDebug::Print(
_L("AknIcon: %x Calling UseDom - Handle = %d, Bitmap ptr = %x, Mask ptr = %x"),
this, iHandle, aBitmap, aMask );
#endif
LeaveIfErrorL( iSvgEngine->UseDom( iHandle,aBitmap,aMask,iBitmapSize,iBitmapDspMode,iMaskDspMode ) );
#ifdef __AKNICON_TRACES
RDebug::Print(
_L("AknIcon: %x UseDom called - Handle = %d, Bitmap ptr = %x, Mask ptr = %x"),
this, iHandle, aBitmap, aMask );
#endif
iHandleActivationStatus = EActivated;
}
}
else
{
if ( iHandleActivationStatus != EActivatedWithFrameBuffer || iAnimated )
{
#ifdef __AKNICON_TRACES
RDebug::Print(
_L("AknIcon: %x Calling UseDom - Handle = %d, Bitmap ptr = %x, Mask ptr = %x"),
this, iHandle, aBitmap, aMask );
#endif
LeaveIfErrorL( iSvgEngine->UseDom( iHandle,aBitmap,aMask,iBitmapSize,iBitmapDspMode,iMaskDspMode ) );
#ifdef __AKNICON_TRACES
RDebug::Print(
_L("AknIcon: %x UseDom called - Handle = %d, Bitmap ptr = %x, Mask ptr = %x"),
this, iHandle, aBitmap, aMask );
#endif
iHandleActivationStatus = EActivatedWithFrameBuffer;
}
}
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::SupportedDisplayMode
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::SupportedDisplayMode(
TDisplayMode& aMode, TDisplayMode aPreferredMode )
{
// Modes currently supported by SVG engine are:
// EGray2, EColor4K, EColor64K, EColor16M
// if ( aMode != EGray2 ) EASK-824CMD:VGISymbianCopyToBitmap fails for bitmaps with EGray2 display modes.Modifying to create bitmaps with supported displaymodes
{
aMode = aPreferredMode;
}
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::UpdateScreen
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::UpdateScreen()
{
if ( iObserver )
{
iObserver->BitmapChanged();
}
else if (iAnimated)
{
iSvgEngine->Stop();
}
else
{
// skip
}
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::ScriptCall
// -----------------------------------------------------------------------------
//
TBool CAknNGAFormatHandler::ScriptCall(
const TDesC& /*aScript*/,
CSvgElementImpl* /*aCallerElement*/ )
{
return EFalse;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::FetchImage
// -----------------------------------------------------------------------------
//
TInt CAknNGAFormatHandler::FetchImage(
const TDesC& /*aUri*/, RFs& /*aSession*/, RFile& /*aFileHandle*/ )
{
return KErrNotSupported;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::SetEngineScaleMode
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::SetEngineScaleMode()
{
TSvgPreserveAspectAlignType alignTypeValue = ESvgPreserveAspectRatio_XmidYmid;
TSvgMeetOrSliceType meetOrSliceTypeValue = ESvgMeetOrSlice_Meet;
switch ( iMode )
{
case EAspectRatioPreserved: // fall through
{
// use default
break;
}
// Ensures SVG content fully covers
// the area of the icon whilst preserving aspect ratio.
case EAspectRatioPreservedSlice:
{
// alignTypeValue use default
meetOrSliceTypeValue = ESvgMeetOrSlice_Slice;
break;
}
// EAspectRatioPreservedAndUnusedSpaceRemoved is mapped to
// the same values as EAspectRatioNotPreserved
// because we already have a frame buffer
// with the dimensions that preserves the aspect ratio.
// This mapping ensures that SVG engine does not calculate aspect
// ratio twice and potentially resulting in precision loss.
case EAspectRatioPreservedAndUnusedSpaceRemoved:
case EAspectRatioNotPreserved:
{
alignTypeValue = ESvgPreserveAspectRatio_None;
// meetOrSliceTypeValue use default
break;
}
default:
{
__ASSERT_DEBUG( 0, User::Invariant() );
}
}
iSvgEngine->SetPreserveAspectRatio( NULL, alignTypeValue, meetOrSliceTypeValue, ETrue);
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::UpdatePresentation
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::UpdatePresentation(
const TInt32& /*aNoOfAnimation*/ )
{
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::UpdatePresentation
// -----------------------------------------------------------------------------
//
TInt CAknNGAFormatHandler::FetchFont( const TDesC& /*aUri*/, RFs& /*aSession*/, RFile& /*aFileHandle*/ )
{
return KErrNotSupported;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::LeaveIfErrorL
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::LeaveIfErrorL( MSvgError* aError )
{
User::LeaveIfNull( aError );
if ( aError->HasError() && !aError->IsWarning() )
{
User::LeaveIfError( SvgErrorToSymbianError( aError->ErrorCode() ) );
}
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::SvgErrorToSymbianError
// -----------------------------------------------------------------------------
//
TInt CAknNGAFormatHandler::SvgErrorToSymbianError( const TSvgErrorCode aError )
{
// most common mapping...
TInt ret = KErrGeneral;
switch ( aError )
{
case ESvgNoError:
ret = KErrNone;
break;
case ESvgFileNotFound:
ret = KErrNotFound;
break;
case ESvgDocumentNotValid: // fall through
case ESvgDocumentNotAvailable:
break;
case ESvgNoMemory:
ret = KErrNoMemory;
break;
case ESvgDiskFull:
ret = KErrDiskFull;
break;
case ESvgUnknown: // fall through
case ESvgMissingRequiredAttribute: // fall through
case ESvgInvalidAttributeValue: // fall through
default:
break;
}
return ret;
}
// -----------------------------------------------------------------------------
// CAknNGAFormatHandler::CleanupNullMaskPointer
// -----------------------------------------------------------------------------
//
void CAknNGAFormatHandler::CleanupNullMaskPointer( TAny* aParam )
{
static_cast<CAknNGAFormatHandler*>( aParam )->iMask = NULL;
}
void CAknNGAFormatHandler::FormCommonHeader(const CFbsBitmap *aBitmap, TBool isMask,TRgb aColor, TBool aMarginFlag)
{
if(!iData)
iData = HBufC8::New(KIconHeaderLength);
TPtr8 tmpBufPtr (iData->Des());
tmpBufPtr.SetLength(KIconHeaderLength);
TAknIconHeader iconheader(tmpBufPtr);
iconheader.Initialize();
iconheader.SetRotation(iAngle);
iconheader.SetIconColor(aColor.Value());
iconheader.SetScaleMode(iMode);
if(aMarginFlag)
iconheader.SetMarginCorrection(ETrue);
iconheader.SetIsMask(isMask);
iconheader.SetBitmapId(aBitmap->Handle());
}
// End of File