office-gobmx/basegfx/test/testtools.cxx

235 lines
8.6 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* 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.
*
************************************************************************/
#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 << ", ";
}
}
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */