--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uigraphics/AknIcon/SvgtFbsRasterizer/src/SvgtFbsRasterizer.cpp Thu Dec 17 09:14:12 2009 +0200
@@ -0,0 +1,675 @@
+/*
+* Copyright (c) 2002 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: CSvgtFbsRasterizer implementation.
+*
+*/
+
+#include "svgtfbsrasterizer.h"
+#include "fbsrasterizerpanics.h"
+#include "SvgtRegisteredBitmap.h"
+#include "svgtgraphicsinterface.h"
+#include <e32std.h>
+#include <nvg.h>
+#include <AknIconHeader.h>
+#include <AknIconUtils.h>
+#include <vgcontext.h>
+
+#include <bitstd.h>
+#include <bitdev.h>
+
+TBool operator==(const CFbsRasterizer::TBitmapDesc& aBitmapDesc1,
+ const CFbsRasterizer::TBitmapDesc& aBitmapDesc2)
+ {
+ return ((&aBitmapDesc1 == &aBitmapDesc2)
+ || (aBitmapDesc1.iSizeInPixels == aBitmapDesc2.iSizeInPixels
+ && aBitmapDesc1.iDispMode == aBitmapDesc2.iDispMode
+ && aBitmapDesc1.iDataType == aBitmapDesc2.iDataType
+ && aBitmapDesc1.iData == aBitmapDesc2.iData
+ && aBitmapDesc1.iDataSize == aBitmapDesc2.iDataSize));
+ }
+
+void CleanupVGImage( TAny* aObj )
+ {
+ VGImage * imageToDestroy = reinterpret_cast<VGImage *>(aObj);
+ if (imageToDestroy && *imageToDestroy != VG_INVALID_HANDLE)
+ {
+ vgDestroyImage(*imageToDestroy);
+ }
+ }
+
+/** Create a new rasterizer.
+@return A pointer to a newly constructed CFbsRasterizer object if successful,
+or NULL if no memory is available.
+ */
+EXPORT_C CFbsRasterizer* CSvgtFbsRasterizer::New()
+ {
+ CSvgtFbsRasterizer* self = new CSvgtFbsRasterizer;
+ if ( self )
+ {
+ self->InitializeRasterizer();
+ }
+ return self;
+ }
+
+/** Constructor */
+CSvgtFbsRasterizer::CSvgtFbsRasterizer()
+ :iRegisteredBmps(_FOFF(CSvgtRegisteredBitmap, iLink)), iRecentBmps(_FOFF(CSvgtRegisteredBitmap, iLink))
+ {
+ RProcess currentProcess;
+ TFileName exeFileName = currentProcess.FileName();
+ exeFileName.Copy(exeFileName.Mid(11));
+ exeFileName.Copy(exeFileName.Left(exeFileName.Length()-4));
+
+ if(exeFileName.Compare(_L("peninputserver"))==0)
+ {
+ iCacheLimit = 0x133333;
+ iSpecialProcess = TRUE;
+ }
+ else
+ {
+ iCacheLimit = KMaxRecentBmpCacheSize;
+ iSpecialProcess = FALSE;
+ }
+ }
+
+CSvgtFbsRasterizer::~CSvgtFbsRasterizer()
+ {
+ while (!iRegisteredBmps.IsEmpty())
+ {
+ delete iRegisteredBmps.First();
+ }
+ while (!iRecentBmps.IsEmpty())
+ {
+ delete iRecentBmps.First();
+ }
+ delete iIdle;
+
+ delete iNvgEngine;
+ delete iGraphicsInterface;
+ if ( iMatricesUpdated )
+ {
+ RestoreMatrices();
+ }
+ }
+
+/** Register a bitmap with this rasterizer for rendering. In this example the extended
+bitmap data is just a buffer that is copied when BeginBitmap() is called and deleted when
+EndBitmap() is called for the same bitmap. The only display modes supported by this example
+raterizer are EColor16MU and EColor16MA
+*/
+void CSvgtFbsRasterizer::BeginBitmap(TInt64 aBitmapId, const TBitmapDesc& aBitmapDesc, const TRegion* aRegionOfInterest)
+ {
+ TRAPD(beginErr, DoBeginBitmapL(aBitmapId, aBitmapDesc, aRegionOfInterest));
+ // If there is error in begin, the consecutive fulction calls should be invalid.
+ iIsRasterizerValidState = ( beginErr == KErrNone);
+ }
+
+void CSvgtFbsRasterizer::DoBeginBitmapL(TInt64 aBitmapId, const TBitmapDesc& aBitmapDesc,
+ const TRegion* /* aRegionOfInterest */)
+ {
+ // Check that the passed extended bitmap description is valid
+ if ((aBitmapDesc.iSizeInPixels.iWidth <= 0) || (aBitmapDesc.iSizeInPixels.iHeight <= 0)
+ || (aBitmapDesc.iDataType != KUidNvgProprietaryFormat)
+ || (!aBitmapDesc.iData )
+ || (aBitmapDesc.iDataSize <= 0))
+ {
+ return;
+ }
+ // Check if the bitmap is already registered
+ CSvgtRegisteredBitmap* foundRegBmp = RegisteredBitmap(aBitmapId);
+ if (!foundRegBmp)
+ {
+ // Not registered: check if the bitmap is in the cache of recently used bitmaps
+ foundRegBmp = RecentBitmap(aBitmapId);
+ if (foundRegBmp)
+ {
+ // Take the bitmap out of the cache and put it in the list of registered bitmaps
+ foundRegBmp->iLink.Deque();
+ iTotalRecentBmpSize -= foundRegBmp->DataSize();
+ iRegisteredBmps.AddLast(*foundRegBmp);
+ }
+ }
+ if (foundRegBmp)
+ {
+ // This bitmap is already registered, just increment its reference count and return
+ foundRegBmp->iRefCount++;
+ return;
+ }
+
+ CSvgtRegisteredBitmap* regBmp = new CSvgtRegisteredBitmap(aBitmapId);
+ if (!regBmp)
+ {
+ return;
+ }
+ TRAPD(err, RenderL(aBitmapDesc, *regBmp));
+ if (err != KErrNone)
+ {
+ delete regBmp;
+ return;
+ }
+ // Success
+ iRegisteredBmps.AddLast(*regBmp);
+ regBmp->iRefCount = 1;
+ }
+
+/** Unregister an extended bitmap from this rasterizer.
+@see CFbsRasterizer::EndBitmap()
+@see BeginBitmap()
+ */
+void CSvgtFbsRasterizer::EndBitmap(TInt64 aBitmapId)
+ {
+ CSvgtRegisteredBitmap* regBmp = RegisteredBitmap(aBitmapId);
+ if (regBmp)
+ {
+ if (--regBmp->iRefCount == 0)
+ {
+ // Put unregistered bitmap in the cache of recently used bitmaps if wholly pre-rendered
+ // and there is an active scheduler to add the idle-time clean-up active object to
+ if (CActiveScheduler::Current())
+ {
+ if (!iIdle)
+ {
+ iIdle = CIdle::New(CActive::EPriorityIdle);
+ if (!iIdle)
+ {
+ delete regBmp;
+ return;
+ }
+ }
+ regBmp->iLink.Deque();
+ if (regBmp->DataSize() <= iCacheLimit)
+ {
+ iRecentBmps.AddFirst(*regBmp);
+ iTotalRecentBmpSize += regBmp->DataSize();
+ }
+ // Delete the least recently used bitmaps if the maximum size of the cache is exceeded
+ while (iTotalRecentBmpSize > iCacheLimit)
+ {
+ regBmp = iRecentBmps.Last();
+ iTotalRecentBmpSize -= regBmp->DataSize();
+ delete regBmp;
+ }
+ // If the cache is not empty make sure the idle-time clean-up active object is scheduled to run
+ if (!iRecentBmps.IsEmpty() && !iIdle->IsActive())
+ {
+ iIdle->Start(TCallBack(IdleFunction, this));
+ }
+ }
+ else
+ {
+ delete regBmp;
+ }
+ }
+ }
+ }
+
+/** Return a scanline from the passed extended bitmap given it's bitmap id.
+ */
+const TUint32* CSvgtFbsRasterizer::ScanLine(TInt64 aBitmapId, const TPoint& aPixel, TInt aLength)
+ {
+ CSvgtRegisteredBitmap* regBmp = RegisteredBitmap(aBitmapId);
+ if (!regBmp)
+ {
+ return NULL;
+ }
+ if (!TRect(regBmp->SizeInPixels()).Contains(aPixel)
+ || (aLength > (regBmp->SizeInPixels().iWidth - aPixel.iX)))
+ {
+ return NULL;
+ }
+
+ return PtrAdd(regBmp->DataAddress(), aPixel.iY * regBmp->DataStride());
+ }
+
+/** No extension interaces are available, KErrNotSupported for all aInterfaceId passed.
+@see CFbsRasterizer::GetInterface()
+ */
+TInt CSvgtFbsRasterizer::GetInterface(TUid /*aInterfaceId*/, TAny*& aInterface)
+ {
+ aInterface = NULL;
+ return KErrExtensionNotSupported;
+ }
+
+
+/** Gets a bitmap that has been registered with this rasterizer.
+
+@param aBitmapId The ID of the bitmap to check for.
+
+@return A pointer to the registered bitmap if found, NULL otherwise.
+ */
+CSvgtRegisteredBitmap* CSvgtFbsRasterizer::RegisteredBitmap(TInt64 aBitmapId)
+ {
+ TDblQueIter<CSvgtRegisteredBitmap> iter(iRegisteredBmps);
+ while (CSvgtRegisteredBitmap* regBmp = iter++)
+ {
+ if (regBmp->iBitmapId == aBitmapId)
+ {
+ return regBmp;
+ }
+ }
+ return NULL;
+ }
+
+/** Gets a bitmap that has been recently used with this rasterizer.
+
+@param aBitmapId The ID of the bitmap to check for.
+
+@return A pointer to the recently used bitmap if found, NULL otherwise.
+ */
+CSvgtRegisteredBitmap* CSvgtFbsRasterizer::RecentBitmap(TInt64 aBitmapId)
+ {
+ TDblQueIter<CSvgtRegisteredBitmap> iter(iRecentBmps);
+ while (CSvgtRegisteredBitmap* regBmp = iter++)
+ {
+ if (regBmp->iBitmapId == aBitmapId)
+ {
+ return regBmp;
+ }
+ }
+ return NULL;
+ }
+
+TInt CSvgtFbsRasterizer::IdleFunction(TAny* aPtr)
+ {
+ CSvgtFbsRasterizer* self = static_cast<CSvgtFbsRasterizer*>(aPtr);
+ if(self->iSpecialProcess!=true)
+ {
+
+ while (!self->iRecentBmps.IsEmpty())
+ {
+ delete self->iRecentBmps.First();
+ }
+ self->iTotalRecentBmpSize = 0;
+ }
+ return 0;
+ }
+
+void CSvgtFbsRasterizer::InitializeRasterizer()
+ {
+ }
+
+void CSvgtFbsRasterizer::RenderBitmapL(CSvgtRegisteredBitmap& aPixMap, CFbsBitmap * aMask,
+ const TBitmapDesc& aBitmapDesc, TPtr8& aDataPtr8, TAknIconHeader& aIconHeader)
+ {
+ TSize newSize = aBitmapDesc.iSizeInPixels;
+ UpdateMatrices();
+ iMatricesUpdated = ETrue;
+ TBool isMargin = aIconHeader.IsMarginCorrection();
+
+ VGImage vgImage = VG_INVALID_HANDLE;
+
+ if (isMargin)
+ {
+ vgImage = vgCreateImage((VGImageFormat) VG_sRGBA_8888_PRE , aBitmapDesc.iSizeInPixels.iWidth,
+ aBitmapDesc.iSizeInPixels.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
+ if (vgImage == VG_INVALID_HANDLE)
+ {
+ User::LeaveIfError(MapOpenVgErrorCodeToSymbian(vgGetError()));
+ }
+ CleanupStack::PushL( TCleanupItem( CleanupVGImage, &vgImage ) );
+ iGraphicsInterface->BindClientBuffer(vgImage);
+ }
+ User::LeaveIfError(iNvgEngine->DrawNvg(aDataPtr8, newSize, &aPixMap, aMask));
+
+ if(isMargin)
+ {
+ iGraphicsInterface->UnBindClientBuffer();
+ newSize = ApplyMarginL(vgImage, aBitmapDesc.iSizeInPixels);
+ if(newSize!=aBitmapDesc.iSizeInPixels)
+ {
+ User::LeaveIfError(iNvgEngine->DrawNvg(aDataPtr8, newSize, &aPixMap, aMask));
+ }
+ else
+ {
+ vgDrawImage(vgImage);
+ User::LeaveIfError(MapOpenVgErrorCodeToSymbian(vgGetError()));
+ }
+
+ CleanupStack::PopAndDestroy();
+ }
+ iGraphicsInterface->CopyBitmapL(&aPixMap, aMask);
+
+ TUint32 iconColor = aIconHeader.GetIconColor();
+
+ if (iconColor & 0xFFFFFF)
+ {
+ CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( &aPixMap );
+ CleanupStack::PushL( dev );
+ CFbsBitGc* gc = NULL;
+ User::LeaveIfError( dev->CreateContext( gc ) );
+ CleanupStack::PushL( gc );
+ TRgb color(iconColor);
+ gc->SetBrushColor( color );
+ gc->SetPenStyle( CGraphicsContext::ENullPen );
+ gc->SetBrushStyle( CGraphicsContext::ESolidBrush );
+ // Fill icon with the given color, mask defines the icon shape.
+ TPoint origin(0, 0);
+ if (newSize != aBitmapDesc.iSizeInPixels)
+ {
+ origin = TPoint((aBitmapDesc.iSizeInPixels.iWidth - newSize.iWidth)/2 , (aBitmapDesc.iSizeInPixels.iHeight - newSize.iHeight)/2 );
+ }
+ gc->DrawRect( TRect( origin, newSize ) );
+ CleanupStack::PopAndDestroy( 2 ); // dev, gc
+ }
+ }
+
+void CSvgtFbsRasterizer::RenderMaskL(CSvgtRegisteredBitmap& aPixMap, CFbsBitmap * aMask,
+ const TBitmapDesc& aBitmapDesc, TPtr8& aDataPtr8, TAknIconHeader& aIconHeader)
+ {
+ UpdateMatrices();
+ iMatricesUpdated = ETrue;
+ TBool isMargin = aIconHeader.IsMarginCorrection();
+
+ VGImage vgImage = VG_INVALID_HANDLE;
+ if (isMargin)
+ {
+ vgImage = vgCreateImage((VGImageFormat) VG_sRGBA_8888_PRE , aBitmapDesc.iSizeInPixels.iWidth,
+ aBitmapDesc.iSizeInPixels.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
+ if (vgImage == VG_INVALID_HANDLE)
+ {
+ User::LeaveIfError(MapOpenVgErrorCodeToSymbian(vgGetError()));
+ }
+ CleanupStack::PushL( TCleanupItem( CleanupVGImage, &vgImage ) );
+ iGraphicsInterface->BindClientBuffer(vgImage);
+ }
+
+ VGfloat color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ vgSeti(VG_SCISSORING, VG_FALSE);
+ vgSetfv(VG_CLEAR_COLOR, 4, color);
+ vgClear(0, 0, aBitmapDesc.iSizeInPixels.iWidth, aBitmapDesc.iSizeInPixels.iHeight);
+
+ User::LeaveIfError(iNvgEngine->DrawNvg(aDataPtr8, aBitmapDesc.iSizeInPixels, &aPixMap, aMask));
+ if (isMargin)
+ {
+ iGraphicsInterface->UnBindClientBuffer();
+ TSize newSize = ApplyMarginL(vgImage, aBitmapDesc.iSizeInPixels);
+ if(newSize!=aBitmapDesc.iSizeInPixels)
+ {
+ User::LeaveIfError(iNvgEngine->DrawNvg(aDataPtr8, newSize, &aPixMap, aMask));
+ }
+ else
+ {
+ vgDrawImage(vgImage);
+ User::LeaveIfError(MapOpenVgErrorCodeToSymbian(vgGetError()));
+ }
+ CleanupStack::PopAndDestroy();
+ }
+
+ TSize bitmapSize = aPixMap.SizeInPixels();
+
+ const TInt KOriginalFilterMasks = vgGeti( VG_FILTER_CHANNEL_MASK );
+ vgSeti( VG_FILTER_CHANNEL_MASK, VG_ALPHA );
+
+ const TInt KStride = CFbsBitmap::ScanLineLength(bitmapSize.iWidth, aPixMap.DisplayMode());
+ VGImageFormat format = ( aPixMap.DisplayMode() == EGray256 ) ? VG_A_8 : VG_BW_1;
+
+ aPixMap.BeginDataAccess();
+ TUint * data = (TUint*)((TUint)aPixMap.DataAddress() + ( KStride * ( aPixMap.SizeInPixels().iHeight - 1 ) ) );
+ vgReadPixels( data, -KStride, format, 0, 0, bitmapSize.iWidth, bitmapSize.iHeight );
+ aPixMap.EndDataAccess();
+
+ vgSeti( VG_FILTER_CHANNEL_MASK, KOriginalFilterMasks );
+
+ }
+
+void CSvgtFbsRasterizer::RenderL( const TBitmapDesc& aBitmapDesc, CSvgtRegisteredBitmap& aBitmap )
+ {
+
+ iIsRasterizerValidState = EFalse;
+
+ User::LeaveIfError(aBitmap.Create(aBitmapDesc.iSizeInPixels, aBitmapDesc.iDispMode));
+
+ if (!iGraphicsInterface)
+ {
+ iGraphicsInterface = CSvgtGraphicsInterface::CreateImplementationL();
+ }
+
+ iGraphicsInterface->InitializeL(aBitmapDesc.iSizeInPixels);
+ iIsRasterizerValidState = ETrue;
+
+ TPtr8 bmpDataPtr8((TUint8*)aBitmapDesc.iData, aBitmapDesc.iDataSize);
+
+ if (!iNvgEngine)
+ {
+ iNvgEngine = CNvgEngine::NewL();
+ }
+
+ iNvgEngine->SetVGImageBinder(iGraphicsInterface);
+
+ TUint8 *temp = (TUint8 *)bmpDataPtr8.Ptr();
+ TPtr8 IconHeaderPtr(temp, KIconHeaderLength, KIconHeaderLength);
+
+ TAknIconHeader iconheader(IconHeaderPtr);
+ //skipping header bytes
+ temp = temp + KIconHeaderLength;
+ TPtr8 newDataPtr8(temp, (bmpDataPtr8.MaxLength() - KIconHeaderLength), (bmpDataPtr8.MaxLength() - KIconHeaderLength));
+
+ CFbsBitmap* mask = NULL;
+
+ VGfloat color[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
+ vgSeti(VG_SCISSORING, VG_FALSE);
+ vgSetfv(VG_CLEAR_COLOR, 4, color);
+ vgClear(0, 0, aBitmapDesc.iSizeInPixels.iWidth, aBitmapDesc.iSizeInPixels.iHeight);
+ TInt rotAngle = iconheader.GetRotation();
+ // setting the rotation angle
+ iNvgEngine->Rotate(-rotAngle, aBitmapDesc.iSizeInPixels.iWidth >> 1,aBitmapDesc.iSizeInPixels.iHeight >>1);
+
+ //setting preserve aspect ratio
+ TNvgAlignStatusType alignTypeValue = ENvgPreserveAspectRatio_XmidYmid;
+ TNvgMeetOrSliceType meetOrSliceTypeValue = ENvgMeet;
+
+ switch ( iconheader.GetScaleMode() )
+ {
+ case EAspectRatioPreserved: // fall through
+ {
+ // use default
+ break;
+ }
+ // Ensures NVG content fully covers the area of the icon whilst preserving aspect ratio.
+ case EAspectRatioPreservedSlice:
+ {
+ // alignTypeValue use default
+ meetOrSliceTypeValue = ENvgSlice;
+ break;
+ }
+ /* EAspectRatioPreservedAndUnusedSpaceRemoved is mapped to the same values as EAspectRatioNotPreserved
+ * because we already have a frame buffer with the dimensions that preserves the aspect ratio.
+ * This mapping ensures that NVG engine does not calculate aspect ratio twice and potentially resulting in precision loss.*/
+ case EAspectRatioPreservedAndUnusedSpaceRemoved:
+ case EAspectRatioNotPreserved:
+ {
+ alignTypeValue = ENvgPreserveAspectRatio_None;
+ // meetOrSliceTypeValue use default
+ break;
+ }
+ default:
+ {
+ User::Leave(KErrCorrupt);
+ }
+ }
+ iNvgEngine->SetPreserveAspectRatio(alignTypeValue, meetOrSliceTypeValue);
+
+ iMatricesUpdated = EFalse;
+ if (iconheader.IsMask())
+ {
+ RenderMaskL(aBitmap, mask, aBitmapDesc, newDataPtr8, iconheader);
+ }
+ else
+ {
+ RenderBitmapL(aBitmap, mask, aBitmapDesc, newDataPtr8, iconheader);
+ }
+
+ if ( iMatricesUpdated )
+ {
+ RestoreMatrices();
+ iMatricesUpdated = EFalse;
+ }
+ }
+
+void CSvgtFbsRasterizer::UpdateMatrices()
+ {
+ iUserStrokePaint = vgGetPaint(VG_STROKE_PATH);
+
+ iUserFillPaint = vgGetPaint(VG_FILL_PATH);
+
+ iMatrixMode = vgGeti(VG_MATRIX_MODE);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+
+ vgGetMatrix(iPathMatrix);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+
+ vgGetMatrix(iImageMatrix);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
+
+ vgGetMatrix(iFillPaintMatrix);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER);
+
+ vgGetMatrix(iStrokePaintMatrix);
+
+ vgSeti(VG_MATRIX_MODE, iMatrixMode);
+
+ }
+
+void CSvgtFbsRasterizer::RestoreMatrices()
+ {
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+
+ vgLoadMatrix(iPathMatrix);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+
+ vgLoadMatrix(iImageMatrix);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER);
+
+ vgLoadMatrix(iFillPaintMatrix);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER);
+
+ vgLoadMatrix(iStrokePaintMatrix);
+
+ vgSeti(VG_MATRIX_MODE, iMatrixMode);
+
+ vgSetPaint(iUserStrokePaint, VG_STROKE_PATH);
+
+ vgSetPaint(iUserFillPaint, VG_FILL_PATH);
+ }
+
+
+TSize CSvgtFbsRasterizer::ApplyMarginL(VGImage aVgImage, TSize aSize)
+ {
+ HBufC8* buf = HBufC8::NewL(aSize.iWidth* sizeof(TUint32));
+ TUint32* ptr = (TUint32*)(buf->Des()).Ptr();
+
+ const TInt validMargin = aSize.iHeight * 12 / 100;
+
+ const TInt Ha = aSize.iHeight;
+ TInt hTa = 0;
+ TInt hNT = 0;
+ TInt C = 0;
+ TInt hNTN = Ha - 2.0 * 0.12 * Ha;
+ TReal R = 1.0;
+ TInt HaN = Ha;
+
+ const TInt lastColumn = aSize.iHeight - 1;
+ for ( TInt curRow = 0; curRow < validMargin; curRow++ )
+ {
+ const TInt y = (aSize.iHeight - 1) - curRow; // h - 1 is the last line
+
+ vgGetImageSubData(aVgImage, ptr, sizeof(TUint)*aSize.iWidth, VG_sRGBA_8888_PRE, 0, y, aSize.iWidth, 1);
+
+ for ( TInt s = lastColumn; s >= 0; --s )
+ {
+ if ( ptr[s] & 0x000000FF )
+ {
+ hTa = curRow;
+ hNT = Ha - 2 * hTa;
+ C = 2 * hTa;
+ R = ( ( (TReal)hNTN / (TReal)hNT ) > 1.0 ) ? 1 : (TReal)hNTN / (TReal)hNT;
+ HaN = Ha * R - C * R + C;
+ curRow = validMargin; // to exit the outer loop
+ break; // to exit the inner
+ }
+
+ }
+ }
+
+ delete buf;
+
+ if(aSize.iHeight > HaN)
+ {
+
+ VGfloat color[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
+
+ vgSetfv(VG_CLEAR_COLOR, 4, color);
+ vgClear(0, 0, aSize.iWidth,aSize.iHeight);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ VGfloat Hr = (VGfloat)HaN/(aSize.iHeight);
+
+ TInt WaN = aSize.iWidth*Hr;
+
+ VGfloat Tx = (aSize.iHeight-HaN)/2;
+ VGfloat Ty = (aSize.iWidth-WaN)/2;
+ vgTranslate(Tx,Ty);
+
+ return( TSize(HaN,WaN));
+ }
+ return aSize;
+
+ }
+
+
+
+TInt CSvgtFbsRasterizer::MapOpenVgErrorCodeToSymbian(TInt aErrorCode)
+ {
+ switch( aErrorCode )
+ {
+ case VGI_OK:
+ return KErrNone;
+
+ case VGI_ERROR_OUT_OF_MEMORY:
+ return KErrNoMemory;
+
+ case VGI_ERROR_INVALID_ARGUMENTS:
+ return KErrArgument;
+
+ case VGI_ERROR_ALREADY_EXISTS:
+ return KErrAlreadyExists;
+
+ case VGI_ERROR_COLORSPACE_NOT_SUPPORTED:
+ return KErrNotSupported;
+
+ case VGI_ERROR_NOT_SUPPORTED:
+ return KErrNotSupported;
+
+ case VGI_ERROR_ILLEGAL_IMAGE_HANDLE:
+ return KErrBadHandle;
+
+ case VGI_ERROR_IMAGE_IN_USE:
+ return KErrInUse;
+
+ case VGI_ERROR_ILLEGAL_OPERATION:
+ return KErrPermissionDenied;
+
+ default:
+ return KErrUnknown;
+ }
+
+ }
+