Kaydet (Commit) 8454c5ef authored tarafından thb's avatar thb

#i105939# Adds special box clipping support to basegfx

üst 44dfc8de
...@@ -83,7 +83,7 @@ namespace basegfx ...@@ -83,7 +83,7 @@ namespace basegfx
sal_uInt32 count() const; sal_uInt32 count() const;
/// Coordinate interface /// Coordinate interface
basegfx::B2DPoint getB2DPoint(sal_uInt32 nIndex) const; const basegfx::B2DPoint& getB2DPoint(sal_uInt32 nIndex) const;
void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue); void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
/// Coordinate insert/append /// Coordinate insert/append
...@@ -201,7 +201,7 @@ namespace basegfx ...@@ -201,7 +201,7 @@ namespace basegfx
@return @return
The outer range of the bezier curve/polygon The outer range of the bezier curve/polygon
*/ */
B2DRange getB2DRange() const; const B2DRange& getB2DRange() const;
/** insert other 2D polygons /** insert other 2D polygons
...@@ -261,6 +261,12 @@ namespace basegfx ...@@ -261,6 +261,12 @@ namespace basegfx
/// apply transformation given in matrix form /// apply transformation given in matrix form
void transform(const basegfx::B2DHomMatrix& rMatrix); void transform(const basegfx::B2DHomMatrix& rMatrix);
// point iterators
const B2DPoint* begin() const;
const B2DPoint* end() const;
B2DPoint* begin();
B2DPoint* end();
}; };
} // end of namespace basegfx } // end of namespace basegfx
......
...@@ -128,6 +128,12 @@ namespace basegfx ...@@ -128,6 +128,12 @@ namespace basegfx
// apply transformation given in matrix form to the polygon // apply transformation given in matrix form to the polygon
void transform(const basegfx::B2DHomMatrix& rMatrix); void transform(const basegfx::B2DHomMatrix& rMatrix);
// polygon iterators
const B2DPolygon* begin() const;
const B2DPolygon* end() const;
B2DPolygon* begin();
B2DPolygon* end();
}; };
} // end of namespace basegfx } // end of namespace basegfx
......
...@@ -28,19 +28,19 @@ ...@@ -28,19 +28,19 @@
* *
************************************************************************/ ************************************************************************/
#ifndef _BGFX_RANGE_B2DMULTIRANGE_HXX #ifndef _BGFX_RANGE_B2DPOLYRANGE_HXX
#define _BGFX_RANGE_B2DMULTIRANGE_HXX #define _BGFX_RANGE_B2DPOLYRANGE_HXX
#include <o3tl/cow_wrapper.hxx> #include <o3tl/cow_wrapper.hxx>
#include <memory> #include <boost/tuple/tuple.hpp>
#include <basegfx/vector/b2enums.hxx>
namespace basegfx namespace basegfx
{ {
class B2DTuple; class B2DTuple;
class B2DRange; class B2DRange;
class B2DPolyPolygon; class B2DPolyPolygon;
class ImplB2DMultiRange; class ImplB2DPolyRange;
/** Multiple ranges in one object. /** Multiple ranges in one object.
...@@ -51,67 +51,89 @@ namespace basegfx ...@@ -51,67 +51,89 @@ namespace basegfx
rectangular objects. Add each modified object to a rectangular objects. Add each modified object to a
B2DMultiRange, then test each viewable object against B2DMultiRange, then test each viewable object against
intersection with the multi range. intersection with the multi range.
Similar in spirit to the poly-polygon vs. polygon relationship.
Note that comparable to polygons, a poly-range can also
contain 'holes' - this is encoded via polygon orientation at
the poly-polygon, and via explicit flags for the poly-range.
*/ */
class B2DMultiRange class B2DPolyRange
{ {
public: public:
B2DMultiRange(); typedef boost::tuple<B2DRange,B2VectorOrientation> ElementType ;
~B2DMultiRange();
B2DPolyRange();
~B2DPolyRange();
/** Create a multi range with exactly one containing range /** Create a multi range with exactly one containing range
*/ */
explicit B2DMultiRange( const B2DRange& rRange ); explicit B2DPolyRange( const ElementType& rElement );
B2DPolyRange( const B2DRange& rRange, B2VectorOrientation eOrient );
B2DPolyRange( const B2DPolyRange& );
B2DPolyRange& operator=( const B2DPolyRange& );
B2DMultiRange( const B2DMultiRange& ); /// unshare this poly-range with all internally shared instances
B2DMultiRange& operator=( const B2DMultiRange& ); void makeUnique();
/** Check whether range is empty. bool operator==(const B2DPolyRange&) const;
bool operator!=(const B2DPolyRange&) const;
@return true, if this object either contains no ranges at /// Number of included ranges
all, or all contained ranges are empty. sal_uInt32 count() const;
*/
bool isEmpty() const;
/** Reset to empty. ElementType getElement(sal_uInt32 nIndex) const;
void setElement(sal_uInt32 nIndex, const ElementType& rElement );
void setElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient );
After this call, the object will not contain any ranges, // insert/append a single range
and isEmpty() will return true. void insertElement(sal_uInt32 nIndex, const ElementType& rElement, sal_uInt32 nCount = 1);
*/ void insertElement(sal_uInt32 nIndex, const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount = 1);
void reset(); void appendElement(const ElementType& rElement, sal_uInt32 nCount = 1);
void appendElement(const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount = 1);
// insert/append multiple ranges
void insertPolyRange(sal_uInt32 nIndex, const B2DPolyRange&);
void appendPolyRange(const B2DPolyRange&);
void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1);
void clear();
// flip range orientations - converts holes to solids, and vice versa
void flip();
/** Get overall range
@return
The union range of all contained ranges
*/
B2DRange getBounds() const;
/** Test whether given tuple is inside one or more of the /** Test whether given tuple is inside one or more of the
included ranges. included ranges. Does *not* use overall range, but checks
individually.
*/ */
bool isInside( const B2DTuple& rTuple ) const; bool isInside( const B2DTuple& rTuple ) const;
/** Test whether given range is inside one or more of the /** Test whether given range is inside one or more of the
included ranges. included ranges. Does *not* use overall range, but checks
individually.
*/ */
bool isInside( const B2DRange& rRange ) const; bool isInside( const B2DRange& rRange ) const;
/** Test whether given range overlaps one or more of the /** Test whether given range overlaps one or more of the
included ranges. included ranges. Does *not* use overall range, but checks
*/ individually.
bool overlaps( const B2DRange& rRange ) const;
/** Add given range to the number of contained ranges.
*/
void addRange( const B2DRange& rRange );
/** Get overall bound rect for all included ranges.
*/ */
B2DRange getBounds() const; bool overlaps( const B2DRange& rRange ) const;
/** Request poly-polygon representing the added ranges.
This method creates a poly-polygon, consisting exactly out /** Request a poly-polygon with solved cross-overs
of the contained ranges.
*/ */
B2DPolyPolygon getPolyPolygon() const; B2DPolyPolygon solveCrossovers() const;
private: private:
o3tl::cow_wrapper< ImplB2DMultiRange > mpImpl; o3tl::cow_wrapper< ImplB2DPolyRange > mpImpl;
}; };
} }
#endif /* _BGFX_RANGE_B2DMULTIRANGE_HXX */ #endif /* _BGFX_RANGE_B2DPOLYRANGE_HXX */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: b2dmultirange.hxx,v $
* $Revision: 1.6 $
*
* 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.
*
************************************************************************/
#ifndef _BGFX_RANGE_B2DRANGECLIPPER_HXX
#define _BGFX_RANGE_B2DRANGECLIPPER_HXX
#include <basegfx/range/b2dpolyrange.hxx>
#include <vector>
namespace basegfx
{
namespace tools
{
/** Extract poly-polygon w/o self-intersections from poly-range
Similar to the solveCrossovers(const B2DPolyPolygon&)
method, this one calculates a self-intersection-free
poly-polygon with the same topology, and encoding
inside/outsidedness via polygon orientation and layering.
*/
B2DPolyPolygon solveCrossovers(const std::vector<B2DRange>& rRanges,
const std::vector<B2VectorOrientation>& rOrientations);
}
}
#endif /* _BGFX_RANGE_B2DRANGECLIPPER_HXX */
This diff is collapsed.
...@@ -44,38 +44,24 @@ ...@@ -44,38 +44,24 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
class CoordinateData2D struct CoordinateData2D : public basegfx::B2DPoint
{ {
basegfx::B2DPoint maPoint;
public: public:
CoordinateData2D() CoordinateData2D() {}
: maPoint()
{}
explicit CoordinateData2D(const basegfx::B2DPoint& rData) explicit CoordinateData2D(const basegfx::B2DPoint& rData)
: maPoint(rData) : B2DPoint(rData)
{} {}
const basegfx::B2DPoint& getCoordinate() const CoordinateData2D& operator=(const basegfx::B2DPoint& rData)
{
return maPoint;
}
void setCoordinate(const basegfx::B2DPoint& rValue)
{
if(rValue != maPoint)
maPoint = rValue;
}
bool operator==(const CoordinateData2D& rData ) const
{ {
return (maPoint == rData.getCoordinate()); B2DPoint::operator=(rData);
return *this;
} }
void transform(const basegfx::B2DHomMatrix& rMatrix) void transform(const basegfx::B2DHomMatrix& rMatrix)
{ {
maPoint *= rMatrix; *this *= rMatrix;
} }
}; };
...@@ -115,12 +101,12 @@ public: ...@@ -115,12 +101,12 @@ public:
const basegfx::B2DPoint& getCoordinate(sal_uInt32 nIndex) const const basegfx::B2DPoint& getCoordinate(sal_uInt32 nIndex) const
{ {
return maVector[nIndex].getCoordinate(); return maVector[nIndex];
} }
void setCoordinate(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue) void setCoordinate(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue)
{ {
maVector[nIndex].setCoordinate(rValue); maVector[nIndex] = rValue;
} }
void insert(sal_uInt32 nIndex, const CoordinateData2D& rValue, sal_uInt32 nCount) void insert(sal_uInt32 nIndex, const CoordinateData2D& rValue, sal_uInt32 nCount)
...@@ -221,6 +207,26 @@ public: ...@@ -221,6 +207,26 @@ public:
aStart->transform(rMatrix); aStart->transform(rMatrix);
} }
} }
const basegfx::B2DPoint* begin() const
{
return &maVector.front();
}
const basegfx::B2DPoint* end() const
{
return &maVector[maVector.size()];
}
basegfx::B2DPoint* begin()
{
return &maVector.front();
}
basegfx::B2DPoint* end()
{
return &maVector[maVector.size()];
}
}; };
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
...@@ -1113,6 +1119,28 @@ public: ...@@ -1113,6 +1119,28 @@ public:
maPoints.transform(rMatrix); maPoints.transform(rMatrix);
} }
} }
const basegfx::B2DPoint* begin() const
{
return maPoints.begin();
}
const basegfx::B2DPoint* end() const
{
return maPoints.end();
}
basegfx::B2DPoint* begin()
{
mpBufferedData.reset();
return maPoints.begin();
}
basegfx::B2DPoint* end()
{
mpBufferedData.reset();
return maPoints.end();
}
}; };
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
...@@ -1173,7 +1201,7 @@ namespace basegfx ...@@ -1173,7 +1201,7 @@ namespace basegfx
return mpPolygon->count(); return mpPolygon->count();
} }
B2DPoint B2DPolygon::getB2DPoint(sal_uInt32 nIndex) const const B2DPoint& B2DPolygon::getB2DPoint(sal_uInt32 nIndex) const
{ {
OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)"); OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
...@@ -1432,7 +1460,7 @@ namespace basegfx ...@@ -1432,7 +1460,7 @@ namespace basegfx
return mpPolygon->getDefaultAdaptiveSubdivision(*this); return mpPolygon->getDefaultAdaptiveSubdivision(*this);
} }
B2DRange B2DPolygon::getB2DRange() const const B2DRange& B2DPolygon::getB2DRange() const
{ {
return mpPolygon->getB2DRange(*this); return mpPolygon->getB2DRange(*this);
} }
...@@ -1540,6 +1568,26 @@ namespace basegfx ...@@ -1540,6 +1568,26 @@ namespace basegfx
mpPolygon->transform(rMatrix); mpPolygon->transform(rMatrix);
} }
} }
const B2DPoint* B2DPolygon::begin() const
{
return mpPolygon->begin();
}
const B2DPoint* B2DPolygon::end() const
{
return mpPolygon->end();
}
B2DPoint* B2DPolygon::begin()
{
return mpPolygon->begin();
}
B2DPoint* B2DPolygon::end()
{
return mpPolygon->end();
}
} // end of namespace basegfx } // end of namespace basegfx
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
......
...@@ -166,6 +166,26 @@ public: ...@@ -166,6 +166,26 @@ public:
maPolygons.end(), maPolygons.end(),
std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique )); std::mem_fun_ref( &basegfx::B2DPolygon::makeUnique ));
} }
const basegfx::B2DPolygon* begin() const
{
return &maPolygons.front();
}
const basegfx::B2DPolygon* end() const
{
return &maPolygons[maPolygons.size()];
}
basegfx::B2DPolygon* begin()
{
return &maPolygons.front();
}
basegfx::B2DPolygon* end()
{
return &maPolygons[maPolygons.size()];
}
}; };
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
...@@ -378,6 +398,26 @@ namespace basegfx ...@@ -378,6 +398,26 @@ namespace basegfx
mpPolyPolygon->transform(rMatrix); mpPolyPolygon->transform(rMatrix);
} }
} }
const B2DPolygon* B2DPolyPolygon::begin() const
{
return mpPolyPolygon->begin();
}
const B2DPolygon* B2DPolyPolygon::end() const
{
return mpPolyPolygon->end();
}
B2DPolygon* B2DPolyPolygon::begin()
{
return mpPolyPolygon->begin();
}
B2DPolygon* B2DPolyPolygon::end()
{
return mpPolyPolygon->end();
}
} // end of namespace basegfx } // end of namespace basegfx
// eof // eof
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: b2dmultirange.cxx,v $
* $Revision: 1.8 $
*
* 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 <basegfx/range/b2drange.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/range/b2dmultirange.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
#include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
#include <algorithm>
#include <vector>
namespace basegfx
{
class ImplB2DMultiRange
{
public:
ImplB2DMultiRange() :
maBounds(),
maRanges()
{
}
explicit ImplB2DMultiRange( const B2DRange& rRange ) :
maBounds(),
maRanges( 1, rRange )
{
}
bool isEmpty() const
{
// no ranges at all, or all ranges empty
return maRanges.empty() ||
::std::count_if( maRanges.begin(),
maRanges.end(),
::boost::mem_fn( &B2DRange::isEmpty ) )
== static_cast<VectorOfRanges::difference_type>(maRanges.size());
}
void reset()
{
// swap in empty vector
VectorOfRanges aTmp;
maRanges.swap( aTmp );
maBounds.reset();
}
template< typename ValueType > bool isInside( const ValueType& rValue ) const
{
if( !maBounds.isInside( rValue ) )
return false;
// cannot use ::boost::bind here, since isInside is overloaded.
// It is currently not possible to resolve the overload
// by considering one of the other template arguments.
VectorOfRanges::const_iterator aCurr( maRanges.begin() );
const VectorOfRanges::const_iterator aEnd ( maRanges.end() );
while( aCurr != aEnd )
if( aCurr->isInside( rValue ) )
return true;
return false;
}
bool overlaps( const B2DRange& rRange ) const
{
if( !maBounds.overlaps( rRange ) )
return false;
const VectorOfRanges::const_iterator aEnd( maRanges.end() );
return ::std::find_if( maRanges.begin(),
aEnd,
::boost::bind<bool>( ::boost::mem_fn( &B2DRange::overlaps ),
_1,
rRange ) ) != aEnd;
}
void addRange( const B2DRange& rRange )
{
maRanges.push_back( rRange );
maBounds.expand( rRange );
}
B2DRange getBounds() const
{
return maBounds;
}
B2DPolyPolygon getPolyPolygon() const
{
B2DPolyPolygon aRes;
// Make range vector unique ( have to avoid duplicate
// rectangles. The polygon clipper will return an empty
// result in this case).
VectorOfRanges aUniqueRanges;
aUniqueRanges.reserve( maRanges.size() );
VectorOfRanges::const_iterator aCurr( maRanges.begin() );
const VectorOfRanges::const_iterator aEnd ( maRanges.end() );
while( aCurr != aEnd )
{
// TODO(F3): It's plain wasted resources to apply a
// general clipping algorithm to the problem at
// hand. Go for a dedicated, scan-line-based approach.
VectorOfRanges::const_iterator aCurrScan( aCurr+1 );
VectorOfRanges::const_iterator aFound( aEnd );
while( aCurrScan != aEnd )
{
if( aCurrScan->equal( *aCurr ) ||
aCurrScan->isInside( *aCurr ) )
{
// current probe is equal to aCurr, or
// completely contains aCurr. Thus, stop
// searching, because aCurr is definitely not
// a member of the unique rect list
aFound = aCurrScan;
break;
}
++aCurrScan;
}
if( aFound == aEnd )
{
// check whether aCurr is fully contained in one
// of the already added rects. If yes, we can skip
// it.
bool bUnique( true );
VectorOfRanges::const_iterator aCurrUnique( aUniqueRanges.begin() );
VectorOfRanges::const_iterator aEndUnique ( aUniqueRanges.end() );
while( aCurrUnique != aEndUnique )
{
if( aCurrUnique->isInside( *aCurr ) )
{
// fully contained, no need to add
bUnique = false;
break;
}
++aCurrUnique;
}
if( bUnique )
aUniqueRanges.push_back( *aCurr );
}
++aCurr;
}
VectorOfRanges::const_iterator aCurrUnique( aUniqueRanges.begin() );
const VectorOfRanges::const_iterator aEndUnique ( aUniqueRanges.end() );
while( aCurrUnique != aEndUnique )
{
// simply merge all unique parts (OR)
aRes.append( tools::createPolygonFromRect( *aCurrUnique++ ) );
}
// remove redundant intersections. Note: since all added
// rectangles are positively oriented, this method cannot
// generate any holes.
aRes = basegfx::tools::solveCrossovers(aRes);
aRes = basegfx::tools::stripNeutralPolygons(aRes);
aRes = basegfx::tools::stripDispensablePolygons(aRes, false);
return aRes;
}
private:
typedef ::std::vector< B2DRange > VectorOfRanges;
B2DRange maBounds;
VectorOfRanges maRanges;
};
// ====================================================================
B2DMultiRange::B2DMultiRange() :
mpImpl()
{
}
B2DMultiRange::B2DMultiRange( const B2DRange& rRange ) :
mpImpl( ImplB2DMultiRange( rRange ) )
{
}
B2DMultiRange::~B2DMultiRange()
{
// otherwise, ImplB2DMultiRange would be an incomplete type
}
B2DMultiRange::B2DMultiRange( const B2DMultiRange& rSrc ) :
mpImpl( rSrc.mpImpl )
{
}
B2DMultiRange& B2DMultiRange::operator=( const B2DMultiRange& rSrc )
{
mpImpl = rSrc.mpImpl;
return *this;
}
bool B2DMultiRange::isEmpty() const
{
return mpImpl->isEmpty();
}
void B2DMultiRange::reset()
{
mpImpl->reset();
}
bool B2DMultiRange::isInside( const B2DTuple& rTuple ) const
{
return mpImpl->isInside( rTuple );
}
bool B2DMultiRange::isInside( const B2DRange& rRange ) const
{
return mpImpl->isInside( rRange );
}
bool B2DMultiRange::overlaps( const B2DRange& rRange ) const
{
return mpImpl->overlaps( rRange );
}
void B2DMultiRange::addRange( const B2DRange& rRange )
{
mpImpl->addRange( rRange );
}
B2DRange B2DMultiRange::getBounds() const
{
return mpImpl->getBounds();
}
B2DPolyPolygon B2DMultiRange::getPolyPolygon() const
{
return mpImpl->getPolyPolygon();
}
} // end of namespace basegfx
// eof
This diff is collapsed.
This diff is collapsed.
...@@ -47,7 +47,8 @@ SLOFILES= \ ...@@ -47,7 +47,8 @@ SLOFILES= \
$(SLO)$/b1drange.obj \ $(SLO)$/b1drange.obj \
$(SLO)$/b2drange.obj \ $(SLO)$/b2drange.obj \
$(SLO)$/b2xrange.obj \ $(SLO)$/b2xrange.obj \
$(SLO)$/b2dmultirange.obj \ $(SLO)$/b2dpolyrange.obj \
$(SLO)$/b2drangeclipper.obj \
$(SLO)$/b3drange.obj $(SLO)$/b3drange.obj
# --- Targets ---------------------------------- # --- Targets ----------------------------------
......
...@@ -41,7 +41,9 @@ ...@@ -41,7 +41,9 @@
#include <basegfx/curve/b2dcubicbezier.hxx> #include <basegfx/curve/b2dcubicbezier.hxx>
#include <basegfx/curve/b2dbeziertools.hxx> #include <basegfx/curve/b2dbeziertools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/range/b2dmultirange.hxx> #include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/range/b2dpolyrange.hxx>
#include <basegfx/numeric/ftools.hxx> #include <basegfx/numeric/ftools.hxx>
#include <basegfx/color/bcolor.hxx> #include <basegfx/color/bcolor.hxx>
#include <basegfx/color/bcolortools.hxx> #include <basegfx/color/bcolortools.hxx>
...@@ -56,214 +58,6 @@ using namespace ::basegfx; ...@@ -56,214 +58,6 @@ using namespace ::basegfx;
namespace basegfx2d namespace basegfx2d
{ {
/// Gets a random ordinal [0,n)
inline double getRandomOrdinal( const ::std::size_t n )
{
return double(n) * rand() / (RAND_MAX + 1.0);
}
class b2dmultirange : public CppUnit::TestFixture
{
private:
B2DMultiRange aDisjunctRanges;
B2DMultiRange aEqualRanges;
B2DMultiRange aIntersectionN;
B2DMultiRange aIntersectionE;
B2DMultiRange aIntersectionS;
B2DMultiRange aIntersectionW;
B2DMultiRange aIntersectionNE;
B2DMultiRange aIntersectionSE;
B2DMultiRange aIntersectionSW;
B2DMultiRange aIntersectionNW;
B2DMultiRange aRingIntersection;
B2DMultiRange aComplexIntersections;
B2DMultiRange aRandomIntersections;
public:
// initialise your test code values here.
void setUp()
{
B2DRange aCenter(1.0, 1.0, -1.0, -1.0);
B2DRange aOffside(9.0, 9.0, 11.0, 11.0);
B2DRange aNorth(1.0, 0.0, -1.0, -2.0);
B2DRange aSouth(1.0, 2.0, -1.0, 0.0);
B2DRange aEast(0.0, 1.0, 2.0, -1.0);
B2DRange aWest(-2.0, 1.0, 0.0, -1.0);
B2DRange aNorthEast(0.0, 0.0, 2.0, -2.0);
B2DRange aSouthEast(0.0, 0.0, 2.0, 2.0);
B2DRange aSouthWest(0.0, 0.0, -2.0, 2.0);
B2DRange aNorthWest(0.0, 0.0, -2.0, -2.0);
B2DRange aNorth2(-1.5, 0.5, 1.5, 3.5);
B2DRange aSouth2(-1.5, -0.5, 1.5, -3.5);
B2DRange aEast2 (0.5, -1.5, 3.5, 1.5);
B2DRange aWest2 (-0.5, -1.5,-3.5, 1.5);
::std::ofstream output("multirange_testcases.gnuplot");
DebugPlotter aPlotter( "multirange testcases",
output );
aPlotter.plot( aCenter, "center" );
aPlotter.plot( aOffside, "offside" );
aPlotter.plot( aNorth, "north" );
aPlotter.plot( aSouth, "south" );
aPlotter.plot( aEast, "east" );
aPlotter.plot( aWest, "west" );
aPlotter.plot( aNorthEast, "northeast" );
aPlotter.plot( aSouthEast, "southeast" );
aPlotter.plot( aSouthWest, "southwest" );
aPlotter.plot( aNorthWest, "northwest" );
aDisjunctRanges.addRange( aCenter );
aDisjunctRanges.addRange( aOffside );
aEqualRanges.addRange( aCenter );
aEqualRanges.addRange( aCenter );
aIntersectionN.addRange( aCenter );
aIntersectionN.addRange( aNorth );
aIntersectionE.addRange( aCenter );
aIntersectionE.addRange( aEast );
aIntersectionS.addRange( aCenter );
aIntersectionS.addRange( aSouth );
aIntersectionW.addRange( aCenter );
aIntersectionW.addRange( aWest );
aIntersectionNE.addRange( aCenter );
aIntersectionNE.addRange( aNorthEast );
aIntersectionSE.addRange( aCenter );
aIntersectionSE.addRange( aSouthEast );
aIntersectionSW.addRange( aCenter );
aIntersectionSW.addRange( aSouthWest );
aIntersectionNW.addRange( aCenter );
aIntersectionNW.addRange( aNorthWest );
aRingIntersection.addRange( aNorth2 );
aRingIntersection.addRange( aEast2 );
aRingIntersection.addRange( aSouth2 );
aRingIntersection.addRange( aWest2 );
aComplexIntersections.addRange( aCenter );
aComplexIntersections.addRange( aOffside );
aComplexIntersections.addRange( aCenter );
aComplexIntersections.addRange( aNorth );
aComplexIntersections.addRange( aEast );
aComplexIntersections.addRange( aSouth );
aComplexIntersections.addRange( aWest );
aComplexIntersections.addRange( aNorthEast );
aComplexIntersections.addRange( aSouthEast );
aComplexIntersections.addRange( aSouthWest );
aComplexIntersections.addRange( aNorthWest );
/*
for( int i=0; i<10; ++i )
{
B2DRange aRandomRange(
getRandomOrdinal( 10 ),
getRandomOrdinal( 10 ),
getRandomOrdinal( 10 ),
getRandomOrdinal( 10 ) );
aRandomIntersections.addRange( aRandomRange );
}
*/
}
void tearDown()
{
}
::basegfx::B2DPolyPolygon shiftPoly( int nCount,
const ::basegfx::B2DPolyPolygon& rPoly )
{
B2DHomMatrix aMatrix;
aMatrix.translate( nCount*4.0,
10.0-nCount*2.0 );
::basegfx::B2DPolyPolygon aRes( rPoly );
aRes.transform( aMatrix );
return aRes;
}
void getPolyPolygon()
{
::std::ofstream output("multirange_getpolypolygon.gnuplot");
DebugPlotter aPlotter( "multirange getPolyPolygon",
output );
B2DPolyPolygon result;
aPlotter.plot( shiftPoly(
0,
aDisjunctRanges.getPolyPolygon() ),
"disjunct" );
aPlotter.plot( shiftPoly(
1,
aEqualRanges.getPolyPolygon() ),
"equal" );
aPlotter.plot( shiftPoly(
2,
aIntersectionN.getPolyPolygon() ),
"intersectionN" );
aPlotter.plot( shiftPoly(
3,
aIntersectionE.getPolyPolygon() ),
"intersectionE" );
aPlotter.plot( shiftPoly(
4,
aIntersectionS.getPolyPolygon() ),
"intersectionS" );
aPlotter.plot( shiftPoly(
5,
aIntersectionW.getPolyPolygon() ),
"intersectionW" );
aPlotter.plot( shiftPoly(
6,
aIntersectionNE.getPolyPolygon() ),
"intersectionNE" );
aPlotter.plot( shiftPoly(
7,
aIntersectionSE.getPolyPolygon() ),
"intersectionSE" );
aPlotter.plot( shiftPoly(
8,
aIntersectionSW.getPolyPolygon() ),
"intersectionSW" );
aPlotter.plot( shiftPoly(
9,
aIntersectionNW.getPolyPolygon() ),
"intersectionNW" );
aPlotter.plot( shiftPoly(
10,
aRingIntersection.getPolyPolygon() ),
"intersection ring" );
aPlotter.plot( shiftPoly(
11,
aComplexIntersections.getPolyPolygon() ),
"intersection complex" );
aPlotter.plot( shiftPoly(
12,
aRandomIntersections.getPolyPolygon() ),
"intersection random" );
CPPUNIT_ASSERT_MESSAGE("getPolyPolygon", true );
}
// Change the following lines only, if you add, remove or rename
// member functions of the current class,
// because these macros are need by auto register mechanism.
CPPUNIT_TEST_SUITE(b2dmultirange);
CPPUNIT_TEST(getPolyPolygon);
CPPUNIT_TEST_SUITE_END();
}; // class b2dmultirange
class b2dsvgdimpex : public CppUnit::TestFixture class b2dsvgdimpex : public CppUnit::TestFixture
{ {
...@@ -505,6 +299,39 @@ public: ...@@ -505,6 +299,39 @@ public:
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
}; // class b2dsvgdimpex }; // class b2dsvgdimpex
class b2dpolyrange : public CppUnit::TestFixture
{
private:
public:
void setUp()
{}
void tearDown()
{}
void check()
{
B2DPolyRange aRange;
aRange.appendElement(B2DRange(0,0,1,1),ORIENTATION_POSITIVE);
aRange.appendElement(B2DRange(2,2,3,3),ORIENTATION_POSITIVE);
CPPUNIT_ASSERT_MESSAGE("simple poly range - count",
aRange.count() == 2);
CPPUNIT_ASSERT_MESSAGE("simple poly range - first element",
aRange.getElement(0).head == B2DRange(0,0,1,1));
CPPUNIT_ASSERT_MESSAGE("simple poly range - second element",
aRange.getElement(1).head == B2DRange(2,2,3,3));
}
// Change the following lines only, if you add, remove or rename
// member functions of the current class,
// because these macros are need by auto register mechanism.
CPPUNIT_TEST_SUITE(b2dpolyrange);
CPPUNIT_TEST(check);
CPPUNIT_TEST_SUITE_END();
};
class b2dbeziertools : public CppUnit::TestFixture class b2dbeziertools : public CppUnit::TestFixture
{ {
private: private:
...@@ -1618,8 +1445,9 @@ public: ...@@ -1618,8 +1445,9 @@ public:
}; // class b2dvector }; // class b2dvector
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dmultirange, "basegfx2d");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dsvgdimpex, "basegfx2d"); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dsvgdimpex, "basegfx2d");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dpolyrange, "basegfx2d");
//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dbeziertools, "basegfx2d"); //CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dbeziertools, "basegfx2d");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dcubicbezier, "basegfx2d"); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dcubicbezier, "basegfx2d");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dhommatrix, "basegfx2d"); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dhommatrix, "basegfx2d");
......
This diff is collapsed.
...@@ -85,6 +85,10 @@ SLOFILES=$(SHL1OBJS) ...@@ -85,6 +85,10 @@ SLOFILES=$(SHL1OBJS)
.INCLUDE : target.mk .INCLUDE : target.mk
.INCLUDE : _cppunit.mk .INCLUDE : _cppunit.mk
.IF "$(verbose)"!="" || "$(VERBOSE)"!=""
CDEFS+= -DVERBOSE
.ENDIF
# --- Enable testshl2 execution in normal build ------------------------ # --- Enable testshl2 execution in normal build ------------------------
$(MISC)$/unittest_succeeded : $(SHL1TARGETN) $(MISC)$/unittest_succeeded : $(SHL1TARGETN)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment