services/terminalmodeservice/src/upnpsvgimageconverter.cpp
branchRCL_3
changeset 10 594d15129e2c
parent 9 5c72fd91570d
equal deleted inserted replaced
9:5c72fd91570d 10:594d15129e2c
     1 /**
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: CUpnpSvgImageConverter class implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "upnpsvgimageconverter.h"
       
    19 #include "upnptmserverimpl.h"
       
    20 #include <f32file.h> 
       
    21 #include "upnpiconconversionactive.h"
       
    22 #include "OstTraceDefinitions.h"
       
    23 #ifdef OST_TRACE_COMPILER_IN_USE
       
    24 #include "upnpsvgimageconverterTraces.h"
       
    25 #endif
       
    26 
       
    27 // Literals
       
    28 _LIT(KLatin,               "LatinPlain12");
       
    29 _LIT(KConvertedIconPath,   "public\\TmServerDevice1\\");
       
    30 _LIT(KCross,               "x");
       
    31 _LIT(KDotBmp,              ".bmp");
       
    32 _LIT(KThreadName,          "ImageConverterThread");
       
    33 _LIT(KSemaphoreName,       "ImageConverterSemaphore");
       
    34 
       
    35 // Constant
       
    36 const TUint KDot           = '.';
       
    37 
       
    38 // ============================ MEMBER FUNCTIONS ===================================
       
    39 
       
    40 // ---------------------------------------------------------------------------------
       
    41 // CUpnpSvgImageConverter::NewL
       
    42 // Two-phased constructor.
       
    43 // @param aIconWidth   Desired width of the serving icon.
       
    44 // @param aIconHeight  Desired height of the serving icon.
       
    45 // ---------------------------------------------------------------------------------
       
    46 //
       
    47 CUpnpSvgImageConverter* CUpnpSvgImageConverter::NewL( TInt aIconWidth, TInt aIconHeight )
       
    48     {
       
    49     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_NEWL_ENTRY );
       
    50     OstTraceExt2( TRACE_NORMAL, CUPNPSVGIMAGECONVERTER_NEWL, "CUpnpSvgImageConverter::NewL;aIconWidth=%d;aIconHeight=%d", aIconWidth, aIconHeight );
       
    51     CUpnpSvgImageConverter* self = new (ELeave) CUpnpSvgImageConverter( );
       
    52     CleanupStack::PushL(self);
       
    53     self->ConstructL( aIconWidth,aIconHeight );
       
    54     CleanupStack::Pop(self);
       
    55     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_NEWL_EXIT );
       
    56     return self;    
       
    57     }
       
    58 
       
    59 // ---------------------------------------------------------------------------------
       
    60 // CUpnpSvgImageConverter::CUpnpSvgImageConverter
       
    61 // C++ default constructor can NOT contain any code, that might leave.
       
    62 // ---------------------------------------------------------------------------------
       
    63 //
       
    64 CUpnpSvgImageConverter::CUpnpSvgImageConverter( )                                      
       
    65     {
       
    66 
       
    67     }
       
    68 
       
    69 // ---------------------------------------------------------------------------------
       
    70 // CUpnpSvgImageConverter::ConstructL
       
    71 // Symbian 2nd phase constructor can leave.
       
    72 // ---------------------------------------------------------------------------------
       
    73 //
       
    74 void CUpnpSvgImageConverter::ConstructL(  TInt aIconWidth, TInt aIconHeight )
       
    75     {
       
    76     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CONSTRUCTL_ENTRY );
       
    77     //Geometric rectangle.
       
    78     TRect lMainRect( 0,0,aIconWidth,aIconHeight );
       
    79     /**
       
    80      * Specifies the font specification to use for text drawing.
       
    81      * Here "LatinPlain12" of height "10" is used.
       
    82      */ 
       
    83     TFontSpec lFontSpec( KLatin,UpnpString::KMaxTUintLength );
       
    84     // A bitmap managed by the font and bitmap server.
       
    85     User::LeaveIfError(iFbsSession.Connect());
       
    86     iBitmap = new ( ELeave ) CFbsBitmap();
       
    87     iMask = new ( ELeave ) CFbsBitmap();
       
    88     //Creates bitmap file of the desired dimensions with desired display mode(64,000 colour)
       
    89     User::LeaveIfError( iBitmap->Create( TSize( lMainRect.Width(),
       
    90                         lMainRect.Height() ),EColor64K ) );
       
    91     User::LeaveIfError( iMask->Create( TSize( lMainRect.Width(),
       
    92                             lMainRect.Height() ),EGray256 ) );  // 256 grayscales display mode as alpha values
       
    93     /**
       
    94      * Create a new Svg Engine interface.
       
    95      * @param iBitmap  bitmap to draw resulting svg image.
       
    96      * @param aReqObserver(NULL) interface for callbacks to retrieve info
       
    97      *                          only client can provide, such as opening files.
       
    98      * @param lFontSpecFont spec to use for text drawing.
       
    99      */
       
   100     iSvgModule = CSvgEngineInterfaceImpl::NewL( iBitmap,NULL,lFontSpec );
       
   101     User::LeaveIfError( iFileSession.Connect() );  
       
   102     TBuf<UpnpString::KMaxFilenameLength> privatePath;  
       
   103     User::LeaveIfError( iFileSession.PrivatePath(privatePath) );
       
   104 
       
   105     privatePath.Append(KConvertedIconPath());
       
   106     privatePath.AppendNum( aIconWidth );
       
   107     privatePath.Append( KCross);
       
   108     privatePath.AppendNum( aIconHeight );
       
   109     privatePath.Append( UpnpString::KDoubleBackSlash16() );
       
   110     TInt err = iFileSession.MkDir(privatePath);
       
   111     if( ( err != KErrNone ) && ( err != KErrAlreadyExists ) )
       
   112         {
       
   113         // Leaves if fails to create a directory
       
   114         User::Leave(err);
       
   115         }
       
   116     iBitMapFilePath.CreateL( UpnpString::KMaxFilenameLength );
       
   117     iBitMapFilePath.Append( privatePath );
       
   118     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CONSTRUCTL_EXIT );
       
   119     }
       
   120 
       
   121 // ---------------------------------------------------------------------------------
       
   122 // CUpnpSvgImageConverter::~CUpnpSvgImageConverter
       
   123 // Destructor
       
   124 // ---------------------------------------------------------------------------------
       
   125 // 
       
   126 CUpnpSvgImageConverter::~CUpnpSvgImageConverter()
       
   127     {  
       
   128     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CUPNPSVGIMAGECONVERTER_ENTRY );
       
   129     iBitMapFilePath.Close();
       
   130     delete iMask;
       
   131     delete iBitmap;
       
   132     delete iSvgModule;        
       
   133     iFbsSession.Disconnect();
       
   134     iFileSession.Close();
       
   135     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CUPNPSVGIMAGECONVERTER_EXIT );
       
   136     }
       
   137 
       
   138 // -----------------------------------------------------------------------------------
       
   139 // CUpnpSvgImageConverter::ConvertToBitmapL
       
   140 // Method invokes svg to bitmap conversion.
       
   141 // It takes svg file as an input and returns converted icon file( bmp ).
       
   142 // Also prepares DOM for given SVG file.
       
   143 // @param aSvgFile Input svg filepath
       
   144 // @param aBitmapFile[out] Bitmap filepath ( converted file ).
       
   145 // -----------------------------------------------------------------------------------
       
   146 void CUpnpSvgImageConverter::ConvertToBitmapL( const TDesC& aSvgFile, RBuf& aBitmapFile )
       
   147     { 
       
   148     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL_ENTRY );
       
   149     /**
       
   150      * Extracts the filename( without filename extension ) from the input svg filepath and 
       
   151      * uses the same filename to create bitmap file ( eg: abc.bmp )
       
   152      */ 
       
   153     TPtrC iconFileNameWithExtension = aSvgFile.Mid((aSvgFile.LocateReverse(KDirectorySeparator))+1);
       
   154     iBitMapFilePath.Append( iconFileNameWithExtension.Left(iconFileNameWithExtension.LocateReverse(KDot)) );
       
   155     iBitMapFilePath.Append( KDotBmp );
       
   156     RFile iconFile;
       
   157     TInt err = iconFile.Create(iFileSession,iBitMapFilePath,EFileRead|EFileWrite|EFileShareAny);
       
   158     OstTrace1( TRACE_NORMAL, CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL, "CUpnpSvgImageConverter::ConvertToBitmapL;err=%d", err );
       
   159     iconFile.Close();
       
   160     aBitmapFile.Close();
       
   161     if ( err == KErrAlreadyExists )
       
   162         {
       
   163         //If the converted file pre-exists, just return the existing filepath.
       
   164         aBitmapFile.CreateL(iBitMapFilePath);
       
   165         }
       
   166     else if ( err == KErrNone )
       
   167         {
       
   168         TInt domHandle;
       
   169         /**
       
   170          * Parses and Prepares DOM for given SVG file.
       
   171          * @param aSvgFile the name of the file  to be parsed
       
   172          * @param domHandle  Handle to the created DOM.
       
   173          * @return lsvgerr Error object specifying  the error occured during operation
       
   174          */
       
   175         MSvgError* lsvgerr = iSvgModule->PrepareDom( aSvgFile,domHandle ,NULL );
       
   176         if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) )
       
   177             {    
       
   178             User::Leave( KErrCancel );
       
   179             }   
       
   180         /**
       
   181          *Initialization of the engine 
       
   182          *@param domHandle Handle to DOM Tree.
       
   183          *@param iBitmap Buffer for drawing the DOM Tree.
       
   184          *@param iMask  Buffer for mask (alpha values) of framebuffer result
       
   185          *@return lsvgerr Error object specifying the error occured.
       
   186          */
       
   187         lsvgerr = iSvgModule->UseDom( domHandle ,iBitmap,iMask );
       
   188         if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) )
       
   189             {      
       
   190             User::Leave( KErrCancel );
       
   191             }
       
   192         /**
       
   193          * Request the SVG Engine to begin an animation. 
       
   194          */
       
   195         iSvgModule->Start( lsvgerr );
       
   196         if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) )
       
   197             {      
       
   198             User::Leave( KErrCancel );
       
   199             }
       
   200         /**
       
   201           * Deletes the DOM tree associated with the Handle.
       
   202           */
       
   203         lsvgerr = iSvgModule->DeleteDom( domHandle ) ;
       
   204         if ( (! lsvgerr ) || ( lsvgerr && lsvgerr->HasError() &&!lsvgerr->IsWarning() ) )
       
   205             {      
       
   206             User::Leave( KErrCancel );
       
   207             }
       
   208         /** 
       
   209          * Creates and starts a new thread to handle asynchronous icon conversion.
       
   210          * A new or separate thread is needed for this purpose since the conversion happens 
       
   211          * in the same thread as of that of the one who invokes.
       
   212          */
       
   213         StartThreadL();
       
   214         // Sets the converted filepath
       
   215         aBitmapFile.CreateL(iBitMapFilePath);
       
   216         }
       
   217     else
       
   218         {
       
   219         User::Leave(err);
       
   220         }
       
   221     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_CONVERTTOBITMAPL_EXIT );
       
   222     }
       
   223 
       
   224 // ---------------------------------------------------------------------------------
       
   225 // CUpnpSvgImageConverter::StartThreadL
       
   226 // Creates a new thread where actual conversion occurs.
       
   227 // Also creates a sempahore and waits on it.
       
   228 // ---------------------------------------------------------------------------------
       
   229 // 
       
   230 void CUpnpSvgImageConverter::StartThreadL( )
       
   231     {   
       
   232     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_STARTTHREADL_ENTRY );
       
   233     // Creates and opens a semaphore
       
   234     RSemaphore semaphore;
       
   235     CleanupClosePushL(semaphore);
       
   236     TInt error = semaphore.CreateGlobal( KSemaphoreName, KErrNone );
       
   237     if ( error == KErrAlreadyExists )
       
   238        {
       
   239        User::LeaveIfError(semaphore.OpenGlobal( KSemaphoreName ));
       
   240        }
       
   241     else
       
   242        {
       
   243        User::LeaveIfError(error);
       
   244        }   
       
   245     // Creates a new thread which will be in suspended state after creation
       
   246     RThread thread;
       
   247     CleanupClosePushL(thread);
       
   248     User::LeaveIfError( thread.Create( KThreadName,
       
   249                                        ImageConverter,
       
   250                                        KDefaultStackSize,
       
   251                                        NULL,
       
   252                                        this,
       
   253                                        EOwnerProcess));
       
   254     thread.SetPriority(EPriorityRealTime);
       
   255     //Resumes the newly created thread
       
   256     thread.Resume();
       
   257     semaphore.Wait(); 
       
   258     CleanupStack::PopAndDestroy(2,&semaphore);
       
   259     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_STARTTHREADL_EXIT );
       
   260     }
       
   261 
       
   262 // ---------------------------------------------------------------------------------
       
   263 // CUpnpSvgImageConverter::Filepath
       
   264 // Method to return the path of the icon file which needs to be converted.
       
   265 // @return Returns reference to Bitmap file path.
       
   266 // ---------------------------------------------------------------------------------
       
   267 // 
       
   268 const TDesC& CUpnpSvgImageConverter::Filepath( )const
       
   269     {
       
   270     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_FILEPATH_ENTRY );
       
   271     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_FILEPATH_EXIT );
       
   272     return iBitMapFilePath; 
       
   273     }
       
   274 
       
   275 // ---------------------------------------------------------------------------------
       
   276 // CUpnpSvgImageConverter::BitmapObject
       
   277 // Method to return the bitmap object.
       
   278 // @return Returns reference to Bitmap object.
       
   279 // ---------------------------------------------------------------------------------
       
   280 // 
       
   281 CFbsBitmap& CUpnpSvgImageConverter::BitmapObject()const 
       
   282     {
       
   283     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_BITMAPOBJECT_ENTRY );
       
   284     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_BITMAPOBJECT_EXIT );
       
   285     return *iBitmap;
       
   286     }
       
   287 
       
   288 // ---------------------------------------------------------------------------------
       
   289 // CUpnpSvgImageConverter::ImageConverter
       
   290 // Static method serving as thread's main function
       
   291 // @param aParam  Pointer to any type object.
       
   292 // @return Returns error code
       
   293 // ---------------------------------------------------------------------------------
       
   294 // 
       
   295 TInt CUpnpSvgImageConverter::ImageConverter( TAny* aParam )
       
   296     {
       
   297     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTER_ENTRY );
       
   298     TInt err( KErrNone );
       
   299     CUpnpSvgImageConverter* svgConverter = static_cast <CUpnpSvgImageConverter*>( aParam );
       
   300     // Create cleanupstack
       
   301     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   302     if ( !cleanupStack )
       
   303         {
       
   304         err = KErrNoMemory;
       
   305         }
       
   306     else
       
   307         {
       
   308         TRAP( err, ImageConverterL(*svgConverter) );
       
   309         }
       
   310     // Create a matching semaphore for signalling the waiting semaphore
       
   311     RSemaphore semaphoreStop;
       
   312     semaphoreStop.OpenGlobal(KSemaphoreName);
       
   313     semaphoreStop.Signal();
       
   314     semaphoreStop.Close();
       
   315     
       
   316     delete cleanupStack;
       
   317     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTER_EXIT );
       
   318     return err;
       
   319     }
       
   320 
       
   321 // ---------------------------------------------------------------------------------
       
   322 // CUpnpSvgImageConverter::ImageConverterL
       
   323 // Called from thread's main function.
       
   324 // Contains the code which can leave.
       
   325 // @param aSvgConverter  Reference to class object.
       
   326 // ---------------------------------------------------------------------------------
       
   327 // 
       
   328 void CUpnpSvgImageConverter::ImageConverterL( CUpnpSvgImageConverter& aSvgConverter )
       
   329     {
       
   330     OstTraceFunctionEntry0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTERL_ENTRY );
       
   331     /** 
       
   332      * Add support for active objects
       
   333      * Create and install active scheduler
       
   334      */
       
   335     CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
       
   336     CleanupStack::PushL(scheduler);
       
   337     CActiveScheduler::Install( scheduler );
       
   338     // Opens the bitmap file and supplies it to the active object
       
   339     RFs fs;
       
   340     CleanupClosePushL( fs );
       
   341     User::LeaveIfError(fs.Connect());
       
   342     RFile bitmapFile;
       
   343     CleanupClosePushL( bitmapFile );
       
   344     User::LeaveIfError( bitmapFile.Open( fs, aSvgConverter.Filepath(), EFileRead|EFileWrite|EFileShareAny ));
       
   345   
       
   346     // Create an active object that is executed in this thread
       
   347     CUpnpIconConversionActive* active = CUpnpIconConversionActive::NewL( bitmapFile );
       
   348     CleanupStack::PushL(active); 
       
   349     // Invoke the request to the active object
       
   350     active->Convert( aSvgConverter.BitmapObject() );
       
   351     // Thread execution starts
       
   352     CActiveScheduler::Start();
       
   353     User::LeaveIfError( active->FetchError() );  // Leaves if the status returned is not KErrNone
       
   354     
       
   355     /**
       
   356      * Thread execution ends (waiting for CActiveScheduler::Stop())
       
   357      * Cleanup the active object and scheduler
       
   358      */ 
       
   359     CleanupStack::PopAndDestroy(UpnpString::KDoubleLineFeedLength,scheduler);
       
   360     OstTraceFunctionExit0( CUPNPSVGIMAGECONVERTER_IMAGECONVERTERL_EXIT );
       
   361     }
       
   362 
       
   363 // End of File