--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/nvgdecoder/src/NVGCSIcon.cpp Thu Jan 07 16:19:02 2010 +0200
@@ -0,0 +1,588 @@
+/*
+* Copyright (c) 2008 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: NVG Decoder source file
+*
+*/
+
+#include "NVGCSIcon.h"
+#include "NVGIconData.h"
+#include "nvgfittoviewbox.h"
+#include "nvg.h"
+#include "NVGUtil.h"
+#include "OpenVGHandleStore.h"
+
+#include <string.h>
+#include <e32math.h>
+
+
+CNVGCSIcon::CNVGCSIcon()
+ : iNVGIconData(0),
+ iPath(VG_INVALID_HANDLE),
+ iFillPaint(VG_INVALID_HANDLE),
+ iStrokePaint(VG_INVALID_HANDLE),
+ iLastFillPaintType(0),
+ iLastStrokePaintType(0),
+ iLastFillPaintColor(0),
+ iLastStrkePaintColor(0),
+ iResetFillPaint(0),
+ iResetStrokePaint(0)
+ {
+ }
+
+CNVGCSIcon::~CNVGCSIcon()
+ {
+ vgSetPaint(VG_INVALID_HANDLE, VG_FILL_PATH);
+ vgSetPaint(VG_INVALID_HANDLE, VG_STROKE_PATH);
+
+ delete iNVGIconData;
+ delete iOpenVGHandles;
+ }
+
+CNVGCSIcon * CNVGCSIcon::NewL(const TDesC8& aBuf)
+ {
+ CNVGCSIcon* self = CNVGCSIcon::NewLC(aBuf);
+
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CNVGCSIcon * CNVGCSIcon::NewLC(const TDesC8& aBuf)
+ {
+ CNVGCSIcon* self = new (ELeave) CNVGCSIcon;
+ CleanupStack::PushL(self);
+
+ self->ConstructL(aBuf);
+
+ return self;
+ }
+
+void CNVGCSIcon::ConstructL(const TDesC8& aBuf)
+ {
+ iNVGIconData = CNVGIconData::NewL(aBuf.Length());
+ iOpenVGHandles = COpenVGHandleStore::NewL();
+
+ if (iPath == VG_INVALID_HANDLE)
+ {
+ iPath = vgCreatePath(VG_PATH_FORMAT_STANDARD,
+ VG_PATH_DATATYPE_S_32, 1.0f/65536.0f, 0.0f, 0, 0,
+ VG_PATH_CAPABILITY_APPEND_TO);
+ iOpenVGHandles->AddPathDHL(iPath);
+ }
+
+ if (iFillPaint == VG_INVALID_HANDLE)
+ {
+ iFillPaint = vgCreatePaint();
+ iOpenVGHandles->AddPaintDHL(iFillPaint);
+ }
+ vgSetPaint(iFillPaint, VG_FILL_PATH);
+
+ if (iStrokePaint == VG_INVALID_HANDLE)
+ {
+ iStrokePaint = vgCreatePaint();
+ iOpenVGHandles->AddPaintDHL(iStrokePaint);
+ }
+ vgSetPaint(iStrokePaint, VG_STROKE_PATH);
+ }
+
+TInt CNVGCSIcon::SetViewBox(TReal32 x, TReal32 y, TReal32 w, TReal32 h) __SOFTFP
+ {
+ iViewBoxX = x;
+ iViewBoxY = y;
+ iViewBoxW = w;
+ iViewBoxH = h;
+
+ return KErrNone;
+ }
+
+TInt CNVGCSIcon::SetPreserveAspectRatio(TInt aPreserveAspectSetting,
+ TInt aSmilFitSetting)
+ {
+ iPreserveAspectSetting = aPreserveAspectSetting;
+ iSmilFitSetting = aSmilFitSetting;
+
+ return KErrNone;
+ }
+
+TInt CNVGCSIcon::Rotate(TReal32 aAngle, TReal32 aX, TReal32 aY) __SOFTFP
+ {
+ iRotationAngle = aAngle;
+ iRotationX = aX;
+ iRotationY = aY;
+
+ return KErrNone;
+ }
+
+void CNVGCSIcon::AddPathDataL(VGint numSegments, const VGubyte * pathSegments, const void * pathData)
+ {
+ iNVGIconData->EncodeInt32L(EPathData);
+ iNVGIconData->EncodeInt32L(numSegments);
+ iNVGIconData->EncodeDataL(pathSegments, numSegments);
+
+ TInt coordinateCount = 0;
+ for (TInt i = 0; i < numSegments; ++i)
+ {
+ switch (pathSegments[i])
+ {
+ case VG_HLINE_TO:
+ case VG_VLINE_TO:
+ coordinateCount += 1;
+ break;
+ case VG_MOVE_TO:
+ case VG_LINE_TO:
+ case VG_SQUAD_TO:
+ coordinateCount += 2;
+ break;
+ case VG_QUAD_TO:
+ case VG_SCUBIC_TO:
+ coordinateCount += 4;
+ break;
+ case VG_SCCWARC_TO:
+ case VG_SCWARC_TO:
+ case VG_LCCWARC_TO:
+ case VG_LCWARC_TO:
+ coordinateCount += 5;
+ break;
+ case VG_CUBIC_TO:
+ coordinateCount += 6;
+ break;
+ default:
+ break;
+ }
+ }
+ iNVGIconData->EncodeInt16L(coordinateCount);
+ iNVGIconData->EncodeDataL(pathData, coordinateCount * 4);
+ }
+
+void CNVGCSIcon::AddDrawPathCommandL(VGPath aPath, VGbitfield aPaintMode)
+ {
+ iOpenVGHandles->AddPathDHL(aPath);
+ iNVGIconData->EncodeInt32L(EPath);
+ iNVGIconData->EncodeInt32L(aPath);
+ iNVGIconData->EncodeInt32L(aPaintMode);
+ }
+
+void CNVGCSIcon::AddLinearGradientCommandL(VGint aCount, VGfloat* aGradientData, VGfloat* aGradientMatrix, VGPaint aPaint)
+ {
+ iOpenVGHandles->AddPaintDHL(aPaint);
+ iNVGIconData->EncodeInt32L(EPaint);
+ AddLinearGradientCommandDataL(aPaint, aCount, aGradientData, aGradientMatrix);
+ }
+
+void CNVGCSIcon::AddRadialGradientCommandL(VGint aCount, VGfloat* aGradientData, VGfloat* aGradientMatrix, VGPaint aPaint)
+ {
+ iOpenVGHandles->AddPaintDHL(aPaint);
+ iNVGIconData->EncodeInt32L(EPaint);
+ AddRadialGradientCommandDataL(aPaint, aCount, aGradientData, aGradientMatrix);
+ }
+
+void CNVGCSIcon::AddSetColorCommandL(VGuint aRgba)
+ {
+ iNVGIconData->EncodeInt32L(EPaint);
+ iNVGIconData->EncodeInt32L(VG_PAINT_TYPE_COLOR);
+ iNVGIconData->EncodeInt32L(aRgba);
+ }
+
+void CNVGCSIcon::AddColorRampCommandL(VGPaint aPaint)
+ {
+ iNVGIconData->EncodeInt32L(EColorRamp);
+ iNVGIconData->EncodeInt32L(aPaint);
+ }
+
+void CNVGCSIcon::AddSetTransformCommandL(const VGfloat* aTransformMatrix, TInt aFlag)
+ {
+ iNVGIconData->EncodeInt32L(ETransform);
+ iNVGIconData->EncodeDataL(aTransformMatrix, 9 * sizeof(VGfloat));
+ iNVGIconData->EncodeInt32L(aFlag);
+ }
+
+void CNVGCSIcon::AddSetStrokeWidthCommandL(VGfloat aStrokeWidth)
+ {
+ iNVGIconData->EncodeInt32L(EStrokeWidth);
+ iNVGIconData->EncodeReal32L(aStrokeWidth);
+ }
+
+void CNVGCSIcon::AddSetStrokeMiterLimitCommandL(VGfloat aMiterLimit)
+ {
+ iNVGIconData->EncodeInt32L(EStrokeMiterLimit);
+ iNVGIconData->EncodeReal32L(aMiterLimit);
+ }
+
+void CNVGCSIcon::AddStrokeLineJoinCapCommandL(VGint aCapStyle, VGint aJoinStyle)
+ {
+ iNVGIconData->EncodeInt32L(EStrokeLineJoinCap);
+ iNVGIconData->EncodeInt32L(aCapStyle);
+ iNVGIconData->EncodeInt32L(aJoinStyle);
+ }
+
+void CNVGCSIcon::AddStrokeLinearGradientCommandL(VGint aCount, VGfloat* aGradientData, VGfloat* aGradientMatrix, VGPaint aPaint)
+ {
+ iOpenVGHandles->AddPaintDHL(aPaint);
+ iNVGIconData->EncodeInt32L(EStrokePaint);
+ AddLinearGradientCommandDataL(aPaint, aCount, aGradientData, aGradientMatrix);
+ }
+
+void CNVGCSIcon::AddStrokeRadialGradientCommandL(VGint aCount, VGfloat* aGradientData, VGfloat* aGradientMatrix, VGPaint aPaint)
+ {
+ iOpenVGHandles->AddPaintDHL(aPaint);
+ iNVGIconData->EncodeInt32L(EStrokePaint);
+ AddRadialGradientCommandDataL(aPaint, aCount, aGradientData, aGradientMatrix);
+ }
+
+void CNVGCSIcon::AddStrokeSetColorCommandL(VGuint aRgba)
+ {
+ iNVGIconData->EncodeInt32L(EStrokePaint);
+ AddSetColorCommandDataL(aRgba);
+ }
+
+void CNVGCSIcon::AddStrokeColorRampCommandL(VGPaint aPaint)
+ {
+ iNVGIconData->EncodeInt32L(EStrokeColorRamp);
+ iNVGIconData->EncodeInt32L(aPaint);
+ }
+
+void CNVGCSIcon::AddLinearGradientCommandDataL(VGPaint aPaint, VGint aCount, VGfloat* aGradientData, VGfloat* aGradientMatrix)
+ {
+ iNVGIconData->EncodeInt32L(VG_PAINT_TYPE_LINEAR_GRADIENT);
+ iNVGIconData->EncodeInt32L(aPaint);
+ iNVGIconData->EncodeInt32L(aCount);
+ iNVGIconData->EncodeDataL(aGradientData, aCount * sizeof(VGfloat));
+ iNVGIconData->EncodeDataL(aGradientMatrix, 9 * sizeof(VGfloat));
+ }
+
+void CNVGCSIcon::AddRadialGradientCommandDataL(VGPaint aPaint, VGint aCount, VGfloat* aGradientData, VGfloat* aGradientMatrix)
+ {
+ iNVGIconData->EncodeInt32L(VG_PAINT_TYPE_RADIAL_GRADIENT);
+ iNVGIconData->EncodeInt32L(aPaint);
+ iNVGIconData->EncodeInt32L(aCount);
+ iNVGIconData->EncodeDataL(aGradientData, aCount * sizeof(VGfloat));
+ iNVGIconData->EncodeDataL(aGradientMatrix, 9 * sizeof(VGfloat));
+ }
+
+void CNVGCSIcon::AddSetColorCommandDataL(VGuint aRgba)
+ {
+ iNVGIconData->EncodeInt32L(VG_PAINT_TYPE_COLOR);
+ iNVGIconData->EncodeInt32L(aRgba);
+ }
+
+TInt CNVGCSIcon::Draw(const TSize aSize, CNvgEngine * aNVGEngine)
+ {
+ NVG_DEBUGP2("DRAWING NVGCSIcon %s, ", __FUNCTION__);
+
+ TInt error = KErrNone;
+
+ iNVGEngine = aNVGEngine;
+
+ // Get Matrix modes and all caller matrices (must be restored afterwards)
+ UpdateClientMatrices();
+
+ TRAP(error, DoDrawL(aSize));
+
+ // restore everything as we may have changed matrix mode
+ RestoreClientMatrices();
+
+ return error;
+ }
+
+TInt CNVGCSIcon::DoDrawL(const TSize aSize)
+ {
+ TInt ret = KErrNone;
+
+ vgSetPaint(iFillPaint, VG_FILL_PATH);
+ vgSetPaint(iStrokePaint, VG_STROKE_PATH);
+ iLastFillPaintColor = 0;
+ iLastStrkePaintColor = 0;
+ iLastFillPaintType = 0;
+ iLastStrokePaintType = 0;
+
+ VGfloat lCurrentPathMatrix[9];
+ vgGetMatrix(lCurrentPathMatrix);
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ vgLoadMatrix(lCurrentPathMatrix);
+ SetRotation();
+#ifdef __MIRROR_
+ vgScale(1.0f, -1.0f);
+ vgTranslate(0, (VGfloat)(-aSize.iHeight) );
+#endif
+
+ SetViewBoxToViewTransformationL(aSize);
+
+
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+
+ VGfloat currentMatrix[9];
+
+ vgGetMatrix(currentMatrix);
+
+ iNVGIconData->BeginRead();
+
+ while (!iNVGIconData->EOF())
+ {
+ switch (iNVGIconData->ReadInt32L())
+ {
+ case EPath:
+ {
+ VGPath path = (VGPath)iNVGIconData->ReadInt32L();
+ VGPaintMode paintMode = (VGPaintMode)iNVGIconData->ReadInt32L();
+
+ if (path == VG_INVALID_HANDLE)
+ {
+ vgDrawPath(iPath, paintMode);
+ }
+ else
+ {
+ vgDrawPath(path, paintMode);
+ }
+
+ break;
+ }
+ case EPathData:
+ {
+ if (iPath != VG_INVALID_HANDLE)
+ {
+ VGint numSegments;
+ VGubyte * pathSegments = 0;
+ VGubyte * pathData = 0;
+
+ numSegments = iNVGIconData->ReadInt32L();
+ pathSegments = new (ELeave) VGubyte[numSegments];
+ CleanupStack::PushL(TCleanupItem(CleanupArray, pathSegments));
+ if (pathSegments)
+ {
+ iNVGIconData->ReadL(pathSegments, numSegments);
+ VGint coordinateCount = iNVGIconData->ReadInt32L();
+ pathData = new (ELeave) VGubyte[coordinateCount * 4];
+ if (pathData)
+ {
+ CleanupStack::PushL(TCleanupItem(CleanupArray, pathData));
+ iNVGIconData->ReadL(pathData, coordinateCount * 4);
+ vgClearPath(iPath, VG_PATH_CAPABILITY_APPEND_TO);
+ vgAppendPathData(iPath, numSegments, pathSegments, pathData);
+ CleanupStack::PopAndDestroy();
+ }
+ }
+ CleanupStack::PopAndDestroy();
+ }
+ break;
+ }
+ case EPaint:
+ {
+ DrawPaintL(iFillPaint, VG_MATRIX_FILL_PAINT_TO_USER, iLastFillPaintType, iLastFillPaintColor, VG_FILL_PATH);
+ break;
+ }
+ case EColorRamp:
+ {
+ iNVGIconData->ReadInt32L();
+ break;
+ }
+ case ETransform:
+ {
+ TInt flag;
+ VGfloat transformMatrix[9];
+
+ TPtr8 tmPtr((TUint8 *)transformMatrix, 9 * sizeof(VGfloat));
+
+ iNVGIconData->ReadL(tmPtr, 9 * sizeof(VGfloat));
+ flag = iNVGIconData->ReadInt32L();
+
+ vgLoadMatrix(currentMatrix);
+ if (flag)
+ {
+ vgMultMatrix(transformMatrix);
+ }
+ }
+ break;
+ case EStrokeWidth:
+ {
+ VGfloat strokeWidth = iNVGIconData->ReadReal32L();
+ vgSetf(VG_STROKE_LINE_WIDTH, strokeWidth);
+ break;
+ }
+ case EStrokeMiterLimit:
+ {
+ VGfloat miterLimit = iNVGIconData->ReadReal32L();
+ vgSetf(VG_STROKE_MITER_LIMIT, miterLimit);
+ break;
+ }
+ case EStrokeLineJoinCap:
+ {
+ VGint lineJoin = iNVGIconData->ReadInt32L();
+ VGint cap = iNVGIconData->ReadInt32L();
+
+ vgSeti(VG_STROKE_JOIN_STYLE, (VGJoinStyle)lineJoin);
+ vgSeti(VG_STROKE_CAP_STYLE, (VGCapStyle)cap);
+ break;
+ }
+ case EStrokePaint:
+ {
+ DrawPaintL(iStrokePaint, VG_MATRIX_STROKE_PAINT_TO_USER, iLastStrokePaintType, iLastStrkePaintColor, VG_STROKE_PATH);
+ break;
+ }
+ case EStrokeColorRamp:
+ {
+ iNVGIconData->ReadInt32L();
+ break;
+ }
+ default:
+ {
+ User::Leave(KErrCorrupt);
+ break;
+ }
+ }
+ }
+
+ iNVGIconData->EndRead();
+
+ return ret;
+ }
+
+void CNVGCSIcon::DrawColorRampL(VGPaint aPaint)
+ {
+ TInt stopCount = iNVGIconData->ReadInt32L();
+ VGfloat * colorRamps = new (ELeave) VGfloat[stopCount];
+ CleanupStack::PushL(TCleanupItem(CleanupArray, colorRamps));
+
+ iNVGIconData->ReadL((TUint8 *)colorRamps, stopCount * sizeof(VGfloat));
+ vgSetParameteri(aPaint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD);
+ vgSetParameterfv(aPaint, VG_PAINT_COLOR_RAMP_STOPS, stopCount, colorRamps);
+
+ CleanupStack::PopAndDestroy();
+ }
+
+void CNVGCSIcon::DrawPaintL(VGPaint aPaint, VGMatrixMode aMatrixMode, TUint & aLastPaintType, TUint & aLastPaintColor, VGPaintMode aPaintMode)
+ {
+ VGPaintType paintType = (VGPaintType)iNVGIconData->ReadInt32L();
+
+ if (paintType == VG_PAINT_TYPE_LINEAR_GRADIENT ||
+ paintType == VG_PAINT_TYPE_RADIAL_GRADIENT)
+ {
+ VGPaintParamType paintPType = VG_PAINT_LINEAR_GRADIENT;
+ if (paintType == VG_PAINT_TYPE_RADIAL_GRADIENT)
+ {
+ paintPType = VG_PAINT_RADIAL_GRADIENT;
+ }
+
+ VGPaint paintHandle = iNVGIconData->ReadInt32L();
+ TInt count = iNVGIconData->ReadInt32L();
+ VGfloat gradientData[5];
+ VGfloat gradientMatrix[9];
+
+ iNVGIconData->ReadL((TUint8 *)gradientData, count * sizeof(VGfloat));
+ iNVGIconData->ReadL((TUint8 *)gradientMatrix, 9 * sizeof(VGfloat));
+
+ if (paintHandle)
+ {
+ vgSetPaint(paintHandle, aPaintMode);
+ vgSeti(VG_MATRIX_MODE, aMatrixMode);
+ vgLoadMatrix(gradientMatrix);
+ if (aPaintMode == VG_FILL_PATH)
+ {
+ iResetFillPaint = 1;
+ }
+ else
+ {
+ iResetStrokePaint = 1;
+ }
+ }
+ else
+ {
+ if (aLastPaintType != paintType)
+ {
+ vgSetParameteri(aPaint, VG_PAINT_TYPE, paintType);
+ }
+ vgSetParameterfv(aPaint, paintPType, count, gradientData);
+
+ vgSeti(VG_MATRIX_MODE, aMatrixMode);
+ vgLoadMatrix(gradientMatrix);
+ }
+ vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+ }
+ else if (paintType == VG_PAINT_TYPE_COLOR)
+ {
+ if (aPaintMode == VG_FILL_PATH && iResetFillPaint)
+ {
+ iResetFillPaint = 0;
+ vgSetPaint(aPaint, aPaintMode);
+ }
+ else if (aPaintMode == VG_STROKE_PATH && iResetStrokePaint)
+ {
+ iResetStrokePaint = 0;
+ vgSetPaint(aPaint, aPaintMode);
+ }
+ TUint color = static_cast<TUint>(iNVGIconData->ReadInt32L());
+ if (aLastPaintType != paintType)
+ {
+ vgSetParameteri(aPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+ vgSetColor(aPaint, color);
+ }
+ else
+ {
+ if (aLastPaintColor != color)
+ {
+ vgSetColor(aPaint, color);
+ }
+ }
+ aLastPaintColor = color;
+ }
+ else
+ {
+ User::Leave(KErrCorrupt);
+ }
+ aLastPaintType = paintType;
+ }
+
+void CNVGCSIcon::SetViewBoxToViewTransformationL(const TSize aSize)
+ {
+ CNvgFitToViewBoxImpl * fitToViewBoxImpl = CNvgFitToViewBoxImpl::NewLC();
+
+ fitToViewBoxImpl->SetAlign((TNvgAlignStatusType)iPreserveAspectSetting);
+ fitToViewBoxImpl->SetScaling((TNvgMeetOrSliceType)iSmilFitSetting);
+
+ fitToViewBoxImpl->SetViewBox(iViewBoxX, iViewBoxY, iViewBoxW, iViewBoxH);
+
+ fitToViewBoxImpl->SetWindowViewportTrans(TRect(0, 0, aSize.iWidth, aSize.iHeight), TSize(0, 0));
+
+ CleanupStack::PopAndDestroy(fitToViewBoxImpl);
+ }
+
+void CNVGCSIcon::SetRotation()
+ {
+ if (iRotationAngle)
+ {
+ vgTranslate(iRotationX, iRotationY);
+
+ vgRotate(iRotationAngle);
+
+ vgTranslate(-iRotationX, -iRotationY);
+ }
+ }
+
+void CNVGCSIcon::UpdateClientMatrices()
+ {
+ 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, iMatrixMode);
+ }
+
+void CNVGCSIcon::RestoreClientMatrices()
+ {
+ 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, iMatrixMode);
+ }