KiCad PCB EDA Suite
plotter.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
40 #include <trigo.h>
41 #include <eda_item.h>
42 #include <plotters/plotter.h>
45 #include <bezier_curves.h>
46 #include <math/util.h> // for KiROUND
47 
48 
50 {
51  m_plotScale = 1;
52  m_currentPenWidth = -1; // To-be-set marker
53  m_penState = 'Z'; // End-of-path idle
54  m_plotMirror = false; // Plot mirror option flag
55  m_mirrorIsHorizontal = true;
56  m_yaxisReversed = false;
57  m_outputFile = nullptr;
58  m_colorMode = false; // Starts as a BW plot
59  m_negativeMode = false;
60 
61  // Temporary init to avoid not initialized vars, will be set later
62  m_IUsPerDecimil = 1; // will be set later to the actual value
63  m_iuPerDeviceUnit = 1; // will be set later to the actual value
64  m_renderSettings = nullptr;
65 }
66 
67 
69 {
70  // Emergency cleanup, but closing the file is usually made in EndPlot().
71  if( m_outputFile )
72  fclose( m_outputFile );
73 }
74 
75 
76 bool PLOTTER::OpenFile( const wxString& aFullFilename )
77 {
78  m_filename = aFullFilename;
79 
80  wxASSERT( !m_outputFile );
81 
82  // Open the file in text mode (not suitable for all plotters but only for most of them.
83  m_outputFile = wxFopen( m_filename, wxT( "wt" ) );
84 
85  if( m_outputFile == nullptr )
86  return false ;
87 
88  return true;
89 }
90 
91 
92 DPOINT PLOTTER::userToDeviceCoordinates( const wxPoint& aCoordinate )
93 {
94  wxPoint pos = aCoordinate - m_plotOffset;
95 
96  double x = pos.x * m_plotScale;
97  double y = ( m_paperSize.y - pos.y * m_plotScale );
98 
99  if( m_plotMirror )
100  {
102  x = ( m_paperSize.x - pos.x * m_plotScale );
103  else
104  y = pos.y * m_plotScale;
105  }
106 
107  if( m_yaxisReversed )
108  y = m_paperSize.y - y;
109 
110  x *= m_iuPerDeviceUnit;
111  y *= m_iuPerDeviceUnit;
112 
113  return DPOINT( x, y );
114 }
115 
116 
117 DPOINT PLOTTER::userToDeviceSize( const wxSize& size )
118 {
119  return DPOINT( size.x * m_plotScale * m_iuPerDeviceUnit,
120  size.y * m_plotScale * m_iuPerDeviceUnit );
121 }
122 
123 
124 double PLOTTER::userToDeviceSize( double size ) const
125 {
126  return size * m_plotScale * m_iuPerDeviceUnit;
127 }
128 
129 
130 #define IU_PER_MILS ( m_IUsPerDecimil * 10 )
131 
132 
134 {
136 }
137 
138 
140 {
142 }
143 
144 
146 {
148 }
149 
150 
151 void PLOTTER::Arc( const SHAPE_ARC& aArc )
152 {
153  Arc( wxPoint( aArc.GetCenter() ), aArc.GetStartAngle(), aArc.GetEndAngle(), aArc.GetRadius(),
154  FILL_T::NO_FILL, aArc.GetWidth() );
155 }
156 
157 
158 void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius,
159  FILL_T fill, int width )
160 {
161  wxPoint start, end;
162  const int delta = 50; // increment (in 0.1 degrees) to draw circles
163 
164  if( StAngle > EndAngle )
165  std::swap( StAngle, EndAngle );
166 
167  SetCurrentLineWidth( width );
168 
169  /* Please NOTE the different sign due to Y-axis flip */
170  start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) );
171  start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) );
172 
173  if( fill != FILL_T::NO_FILL )
174  {
175  MoveTo( centre );
176  LineTo( start );
177  }
178  else
179  {
180  MoveTo( start );
181  }
182 
183  for( int ii = StAngle + delta; ii < EndAngle; ii += delta )
184  {
185  end.x = centre.x + KiROUND( cosdecideg( radius, -ii ) );
186  end.y = centre.y + KiROUND( sindecideg( radius, -ii ) );
187  LineTo( end );
188  }
189 
190  end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) );
191  end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) );
192 
193  if( fill != FILL_T::NO_FILL )
194  {
195  LineTo( end );
196  FinishTo( centre );
197  }
198  else
199  {
200  FinishTo( end );
201  }
202 }
203 
204 
205 void PLOTTER::BezierCurve( const wxPoint& aStart, const wxPoint& aControl1,
206  const wxPoint& aControl2, const wxPoint& aEnd,
207  int aTolerance, int aLineThickness )
208 {
209  // Generic fallback: Quadratic Bezier curve plotted as a polyline
210  int minSegLen = aLineThickness; // The segment min length to approximate a bezier curve
211 
212  std::vector<wxPoint> ctrlPoints;
213  ctrlPoints.push_back( aStart );
214  ctrlPoints.push_back( aControl1 );
215  ctrlPoints.push_back( aControl2 );
216  ctrlPoints.push_back( aEnd );
217 
218  BEZIER_POLY bezier_converter( ctrlPoints );
219 
220  std::vector<wxPoint> approxPoints;
221  bezier_converter.GetPoly( approxPoints, minSegLen );
222 
223  SetCurrentLineWidth( aLineThickness );
224  MoveTo( aStart );
225 
226  for( unsigned ii = 1; ii < approxPoints.size()-1; ii++ )
227  LineTo( approxPoints[ii] );
228 
229  FinishTo( aEnd );
230 }
231 
232 
233 void PLOTTER::PlotImage(const wxImage& aImage, const wxPoint& aPos, double aScaleFactor )
234 {
235  wxSize size( aImage.GetWidth() * aScaleFactor, aImage.GetHeight() * aScaleFactor );
236 
237  wxPoint start = aPos;
238  start.x -= size.x / 2;
239  start.y -= size.y / 2;
240 
241  wxPoint end = start;
242  end.x += size.x;
243  end.y += size.y;
244 
245  Rect( start, end, FILL_T::NO_FILL );
246 }
247 
248 
249 void PLOTTER::markerSquare( const wxPoint& position, int radius )
250 {
251  double r = KiROUND( radius / 1.4142 );
252  std::vector< wxPoint > corner_list;
253  wxPoint corner;
254  corner.x = position.x + r;
255  corner.y = position.y + r;
256  corner_list.push_back( corner );
257  corner.x = position.x + r;
258  corner.y = position.y - r;
259  corner_list.push_back( corner );
260  corner.x = position.x - r;
261  corner.y = position.y - r;
262  corner_list.push_back( corner );
263  corner.x = position.x - r;
264  corner.y = position.y + r;
265  corner_list.push_back( corner );
266  corner.x = position.x + r;
267  corner.y = position.y + r;
268  corner_list.push_back( corner );
269 
270  PlotPoly( corner_list, FILL_T::NO_FILL, GetCurrentLineWidth() );
271 }
272 
273 
274 void PLOTTER::markerCircle( const wxPoint& position, int radius )
275 {
276  Circle( position, radius * 2, FILL_T::NO_FILL, GetCurrentLineWidth() );
277 }
278 
279 
280 void PLOTTER::markerLozenge( const wxPoint& position, int radius )
281 {
282  std::vector< wxPoint > corner_list;
283  wxPoint corner;
284  corner.x = position.x;
285  corner.y = position.y + radius;
286  corner_list.push_back( corner );
287  corner.x = position.x + radius;
288  corner.y = position.y,
289  corner_list.push_back( corner );
290  corner.x = position.x;
291  corner.y = position.y - radius;
292  corner_list.push_back( corner );
293  corner.x = position.x - radius;
294  corner.y = position.y;
295  corner_list.push_back( corner );
296  corner.x = position.x;
297  corner.y = position.y + radius;
298  corner_list.push_back( corner );
299 
300  PlotPoly( corner_list, FILL_T::NO_FILL, GetCurrentLineWidth() );
301 }
302 
303 
304 void PLOTTER::markerHBar( const wxPoint& pos, int radius )
305 {
306  MoveTo( wxPoint( pos.x - radius, pos.y ) );
307  FinishTo( wxPoint( pos.x + radius, pos.y ) );
308 }
309 
310 
311 void PLOTTER::markerSlash( const wxPoint& pos, int radius )
312 {
313  MoveTo( wxPoint( pos.x - radius, pos.y - radius ) );
314  FinishTo( wxPoint( pos.x + radius, pos.y + radius ) );
315 }
316 
317 
318 void PLOTTER::markerBackSlash( const wxPoint& pos, int radius )
319 {
320  MoveTo( wxPoint( pos.x + radius, pos.y - radius ) );
321  FinishTo( wxPoint( pos.x - radius, pos.y + radius ) );
322 }
323 
324 
325 void PLOTTER::markerVBar( const wxPoint& pos, int radius )
326 {
327  MoveTo( wxPoint( pos.x, pos.y - radius ) );
328  FinishTo( wxPoint( pos.x, pos.y + radius ) );
329 }
330 
331 
332 void PLOTTER::Marker( const wxPoint& position, int diametre, unsigned aShapeId )
333 {
334  int radius = diametre / 2;
335 
336  /* Marker are composed by a series of 'parts' superimposed; not every
337  combination make sense, obviously. Since they are used in order I
338  tried to keep the uglier/more complex constructions at the end.
339  Also I avoided the |/ |\ -/ -\ construction because they're *very*
340  ugly... if needed they could be added anyway... I'd like to see
341  a board with more than 58 drilling/slotting tools!
342  If Visual C++ supported the 0b literals they would be optimally
343  and easily encoded as an integer array. We have to do with octal */
344  static const unsigned char marker_patterns[MARKER_COUNT] = {
345 
346  // Bit order: O Square Lozenge - | \ /
347  // First choice: simple shapes
348  0003, // X
349  0100, // O
350  0014, // +
351  0040, // Sq
352  0020, // Lz
353 
354  // Two simple shapes
355  0103, // X O
356  0017, // X +
357  0043, // X Sq
358  0023, // X Lz
359  0114, // O +
360  0140, // O Sq
361  0120, // O Lz
362  0054, // + Sq
363  0034, // + Lz
364  0060, // Sq Lz
365 
366  // Three simple shapes
367  0117, // X O +
368  0143, // X O Sq
369  0123, // X O Lz
370  0057, // X + Sq
371  0037, // X + Lz
372  0063, // X Sq Lz
373  0154, // O + Sq
374  0134, // O + Lz
375  0074, // + Sq Lz
376 
377  // Four simple shapes
378  0174, // O Sq Lz +
379  0163, // X O Sq Lz
380  0157, // X O Sq +
381  0137, // X O Lz +
382  0077, // X Sq Lz +
383 
384  // This draws *everything *
385  0177, // X O Sq Lz +
386 
387  // Here we use the single bars... so the cross is forbidden
388  0110, // O -
389  0104, // O |
390  0101, // O /
391  0050, // Sq -
392  0044, // Sq |
393  0041, // Sq /
394  0030, // Lz -
395  0024, // Lz |
396  0021, // Lz /
397  0150, // O Sq -
398  0144, // O Sq |
399  0141, // O Sq /
400  0130, // O Lz -
401  0124, // O Lz |
402  0121, // O Lz /
403  0070, // Sq Lz -
404  0064, // Sq Lz |
405  0061, // Sq Lz /
406  0170, // O Sq Lz -
407  0164, // O Sq Lz |
408  0161, // O Sq Lz /
409 
410  // Last resort: the backlash component (easy to confound)
411  0102, // \ O
412  0042, // \ Sq
413  0022, // \ Lz
414  0142, // \ O Sq
415  0122, // \ O Lz
416  0062, // \ Sq Lz
417  0162 // \ O Sq Lz
418  };
419 
420  if( aShapeId >= MARKER_COUNT )
421  {
422  // Fallback shape
423  markerCircle( position, radius );
424  }
425  else
426  {
427  // Decode the pattern and draw the corresponding parts
428  unsigned char pat = marker_patterns[aShapeId];
429 
430  if( pat & 0001 )
431  markerSlash( position, radius );
432 
433  if( pat & 0002 )
434  markerBackSlash( position, radius );
435 
436  if( pat & 0004 )
437  markerVBar( position, radius );
438 
439  if( pat & 0010 )
440  markerHBar( position, radius );
441 
442  if( pat & 0020 )
443  markerLozenge( position, radius );
444 
445  if( pat & 0040 )
446  markerSquare( position, radius );
447 
448  if( pat & 0100 )
449  markerCircle( position, radius );
450  }
451 }
452 
453 
454 void PLOTTER::segmentAsOval( const wxPoint& start, const wxPoint& end, int width,
455  OUTLINE_MODE tracemode )
456 {
457  wxPoint center( (start.x + end.x) / 2, (start.y + end.y) / 2 );
458  wxSize size( end.x - start.x, end.y - start.y );
459  double orient;
460 
461  if( size.y == 0 )
462  orient = 0;
463  else if( size.x == 0 )
464  orient = 900;
465  else
466  orient = -ArcTangente( size.y, size.x );
467 
468  size.x = KiROUND( EuclideanNorm( size ) ) + width;
469  size.y = width;
470 
471  FlashPadOval( center, size, orient, tracemode, nullptr );
472 }
473 
474 
475 void PLOTTER::sketchOval( const wxPoint& pos, const wxSize& aSize, double orient, int width )
476 {
477  SetCurrentLineWidth( width );
478  width = m_currentPenWidth;
479  int radius, deltaxy, cx, cy;
480  wxSize size( aSize );
481 
482  if( size.x > size.y )
483  {
484  std::swap( size.x, size.y );
485  orient = AddAngles( orient, 900 );
486  }
487 
488  deltaxy = size.y - size.x; /* distance between centers of the oval */
489  radius = size.x / 2;
490  cx = -radius;
491  cy = -deltaxy / 2;
492  RotatePoint( &cx, &cy, orient );
493  MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
494  cx = -radius;
495  cy = deltaxy / 2;
496  RotatePoint( &cx, &cy, orient );
497  FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );
498 
499  cx = radius;
500  cy = -deltaxy / 2;
501  RotatePoint( &cx, &cy, orient );
502  MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
503  cx = radius;
504  cy = deltaxy / 2;
505  RotatePoint( &cx, &cy, orient );
506  FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );
507 
508  cx = 0;
509  cy = deltaxy / 2;
510  RotatePoint( &cx, &cy, orient );
511  Arc( wxPoint( cx + pos.x, cy + pos.y ), orient + 1800, orient + 3600, radius, FILL_T::NO_FILL );
512  cx = 0;
513  cy = -deltaxy / 2;
514  RotatePoint( &cx, &cy, orient );
515  Arc( wxPoint( cx + pos.x, cy + pos.y ), orient, orient + 1800, radius, FILL_T::NO_FILL );
516 }
517 
518 
519 void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
520  OUTLINE_MODE tracemode, void* aData )
521 {
522  if( tracemode == FILLED )
523  {
524  if( start == end )
525  {
526  Circle( start, width, FILL_T::FILLED_SHAPE, 0 );
527  }
528  else
529  {
530  SetCurrentLineWidth( width );
531  MoveTo( start );
532  FinishTo( end );
533  }
534  }
535  else
536  {
537  SetCurrentLineWidth( -1 );
538  segmentAsOval( start, end, width, tracemode );
539  }
540 }
541 
542 
543 void PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
544  int radius, int width, OUTLINE_MODE tracemode, void* aData )
545 {
546  if( tracemode == FILLED )
547  {
548  Arc( centre, StAngle, EndAngle, radius, FILL_T::NO_FILL, width );
549  }
550  else
551  {
552  SetCurrentLineWidth( -1 );
553  Arc( centre, StAngle, EndAngle, radius - ( width - m_currentPenWidth ) / 2,
554  FILL_T::NO_FILL, -1 );
555  Arc( centre, StAngle, EndAngle, radius + ( width - m_currentPenWidth ) / 2,
556  FILL_T::NO_FILL, -1 );
557  }
558 }
559 
560 
561 void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
562  OUTLINE_MODE tracemode, void* aData )
563 {
564  if( tracemode == FILLED )
565  {
566  Rect( p1, p2, FILL_T::NO_FILL, width );
567  }
568  else
569  {
570  SetCurrentLineWidth( -1 );
571  wxPoint offsetp1( p1.x - (width - m_currentPenWidth) / 2,
572  p1.y - (width - m_currentPenWidth) / 2 );
573  wxPoint offsetp2( p2.x + (width - m_currentPenWidth) / 2,
574  p2.y + (width - m_currentPenWidth) / 2 );
575  Rect( offsetp1, offsetp2, FILL_T::NO_FILL, -1 );
576  offsetp1.x += ( width - m_currentPenWidth );
577  offsetp1.y += ( width - m_currentPenWidth );
578  offsetp2.x -= ( width - m_currentPenWidth );
579  offsetp2.y -= ( width - m_currentPenWidth );
580  Rect( offsetp1, offsetp2, FILL_T::NO_FILL, -1 );
581  }
582 }
583 
584 
585 void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, OUTLINE_MODE tracemode,
586  void* aData )
587 {
588  if( tracemode == FILLED )
589  {
590  Circle( pos, diametre, FILL_T::NO_FILL, width );
591  }
592  else
593  {
594  SetCurrentLineWidth( -1 );
595  Circle( pos, diametre - width + m_currentPenWidth, FILL_T::NO_FILL, -1 );
596  Circle( pos, diametre + width - m_currentPenWidth, FILL_T::NO_FILL, -1 );
597  }
598 }
599 
600 
601 void PLOTTER::FilledCircle( const wxPoint& pos, int diametre, OUTLINE_MODE tracemode, void* aData )
602 {
603  if( tracemode == FILLED )
604  {
605  Circle( pos, diametre, FILL_T::FILLED_SHAPE, 0 );
606  }
607  else
608  {
609  SetCurrentLineWidth( -1 );
610  Circle( pos, diametre, FILL_T::NO_FILL, -1 );
611  }
612 }
613 
614 
615 void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int aWidth, void* aData )
616 {
617  std::vector<wxPoint> cornerList;
618  cornerList.reserve( aCornerList.PointCount() );
619 
620  for( int ii = 0; ii < aCornerList.PointCount(); ii++ )
621  cornerList.emplace_back( aCornerList.CPoint( ii ) );
622 
623  if( aCornerList.IsClosed() && cornerList.front() != cornerList.back() )
624  cornerList.emplace_back( aCornerList.CPoint( 0 ) );
625 
626  PlotPoly( cornerList, aFill, aWidth, aData );
627 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
void segmentAsOval(const wxPoint &start, const wxPoint &end, int width, OUTLINE_MODE tracemode)
Convert a thick segment and plot it as an oval.
Definition: plotter.cpp:454
void FinishTo(const wxPoint &pos)
Definition: plotter.h:273
OUTLINE_MODE
Definition: outline_mode.h:24
double GetDotMarkLenIU() const
Definition: plotter.cpp:133
void markerHBar(const wxPoint &pos, int radius)
Plot a - bar centered on the position.
Definition: plotter.cpp:304
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:585
wxString m_filename
Definition: plotter.h:600
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr)=0
Draw a polygon ( filled or not ).
void GetPoly(std::vector< wxPoint > &aOutput, int aMinSegLen=0)
Convert a Bezier curve to a polygon.
static const unsigned MARKER_COUNT
Draw a marker (used for the drill map).
Definition: plotter.h:436
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition: plotter.cpp:76
double GetRadius() const
Definition: shape_arc.cpp:452
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, OUTLINE_MODE aTraceMode, void *aData)=0
FILE * m_outputFile
Output file.
Definition: plotter.h:590
double m_iuPerDeviceUnit
Definition: plotter.h:581
virtual void ThickRect(const wxPoint &p1, const wxPoint &p2, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:561
virtual void FilledCircle(const wxPoint &pos, int diametre, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:601
virtual void BezierCurve(const wxPoint &aStart, const wxPoint &aControl1, const wxPoint &aControl2, const wxPoint &aEnd, int aTolerance, int aLineThickness=USE_DEFAULT_LINE_WIDTH)
Generic fallback: Cubic Bezier curve rendered as a polyline In KiCad the bezier curves have 4 control...
Definition: plotter.cpp:205
double GetStartAngle() const
Definition: shape_arc.cpp:404
virtual ~PLOTTER()
Definition: plotter.cpp:68
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
double m_IUsPerDecimil
Definition: plotter.h:579
int PointCount() const
Return the number of points (vertices) in this line chain.
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:519
PLOTTER()
Definition: plotter.cpp:49
FILL_T
Definition: eda_shape.h:53
double GetDashGapLenIU() const
Definition: plotter.cpp:145
double m_plotScale
Plot scale - chosen by the user (even implicitly with 'fit in a4')
Definition: plotter.h:573
virtual int GetCurrentLineWidth() const
Definition: plotter.h:168
bool m_yaxisReversed
Definition: plotter.h:587
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void LineTo(const wxPoint &pos)
Definition: plotter.h:268
bool m_plotMirror
Definition: plotter.h:584
bool m_colorMode
Definition: plotter.h:593
int m_currentPenWidth
Definition: plotter.h:595
bool IsClosed() const override
T AddAngles(T a1, T2 a2)
Add two angles (keeping the result normalized). T2 is here.
Definition: trigo.h:341
constexpr double dot_mark_len(double aLineWidth)
Dashed and dotted line patterns.
RENDER_SETTINGS * m_renderSettings
Definition: plotter.h:607
a few functions useful in geometry calculations.
constexpr double dash_gap_len(double aLineWidth)
virtual DPOINT userToDeviceSize(const wxSize &size)
Modify size according to the plotter scale factors (wxSize version, returns a DPOINT).
Definition: plotter.cpp:117
bool m_negativeMode
Definition: plotter.h:594
E_SERIE r
Definition: eserie.cpp:41
double GetEndAngle() const
Definition: shape_arc.cpp:414
void markerSlash(const wxPoint &pos, int radius)
Plot a / bar centered on the position.
Definition: plotter.cpp:311
void Marker(const wxPoint &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord position.
Definition: plotter.cpp:332
void MoveTo(const wxPoint &pos)
Definition: plotter.h:263
virtual DPOINT userToDeviceCoordinates(const wxPoint &aCoordinate)
Modify coordinates according to the orientation, scale factor, and offsets trace.
Definition: plotter.cpp:92
double cosdecideg(double r, double a)
Circle generation utility: computes r * cos(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:452
Bezier curves to polygon converter.
Definition: bezier_curves.h:36
virtual void PlotImage(const wxImage &aImage, const wxPoint &aPos, double aScaleFactor)
Only PostScript plotters can plot bitmaps.
Definition: plotter.cpp:233
double sindecideg(double r, double a)
Circle generation utility: computes r * sin(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:443
int GetWidth() const
Definition: shape_arc.h:156
wxPoint m_plotOffset
Definition: plotter.h:583
double GetDashMarkLenIU() const
Definition: plotter.cpp:139
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void markerLozenge(const wxPoint &position, int radius)
Plot a lozenge centered on the position.
Definition: plotter.cpp:280
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
void markerCircle(const wxPoint &pos, int radius)
Plot a circle centered on the position.
Definition: plotter.cpp:274
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
char m_penState
Definition: plotter.h:596
virtual void ThickArc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:543
virtual void Arc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)
Generic fallback: arc rendered as a polyline.
Definition: plotter.cpp:158
constexpr int delta
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:183
VECTOR2< double > DPOINT
Definition: vector2d.h:645
void markerVBar(const wxPoint &pos, int radius)
Plot a | bar centered on the position.
Definition: plotter.cpp:325
wxSize m_paperSize
Definition: plotter.h:603
void markerSquare(const wxPoint &position, int radius)
Plot a square centered on the position.
Definition: plotter.cpp:249
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
void markerBackSlash(const wxPoint &pos, int radius)
Plot a \ bar centered on the position.
Definition: plotter.cpp:318
void sketchOval(const wxPoint &pos, const wxSize &size, double orient, int width)
Definition: plotter.cpp:475
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:424
virtual void Circle(const wxPoint &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
constexpr double dash_mark_len(double aLineWidth)
bool m_mirrorIsHorizontal
Definition: plotter.h:586