diff options
Diffstat (limited to 'basegfx/test/testtools.cxx')
-rw-r--r-- | basegfx/test/testtools.cxx | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/basegfx/test/testtools.cxx b/basegfx/test/testtools.cxx new file mode 100644 index 000000000000..e96eb4d8edce --- /dev/null +++ b/basegfx/test/testtools.cxx @@ -0,0 +1,235 @@ +/************************************************************************* + * + * 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 "testtools.hxx" + +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/curve/b2dcubicbezier.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> + +#include <algorithm> + + +namespace basegfx +{ + namespace testtools + { + Plotter::Plotter( ::std::ostream& rOutputStream ) : + mrOutputStream(rOutputStream), + maPoints(), + mbFirstElement( true ) + { + // output gnuplot setup. We switch gnuplot to parametric + // mode, therefore every plot has at least _two_ + // functions: one for the x and one for the y value, both + // depending on t. + mrOutputStream << "#!/usr/bin/gnuplot -persist" << ::std::endl + << "#" << ::std::endl + << "# automatically generated by basegfx::testtools::Plotter, don't change!" << ::std::endl + << "#" << ::std::endl + << "set parametric" << ::std::endl + // This function plots a cubic bezier curve. P,q,r,s + // are the control point elements of the corresponding + // output coordinate component (i.e. x components for + // the x plot, and y components for the y plot) + << "cubicBezier(p,q,r,s,t) = p*(1-t)**3+q*3*(1-t)**2*t+r*3*(1-t)*t**2+s*t**3" << ::std::endl + + // This function plots the derivative of a cubic + // bezier curve. P,q,r,s are the control point + // components of the _original_ curve + << "cubicBezDerivative(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2" << ::std::endl + + // Plot a line's x component of a line in implicit + // form ax + by + c = 0 + << "implicitLineX(a,b,c,t) = a*-c + t*-b" << ::std::endl + + // Plot a line's y component of a line in implicit + // form ax + by + c = 0 + << "implicitLineY(a,b,c,t) = b*-c + t*a" << ::std::endl + + // Plot a line's component of a line between a and b + // (where a and b should be the corresponding + // components of the line's start and end point, + // respectively) + << "line(a,b,t) = a*(1-t) + b*t" << ::std::endl << ::std::endl + << "# end of setup" << ::std::endl << ::std::endl + + // Start the actual plot line + << "plot [t=0:1] "; + } + + namespace + { + class PointWriter + { + public: + PointWriter( ::std::ostream& rOutputStream ) : + mrOutputStream( rOutputStream ) + { + } + + void operator()( const B2DPoint& rPoint ) const + { + mrOutputStream << rPoint.getX() << "\t" << rPoint.getY() << ::std::endl; + mrOutputStream << "e" << ::std::endl; + } + + private: + ::std::ostream& mrOutputStream; + }; + } + + Plotter::~Plotter() + { + // End the plot line + mrOutputStream << ::std::endl; + + // write stored data points. Cannot write before, since + // this is an inline dataset, which must be after the plot <...> + // line + ::std::for_each( maPoints.begin(), maPoints.end(), PointWriter(mrOutputStream) ); + } + + void Plotter::plot( const B2DPolygon& rPoly ) + { + const sal_uInt32 pointCount( rPoly.count() ); + + if( pointCount < 1 ) + return; + + if( pointCount == 1 ) + { + plot( rPoly.getB2DPoint(0) ); + return; + } + + sal_uInt32 i; + for( i=0; i<pointCount-1; ++i ) + { + if(rPoly.isNextControlPointUsed(i) || rPoly.isPrevControlPointUsed(i + 1)) + { + const B2DCubicBezier aBezierPlot( + rPoly.getB2DPoint(i), rPoly.getNextControlPoint(i), + rPoly.getPrevControlPoint(i + 1), rPoly.getB2DPoint(i + 1)); + + plot(aBezierPlot); + } + else + { + plot( rPoly.getB2DPoint(i), rPoly.getB2DPoint(i+1) ); + } + } + } + + void Plotter::plot( const B2DPolyPolygon& rPolyPoly ) + { + const sal_uInt32 nPolyCount( rPolyPoly.count() ); + + sal_uInt32 i; + for( i=0; i<nPolyCount; ++i ) + { + plot( rPolyPoly.getB2DPolygon(i) ); + } + } + + void Plotter::plot( const B2DPoint& rPoint ) + { + maPoints.push_back( rPoint ); + writeSeparator(); + mrOutputStream << "'-' using ($1):($2) title \"Point " << maPoints.size() << "\" with points"; + } + + void Plotter::plot( const B2DRange& rRect ) + { + // TODO: do that also as a data file plot. maPoints must + // then become polymorph, but WTF. + + // decompose into four lines + plot( B2DPoint(rRect.getMinX(), + rRect.getMinY()), + B2DPoint(rRect.getMaxX(), + rRect.getMinY()) ); + plot( B2DPoint(rRect.getMaxX(), + rRect.getMinY()), + B2DPoint(rRect.getMaxX(), + rRect.getMaxY()) ); + plot( B2DPoint(rRect.getMaxX(), + rRect.getMaxY()), + B2DPoint(rRect.getMinX(), + rRect.getMaxY()) ); + plot( B2DPoint(rRect.getMinX(), + rRect.getMaxY()), + B2DPoint(rRect.getMinX(), + rRect.getMinY()) ); + } + + void Plotter::plot( const B2DPoint& rStartPoint, const B2DPoint& rEndPoint ) + { + writeSeparator(); + mrOutputStream << "line(" << rStartPoint.getX() + << "," << rEndPoint.getX() + << ",t), " + << "line(" << rStartPoint.getY() + << "," << rEndPoint.getY() + << ",t)"; + } + + void Plotter::plot( const B2DCubicBezier& rCurve ) + { + writeSeparator(); + mrOutputStream << "cubicBezier(" << rCurve.getStartPoint().getX() + << "," << rCurve.getControlPointA().getX() + << "," << rCurve.getControlPointB().getX() + << "," << rCurve.getEndPoint().getX() + << ",t), " + << "cubicBezier(" << rCurve.getStartPoint().getY() + << "," << rCurve.getControlPointA().getY() + << "," << rCurve.getControlPointB().getY() + << "," << rCurve.getEndPoint().getY() + << ",t)"; + } + + void Plotter::writeSeparator() + { + if( mbFirstElement ) + { + mbFirstElement = false; + } + else + { + mrOutputStream << ", "; + } + } + + } +} |