KiCad PCB EDA Suite
GERBER_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) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2019 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 
30 #include <fctsys.h>
31 #include <gr_basic.h>
32 #include <trigo.h>
33 #include <eda_base_frame.h>
34 #include <base_struct.h>
35 #include <common.h>
36 #include <plotter.h>
37 #include <macros.h>
38 #include <kicad_string.h>
40 
41 #include <build_version.h>
42 
43 #include <gbr_metadata.h>
44 
45 
47 {
48  workFile = NULL;
49  finalFile = NULL;
50  currentAperture = apertures.end();
52 
53  // number of digits after the point (number of digits of the mantissa
54  // Be carefull: the Gerber coordinates are stored in an integer
55  // so 6 digits (inches) or 5 digits (mm) is a good value
56  // To avoid overflow, 7 digits (inches) or 6 digits is a max.
57  // with lower values than 6 digits (inches) or 5 digits (mm),
58  // Creating self-intersecting polygons from non-intersecting polygons
59  // happen easily.
60  m_gerberUnitInch = false;
61  m_gerberUnitFmt = 6;
62  m_useX2format = true;
63  m_useNetAttributes = true;
64 }
65 
66 
67 void GERBER_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
68  double aScale, bool aMirror )
69 {
70  wxASSERT( aMirror == false );
71  m_plotMirror = false;
72  plotOffset = aOffset;
73  wxASSERT( aScale == 1 ); // aScale parameter is not used in Gerber
74  plotScale = 1; // Plot scale is *always* 1.0
75 
76  m_IUsPerDecimil = aIusPerDecimil;
77  // gives now a default value to iuPerDeviceUnit (because the units of the caller is now known)
78  // which could be modified later by calling SetGerberCoordinatesFormat()
79  iuPerDeviceUnit = pow( 10.0, m_gerberUnitFmt ) / ( m_IUsPerDecimil * 10000.0 );
80 
81  // We don't handle the filmbox, and it's more useful to keep the
82  // origin at the origin
83  paperSize.x = 0;
84  paperSize.y = 0;
85  SetDefaultLineWidth( 100 * aIusPerDecimil ); // Arbitrary default
86 }
87 
88 
89 void GERBER_PLOTTER::SetGerberCoordinatesFormat( int aResolution, bool aUseInches )
90 {
91  m_gerberUnitInch = aUseInches;
92  m_gerberUnitFmt = aResolution;
93 
94  iuPerDeviceUnit = pow( 10.0, m_gerberUnitFmt ) / ( m_IUsPerDecimil * 10000.0 );
95 
96  if( ! m_gerberUnitInch )
97  iuPerDeviceUnit *= 25.4; // gerber output in mm
98 }
99 
100 
101 void GERBER_PLOTTER::emitDcode( const DPOINT& pt, int dcode )
102 {
103 
104  fprintf( outputFile, "X%dY%dD%02d*\n",
105  KiROUND( pt.x ), KiROUND( pt.y ), dcode );
106 }
107 
108 
110 {
111  // disable a Gerber net attribute (exists only in X2 with net attributes mode).
112  if( m_objectAttributesDictionnary.empty() ) // No net attribute or not X2 mode
113  return;
114 
115  // Remove all net attributes from object attributes dictionary
116  if( m_useX2format )
117  fputs( "%TD*%\n", outputFile );
118  else
119  fputs( "G04 #@! TD*\n", outputFile );
120 
122 }
123 
124 
125 void GERBER_PLOTTER::StartBlock( void* aData )
126 {
127  // Currently, it is the same as EndBlock(): clear all aperture net attributes
128  EndBlock( aData );
129 }
130 
131 
132 void GERBER_PLOTTER::EndBlock( void* aData )
133 {
134  // Remove all net attributes from object attributes dictionary
136 }
137 
138 
140 {
141  // print a Gerber net attribute record.
142  // it is added to the object attributes dictionary
143  // On file, only modified or new attributes are printed.
144  if( aData == NULL )
145  return;
146 
147  if( !m_useNetAttributes )
148  return;
149 
150  bool useX1StructuredComment = !m_useX2format;
151 
152  bool clearDict;
153  std::string short_attribute_string;
154 
155  if( !FormatNetAttribute( short_attribute_string, m_objectAttributesDictionnary,
156  aData, clearDict, useX1StructuredComment ) )
157  return;
158 
159  if( clearDict )
161 
162  if( !short_attribute_string.empty() )
163  fputs( short_attribute_string.c_str(), outputFile );
164 
165  if( m_useX2format && !aData->m_ExtraData.IsEmpty() )
166  {
167  std::string extra_data = TO_UTF8( aData->m_ExtraData );
168  fputs( extra_data.c_str(), outputFile );
169  }
170 }
171 
172 
174 {
175  wxASSERT( outputFile );
176 
177  finalFile = outputFile; // the actual gerber file will be created later
178 
179  // Create a temporary filename to store gerber file
180  // note tmpfile() does not work under Vista and W7 in user mode
181  m_workFilename = filename + wxT(".tmp");
182  workFile = wxFopen( m_workFilename, wxT( "wt" ));
184  wxASSERT( outputFile );
185 
186  if( outputFile == NULL )
187  return false;
188 
189  for( unsigned ii = 0; ii < m_headerExtraLines.GetCount(); ii++ )
190  {
191  if( ! m_headerExtraLines[ii].IsEmpty() )
192  fprintf( outputFile, "%s\n", TO_UTF8( m_headerExtraLines[ii] ) );
193  }
194 
195  // Set coordinate format to 3.6 or 4.5 absolute, leading zero omitted
196  // the number of digits for the integer part of coordinates is needed
197  // in gerber format, but is not very important when omitting leading zeros
198  // It is fixed here to 3 (inch) or 4 (mm), but is not actually used
199  int leadingDigitCount = m_gerberUnitInch ? 3 : 4;
200 
201  fprintf( outputFile, "%%FSLAX%d%dY%d%d*%%\n",
202  leadingDigitCount, m_gerberUnitFmt,
203  leadingDigitCount, m_gerberUnitFmt );
204  fprintf( outputFile,
205  "G04 Gerber Fmt %d.%d, Leading zero omitted, Abs format (unit %s)*\n",
206  leadingDigitCount, m_gerberUnitFmt,
207  m_gerberUnitInch ? "inch" : "mm" );
208 
209  wxString Title = creator + wxT( " " ) + GetBuildVersion();
210  // In gerber files, ASCII7 chars only are allowed.
211  // So use a ISO date format (using a space as separator between date and time),
212  // not a localized date format
213  wxDateTime date = wxDateTime::Now();
214  fprintf( outputFile, "G04 Created by KiCad (%s) date %s*\n",
215  TO_UTF8( Title ), TO_UTF8( date.FormatISOCombined( ' ') ) );
216 
217  /* Mass parameter: unit = INCHES/MM */
218  if( m_gerberUnitInch )
219  fputs( "%MOIN*%\n", outputFile );
220  else
221  fputs( "%MOMM*%\n", outputFile );
222 
223  // Be sure the usual dark polarity is selected:
224  fputs( "%LPD*%\n", outputFile );
225 
226  fputs( "G04 APERTURE LIST*\n", outputFile );
227 
228  return true;
229 }
230 
231 
233 {
234  char line[1024];
235  wxString msg;
236 
237  wxASSERT( outputFile );
238 
239  /* Outfile is actually a temporary file i.e. workFile */
240  fputs( "M02*\n", outputFile );
241  fflush( outputFile );
242 
243  fclose( workFile );
244  workFile = wxFopen( m_workFilename, wxT( "rt" ));
245  wxASSERT( workFile );
247 
248  // Placement of apertures in RS274X
249  while( fgets( line, 1024, workFile ) )
250  {
251  fputs( line, outputFile );
252 
253  char* substr = strtok( line, "\n\r" );
254 
255  if( substr && strcmp( substr, "G04 APERTURE LIST*" ) == 0 )
256  {
258  fputs( "G04 APERTURE END LIST*\n", outputFile );
259  }
260  }
261 
262  fclose( workFile );
263  fclose( finalFile );
264  ::wxRemoveFile( m_workFilename );
265  outputFile = 0;
266 
267  return true;
268 }
269 
270 
272 {
273  defaultPenWidth = width;
274  currentAperture = apertures.end();
275 }
276 
277 
278 void GERBER_PLOTTER::SetCurrentLineWidth( int width, void* aData )
279 {
280  if( width == DO_NOT_SET_LINE_WIDTH )
281  return;
282 
283  int pen_width;
284 
285  if( width > 0 )
286  pen_width = width;
287  else
288  pen_width = defaultPenWidth;
289 
290  GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
291  int aperture_attribute = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
292 
293  selectAperture( wxSize( pen_width, pen_width ), APERTURE::AT_PLOTTING, aperture_attribute );
294  currentPenWidth = pen_width;
295 }
296 
297 
298 std::vector<APERTURE>::iterator GERBER_PLOTTER::getAperture( const wxSize& aSize,
299  APERTURE::APERTURE_TYPE aType, int aApertureAttribute )
300 {
301  int last_D_code = 9;
302 
303  // Search an existing aperture
304  std::vector<APERTURE>::iterator tool = apertures.begin();
305 
306  while( tool != apertures.end() )
307  {
308  last_D_code = tool->m_DCode;
309 
310  if( (tool->m_Type == aType) && (tool->m_Size == aSize) &&
311  (tool->m_ApertureAttribute == aApertureAttribute) )
312  return tool;
313 
314  ++tool;
315  }
316 
317  // Allocate a new aperture
318  APERTURE new_tool;
319  new_tool.m_Size = aSize;
320  new_tool.m_Type = aType;
321  new_tool.m_DCode = last_D_code + 1;
322  new_tool.m_ApertureAttribute = aApertureAttribute;
323 
324  apertures.push_back( new_tool );
325 
326  return apertures.end() - 1;
327 }
328 
329 
330 void GERBER_PLOTTER::selectAperture( const wxSize& aSize,
332  int aApertureAttribute )
333 {
334  bool change = ( currentAperture == apertures.end() ) ||
335  ( currentAperture->m_Type != aType ) ||
336  ( currentAperture->m_Size != aSize );
337 
338  if( !m_useNetAttributes )
339  aApertureAttribute = 0;
340  else
341  change = change || ( currentAperture->m_ApertureAttribute != aApertureAttribute );
342 
343  if( change )
344  {
345  // Pick an existing aperture or create a new one
346  currentAperture = getAperture( aSize, aType, aApertureAttribute );
347  fprintf( outputFile, "D%d*\n", currentAperture->m_DCode );
348  }
349 }
350 
351 void GERBER_PLOTTER::selectAperture( int aDiameter, double aPolygonRotation,
352  APERTURE::APERTURE_TYPE aType, int aApertureAttribute )
353 {
354  // Pick an existing aperture or create a new one, matching the
355  // aDiameter, aPolygonRotation, type and attributes for type =
356  // AT_REGULAR_POLY3 to AT_REGULAR_POLY12
357 
358  wxASSERT( aType>= APERTURE::APERTURE_TYPE::AT_REGULAR_POLY3 &&
359  aType <= APERTURE::APERTURE_TYPE::AT_REGULAR_POLY12 );
360 
361  // To use selectAperture( size, ... ) calculate a equivalent aperture size:
362  // for AT_REGULAR_POLYxx the parameter APERTURE::m_Size contains
363  // aDiameter (in m_Size.x) and aPolygonRotation in 1/1000 degree (in m_Size.y)
364  wxSize size( aDiameter, (int)( aPolygonRotation * 1000.0 ) );
365  selectAperture( size, aType, aApertureAttribute );
366 }
367 
369 {
370  wxASSERT( outputFile );
371  char cbuf[1024];
372 
373  bool useX1StructuredComment = false;
374 
375  if( !m_useX2format )
376  useX1StructuredComment = true;
377 
378  // Init
379  for( std::vector<APERTURE>::iterator tool = apertures.begin();
380  tool != apertures.end(); ++tool )
381  {
382  // apertude sizes are in inch or mm, regardless the
383  // coordinates format
384  double fscale = 0.0001 * plotScale / m_IUsPerDecimil; // inches
385 
386  if(! m_gerberUnitInch )
387  fscale *= 25.4; // size in mm
388 
389  int attribute = tool->m_ApertureAttribute;
390 
391  if( attribute != m_apertureAttribute )
392  {
395  useX1StructuredComment ).c_str(), outputFile );
396  }
397 
398  char* text = cbuf + sprintf( cbuf, "%%ADD%d", tool->m_DCode );
399 
400  /* Please note: the Gerber specs for mass parameters say that
401  exponential syntax is *not* allowed and the decimal point should
402  also be always inserted. So the %g format is ruled out, but %f is fine
403  (the # modifier forces the decimal point). Sadly the %f formatter
404  can't remove trailing zeros but thats not a problem, since nothing
405  forbid it (the file is only slightly longer) */
406 
407  switch( tool->m_Type )
408  {
409  case APERTURE::AT_CIRCLE:
410  sprintf( text, "C,%#f*%%\n", tool->GetDiameter() * fscale );
411  break;
412 
413  case APERTURE::AT_RECT:
414  sprintf( text, "R,%#fX%#f*%%\n", tool->m_Size.x * fscale,
415  tool->m_Size.y * fscale );
416  break;
417 
419  sprintf( text, "C,%#f*%%\n", tool->m_Size.x * fscale );
420  break;
421 
422  case APERTURE::AT_OVAL:
423  sprintf( text, "O,%#fX%#f*%%\n", tool->m_Size.x * fscale,
424  tool->m_Size.y * fscale );
425  break;
426 
438  sprintf( text, "P,%#fX%dX%#f*%%\n", tool->GetDiameter() * fscale,
439  tool->GetVerticeCount(), tool->GetRotation() );
440  break;
441  }
442 
443  fputs( cbuf, outputFile );
444 
445  m_apertureAttribute = attribute;
446 
447  // Currently reset the aperture attribute. Perhaps a better optimization
448  // is to store the last attribute
449  if( attribute )
450  {
451  if( m_useX2format )
452  fputs( "%TD*%\n", outputFile );
453  else
454  fputs( "G04 #@! TD*\n", outputFile );
455 
457  }
458 
459  }
460 }
461 
462 
463 void GERBER_PLOTTER::PenTo( const wxPoint& aPos, char plume )
464 {
465  wxASSERT( outputFile );
466  DPOINT pos_dev = userToDeviceCoordinates( aPos );
467 
468  switch( plume )
469  {
470  case 'Z':
471  break;
472 
473  case 'U':
474  emitDcode( pos_dev, 2 );
475  break;
476 
477  case 'D':
478  emitDcode( pos_dev, 1 );
479  }
480 
481  penState = plume;
482 }
483 
484 
485 void GERBER_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width )
486 {
487  std::vector< wxPoint > cornerList;
488 
489  // Build corners list
490  cornerList.push_back( p1 );
491  wxPoint corner(p1.x, p2.y);
492  cornerList.push_back( corner );
493  cornerList.push_back( p2 );
494  corner.x = p2.x;
495  corner.y = p1.y;
496  cornerList.push_back( corner );
497  cornerList.push_back( p1 );
498 
499  PlotPoly( cornerList, fill, width );
500 }
501 
502 
503 void GERBER_PLOTTER::Circle( const wxPoint& aCenter, int aDiameter, FILL_T aFill, int aWidth )
504 {
505  Arc( aCenter, 0, 3600, aDiameter / 2, aFill, aWidth );
506 }
507 
508 
509 void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle,
510  int aRadius, FILL_T aFill, int aWidth )
511 {
512  SetCurrentLineWidth( aWidth );
513 
514  wxPoint start, end;
515  start.x = aCenter.x + KiROUND( cosdecideg( aRadius, aStAngle ) );
516  start.y = aCenter.y - KiROUND( sindecideg( aRadius, aStAngle ) );
517  MoveTo( start );
518  end.x = aCenter.x + KiROUND( cosdecideg( aRadius, aEndAngle ) );
519  end.y = aCenter.y - KiROUND( sindecideg( aRadius, aEndAngle ) );
520  DPOINT devEnd = userToDeviceCoordinates( end );
521  DPOINT devCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
522 
523  fprintf( outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
524 
525  if( aStAngle < aEndAngle )
526  fprintf( outputFile, "G03" );
527  else
528  fprintf( outputFile, "G02" );
529 
530  fprintf( outputFile, "X%dY%dI%dJ%dD01*\n",
531  KiROUND( devEnd.x ), KiROUND( devEnd.y ),
532  KiROUND( devCenter.x ), KiROUND( devCenter.y ) );
533 
534  fprintf( outputFile, "G01*\n" ); // Back to linear interpol (perhaps useless here).
535 }
536 
537 
538 void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList,
539  FILL_T aFill, int aWidth, void * aData )
540 {
541  if( aCornerList.size() <= 1 )
542  return;
543 
544  // Gerber format does not know filled polygons with thick outline
545  // Therefore, to plot a filled polygon with outline having a thickness,
546  // one should plot outline as thick segments
547  GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
548 
549  SetCurrentLineWidth( aWidth, gbr_metadata );
550 
551  if( gbr_metadata )
552  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
553 
554  if( aFill )
555  {
556  fputs( "G36*\n", outputFile );
557 
558  MoveTo( aCornerList[0] );
559  fputs( "G01*\n", outputFile ); // Set linear interpolation.
560 
561  for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
562  LineTo( aCornerList[ii] );
563 
564  FinishTo( aCornerList[0] );
565  fputs( "G37*\n", outputFile );
566  }
567 
568  if( aWidth > 0 )
569  {
570  MoveTo( aCornerList[0] );
571 
572  for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
573  LineTo( aCornerList[ii] );
574 
575  // Ensure the thick outline is closed for filled polygons
576  // (if not filled, could be only a polyline)
577  if( aFill && ( aCornerList[aCornerList.size()-1] != aCornerList[0] ) )
578  LineTo( aCornerList[0] );
579 
580  PenFinish();
581  }
582 }
583 
584 
585 void GERBER_PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
586  EDA_DRAW_MODE_T tracemode, void* aData )
587 {
588  if( tracemode == FILLED )
589  {
590  GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
591  SetCurrentLineWidth( width, gbr_metadata );
592 
593  if( gbr_metadata )
594  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
595 
596  MoveTo( start );
597  FinishTo( end );
598  }
599  else
600  {
602  segmentAsOval( start, end, width, tracemode );
603  }
604 }
605 
606 void GERBER_PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
607  int radius, int width, EDA_DRAW_MODE_T tracemode, void* aData )
608 {
609  GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
610  SetCurrentLineWidth( width, gbr_metadata );
611 
612  if( gbr_metadata )
613  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
614 
615  if( tracemode == FILLED )
616  Arc( centre, StAngle, EndAngle, radius, NO_FILL, DO_NOT_SET_LINE_WIDTH );
617  else
618  {
620  Arc( centre, StAngle, EndAngle,
621  radius - ( width - currentPenWidth ) / 2,
623  Arc( centre, StAngle, EndAngle,
624  radius + ( width - currentPenWidth ) / 2, NO_FILL,
626  }
627 }
628 
629 
630 void GERBER_PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
631  EDA_DRAW_MODE_T tracemode, void* aData )
632 {
633  GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
634  SetCurrentLineWidth( width, gbr_metadata );
635 
636  if( gbr_metadata )
637  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
638 
639  if( tracemode == FILLED )
640  Rect( p1, p2, NO_FILL, DO_NOT_SET_LINE_WIDTH );
641  else
642  {
644  wxPoint offsetp1( p1.x - (width - currentPenWidth) / 2,
645  p1.y - (width - currentPenWidth) / 2 );
646  wxPoint offsetp2( p2.x + (width - currentPenWidth) / 2,
647  p2.y + (width - currentPenWidth) / 2 );
648  Rect( offsetp1, offsetp2, NO_FILL, -1 );
649  offsetp1.x += (width - currentPenWidth);
650  offsetp1.y += (width - currentPenWidth);
651  offsetp2.x -= (width - currentPenWidth);
652  offsetp2.y -= (width - currentPenWidth);
653  Rect( offsetp1, offsetp2, NO_FILL, DO_NOT_SET_LINE_WIDTH );
654  }
655 }
656 
657 
658 void GERBER_PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width,
659  EDA_DRAW_MODE_T tracemode, void* aData )
660 {
661  GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
662  SetCurrentLineWidth( width, gbr_metadata );
663 
664  if( gbr_metadata )
665  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
666 
667  if( tracemode == FILLED )
668  Circle( pos, diametre, NO_FILL, DO_NOT_SET_LINE_WIDTH );
669  else
670  {
672  Circle( pos, diametre - (width - currentPenWidth),
674  Circle( pos, diametre + (width - currentPenWidth),
676  }
677 }
678 
679 
680 void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T trace_mode, void* aData )
681 {
682  wxSize size( diametre, diametre );
683  GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
684 
685  if( trace_mode == SKETCH )
686  {
688 
689  if( gbr_metadata )
690  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
691 
693  }
694  else
695  {
696  DPOINT pos_dev = userToDeviceCoordinates( pos );
697 
698  int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
699  selectAperture( size, APERTURE::AT_CIRCLE, aperture_attrib );
700 
701  if( gbr_metadata )
702  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
703 
704  emitDcode( pos_dev, 3 );
705  }
706 }
707 
708 
709 void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient,
710  EDA_DRAW_MODE_T trace_mode, void* aData )
711 {
712  wxASSERT( outputFile );
713  wxSize size( aSize );
714  GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
715 
716  /* Plot a flashed shape. */
717  if( ( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 )
718  && trace_mode == FILLED )
719  {
720  if( orient == 900 || orient == 2700 ) /* orientation turned 90 deg. */
721  std::swap( size.x, size.y );
722 
723  DPOINT pos_dev = userToDeviceCoordinates( pos );
724  int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
725  selectAperture( size, APERTURE::AT_OVAL, aperture_attrib );
726 
727  if( gbr_metadata )
728  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
729 
730  emitDcode( pos_dev, 3 );
731  }
732  else /* Plot pad as a segment. */
733  {
734  if( size.x > size.y )
735  {
736  std::swap( size.x, size.y );
737 
738  if( orient < 2700 )
739  orient += 900;
740  else
741  orient -= 2700;
742  }
743 
744  if( trace_mode == FILLED )
745  {
746  // TODO: use an aperture macro to declare the rotated pad
747 
748  // Flash a pad anchor, if a netlist attribute is set
749  if( aData )
750  FlashPadCircle( pos, size.x, trace_mode, aData );
751 
752  // The pad is reduced to an segment with dy > dx
753  int delta = size.y - size.x;
754  int x0 = 0;
755  int y0 = -delta / 2;
756  int x1 = 0;
757  int y1 = delta / 2;
758  RotatePoint( &x0, &y0, orient );
759  RotatePoint( &x1, &y1, orient );
760  GBR_METADATA metadata;
761 
762  if( gbr_metadata )
763  {
764  metadata = *gbr_metadata;
765 
766  // If the pad is drawn on a copper layer,
767  // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
768  if( metadata.IsCopper() )
770 
771  // Clear .P attribute, only allowed for flashed items
772  wxString attrname( ".P" );
773  metadata.m_NetlistMetadata.ClearAttribute( &attrname );
774  }
775 
776  ThickSegment( wxPoint( pos.x + x0, pos.y + y0 ),
777  wxPoint( pos.x + x1, pos.y + y1 ),
778  size.x, trace_mode, &metadata );
779  }
780  else
781  {
782  sketchOval( pos, size, orient, -1 );
783  }
784  }
785 }
786 
787 
788 void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
789  double orient, EDA_DRAW_MODE_T trace_mode, void* aData )
790 
791 {
792  wxASSERT( outputFile );
793  wxSize size( aSize );
794  GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
795 
796  // Plot as an aperture flash
797  switch( int( orient ) )
798  {
799  case 900:
800  case 2700: // rotation of 90 degrees or 270 swaps sizes
801  std::swap( size.x, size.y );
802  // Pass through
803  case 0:
804  case 1800:
805  if( trace_mode == SKETCH )
806  {
808 
809  if( gbr_metadata )
810  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
811 
812  Rect( wxPoint( pos.x - (size.x - currentPenWidth) / 2,
813  pos.y - (size.y - currentPenWidth) / 2 ),
814  wxPoint( pos.x + (size.x - currentPenWidth) / 2,
815  pos.y + (size.y - currentPenWidth) / 2 ),
817  }
818  else
819  {
820  DPOINT pos_dev = userToDeviceCoordinates( pos );
821  int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
822  selectAperture( size, APERTURE::AT_RECT, aperture_attrib );
823 
824  if( gbr_metadata )
825  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
826 
827  emitDcode( pos_dev, 3 );
828  }
829  break;
830 
831  default: // plot pad shape as polygon
832  {
833  // XXX to do: use an aperture macro to declare the rotated pad
834  wxPoint coord[4];
835  // coord[0] is assumed the lower left
836  // coord[1] is assumed the upper left
837  // coord[2] is assumed the upper right
838  // coord[3] is assumed the lower right
839 
840  /* Trace the outline. */
841  coord[0].x = -size.x/2; // lower left
842  coord[0].y = size.y/2;
843  coord[1].x = -size.x/2; // upper left
844  coord[1].y = -size.y/2;
845  coord[2].x = size.x/2; // upper right
846  coord[2].y = -size.y/2;
847  coord[3].x = size.x/2; // lower right
848  coord[3].y = size.y/2;
849 
850  FlashPadTrapez( pos, coord, orient, trace_mode, aData );
851  }
852  break;
853  }
854 }
855 
856 void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
857  int aCornerRadius, double aOrient,
858  EDA_DRAW_MODE_T aTraceMode, void* aData )
859 
860 {
861  GBR_METADATA gbr_metadata;
862 
863  if( aData )
864  {
865  gbr_metadata = *static_cast<GBR_METADATA*>( aData );
866  // If the pad is drawn on a copper layer,
867  // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
868  if( gbr_metadata.IsCopper() )
870 
871  wxString attrname( ".P" );
872  gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
873  }
874 
875  if( aTraceMode != FILLED )
877 
878  // Currently, a Pad RoundRect is plotted as polygon.
879  // TODO: use Aperture macro and flash it
880  SHAPE_POLY_SET outline;
881  TransformRoundChamferedRectToPolygon( outline, aPadPos, aSize, aOrient,
882  aCornerRadius, 0.0, 0, GetPlotterArcHighDef() );
883 
884  if( aTraceMode != FILLED )
885  outline.Inflate( -GetCurrentLineWidth()/2, 16 );
886 
887  std::vector< wxPoint > cornerList;
888  // TransformRoundRectToPolygon creates only one convex polygon
889  SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
890  cornerList.reserve( poly.PointCount() + 1 );
891 
892  for( int ii = 0; ii < poly.PointCount(); ++ii )
893  cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
894 
895  // Close polygon
896  cornerList.push_back( cornerList[0] );
897 
898  PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL,
899  aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata );
900 
901  // Now, flash a pad anchor, if a netlist attribute is set
902  // (remove me when a Aperture macro will be used)
903  if( aData && aTraceMode == FILLED )
904  {
905  int diameter = std::min( aSize.x, aSize.y );
906  FlashPadCircle( aPadPos, diameter, aTraceMode , aData );
907  }
908 }
909 
910 void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
911  SHAPE_POLY_SET* aPolygons,
912  EDA_DRAW_MODE_T aTraceMode, void* aData )
913 
914 {
915  // A Pad custom is plotted as polygon.
916 
917  // A flashed circle @aPadPos is added (anchor pad)
918  // However, because the anchor pad can be circle or rect, we use only
919  // a circle not bigger than the rect.
920  // the main purpose is to print a flashed DCode as pad anchor
921  if( aTraceMode == FILLED )
922  FlashPadCircle( aPadPos, std::min( aSize.x, aSize.y ), aTraceMode, aData );
923 
924  GBR_METADATA gbr_metadata;
925 
926  if( aData )
927  {
928  gbr_metadata = *static_cast<GBR_METADATA*>( aData );
929  // If the pad is drawn on a copper layer,
930  // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
931  if( gbr_metadata.IsCopper() )
933 
934  wxString attrname( ".P" );
935  gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
936  }
937 
938  SHAPE_POLY_SET polyshape = *aPolygons;
939 
940  if( aTraceMode != FILLED )
941  {
943  polyshape.Inflate( -GetCurrentLineWidth()/2, 16 );
944  }
945 
946  std::vector< wxPoint > cornerList;
947 
948  for( int cnt = 0; cnt < polyshape.OutlineCount(); ++cnt )
949  {
950  SHAPE_LINE_CHAIN& poly = polyshape.Outline( cnt );
951 
952  cornerList.clear();
953 
954  for( int ii = 0; ii < poly.PointCount(); ++ii )
955  cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
956 
957  // Close polygon
958  cornerList.push_back( cornerList[0] );
959 
960  PlotPoly( cornerList,
961  aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL,
962  aTraceMode == FILLED ? 0 : GetCurrentLineWidth(), &gbr_metadata );
963  }
964 }
965 
966 
967 void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners,
968  double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData )
969 
970 {
971  // Currently, a Pad Trapezoid is plotted as polygon.
972  // TODO: use Aperture macro and flash it
973 
974  // polygon corners list
975  std::vector< wxPoint > cornerList;
976 
977  for( int ii = 0; ii < 4; ii++ )
978  cornerList.push_back( aCorners[ii] );
979 
980  // Now, flash a pad anchor, if a netlist attribute is set
981  // (remove me when a Aperture macro will be used)
982  if( aData && ( aTrace_Mode == FILLED ) )
983  {
984  // Calculate the radius of the circle inside the shape
985  // It is the smaller dist from shape pos to edges
986  int radius = INT_MAX;
987 
988  for( unsigned ii = 0, jj = cornerList.size()-1; ii < cornerList.size();
989  jj = ii, ii++ )
990  {
991  SEG segment( aCorners[ii], aCorners[jj] );
992  int dist = segment.LineDistance( VECTOR2I( 0, 0) );
993  radius = std::min( radius, dist );
994  }
995 
996  FlashPadCircle( aPadPos, radius*2, aTrace_Mode, aData );
997  }
998 
999  // Draw the polygon and fill the interior as required
1000  for( unsigned ii = 0; ii < 4; ii++ )
1001  {
1002  RotatePoint( &cornerList[ii], aPadOrient );
1003  cornerList[ii] += aPadPos;
1004  }
1005 
1006  // Close the polygon
1007  cornerList.push_back( cornerList[0] );
1008  GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
1009 
1010  GBR_METADATA metadata;
1011 
1012  if( gbr_metadata )
1013  {
1014  metadata = *gbr_metadata;
1015  // If the pad is drawn on a copper layer,
1016  // set attribute to GBR_APERTURE_ATTRIB_CONDUCTOR
1017  if( metadata.IsCopper() )
1019 
1020  wxString attrname( ".P" );
1021  metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
1022  }
1023 
1025  PlotPoly( cornerList, aTrace_Mode == FILLED ? FILLED_SHAPE : NO_FILL,
1026  aTrace_Mode == FILLED ? 0 : GetCurrentLineWidth(),
1027  &metadata );
1028 }
1029 
1030 
1031 void GERBER_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos,
1032  int aDiameter, int aCornerCount,
1033  double aOrient, EDA_DRAW_MODE_T aTraceMode,
1034  void* aData )
1035 {
1036  GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
1037 
1038  if( aTraceMode == SKETCH )
1039  {
1040  // Build the polygon:
1041  std::vector< wxPoint > cornerList;
1042 
1043  double angle_delta = 3600.0 / aCornerCount; // in 0.1 degree
1044 
1045  for( int ii = 0; ii < aCornerCount; ii++ )
1046  {
1047  double rot = aOrient + (angle_delta*ii);
1048  wxPoint vertice( aDiameter/2, 0 );
1049  RotatePoint( &vertice, rot );
1050  vertice += aShapePos;
1051  cornerList.push_back( vertice );
1052  }
1053 
1054  cornerList.push_back( cornerList[0] ); // Close the shape
1055 
1056  SetCurrentLineWidth( aDiameter/8, gbr_metadata );
1057  PlotPoly( cornerList, NO_FILL, GetCurrentLineWidth(), gbr_metadata );
1058  }
1059  else
1060  {
1061  DPOINT pos_dev = userToDeviceCoordinates( aShapePos );
1062 
1063  int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
1064 
1065  APERTURE::APERTURE_TYPE apert_type =
1067  selectAperture( aDiameter, aOrient, apert_type, aperture_attrib );
1068 
1069  if( gbr_metadata )
1070  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
1071 
1072  emitDcode( pos_dev, 3 );
1073  }
1074 }
1075 
1076 
1077 void GERBER_PLOTTER::Text( const wxPoint& aPos, const COLOR4D aColor,
1078  const wxString& aText, double aOrient, const wxSize& aSize,
1079  enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify,
1080  int aWidth, bool aItalic, bool aBold, bool aMultilineAllowed,
1081  void* aData )
1082 {
1083  GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
1084 
1085  if( gbr_metadata )
1086  formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
1087 
1088  PLOTTER::Text( aPos, aColor, aText, aOrient, aSize,
1089  aH_justify, aV_justify, aWidth, aItalic, aBold, aMultilineAllowed, aData );
1090 }
1091 
1092 
1093 void GERBER_PLOTTER::SetLayerPolarity( bool aPositive )
1094 {
1095  if( aPositive )
1096  fprintf( outputFile, "%%LPD*%%\n" );
1097  else
1098  fprintf( outputFile, "%%LPC*%%\n" );
1099 }
virtual void SetDefaultLineWidth(int width) override
Set the default line width.
std::vector< APERTURE >::iterator getAperture(const wxSize &aSize, APERTURE::APERTURE_TYPE aType, int aApertureAttribute)
Function getAperture returns a reference to the aperture which meets the size anf type of tool if the...
void FinishTo(const wxPoint &pos)
Definition: plotter.h:254
virtual void FlashPadRoundRect(const wxPoint &aPadPos, const wxSize &aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode, void *aData) override
Roundrect pad at the moment are not handled as aperture, since they require aperture macros TODO: alw...
a class to handle special data (items attributes) during plot.
void writeApertureList()
Generate the table of D codes.
void clearNetAttribute()
clear a Gerber net attribute record (clear object attribute dictionary) and output the clear object a...
EDA_TEXT_HJUSTIFY_T
Definition: eda_text.h:44
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData) override
virtual void PenTo(const wxPoint &pos, char plume) override
moveto/lineto primitive, moves the 'pen' to the specified direction
void PenFinish()
Definition: plotter.h:260
virtual void FlashPadTrapez(const wxPoint &aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData) override
Trapezoidal pad at the moment are never handled as aperture, since they require aperture macros TODO:...
int OutlineCount() const
Returns the number of outlines in the set
static const int dist[10][10]
Definition: ar_matrix.cpp:320
virtual void SetLayerPolarity(bool aPositive) override
Change the plot polarity and begin a new layer Used to 'scratch off' silk screen away from solder mas...
APERTURE_TYPE
Definition: plotter.h:1041
virtual void EndBlock(void *aData) override
calling this function allows one to define the end of a group of drawing items the group is started b...
APERTURE_TYPE m_Type
Definition: plotter.h:1107
wxSize m_Size
Definition: plotter.h:1112
bool m_useNetAttributes
Definition: plotter.h:1351
void formatNetAttribute(GBR_NETLIST_METADATA *aData)
print a Gerber net attribute object record.
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aApproxErrorMax, int aMinSegPerCircleCount)
convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corner...
virtual void FlashPadCustom(const wxPoint &aPadPos, const wxSize &aSize, SHAPE_POLY_SET *aPolygons, EDA_DRAW_MODE_T aTraceMode, void *aData) override
virtual function FlashPadCustom
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=NULL) override
Gerber polygon: they can (and should) be filled with the appropriate G36/G37 sequence.
virtual void FlashRegularPolygon(const wxPoint &aShapePos, int aDiameter, int aCornerCount, double aOrient, EDA_DRAW_MODE_T aTraceMode, void *aData) override
Flash a regular polygon.
bool IsCopper()
Allowed attributes are not the same on board copper layers and on other layers Therefore a flag can b...
Definition: gbr_metadata.h:173
std::vector< APERTURE > apertures
Definition: plotter.h:1342
bool FormatNetAttribute(std::string &aPrintedText, std::string &aLastNetAttributes, GBR_NETLIST_METADATA *aData, bool &aClearPreviousAttributes, bool aUseX1StructuredComment)
Generates the string to print to a gerber file, to set a net attribute for a graphic object.
void selectAperture(const wxSize &aSize, APERTURE::APERTURE_TYPE aType, int aApertureAttribute)
Pick an existing aperture or create a new one, matching the size, type and attributes.
int LineDistance(const VECTOR2I &aP, bool aDetermineSide=false) const
Function LineDistance()
Definition: seg.h:357
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:206
char penState
Current pen state: 'U', 'D' or 'Z' (see PenTo)
Definition: plotter.h:576
this class handle info which can be added in a gerber file as attribute of an obtect the GBR_INFO_TYP...
double m_IUsPerDecimil
Definition: plotter.h:553
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Performs outline inflation/deflation.
bool m_gerberUnitInch
Definition: plotter.h:1345
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
int PointCount() const
Function PointCount()
wxArrayString m_headerExtraLines
Definition: plotter.h:586
virtual void FlashPadOval(const wxPoint &pos, const wxSize &size, double orient, EDA_DRAW_MODE_T trace_mode, void *aData) override
Filled oval flashes are handled as aperture in the 90 degree positions only.
wxPoint plotOffset
Plot offset (in IUs)
Definition: plotter.h:559
virtual bool StartPlot() override
Function StartPlot Write GERBER header to file initialize global variable g_Plot_PlotOutputFile.
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) override
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: gr_text.cpp:215
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) override
Draws text with the plotter.
virtual int GetCurrentLineWidth() const
Definition: plotter.h:152
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:48
wxString m_ExtraData
a string to print after TO object attributes, if not empty it is printed "as this"
void LineTo(const wxPoint &pos)
Definition: plotter.h:249
virtual void Rect(const wxPoint &p1, const wxPoint &p2, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH) override
static const int USE_DEFAULT_LINE_WIDTH
Definition: plotter.h:102
bool m_plotMirror
X axis orientation (SVG) and plot mirrored (only for PS, PDF HPGL and SVG)
Definition: plotter.h:563
virtual void SetCurrentLineWidth(int width, void *aData=NULL) override
Set the line width for the next drawing.
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
Class SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
EDA_DRAW_MODE_T
Definition: eda_text.h:59
int m_gerberUnitFmt
Definition: plotter.h:1346
Base window classes and related definitions.
double plotScale
Plot scale - chosen by the user (even implicitly with 'fit in a4')
Definition: plotter.h:547
virtual void SetViewport(const wxPoint &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB GetApertureAttrib()
Definition: gbr_metadata.h:150
void emitDcode(const DPOINT &pt, int dcode)
Emit a D-Code record, using proper conversions to format a leading zero omitted gerber coordinate (fo...
virtual void ThickArc(const wxPoint &centre, double StAngle, double EndAngle, int rayon, int width, EDA_DRAW_MODE_T tracemode, void *aData) override
FILE * finalFile
Definition: plotter.h:1334
virtual void FlashPadCircle(const wxPoint &pos, int diametre, EDA_DRAW_MODE_T trace_mode, void *aData) override
Filled circular flashes are stored as apertures.
aperture used for connected items like tracks (not vias)
Definition: gbr_metadata.h:84
EDA_TEXT_VJUSTIFY_T
Definition: eda_text.h:51
void MoveTo(const wxPoint &pos)
Definition: plotter.h:244
bool m_useX2format
Definition: plotter.h:1348
Definition: seg.h:36
virtual DPOINT userToDeviceCoordinates(const wxPoint &aCoordinate)
Modifies coordinates according to the orientation, scale factor, and offsets trace.
Definition: plotter.cpp:97
static std::string FormatAttribute(GBR_APERTURE_ATTRIB aAttribute, bool aUseX1StructuredComment)
double cosdecideg(double r, double a)
Circle generation utility: computes r * cos(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:365
double sindecideg(double r, double a)
Circle generation utility: computes r * sin(a) Where a is in decidegrees, not in radians.
Definition: trigo.h:356
virtual void StartBlock(void *aData) override
calling this function allows one to define the beginning of a group of drawing items (used in X2 form...
virtual void Arc(const wxPoint &aCenter, double aStAngle, double aEndAngle, int aRadius, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH) override
Generic fallback: arc rendered as a polyline.
int currentPenWidth
Definition: plotter.h:574
int defaultPenWidth
true to generate a negative image (PS mode mainly)
Definition: plotter.h:573
virtual bool EndPlot() override
Class SHAPE_LINE_CHAIN.
FILE * outputFile
true if the Y axis is top to bottom (SVG)
Definition: plotter.h:568
std::string m_objectAttributesDictionnary
Definition: plotter.h:1328
The common library.
int GetPlotterArcHighDef() const
Definition: plotter.h:220
virtual void SetGerberCoordinatesFormat(int aResolution, bool aUseInches=false) override
Function SetGerberCoordinatesFormat selection of Gerber units and resolution (number of digits in man...
FILL_T
Enum FILL_T is the set of fill types used in plotting or drawing enclosed areas.
Definition: base_struct.h:42
virtual void FlashPadRect(const wxPoint &pos, const wxSize &size, double orient, EDA_DRAW_MODE_T trace_mode, void *aData) override
Filled rect flashes are handled as aperture in the 0 90 180 or 270 degree orientation only and as pol...
void ClearAttribute(const wxString *aName)
remove the net attribute specified by aName If aName == NULL or empty, remove all attributes
VECTOR2I & Point(int aIndex)
Function Point()
void SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)
Definition: gbr_metadata.h:145
wxString m_workFilename
Definition: plotter.h:1335
GBR_NETLIST_METADATA m_NetlistMetadata
a item to handle object attribute:
Definition: gbr_metadata.h:184
int m_apertureAttribute
Definition: plotter.h:1331
virtual void Circle(const wxPoint &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH) override
int m_DCode
Definition: plotter.h:1115
int m_ApertureAttribute
Definition: plotter.h:1120
FILE * workFile
Definition: plotter.h:1333
double iuPerDeviceUnit
Device scale (from IUs to plotter device units - usually decimils)
Definition: plotter.h:556
static const int DO_NOT_SET_LINE_WIDTH
Definition: plotter.h:101
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:407
wxString filename
Definition: plotter.h:580
std::vector< APERTURE >::iterator currentAperture
Definition: plotter.h:1343
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, EDA_DRAW_MODE_T tracemode, void *aData) override
void sketchOval(const wxPoint &pos, const wxSize &size, double orient, int width)
Definition: plotter.cpp:428
wxString creator
Definition: plotter.h:579
wxSize paperSize
Paper size in IU - not in mils.
Definition: plotter.h:584
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:114
#define min(a, b)
Definition: auxiliary.h:85
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39