diff -r 000000000000 -r d46562c3d99d svgtopt/gfx2d/src/GfxGeom/GfxAffineTransform.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtopt/gfx2d/src/GfxGeom/GfxAffineTransform.cpp Thu Jan 07 16:19:02 2010 +0200 @@ -0,0 +1,733 @@ +/* +* 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 "GfxAffineTransform.h" + +#include "GfxGeneralPath.h" +#include "Gfxtrignometric.h" + +#include "e32debug.h" + +// ========================================================================== +// Notes: +// +// [ x'] [ m00 m01 m02 ] [ x ] [ m00x + m01y + m02 ] +// [ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ] +// [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ] +// +// ========================================================================== + +// ========================================================================== +// Constructor +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxAffineTransform::TGfxAffineTransform() +// --------------------------------------------------------------------------- + TGfxAffineTransform::TGfxAffineTransform() + :iM00(KFloatFixOne), + iM10(KFloatFixZero), + iM01(KFloatFixZero), + iM11(KFloatFixOne), + iM02(KFloatFixZero), + iM12(KFloatFixZero) + { + iTransType = KTransformIdentity; + } + + +// ========================================================================== +// Constructor with elements +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxAffineTransform::TGfxAffineTransform( TReal32 aM00, +// --------------------------------------------------------------------------- + TGfxAffineTransform::TGfxAffineTransform( TReal32 aM00, + TReal32 aM10, + TReal32 aM01, + TReal32 aM11, + TReal32 aM02, + TReal32 aM12 ) + { + SetTransform( aM00, aM10, aM01, aM11, aM02, aM12 ); + } + +// -------------------------------------------------------------------------- +// TGfxAffineTransform::TGfxAffineTransform( TReal32 aM00, +// --------------------------------------------------------------------------- +TGfxAffineTransform::TGfxAffineTransform( TReal32 aM00, + TReal32 aM10, + TReal32 aM01, + TReal32 aM11, + TReal32 aM02, + TReal32 aM12, + TGfxTransformType aType ) + :iM00(aM00), + iM10(aM10), + iM01(aM01), + iM11(aM11), + iM02(aM02), + iM12(aM12) + { + iTransType = aType; + } + +// ========================================================================== +// Generally used instance creation: Rotation matrix +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxAffineTransform TGfxAffineTransform::GetRotateInstance( TReal32 aTheta ) +// --------------------------------------------------------------------------- + TGfxAffineTransform TGfxAffineTransform::GetRotateInstance( TReal32 aTheta ) + { + TGfxAffineTransform tmp; + tmp.SetToRotate( aTheta ); + return tmp; + } + +// ========================================================================== +// Generally used instance creation: another Rotation matrix +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxAffineTransform TGfxAffineTransform::GetRotateInstance( TReal32 aTheta, +// --------------------------------------------------------------------------- + TGfxAffineTransform TGfxAffineTransform::GetRotateInstance( TReal32 aTheta, + const TFloatFixPt& aX, + const TFloatFixPt& aY ) + { + TGfxAffineTransform tmp; + tmp.SetToRotate( aTheta ); + + TFloatFixPt x = aX; + TFloatFixPt y = aY; + TFloatFixPt KOne( KFloatFixOne ); + tmp.iM02 = x * ( KOne - tmp.iM00 ) + y * tmp.iM10; + tmp.iM12 = y * ( KOne - tmp.iM00 ) - x * tmp.iM10; + tmp.iTransType |= KTransformTranslate; + return tmp; + } + +// ========================================================================== +// Added Zoom Instance for better calculation +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxAffineTransform TGfxAffineTransform::GetZoomInstance( sf,ax,ay); +// --------------------------------------------------------------------------- + TGfxAffineTransform TGfxAffineTransform::GetZoomInstance( TReal32 aScaleFactor, + const TFloatFixPt& aX, + const TFloatFixPt& aY ) + { + TFloatFixPt KOne( KFloatFixOne ); + TGfxAffineTransform tmp; + tmp.iM00 = aScaleFactor; + tmp.iM11 = aScaleFactor; + + TMatrixElType x = ( TMatrixElType ) aX; + TMatrixElType y = ( TMatrixElType ) aY; + tmp.iM02 = x * ( KOne - tmp.iM00 ); + tmp.iM12 = y * ( KOne - tmp.iM11 ); + tmp.iTransType |= KTransformTranslate | KTransformScale; + return tmp; + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::SetToRotate( TReal32 aTheta ) +// --------------------------------------------------------------------------- +void TGfxAffineTransform::SetToRotate( TReal32 aTheta ) + { + TFloatFixPt KZero; + #ifdef SVG_FLOAT_BUILD + TFloatFixPt cs = TFloatFixPt::CosFloatDouble( aTheta ); //(GfxMath::svgScalarCos((TInt32)(aTheta * TReal(0x10000)))); + TFloatFixPt sn = TFloatFixPt::SinFloatDouble( aTheta ); //(GfxMath::svgScalarSin((TInt32)(aTheta * TReal(0x10000)))); + #else + TFloatFixPt cs (GfxMath::svgScalarCos((TInt32)(aTheta * TReal(0x10000))), ETrue); + TFloatFixPt sn (GfxMath::svgScalarSin((TInt32)(aTheta * TReal(0x10000))), ETrue); + #endif + iM00 = cs; + iM10 = sn; + iM01 = KZero - sn; + iM11 = cs; + + iM02 = KZero; + iM12 = KZero; + iTransType = KTransformShear | KTransformScale; + } + +// ========================================================================== +// Generally used instance creation: Scale matrix +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxAffineTransform TGfxAffineTransform::GetScaleInstance( TReal32 aSx, +// --------------------------------------------------------------------------- + TGfxAffineTransform TGfxAffineTransform::GetScaleInstance( TReal32 aSx, + TReal32 aSy ) + { + return TGfxAffineTransform( ( TReal32 ) aSx, + 0.0f, + 0.0f, + ( TReal32 ) aSy, + 0.0f, + 0.0f, + KTransformScale ); + } + +// ========================================================================== +// Generally used instance creation: Shear matrix +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxAffineTransform TGfxAffineTransform::GetShearInstance( TReal32 aShx, +// --------------------------------------------------------------------------- + TGfxAffineTransform TGfxAffineTransform::GetShearInstance( TReal32 aShx, + TReal32 aShy ) + { + #ifdef SVG_FLOAT_BUILD + TFloatFixPt tnshx = TFloatFixPt::TanFloatDouble( aShx ); //(GfxMath::svgScalarTan(TInt(aShx*0x10000))); + TFloatFixPt tnshy = TFloatFixPt::TanFloatDouble( aShy ); //(GfxMath::svgScalarTan(TInt(aShy*0x10000))); + #else + TFloatFixPt tnshx(GfxMath::svgScalarTan(TInt(aShx*0x10000)), ETrue); + TFloatFixPt tnshy(GfxMath::svgScalarTan(TInt(aShy*0x10000)), ETrue); + #endif + + return TGfxAffineTransform( 1.0f, + TReal32(tnshy), + TReal32(tnshx), + 1.0f, + 0.0f, + 0.0f, + KTransformShear ); + } + + +// ========================================================================== +// Generally used instance creation: Translate matrix +// ========================================================================== +// -------------------------------------------------------------------------- +// TGfxAffineTransform TGfxAffineTransform::GetTranslateInstance( const TFixPt& aTx, +// --------------------------------------------------------------------------- + TGfxAffineTransform TGfxAffineTransform::GetTranslateInstance( const TFloatFixPt& aTx, + const TFloatFixPt& aTy ) + { + return TGfxAffineTransform( 1.0f, + 0.0f, + 0.0f, + 1.0f, + ( TReal32 ) aTx, + ( TReal32 ) aTy, + KTransformTranslate ); + } + +// -------------------------------------------------------------------------- +// TReal32 TGfxAffineTransform::Determinant() const +// --------------------------------------------------------------------------- + TReal32 TGfxAffineTransform::Determinant() const + { + return iM00 * iM11 - iM10 * iM01; + } + +// -------------------------------------------------------------------------- +// TBool TGfxAffineTransform::IsIdentity() const +// --------------------------------------------------------------------------- + TBool TGfxAffineTransform::IsIdentity() const + { + return ( (int)iTransType == KTransformIdentity ); + } + +// -------------------------------------------------------------------------- +// TReal32 TGfxAffineTransform::ScaleX() const +// --------------------------------------------------------------------------- + TReal32 TGfxAffineTransform::ScaleX() const + { + return iM00; + } + +// -------------------------------------------------------------------------- +// TReal32 TGfxAffineTransform::ScaleY() const +// --------------------------------------------------------------------------- + TReal32 TGfxAffineTransform::ScaleY() const + { + return iM11; + } + +// -------------------------------------------------------------------------- +// TReal32 TGfxAffineTransform::ShearX() const +// --------------------------------------------------------------------------- + TReal32 TGfxAffineTransform::ShearX() const + { + return iM01; + } + +// -------------------------------------------------------------------------- +// TReal32 TGfxAffineTransform::ShearY() const +// --------------------------------------------------------------------------- + TReal32 TGfxAffineTransform::ShearY() const + { + return iM10; + } + +// -------------------------------------------------------------------------- +// TReal32 TGfxAffineTransform::TranslateX() const +// --------------------------------------------------------------------------- + TReal32 TGfxAffineTransform::TranslateX() const + { + return iM02; + } + +// -------------------------------------------------------------------------- +// TReal32 TGfxAffineTransform::TranslateY() const +// --------------------------------------------------------------------------- + TReal32 TGfxAffineTransform::TranslateY() const + { + return iM12; + } + + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Concatenate( const TGfxAffineTransform& aTransform ) +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Concatenate( const TGfxAffineTransform& aTransform ) + { + + if ( IsIdentity() ) + { + iM00 = aTransform.iM00; + iM01 = aTransform.iM01; + iM02 = aTransform.iM02; + iM11 = aTransform.iM11; + iM10 = aTransform.iM10; + iM12 = aTransform.iM12; + iTransType = aTransform.iTransType; + } + else if ( aTransform.IsIdentity() ) + { + // Do nothing + } + else + { + TFloatFixPt m0, m1; + m0 = iM00; + m1 = iM01; + iM00 = aTransform.iM00 * m0 + aTransform.iM10 * m1; + iM01 = aTransform.iM01 * m0 + aTransform.iM11 * m1; + iM02 += aTransform.iM02 * m0 + aTransform.iM12 * m1; + m0 = iM10; + m1 = iM11; + iM11 = aTransform.iM01 * m0 + aTransform.iM11 * m1; + iM10 = aTransform.iM00 * m0 + aTransform.iM10 * m1; + iM12 += aTransform.iM02 * m0 + aTransform.iM12 * m1; + iTransType |= aTransform.iTransType; + } + } + +// -------------------------------------------------------------------------- +// TGfxAffineTransform TGfxAffineTransform::CreateInverse() +// --------------------------------------------------------------------------- + TGfxAffineTransform TGfxAffineTransform::CreateInverse() + { + TFloatFixPt KZero; + TFloatFixPt det = iM00* iM11 - iM01* iM10; + if ( det == KZero ) + return TGfxAffineTransform(); + else + { + #ifdef SVG_FLOAT_BUILD + TFloatFixPt idet = TFloatFixPt(1.0f) / det; + #else + TFloatFixPt idet = TFloatFixPt(0x10000,ETrue)/ det; + + #endif + return TGfxAffineTransform( iM11 * idet, + KZero - iM10 * idet, + KZero - iM01 * idet, + iM00 * idet, + ( iM01 * iM12 - iM11 * iM02 ) * idet, + ( iM10 * iM02 - iM00 * iM12 ) * idet ); + } + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Rotate( TReal32 aTheta ) +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Rotate( TReal32 aTheta ) + { + Concatenate( GetRotateInstance( aTheta ) ); + iTransType |= ( KTransformShear | KTransformScale ); + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Rotate( TReal32 aTheta, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Rotate( TReal32 aTheta, + const TFloatFixPt& aX, + const TFloatFixPt& aY ) + { + Concatenate( GetRotateInstance( aTheta, aX, aY ) ); + iTransType |= ( KTransformShear | KTransformScale | KTransformTranslate ); + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Scale( TReal32 aSx, TReal32 aSy ) +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Scale( TReal32 aSx, TReal32 aSy ) + { + Concatenate( GetScaleInstance( aSx, aSy ) ); + iTransType |= KTransformScale; + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Translate( const TFixPt& aTx, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Translate( const TFloatFixPt& aTx, + const TFloatFixPt& aTy ) + { + Concatenate( GetTranslateInstance( aTx, aTy ) ); + iTransType |= KTransformTranslate; + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Shear( TReal32 aShX, TReal32 aShY ) +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Shear( TReal32 aShX, TReal32 aShY ) + { + Concatenate( GetShearInstance( aShX, aShY ) ); + iTransType |= KTransformShear; + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::SetTransform( TReal32 aM00, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::SetTransform( TReal32 aM00, + TReal32 aM10, + TReal32 aM01, + TReal32 aM11, + TReal32 aM02, + TReal32 aM12 ) + { + iM00 = aM00; + iM01 = aM01; + iM02 = aM02; + iM10 = aM10; + iM11 = aM11; + iM12 = aM12; + UpdateState(); + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Transform( TGfxPoint2D* aSrcPts, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Transform( TGfxPoint2D* aSrcPts, + TGfxPoint2D* aDstPts, + TInt32 aNumPts ) const + { + + if ( (int)iTransType == KTransformIdentity ) + { + if ( aSrcPts != aDstPts ) + { + for ( TInt32 i = 0; i < aNumPts; i++ ) + { + aDstPts[i] = aSrcPts[i]; + } + } + return; + } + + if ( (int)iTransType == KTransformScale ) + { + for ( TInt32 i = 0; i < aNumPts; i++ ) + { + aDstPts[i].iX = aSrcPts[i].iX * iM00; + aDstPts[i].iY = aSrcPts[i].iY * iM11; + } + } + else if ( (int)iTransType == KTransformTranslate ) + { + for ( TInt32 i = 0; i < aNumPts; i++ ) + { + aDstPts[i].iX = aSrcPts[i].iX + iM02; + aDstPts[i].iY = aSrcPts[i].iY + iM12; + } + } + else if ( (int)iTransType == ( KTransformScale | KTransformTranslate ) ) + { + for ( TInt32 i = 0; i < aNumPts; i++ ) + { + aDstPts[i].iX = ( aSrcPts[i].iX * iM00 ) + iM02; + aDstPts[i].iY = ( aSrcPts[i].iY * iM11 ) + iM12; + } + } + else + { + TFloatFixPt x, y; + + for ( TInt32 i = 0; i < aNumPts; i++ ) + { + x = aSrcPts[i].iX; + y = aSrcPts[i].iY; + aDstPts[i].iX = ( iM00 * x ) + ( iM01 * y ) + iM02; + aDstPts[i].iY = ( iM10 * x ) + ( iM11 * y ) + iM12; + } + } + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Transform( TFixPt* aSrcPts, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Transform( TFloatFixPt* aSrcPts, + TFloatFixPt* aDstPts, + TInt32 aNumPts ) const + { + aNumPts <<= 1; + + if ( (int)iTransType == KTransformIdentity ) + { + if ( aSrcPts != aDstPts ) + { + for ( TInt32 i = 0; i < aNumPts; i++ ) + { + *aDstPts++ = *aSrcPts++; + *aDstPts++ = *aSrcPts++; + } + } + return; + } + + if ( (int)iTransType == KTransformScale ) + { + for ( TInt32 i = 0; i < aNumPts; i += 2 ) + { + *aDstPts++ = *aSrcPts++ * iM00; + *aDstPts++ = *aSrcPts++ * iM11; + } + } + else if ( (int)iTransType == KTransformTranslate ) + { + for ( TInt32 i = 0; i < aNumPts; i += 2 ) + { + *aDstPts++ = *aSrcPts++ + iM02; + *aDstPts++ = *aSrcPts++ + iM12; + } + } + else if ( (int)iTransType == ( KTransformScale | KTransformTranslate ) ) + { + for ( TInt32 i = 0; i < aNumPts; i += 2 ) + { + *aDstPts++ = ( *aSrcPts++ * iM00 ) + iM02; + *aDstPts++ = ( *aSrcPts++ * iM11 ) + iM12; + } + } + else + { + TFloatFixPt x, y; + + for ( TInt32 i = 0; i < aNumPts; i += 2 ) + { + x = *aSrcPts++; + y = *aSrcPts++; + *aDstPts++ = ( iM00 * x ) + ( iM01 * y ) + iM02; + *aDstPts++ = ( iM10 * x ) + ( iM11 * y ) + iM12; + } + } + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Transform( TFixPt* aSrcDstPts, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Transform( TFloatFixPt* aSrcDstPts, + TInt32 aNumPts ) const + { + if ( (int)iTransType == KTransformIdentity ) + return; + + aNumPts <<= 1; + + if ( (int)iTransType == KTransformScale ) + { + for ( TInt32 i = 0; i < aNumPts; i += 2 ) + { + *aSrcDstPts++ *= iM00; + *aSrcDstPts++ *= iM11; + } + } + else if ( (int)iTransType == KTransformTranslate ) + { + for ( TInt32 i = 0; i < aNumPts; i += 2 ) + { + *aSrcDstPts++ += iM02; + *aSrcDstPts++ += iM12; + } + } + else if ( (int)iTransType == ( KTransformScale | KTransformTranslate ) ) + { + for ( TInt32 i = 0; i < aNumPts; i += 2 ) + { + *aSrcDstPts *= iM00; + *aSrcDstPts++ += iM02; + *aSrcDstPts *= iM11; + *aSrcDstPts++ += iM12; + } + } + else + { + TFloatFixPt x, y; + + for ( TInt32 i = 0; i < aNumPts; i += 2 ) + { + x = *aSrcDstPts; + y = *( aSrcDstPts + 1 ); + *aSrcDstPts++ = ( iM00 * x ) + ( iM01 * y ) + iM02; + *aSrcDstPts++ = ( iM10 * x ) + ( iM11 * y ) + iM12; + } + } + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::UpdateState() +// --------------------------------------------------------------------------- +void TGfxAffineTransform::UpdateState() + { + TFloatFixPt KZero; + TFloatFixPt KOne( KFloatFixOne ); + iTransType = KTransformIdentity; + + if ( iM02 != KZero || iM12 != KZero ) + iTransType |= KTransformTranslate; + + if ( iM00 != KZero || iM11 != KZero ) + iTransType |= KTransformScale; + + if ( iM01 != KZero || iM10 != KZero ) + iTransType |= KTransformShear; + + if ( (int)iTransType == KTransformScale && iM00 == KOne && iM11 == KOne ) + iTransType = KTransformIdentity; + } + +// -------------------------------------------------------------------------- +// TUint32 TGfxAffineTransform::TransformType() +// --------------------------------------------------------------------------- +TUint32 TGfxAffineTransform::TransformType() + { + return iTransType; + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::Print() +// prints out the matrix +// --------------------------------------------------------------------------- + void TGfxAffineTransform::Print() +{ + RDebug::Printf("a=%f b=%f c=%f d=%f e=%f f=%f", (TReal32)iM00, (TReal32)iM10, (TReal32)iM01, (TReal32)iM11, (TReal32)iM02, (TReal32)iM12); +} + +// -------------------------------------------------------------------------- +// Get the scaling factor set in this transform. This function returns correctly +// for a uniform scaling in both directions only. +// --------------------------------------------------------------------------- + TFloatFixPt TGfxAffineTransform::ScalingFactor() const +{ + TGfxPoint2D ep( 1, 0 ), org( 2, 0 ); + Transform( &ep, & ep, 1 ); + Transform( &org, & org, 1 ); + ep.iX -= org.iX; + ep.iY -= org.iY; + return TFloatFixPt::Sqrt( ep.iX * ep.iX + ep.iY * ep.iY ); +} + + + +// -------------------------------------------------------------------------- +// +// Appends this transform with the existing transform +// Multiply in reverse order +// For Ex: In cases of zoom, rotate and pan of already transformed content. +// If T is the existing transform and zoom operation has to be applied to it +// the resultant transform would be Z*T. +// +// void TGfxAffineTransform::AppendTransform( const TGfxAffineTransform& aTransform ) +// --------------------------------------------------------------------------- + void TGfxAffineTransform::AppendTransform( const TGfxAffineTransform& aTransform ) + { + + if ( IsIdentity() ) + { + iM00 = aTransform.iM00; + iM01 = aTransform.iM01; + iM02 = aTransform.iM02; + iM11 = aTransform.iM11; + iM10 = aTransform.iM10; + iM12 = aTransform.iM12; + iTransType = aTransform.iTransType; + } + else if ( aTransform.IsIdentity() ) + { + // Do nothing + } + else + { + TMatrixElType m00, m01,m02,m10,m11,m12; + m00 = iM00; + m01 = iM01; + m02 = iM02; + m10 = iM10; + m11 = iM11; + m12 = iM12; + iM00 = aTransform.iM00 * m00 + aTransform.iM01 * m10; + iM01 = aTransform.iM00 * m01 + aTransform.iM01 * m11; + iM02 = aTransform.iM00 * m02 + aTransform.iM01 * m12 + aTransform.iM02; + + iM10 = aTransform.iM10 * m00 + aTransform.iM11 * m10; + iM11 = aTransform.iM10 * m01 + aTransform.iM11 * m11; + iM12 = aTransform.iM10 * m02 + aTransform.iM11 * m12 + aTransform.iM12; + + iTransType |= aTransform.iTransType; + } + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::UserRoatate( TReal32 aTheta, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::UserRotate( TReal32 aTheta, + const TFloatFixPt& aX, + const TFloatFixPt& aY ) + { + AppendTransform( GetRotateInstance( aTheta, aX, aY ) ); + iTransType |= ( KTransformShear | KTransformScale | KTransformTranslate ); + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::UserZoom( TReal32 aScaleFactor, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::UserZoom( TReal32 aScaleFactor, + const TFloatFixPt& aX, + const TFloatFixPt& aY ) + { + AppendTransform( GetZoomInstance( aScaleFactor, aX, aY ) ); + iTransType |= ( KTransformScale | KTransformTranslate ); + } + +// -------------------------------------------------------------------------- +// void TGfxAffineTransform::UserPan( const TFloatFixPt& aTx, +// --------------------------------------------------------------------------- + void TGfxAffineTransform::UserPan( const TFloatFixPt& aTx, + const TFloatFixPt& aTy ) + { + AppendTransform( GetTranslateInstance( aTx, aTy ) ); + iTransType |= KTransformTranslate; + } + + +//