KiCad PCB EDA Suite
plot_brditems_plotter.cpp
Go to the documentation of this file.
1 
7 /*
8  * This program source code file is part of KiCad, a free EDA CAD application.
9  *
10  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.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 <trigo.h>
36 #include <macros.h>
37 #include <wxBasePcbFrame.h>
38 
39 #include <class_board.h>
40 #include <class_module.h>
41 #include <class_track.h>
42 #include <class_edge_mod.h>
43 #include <class_pcb_text.h>
44 #include <class_zone.h>
45 #include <class_drawsegment.h>
46 #include <class_mire.h>
47 #include <class_dimension.h>
48 
49 #include <pcbnew.h>
50 #include <pcbplot.h>
51 #include <plot_auxiliary_data.h>
52 
53 /* class BRDITEMS_PLOTTER is a helper class to plot board items
54  * and a group of board items
55  */
56 
58 {
60  if( color == COLOR4D::WHITE )
61  color = COLOR4D( LIGHTGRAY );
62  return color;
63 }
64 
65 
66 void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPlotMode )
67 {
68  wxPoint shape_pos = aPad->ShapePos();
69  GBR_METADATA gbr_metadata;
70 
71  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
72  bool isOnExternalCopperLayer = ( m_layerMask & LSET::ExternalCuMask() ).any();
73  bool isPadOnBoardTechLayers = ( aPad->GetLayerSet() & LSET::AllBoardTechMask() ).any();
74 
75  gbr_metadata.SetCmpReference( aPad->GetParent()->GetReference() );
76 
77  if( isOnCopperLayer )
78  {
79  gbr_metadata.SetNetAttribType( GBR_NETINFO_ALL );
80  gbr_metadata.SetCopper( true );
81 
82  if( isOnExternalCopperLayer )
83  gbr_metadata.SetPadName( aPad->GetPadName() );
84 
85  gbr_metadata.SetNetName( aPad->GetNetname() );
86 
87  // Some pads are mechanical pads ( through hole or smd )
88  // when this is the case, they have no pad name and/or are not plated.
89  // In this case gerber files have slightly different attributes.
91  aPad->GetPadName().IsEmpty() )
92  gbr_metadata.m_NetlistMetadata.m_NotInNet = true;
93 
94  if( !isOnExternalCopperLayer || !isPadOnBoardTechLayers )
95  {
96  // On internal layers one cannot use the GBR_NETLIST_METADATA::GBR_INFO_FLASHED_PAD
97  // attribute when the component is on an external layer (most of the case)
98  // Also, if a SMD pad is not on a tech layer (masks) use also net+cmp attribute, because
99  // it is not really a pad (can be a "pad", actually a node in a virtual component)
102 
103  if( !isPadOnBoardTechLayers )
104  // such a pad is not soldered and is not a connecting point.
105  // Just set aperture attribute as conductor
106  // If it is a through hole pad, it will be adjusted later
108 
109  switch( aPad->GetAttribute() )
110  {
111  case PAD_ATTRIB_HOLE_NOT_PLATED: // Mechanical pad through hole
113  break;
114 
115  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
117  break;
118 
119  default:
120  break;
121  }
122  }
123  else // Some attributes are reserved to the external copper layers
124  {
125  switch( aPad->GetAttribute() )
126  {
127  case PAD_ATTRIB_HOLE_NOT_PLATED: // Mechanical pad through hole
129  break;
130 
131  case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
133  break;
134 
135  case PAD_ATTRIB_CONN: // Connector pads have no solder paste.
137  break;
138 
139  case PAD_ATTRIB_SMD: // SMD pads (One external copper layer only) with solder paste
140  if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // perhaps a BGA pad
142  else
144  break;
145  }
146  }
147 
150  }
151  else
152  {
154  }
155 
156  // Set plot color (change WHITE to LIGHTGRAY because
157  // the white items are not seen on a white paper or screen
158  m_plotter->SetColor( aColor != WHITE ? aColor : LIGHTGRAY);
159 
160  switch( aPad->GetShape() )
161  {
162  case PAD_SHAPE_CIRCLE:
163  m_plotter->FlashPadCircle( shape_pos, aPad->GetSize().x, aPlotMode, &gbr_metadata );
164  break;
165 
166  case PAD_SHAPE_OVAL:
167  m_plotter->FlashPadOval( shape_pos, aPad->GetSize(),
168  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
169  break;
170 
171  case PAD_SHAPE_TRAPEZOID:
172  {
173  wxPoint coord[4];
174  aPad->BuildPadPolygon( coord, wxSize(0,0), 0 );
175  m_plotter->FlashPadTrapez( shape_pos, coord,
176  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
177  }
178  break;
179 
180  case PAD_SHAPE_ROUNDRECT:
181  m_plotter->FlashPadRoundRect( shape_pos, aPad->GetSize(), aPad->GetRoundRectCornerRadius(),
182  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
183  break;
184 
185  case PAD_SHAPE_RECT:
186  default:
187  m_plotter->FlashPadRect( shape_pos, aPad->GetSize(),
188  aPad->GetOrientation(), aPlotMode, &gbr_metadata );
189  break;
190  }
191 }
192 
193 
195 {
196  // see if we want to plot VALUE and REF fields
197  bool trace_val = GetPlotValue();
198  bool trace_ref = GetPlotReference();
199 
200  TEXTE_MODULE* textModule = &aModule->Reference();
201  LAYER_NUM textLayer = textModule->GetLayer();
202 
203  if( textLayer >= PCB_LAYER_ID_COUNT ) // how will this ever be true?
204  return false;
205 
206  if( !m_layerMask[textLayer] )
207  trace_ref = false;
208 
209  if( !textModule->IsVisible() && !GetPlotInvisibleText() )
210  trace_ref = false;
211 
212  textModule = &aModule->Value();
213  textLayer = textModule->GetLayer();
214 
215  if( textLayer > PCB_LAYER_ID_COUNT ) // how will this ever be true?
216  return false;
217 
218  if( !m_layerMask[textLayer] )
219  trace_val = false;
220 
221  if( !textModule->IsVisible() && !GetPlotInvisibleText() )
222  trace_val = false;
223 
224  // Plot text fields, if allowed
225  if( trace_ref )
226  {
227  if( GetReferenceColor() == COLOR4D::UNSPECIFIED )
228  PlotTextModule( &aModule->Reference(), getColor( textLayer ) );
229  else
230  PlotTextModule( &aModule->Reference(), GetReferenceColor() );
231  }
232 
233  if( trace_val )
234  {
235  if( GetValueColor() == COLOR4D::UNSPECIFIED )
236  PlotTextModule( &aModule->Value(), getColor( textLayer ) );
237  else
238  PlotTextModule( &aModule->Value(), GetValueColor() );
239  }
240 
241  for( BOARD_ITEM *item = aModule->GraphicalItems().GetFirst(); item; item = item->Next() )
242  {
243  textModule = dyn_cast<TEXTE_MODULE*>( item );
244 
245  if( !textModule )
246  continue;
247 
248  if( !textModule->IsVisible() )
249  continue;
250 
251  textLayer = textModule->GetLayer();
252 
253  if( textLayer >= PCB_LAYER_ID_COUNT )
254  return false;
255 
256  if( !m_layerMask[textLayer] )
257  continue;
258 
259  PlotTextModule( textModule, getColor( textLayer ) );
260  }
261 
262  return true;
263 }
264 
265 
266 // plot items like text and graphics, but not tracks and module
268 {
269  for( BOARD_ITEM* item = m_board->m_Drawings; item; item = item->Next() )
270  {
271  switch( item->Type() )
272  {
273  case PCB_LINE_T:
274  PlotDrawSegment( (DRAWSEGMENT*) item);
275  break;
276 
277  case PCB_TEXT_T:
278  PlotTextePcb( (TEXTE_PCB*) item );
279  break;
280 
281  case PCB_DIMENSION_T:
282  PlotDimension( (DIMENSION*) item );
283  break;
284 
285  case PCB_TARGET_T:
286  PlotPcbTarget( (PCB_TARGET*) item );
287  break;
288 
289  case PCB_MARKER_T:
290  default:
291  break;
292  }
293  }
294 }
295 
297 {
298  wxSize size;
299  wxPoint pos;
300  double orient;
301  int thickness;
302 
303  if( aColor == COLOR4D::WHITE )
304  aColor = COLOR4D( LIGHTGRAY );
305 
306  m_plotter->SetColor( aColor );
307 
308  // calculate some text parameters :
309  size = pt_texte->GetTextSize();
310  pos = pt_texte->GetTextPos();
311 
312  orient = pt_texte->GetDrawRotation();
313 
314  thickness = pt_texte->GetThickness();
315 
316  if( pt_texte->IsMirrored() )
317  size.x = -size.x; // Text is mirrored
318 
319  // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
320  // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
321  // (like bold text) and we manage the thickness.
322  // So we set bold flag to true
323  bool allow_bold = pt_texte->IsBold() || thickness;
324 
325  GBR_METADATA gbr_metadata;
327  MODULE* parent = static_cast<MODULE*> ( pt_texte->GetParent() );
328  gbr_metadata.SetCmpReference( parent->GetReference() );
329 
330  m_plotter->Text( pos, aColor,
331  pt_texte->GetShownText(),
332  orient, size,
333  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
334  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
335 }
336 
337 
339 {
340  if( !m_layerMask[aDim->GetLayer()] )
341  return;
342 
343  DRAWSEGMENT draw;
344 
345  draw.SetWidth( aDim->GetWidth() );
346  draw.SetLayer( aDim->GetLayer() );
347 
348  COLOR4D color = aDim->GetBoard()->GetLayerColor( aDim->GetLayer() );
349 
350  // Set plot color (change WHITE to LIGHTGRAY because
351  // the white items are not seen on a white paper or screen
352  m_plotter->SetColor( color != WHITE ? color : LIGHTGRAY);
353 
354  PlotTextePcb( &aDim->Text() );
355 
356  draw.SetStart( aDim->m_crossBarO );
357  draw.SetEnd( aDim->m_crossBarF );
358  PlotDrawSegment( &draw );
359 
360  draw.SetStart( aDim->m_featureLineGO);
361  draw.SetEnd( aDim->m_featureLineGF );
362  PlotDrawSegment( &draw );
363 
364  draw.SetStart( aDim->m_featureLineDO );
365  draw.SetEnd( aDim->m_featureLineDF );
366  PlotDrawSegment( &draw );
367 
368  draw.SetStart( aDim->m_crossBarF );
369  draw.SetEnd( aDim->m_arrowD1F );
370  PlotDrawSegment( &draw );
371 
372  draw.SetStart( aDim->m_crossBarF );
373  draw.SetEnd( aDim->m_arrowD2F );
374  PlotDrawSegment( &draw );
375 
376  draw.SetStart( aDim->m_crossBarO );
377  draw.SetEnd( aDim->m_arrowG1F );
378  PlotDrawSegment( &draw );
379 
380  draw.SetStart( aDim->m_crossBarO );
381  draw.SetEnd( aDim->m_arrowG2F );
382  PlotDrawSegment( &draw );
383 }
384 
385 
387 {
388  int dx1, dx2, dy1, dy2, radius;
389 
390  if( !m_layerMask[aMire->GetLayer()] )
391  return;
392 
393  m_plotter->SetColor( getColor( aMire->GetLayer() ) );
394 
395  DRAWSEGMENT draw;
396 
397  draw.SetShape( S_CIRCLE );
398  draw.SetWidth( aMire->GetWidth() );
399  draw.SetLayer( aMire->GetLayer() );
400  draw.SetStart( aMire->GetPosition() );
401  radius = aMire->GetSize() / 3;
402 
403  if( aMire->GetShape() ) // shape X
404  radius = aMire->GetSize() / 2;
405 
406  // Draw the circle
407  draw.SetEnd( wxPoint( draw.GetStart().x + radius, draw.GetStart().y ));
408 
409  PlotDrawSegment( &draw );
410 
411  draw.SetShape( S_SEGMENT );
412 
413  radius = aMire->GetSize() / 2;
414  dx1 = radius;
415  dy1 = 0;
416  dx2 = 0;
417  dy2 = radius;
418 
419  if( aMire->GetShape() ) // Shape X
420  {
421  dx1 = dy1 = radius;
422  dx2 = dx1;
423  dy2 = -dy1;
424  }
425 
426  wxPoint mirePos( aMire->GetPosition() );
427 
428  // Draw the X or + shape:
429  draw.SetStart( wxPoint( mirePos.x - dx1, mirePos.y - dy1 ));
430  draw.SetEnd( wxPoint( mirePos.x + dx1, mirePos.y + dy1 ));
431  PlotDrawSegment( &draw );
432 
433  draw.SetStart( wxPoint( mirePos.x - dx2, mirePos.y - dy2 ));
434  draw.SetEnd( wxPoint( mirePos.x + dx2, mirePos.y + dy2 ));
435  PlotDrawSegment( &draw );
436 }
437 
438 
439 // Plot footprints graphic items (outlines)
441 {
442  for( MODULE* module = m_board->m_Modules; module; module = module->Next() )
443  {
444  for( BOARD_ITEM* item = module->GraphicalItems().GetFirst(); item; item = item->Next() )
445  {
446  EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( item );
447 
448  if( edge && m_layerMask[edge->GetLayer()] )
449  Plot_1_EdgeModule( edge );
450  }
451  }
452 }
453 
454 
455 //* Plot a graphic item (outline) relative to a footprint
457 {
458  int type_trace; // Type of item to plot.
459  int thickness; // Segment thickness.
460  int radius; // Circle radius.
461 
462  if( aEdge->Type() != PCB_MODULE_EDGE_T )
463  return;
464 
465  m_plotter->SetColor( getColor( aEdge->GetLayer() ) );
466 
467  type_trace = aEdge->GetShape();
468  thickness = aEdge->GetWidth();
469 
470  wxPoint pos( aEdge->GetStart() );
471  wxPoint end( aEdge->GetEnd() );
472 
473  GBR_METADATA gbr_metadata;
475  MODULE* parent = static_cast<MODULE*> ( aEdge->GetParent() );
476  gbr_metadata.SetCmpReference( parent->GetReference() );
477 
478  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
479 
480  if( isOnCopperLayer )
481  {
482  gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_ETCHEDCMP );
483  gbr_metadata.SetCopper( true );
484  }
485  else if( aEdge->GetLayer() == Edge_Cuts ) // happens also when plotting copper layers
486  {
487  gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR );
488  }
489 
490  switch( type_trace )
491  {
492  case S_SEGMENT:
493  m_plotter->ThickSegment( pos, end, thickness, GetPlotMode(), &gbr_metadata );
494  break;
495 
496  case S_CIRCLE:
497  radius = KiROUND( GetLineLength( end, pos ) );
498  m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
499  break;
500 
501  case S_ARC:
502  {
503  radius = KiROUND( GetLineLength( end, pos ) );
504  double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
505  double endAngle = startAngle + aEdge->GetAngle();
506 
507  m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
508  }
509  break;
510 
511  case S_POLYGON:
512  {
513  const std::vector<wxPoint>& polyPoints = aEdge->GetPolyPoints();
514 
515  if( polyPoints.size() <= 1 ) // Malformed polygon
516  break;
517 
518  // We must compute true coordinates from m_PolyList
519  // which are relative to module position, orientation 0
520  MODULE* module = aEdge->GetParentModule();
521 
522  std::vector< wxPoint > cornerList;
523 
524  cornerList.reserve( polyPoints.size() );
525 
526  for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
527  {
528  wxPoint corner = polyPoints[ii];
529 
530  if( module )
531  {
532  RotatePoint( &corner, module->GetOrientation() );
533  corner += module->GetPosition();
534  }
535 
536  cornerList.push_back( corner );
537  }
538 
539  m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness, &gbr_metadata );
540  }
541  break;
542  }
543 }
544 
545 
546 // Plot a PCB Text, i.e. a text found on a copper or technical layer
548 {
549  double orient;
550  int thickness;
551  wxPoint pos;
552  wxSize size;
553  wxString shownText( pt_texte->GetShownText() );
554 
555  if( shownText.IsEmpty() )
556  return;
557 
558  if( !m_layerMask[pt_texte->GetLayer()] )
559  return;
560 
561  GBR_METADATA gbr_metadata;
562 
563  if( IsCopperLayer( pt_texte->GetLayer() ) )
564  {
566  }
567 
568  m_plotter->SetColor( getColor( pt_texte->GetLayer() ) );
569 
570  size = pt_texte->GetTextSize();
571  pos = pt_texte->GetTextPos();
572  orient = pt_texte->GetTextAngle();
573  thickness = pt_texte->GetThickness();
574 
575  if( pt_texte->IsMirrored() )
576  size.x = -size.x;
577 
578  // Non bold texts thickness is clamped at 1/6 char size by the low level draw function.
579  // but in Pcbnew we do not manage bold texts and thickness up to 1/4 char size
580  // (like bold text) and we manage the thickness.
581  // So we set bold flag to true
582  bool allow_bold = pt_texte->IsBold() || thickness;
583 
584  if( pt_texte->IsMultilineAllowed() )
585  {
586  std::vector<wxPoint> positions;
587  wxArrayString strings_list;
588  wxStringSplit( shownText, strings_list, '\n' );
589  positions.reserve( strings_list.Count() );
590 
591  pt_texte->GetPositionsOfLinesOfMultilineText( positions, strings_list.Count() );
592 
593  for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
594  {
595  wxString& txt = strings_list.Item( ii );
596  m_plotter->Text( positions[ii], COLOR4D::UNSPECIFIED, txt, orient, size,
597  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
598  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
599  }
600  }
601  else
602  {
603  m_plotter->Text( pos, COLOR4D::UNSPECIFIED, shownText, orient, size,
604  pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
605  thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
606  }
607 }
608 
609 
610 /* Plot areas (given by .m_FilledPolysList member) in a zone
611  */
613 {
614  const SHAPE_POLY_SET& polysList = aZone->GetFilledPolysList();
615 
616  if( polysList.IsEmpty() )
617  return;
618 
619  GBR_METADATA gbr_metadata;
620 
621  bool isOnCopperLayer = aZone->IsOnCopperLayer();
622 
623  if( isOnCopperLayer )
624  {
625  gbr_metadata.SetNetName( aZone->GetNetname() );
626  gbr_metadata.SetCopper( true );
627 
628  // Zones with no net name can exist.
629  // they are not used to connect items, so the aperture attribute cannot
630  // be set as conductor
631  if( aZone->GetNetname().IsEmpty() )
633  else
634  {
637  }
638  }
639 
640  // We need a buffer to store corners coordinates:
641  static std::vector< wxPoint > cornerList;
642  cornerList.clear();
643 
644  m_plotter->SetColor( getColor( aZone->GetLayer() ) );
645 
646  /* Plot all filled areas: filled areas have a filled area and a thick
647  * outline we must plot the filled area itself ( as a filled polygon
648  * OR a set of segments ) and plot the thick outline itself
649  *
650  * in non filled mode the outline is plotted, but not the filling items
651  */
652  for( auto ic = polysList.CIterate(); ic; ++ic )
653  {
654  wxPoint pos( ic->x, ic->y );
655  cornerList.push_back( pos );
656 
657  if( ic.IsEndContour() ) // Plot the current filled area outline
658  {
659  // First, close the outline
660  if( cornerList[0] != cornerList[cornerList.size() - 1] )
661  {
662  cornerList.push_back( cornerList[0] );
663  }
664 
665  // Plot the current filled area and its outline
666  if( GetPlotMode() == FILLED )
667  {
668  // Plot the filled area polygon.
669  // The area can be filled by segments or uses solid polygons
670  if( aZone->GetFillMode() == 0 ) // We are using solid polygons
671  {
672  m_plotter->PlotPoly( cornerList, FILLED_SHAPE, aZone->GetMinThickness(), &gbr_metadata );
673  }
674  else // We are using areas filled by segments: plot segments and outline
675  {
676  for( unsigned iseg = 0; iseg < aZone->FillSegments().size(); iseg++ )
677  {
678  wxPoint start = aZone->FillSegments()[iseg].m_Start;
679  wxPoint end = aZone->FillSegments()[iseg].m_End;
680  m_plotter->ThickSegment( start, end,
681  aZone->GetMinThickness(),
682  GetPlotMode(), &gbr_metadata );
683  }
684 
685  // Plot the area outline only
686  if( aZone->GetMinThickness() > 0 )
687  m_plotter->PlotPoly( cornerList, NO_FILL, aZone->GetMinThickness() );
688  }
689  }
690  else
691  {
692  if( aZone->GetMinThickness() > 0 )
693  {
694  for( unsigned jj = 1; jj<cornerList.size(); jj++ )
695  m_plotter->ThickSegment( cornerList[jj -1], cornerList[jj],
696  aZone->GetMinThickness(),
697  GetPlotMode(), &gbr_metadata );
698  }
699 
701  }
702 
703  cornerList.clear();
704  }
705  }
706 }
707 
708 
709 /* Plot items type DRAWSEGMENT on layers allowed by aLayerMask
710  */
712 {
713  if( !m_layerMask[aSeg->GetLayer()] )
714  return;
715 
716  int radius = 0;
717  double StAngle = 0, EndAngle = 0;
718  int thickness = aSeg->GetWidth();
719 
720  m_plotter->SetColor( getColor( aSeg->GetLayer() ) );
721 
722  wxPoint start( aSeg->GetStart() );
723  wxPoint end( aSeg->GetEnd() );
724 
725  GBR_METADATA gbr_metadata;
726 
727  bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
728 
729  if( isOnCopperLayer && aSeg->GetLayer() == Edge_Cuts ) // can happens when plotting copper layers
730  {
732  }
733 
734  switch( aSeg->GetShape() )
735  {
736  case S_CIRCLE:
737  radius = KiROUND( GetLineLength( end, start ) );
738  m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
739  break;
740 
741  case S_ARC:
742  radius = KiROUND( GetLineLength( end, start ) );
743  StAngle = ArcTangente( end.y - start.y, end.x - start.x );
744  EndAngle = StAngle + aSeg->GetAngle();
745  m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
746  break;
747 
748  case S_CURVE:
749  {
750  m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
751  const std::vector<wxPoint>& bezierPoints = aSeg->GetBezierPoints();
752 
753  for( unsigned i = 1; i < bezierPoints.size(); i++ )
754  m_plotter->ThickSegment( bezierPoints[i - 1], bezierPoints[i],
755  thickness, GetPlotMode(), &gbr_metadata );
756  }
757  break;
758 
759  default:
760  m_plotter->ThickSegment( start, end, thickness, GetPlotMode(), &gbr_metadata );
761  }
762 }
763 
764 
769  const wxPoint &aDrillPos, wxSize aDrillSize,
770  const wxSize &aPadSize,
771  double aOrientation, int aSmallDrill )
772 {
773  // Small drill marks have no significance when applied to slots
774  if( aSmallDrill && aDrillShape == PAD_DRILL_SHAPE_CIRCLE )
775  aDrillSize.x = std::min( aSmallDrill, aDrillSize.x );
776 
777  // Round holes only have x diameter, slots have both
778  aDrillSize.x -= getFineWidthAdj();
779  aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 );
780 
781  if( aDrillShape == PAD_DRILL_SHAPE_OBLONG )
782  {
783  aDrillSize.y -= getFineWidthAdj();
784  aDrillSize.y = Clamp( 1, aDrillSize.y, aPadSize.y - 1 );
785  m_plotter->FlashPadOval( aDrillPos, aDrillSize, aOrientation, GetPlotMode(), NULL );
786  }
787  else
788  m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetPlotMode(), NULL );
789 }
790 
791 
793 {
794  /* If small drills marks were requested prepare a clamp value to pass
795  to the helper function */
796  int small_drill = (GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE) ?
797  SMALL_DRILL : 0;
798 
799  /* In the filled trace mode drill marks are drawn white-on-black to scrape
800  the underlying pad. This works only for drivers supporting color change,
801  obviously... it means that:
802  - PS, SVG and PDF output is correct (i.e. you have a 'donut' pad)
803  - In HPGL you can't see them
804  - In gerbers you can't see them, too. This is arguably the right thing to
805  do since having drill marks and high speed drill stations is a sure
806  recipe for broken tools and angry manufacturers. If you *really* want them
807  you could start a layer with negative polarity to scrape the film.
808  - In DXF they go into the 'WHITE' layer. This could be useful.
809  */
810  if( GetPlotMode() == FILLED )
812 
813  for( TRACK *pts = m_board->m_Track; pts != NULL; pts = pts->Next() )
814  {
815  const VIA* via = dyn_cast<const VIA*>( pts );
816 
817  if( via )
819  wxSize( via->GetDrillValue(), 0 ),
820  wxSize( via->GetWidth(), 0 ), 0, small_drill );
821  }
822 
823  for( MODULE *Module = m_board->m_Modules; Module != NULL; Module = Module->Next() )
824  {
825  for( D_PAD *pad = Module->Pads(); pad != NULL; pad = pad->Next() )
826  {
827  if( pad->GetDrillSize().x == 0 )
828  continue;
829 
830  plotOneDrillMark( pad->GetDrillShape(),
831  pad->GetPosition(), pad->GetDrillSize(),
832  pad->GetSize(), pad->GetOrientation(),
833  small_drill );
834  }
835  }
836 
837  if( GetPlotMode() == FILLED )
839 }
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Function wxStringSplit splits aString to a string list separated at aSplitter.
Definition: common.cpp:137
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
COLOR4D GetLayerColor(PCB_LAYER_ID aLayer) const
Function GetLayerColor gets a layer color for any valid layer, including non-copper ones...
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
void SetPadName(const wxString &aPadname)
#define SMALL_DRILL
Definition: pcbplot.h:72
BOARD_ITEM_CONTAINER * GetParent() const
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:78
TEXTE_MODULE & Reference()
Definition: class_module.h:456
void SetShape(STROKE_T aShape)
PCB_TARGET class definition.
aperture used for edge connecto pad (outer layers)
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:183
bool IsMultilineAllowed() const
Definition: eda_text.h:188
double GetDrawRotation() const
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:127
PAD_ATTR_T GetAttribute() const
Definition: class_pad.h:238
TEXTE_PCB class definition.
const wxPoint & GetTextPos() const
Definition: eda_text.h:224
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
bool IsItalic() const
Definition: eda_text.h:170
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:63
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
int GetMinThickness() const
Definition: class_zone.h:209
wxPoint m_crossBarF
int GetWidth() const
Definition: class_mire.h:72
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
void BuildPadPolygon(wxPoint aCoord[4], wxSize aInflateValue, double aRotation) const
Function BuildPadPolygon Has meaning only for polygonal pads (trapezoid and rectangular) Build the Co...
virtual void ThickCircle(const wxPoint &pos, int diametre, int width, EDA_DRAW_MODE_T tracemode, void *aData)
void PlotPad(D_PAD *aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPlotMode)
Plot a pad.
int GetWidth() const
void SetNetAttribType(int aNetAttribType)
Class BOARD to handle a board.
void PlotDimension(DIMENSION *Dimension)
const wxPoint & GetPosition() const override
Definition: class_module.h:144
int GetRoundRectCornerRadius() const
Function GetRoundRectCornerRadius Has meaning only for rounded rect pads.
Definition: class_pad.h:351
polygon (not yet used for tracks, but could be in microwave apps)
MODULE * Next() const
Definition: class_module.h:100
MODULE * GetParent() const
Definition: class_pad.h:108
Smd pad, appears on the solder paste layer (default)
Definition: pad_shapes.h:59
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
PLOTTER * m_plotter
Definition: pcbplot.h:78
void PlotDrillMarks()
Function PlotDrillMarks Draw a drill mark for pads and vias.
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:104
aperture used for through hole component on outer layer
bool PlotAllTextsModule(MODULE *aModule)
Classes to handle copper zones.
usual segment : line with rounded ends
const std::vector< wxPoint > & GetPolyPoints() const
wxPoint m_featureLineDF
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
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.
PAD_SHAPE_T GetShape() const
Function GetShape.
Definition: class_pad.h:166
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:44
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:190
bool GetPlotValue() const
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:106
DLIST< BOARD_ITEM > & GraphicalItems()
Definition: class_module.h:137
Casted dyn_cast(From aObject)
Function dyn_cast()
Definition: typeinfo.h:73
BOARD * m_board
Definition: pcbplot.h:79
double GetTextAngle() const
Definition: eda_text.h:164
bool IsBold() const
Definition: eda_text.h:173
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)
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:154
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
void PlotFilledAreas(ZONE_CONTAINER *aZone)
Board plot function definition file.
wxPoint m_featureLineGO
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:135
BOARD_ITEM * Next() const
std::vector< SEGMENT > & FillSegments()
Definition: class_zone.h:244
DIMENSION class definition.
aperture used for BGA pad with a solder mask defined by the solder mask
virtual void FlashPadCircle(const wxPoint &aPadPos, int aDiameter, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadCircle
DrillMarksType GetDrillMarksType() const
STROKE_T GetShape() const
int GetShape() const
Definition: class_mire.h:66
Classes used in Pcbnew, CvPcb and GerbView.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
void PlotPcbTarget(PCB_TARGET *PtMire)
double GetOrientation() const
Definition: class_module.h:148
Class SHAPE_POLY_SET.
TEXTE_MODULE & Value()
read/write accessors:
Definition: class_module.h:455
EDA_DRAW_MODE_T
Definition: eda_text.h:62
void PlotBoardGraphicItems()
plot items like text and graphics, but not tracks and modules
const wxPoint & GetStart() const
Definition: class_track.h:121
Arcs (with rounded ends)
virtual void FlashPadRoundRect(const wxPoint &aPadPos, const wxSize &aSize, int aCornerRadius, double aOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadRoundRect
COLOR4D GetReferenceColor() const
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:235
wxPoint m_arrowG1F
void Plot_1_EdgeModule(EDGE_MODULE *aEdge)
wxPoint m_arrowD2F
wxPoint m_arrowG2F
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
D_PAD * Next() const
Definition: class_pad.h:106
static LSET ExternalCuMask()
Function ExternalCuMask returns a mask holding the Front and Bottom layers.
Definition: lset.cpp:669
const wxSize & GetSize() const
Definition: class_pad.h:182
DLIST< BOARD_ITEM > m_Drawings
Definition: class_board.h:242
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:327
Common plot library Plot settings, and plotting engines (Postscript, Gerber, HPGL and DXF) ...
aperture used for mechanical pads (NPTH)
Bezier Curve.
bool GetPlotReference() const
Like smd, does not appear on the solder paste layer (default) note also has a special attribute in Ge...
Definition: pad_shapes.h:60
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:112
const SHAPE_POLY_SET & GetFilledPolysList() const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: class_zone.h:587
COLOR4D GetColor() const
aperture used for connected items like tracks (not vias)
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:113
void SetStart(const wxPoint &aStart)
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
const std::vector< wxPoint > & GetBezierPoints() const
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:191
void SetNetName(const wxString &aNetname)
virtual void FlashPadRect(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadRect
PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.h:179
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:111
const wxPoint & GetPosition() const override
Definition: class_mire.h:63
TRACK * Next() const
Definition: class_track.h:98
double GetAngle() const
bool GetPlotInvisibleText() const
const wxString & GetNetname() const
Function GetNetname.
int GetFillMode() const
Definition: class_zone.h:186
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.
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:412
virtual void FlashPadOval(const wxPoint &aPadPos, const wxSize &aSize, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void *aData)=0
virtual function FlashPadOval
bool IsMirrored() const
Definition: eda_text.h:179
DLIST< MODULE > m_Modules
Definition: class_board.h:243
bool IsVisible() const
Definition: eda_text.h:176
int GetWidth() const
Definition: class_track.h:115
virtual void ThickSegment(const wxPoint &start, const wxPoint &end, int width, EDA_DRAW_MODE_T tracemode, void *aData)
LSET m_layerMask
Definition: pcbplot.h:80
TEXTE_PCB & Text()
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees, but soon degrees.
Definition: class_pad.h:214
EDA_DRAW_MODE_T GetPlotMode() const
Usual pad.
Definition: pad_shapes.h:58
aperture used for SMD pad with a solder mask defined by the solder mask
The common library.
int GetWidth() const
void PlotTextePcb(TEXTE_PCB *pt_texte)
Definition: colors.h:49
wxPoint ShapePos() const
Definition: class_pad.cpp:418
void SetEnd(const wxPoint &aEnd)
COLOR4D GetValueColor() const
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
int GetSize() const
Definition: class_mire.h:69
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
MODULE * GetParentModule() const
Function GetParentModule returns a pointer to the parent module, or NULL if DRAWSEGMENT does not belo...
This file is part of the common libary.
static LSET AllBoardTechMask()
Function AllTechMask returns a mask holding board technical layers (no CU layer) on both side...
Definition: lset.cpp:716
wxPoint m_crossBarO
void SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)
bool m_NotInNet
true if a pad of a footprint cannot be connected (for instance a mechanical NPTH, ot a not named pad)...
wxString GetPadName() const
Definition: class_pad.cpp:433
int getFineWidthAdj()
Definition: pcbplot.h:95
DLIST< TRACK > m_Track
Definition: class_board.h:244
GBR_NETLIST_METADATA m_NetlistMetadata
a item to handle object attribute:
Module description (excepted pads)
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
const wxSize & GetTextSize() const
Definition: eda_text.h:215
Basic classes for most KiCad items.
aperture used for not connected items (texts, outlines on copper)
EDGE_MODULE class definition.
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:103
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
void SetCopper(bool aValue)
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
wxPoint m_featureLineDO
print info associated to a net (TO.N attribute)
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:767
void SetCmpReference(const wxString &aComponentRef)
COLOR4D getColor(LAYER_NUM aLayer)
Function getColor.
Class DIMENSION.
#define GBR_NETINFO_ALL
#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)
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)