uigraphics/AknIcon/SvgtFbsRasterizer/src/SvgtFbsRasterizer.cpp
changeset 0 05e9090e2422
child 1 ba33815114d6
equal deleted inserted replaced
-1:000000000000 0:05e9090e2422
       
     1 /*
       
     2 * Copyright (c) 2002 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:    CSvgtFbsRasterizer implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "svgtfbsrasterizer.h"
       
    19 #include "fbsrasterizerpanics.h"
       
    20 #include "SvgtRegisteredBitmap.h"
       
    21 #include "svgtgraphicsinterface.h"
       
    22 #include <e32std.h>
       
    23 #include <nvg.h>
       
    24 #include <AknIconHeader.h>
       
    25 #include <AknIconUtils.h>
       
    26 #include <vgcontext.h>
       
    27 
       
    28 #include <bitstd.h>
       
    29 #include <bitdev.h>
       
    30 
       
    31 TBool operator==(const CFbsRasterizer::TBitmapDesc& aBitmapDesc1, 
       
    32 				 const CFbsRasterizer::TBitmapDesc& aBitmapDesc2)
       
    33 	{
       
    34 	return ((&aBitmapDesc1 == &aBitmapDesc2)
       
    35 			|| (aBitmapDesc1.iSizeInPixels == aBitmapDesc2.iSizeInPixels
       
    36 				&& aBitmapDesc1.iDispMode == aBitmapDesc2.iDispMode
       
    37 				&& aBitmapDesc1.iDataType == aBitmapDesc2.iDataType
       
    38 				&& aBitmapDesc1.iData == aBitmapDesc2.iData
       
    39 				&& aBitmapDesc1.iDataSize == aBitmapDesc2.iDataSize));	
       
    40 	}
       
    41 
       
    42 void CleanupVGImage( TAny* aObj )
       
    43     {
       
    44     VGImage * imageToDestroy = reinterpret_cast<VGImage *>(aObj); 
       
    45     if (imageToDestroy && *imageToDestroy != VG_INVALID_HANDLE)
       
    46         {
       
    47         vgDestroyImage(*imageToDestroy);
       
    48         }
       
    49     }
       
    50 
       
    51 /** Create a new rasterizer.
       
    52 @return A pointer to a newly constructed CFbsRasterizer object if successful,
       
    53 or NULL if no memory is available.
       
    54  */
       
    55 EXPORT_C CFbsRasterizer* CSvgtFbsRasterizer::New()
       
    56 	{
       
    57 	CSvgtFbsRasterizer* self = new CSvgtFbsRasterizer;
       
    58 	if ( self )
       
    59 	    {
       
    60 	    self->InitializeRasterizer();
       
    61 	    }
       
    62 	return self;
       
    63 	}
       
    64 
       
    65 /** Constructor */
       
    66 CSvgtFbsRasterizer::CSvgtFbsRasterizer()
       
    67     :iRegisteredBmps(_FOFF(CSvgtRegisteredBitmap, iLink)), iRecentBmps(_FOFF(CSvgtRegisteredBitmap, iLink))
       
    68 	{
       
    69 	    RProcess currentProcess;
       
    70 	    TFileName exeFileName = currentProcess.FileName();
       
    71 	    exeFileName.Copy(exeFileName.Mid(11));
       
    72 	    exeFileName.Copy(exeFileName.Left(exeFileName.Length()-4));
       
    73 	    
       
    74 	    if(exeFileName.Compare(_L("peninputserver"))==0)
       
    75 	        {
       
    76 	        iCacheLimit = 0x133333;
       
    77 	        iSpecialProcess = TRUE;	        
       
    78 	        }
       
    79 	    else
       
    80 	        {
       
    81 	        iCacheLimit = KMaxRecentBmpCacheSize;
       
    82 	        iSpecialProcess = FALSE;            
       
    83 	        }
       
    84 	}
       
    85 
       
    86 CSvgtFbsRasterizer::~CSvgtFbsRasterizer()
       
    87     {
       
    88     while (!iRegisteredBmps.IsEmpty())
       
    89         {
       
    90         delete iRegisteredBmps.First();
       
    91         }
       
    92     while (!iRecentBmps.IsEmpty())
       
    93         {
       
    94         delete iRecentBmps.First();
       
    95         }
       
    96     delete iIdle;
       
    97     
       
    98     delete iNvgEngine;
       
    99     delete iGraphicsInterface;
       
   100     if ( iMatricesUpdated )
       
   101         {
       
   102         RestoreMatrices();
       
   103         }
       
   104     }
       
   105 
       
   106 /** Register a bitmap with this rasterizer for rendering. In this example the extended 
       
   107 bitmap data is just a buffer that is copied when BeginBitmap() is called and deleted when
       
   108 EndBitmap() is called for the same bitmap. The only display modes supported by this example
       
   109 raterizer are EColor16MU and EColor16MA
       
   110 */
       
   111 void CSvgtFbsRasterizer::BeginBitmap(TInt64 aBitmapId, const TBitmapDesc& aBitmapDesc, const TRegion* aRegionOfInterest)
       
   112 	{
       
   113 	TRAPD(beginErr, DoBeginBitmapL(aBitmapId, aBitmapDesc, aRegionOfInterest));
       
   114 	// If there is error in begin, the consecutive fulction calls should be invalid.
       
   115 	iIsRasterizerValidState = ( beginErr == KErrNone); 
       
   116 	}
       
   117 
       
   118 void CSvgtFbsRasterizer::DoBeginBitmapL(TInt64 aBitmapId, const TBitmapDesc& aBitmapDesc,
       
   119         const TRegion* /* aRegionOfInterest */)
       
   120     {
       
   121     // Check that the passed extended bitmap description is valid
       
   122     if ((aBitmapDesc.iSizeInPixels.iWidth <= 0) || (aBitmapDesc.iSizeInPixels.iHeight <= 0)
       
   123             || (aBitmapDesc.iDataType != KUidNvgProprietaryFormat)
       
   124             || (!aBitmapDesc.iData )
       
   125             || (aBitmapDesc.iDataSize <= 0))
       
   126         {
       
   127         return;
       
   128         }
       
   129     // Check if the bitmap is already registered
       
   130     CSvgtRegisteredBitmap* foundRegBmp = RegisteredBitmap(aBitmapId);
       
   131     if (!foundRegBmp)
       
   132         {
       
   133         // Not registered: check if the bitmap is in the cache of recently used bitmaps
       
   134         foundRegBmp = RecentBitmap(aBitmapId);
       
   135         if (foundRegBmp)
       
   136             {
       
   137             // Take the bitmap out of the cache and put it in the list of registered bitmaps
       
   138             foundRegBmp->iLink.Deque();
       
   139             iTotalRecentBmpSize -= foundRegBmp->DataSize();
       
   140             iRegisteredBmps.AddLast(*foundRegBmp);
       
   141             }
       
   142         }
       
   143     if (foundRegBmp)
       
   144         {
       
   145         // This bitmap is already registered, just increment its reference count and return
       
   146         foundRegBmp->iRefCount++;
       
   147         return;
       
   148         }
       
   149     
       
   150     CSvgtRegisteredBitmap* regBmp = new CSvgtRegisteredBitmap(aBitmapId);
       
   151     if (!regBmp)
       
   152         {
       
   153         return;
       
   154         }
       
   155     TRAPD(err, RenderL(aBitmapDesc, *regBmp));
       
   156     if (err != KErrNone)
       
   157         {
       
   158         delete regBmp;
       
   159         return;
       
   160         }
       
   161     // Success
       
   162     iRegisteredBmps.AddLast(*regBmp);
       
   163     regBmp->iRefCount = 1;
       
   164     }
       
   165 
       
   166 /** Unregister an extended bitmap from this rasterizer. 
       
   167 @see CFbsRasterizer::EndBitmap()
       
   168 @see BeginBitmap()
       
   169  */
       
   170 void CSvgtFbsRasterizer::EndBitmap(TInt64 aBitmapId)
       
   171 	{
       
   172 	CSvgtRegisteredBitmap* regBmp = RegisteredBitmap(aBitmapId);
       
   173 	    if (regBmp)
       
   174 	        {
       
   175 	        if (--regBmp->iRefCount == 0)
       
   176 	            {
       
   177 	            // Put unregistered bitmap in the cache of recently used bitmaps if wholly pre-rendered
       
   178 	            // and there is an active scheduler to add the idle-time clean-up active object to
       
   179 	            if (CActiveScheduler::Current())
       
   180 	                {
       
   181 	                if (!iIdle)
       
   182 	                    {
       
   183 	                    iIdle = CIdle::New(CActive::EPriorityIdle);
       
   184 	                    if (!iIdle)
       
   185 	                        {
       
   186 	                        delete regBmp;
       
   187 	                        return;
       
   188 	                        }
       
   189 	                    }
       
   190 	                regBmp->iLink.Deque();
       
   191 	                if (regBmp->DataSize() <= iCacheLimit)
       
   192 	                    {
       
   193 	                    iRecentBmps.AddFirst(*regBmp);
       
   194 	                    iTotalRecentBmpSize += regBmp->DataSize();
       
   195 	                    }
       
   196 	                // Delete the least recently used bitmaps if the maximum size of the cache is exceeded
       
   197 	                while (iTotalRecentBmpSize > iCacheLimit)
       
   198 	                    {
       
   199 	                    regBmp = iRecentBmps.Last();
       
   200 	                    iTotalRecentBmpSize -= regBmp->DataSize();
       
   201 	                    delete regBmp;
       
   202 	                    }
       
   203 	                // If the cache is not empty make sure the idle-time clean-up active object is scheduled to run
       
   204 	                if (!iRecentBmps.IsEmpty() && !iIdle->IsActive())
       
   205 	                    {
       
   206 	                    iIdle->Start(TCallBack(IdleFunction, this));
       
   207 	                    }
       
   208 	                }  
       
   209 	            else
       
   210 	                {
       
   211 	                delete regBmp;
       
   212 	                }
       
   213 	            }
       
   214 	        }
       
   215 	}
       
   216 
       
   217 /** Return a scanline from the passed extended bitmap given it's bitmap id. 
       
   218  */
       
   219 const TUint32* CSvgtFbsRasterizer::ScanLine(TInt64 aBitmapId, const TPoint& aPixel, TInt aLength)
       
   220 	{
       
   221 	CSvgtRegisteredBitmap* regBmp = RegisteredBitmap(aBitmapId);
       
   222     if (!regBmp)
       
   223         {
       
   224         return NULL;
       
   225         }
       
   226     if (!TRect(regBmp->SizeInPixels()).Contains(aPixel)
       
   227         || (aLength > (regBmp->SizeInPixels().iWidth - aPixel.iX)))
       
   228         {
       
   229         return NULL;
       
   230         }
       
   231 
       
   232     return PtrAdd(regBmp->DataAddress(), aPixel.iY * regBmp->DataStride());
       
   233 	}
       
   234 
       
   235 /**  No extension interaces are available, KErrNotSupported for all aInterfaceId passed.
       
   236 @see CFbsRasterizer::GetInterface()
       
   237  */
       
   238 TInt CSvgtFbsRasterizer::GetInterface(TUid /*aInterfaceId*/, TAny*& aInterface)
       
   239 	{
       
   240 	aInterface = NULL;
       
   241 	return KErrExtensionNotSupported;
       
   242 	}
       
   243 
       
   244 
       
   245 /** Gets a bitmap that has been registered with this rasterizer.
       
   246 
       
   247 @param aBitmapId The ID of the bitmap to check for.
       
   248 
       
   249 @return A pointer to the registered bitmap if found, NULL otherwise.
       
   250  */
       
   251 CSvgtRegisteredBitmap* CSvgtFbsRasterizer::RegisteredBitmap(TInt64 aBitmapId)
       
   252     {
       
   253     TDblQueIter<CSvgtRegisteredBitmap> iter(iRegisteredBmps);
       
   254     while (CSvgtRegisteredBitmap* regBmp = iter++)
       
   255         {
       
   256         if (regBmp->iBitmapId == aBitmapId)
       
   257             {
       
   258             return regBmp;
       
   259             }
       
   260         }
       
   261     return NULL;
       
   262     }
       
   263 
       
   264 /** Gets a bitmap that has been recently used with this rasterizer.
       
   265 
       
   266 @param aBitmapId The ID of the bitmap to check for.
       
   267 
       
   268 @return A pointer to the recently used bitmap if found, NULL otherwise.
       
   269  */
       
   270 CSvgtRegisteredBitmap* CSvgtFbsRasterizer::RecentBitmap(TInt64 aBitmapId)
       
   271     {
       
   272     TDblQueIter<CSvgtRegisteredBitmap> iter(iRecentBmps);
       
   273     while (CSvgtRegisteredBitmap* regBmp = iter++)
       
   274         {
       
   275         if (regBmp->iBitmapId == aBitmapId)
       
   276             {
       
   277             return regBmp;
       
   278             }
       
   279         }
       
   280     return NULL;
       
   281     }
       
   282 
       
   283 TInt CSvgtFbsRasterizer::IdleFunction(TAny* aPtr)
       
   284     {
       
   285      CSvgtFbsRasterizer* self = static_cast<CSvgtFbsRasterizer*>(aPtr);    
       
   286     if(self->iSpecialProcess!=true)
       
   287         {
       
   288        
       
   289         while (!self->iRecentBmps.IsEmpty())
       
   290             {
       
   291             delete self->iRecentBmps.First();
       
   292             }
       
   293         self->iTotalRecentBmpSize = 0;        
       
   294         }
       
   295     return 0;
       
   296     }
       
   297 
       
   298 void CSvgtFbsRasterizer::InitializeRasterizer()
       
   299     {
       
   300     }
       
   301 
       
   302 void CSvgtFbsRasterizer::RenderBitmapL(CSvgtRegisteredBitmap& aPixMap, CFbsBitmap * aMask, 
       
   303                                         const TBitmapDesc& aBitmapDesc, TPtr8& aDataPtr8, TAknIconHeader& aIconHeader)
       
   304     {
       
   305     TSize newSize = aBitmapDesc.iSizeInPixels;
       
   306     UpdateMatrices();
       
   307     iMatricesUpdated = ETrue;
       
   308     TBool isMargin = aIconHeader.IsMarginCorrection();
       
   309     
       
   310     VGImage vgImage = VG_INVALID_HANDLE;
       
   311         
       
   312     if (isMargin)
       
   313         {
       
   314         vgImage = vgCreateImage((VGImageFormat)  VG_sRGBA_8888_PRE , aBitmapDesc.iSizeInPixels.iWidth,
       
   315                                     aBitmapDesc.iSizeInPixels.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
       
   316         if (vgImage == VG_INVALID_HANDLE)
       
   317             {
       
   318             User::LeaveIfError(MapOpenVgErrorCodeToSymbian(vgGetError()));
       
   319             }
       
   320         CleanupStack::PushL( TCleanupItem( CleanupVGImage, &vgImage ) );
       
   321         iGraphicsInterface->BindClientBuffer(vgImage);
       
   322         }
       
   323     User::LeaveIfError(iNvgEngine->DrawNvg(aDataPtr8, newSize, &aPixMap, aMask));
       
   324    
       
   325     if(isMargin)
       
   326         {
       
   327         iGraphicsInterface->UnBindClientBuffer(); 
       
   328         newSize = ApplyMarginL(vgImage, aBitmapDesc.iSizeInPixels);
       
   329         if(newSize!=aBitmapDesc.iSizeInPixels)
       
   330         		{
       
   331         		User::LeaveIfError(iNvgEngine->DrawNvg(aDataPtr8, newSize, &aPixMap, aMask));
       
   332        		  }
       
   333        	else
       
   334        		  {
       
   335        		  vgDrawImage(vgImage);
       
   336        		  User::LeaveIfError(MapOpenVgErrorCodeToSymbian(vgGetError()));
       
   337             }
       
   338         	
       
   339         CleanupStack::PopAndDestroy();
       
   340         }
       
   341     iGraphicsInterface->CopyBitmapL(&aPixMap, aMask);
       
   342     
       
   343     TUint32 iconColor = aIconHeader.GetIconColor();
       
   344     
       
   345     if (iconColor & 0xFFFFFF)
       
   346         {
       
   347         CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( &aPixMap );
       
   348         CleanupStack::PushL( dev );
       
   349         CFbsBitGc* gc = NULL;
       
   350         User::LeaveIfError( dev->CreateContext( gc ) );
       
   351         CleanupStack::PushL( gc );
       
   352         TRgb color(iconColor);          
       
   353         gc->SetBrushColor( color );
       
   354         gc->SetPenStyle( CGraphicsContext::ENullPen );
       
   355         gc->SetBrushStyle( CGraphicsContext::ESolidBrush );
       
   356         // Fill icon with the given color, mask defines the icon shape.
       
   357         TPoint origin(0, 0);
       
   358         if (newSize != aBitmapDesc.iSizeInPixels)
       
   359             {
       
   360             origin = TPoint((aBitmapDesc.iSizeInPixels.iWidth - newSize.iWidth)/2 , (aBitmapDesc.iSizeInPixels.iHeight - newSize.iHeight)/2  );
       
   361             }
       
   362         gc->DrawRect( TRect( origin, newSize ) );
       
   363         CleanupStack::PopAndDestroy( 2 ); // dev, gc
       
   364         }
       
   365     }
       
   366 
       
   367 void CSvgtFbsRasterizer::RenderMaskL(CSvgtRegisteredBitmap& aPixMap, CFbsBitmap * aMask, 
       
   368                                       const TBitmapDesc& aBitmapDesc, TPtr8& aDataPtr8, TAknIconHeader& aIconHeader)
       
   369     {
       
   370     UpdateMatrices();
       
   371     iMatricesUpdated = ETrue;
       
   372     TBool isMargin = aIconHeader.IsMarginCorrection();
       
   373     
       
   374     VGImage vgImage = VG_INVALID_HANDLE;
       
   375     if (isMargin)
       
   376         {
       
   377         vgImage = vgCreateImage((VGImageFormat)  VG_sRGBA_8888_PRE , aBitmapDesc.iSizeInPixels.iWidth, 
       
   378                                      aBitmapDesc.iSizeInPixels.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
       
   379         if (vgImage == VG_INVALID_HANDLE)
       
   380             {
       
   381             User::LeaveIfError(MapOpenVgErrorCodeToSymbian(vgGetError()));
       
   382             }
       
   383         CleanupStack::PushL( TCleanupItem( CleanupVGImage, &vgImage ) );
       
   384         iGraphicsInterface->BindClientBuffer(vgImage);
       
   385         }
       
   386         
       
   387     VGfloat color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
       
   388     vgSeti(VG_SCISSORING, VG_FALSE);
       
   389     vgSetfv(VG_CLEAR_COLOR, 4, color);
       
   390     vgClear(0, 0, aBitmapDesc.iSizeInPixels.iWidth, aBitmapDesc.iSizeInPixels.iHeight);
       
   391 
       
   392     User::LeaveIfError(iNvgEngine->DrawNvg(aDataPtr8, aBitmapDesc.iSizeInPixels, &aPixMap, aMask));
       
   393     if (isMargin)
       
   394         {
       
   395         iGraphicsInterface->UnBindClientBuffer();
       
   396         TSize newSize = ApplyMarginL(vgImage, aBitmapDesc.iSizeInPixels);
       
   397         if(newSize!=aBitmapDesc.iSizeInPixels)
       
   398         		{
       
   399         		User::LeaveIfError(iNvgEngine->DrawNvg(aDataPtr8, newSize, &aPixMap, aMask));
       
   400        		  }
       
   401        	else
       
   402        		  {
       
   403        		  vgDrawImage(vgImage);
       
   404        		  User::LeaveIfError(MapOpenVgErrorCodeToSymbian(vgGetError()));
       
   405             }
       
   406         CleanupStack::PopAndDestroy();
       
   407         }
       
   408     
       
   409     TSize bitmapSize = aPixMap.SizeInPixels();
       
   410 
       
   411     const TInt KOriginalFilterMasks = vgGeti( VG_FILTER_CHANNEL_MASK );
       
   412     vgSeti( VG_FILTER_CHANNEL_MASK, VG_ALPHA );
       
   413 
       
   414     const TInt KStride = CFbsBitmap::ScanLineLength(bitmapSize.iWidth, aPixMap.DisplayMode());
       
   415     VGImageFormat format = ( aPixMap.DisplayMode() == EGray256 ) ? VG_A_8 : VG_BW_1;
       
   416     
       
   417     aPixMap.BeginDataAccess();
       
   418     TUint * data = (TUint*)((TUint)aPixMap.DataAddress() + ( KStride * ( aPixMap.SizeInPixels().iHeight - 1  ) ) );
       
   419     vgReadPixels( data, -KStride, format, 0, 0, bitmapSize.iWidth, bitmapSize.iHeight );
       
   420     aPixMap.EndDataAccess();
       
   421 
       
   422     vgSeti( VG_FILTER_CHANNEL_MASK, KOriginalFilterMasks );
       
   423 
       
   424     }
       
   425 
       
   426 void CSvgtFbsRasterizer::RenderL( const TBitmapDesc& aBitmapDesc, CSvgtRegisteredBitmap& aBitmap  )
       
   427     {
       
   428     
       
   429     iIsRasterizerValidState = EFalse;
       
   430 
       
   431     User::LeaveIfError(aBitmap.Create(aBitmapDesc.iSizeInPixels, aBitmapDesc.iDispMode));
       
   432     
       
   433     if (!iGraphicsInterface)
       
   434         {
       
   435         iGraphicsInterface = CSvgtGraphicsInterface::CreateImplementationL();
       
   436         }
       
   437     
       
   438     iGraphicsInterface->InitializeL(aBitmapDesc.iSizeInPixels);
       
   439     iIsRasterizerValidState  = ETrue;
       
   440 
       
   441     TPtr8 bmpDataPtr8((TUint8*)aBitmapDesc.iData, aBitmapDesc.iDataSize);
       
   442     
       
   443     if (!iNvgEngine)
       
   444         {
       
   445         iNvgEngine = CNvgEngine::NewL();
       
   446         }
       
   447         
       
   448     iNvgEngine->SetVGImageBinder(iGraphicsInterface);
       
   449     
       
   450     TUint8 *temp = (TUint8 *)bmpDataPtr8.Ptr();
       
   451     TPtr8 IconHeaderPtr(temp, KIconHeaderLength, KIconHeaderLength);
       
   452 
       
   453     TAknIconHeader iconheader(IconHeaderPtr);
       
   454     //skipping header bytes
       
   455     temp = temp + KIconHeaderLength;
       
   456     TPtr8 newDataPtr8(temp, (bmpDataPtr8.MaxLength() - KIconHeaderLength), (bmpDataPtr8.MaxLength() - KIconHeaderLength));
       
   457 
       
   458     CFbsBitmap* mask = NULL;
       
   459     
       
   460     VGfloat color[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
       
   461     vgSeti(VG_SCISSORING, VG_FALSE);
       
   462     vgSetfv(VG_CLEAR_COLOR, 4, color);
       
   463     vgClear(0, 0, aBitmapDesc.iSizeInPixels.iWidth, aBitmapDesc.iSizeInPixels.iHeight);
       
   464     TInt rotAngle = iconheader.GetRotation();
       
   465     // setting the rotation angle
       
   466     iNvgEngine->Rotate(-rotAngle,  aBitmapDesc.iSizeInPixels.iWidth >> 1,aBitmapDesc.iSizeInPixels.iHeight >>1);
       
   467     
       
   468     //setting preserve aspect ratio
       
   469     TNvgAlignStatusType alignTypeValue = ENvgPreserveAspectRatio_XmidYmid;
       
   470     TNvgMeetOrSliceType meetOrSliceTypeValue = ENvgMeet;
       
   471     
       
   472     switch ( iconheader.GetScaleMode() )
       
   473         {
       
   474         case EAspectRatioPreserved: // fall through
       
   475             {
       
   476             // use default
       
   477             break;
       
   478             }
       
   479             // Ensures NVG content fully covers the area of the icon whilst preserving aspect ratio.
       
   480         case EAspectRatioPreservedSlice:
       
   481             {
       
   482             // alignTypeValue use default
       
   483             meetOrSliceTypeValue = ENvgSlice;
       
   484             break;
       
   485             } 
       
   486             /* EAspectRatioPreservedAndUnusedSpaceRemoved is mapped to the same values as EAspectRatioNotPreserved
       
   487              * because we already have a frame buffer with the dimensions that preserves the aspect ratio.
       
   488              * This mapping ensures that NVG engine does not calculate aspect ratio twice and potentially resulting in precision loss.*/
       
   489         case EAspectRatioPreservedAndUnusedSpaceRemoved:                        
       
   490         case EAspectRatioNotPreserved:
       
   491             {            
       
   492             alignTypeValue = ENvgPreserveAspectRatio_None;
       
   493             // meetOrSliceTypeValue use default
       
   494             break;
       
   495             }
       
   496         default:
       
   497             {
       
   498             User::Leave(KErrCorrupt);
       
   499             }
       
   500         }    
       
   501     iNvgEngine->SetPreserveAspectRatio(alignTypeValue, meetOrSliceTypeValue);
       
   502 
       
   503     iMatricesUpdated = EFalse;
       
   504     if (iconheader.IsMask())
       
   505         {
       
   506         RenderMaskL(aBitmap, mask, aBitmapDesc, newDataPtr8, iconheader);
       
   507         }
       
   508     else
       
   509         {
       
   510         RenderBitmapL(aBitmap, mask, aBitmapDesc, newDataPtr8, iconheader);
       
   511         }
       
   512     
       
   513     if ( iMatricesUpdated )
       
   514         {
       
   515         RestoreMatrices();
       
   516         iMatricesUpdated = EFalse;
       
   517         }
       
   518     }
       
   519 
       
   520 void CSvgtFbsRasterizer::UpdateMatrices()
       
   521     {
       
   522     iUserStrokePaint = vgGetPaint(VG_STROKE_PATH);
       
   523     
       
   524     iUserFillPaint = vgGetPaint(VG_FILL_PATH);
       
   525     
       
   526     iMatrixMode = vgGeti(VG_MATRIX_MODE);
       
   527     
       
   528     vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
       
   529     
       
   530     vgGetMatrix(iPathMatrix);
       
   531     
       
   532     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
   533     
       
   534     vgGetMatrix(iImageMatrix);
       
   535     
       
   536     vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
       
   537     
       
   538     vgGetMatrix(iFillPaintMatrix);
       
   539     
       
   540     vgSeti(VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER);
       
   541     
       
   542     vgGetMatrix(iStrokePaintMatrix);
       
   543     
       
   544     vgSeti(VG_MATRIX_MODE, iMatrixMode);
       
   545     
       
   546     }
       
   547 
       
   548 void CSvgtFbsRasterizer::RestoreMatrices()
       
   549     {
       
   550     vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
       
   551     
       
   552     vgLoadMatrix(iPathMatrix);
       
   553     
       
   554     vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
   555     
       
   556     vgLoadMatrix(iImageMatrix);
       
   557     
       
   558     vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
       
   559     
       
   560     vgLoadMatrix(iFillPaintMatrix);
       
   561     
       
   562     vgSeti(VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER);
       
   563     
       
   564     vgLoadMatrix(iStrokePaintMatrix);
       
   565     
       
   566     vgSeti(VG_MATRIX_MODE, iMatrixMode);
       
   567     
       
   568     vgSetPaint(iUserStrokePaint, VG_STROKE_PATH);
       
   569     
       
   570     vgSetPaint(iUserFillPaint, VG_FILL_PATH);
       
   571     }
       
   572 
       
   573 
       
   574 TSize CSvgtFbsRasterizer::ApplyMarginL(VGImage aVgImage, TSize aSize)
       
   575     {
       
   576     HBufC8* buf = HBufC8::NewL(aSize.iWidth* sizeof(TUint32));
       
   577     TUint32* ptr = (TUint32*)(buf->Des()).Ptr();
       
   578     
       
   579     const TInt validMargin = aSize.iHeight * 12 / 100;
       
   580     
       
   581     const TInt Ha = aSize.iHeight;
       
   582     TInt hTa = 0;
       
   583     TInt hNT = 0;
       
   584     TInt C = 0;
       
   585     TInt hNTN = Ha - 2.0 * 0.12 * Ha;   
       
   586     TReal R = 1.0;
       
   587     TInt HaN = Ha;
       
   588     
       
   589     const TInt lastColumn = aSize.iHeight - 1;
       
   590     for ( TInt curRow = 0; curRow < validMargin; curRow++ )
       
   591         {
       
   592         const TInt y = (aSize.iHeight - 1) - curRow; // h - 1 is the last line
       
   593         
       
   594         vgGetImageSubData(aVgImage, ptr, sizeof(TUint)*aSize.iWidth, VG_sRGBA_8888_PRE, 0, y, aSize.iWidth, 1);
       
   595                                 
       
   596         for ( TInt s = lastColumn; s >= 0; --s )
       
   597             {
       
   598             if ( ptr[s] & 0x000000FF ) 
       
   599                 {
       
   600                 hTa = curRow;
       
   601                 hNT = Ha - 2 * hTa;
       
   602                 C = 2 * hTa;
       
   603                 R = ( ( (TReal)hNTN / (TReal)hNT ) > 1.0 ) ? 1 : (TReal)hNTN / (TReal)hNT;
       
   604                 HaN = Ha * R - C * R + C;
       
   605                 curRow = validMargin; // to exit the outer loop
       
   606                 break; // to exit the inner
       
   607                 }
       
   608             
       
   609             }
       
   610         }
       
   611     
       
   612     delete buf;
       
   613         
       
   614     if(aSize.iHeight > HaN)
       
   615         {
       
   616         
       
   617         VGfloat color[4] = { 1.0f, 1.0f, 1.0f, 0.0f }; 
       
   618         
       
   619         vgSetfv(VG_CLEAR_COLOR, 4, color);
       
   620         vgClear(0, 0, aSize.iWidth,aSize.iHeight);
       
   621         
       
   622         vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);   
       
   623         VGfloat Hr = (VGfloat)HaN/(aSize.iHeight);
       
   624         
       
   625         TInt WaN = aSize.iWidth*Hr;
       
   626         
       
   627         VGfloat Tx = (aSize.iHeight-HaN)/2;
       
   628         VGfloat Ty = (aSize.iWidth-WaN)/2;
       
   629         vgTranslate(Tx,Ty);
       
   630         
       
   631         return( TSize(HaN,WaN));    
       
   632         }
       
   633     return aSize;
       
   634     
       
   635     }
       
   636 
       
   637 
       
   638 
       
   639 TInt CSvgtFbsRasterizer::MapOpenVgErrorCodeToSymbian(TInt aErrorCode)
       
   640     {
       
   641     switch( aErrorCode )
       
   642         {
       
   643         case VGI_OK:
       
   644             return KErrNone;
       
   645             
       
   646         case VGI_ERROR_OUT_OF_MEMORY:
       
   647             return KErrNoMemory;
       
   648             
       
   649         case VGI_ERROR_INVALID_ARGUMENTS:
       
   650             return KErrArgument;
       
   651             
       
   652         case VGI_ERROR_ALREADY_EXISTS:
       
   653             return KErrAlreadyExists;
       
   654             
       
   655         case VGI_ERROR_COLORSPACE_NOT_SUPPORTED:
       
   656             return KErrNotSupported;
       
   657             
       
   658         case VGI_ERROR_NOT_SUPPORTED:
       
   659             return KErrNotSupported;
       
   660 
       
   661         case VGI_ERROR_ILLEGAL_IMAGE_HANDLE:
       
   662             return KErrBadHandle;
       
   663 
       
   664         case VGI_ERROR_IMAGE_IN_USE:
       
   665             return KErrInUse;
       
   666 
       
   667         case VGI_ERROR_ILLEGAL_OPERATION:
       
   668             return KErrPermissionDenied;
       
   669 
       
   670         default:
       
   671             return KErrUnknown;
       
   672         }
       
   673 
       
   674     }
       
   675