diff -r 000000000000 -r 88edb906c587 svgtopt/gfx2d/src/GfxGc/GfxGradientPaint.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtopt/gfx2d/src/GfxGc/GfxGradientPaint.cpp Wed Nov 03 18:56:10 2010 +0200 @@ -0,0 +1,594 @@ +/* +* 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: Graphics Extension Library source file +* +*/ + + + +#include "GfxGradientPaint.h" +#include "GfxFloatFixPt.h" + +static inline void svgMatrix2x3Identity(SVGMatrix2x3* m) + { + TInt i, j; + for (i=0; i<2; i++) + for (j=0; j<3; j++) + m->matrix[i][j] = (i == j) ? KFloatFixOne : KFloatFixZero; + } + +// ========================================================================== +// Common Constructor +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxGradientPaint::TGfxGradientPaint(): iGradientUnits(KobjectBoundingBox), +// --------------------------------------------------------------------------- + TGfxGradientPaint::TGfxGradientPaint(): iGradientUnits(KobjectBoundingBox), + iSpreadMethod(KspreadMethodPad) + { + + svgMatrix2x3Identity(&iGradientTransform); + + } + + TGfxGradientPaint::~TGfxGradientPaint() + { + } + +// -------------------------------------------------------------------------- +// void TGfxColor::SetFill(VGPaint aFillPaint) +// --------------------------------------------------------------------------- + void TGfxGradientPaint::SetFill(VGPaint aFillPaint, TGfxRectangle2D& aBBox, TFloatFixPt aOpacity,void* Renderer) + { + TGfxRectangle2D lBox = aBBox; + TUint32 flatColor = GetColor(); + TUint32 opacity = (TInt)(aOpacity * TFloatFixPt(255.0f)); +// VGuint fillColor = ((flatColor&0x000000FF)<<24) | +// ((flatColor&0x0000FF00)<<8) | +// ((flatColor&0x00FF0000)>>8) | +// opacity; + CVGRenderer *aVgRenderer=(CVGRenderer*) Renderer; + + + + + aVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR ); + + aVgRenderer->vgSetColor( aFillPaint, flatColor << 8 | opacity ); + + aVgRenderer->vgSetPaint( aFillPaint, VG_FILL_PATH ); + + } + + +// ========================================================================== +// Linear Gradient Constructor +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxLinearGradientPaint::TGfxLinearGradientPaint():TGfxGradientPaint(), +// --------------------------------------------------------------------------- + TGfxLinearGradientPaint::TGfxLinearGradientPaint():TGfxGradientPaint(), + iX1(0), + iY1(0), + iX2(1), + iY2(0) + { + } + +// -------------------------------------------------------------------------- +// void TGfxColor::SetFill(VGPaint aFillPaint) +// --------------------------------------------------------------------------- + + void TGfxLinearGradientPaint::SetFill(VGPaint aFillPaint, TGfxRectangle2D& aBBox, TFloatFixPt aOpacity,void* aPseudo) + { + const TFloatFixPt KInverse255 = TFloatFixPt( 1.0f / 255.0f ); + + CVGRenderer *iVgRenderer=(CVGRenderer*) aPseudo; + VGint colorRamp = VG_COLOR_RAMP_SPREAD_PAD; // default value + VGfloat offsetVal = 0.0f; + VGfloat rVal = 0.0f; + VGfloat gVal = 0.0f; + VGfloat bVal = 0.0f; + + VGfloat fX0 = 0.0f; + VGfloat fY0 = 0.0f; + VGfloat fX1 = 0.0f; + VGfloat fY1 = 0.0f; + + iVgRenderer->vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); + //vgLoadIdentity(); + + // need to determine the gradient units... determines how the gradient is applied. + if(iGradientUnits==KobjectBoundingBox) + { + /* + fX0 = (VGfloat)( aBBox.iX + ( aBBox.iWidth * iX1 ) ); + fY0 = (VGfloat)( aBBox.iY + ( aBBox.iHeight* iY1 ) ); + fX1 = (VGfloat)( aBBox.iX + ( aBBox.iWidth * iX2 ) ); + fY1 = (VGfloat)( aBBox.iY + ( aBBox.iHeight* iY2 ) ); + */ + fX0 = (VGfloat)( iX1 ); + fY0 = (VGfloat)( iY1 ); + fX1 = (VGfloat)( iX2 ); + fY1 = (VGfloat)( iY2 ); + + VGfloat gradientTrMatrix[] = + { svgFixedToFloat(iGradientTransform.matrix[0][0]) , svgFixedToFloat(iGradientTransform.matrix[1][0]), 0, + svgFixedToFloat(iGradientTransform.matrix[0][1]) , svgFixedToFloat(iGradientTransform.matrix[1][1]), 0, + svgFixedToFloat(iGradientTransform.matrix[0][2]) , svgFixedToFloat(iGradientTransform.matrix[1][2]), 1 }; + + VGfloat boundsMatrix[] = + { svgFixedToFloat(aBBox.iWidth.iValue) , 0, 0, + 0 , svgFixedToFloat(aBBox.iHeight.iValue), 0, + svgFixedToFloat(aBBox.iX.iValue) , svgFixedToFloat(aBBox.iY.iValue), 1 }; + + iVgRenderer->vgLoadMatrix(boundsMatrix); + iVgRenderer->vgMultMatrix(gradientTrMatrix); + + } + else //KuserSpaceOnUse + { + fX0 = (VGfloat)iX1; + fY0 = (VGfloat)iY1; + fX1 = (VGfloat)iX2; + fY1 = (VGfloat)iY2; + VGfloat gradientMatrix[] = + { svgFixedToFloat(iGradientTransform.matrix[0][0]) , svgFixedToFloat(iGradientTransform.matrix[1][0]), 0, + svgFixedToFloat(iGradientTransform.matrix[0][1]) , svgFixedToFloat(iGradientTransform.matrix[1][1]), 0, + svgFixedToFloat(iGradientTransform.matrix[0][2]) , svgFixedToFloat(iGradientTransform.matrix[1][2]), 1 }; + + iVgRenderer->vgLoadMatrix(gradientMatrix); + } + + // format { x0, y0, x1, y1} + VGfloat gradient[4] = { fX0, fY0, fX1, fY1 }; + + if (!iStopData) + return; + + TInt stopCount = iStopData->Count(); + + + + //If no 'stop' elements are defined, then painting shall occur as if + + //none were specified as the paint style. + + if(0 == stopCount) + { + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR ); + VGfloat colorRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f}; + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_COLOR, 4, colorRGBA); + iVgRenderer->vgSetPaint( aFillPaint, VG_FILL_PATH ); + return ; + } + // If one 'stop' is defined, then painting shall occur with the solid + // color fill using the color defined for that gradient stop. + else if(1 == stopCount) + { + VGfloat colorRGBA[4]; + TInt col,r,g,b; + VGfloat alpha; + + col = iStopData->operator[](0).iStopColor; + alpha = (VGfloat)iStopData->operator[](0).iStopOpacity; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + colorRGBA[0] = (VGfloat)(TFloatFixPt( r ) * KInverse255); + colorRGBA[1] = (VGfloat)(TFloatFixPt( g ) * KInverse255); + colorRGBA[2] = (VGfloat)(TFloatFixPt( b ) * KInverse255); + colorRGBA[3] = alpha * (VGfloat)aOpacity; + + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR ); + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_COLOR, 4, colorRGBA); + iVgRenderer->vgSetPaint( aFillPaint, VG_FILL_PATH ); + return ; + } + else if(stopCount > 0) + { + + // Check if X1=X2 and Y1=Y2 , then the painting shall occur with the solid + // color fill using the color defined in the last gradient stop. + if( ( iX1 == iX2 ) && ( iY1 == iY2 ) && ( iGradientUnits == KuserSpaceOnUse) ) + { + VGfloat colorRGBA[4]; + TInt col,r,g,b; + VGfloat alpha; + + col = iStopData->operator[]( stopCount - 1 ).iStopColor; + alpha = (VGfloat)iStopData->operator[]( stopCount - 1 ).iStopOpacity; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + colorRGBA[0] = (VGfloat)(TFloatFixPt( r ) * KInverse255); + colorRGBA[1] = (VGfloat)(TFloatFixPt( g ) * KInverse255); + colorRGBA[2] = (VGfloat)(TFloatFixPt( b ) * KInverse255); + colorRGBA[3] = alpha * (VGfloat)aOpacity; + + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR ); + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_COLOR, 4, colorRGBA); + iVgRenderer->vgSetPaint( aFillPaint, VG_FILL_PATH ); + return ; + } + // Using non-ELeave version and checking for NULL to avoid (ELeave) and TRAP + VGfloat *stops = new VGfloat [(stopCount+2)*5]; + if ( !stops ) + { + return; + } + + VGfloat *lclStop = stops; + + TInt i=0; + + TInt col,r,g,b; + VGfloat alpha = 0.0f; + TInt additionalStopsAdded = 0; + + if( iStopData->operator[](0).iOffset != TFloatFixPt(0) ) + { + //if the first stop didn't have an offset == 0 then we need to force a zero on it + //for safety in OpenVG and VGR + *lclStop++ = 0.0f; + col = iStopData->operator[](0).iStopColor; + alpha = (VGfloat)iStopData->operator[](0).iStopOpacity; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + rVal = (VGfloat)(TFloatFixPt( r ) * KInverse255); + *lclStop++ = rVal; + + gVal = (VGfloat)(TFloatFixPt( g ) * KInverse255); + *lclStop++ = gVal; + + bVal = (VGfloat)(TFloatFixPt( b ) * KInverse255); + *lclStop++ = bVal; + + *lclStop++ = alpha * (VGfloat)aOpacity; + additionalStopsAdded++; + } + + for( ; i < stopCount; i++) + { + offsetVal = (VGfloat)(iStopData->operator[](i).iOffset); + *lclStop++ = offsetVal; + + col = iStopData->operator[](i).iStopColor; + alpha = (VGfloat)iStopData->operator[](i).iStopOpacity; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + rVal = (VGfloat)(TFloatFixPt( r ) * KInverse255); + *lclStop++ = rVal; + + gVal = (VGfloat)(TFloatFixPt( g ) * KInverse255); + *lclStop++ = gVal; + + bVal = (VGfloat)(TFloatFixPt( b ) * KInverse255); + *lclStop++ = bVal; + + *lclStop++ = alpha * (VGfloat)aOpacity; + } + + if (offsetVal != 1.0f) + { + //if the last stop didn't have an offset == 1 then we need to force one on it + //for safety in OpenVG and VGR + *lclStop++ = 1.0f; + col = iStopData->operator[](i-1).iStopColor; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + rVal = (VGfloat)(TFloatFixPt( r ) * KInverse255); + *lclStop++ = rVal; + + gVal = (VGfloat)(TFloatFixPt( g ) * KInverse255); + *lclStop++ = gVal; + + bVal = (VGfloat)(TFloatFixPt( b ) * KInverse255); + *lclStop++ = bVal; + + *lclStop++ = alpha * (VGfloat)aOpacity; + additionalStopsAdded++; + } + + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_COLOR_RAMP_STOPS, (stopCount+additionalStopsAdded)*5, stops ); + delete [] stops; + } + + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT ); + + if(iSpreadMethod==KspreadMethodReflect) + { + colorRamp = VG_COLOR_RAMP_SPREAD_REFLECT; + } + else if(iSpreadMethod==KspreadMethodRepeat) + { + colorRamp = VG_COLOR_RAMP_SPREAD_REPEAT; + } + + + + + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, colorRamp ); + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_LINEAR_GRADIENT, 4, gradient); + iVgRenderer->vgSetPaint( aFillPaint, VG_FILL_PATH ); + } + +// ========================================================================== +// Radial Gradient Constructor +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxRadialGradientPaint::TGfxRadialGradientPaint():TGfxGradientPaint(), +// --------------------------------------------------------------------------- + TGfxRadialGradientPaint::TGfxRadialGradientPaint():TGfxGradientPaint(), + iCx(TReal32(0.5)), + iCy(TReal32(0.5)), + iR(TReal32(0.5)), + iFx( KMAXFLOATFIX ), + iFy( KMAXFLOATFIX ) + +// iFx(0x7fff), +// iFy(0x7fff) +// iFx(1e38), +// iFy(1e38) + + { + } + + + +// -------------------------------------------------------------------------- +// void TGfxColor::SetFill(VGPaint aFillPaint) +// --------------------------------------------------------------------------- + + void TGfxRadialGradientPaint::SetFill(VGPaint aFillPaint, TGfxRectangle2D& aBBox, TFloatFixPt aOpacity,void* aPseudo) + { + const TFloatFixPt KInverse255 = TFloatFixPt( 1.0f / 255.0f ); + CVGRenderer *iVgRenderer=(CVGRenderer*) aPseudo; + VGint colorRamp = VG_COLOR_RAMP_SPREAD_PAD; // default value + + //TGfxRectangle2D lBox = aBBox; + TFloatFixPt invalid(KMAXFLOATFIX); + VGfloat offsetVal = 0.0f; + VGfloat rVal = 0.0f; + VGfloat gVal = 0.0f; + VGfloat bVal = 0.0f; + VGfloat fCx = 0.0f; + VGfloat fCy = 0.0f; + VGfloat fR = 0.0f; + VGfloat fFx = 0.0f; + VGfloat fFy = 0.0f; + + + iVgRenderer->vgSeti(VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); + //vgLoadIdentity(); + + if(iGradientUnits==KobjectBoundingBox) + { + fCx = (VGfloat)iCx; + fCy = (VGfloat)iCy; + + fR = (VGfloat)iR; + + fFx = (VGfloat)iFx; + if(iFx == invalid) + fFx = fCx; //Fx was not set + else + fFx = (VGfloat)iFx; + + fFy = (VGfloat)iFy; + if(iFy == invalid) + fFy = fCy; //Fy was not set + else + fFy = (VGfloat)iFy; + VGfloat gradientTrMatrix[] = + { svgFixedToFloat(iGradientTransform.matrix[0][0]) , svgFixedToFloat(iGradientTransform.matrix[1][0]), 0, + svgFixedToFloat(iGradientTransform.matrix[0][1]) , svgFixedToFloat(iGradientTransform.matrix[1][1]), 0, + svgFixedToFloat(iGradientTransform.matrix[0][2]) , svgFixedToFloat(iGradientTransform.matrix[1][2]), 1 }; + + VGfloat boundsMatrix[] = + { svgFixedToFloat(aBBox.iWidth.iValue) , 0, 0, + 0 , svgFixedToFloat(aBBox.iHeight.iValue), 0, + svgFixedToFloat(aBBox.iX.iValue) , svgFixedToFloat(aBBox.iY.iValue), 1 }; + + iVgRenderer->vgLoadMatrix(boundsMatrix); + iVgRenderer->vgMultMatrix(gradientTrMatrix); + + } + else //if(iGradientUnits==KuserSpaceOnUse) + { + // values are user defined coordinates + fCx = (VGfloat)iCx; + fCy = (VGfloat)iCy; + + fR = (VGfloat)iR; + + fFx = (VGfloat)iFx; + if(iFx == invalid) + fFx = fCx; //Fx was not set + else + fFx = (VGfloat)iFx; + + fFy = (VGfloat)iFy; + if(iFy == invalid) + fFy = fCy; //Fy was not set + else + fFy = (VGfloat)iFy; + + VGfloat gradientMatrix[] = + { svgFixedToFloat(iGradientTransform.matrix[0][0]) , svgFixedToFloat(iGradientTransform.matrix[1][0]), 0, + svgFixedToFloat(iGradientTransform.matrix[0][1]) , svgFixedToFloat(iGradientTransform.matrix[1][1]), 0, + svgFixedToFloat(iGradientTransform.matrix[0][2]) , svgFixedToFloat(iGradientTransform.matrix[1][2]), 1 }; + iVgRenderer->vgLoadMatrix(gradientMatrix); + } + + // format { cx, cy, fx, fy, r} + VGfloat gradient[5] = { fCx, fCy, fFx, fFy, fR}; + + if (!iStopData) + return; + + + + + TInt stopCount = iStopData->Count(); + + //If no 'stop' elements are defined, then painting shall occur as if + //none were specified as the paint style. + if(0 == stopCount) + { + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR ); + VGfloat colorRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f}; + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_COLOR, 4, colorRGBA); + iVgRenderer->vgSetPaint( aFillPaint, VG_FILL_PATH ); + return ; + } + // If one 'stop' is defined, then painting shall occur with the solid + // color fill using the color defined for that gradient stop. + else if(1 == stopCount) + { + VGfloat colorRGBA[4]; + TInt col,r,g,b; + VGfloat alpha=0.0f; + + col = iStopData->operator[](0).iStopColor; + alpha = (VGfloat)iStopData->operator[](0).iStopOpacity; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + colorRGBA[0] = (VGfloat)(TFloatFixPt( r ) * KInverse255); + colorRGBA[1] = (VGfloat)(TFloatFixPt( g ) * KInverse255); + colorRGBA[2] = (VGfloat)(TFloatFixPt( b ) * KInverse255); + colorRGBA[3] = alpha * (VGfloat)aOpacity; + + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR ); + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_COLOR, 4, colorRGBA); + iVgRenderer->vgSetPaint( aFillPaint, VG_FILL_PATH ); + return ; + } + else if(stopCount > 0) + { + // Using non-ELeave version and checking for NULL to avoid (ELeave) and TRAP + VGfloat *stops = new VGfloat [(stopCount+2)*5]; + if ( !stops ) + { + return; + } + + VGfloat *lclStop = stops; + + TInt i=0; + TInt col,r,g,b; + VGfloat alpha; + TInt additionalStopsAdded = 0; + + if( iStopData->operator[](0).iOffset != TFloatFixPt(0) ) + { + //if the first stop didn't have an offset == 0 then we need to force a zero on it + //for safety in OpenVG and VGR + *lclStop++ = 0.0f; + col = iStopData->operator[](0).iStopColor; + alpha = (VGfloat)iStopData->operator[](0).iStopOpacity; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + rVal = (VGfloat)(TFloatFixPt( r ) * KInverse255); + *lclStop++ = rVal; + + gVal = (VGfloat)(TFloatFixPt( g )* KInverse255); + *lclStop++ = gVal; + + bVal = (VGfloat)(TFloatFixPt( b ) * KInverse255); + *lclStop++ = bVal; + + *lclStop++ = alpha * (VGfloat)aOpacity; + additionalStopsAdded++; + + } + for( ; i < stopCount; i++) + { + offsetVal = (VGfloat)(iStopData->operator[](i).iOffset); + *lclStop++ = offsetVal; + + col = iStopData->operator[](i).iStopColor; + alpha = (VGfloat)iStopData->operator[](i).iStopOpacity; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + rVal = (VGfloat)(TFloatFixPt( r ) * KInverse255); + *lclStop++ = rVal; + + gVal = (VGfloat)(TFloatFixPt( g ) * KInverse255); + *lclStop++ = gVal; + + bVal = (VGfloat)(TFloatFixPt( b ) * KInverse255); + *lclStop++ = bVal; + + *lclStop++ = alpha * (VGfloat)aOpacity; + } + + if (offsetVal != 1.0f) + { + //if the last stop didn't have an offset == 1 then we need to force one on it + //for safety in OpenVG and VGR + *lclStop++ = 1.0f; + col = iStopData->operator[](i-1).iStopColor; + alpha = (VGfloat)iStopData->operator[](i-1).iStopOpacity; + r = (col & 0x00ff0000)>>16; + g = (col & 0x0000ff00)>>8; + b = (col & 0x000000ff); + + rVal = (VGfloat)(TFloatFixPt( r ) * KInverse255); + *lclStop++ = rVal; + + gVal = (VGfloat)(TFloatFixPt( g ) * KInverse255); + *lclStop++ = gVal; + + bVal = (VGfloat)(TFloatFixPt( b ) * KInverse255); + *lclStop++ = bVal; + + *lclStop++ = alpha * (VGfloat)aOpacity; + additionalStopsAdded++; + } + + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_COLOR_RAMP_STOPS, (stopCount+additionalStopsAdded)*5, stops ); + delete [] stops; + } + + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT ); + + if(iSpreadMethod==KspreadMethodReflect) + { + colorRamp = VG_COLOR_RAMP_SPREAD_REFLECT; + } + else if(iSpreadMethod==KspreadMethodRepeat) + { + colorRamp = VG_COLOR_RAMP_SPREAD_REPEAT; + } + + + iVgRenderer->vgSetParameteri( aFillPaint, VG_PAINT_COLOR_RAMP_SPREAD_MODE, colorRamp ); + iVgRenderer->vgSetParameterfv( aFillPaint, VG_PAINT_RADIAL_GRADIENT, 5, gradient); + iVgRenderer->vgSetPaint( aFillPaint, VG_FILL_PATH ); + }