ooo-build r11731 - in trunk: . patches/src680



Author: thorstenb
Date: Thu Feb 28 09:08:39 2008
New Revision: 11731
URL: http://svn.gnome.org/viewvc/ooo-build?rev=11731&view=rev

Log:
        * patches/src680/svg-import-basegfx.diff: added some amount of
        elliptical arc support.



Modified:
   trunk/ChangeLog
   trunk/patches/src680/svg-import-basegfx.diff

Modified: trunk/patches/src680/svg-import-basegfx.diff
==============================================================================
--- trunk/patches/src680/svg-import-basegfx.diff	(original)
+++ trunk/patches/src680/svg-import-basegfx.diff	Thu Feb 28 09:08:39 2008
@@ -43,9 +43,247 @@
  
  		// create 3d PolyPolygon from given 2d PolyPolygon. The given fZCoordinate is used to expand the
  		// third coordinate.
---- basegfx/source/polygon/b2dsvgpolypolygon.cxx	2008-02-24 11:25:04.000000000 +0100
-+++ basegfx/source/polygon/b2dsvgpolypolygon.cxx	2008-02-24 11:24:13.000000000 +0100
-@@ -665,6 +665,32 @@
+--- basegfx/source/polygon/b2dsvgpolypolygon.cxx	18 Jul 2007 11:07:24 -0000	1.7
++++ basegfx/source/polygon/b2dsvgpolypolygon.cxx	28 Feb 2008 08:57:11 -0000
+@@ -37,7 +37,9 @@
+ #include "precompiled_basegfx.hxx"
+ 
+ #include <basegfx/polygon/b2dpolypolygontools.hxx>
++#include <basegfx/polygon/b2dpolygontools.hxx>
+ #include <basegfx/polygon/b2dpolypolygon.hxx>
++#include <basegfx/matrix/b2dhommatrix.hxx>
+ 
+ #ifndef _RTL_USTRING_
+ #include <rtl/ustring.hxx>
+@@ -74,7 +76,7 @@
+                 }
+             }
+ 
+-            bool lcl_isOnNumberChar(const ::rtl::OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true)
++            inline bool lcl_isOnNumberChar(const ::rtl::OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true)
+             {
+                 const sal_Unicode aChar(rStr[nPos]);
+ 
+@@ -151,6 +153,37 @@
+                 return true;
+             }
+ 
++            bool lcl_importNumberAndSpaces(sal_Int32&                o_nRetval,
++                                           sal_Int32& 				io_rPos, 
++                                           const ::rtl::OUString& 	rStr, 
++                                           const sal_Int32 		nLen)
++            {
++                sal_Unicode aChar( rStr[io_rPos] );
++                ::rtl::OUStringBuffer sNumberString;
++
++                if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
++                {
++                    sNumberString.append(rStr[io_rPos]);
++                    aChar = rStr[++io_rPos];
++                }
++
++                while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
++                {
++                    sNumberString.append(rStr[io_rPos]);
++                    aChar = rStr[++io_rPos];
++                }
++
++                if(sNumberString.getLength())
++                {
++                    o_nRetval = sNumberString.makeStringAndClear().toInt32();
++                    lcl_skipSpacesAndCommas(io_rPos, rStr, nLen);
++
++                    return true;
++                }
++
++                return false;
++            }
++
+             void lcl_skipNumber(sal_Int32& 				io_rPos, 
+                                 const ::rtl::OUString& 	rStr, 
+                                 const sal_Int32 		nLen)
+@@ -623,24 +656,169 @@
+                         break;
+                     }
+ 
+-                    // #100617# not yet supported: elliptical arc
+-                    case 'A' :
+-                        // FALLTHROUGH intended
+                     case 'a' :
+                     {
+-                        OSL_ENSURE(false, "importFromSvgD(): non-interpreted tags in svg:d element (elliptical arc)!");
++                        bRelative = true;
++                        // FALLTHROUGH intended
++                    }
++                    case 'A' :
++                    {
+                         nPos++;
+                         lcl_skipSpaces(nPos, rSvgDStatement, nLen);
+ 
+                         while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
+                         {
+-                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
+-                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
+-                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
+-                            lcl_skipNumberAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
+-                            lcl_skipNumberAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
+-                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
+-                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
++                            double nX, nY;
++                            double fRX, fRY, fPhi;
++                            sal_Int32 bLargeArcFlag, bSweepFlag;
++
++                            if(!lcl_importDoubleAndSpaces(fRX, nPos, rSvgDStatement, nLen)) return false;
++                            if(!lcl_importDoubleAndSpaces(fRY, nPos, rSvgDStatement, nLen)) return false;
++                            if(!lcl_importDoubleAndSpaces(fPhi, nPos, rSvgDStatement, nLen)) return false;
++                            if(!lcl_importNumberAndSpaces(bLargeArcFlag, nPos, rSvgDStatement, nLen)) return false;
++                            if(!lcl_importNumberAndSpaces(bSweepFlag, nPos, rSvgDStatement, nLen)) return false;
++                            if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
++                            if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
++
++                            if(bRelative)
++                            {
++                                nX += nLastX;
++                                nY += nLastY;
++                            }
++
++							const B2DPoint aPrevPoint(aCurrPoly.getB2DPoint(aCurrPoly.count() - 1));
++
++                            if( nX == nLastX && nY == nLastY )
++                                continue; // start==end -> skip according to SVG spec
++
++                            if( fRX == 0.0 || fRY == 0.0 )
++                            {
++                                // straight line segment according to SVG spec
++                                aCurrPoly.append(B2DPoint(nX, nY));
++                            }
++                            else
++                            {
++                                // normalize according to SVG spec
++                                fRX=fabs(fRX); fRY=fabs(fRY);
++                                
++                                // from the SVG spec, appendix F.6.4
++
++                                // |x1'|   |cos phi   sin phi|  |(x1 - x2)/2|
++                                // |y1'| = |-sin phi  cos phi|  |(y1 - y2)/2|
++                                const B2DPoint p1(nLastX, nLastY);
++                                const B2DPoint p2(nX, nY);
++                                B2DHomMatrix aRotate; aRotate.rotate(-fPhi*M_PI/180);
++                                
++                                const B2DPoint p1_prime( aRotate * B2DPoint(((p1-p2)/2.0)) );
++
++                                //           ______________________________________       rx y1'
++                                // |cx'|  + /  rx^2 ry^2 - rx^2 y1'^2 - ry^2 x1^2           ry
++                                // |cy'| =-/       rx^2y1'^2 + ry^2 x1'^2               - ry x1' 
++                                //                                                          rx
++                                // chose + if f_A != f_S
++                                // chose - if f_A  = f_S
++                                B2DPoint aCenter_prime;
++                                const double fRadicant(
++                                    (fRX*fRX*fRY*fRY - fRX*fRX*p1_prime.getY()*p1_prime.getY() - fRY*fRY*p1_prime.getX()*p1_prime.getX())/
++                                    (fRX*fRX*p1_prime.getY()*p1_prime.getY() + fRY*fRY*p1_prime.getX()*p1_prime.getX()));
++                                if( fRadicant < 0.0 )
++                                {
++                                    // no solution - according to SVG
++                                    // spec, scale up ellipse
++                                    // uniformly such that it passes
++                                    // through end points (denominator
++                                    // of radicant solved for fRY,
++                                    // with s=fRX/fRY)
++                                    const double fRatio(fRX/fRY);
++                                    const double fRadicant2(
++                                        p1_prime.getY()*p1_prime.getY() - 
++                                        p1_prime.getX()*p1_prime.getX()/(fRatio*fRatio));
++                                    if( fRadicant2 < 0.0 )
++                                    {
++                                        // only trivial solution, one
++                                        // of the axes 0 -> straight
++                                        // line segment according to
++                                        // SVG spec
++                                        aCurrPoly.append(B2DPoint(nX, nY));
++                                        continue;
++                                    }
++                                    
++                                    fRY=sqrt(fRadicant2);
++                                    fRX=fRatio*fRY;
++
++                                    // keep center_prime forced to (0,0)
++                                }
++                                else
++                                {
++                                    const double fFactor(
++                                        (bLargeArcFlag==bSweepFlag) ? -1.0 : 1.0 *
++                                        sqrt((fRX*fRX*fRY*fRY - fRX*fRX*p1_prime.getY()*p1_prime.getY() - fRY*fRY*p1_prime.getX()*p1_prime.getX())/
++                                             (fRX*fRX*p1_prime.getY()*p1_prime.getY() + fRY*fRY*p1_prime.getX()*p1_prime.getX())));
++
++                                    // actually calculate center_prime
++                                    aCenter_prime = B2DPoint(
++                                        fFactor*fRX*p1_prime.getY()/fRY,
++                                        -fFactor*fRY*p1_prime.getX()/fRX);
++                                }
++
++                                // |cx|   | cos phi  -sin phi |  | cx' |    (x1+x2)/2
++                                // |cy| = | sin phi   cos phi |  | cy' | +  (y1+y2)/2 
++                                aRotate.identity(); aRotate.rotate(fPhi*M_PI/180);
++                                const B2DPoint aCenter( aRotate * aCenter_prime + 
++                                                        (p1+p2)/2.0);
++                                
++                                //              +           u - v 
++                                // angle(u,v) =  arccos( ------------ )     (take the sign of (ux vy - uy vx))
++                                //              -        ||u|| ||v||
++
++                                //                  1    | (x1' - cx')/rx |
++                                // theta1 = angle((   ), |                | )
++                                //                  0    | (y1' - cy')/ry |
++                                const B2DPoint aRadii(fRX,fRY);
++                                double fTheta1( 
++                                    B2DVector(1.0,0.0).angle(
++                                        (p1_prime-aCenter_prime)/aRadii));
++
++                                //                 |1|    |  (-x1' - cx')/rx |
++                                // theta2 = angle( | | ,  |                  | )
++                                //                 |0|    |  (-y1' - cy')/ry |
++                                double fTheta2( 
++                                    B2DVector(1.0,0.0).angle(
++                                        (-p1_prime-aCenter_prime)/aRadii));
++
++                                // map both angles to [0,2pi)
++                                fTheta1 = fmod(2*M_PI+fTheta1,2*M_PI);
++                                fTheta2 = fmod(2*M_PI+fTheta2,2*M_PI);
++
++                                // make sure the large arc is taken
++                                // (since
++                                // createPolygonFromEllipseSegment()
++                                // normalizes to e.g. cw arc)
++                                const bool bFlipSegment( (bLargeArcFlag!=0) == 
++                                    (fmod(fTheta2+2*M_PI-fTheta1,
++                                          2*M_PI)<M_PI) );
++                                if( bFlipSegment )
++                                    std::swap(fTheta1,fTheta2);
++
++                                // finally, create bezier polygon from this
++                                B2DPolygon aSegment(
++                                    tools::createPolygonFromEllipseSegment( 
++                                        aCenter,
++                                        fRX,fRY,
++                                        fTheta1, fTheta2 ));
++
++                                // createPolygonFromEllipseSegment()
++                                // always creates arcs that are
++                                // positively oriented - flip polygon
++                                // if we swapped angles above
++                                if( bFlipSegment )
++                                    aSegment.flip();
++                                aCurrPoly.append(aSegment);
++                            }
++
++                            // set last position
++                            nLastX = nX;
++                            nLastY = nY;
+                         }
+                         break;
+                     }
+@@ -665,6 +843,32 @@
              return true;
          }
  
