KiCad PCB EDA Suite
plot_brditems_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) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <fctsys.h>
25 #include <common.h>
26 #include <plotter.h>
27 #include <base_struct.h>
28 #include <draw_graphic_text.h>
29 #include <trigo.h>
30 #include <macros.h>
31 #include <pcb_base_frame.h>
32 
33 #include <class_board.h>
34 #include <class_module.h>
35 #include <class_track.h>
36 #include <class_edge_mod.h>
37 #include <class_pcb_text.h>
38 #include <class_zone.h>
39 #include <class_drawsegment.h>
40 #include <class_pcb_target.h>
41 #include <class_dimension.h>
43 
44 #include <pcbnew.h>
45 #include <pcbplot.h>
46 #include <gbr_metadata.h>
47 
48 /* class BRDITEMS_PLOTTER is a helper class to plot board items
49  * and a group of board items
50  */
51 
53 {
54  COLOR4D color = m_board->Colors().GetLayerColor( aLayer );
55 
56  // A hack to avoid plotting ahite itmen in white color, expecting the paper
57  // is also white: use a non white color:
58  if( color == COLOR4D::WHITE )
59  color = COLOR4D( LIGHTGRAY );
60 
61  return color;
62 }
63 
64 
65 void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPlotMode )
66 {
67  wxPoint shape_pos = aPad->ShapePos();
68  GBR_METADATA gbr_metadata;
69 
70  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
71  bool isOnExternalCopperLayer = ( m_layerMask & LSET::ExternalCuMask() ).any();
72  bool isPadOnBoardTechLayers = ( aPad->GetLayerSet() & LSET::AllBoardTechMask() ).any();
73 
74  gbr_metadata.SetCmpReference( aPad->GetParent()->GetReference() );
75 
76  if( isOnCopperLayer )
77  {
78  gbr_metadata.SetNetAttribType( GBR_NETINFO_ALL );
79  gbr_metadata.SetCopper( true );
80 
81  if( isOnExternalCopperLayer )
82  gbr_metadata.SetPadName( aPad->GetName() );
83 
84  gbr_metadata.SetNetName( aPad->GetNetname() );
85 
86  // Some pads are mechanical pads ( through hole or smd )
87  // when this is the case, they have no pad name and/or are not plated.
88  // In this case gerber files have slightly different attributes.
90  aPad->GetName().IsEmpty() )
91  gbr_metadata.m_NetlistMetadata.m_NotInNet = true;
92 
93  if( !isOnExternalCopperLayer || !isPadOnBoardTechLayers )
94  {
95  // On internal layers one cannot use the GBR_NETLIST_METADATA::GBR_INFO_FLASHED_PAD
96  // attribute when the component is on an external layer (most of the case)
97  // Also, if a SMD pad is not on a tech layer (masks) use also net+cmp attribute, because
98  // it is not really a pad (can be a "pad", actually a node in a virtual component)
101 
102  if( !isPadOnBoardTechLayers )
103  // such a pad is not soldered and is not a connecting point.
104  // Just set aperture attribute as conductor
105  // If it is a through hole pad, it will be adjusted later
107 
108  switch( aPad->GetAttribute() )
109  {
110  case PAD_ATTRIB_HOLE_NOT_PLATED: // Mechanical pad through hole
112  break;
113 
114  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
116  break;
117 
118  default:
119  break;
120  }
121  }
122  else // Some attributes are reserved to the external copper layers
123  {
124  switch( aPad->GetAttribute() )
125  {
126  case PAD_ATTRIB_HOLE_NOT_PLATED: // Mechanical pad through hole
128  break;
129 
130  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
132  break;
133 
134  case PAD_ATTRIB_CONN: // Connector pads have no solder paste.
136  break;
137 
138  case PAD_ATTRIB_SMD: // SMD pads (One external copper layer only) with solder paste
139  if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // perhaps a BGA pad
141  else
143  break;
144  }
145  }
146 
149  }
150  else
151  {
153  }
154 
155  // Set plot color (change WHITE to LIGHTGRAY because
156  // the white items are not seen on a white paper or screen
157  m_plotter->SetColor( aColor != WHITE ? aColor : LIGHTGRAY);
158 
159  switch( aPad->GetShape() )
160  {
161  case PAD_SHAPE_CIRCLE:
162  m_plotter->FlashPadCircle( shape_pos, aPad->GetSize().x, aPlotMode, &gbr_metadata );
163  break;
164 
165  case PAD_SHAPE_OVAL:
166  m_plotter->FlashPadOval( shape_pos, aPad->GetSize(),
167  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
168  break;
169 
170  case PAD_SHAPE_TRAPEZOID:
171  {
172  wxPoint coord[4];
173  aPad->BuildPadPolygon( coord, wxSize(0,0), 0 );
174  m_plotter->FlashPadTrapez( shape_pos, coord,
175  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
176  }
177  break;
178 
179  case PAD_SHAPE_ROUNDRECT:
180  m_plotter->FlashPadRoundRect( shape_pos, aPad->GetSize(), aPad->GetRoundRectCornerRadius(),
181  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
182  break;
183 
185  {
186  SHAPE_POLY_SET polygons;
187  const int segmentToCircleCount = 64;
188  const int corner_radius = aPad->GetRoundRectCornerRadius( aPad->GetSize() );
189  TransformRoundChamferedRectToPolygon( polygons, shape_pos, aPad->GetSize(),
190  aPad->GetOrientation(), corner_radius, aPad->GetChamferRectRatio(),
191  aPad->GetChamferPositions(), segmentToCircleCount );
192 
193  if( polygons.OutlineCount() == 0 )
194  break;
195 
196  int min_dim = std::min( aPad->GetSize().x, aPad->GetSize().y ) /2;
197  m_plotter->FlashPadCustom( shape_pos,wxSize( min_dim, min_dim ), &polygons, aPlotMode, &gbr_metadata );
198  }
199  break;
200 
201  case PAD_SHAPE_CUSTOM:
202  {
203  SHAPE_POLY_SET polygons;
204  aPad->MergePrimitivesAsPolygon(&polygons, 64 );
205 
206  if( polygons.OutlineCount() == 0 )
207  break;
208 
209  aPad->CustomShapeAsPolygonToBoardPosition( &polygons, shape_pos, aPad->GetOrientation() );
210  m_plotter->FlashPadCustom( shape_pos, aPad->GetSize(), &polygons, aPlotMode, &gbr_metadata );
211  }
212  break;
213 
214  case PAD_SHAPE_RECT:
215  default:
216  m_plotter->FlashPadRect( shape_pos, aPad->GetSize(),
217  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
218  break;
219  }
220 }
221 
222 
224 {
225  TEXTE_MODULE* textModule = &aModule->Reference();
226  LAYER_NUM textLayer = textModule->GetLayer();
227 
228  if( GetPlotReference() && m_layerMask[textLayer]
229  && ( textModule->IsVisible() || GetPlotInvisibleText() ) )
230  {
231  PlotTextModule( textModule, getColor( textLayer ) );
232  }
233 
234  textModule = &aModule->Value();
235  textLayer = textModule->GetLayer();
236 
237  if( GetPlotValue() && m_layerMask[textLayer]
238  && ( textModule->IsVisible() || GetPlotInvisibleText() ) )
239  {
240  PlotTextModule( textModule, getColor( textLayer ) );
241  }
242 
243  for( BOARD_ITEM* item = aModule->GraphicalItemsList().GetFirst(); item; item = item->Next() )
244  {
245  textModule = dyn_cast<TEXTE_MODULE*>( item );
246 
247  if( !textModule )
248  continue;
249 
250  if( !textModule->IsVisible() )
251  continue;
252 
253  textLayer = textModule->GetLayer();
254 
255  if( textLayer >= PCB_LAYER_ID_COUNT )
256  return false;
257 
258  if( !m_layerMask[textLayer] )
259  continue;
260 
261  if( textModule->GetText() == wxT( "%R" ) && !GetPlotReference() )
262  continue;
263 
264  if( textModule->GetText() == wxT( "%V" ) && !GetPlotValue() )
265  continue;
266 
267  PlotTextModule( textModule, getColor( textLayer ) );
268  }
269 
270  return true;
271 }
272 
273 
274 // plot items like text and graphics, but not tracks and module
276 {
277  for( auto item : m_board->Drawings() )
278  {
279  switch( item->Type() )
280  {
281  case PCB_LINE_T: PlotDrawSegment( (DRAWSEGMENT*) item); break;
282  case PCB_TEXT_T: PlotTextePcb( (TEXTE_PCB*) item ); break;
283  case PCB_DIMENSION_T: PlotDimension( (DIMENSION*) item ); break;
284  case PCB_TARGET_T: PlotPcbTarget( (PCB_TARGET*) item ); break;
285  default: break;
286  }
287  }
288 }
289 
291 {
292  wxSize size;
293  wxPoint pos;
294  double orient;
295  int thickness;
296 
297  if( aColor == COLOR4D::WHITE )
298  aColor = COLOR4D( LIGHTGRAY );
299 
300  m_plotter->SetColor( aColor );
301 
302  // calculate some text parameters :
303  size = pt_texte->GetTextSize();
304  pos = pt_texte->GetTextPos();
305 
306  orient = pt_texte->GetDrawRotation();
307 
308  thickness = pt_texte->GetThickness();
309 
310  if( pt_texte->IsMirrored() )
311  size.x = -size.x; // Text is mirrored
312 
313  // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
314  // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
315  // (like bold text) and we manage the thickness.
316  // So we set bold flag to true
317  bool allow_bold = pt_texte->IsBold() || thickness;
318 
319  GBR_METADATA gbr_metadata;
321  MODULE* parent = static_cast<MODULE*> ( pt_texte->GetParent() );
322  gbr_metadata.SetCmpReference( parent->GetReference() );
323 
324  m_plotter->Text( pos, aColor, pt_texte->GetShownText(), orient, size,
325  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
326  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
327 }
328 
329 
331 {
332  if( !m_layerMask[aDim->GetLayer()] )
333  return;
334 
335  DRAWSEGMENT draw;
336 
337  draw.SetWidth( aDim->GetWidth() );
338  draw.SetLayer( aDim->GetLayer() );
339 
341 
342  // Set plot color (change WHITE to LIGHTGRAY because
343  // the white items are not seen on a white paper or screen
345 
346  PlotTextePcb( &aDim->Text() );
347 
348  draw.SetStart( aDim->m_crossBarO );
349  draw.SetEnd( aDim->m_crossBarF );
350  PlotDrawSegment( &draw );
351 
352  draw.SetStart( aDim->m_featureLineGO);
353  draw.SetEnd( aDim->m_featureLineGF );
354  PlotDrawSegment( &draw );
355 
356  draw.SetStart( aDim->m_featureLineDO );
357  draw.SetEnd( aDim->m_featureLineDF );
358  PlotDrawSegment( &draw );
359 
360  draw.SetStart( aDim->m_crossBarF );
361  draw.SetEnd( aDim->m_arrowD1F );
362  PlotDrawSegment( &draw );
363 
364  draw.SetStart( aDim->m_crossBarF );
365  draw.SetEnd( aDim->m_arrowD2F );
366  PlotDrawSegment( &draw );
367 
368  draw.SetStart( aDim->m_crossBarO );
369  draw.SetEnd( aDim->m_arrowG1F );
370  PlotDrawSegment( &draw );
371 
372  draw.SetStart( aDim->m_crossBarO );
373  draw.SetEnd( aDim->m_arrowG2F );
374  PlotDrawSegment( &draw );
375 }
376 
377 
379 {
380  int dx1, dx2, dy1, dy2, radius;
381 
382  if( !m_layerMask[aMire->GetLayer()] )
383  return;
384 
385  m_plotter->SetColor( getColor( aMire->GetLayer() ) );
386 
387  DRAWSEGMENT draw;
388 
389  draw.SetShape( S_CIRCLE );
390  draw.SetWidth( aMire->GetWidth() );
391  draw.SetLayer( aMire->GetLayer() );
392  draw.SetStart( aMire->GetPosition() );
393  radius = aMire->GetSize() / 3;
394 
395  if( aMire->GetShape() ) // shape X
396  radius = aMire->GetSize() / 2;
397 
398  // Draw the circle
399  draw.SetEnd( wxPoint( draw.GetStart().x + radius, draw.GetStart().y ));
400 
401  PlotDrawSegment( &draw );
402 
403  draw.SetShape( S_SEGMENT );
404 
405  radius = aMire->GetSize() / 2;
406  dx1 = radius;
407  dy1 = 0;
408  dx2 = 0;
409  dy2 = radius;
410 
411  if( aMire->GetShape() ) // Shape X
412  {
413  dx1 = dy1 = radius;
414  dx2 = dx1;
415  dy2 = -dy1;
416  }
417 
418  wxPoint mirePos( aMire->GetPosition() );
419 
420  // Draw the X or + shape:
421  draw.SetStart( wxPoint( mirePos.x - dx1, mirePos.y - dy1 ));
422  draw.SetEnd( wxPoint( mirePos.x + dx1, mirePos.y + dy1 ));
423  PlotDrawSegment( &draw );
424 
425  draw.SetStart( wxPoint( mirePos.x - dx2, mirePos.y - dy2 ));
426  draw.SetEnd( wxPoint( mirePos.x + dx2, mirePos.y + dy2 ));
427  PlotDrawSegment( &draw );
428 }
429 
430 
431 // Plot footprints graphic items (outlines)
433 {
434  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
435  {
436  for( BOARD_ITEM* item = module->GraphicalItemsList().GetFirst(); item; item = item->Next() )
437  {
438  EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( item );
439 
440  if( edge && m_layerMask[edge->GetLayer()] )
441  Plot_1_EdgeModule( edge );
442  }
443  }
444 }
445 
446 
447 //* Plot a graphic item (outline) relative to a footprint
449 {
450  int type_trace; // Type of item to plot.
451  int thickness; // Segment thickness.
452  int radius; // Circle radius.
453 
454  if( aEdge->Type() != PCB_MODULE_EDGE_T )
455  return;
456 
457  m_plotter->SetColor( getColor( aEdge->GetLayer() ) );
458 
459  type_trace = aEdge->GetShape();
460  thickness = aEdge->GetWidth();
461 
462  wxPoint pos( aEdge->GetStart() );
463  wxPoint end( aEdge->GetEnd() );
464 
465  GBR_METADATA gbr_metadata;
467  MODULE* parent = static_cast<MODULE*> ( aEdge->GetParent() );
468  gbr_metadata.SetCmpReference( parent->GetReference() );
469 
470  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
471 
472  if( isOnCopperLayer )
473  {
474  gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_ETCHEDCMP );
475  gbr_metadata.SetCopper( true );
476  }
477  else if( aEdge->GetLayer() == Edge_Cuts ) // happens also when plotting copper layers
478  {
479  gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR );
480  }
481 
482  switch( type_trace )
483  {
484  case S_SEGMENT:
485  m_plotter->ThickSegment( pos, end, thickness, GetPlotMode(), &gbr_metadata );
486  break;
487 
488  case S_CIRCLE:
489  radius = KiROUND( GetLineLength( end, pos ) );
490  m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
491  break;
492 
493  case S_ARC:
494  {
495  radius = KiROUND( GetLineLength( end, pos ) );
496  double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
497  double endAngle = startAngle + aEdge->GetAngle();
498 
499  // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg
500  if( std::abs( aEdge->GetAngle() ) == 3600.0 )
501  m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
502  else
503  m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
504  }
505  break;
506 
507  case S_POLYGON:
508  if( aEdge->IsPolyShapeValid() )
509  {
510  const std::vector<wxPoint>& polyPoints = aEdge->BuildPolyPointsList();
511 
512  // We must compute true coordinates from m_PolyList
513  // which are relative to module position, orientation 0
514  MODULE* module = aEdge->GetParentModule();
515 
516  std::vector< wxPoint > cornerList;
517 
518  cornerList.reserve( polyPoints.size() );
519 
520  for( wxPoint corner : polyPoints )
521  {
522  if( module )
523  {
524  RotatePoint( &corner, module->GetOrientation() );
525  corner += module->GetPosition();
526  }
527 
528  cornerList.push_back( corner );
529  }
530 
531  if( !aEdge->IsPolygonFilled() )
532  {
533  for( size_t i = 1; i < cornerList.size(); i++ )
534  {
535  m_plotter->ThickSegment( cornerList[i-1], cornerList[i], thickness,
536  GetPlotMode(), &gbr_metadata );
537  }
538 
539  m_plotter->ThickSegment( cornerList.back(), cornerList.front(), thickness,
540  GetPlotMode(), &gbr_metadata );
541 
542  }
543  else
544  {
545  m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness, &gbr_metadata );
546  }
547  }
548  break;
549  }
550 }
551 
552 
553 // Plot a PCB Text, i.e. a text found on a copper or technical layer
555 {
556  double orient;
557  int thickness;
558  wxPoint pos;
559  wxSize size;
560  wxString shownText( pt_texte->GetShownText() );
561 
562  if( shownText.IsEmpty() )
563  return;
564 
565  if( !m_layerMask[pt_texte->GetLayer()] )
566  return;
567 
568  GBR_METADATA gbr_metadata;
569 
570  if( IsCopperLayer( pt_texte->GetLayer() ) )
572 
573  COLOR4D color = getColor( pt_texte->GetLayer() );
575 
576  size = pt_texte->GetTextSize();
577  pos = pt_texte->GetTextPos();
578  orient = pt_texte->GetTextAngle();
579  thickness = pt_texte->GetThickness();
580 
581  if( pt_texte->IsMirrored() )
582  size.x = -size.x;
583 
584  // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
585  // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
586  // (like bold text) and we manage the thickness.
587  // So we set bold flag to true
588  bool allow_bold = pt_texte->IsBold() || thickness;
589 
590  if( pt_texte->IsMultilineAllowed() )
591  {
592  std::vector<wxPoint> positions;
593  wxArrayString strings_list;
594  wxStringSplit( shownText, strings_list, '\n' );
595  positions.reserve( strings_list.Count() );
596 
597  pt_texte->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
598 
599  for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
600  {
601  wxString& txt = strings_list.Item( ii );
602  m_plotter->Text( positions[ii], color, txt, orient, size,
603  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
604  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
605  }
606  }
607  else
608  {
609  m_plotter->Text( pos, color, shownText, orient, size,
610  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
611  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
612  }
613 }
614 
615 
616 /* Plot areas (given by .m_FilledPolysList member) in a zone
617  */
619 {
620  const SHAPE_POLY_SET& polysList = aZone->GetFilledPolysList();
621 
622  if( polysList.IsEmpty() )
623  return;
624 
625  GBR_METADATA gbr_metadata;
626 
627  bool isOnCopperLayer = aZone->IsOnCopperLayer();
628 
629  if( isOnCopperLayer )
630  {
631  gbr_metadata.SetNetName( aZone->GetNetname() );
632  gbr_metadata.SetCopper( true );
633 
634  // Zones with no net name can exist.
635  // they are not used to connect items, so the aperture attribute cannot
636  // be set as conductor
637  if( aZone->GetNetname().IsEmpty() )
639  else
640  {
643  }
644  }
645 
646  // We need a buffer to store corners coordinates:
647  static std::vector< wxPoint > cornerList;
648  cornerList.clear();
649 
650  m_plotter->SetColor( getColor( aZone->GetLayer() ) );
651 
652  /* Plot all filled areas: filled areas have a filled area and a thick
653  * outline we must plot the filled area itself ( as a filled polygon
654  * OR a set of segments ) and plot the thick outline itself
655  *
656  * in non filled mode the outline is plotted, but not the filling items
657  */
658  for( auto ic = polysList.CIterate(); ic; ++ic )
659  {
660  wxPoint pos( ic->x, ic->y );
661  cornerList.push_back( pos );
662 
663  if( ic.IsEndContour() ) // Plot the current filled area outline
664  {
665  // First, close the outline
666  if( cornerList[0] != cornerList[cornerList.size() - 1] )
667  cornerList.push_back( cornerList[0] );
668 
669  // Plot the current filled area and its outline
670  if( GetPlotMode() == FILLED )
671  {
672  m_plotter->PlotPoly( cornerList, FILLED_SHAPE, aZone->GetMinThickness(), &gbr_metadata );
673  }
674  else
675  {
676  if( aZone->GetMinThickness() > 0 )
677  {
678  for( unsigned jj = 1; jj < cornerList.size(); jj++ )
679  {
680  m_plotter->ThickSegment( cornerList[jj -1], cornerList[jj],
681  aZone->GetMinThickness(),
682  GetPlotMode(), &gbr_metadata );
683  }
684  }
685 
687  }
688 
689  cornerList.clear();
690  }
691  }
692 }
693 
694 
695 /* Plot items type DRAWSEGMENT on layers allowed by aLayerMask
696  */
698 {
699  if( !m_layerMask[aSeg->GetLayer()] )
700  return;
701 
702  int radius = 0;
703  double StAngle = 0, EndAngle = 0;
704  int thickness = aSeg->GetWidth();
705 
706  m_plotter->SetColor( getColor( aSeg->GetLayer() ) );
707 
708  wxPoint start( aSeg->GetStart() );
709  wxPoint end( aSeg->GetEnd() );
710 
711  GBR_METADATA gbr_metadata;
712 
713  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
714 
715  if( isOnCopperLayer && aSeg->GetLayer() == Edge_Cuts ) // can happens when plotting copper layers
717 
718  switch( aSeg->GetShape() )
719  {
720  case S_CIRCLE:
721  radius = KiROUND( GetLineLength( end, start ) );
722  m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
723  break;
724 
725  case S_ARC:
726  radius = KiROUND( GetLineLength( end, start ) );
727  StAngle = ArcTangente( end.y - start.y, end.x - start.x );
728  EndAngle = StAngle + aSeg->GetAngle();
729 
730  // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg
731  if( std::abs( aSeg->GetAngle() ) == 3600.0 )
732  m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
733  else
734  m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
735  break;
736 
737  case S_CURVE:
738  {
739  m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
740  const std::vector<wxPoint>& bezierPoints = aSeg->GetBezierPoints();
741 
742  for( unsigned i = 1; i < bezierPoints.size(); i++ )
743  {
744  m_plotter->ThickSegment( bezierPoints[i - 1], bezierPoints[i],
745  thickness, GetPlotMode(), &gbr_metadata );
746  }
747  }
748  break;
749 
750  case S_POLYGON:
751  {
752  if( !aSeg->IsPolygonFilled() )
753  {
754  for( auto it = aSeg->GetPolyShape().IterateSegments( 0 ); it; it++ )
755  {
756  auto seg = it.Get();
757  m_plotter->ThickSegment( wxPoint( seg.A ), wxPoint( seg.B ),
758  thickness, GetPlotMode(), &gbr_metadata );
759  }
760  }
761  else
762  {
763  m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
764  // Draw the polygon: only one polygon is expected
765  // However we provide a multi polygon shape drawing
766  // ( for the future or to show a non expected shape )
767  // This must be simplified and fractured to prevent overlapping polygons
768  // from generating invalid Gerber files
769  auto tmpPoly = SHAPE_POLY_SET( aSeg->GetPolyShape() );
771 
772  for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj )
773  {
774  SHAPE_LINE_CHAIN& poly = tmpPoly.Outline( jj );
775  m_plotter->PlotPoly( poly, FILLED_SHAPE, thickness, &gbr_metadata );
776  }
777  }
778  }
779  break;
780 
781  default:
782  m_plotter->ThickSegment( start, end, thickness, GetPlotMode(), &gbr_metadata );
783  }
784 }
785 
786 
790 void BRDITEMS_PLOTTER::plotOneDrillMark( PAD_DRILL_SHAPE_T aDrillShape, const wxPoint &aDrillPos,
791  wxSize aDrillSize, const wxSize &aPadSize,
792  double aOrientation, int aSmallDrill )
793 {
794  // Small drill marks have no significance when applied to slots
795  if( aSmallDrill && aDrillShape == PAD_DRILL_SHAPE_CIRCLE )
796  aDrillSize.x = std::min( aSmallDrill, aDrillSize.x );
797 
798  // Round holes only have x diameter, slots have both
799  aDrillSize.x -= getFineWidthAdj();
800  aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 );
801 
802  if( aDrillShape == PAD_DRILL_SHAPE_OBLONG )
803  {
804  aDrillSize.y -= getFineWidthAdj();
805  aDrillSize.y = Clamp( 1, aDrillSize.y, aPadSize.y - 1 );
806  m_plotter->FlashPadOval( aDrillPos, aDrillSize, aOrientation, GetPlotMode(), NULL );
807  }
808  else
809  m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetPlotMode(), NULL );
810 }
811 
812 
814 {
815  /* If small drills marks were requested prepare a clamp value to pass
816  to the helper function */
817  int small_drill = (GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE) ?
818  SMALL_DRILL : 0;
819 
820  /* In the filled trace mode drill marks are drawn white-on-black to scrape
821  the underlying pad. This works only for drivers supporting color change,
822  obviously... it means that:
823  - PS, SVG and PDF output is correct (i.e. you have a 'donut' pad)
824  - In HPGL you can't see them
825  - In gerbers you can't see them, too. This is arguably the right thing to
826  do since having drill marks and high speed drill stations is a sure
827  recipe for broken tools and angry manufacturers. If you *really* want them
828  you could start a layer with negative polarity to scrape the film.
829  - In DXF they go into the 'WHITE' layer. This could be useful.
830  */
831  if( GetPlotMode() == FILLED )
833 
834  for( TRACK* pts = m_board->m_Track; pts != NULL; pts = pts->Next() )
835  {
836  const VIA* via = dyn_cast<const VIA*>( pts );
837 
838  if( via )
839  {
841  wxSize( via->GetDrillValue(), 0 ),
842  wxSize( via->GetWidth(), 0 ), 0, small_drill );
843  }
844  }
845 
846  for( MODULE* Module = m_board->m_Modules; Module != NULL; Module = Module->Next() )
847  {
848  for( D_PAD* pad = Module->PadsList(); pad != NULL; pad = pad->Next() )
849  {
850  if( pad->GetDrillSize().x == 0 )
851  continue;
852 
853  plotOneDrillMark( pad->GetDrillShape(),
854  pad->GetPosition(), pad->GetDrillSize(),
855  pad->GetSize(), pad->GetOrientation(),
856  small_drill );
857  }
858  }
859 
860  if( GetPlotMode() == FILLED )
862 }
D_PAD * Next() const
Definition: class_pad.h:162
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
Definition: common.cpp:188
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:676
a class to handle special data (items attributes) during plot.
bool IsBold() const
Definition: eda_text.h:190
void SetPadName(const wxString &aPadname)
Definition: gbr_metadata.h:163
#define SMALL_DRILL
Definition: pcbplot.h:72
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:59
double GetOrientation() const
Definition: class_module.h:188
aperture used for etched components
Definition: gbr_metadata.h:83
TEXTE_MODULE & Reference()
Definition: class_module.h:503
void SetShape(STROKE_T aShape)
int OutlineCount() const
Returns the number of outlines in the set
aperture used for edge connecto pad (outer layers)
Definition: gbr_metadata.h:93
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:208
bool IsMirrored() const
Definition: eda_text.h:196
int GetWidth() const
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Function GetLineLength returns the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:200
const T & Clamp(const T &lower, const T &value, const T &upper)
Function Clamp limits value within the range lower <= value <= upper.
Definition: macros.h:138
TEXTE_PCB class definition.
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:118
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
bool MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon=NULL, int aCircleToSegmentsCount=ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF)
Merge all basic shapes, converted to a polygon in one polygon, in m_customShapeAsPolygon.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
wxPoint m_crossBarF
print info associated to a component (TO.C attribute)
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
wxPoint m_arrowD1F
virtual void SetColor(COLOR4D color)=0
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:511
const wxPoint & GetStart() const
Definition: class_track.h:133
STROKE_T GetShape() const
void PlotPad(D_PAD *aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPlotMode)
Plot a pad.
int GetSize() const
bool IsVisible() const
Definition: eda_text.h:193
void SetNetAttribType(int aNetAttribType)
Definition: gbr_metadata.h:152
Class BOARD to handle a board.
void PlotDimension(DIMENSION *Dimension)
int color
Definition: DXF_plotter.cpp:62
polygon (not yet used for tracks, but could be in microwave apps)
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:62
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:185
PLOTTER * m_plotter
Definition: pcbplot.h:78
void PlotDrillMarks()
Function PlotDrillMarks Draw a drill mark for pads and vias.
double GetTextAngle() const
Definition: eda_text.h:181
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
aperture used for through hole component on outer layer
Definition: gbr_metadata.h:88
bool PlotAllTextsModule(MODULE *aModule)
Classes to handle copper zones.
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:171
usual segment : line with rounded ends
virtual const wxString GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:147
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aCircleToSegmentsCount)
convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corner...
const std::vector< wxPoint > & GetBezierPoints() const
wxPoint m_featureLineDF
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
const std::vector< wxPoint > BuildPolyPointsList() const
Build and return the list of corners in a std::vector<wxPoint> It must be used only to convert the SH...
virtual wxString GetShownText() const override
Returns the string actually shown after processing of the base text.
virtual void PlotPoly(const std::vector< wxPoint > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=NULL)=0
Function PlotPoly.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
#define abs(a)
Definition: auxiliary.h:84
PAD_DRILL_SHAPE_T
Enum PAD_DRILL_SHAPE_T is the set of pad drill shapes, used with D_PAD::{Set,Get}DrillShape()
Definition: pad_shapes.h:47
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
BOARD * m_board
Definition: pcbplot.h:79
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:417
Functions relatives to tracks, vias and segments used to fill zones.
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
virtual void FlashPadCustom(const wxPoint &aPadPos, const wxSize &aSize, SHAPE_POLY_SET *aPolygons, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCustom
This file contains miscellaneous commonly used macros and functions.
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:462
int GetChamferPositions() const
has meaning only for chamfered rect pads
Definition: class_pad.h:695
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.
void PlotFilledAreas(ZONE_CONTAINER *aZone)
Classes used in Pcbnew, CvPcb and GerbView.
Board plot function definition file.
wxPoint m_featureLineGO
bool IsItalic() const
Definition: eda_text.h:187
DIMENSION class definition.
COLOR4D GetLayerColor(LAYER_NUM aLayer) const
Function GetLayerColor.
aperture used for BGA pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:92
virtual void FlashPadCircle(const wxPoint &aPadPos, int aDiameter, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCircle
int GetWidth() const
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:207
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
void PlotPcbTarget(PCB_TARGET *PtMire)
Class SHAPE_POLY_SET.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:502
EDA_DRAW_MODE_T
Definition: eda_text.h:78
void PlotBoardGraphicItems()
plot items like text and graphics, but not tracks and modules
COLOR4D GetColor() const
const wxSize & GetTextSize() const
Definition: eda_text.h:232
Arcs (with rounded ends)
double GetChamferRectRatio() const
has meaning only for chamfered rect pads
Definition: class_pad.h:672
virtual void FlashPadRoundRect(const wxPoint &aPadPos, const wxSize &aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadRoundRect
LSET GetLayerSet() const override
Function GetLayerSet returns a "layer mask", which is a bitmap of all layers on which the TRACK segme...
Definition: class_pad.h:414
wxPoint m_arrowG1F
void Plot_1_EdgeModule(EDGE_MODULE *aEdge)
wxPoint m_arrowD2F
wxPoint m_arrowG2F
MODULE * GetParentModule() const
Function GetParentModule returns a pointer to the parent module, or NULL if DRAWSEGMENT does not belo...
static LSET ExternalCuMask()
Function ExternalCuMask returns a mask holding the Front and Bottom layers.
Definition: lset.cpp:706
const wxString & GetName() const
Definition: class_pad.h:192
aperture used for mechanical pads (NPTH)
Definition: gbr_metadata.h:94
SHAPE_POLY_SET & GetPolyShape()
Bezier Curve.
const wxString & GetNetname() const
Function GetNetname.
T * GetFirst() const
Function GetFirst returns the first T* in the list without removing it, or NULL if the list is empty.
Definition: dlist.h:163
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:63
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:98
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
int GetWidth() const
bool IsMultilineAllowed() const
Definition: eda_text.h:205
aperture used for connected items like tracks (not vias)
Definition: gbr_metadata.h:84
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:99
void SetStart(const wxPoint &aStart)
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
bool GetPlotValue() const
MODULE * GetParent() const
Definition: class_pad.h:164
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
void SetNetName(const wxString &aNetname)
Definition: gbr_metadata.h:162
double GetAngle() const
const COLORS_DESIGN_SETTINGS & Colors() const
Function GetColorSettings.
Definition: class_board.h:567
virtual void FlashPadRect(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadRect
BOARD_ITEM * Next() const
int GetWidth() const
Definition: class_track.h:127
Class to handle a graphic segment.
void plotOneDrillMark(PAD_DRILL_SHAPE_T aDrillShape, const wxPoint &aDrillPos, wxSize aDrillSize, const wxSize &aPadSize, double aOrientation, int aSmallDrill)
Helper function to plot a single drill mark.
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadOval
DLIST< MODULE > m_Modules
Definition: class_board.h:248
Class SHAPE_LINE_CHAIN.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:394
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
Definition: plotter.cpp:456
void CustomShapeAsPolygonToBoardPosition(SHAPE_POLY_SET *aMergedPolygon, wxPoint aPosition, double aRotation) const
When created, the corners coordinates are relative to the pad position, orientation 0,...
LSET m_layerMask
Definition: pcbplot.h:80
TEXTE_PCB & Text()
size_t i
Definition: json11.cpp:597
wxPoint ShapePos() const
Definition: class_pad.cpp:562
int GetShape() const
aperture used for SMD pad with a solder mask defined by the solder mask
Definition: gbr_metadata.h:90
The common library.
int GetMinThickness() const
Definition: class_zone.h:199
bool GetPlotInvisibleText() const
bool IsPolyShapeValid() const
void PlotTextePcb(TEXTE_PCB *pt_texte)
Definition: colors.h:49
void SetEnd(const wxPoint &aEnd)
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:543
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
static LSET AllBoardTechMask()
Function AllTechMask returns a mask holding board technical layers (no CU layer) on both side.
Definition: lset.cpp:753
const wxPoint & GetTextPos() const
Definition: eda_text.h:241
void GetPositionsOfLinesOfMultilineText(std::vector< wxPoint > &aPositions, int aLineCount) const
Function GetPositionsOfLinesOfMultilineText Populates aPositions with the position of each line of a ...
Definition: eda_text.cpp:331
wxPoint m_crossBarO
PCB_TARGET class definition.
void SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)
Definition: gbr_metadata.h:142
DLIST< BOARD_ITEM > & GraphicalItemsList()
Definition: class_module.h:165
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
int getFineWidthAdj()
Definition: pcbplot.h:95
DLIST< TRACK > m_Track
Definition: class_board.h:249
GBR_NETLIST_METADATA m_NetlistMetadata
a item to handle object attribute:
Definition: gbr_metadata.h:181
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:218
Module description (excepted pads)
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:152
Basic classes for most KiCad items.
aperture used for not connected items (texts, outlines on copper)
Definition: gbr_metadata.h:86
const wxSize & GetSize() const
Definition: class_pad.h:271
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
BOARD_ITEM_CONTAINER * GetParent() const
void SetCopper(bool aValue)
Definition: gbr_metadata.h:171
virtual void FlashPadTrapez(const wxPoint &aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadTrapez flash a trapezoidal pad
double GetDrawRotation() const
DrillMarksType GetDrillMarksType() const
wxPoint m_featureLineDO
print info associated to a net (TO.N attribute)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool IsPolygonFilled() const
Polygonal shape is not always filled.
bool GetPlotReference() const
const wxPoint GetPosition() const override
Definition: class_module.h:183
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:191
void SetCmpReference(const wxString &aComponentRef)
Definition: gbr_metadata.h:164
COLOR4D getColor(LAYER_NUM aLayer)
Function getColor.
Class DIMENSION.
DLIST_ITERATOR_WRAPPER< BOARD_ITEM > Drawings()
Definition: class_board.h:253
const wxPoint GetPosition() const override
#define GBR_NETINFO_ALL
SEGMENT_ITERATOR IterateSegments(int aFirst, int aLast, bool aIterateHoles=false)
Returns an iterator object, for iterating between aFirst and aLast outline, with or without holes (de...
KICAD_T Type() const
Function Type()
Definition: base_struct.h:204
#define min(a, b)
Definition: auxiliary.h:85
const SHAPE_POLY_SET & GetFilledPolysList() const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: class_zone.h:580
EDA_DRAW_MODE_T GetPlotMode() const
virtual void SetCurrentLineWidth(int width, void *aData=NULL)=0
Set the line width for the next drawing.
void PlotDrawSegment(DRAWSEGMENT *PtSegm)
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
wxPoint m_featureLineGF
void SetWidth(int aWidth)
void PlotTextModule(TEXTE_MODULE *aTextMod, COLOR4D aColor)