[Libreoffice-commits] .: 3 commits - basegfx/inc basegfx/prj basegfx/source

Fridrich Strba fridrich at kemper.freedesktop.org
Wed Jun 22 03:54:55 PDT 2011


 basegfx/inc/basegfx/tools/unotools.hxx       |   55 +++++
 basegfx/prj/d.lst                            |    1 
 basegfx/source/polygon/b2dsvgpolypolygon.cxx |    7 
 basegfx/source/tools/makefile.mk             |    3 
 basegfx/source/tools/unotools.cxx            |  264 +++++++++++++++++++++++++++
 5 files changed, 324 insertions(+), 6 deletions(-)

New commits:
commit 2fd4deb01aa727ef8db7b0e668439d0d93a212f7
Author: Fridrich Å trba <fridrich.strba at bluewin.ch>
Date:   Wed Jun 22 09:36:20 2011 +0200

    Use the sweep flag to determine the drawing direction
    
    The previous solution was giving somehow acceptable results
    in the majority of cases, but was pretty broken
    with corner cases where the arc is exactly half of the whole ellipse and where
    the large arc flag is largely irrelevant.
    If the sweep flag is equal to 0 drawing goes in the sense of decreasing angles.
    If it is set, drawing goes in the sense of increasing angles.

diff --git a/basegfx/source/polygon/b2dsvgpolypolygon.cxx b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
index 187e396..02b338e 100644
--- a/basegfx/source/polygon/b2dsvgpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
@@ -787,10 +787,7 @@ namespace basegfx
                                 // (since
                                 // createPolygonFromEllipseSegment()
                                 // normalizes to e.g. cw arc)
-                                const bool bLessThanPi(fmod(fTheta2+2*M_PI-fTheta1,
-                                          2*M_PI)<M_PI);
-                                const bool bFlipSegment( (bLargeArcFlag!=0) == bLessThanPi );
-                                if( bFlipSegment )
+                                if( !bSweepFlag )
                                     std::swap(fTheta1,fTheta2);
 
                                 // finally, create bezier polygon from this
@@ -812,7 +809,7 @@ namespace basegfx
                                 // always creates arcs that are
                                 // positively oriented - flip polygon
                                 // if we swapped angles above
-                                if( bFlipSegment )
+                                if( !bSweepFlag )
                                     aSegment.flip();
                                 aCurrPoly.append(aSegment);
                             }
commit 54ebb20ea87c0a3194f1960f56894037c2449ed9
Author: Fridrich Å trba <fridrich.strba at bluewin.ch>
Date:   Tue Jun 21 09:40:32 2011 +0200

    Fix deliver

diff --git a/basegfx/prj/d.lst b/basegfx/prj/d.lst
index 06888a8..a654a17 100644
--- a/basegfx/prj/d.lst
+++ b/basegfx/prj/d.lst
@@ -93,7 +93,7 @@ mkdir: %_DEST%\inc\basegfx\tools
 ..\inc\basegfx\tools\keystoplerp.hxx %_DEST%\inc\basegfx\tools\keystoplerp.hxx
 ..\inc\basegfx\tools\lerp.hxx %_DEST%\inc\basegfx\tools\lerp.hxx
 ..\inc\basegfx\tools\unopolypolygon.hxx %_DEST%\inc\basegfx\tools\unopolypolygon.hxx
-..\inc\basegfx\tools\unotools.hxx %_DEST%\inc%_EXT%\basegfx\tools\unotools.hxx
+..\inc\basegfx\tools\unotools.hxx %_DEST%\inc\basegfx\tools\unotools.hxx
 ..\inc\basegfx\tools\b2dclipstate.hxx %_DEST%\inc\basegfx\tools\b2dclipstate.hxx
 ..\inc\basegfx\tools\rectcliptools.hxx %_DEST%\inc\basegfx\tools\rectcliptools.hxx
 ..\inc\basegfx\tools\tools.hxx %_DEST%\inc\basegfx\tools\tools.hxx
commit 246168e94709a5ea7f34914d8e246af0985a9c81
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Jun 21 09:11:29 2011 +0200

    Teach LibreOffice proper svg:d support

