diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2008-08-19 22:59:27 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2008-08-19 22:59:27 +0000 |
commit | 46451f0a30baf49a85c1dc845eb5fe363a118844 (patch) | |
tree | 75f950ce43b68761f4aa502f5d54575ff6cc963d /basegfx/source/curve/b2dbeziertools.cxx | |
parent | 7db9f195461768420b561a43acc2a4011a51593c (diff) |
INTEGRATION: CWS aw033 (1.12.12); FILE MERGED
2008/05/14 14:41:46 aw 1.12.12.2: RESYNC: (1.12-1.13); FILE MERGED
2007/11/07 14:24:29 aw 1.12.12.1: #i39532# committing to have a base for HDU
Diffstat (limited to 'basegfx/source/curve/b2dbeziertools.cxx')
-rw-r--r-- | basegfx/source/curve/b2dbeziertools.cxx | 132 |
1 files changed, 130 insertions, 2 deletions
diff --git a/basegfx/source/curve/b2dbeziertools.cxx b/basegfx/source/curve/b2dbeziertools.cxx index de2cdb78291a..dd19356af488 100644 --- a/basegfx/source/curve/b2dbeziertools.cxx +++ b/basegfx/source/curve/b2dbeziertools.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: b2dbeziertools.cxx,v $ - * $Revision: 1.13 $ + * $Revision: 1.14 $ * * This file is part of OpenOffice.org. * @@ -30,9 +30,137 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_basegfx.hxx" +#include <basegfx/curve/b2dbeziertools.hxx> #include <basegfx/curve/b2dcubicbezier.hxx> +#include <algorithm> + +////////////////////////////////////////////////////////////////////////////// + +namespace basegfx +{ + B2DCubicBezierHelper::B2DCubicBezierHelper(const B2DCubicBezier& rBase, sal_uInt32 nDivisions) + : maLengthArray(), + mnEdgeCount(0) + { + const bool bIsBezier(rBase.isBezier()); + + if(bIsBezier) + { + // check nDivisions; at least one is needed, but also prevent too big values + if(nDivisions < 1) + { + nDivisions = 1; + } + else if(nDivisions > 1000) + { + nDivisions = 1000; + } + + // set nEdgeCount + mnEdgeCount = nDivisions + 1; + + // fill in maLengthArray + maLengthArray.clear(); + maLengthArray.reserve(mnEdgeCount); + B2DPoint aCurrent(rBase.getStartPoint()); + double fLength(0.0); + + for(sal_uInt32 a(1);;) + { + const B2DPoint aNext(rBase.interpolatePoint((double)a / (double)mnEdgeCount)); + const B2DVector aEdge(aNext - aCurrent); + + fLength += aEdge.getLength(); + maLengthArray.push_back(fLength); + + if(++a < mnEdgeCount) + { + aCurrent = aNext; + } + else + { + const B2DPoint aLastNext(rBase.getEndPoint()); + const B2DVector aLastEdge(aLastNext - aNext); + + fLength += aLastEdge.getLength(); + maLengthArray.push_back(fLength); + break; + } + } + } + else + { + maLengthArray.clear(); + maLengthArray.push_back(rBase.getEdgeLength()); + mnEdgeCount = 1; + } + } + + double B2DCubicBezierHelper::distanceToRelative(double fDistance) const + { + if(fDistance <= 0.0) + { + return 0.0; + } + + const double fLength(getLength()); + + if(fTools::moreOrEqual(fDistance, fLength)) + { + return 1.0; + } + + // fDistance is in ]0.0 .. fLength[ + + if(1 == mnEdgeCount) + { + // not a bezier, linear edge + return fDistance / fLength; + } + + // it is a bezier + ::std::vector< double >::const_iterator aIter = ::std::lower_bound(maLengthArray.begin(), maLengthArray.end(), fDistance); + const sal_uInt32 nIndex(aIter - maLengthArray.begin()); + const double fHighBound(maLengthArray[nIndex]); + const double fLowBound(nIndex ? maLengthArray[nIndex - 1] : 0.0); + const double fLinearInterpolatedLength((fDistance - fLowBound) / (fHighBound - fLowBound)); + + return (static_cast< double >(nIndex) + fLinearInterpolatedLength) / static_cast< double >(mnEdgeCount); + } + + double B2DCubicBezierHelper::relativeToDistance(double fRelative) const + { + if(fRelative <= 0.0) + { + return 0.0; + } + + const double fLength(getLength()); + + if(fTools::moreOrEqual(fRelative, 1.0)) + { + return fLength; + } + + // fRelative is in ]0.0 .. 1.0[ + + if(1 == mnEdgeCount) + { + // not a bezier, linear edge + return fRelative * fLength; + } + + // fRelative is in ]0.0 .. 1.0[ + const double fIndex(fRelative * static_cast< double >(mnEdgeCount)); + double fIntIndex; + const double fFractIndex(modf(fIndex, &fIntIndex)); + const sal_uInt32 nIntIndex(static_cast< sal_uInt32 >(fIntIndex)); + const double fStartDistance(nIntIndex ? maLengthArray[nIntIndex - 1] : 0.0); + + return fStartDistance + ((maLengthArray[nIntIndex] - fStartDistance) * fFractIndex); + } +} // end of namespace basegfx ////////////////////////////////////////////////////////////////////////////// -// necessary stuff moved to B2DCubicBezier // eof |