services/terminalmodeservice/src/upnpsvgimageconverter.cpp
branchRCL_3
changeset 9 5c72fd91570d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/services/terminalmodeservice/src/upnpsvgimageconverter.cpp	Tue Aug 31 16:06:48 2010 +0300
@@ -0,0 +1,363 @@
+/**
+* Copyright (c) 2010 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: CUpnpSvgImageConverter class implementation.
+*
+*/
+
+#include "upnpsvgimageconverter.h"
+#include "upnptmserverimpl.h"
+#include <f32file.h> 
+#include "upnpiconconversionactive.h"
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "upnpsvgimageconverterTraces.h"
+#endif
+
+// Literals
+_LIT(KLatin,               "LatinPlain12");
+_LIT(KConvertedIconPath,   "public\\TmServerDevice1\\");
+_LIT(KCross,               "x");
+_LIT(KDotBmp,              ".bmp");
+_LIT(KThreadName,          "ImageConverterThread");
+_LIT(KSemaphoreName,       "ImageConverterSemaphore");
+
+// Constant
+const TUint KDot           = '.';
+
+// ============================ MEMBER FUNCTIONS ===================================
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::NewL
+// Two-phased constructor.
+// @param aIconWidth   Desired width of the serving icon.
+// @param aIconHeight  Desired height of the serving icon.
+// ---------------------------------------------------------------------------------
+//
+CUpnpSvgImageConverter* CUpnpSvgImageConverter::NewL( TInt aIconWidth, TInt aIconHeight )
+    {
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_NEWL_ENTRY );
+    OstTraceExt2( TRACE_NORMAL, CUPNPSVGIMAGECONVERTER_NEWL, "CUpnpSvgImageConverter::NewL;aIconWidth=%d;aIconHeight=%d", aIconWidth, aIconHeight );
+    CUpnpSvgImageConverter* self = new (ELeave) CUpnpSvgImageConverter( );
+    CleanupStack::PushL(self);
+    self->ConstructL( aIconWidth,aIconHeight );
+    CleanupStack::Pop(self);
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_NEWL_EXIT );
+    return self;    
+    }
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::CUpnpSvgImageConverter
+// C++ default constructor can NOT contain any code, that might leave.
+// ---------------------------------------------------------------------------------
+//
+CUpnpSvgImageConverter::CUpnpSvgImageConverter( )                                      
+    {
+
+    }
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::ConstructL
+// Symbian 2nd phase constructor can leave.
+// ---------------------------------------------------------------------------------
+//
+void CUpnpSvgImageConverter::ConstructL(  TInt aIconWidth, TInt aIconHeight )
+    {
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CONSTRUCTL_ENTRY );
+    //Geometric rectangle.
+    TRect lMainRect( 0,0,aIconWidth,aIconHeight );
+    /**
+     * Specifies the font specification to use for text drawing.
+     * Here "LatinPlain12" of height "10" is used.
+     */ 
+    TFontSpec lFontSpec( KLatin,UpnpString::KMaxTUintLength );
+    // A bitmap managed by the font and bitmap server.
+    User::LeaveIfError(iFbsSession.Connect());
+    iBitmap = new ( ELeave ) CFbsBitmap();
+    iMask = new ( ELeave ) CFbsBitmap();
+    //Creates bitmap file of the desired dimensions with desired display mode(64,000 colour)
+    User::LeaveIfError( iBitmap->Create( TSize( lMainRect.Width(),
+                        lMainRect.Height() ),EColor64K ) );
+    User::LeaveIfError( iMask->Create( TSize( lMainRect.Width(),
+                            lMainRect.Height() ),EGray256 ) );  // 256 grayscales display mode as alpha values
+    /**
+     * Create a new Svg Engine interface.
+     * @param iBitmap  bitmap to draw resulting svg image.
+     * @param aReqObserver(NULL) interface for callbacks to retrieve info
+     *                          only client can provide, such as opening files.
+     * @param lFontSpecFont spec to use for text drawing.
+     */
+    iSvgModule = CSvgEngineInterfaceImpl::NewL( iBitmap,NULL,lFontSpec );
+    User::LeaveIfError( iFileSession.Connect() );  
+    TBuf<UpnpString::KMaxFilenameLength> privatePath;  
+    User::LeaveIfError( iFileSession.PrivatePath(privatePath) );
+
+    privatePath.Append(KConvertedIconPath());
+    privatePath.AppendNum( aIconWidth );
+    privatePath.Append( KCross);
+    privatePath.AppendNum( aIconHeight );
+    privatePath.Append( UpnpString::KDoubleBackSlash16() );
+    TInt err = iFileSession.MkDir(privatePath);
+    if( ( err != KErrNone ) && ( err != KErrAlreadyExists ) )
+        {
+        // Leaves if fails to create a directory
+        User::Leave(err);
+        }
+    iBitMapFilePath.CreateL( UpnpString::KMaxFilenameLength );
+    iBitMapFilePath.Append( privatePath );
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CONSTRUCTL_EXIT );
+    }
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::~CUpnpSvgImageConverter
+// Destructor
+// ---------------------------------------------------------------------------------
+// 
+CUpnpSvgImageConverter::~CUpnpSvgImageConverter()
+    {  
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CUPNPSVGIMAGECONVERTER_ENTRY );
+    iBitMapFilePath.Close();
+    delete iMask;
+    delete iBitmap;
+    delete iSvgModule;        
+    iFbsSession.Disconnect();
+    iFileSession.Close();
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CUPNPSVGIMAGECONVERTER_EXIT );
+    }
+
+// -----------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::ConvertToBitmapL
+// Method invokes svg to bitmap conversion.
+// It takes svg file as an input and returns converted icon file( bmp ).
+// Also prepares DOM for given SVG file.
+// @param aSvgFile Input svg filepath
+// @param aBitmapFile[out] Bitmap filepath ( converted file ).
+// -----------------------------------------------------------------------------------
+void CUpnpSvgImageConverter::ConvertToBitmapL( const TDesC& aSvgFile, RBuf& aBitmapFile )
+    { 
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL_ENTRY );
+    /**
+     * Extracts the filename( without filename extension ) from the input svg filepath and 
+     * uses the same filename to create bitmap file ( eg: abc.bmp )
+     */ 
+    TPtrC iconFileNameWithExtension = aSvgFile.Mid((aSvgFile.LocateReverse(KDirectorySeparator))+1);
+    iBitMapFilePath.Append( iconFileNameWithExtension.Left(iconFileNameWithExtension.LocateReverse(KDot)) );
+    iBitMapFilePath.Append( KDotBmp );
+    RFile iconFile;
+    TInt err = iconFile.Create(iFileSession,iBitMapFilePath,EFileRead|EFileWrite|EFileShareAny);
+    OstTrace1( TRACE_NORMAL, CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL, "CUpnpSvgImageConverter::ConvertToBitmapL;err=%d", err );
+    iconFile.Close();
+    aBitmapFile.Close();
+    if ( err == KErrAlreadyExists )
+        {
+        //If the converted file pre-exists, just return the existing filepath.
+        aBitmapFile.CreateL(iBitMapFilePath);
+        }
+    else if ( err == KErrNone )
+        {
+        TInt domHandle;
+        /**
+         * Parses and Prepares DOM for given SVG file.
+         * @param aSvgFile the name of the file  to be parsed
+         * @param domHandle  Handle to the created DOM.
+         * @return lsvgerr Error object specifying  the error occured during operation
+         */
+        MSvgError* lsvgerr = iSvgModule->PrepareDom( aSvgFile,domHandle ,NULL );
+        if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) )
+            {    
+            User::Leave( KErrCancel );
+            }   
+        /**
+         *Initialization of the engine 
+         *@param domHandle Handle to DOM Tree.
+         *@param iBitmap Buffer for drawing the DOM Tree.
+         *@param iMask  Buffer for mask (alpha values) of framebuffer result
+         *@return lsvgerr Error object specifying the error occured.
+         */
+        lsvgerr = iSvgModule->UseDom( domHandle ,iBitmap,iMask );
+        if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) )
+            {      
+            User::Leave( KErrCancel );
+            }
+        /**
+         * Request the SVG Engine to begin an animation. 
+         */
+        iSvgModule->Start( lsvgerr );
+        if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) )
+            {      
+            User::Leave( KErrCancel );
+            }
+        /**
+          * Deletes the DOM tree associated with the Handle.
+          */
+        lsvgerr = iSvgModule->DeleteDom( domHandle ) ;
+        if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) )
+            {      
+            User::Leave( KErrCancel );
+            }
+        /** 
+         * Creates and starts a new thread to handle asynchronous icon conversion.
+         * A new or separate thread is needed for this purpose since the conversion happens 
+         * in the same thread as of that of the one who invokes.
+         */
+        StartThreadL();
+        // Sets the converted filepath
+        aBitmapFile.CreateL(iBitMapFilePath);
+        }
+    else
+        {
+        User::Leave(err);
+        }
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL_EXIT );
+    }
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::StartThreadL
+// Creates a new thread where actual conversion occurs.
+// Also creates a sempahore and waits on it.
+// ---------------------------------------------------------------------------------
+// 
+void CUpnpSvgImageConverter::StartThreadL( )
+    {   
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_STARTTHREADL_ENTRY );
+    // Creates and opens a semaphore
+    RSemaphore semaphore;
+    CleanupClosePushL(semaphore);
+    TInt error = semaphore.CreateGlobal( KSemaphoreName, KErrNone );
+    if ( error == KErrAlreadyExists )
+       {
+       User::LeaveIfError(semaphore.OpenGlobal( KSemaphoreName ));
+       }
+    else
+       {
+       User::LeaveIfError(error);
+       }   
+    // Creates a new thread which will be in suspended state after creation
+    RThread thread;
+    CleanupClosePushL(thread);
+    User::LeaveIfError( thread.Create( KThreadName,
+                                       ImageConverter,
+                                       KDefaultStackSize,
+                                       NULL,
+                                       this,
+                                       EOwnerProcess));
+    thread.SetPriority(EPriorityRealTime);
+    //Resumes the newly created thread
+    thread.Resume();
+    semaphore.Wait(); 
+    CleanupStack::PopAndDestroy(2,&semaphore);
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_STARTTHREADL_EXIT );
+    }
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::Filepath
+// Method to return the path of the icon file which needs to be converted.
+// @return Returns reference to Bitmap file path.
+// ---------------------------------------------------------------------------------
+// 
+const TDesC& CUpnpSvgImageConverter::Filepath( )const
+    {
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_FILEPATH_ENTRY );
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_FILEPATH_EXIT );
+    return iBitMapFilePath; 
+    }
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::BitmapObject
+// Method to return the bitmap object.
+// @return Returns reference to Bitmap object.
+// ---------------------------------------------------------------------------------
+// 
+CFbsBitmap& CUpnpSvgImageConverter::BitmapObject()const 
+    {
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_BITMAPOBJECT_ENTRY );
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_BITMAPOBJECT_EXIT );
+    return *iBitmap;
+    }
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::ImageConverter
+// Static method serving as thread's main function
+// @param aParam  Pointer to any type object.
+// @return Returns error code
+// ---------------------------------------------------------------------------------
+// 
+TInt CUpnpSvgImageConverter::ImageConverter( TAny* aParam )
+    {
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTER_ENTRY );
+    TInt err( KErrNone );
+    CUpnpSvgImageConverter* svgConverter = static_cast <CUpnpSvgImageConverter*>( aParam );
+    // Create cleanupstack
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    if ( !cleanupStack )
+        {
+        err = KErrNoMemory;
+        }
+    else
+        {
+        TRAP( err, ImageConverterL(*svgConverter) );
+        }
+    // Create a matching semaphore for signalling the waiting semaphore
+    RSemaphore semaphoreStop;
+    semaphoreStop.OpenGlobal(KSemaphoreName);
+    semaphoreStop.Signal();
+    semaphoreStop.Close();
+    
+    delete cleanupStack;
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTER_EXIT );
+    return err;
+    }
+
+// ---------------------------------------------------------------------------------
+// CUpnpSvgImageConverter::ImageConverterL
+// Called from thread's main function.
+// Contains the code which can leave.
+// @param aSvgConverter  Reference to class object.
+// ---------------------------------------------------------------------------------
+// 
+void CUpnpSvgImageConverter::ImageConverterL( CUpnpSvgImageConverter& aSvgConverter )
+    {
+    OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTERL_ENTRY );
+    /** 
+     * Add support for active objects
+     * Create and install active scheduler
+     */
+    CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
+    CleanupStack::PushL(scheduler);
+    CActiveScheduler::Install( scheduler );
+    // Opens the bitmap file and supplies it to the active object
+    RFs fs;
+    CleanupClosePushL( fs );
+    User::LeaveIfError(fs.Connect());
+    RFile bitmapFile;
+    CleanupClosePushL( bitmapFile );
+    User::LeaveIfError( bitmapFile.Open( fs, aSvgConverter.Filepath(), EFileRead|EFileWrite|EFileShareAny ));
+  
+    // Create an active object that is executed in this thread
+    CUpnpIconConversionActive* active = CUpnpIconConversionActive::NewL( bitmapFile );
+    CleanupStack::PushL(active); 
+    // Invoke the request to the active object
+    active->Convert( aSvgConverter.BitmapObject() );
+    // Thread execution starts
+    CActiveScheduler::Start();
+    User::LeaveIfError( active->FetchError() );  // Leaves if the status returned is not KErrNone
+    
+    /**
+     * Thread execution ends (waiting for CActiveScheduler::Stop())
+     * Cleanup the active object and scheduler
+     */ 
+    CleanupStack::PopAndDestroy(UpnpString::KDoubleLineFeedLength,scheduler);
+    OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTERL_EXIT );
+    }
+
+// End of File