update dev300-m58
[ooovba.git] / basegfx / source / tools / debugplotter.cxx
blob5e574254ca98766c9fdb58e9566e27cc12f31083
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: debugplotter.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_basegfx.hxx"
33 #include <osl/diagnose.h>
35 #include <basegfx/curve/b2dcubicbezier.hxx>
37 #include <basegfx/tools/debugplotter.hxx>
38 #include <boost/bind.hpp>
41 namespace basegfx
43 namespace
45 void outputHeader( const ::rtl::OString& rTitle,
46 ::std::ostream* pStm )
48 // output gnuplot setup
49 if( pStm )
51 *pStm << "#!/usr/bin/gnuplot -persist" << ::std::endl <<
52 "#" << ::std::endl <<
53 "# automatically generated by basegfx, don't change!" << ::std::endl <<
54 "#" << ::std::endl <<
55 "# --- " << (const sal_Char*)rTitle << " ---" << ::std::endl <<
56 "#" << ::std::endl <<
57 "set parametric" << ::std::endl <<
58 "# set terminal postscript eps enhanced color " << ::std::endl <<
59 "# set output \"plot.eps\"" << ::std::endl <<
60 // This function plots a cubic bezier curve. P,q,r,s
61 // are the control point elements of the corresponding
62 // output coordinate component (i.e. x components for
63 // the x plot, and y components for the y plot)
64 "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 <<
65 // This function plots the derivative of a cubic
66 // bezier curve. P,q,r,s are the control point
67 // components of the _original_ curve
68 "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 <<
69 // Plot a line's component of a line between a and b
70 // (where a and b should be the corresponding
71 // components of the line's start and end point,
72 // respectively)
73 "line(p,q,r) = p*(1-t)+q*t" << ::std::endl <<
74 // Plot a line's x component of a line in implicit
75 // form ax + by + c = 0
76 "implicitLineX(a,b,c,t) = a*-c + t*-b" << ::std::endl <<
77 // Plot a line's y component of a line in implicit
78 // form ax + by + c = 0
79 "implicitLineY(a,b,c,t) = b*-c + t*a" << ::std::endl <<
80 "pointmarkx(c,t) = c-0.03*t" << ::std::endl << // hack for displaying single points in parametric form
81 "pointmarky(c,t) = c+0.03*t" << ::std::endl << // hack for displaying single points in parametric form
82 "# end of setup" << ::std::endl;
84 else
86 OSL_TRACE( "#!/usr/bin/gnuplot -persist\n",
87 "#\n",
88 "# automatically generated by basegfx, don't change!\n",
89 "#\n",
90 "# --- %s ---\n",
91 "#\n",
92 "set parametric\n",
93 // This function plots a cubic bezier curve. P,q,r,s
94 // are the control point elements of the corresponding
95 // output coordinate component (i.e. x components for
96 // the x plot, and y components for the y plot)
97 "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\n",
98 // This function plots the derivative of a cubic
99 // bezier curve. P,q,r,s are the control point
100 // components of the _original_ curve
101 "cubicBezDerivative(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2\n",
102 // Plot a line's component of a line between a and b
103 // (where a and b should be the corresponding
104 // components of the line's start and end point,
105 // respectively)
106 "line(p,q,r) = p*(1-t)+q*t\n",
107 // Plot a line's x component of a line in implicit
108 // form ax + by + c = 0
109 "implicitLineX(a,b,c,t) = a*-c + t*-b\n",
110 // Plot a line's y component of a line in implicit
111 // form ax + by + c = 0
112 "implicitLineY(a,b,c,t) = b*-c + t*a\n",
113 "pointmarkx(c,t) = c-0.03*t\n", // hack for displaying single points in parametric form
114 "pointmarky(c,t) = c+0.03*t\n", // hack for displaying single points in parametric form
115 "# end of setup\n",
116 (const sal_Char*)rTitle );
120 class Writer
122 public:
123 Writer( ::std::ostream* pStm ) :
124 mpStream( pStm )
128 void outputPoint( const ::std::pair< B2DPoint, ::rtl::OString >& rElem )
130 if( mpStream )
131 *mpStream << " " << rElem.first.getX() << "\t" << rElem.first.getY() << ::std::endl;
132 else
133 OSL_TRACE( " %f\t%f\n", rElem.first.getX(), rElem.first.getY() );
136 void outputVector( const ::std::pair< B2DVector, ::rtl::OString >& rElem )
138 if( mpStream )
139 *mpStream << " " << rElem.first.getX() << "\t" << rElem.first.getY() << ::std::endl << ::std::endl;
140 else
141 OSL_TRACE( " %f\t%f\n\n", rElem.first.getX(), rElem.first.getY() );
144 void outputRect( const ::std::pair< B2DRange, ::rtl::OString >& rElem )
146 const double nX0( rElem.first.getMinX() );
147 const double nY0( rElem.first.getMinY() );
148 const double nX1( rElem.first.getMaxX() );
149 const double nY1( rElem.first.getMaxY() );
151 if( mpStream )
152 *mpStream << " "
153 << nX0 << "\t" << nY0 << "\t"
154 << nX1 << "\t" << nY0 << "\t"
155 << nX1 << "\t" << nY1 << "\t"
156 << nX0 << "\t" << nY1 << "\t"
157 << nX0 << "\t" << nY0 << ::std::endl << ::std::endl;
159 else
160 OSL_TRACE( " %f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n\n",
161 nX0, nY0,
162 nX1, nY0,
163 nX1, nY1,
164 nX0, nY1,
165 nX0, nY0 );
168 private:
169 ::std::ostream* mpStream;
173 DebugPlotter::DebugPlotter( const sal_Char* pTitle ) :
174 maTitle( pTitle ),
175 maPoints(),
176 maVectors(),
177 maRanges(),
178 maPolygons(),
179 mpOutputStream(NULL)
183 DebugPlotter::DebugPlotter( const sal_Char* pTitle,
184 ::std::ostream& rOutputStream ) :
185 maTitle( pTitle ),
186 maPoints(),
187 maVectors(),
188 maRanges(),
189 maPolygons(),
190 mpOutputStream(&rOutputStream)
194 DebugPlotter::~DebugPlotter()
196 const bool bHavePoints( !maPoints.empty() );
197 const bool bHaveVectors( !maVectors.empty() );
198 const bool bHaveRanges( !maRanges.empty() );
199 const bool bHavePolygons( !maPolygons.empty() );
201 if( bHavePoints ||
202 bHaveVectors ||
203 bHaveRanges ||
204 bHavePolygons )
206 outputHeader( maTitle, mpOutputStream );
208 print( "\n\n# parametric primitive output\n"
209 "plot [t=0:1] \\\n" );
211 // output plot declarations for used entities
212 bool bNeedColon( false );
213 if( bHavePoints )
215 print( " '-' using ($1):($2) title \"Points\" with points" );
216 bNeedColon = true;
218 if( bHaveVectors )
220 if( bNeedColon )
221 print( ", \\\n" );
223 print( " '-' using ($1):($2) title \"Vectors\" with lp" );
224 bNeedColon = true;
226 if( bHaveRanges )
228 if( bNeedColon )
229 print( ", \\\n" );
231 print( " '-' using ($1):($2) title \"Ranges\" with lines" );
232 bNeedColon = true;
234 if( bHavePolygons )
236 const ::std::size_t nSize( maPolygons.size() );
237 for( ::std::size_t i=0; i<nSize; ++i )
239 if( maPolygons.at(i).first.areControlPointsUsed() )
241 const B2DPolygon& rCurrPoly( maPolygons.at(i).first );
243 const sal_uInt32 nCount( rCurrPoly.count() );
244 for( sal_uInt32 k=0; k<nCount; ++k )
246 if( bNeedColon )
247 print( ", \\\n" );
249 const B2DPoint& rP0( rCurrPoly.getB2DPoint(k) );
250 const B2DPoint& rP1( rCurrPoly.getNextControlPoint(k) );
251 const B2DPoint& rP2( rCurrPoly.getPrevControlPoint((k + 1) % nCount) );
252 const B2DPoint& rP3( k+1<nCount ? rCurrPoly.getB2DPoint(k+1) : rCurrPoly.getB2DPoint(k) );
254 if( mpOutputStream )
255 *mpOutputStream << " cubicBezier("
256 << rP0.getX() << ","
257 << rP1.getX() << ","
258 << rP2.getX() << ","
259 << rP3.getX() << ",t), \\\n cubicBezier("
260 << rP0.getY() << ","
261 << rP1.getY() << ","
262 << rP2.getY() << ","
263 << rP3.getY() << ",t)";
264 else
265 OSL_TRACE( " cubicBezier(%f,%f,%f,%f,t), \\\n"
266 " cubicBezier(%f,%f,%f,%f,t)",
267 rP0.getX(),
268 rP1.getX(),
269 rP2.getX(),
270 rP3.getX(),
271 rP0.getY(),
272 rP1.getY(),
273 rP2.getY(),
274 rP3.getY() );
276 bNeedColon = true;
279 else
281 if( bNeedColon )
282 print( ", \\\n" );
284 if( mpOutputStream )
285 *mpOutputStream << " '-' using ($1):($2) title \"Polygon "
286 << (const sal_Char*)maPolygons.at(i).second << "\" with lp";
287 else
288 OSL_TRACE( " '-' using ($1):($2) title \"Polygon %s\" with lp",
289 (const sal_Char*)maPolygons.at(i).second );
291 bNeedColon = true;
296 if( bHavePoints )
298 Writer aWriter( mpOutputStream );
300 ::std::for_each( maPoints.begin(),
301 maPoints.end(),
302 ::boost::bind( &Writer::outputPoint,
303 ::boost::ref( aWriter ),
304 _1 ) );
305 print( "e\n" );
308 if( bHaveVectors )
310 Writer aWriter( mpOutputStream );
312 ::std::for_each( maVectors.begin(),
313 maVectors.end(),
314 ::boost::bind( &Writer::outputVector,
315 ::boost::ref( aWriter ),
316 _1 ) );
317 print( "e\n" );
320 if( bHaveRanges )
322 Writer aWriter( mpOutputStream );
324 ::std::for_each( maRanges.begin(),
325 maRanges.end(),
326 ::boost::bind( &Writer::outputRect,
327 ::boost::ref( aWriter ),
328 _1 ) );
329 print( "e\n" );
332 if( bHavePolygons )
334 const ::std::size_t nSize( maPolygons.size() );
335 for( ::std::size_t i=0; i<nSize; ++i )
337 if( !maPolygons.at(i).first.areControlPointsUsed() )
339 const B2DPolygon& rCurrPoly( maPolygons.at(i).first );
341 const sal_uInt32 nCount( rCurrPoly.count() );
342 for( sal_uInt32 k=0; k<nCount; ++k )
344 const B2DPoint& rP( rCurrPoly.getB2DPoint(k) );
346 if( mpOutputStream )
347 *mpOutputStream << " " << rP.getX() << "," << rP.getY();
348 else
349 OSL_TRACE( " %f,%f",
350 rP.getX(),
351 rP.getX() );
354 print( "\ne\n" );
361 void DebugPlotter::plot( const B2DPoint& rPoint,
362 const sal_Char* pTitle )
364 maPoints.push_back( ::std::make_pair( rPoint,
365 ::rtl::OString( pTitle ) ) );
368 void DebugPlotter::plot( const B2DVector& rVec,
369 const sal_Char* pTitle )
371 maVectors.push_back( ::std::make_pair( rVec,
372 ::rtl::OString( pTitle ) ) );
375 void DebugPlotter::plot( const B2DCubicBezier& rBezier,
376 const sal_Char* pTitle )
378 B2DPolygon aPoly;
379 aPoly.append(rBezier.getStartPoint());
380 aPoly.appendBezierSegment(rBezier.getControlPointA(), rBezier.getControlPointB(), rBezier.getEndPoint());
381 maPolygons.push_back( ::std::make_pair( aPoly,
382 ::rtl::OString( pTitle ) ) );
385 void DebugPlotter::plot( const B2DRange& rRange,
386 const sal_Char* pTitle )
388 maRanges.push_back( ::std::make_pair( rRange,
389 ::rtl::OString( pTitle ) ) );
392 void DebugPlotter::plot( const B2DPolygon& rPoly,
393 const sal_Char* pTitle )
395 maPolygons.push_back( ::std::make_pair( rPoly,
396 ::rtl::OString( pTitle ) ) );
399 void DebugPlotter::plot( const B2DPolyPolygon& rPoly,
400 const sal_Char* pTitle )
402 const ::rtl::OString aTitle( pTitle );
403 const sal_uInt32 nCount( rPoly.count() );
404 for( sal_uInt32 i=0; i<nCount; ++i )
405 maPolygons.push_back( ::std::make_pair( rPoly.getB2DPolygon( i ),
406 aTitle ) );
409 void DebugPlotter::print( const sal_Char* pStr )
411 if( mpOutputStream )
412 *mpOutputStream << pStr;
413 else
414 OSL_TRACE( pStr );