@@ -78,7 +316,7 @@
          ::rtl::OUString exportToSvgD(
  			const B2DPolyPolygon& rPolyPolygon,
  			bool bUseRelativeCoordinates, 
-@@ -678,13 +704,23 @@
+@@ -678,13 +882,23 @@
              {
                  const B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(i));
                  const sal_uInt32 nPointCount(aPolygon.count());
@@ -104,7 +342,7 @@
  
                      if(0 == j)
                      {
-@@ -697,15 +733,17 @@
+@@ -697,15 +911,17 @@
                      else
                      {
  						// handle edge from j-1 to j
@@ -128,7 +366,7 @@
  							const bool bSymmetricControlVector(CONTINUITY_C2 == aPrevCont);
  							bool bIsQuadraticBezier(false);
  
-@@ -798,7 +836,13 @@
+@@ -798,7 +1014,13 @@
                          }
                          else
                          {
@@ -143,893 +381,43 @@
                              if(aLastPoint.getX() == aCurrent.getX())
                              {
  								// export as vertical line
---- basegfx/source/polygon/b2dsvgpolypolygon.cxx.orig	1970-01-01 01:00:00.000000000 +0100
-+++ basegfx/source/polygon/b2dsvgpolypolygon.cxx.orig	2008-02-23 23:29:27.000000000 +0100
-@@ -0,0 +1,887 @@
-+/*************************************************************************
-+ *
-+ *  OpenOffice.org - a multi-platform office productivity suite
-+ *
-+ *  $RCSfile: b2dsvgpolypolygon.cxx,v $
-+ *
-+ *  $Revision: 1.7 $
-+ *
-+ *  last change: $Author: obo $ $Date: 2007/07/18 11:07:24 $
-+ *
-+ *  The Contents of this file are made available subject to
-+ *  the terms of GNU Lesser General Public License Version 2.1.
-+ *
-+ *
-+ *    GNU Lesser General Public License Version 2.1
-+ *    =============================================
-+ *    Copyright 2005 by Sun Microsystems, Inc.
-+ *    901 San Antonio Road, Palo Alto, CA 94303, USA
-+ *
-+ *    This library is free software; you can redistribute it and/or
-+ *    modify it under the terms of the GNU Lesser General Public
-+ *    License version 2.1, as published by the Free Software Foundation.
-+ *
-+ *    This library is distributed in the hope that it will be useful,
-+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ *    Lesser General Public License for more details.
-+ *
-+ *    You should have received a copy of the GNU Lesser General Public
-+ *    License along with this library; if not, write to the Free Software
-+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-+ *    MA  02111-1307  USA
-+ *
-+ ************************************************************************/
-+
-+// MARKER(update_precomp.py): autogen include statement, do not remove
-+#include "precompiled_basegfx.hxx"
-+
-+#include <basegfx/polygon/b2dpolypolygontools.hxx>
-+#include <basegfx/polygon/b2dpolypolygon.hxx>
-+
-+#ifndef _RTL_USTRING_
-+#include <rtl/ustring.hxx>
-+#endif
-+#ifndef INCLUDED_RTL_MATH_HXX
-+#include <rtl/math.hxx>
-+#endif
-+
-+namespace basegfx
-+{
-+	namespace tools
-+	{
-+        namespace
-+        {
-+            void lcl_skipSpaces(sal_Int32& 				io_rPos, 
-+                                const ::rtl::OUString& 	rStr, 
-+                                const sal_Int32 		nLen)
-+            {
-+                while( io_rPos < nLen &&
-+                       sal_Unicode(' ') == rStr[io_rPos] )
-+                {
-+                    ++io_rPos;
-+                }
-+            }
-+
-+            void lcl_skipSpacesAndCommas(sal_Int32& 			io_rPos, 
-+                                         const ::rtl::OUString& rStr, 
-+                                         const sal_Int32 		nLen)
-+            {
-+                while(io_rPos < nLen 
-+                      && (sal_Unicode(' ') == rStr[io_rPos] || sal_Unicode(',') == rStr[io_rPos]))
-+                {
-+                    ++io_rPos;
-+                }
-+            }
-+
-+            bool lcl_isOnNumberChar(const ::rtl::OUString& rStr, const sal_Int32 nPos, bool bSignAllowed = true)
-+            {
-+                const sal_Unicode aChar(rStr[nPos]);
-+
-+                const bool bPredicate( (sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
-+                                       || (bSignAllowed && sal_Unicode('+') == aChar)
-+                                       || (bSignAllowed && sal_Unicode('-') == aChar) );
-+
-+                return bPredicate;
-+            }
-+
-+            bool lcl_getDoubleChar(double& 					o_fRetval,
-+                                   sal_Int32& 				io_rPos, 
-+                                   const ::rtl::OUString& 	rStr, 
-+                                   const sal_Int32 			/*nLen*/)
-+            {
-+                sal_Unicode aChar( rStr[io_rPos] );
-+                ::rtl::OUStringBuffer sNumberString;
-+
-+                if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
-+                {
-+                    sNumberString.append(rStr[io_rPos]);
-+                    aChar = rStr[++io_rPos];
-+                }
-+
-+                while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
-+                      || sal_Unicode('.') == aChar)
-+                {
-+                    sNumberString.append(rStr[io_rPos]);
-+                    aChar = rStr[++io_rPos];
-+                }
-+
-+                if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
-+                {
-+                    sNumberString.append(rStr[io_rPos]);
-+                    aChar = rStr[++io_rPos];
-+	
-+                    if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
-+                    {
-+                        sNumberString.append(rStr[io_rPos]);
-+                        aChar = rStr[++io_rPos];
-+                    }
-+
-+                    while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
-+                    {
-+                        sNumberString.append(rStr[io_rPos]);
-+                        aChar = rStr[++io_rPos];
-+                    }
-+                }
-+
-+                if(sNumberString.getLength())
-+                {
-+                    rtl_math_ConversionStatus eStatus;
-+                    o_fRetval = ::rtl::math::stringToDouble( sNumberString.makeStringAndClear(), 
-+                                                             (sal_Unicode)('.'), 
-+                                                             (sal_Unicode)(','), 
-+                                                             &eStatus, 
-+                                                             NULL );
-+                    return ( eStatus == rtl_math_ConversionStatus_Ok );
-+                }
-+
-+                return false;
-+            }
-+
-+            bool lcl_importDoubleAndSpaces( double& 				o_fRetval, 
-+                                            sal_Int32& 				io_rPos, 
-+                                            const ::rtl::OUString& 	rStr, 
-+                                            const sal_Int32 		nLen )
-+            {
-+                if( !lcl_getDoubleChar(o_fRetval, io_rPos, rStr, nLen) )
-+                    return false;
-+
-+                lcl_skipSpacesAndCommas(io_rPos, rStr, nLen);
-+
-+                return true;
-+            }
-+
-+            void lcl_skipNumber(sal_Int32& 				io_rPos, 
-+                                const ::rtl::OUString& 	rStr, 
-+                                const sal_Int32 		nLen)
-+            {
-+                bool bSignAllowed(true);
-+
-+                while(io_rPos < nLen && lcl_isOnNumberChar(rStr, io_rPos, bSignAllowed))
-+                {
-+                    bSignAllowed = false;
-+                    ++io_rPos;
-+                }
-+            }
-+
-+            void lcl_skipDouble(sal_Int32& 				io_rPos, 
-+                                const ::rtl::OUString& 	rStr, 
-+                                const sal_Int32 		/*nLen*/)
-+            {
-+                sal_Unicode aChar( rStr[io_rPos] );
-+
-+                if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
-+                    aChar = rStr[++io_rPos];
-+
-+                while((sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
-+                      || sal_Unicode('.') == aChar)
-+                {
-+                    aChar = rStr[++io_rPos];
-+                }
-+
-+                if(sal_Unicode('e') == aChar || sal_Unicode('E') == aChar)
-+                {
-+                    aChar = rStr[++io_rPos];
-+	
-+                    if(sal_Unicode('+') == aChar || sal_Unicode('-') == aChar)
-+                        aChar = rStr[++io_rPos];
-+
-+                    while(sal_Unicode('0') <= aChar && sal_Unicode('9') >= aChar)
-+                    {
-+                        aChar = rStr[++io_rPos];
-+                    }
-+                }
-+            }
-+            void lcl_skipNumberAndSpacesAndCommas(sal_Int32& 				io_rPos, 
-+                                                  const ::rtl::OUString& 	rStr, 
-+                                                  const sal_Int32 			nLen)
-+            {
-+                lcl_skipNumber(io_rPos, rStr, nLen);
-+                lcl_skipSpacesAndCommas(io_rPos, rStr, nLen);
-+            }
-+
-+			// #100617# Allow to skip doubles, too.
-+            void lcl_skipDoubleAndSpacesAndCommas(sal_Int32& 				io_rPos, 
-+                                                  const ::rtl::OUString& 	rStr, 
-+                                                  const sal_Int32 			nLen)
-+            {
-+                lcl_skipDouble(io_rPos, rStr, nLen);
-+                lcl_skipSpacesAndCommas(io_rPos, rStr, nLen);
-+            }
-+
-+            void lcl_putNumberChar( ::rtl::OUString& rStr, 
-+                                    double 		 	 fValue )
-+            {
-+                rStr += ::rtl::OUString::valueOf( fValue );
-+            }
-+
-+            void lcl_putNumberCharWithSpace( ::rtl::OUString& rStr, 
-+                                             double 		  fValue,
-+                                             double 		  fOldValue,
-+                                             bool 			  bUseRelativeCoordinates )
-+            {
-+                if( bUseRelativeCoordinates )
-+                    fValue -= fOldValue;
-+
-+                const sal_Int32 aLen( rStr.getLength() );
-+                if(aLen)
-+                {
-+                    if( lcl_isOnNumberChar(rStr, aLen - 1, false) && 
-+                        fValue >= 0.0 )
-+                    {
-+                        rStr += ::rtl::OUString::valueOf( 
-+                            sal_Unicode(' ') );
-+                    }
-+                }
-+
-+                lcl_putNumberChar(rStr, fValue);
-+            }
-+
-+            inline sal_Unicode lcl_getCommand( sal_Char cUpperCaseCommand,
-+                                               sal_Char cLowerCaseCommand,
-+                                               bool 	bUseRelativeCoordinates )
-+            {
-+                return bUseRelativeCoordinates ? cLowerCaseCommand : cUpperCaseCommand;
-+            }
-+        }
-+
-+        bool importFromSvgD(B2DPolyPolygon& o_rPolyPolygon, const ::rtl::OUString& 	rSvgDStatement)
-+        {
-+            o_rPolyPolygon.clear();
-+            const sal_Int32 nLen(rSvgDStatement.getLength());
-+            sal_Int32 nPos(0);
-+            bool bIsClosed(false);
-+            double nLastX( 0.0 );
-+            double nLastY( 0.0 );
-+			B2DPolygon aCurrPoly;
-+
-+			// skip initial whitespace
-+            lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+            while(nPos < nLen)
-+            {
-+                bool bRelative(false);
-+                bool bMoveTo(false);
-+                const sal_Unicode aCurrChar(rSvgDStatement[nPos]);
-+
-+                switch(aCurrChar)
-+                {
-+                    case 'z' :
-+                    case 'Z' :
-+                    {
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        // remember closed state of current polygon
-+                        bIsClosed = true;
-+                        break;
-+                    }
-+				
-+                    case 'm' :
-+                    case 'M' :
-+                    {
-+                        bMoveTo = true;
-+                        // FALLTHROUGH intended
-+                    }
-+                    case 'l' :
-+                    case 'L' :
-+                    {
-+                        if('m' == aCurrChar || 'l' == aCurrChar)
-+						{
-+                            bRelative = true;
-+						}
-+
-+                        if(bMoveTo)
-+                        {
-+							// new polygon start, finish old one
-+                            if(aCurrPoly.count())
-+                            {
-+                                aCurrPoly.setClosed(bIsClosed);
-+                                bIsClosed = false;
-+                                o_rPolyPolygon.append(aCurrPoly);
-+                                aCurrPoly.clear();
-+                            }
-+                        }
-+
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
-+                        {
-+                            double nX, nY;
-+
-+                            if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
-+
-+                            if(bRelative)
-+                            {
-+                                nX += nLastX;
-+                                nY += nLastY;
-+                            }
-+
-+                            // set last position
-+                            nLastX = nX;
-+                            nLastY = nY;
-+						
-+                            // add point
-+                            aCurrPoly.append(B2DPoint(nX, nY));
-+                        }
-+                        break;
-+                    }
-+
-+                    case 'h' :
-+                    {
-+                        bRelative = true;
-+                        // FALLTHROUGH intended
-+                    }
-+                    case 'H' :
-+                    {
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
-+                        {
-+                            double nX, nY(nLastY);
-+
-+                            if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
-+
-+                            if(bRelative)
-+							{
-+                                nX += nLastX;
-+							}
-+
-+                            // set last position
-+                            nLastX = nX;
-+						
-+                            // add point
-+                            aCurrPoly.append(B2DPoint(nX, nY));
-+                        }
-+                        break;
-+                    }
-+				
-+                    case 'v' :
-+                    {
-+                        bRelative = true;
-+                        // FALLTHROUGH intended
-+                    }
-+                    case 'V' :
-+                    {
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
-+                        {
-+                            double nX(nLastX), nY;
-+
-+                            if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
-+
-+                            if(bRelative)
-+							{
-+                                nY += nLastY;
-+							}
-+
-+                            // set last position
-+                            nLastY = nY;
-+						
-+                            // add point
-+                            aCurrPoly.append(B2DPoint(nX, nY));
-+                        }
-+                        break;
-+                    }
-+				
-+                    case 's' :
-+                    {
-+                        bRelative = true;
-+                        // FALLTHROUGH intended
-+                    }
-+                    case 'S' :
-+                    {
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
-+                        {
-+                            double nX, nY;
-+                            double nX2, nY2;
-+
-+                            if(!lcl_importDoubleAndSpaces(nX2, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY2, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
-+
-+                            if(bRelative)
-+                            {
-+                                nX2 += nLastX;
-+                                nY2 += nLastY;
-+                                nX += nLastX;
-+                                nY += nLastY;
-+                            }
-+
-+							// ensure existance of start point
-+							if(!aCurrPoly.count())
-+							{
-+                                aCurrPoly.append(B2DPoint(nLastX, nLastY));
-+							}
-+
-+							// get first control point. It's the reflection of the PrevControlPoint
-+							// of the last point. If not existent, use current point (see SVG)
-+							B2DPoint aPrevControl(B2DPoint(nLastX, nLastY));
-+							const sal_uInt32 nIndex(aCurrPoly.count() - 1);
-+
-+							if(aCurrPoly.areControlPointsUsed() && aCurrPoly.isPrevControlPointUsed(nIndex))
-+							{
-+								const B2DPoint aPrevPoint(aCurrPoly.getB2DPoint(nIndex));
-+								const B2DPoint aPrevControlPoint(aCurrPoly.getPrevControlPoint(nIndex));
-+
-+								// use mirrored previous control point
-+								aPrevControl.setX((2.0 * aPrevPoint.getX()) - aPrevControlPoint.getX());
-+								aPrevControl.setY((2.0 * aPrevPoint.getY()) - aPrevControlPoint.getY());
-+							}
-+
-+							// append curved edge
-+							aCurrPoly.appendBezierSegment(aPrevControl, B2DPoint(nX2, nY2), B2DPoint(nX, nY));
-+
-+                            // set last position
-+                            nLastX = nX;
-+                            nLastY = nY;
-+                        }
-+                        break;
-+                    }
-+				
-+                    case 'c' :
-+                    {
-+                        bRelative = true;
-+                        // FALLTHROUGH intended
-+                    }
-+                    case 'C' :
-+                    {
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
-+                        {
-+                            double nX, nY;
-+                            double nX1, nY1;
-+                            double nX2, nY2;
-+
-+                            if(!lcl_importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nX2, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY2, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
-+
-+                            if(bRelative)
-+                            {
-+                                nX1 += nLastX;
-+                                nY1 += nLastY;
-+                                nX2 += nLastX;
-+                                nY2 += nLastY;
-+                                nX += nLastX;
-+                                nY += nLastY;
-+                            }
-+
-+							// ensure existance of start point
-+							if(!aCurrPoly.count())
-+							{
-+                                aCurrPoly.append(B2DPoint(nLastX, nLastY));
-+							}
-+
-+							// append curved edge
-+							aCurrPoly.appendBezierSegment(B2DPoint(nX1, nY1), B2DPoint(nX2, nY2), B2DPoint(nX, nY));
-+
-+                            // set last position
-+                            nLastX = nX;
-+                            nLastY = nY;
-+                        }
-+                        break;
-+                    }
-+				
-+                    // #100617# quadratic beziers are imported as cubic ones
-+                    case 'q' :
-+                    {
-+                        bRelative = true;
-+                        // FALLTHROUGH intended
-+                    }
-+                    case 'Q' :
-+                    {
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
-+                        {
-+                            double nX, nY;
-+                            double nX1, nY1;
-+
-+                            if(!lcl_importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
-+
-+                            if(bRelative)
-+                            {
-+                                nX1 += nLastX;
-+                                nY1 += nLastY;
-+                                nX += nLastX;
-+                                nY += nLastY;
-+                            }
-+
-+                            // calculate the cubic bezier coefficients from the quadratic ones
-+                            const double nX1Prime((nX1 * 2.0 + nLastX) / 3.0);
-+                            const double nY1Prime((nY1 * 2.0 + nLastY) / 3.0);
-+                            const double nX2Prime((nX1 * 2.0 + nX) / 3.0);
-+                            const double nY2Prime((nY1 * 2.0 + nY) / 3.0);
-+
-+							// ensure existance of start point
-+							if(!aCurrPoly.count())
-+							{
-+                                aCurrPoly.append(B2DPoint(nLastX, nLastY));
-+							}
-+
-+							// append curved edge
-+							aCurrPoly.appendBezierSegment(B2DPoint(nX1Prime, nY1Prime), B2DPoint(nX2Prime, nY2Prime), B2DPoint(nX, nY));
-+
-+                            // set last position
-+                            nLastX = nX;
-+                            nLastY = nY;
-+                        }
-+                        break;
-+                    }
-+				
-+                    // #100617# relative quadratic beziers are imported as cubic
-+                    case 't' :
-+                    {
-+                        bRelative = true;
-+                        // FALLTHROUGH intended
-+                    }
-+                    case 'T' :
-+                    {
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
-+                        {
-+                            double nX, nY;
-+
-+                            if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
-+                            if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
-+
-+                            if(bRelative)
-+                            {
-+                                nX += nLastX;
-+                                nY += nLastY;
-+                            }
-+
-+							// ensure existance of start point
-+							if(!aCurrPoly.count())
-+							{
-+                                aCurrPoly.append(B2DPoint(nLastX, nLastY));
-+							}
-+
-+							// get first control point. It's the reflection of the PrevControlPoint
-+							// of the last point. If not existent, use current point (see SVG)
-+							B2DPoint aPrevControl(B2DPoint(nLastX, nLastY));
-+							const sal_uInt32 nIndex(aCurrPoly.count() - 1);
-+							const B2DPoint aPrevPoint(aCurrPoly.getB2DPoint(nIndex));
-+
-+							if(aCurrPoly.areControlPointsUsed() && aCurrPoly.isPrevControlPointUsed(nIndex))
-+							{
-+								const B2DPoint aPrevControlPoint(aCurrPoly.getPrevControlPoint(nIndex));
-+
-+								// use mirrored previous control point
-+								aPrevControl.setX((2.0 * aPrevPoint.getX()) - aPrevControlPoint.getX());
-+								aPrevControl.setY((2.0 * aPrevPoint.getY()) - aPrevControlPoint.getY());
-+							}
-+
-+							if(!aPrevControl.equal(aPrevPoint))
-+							{
-+								// there is a prev control point, and we have the already mirrored one
-+								// in aPrevControl. We also need the quadratic control point for this
-+								// new quadratic segment to calculate the 2nd cubic control point
-+								const B2DPoint aQuadControlPoint(
-+									((3.0 * aPrevControl.getX()) - aPrevPoint.getX()) / 2.0,
-+									((3.0 * aPrevControl.getY()) - aPrevPoint.getY()) / 2.0);
-+								
-+								// calculate the cubic bezier coefficients from the quadratic ones.
-+								const double nX2Prime((aQuadControlPoint.getX() * 2.0 + nX) / 3.0);
-+								const double nY2Prime((aQuadControlPoint.getY() * 2.0 + nY) / 3.0);
-+								
-+								// append curved edge, use mirrored cubic control point directly
-+								aCurrPoly.appendBezierSegment(aPrevControl, B2DPoint(nX2Prime, nY2Prime), B2DPoint(nX, nY));
-+							}
-+							else
-+							{
-+								// when no previous control, SVG says to use current point -> straight line.
-+								// Just add end point
-+								aCurrPoly.append(B2DPoint(nX, nY));
-+							}
-+
-+                            // set last position
-+                            nLastX = nX;
-+                            nLastY = nY;
-+                        }
-+                        break;
-+                    }
-+
-+                    // #100617# not yet supported: elliptical arc
-+                    case 'A' :
-+                        // FALLTHROUGH intended
-+                    case 'a' :
-+                    {
-+                        OSL_ENSURE(false, "importFromSvgD(): non-interpreted tags in svg:d element (elliptical arc)!");
-+                        nPos++;
-+                        lcl_skipSpaces(nPos, rSvgDStatement, nLen);
-+
-+                        while(nPos < nLen && lcl_isOnNumberChar(rSvgDStatement, nPos))
-+                        {
-+                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
-+                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
-+                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
-+                            lcl_skipNumberAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
-+                            lcl_skipNumberAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
-+                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
-+                            lcl_skipDoubleAndSpacesAndCommas(nPos, rSvgDStatement, nLen);
-+                        }
-+                        break;
-+                    }
-+
-+                    default:
-+                    {
-+                        OSL_ENSURE(false, "importFromSvgD(): skipping tags in svg:d element (unknown)!");
-+                        OSL_TRACE("importFromSvgD(): skipping tags in svg:d element (unknown: \"%c\")!", aCurrChar);
-+                        ++nPos;
-+                        break;
-+                    }
-+                }
-+            }
-+
-+            if(aCurrPoly.count())
-+            {
-+                // end-process last poly
-+                aCurrPoly.setClosed(bIsClosed);
-+                o_rPolyPolygon.append(aCurrPoly);
-+            }
-+
-+            return true;
-+        }
-+
-+        bool importFromSvgPoints( B2DPolygon&            o_rPoly,
-+                                  const ::rtl::OUString& rSvgPointsAttribute )
-+        {
-+            o_rPoly.clear();
-+            const sal_Int32 nLen(rSvgPointsAttribute.getLength());
-+            sal_Int32 nPos(0);
-+            double nX, nY;
-+
-+            // skip initial whitespace
-+            lcl_skipSpaces(nPos, rSvgPointsAttribute, nLen);
-+
-+            while(nPos < nLen)
-+            {
-+                if(!lcl_importDoubleAndSpaces(nX, nPos, rSvgPointsAttribute, nLen)) return false;
-+                if(!lcl_importDoubleAndSpaces(nY, nPos, rSvgPointsAttribute, nLen)) return false;
-+                
-+                // add point        
-+                o_rPoly.append(B2DPoint(nX, nY));
-+
-+                // skip to next number, or finish
-+                lcl_skipSpaces(nPos, rSvgPointsAttribute, nLen);
-+            }
-+
-+            return true;
-+        }
-+
-+        ::rtl::OUString exportToSvgD(
-+			const B2DPolyPolygon& rPolyPolygon,
-+			bool bUseRelativeCoordinates, 
-+			bool bDetectQuadraticBeziers)
-+        {
-+            const sal_uInt32 nCount(rPolyPolygon.count());
-+            ::rtl::OUString aResult;
-+            B2DPoint aLastPoint(0.0, 0.0); // SVG assumes (0,0) as the initial current point
-+
-+            for(sal_uInt32 i(0); i < nCount; i++)
-+            {
-+                const B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(i));
-+                const sal_uInt32 nPointCount(aPolygon.count());
-+                const bool bPolyUsesControlPoints(aPolygon.areControlPointsUsed());
-+                sal_Unicode aLastSVGCommand(' '); // last SVG command char
-+				B2DPoint aLeft, aRight; // for quadratic bezier test
-+
-+                for(sal_uInt32 j(0); j < nPointCount; j++)
-+                {
-+                    const B2DPoint aCurrent(aPolygon.getB2DPoint(j));
-+
-+                    if(0 == j)
-+                    {
-+						// handle first polygon point
-+                        aResult += ::rtl::OUString::valueOf(lcl_getCommand('M', 'm', bUseRelativeCoordinates));
-+                        lcl_putNumberCharWithSpace(aResult, aCurrent.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                        lcl_putNumberCharWithSpace(aResult, aCurrent.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                        aLastSVGCommand =  lcl_getCommand('L', 'l', bUseRelativeCoordinates);
-+                    }
-+                    else
-+                    {
-+						// handle edge from j-1 to j
-+						const bool bEdgeIsBezier(bPolyUsesControlPoints
-+							&& (aPolygon.isNextControlPointUsed(j - 1) || aPolygon.isPrevControlPointUsed(j)));
-+
-+                        if(bEdgeIsBezier)
-+                        {
-+                            // handle bezier edge
-+                            const B2DPoint aControl0(aPolygon.getNextControlPoint(j - 1));
-+                            const B2DPoint aControl1(aPolygon.getPrevControlPoint(j));
-+							const B2VectorContinuity aPrevCont(aPolygon.getContinuityInPoint(j - 1));
-+							const bool bSymmetricControlVector(CONTINUITY_C2 == aPrevCont);
-+							bool bIsQuadraticBezier(false);
-+
-+							if(bDetectQuadraticBeziers)
-+							{
-+								// check for quadratic beziers - that's
-+								// the case if both control points are in
-+								// the same place when they are prolonged
-+								// to the common quadratic control point
-+								//
-+								// Left: P = (3P1 - P0) / 2 
-+								// Right: P = (3P2 - P3) / 2
-+								aLeft = B2DPoint((3.0 * aControl0 - aLastPoint) / 2.0);
-+								aRight= B2DPoint((3.0 * aControl1 - aCurrent) / 2.0);
-+								bIsQuadraticBezier = aLeft.equal(aRight);
-+							}
-+
-+							if(bIsQuadraticBezier)
-+							{
-+                                // approximately equal, export as quadratic bezier
-+                                if(bSymmetricControlVector)
-+                                {
-+                                    const sal_Unicode aCommand(lcl_getCommand('T', 't', bUseRelativeCoordinates));
-+
-+                                    if(aLastSVGCommand != aCommand)
-+                                    {
-+                                        aResult += ::rtl::OUString::valueOf(aCommand);
-+                                        aLastSVGCommand = aCommand;
-+                                    }
-+                                    
-+                                    lcl_putNumberCharWithSpace(aResult, aCurrent.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aCurrent.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                                    aLastSVGCommand = aCommand;
-+                                }
-+                                else
-+                                {
-+                                    const sal_Unicode aCommand(lcl_getCommand('Q', 'q', bUseRelativeCoordinates));
-+
-+                                    if(aLastSVGCommand != aCommand)
-+                                    {
-+                                        aResult += ::rtl::OUString::valueOf(aCommand);
-+                                        aLastSVGCommand = aCommand;
-+                                    }
-+                                    
-+                                    lcl_putNumberCharWithSpace(aResult, aLeft.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aLeft.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aCurrent.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aCurrent.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                                    aLastSVGCommand = aCommand;
-+                                }
-+                            }
-+                            else
-+                            {
-+                                // export as cubic bezier
-+                                if(bSymmetricControlVector)
-+                                {
-+                                    const sal_Unicode aCommand(lcl_getCommand('S', 's', bUseRelativeCoordinates));
-+
-+                                    if(aLastSVGCommand != aCommand)
-+                                    {
-+                                        aResult += ::rtl::OUString::valueOf(aCommand);
-+                                        aLastSVGCommand = aCommand;
-+                                    }
-+                                    
-+                                    lcl_putNumberCharWithSpace(aResult, aControl1.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aControl1.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aCurrent.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aCurrent.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                                    aLastSVGCommand = aCommand;
-+                                }
-+                                else
-+                                {
-+                                    const sal_Unicode aCommand(lcl_getCommand('C', 'c', bUseRelativeCoordinates));
-+
-+                                    if(aLastSVGCommand != aCommand)
-+                                    {
-+                                        aResult += ::rtl::OUString::valueOf(aCommand);
-+                                        aLastSVGCommand = aCommand;
-+                                    }
-+                                    
-+                                    lcl_putNumberCharWithSpace(aResult, aControl0.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aControl0.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aControl1.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aControl1.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aCurrent.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                                    lcl_putNumberCharWithSpace(aResult, aCurrent.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                                    aLastSVGCommand = aCommand;
-+                                }
-+                            }                            
-+                        }
-+                        else
-+                        {
-+                            // normal straight line points
-+                            if(aLastPoint.getX() == aCurrent.getX())
-+                            {
-+								// export as vertical line
-+                                const sal_Unicode aCommand(lcl_getCommand('V', 'v', bUseRelativeCoordinates));
-+
-+								if(aLastSVGCommand != aCommand)
-+                                {
-+									aResult += ::rtl::OUString::valueOf(aCommand);
-+                                    aLastSVGCommand = aCommand;
-+                                }
-+
-+								lcl_putNumberCharWithSpace(aResult, aCurrent.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                            }
-+                            else if(aLastPoint.getY() == aCurrent.getY())
-+                            {
-+								// export as horizontal line
-+                                const sal_Unicode aCommand(lcl_getCommand('H', 'h', bUseRelativeCoordinates));
-+
-+								if(aLastSVGCommand != aCommand)
-+                                {
-+									aResult += ::rtl::OUString::valueOf(aCommand);
-+                                    aLastSVGCommand = aCommand;
-+                                }
-+
-+								lcl_putNumberCharWithSpace(aResult, aCurrent.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+                            }
-+                            else
-+                            {
-+								// export as line
-+                                const sal_Unicode aCommand(lcl_getCommand('L', 'l', bUseRelativeCoordinates));
-+
-+								if(aLastSVGCommand != aCommand)
-+                                {
-+									aResult += ::rtl::OUString::valueOf(aCommand);
-+                                    aLastSVGCommand = aCommand;
-+                                }
-+
-+								lcl_putNumberCharWithSpace(aResult, aCurrent.getX(), aLastPoint.getX(), bUseRelativeCoordinates);
-+								lcl_putNumberCharWithSpace(aResult, aCurrent.getY(), aLastPoint.getY(), bUseRelativeCoordinates);
-+                            }
-+                        }
-+                    }
-+
-+                    aLastPoint = aCurrent;
-+                }
-+
-+                // close path if closed poly (Z and z are equivalent here, but looks nicer
-+				// when case is matched)
-+                if(aPolygon.isClosed())
-+				{
-+                    aResult += ::rtl::OUString::valueOf(lcl_getCommand('Z', 'z', bUseRelativeCoordinates));
-+				}
-+            }
-+
-+            return aResult;
-+        }
-+    }
-+}
-+
-+// eof
+--- basegfx/test/basegfx2d.cxx	18 Jul 2007 11:08:37 -0000	1.9
++++ basegfx/test/basegfx2d.cxx	28 Feb 2008 09:04:44 -0000
+@@ -470,6 +470,37 @@
+         aExport = tools::exportToSvgD( aPoly );
+         CPPUNIT_ASSERT_MESSAGE("exporting complex polygon to SVG-D (round-trip)", 
+                                !aExport.compareToAscii(sExportString2));
++
++        const B2DPolygon aCircle( 
++            tools::createPolygonFromEllipse( B2DPoint(0,0),
++                                             1.0, 2.0 ));
++        aExport = tools::exportToSvgD( B2DPolyPolygon(aCircle), false, false);
++
++        const char* sExportString3 =
++            "M1 0S0.552284749830794 2 0 2-1 1.10456949966159-1 0-0.552284749830794-2 0-2 1-1.10456949966159 1 0Z";
++        CPPUNIT_ASSERT_MESSAGE("exporting bezier circle polygon to SVG-D", 
++                               !aExport.compareToAscii(sExportString3));
++
++        ::std::ofstream output("elliptical_arc.gnuplot");
++        DebugPlotter aPlotter( "elliptical arg testcases",
++                               output );
++
++        tools::importFromSvgD( aPoly,
++                               ::rtl::OUString::createFromAscii( 
++                                   "M300,200 h-150 a150,150 0 1,0 150,-150 z") );
++        aPlotter.plot( aPoly, "a" );
++        tools::importFromSvgD( aPoly,
++                               ::rtl::OUString::createFromAscii( 
++                                   "M275,175 v-150 a150,150 0 0,0 -150,150 z") );
++        aPlotter.plot( aPoly, "b" );
++        tools::importFromSvgD( aPoly,
++                               ::rtl::OUString::createFromAscii( 
++            "M600,350 l 50,-25 "
++            "a25,25 -30 0,1 50,-25 l 50,-25 "
++            "a25,50 -30 0,1 50,-25 l 50,-25 "
++            "a25,75 -30 0,1 50,-25 l 50,-25 "
++            "a25,100 -30 0,1 50,-25 l 50,-25") );
++        aPlotter.plot( aPoly, "c" );
+     }
+ 
+     // Change the following lines only, if you add, remove or rename 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]