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