1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_basegfx.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "testtools.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 34*cdf0e10cSrcweir #include <basegfx/vector/b2dvector.hxx> 35*cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx> 36*cdf0e10cSrcweir #include <basegfx/curve/b2dcubicbezier.hxx> 37*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 38*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx> 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include <algorithm> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir namespace basegfx 44*cdf0e10cSrcweir { 45*cdf0e10cSrcweir namespace testtools 46*cdf0e10cSrcweir { 47*cdf0e10cSrcweir Plotter::Plotter( ::std::ostream& rOutputStream ) : 48*cdf0e10cSrcweir mrOutputStream(rOutputStream), 49*cdf0e10cSrcweir maPoints(), 50*cdf0e10cSrcweir mbFirstElement( true ) 51*cdf0e10cSrcweir { 52*cdf0e10cSrcweir // output gnuplot setup. We switch gnuplot to parametric 53*cdf0e10cSrcweir // mode, therefore every plot has at least _two_ 54*cdf0e10cSrcweir // functions: one for the x and one for the y value, both 55*cdf0e10cSrcweir // depending on t. 56*cdf0e10cSrcweir mrOutputStream << "#!/usr/bin/gnuplot -persist" << ::std::endl 57*cdf0e10cSrcweir << "#" << ::std::endl 58*cdf0e10cSrcweir << "# automatically generated by basegfx::testtools::Plotter, don't change!" << ::std::endl 59*cdf0e10cSrcweir << "#" << ::std::endl 60*cdf0e10cSrcweir << "set parametric" << ::std::endl 61*cdf0e10cSrcweir // This function plots a cubic bezier curve. P,q,r,s 62*cdf0e10cSrcweir // are the control point elements of the corresponding 63*cdf0e10cSrcweir // output coordinate component (i.e. x components for 64*cdf0e10cSrcweir // the x plot, and y components for the y plot) 65*cdf0e10cSrcweir << "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 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir // This function plots the derivative of a cubic 68*cdf0e10cSrcweir // bezier curve. P,q,r,s are the control point 69*cdf0e10cSrcweir // components of the _original_ curve 70*cdf0e10cSrcweir << "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 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir // Plot a line's x component of a line in implicit 73*cdf0e10cSrcweir // form ax + by + c = 0 74*cdf0e10cSrcweir << "implicitLineX(a,b,c,t) = a*-c + t*-b" << ::std::endl 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir // Plot a line's y component of a line in implicit 77*cdf0e10cSrcweir // form ax + by + c = 0 78*cdf0e10cSrcweir << "implicitLineY(a,b,c,t) = b*-c + t*a" << ::std::endl 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir // Plot a line's component of a line between a and b 81*cdf0e10cSrcweir // (where a and b should be the corresponding 82*cdf0e10cSrcweir // components of the line's start and end point, 83*cdf0e10cSrcweir // respectively) 84*cdf0e10cSrcweir << "line(a,b,t) = a*(1-t) + b*t" << ::std::endl << ::std::endl 85*cdf0e10cSrcweir << "# end of setup" << ::std::endl << ::std::endl 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir // Start the actual plot line 88*cdf0e10cSrcweir << "plot [t=0:1] "; 89*cdf0e10cSrcweir } 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir namespace 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir class PointWriter 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir public: 96*cdf0e10cSrcweir PointWriter( ::std::ostream& rOutputStream ) : 97*cdf0e10cSrcweir mrOutputStream( rOutputStream ) 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir void operator()( const B2DPoint& rPoint ) const 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir mrOutputStream << rPoint.getX() << "\t" << rPoint.getY() << ::std::endl; 104*cdf0e10cSrcweir mrOutputStream << "e" << ::std::endl; 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir private: 108*cdf0e10cSrcweir ::std::ostream& mrOutputStream; 109*cdf0e10cSrcweir }; 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir Plotter::~Plotter() 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir // End the plot line 115*cdf0e10cSrcweir mrOutputStream << ::std::endl; 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir // write stored data points. Cannot write before, since 118*cdf0e10cSrcweir // this is an inline dataset, which must be after the plot <...> 119*cdf0e10cSrcweir // line 120*cdf0e10cSrcweir ::std::for_each( maPoints.begin(), maPoints.end(), PointWriter(mrOutputStream) ); 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir void Plotter::plot( const B2DPolygon& rPoly ) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir const sal_uInt32 pointCount( rPoly.count() ); 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir if( pointCount < 1 ) 128*cdf0e10cSrcweir return; 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir if( pointCount == 1 ) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir plot( rPoly.getB2DPoint(0) ); 133*cdf0e10cSrcweir return; 134*cdf0e10cSrcweir } 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir sal_uInt32 i; 137*cdf0e10cSrcweir for( i=0; i<pointCount-1; ++i ) 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir if(rPoly.isNextControlPointUsed(i) || rPoly.isPrevControlPointUsed(i + 1)) 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir const B2DCubicBezier aBezierPlot( 142*cdf0e10cSrcweir rPoly.getB2DPoint(i), rPoly.getNextControlPoint(i), 143*cdf0e10cSrcweir rPoly.getPrevControlPoint(i + 1), rPoly.getB2DPoint(i + 1)); 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir plot(aBezierPlot); 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir else 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir plot( rPoly.getB2DPoint(i), rPoly.getB2DPoint(i+1) ); 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir void Plotter::plot( const B2DPolyPolygon& rPolyPoly ) 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir const sal_uInt32 nPolyCount( rPolyPoly.count() ); 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir sal_uInt32 i; 159*cdf0e10cSrcweir for( i=0; i<nPolyCount; ++i ) 160*cdf0e10cSrcweir { 161*cdf0e10cSrcweir plot( rPolyPoly.getB2DPolygon(i) ); 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir void Plotter::plot( const B2DPoint& rPoint ) 166*cdf0e10cSrcweir { 167*cdf0e10cSrcweir maPoints.push_back( rPoint ); 168*cdf0e10cSrcweir writeSeparator(); 169*cdf0e10cSrcweir mrOutputStream << "'-' using ($1):($2) title \"Point " << maPoints.size() << "\" with points"; 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir void Plotter::plot( const B2DRange& rRect ) 173*cdf0e10cSrcweir { 174*cdf0e10cSrcweir // TODO: do that also as a data file plot. maPoints must 175*cdf0e10cSrcweir // then become polymorph, but WTF. 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir // decompose into four lines 178*cdf0e10cSrcweir plot( B2DPoint(rRect.getMinX(), 179*cdf0e10cSrcweir rRect.getMinY()), 180*cdf0e10cSrcweir B2DPoint(rRect.getMaxX(), 181*cdf0e10cSrcweir rRect.getMinY()) ); 182*cdf0e10cSrcweir plot( B2DPoint(rRect.getMaxX(), 183*cdf0e10cSrcweir rRect.getMinY()), 184*cdf0e10cSrcweir B2DPoint(rRect.getMaxX(), 185*cdf0e10cSrcweir rRect.getMaxY()) ); 186*cdf0e10cSrcweir plot( B2DPoint(rRect.getMaxX(), 187*cdf0e10cSrcweir rRect.getMaxY()), 188*cdf0e10cSrcweir B2DPoint(rRect.getMinX(), 189*cdf0e10cSrcweir rRect.getMaxY()) ); 190*cdf0e10cSrcweir plot( B2DPoint(rRect.getMinX(), 191*cdf0e10cSrcweir rRect.getMaxY()), 192*cdf0e10cSrcweir B2DPoint(rRect.getMinX(), 193*cdf0e10cSrcweir rRect.getMinY()) ); 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir void Plotter::plot( const B2DPoint& rStartPoint, const B2DPoint& rEndPoint ) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir writeSeparator(); 199*cdf0e10cSrcweir mrOutputStream << "line(" << rStartPoint.getX() 200*cdf0e10cSrcweir << "," << rEndPoint.getX() 201*cdf0e10cSrcweir << ",t), " 202*cdf0e10cSrcweir << "line(" << rStartPoint.getY() 203*cdf0e10cSrcweir << "," << rEndPoint.getY() 204*cdf0e10cSrcweir << ",t)"; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir void Plotter::plot( const B2DCubicBezier& rCurve ) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir writeSeparator(); 210*cdf0e10cSrcweir mrOutputStream << "cubicBezier(" << rCurve.getStartPoint().getX() 211*cdf0e10cSrcweir << "," << rCurve.getControlPointA().getX() 212*cdf0e10cSrcweir << "," << rCurve.getControlPointB().getX() 213*cdf0e10cSrcweir << "," << rCurve.getEndPoint().getX() 214*cdf0e10cSrcweir << ",t), " 215*cdf0e10cSrcweir << "cubicBezier(" << rCurve.getStartPoint().getY() 216*cdf0e10cSrcweir << "," << rCurve.getControlPointA().getY() 217*cdf0e10cSrcweir << "," << rCurve.getControlPointB().getY() 218*cdf0e10cSrcweir << "," << rCurve.getEndPoint().getY() 219*cdf0e10cSrcweir << ",t)"; 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir void Plotter::writeSeparator() 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir if( mbFirstElement ) 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir mbFirstElement = false; 227*cdf0e10cSrcweir } 228*cdf0e10cSrcweir else 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir mrOutputStream << ", "; 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir } 236