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 <class_board.h>
27 #include <class_track.h>
28 #include <class_pcb_group.h>
29 #include <class_module.h>
30 #include <class_pad.h>
31 #include <class_drawsegment.h>
32 #include <class_zone.h>
33 #include <class_pcb_text.h>
34 #include <class_marker_pcb.h>
35 #include <class_dimension.h>
36 #include <class_pcb_target.h>
37 
39 #include <pcb_painter.h>
40 #include <pcb_display_options.h>
41 #include <project/net_settings.h>
43 
48 #include <geometry/shape_segment.h>
49 #include <geometry/shape_circle.h>
50 
51 using namespace KIGFX;
52 
54 {
55  m_backgroundColor = COLOR4D( 0.0, 0.0, 0.0, 1.0 );
56  m_padNumbers = true;
57  m_netNamesOnPads = true;
58  m_netNamesOnTracks = true;
59  m_netNamesOnVias = true;
60  m_zoneOutlines = true;
63  m_sketchGraphics = false;
64  m_sketchText = false;
68 
69  m_trackOpacity = 1.0;
70  m_viaOpacity = 1.0;
71  m_padOpacity = 1.0;
72  m_zoneOpacity = 1.0;
73 
74  // By default everything should be displayed as filled
75  for( unsigned int i = 0; i < arrayDim( m_sketchMode ); ++i )
76  {
77  m_sketchMode[i] = false;
78  }
79 
80  update();
81 }
82 
83 
85 {
87 
88  // Init board layers colors:
89  for( int i = 0; i < PCB_LAYER_ID_COUNT; i++ )
90  {
91  m_layerColors[i] = aSettings->GetColor( i );
92 
93  // Guard: if the alpah channel is too small, the layer is not visible.
94  // clamp it to 0.2
95  if( m_layerColors[i].a < 0.2 )
96  m_layerColors[i].a = 0.2;
97  }
98 
99  // Init specific graphic layers colors:
100  for( int i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; i++ )
101  m_layerColors[i] = aSettings->GetColor( i );
102 
103  // Default colors for specific layers (not really board layers).
104  m_layerColors[LAYER_VIAS_HOLES] = COLOR4D( 0.5, 0.4, 0.0, 0.8 );
106  m_layerColors[LAYER_VIAS_NETNAMES] = COLOR4D( 0.2, 0.2, 0.2, 0.9 );
107  m_layerColors[LAYER_PADS_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  // LAYER_PADS_TH, LAYER_NON_PLATEDHOLES, LAYER_ANCHOR ,LAYER_RATSNEST,
112  // LAYER_VIA_THROUGH, LAYER_VIA_BBLIND, LAYER_VIA_MICROVIA
113  // are initialized from aSettings
114 
115  // Netnames for copper layers
116  for( LSEQ cu = LSET::AllCuMask().CuStack(); cu; ++cu )
117  {
118  const COLOR4D lightLabel( 0.8, 0.8, 0.8, 0.7 );
119  const COLOR4D darkLabel = lightLabel.Inverted();
120  PCB_LAYER_ID layer = *cu;
121 
122  if( m_layerColors[layer].GetBrightness() > 0.5 )
123  m_layerColors[GetNetnameLayer( layer )] = darkLabel;
124  else
125  m_layerColors[GetNetnameLayer( layer )] = lightLabel;
126  }
127 
128  update();
129 }
130 
131 
133  bool aShowPageLimits )
134 {
137  m_padNumbers = aOptions.m_DisplayPadNum;
139  m_sketchText = !aOptions.m_DisplayTextFill;
142 
143  // Whether to draw tracks, vias & pads filled or as outlines
149 
150  // Net names display settings
151  switch( aOptions.m_DisplayNetNamesMode )
152  {
153  case 0:
154  m_netNamesOnPads = false;
155  m_netNamesOnTracks = false;
156  m_netNamesOnVias = false;
157  break;
158 
159  case 1:
160  m_netNamesOnPads = true;
161  m_netNamesOnTracks = false;
162  m_netNamesOnVias = true; // Follow pads or tracks? For now we chose pads....
163  break;
164 
165  case 2:
166  m_netNamesOnPads = false;
167  m_netNamesOnTracks = true;
168  m_netNamesOnVias = false; // Follow pads or tracks? For now we chose pads....
169  break;
170 
171  case 3:
172  m_netNamesOnPads = true;
173  m_netNamesOnTracks = true;
174  m_netNamesOnVias = true;
175  break;
176  }
177 
178  // Zone display settings
180 
181  // Clearance settings
182  switch( aOptions.m_ShowTrackClearanceMode )
183  {
186  break;
187 
190  break;
191 
194  break;
195 
198  break;
199 
202  break;
203  }
204 
205  if( aOptions.m_DisplayPadIsol )
206  m_clearance |= CL_PADS;
207 
209 
210  m_netColorMode = aOptions.m_NetColorMode;
211 
213 
214  m_trackOpacity = aOptions.m_TrackOpacity;
215  m_viaOpacity = aOptions.m_ViaOpacity;
216  m_padOpacity = aOptions.m_PadOpacity;
217  m_zoneOpacity = aOptions.m_ZoneOpacity;
218 
219  m_showPageLimits = aShowPageLimits;
220 }
221 
222 
223 COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const
224 {
225  int netCode = -1;
226  const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
227  const BOARD_CONNECTED_ITEM* conItem = dynamic_cast<const BOARD_CONNECTED_ITEM*> ( aItem );
228 
229  // Zones should pull from the copper layer
230  if( item && item->Type() == PCB_ZONE_AREA_T && IsZoneLayer( aLayer ) )
231  aLayer = aLayer - LAYER_ZONE_START;
232 
233  // Make items invisible in "other layers hidden" contrast mode
234  if( m_contrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN && m_activeLayers.count( aLayer ) == 0 )
235  return COLOR4D::CLEAR;
236 
237  // Hide net names in "dimmed" contrast mode
239  && m_activeLayers.count( aLayer ) == 0 )
240  return COLOR4D::CLEAR;
241 
242  // Normal path: get the layer base color
243  COLOR4D color = m_layerColors[aLayer];
244 
245  if( item )
246  {
247  // Selection disambiguation
248  if( item->IsBrightened() )
249  return color.Brightened( m_selectFactor ).WithAlpha( 0.8 );
250 
251  // Don't let pads that *should* be NPTHs get lost
252  if( item->Type() == PCB_PAD_T && dyn_cast<const D_PAD*>( item )->PadShouldBeNPTH() )
253  aLayer = LAYER_MOD_TEXT_INVISIBLE;
254 
255  if( item->IsSelected() )
256  color = m_layerColorsSel[aLayer];
257  }
258  else
259  {
260  return m_layerColors[aLayer];
261  }
262 
263  // Try to obtain the netcode for the item
264  if( conItem )
265  netCode = conItem->GetNetCode();
266 
268  bool highlighted = m_highlightEnabled && m_highlightNetcodes.count( netCode );
269  bool activeLayer = m_activeLayers.count( aLayer );
270 
271  // Apply net color overrides
272  if( conItem && m_netColorMode == NET_COLOR_MODE::ALL && IsNetCopperLayer( aLayer ) )
273  {
274  COLOR4D netColor = COLOR4D::UNSPECIFIED;
275 
276  auto ii = m_netColors.find( netCode );
277 
278  if( ii != m_netColors.end() )
279  netColor = ii->second;
280 
281  if( netColor == COLOR4D::UNSPECIFIED )
282  {
283  auto jj = m_netclassColors.find( conItem->GetNetClassName() );
284 
285  if( jj != m_netclassColors.end() )
286  netColor = jj->second;
287  }
288 
289  if( netColor == COLOR4D::UNSPECIFIED )
290  netColor = color;
291 
292  if( item->IsSelected() )
293  {
294  // Selection brightening overrides highlighting
295  netColor.Brighten( m_selectFactor );
296  }
297  else if( m_highlightEnabled )
298  {
299  // Highlight brightens objects on all layers and darkens everything else for contrast
300  if( highlighted )
301  netColor.Brighten( m_highlightFactor );
302  else
303  netColor.Darken( 1.0 - m_highlightFactor );
304  }
305 
306  color = netColor;
307  }
308  else if( !item->IsSelected() && m_highlightEnabled )
309  {
310  // Single net highlight mode
311  color = m_highlightNetcodes.count( netCode ) ? m_layerColorsHi[aLayer]
312  : m_layerColorsDark[aLayer];
313  }
314 
315  // Apply high-contrast dimming
316  if( dimmedMode && !activeLayer && !highlighted )
318 
319  // For vias, some layers depend on other layers in high contrast mode
320  if( m_hiContrastEnabled && !item->IsSelected() && item->Type() == PCB_VIA_T &&
321  ( aLayer == LAYER_VIAS_HOLES ||
322  aLayer == LAYER_VIA_THROUGH ||
323  aLayer == LAYER_VIA_MICROVIA ||
324  aLayer == LAYER_VIA_BBLIND ) )
325  {
326  const VIA* via = static_cast<const VIA*>( item );
327  const BOARD* pcb = static_cast<const BOARD*>( item->GetParent() );
328  bool viaActiveLayer = false;
329 
330  for( int layer : m_activeLayers )
331  {
332  auto lay_id = static_cast<PCB_LAYER_ID>( layer );
333  viaActiveLayer |= via->IsOnLayer( lay_id ) && pcb->IsLayerVisible( lay_id );
334  }
335 
336  if( !viaActiveLayer )
337  color.Darken( 1.0 - m_highlightFactor );
338  }
339 
340  // Apply per-type opacity overrides
341  if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
342  color.a *= m_trackOpacity;
343  else if( item->Type() == PCB_VIA_T )
344  color.a *= m_viaOpacity;
345  else if( item->Type() == PCB_PAD_T )
346  color.a *= m_padOpacity;
347  else if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T )
348  color.a *= m_zoneOpacity;
349 
350  // No special modificators enabled
351  return color;
352 }
353 
354 
356  PAINTER( aGal )
357 {
358 }
359 
360 
361 int PCB_PAINTER::getLineThickness( int aActualThickness ) const
362 {
363  // if items have 0 thickness, draw them with the outline
364  // width, otherwise respect the set value (which, no matter
365  // how small will produce something)
366  if( aActualThickness == 0 )
368 
369  return aActualThickness;
370 }
371 
372 
373 int PCB_PAINTER::getDrillShape( const D_PAD* aPad ) const
374 {
375  return aPad->GetDrillShape();
376 }
377 
378 
380 {
381  return VECTOR2D( aPad->GetDrillSize() );
382 }
383 
384 
385 int PCB_PAINTER::getDrillSize( const VIA* aVia ) const
386 {
387  return aVia->GetDrillValue();
388 }
389 
390 
391 bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
392 {
393  const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
394 
395  if( !item )
396  return false;
397 
398  // the "cast" applied in here clarifies which overloaded draw() is called
399  switch( item->Type() )
400  {
401  case PCB_TRACE_T:
402  draw( static_cast<const TRACK*>( item ), aLayer );
403  break;
404 
405  case PCB_ARC_T:
406  draw( static_cast<const ARC*>( item ), aLayer );
407  break;
408 
409  case PCB_VIA_T:
410  draw( static_cast<const VIA*>( item ), aLayer );
411  break;
412 
413  case PCB_PAD_T:
414  draw( static_cast<const D_PAD*>( item ), aLayer );
415  break;
416 
417  case PCB_LINE_T:
418  case PCB_MODULE_EDGE_T:
419  draw( static_cast<const DRAWSEGMENT*>( item ), aLayer );
420  break;
421 
422  case PCB_TEXT_T:
423  draw( static_cast<const TEXTE_PCB*>( item ), aLayer );
424  break;
425 
426  case PCB_MODULE_TEXT_T:
427  draw( static_cast<const TEXTE_MODULE*>( item ), aLayer );
428  break;
429 
430  case PCB_MODULE_T:
431  draw( static_cast<const MODULE*>( item ), aLayer );
432  break;
433 
434  case PCB_GROUP_T:
435  draw( static_cast<const PCB_GROUP*>( item ), aLayer );
436  break;
437 
438  case PCB_ZONE_AREA_T:
439  draw( static_cast<const ZONE_CONTAINER*>( item ), aLayer );
440  break;
441 
443  draw( static_cast<const ZONE_CONTAINER*>( item ), aLayer );
444  break;
445 
446  case PCB_DIM_ALIGNED_T:
447  case PCB_DIM_CENTER_T:
449  case PCB_DIM_LEADER_T:
450  draw( static_cast<const DIMENSION*>( item ), aLayer );
451  break;
452 
453  case PCB_TARGET_T:
454  draw( static_cast<const PCB_TARGET*>( item ) );
455  break;
456 
457  case PCB_MARKER_T:
458  draw( static_cast<const MARKER_PCB*>( item ) );
459  break;
460 
461  default:
462  // Painter does not know how to draw the object
463  return false;
464  }
465 
466  return true;
467 }
468 
469 
470 void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
471 {
472  VECTOR2D start( aTrack->GetStart() );
473  VECTOR2D end( aTrack->GetEnd() );
474  int width = aTrack->GetWidth();
475 
477  {
478  // If there is a net name - display it on the track
479  if( aTrack->GetNetCode() > NETINFO_LIST::UNCONNECTED )
480  {
481  VECTOR2D line = ( end - start );
482  double length = line.EuclideanNorm();
483 
484  // Check if the track is long enough to have a netname displayed
485  if( length < 10 * width )
486  return;
487 
488  const wxString& netName = UnescapeString( aTrack->GetShortNetname() );
489  VECTOR2D textPosition = start + line / 2.0; // center of the track
490 
491  double textOrientation;
492 
493  if( end.y == start.y ) // horizontal
494  textOrientation = 0;
495  else if( end.x == start.x ) // vertical
496  textOrientation = M_PI / 2;
497  else
498  textOrientation = -atan( line.y / line.x );
499 
500  double textSize = width;
501 
502  m_gal->SetIsStroke( true );
503  m_gal->SetIsFill( false );
505  m_gal->SetLineWidth( width / 10.0 );
506  m_gal->SetFontBold( false );
507  m_gal->SetFontItalic( false );
508  m_gal->SetTextMirrored( false );
509  m_gal->SetGlyphSize( VECTOR2D( textSize * 0.7, textSize * 0.7 ) );
512  m_gal->BitmapText( netName, textPosition, textOrientation );
513  }
514  }
515  else if( IsCopperLayer( aLayer ) )
516  {
517  // Draw a regular track
518  COLOR4D color = m_pcbSettings.GetColor( aTrack, aLayer );
519  bool outline_mode = m_pcbSettings.m_sketchMode[LAYER_TRACKS];
522  m_gal->SetIsStroke( outline_mode );
523  m_gal->SetIsFill( not outline_mode );
525 
526  m_gal->DrawSegment( start, end, width );
527 
528  // Clearance lines
529  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING | PCB_RENDER_SETTINGS::CL_TRACKS;
530 
531  if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags )
532  {
534  m_gal->SetIsFill( false );
535  m_gal->SetIsStroke( true );
537  m_gal->DrawSegment( start, end,
538  width + aTrack->GetClearance( ToLAYER_ID( aLayer ) ) * 2 );
539  }
540  }
541 }
542 
543 
544 void PCB_PAINTER::draw( const ARC* aArc, int aLayer )
545 {
546  VECTOR2D center( aArc->GetCenter() );
547  int width = aArc->GetWidth();
548 
549  if( IsCopperLayer( aLayer ) )
550  {
551  // Draw a regular track
552  COLOR4D color = m_pcbSettings.GetColor( aArc, aLayer );
553  bool outline_mode = m_pcbSettings.m_sketchMode[LAYER_TRACKS];
556  m_gal->SetIsStroke( outline_mode );
557  m_gal->SetIsFill( not outline_mode );
559 
560  auto radius = aArc->GetRadius();
561  auto start_angle = DECIDEG2RAD( aArc->GetArcAngleStart() );
562  auto angle = DECIDEG2RAD( aArc->GetAngle() );
563 
564  m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width );
565 
566  // Clearance lines
567  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING | PCB_RENDER_SETTINGS::CL_TRACKS;
568 
569  if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags )
570  {
572  m_gal->SetIsFill( false );
573  m_gal->SetIsStroke( true );
575 
576  m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle,
577  width + aArc->GetClearance( ToLAYER_ID( aLayer ) ) * 2 );
578  }
579  }
580 }
581 
582 
583 void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
584 {
585  VECTOR2D center( aVia->GetStart() );
586  double radius = 0.0;
587 
588  // Draw description layer
589  if( IsNetnameLayer( aLayer ) )
590  {
591  VECTOR2D position( center );
592 
593  // Is anything that we can display enabled?
595  {
596  bool displayNetname = ( !aVia->GetNetname().empty() );
597  double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
598  double size = aVia->GetWidth();
599 
600  // Font size limits
601  if( size > maxSize )
602  size = maxSize;
603 
604  m_gal->Save();
605  m_gal->Translate( position );
606 
607  // Default font settings
610 
611  // Set the text position to the pad shape position (the pad position is not the best place)
612  VECTOR2D textpos( 0.0, 0.0 );
613 
614  if( displayNetname )
615  {
616  wxString netname = UnescapeString( aVia->GetShortNetname() );
617  // calculate the size of net name text:
618  double tsize = 1.5 * size / netname.Length();
619  tsize = std::min( tsize, size );
620  // Use a smaller text size to handle interline, pen size..
621  tsize *= 0.7;
622  VECTOR2D namesize( tsize, tsize );
623 
624  m_gal->SetGlyphSize( namesize );
625  m_gal->SetLineWidth( namesize.x / 12.0 );
626  m_gal->BitmapText( netname, textpos, 0.0 );
627  }
628 
629 
630  m_gal->Restore();
631  }
632  return;
633  }
634 
635  // Choose drawing settings depending on if we are drawing via's pad or hole
636  if( aLayer == LAYER_VIAS_HOLES )
637  radius = getDrillSize( aVia ) / 2.0;
638  else
639  radius = aVia->GetWidth() / 2.0;
640 
643  if( IsCopperLayer( aLayer ) && !aVia->IsPadOnLayer( aLayer ) )
644  radius = getDrillSize(aVia) / 2.0 ;
645 
646  bool sketchMode = false;
647  COLOR4D color = m_pcbSettings.GetColor( aVia, aLayer );
648 
649  switch( aVia->GetViaType() )
650  {
651  case VIATYPE::THROUGH:
653  break;
654 
657  break;
658 
659  case VIATYPE::MICROVIA:
661  break;
662 
663  default:
664  wxASSERT( false );
665  break;
666  }
667 
668  m_gal->SetIsFill( !sketchMode );
669  m_gal->SetIsStroke( sketchMode );
670 
671  if( sketchMode )
672  {
673  // Outline mode
676  }
677  else
678  {
679  // Filled mode
681  }
682 
683  if( ( aVia->GetViaType() == VIATYPE::BLIND_BURIED || aVia->GetViaType() == VIATYPE::MICROVIA )
684  && aLayer != LAYER_VIAS_HOLES
686  {
687  // Outer circles of blind/buried and micro-vias are drawn in a special way to indicate the
688  // top and bottom layers
689  PCB_LAYER_ID layerTop, layerBottom;
690  aVia->LayerPair( &layerTop, &layerBottom );
691 
692  if( !sketchMode )
693  m_gal->SetLineWidth( ( aVia->GetWidth() - aVia->GetDrillValue() ) / 2.0 );
694 
695  if( aLayer == layerTop )
696  m_gal->DrawArc( center, radius, 0.0, M_PI / 2.0 );
697 
698  else if( aLayer == layerBottom )
699  m_gal->DrawArc( center, radius, M_PI, 3.0 * M_PI / 2.0 );
700 
701  else if( aLayer == LAYER_VIA_BBLIND || aLayer == LAYER_VIA_MICROVIA )
702  {
703  m_gal->DrawArc( center, radius, M_PI / 2.0, M_PI );
704  m_gal->DrawArc( center, radius, 3.0 * M_PI / 2.0, 2.0 * M_PI );
705  }
706  }
707  else
708  {
709  // Draw the outer circles of normal vias and the holes for all vias
710  m_gal->DrawCircle( center, radius );
711  }
712 
713  // Clearance lines
714  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING | PCB_RENDER_SETTINGS::CL_VIAS;
715 
716  if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags
717  && aLayer != LAYER_VIAS_HOLES )
718  {
720  m_gal->SetIsFill( false );
721  m_gal->SetIsStroke( true );
723  m_gal->DrawCircle( center, radius + aVia->GetClearance( aVia->GetLayer() ) );
724  }
725 }
726 
727 
728 void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
729 {
730  // Draw description layer
731  if( IsNetnameLayer( aLayer ) )
732  {
733  // Is anything that we can display enabled?
735  {
736  bool displayNetname = ( m_pcbSettings.m_netNamesOnPads && !aPad->GetNetname().empty() );
737  EDA_RECT padBBox = aPad->GetBoundingBox();
738  VECTOR2D position = padBBox.Centre();
739  VECTOR2D padsize = VECTOR2D( padBBox.GetSize() );
740 
741  if( aPad->GetShape() != PAD_SHAPE_CUSTOM )
742  {
743  // Don't allow a 45ยบ rotation to bloat a pad's bounding box unnecessarily
744  double limit = std::min( aPad->GetSize().x, aPad->GetSize().y ) * 1.1;
745 
746  if( padsize.x > limit && padsize.y > limit )
747  {
748  padsize.x = limit;
749  padsize.y = limit;
750  }
751  }
752 
753  double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
754  double size = padsize.y;
755 
756  m_gal->Save();
757  m_gal->Translate( position );
758 
759  // Keep the size ratio for the font, but make it smaller
760  if( padsize.x < padsize.y )
761  {
762  m_gal->Rotate( DECIDEG2RAD( -900.0 ) );
763  size = padsize.x;
764  std::swap( padsize.x, padsize.y );
765  }
766 
767  // Font size limits
768  if( size > maxSize )
769  size = maxSize;
770 
771  // Default font settings
774  m_gal->SetFontBold( false );
775  m_gal->SetFontItalic( false );
776  m_gal->SetTextMirrored( false );
778  m_gal->SetIsStroke( true );
779  m_gal->SetIsFill( false );
780 
781  // We have already translated the GAL to be centered at the center of the pad's
782  // bounding box
783  VECTOR2D textpos( 0.0, 0.0 );
784 
785  // Divide the space, to display both pad numbers and netnames and set the Y text
786  // position to display 2 lines
787  if( displayNetname && m_pcbSettings.m_padNumbers )
788  {
789  size = size / 2.0;
790  textpos.y = size / 2.0;
791  }
792 
793  if( displayNetname )
794  {
795  wxString netname = UnescapeString( aPad->GetShortNetname() );
796  // calculate the size of net name text:
797  double tsize = 1.5 * padsize.x / netname.Length();
798  tsize = std::min( tsize, size );
799  // Use a smaller text size to handle interline, pen size..
800  tsize *= 0.7;
801  VECTOR2D namesize( tsize, tsize );
802 
803  m_gal->SetGlyphSize( namesize );
804  m_gal->SetLineWidth( namesize.x / 12.0 );
805  m_gal->BitmapText( netname, textpos, 0.0 );
806  }
807 
809  {
810  const wxString& padName = aPad->GetName();
811  textpos.y = -textpos.y;
812  double tsize = 1.5 * padsize.x / padName.Length();
813  tsize = std::min( tsize, size );
814  // Use a smaller text size to handle interline, pen size..
815  tsize *= 0.7;
816  tsize = std::min( tsize, size );
817  VECTOR2D numsize( tsize, tsize );
818 
819  m_gal->SetGlyphSize( numsize );
820  m_gal->SetLineWidth( numsize.x / 12.0 );
821  m_gal->BitmapText( padName, textpos, 0.0 );
822  }
823 
824  m_gal->Restore();
825  }
826  return;
827  }
828 
829  // Pad drawing
830  COLOR4D color;
831 
832  // Pad hole color is pad-type-specific: the background color for plated holes and the
833  // pad color for NPTHs. Note the extra check for "should be" NPTHs to keep mis-marked
834  // holes with no annular ring from getting "lost" in the background.
835  if( ( aLayer == LAYER_PADS_PLATEDHOLES ) && !aPad->PadShouldBeNPTH() )
837  else
838  color = m_pcbSettings.GetColor( aPad, aLayer );
839 
841  {
842  // Outline mode
843  m_gal->SetIsFill( false );
844  m_gal->SetIsStroke( true );
847  }
848  else
849  {
850  // Filled mode
851  m_gal->SetIsFill( true );
852  m_gal->SetIsStroke( false );
854  }
855 
856  // Choose drawing settings depending on if we are drawing a pad itself or a hole
857  if( aLayer == LAYER_PADS_PLATEDHOLES || aLayer == LAYER_NON_PLATEDHOLES )
858  {
859  const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
860 
861  if( seg->GetSeg().A == seg->GetSeg().B ) // Circular hole
862  m_gal->DrawCircle( seg->GetSeg().A, seg->GetWidth()/2 );
863  else
864  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() );
865  }
866  else
867  {
868  wxSize pad_size = aPad->GetSize();
869  wxSize margin;
870 
871  switch( aLayer )
872  {
873  case F_Mask:
874  case B_Mask:
875  margin.x = margin.y = aPad->GetSolderMaskMargin();
876  break;
877 
878  case F_Paste:
879  case B_Paste:
880  margin = aPad->GetSolderPasteMargin();
881  break;
882 
883  default:
884  margin.x = margin.y = 0;
885  break;
886  }
887 
888  if( margin.x != margin.y )
889  {
890  const_cast<D_PAD*>( aPad )->SetSize( pad_size + margin + margin );
891  margin.x = margin.y = 0;
892  }
893 
894  // Once we change the size of the pad, check that there is still a pad remaining
895  if( !aPad->GetSize().x || !aPad->GetSize().y )
896  {
897  // Reset the stored pad size
898  if( aPad->GetSize() != pad_size )
899  const_cast<D_PAD*>( aPad )->SetSize( pad_size );
900 
901  return;
902  }
903 
904  const std::shared_ptr<SHAPE_COMPOUND> shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
905 
906  if( shapes && shapes->Size() == 1 && shapes->Shapes()[0]->Type() == SH_SEGMENT )
907  {
908  const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shapes->Shapes()[0];
909  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() + 2 * margin.x );
910  }
911  else if( shapes && shapes->Size() == 1 && shapes->Shapes()[0]->Type() == SH_CIRCLE )
912  {
913  const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shapes->Shapes()[0];
914  m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + margin.x );
915  }
916  else
917  {
918  SHAPE_POLY_SET polySet;
919  aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ), margin.x );
920  m_gal->DrawPolygon( polySet );
921  }
922 
923  if( aPad->GetSize() != pad_size )
924  const_cast<D_PAD*>( aPad )->SetSize( pad_size );
925  }
926 
927  // Clearance outlines
928  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_PADS;
929 
930  if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags
931  && ( aLayer == LAYER_PAD_FR
932  || aLayer == LAYER_PAD_BK
933  || aLayer == LAYER_PADS_TH ) )
934  {
936  m_gal->SetIsStroke( true );
937  m_gal->SetIsFill( false );
939  int clearance = aPad->GetClearance( aPad->GetLayer() );
940 
941  const std::shared_ptr<SHAPE_COMPOUND> shapes =
942  std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
943 
944  if( shapes && shapes->Size() == 1 && shapes->Shapes()[0]->Type() == SH_SEGMENT )
945  {
946  const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shapes->Shapes()[0];
947  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() + 2 * clearance );
948  }
949  else if( shapes && shapes->Size() == 1 && shapes->Shapes()[0]->Type() == SH_CIRCLE )
950  {
951  const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shapes->Shapes()[0];
952  m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + clearance );
953  }
954  else
955  {
956  SHAPE_POLY_SET polySet;
957  aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ), clearance );
958  m_gal->DrawPolygon( polySet );
959  }
960  }
961 }
962 
963 
964 void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
965 {
966  const COLOR4D& color = m_pcbSettings.GetColor( aSegment, aSegment->GetLayer() );
967  bool sketch = m_pcbSettings.m_sketchGraphics;
968  int thickness = getLineThickness( aSegment->GetWidth() );
969  VECTOR2D start( aSegment->GetStart() );
970  VECTOR2D end( aSegment->GetEnd() );
971 
972  m_gal->SetIsFill( !sketch );
973  m_gal->SetIsStroke( sketch );
977 
978  switch( aSegment->GetShape() )
979  {
980  case S_SEGMENT:
981  m_gal->DrawSegment( start, end, thickness );
982  break;
983 
984  case S_RECT:
985  {
986  std::vector<wxPoint> pts = aSegment->GetRectCorners();
987 
988  if( aSegment->GetWidth() > 0 )
989  {
990  m_gal->DrawSegment( pts[0], pts[1], thickness );
991  m_gal->DrawSegment( pts[1], pts[2], thickness );
992  m_gal->DrawSegment( pts[2], pts[3], thickness );
993  m_gal->DrawSegment( pts[3], pts[0], thickness );
994  }
995  else
996  {
997  SHAPE_POLY_SET poly;
998  poly.NewOutline();
999 
1000  for( const wxPoint& pt : pts )
1001  poly.Append( pt );
1002 
1003  m_gal->DrawPolygon( poly );
1004  }
1005  }
1006  break;
1007 
1008  case S_ARC:
1009  m_gal->DrawArcSegment( start, aSegment->GetRadius(),
1010  DECIDEG2RAD( aSegment->GetArcAngleStart() ),
1011  DECIDEG2RAD( aSegment->GetArcAngleStart() + aSegment->GetAngle() ), // Change this
1012  thickness );
1013  break;
1014 
1015  case S_CIRCLE:
1016  if( sketch )
1017  {
1018  m_gal->DrawCircle( start, aSegment->GetRadius() - thickness / 2 );
1019  m_gal->DrawCircle( start, aSegment->GetRadius() + thickness / 2 );
1020  }
1021  else
1022  {
1023  m_gal->SetLineWidth( thickness );
1024  m_gal->SetIsFill( aSegment->GetWidth() == 0 );
1025  m_gal->SetIsStroke( aSegment->GetWidth() > 0 );
1026  m_gal->DrawCircle( start, aSegment->GetRadius() );
1027  }
1028  break;
1029 
1030  case S_POLYGON:
1031  {
1032  SHAPE_POLY_SET& shape = const_cast<DRAWSEGMENT*>( aSegment )->GetPolyShape();
1033 
1034  if( shape.OutlineCount() == 0 )
1035  break;
1036 
1037  // On Opengl, a not convex filled polygon is usually drawn by using triangles as primitives.
1038  // CacheTriangulation() can create basic triangle primitives to draw the polygon solid shape
1039  // on Opengl.
1040  // GLU tesselation is much slower, so currently we are using our tesselation.
1041  if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() )
1042  {
1043  shape.CacheTriangulation();
1044  }
1045 
1046  m_gal->Save();
1047 
1048  if( MODULE* module = aSegment->GetParentModule() )
1049  {
1050  m_gal->Translate( module->GetPosition() );
1051  m_gal->Rotate( -module->GetOrientationRadians() );
1052  }
1053 
1054  m_gal->SetLineWidth( thickness );
1055 
1056  if( sketch )
1057  m_gal->SetIsFill( false );
1058  else
1059  m_gal->SetIsFill( aSegment->IsPolygonFilled() );
1060 
1061  m_gal->SetIsStroke( true );
1062  m_gal->DrawPolygon( shape );
1063 
1064  m_gal->Restore();
1065  break;
1066  }
1067 
1068  case S_CURVE:
1069  m_gal->SetIsFill( false );
1070  m_gal->SetIsStroke( true );
1071  m_gal->SetLineWidth( thickness );
1072  // Use thickness as filter value to convert the curve to polyline
1073  // when the curve is not supported
1074  m_gal->DrawCurve( VECTOR2D( aSegment->GetStart() ),
1075  VECTOR2D( aSegment->GetBezControl1() ),
1076  VECTOR2D( aSegment->GetBezControl2() ),
1077  VECTOR2D( aSegment->GetEnd() ), thickness );
1078  break;
1079 
1080  case S_LAST:
1081  break;
1082  }
1083 }
1084 
1085 
1086 void PCB_PAINTER::draw( const TEXTE_PCB* aText, int aLayer )
1087 {
1088  wxString shownText( aText->GetShownText() );
1089 
1090  if( shownText.Length() == 0 )
1091  return;
1092 
1093  const COLOR4D& color = m_pcbSettings.GetColor( aText, aText->GetLayer() );
1094  VECTOR2D position( aText->GetTextPos().x, aText->GetTextPos().y );
1095 
1097  {
1098  // Outline mode
1100  }
1101  else
1102  {
1103  // Filled mode
1105  }
1106 
1108  m_gal->SetIsFill( false );
1109  m_gal->SetIsStroke( true );
1110  m_gal->SetTextAttributes( aText );
1111  m_gal->StrokeText( shownText, position, aText->GetTextAngleRadians() );
1112 }
1113 
1114 
1115 void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer )
1116 {
1117  wxString shownText( aText->GetShownText() );
1118 
1119  if( shownText.Length() == 0 )
1120  return;
1121 
1122  const COLOR4D& color = m_pcbSettings.GetColor( aText, aLayer );
1123  VECTOR2D position( aText->GetTextPos().x, aText->GetTextPos().y );
1124 
1126  {
1127  // Outline mode
1129  }
1130  else
1131  {
1132  // Filled mode
1134  }
1135 
1137  m_gal->SetIsFill( false );
1138  m_gal->SetIsStroke( true );
1139  m_gal->SetTextAttributes( aText );
1140  m_gal->StrokeText( shownText, position, aText->GetDrawRotationRadians() );
1141 
1142  // Draw the umbilical line
1143  if( aText->IsSelected() )
1144  {
1146  m_gal->SetStrokeColor( COLOR4D( 0.0, 0.0, 1.0, 1.0 ) );
1147  m_gal->DrawLine( position, aText->GetParent()->GetPosition() );
1148  }
1149 }
1150 
1151 
1152 void PCB_PAINTER::draw( const MODULE* aModule, int aLayer )
1153 {
1154  if( aLayer == LAYER_ANCHOR )
1155  {
1156  const COLOR4D color = m_pcbSettings.GetColor( aModule, aLayer );
1157 
1158  // Keep the size and width constant, not related to the scale because the anchor
1159  // is just a marker on screen
1160  double anchorSize = 5.0 / m_gal->GetWorldScale(); // 5 pixels size
1161  double anchorThickness = 1.0 / m_gal->GetWorldScale(); // 1 pixels width
1162 
1163  // Draw anchor
1164  m_gal->SetIsFill( false );
1165  m_gal->SetIsStroke( true );
1167  m_gal->SetLineWidth( anchorThickness );
1168 
1169  VECTOR2D center = aModule->GetPosition();
1170  m_gal->DrawLine( center - VECTOR2D( anchorSize, 0 ), center + VECTOR2D( anchorSize, 0 ) );
1171  m_gal->DrawLine( center - VECTOR2D( 0, anchorSize ), center + VECTOR2D( 0, anchorSize ) );
1172 
1173 #if 0 // For debug purpose only: draw the footing bounding box
1174  double bboxThickness = 1.0 / m_gal->GetWorldScale();
1175  m_gal->SetLineWidth( bboxThickness );
1176  EDA_RECT rect = aModule->GetBoundingBoxBase();
1177  m_gal->DrawRectangle( VECTOR2D( rect.GetOrigin() ), VECTOR2D( rect.GetEnd() ) );
1178 #endif
1179  }
1180 }
1181 
1182 
1183 void PCB_PAINTER::draw( const PCB_GROUP* aGroup, int aLayer )
1184 {
1185  if( aLayer == LAYER_ANCHOR )
1186  {
1187  const COLOR4D color = m_pcbSettings.GetColor( aGroup, LAYER_ANCHOR );
1188 
1189  EDA_RECT bbox = aGroup->GetBoundingBox();
1192  wxPoint topLeft = bbox.GetPosition();
1193  wxPoint width = wxPoint( bbox.GetWidth(), 0 );
1194  wxPoint height = wxPoint( 0, bbox.GetHeight() );
1195 
1196  m_gal->DrawLine( topLeft, topLeft + width );
1197  m_gal->DrawLine( topLeft + width, topLeft + width + height );
1198  m_gal->DrawLine( topLeft + width + height, topLeft + height );
1199  m_gal->DrawLine( topLeft + height, topLeft );
1200 
1201  wxString name = aGroup->GetName();
1202 
1203  int ptSize = 12;
1204  int scaledSize = abs( KiROUND( m_gal->GetScreenWorldMatrix().GetScale().x * ptSize ) );
1205  int unscaledSize = Mils2iu( ptSize );
1206 
1207  // Scale by zoom a bit, but not too much
1208  int textSize = ( scaledSize + unscaledSize ) / 2;
1209  int penWidth = textSize / 12;
1210  wxPoint textOffset = wxPoint( width.x / 2, - KiROUND( textSize * 0.6 ) );
1211  wxPoint titleHeight = wxPoint( 0, KiROUND( textSize * 2.0 ) );
1212 
1213  if( !name.IsEmpty() && (int) aGroup->GetName().Length() * textSize < bbox.GetWidth() )
1214  {
1215  m_gal->DrawLine( topLeft, topLeft - titleHeight );
1216  m_gal->DrawLine( topLeft - titleHeight, topLeft + width - titleHeight );
1217  m_gal->DrawLine( topLeft + width - titleHeight, topLeft + width );
1218 
1221  m_gal->SetIsFill( false );
1222  m_gal->SetGlyphSize( VECTOR2D( textSize, textSize ) );
1223  m_gal->SetLineWidth( penWidth );
1224  m_gal->StrokeText( aGroup->GetName(), topLeft + textOffset, 0.0 );
1225  }
1226  }
1227 }
1228 
1229 
1230 void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone, int aLayer )
1231 {
1238  wxASSERT( IsZoneLayer( aLayer ) );
1239  PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( aLayer - LAYER_ZONE_START );
1240 
1241  if( !aZone->IsOnLayer( layer ) )
1242  return;
1243 
1244  COLOR4D color = m_pcbSettings.GetColor( aZone, layer );
1245  std::deque<VECTOR2D> corners;
1247 
1248  // Draw the outline
1249  const SHAPE_POLY_SET* outline = aZone->Outline();
1250 
1251  if( m_pcbSettings.m_zoneOutlines && outline && outline->OutlineCount() > 0 )
1252  {
1254  m_gal->SetIsFill( false );
1255  m_gal->SetIsStroke( true );
1257 
1258  // Draw each contour (main contour and holes)
1259 
1260  /* This line:
1261  * m_gal->DrawPolygon( *outline );
1262  * should be enough, but currently does not work to draw holes contours in a complex polygon
1263  * so each contour is draw as a simple polygon
1264  */
1265 
1266  // Draw the main contour
1267  m_gal->DrawPolyline( outline->COutline( 0 ) );
1268 
1269  // Draw holes
1270  int holes_count = outline->HoleCount( 0 );
1271 
1272  for( int ii = 0; ii < holes_count; ++ii )
1273  m_gal->DrawPolyline( outline->CHole( 0, ii ) );
1274 
1275  // Draw hatch lines
1276  for( const SEG& hatchLine : aZone->GetHatchLines() )
1277  m_gal->DrawLine( hatchLine.A, hatchLine.B );
1278  }
1279 
1280  // Draw the filling
1281  if( displayMode != ZONE_DISPLAY_MODE::HIDE_FILLED )
1282  {
1283  const SHAPE_POLY_SET& polySet = aZone->GetFilledPolysList( layer );
1284 
1285  if( polySet.OutlineCount() == 0 ) // Nothing to draw
1286  return;
1287 
1288  // Set up drawing options
1289  int outline_thickness = 0;
1290 
1291  if( aZone->GetFilledPolysUseThickness( layer ) )
1292  outline_thickness = aZone->GetMinThickness();
1293 
1295  m_gal->SetFillColor( color );
1296  m_gal->SetLineWidth( outline_thickness );
1297 
1298  if( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED )
1299  {
1300  m_gal->SetIsFill( true );
1301  m_gal->SetIsStroke( outline_thickness > 0 );
1302  }
1303  else if( displayMode == ZONE_DISPLAY_MODE::SHOW_OUTLINED )
1304  {
1305  m_gal->SetIsFill( false );
1306  m_gal->SetIsStroke( true );
1307  }
1308 
1309  m_gal->DrawPolygon( polySet );
1310  }
1311 }
1312 
1313 
1314 void PCB_PAINTER::draw( const DIMENSION* aDimension, int aLayer )
1315 {
1316  const COLOR4D& strokeColor = m_pcbSettings.GetColor( aDimension, aLayer );
1317 
1318  m_gal->SetStrokeColor( strokeColor );
1319  m_gal->SetIsFill( false );
1320  m_gal->SetIsStroke( true );
1321 
1323  {
1324  // Outline mode
1326  }
1327  else
1328  {
1329  // Filled mode
1330  m_gal->SetLineWidth( getLineThickness( aDimension->GetLineThickness() ) );
1331  }
1332 
1333  // Draw dimension shapes
1334  // TODO(JE) lift this out
1335  for( const std::shared_ptr<SHAPE>& shape : aDimension->GetShapes() )
1336  {
1337  switch( shape->Type() )
1338  {
1339  case SH_SEGMENT:
1340  {
1341  const SEG& seg = static_cast<const SHAPE_SEGMENT*>( shape.get() )->GetSeg();
1342  m_gal->DrawLine( seg.A, seg.B );
1343  break;
1344  }
1345 
1346  case SH_CIRCLE:
1347  {
1348  int radius = static_cast<const SHAPE_CIRCLE*>( shape.get() )->GetRadius();
1349  m_gal->DrawCircle( shape->Centre(), radius );
1350  break;
1351  }
1352 
1353  default:
1354  break;
1355  }
1356  }
1357  // Draw text
1358  TEXTE_PCB& text = aDimension->Text();
1359  VECTOR2D position( text.GetTextPos().x, text.GetTextPos().y );
1360 
1362  {
1363  // Outline mode
1365  }
1366  else
1367  {
1368  // Filled mode
1370  }
1371 
1372  m_gal->SetTextAttributes( &text );
1373  m_gal->StrokeText( text.GetShownText(), position, text.GetTextAngleRadians() );
1374 }
1375 
1376 
1377 void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
1378 {
1379  const COLOR4D& strokeColor = m_pcbSettings.GetColor( aTarget, aTarget->GetLayer() );
1380  VECTOR2D position( aTarget->GetPosition() );
1381  double size, radius;
1382 
1383  m_gal->SetLineWidth( getLineThickness( aTarget->GetWidth() ) );
1384  m_gal->SetStrokeColor( strokeColor );
1385  m_gal->SetIsFill( false );
1386  m_gal->SetIsStroke( true );
1387 
1388  m_gal->Save();
1389  m_gal->Translate( position );
1390 
1391  if( aTarget->GetShape() )
1392  {
1393  // shape x
1394  m_gal->Rotate( M_PI / 4.0 );
1395  size = 2.0 * aTarget->GetSize() / 3.0;
1396  radius = aTarget->GetSize() / 2.0;
1397  }
1398  else
1399  {
1400  // shape +
1401  size = aTarget->GetSize() / 2.0;
1402  radius = aTarget->GetSize() / 3.0;
1403  }
1404 
1405  m_gal->DrawLine( VECTOR2D( -size, 0.0 ), VECTOR2D( size, 0.0 ) );
1406  m_gal->DrawLine( VECTOR2D( 0.0, -size ), VECTOR2D( 0.0, size ) );
1407  m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), radius );
1408 
1409  m_gal->Restore();
1410 }
1411 
1412 
1413 void PCB_PAINTER::draw( const MARKER_PCB* aMarker )
1414 {
1415  SHAPE_LINE_CHAIN polygon;
1416  aMarker->ShapeToPolygon( polygon );
1417 
1418  auto strokeColor = m_pcbSettings.GetColor( aMarker, aMarker->GetColorLayer() );
1419 
1420  m_gal->Save();
1421  m_gal->Translate( aMarker->GetPosition() );
1422  m_gal->SetFillColor( strokeColor );
1423  m_gal->SetIsFill( true );
1424  m_gal->SetIsStroke( false );
1425  m_gal->DrawPolygon( polygon );
1426  m_gal->Restore();
1427 }
1428 
1429 
1430 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:749
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
void SetFontItalic(const bool aItalic)
Set italic property of current font.
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.
EDA_RECT GetBoundingBoxBase() const
Returns the last calculated bounding box of the footprint (does not recalculate it).
Definition: class_module.h:159
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:61
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...
to draw blind/buried vias
virtual void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a rectangle.
class ALIGNED_DIMENSION, a linear dimension (graphic item)
Definition: typeinfo.h:101
int GetNetCode() const
Function GetNetCode.
virtual void LoadColors(const COLOR_SETTINGS *aSettings) override
Definition: pcb_painter.cpp:84
class LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:102
int OutlineCount() const
Returns the number of outlines in the set
TEXTE_PCB class definition.
COLOR4D Inverted() const
Function Inverted Returns an inverted color, alpha remains the same.
Definition: color4d.h:319
int GetRadius() const
Definition: shape_circle.h:94
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
COLOR4D & Brighten(double aFactor)
Function Brighten Makes the color brighter by a given factor.
Definition: color4d.h:206
bool IsSelected() const
Definition: base_struct.h:203
ZONE_DISPLAY_MODE
Determines how zones should be displayed
multilayer pads, usually with holes
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
int GetNetnameLayer(int aLayer)
Returns a netname layer corresponding to the given layer.
virtual void BitmapText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle)
Draws a text using a bitmap font.
double m_zoneOpacity
Opacity override for filled zones.
Definition: pcb_painter.h:252
COLOR4D m_layerColorsHi[LAYER_ID_COUNT]
COLOR4D m_layerColors[LAYER_ID_COUNT]
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:109
const wxPoint & GetStart() const
Definition: class_track.h:116
double m_TrackOpacity
Opacity override for all tracks.
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Function GetEffectiveHoleShape Returns a SHAPE object representing the pad's hole.
Definition: class_pad.cpp:273
STROKE_T GetShape() const
PCB_GROUP is a set of BOARD_ITEMs (i.e., without duplicates)
handle color for not plated holes (holes, not pads)
anchor of items having an anchor point (texts, footprints)
int GetSize() const
virtual void SetTextAttributes(const EDA_TEXT *aText)
Loads attributes of the given text (bold/italic/underline/mirrored and so on).
GAL_LAYER_ID GetColorLayer() const
class CENTER_DIMENSION, a center point marking (graphic item)
Definition: typeinfo.h:103
virtual void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle)
Draw an arc.
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: class_zone.cpp:311
bool m_sketchMode[GAL_LAYER_ID_END]
Flag determining if items on a given layer should be drawn as an outline or a filled item
Definition: pcb_painter.h:191
int color
Definition: DXF_plotter.cpp:61
polygon (not yet used for tracks, but could be in microwave apps)
double m_ViaOpacity
Opacity override for all types of via.
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:106
virtual VECTOR2D getDrillSize(const D_PAD *aPad) const
Return drill size for a pad (internal units).
Net/netclass colors are shown on all net copper.
Net/netclass colors are shown on ratsnest lines only.
int GetWidth() const
Definition: eda_rect.h:119
wxPoint GetPosition() const override
double GetArcAngleStart() const
function GetArcAngleStart()
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:300
bool m_padNumbers
Flag determining if pad numbers should be visible
Definition: pcb_painter.h:200
bool GetFilledPolysUseThickness() const
Definition: class_zone.h:682
class TEXTE_PCB, text on a layer
Definition: typeinfo.h:92
to draw via holes (pad holes do not use this layer)
const SHAPE_POLY_SET & GetFilledPolysList(PCB_LAYER_ID aLayer) const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: class_zone.h:627
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
wxString GetNetname() const
Function GetNetname.
bool IsBrightened() const
Definition: base_struct.h:205
usual segment : line with rounded ends
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
bool IsNetCopperLayer(LAYER_NUM aLayer)
Checks if the given layer is "net copper", meaning it is eligible for net coloring.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
const VECTOR2I GetCenter() const
Definition: shape_circle.h:99
PCB_RENDER_SETTINGS m_pcbSettings
Definition: pcb_painter.h:281
const EDA_RECT GetBoundingBox() const override
virtual wxPoint GetPosition() const
Definition: base_struct.h:337
Add new GAL layers here.
VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:85
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected and have...
const std::vector< std::shared_ptr< SHAPE > > & GetShapes() const
class EDGE_MODULE, a footprint edge
Definition: typeinfo.h:94
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:269
bool m_netNamesOnPads
Flag determining if net names should be visible for pads
Definition: pcb_painter.h:203
double GetDrawRotationRadians() const
bool IsTriangulationUpToDate() const
wxString GetNetClassName() const
Function GetNetClassName returns a pointer to the netclass of the zone.
bool m_sketchGraphics
Flag determining if graphic items should be outlined or stroked
Definition: pcb_painter.h:194
GAL * m_gal
Instance of graphic abstraction layer that gives an interface to call commands used to draw (eg.
Definition: painter.h:110
A single base class (TRACK) represents both tracks and vias, with subclasses for curved tracks (ARC) ...
const SEG & GetSeg() const
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
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.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition: color4d.h:372
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.
Only the zone outline is shown.
std::map< wxString, KIGFX::COLOR4D > m_netclassColors
Overrides for specific netclass colors
Definition: pcb_painter.h:235
wxPoint GetPosition() const override
NET_COLOR_MODE m_netColorMode
How to display nets and netclasses with color overrides
Definition: pcb_painter.h:232
DIMENSION class definition.
std::set< unsigned int > m_activeLayers
Stores active layers number.
const wxPoint GetEnd() const
Definition: eda_rect.h:116
void SetFontBold(const bool aBold)
Set bold property of current font.
segment with non rounded ends
class MODULE, a footprint
Definition: typeinfo.h:89
RATSNEST_MODE m_RatsnestMode
Ratsnest draw mode (all layers vs only visible layers)
virtual int GetClearance(PCB_LAYER_ID aLayer, BOARD_ITEM *aItem=nullptr, wxString *aSource=nullptr) const
Function GetClearance returns the clearance in internal units.
Markers used to show a drc problem on boards.
int GetWidth() const
int GetSolderMaskMargin() const
Function GetSolderMaskMargin.
Definition: class_pad.cpp:649
PCB_DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
Non-active layers are shown normally (no high-contrast mode)
PCB_LAYER_ID
A quick note on layer IDs:
PAINTER contains all the knowledge about how to draw graphical object onto any particular output devi...
Definition: painter.h:58
double a
Alpha component.
Definition: color4d.h:369
int getLineThickness(int aActualThickness) const
Function getLineThickness() Get the thickness to draw for a line (e.g.
bool GetDrawIndividualViaLayers() const
Definition: pcb_painter.h:171
COLOR4D m_layerColorsDark[LAYER_ID_COUNT]
virtual void DrawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth)
Draw a rounded segment.
void ResetTextAttributes()
Reset text attributes to default styling.
wxString GetShortNetname() const
Function GetShortNetname.
#define NULL
VECTOR2< double > VECTOR2D
Definition: vector2d.h:593
static const double MAX_FONT_SIZE
Maximum font size for netnames (and other dynamically shown strings)
Definition: pcb_painter.h:223
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 ...
wxString GetName() const
bool m_hiContrastEnabled
Parameters for display modes.
std::vector< wxPoint > GetRectCorners() const
virtual void update()
Function update Precalculates extra colors for layers (e.g.
SHAPE_POLY_SET.
const wxPoint GetOrigin() const
Definition: eda_rect.h:114
bool IsZoneLayer(LAYER_NUM aLayer)
virtual void StrokeText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle)
Draws a vector type text using preloaded Newstroke font.
const wxPoint GetPosition() const
Definition: eda_rect.h:115
static const COLOR4D CLEAR
Definition: color4d.h:377
void SetBackgroundColor(const COLOR4D &aColor) override
Sets the background color.
Definition: pcb_painter.h:149
Arcs (with rounded ends)
to draw usual through hole vias
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: class_pad.h:326
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon) const
Returns the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to th...
last value for this list
MODULE * GetParentModule() const
Function GetParentModule returns a pointer to the parent module, or NULL if DRAWSEGMENT does not belo...
const wxString & GetName() const
Definition: class_pad.h:132
RATSNEST_MODE m_ratsnestDisplayMode
Definition: pcb_painter.h:246
EDA_ITEM * GetParent() const
Definition: base_struct.h:195
HIGH_CONTRAST_MODE m_ContrastModeDisplay
How inactive layers are displayed.
virtual bool IsOpenGlEngine()
Returns true if the GAL engine is a opengl based type.
virtual wxPoint GetCenter() const
Function GetCenter()
a few functions useful in geometry calculations.
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Function GetEffectiveShape Some pad shapes can be complex (rounded/chamfered rectangle),...
Definition: class_pad.cpp:264
void SetTextMirrored(const bool aMirrored)
Set a mirrored property of text.
Bezier Curve.
double GetRadius() const
double m_viaOpacity
Opacity override for all types of via.
Definition: pcb_painter.h:250
void SetVerticalJustify(const EDA_TEXT_VJUSTIFY_T aVerticalJustify)
Set the vertical justify for text drawing.
const std::vector< SEG > & GetHatchLines() const
Definition: class_zone.h:793
int NewOutline()
Creates a new empty polygon in the set and returns its index
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aMaxError=ARC_HIGH_DEF, bool ignoreLineWidth=false) const override
Function TransformShapeWithClearanceToPolygon Convert the pad shape to a closed polygon.
bool m_curvedRatsnestlines
Flag determining if ratsnest lines should be drawn curved
Definition: pcb_painter.h:215
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
int GetHeight() const
Definition: eda_rect.h:120
int GetWidth() const
line chain (polyline)
Definition: shape.h:45
double m_ZoneOpacity
Opacity override for filled zone areas.
Pad object description.
bool m_sketchText
Flag determining if text items should be outlined or stroked
Definition: pcb_painter.h:197
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:105
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:160
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
Definition: seg.h:39
double GetTextAngleRadians() const
Definition: eda_text.h:177
double GetAngle() const
double GetAngle() const
COLOR4D GetColor(int aLayer) const
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
bool m_netNamesOnTracks
Flag determining if net names should be visible for tracks
Definition: pcb_painter.h:206
bool IsLayerVisible(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
double m_trackOpacity
Opacity override for all tracks.
Definition: pcb_painter.h:249
double m_PadOpacity
Opacity override for SMD pads and PTHs.
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:99
virtual wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
smd pads, front layer
virtual void Restore()
Restore the context.
std::map< int, KIGFX::COLOR4D > m_netColors
Overrides for specific net colors, stored as netcodes for the ratsnest to access easily
Definition: pcb_painter.h:238
int GetWidth() const
Definition: class_track.h:110
virtual void DrawPolygon(const std::deque< VECTOR2D > &aPointList)
Draw a polygon.
int m_clearance
Clearance visibility settings
Definition: pcb_painter.h:229
Board layer functions and definitions.
Class to handle a graphic segment.
const char * name
Definition: DXF_plotter.cpp:60
virtual void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius)
Draw a circle using world coordinates.
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: class_pad.cpp:694
Information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:176
SHAPE_LINE_CHAIN.
COLOR4D & Darken(double aFactor)
Function Darken Makes the color darker by a given factor.
Definition: color4d.h:223
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:152
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void LoadDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aShowPageLimits)
Function LoadDisplayOptions Loads settings related to display options (high-contrast mode,...
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...
TEXTE_PCB & Text()
const COLOR4D & GetBackgroundColor() override
Function GetBackgroundColor Returns current background color settings.
Definition: pcb_painter.h:147
const wxSize & GetDrillSize() const
Definition: class_pad.h:230
VECTOR2I A
Definition: seg.h:47
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
int GetLineThickness() const
double DECIDEG2RAD(double deg)
Definition: trigo.h:223
ZONE_DISPLAY_MODE m_ZoneDisplayMode
int GetShape() const
HIGH_CONTRAST_MODE m_contrastModeDisplay
How to display inactive layers (HIGH_CONTRAST_MODE:NORMAL, DIMMED or HIDDEN )
Definition: pcb_painter.h:244
VIATYPE GetViaType() const
Definition: class_track.h:381
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
const wxPoint & GetBezControl2() const
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
int GetMinThickness() const
Definition: class_zone.h:224
virtual bool Draw(const VIEW_ITEM *aItem, int aLayer) override
Function Draw Takes an instance of VIEW_ITEM and passes it to a function that know how to draw the it...
wxPoint Centre() const
Definition: eda_rect.h:62
const wxPoint & GetEnd() const
Definition: class_track.h:113
PCB_PAINTER(GAL *aGal)
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
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:251
const wxPoint & GetTextPos() const
Definition: eda_text.h:248
void SetGlyphSize(const VECTOR2D aGlyphSize)
Set the font glyph size.
virtual void DrawArcSegment(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle, double aWidth)
Draw an arc segment.
PCB_TARGET class definition.
class ORTHOGONAL_DIMENSION, a linear dimension constrained to x/y
Definition: typeinfo.h:104
double GetArcAngleStart() const
void CacheTriangulation(bool aPartition=true)
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
const wxPoint & GetBezControl1() const
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:299
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
bool m_zoneOutlines
Flag determining if zones should have outlines drawn
Definition: pcb_painter.h:212
wxPoint GetPosition() const override
Definition: class_module.h:219
Non-active layers are dimmed (old high-contrast mode)
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
PAD_SHAPE_T GetShape() const
Definition: class_pad.h:157
virtual void Save()
Save the context.
void SetHorizontalJustify(const EDA_TEXT_HJUSTIFY_T aHorizontalJustify)
Set the horizontal justify for text drawing.
class ZONE_CONTAINER, managed by a footprint
Definition: typeinfo.h:95
const wxSize & GetSize() const
Definition: class_pad.h:224
class DRAWSEGMENT, a segment not on copper layers
Definition: typeinfo.h:91
void draw(const TRACK *aTrack, int aLayer)
double GetWorldScale() const
Get the world scale.
BOARD_ITEM_CONTAINER * GetParent() const
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.
int GetWidth() const
bool PadShouldBeNPTH() const
A pad whose hole is the same size as the pad is a NPTH.
Definition: class_pad.cpp:1105
static constexpr int Millimeter2iu(double mm)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:478
bool IsPolygonFilled() const
Polygonal shape is not always filled.
std::set< int > m_highlightNetcodes
Definition of PCB_DISPLAY_OPTIONS class.
ZONE_DISPLAY_MODE m_zoneDisplayMode
Option for different display modes for zones
Definition: pcb_painter.h:226
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:904
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox The bounding box is cached, so this will be efficient most of the time.
Definition: class_pad.cpp:470
Abstract dimension API.
Additional netnames layers (not associated with a PCB layer)
bool IsPadOnLayer(int aLayer) const
Checks to see whether the via should have a pad on the specific layer.
Outlines of filled polygons are shown.
Class to handle a set of BOARD_ITEMs.
bool m_netNamesOnVias
Flag determining if net names should be visible for vias
Definition: pcb_painter.h:209
COLOR4D m_layerColorsSel[LAYER_ID_COUNT]
const wxSize GetSize() const
Definition: eda_rect.h:103
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
Function Type()
Definition: base_struct.h:193
axis-aligned rectangle
Definition: shape.h:43
Class GAL is the abstract interface for drawing on a 2D-surface.
bool m_globalRatsnestlines
Flag determining if ratsnest lines are shown by default
Definition: pcb_painter.h:218
virtual int getDrillShape(const D_PAD *aPad) const
Return drill shape of a pad.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:99
VECTOR2I B
Definition: seg.h:48