diff --git a/basegfx/inc/basegfx/tools/unotools.hxx b/basegfx/inc/basegfx/tools/unotools.hxx
new file mode 100644
index 0000000..e7bcc27
--- /dev/null
+++ b/basegfx/inc/basegfx/tools/unotools.hxx
@@ -0,0 +1,55 @@
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ *       Thorsten Behrens <tbehrens at novell.com>
+ * Portions created by the Initial Developer are Copyright (C) 2011 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef INCLUDED_BASEGFX_UNOTOOLS_HXX
+#define INCLUDED_BASEGFX_UNOTOOLS_HXX
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/rendering/FillRule.hpp>
+#include <com/sun/star/rendering/XLinePolyPolygon2D.hpp>
+#include <com/sun/star/rendering/XBezierPolyPolygon2D.hpp>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+
+
+namespace basegfx
+{
+class B2DPolyPolygon;
+
+namespace unotools
+{
+
+    B2DPolyPolygon polyPolygonBezierToB2DPolyPolygon(const ::com::sun::star::drawing::PolyPolygonBezierCoords& rSourcePolyPolygon)
+        throw( ::com::sun::star::lang::IllegalArgumentException );
+
+    void b2DPolyPolygonToPolyPolygonBezier( const B2DPolyPolygon& rPolyPoly,
+                                            ::com::sun::star::drawing::PolyPolygonBezierCoords& rRetval );
+}
+}
+
+#endif /* INCLUDED_BASEGFX_UNOTOOLS_HXX */
diff --git a/basegfx/prj/d.lst b/basegfx/prj/d.lst
index dd4a2d8..06888a8 100644
--- a/basegfx/prj/d.lst
+++ b/basegfx/prj/d.lst
@@ -93,6 +93,7 @@ mkdir: %_DEST%\inc\basegfx\tools
 ..\inc\basegfx\tools\keystoplerp.hxx %_DEST%\inc\basegfx\tools\keystoplerp.hxx
 ..\inc\basegfx\tools\lerp.hxx %_DEST%\inc\basegfx\tools\lerp.hxx
 ..\inc\basegfx\tools\unopolypolygon.hxx %_DEST%\inc\basegfx\tools\unopolypolygon.hxx
+..\inc\basegfx\tools\unotools.hxx %_DEST%\inc%_EXT%\basegfx\tools\unotools.hxx
 ..\inc\basegfx\tools\b2dclipstate.hxx %_DEST%\inc\basegfx\tools\b2dclipstate.hxx
 ..\inc\basegfx\tools\rectcliptools.hxx %_DEST%\inc\basegfx\tools\rectcliptools.hxx
 ..\inc\basegfx\tools\tools.hxx %_DEST%\inc\basegfx\tools\tools.hxx
diff --git a/basegfx/source/tools/makefile.mk b/basegfx/source/tools/makefile.mk
index 0a0977f..6023a32 100755
--- a/basegfx/source/tools/makefile.mk
+++ b/basegfx/source/tools/makefile.mk
@@ -44,7 +44,8 @@ SLOFILES= $(SLO)$/b2dclipstate.obj	\
           $(SLO)$/keystoplerp.obj	\
           $(SLO)$/liangbarsky.obj	\
           $(SLO)$/tools.obj		    \
-          $(SLO)$/unopolypolygon.obj
+          $(SLO)$/unopolypolygon.obj\
+          $(SLO)$/unotools.obj
 
 # --- Targets ----------------------------------
 
