uiacceltk/hitchcock/coretoolkit/src/HuiFxEffectParser.cpp
changeset 0 15bf7259bb7c
child 3 d8a3531bc6b8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/src/HuiFxEffectParser.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,1215 @@
+/*
+* Copyright (c) 2008 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:   
+*
+*/
+
+
+
+#include "HuiFxEffectParser.h"
+
+#include <stdarg.h>
+#include <gmxmldocument.h>
+#include <gmxmlelement.h>
+#include <gmxmlnode.h>
+#include <gmxmltext.h>
+#include <gmxmlprocessinginstruction.h>
+#include <gmxmlcdatasection.h>
+#include "HuiFxConstants.h"
+#include "HuiFxFilter.h"
+#include "HuiFxGroupLayer.h"
+#include "HuiFxFilterLayer.h"
+#include "HuiFxVisualLayer.h"
+#include "HuiFxEffect.h"
+#include "HuiFxParameter.h"
+#include "HuiFxScalarParameter.h"
+#include "HuiFxColorParameter.h"
+#include "uiacceltk/HuiVisual.h"  // Class definition
+#include "alflogger.h"
+#include "huieffectable.h"
+#include <stdlib.h>
+
+//#define _HUI_FX_PARSER_LOGGING // Enable this, if you need to debug the xml parsing. otherwise leave this out, because the logging breaks the timing of effects
+// Debugging macros
+#if !defined(NDEBUG)
+#define FAIL(CODE, MSG)         FailL(CODE, MSG)
+#define FAIL1(CODE, MSG, P1)    FailL(CODE, MSG, P1)
+#else
+#define FAIL(CODE, MSG)
+#define FAIL1(CODE, MSG, P1)
+#endif
+
+CHuiFxEffectParser* CHuiFxEffectParser::NewL(CHuiFxEngine& aEngine, MHuiEffectable* aVisual)
+    {
+    CHuiFxEffectParser* self = NewLC(aEngine, aVisual);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CHuiFxEffectParser* CHuiFxEffectParser::NewLC(CHuiFxEngine& aEngine, MHuiEffectable* aVisual)
+    {
+    CHuiFxEffectParser* self = new (ELeave) CHuiFxEffectParser( aEngine, aVisual );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+    
+void CHuiFxEffectParser::ConstructL()
+    {
+    iParser = CMDXMLParser::NewL( this ) ;
+    User::LeaveIfError( iFs.Connect() );
+    CActiveScheduler::Add( this );
+    }
+    
+CHuiFxEffectParser::CHuiFxEffectParser( CHuiFxEngine& aEngine, MHuiEffectable* aVisual ) :
+    CActive( EPriorityHigh ),
+    iEngine( aEngine ),
+    iVisual( aVisual ),
+    iParsingEndedObserver( NULL ), iParsingEndedHandle(0)
+    {
+    __ALFFXLOGSTRING2("CHuiFxEffectParser::CHuiFxEffectParser - this: 0x%x aVisual 0x%x", this, aVisual);
+    }
+    
+CHuiFxEffectParser::~CHuiFxEffectParser()
+    {
+    Cancel();
+    
+    delete iParser;
+    iParser = NULL;
+    
+    delete iDoc;
+    iDoc = NULL;
+    
+    delete iEffect;
+    iEffect = NULL;
+    
+    iFs.Close();
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::~CHuiFxEffectParser - 0x%x ", this);
+}
+    
+void CHuiFxEffectParser::ParseFileCompleteL()
+    {
+    TRequestStatus* status = &iStatus;
+    TInt err = KErrNone; // We don't get any error from the caller.
+    if ( iIsCancelled )
+       {
+       err = KErrCancel;
+       }
+    User::RequestComplete( status, err );
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::ParseFileCompleteL - 0x%x",this);
+    }
+
+void CHuiFxEffectParser::RunL()
+    {
+    __ALFFXLOGSTRING2("CHuiFxEffectParser::RunL - this 0x%x, status: %d", this, iStatus.Int());
+    // RunL will only be called once after the parsing completes
+    if ( iStatus.Int() == KErrNone )
+        {
+        BuildEffectL();
+        iEffect->SetEffectFlags( iFlags );
+        iFlags = 0;
+        // As soon as the visual gets the effect, it kills this effect parser.
+        // Therefore the effect must be stored into a temporary variable 
+        // and the member of the parser set to null to prevent the fresly released visual
+        // from being destroyed immediately.
+        // CHuiVisual::SetEffect does dot leave, it just stores the pointer to its own data area,
+        // so this is a safe trick, and the boat does not leak.
+        if (iParsingEndedObserver)
+            {
+            iParsingEndedObserver->ParsingEnded(iParsingEndedHandle);
+            }
+
+#ifndef HUIFX_EFFECTCACHE_ENABLED
+        CHuiFxEffect* tempEffect = iEffect;
+#endif
+        iEffect = NULL;
+        if (iVisual)
+            {
+            iVisual->EffectSetOpacity(1.0f);
+#ifndef HUIFX_EFFECTCACHE_ENABLED
+            iVisual->SetEffect( tempEffect );
+#endif
+            }
+        }
+    else if ( iStatus.Int() != KErrCancel )
+        {
+        // some error during parsing - delete possible incomplete effect
+        // and set the effect in the visual to NULL as we did not succeed in creating
+        // a decent effect
+        if (iParsingEndedObserver)
+            {
+            iParsingEndedObserver->ParsingEnded(iParsingEndedHandle);
+            }
+        delete iEffect;
+        iEffect = NULL;
+        if (iVisual)
+            {
+            iVisual->EffectSetOpacity(1.0f);
+            iVisual->EffectSetEffect( NULL );
+            }
+        }
+    else // We got cancelled
+        {
+        delete iEffect;
+        iEffect = NULL;
+        }    
+    delete this;
+    // MUST NOT DO ANYTHING AFTER THE delete this -line!
+    }
+
+TInt CHuiFxEffectParser::RunError( TInt /*aError*/ )
+    {
+    // we signal that we handled the error 
+    delete iEffect;
+    iEffect = NULL;
+    if ( iVisual )
+        {
+        iVisual->EffectSetEffect( NULL );
+        }
+    return KErrNone;
+    }
+
+void CHuiFxEffectParser::DoCancel()
+    {
+    // cancel the parsing.
+    // 
+    iIsCancelled = ETrue;
+    iParser->Cancel();
+    // parser should now call our ParseFileCompleteL()
+    // Unfortunately it will not tell us any error code.
+    // Therefore we must remember that we were cancelled.
+    // We can only be cancelled when CHuiFxEffectParser is deleted.
+    // We do not call iVisual->SetEffect any more in that case 
+    // because in that case the parser gets deleted anyway.
+    // We don't want to be deleted twice - though setting the parser to NULL after
+    // deleting should take care of that anyway.
+    
+    // Actually it seems that parser will not necessarily call us,
+    // so we must ensure ourselves that we are completed (but only once!)
+    // Otherwise then whole system will hang waiting for an event
+    
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrCancel );
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::DoCancel - 0x%x",this);
+    }
+
+void CHuiFxEffectParser::ParseL( const TDesC& aFile, TRect aExtRect )
+    {
+    __ALFFXLOGSTRING2("CHuiFxEffectParser::ParseL - 0x%x %S",this, &aFile);
+    iIsCancelled = EFalse;
+    iExtRect = aExtRect;
+    TInt err = iParser->ParseFile( iFs, aFile );
+    if ( err != KErrNone )
+        {
+        // If parsing fails, give up immediately
+        iVisual->EffectSetEffect( NULL );
+        User::Leave( err );
+        }
+    iStatus = KRequestPending;
+    SetActive();
+    // BuildEffectL is called in RunL when parser calls our callback which completes us.
+    __ALFFXLOGSTRING("CHuiFxEffectParser::ParseL - activated ");
+    }
+
+void CHuiFxEffectParser::Effect( CHuiFxEffect*& aEffect )
+    {
+    aEffect = iEffect;
+    iEffect = NULL;
+    }
+
+void CHuiFxEffectParser::SetEffectEndObserver( MAlfGfxEffectObserver* aEffectEndObserver, TInt aHandle )
+    {
+    iEffectEndObserver = aEffectEndObserver;
+    iHandle = aHandle;
+    }
+
+void CHuiFxEffectParser::SetParsingEndedObserver( MHuiFxParsingEndedObserver *aObserver, TInt aHandle )
+    {
+    iParsingEndedObserver = aObserver;
+    iParsingEndedHandle = aHandle;
+    }
+
+
+void CHuiFxEffectParser::SetEffectFlags( TInt aFlags )
+    {
+    iFlags = aFlags;
+    }
+    
+void CHuiFxEffectParser::BuildEffectL()
+    {
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::BuildEffectL - 0x%x",this);    
+    iEffect = CHuiFxEffect::NewL( iEngine );
+    iEffect->SetEffectEndObserver( iEffectEndObserver, iHandle );
+    iEffectEndObserver = NULL;
+    iHandle = 0;
+    iDoc = iParser->DetachXMLDoc();
+    User::LeaveIfNull( iDoc );
+    CMDXMLElement* root = iDoc->DocumentElement();
+    User::LeaveIfNull( root );
+    CMDXMLNode* node = root->FirstChild();
+    if( node->NodeName().Compare( KLitLayers ) != 0 )
+        {
+        FAIL(KErrGeneral, _L("Layer list not found"));
+        }
+    for (node = node->FirstChild(); node; node = node->NextSibling())
+        {
+        ParseNodeL( node, NULL );
+        }
+    __ALFFXLOGSTRING("CHuiFxEffectParser::BuildEffectL - complete ");
+    }
+    
+void CHuiFxEffectParser::ParseNodeL( CMDXMLNode* aNode, CHuiFxLayer* aLayer)
+    {
+    switch( ResolveNode( aNode ) )
+        {
+        case ENodeTypeUnknown:
+            {
+#ifdef _HUI_FX_PARSER_LOGGING
+            __ALFFXLOGSTRING("CHuiFxEffectParser::ParseNodeL - ENodeTypeUnknown");
+#endif
+            FAIL(KErrGeneral, _L("Unknown node type"));
+            break;
+            }
+            
+        case ENodeTypeGroup:
+            {
+#ifdef _HUI_FX_PARSER_LOGGING
+            __ALFFXLOGSTRING("CHuiFxEffectParser::ParseNodeL - ENodeTypeGroup");
+#endif
+            // can't have group layers inside group layer
+            if (aLayer && aLayer->Type() == ELayerTypeGroup)
+                {
+                FAIL(KErrGeneral, _L("Nested group layers not supported"));
+                }
+            
+            CHuiFxGroupLayer* group = CHuiFxGroupLayer::NewL();
+            CleanupStack::PushL( group );
+            for (CMDXMLNode* node = aNode->FirstChild(); node; node = node->NextSibling())
+                {
+                ParseNodeL( node, group );
+                }
+            iEffect->AddLayerL( group ); // ownership transferred
+            CleanupStack::Pop( group );
+            break;
+            }
+            
+        case ENodeTypeFilter:
+            {
+#ifdef _HUI_FX_PARSER_LOGGING
+            __ALFFXLOGSTRING("CHuiFxEffectParser::ParseNodeL - ENodeTypeFilter");
+#endif
+            THuiFxFilterType filterType = GetFilterTypeL( aNode );
+            CHuiFxFilter* filter = iEngine.CreateFilterL( filterType );
+            CleanupStack::PushL( filter );
+            CHuiFxFilterLayer* filterLayer = CHuiFxFilterLayer::NewL( filter );
+            CleanupStack::Pop( filter );
+            CleanupStack::PushL( filterLayer );
+            if (aLayer && aLayer->Type() == ELayerTypeGroup)
+                {
+                CHuiFxGroupLayer* group = reinterpret_cast<CHuiFxGroupLayer*>(aLayer);
+                group->AddLayerL( filterLayer ); // ownership transferred
+                }
+            else
+                {
+                iEffect->AddLayerL( filterLayer ); // ownership transferred
+                }
+            CleanupStack::Pop( filterLayer );
+            
+            if (filterType == EFilterTypeTransform)
+                {
+                filterLayer->SetTransformed(ETrue);
+                }
+            
+            for (CMDXMLNode* node = aNode->FirstChild(); node; node = node->NextSibling())
+                {
+                ParseNodeL( node, filterLayer );
+                }
+            break;
+            }
+            
+        case ENodeTypeVisual:
+            {
+#ifdef _HUI_FX_PARSER_LOGGING
+            __ALFFXLOGSTRING("CHuiFxEffectParser::ParseNodeL - ENodeTypeVisual");
+#endif
+            TPtrC16 extBitmap;
+            THuiFxVisualSrcType srcType = GetSrcTypeL( aNode, extBitmap );
+            CHuiFxVisualLayer* visual = CHuiFxVisualLayer::NewL( *iVisual );
+            CleanupStack::PushL( visual );
+            visual->SetSourceType( srcType );
+            if ( srcType == EVisualSrcBitmap && extBitmap.Length() > 0 )
+                {
+                visual->SetExtBitmapFileL( extBitmap );
+                }
+            if (aLayer && aLayer->Type() == ELayerTypeGroup)
+                {
+                CHuiFxGroupLayer* group = reinterpret_cast<CHuiFxGroupLayer*>(aLayer);
+                group->AddLayerL( visual ); // ownership transferred
+                }
+            else
+                {
+                iEffect->AddLayerL( visual ); // ownership transferred
+                }
+            for (CMDXMLNode* node = aNode->FirstChild(); node; node = node->NextSibling())
+                {
+                ParseNodeL( node, visual );
+                }
+            CleanupStack::Pop( visual );
+            break;
+            }
+         
+         case ENodeTypeBlending:
+            {
+#ifdef _HUI_FX_PARSER_LOGGING
+            __ALFFXLOGSTRING("CHuiFxEffectParser::ParseNodeL - ENodeTypeBlending");
+#endif
+            CMDXMLNode* blendingNode = aNode->FirstChild();
+            if( blendingNode->NodeType() != CMDXMLNode::ETextNode )
+                {
+                FAIL(KErrGeneral, _L("Bad blending mode"));
+                }
+            TPtrC modePtr( ((CMDXMLText *)blendingNode)->Data() );
+            
+            // set replace as default blending mode
+            THuiFxBlendingMode blendingMode = EBlendingModeReplace;
+            if( modePtr.Compare( KLitReplace ) == 0 )
+                {
+                blendingMode = EBlendingModeReplace;
+                }
+            else if( modePtr.Compare( KLitOver ) == 0 )
+                {
+                blendingMode = EBlendingModeOver;
+                }
+            else if( modePtr.Compare( KLitMultiply ) == 0 )
+                {
+                blendingMode = EBlendingModeMultiply;
+                }
+            else if( modePtr.Compare( KLitAdditive ) == 0 )
+                {
+                blendingMode = EBlendingModeAdditive;
+                }
+            else if( modePtr.Compare( KLitDarken ) == 0 )
+                {
+                blendingMode = EBlendingModeDarken;
+                }
+            else if( modePtr.Compare( KLitLighten ) == 0 )
+                {
+                blendingMode = EBlendingModeLighten;
+                }
+            else
+                {
+                FAIL(KErrGeneral, _L("Bad blending mode"));
+                }
+                
+            if (aLayer && aLayer->Type() == ELayerTypeGroup)
+                {
+                aLayer->SetBlendingMode( blendingMode );
+                }
+            else
+                {
+                // TODO: should other layers have a blending mode?
+                FAIL(KErrGeneral, _L("Blending mode can only be set for a group layer"));
+                }            
+            break;
+            }
+            
+         case  ENodeTypeParam:
+            {
+#ifdef _HUI_FX_PARSER_LOGGING
+            __ALFFXLOGSTRING("CHuiFxEffectParser::ParseNodeL - ENodeTypeParam");
+#endif
+            ResolveParamL(aNode, aLayer);
+            break;
+            }
+            
+        default:
+            __ALFFXLOGSTRING("CHuiFxEffectParser::ParseNodeL - default??");
+            break;
+        }
+    
+    }
+    
+CHuiFxEffectParser::TNodeType CHuiFxEffectParser::ResolveNode( CMDXMLNode* aNode )
+    {    
+    TPtrC nodeName( aNode->NodeName() );
+    if( nodeName.Compare( KLitLayerGroup ) == 0 )
+        {
+        return ENodeTypeGroup;
+        }
+    else if( nodeName.Compare( KLitFilter ) == 0 )
+        {
+        return ENodeTypeFilter;
+        }
+    else if( nodeName.Compare( KLitVisual ) == 0 )
+        {
+        return ENodeTypeVisual;
+        }
+    else if( nodeName.Compare( KLitBlending ) == 0 )
+        {
+        return ENodeTypeBlending;
+        }
+    else if( nodeName.Compare( KLitParam ) == 0 )
+        {
+        return ENodeTypeParam;
+        }
+    else if( nodeName.Compare( KLitStyle ) == 0 )
+        {
+        return ENodeTypeStyle;
+        }
+    else if( nodeName.Compare( KLitDuration ) == 0 )
+        {
+        return ENodeTypeDuration;
+        }
+    else if( nodeName.Compare( KLitKeyFrame ) == 0 )
+        {
+        return ENodeTypeKeyFrame;
+        }
+    else if( nodeName.Compare( KLitMarker ) == 0 )
+        {
+        return ENodeTypeMarker;
+        }
+    else if( nodeName.Compare( KLitStart ) == 0 )
+        {
+        return ENodeTypeStart;
+        }
+    else if( nodeName.Compare( KLitEnd ) == 0 )
+        {
+        return ENodeTypeEnd;
+        }
+    else
+        {
+        return ENodeTypeUnknown;
+        }
+    }
+
+// not locale dependent float parser
+static TReal32 ParseFloatVal(TPtrC valuePtr)
+    {
+    HBufC8 *buf = HBufC8::New(valuePtr.Length()+1);
+    if (!buf) return 0.0;
+    CleanupStack::PushL(buf);
+    buf->Des().Copy(valuePtr);
+    
+    TUint8 *buf2 = new TUint8[valuePtr.Length()+1];
+    if (!buf2) return 0.0;
+    int s = valuePtr.Length();
+    int i = 0;
+    for(;i<s;i++)
+        buf2[i] = buf->operator[](i);
+    buf2[i] = 0;
+    
+    TReal32 v = atof((const char*)buf2);
+    delete [] buf2;
+    CleanupStack::PopAndDestroy(buf);
+    return v;
+    }
+
+TReal32 CHuiFxEffectParser::ParseFloatAttributeL(CMDXMLNode* aNode, const TDesC& aName, TBool aMustExist)
+    {
+    TInt index = ((CMDXMLElement*)aNode)->FindIndex(aName);
+    if( index == KErrNotFound )
+        {
+        if (aMustExist)
+            {
+            FAIL1(KErrGeneral, _L("Attribute not found: %S"), &aName); // leaves 
+            return 0.0f; // never reached. For completeness
+            }
+        else
+            {
+            return 0.0f;
+            }
+        }
+
+    TPtrC attributeValue;
+    TPtrC attributeName;
+    TReal32 value = 0.0f;
+    User::LeaveIfError(((CMDXMLElement*)aNode)->AttributeDetails( index, attributeName, attributeValue ));
+
+    value = ParseFloatVal(attributeValue);
+    return value;
+    }
+
+TReal32 CHuiFxEffectParser::ParseFloatValueL(CMDXMLNode* aNode)
+    {
+    if ( !aNode || aNode->NodeType() != CMDXMLNode::ETextNode )
+        {
+        FAIL(KErrGeneral, _L("Text node expected while parsing a floating point value"));
+        }
+    
+    TPtrC valuePtr( ((CMDXMLText *)aNode)->Data() );
+    TReal32 v = ParseFloatVal(valuePtr);
+    return v;
+    }
+
+TRgb CHuiFxEffectParser::ParseColorValueL(CMDXMLNode* aNode)
+    {
+    // Parse color definition in HTML notation (#aarrggbb)
+    if ( !aNode || aNode->NodeType() != CMDXMLNode::ETextNode )
+        {
+        FAIL(KErrGeneral, _L("Text node expected while parsing a color value")); // leaves
+        return KRgbBlack; // never reached. For completeness
+        }
+    
+    TPtrC valuePtr( ((CMDXMLText *)aNode)->Data() );
+    TLex parser(valuePtr);
+
+    if (parser.Get() != '#')
+            {
+            FAIL(KErrGeneral, _L("Invalid color specification")); // leaves
+            return KRgbBlack; // never reached. For completeness
+            }
+
+    TUint32 color;
+    parser.Val(color, EHex);
+    // Opaque alpha by default
+    if (valuePtr.Length() <= 7)
+        {
+        color |= 0xff000000;
+        }
+    
+    TUint32 r = (color & 0x00ff0000) >> 16;
+    TUint32 g = (color & 0x0000ff00) >> 8;
+    TUint32 b = (color & 0x000000ff);
+    TUint32 a = (color & 0xff000000) >> 24;
+    
+    return TRgb(r, g, b, a);
+    }
+
+template <>
+TReal32 CHuiFxEffectParser::ParseAnimationKeyFrameValueL(CMDXMLNode* aNode, RHuiFxScalarTimeLine& /*aTimeLine*/)
+    {
+    return ParseFloatValueL(aNode);
+    }
+
+template <>
+TRgb CHuiFxEffectParser::ParseAnimationKeyFrameValueL(CMDXMLNode* aNode, RHuiFxColorTimeLine& /*aTimeLine*/)
+    {
+    return ParseColorValueL(aNode);
+    }
+
+template <typename PARAM_TYPE, typename TIMELINE_TYPE, typename VALUE_TYPE>
+void CHuiFxEffectParser::ParseAnimationNodeL(CMDXMLNode* aNode, PARAM_TYPE& aParam, TIMELINE_TYPE& aTimeLine)
+    {
+#ifdef _HUI_FX_PARSER_LOGGING
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::ParseAnimationNodeL - 0x%x", this);
+#endif
+    switch( ResolveNode( aNode ) )
+        {
+        case ENodeTypeDuration:
+            {
+            aTimeLine.SetDuration(ParseFloatValueL(aNode->FirstChild()));
+            }
+            break;
+        case ENodeTypeStyle:
+            {
+            CMDXMLNode* styleNode = aNode->FirstChild();
+            if (styleNode->NodeType() != CMDXMLNode::ETextNode)
+                {
+                FAIL(KErrGeneral, _L("Text node expected while parsing an interpolation mode"));
+                }
+            TPtrC modePtr( ((CMDXMLText *)styleNode)->Data() );
+            
+            if( modePtr.Compare( KLitHold ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeHold);
+                }
+            else if( modePtr.Compare( KLitLinear ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeLinear);
+                }
+            else if( modePtr.Compare( KLitInQuad ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeInQuad);
+                }
+            else if( modePtr.Compare( KLitOutQuad ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeOutQuad);
+                }
+            else if( modePtr.Compare( KLitInOutQuad ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeInOutQuad);
+                }
+            else if( modePtr.Compare( KLitOutInQuad ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeOutInQuad);
+                }
+            else if( modePtr.Compare( KLitInBack ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeInBack);
+                }
+            else if( modePtr.Compare( KLitOutBack ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeOutBack);
+                }
+            else if( modePtr.Compare( KLitInOutBack ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeInOutBack);
+                }
+            else if( modePtr.Compare( KLitOutInBack ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeOutInBack);
+                }
+            else if( modePtr.Compare( KLitQuadraticBezier ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeQuadraticBezier);
+                }
+            else if( modePtr.Compare( KLitCubicBezier ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeCubicBezier);
+                }
+/*                
+            else if( modePtr.Compare( KLitDeclerate ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeDecelerate);
+                }
+            else if( modePtr.Compare( KLitAccelerate ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeAccelerate);
+                }
+            else if( modePtr.Compare( KLitImpulse ) == 0 )
+                {
+                aTimeLine.SetInterpolationMode(EInterpolationModeImpulse);
+                }
+*/                
+            else
+                {
+                // unknown (unsupported) interpolation modes default to linear
+                // (at least during testing when we add modes)
+                aTimeLine.SetInterpolationMode(EInterpolationModeLinear);
+//                FAIL(KErrGeneral, _L("Unknown interpolation mode"));
+                }
+            break;
+            }
+        case ENodeTypeMarker:
+            {
+            TReal32 time = ParseFloatAttributeL(aNode, KLitAt);
+            TInt typeIndex = ((CMDXMLElement*)aNode)->FindIndex( KLitType );
+            
+            if (typeIndex == KErrNotFound)
+                {
+                FAIL(KErrGeneral, _L("Marker name not found"));
+                }
+
+            TPtrC attributeValue;
+            TPtrC attributeName;
+            User::LeaveIfError(((CMDXMLElement*)aNode)->AttributeDetails( typeIndex, attributeName, attributeValue ));
+
+            // TODO: Should this be controllable?
+            aTimeLine.SetLoopingMode(ELoopingModeRepeat);
+
+            if (attributeValue.Compare(KLitLoopStart) == 0)
+                {
+                aTimeLine.SetLoopStart(time);
+                }
+            else if (attributeValue.Compare(KLitLoopEnd) == 0)
+                {
+                aTimeLine.SetLoopEnd(time);
+                }
+            else
+                {
+                FAIL(KErrGeneral, _L("Unsupported marker type"));
+                }
+            break;
+            }
+        case ENodeTypeKeyFrame:
+            {
+            TReal32 time = ParseFloatAttributeL(aNode, KLitAt);
+            TReal32 aux1 = ParseFloatAttributeL(aNode, KLitAux1, EFalse);
+            TReal32 aux2 = ParseFloatAttributeL(aNode, KLitAux2, EFalse);
+            VALUE_TYPE value = ParseAnimationKeyFrameValueL<PARAM_TYPE::ValueType, TIMELINE_TYPE>(aNode->FirstChild(), aTimeLine);
+            TRAPD(err, aTimeLine.AppendKeyFrameL(time, value, aux1, aux2));
+            if (err != KErrNone)
+                {
+                FAIL(KErrGeneral, _L("Unable to append new key frame to timeline"));
+                }
+            }
+            break;
+        case ENodeTypeStart:
+            {
+            TInt refIndex  = ((CMDXMLElement*)aNode)->FindIndex( KLitRef );
+            TReal32 refValue = 0;
+            TBool needRefValue = EFalse;
+            THuiFxReferencePoint ref = EReferencePointUndefined;
+            if ( refIndex != KErrNotFound )
+                {
+                ref = GetReferencePointL( aNode, refValue, needRefValue );
+                }
+            aParam.SetStartReference( ref );
+            if ( needRefValue )
+                {
+                aParam.SetStartValue( refValue );
+                }
+            if ( aParam.StartReference() != EReferencePointUndefined &&
+               aParam.EndReference() != EReferencePointUndefined )
+                {
+                aParam.SetReferencePoint( EReferencePointUndefined );
+                }
+	     float value = ParseFloatValueL(aNode->FirstChild());
+	     aParam.SetStartMultiplier( value );
+
+            }
+            break;
+        case ENodeTypeEnd:
+            {
+            TInt refIndex  = ((CMDXMLElement*)aNode)->FindIndex( KLitRef );
+            TReal32 refValue = 0;
+            TBool needRefValue = EFalse;
+            THuiFxReferencePoint ref = EReferencePointUndefined;
+            if ( refIndex != KErrNotFound )
+                {
+                ref = GetReferencePointL( aNode, refValue, needRefValue );
+                }
+            aParam.SetEndReference( ref );
+            if ( needRefValue )
+                {
+                aParam.SetEndValue( refValue );
+                }
+            if ( aParam.StartReference() != EReferencePointUndefined &&
+               aParam.EndReference() != EReferencePointUndefined )
+                {
+                aParam.SetReferencePoint( EReferencePointUndefined );
+                }
+            float value = ParseFloatValueL(aNode->FirstChild());
+            aParam.SetEndMultiplier( value );
+
+            }
+            break;
+        }
+#ifdef _HUI_FX_PARSER_LOGGING
+    __ALFFXLOGSTRING("CHuiFxEffectParser::ParseAnimationNodeL - out");
+#endif
+    }
+
+
+void CHuiFxEffectParser::ResolveParamL( CMDXMLNode* aNode, CHuiFxLayer* aLayer )
+    {
+#ifdef _HUI_FX_PARSER_LOGGING
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::ResolveParamL - 0x%x",this);
+#endif
+    ASSERT(aNode->NodeType() == CMDXMLNode::EElementNode);
+
+    TInt nameIndex = ((CMDXMLElement*)aNode)->FindIndex( KLitName );
+    TInt typeIndex = ((CMDXMLElement*)aNode)->FindIndex( KLitType );
+    TInt refIndex  = ((CMDXMLElement*)aNode)->FindIndex( KLitRef );
+    if( nameIndex == KErrNotFound )
+        {
+        FAIL(KErrGeneral, _L("Parameter name not found"));
+        }
+    
+    THuiFxReferencePoint ref = EReferencePointIdentity;
+    TBool isAnimated = EFalse;
+    TPtrC paramName;
+    TPtrC attributeName;
+    User::LeaveIfError(((CMDXMLElement*)aNode)->AttributeDetails(nameIndex, attributeName, paramName));
+
+    if (typeIndex != KErrNotFound)
+        {
+        TPtrC paramType;
+        User::LeaveIfError(((CMDXMLElement*)aNode)->AttributeDetails(typeIndex, attributeName, paramType));
+
+        if( paramType.Compare( KLitAnim ) == 0 )
+            {
+            isAnimated = ETrue;
+            aLayer->SetAnimated(ETrue);
+            }
+        else
+            {
+            FAIL(KErrGeneral, _L("Unsupported parameter type"));
+            }
+        }
+    
+    TReal32 refValue;
+    TBool needRefValue = EFalse;
+    
+    
+    if ( refIndex != KErrNotFound )
+        {
+        ref = GetReferencePointL( aNode, refValue, needRefValue );
+        if ( ref == EReferencePointUndefined )
+            {
+            // For the parameters an undefined reference point means no value for the change
+            ref = EReferencePointIdentity;
+            }
+        }
+    
+    MHuiFxParameter* param = NULL;
+    if (aLayer && aLayer->Type() == ELayerTypeFilter)
+        {
+        CHuiFxFilterLayer* filterLayer = reinterpret_cast<CHuiFxFilterLayer*>(aLayer);
+        // We must check if we really have a filter.
+        // If the filter type was incorrect, a filter was not created
+        // We should not crash or panic even if the effect file is not syntactically correct.
+        // An incorrect file should simply produce no effect.
+        CHuiFxFilter& filter = filterLayer->Filter();
+        
+        if ( &filter )
+            {
+            param = filter.Parameter( paramName );
+            }
+        }
+    else if (aLayer && aLayer->Type() == ELayerTypeVisual)
+        {
+        CHuiFxVisualLayer* visualLayer = reinterpret_cast<CHuiFxVisualLayer*>(aLayer); 
+        param = visualLayer->Parameter(paramName);
+        }
+    
+    if (!param)
+        {
+        FAIL(KErrNotFound, _L("Parameter name not recognized")); // leaves
+        return; // never reached. For completeness
+        }
+
+    param->SetReferencePoint(ref);
+    if ( needRefValue )
+        {
+        param->SetReferenceValue( refValue );
+        }
+    
+    if (isAnimated)
+        {
+        // Collect animation keyframes and other parameters
+        switch (param->Type())
+            {
+            case EParameterTypeScalar:
+                {
+                RHuiFxScalarTimeLine* t = new (ELeave) RHuiFxScalarTimeLine();
+                CHuiFxScalarParameter* p = static_cast<CHuiFxScalarParameter*>(param); 
+                CleanupStack::PushL(t);
+                for (CMDXMLNode* child = aNode->FirstChild(); child; child = child->NextSibling())
+                    {
+                    ParseAnimationNodeL<CHuiFxScalarParameter, RHuiFxScalarTimeLine, CHuiFxScalarParameter::ValueType>(child, *p, *t);
+                    }
+                CleanupStack::Pop(t);
+                p->SetTimeLine(t);
+                if ( p->ReferencePoint() == EReferencePointUndefined )
+                    {
+                    if ( paramName.Compare( KLitScaleX ) == 0 )
+                        {
+                        p->SetReferencePoint( EReferencePointVisualWidth );
+                        }
+                    else if ( paramName.Compare( KLitScaleY ) == 0 )
+                        {
+                        p->SetReferencePoint( EReferencePointVisualHeight );
+                        }
+                    else
+                        {
+                        p->SetReferencePoint( EReferencePointIdentity );
+                        }
+                    }
+                break;
+                }
+        case EParameterTypeColor:
+                {
+                RHuiFxColorTimeLine* t = new (ELeave) RHuiFxColorTimeLine();
+                CHuiFxColorParameter* p = static_cast<CHuiFxColorParameter*>(param); 
+                CleanupStack::PushL(t);
+                for (CMDXMLNode* child = aNode->FirstChild(); child; child = child->NextSibling())
+                    {
+                    ParseAnimationNodeL<CHuiFxColorParameter, RHuiFxColorTimeLine, CHuiFxColorParameter::ValueType>(child, *p, *t);
+                    }
+                CleanupStack::Pop(t);
+                p->SetTimeLine(t);
+                if ( p->ReferencePoint() == EReferencePointUndefined )
+                    {
+                    p->SetReferencePoint( EReferencePointIdentity );
+                    }
+                break;
+                }
+            }
+        }
+    else
+        {
+        switch (param->Type())
+            {
+            case EParameterTypeScalar:
+                {
+                CHuiFxScalarParameter* p = static_cast<CHuiFxScalarParameter*>(param); 
+                p->SetValue(ParseFloatValueL(aNode->FirstChild()));
+                break;
+                }
+        case EParameterTypeColor:
+                {
+                CHuiFxColorParameter* p = static_cast<CHuiFxColorParameter*>(param); 
+                p->SetValue(ParseColorValueL(aNode->FirstChild()));
+                break;
+                }
+            }
+        }
+#ifdef _HUI_FX_PARSER_LOGGING
+    __ALFFXLOGSTRING("CHuiFxEffectParser::ResolveParamL - out ");
+#endif
+    }
+
+THuiFxFilterType CHuiFxEffectParser::GetFilterTypeL( CMDXMLNode* aNode )
+    {
+#ifdef _HUI_FX_PARSER_LOGGING
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::GetFilterTypeL - 0x%x",this);
+#endif
+    if (aNode->NodeType() != CMDXMLNode::EElementNode)
+        {
+        FAIL(KErrGeneral, _L("Text node expected while reading filter type"));
+        }
+    
+    TInt attributeIndex = ((CMDXMLElement*)aNode)->FindIndex( KLitType );
+
+    if (attributeIndex == KErrNotFound)
+        {
+        FAIL(KErrGeneral, _L("Filter type not found"));
+        }
+    
+    TPtrC attributeValue;
+    TPtrC attributeName;
+    User::LeaveIfError(((CMDXMLElement*)aNode)->AttributeDetails( attributeIndex, attributeName, attributeValue));
+
+    if( attributeValue.Compare( KLitDesaturate ) == 0 )
+        {
+        return EFilterTypeDesaturate;
+        }
+    else if( attributeValue.Compare( KLitBlur ) == 0 )
+        {
+        return EFilterTypeBlur;
+        }
+    else if( attributeValue.Compare( KLitGlow ) == 0 )
+        {
+        return EFilterTypeGlow;
+        }
+    else if( attributeValue.Compare( KLitBrightnessContrast ) == 0 )
+        {
+        return EFilterTypeBrightnessContrast;
+        }
+    else if( attributeValue.Compare( KlitHSL ) == 0 )
+        {
+        return EFilterTypeHSL;
+        }
+    else if( attributeValue.Compare( KlitColorize ) == 0 )
+        {
+        return EFilterTypeColorize;
+        }
+    else if( attributeValue.Compare( KlitOutline ) == 0 )
+        {
+        return EFilterTypeOutline;
+        }
+    else if( attributeValue.Compare( KLitDropShadow ) == 0 )
+        {
+        // drop shadow is generated using outline filter
+        return EFilterTypeOutline;
+        }
+    else if( attributeValue.Compare( KlitBevel ) == 0 )
+        {
+        return EFilterTypeBevel;
+        }
+    else if ( attributeValue.Compare ( KlitTransform ) == 0 )
+        {
+        return EFilterTypeTransform;
+        }
+    else
+        {
+        return EFilterTypeUnknown;
+        }
+    }
+    
+THuiFxReferencePoint CHuiFxEffectParser::GetReferencePointL( CMDXMLNode* aNode, TReal32& aRefValue, TBool& aNeedRefValue )
+    {
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::GetReferencePointL - 0x%x",this);
+    if (aNode->NodeType() != CMDXMLNode::EElementNode)
+        {
+        FAIL(KErrGeneral, _L("Text node expected while reading ref type"));
+        }
+    
+    TInt attributeIndex = ((CMDXMLElement*)aNode)->FindIndex( KLitRef );
+
+    THuiFxReferencePoint ref = EReferencePointIdentity;
+    if (attributeIndex == KErrNotFound)
+        {
+        ref = EReferencePointUndefined;
+        return ref;
+        }
+    aRefValue = 0;
+        
+    TPtrC attributeName;
+    TPtrC paramRef;
+    User::LeaveIfError(((CMDXMLElement*)aNode)->AttributeDetails( attributeIndex, attributeName, paramRef));
+    TReal32 refValue = 0;
+    TBool needRefValue = EFalse;
+
+    if ( paramRef.Compare( KLitVisualWidth ) == 0 )
+        {
+        ref = EReferencePointVisualWidth;
+        }
+    else if ( paramRef.Compare( KLitVisualHeight ) == 0 )
+        {
+        ref = EReferencePointVisualHeight;
+        }
+    else if ( paramRef.Compare( KLitVisualTop ) == 0 )
+        {
+        ref = EReferencePointVisualTop;
+        }
+    else if ( paramRef.Compare( KLitVisualBottom ) == 0 )
+        {
+        ref = EReferencePointVisualBottom;
+        }
+    else if ( paramRef.Compare( KLitVisualLeft ) == 0 )
+        {
+        ref = EReferencePointVisualLeft;
+        }
+    else if ( paramRef.Compare( KLitVisualRight ) == 0 )
+        {
+        ref = EReferencePointVisualRight;
+        }
+    else if ( paramRef.Compare( KLitDisplayWidth ) == 0 )
+        {
+        ref = EReferencePointDisplayWidth;
+        }
+    else if ( paramRef.Compare( KLitDisplayHeight ) == 0 )
+        {
+        ref = EReferencePointDisplayHeight;
+        }
+    else if ( paramRef.Compare( KLitDisplayTop ) == 0 )
+        {
+        ref = EReferencePointDisplayTop;
+        }
+    else if ( paramRef.Compare( KLitDisplayBottom ) == 0 )
+        {
+        ref = EReferencePointDisplayBottom;
+        }
+    else if ( paramRef.Compare( KLitDisplayLeft ) == 0 )
+        {
+        ref = EReferencePointDisplayLeft;
+        }
+    else if ( paramRef.Compare( KLitDisplayRight ) == 0 )
+        {
+        ref = EReferencePointDisplayRight;
+        }
+    else if ( paramRef.Compare( KLitExtRectWidth ) == 0 )
+        {
+        needRefValue = ETrue;
+        ref = EReferencePointExtRectWidth;
+        refValue = iExtRect.Width();
+        }
+    else if ( paramRef.Compare( KLitExtRectHeight ) == 0 )
+        {
+        needRefValue = ETrue;
+        ref = EReferencePointExtRectHeight;
+        refValue = iExtRect.Height();
+        }
+    else if ( paramRef.Compare( KLitExtRectTop ) == 0 )
+        {
+        needRefValue = ETrue;
+        ref = EReferencePointExtRectTop;
+        refValue = iExtRect.iTl.iY;
+        }
+    else if ( paramRef.Compare( KLitExtRectBottom ) == 0 )
+        {
+        needRefValue = ETrue;
+        ref = EReferencePointExtRectBottom;
+        refValue = iExtRect.iBr.iY;
+        }
+    else if ( paramRef.Compare( KLitExtRectLeft ) == 0 )
+        {
+        needRefValue = ETrue;
+        ref = EReferencePointExtRectLeft;
+        refValue = iExtRect.iTl.iX;
+        }
+    else if ( paramRef.Compare( KLitExtRectRight ) == 0 )
+        {
+        needRefValue = ETrue;
+        ref = EReferencePointExtRectRight;
+        refValue = iExtRect.iBr.iX;
+        }
+    // these are deprecated
+    else if (paramRef.Compare(KLitVisualWidth1) == 0)
+        {
+        ref = EReferencePointVisualWidth; 
+        }
+    else if (paramRef.Compare(KLitVisualHeight1) == 0)
+        {
+        ref = EReferencePointVisualHeight; 
+        }
+    else if (paramRef.Compare(KLitDisplayWidth1) == 0)
+        {
+        ref = EReferencePointDisplayWidth; 
+        }
+    else if (paramRef.Compare(KLitDisplayHeight1) == 0)
+        {
+        ref = EReferencePointDisplayHeight; 
+        }
+    else
+        {
+        FAIL(KErrGeneral, _L("Unsupported parameter reference point"));
+        }
+    aRefValue = refValue;
+    aNeedRefValue = needRefValue;
+#ifdef _HUI_FX_PARSER_LOGGING
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::GetReferencePointL - return %d",ref);
+#endif
+    return ref;
+    }
+
+THuiFxVisualSrcType CHuiFxEffectParser::GetSrcTypeL( CMDXMLNode* aNode, TPtrC16& aBitmap )
+    {
+#ifdef _HUI_FX_PARSER_LOGGING
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::GetSrcTypeL - 0x%x ",this);
+#endif
+    if (aNode->NodeType() != CMDXMLNode::EElementNode)
+        {
+        FAIL(KErrGeneral, _L("Text node expected while reading visual source type"));
+        }
+    TInt attributeIndex = ((CMDXMLElement*)aNode)->FindIndex( KLitSrc );
+    
+    if (attributeIndex == KErrNotFound)
+        {
+        // If src not found, the source defaults to visual itself
+        return EVisualSrcVisual;
+        }
+        
+    TPtrC attributeValue;
+    TPtrC attributeName;
+    User::LeaveIfError(((CMDXMLElement*)aNode)->AttributeDetails( attributeIndex, attributeName, attributeValue ));
+  
+    if( attributeValue.Compare( KLitItem ) == 0 )
+        {
+        return EVisualSrcVisual;
+        }
+    else if ( attributeValue.Compare( KLitInput1 ) == 0 )
+        {
+        // This means that the source is given as a parameter to the effect
+        return EVisualSrcInput1;
+        }
+    else if ( attributeValue.Compare( KLitInput2 ) == 0 )
+        {
+        // This means that the source is given as a parameter to the effect
+        return EVisualSrcInput2;
+        }
+    else
+        {
+        // if nothing else is defined, the src represents an external file (bitmap)
+        aBitmap.Set( attributeValue );
+        return EVisualSrcBitmap;
+        }
+    
+    }
+
+
+void CHuiFxEffectParser::FailL(TInt aCode, TRefByValue<const TDesC> aFormat, ...)
+    {
+    TBuf<512> message;
+    VA_LIST args;
+    VA_START(args, aFormat);
+    message.Append(_L("CHuiFxEffectParser::Fail(): "));
+    message.AppendFormatList(aFormat, args);
+    VA_END(args);
+    __ALFFXLOGSTRING1("CHuiFxEffectParser::FailL %S", &message);
+    User::InfoPrint( message );
+    User::Leave(aCode);
+    }