uifw/ganes/src/HgVgImageCreator.cpp
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/ganes/src/HgVgImageCreator.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,193 @@
+/*
+* Copyright (c) 2009 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 FILES
+
+#include "HgVgImageCreator.h"
+#include "HgVgEGL.h"
+
+#include <e32math.h>
+#include <gulicon.h>
+#include <fbs.h>
+#include <nvg.h>
+#include <AknIconHeader.h>
+#include <AknIconUtils.h>
+
+
+static const TUid KUidMySingleton = { 0x100000E9 };
+
+
+static TAknIconHeader GetNvgIconHeader(HBufC8* aNVGData)
+    {
+    // Parse the icon header info from the extended data
+    TPtr8 IconHeaderPtr((TUint8*)aNVGData->Des().Ptr(), KIconHeaderLength, KIconHeaderLength);
+    TAknIconHeader iconheader(IconHeaderPtr);
+    
+    return iconheader;
+    }
+    
+static TPtr8 GetNvgDataWithoutHeader(HBufC8* aNVGData)
+    {
+    // The rest of the data (after the iconheader) are the OVG drawing instructions
+    TInt lengthAfterHeader = aNVGData->Length() - KIconHeaderLength;
+    TPtr8 nvgDataVoidIC((TUint8 *)aNVGData->Des().Ptr() + KIconHeaderLength, lengthAfterHeader, lengthAfterHeader);
+    
+    return nvgDataVoidIC;
+    }
+
+static HBufC8* ReadNVGDataL(const CFbsBitmap& aBitmap)
+    {
+    // Fetch the extended data
+    aBitmap.BeginDataAccess();
+    const TUint32* data = aBitmap.DataAddress();
+    TInt dataSize = aBitmap.DataSize();
+    TUint8* compressedData = new (ELeave) TUint8[dataSize];
+    CleanupStack::PushL(compressedData);
+    Mem::Copy(compressedData, data, dataSize);
+    aBitmap.EndDataAccess(ETrue);
+    
+    // Create a descriptor out of the extended bitmap data. The iNVGData
+    // will now contain the direct OpenVG commands
+    TPtr8 nvgDataPtr(compressedData, dataSize, dataSize);
+    HBufC8* dataBuf = nvgDataPtr.AllocL();
+    
+    CleanupStack::PopAndDestroy(compressedData);
+    return dataBuf;
+    }
+
+VGImage CHgVgImageCreator::RenderImageFromIconL( const CFbsBitmap* aBitmap )
+    {
+    User::LeaveIfNull(aBitmap);
+    User::LeaveIfNull(iEGL);
+        
+    HBufC8* nvgData = ReadNVGDataL(*aBitmap);
+
+    TSize size = aBitmap->SizeInPixels();
+
+    VGImage image = vgCreateImage(VG_sARGB_8888_PRE, size.iWidth, size.iHeight,VG_IMAGE_QUALITY_NONANTIALIASED);
+    
+    const EGLint    KColorAttribList[] =
+            {
+            EGL_NONE
+            };
+
+    CNvgEngine* nvgEngine = CNvgEngine::NewL();
+    CleanupStack::PushL(nvgEngine);
+    
+    EGLSurface newSurface = eglCreatePbufferFromClientBuffer(
+        iEGL->Display(), EGL_OPENVG_IMAGE,
+        static_cast<EGLClientBuffer>(image),    // Use the image as buffer
+        iEGL->CurrentConfig(), KColorAttribList );
+    
+    eglMakeCurrent( iEGL->Display(), newSurface, newSurface, iEGL->Context() );
+    
+    vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+    vgLoadIdentity();
+    vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+    vgLoadIdentity();    
+    vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
+    vgSeti( VG_SCISSORING, VG_FALSE );
+    
+
+    TAknIconHeader iconheader = GetNvgIconHeader(nvgData);        
+    // Set preserve aspect ratio according to the header info
+    TNvgAlignStatusType alignTypeValue = ENvgPreserveAspectRatio_XmidYmid;
+    TNvgMeetOrSliceType meetOrSliceTypeValue = ENvgMeet;
+    if ( iconheader.GetScaleMode() == EAspectRatioPreserved )
+        {
+        
+        }
+    else if (iconheader.GetScaleMode() == EAspectRatioPreservedSlice)
+        {
+        meetOrSliceTypeValue = ENvgSlice;
+        }
+    else if (iconheader.GetScaleMode() == EAspectRatioPreservedAndUnusedSpaceRemoved || 
+            iconheader.GetScaleMode() == EAspectRatioNotPreserved )
+        {
+        alignTypeValue = ENvgPreserveAspectRatio_None;
+        }
+
+    nvgEngine->SetPreserveAspectRatio(alignTypeValue, meetOrSliceTypeValue);
+    nvgEngine->Rotate(iconheader.GetRotation(),size.iWidth >>1, size.iHeight >>1);
+    
+    nvgEngine->DrawNvg(GetNvgDataWithoutHeader(nvgData), size, NULL, NULL);
+        
+    // TODO: Error handling. DrawNvg mey fail icon rendering.
+    
+    delete nvgData;
+
+    CleanupStack::PopAndDestroy(nvgEngine);
+    
+    // TODO: should we call explicitly vgFlush at this point to force all commands
+    // complete before eglMakeCurrent?
+    
+    eglMakeCurrent(iEGL->Display(), iEGL->Surface(), iEGL->Surface(), iEGL->Context());
+        
+    if ( newSurface != EGL_NO_SURFACE )
+        {
+        eglDestroySurface( iEGL->Display(), newSurface );
+        }
+
+    // reset states, and matrices which nvg lefts dirty.    
+    vgSeti( VG_BLEND_MODE, VG_BLEND_SRC_OVER );
+    vgSeti( VG_SCISSORING, VG_FALSE );
+    vgSeti( VG_MASKING, VG_FALSE );
+    vgSeti( VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER );
+    vgLoadIdentity();
+    vgSeti( VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER );
+    vgLoadIdentity();
+    
+    return image;
+
+    }
+
+CHgVgImageCreator* CHgVgImageCreator::InstanceL()
+    {
+    CHgVgImageCreator* instance = static_cast<CHgVgImageCreator*>( CCoeEnv::Static( KUidMySingleton ) );
+    
+    if ( !instance )
+        {
+        instance = new ( ELeave ) CHgVgImageCreator;
+        CleanupStack::PushL( instance );
+        instance->ConstructL();
+        CleanupStack::Pop();
+        }
+    
+    return instance;
+    }
+
+    
+CHgVgImageCreator::CHgVgImageCreator() : CCoeStatic( KUidMySingleton )
+     {
+     }
+
+CHgVgImageCreator::~CHgVgImageCreator()
+    {
+    //delete iNvgEngine;
+    }
+
+void CHgVgImageCreator::ConstructL()
+    {
+    //iNvgEngine = CNvgEngine::NewL();
+    }
+    
+void CHgVgImageCreator::Initialize(CHgVgEGL* aEGL)
+    {
+    iEGL = aEGL;
+    }
+
+// End of File