diff --git a/basegfx/source/tools/unotools.cxx b/basegfx/source/tools/unotools.cxx
new file mode 100644
index 0000000..710568b
--- /dev/null
+++ b/basegfx/source/tools/unotools.cxx
@@ -0,0 +1,264 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * Portions Copright 2011 Thorsten Behrens <tbehrens at novell.com>
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_basegfx.hxx"
+
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/drawing/PointSequence.hpp>
+#include <com/sun/star/drawing/FlagSequence.hpp>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/curve/b2dcubicbezier.hxx>
+
+#include <basegfx/tools/unotools.hxx>
+#include <comphelper/sequence.hxx>
+
+
+using namespace ::com::sun::star;
+
+namespace basegfx
+{
+namespace unotools
+{
+
+    B2DPolyPolygon polyPolygonBezierToB2DPolyPolygon(const drawing::PolyPolygonBezierCoords& rSourcePolyPolygon)
+        throw( lang::IllegalArgumentException )
+    {
+        const sal_Int32 nOuterSequenceCount(rSourcePolyPolygon.Coordinates.getLength());
+        B2DPolyPolygon aNewPolyPolygon;
+
+        if(rSourcePolyPolygon.Flags.getLength() != nOuterSequenceCount)
+            throw lang::IllegalArgumentException();
+
+        // get pointers to inner sequence
+        const drawing::PointSequence* pInnerSequence = rSourcePolyPolygon.Coordinates.getConstArray();
+        const drawing::FlagSequence* pInnerSequenceFlags = rSourcePolyPolygon.Flags.getConstArray();
+
+        for(sal_Int32 a(0); a < nOuterSequenceCount; a++)
+        {
+            const sal_Int32 nInnerSequenceCount(pInnerSequence->getLength());
+
+            if(pInnerSequenceFlags->getLength() != nInnerSequenceCount)
+                throw lang::IllegalArgumentException();
+
+            // prepare new polygon
+            basegfx::B2DPolygon aNewPolygon;
+            const awt::Point* pArray = pInnerSequence->getConstArray();
+            const drawing::PolygonFlags* pArrayFlags = pInnerSequenceFlags->getConstArray();
+
+            // get first point and flag
+            basegfx::B2DPoint aNewCoordinatePair(pArray->X, pArray->Y); pArray++;
+            drawing::PolygonFlags ePolyFlag(*pArrayFlags); pArrayFlags++;
+            basegfx::B2DPoint aControlA;
+            basegfx::B2DPoint aControlB;
+
+            // first point is not allowed to be a control point
+            if(drawing::PolygonFlags_CONTROL == ePolyFlag)
+                throw lang::IllegalArgumentException();
+
+            // add first point as start point
+            aNewPolygon.append(aNewCoordinatePair);
+            for(sal_Int32 b(1); b < nInnerSequenceCount;)
+            {
+                // prepare loop
+                bool bControlA(false);
+                bool bControlB(false);
+
+                // get next point and flag
+                aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
+                ePolyFlag = *pArrayFlags;
+                pArray++; pArrayFlags++; b++;
+
+                if(b < nInnerSequenceCount && drawing::PolygonFlags_CONTROL == ePolyFlag)
+                {
+                    aControlA = aNewCoordinatePair;
+                    bControlA = true;
+
+                    // get next point and flag
+                    aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
+                    ePolyFlag = *pArrayFlags;
+                    pArray++; pArrayFlags++; b++;
+                }
+
+                if(b < nInnerSequenceCount && drawing::PolygonFlags_CONTROL == ePolyFlag)
+                {
+                    aControlB = aNewCoordinatePair;
+                    bControlB = true;
+
+                    // get next point and flag
+                    aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
+                    ePolyFlag = *pArrayFlags;
+                    pArray++; pArrayFlags++; b++;
+                }
+
+                // two or no control points are consumed, another one would be an error.
+                // It's also an error if only one control point was read
+                if(drawing::PolygonFlags_CONTROL == ePolyFlag || bControlA != bControlB)
+                    throw lang::IllegalArgumentException();
+
+                // the previous writes used the B2DPolyPoygon -> PolyPolygon converter
+                // which did not create minimal PolyPolygons, but created all control points
+                // as null vectors (identical points). Because of the former P(CA)(CB)-norm of
+                // B2DPolygon and it's unused sign of being the zero-vector and CA and CB being
+                // relative to P, an empty edge was exported as P == CA == CB. Luckily, the new
+                // export format can be read without errors by the old OOo-versions, so we need only
+                // to correct here at read and do not need to export a wrong but compatible version
+                // for the future.
+                if(bControlA
+                   && aControlA.equal(aControlB)
+                   && aControlA.equal(aNewPolygon.getB2DPoint(aNewPolygon.count() - 1)))
+                {
+                    bControlA = bControlB = false;
+                }
+
+                if(bControlA)
+                {
+                    // add bezier edge
+                    aNewPolygon.appendBezierSegment(aControlA, aControlB, aNewCoordinatePair);
+                }
+                else
+                {
+                    // add edge
+                    aNewPolygon.append(aNewCoordinatePair);
+                }
+            }
+
+            // next sequence
+            pInnerSequence++;
+            pInnerSequenceFlags++;
+
+            // #i72807# API import uses old line start/end-equal definition for closed,
+            // so we need to correct this to closed state here
+            basegfx::tools::checkClosed(aNewPolygon);
+
+            // add new subpolygon
+            aNewPolyPolygon.append(aNewPolygon);
+        }
+
+        return aNewPolyPolygon;
+    }
+
+    /////////////////////////////////////////////////////////////////////////////////
+
+    void b2DPolyPolygonToPolyPolygonBezier( const basegfx::B2DPolyPolygon& rPolyPoly,
+                                            drawing::PolyPolygonBezierCoords& rRetval )
+    {
+        rRetval.Coordinates.realloc(rPolyPoly.count());
+        rRetval.Flags.realloc(rPolyPoly.count());
+
+        drawing::PointSequence* pOuterSequence = rRetval.Coordinates.getArray();
+        drawing::FlagSequence*  pOuterFlags = rRetval.Flags.getArray();
+
+        for(sal_uInt32 a=0;a<rPolyPoly.count();a++)
+        {
+            const B2DPolygon& rPoly = rPolyPoly.getB2DPolygon(a);
+            sal_uInt32 nCount(rPoly.count());
+            const bool bClosed(rPoly.isClosed());
+
+            // calculate input vertex count
+            const sal_uInt32 nLoopCount(bClosed ? nCount : (nCount ? nCount - 1L : 0L ));
+
+            std::vector<awt::Point> aPoints; aPoints.reserve(nLoopCount);
+            std::vector<drawing::PolygonFlags> aFlags; aFlags.reserve(nLoopCount);
+
+            // prepare insert index and current point
+            basegfx::B2DCubicBezier aBezier;
+            aBezier.setStartPoint(rPoly.getB2DPoint(0));
+
+            for(sal_uInt32 b(0L); b<nLoopCount; b++)
+            {
+                // add current point (always) and remember StartPointIndex for evtl. later corrections
+                const awt::Point aStartPoint(fround(aBezier.getStartPoint().getX()),
+                                             fround(aBezier.getStartPoint().getY()));
+                const sal_uInt32 nStartPointIndex(aPoints.size());
+                aPoints.push_back(aStartPoint);
+                aFlags.push_back(drawing::PolygonFlags_NORMAL);
+
+                // prepare next segment
+                const sal_uInt32 nNextIndex((b + 1) % nCount);
+                aBezier.setEndPoint(rPoly.getB2DPoint(nNextIndex));
+                aBezier.setControlPointA(rPoly.getNextControlPoint(b));
+                aBezier.setControlPointB(rPoly.getPrevControlPoint(nNextIndex));
+
+                if(aBezier.isBezier())
+                {
+                    // if one is used, add always two control points due to the old schema
+                    aPoints.push_back( awt::Point(fround(aBezier.getControlPointA().getX()),
+                                                  fround(aBezier.getControlPointA().getY())) );
+                    aFlags.push_back(drawing::PolygonFlags_CONTROL);
+
+                    aPoints.push_back( awt::Point(fround(aBezier.getControlPointB().getX()),
+                                                  fround(aBezier.getControlPointB().getY())) );
+                    aFlags.push_back(drawing::PolygonFlags_CONTROL);
+                }
+
+                // test continuity with previous control point to set flag value
+                if(aBezier.getControlPointA() != aBezier.getStartPoint() && (bClosed || b))
+                {
+                    const basegfx::B2VectorContinuity eCont(rPoly.getContinuityInPoint(b));
+
+                    if(basegfx::CONTINUITY_C1 == eCont)
+                    {
+                        aFlags[nStartPointIndex] = drawing::PolygonFlags_SMOOTH;
+                    }
+                    else if(basegfx::CONTINUITY_C2 == eCont)
+                    {
+                        aFlags[nStartPointIndex] = drawing::PolygonFlags_SYMMETRIC;
+                    }
+                }
+
+                // prepare next polygon step
+                aBezier.setStartPoint(aBezier.getEndPoint());
+            }
+
+            if(bClosed)
+            {
+                // add first point again as closing point due to old definition
+                aPoints.push_back( aPoints[0] );
+                aFlags.push_back(drawing::PolygonFlags_NORMAL);
+            }
+            else
+            {
+                // add last point as closing point
+                const basegfx::B2DPoint aClosingPoint(rPoly.getB2DPoint(nCount - 1L));
+                const awt::Point aEnd(fround(aClosingPoint.getX()),
+                                      fround(aClosingPoint.getY()));
+                aPoints.push_back(aEnd);
+                aFlags.push_back(drawing::PolygonFlags_NORMAL);
+            }
+
+            *pOuterSequence++ = comphelper::containerToSequence(aPoints);
+            *pOuterFlags++ = comphelper::containerToSequence(aFlags);
+        }
+    }
+
+}
+}


More information about the Libreoffice-commits mailing list