diff options
Diffstat (limited to 'basegfx/source/range')
-rw-r--r-- | basegfx/source/range/b1drange.cxx | 56 | ||||
-rw-r--r-- | basegfx/source/range/b2dmultirange.cxx | 279 | ||||
-rw-r--r-- | basegfx/source/range/b2drange.cxx | 74 | ||||
-rw-r--r-- | basegfx/source/range/b2xrange.cxx | 142 | ||||
-rw-r--r-- | basegfx/source/range/b3drange.cxx | 85 | ||||
-rw-r--r-- | basegfx/source/range/makefile.mk | 51 |
6 files changed, 687 insertions, 0 deletions
diff --git a/basegfx/source/range/b1drange.cxx b/basegfx/source/range/b1drange.cxx new file mode 100644 index 000000000000..6581b04680e2 --- /dev/null +++ b/basegfx/source/range/b1drange.cxx @@ -0,0 +1,56 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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 <basegfx/range/b1drange.hxx> +#include <basegfx/range/b1irange.hxx> +#include <basegfx/numeric/ftools.hxx> + +namespace basegfx +{ + B1DRange::B1DRange( const B1IRange& rRange ) : + maRange() + { + if( !rRange.isEmpty() ) + { + maRange = rRange.getMinimum(); + expand(rRange.getMaximum()); + } + } + + B1IRange fround(const B1DRange& rRange) + { + return rRange.isEmpty() ? + B1IRange() : + B1IRange( fround( rRange.getMinimum()), + fround( rRange.getMaximum()) ); + } + +} // end of namespace basegfx + +// eof diff --git a/basegfx/source/range/b2dmultirange.cxx b/basegfx/source/range/b2dmultirange.cxx new file mode 100644 index 000000000000..3a47be3b7dc9 --- /dev/null +++ b/basegfx/source/range/b2dmultirange.cxx @@ -0,0 +1,279 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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 <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 diff --git a/basegfx/source/range/b2drange.cxx b/basegfx/source/range/b2drange.cxx new file mode 100644 index 000000000000..693470c3ef14 --- /dev/null +++ b/basegfx/source/range/b2drange.cxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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 <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2irange.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> + +namespace basegfx +{ + B2DRange::B2DRange( const B2IRange& rRange ) : + maRangeX(), + maRangeY() + { + if( !rRange.isEmpty() ) + { + maRangeX = rRange.getMinX(); + maRangeY = rRange.getMinY(); + + maRangeX.expand(rRange.getMaxX()); + maRangeY.expand(rRange.getMaxY()); + } + } + + void B2DRange::transform(const B2DHomMatrix& rMatrix) + { + if(!isEmpty() && !rMatrix.isIdentity()) + { + const B2DRange aSource(*this); + reset(); + expand(rMatrix * B2DPoint(aSource.getMinX(), aSource.getMinY())); + expand(rMatrix * B2DPoint(aSource.getMaxX(), aSource.getMinY())); + expand(rMatrix * B2DPoint(aSource.getMinX(), aSource.getMaxY())); + expand(rMatrix * B2DPoint(aSource.getMaxX(), aSource.getMaxY())); + } + } + + B2IRange fround(const B2DRange& rRange) + { + return rRange.isEmpty() ? + B2IRange() : + B2IRange(fround(rRange.getMinimum()), + fround(rRange.getMaximum())); + } +} // end of namespace basegfx + +// eof diff --git a/basegfx/source/range/b2xrange.cxx b/basegfx/source/range/b2xrange.cxx new file mode 100644 index 000000000000..296b54574800 --- /dev/null +++ b/basegfx/source/range/b2xrange.cxx @@ -0,0 +1,142 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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 <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2irange.hxx> +#include <basegfx/range/b2ibox.hxx> + + +namespace basegfx +{ + namespace + { + /** Generic implementation of the difference set computation + + @tpl RangeType + Type to operate on. Must provide ValueType and TraitsType + nested types. + */ + template< class RangeType > void doComputeSetDifference( + ::std::vector< RangeType >& o_rRanges, + const RangeType& a, + const RangeType& b ) + { + o_rRanges.clear(); + + // special-casing the empty rect case (this will fail most + // of the times below, because of the DBL_MIN/MAX special + // values denoting emptyness in the rectangle. + if( a.isEmpty() ) + { + o_rRanges.push_back( b ); + return; + } + if( b.isEmpty() ) + { + o_rRanges.push_back( a ); + return; + } + + const typename RangeType::ValueType ax(a.getMinX()); + const typename RangeType::ValueType ay(a.getMinY()); + const typename RangeType::TraitsType::DifferenceType aw(a.getWidth()); + const typename RangeType::TraitsType::DifferenceType ah(a.getHeight()); + const typename RangeType::ValueType bx(b.getMinX()); + const typename RangeType::ValueType by(b.getMinY()); + const typename RangeType::TraitsType::DifferenceType bw(b.getWidth()); + const typename RangeType::TraitsType::DifferenceType bh(b.getHeight()); + + const typename RangeType::TraitsType::DifferenceType h0( (by > ay) ? by - ay : 0 ); + const typename RangeType::TraitsType::DifferenceType h3( (by + bh < ay + ah) ? ay + ah - by - bh : 0 ); + const typename RangeType::TraitsType::DifferenceType w1( (bx > ax) ? bx - ax : 0 ); + const typename RangeType::TraitsType::DifferenceType w2( (ax + aw > bx + bw) ? ax + aw - bx - bw : 0 ); + const typename RangeType::TraitsType::DifferenceType h12( (h0 + h3 < ah) ? ah - h0 - h3 : 0 ); + + // TODO(E2): Use numeric_cast instead of static_cast here, + // need range checks! + if (h0 > 0) + o_rRanges.push_back( + RangeType(ax,ay, + static_cast<typename RangeType::ValueType>(ax+aw), + static_cast<typename RangeType::ValueType>(ay+h0)) ); + + if (w1 > 0 && h12 > 0) + o_rRanges.push_back( + RangeType(ax, + static_cast<typename RangeType::ValueType>(ay+h0), + static_cast<typename RangeType::ValueType>(ax+w1), + static_cast<typename RangeType::ValueType>(ay+h0+h12)) ); + + if (w2 > 0 && h12 > 0) + o_rRanges.push_back( + RangeType(static_cast<typename RangeType::ValueType>(bx+bw), + static_cast<typename RangeType::ValueType>(ay+h0), + static_cast<typename RangeType::ValueType>(bx+bw+w2), + static_cast<typename RangeType::ValueType>(ay+h0+h12)) ); + + if (h3 > 0) + o_rRanges.push_back( + RangeType(ax, + static_cast<typename RangeType::ValueType>(ay+h0+h12), + static_cast<typename RangeType::ValueType>(ax+aw), + static_cast<typename RangeType::ValueType>(ay+h0+h12+h3)) ); + } + } + + ::std::vector< B2IRange >& computeSetDifference( ::std::vector< B2IRange >& o_rResult, + const B2IRange& rFirst, + const B2IRange& rSecond ) + { + doComputeSetDifference( o_rResult, rFirst, rSecond ); + + return o_rResult; + } + + ::std::vector< B2DRange >& computeSetDifference( ::std::vector< B2DRange >& o_rResult, + const B2DRange& rFirst, + const B2DRange& rSecond ) + { + doComputeSetDifference( o_rResult, rFirst, rSecond ); + + return o_rResult; + } + + ::std::vector< B2IBox >& computeSetDifference( ::std::vector< B2IBox >& o_rResult, + const B2IBox& rFirst, + const B2IBox& rSecond ) + { + doComputeSetDifference( o_rResult, rFirst, rSecond ); + + return o_rResult; + } + +} // end of namespace basegfx + +// eof diff --git a/basegfx/source/range/b3drange.cxx b/basegfx/source/range/b3drange.cxx new file mode 100644 index 000000000000..aaeeae684bdd --- /dev/null +++ b/basegfx/source/range/b3drange.cxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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 <basegfx/range/b3drange.hxx> +#include <basegfx/range/b3irange.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/matrix/b3dhommatrix.hxx> + +namespace basegfx +{ + B3DRange::B3DRange(const B3IRange& rRange) : + maRangeX(), + maRangeY(), + maRangeZ() + { + if( !rRange.isEmpty() ) + { + maRangeX = rRange.getMinX(); + maRangeY = rRange.getMinY(); + maRangeZ = rRange.getMinZ(); + + maRangeX.expand( rRange.getMaxX() ); + maRangeY.expand( rRange.getMaxY() ); + maRangeZ.expand( rRange.getMaxZ() ); + } + } + + void B3DRange::transform(const B3DHomMatrix& rMatrix) + { + if(!isEmpty() && !rMatrix.isIdentity()) + { + const B3DRange aSource(*this); + reset(); + expand(rMatrix * B3DPoint(aSource.getMinX(), aSource.getMinY(), aSource.getMinZ())); + expand(rMatrix * B3DPoint(aSource.getMaxX(), aSource.getMinY(), aSource.getMinZ())); + expand(rMatrix * B3DPoint(aSource.getMinX(), aSource.getMaxY(), aSource.getMinZ())); + expand(rMatrix * B3DPoint(aSource.getMaxX(), aSource.getMaxY(), aSource.getMinZ())); + expand(rMatrix * B3DPoint(aSource.getMinX(), aSource.getMinY(), aSource.getMaxZ())); + expand(rMatrix * B3DPoint(aSource.getMaxX(), aSource.getMinY(), aSource.getMaxZ())); + expand(rMatrix * B3DPoint(aSource.getMinX(), aSource.getMaxY(), aSource.getMaxZ())); + expand(rMatrix * B3DPoint(aSource.getMaxX(), aSource.getMaxY(), aSource.getMaxZ())); + } + } + + B3IRange fround(const B3DRange& rRange ) + { + return rRange.isEmpty() ? + B3IRange() : + B3IRange(fround(rRange.getMinX()), + fround(rRange.getMinY()), + fround(rRange.getMinZ()), + fround(rRange.getMaxX()), + fround(rRange.getMaxY()), + fround(rRange.getMaxZ())); + } + +} // end of namespace basegfx + +// eof diff --git a/basegfx/source/range/makefile.mk b/basegfx/source/range/makefile.mk new file mode 100644 index 000000000000..04d8e8e66fa2 --- /dev/null +++ b/basegfx/source/range/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# 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. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=basegfx +TARGET=range + +#UNOUCRRDB=$(SOLARBINDIR)$/applicat.rdb +ENABLE_EXCEPTIONS=TRUE +#USE_DEFFILE=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk + +# --- Files ------------------------------------- + +SLOFILES= \ + $(SLO)$/b1drange.obj \ + $(SLO)$/b2drange.obj \ + $(SLO)$/b2xrange.obj \ + $(SLO)$/b2dmultirange.obj \ + $(SLO)$/b3drange.obj + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk |