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-2020 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 <fill_type.h>
41 #include <vector>
42 #include <trigo.h>
43 #include <eda_item.h>
44 #include <plotter.h>
47 #include <bezier_curves.h>
48 #include <math/util.h> // for KiROUND
49 
51 {
52  m_plotScale = 1;
53  m_currentPenWidth = -1; // To-be-set marker
54  m_penState = 'Z'; // End-of-path idle
55  m_plotMirror = false; // Plot mirror option flag
56  m_mirrorIsHorizontal = true;
57  m_yaxisReversed = false;
58  m_outputFile = nullptr;
59  m_colorMode = false; // Starts as a BW plot
60  m_negativeMode = false;
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 
68 {
69  // Emergency cleanup, but closing the file is
70  // 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
83  // but only for most of them
84  m_outputFile = wxFopen( m_filename, wxT( "wt" ) );
85 
86  if( m_outputFile == NULL )
87  return false ;
88 
89  return true;
90 }
91 
92 
93 DPOINT PLOTTER::userToDeviceCoordinates( const wxPoint& aCoordinate )
94 {
95  wxPoint pos = aCoordinate - m_plotOffset;
96 
97  // Don't allow overflows; they can cause rendering failures in some file viewers
98  // (such as Acrobat)
99  int clampSize = MAX_PAGE_SIZE_MILS * m_IUsPerDecimil * 10 / 2;
100  pos.x = std::max( -clampSize, std::min( pos.x, clampSize ) );
101  pos.y = std::max( -clampSize, std::min( pos.y, clampSize ) );
102 
103  double x = pos.x * m_plotScale;
104  double y = ( m_paperSize.y - pos.y * m_plotScale );
105 
106  if( m_plotMirror )
107  {
109  x = ( m_paperSize.x - pos.x * m_plotScale );
110  else
111  y = pos.y * m_plotScale;
112  }
113 
114  if( m_yaxisReversed )
115  y = m_paperSize.y - y;
116 
117  x *= m_iuPerDeviceUnit;
118  y *= m_iuPerDeviceUnit;
119 
120  return DPOINT( x, y );
121 }
122 
123 
124 DPOINT PLOTTER::userToDeviceSize( const wxSize& size )
125 {
126  return DPOINT( size.x * m_plotScale * m_iuPerDeviceUnit,
127  size.y * m_plotScale * m_iuPerDeviceUnit );
128 }
129 
130 
131 double PLOTTER::userToDeviceSize( double size ) const
132 {
133  return size * m_plotScale * m_iuPerDeviceUnit;
134 }
135 
136 
137 #define IU_PER_MILS ( m_IUsPerDecimil * 10 )
138 
140 {
142 }
143 
144 
146 {
148 }
149 
150 
152 {
154 }
155 
156 
157 void PLOTTER::Arc( const SHAPE_ARC& aArc )
158 {
159  Arc( wxPoint( aArc.GetCenter() ), aArc.GetStartAngle(), aArc.GetEndAngle(), aArc.GetRadius(),
160  FILL_TYPE::NO_FILL, aArc.GetWidth() );
161 }
162 
163 
164 void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius,
165  FILL_TYPE fill, int width )
166 {
167  wxPoint start, end;
168  const int delta = 50; // increment (in 0.1 degrees) to draw circles
169 
170  if( StAngle > EndAngle )
171  std::swap( StAngle, EndAngle );
172 
173  SetCurrentLineWidth( width );
174  /* Please NOTE the different sign due to Y-axis flip */
175  start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) );
176  start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) );
177 
178  if( fill != FILL_TYPE::NO_FILL )
179  {
180  MoveTo( centre );
181  LineTo( start );
182  }
183  else
184  {
185  MoveTo( start );
186  }
187 
188  for( int ii = StAngle + delta; ii < EndAngle; ii += delta )
189  {
190  end.x = centre.x + KiROUND( cosdecideg( radius, -ii ) );
191  end.y = centre.y + KiROUND( sindecideg( radius, -ii ) );
192  LineTo( end );
193  }
194 
195  end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) );
196  end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) );
197 
198  if( fill != FILL_TYPE::NO_FILL )
199  {
200  LineTo( end );
201  FinishTo( centre );
202  }
203  else
204  {
205  FinishTo( end );
206  }
207 }
208 
209 
210 void PLOTTER::BezierCurve( const wxPoint& aStart, const wxPoint& aControl1,
211  const wxPoint& aControl2, const wxPoint& aEnd,
212  int aTolerance, int aLineThickness )
213 {
214  // Generic fallback: Quadratic Bezier curve plotted as a polyline
215  int minSegLen = aLineThickness; // The segment min length to approximate a bezier curve
216 
217  std::vector<wxPoint> ctrlPoints;
218  ctrlPoints.push_back( aStart );
219  ctrlPoints.push_back( aControl1 );
220  ctrlPoints.push_back( aControl2 );
221  ctrlPoints.push_back( aEnd );
222 
223  BEZIER_POLY bezier_converter( ctrlPoints );
224 
225  std::vector<wxPoint> approxPoints;
226  bezier_converter.GetPoly( approxPoints, minSegLen );
227 
228  SetCurrentLineWidth( aLineThickness );
229  MoveTo( aStart );
230 
231  for( unsigned ii = 1; ii < approxPoints.size()-1; ii++ )
232  LineTo( approxPoints[ii] );
233 
234  FinishTo( aEnd );
235 }
236 
237 
238 void PLOTTER::PlotImage(const wxImage & aImage, const wxPoint& aPos, double aScaleFactor )
239 {
240  wxSize size( aImage.GetWidth() * aScaleFactor,
241  aImage.GetHeight() * aScaleFactor );
242 
243  wxPoint start = aPos;
244  start.x -= size.x / 2;
245  start.y -= size.y / 2;
246 
247  wxPoint end = start;
248  end.x += size.x;
249  end.y += size.y;
250 
251  Rect( start, end, FILL_TYPE::NO_FILL );
252 }
253 
254 
255 void PLOTTER::markerSquare( const wxPoint& position, int radius )
256 {
257  double r = KiROUND( radius / 1.4142 );
258  std::vector< wxPoint > corner_list;
259  wxPoint 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  corner.x = position.x - r;
270  corner.y = position.y + r;
271  corner_list.push_back( corner );
272  corner.x = position.x + r;
273  corner.y = position.y + r;
274  corner_list.push_back( corner );
275 
277 }
278 
279 
280 void PLOTTER::markerCircle( const wxPoint& position, int radius )
281 {
282  Circle( position, radius * 2, FILL_TYPE::NO_FILL, GetCurrentLineWidth() );
283 }
284 
285 
286 void PLOTTER::markerLozenge( const wxPoint& position, int radius )
287 {
288  std::vector< wxPoint > corner_list;
289  wxPoint 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  corner.x = position.x - radius;
300  corner.y = position.y;
301  corner_list.push_back( corner );
302  corner.x = position.x;
303  corner.y = position.y + radius;
304  corner_list.push_back( corner );
305 
307 }
308 
309 
310 void PLOTTER::markerHBar( const wxPoint& pos, int radius )
311 {
312  MoveTo( wxPoint( pos.x - radius, pos.y ) );
313  FinishTo( wxPoint( pos.x + radius, pos.y ) );
314 }
315 
316 
317 void PLOTTER::markerSlash( const wxPoint& pos, int radius )
318 {
319  MoveTo( wxPoint( pos.x - radius, pos.y - radius ) );
320  FinishTo( wxPoint( pos.x + radius, pos.y + radius ) );
321 }
322 
323 
324 void PLOTTER::markerBackSlash( const wxPoint& pos, int radius )
325 {
326  MoveTo( wxPoint( pos.x + radius, pos.y - radius ) );
327  FinishTo( wxPoint( pos.x - radius, pos.y + radius ) );
328 }
329 
330 
331 void PLOTTER::markerVBar( const wxPoint& pos, int radius )
332 {
333  MoveTo( wxPoint( pos.x, pos.y - radius ) );
334  FinishTo( wxPoint( pos.x, pos.y + radius ) );
335 }
336 
337 
338 void PLOTTER::Marker( const wxPoint& position, int diametre, unsigned aShapeId )
339 {
340  int radius = diametre / 2;
341  /* Marker are composed by a series of 'parts' superimposed; not every
342  combination make sense, obviously. Since they are used in order I
343  tried to keep the uglier/more complex constructions at the end.
344  Also I avoided the |/ |\ -/ -\ construction because they're *very*
345  ugly... if needed they could be added anyway... I'd like to see
346  a board with more than 58 drilling/slotting tools!
347  If Visual C++ supported the 0b literals they would be optimally
348  and easily encoded as an integer array. We have to do with octal */
349  static const unsigned char marker_patterns[MARKER_COUNT] = {
350  // Bit order: O Square Lozenge - | \ /
351  // First choice: simple shapes
352  0003, // X
353  0100, // O
354  0014, // +
355  0040, // Sq
356  0020, // Lz
357  // Two simple shapes
358  0103, // X O
359  0017, // X +
360  0043, // X Sq
361  0023, // X Lz
362  0114, // O +
363  0140, // O Sq
364  0120, // O Lz
365  0054, // + Sq
366  0034, // + Lz
367  0060, // Sq Lz
368  // Three simple shapes
369  0117, // X O +
370  0143, // X O Sq
371  0123, // X O Lz
372  0057, // X + Sq
373  0037, // X + Lz
374  0063, // X Sq Lz
375  0154, // O + Sq
376  0134, // O + Lz
377  0074, // + Sq Lz
378  // Four simple shapes
379  0174, // O Sq Lz +
380  0163, // X O Sq Lz
381  0157, // X O Sq +
382  0137, // X O Lz +
383  0077, // X Sq Lz +
384  // This draws *everything *
385  0177, // X O Sq Lz +
386  // Here we use the single bars... so the cross is forbidden
387  0110, // O -
388  0104, // O |
389  0101, // O /
390  0050, // Sq -
391  0044, // Sq |
392  0041, // Sq /
393  0030, // Lz -
394  0024, // Lz |
395  0021, // Lz /
396  0150, // O Sq -
397  0144, // O Sq |
398  0141, // O Sq /
399  0130, // O Lz -
400  0124, // O Lz |
401  0121, // O Lz /
402  0070, // Sq Lz -
403  0064, // Sq Lz |
404  0061, // Sq Lz /
405  0170, // O Sq Lz -
406  0164, // O Sq Lz |
407  0161, // O Sq Lz /
408  // Last resort: the backlash component (easy to confound)
409  0102, // \ O
410  0042, // \ Sq
411  0022, // \ Lz
412  0142, // \ O Sq
413  0122, // \ O Lz
414  0062, // \ Sq Lz
415  0162 // \ O Sq Lz
416  };
417  if( aShapeId >= MARKER_COUNT )
418  {
419  // Fallback shape
420  markerCircle( position, radius );
421  }
422  else
423  {
424  // Decode the pattern and draw the corresponding parts
425  unsigned char pat = marker_patterns[aShapeId];
426  if( pat & 0001 )
427  markerSlash( position, radius );
428  if( pat & 0002 )
429  markerBackSlash( position, radius );
430  if( pat & 0004 )
431  markerVBar( position, radius );
432  if( pat & 0010 )
433  markerHBar( position, radius );
434  if( pat & 0020 )
435  markerLozenge( position, radius );
436  if( pat & 0040 )
437  markerSquare( position, radius );
438  if( pat & 0100 )
439  markerCircle( position, radius );
440  }
441 }
442 
443 
444 void PLOTTER::segmentAsOval( const wxPoint& start, const wxPoint& end, int width,
445  OUTLINE_MODE tracemode )
446 {
447  wxPoint center( (start.x + end.x) / 2, (start.y + end.y) / 2 );
448  wxSize size( end.x - start.x, end.y - start.y );
449  double orient;
450 
451  if( size.y == 0 )
452  orient = 0;
453  else if( size.x == 0 )
454  orient = 900;
455  else
456  orient = -ArcTangente( size.y, size.x );
457 
458  size.x = KiROUND( EuclideanNorm( size ) ) + width;
459  size.y = width;
460 
461  FlashPadOval( center, size, orient, tracemode, NULL );
462 }
463 
464 
465 void PLOTTER::sketchOval( const wxPoint& pos, const wxSize& aSize, double orient, int width )
466 {
467  SetCurrentLineWidth( width );
468  width = m_currentPenWidth;
469  int radius, deltaxy, cx, cy;
470  wxSize size( aSize );
471 
472  if( size.x > size.y )
473  {
474  std::swap( size.x, size.y );
475  orient = AddAngles( orient, 900 );
476  }
477 
478  deltaxy = size.y - size.x; /* distance between centers of the oval */
479  radius = ( size.x - width ) / 2;
480  cx = -radius;
481  cy = -deltaxy / 2;
482  RotatePoint( &cx, &cy, orient );
483  MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
484  cx = -radius;
485  cy = deltaxy / 2;
486  RotatePoint( &cx, &cy, orient );
487  FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );
488 
489  cx = radius;
490  cy = -deltaxy / 2;
491  RotatePoint( &cx, &cy, orient );
492  MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
493  cx = radius;
494  cy = deltaxy / 2;
495  RotatePoint( &cx, &cy, orient );
496  FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );
497 
498  cx = 0;
499  cy = deltaxy / 2;
500  RotatePoint( &cx, &cy, orient );
501  Arc( wxPoint( cx + pos.x, cy + pos.y ),
502  orient + 1800, orient + 3600,
503  radius, FILL_TYPE::NO_FILL );
504  cx = 0;
505  cy = -deltaxy / 2;
506  RotatePoint( &cx, &cy, orient );
507  Arc( wxPoint( cx + pos.x, cy + pos.y ),
508  orient, orient + 1800,
509  radius, FILL_TYPE::NO_FILL );
510 }
511 
512 
513 void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
514  OUTLINE_MODE tracemode, void* aData )
515 {
516  if( tracemode == FILLED )
517  {
518  if( start == end )
519  {
520  Circle( start, width, FILL_TYPE::FILLED_SHAPE, 0 );
521  }
522  else
523  {
524  SetCurrentLineWidth( width );
525  MoveTo( start );
526  FinishTo( end );
527  }
528  }
529  else
530  {
531  SetCurrentLineWidth( -1 );
532  segmentAsOval( start, end, width, tracemode );
533  }
534 }
535 
536 
537 void PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
538  int radius, int width, OUTLINE_MODE tracemode, void* aData )
539 {
540  if( tracemode == FILLED )
541  Arc( centre, StAngle, EndAngle, radius, FILL_TYPE::NO_FILL, width );
542  else
543  {
544  SetCurrentLineWidth( -1 );
545  Arc( centre, StAngle, EndAngle,
546  radius - ( width - m_currentPenWidth ) / 2, FILL_TYPE::NO_FILL, -1 );
547  Arc( centre, StAngle, EndAngle,
548  radius + ( width - m_currentPenWidth ) / 2, FILL_TYPE::NO_FILL, -1 );
549  }
550 }
551 
552 
553 void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
554  OUTLINE_MODE tracemode, void* aData )
555 {
556  if( tracemode == FILLED )
557  Rect( p1, p2, FILL_TYPE::NO_FILL, width );
558  else
559  {
560  SetCurrentLineWidth( -1 );
561  wxPoint offsetp1( p1.x - (width - m_currentPenWidth) / 2,
562  p1.y - (width - m_currentPenWidth) / 2 );
563  wxPoint offsetp2( p2.x + (width - m_currentPenWidth) / 2,
564  p2.y + (width - m_currentPenWidth) / 2 );
565  Rect( offsetp1, offsetp2, FILL_TYPE::NO_FILL, -1 );
566  offsetp1.x += (width - m_currentPenWidth);
567  offsetp1.y += (width - m_currentPenWidth);
568  offsetp2.x -= (width - m_currentPenWidth);
569  offsetp2.y -= (width - m_currentPenWidth);
570  Rect( offsetp1, offsetp2, FILL_TYPE::NO_FILL, -1 );
571  }
572 }
573 
574 
575 void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, OUTLINE_MODE tracemode,
576  void* aData )
577 {
578  if( tracemode == FILLED )
579  {
580  Circle( pos, diametre, FILL_TYPE::NO_FILL, width );
581  }
582  else
583  {
584  SetCurrentLineWidth( -1 );
585  Circle( pos, diametre - width + m_currentPenWidth, FILL_TYPE::NO_FILL, -1 );
586  Circle( pos, diametre + width - m_currentPenWidth, FILL_TYPE::NO_FILL, -1 );
587  }
588 }
589 
590 
591 void PLOTTER::FilledCircle( const wxPoint& pos, int diametre, OUTLINE_MODE tracemode, void* aData )
592 {
593  if( tracemode == FILLED )
594  {
595  Circle( pos, diametre, FILL_TYPE::FILLED_SHAPE, 0 );
596  }
597  else
598  {
599  SetCurrentLineWidth( -1 );
600  Circle( pos, diametre, FILL_TYPE::NO_FILL, -1 );
601  }
602 }
603 
604 
605 void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_TYPE aFill,
606  int aWidth, void * aData )
607 {
608  std::vector<wxPoint> cornerList;
609  cornerList.reserve( aCornerList.PointCount() );
610 
611  for( int ii = 0; ii < aCornerList.PointCount(); ii++ )
612  cornerList.emplace_back( aCornerList.CPoint( ii ) );
613 
614  if( aCornerList.IsClosed() && cornerList.front() != cornerList.back() )
615  cornerList.emplace_back( aCornerList.CPoint( 0 ) );
616 
617  PlotPoly( cornerList, aFill, aWidth, aData );
618 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
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:444
void FinishTo(const wxPoint &pos)
Definition: plotter.h:273
OUTLINE_MODE
Definition: outline_mode.h:24
double GetDotMarkLenIU() const
Definition: plotter.cpp:139
void markerHBar(const wxPoint &pos, int radius)
Plot a - bar centered on the position.
Definition: plotter.cpp:310
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_TYPE aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr)=0
Draw a polygon ( filled or not ).
FILL_TYPE
The set of fill types used in plotting or drawing enclosed areas.
Definition: fill_type.h:28
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:575
wxString m_filename
Definition: plotter.h:600
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_TYPE fill, int width=USE_DEFAULT_LINE_WIDTH)=0
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:411
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:553
virtual void FilledCircle(const wxPoint &pos, int diametre, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:591
#define DASH_MARK_LEN(aLineWidth)
virtual void Arc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, FILL_TYPE fill, int width=USE_DEFAULT_LINE_WIDTH)
Generic fallback: arc rendered as a polyline.
Definition: plotter.cpp:164
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:210
double GetStartAngle() const
Definition: shape_arc.cpp:363
virtual ~PLOTTER()
Definition: plotter.cpp:67
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
double m_IUsPerDecimil
Definition: plotter.h:579
int PointCount() const
Function PointCount()
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:513
PLOTTER()
Definition: plotter.cpp:50
double GetDashGapLenIU() const
Definition: plotter.cpp:151
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
Function Point()
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
#define NULL
bool IsClosed() const override
Function IsClosed()
T AddAngles(T a1, T2 a2)
Add two angles (keeping the result normalized). T2 is here.
Definition: trigo.h:335
#define DOT_MARK_LEN(aLineWidth)
RENDER_SETTINGS * m_renderSettings
Definition: plotter.h:607
a few functions useful in geometry calculations.
virtual DPOINT userToDeviceSize(const wxSize &size)
Modify size according to the plotter scale factors (wxSize version, returns a DPOINT).
Definition: plotter.cpp:124
bool m_negativeMode
Definition: plotter.h:594
virtual void Circle(const wxPoint &pos, int diametre, FILL_TYPE fill, int width=USE_DEFAULT_LINE_WIDTH)=0
double GetEndAngle() const
Definition: shape_arc.cpp:373
void markerSlash(const wxPoint &pos, int radius)
Plot a / bar centered on the position.
Definition: plotter.cpp:317
void Marker(const wxPoint &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord position.
Definition: plotter.cpp:338
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:93
double cosdecideg(double r, double a)
Circle generation utility: computes r * cos(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:439
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:238
double sindecideg(double r, double a)
Circle generation utility: computes r * sin(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:430
int GetWidth() const
Definition: shape_arc.h:112
wxPoint m_plotOffset
Definition: plotter.h:583
double GetDashMarkLenIU() const
Definition: plotter.cpp:145
SHAPE_LINE_CHAIN.
void markerLozenge(const wxPoint &position, int radius)
Plot a lozenge centered on the position.
Definition: plotter.cpp:286
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:70
#define DASH_GAP_LEN(aLineWidth)
void markerCircle(const wxPoint &pos, int radius)
Plot a circle centered on the position.
Definition: plotter.cpp:280
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:537
#define MAX_PAGE_SIZE_MILS
Definition: page_info.h:41
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:182
VECTOR2< double > DPOINT
Definition: vector2d.h:628
void markerVBar(const wxPoint &pos, int radius)
Plot a | bar centered on the position.
Definition: plotter.cpp:331
wxSize m_paperSize
Definition: plotter.h:603
void markerSquare(const wxPoint &position, int radius)
Plot a square centered on the position.
Definition: plotter.cpp:255
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:324
void sketchOval(const wxPoint &pos, const wxSize &size, double orient, int width)
Definition: plotter.cpp:465
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:383
bool m_mirrorIsHorizontal
Definition: plotter.h:586