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 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 
42 #include <trigo.h>
43 #include <eda_base_frame.h>
44 #include <base_struct.h>
45 #include <common.h>
46 #include <plotter.h>
47 #include <macros.h>
48 #include <base_screen.h>
49 #include <draw_graphic_text.h>
52 
54 {
55  plotScale = 1;
56  defaultPenWidth = 0;
57  currentPenWidth = -1; // To-be-set marker
58  penState = 'Z'; // End-of-path idle
59  m_plotMirror = false; // Plot mirror option flag
60  m_mirrorIsHorizontal = true;
61  m_yaxisReversed = false;
62  outputFile = 0;
63  colorMode = false; // Starts as a BW plot
64  negativeMode = false;
65  // Temporary init to avoid not initialized vars, will be set later
66  m_IUsPerDecimil = 1; // will be set later to the actual value
67  iuPerDeviceUnit = 1; // will be set later to the actual value
68 }
69 
71 {
72  // Emergency cleanup, but closing the file is
73  // usually made in EndPlot().
74  if( outputFile )
75  fclose( outputFile );
76 }
77 
78 
79 bool PLOTTER::OpenFile( const wxString& aFullFilename )
80 {
81  filename = aFullFilename;
82 
83  wxASSERT( !outputFile );
84 
85  // Open the file in text mode (not suitable for all plotters
86  // but only for most of them
87  outputFile = wxFopen( filename, wxT( "wt" ) );
88 
89  if( outputFile == NULL )
90  return false ;
91 
92  return true;
93 }
94 
95 
97 {
98  wxPoint pos = aCoordinate - plotOffset;
99 
100  double x = pos.x * plotScale;
101  double y = ( paperSize.y - pos.y * plotScale );
102 
103  if( m_plotMirror )
104  {
106  x = ( paperSize.x - pos.x * plotScale );
107  else
108  y = pos.y * plotScale;
109  }
110 
111  if( m_yaxisReversed )
112  y = paperSize.y - y;
113 
114  x *= iuPerDeviceUnit;
115  y *= iuPerDeviceUnit;
116 
117  return DPOINT( x, y );
118 }
119 
120 
121 DPOINT PLOTTER::userToDeviceSize( const wxSize& size )
122 {
123  return DPOINT( size.x * plotScale * iuPerDeviceUnit,
124  size.y * plotScale * iuPerDeviceUnit );
125 }
126 
127 
128 double PLOTTER::userToDeviceSize( double size ) const
129 {
130  return size * plotScale * iuPerDeviceUnit;
131 }
132 
133 
134 #define IU_PER_MILS ( m_IUsPerDecimil * 10 )
135 
137 {
139 }
140 
141 
143 {
145 }
146 
147 
149 {
151 }
152 
153 
154 void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius,
155  FILL_T fill, int width )
156 {
157  wxPoint start, end;
158  const int delta = 50; // increment (in 0.1 degrees) to draw circles
159 
160  if( StAngle > EndAngle )
161  std::swap( StAngle, EndAngle );
162 
163  SetCurrentLineWidth( width );
164  /* Please NOTE the different sign due to Y-axis flip */
165  start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) );
166  start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) );
167  MoveTo( start );
168  for( int ii = StAngle + delta; ii < EndAngle; ii += delta )
169  {
170  end.x = centre.x + KiROUND( cosdecideg( radius, -ii ) );
171  end.y = centre.y + KiROUND( sindecideg( radius, -ii ) );
172  LineTo( end );
173  }
174 
175  end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) );
176  end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) );
177  FinishTo( end );
178 }
179 
180 
181 void PLOTTER::PlotImage(const wxImage & aImage, const wxPoint& aPos, double aScaleFactor )
182 {
183  wxSize size( aImage.GetWidth() * aScaleFactor,
184  aImage.GetHeight() * aScaleFactor );
185 
186  wxPoint start = aPos;
187  start.x -= size.x / 2;
188  start.y -= size.y / 2;
189 
190  wxPoint end = start;
191  end.x += size.x;
192  end.y += size.y;
193 
194  Rect( start, end, NO_FILL );
195 }
196 
197 
198 void PLOTTER::markerSquare( const wxPoint& position, int radius )
199 {
200  double r = KiROUND( radius / 1.4142 );
201  std::vector< wxPoint > corner_list;
202  wxPoint corner;
203  corner.x = position.x + r;
204  corner.y = position.y + r;
205  corner_list.push_back( corner );
206  corner.x = position.x + r;
207  corner.y = position.y - r;
208  corner_list.push_back( corner );
209  corner.x = position.x - r;
210  corner.y = position.y - r;
211  corner_list.push_back( corner );
212  corner.x = position.x - r;
213  corner.y = position.y + r;
214  corner_list.push_back( corner );
215  corner.x = position.x + r;
216  corner.y = position.y + r;
217  corner_list.push_back( corner );
218 
219  PlotPoly( corner_list, NO_FILL, GetCurrentLineWidth() );
220 }
221 
222 
223 void PLOTTER::markerCircle( const wxPoint& position, int radius )
224 {
225  Circle( position, radius * 2, NO_FILL, GetCurrentLineWidth() );
226 }
227 
228 
229 void PLOTTER::markerLozenge( const wxPoint& position, int radius )
230 {
231  std::vector< wxPoint > corner_list;
232  wxPoint corner;
233  corner.x = position.x;
234  corner.y = position.y + radius;
235  corner_list.push_back( corner );
236  corner.x = position.x + radius;
237  corner.y = position.y,
238  corner_list.push_back( corner );
239  corner.x = position.x;
240  corner.y = position.y - radius;
241  corner_list.push_back( corner );
242  corner.x = position.x - radius;
243  corner.y = position.y;
244  corner_list.push_back( corner );
245  corner.x = position.x;
246  corner.y = position.y + radius;
247  corner_list.push_back( corner );
248 
249  PlotPoly( corner_list, NO_FILL, GetCurrentLineWidth() );
250 }
251 
252 
253 void PLOTTER::markerHBar( const wxPoint& pos, int radius )
254 {
255  MoveTo( wxPoint( pos.x - radius, pos.y ) );
256  FinishTo( wxPoint( pos.x + radius, pos.y ) );
257 }
258 
259 
260 void PLOTTER::markerSlash( const wxPoint& pos, int radius )
261 {
262  MoveTo( wxPoint( pos.x - radius, pos.y - radius ) );
263  FinishTo( wxPoint( pos.x + radius, pos.y + radius ) );
264 }
265 
266 
267 void PLOTTER::markerBackSlash( const wxPoint& pos, int radius )
268 {
269  MoveTo( wxPoint( pos.x + radius, pos.y - radius ) );
270  FinishTo( wxPoint( pos.x - radius, pos.y + radius ) );
271 }
272 
273 
274 void PLOTTER::markerVBar( const wxPoint& pos, int radius )
275 {
276  MoveTo( wxPoint( pos.x, pos.y - radius ) );
277  FinishTo( wxPoint( pos.x, pos.y + radius ) );
278 }
279 
280 
281 void PLOTTER::Marker( const wxPoint& position, int diametre, unsigned aShapeId )
282 {
283  int radius = diametre / 2;
284  /* Marker are composed by a series of 'parts' superimposed; not every
285  combination make sense, obviously. Since they are used in order I
286  tried to keep the uglier/more complex constructions at the end.
287  Also I avoided the |/ |\ -/ -\ construction because they're *very*
288  ugly... if needed they could be added anyway... I'd like to see
289  a board with more than 58 drilling/slotting tools!
290  If Visual C++ supported the 0b literals they would be optimally
291  and easily encoded as an integer array. We have to do with octal */
292  static const unsigned char marker_patterns[MARKER_COUNT] = {
293  // Bit order: O Square Lozenge - | \ /
294  // First choice: simple shapes
295  0003, // X
296  0100, // O
297  0014, // +
298  0040, // Sq
299  0020, // Lz
300  // Two simple shapes
301  0103, // X O
302  0017, // X +
303  0043, // X Sq
304  0023, // X Lz
305  0114, // O +
306  0140, // O Sq
307  0120, // O Lz
308  0054, // + Sq
309  0034, // + Lz
310  0060, // Sq Lz
311  // Three simple shapes
312  0117, // X O +
313  0143, // X O Sq
314  0123, // X O Lz
315  0057, // X + Sq
316  0037, // X + Lz
317  0063, // X Sq Lz
318  0154, // O + Sq
319  0134, // O + Lz
320  0074, // + Sq Lz
321  // Four simple shapes
322  0174, // O Sq Lz +
323  0163, // X O Sq Lz
324  0157, // X O Sq +
325  0137, // X O Lz +
326  0077, // X Sq Lz +
327  // This draws *everything *
328  0177, // X O Sq Lz +
329  // Here we use the single bars... so the cross is forbidden
330  0110, // O -
331  0104, // O |
332  0101, // O /
333  0050, // Sq -
334  0044, // Sq |
335  0041, // Sq /
336  0030, // Lz -
337  0024, // Lz |
338  0021, // Lz /
339  0150, // O Sq -
340  0144, // O Sq |
341  0141, // O Sq /
342  0130, // O Lz -
343  0124, // O Lz |
344  0121, // O Lz /
345  0070, // Sq Lz -
346  0064, // Sq Lz |
347  0061, // Sq Lz /
348  0170, // O Sq Lz -
349  0164, // O Sq Lz |
350  0161, // O Sq Lz /
351  // Last resort: the backlash component (easy to confound)
352  0102, // \ O
353  0042, // \ Sq
354  0022, // \ Lz
355  0142, // \ O Sq
356  0122, // \ O Lz
357  0062, // \ Sq Lz
358  0162 // \ O Sq Lz
359  };
360  if( aShapeId >= MARKER_COUNT )
361  {
362  // Fallback shape
363  markerCircle( position, radius );
364  }
365  else
366  {
367  // Decode the pattern and draw the corresponding parts
368  unsigned char pat = marker_patterns[aShapeId];
369  if( pat & 0001 )
370  markerSlash( position, radius );
371  if( pat & 0002 )
372  markerBackSlash( position, radius );
373  if( pat & 0004 )
374  markerVBar( position, radius );
375  if( pat & 0010 )
376  markerHBar( position, radius );
377  if( pat & 0020 )
378  markerLozenge( position, radius );
379  if( pat & 0040 )
380  markerSquare( position, radius );
381  if( pat & 0100 )
382  markerCircle( position, radius );
383  }
384 }
385 
386 
387 void PLOTTER::segmentAsOval( const wxPoint& start, const wxPoint& end, int width,
388  EDA_DRAW_MODE_T tracemode )
389 {
390  wxPoint center( (start.x + end.x) / 2, (start.y + end.y) / 2 );
391  wxSize size( end.x - start.x, end.y - start.y );
392  double orient;
393 
394  if( size.y == 0 )
395  orient = 0;
396  else if( size.x == 0 )
397  orient = 900;
398  else
399  orient = -ArcTangente( size.y, size.x );
400 
401  size.x = KiROUND( EuclideanNorm( size ) ) + width;
402  size.y = width;
403 
404  FlashPadOval( center, size, orient, tracemode, NULL );
405 }
406 
407 
408 void PLOTTER::sketchOval( const wxPoint& pos, const wxSize& aSize, double orient, int width )
409 {
410  SetCurrentLineWidth( width );
411  width = currentPenWidth;
412  int radius, deltaxy, cx, cy;
413  wxSize size( aSize );
414 
415  if( size.x > size.y )
416  {
417  std::swap( size.x, size.y );
418  orient = AddAngles( orient, 900 );
419  }
420 
421  deltaxy = size.y - size.x; /* distance between centers of the oval */
422  radius = ( size.x - width ) / 2;
423  cx = -radius;
424  cy = -deltaxy / 2;
425  RotatePoint( &cx, &cy, orient );
426  MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
427  cx = -radius;
428  cy = deltaxy / 2;
429  RotatePoint( &cx, &cy, orient );
430  FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );
431 
432  cx = radius;
433  cy = -deltaxy / 2;
434  RotatePoint( &cx, &cy, orient );
435  MoveTo( wxPoint( cx + pos.x, cy + pos.y ) );
436  cx = radius;
437  cy = deltaxy / 2;
438  RotatePoint( &cx, &cy, orient );
439  FinishTo( wxPoint( cx + pos.x, cy + pos.y ) );
440 
441  cx = 0;
442  cy = deltaxy / 2;
443  RotatePoint( &cx, &cy, orient );
444  Arc( wxPoint( cx + pos.x, cy + pos.y ),
445  orient + 1800, orient + 3600,
446  radius, NO_FILL );
447  cx = 0;
448  cy = -deltaxy / 2;
449  RotatePoint( &cx, &cy, orient );
450  Arc( wxPoint( cx + pos.x, cy + pos.y ),
451  orient, orient + 1800,
452  radius, NO_FILL );
453 }
454 
455 
456 void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
457  EDA_DRAW_MODE_T tracemode, void* aData )
458 {
459  if( tracemode == FILLED )
460  {
461  SetCurrentLineWidth( width );
462  MoveTo( start );
463  FinishTo( end );
464  }
465  else
466  {
467  SetCurrentLineWidth( -1 );
468  segmentAsOval( start, end, width, tracemode );
469  }
470 }
471 
472 
473 void PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
474  int radius, int width, EDA_DRAW_MODE_T tracemode, void* aData )
475 {
476  if( tracemode == FILLED )
477  Arc( centre, StAngle, EndAngle, radius, NO_FILL, width );
478  else
479  {
480  SetCurrentLineWidth( -1 );
481  Arc( centre, StAngle, EndAngle,
482  radius - ( width - currentPenWidth ) / 2, NO_FILL, -1 );
483  Arc( centre, StAngle, EndAngle,
484  radius + ( width - currentPenWidth ) / 2, NO_FILL, -1 );
485  }
486 }
487 
488 
489 void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
490  EDA_DRAW_MODE_T tracemode, void* aData )
491 {
492  if( tracemode == FILLED )
493  Rect( p1, p2, NO_FILL, width );
494  else
495  {
496  SetCurrentLineWidth( -1 );
497  wxPoint offsetp1( p1.x - (width - currentPenWidth) / 2,
498  p1.y - (width - currentPenWidth) / 2 );
499  wxPoint offsetp2( p2.x + (width - currentPenWidth) / 2,
500  p2.y + (width - currentPenWidth) / 2 );
501  Rect( offsetp1, offsetp2, NO_FILL, -1 );
502  offsetp1.x += (width - currentPenWidth);
503  offsetp1.y += (width - currentPenWidth);
504  offsetp2.x -= (width - currentPenWidth);
505  offsetp2.y -= (width - currentPenWidth);
506  Rect( offsetp1, offsetp2, NO_FILL, -1 );
507  }
508 }
509 
510 
511 void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width,
512  EDA_DRAW_MODE_T tracemode, void* aData )
513 {
514  if( tracemode == FILLED )
515  Circle( pos, diametre, NO_FILL, width );
516  else
517  {
518  SetCurrentLineWidth( -1 );
519  Circle( pos, diametre - width + currentPenWidth, NO_FILL, -1 );
520  Circle( pos, diametre + width - currentPenWidth, NO_FILL, -1 );
521  }
522 }
523 
524 
525 void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill,
526  int aWidth, void * aData )
527 {
528  std::vector< wxPoint > cornerList;
529 
530  for( int ii = 0; ii < aCornerList.PointCount(); ii++ )
531  cornerList.push_back( wxPoint( aCornerList.CPoint( ii ) ) );
532 
533  PlotPoly( cornerList , aFill, aWidth, aData );
534 }
535 
536 
537 void PLOTTER::SetPageSettings( const PAGE_INFO& aPageSettings )
538 {
539  pageInfo = aPageSettings;
540 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
void FinishTo(const wxPoint &pos)
Definition: plotter.h:251
void markerHBar(const wxPoint &pos, int radius)
Plot a - bar centered on the position.
Definition: plotter.cpp:253
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:120
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:511
int PointCount() const
Function PointCount()
static const unsigned MARKER_COUNT
Draw a marker (used for the drill map)
Definition: plotter.h:401
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition: plotter.cpp:79
double GetDotMarkLenIU() const
Definition: plotter.cpp:136
#define DASH_MARK_LEN(aLineWidth)
bool colorMode
Definition: plotter.h:557
virtual ~PLOTTER()
Definition: plotter.cpp:70
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
char penState
Current pen state: &#39;U&#39;, &#39;D&#39; or &#39;Z&#39; (see PenTo)
Definition: plotter.h:562
double m_IUsPerDecimil
Definition: plotter.h:539
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=NULL)=0
Function PlotPoly.
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: plotter.cpp:537
wxPoint plotOffset
Plot offset (in IUs)
Definition: plotter.h:545
static const int delta[8][2]
Definition: solve.cpp:112
PAGE_INFO pageInfo
Definition: plotter.h:568
PLOTTER()
Definition: plotter.cpp:53
virtual void ThickArc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:473
This file contains miscellaneous commonly used macros and functions.
virtual void ThickRect(const wxPoint &p1, const wxPoint &p2, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:489
bool m_yaxisReversed
true to mirror horizontally (else vertically)
Definition: plotter.h:551
void LineTo(const wxPoint &pos)
Definition: plotter.h:246
bool m_plotMirror
X axis orientation (SVG) and plot mirrored (only for PS, PDF HPGL and SVG)
Definition: plotter.h:549
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
T AddAngles(T a1, T2 a2)
Add two angles (keeping the result normalized). T2 is here.
Definition: trigo.h:288
EDA_DRAW_MODE_T
Definition: eda_text.h:77
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
Definition: page_info.h:54
#define DOT_MARK_LEN(aLineWidth)
Base window classes and related definitions.
double plotScale
Plot scale - chosen by the user (even implicitly with &#39;fit in a4&#39;)
Definition: plotter.h:533
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:121
void markerSlash(const wxPoint &pos, int radius)
Plot a / bar centered on the position.
Definition: plotter.cpp:260
void Marker(const wxPoint &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord position.
Definition: plotter.cpp:281
void MoveTo(const wxPoint &pos)
Definition: plotter.h:241
virtual DPOINT userToDeviceCoordinates(const wxPoint &aCoordinate)
Modifies coordinates according to the orientation, scale factor, and offsets trace.
Definition: plotter.cpp:96
double cosdecideg(double r, double a)
Circle generation utility: computes r * cos(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:354
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:181
double sindecideg(double r, double a)
Circle generation utility: computes r * sin(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:345
int currentPenWidth
Definition: plotter.h:560
virtual int GetCurrentLineWidth() const
Definition: plotter.h:152
int defaultPenWidth
true to generate a negative image (PS mode mainly)
Definition: plotter.h:559
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadOval
Class SHAPE_LINE_CHAIN.
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:456
void markerLozenge(const wxPoint &position, int radius)
Plot a lozenge centered on the position.
Definition: plotter.cpp:229
FILE * outputFile
true if the Y axis is top to bottom (SVG)
Definition: plotter.h:554
double GetDashGapLenIU() const
Definition: plotter.cpp:148
#define DASH_GAP_LEN(aLineWidth)
The common library.
void markerCircle(const wxPoint &pos, int radius)
Plot a circle centered on the position.
Definition: plotter.cpp:223
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:154
FILL_T
Enum FILL_T is the set of fill types used in plotting or drawing enclosed areas.
Definition: base_struct.h:54
Basic classes for most KiCad items.
double GetDashMarkLenIU() const
Definition: plotter.cpp:142
BASE_SCREEN class implementation.
double iuPerDeviceUnit
Device scale (from IUs to plotter device units - usually decimils)
Definition: plotter.h:542
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:387
VECTOR2< double > DPOINT
Definition: vector2d.h:592
wxString filename
Definition: plotter.h:566
void markerVBar(const wxPoint &pos, int radius)
Plot a | bar centered on the position.
Definition: plotter.cpp:274
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
void markerSquare(const wxPoint &position, int radius)
Plot a square centered on the position.
Definition: plotter.cpp:198
void markerBackSlash(const wxPoint &pos, int radius)
Plot a \ bar centered on the position.
Definition: plotter.cpp:267
void sketchOval(const wxPoint &pos, const wxSize &size, double orient, int width)
Definition: plotter.cpp:408
virtual void Circle(const wxPoint &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
wxSize paperSize
Paper size in IU - not in mils.
Definition: plotter.h:570
bool m_mirrorIsHorizontal
Definition: plotter.h:550
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
bool negativeMode
true to plot in color, false to plot in black and white
Definition: plotter.h:558