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 <fctsys.h>
41 #include <vector>
42 #include <trigo.h>
43 #include <base_struct.h>
44 #include <plotter.h>
45 #include <gr_text.h>
48 #include <bezier_curves.h>
49 #include <math/util.h> // for KiROUND
50 
52 {
53  plotScale = 1;
54  currentPenWidth = -1; // To-be-set marker
55  penState = 'Z'; // End-of-path idle
56  m_plotMirror = false; // Plot mirror option flag
57  m_mirrorIsHorizontal = true;
58  m_yaxisReversed = false;
59  outputFile = 0;
60  colorMode = false; // Starts as a BW plot
61  negativeMode = false;
62  // Temporary init to avoid not initialized vars, will be set later
63  m_IUsPerDecimil = 1; // will be set later to the actual value
64  iuPerDeviceUnit = 1; // will be set later to the actual value
65  m_renderSettings = nullptr;
66 }
67 
69 {
70  // Emergency cleanup, but closing the file is
71  // usually made in EndPlot().
72  if( outputFile )
73  fclose( outputFile );
74 }
75 
76 
77 bool PLOTTER::OpenFile( const wxString& aFullFilename )
78 {
79  filename = aFullFilename;
80 
81  wxASSERT( !outputFile );
82 
83  // Open the file in text mode (not suitable for all plotters
84  // but only for most of them
85  outputFile = wxFopen( filename, wxT( "wt" ) );
86 
87  if( outputFile == NULL )
88  return false ;
89 
90  return true;
91 }
92 
93 
95 {
96  wxPoint pos = aCoordinate - plotOffset;
97 
98  // Don't allow overflows; they can cause rendering failures in some file viewers
99  // (such as Acrobat)
100  int clampSize = MAX_PAGE_SIZE_MILS * m_IUsPerDecimil * 10 / 2;
101  pos.x = std::max( -clampSize, std::min( pos.x, clampSize ) );
102  pos.y = std::max( -clampSize, std::min( pos.y, clampSize ) );
103 
104  double x = pos.x * plotScale;
105  double y = ( paperSize.y - pos.y * plotScale );
106 
107  if( m_plotMirror )
108  {
110  x = ( paperSize.x - pos.x * plotScale );
111  else
112  y = pos.y * plotScale;
113  }
114 
115  if( m_yaxisReversed )
116  y = paperSize.y - y;
117 
118  x *= iuPerDeviceUnit;
119  y *= iuPerDeviceUnit;
120 
121  return DPOINT( x, y );
122 }
123 
124 
125 DPOINT PLOTTER::userToDeviceSize( const wxSize& size )
126 {
127  return DPOINT( size.x * plotScale * iuPerDeviceUnit,
128  size.y * plotScale * iuPerDeviceUnit );
129 }
130 
131 
132 double PLOTTER::userToDeviceSize( double size ) const
133 {
134  return size * plotScale * iuPerDeviceUnit;
135 }
136 
137 
138 #define IU_PER_MILS ( m_IUsPerDecimil * 10 )
139 
141 {
143 }
144 
145 
147 {
149 }
150 
151 
153 {
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  /* Please NOTE the different sign due to Y-axis flip */
169  start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) );
170  start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) );
171 
172  if( fill != NO_FILL )
173  {
174  MoveTo( centre );
175  LineTo( start );
176  }
177  else
178  {
179  MoveTo( start );
180  }
181 
182  for( int ii = StAngle + delta; ii < EndAngle; ii += delta )
183  {
184  end.x = centre.x + KiROUND( cosdecideg( radius, -ii ) );
185  end.y = centre.y + KiROUND( sindecideg( radius, -ii ) );
186  LineTo( end );
187  }
188 
189  end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) );
190  end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) );
191 
192  if( fill != NO_FILL )
193  {
194  LineTo( end );
195  FinishTo( centre );
196  }
197  else
198  {
199  FinishTo( end );
200  }
201 }
202 
203 
204 void PLOTTER::BezierCurve( const wxPoint& aStart, const wxPoint& aControl1,
205  const wxPoint& aControl2, const wxPoint& aEnd,
206  int aTolerance, int aLineThickness )
207 {
208  // Generic fallback: Quadratic Bezier curve plotted as a polyline
209  int minSegLen = aLineThickness; // The segment min length to approximate a bezier curve
210 
211  std::vector<wxPoint> ctrlPoints;
212  ctrlPoints.push_back( aStart );
213  ctrlPoints.push_back( aControl1 );
214  ctrlPoints.push_back( aControl2 );
215  ctrlPoints.push_back( aEnd );
216 
217  BEZIER_POLY bezier_converter( ctrlPoints );
218 
219  std::vector<wxPoint> approxPoints;
220  bezier_converter.GetPoly( approxPoints, minSegLen );
221 
222  SetCurrentLineWidth( aLineThickness );
223  MoveTo( aStart );
224 
225  for( unsigned ii = 1; ii < approxPoints.size()-1; ii++ )
226  LineTo( approxPoints[ii] );
227 
228  FinishTo( aEnd );
229 }
230 
231 
232 void PLOTTER::PlotImage(const wxImage & aImage, const wxPoint& aPos, double aScaleFactor )
233 {
234  wxSize size( aImage.GetWidth() * aScaleFactor,
235  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, 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, NO_FILL, GetCurrentLineWidth() );
271 }
272 
273 
274 void PLOTTER::markerCircle( const wxPoint& position, int radius )
275 {
276  Circle( position, radius * 2, 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, 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  /* Marker are composed by a series of 'parts' superimposed; not every
336  combination make sense, obviously. Since they are used in order I
337  tried to keep the uglier/more complex constructions at the end.
338  Also I avoided the |/ |\ -/ -\ construction because they're *very*
339  ugly... if needed they could be added anyway... I'd like to see
340  a board with more than 58 drilling/slotting tools!
341  If Visual C++ supported the 0b literals they would be optimally
342  and easily encoded as an integer array. We have to do with octal */
343  static const unsigned char marker_patterns[MARKER_COUNT] = {
344  // Bit order: O Square Lozenge - | \ /
345  // First choice: simple shapes
346  0003, // X
347  0100, // O
348  0014, // +
349  0040, // Sq
350  0020, // Lz
351  // Two simple shapes
352  0103, // X O
353  0017, // X +
354  0043, // X Sq
355  0023, // X Lz
356  0114, // O +
357  0140, // O Sq
358  0120, // O Lz
359  0054, // + Sq
360  0034, // + Lz
361  0060, // Sq Lz
362  // Three simple shapes
363  0117, // X O +
364  0143, // X O Sq
365  0123, // X O Lz
366  0057, // X + Sq
367  0037, // X + Lz
368  0063, // X Sq Lz
369  0154, // O + Sq
370  0134, // O + Lz
371  0074, // + Sq Lz
372  // Four simple shapes
373  0174, // O Sq Lz +
374  0163, // X O Sq Lz
375  0157, // X O Sq +
376  0137, // X O Lz +
377  0077, // X Sq Lz +
378  // This draws *everything *
379  0177, // X O Sq Lz +
380  // Here we use the single bars... so the cross is forbidden
381  0110, // O -
382  0104, // O |
383  0101, // O /
384  0050, // Sq -
385  0044, // Sq |
386  0041, // Sq /
387  0030, // Lz -
388  0024, // Lz |
389  0021, // Lz /
390  0150, // O Sq -
391  0144, // O Sq |
392  0141, // O Sq /
393  0130, // O Lz -
394  0124, // O Lz |
395  0121, // O Lz /
396  0070, // Sq Lz -
397  0064, // Sq Lz |
398  0061, // Sq Lz /
399  0170, // O Sq Lz -
400  0164, // O Sq Lz |
401  0161, // O Sq Lz /
402  // Last resort: the backlash component (easy to confound)
403  0102, // \ O
404  0042, // \ Sq
405  0022, // \ Lz
406  0142, // \ O Sq
407  0122, // \ O Lz
408  0062, // \ Sq Lz
409  0162 // \ O Sq Lz
410  };
411  if( aShapeId >= MARKER_COUNT )
412  {
413  // Fallback shape
414  markerCircle( position, radius );
415  }
416  else
417  {
418  // Decode the pattern and draw the corresponding parts
419  unsigned char pat = marker_patterns[aShapeId];
420  if( pat & 0001 )
421  markerSlash( position, radius );
422  if( pat & 0002 )
423  markerBackSlash( position, radius );
424  if( pat & 0004 )
425  markerVBar( position, radius );
426  if( pat & 0010 )
427  markerHBar( position, radius );
428  if( pat & 0020 )
429  markerLozenge( position, radius );
430  if( pat & 0040 )
431  markerSquare( position, radius );
432  if( pat & 0100 )
433  markerCircle( position, radius );
434  }
435 }
436 
437 
438 void PLOTTER::segmentAsOval( const wxPoint& start, const wxPoint& end, int width,
439  EDA_DRAW_MODE_T tracemode )
440 {
441  wxPoint center( (start.x + end.x) / 2, (start.y + end.y) / 2 );
442  wxSize size( end.x - start.x, end.y - start.y );
443  double orient;
444 
445  if( size.y == 0 )
446  orient = 0;
447  else if( size.x == 0 )
448  orient = 900;
449  else
450  orient = -ArcTangente( size.y, size.x );
451 
452  size.x = KiROUND( EuclideanNorm( size ) ) + width;
453  size.y = width;
454 
455  FlashPadOval( center, size, orient, tracemode, NULL );
456 }
457 
458 
459 void PLOTTER::sketchOval( const wxPoint& pos, const wxSize& aSize, double orient, int width )
460 {
461  SetCurrentLineWidth( width );
462  width = currentPenWidth;
463  int radius, deltaxy, cx, cy;
464  wxSize size( aSize );
465 
466  if( size.x > size.y )
467  {
468  std::swap( size.x, size.y );
469  orient = AddAngles( orient, 900 );
470  }
471 
472  deltaxy = size.y - size.x; /* distance between centers of the oval */
473  radius = ( size.x - width ) / 2;
474  cx = -radius;
475  cy = -deltaxy / 2;
476  RotatePoint( &cx, &cy, orient );
477  MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
478  cx = -radius;
479  cy = deltaxy / 2;
480  RotatePoint( &cx, &cy, orient );
481  FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );
482 
483  cx = radius;
484  cy = -deltaxy / 2;
485  RotatePoint( &cx, &cy, orient );
486  MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
487  cx = radius;
488  cy = deltaxy / 2;
489  RotatePoint( &cx, &cy, orient );
490  FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );
491 
492  cx = 0;
493  cy = deltaxy / 2;
494  RotatePoint( &cx, &cy, orient );
495  Arc( wxPoint( cx + pos.x, cy + pos.y ),
496  orient + 1800, orient + 3600,
497  radius, NO_FILL );
498  cx = 0;
499  cy = -deltaxy / 2;
500  RotatePoint( &cx, &cy, orient );
501  Arc( wxPoint( cx + pos.x, cy + pos.y ),
502  orient, orient + 1800,
503  radius, NO_FILL );
504 }
505 
506 
507 void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
508  EDA_DRAW_MODE_T tracemode, void* aData )
509 {
510  if( tracemode == FILLED )
511  {
512  if( start == end )
513  {
514  Circle( start, width, FILLED_SHAPE, 0 );
515  }
516  else
517  {
518  SetCurrentLineWidth( width );
519  MoveTo( start );
520  FinishTo( end );
521  }
522  }
523  else
524  {
525  SetCurrentLineWidth( -1 );
526  segmentAsOval( start, end, width, tracemode );
527  }
528 }
529 
530 
531 void PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
532  int radius, int width, EDA_DRAW_MODE_T tracemode, void* aData )
533 {
534  if( tracemode == FILLED )
535  Arc( centre, StAngle, EndAngle, radius, NO_FILL, width );
536  else
537  {
538  SetCurrentLineWidth( -1 );
539  Arc( centre, StAngle, EndAngle,
540  radius - ( width - currentPenWidth ) / 2, NO_FILL, -1 );
541  Arc( centre, StAngle, EndAngle,
542  radius + ( width - currentPenWidth ) / 2, NO_FILL, -1 );
543  }
544 }
545 
546 
547 void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
548  EDA_DRAW_MODE_T tracemode, void* aData )
549 {
550  if( tracemode == FILLED )
551  Rect( p1, p2, NO_FILL, width );
552  else
553  {
554  SetCurrentLineWidth( -1 );
555  wxPoint offsetp1( p1.x - (width - currentPenWidth) / 2,
556  p1.y - (width - currentPenWidth) / 2 );
557  wxPoint offsetp2( p2.x + (width - currentPenWidth) / 2,
558  p2.y + (width - currentPenWidth) / 2 );
559  Rect( offsetp1, offsetp2, NO_FILL, -1 );
560  offsetp1.x += (width - currentPenWidth);
561  offsetp1.y += (width - currentPenWidth);
562  offsetp2.x -= (width - currentPenWidth);
563  offsetp2.y -= (width - currentPenWidth);
564  Rect( offsetp1, offsetp2, NO_FILL, -1 );
565  }
566 }
567 
568 
569 void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width,
570  EDA_DRAW_MODE_T tracemode, void* aData )
571 {
572  if( tracemode == FILLED )
573  Circle( pos, diametre, NO_FILL, width );
574  else
575  {
576  SetCurrentLineWidth( -1 );
577  Circle( pos, diametre - width + currentPenWidth, NO_FILL, -1 );
578  Circle( pos, diametre + width - currentPenWidth, NO_FILL, -1 );
579  }
580 }
581 
582 
583 void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill,
584  int aWidth, void * aData )
585 {
586  std::vector<wxPoint> cornerList;
587  cornerList.reserve( aCornerList.PointCount() );
588 
589  for( int ii = 0; ii < aCornerList.PointCount(); ii++ )
590  cornerList.emplace_back( aCornerList.CPoint( ii ) );
591 
592  if( aCornerList.IsClosed() && cornerList.front() != cornerList.back() )
593  cornerList.emplace_back( aCornerList.CPoint( 0 ) );
594 
595  PlotPoly( cornerList, aFill, aWidth, aData );
596 }
597 
598 
599 wxPenStyle GetwxPenStyle( PLOT_DASH_TYPE aType )
600 {
601  switch( aType )
602  {
605  return wxPENSTYLE_SOLID;
607  return wxPENSTYLE_SHORT_DASH;
608  case PLOT_DASH_TYPE::DOT:
609  return wxPENSTYLE_DOT;
611  return wxPENSTYLE_DOT_DASH;
612  default:
613  wxFAIL_MSG( "Unhandled PlotDashType" );
614  return wxPENSTYLE_SOLID;
615  }
616 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:128
void FinishTo(const wxPoint &pos)
Definition: plotter.h:267
double GetDotMarkLenIU() const
Definition: plotter.cpp:140
void markerHBar(const wxPoint &pos, int radius)
Plot a - bar centered on the position.
Definition: plotter.cpp:304
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:569
void GetPoly(std::vector< wxPoint > &aOutput, int aMinSegLen=0)
Converts Bezier curve to a polygon.
static const unsigned MARKER_COUNT
Draw a marker (used for the drill map)
Definition: plotter.h:428
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition: plotter.cpp:77
#define DASH_MARK_LEN(aLineWidth)
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:204
bool colorMode
Definition: plotter.h:589
virtual ~PLOTTER()
Definition: plotter.cpp:68
char penState
Definition: plotter.h:592
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
double m_IUsPerDecimil
Definition: plotter.h:571
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=NULL)=0
Function PlotPoly.
int PointCount() const
Function PointCount()
wxPoint plotOffset
Plot offset (in IUs)
Definition: plotter.h:577
PLOTTER()
Definition: plotter.cpp:51
virtual void ThickArc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:531
double GetDashGapLenIU() const
Definition: plotter.cpp:152
virtual int GetCurrentLineWidth() const
Definition: plotter.h:158
virtual void ThickRect(const wxPoint &p1, const wxPoint &p2, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:547
bool m_yaxisReversed
true to mirror horizontally (else vertically)
Definition: plotter.h:583
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void LineTo(const wxPoint &pos)
Definition: plotter.h:262
bool m_plotMirror
X axis orientation (SVG) and plot mirrored (only for PS, PDF HPGL and SVG)
Definition: plotter.h:581
#define NULL
T AddAngles(T a1, T2 a2)
Add two angles (keeping the result normalized). T2 is here.
Definition: trigo.h:304
EDA_DRAW_MODE_T
Definition: eda_text.h:63
#define DOT_MARK_LEN(aLineWidth)
double plotScale
Plot scale - chosen by the user (even implicitly with 'fit in a4')
Definition: plotter.h:565
RENDER_SETTINGS * m_renderSettings
Definition: plotter.h:603
a few functions useful in geometry calculations.
virtual DPOINT userToDeviceSize(const wxSize &size)
Modifies size according to the plotter scale factors (wxSize version, returns a DPOINT)
Definition: plotter.cpp:125
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
PLOT_DASH_TYPE
Enum for choosing dashed line type.
Definition: plotter.h:87
void MoveTo(const wxPoint &pos)
Definition: plotter.h:257
virtual DPOINT userToDeviceCoordinates(const wxPoint &aCoordinate)
Modifies coordinates according to the orientation, scale factor, and offsets trace.
Definition: plotter.cpp:94
double cosdecideg(double r, double a)
Circle generation utility: computes r * cos(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:408
Bezier curves to polygon converter.
Definition: bezier_curves.h:35
virtual void PlotImage(const wxImage &aImage, const wxPoint &aPos, double aScaleFactor)
Function PlotImage Only Postscript plotters can plot bitmaps for plotters that cannot plot a bitmap,...
Definition: plotter.cpp:232
double sindecideg(double r, double a)
Circle generation utility: computes r * sin(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:399
int currentPenWidth
Definition: plotter.h:591
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadOval
double GetDashMarkLenIU() const
Definition: plotter.cpp:146
SHAPE_LINE_CHAIN.
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:507
void markerLozenge(const wxPoint &position, int radius)
Plot a lozenge centered on the position.
Definition: plotter.cpp:280
FILE * outputFile
true if the Y axis is top to bottom (SVG)
Definition: plotter.h:586
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:68
#define DASH_GAP_LEN(aLineWidth)
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
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
FILL_T
Enum FILL_T is the set of fill types used in plotting or drawing enclosed areas.
Definition: base_struct.h:42
#define MAX_PAGE_SIZE_MILS
Definition: page_info.h:41
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:162
bool IsClosed() const
Function IsClosed()
double iuPerDeviceUnit
Device scale (from IUs to plotter device units - usually decimils)
Definition: plotter.h:574
void segmentAsOval(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode)
Cdonvert a thick segment and plot it as an oval.
Definition: plotter.cpp:438
VECTOR2< double > DPOINT
Definition: vector2d.h:599
wxString filename
Definition: plotter.h:596
void markerVBar(const wxPoint &pos, int radius)
Plot a | bar centered on the position.
Definition: plotter.cpp:325
void markerSquare(const wxPoint &position, int radius)
Plot a square centered on the position.
Definition: plotter.cpp:249
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:459
virtual void Circle(const wxPoint &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
wxPenStyle GetwxPenStyle(PLOT_DASH_TYPE aType)
Convert KiCad line plot styles to wxWidgets device context styles.
Definition: plotter.cpp:599
wxSize paperSize
Definition: plotter.h:599
bool m_mirrorIsHorizontal
Definition: plotter.h:582
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
bool negativeMode
Definition: plotter.h:590