--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/gfx2d/src/GfxGeom/GfxFlatteningPathIterator.cpp Thu Jan 07 16:19:02 2010 +0200
@@ -0,0 +1,349 @@
+/*
+* 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 "GfxFlatteningPathIterator.h"
+#include "GfxShape.h"
+#include "GfxAffineTransform.h"
+
+
+// ---------------------------------------------------------------------------
+// Constructors
+// ---------------------------------------------------------------------------
+CGfxFlatteningPathIterator::CGfxFlatteningPathIterator( TInt32 aLimit )
+ : iIdx( 0 ),
+ iSegType( EGfxSegClose ),
+ iIsDone( EFalse ),
+ iLimit( aLimit )
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// Create a new instance.
+// ---------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// CGfxFlatteningPathIterator* CGfxFlatteningPathIterator::NewL( MGfxShape* aSrc,
+// ---------------------------------------------------------------------------
+ CGfxFlatteningPathIterator* CGfxFlatteningPathIterator::NewL( MGfxShape* aSrc,
+ TGfxAffineTransform* aAt,
+ TInt32 aLimit )
+ {
+ CGfxFlatteningPathIterator* self = new ( ELeave )
+ CGfxFlatteningPathIterator( aLimit );
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aSrc, aAt );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Second phase in constructing this object.
+// ---------------------------------------------------------------------------
+void CGfxFlatteningPathIterator::ConstructL( MGfxShape* aSrc,
+ TGfxAffineTransform* aAt )
+ {
+ aSrc->GetPathIteratorL( aAt, iSrc );
+ iCoords = new ( ELeave ) RArray<TFloatFixPt>( 10 );
+ iCoords->AppendL( NULL );
+ iCoords->Remove(0);
+ NextL();
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// CGfxFlatteningPathIterator::~CGfxFlatteningPathIterator()
+// ---------------------------------------------------------------------------
+ CGfxFlatteningPathIterator::~CGfxFlatteningPathIterator()
+ {
+ if ( iSrc )
+ {
+ delete iSrc;
+ iSrc = NULL;
+ }
+ if ( iCoords )
+ {
+ iCoords->Close();
+ delete iCoords;
+ iCoords = NULL;
+ }
+ }
+
+
+// --------------------------------------------------------------------------
+// TGfxSegType CGfxFlatteningPathIterator::CurrentSegment( TFloatFixPt* aCoords )
+// ---------------------------------------------------------------------------
+ TGfxSegType CGfxFlatteningPathIterator::CurrentSegment( TFloatFixPt* aCoords )
+ {
+ if ( iCoords->Count() > 0 && iCoords->Count() > iIdx )
+ {
+ aCoords[0] = ( *iCoords )[iIdx];
+ aCoords[1] = ( *iCoords )[iIdx + 1];
+ }
+
+ return iSegType;
+ }
+
+
+// --------------------------------------------------------------------------
+// TBool CGfxFlatteningPathIterator::IsDone()
+// ---------------------------------------------------------------------------
+ TBool CGfxFlatteningPathIterator::IsDone()
+ {
+ return iIsDone;
+ }
+
+
+// --------------------------------------------------------------------------
+// void CGfxFlatteningPathIterator::Next()
+// ---------------------------------------------------------------------------
+ void CGfxFlatteningPathIterator::NextL()
+ {
+ iIdx += 2;
+
+ if ( iCoords->Count() <= 0 || iCoords->Count() <= iIdx )
+ {
+ TFloatFixPt tmpcoords[6];
+ TInt i;
+
+ iCoords->Reset();
+ iIdx = 0;
+ if ( iSrc->IsDone() )
+ {
+ iIsDone = ETrue;
+ }
+ else
+ {
+ iSegType = iSrc->CurrentSegment( tmpcoords );
+ switch ( iSegType )
+ {
+ case EGfxSegMoveTo:
+ iLastX = tmpcoords[0];
+ iLastY = tmpcoords[1];
+ iCoords->AppendL( iLastX );
+ iCoords->AppendL( iLastY );
+ break;
+ case EGfxSegLineTo:
+ iLastX = tmpcoords[0];
+ iLastY = tmpcoords[1];
+ iCoords->AppendL( iLastX );
+ iCoords->AppendL( iLastY );
+ break;
+ case EGfxSegQuadTo:
+ iCoords->AppendL( iLastX );
+ iCoords->AppendL( iLastY );
+ iCoords->AppendL( tmpcoords[0] );
+ iCoords->AppendL( tmpcoords[1] );
+ iCoords->AppendL( tmpcoords[2] );
+ iCoords->AppendL( tmpcoords[3] );
+
+ for ( i = 0; i < iLimit; i++ )
+ CreateSubcurveQuadL( iCoords );
+ //CreateSubcurveQuad(iCoords);
+ //CreateSubcurveQuad(iCoords);
+ //CreateSubcurveQuad(iCoords);
+
+ iIdx = 2;
+ iLastX = tmpcoords[2];
+ iLastY = tmpcoords[3];
+ iSegType = EGfxSegLineTo;
+ break;
+ case EGfxSegCubicTo:
+ iCoords->AppendL( iLastX );
+ iCoords->AppendL( iLastY );
+ iCoords->AppendL( tmpcoords[0] );
+ iCoords->AppendL( tmpcoords[1] );
+ iCoords->AppendL( tmpcoords[2] );
+ iCoords->AppendL( tmpcoords[3] );
+ iCoords->AppendL( tmpcoords[4] );
+ iCoords->AppendL( tmpcoords[5] );
+
+ for ( i = 0; i < iLimit; i++ )
+ CreateSubcurveCubicL( iCoords );
+
+ iIdx = 2;
+ iLastX = tmpcoords[4];
+ iLastY = tmpcoords[5];
+ iSegType = EGfxSegLineTo;
+ break;
+ case EGfxSegClose: // (cdm)
+ iLastX = tmpcoords[0];
+ iLastY = tmpcoords[1];
+ iCoords->AppendL( iLastX );
+ iCoords->AppendL( iLastY );
+ break;
+
+ default:
+ break;
+ }
+ iSrc->NextL();
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// void CGfxFlatteningPathIterator::SetFlatness( TFloatFixPt& aFlatness )
+// ---------------------------------------------------------------------------
+ void CGfxFlatteningPathIterator::SetFlatness( TFloatFixPt& aFlatness )
+ {
+ iFlatness = aFlatness;
+ }
+
+// --------------------------------------------------------------------------
+// void CGfxFlatteningPathIterator::SetRecursionLimit( TInt32 aLimit )
+// ---------------------------------------------------------------------------
+ void CGfxFlatteningPathIterator::SetRecursionLimit( TInt32 aLimit )
+ {
+ iLimit = aLimit;
+ }
+
+// --------------------------------------------------------------------------
+// TFloatFixPt CGfxFlatteningPathIterator::Flatness()
+// ---------------------------------------------------------------------------
+ TFloatFixPt CGfxFlatteningPathIterator::Flatness()
+ {
+ return iFlatness;
+ }
+
+// --------------------------------------------------------------------------
+// TInt32 CGfxFlatteningPathIterator::RecursionLimit()
+// ---------------------------------------------------------------------------
+ TInt32 CGfxFlatteningPathIterator::RecursionLimit()
+ {
+ return iLimit;
+ }
+
+
+
+
+// --------------------------------------------------------------------------
+// void CGfxFlatteningPathIterator::CreateSubcurveQuad( RArray<TFloatFixPt>* aCtrlPoints )
+// ---------------------------------------------------------------------------
+void CGfxFlatteningPathIterator::CreateSubcurveQuadL( RArray<TFloatFixPt>* aCtrlPoints )
+ {
+ TInt32 ix = 0;
+ TFloatFixPt x0, y0, xm, ym, x1, y1;
+ TInt32 lCount;
+
+ while ( ix + 5 < aCtrlPoints->Count() )
+ {
+ lCount = ix;
+ x0 = ( *aCtrlPoints )[lCount++];
+ y0 = ( *aCtrlPoints )[lCount++];
+ xm = ( *aCtrlPoints )[lCount++];
+ ym = ( *aCtrlPoints )[lCount++];
+ x1 = ( *aCtrlPoints )[lCount++];
+ y1 = ( *aCtrlPoints )[lCount++];
+ #ifdef SVG_FLOAT_BUILD
+ x0 = ( x0 + xm ) * .5f;
+ y0 = ( y0 + ym ) * .5f;
+ x1 = ( x1 + xm ) * .5f;
+ y1 = ( y1 + ym ) * .5f;
+ xm = ( x0 + x1 ) * .5f;
+ ym = ( y0 + y1 ) * .5f;
+ #else
+ x0 = ( x0 + xm ) >> 1;
+ y0 = ( y0 + ym ) >> 1;
+ x1 = ( x1 + xm ) >> 1;
+ y1 = ( y1 + ym ) >> 1;
+ xm = ( x0 + x1 ) >> 1;
+ ym = ( y0 + y1 ) >> 1;
+ #endif
+ lCount=ix + 2;
+ ( *aCtrlPoints )[lCount] = xm;
+ ( *aCtrlPoints )[lCount + 1] = ym;
+ aCtrlPoints->InsertL( TFloatFixPt( x0 ), lCount++);
+ aCtrlPoints->InsertL( TFloatFixPt( y0 ), lCount );
+ aCtrlPoints->InsertL( TFloatFixPt( x1 ), ix + 6 );
+ aCtrlPoints->InsertL( TFloatFixPt( y1 ), ix + 7 );
+ ix += 8;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// void CGfxFlatteningPathIterator::CreateSubcurveCubic( RArray<TFloatFixPt>* aCtrlPoints )
+// ---------------------------------------------------------------------------
+void CGfxFlatteningPathIterator::CreateSubcurveCubicL( RArray<TFloatFixPt>* aCtrlPoints )
+ {
+ TInt32 ix = 0;
+ TFloatFixPt x0, y0, xm, ym, xm1, ym1, xm2, ym2, x1, y1;
+ TInt32 lCount;
+ while ( ix + 7 < aCtrlPoints->Count() )
+ {
+ lCount = ix;
+ x0 = ( *aCtrlPoints )[lCount++];
+ y0 = ( *aCtrlPoints )[lCount++];
+ xm1 = ( *aCtrlPoints )[lCount++];
+ ym1 = ( *aCtrlPoints )[lCount++];
+ xm2 = ( *aCtrlPoints )[lCount++];
+ ym2 = ( *aCtrlPoints )[lCount++];
+ x1 = ( *aCtrlPoints )[lCount++];
+ y1 = ( *aCtrlPoints )[lCount ];
+
+ #ifdef SVG_FLOAT_BUILD
+ x0 = ( x0 + xm1 ) * .5f;
+ y0 = ( y0 + ym1 ) * .5f;
+ x1 = ( x1 + xm2 ) * .5f;
+ y1 = ( y1 + ym2 ) * .5f;
+ xm = ( xm1 + xm2 ) * .5f;
+ ym = ( ym1 + ym2 ) * .5f;
+ xm1 = ( x0 + xm ) * .5f;
+ ym1 = ( y0 + ym ) * .5f;
+ xm2 = ( x1 + xm ) * .5f;
+ ym2 = ( y1 + ym ) * .5f;
+ xm = ( xm1 + xm2 ) * .5f;
+ ym = ( ym1 + ym2 ) * .5f;
+ #else
+ x0 = ( x0 + xm1 ) >> 1;
+ y0 = ( y0 + ym1 ) >> 1;
+ x1 = ( x1 + xm2 ) >> 1;
+ y1 = ( y1 + ym2 ) >> 1;
+ xm = ( xm1 + xm2 ) >> 1;
+ ym = ( ym1 + ym2 ) >> 1;
+ xm1 = ( x0 + xm ) >> 1;
+ ym1 = ( y0 + ym ) >> 1;
+ xm2 = ( x1 + xm ) >> 1;
+ ym2 = ( y1 + ym ) >> 1;
+ xm = ( xm1 + xm2 ) >> 1;
+ ym = ( ym1 + ym2 ) >> 1;
+ #endif
+ lCount=ix + 2;
+ ( *aCtrlPoints )[lCount++] = x0;
+ ( *aCtrlPoints )[lCount++] = y0;
+ ( *aCtrlPoints )[lCount++] = xm1;
+ ( *aCtrlPoints )[lCount++] = ym1;
+
+ aCtrlPoints->InsertL( TFloatFixPt( y1 ), lCount);
+ aCtrlPoints->InsertL( TFloatFixPt( x1 ), lCount );
+ aCtrlPoints->InsertL( TFloatFixPt( ym2 ), lCount );
+ aCtrlPoints->InsertL( TFloatFixPt( xm2 ), lCount );
+ aCtrlPoints->InsertL( TFloatFixPt( ym ), lCount );
+ aCtrlPoints->InsertL( TFloatFixPt( xm ), lCount );
+ ix += 12;
+ }
+ }
+
+
+// --------------------------------------------------------------------------
+// void CGfxFlatteningPathIterator::PolygonizeL( CGfxEdgeListP* /* aRenderer */, TInt /* aFlatness */ )
+// ---------------------------------------------------------------------------
+ void CGfxFlatteningPathIterator::PolygonizeL( CGfxEdgeListP* /* aRenderer */, TInt /* aFlatness */ )
+{
+}