KiCad PCB EDA Suite
pcb_painter.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) 2013-2019 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <board.h>
27 #include <track.h>
28 #include <pcb_group.h>
29 #include <footprint.h>
30 #include <pad.h>
31 #include <pcb_shape.h>
32 #include <kicad_string.h>
33 #include <zone.h>
34 #include <pcb_text.h>
35 #include <pcb_marker.h>
36 #include <dimension.h>
37 #include <pcb_target.h>
38 #include <core/arraydim.h>
39 
41 #include <pcb_painter.h>
42 #include <pcb_display_options.h>
43 #include <project/net_settings.h>
45 
50 #include <geometry/shape_rect.h>
51 #include <geometry/shape_segment.h>
52 #include <geometry/shape_simple.h>
53 #include <geometry/shape_circle.h>
54 
55 using namespace KIGFX;
56 
58 {
59  m_backgroundColor = COLOR4D( 0.0, 0.0, 0.0, 1.0 );
60  m_padNumbers = true;
61  m_netNamesOnPads = true;
62  m_netNamesOnTracks = true;
63  m_netNamesOnVias = true;
64  m_zoneOutlines = true;
67  m_sketchGraphics = false;
68  m_sketchText = false;
72 
73  m_trackOpacity = 1.0;
74  m_viaOpacity = 1.0;
75  m_padOpacity = 1.0;
76  m_zoneOpacity = 1.0;
77 
78  // By default everything should be displayed as filled
79  for( unsigned int i = 0; i < arrayDim( m_sketchMode ); ++i )
80  m_sketchMode[i] = false;
81 
82  update();
83 }
84 
85 
87 {
89 
90  // Init board layers colors:
91  for( int i = 0; i < PCB_LAYER_ID_COUNT; i++ )
92  {
93  m_layerColors[i] = aSettings->GetColor( i );
94 
95  // Guard: if the alpah channel is too small, the layer is not visible.
96  if( m_layerColors[i].a < 0.2 )
97  m_layerColors[i].a = 0.2;
98  }
99 
100  // Init specific graphic layers colors:
101  for( int i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; i++ )
102  m_layerColors[i] = aSettings->GetColor( i );
103 
104  // Colors for layers that aren't theme-able
106  m_layerColors[LAYER_VIA_NETNAMES] = COLOR4D( 0.2, 0.2, 0.2, 0.9 );
107  m_layerColors[LAYER_PAD_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
108  m_layerColors[LAYER_PAD_FR_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
109  m_layerColors[LAYER_PAD_BK_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
110 
111  // Netnames for copper layers
112  for( LSEQ cu = LSET::AllCuMask().CuStack(); cu; ++cu )
113  {
114  const COLOR4D lightLabel( 0.8, 0.8, 0.8, 0.7 );
115  const COLOR4D darkLabel = lightLabel.Inverted();
116  PCB_LAYER_ID layer = *cu;
117 
118  if( m_layerColors[layer].GetBrightness() > 0.5 )
119  m_layerColors[GetNetnameLayer( layer )] = darkLabel;
120  else
121  m_layerColors[GetNetnameLayer( layer )] = lightLabel;
122  }
123 
124  update();
125 }
126 
127 
129  bool aShowPageLimits )
130 {
133  m_padNumbers = aOptions.m_DisplayPadNum;
135  m_sketchText = !aOptions.m_DisplayTextFill;
138 
139  // Whether to draw tracks, vias & pads filled or as outlines
145 
146  // Net names display settings
147  switch( aOptions.m_DisplayNetNamesMode )
148  {
149  case 0:
150  m_netNamesOnPads = false;
151  m_netNamesOnTracks = false;
152  m_netNamesOnVias = false;
153  break;
154 
155  case 1:
156  m_netNamesOnPads = true;
157  m_netNamesOnTracks = false;
158  m_netNamesOnVias = true; // Follow pads or tracks? For now we chose pads....
159  break;
160 
161  case 2:
162  m_netNamesOnPads = false;
163  m_netNamesOnTracks = true;
164  m_netNamesOnVias = false; // Follow pads or tracks? For now we chose pads....
165  break;
166 
167  case 3:
168  m_netNamesOnPads = true;
169  m_netNamesOnTracks = true;
170  m_netNamesOnVias = true;
171  break;
172  }
173 
174  // Zone display settings
176 
177  // Clearance settings
178  switch( aOptions.m_ShowTrackClearanceMode )
179  {
182  break;
183 
186  break;
187 
190  break;
191 
194  break;
195 
198  break;
199  }
200 
201  if( aOptions.m_DisplayPadIsol )
203 
205 
206  m_netColorMode = aOptions.m_NetColorMode;
207 
209 
210  m_trackOpacity = aOptions.m_TrackOpacity;
211  m_viaOpacity = aOptions.m_ViaOpacity;
212  m_padOpacity = aOptions.m_PadOpacity;
213  m_zoneOpacity = aOptions.m_ZoneOpacity;
214 
215  m_showPageLimits = aShowPageLimits;
216 }
217 
218 
219 COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const
220 {
221  const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
222  const BOARD_CONNECTED_ITEM* conItem = dynamic_cast<const BOARD_CONNECTED_ITEM*> ( aItem );
223  int netCode = -1;
224  int originalLayer = aLayer;
225 
226  // Marker shadows
227  if( aLayer == LAYER_MARKER_SHADOWS )
228  return m_backgroundColor.WithAlpha( 0.6 );
229 
230  if( IsHoleLayer( aLayer ) && m_isPrinting )
231  {
232  // Careful that we don't end up with the same colour for the annular ring and the hole
233  // when printing in B&W.
234  const PAD* pad = dynamic_cast<const PAD*>( item );
235  const VIA* via = dynamic_cast<const VIA*>( item );
236  int holeLayer = aLayer;
237  int annularRingLayer;
238 
239  if( pad )
240  annularRingLayer = LAYER_PADS_TH;
241  else if( via && via->GetViaType() == VIATYPE::MICROVIA )
242  annularRingLayer = LAYER_VIA_MICROVIA;
243  else if( via && via->GetViaType() == VIATYPE::BLIND_BURIED )
244  annularRingLayer = LAYER_VIA_BBLIND;
245  else
246  annularRingLayer = LAYER_VIA_THROUGH;
247 
248  if( m_layerColors[ holeLayer ] == m_layerColors[ annularRingLayer ] )
249  aLayer = LAYER_PCB_BACKGROUND;
250  }
251 
252  // Zones should pull from the copper layer
253  if( item && item->Type() == PCB_ZONE_T && IsZoneLayer( aLayer ) )
254  aLayer = aLayer - LAYER_ZONE_START;
255 
256  // Hole walls should pull from the copper layer
257  if( aLayer == LAYER_PAD_HOLEWALLS )
258  aLayer = LAYER_PADS_TH;
259  else if( aLayer == LAYER_VIA_HOLEWALLS )
260  aLayer = LAYER_VIA_THROUGH;
261 
262  // Normal path: get the layer base color
263  COLOR4D color = m_layerColors[aLayer];
264 
265  if( !item )
266  return m_layerColors[aLayer];
267 
268  // Selection disambiguation
269  if( item->IsBrightened() )
270  return color.Brightened( m_selectFactor ).WithAlpha( 0.8 );
271 
272  // Normal selection
273  if( item->IsSelected() )
274  color = m_layerColorsSel[aLayer];
275 
276  // Try to obtain the netcode for the item
277  if( conItem )
278  netCode = conItem->GetNetCode();
279 
280  bool highlighted = m_highlightEnabled && m_highlightNetcodes.count( netCode );
281  bool selected = item->IsSelected();
282 
283  // Apply net color overrides
284  if( conItem && m_netColorMode == NET_COLOR_MODE::ALL && IsNetCopperLayer( aLayer ) )
285  {
286  COLOR4D netColor = COLOR4D::UNSPECIFIED;
287 
288  auto ii = m_netColors.find( netCode );
289 
290  if( ii != m_netColors.end() )
291  netColor = ii->second;
292 
293  if( netColor == COLOR4D::UNSPECIFIED )
294  {
295  auto jj = m_netclassColors.find( conItem->GetNetClassName() );
296 
297  if( jj != m_netclassColors.end() )
298  netColor = jj->second;
299  }
300 
301  if( netColor == COLOR4D::UNSPECIFIED )
302  netColor = color;
303 
304  if( selected )
305  {
306  // Selection brightening overrides highlighting
307  netColor.Brighten( m_selectFactor );
308  }
309  else if( m_highlightEnabled )
310  {
311  // Highlight brightens objects on all layers and darkens everything else for contrast
312  if( highlighted )
313  netColor.Brighten( m_highlightFactor );
314  else
315  netColor.Darken( 1.0 - m_highlightFactor );
316  }
317 
318  color = netColor;
319  }
320  else if( !selected && m_highlightEnabled )
321  {
322  // Single net highlight mode
323  color = m_highlightNetcodes.count( netCode ) ? m_layerColorsHi[aLayer]
324  : m_layerColorsDark[aLayer];
325  }
326 
327  // Apply high-contrast dimming
328  if( m_hiContrastEnabled && !highlighted && !selected )
329  {
331  bool isActive = m_highContrastLayers.count( aLayer );
332 
333  if( originalLayer == LAYER_PADS_TH )
334  {
335  if( !static_cast<const PAD*>( item )->FlashLayer( primary ) )
336  isActive = false;
337  }
338  else if( originalLayer == LAYER_VIA_THROUGH )
339  {
340  if( !static_cast<const VIA*>( item )->FlashLayer( primary ) )
341  isActive = false;
342  }
343 
344  if( !isActive )
345  {
348  else
350  }
351  }
352 
353  // Apply per-type opacity overrides
354  if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
355  color.a *= m_trackOpacity;
356  else if( item->Type() == PCB_VIA_T )
357  color.a *= m_viaOpacity;
358  else if( item->Type() == PCB_PAD_T )
359  color.a *= m_padOpacity;
360  else if( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
361  color.a *= m_zoneOpacity;
362 
363  // No special modificators enabled
364  return color;
365 }
366 
367 
369  PAINTER( aGal )
370 {
371 }
372 
373 
374 int PCB_PAINTER::getLineThickness( int aActualThickness ) const
375 {
376  // if items have 0 thickness, draw them with the outline
377  // width, otherwise respect the set value (which, no matter
378  // how small will produce something)
379  if( aActualThickness == 0 )
381 
382  return aActualThickness;
383 }
384 
385 
386 int PCB_PAINTER::getDrillShape( const PAD* aPad ) const
387 {
388  return aPad->GetDrillShape();
389 }
390 
391 
393 {
394  return VECTOR2D( aPad->GetDrillSize() );
395 }
396 
397 
398 int PCB_PAINTER::getDrillSize( const VIA* aVia ) const
399 {
400  return aVia->GetDrillValue();
401 }
402 
403 
404 bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
405 {
406  const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
407 
408  if( !item )
409  return false;
410 
411  // the "cast" applied in here clarifies which overloaded draw() is called
412  switch( item->Type() )
413  {
414  case PCB_TRACE_T:
415  draw( static_cast<const TRACK*>( item ), aLayer );
416  break;
417 
418  case PCB_ARC_T:
419  draw( static_cast<const ARC*>( item ), aLayer );
420  break;
421 
422  case PCB_VIA_T:
423  draw( static_cast<const VIA*>( item ), aLayer );
424  break;
425 
426  case PCB_PAD_T:
427  draw( static_cast<const PAD*>( item ), aLayer );
428  break;
429 
430  case PCB_SHAPE_T:
431  case PCB_FP_SHAPE_T:
432  draw( static_cast<const PCB_SHAPE*>( item ), aLayer );
433  break;
434 
435  case PCB_TEXT_T:
436  draw( static_cast<const PCB_TEXT*>( item ), aLayer );
437  break;
438 
439  case PCB_FP_TEXT_T:
440  draw( static_cast<const FP_TEXT*>( item ), aLayer );
441  break;
442 
443  case PCB_FOOTPRINT_T:
444  draw( static_cast<const FOOTPRINT*>( item ), aLayer );
445  break;
446 
447  case PCB_GROUP_T:
448  draw( static_cast<const PCB_GROUP*>( item ), aLayer );
449  break;
450 
451  case PCB_ZONE_T:
452  draw( static_cast<const ZONE*>( item ), aLayer );
453  break;
454 
455  case PCB_FP_ZONE_T:
456  draw( static_cast<const ZONE*>( item ), aLayer );
457  break;
458 
459  case PCB_DIM_ALIGNED_T:
460  case PCB_DIM_CENTER_T:
462  case PCB_DIM_LEADER_T:
463  draw( static_cast<const DIMENSION_BASE*>( item ), aLayer );
464  break;
465 
466  case PCB_TARGET_T:
467  draw( static_cast<const PCB_TARGET*>( item ) );
468  break;
469 
470  case PCB_MARKER_T:
471  draw( static_cast<const PCB_MARKER*>( item ), aLayer );
472  break;
473 
474  default:
475  // Painter does not know how to draw the object
476  return false;
477  }
478 
479  return true;
480 }
481 
482 
483 void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
484 {
485  VECTOR2D start( aTrack->GetStart() );
486  VECTOR2D end( aTrack->GetEnd() );
487  int width = aTrack->GetWidth();
488  COLOR4D color = m_pcbSettings.GetColor( aTrack, aLayer );
489 
490  if( IsNetnameLayer( aLayer ) )
491  {
493  return;
494 
495  if( aTrack->GetNetCode() <= NETINFO_LIST::UNCONNECTED )
496  return;
497 
498  VECTOR2D line = ( end - start );
499  double length = line.EuclideanNorm();
500 
501  // Check if the track is long enough to have a netname displayed
502  if( length < 10 * width )
503  return;
504 
505  const wxString& netName = UnescapeString( aTrack->GetShortNetname() );
506  double textSize = width;
507  double penWidth = width / 12.0;
508  VECTOR2D textPosition = start + line / 2.0; // center of the track
509  double textOrientation;
510 
511  if( end.y == start.y ) // horizontal
512  {
513  textOrientation = 0;
514  textPosition.y += penWidth;
515  }
516  else if( end.x == start.x ) // vertical
517  {
518  textOrientation = M_PI / 2;
519  textPosition.x += penWidth;
520  }
521  else
522  {
523  textOrientation = -atan( line.y / line.x );
524  textPosition.x += penWidth / 1.4;
525  textPosition.y += penWidth / 1.4;
526  }
527 
528 
529  m_gal->SetIsStroke( true );
530  m_gal->SetIsFill( false );
532  m_gal->SetLineWidth( penWidth );
533  m_gal->SetFontBold( false );
534  m_gal->SetFontItalic( false );
535  m_gal->SetFontUnderlined( false );
536  m_gal->SetTextMirrored( false );
537  m_gal->SetGlyphSize( VECTOR2D( textSize * 0.55, textSize * 0.55 ) );
540  m_gal->BitmapText( netName, textPosition, textOrientation );
541 
542  return;
543  }
544  else if( IsCopperLayer( aLayer ) )
545  {
546  // Draw a regular track
547  bool outline_mode = m_pcbSettings.m_sketchMode[LAYER_TRACKS];
550  m_gal->SetIsStroke( outline_mode );
551  m_gal->SetIsFill( not outline_mode );
553 
554  m_gal->DrawSegment( start, end, width );
555  }
556 
557  // Clearance lines
558  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING
560 
561  if( ( m_pcbSettings.m_clearanceDisplayFlags & clearanceFlags ) == clearanceFlags )
562  {
563  int clearance = aTrack->GetOwnClearance( m_pcbSettings.GetActiveLayer() );
564 
566  m_gal->SetIsFill( false );
567  m_gal->SetIsStroke( true );
569  m_gal->DrawSegment( start, end, width + clearance * 2 );
570  }
571 }
572 
573 
574 void PCB_PAINTER::draw( const ARC* aArc, int aLayer )
575 {
576  VECTOR2D center( aArc->GetCenter() );
577  int width = aArc->GetWidth();
578  COLOR4D color = m_pcbSettings.GetColor( aArc, aLayer );
579  double radius = aArc->GetRadius();
580  double start_angle = DECIDEG2RAD( aArc->GetArcAngleStart() );
581  double angle = DECIDEG2RAD( aArc->GetAngle() );
582 
583  if( IsNetnameLayer( aLayer ) )
584  {
585  // Ummm, yeah. Anyone fancy implementing text on a path?
586  return;
587  }
588  else if( IsCopperLayer( aLayer ) )
589  {
590  // Draw a regular track
591  bool outline_mode = m_pcbSettings.m_sketchMode[LAYER_TRACKS];
594  m_gal->SetIsStroke( outline_mode );
595  m_gal->SetIsFill( not outline_mode );
597 
598  m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width );
599  }
600 
601  // Clearance lines
602  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING
604 
605  if( ( m_pcbSettings.m_clearanceDisplayFlags & clearanceFlags ) == clearanceFlags )
606  {
607  int clearance = aArc->GetOwnClearance( m_pcbSettings.GetActiveLayer() );
608 
610  m_gal->SetIsFill( false );
611  m_gal->SetIsStroke( true );
613 
614  m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle,
615  width + clearance * 2 );
616  }
617 }
618 
619 
620 void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
621 {
622  BOARD* board = aVia->GetBoard();
624  COLOR4D color = m_pcbSettings.GetColor( aVia, aLayer );
625  VECTOR2D center( aVia->GetStart() );
626 
627  if( color == COLOR4D::CLEAR )
628  return;
629 
630  // Draw description layer
631  if( IsNetnameLayer( aLayer ) )
632  {
633  VECTOR2D position( center );
634 
635  // Is anything that we can display enabled?
636  if( !m_pcbSettings.m_netNamesOnVias || aVia->GetNetname().empty() )
637  return;
638 
639  double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
640  double size = aVia->GetWidth();
641 
642  // Font size limits
643  if( size > maxSize )
644  size = maxSize;
645 
646  m_gal->Save();
647  m_gal->Translate( position );
648 
649  // Default font settings
652 
653  // Set the text position to the pad shape position (the pad position is not the best place)
654  VECTOR2D textpos( 0.0, 0.0 );
655 
656  wxString netname = UnescapeString( aVia->GetShortNetname() );
657  // calculate the size of net name text:
658  double tsize = 1.5 * size / netname.Length();
659  tsize = std::min( tsize, size );
660  // Use a smaller text size to handle interline, pen size..
661  tsize *= 0.7;
662  VECTOR2D namesize( tsize, tsize );
663 
664  m_gal->SetGlyphSize( namesize );
665  m_gal->SetLineWidth( namesize.x / 12.0 );
666  m_gal->BitmapText( netname, textpos, 0.0 );
667 
668  m_gal->Restore();
669 
670  return;
671  }
672  else if( aLayer == LAYER_VIA_HOLEWALLS )
673  {
674  int platingThickness = bds.GetHolePlatingThickness();
675 
676  m_gal->SetIsFill( false );
677  m_gal->SetIsStroke( true );
679  m_gal->SetLineWidth( platingThickness );
680 
681  m_gal->DrawCircle( center, ( getDrillSize( aVia ) + platingThickness ) / 2.0 );
682 
683  return;
684  }
685 
686  bool sketchMode = false;
687 
688  switch( aVia->GetViaType() )
689  {
693  default: wxASSERT( false ); break;
694  }
695 
696  if( sketchMode )
697  {
698  // Outline mode
699  m_gal->SetIsStroke( true );
700  m_gal->SetIsFill( false );
703  }
704  else
705  {
706  // Filled mode
707  m_gal->SetIsFill( true );
708  m_gal->SetIsStroke( false );
710  }
711 
712  if( aLayer == LAYER_VIA_HOLES )
713  {
714  m_gal->DrawCircle( center, getDrillSize( aVia ) / 2.0 );
715  }
717  {
718  m_gal->DrawCircle( center, aVia->GetWidth() / 2.0 );
719  }
720  else if( aLayer == LAYER_VIA_BBLIND || aLayer == LAYER_VIA_MICROVIA )
721  {
722  // Outer circles of blind/buried and micro-vias are drawn in a special way to indicate the
723  // top and bottom layers
724  PCB_LAYER_ID layerTop, layerBottom;
725  aVia->LayerPair( &layerTop, &layerBottom );
726 
727  double radius = aVia->GetWidth() / 2.0;
728 
729  if( !sketchMode )
730  m_gal->SetLineWidth( ( aVia->GetWidth() - aVia->GetDrillValue() ) / 2.0 );
731 
732  m_gal->DrawArc( center, radius, M_PI / 2.0, M_PI );
733  m_gal->DrawArc( center, radius, 3.0 * M_PI / 2.0, 2.0 * M_PI );
734 
735  if( sketchMode )
736  m_gal->SetStrokeColor( m_pcbSettings.GetColor( aVia, layerTop ) );
737  else
738  m_gal->SetFillColor( m_pcbSettings.GetColor( aVia, layerTop ) );
739 
740  m_gal->DrawArc( center, radius, 0.0, M_PI / 2.0 );
741 
742  if( sketchMode )
743  m_gal->SetStrokeColor( m_pcbSettings.GetColor( aVia, layerBottom ) );
744  else
745  m_gal->SetFillColor( m_pcbSettings.GetColor( aVia, layerBottom ) );
746 
747  m_gal->DrawArc( center, radius, M_PI, 3.0 * M_PI / 2.0 );
748  }
749 
750  // Clearance lines
751  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING | PCB_RENDER_SETTINGS::CL_VIAS;
752 
753  if( ( m_pcbSettings.m_clearanceDisplayFlags & clearanceFlags ) == clearanceFlags
754  && aLayer != LAYER_VIA_HOLES )
755  {
756  PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
757  double radius;
758 
759  if( aVia->FlashLayer( activeLayer ) )
760  radius = aVia->GetWidth() / 2.0;
761  else
762  radius = getDrillSize( aVia ) / 2.0 + bds.GetHolePlatingThickness();
763 
765  m_gal->SetIsFill( false );
766  m_gal->SetIsStroke( true );
768  m_gal->DrawCircle( center, radius + aVia->GetOwnClearance( activeLayer ) );
769  }
770 }
771 
772 
773 bool isImplicitNet( const wxString& aNetName )
774 {
775  return aNetName.StartsWith( wxT( "Net-(" ) ) || aNetName.StartsWith( wxT( "unconnected-(" ) );
776 }
777 
778 
779 void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
780 {
781  BOARD* board = aPad->GetBoard();
783  COLOR4D color = m_pcbSettings.GetColor( aPad, aLayer );
784 
785  if( IsNetnameLayer( aLayer ) )
786  {
787  // Is anything that we can display enabled?
789  {
790  bool displayNetname = ( m_pcbSettings.m_netNamesOnPads && !aPad->GetNetname().empty() );
791  EDA_RECT padBBox = aPad->GetBoundingBox();
792  VECTOR2D position = padBBox.Centre();
793  VECTOR2D padsize = VECTOR2D( padBBox.GetSize() );
794 
795  if( aPad->GetShape() != PAD_SHAPE_CUSTOM )
796  {
797  // Don't allow a 45ยบ rotation to bloat a pad's bounding box unnecessarily
798  double limit = std::min( aPad->GetSize().x, aPad->GetSize().y ) * 1.1;
799 
800  if( padsize.x > limit && padsize.y > limit )
801  {
802  padsize.x = limit;
803  padsize.y = limit;
804  }
805  }
806 
807  double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
808  double size = padsize.y;
809 
810  m_gal->Save();
811  m_gal->Translate( position );
812 
813  // Keep the size ratio for the font, but make it smaller
814  if( padsize.x < padsize.y )
815  {
816  m_gal->Rotate( DECIDEG2RAD( -900.0 ) );
817  size = padsize.x;
818  std::swap( padsize.x, padsize.y );
819  }
820 
821  // Font size limits
822  if( size > maxSize )
823  size = maxSize;
824 
825  // Default font settings
828  m_gal->SetFontBold( false );
829  m_gal->SetFontItalic( false );
830  m_gal->SetFontUnderlined( false );
831  m_gal->SetTextMirrored( false );
832  m_gal->SetStrokeColor( m_pcbSettings.GetColor( aPad, aLayer ) );
833  m_gal->SetIsStroke( true );
834  m_gal->SetIsFill( false );
835 
836  // We have already translated the GAL to be centered at the center of the pad's
837  // bounding box
838  VECTOR2D textpos( 0.0, 0.0 );
839 
840  // Divide the space, to display both pad numbers and netnames and set the Y text
841  // position to display 2 lines
842  if( displayNetname && m_pcbSettings.m_padNumbers )
843  {
844  size = size / 2.0;
845  textpos.y = size / 2.0;
846  }
847 
848  if( displayNetname )
849  {
850  wxString netname = UnescapeString( aPad->GetShortNetname() );
851  wxString pinType = aPad->GetPinType();
852 
853  if( pinType == wxT( "no_connect" ) || pinType.EndsWith( wxT( "+no_connect" ) ) )
854  netname = "x";
855  else if( pinType == wxT( "free" ) && isImplicitNet( netname ) )
856  netname = "*";
857 
858  // calculate the size of net name text:
859  double tsize = 1.5 * padsize.x / netname.Length();
860  tsize = std::min( tsize, size );
861  // Use a smaller text size to handle interline, pen size..
862  tsize *= 0.7;
863  VECTOR2D namesize( tsize, tsize );
864 
865  m_gal->SetGlyphSize( namesize );
866  m_gal->SetLineWidth( namesize.x / 12.0 );
867  m_gal->BitmapText( netname, textpos, 0.0 );
868  }
869 
871  {
872  const wxString& padName = aPad->GetName();
873  textpos.y = -textpos.y;
874  double tsize = 1.5 * padsize.x / padName.Length();
875  tsize = std::min( tsize, size );
876  // Use a smaller text size to handle interline, pen size..
877  tsize *= 0.7;
878  tsize = std::min( tsize, size );
879  VECTOR2D numsize( tsize, tsize );
880 
881  m_gal->SetGlyphSize( numsize );
882  m_gal->SetLineWidth( numsize.x / 12.0 );
883  m_gal->BitmapText( padName, textpos, 0.0 );
884  }
885 
886  m_gal->Restore();
887  }
888  return;
889  }
890  else if( aLayer == LAYER_PAD_HOLEWALLS )
891  {
892  int platingThickness = bds.GetHolePlatingThickness();
893 
894  m_gal->SetIsFill( false );
895  m_gal->SetIsStroke( true );
896  m_gal->SetLineWidth( platingThickness );
898 
899  const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
900  int holeSize = seg->GetWidth() + platingThickness;
901 
902  if( seg->GetSeg().A == seg->GetSeg().B ) // Circular hole
903  m_gal->DrawCircle( seg->GetSeg().A, holeSize / 2 );
904  else
905  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, holeSize );
906 
907  return;
908  }
909 
911  {
912  // Outline mode
913  m_gal->SetIsFill( false );
914  m_gal->SetIsStroke( true );
917  }
918  else
919  {
920  // Filled mode
921  m_gal->SetIsFill( true );
922  m_gal->SetIsStroke( false );
924  }
925 
926  if( aLayer == LAYER_PAD_PLATEDHOLES || aLayer == LAYER_NON_PLATEDHOLES )
927  {
928  const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
929 
930  if( seg->GetSeg().A == seg->GetSeg().B ) // Circular hole
931  m_gal->DrawCircle( seg->GetSeg().A, getDrillSize( aPad ).x / 2 );
932  else
933  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() );
934  }
935  else
936  {
937  wxSize pad_size = aPad->GetSize();
938  wxSize margin;
939 
940  switch( aLayer )
941  {
942  case F_Mask:
943  case B_Mask:
944  margin.x = margin.y = aPad->GetSolderMaskMargin();
945  break;
946 
947  case F_Paste:
948  case B_Paste:
949  margin = aPad->GetSolderPasteMargin();
950  break;
951 
952  default:
953  margin.x = margin.y = 0;
954  break;
955  }
956 
957  std::unique_ptr<PAD> dummyPad;
958  std::shared_ptr<SHAPE_COMPOUND> shapes;
959  bool simpleShapes = true;
960 
961  if( margin.x != margin.y && aPad->GetShape() != PAD_SHAPE_CUSTOM )
962  {
963  // Our algorithms below (polygon inflation in particular) can't handle differential
964  // inflation along separate axes. So for those cases we build a dummy pad instead,
965  // and inflate it.
966 
967  // Margin is added to both sides. If the total margin is larger than the pad
968  // then don't display this layer
969  if( pad_size.x + 2 * margin.x <= 0 || pad_size.y + 2 * margin.y <= 0 )
970  return;
971 
972  dummyPad.reset( static_cast<PAD*>( aPad->Duplicate() ) );
973  dummyPad->SetSize( pad_size + margin + margin );
974  shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( dummyPad->GetEffectiveShape() );
975  margin.x = margin.y = 0;
976  }
977  else
978  {
979  shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
980  }
981 
982  for( SHAPE* shape : shapes->Shapes() )
983  {
984  // Drawing components of compound shapes in outline mode produces a mess.
986  simpleShapes = false;
987 
988  if( !simpleShapes )
989  break;
990 
991  switch( shape->Type() )
992  {
993  case SH_SEGMENT:
994  case SH_CIRCLE:
995  case SH_RECT:
996  case SH_SIMPLE:
997  // OK so far
998  break;
999 
1000  default:
1001  // Not OK
1002  simpleShapes = false;
1003  break;
1004  }
1005  }
1006 
1007  if( simpleShapes )
1008  {
1009  for( SHAPE* shape : shapes->Shapes() )
1010  {
1011  switch( shape->Type() )
1012  {
1013  case SH_SEGMENT:
1014  {
1015  const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape;
1016  int effectiveWidth = seg->GetWidth() + 2 * margin.x;
1017 
1018  if( effectiveWidth > 0 )
1019  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, effectiveWidth );
1020  }
1021  break;
1022 
1023  case SH_CIRCLE:
1024  {
1025  const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape;
1026  int effectiveRadius = circle->GetRadius() + margin.x;
1027 
1028  if( effectiveRadius > 0 )
1029  m_gal->DrawCircle( circle->GetCenter(), effectiveRadius );
1030  }
1031  break;
1032 
1033  case SH_RECT:
1034  {
1035  const SHAPE_RECT* r = (SHAPE_RECT*) shape;
1036  VECTOR2I position = r->GetPosition();
1037  VECTOR2I effectiveSize = r->GetSize() + margin;
1038 
1039  // At this point, if margin.x < 0 the actual rectangle size is
1040  // smaller than SHAPE_RECT r (the pad size was not modifed)
1041  if( margin.x < 0 )
1042  {
1043  if( effectiveSize.x > 0 && effectiveSize.y > 0 )
1044  m_gal->DrawRectangle( position - margin, position + effectiveSize );
1045  }
1046  else
1047  {
1048  m_gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
1049  }
1050 
1051  // Now add on a rounded margin (using segments) if the margin > 0
1052  if( margin.x > 0 )
1053  {
1054  m_gal->DrawSegment( position,
1055  position + VECTOR2I( r->GetWidth(), 0 ),
1056  margin.x * 2 );
1057  m_gal->DrawSegment( position + VECTOR2I( r->GetWidth(), 0 ),
1058  position + r->GetSize(),
1059  margin.x * 2 );
1060  m_gal->DrawSegment( position + r->GetSize(),
1061  position + VECTOR2I( 0, r->GetHeight() ),
1062  margin.x * 2 );
1063  m_gal->DrawSegment( position + VECTOR2I( 0, r->GetHeight() ),
1064  position,
1065  margin.x * 2 );
1066  }
1067  }
1068  break;
1069 
1070  case SH_SIMPLE:
1071  {
1072  const SHAPE_SIMPLE* poly = static_cast<const SHAPE_SIMPLE*>( shape );
1073  m_gal->DrawPolygon( poly->Vertices() );
1074 
1075  // Now add on a rounded margin (using segments) if the margin > 0
1076  if( margin.x > 0 )
1077  {
1078  for( size_t ii = 0; ii < poly->GetSegmentCount(); ++ii )
1079  {
1080  SEG seg = poly->GetSegment( ii );
1081  m_gal->DrawSegment( seg.A, seg.B, margin.x * 2 );
1082  }
1083  }
1084  }
1085  break;
1086 
1087  default:
1088  // Better not get here; we already pre-flighted the shapes...
1089  break;
1090  }
1091  }
1092  }
1093  else
1094  {
1095  // This is expensive. Avoid if possible.
1096 
1097  SHAPE_POLY_SET polySet;
1098  aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ), margin.x,
1099  bds.m_MaxError, ERROR_INSIDE );
1100  m_gal->DrawPolygon( polySet );
1101  }
1102  }
1103 
1104  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_PADS;
1105 
1106  if( ( m_pcbSettings.m_clearanceDisplayFlags & clearanceFlags ) == clearanceFlags
1107  && ( aLayer == LAYER_PAD_FR || aLayer == LAYER_PAD_BK || aLayer == LAYER_PADS_TH ) )
1108  {
1109  /* Showing the clearance area is not obvious.
1110  * - A pad can be removed from some copper layers.
1111  * - For non copper layers, what is the clearance area?
1112  * So for copper layers, the clearance area is the shape if the pad is flashed on this
1113  * layer and the hole clearance area for other copper layers.
1114  * For other layers, use the pad shape, although one can use an other criteria,
1115  * depending on the non copper layer.
1116  */
1117  int activeLayer = m_pcbSettings.GetActiveLayer();
1118  bool flashActiveLayer = IsCopperLayer( activeLayer ) ?
1119  aPad->FlashLayer( activeLayer ) : true;
1120 
1121  if( flashActiveLayer || aPad->GetDrillSize().x )
1122  {
1124  m_gal->SetIsStroke( true );
1125  m_gal->SetIsFill( false );
1127 
1128  int clearance = aPad->GetOwnClearance( m_pcbSettings.GetActiveLayer() );
1129 
1130  if( flashActiveLayer && clearance > 0 )
1131  {
1132  auto shape = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
1133 
1134  if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_SEGMENT )
1135  {
1136  const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape->Shapes()[0];
1137  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
1138  seg->GetWidth() + 2 * clearance );
1139  }
1140  else if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_CIRCLE )
1141  {
1142  const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape->Shapes()[0];
1143  m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + clearance );
1144  }
1145  else
1146  {
1147  SHAPE_POLY_SET polySet;
1148  aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ),
1149  clearance,
1150  bds.m_MaxError, ERROR_OUTSIDE );
1151  m_gal->DrawPolygon( polySet );
1152  }
1153  }
1154  else if( aPad->GetEffectiveHoleShape() && clearance > 0 )
1155  {
1156  clearance += bds.GetHolePlatingThickness();
1157 
1158  const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
1159  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
1160  seg->GetWidth() + 2 * clearance );
1161  }
1162  }
1163  }
1164 }
1165 
1166 
1167 void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
1168 {
1169  const COLOR4D& color = m_pcbSettings.GetColor( aShape, aShape->GetLayer() );
1170  bool sketch = m_pcbSettings.m_sketchGraphics;
1171  int thickness = getLineThickness( aShape->GetWidth() );
1172  VECTOR2D start( aShape->GetStart() );
1173  VECTOR2D end( aShape->GetEnd() );
1174 
1175  if( sketch )
1176  {
1177  m_gal->SetIsFill( false );
1178  m_gal->SetIsStroke( true );
1180  }
1181 
1182  m_gal->SetFillColor( color );
1184 
1185  switch( aShape->GetShape() )
1186  {
1187  case S_SEGMENT:
1188  if( sketch )
1189  {
1190  m_gal->DrawSegment( start, end, thickness );
1191  }
1192  else
1193  {
1194  m_gal->SetIsFill( true );
1195  m_gal->SetIsStroke( false );
1196 
1197  m_gal->DrawSegment( start, end, thickness );
1198  }
1199  break;
1200 
1201  case S_RECT:
1202  {
1203  std::vector<wxPoint> pts = aShape->GetRectCorners();
1204 
1205  if( sketch )
1206  {
1207  m_gal->DrawSegment( pts[0], pts[1], thickness );
1208  m_gal->DrawSegment( pts[1], pts[2], thickness );
1209  m_gal->DrawSegment( pts[2], pts[3], thickness );
1210  m_gal->DrawSegment( pts[3], pts[0], thickness );
1211  }
1212  else
1213  {
1214  m_gal->SetIsFill( true );
1215  m_gal->SetIsStroke( false );
1216 
1217  if( thickness > 0 )
1218  {
1219  m_gal->DrawSegment( pts[0], pts[1], thickness );
1220  m_gal->DrawSegment( pts[1], pts[2], thickness );
1221  m_gal->DrawSegment( pts[2], pts[3], thickness );
1222  m_gal->DrawSegment( pts[3], pts[0], thickness );
1223  }
1224 
1225  if( aShape->IsFilled() )
1226  {
1227  SHAPE_POLY_SET poly;
1228  poly.NewOutline();
1229 
1230  for( const wxPoint& pt : pts )
1231  poly.Append( pt );
1232 
1233  m_gal->DrawPolygon( poly );
1234  }
1235  }
1236  }
1237  break;
1238 
1239  case S_ARC:
1240  if( sketch )
1241  {
1242  m_gal->DrawArcSegment( start, aShape->GetRadius(),
1243  DECIDEG2RAD( aShape->GetArcAngleStart() ),
1244  DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this
1245  thickness );
1246  }
1247  else
1248  {
1249  m_gal->SetIsFill( true );
1250  m_gal->SetIsStroke( false );
1251 
1252  m_gal->DrawArcSegment( start, aShape->GetRadius(),
1253  DECIDEG2RAD( aShape->GetArcAngleStart() ),
1254  DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this
1255  thickness );
1256  }
1257  break;
1258 
1259  case S_CIRCLE:
1260  if( sketch )
1261  {
1262  m_gal->DrawCircle( start, aShape->GetRadius() - thickness / 2 );
1263  m_gal->DrawCircle( start, aShape->GetRadius() + thickness / 2 );
1264  }
1265  else
1266  {
1267  m_gal->SetIsFill( aShape->IsFilled() );
1268  m_gal->SetIsStroke( thickness > 0 );
1269  m_gal->SetLineWidth( thickness );
1270 
1271  m_gal->DrawCircle( start, aShape->GetRadius() );
1272  }
1273  break;
1274 
1275  case S_POLYGON:
1276  {
1277  SHAPE_POLY_SET& shape = const_cast<PCB_SHAPE*>( aShape )->GetPolyShape();
1278  FOOTPRINT* parentFootprint = aShape->GetParentFootprint();
1279 
1280  if( shape.OutlineCount() == 0 )
1281  break;
1282 
1283  if( parentFootprint )
1284  {
1285  m_gal->Save();
1286  m_gal->Translate( parentFootprint->GetPosition() );
1287  m_gal->Rotate( -parentFootprint->GetOrientationRadians() );
1288  }
1289 
1290  if( sketch )
1291  {
1292  for( int ii = 0; ii < shape.Outline( 0 ).SegmentCount(); ++ii )
1293  {
1294  SEG seg = shape.Outline( 0 ).Segment( ii );
1295  m_gal->DrawSegment( seg.A, seg.B, thickness );
1296  }
1297  }
1298  else
1299  {
1300  m_gal->SetIsFill( true );
1301  m_gal->SetIsStroke( false );
1302 
1303  if( thickness > 0 )
1304  {
1305  for( int ii = 0; ii < shape.Outline( 0 ).SegmentCount(); ++ii )
1306  {
1307  SEG seg = shape.Outline( 0 ).Segment( ii );
1308  m_gal->DrawSegment( seg.A, seg.B, thickness );
1309  }
1310  }
1311 
1312  if( aShape->IsFilled() )
1313  {
1314  // On Opengl, a not convex filled polygon is usually drawn by using triangles
1315  // as primitives. CacheTriangulation() can create basic triangle primitives to
1316  // draw the polygon solid shape on Opengl. GLU tesselation is much slower, so
1317  // currently we are using our tesselation.
1318  if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() )
1319  shape.CacheTriangulation();
1320 
1321  m_gal->DrawPolygon( shape );
1322  }
1323  }
1324 
1325  if( parentFootprint )
1326  m_gal->Restore();
1327  }
1328  break;
1329 
1330  case S_CURVE:
1331  if( sketch )
1332  {
1333  // Use thickness as filter value to convert the curve to polyline when the curve
1334  // is not supported
1335  m_gal->DrawCurve( VECTOR2D( aShape->GetStart() ),
1336  VECTOR2D( aShape->GetBezControl1() ),
1337  VECTOR2D( aShape->GetBezControl2() ),
1338  VECTOR2D( aShape->GetEnd() ), thickness );
1339  }
1340  else
1341  {
1342  m_gal->SetIsFill( aShape->IsFilled() );
1343  m_gal->SetIsStroke( thickness > 0 );
1344  m_gal->SetLineWidth( thickness );
1345 
1346  // Use thickness as filter value to convert the curve to polyline when the curve
1347  // is not supported
1348  m_gal->DrawCurve( VECTOR2D( aShape->GetStart() ),
1349  VECTOR2D( aShape->GetBezControl1() ),
1350  VECTOR2D( aShape->GetBezControl2() ),
1351  VECTOR2D( aShape->GetEnd() ), thickness );
1352  }
1353  break;
1354 
1355  case S_LAST:
1356  break;
1357  }
1358 }
1359 
1360 
1361 void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer )
1362 {
1363  wxString shownText( aText->GetShownText() );
1364 
1365  if( shownText.Length() == 0 )
1366  return;
1367 
1368  const COLOR4D& color = m_pcbSettings.GetColor( aText, aText->GetLayer() );
1369  VECTOR2D position( aText->GetTextPos().x, aText->GetTextPos().y );
1370 
1372  {
1373  // Outline mode
1375  }
1376  else
1377  {
1378  // Filled mode
1380  }
1381 
1383  m_gal->SetIsFill( false );
1384  m_gal->SetIsStroke( true );
1385  m_gal->SetTextAttributes( aText );
1386  m_gal->StrokeText( shownText, position, aText->GetTextAngleRadians() );
1387 }
1388 
1389 
1390 void PCB_PAINTER::draw( const FP_TEXT* aText, int aLayer )
1391 {
1392  wxString shownText( aText->GetShownText() );
1393 
1394  if( shownText.Length() == 0 )
1395  return;
1396 
1397  const COLOR4D& color = m_pcbSettings.GetColor( aText, aLayer );
1398  VECTOR2D position( aText->GetTextPos().x, aText->GetTextPos().y );
1399 
1401  {
1402  // Outline mode
1404  }
1405  else
1406  {
1407  // Filled mode
1409  }
1410 
1412  m_gal->SetIsFill( false );
1413  m_gal->SetIsStroke( true );
1414  m_gal->SetTextAttributes( aText );
1415  m_gal->StrokeText( shownText, position, aText->GetDrawRotationRadians() );
1416 
1417  // Draw the umbilical line
1418  if( aText->IsSelected() )
1419  {
1422  m_gal->DrawLine( position, aText->GetParent()->GetPosition() );
1423  }
1424 }
1425 
1426 
1427 void PCB_PAINTER::draw( const FOOTPRINT* aFootprint, int aLayer )
1428 {
1429  if( aLayer == LAYER_ANCHOR )
1430  {
1431  const COLOR4D color = m_pcbSettings.GetColor( aFootprint, aLayer );
1432 
1433  // Keep the size and width constant, not related to the scale because the anchor
1434  // is just a marker on screen
1435  double anchorSize = 5.0 / m_gal->GetWorldScale(); // 5 pixels size
1436  double anchorThickness = 1.0 / m_gal->GetWorldScale(); // 1 pixels width
1437 
1438  // Draw anchor
1439  m_gal->SetIsFill( false );
1440  m_gal->SetIsStroke( true );
1442  m_gal->SetLineWidth( anchorThickness );
1443 
1444  VECTOR2D center = aFootprint->GetPosition();
1445  m_gal->DrawLine( center - VECTOR2D( anchorSize, 0 ), center + VECTOR2D( anchorSize, 0 ) );
1446  m_gal->DrawLine( center - VECTOR2D( 0, anchorSize ), center + VECTOR2D( 0, anchorSize ) );
1447 
1448 #if 0 // For debug purpose only: draw the footing bounding box
1449  double bboxThickness = 1.0 / m_gal->GetWorldScale();
1450  m_gal->SetLineWidth( bboxThickness );
1451  EDA_RECT rect = aFootprint->GetBoundingBox();
1452  m_gal->DrawRectangle( VECTOR2D( rect.GetOrigin() ), VECTOR2D( rect.GetEnd() ) );
1453 
1454  double bboxThickness = 3.0 / m_gal->GetWorldScale();
1455  m_gal->SetLineWidth( bboxThickness );
1456  SHAPE_POLY_SET convex = aFootprint->GetBoundingHull();
1457 
1458  m_gal->DrawPolyline( convex.COutline( 0 ) );
1459 #endif
1460  }
1461 }
1462 
1463 
1464 void PCB_PAINTER::draw( const PCB_GROUP* aGroup, int aLayer )
1465 {
1466  if( aLayer == LAYER_ANCHOR )
1467  {
1468  if( aGroup->IsSelected() && !( aGroup->GetParent() && aGroup->GetParent()->IsSelected() ) )
1469  {
1470  // Selected on our own; draw enclosing box
1471  }
1472  else if( aGroup->IsEntered() )
1473  {
1474  // Entered group; draw enclosing box
1475  }
1476  else
1477  {
1478  return;
1479  }
1480 
1481  const COLOR4D color = m_pcbSettings.GetColor( aGroup, LAYER_ANCHOR );
1482 
1483  EDA_RECT bbox = aGroup->GetBoundingBox();
1486  wxPoint topLeft = bbox.GetPosition();
1487  wxPoint width = wxPoint( bbox.GetWidth(), 0 );
1488  wxPoint height = wxPoint( 0, bbox.GetHeight() );
1489 
1490  m_gal->DrawLine( topLeft, topLeft + width );
1491  m_gal->DrawLine( topLeft + width, topLeft + width + height );
1492  m_gal->DrawLine( topLeft + width + height, topLeft + height );
1493  m_gal->DrawLine( topLeft + height, topLeft );
1494 
1495  wxString name = aGroup->GetName();
1496 
1497  int ptSize = 12;
1498  int scaledSize = abs( KiROUND( m_gal->GetScreenWorldMatrix().GetScale().x * ptSize ) );
1499  int unscaledSize = Mils2iu( ptSize );
1500 
1501  // Scale by zoom a bit, but not too much
1502  int textSize = ( scaledSize + ( unscaledSize * 2 ) ) / 3;
1503  int penWidth = textSize / 10;
1504  wxPoint textOffset = wxPoint( width.x / 2, - KiROUND( textSize * 0.5 ) );
1505  wxPoint titleHeight = wxPoint( 0, KiROUND( textSize * 2.0 ) );
1506 
1507  if( !name.IsEmpty() && (int) aGroup->GetName().Length() * textSize < bbox.GetWidth() )
1508  {
1509  m_gal->DrawLine( topLeft, topLeft - titleHeight );
1510  m_gal->DrawLine( topLeft - titleHeight, topLeft + width - titleHeight );
1511  m_gal->DrawLine( topLeft + width - titleHeight, topLeft + width );
1512 
1513  m_gal->SetFontBold( false );
1514  m_gal->SetFontItalic( true );
1515  m_gal->SetFontUnderlined( false );
1519  m_gal->SetIsFill( false );
1520  m_gal->SetGlyphSize( VECTOR2D( textSize, textSize ) );
1521  m_gal->SetLineWidth( penWidth );
1522  m_gal->StrokeText( aGroup->GetName(), topLeft + textOffset, 0.0 );
1523  }
1524  }
1525 }
1526 
1527 
1528 void PCB_PAINTER::draw( const ZONE* aZone, int aLayer )
1529 {
1536  wxASSERT( IsZoneLayer( aLayer ) );
1537  PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( aLayer - LAYER_ZONE_START );
1538 
1539  if( !aZone->IsOnLayer( layer ) )
1540  return;
1541 
1542  COLOR4D color = m_pcbSettings.GetColor( aZone, layer );
1543  std::deque<VECTOR2D> corners;
1545 
1546  // Draw the outline
1547  const SHAPE_POLY_SET* outline = aZone->Outline();
1548 
1549  if( m_pcbSettings.m_zoneOutlines && outline && outline->OutlineCount() > 0 )
1550  {
1552  m_gal->SetIsFill( false );
1553  m_gal->SetIsStroke( true );
1555 
1556  // Draw each contour (main contour and holes)
1557 
1558  /* This line:
1559  * m_gal->DrawPolygon( *outline );
1560  * should be enough, but currently does not work to draw holes contours in a complex polygon
1561  * so each contour is draw as a simple polygon
1562  */
1563 
1564  // Draw the main contour
1565  m_gal->DrawPolyline( outline->COutline( 0 ) );
1566 
1567  // Draw holes
1568  int holes_count = outline->HoleCount( 0 );
1569 
1570  for( int ii = 0; ii < holes_count; ++ii )
1571  m_gal->DrawPolyline( outline->CHole( 0, ii ) );
1572 
1573  // Draw hatch lines
1574  for( const SEG& hatchLine : aZone->GetHatchLines() )
1575  m_gal->DrawLine( hatchLine.A, hatchLine.B );
1576  }
1577 
1578  // Draw the filling
1579  if( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED
1580  || displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED_OUTLINE )
1581  {
1582  const SHAPE_POLY_SET& polySet = aZone->GetFilledPolysList( layer );
1583 
1584  if( polySet.OutlineCount() == 0 ) // Nothing to draw
1585  return;
1586 
1587  // Set up drawing options
1588  int outline_thickness = 0;
1589 
1590  if( aZone->GetFilledPolysUseThickness( layer ) )
1591  outline_thickness = aZone->GetMinThickness();
1592 
1594  m_gal->SetFillColor( color );
1595  m_gal->SetLineWidth( outline_thickness );
1596 
1597  if( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED )
1598  {
1599  m_gal->SetIsFill( true );
1600  m_gal->SetIsStroke( outline_thickness > 0 );
1601  }
1602  else if( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED_OUTLINE )
1603  {
1604  m_gal->SetIsFill( false );
1605  m_gal->SetIsStroke( true );
1606  }
1607 
1608  m_gal->DrawPolygon( polySet );
1609  }
1610 }
1611 
1612 
1613 void PCB_PAINTER::draw( const DIMENSION_BASE* aDimension, int aLayer )
1614 {
1615  const COLOR4D& strokeColor = m_pcbSettings.GetColor( aDimension, aLayer );
1616 
1617  m_gal->SetStrokeColor( strokeColor );
1618  m_gal->SetIsFill( false );
1619  m_gal->SetIsStroke( true );
1620 
1622  {
1623  // Outline mode
1625  }
1626  else
1627  {
1628  // Filled mode
1629  m_gal->SetLineWidth( getLineThickness( aDimension->GetLineThickness() ) );
1630  }
1631 
1632  // Draw dimension shapes
1633  // TODO(JE) lift this out
1634  for( const std::shared_ptr<SHAPE>& shape : aDimension->GetShapes() )
1635  {
1636  switch( shape->Type() )
1637  {
1638  case SH_SEGMENT:
1639  {
1640  const SEG& seg = static_cast<const SHAPE_SEGMENT*>( shape.get() )->GetSeg();
1641  m_gal->DrawLine( seg.A, seg.B );
1642  break;
1643  }
1644 
1645  case SH_CIRCLE:
1646  {
1647  int radius = static_cast<const SHAPE_CIRCLE*>( shape.get() )->GetRadius();
1648  m_gal->DrawCircle( shape->Centre(), radius );
1649  break;
1650  }
1651 
1652  default:
1653  break;
1654  }
1655  }
1656  // Draw text
1657  PCB_TEXT& text = aDimension->Text();
1658  VECTOR2D position( text.GetTextPos().x, text.GetTextPos().y );
1659 
1661  {
1662  // Outline mode
1664  }
1665  else
1666  {
1667  // Filled mode
1669  }
1670 
1671  m_gal->SetTextAttributes( &text );
1672  m_gal->StrokeText( text.GetShownText(), position, text.GetTextAngleRadians() );
1673 }
1674 
1675 
1676 void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
1677 {
1678  const COLOR4D& strokeColor = m_pcbSettings.GetColor( aTarget, aTarget->GetLayer() );
1679  VECTOR2D position( aTarget->GetPosition() );
1680  double size, radius;
1681 
1682  m_gal->SetLineWidth( getLineThickness( aTarget->GetWidth() ) );
1683  m_gal->SetStrokeColor( strokeColor );
1684  m_gal->SetIsFill( false );
1685  m_gal->SetIsStroke( true );
1686 
1687  m_gal->Save();
1688  m_gal->Translate( position );
1689 
1690  if( aTarget->GetShape() )
1691  {
1692  // shape x
1693  m_gal->Rotate( M_PI / 4.0 );
1694  size = 2.0 * aTarget->GetSize() / 3.0;
1695  radius = aTarget->GetSize() / 2.0;
1696  }
1697  else
1698  {
1699  // shape +
1700  size = aTarget->GetSize() / 2.0;
1701  radius = aTarget->GetSize() / 3.0;
1702  }
1703 
1704  m_gal->DrawLine( VECTOR2D( -size, 0.0 ), VECTOR2D( size, 0.0 ) );
1705  m_gal->DrawLine( VECTOR2D( 0.0, -size ), VECTOR2D( 0.0, size ) );
1706  m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), radius );
1707 
1708  m_gal->Restore();
1709 }
1710 
1711 
1712 void PCB_PAINTER::draw( const PCB_MARKER* aMarker, int aLayer )
1713 {
1714  bool isShadow = aLayer == LAYER_MARKER_SHADOWS;
1715 
1716  // Don't paint shadows for invisible markers.
1717  // It would be nice to do this through layer dependencies but we can't do an "or" there today
1718  if( isShadow && aMarker->GetBoard()
1719  && !aMarker->GetBoard()->IsElementVisible( aMarker->GetColorLayer() ) )
1720  {
1721  return;
1722  }
1723 
1724  SHAPE_LINE_CHAIN polygon;
1725  aMarker->ShapeToPolygon( polygon );
1726 
1728  : aMarker->GetColorLayer() );
1729 
1730  m_gal->Save();
1731  m_gal->Translate( aMarker->GetPosition() );
1732 
1733  if( isShadow )
1734  {
1736  m_gal->SetIsStroke( true );
1737  m_gal->SetLineWidth( aMarker->MarkerScale() );
1738  }
1739  else
1740  {
1741  m_gal->SetFillColor( color );
1742  m_gal->SetIsFill( true );
1743  }
1744 
1745  m_gal->DrawPolygon( polygon );
1746  m_gal->Restore();
1747 }
1748 
1749 
1750 const double PCB_RENDER_SETTINGS::MAX_FONT_SIZE = Millimeter2iu( 10.0 );
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
virtual const SEG GetSegment(int aIndex) const override
Definition: shape_simple.h:185
virtual void DrawPolyline(const std::deque< VECTOR2D > &aPointList)
Draw a polyline.
Virtual layers for stacking zones and tracks on a given copper layer.
Filled polygons are shown.
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
Definition: track.cpp:435
Definition: track.h:343
to draw blind/buried vias
virtual void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a rectangle.
virtual wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: track.h:301
bool IsFilled() const
Definition: pcb_shape.h:96
SHAPE_SIMPLE.
Definition: shape_simple.h:43
SHAPE_POLY_SET GetBoundingHull() const
Return a bounding polygon for the shapes and pads in the footprint.
Definition: footprint.cpp:738
class ALIGNED_DIMENSION, a linear dimension (graphic item)
Definition: typeinfo.h:100
virtual void LoadColors(const COLOR_SETTINGS *aSettings) override
Definition: pcb_painter.cpp:86
class LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:101
double GetOrientationRadians() const
Definition: footprint.h:188
int OutlineCount() const
Return the number of vertices in a given outline/hole.
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
COLOR4D Inverted() const
Returns an inverted color, alpha remains the same.
Definition: color4d.h:312
int GetRadius() const
Definition: shape_circle.h:107
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
COLOR4D & Brighten(double aFactor)
Makes the color brighter by a given factor.
Definition: color4d.h:204
bool IsSelected() const
Definition: eda_item.h:172
multilayer pads, usually with holes
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
Definition: pcb_shape.h:156
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
virtual void BitmapText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle)
Draw a text using a bitmap font.
double m_zoneOpacity
Opacity override for filled zones.
Definition: pcb_painter.h:234
COLOR4D m_layerColorsHi[LAYER_ID_COUNT]
COLOR4D m_layerColors[LAYER_ID_COUNT]
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
const wxPoint & GetStart() const
Definition: track.h:116
Outlines of filled polygons are shown.
double m_TrackOpacity
Opacity override for all tracks.
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:50
to draw via holes (pad holes do not use this layer)
handle color for not plated holes (holes, not pads)
anchor of items having an anchor point (texts, footprints)
int GetSize() const
Definition: pcb_target.h:67
bool IsFlippedX() const
Return true if flip flag for the X axis is set.
virtual void SetTextAttributes(const EDA_TEXT *aText)
Loads attributes of the given text (bold/italic/underline/mirrored and so on).
int GetHolePlatingThickness() const
Pad & via drills are finish size.
class CENTER_DIMENSION, a center point marking (graphic item)
Definition: typeinfo.h:102
virtual void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle)
Draw an arc.
bool m_sketchMode[GAL_LAYER_ID_END]
Definition: pcb_painter.h:196
SHAPE_POLY_SET * Outline()
Definition: zone.h:323
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
Definition: pcb_shape.h:201
int color
Definition: DXF_plotter.cpp:60
std::vector< wxPoint > GetRectCorners() const
Definition: pcb_shape.cpp:970
int GetWidth() const
Definition: pcb_shape.h:118
double m_ViaOpacity
Opacity override for all types of via.
double GetArcAngleStart() const
function GetArcAngleStart()
Definition: pcb_shape.cpp:413
Net/netclass colors are shown on all net copper.
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:54
Net/netclass colors are shown on ratsnest lines only.
int GetWidth() const
Definition: eda_rect.h:114
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
COLOR4D WithAlpha(double aAlpha) const
Return a color with the same color, but the given alpha.
Definition: color4d.h:300
usual segment : line with rounded ends
Definition: board_item.h:50
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Return a SHAPE object representing the pad's hole.
Definition: pcbnew/pad.cpp:286
wxString GetNetname() const
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Test to see if this object is on the given layer.
Definition: zone.cpp:313
bool isImplicitNet(const wxString &aNetName)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:591
bool IsBrightened() const
Definition: eda_item.h:175
Arcs (with rounded ends)
Definition: board_item.h:52
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
bool IsNetCopperLayer(LAYER_NUM aLayer)
Checks if the given layer is "net copper", meaning it is eligible for net coloring.
const SHAPE_POLY_SET & GetFilledPolysList(PCB_LAYER_ID aLayer) const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: zone.h:655
PAD_SHAPE_T GetShape() const
Definition: pad.h:169
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
const VECTOR2I GetCenter() const
Definition: shape_circle.h:112
PCB_RENDER_SETTINGS m_pcbSettings
Definition: pcb_painter.h:295
const EDA_RECT GetBoundingBox() const override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
Definition: pcb_group.cpp:193
virtual wxPoint GetPosition() const
Definition: eda_item.h:301
An abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:81
segment with non rounded ends
Definition: board_item.h:51
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:269
bool IsTriangulationUpToDate() const
virtual wxString GetNetClassName() const
Returns the netclass of the zone.
std::set< unsigned int > m_highContrastLayers
GAL * m_gal
Instance of graphic abstraction layer that gives an interface to call commands used to draw (eg.
Definition: painter.h:101
const SEG & GetSeg() const
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
int GetEffectiveTextPenWidth(int aDefaultWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultWidth.
Definition: eda_text.cpp:157
virtual void SetLineWidth(float aLineWidth)
Set the line width.
virtual void Rotate(double aAngle)
Rotate the context.
Ratsnest lines are drawn to items on all layers (default)
TRACE_CLEARANCE_DISPLAY_MODE_T m_ShowTrackClearanceMode
How trace clearances are displayed.
virtual VECTOR2D getDrillSize(const PAD *aPad) const
Return drill size for a pad (internal units).
int GetLineThickness() const
Definition: dimension.h:187
std::map< wxString, KIGFX::COLOR4D > m_netclassColors
Overrides for specific net colors, stored as netcodes for the ratsnest to access easily.
Definition: pcb_painter.h:222
const VECTOR2I GetSize() const
Definition: shape_rect.h:124
wxPoint GetPosition() const override
Definition: pcb_target.h:61
NET_COLOR_MODE m_netColorMode
Overrides for specific netclass colors.
Definition: pcb_painter.h:219
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:53
const wxPoint GetEnd() const
Definition: eda_rect.h:108
void SetFontBold(const bool aBold)
Set bold property of current font.
RATSNEST_MODE m_RatsnestMode
Ratsnest draw mode (all layers vs only visible layers)
int GetWidth() const
Definition: pcb_target.h:70
const wxSize & GetDrillSize() const
Definition: pad.h:242
Container for display options like enable/disable some optional drawings.
PCB_LAYER_ID
A quick note on layer IDs:
Contains all the knowledge about how to draw graphical object onto any particular output device.
Definition: painter.h:57
double a
Alpha component.
Definition: color4d.h:361
bool FlashLayer(int aLayer) const
Check to see whether the pad should be flashed on the specific layer.
Definition: pcbnew/pad.cpp:202
bool IsEntered() const
Definition: eda_item.h:173
int getLineThickness(int aActualThickness) const
Get the thickness to draw for a line (e.g.
const std::vector< std::shared_ptr< SHAPE > > & GetShapes() const
Definition: dimension.h:215
double GetDrawRotationRadians() const
Definition: fp_text.h:175
bool GetDrawIndividualViaLayers() const
Definition: pcb_painter.h:174
COLOR4D m_layerColorsDark[LAYER_ID_COUNT]
int GetMinThickness() const
Definition: zone.h:247
virtual void DrawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth)
Draw a rounded segment.
void ResetTextAttributes()
Reset text attributes to default styling.
const std::vector< SEG > & GetHatchLines() const
Definition: zone.h:823
wxString GetShortNetname() const
#define NULL
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
static const double MAX_FONT_SIZE
< Maximum font size for netnames (and other dynamically shown strings)
Definition: pcb_painter.h:194
last value for this list
Definition: board_item.h:56
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Definition: track.cpp:173
wxString GetName() const
Definition: pcb_group.h:65
bool m_hiContrastEnabled
Parameters for display modes.
virtual void update()
Precalculates extra colors for layers (e.g.
Represent a set of closed polygons.
static const COLOR4D CLEAR
Definition: color4d.h:369
bool FlashLayer(int aLayer) const
Checks to see whether the via should have a pad on the specific layer.
Definition: track.cpp:494
SHAPE_LINE_CHAIN & Outline(int aIndex)
const wxPoint GetOrigin() const
Definition: eda_rect.h:106
bool IsZoneLayer(LAYER_NUM aLayer)
const VECTOR2I & GetPosition() const
Definition: shape_rect.h:116
virtual void StrokeText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle)
Draw a vector type text using preloaded Newstroke font.
const wxPoint GetPosition() const
Definition: eda_rect.h:107
void SetBackgroundColor(const COLOR4D &aColor) override
Set the background color.
Definition: pcb_painter.h:150
const wxSize & GetSize() const
Definition: pad.h:232
to draw usual through hole vias
PCB_TEXT & Text()
Definition: dimension.h:209
Non-active layers are shown normally (no high-contrast mode)
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Definition: pcb_shape.h:145
virtual BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
const wxString & GetName() const
Definition: pad.h:133
const EDA_RECT GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
Definition: pcbnew/pad.cpp:518
RATSNEST_MODE m_ratsnestDisplayMode
Definition: pcb_painter.h:214
const wxString & GetPinType() const
Definition: pad.h:145
const SHAPE_LINE_CHAIN & Vertices() const
Function Vertices()
Definition: shape_simple.h:133
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pcbnew/pad.cpp:277
virtual bool IsOpenGlEngine()
Return true if the GAL engine is a OpenGL based type.
a few functions useful in geometry calculations.
ZONE handles a list of polygons defining a copper zone.
Definition: zone.h:57
class ZONE, a copper pour area
Definition: typeinfo.h:105
An abstract shape on 2D plane.
Definition: shape.h:116
void SetTextMirrored(const bool aMirrored)
Set a mirrored property of text.
double GetRadius() const
Definition: track.cpp:922
double m_viaOpacity
Opacity override for all types of via.
Definition: pcb_painter.h:232
void SetVerticalJustify(const EDA_TEXT_VJUSTIFY_T aVerticalJustify)
Set the vertical justify for text drawing.
void SetFontItalic(bool aItalic)
Set italic property of current font.
GAL_LAYER_ID GetColorLayer() const
Definition: pcb_marker.cpp:179
int NewOutline()
Creates a new hole in a given outline.
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
int SegmentCount() const
Function SegmentCount()
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
int GetHeight() const
Definition: eda_rect.h:115
circle
Definition: shape.h:46
double m_ZoneOpacity
Opacity override for filled zone areas.
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:104
int m_clearanceDisplayFlags
How to display nets and netclasses with color overrides.
Definition: pcb_painter.h:216
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition: board.cpp:507
int GetSolderMaskMargin() const
Definition: pcbnew/pad.cpp:697
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon, int aScale=-1) const
Return the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to the...
Definition: seg.h:41
virtual size_t GetSegmentCount() const override
Definition: shape_simple.h:187
double GetTextAngleRadians() const
Definition: eda_text.h:184
double GetAngle() const
Definition: track.cpp:928
int MarkerScale() const
The scaling factor to convert polygonal shape coordinates to internal units.
Definition: marker_base.h:66
COLOR4D GetColor(int aLayer) const
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aMaxError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
SEG Segment(int aIndex)
Function Segment()
double m_trackOpacity
Opacity override for all tracks.
Definition: pcb_painter.h:231
void SetGlyphSize(const VECTOR2D aSize)
Set the font glyph size.
double m_PadOpacity
Opacity override for SMD pads and PTHs.
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:98
smd pads, front layer
virtual void Restore()
Restore the context.
std::map< int, KIGFX::COLOR4D > m_netColors
Set of net codes that should not have their ratsnest displayed.
Definition: pcb_painter.h:225
int GetWidth() const
Definition: track.h:110
virtual void DrawPolygon(const std::deque< VECTOR2D > &aPointList)
Draw a polygon.
Board layer functions and definitions.
void SetFontUnderlined(bool aUnderlined)
const char * name
Definition: DXF_plotter.cpp:59
wxSize GetSolderPasteMargin() const
Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad size,...
Definition: pcbnew/pad.cpp:742
virtual void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius)
Draw a circle using world coordinates.
FOOTPRINT * GetParentFootprint() const
Function GetParentFootprint returns a pointer to the parent footprint, or NULL if PCB_SHAPE does not ...
Definition: pcb_shape.cpp:478
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: pad.h:346
Definition: track.h:262
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
SHAPE_LINE_CHAIN.
COLOR4D & Darken(double aFactor)
Makes the color darker by a given factor.
Definition: color4d.h:221
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:150
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void LoadDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aShowPageLimits)
Load settings related to display options (high-contrast mode, full or outline modes for vias/pads/tra...
const wxPoint & GetBezControl2() const
Definition: pcb_shape.h:136
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: footprint.cpp:630
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
virtual COLOR4D GetColor(const VIEW_ITEM *aItem, int aLayer) const override
Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer using curr...
class ZONE, managed by a footprint
Definition: typeinfo.h:94
VECTOR2I A
Definition: seg.h:49
double GetAngle() const
Definition: pcb_shape.h:127
Handle the component boundary box.
Definition: eda_rect.h:42
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition: color4d.h:364
double DECIDEG2RAD(double deg)
Definition: trigo.h:235
bool IsHoleLayer(LAYER_NUM aLayer)
ZONE_DISPLAY_MODE m_ZoneDisplayMode
int GetShape() const
Definition: pcb_target.h:64
HIGH_CONTRAST_MODE m_contrastModeDisplay
Definition: pcb_painter.h:213
VIATYPE GetViaType() const
Definition: track.h:373
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:149
PCB_LAYER_ID GetActiveLayer() const
virtual bool Draw(const VIEW_ITEM *aItem, int aLayer) override
Takes an instance of VIEW_ITEM and passes it to a function that knows how to draw the item.
wxPoint GetPosition() const override
Definition: footprint.h:182
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Return an item's "own" clearance in internal units.
wxPoint Centre() const
Definition: eda_rect.h:60
const wxPoint & GetEnd() const
Definition: track.h:113
PCB_PAINTER(GAL *aGal)
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
ring
Definition: board_item.h:53
Color settings are a bit different than most of the settings objects in that there can be more than o...
double m_padOpacity
Opacity override for SMD pads and PTHs.
Definition: pcb_painter.h:233
const wxPoint & GetTextPos() const
Definition: eda_text.h:254
virtual void DrawArcSegment(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle, double aWidth)
Draw an arc segment.
virtual BOARD_ITEM * Duplicate() const
Create a copy of a of this BOARD_ITEM.
Definition: board_item.h:202
const int GetHeight() const
Definition: shape_rect.h:140
class ORTHOGONAL_DIMENSION, a linear dimension constrained to x/y
Definition: typeinfo.h:103
double GetArcAngleStart() const
Definition: track.cpp:940
void CacheTriangulation(bool aPartition=true)
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
axis-aligned rectangle
Definition: shape.h:43
Non-active layers are hidden.
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:130
virtual void Save()
Save the context.
void SetHorizontalJustify(const EDA_TEXT_HJUSTIFY_T aHorizontalJustify)
Set the horizontal justify for text drawing.
const int GetWidth() const
Definition: shape_rect.h:132
Definition: pad.h:60
virtual int getDrillShape(const PAD *aPad) const
Return drill shape of a pad.
void draw(const TRACK *aTrack, int aLayer)
double GetWorldScale() const
Get the world scale.
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
virtual void Translate(const VECTOR2D &aTranslation)
Translate the context.
virtual void DrawCurve(const VECTOR2D &startPoint, const VECTOR2D &controlPointA, const VECTOR2D &controlPointB, const VECTOR2D &endPoint, double aFilterValue=0.0)
Draw a cubic bezier spline.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
virtual wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: fp_text.cpp:410
Abstract dimension API.
Definition: dimension.h:95
int GetWidth() const
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
wxPoint GetPosition() const override
Definition: pcb_marker.h:67
Bezier Curve.
Definition: board_item.h:55
static constexpr int Millimeter2iu(double mm)
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
static const int UNCONNECTED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
Definition: netinfo.h:365
std::set< int > m_highlightNetcodes
const wxPoint & GetBezControl1() const
Definition: pcb_shape.h:133
Definition of PCB_DISPLAY_OPTIONS class.
simple polygon
Definition: shape.h:47
ZONE_DISPLAY_MODE m_zoneDisplayMode
Definition: pcb_painter.h:212
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905
Definition: track.h:83
Additional netnames layers (not associated with a PCB layer)
COLOR4D m_layerColorsSel[LAYER_ID_COUNT]
const wxSize GetSize() const
Definition: eda_rect.h:96
bool IsNetnameLayer(LAYER_NUM aLayer)
Test whether a layer is a netname layer.
NET_COLOR_MODE m_NetColorMode
How to use color overrides on specific nets and netclasses.
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:162
line segment
Definition: shape.h:44
Abstract interface for drawing on a 2D-surface.
bool GetFilledPolysUseThickness() const
Definition: zone.h:712
Container for design settings for a BOARD object.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98
VECTOR2I B
Definition: seg.h:50