svgtopt/gfx2d/src/GfxGeom/GfxFlatteningPathIterator.cpp
changeset 46 88edb906c587
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/gfx2d/src/GfxGeom/GfxFlatteningPathIterator.cpp	Wed Nov 03 18:56:10 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 */ )
+{
+}