KiCad PCB EDA Suite
gen_drill_report_files.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 1992-2015 Jean_Pierre Charras <jp.charras at wanadoo.fr>
10  * Copyright (C) 1992-2015 KiCad Developers, see change_log.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 
30 #include <fctsys.h>
31 #include <common.h>
32 #include <plot_common.h>
33 #include <base_struct.h>
34 #include <drawtxt.h>
35 #include <confirm.h>
36 #include <kicad_string.h>
37 #include <macros.h>
38 
39 #include <class_board.h>
40 
41 #include <pcbnew.h>
42 #include <pcbplot.h>
44 
45 /* Conversion utilities - these will be used often in there... */
46 inline double diameter_in_inches( double ius )
47 {
48  return ius * 0.001 / IU_PER_MILS;
49 }
50 
51 
52 inline double diameter_in_mm( double ius )
53 {
54  return ius / IU_PER_MM;
55 }
56 
57 
58 bool EXCELLON_WRITER::GenDrillMapFile( const wxString& aFullFileName,
59  PlotFormat aFormat )
60 {
61  double scale = 1.0;
62  wxPoint offset;
63  PLOTTER* plotter = NULL;
64  PAGE_INFO dummy( PAGE_INFO::A4, false );
65 
66  PCB_PLOT_PARAMS plot_opts; // starts plotting with default options
67 
68  LOCALE_IO toggle; // use standard C notation for float numbers
69 
70  const PAGE_INFO& page_info = m_pageInfo ? *m_pageInfo : dummy;
71 
72  // Calculate dimensions and center of PCB
74 
75  // Calculate the scale for the format type, scale 1 in HPGL, drawing on
76  // an A4 sheet in PS, + text description of symbols
77  switch( aFormat )
78  {
79  case PLOT_FORMAT_GERBER:
80  offset = GetOffset();
81  plotter = new GERBER_PLOTTER();
82  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
83  plotter->SetGerberCoordinatesFormat( 5 ); // format x.5 unit = mm
84  break;
85 
86  case PLOT_FORMAT_HPGL: // Scale for HPGL format.
87  {
88  HPGL_PLOTTER* hpgl_plotter = new HPGL_PLOTTER;
89  plotter = hpgl_plotter;
90  hpgl_plotter->SetPenNumber( plot_opts.GetHPGLPenNum() );
91  hpgl_plotter->SetPenSpeed( plot_opts.GetHPGLPenSpeed() );
92  plotter->SetPageSettings( page_info );
93  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
94  }
95  break;
96 
97 
98  default:
99  wxASSERT( false );
100  // fall through
101  case PLOT_FORMAT_PDF:
102  case PLOT_FORMAT_POST:
103  {
104  PAGE_INFO pageA4( wxT( "A4" ) );
105  wxSize pageSizeIU = pageA4.GetSizeIU();
106 
107  // Reserve a margin around the page.
108  int margin = KiROUND( 20 * IU_PER_MM );
109 
110  // Calculate a scaling factor to print the board on the sheet
111  double Xscale = double( pageSizeIU.x - ( 2 * margin ) ) / bbbox.GetWidth();
112 
113  // We should print the list of drill sizes, so reserve room for it
114  // 60% height for board 40% height for list
115  int ypagesize_for_board = KiROUND( pageSizeIU.y * 0.6 );
116  double Yscale = double( ypagesize_for_board - margin ) / bbbox.GetHeight();
117 
118  scale = std::min( Xscale, Yscale );
119 
120  // Experience shows the scale should not to large, because texts
121  // create problem (can be to big or too small).
122  // So the scale is clipped at 3.0;
123  scale = std::min( scale, 3.0 );
124 
125  offset.x = KiROUND( double( bbbox.Centre().x ) -
126  ( pageSizeIU.x / 2.0 ) / scale );
127  offset.y = KiROUND( double( bbbox.Centre().y ) -
128  ( ypagesize_for_board / 2.0 ) / scale );
129 
130  if( aFormat == PLOT_FORMAT_PDF )
131  plotter = new PDF_PLOTTER;
132  else
133  plotter = new PS_PLOTTER;
134 
135  plotter->SetPageSettings( pageA4 );
136  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
137  }
138  break;
139 
140  case PLOT_FORMAT_DXF:
141  {
142  DXF_PLOTTER* dxf_plotter = new DXF_PLOTTER;
143  plotter = dxf_plotter;
144  plotter->SetPageSettings( page_info );
145  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
146  }
147  break;
148 
149  case PLOT_FORMAT_SVG:
150  {
151  SVG_PLOTTER* svg_plotter = new SVG_PLOTTER;
152  plotter = svg_plotter;
153  plotter->SetPageSettings( page_info );
154  plotter->SetViewport( offset, IU_PER_MILS/10, scale, false );
155  }
156  break;
157  }
158 
159  plotter->SetCreator( wxT( "PCBNEW" ) );
160  plotter->SetDefaultLineWidth( 5 * IU_PER_MILS );
161  plotter->SetColorMode( false );
162 
163  if( ! plotter->OpenFile( aFullFileName ) )
164  {
165  delete plotter;
166  return false;
167  }
168 
169  plotter->StartPlot();
170 
171  // Draw items on edge layer (not all, only items useful for drill map
172  BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts );
173  itemplotter.SetLayerSet( Edge_Cuts );
174 
175  for( EDA_ITEM* PtStruct = m_pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
176  {
177  switch( PtStruct->Type() )
178  {
179  case PCB_LINE_T:
180  itemplotter.PlotDrawSegment( (DRAWSEGMENT*) PtStruct );
181  break;
182 
183  case PCB_TEXT_T:
184  itemplotter.PlotTextePcb( (TEXTE_PCB*) PtStruct );
185  break;
186 
187  case PCB_DIMENSION_T:
188  case PCB_TARGET_T:
189  case PCB_MARKER_T: // do not draw
190  default:
191  break;
192  }
193  }
194 
195  int x, y;
196  int plotX, plotY, TextWidth;
197  int intervalle = 0;
198  char line[1024];
199  wxString msg;
200  int textmarginaftersymbol = KiROUND( 2 * IU_PER_MM );
201 
202  // Set Drill Symbols width
203  plotter->SetDefaultLineWidth( 0.2 * IU_PER_MM / scale );
204  plotter->SetCurrentLineWidth( -1 );
205 
206  // Plot board outlines and drill map
207  plotDrillMarks( plotter );
208 
209  // Print a list of symbols used.
210  int charSize = 3 * IU_PER_MM; // text size in IUs
211  double charScale = 1.0 / scale; // real scale will be 1/scale,
212  // because the global plot scale is scale
213  TextWidth = KiROUND( (charSize * charScale) / 10.0 ); // Set text width (thickness)
214  intervalle = KiROUND( charSize * charScale ) + TextWidth;
215 
216  // Trace information.
217  plotX = KiROUND( bbbox.GetX() + textmarginaftersymbol * charScale );
218  plotY = bbbox.GetBottom() + intervalle;
219 
220  // Plot title "Info"
221  wxString Text = wxT( "Drill Map:" );
222  plotter->Text( wxPoint( plotX, plotY ), COLOR4D::UNSPECIFIED, Text, 0,
223  wxSize( KiROUND( charSize * charScale ),
224  KiROUND( charSize * charScale ) ),
226  TextWidth, false, false );
227 
228  for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
229  {
230  DRILL_TOOL& tool = m_toolListBuffer[ii];
231 
232  if( tool.m_TotalCount == 0 )
233  continue;
234 
235  plotY += intervalle;
236 
237  int plot_diam = KiROUND( tool.m_Diameter );
238  x = KiROUND( plotX - textmarginaftersymbol * charScale - plot_diam / 2.0 );
239  y = KiROUND( plotY + charSize * charScale );
240  plotter->Marker( wxPoint( x, y ), plot_diam, ii );
241 
242  // List the diameter of each drill in mm and inches.
243  sprintf( line, "%2.2fmm / %2.3f\" ",
244  diameter_in_mm( tool.m_Diameter ),
245  diameter_in_inches( tool.m_Diameter ) );
246 
247  msg = FROM_UTF8( line );
248 
249  // Now list how many holes and ovals are associated with each drill.
250  if( ( tool.m_TotalCount == 1 )
251  && ( tool.m_OvalCount == 0 ) )
252  sprintf( line, "(1 hole)" );
253  else if( tool.m_TotalCount == 1 ) // && ( toolm_OvalCount == 1 )
254  sprintf( line, "(1 slot)" );
255  else if( tool.m_OvalCount == 0 )
256  sprintf( line, "(%d holes)", tool.m_TotalCount );
257  else if( tool.m_OvalCount == 1 )
258  sprintf( line, "(%d holes + 1 slot)", tool.m_TotalCount - 1 );
259  else // if ( toolm_OvalCount > 1 )
260  sprintf( line, "(%d holes + %d slots)",
261  tool.m_TotalCount - tool.m_OvalCount,
262  tool.m_OvalCount );
263 
264  msg += FROM_UTF8( line );
265 
266  if( tool.m_Hole_NotPlated )
267  msg += wxT( " (not plated)" );
268 
269  plotter->Text( wxPoint( plotX, y ), COLOR4D::UNSPECIFIED, msg, 0,
270  wxSize( KiROUND( charSize * charScale ),
271  KiROUND( charSize * charScale ) ),
273  TextWidth, false, false );
274 
275  intervalle = KiROUND( ( ( charSize * charScale ) + TextWidth ) * 1.2 );
276 
277  if( intervalle < ( plot_diam + ( 1 * IU_PER_MM / scale ) + TextWidth ) )
278  intervalle = plot_diam + ( 1 * IU_PER_MM / scale ) + TextWidth;
279  }
280 
281  plotter->EndPlot();
282  delete plotter;
283 
284  return true;
285 }
286 
287 
288 bool EXCELLON_WRITER::GenDrillReportFile( const wxString& aFullFileName )
289 {
290  FILE_OUTPUTFORMATTER out( aFullFileName );
291 
292  static const char separator[] =
293  " =============================================================\n";
294 
295  wxASSERT( m_pcb );
296 
297  unsigned totalHoleCount;
298  wxString brdFilename = m_pcb->GetFileName();
299 
300  std::vector<DRILL_LAYER_PAIR> hole_sets = getUniqueLayerPairs();
301 
302  out.Print( 0, "Drill report for %s\n", TO_UTF8( brdFilename ) );
303  out.Print( 0, "Created on %s\n\n", TO_UTF8( DateAndTime() ) );
304 
305  // Output the cu layer stackup, so layer name references make sense.
306  out.Print( 0, "Copper Layer Stackup:\n" );
307  out.Print( 0, separator );
308 
310 
311  int conventional_layer_num = 1;
312  for( LSEQ seq = cu.Seq(); seq; ++seq, ++conventional_layer_num )
313  {
314  out.Print( 0, " L%-2d: %-25s %s\n",
315  conventional_layer_num,
316  TO_UTF8( m_pcb->GetLayerName( *seq ) ),
317  layerName( *seq ).c_str() // generic layer name
318  );
319  }
320 
321  out.Print( 0, "\n\n" );
322 
323  /* output hole lists:
324  * 1 - through holes
325  * 2 - for partial holes only: by layer starting and ending pair
326  * 3 - Non Plated through holes
327  */
328 
329  bool buildNPTHlist = false;
330 
331  // in this loop are plated only:
332  for( unsigned pair_ndx = 0; pair_ndx < hole_sets.size(); ++pair_ndx )
333  {
334  DRILL_LAYER_PAIR pair = hole_sets[pair_ndx];
335 
336  buildHolesList( pair, buildNPTHlist );
337 
338  if( pair == DRILL_LAYER_PAIR( F_Cu, B_Cu ) )
339  {
340  out.Print( 0, "Drill file '%s' contains\n",
341  TO_UTF8( drillFileName( pair, false, m_merge_PTH_NPTH ) ) );
342 
343  out.Print( 0, " plated through holes:\n" );
344  out.Print( 0, separator );
345  totalHoleCount = printToolSummary( out, false );
346  out.Print( 0, " Total plated holes count %u\n", totalHoleCount );
347  }
348  else // blind/buried
349  {
350  out.Print( 0, "Drill file '%s' contains\n",
351  TO_UTF8( drillFileName( pair, false, m_merge_PTH_NPTH ) ) );
352 
353  out.Print( 0, " holes connecting layer pair: '%s and %s' (%s vias):\n",
354  TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( pair.first ) ) ),
355  TO_UTF8( m_pcb->GetLayerName( ToLAYER_ID( pair.second ) ) ),
356  pair.first == F_Cu || pair.second == B_Cu ? "blind" : "buried"
357  );
358 
359  out.Print( 0, separator );
360  totalHoleCount = printToolSummary( out, false );
361  out.Print( 0, " Total plated holes count %u\n", totalHoleCount );
362  }
363 
364  out.Print( 0, "\n\n" );
365  }
366 
367  // NPTHoles. Generate the full list (pads+vias) if PTH and NPTH are merged,
368  // or only the NPTH list (which never has vias)
369  if( !m_merge_PTH_NPTH )
370  buildNPTHlist = true;
371 
372  buildHolesList( DRILL_LAYER_PAIR( F_Cu, B_Cu ), buildNPTHlist );
373 
374  // nothing wrong with an empty NPTH file in report.
375  if( m_merge_PTH_NPTH )
376  out.Print( 0, "Not plated through holes are merged with plated holes\n" );
377  else
378  out.Print( 0, "Drill file '%s' contains\n",
380  true, m_merge_PTH_NPTH ) ) );
381 
382  out.Print( 0, " unplated through holes:\n" );
383  out.Print( 0, separator );
384  totalHoleCount = printToolSummary( out, true );
385  out.Print( 0, " Total unplated holes count %u\n", totalHoleCount );
386 
387  return true;
388 }
389 
390 
392 {
393  // Plot the drill map:
394  wxPoint pos;
395 
396  for( unsigned ii = 0; ii < m_holeListBuffer.size(); ii++ )
397  {
398  const HOLE_INFO& hole = m_holeListBuffer[ii];
399  pos = hole.m_Hole_Pos;
400 
401  // Always plot the drill symbol (for slots identifies the needed cutter!
402  aPlotter->Marker( pos, hole.m_Hole_Diameter, hole.m_Tool_Reference - 1 );
403 
404  if( hole.m_Hole_Shape != 0 )
405  {
406  wxSize oblong_size = hole.m_Hole_Size;
407  aPlotter->FlashPadOval( pos, oblong_size, hole.m_Hole_Orient, SKETCH, NULL );
408  }
409  }
410 
411  return true;
412 }
413 
414 
415 unsigned EXCELLON_WRITER::printToolSummary( OUTPUTFORMATTER& out, bool aSummaryNPTH ) const
416 {
417  unsigned totalHoleCount = 0;
418 
419  for( unsigned ii = 0; ii < m_toolListBuffer.size(); ii++ )
420  {
421  const DRILL_TOOL& tool = m_toolListBuffer[ii];
422 
423  if( aSummaryNPTH && !tool.m_Hole_NotPlated )
424  continue;
425 
426  if( !aSummaryNPTH && tool.m_Hole_NotPlated )
427  continue;
428 
429  // List the tool number assigned to each drill,
430  // in mm then in inches.
431  int tool_number = ii+1;
432  out.Print( 0, " T%d %2.2fmm %2.3f\" ", tool_number,
433  diameter_in_mm( tool.m_Diameter ),
434  diameter_in_inches( tool.m_Diameter ) );
435 
436  // Now list how many holes and ovals are associated with each drill.
437  if( ( tool.m_TotalCount == 1 ) && ( tool.m_OvalCount == 0 ) )
438  out.Print( 0, "(1 hole)\n" );
439  else if( tool.m_TotalCount == 1 )
440  out.Print( 0, "(1 hole) (with 1 slot)\n" );
441  else if( tool.m_OvalCount == 0 )
442  out.Print( 0, "(%d holes)\n", tool.m_TotalCount );
443  else if( tool.m_OvalCount == 1 )
444  out.Print( 0, "(%d holes) (with 1 slot)\n", tool.m_TotalCount );
445  else // tool.m_OvalCount > 1
446  out.Print( 0, "(%d holes) (with %d slots)\n",
447  tool.m_TotalCount, tool.m_OvalCount );
448 
449  totalHoleCount += tool.m_TotalCount;
450  }
451 
452  out.Print( 0, "\n" );
453 
454  return totalHoleCount;
455 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:639
double diameter_in_inches(double ius)
std::vector< DRILL_TOOL > m_toolListBuffer
double diameter_in_mm(double ius)
virtual void SetCreator(const wxString &aCreator)
Definition: plot_common.h:151
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
virtual bool StartPlot()=0
This file is part of the common library.
PlotFormat
Enum PlotFormat is the set of supported output plot formats.
Definition: plot_common.h:49
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Class BOARD to handle a board.
int GetHeight() const
const wxString drillFileName(DRILL_LAYER_PAIR aPair, bool aNPTH, bool aMerge_PTH_NPTH) const
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
Class OUTPUTFORMATTER is an important interface (abstract class) used to output 8 bit text in a conve...
Definition: richio.h:327
void buildHolesList(DRILL_LAYER_PAIR aLayerPair, bool aGenerateNPTH_list)
Function BuildHolesList Create the list of holes and tools for a given board The list is sorted by in...
virtual void SetPageSettings(const PAGE_INFO &aPageSettings)
#define cu(a)
Definition: auxiliary.h:88
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
unsigned printToolSummary(OUTPUTFORMATTER &aOut, bool aSummaryNPTH) const
Function printToolSummary prints m_toolListBuffer[] tools to aOut and returns total hole count...
virtual void SetGerberCoordinatesFormat(int aResolution, bool aUseInches=false)
Definition: plot_common.h:415
This file contains miscellaneous commonly used macros and functions.
virtual void Text(const wxPoint &aPos, const COLOR4D aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, bool aMultilineAllowed=false, void *aData=NULL)
Draws text with the plotter.
Definition: drawtxt.cpp:227
Board plot function definition file.
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:839
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:337
BOARD_ITEM * Next() const
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
virtual bool EndPlot()=0
Class LSET is a set of PCB_LAYER_IDs.
void SetLayerSet(LSET aLayerMask)
Definition: pcbplot.h:104
int GetHPGLPenNum() const
const wxString & GetFileName() const
Definition: class_board.h:237
Class PAGE_INFO describes the page size and margins of a paper page on which to eventually print or p...
virtual void SetPenSpeed(int speed)
Definition: plot_common.h:586
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
DLIST< BOARD_ITEM > m_Drawings
Definition: class_board.h:242
Common plot library Plot settings, and plotting engines (Postscript, Gerber, HPGL and DXF) ...
static const wxChar A4[]
int GetBottom() const
wxPoint Centre() const
bool plotDrillMarks(PLOTTER *aPlotter)
Helper function.
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board...
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:112
std::pair< PCB_LAYER_ID, PCB_LAYER_ID > DRILL_LAYER_PAIR
const PAGE_INFO * m_pageInfo
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
virtual void SetViewport(const wxPoint &aOffset, double aIusPerDecimil, double aScale, bool aMirror)=0
Set the plot offset and scaling for the current plot.
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:113
void Marker(const wxPoint &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord x0, y0.
virtual void SetDefaultLineWidth(int width)=0
Set the default line width.
Base plotter engine class.
Definition: plot_common.h:86
bool GenDrillMapFile(const wxString &aFullFileName, PlotFormat aFormat)
Function GenDrillMapFile Plot a map of drill marks for holes.
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:111
const int scale
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
std::vector< HOLE_INFO > m_holeListBuffer
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadOval
virtual void SetPenNumber(int number)
Definition: plot_common.h:591
std::vector< DRILL_LAYER_PAIR > getUniqueLayerPairs() const
Get unique layer pairs by examining the micro and blind_buried vias.
int GetHPGLPenSpeed() const
Class EDA_RECT handles the component boundary box.
int GetX() const
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
The common library.
int GetWidth() const
bool GenDrillReportFile(const wxString &aFullFileName)
Function GenDrillReportFile Create a plain text report file giving a list of drill values and drill c...
void PlotTextePcb(TEXTE_PCB *pt_texte)
Class FILE_OUTPUTFORMATTER may be used for text file output.
Definition: richio.h:492
Classes used in drill files, map files and report files generation.
This file is part of the common libary.
Basic classes for most KiCad items.
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Function Print formats and writes text to the output stream.
Definition: richio.cpp:408
const wxPoint GetOffset()
Return the plot offset (usually the position of the auxiliary axis.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:767
const std::string layerName(PCB_LAYER_ID aLayer) const
virtual void SetColorMode(bool _color_mode)
Definition: plot_common.h:116
wxString DateAndTime()
Function DateAndTime.
Definition: string.cpp:229
#define min(a, b)
Definition: auxiliary.h:85
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
void PlotDrawSegment(DRAWSEGMENT *PtSegm)