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  {
81  m_sketchMode[i] = false;
82  }
83 
84  update();
85 }
86 
87 
89 {
91 
92  // Init board layers colors:
93  for( int i = 0; i < PCB_LAYER_ID_COUNT; i++ )
94  {
95  m_layerColors[i] = aSettings->GetColor( i );
96 
97  // Guard: if the alpah channel is too small, the layer is not visible.
98  // clamp it to 0.2
99  if( m_layerColors[i].a < 0.2 )
100  m_layerColors[i].a = 0.2;
101  }
102 
103  // Init specific graphic layers colors:
104  for( int i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; i++ )
105  m_layerColors[i] = aSettings->GetColor( i );
106 
107  // Default colors for specific layers (not really board layers).
109  m_layerColors[LAYER_VIAS_NETNAMES] = COLOR4D( 0.2, 0.2, 0.2, 0.9 );
110  m_layerColors[LAYER_PADS_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
111  m_layerColors[LAYER_PAD_FR_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
112  m_layerColors[LAYER_PAD_BK_NETNAMES] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
113 
114  // LAYER_PADS_TH, LAYER_NON_PLATEDHOLES, LAYER_ANCHOR ,LAYER_RATSNEST,
115  // LAYER_VIA_THROUGH, LAYER_VIA_BBLIND, LAYER_VIA_MICROVIA
116  // are initialized from aSettings
117 
118  // Netnames for copper layers
119  for( LSEQ cu = LSET::AllCuMask().CuStack(); cu; ++cu )
120  {
121  const COLOR4D lightLabel( 0.8, 0.8, 0.8, 0.7 );
122  const COLOR4D darkLabel = lightLabel.Inverted();
123  PCB_LAYER_ID layer = *cu;
124 
125  if( m_layerColors[layer].GetBrightness() > 0.5 )
126  m_layerColors[GetNetnameLayer( layer )] = darkLabel;
127  else
128  m_layerColors[GetNetnameLayer( layer )] = lightLabel;
129  }
130 
131  update();
132 }
133 
134 
136  bool aShowPageLimits )
137 {
140  m_padNumbers = aOptions.m_DisplayPadNum;
142  m_sketchText = !aOptions.m_DisplayTextFill;
145 
146  // Whether to draw tracks, vias & pads filled or as outlines
152 
153  // Net names display settings
154  switch( aOptions.m_DisplayNetNamesMode )
155  {
156  case 0:
157  m_netNamesOnPads = false;
158  m_netNamesOnTracks = false;
159  m_netNamesOnVias = false;
160  break;
161 
162  case 1:
163  m_netNamesOnPads = true;
164  m_netNamesOnTracks = false;
165  m_netNamesOnVias = true; // Follow pads or tracks? For now we chose pads....
166  break;
167 
168  case 2:
169  m_netNamesOnPads = false;
170  m_netNamesOnTracks = true;
171  m_netNamesOnVias = false; // Follow pads or tracks? For now we chose pads....
172  break;
173 
174  case 3:
175  m_netNamesOnPads = true;
176  m_netNamesOnTracks = true;
177  m_netNamesOnVias = true;
178  break;
179  }
180 
181  // Zone display settings
183 
184  // Clearance settings
185  switch( aOptions.m_ShowTrackClearanceMode )
186  {
189  break;
190 
193  break;
194 
197  break;
198 
201  break;
202 
205  break;
206  }
207 
208  if( aOptions.m_DisplayPadIsol )
209  m_clearance |= CL_PADS;
210 
212 
213  m_netColorMode = aOptions.m_NetColorMode;
214 
216 
217  m_trackOpacity = aOptions.m_TrackOpacity;
218  m_viaOpacity = aOptions.m_ViaOpacity;
219  m_padOpacity = aOptions.m_PadOpacity;
220  m_zoneOpacity = aOptions.m_ZoneOpacity;
221 
222  m_showPageLimits = aShowPageLimits;
223 }
224 
225 
226 COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const
227 {
228  int netCode = -1;
229  const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
230  const BOARD_CONNECTED_ITEM* conItem = dynamic_cast<const BOARD_CONNECTED_ITEM*> ( aItem );
231 
232  // Marker shadows
233  if( aLayer == LAYER_MARKER_SHADOWS )
234  return m_backgroundColor.WithAlpha( 0.6 );
235 
236  if( !item )
237  return m_layerColors[aLayer];
238 
239  // Pad hole color is pad-type-specific: the background color for PTHs (which are assumed
240  // to have an annular ring) and the pad color for NPTHs (which are assumed *not* to have
241  // an annular ring).
242  // However, this means a PTH pad with *no* annular ring won't get drawn, so we need to
243  // special-case that.
244  // We have the opposite issue when printing in B&W: both a PTH hole and its annular ring
245  // will normally get assigned black, so we need to special-case that too.
246  if( aLayer == LAYER_PADS_PLATEDHOLES || aLayer == LAYER_NON_PLATEDHOLES )
247  {
248  const PAD* pad = static_cast<const PAD*>( item );
249  bool hasAnnularRing = pad->GetSizeX() > pad->GetDrillSizeX()
250  && pad->GetSizeY() > pad->GetDrillSizeY();
251 
252  if( !hasAnnularRing && m_layerColors[ aLayer ] == m_layerColors[ LAYER_PCB_BACKGROUND ] )
253  aLayer = LAYER_MOD_TEXT_INVISIBLE;
254 
255  if( hasAnnularRing && m_layerColors[ aLayer ] == m_layerColors[ LAYER_PADS_TH ] )
256  aLayer = LAYER_PCB_BACKGROUND;
257  }
258  else if( aLayer == LAYER_VIAS_HOLES )
259  {
260  const VIA* via = static_cast<const VIA*>( item );
261  int annularRingLayer;
262 
263  if( via->GetViaType() == VIATYPE::MICROVIA )
264  annularRingLayer = LAYER_VIA_MICROVIA;
265  else if( via->GetViaType() == VIATYPE::BLIND_BURIED )
266  annularRingLayer = LAYER_VIA_BBLIND;
267  else
268  annularRingLayer = LAYER_VIA_THROUGH;
269 
270  if( m_layerColors[ aLayer ] == m_layerColors[ annularRingLayer ] )
271  aLayer = LAYER_PCB_BACKGROUND;
272  }
273 
274  // Zones should pull from the copper layer
275  if( item && item->Type() == PCB_ZONE_T && IsZoneLayer( aLayer ) )
276  aLayer = aLayer - LAYER_ZONE_START;
277 
278  // Normal path: get the layer base color
279  COLOR4D color = m_layerColors[aLayer];
280 
281  // Selection disambiguation
282  if( item->IsBrightened() )
283  return color.Brightened( m_selectFactor ).WithAlpha( 0.8 );
284 
285  // Normal selection
286  if( item->IsSelected() )
287  color = m_layerColorsSel[aLayer];
288 
289  // Try to obtain the netcode for the item
290  if( conItem )
291  netCode = conItem->GetNetCode();
292 
293  bool highlighted = m_highlightEnabled && m_highlightNetcodes.count( netCode );
294  bool selected = item->IsSelected();
295 
296  // Apply net color overrides
297  if( conItem && m_netColorMode == NET_COLOR_MODE::ALL && IsNetCopperLayer( aLayer ) )
298  {
299  COLOR4D netColor = COLOR4D::UNSPECIFIED;
300 
301  auto ii = m_netColors.find( netCode );
302 
303  if( ii != m_netColors.end() )
304  netColor = ii->second;
305 
306  if( netColor == COLOR4D::UNSPECIFIED )
307  {
308  auto jj = m_netclassColors.find( conItem->GetNetClassName() );
309 
310  if( jj != m_netclassColors.end() )
311  netColor = jj->second;
312  }
313 
314  if( netColor == COLOR4D::UNSPECIFIED )
315  netColor = color;
316 
317  if( selected )
318  {
319  // Selection brightening overrides highlighting
320  netColor.Brighten( m_selectFactor );
321  }
322  else if( m_highlightEnabled )
323  {
324  // Highlight brightens objects on all layers and darkens everything else for contrast
325  if( highlighted )
326  netColor.Brighten( m_highlightFactor );
327  else
328  netColor.Darken( 1.0 - m_highlightFactor );
329  }
330 
331  color = netColor;
332  }
333  else if( !selected && m_highlightEnabled )
334  {
335  // Single net highlight mode
336  color = m_highlightNetcodes.count( netCode ) ? m_layerColorsHi[aLayer]
337  : m_layerColorsDark[aLayer];
338  }
339 
340  // Apply high-contrast dimming
341  if( m_hiContrastEnabled && !highlighted && !selected )
342  {
344  bool isActive = m_highContrastLayers.count( aLayer );
345 
346  // Items drawn on synthetic layers depend on crossing the primary layer for active
347  // state determination
348  if( primary != UNDEFINED_LAYER )
349  {
350  if( item->Type() == PCB_VIA_T )
351  {
352  isActive = static_cast<const VIA*>( item )->IsOnLayer( primary );
353  }
354  else if( item->Type() == PCB_PAD_T )
355  {
356  isActive = static_cast<const PAD*>( item )->IsOnLayer( primary );
357  }
358  else if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
359  {
360  // Track itself isn't on a synthetic layer, but its netname annotations are.
361  isActive = static_cast<const TRACK*>( item )->IsOnLayer( primary );
362  }
363  }
364 
365  if( !isActive )
366  {
369  else
371  }
372  }
373 
374  // Apply per-type opacity overrides
375  if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
376  color.a *= m_trackOpacity;
377  else if( item->Type() == PCB_VIA_T )
378  color.a *= m_viaOpacity;
379  else if( item->Type() == PCB_PAD_T )
380  color.a *= m_padOpacity;
381  else if( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
382  color.a *= m_zoneOpacity;
383 
384  // No special modificators enabled
385  return color;
386 }
387 
388 
390  PAINTER( aGal )
391 {
392 }
393 
394 
395 int PCB_PAINTER::getLineThickness( int aActualThickness ) const
396 {
397  // if items have 0 thickness, draw them with the outline
398  // width, otherwise respect the set value (which, no matter
399  // how small will produce something)
400  if( aActualThickness == 0 )
402 
403  return aActualThickness;
404 }
405 
406 
407 int PCB_PAINTER::getDrillShape( const PAD* aPad ) const
408 {
409  return aPad->GetDrillShape();
410 }
411 
412 
414 {
415  return VECTOR2D( aPad->GetDrillSize() );
416 }
417 
418 
419 int PCB_PAINTER::getDrillSize( const VIA* aVia ) const
420 {
421  return aVia->GetDrillValue();
422 }
423 
424 
425 bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
426 {
427  const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
428 
429  if( !item )
430  return false;
431 
432  // the "cast" applied in here clarifies which overloaded draw() is called
433  switch( item->Type() )
434  {
435  case PCB_TRACE_T:
436  draw( static_cast<const TRACK*>( item ), aLayer );
437  break;
438 
439  case PCB_ARC_T:
440  draw( static_cast<const ARC*>( item ), aLayer );
441  break;
442 
443  case PCB_VIA_T:
444  draw( static_cast<const VIA*>( item ), aLayer );
445  break;
446 
447  case PCB_PAD_T:
448  draw( static_cast<const PAD*>( item ), aLayer );
449  break;
450 
451  case PCB_SHAPE_T:
452  case PCB_FP_SHAPE_T:
453  draw( static_cast<const PCB_SHAPE*>( item ), aLayer );
454  break;
455 
456  case PCB_TEXT_T:
457  draw( static_cast<const PCB_TEXT*>( item ), aLayer );
458  break;
459 
460  case PCB_FP_TEXT_T:
461  draw( static_cast<const FP_TEXT*>( item ), aLayer );
462  break;
463 
464  case PCB_FOOTPRINT_T:
465  draw( static_cast<const FOOTPRINT*>( item ), aLayer );
466  break;
467 
468  case PCB_GROUP_T:
469  draw( static_cast<const PCB_GROUP*>( item ), aLayer );
470  break;
471 
472  case PCB_ZONE_T:
473  draw( static_cast<const ZONE*>( item ), aLayer );
474  break;
475 
476  case PCB_FP_ZONE_T:
477  draw( static_cast<const ZONE*>( item ), aLayer );
478  break;
479 
480  case PCB_DIM_ALIGNED_T:
481  case PCB_DIM_CENTER_T:
483  case PCB_DIM_LEADER_T:
484  draw( static_cast<const DIMENSION_BASE*>( item ), aLayer );
485  break;
486 
487  case PCB_TARGET_T:
488  draw( static_cast<const PCB_TARGET*>( item ) );
489  break;
490 
491  case PCB_MARKER_T:
492  draw( static_cast<const PCB_MARKER*>( item ), aLayer );
493  break;
494 
495  default:
496  // Painter does not know how to draw the object
497  return false;
498  }
499 
500  return true;
501 }
502 
503 
504 void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
505 {
506  VECTOR2D start( aTrack->GetStart() );
507  VECTOR2D end( aTrack->GetEnd() );
508  int width = aTrack->GetWidth();
509 
511  {
512  // If there is a net name - display it on the track
513  if( aTrack->GetNetCode() > NETINFO_LIST::UNCONNECTED )
514  {
515  VECTOR2D line = ( end - start );
516  double length = line.EuclideanNorm();
517 
518  // Check if the track is long enough to have a netname displayed
519  if( length < 10 * width )
520  return;
521 
522  const wxString& netName = UnescapeString( aTrack->GetShortNetname() );
523  VECTOR2D textPosition = start + line / 2.0; // center of the track
524 
525  double textOrientation;
526 
527  if( end.y == start.y ) // horizontal
528  textOrientation = 0;
529  else if( end.x == start.x ) // vertical
530  textOrientation = M_PI / 2;
531  else
532  textOrientation = -atan( line.y / line.x );
533 
534  double textSize = width;
535 
536  m_gal->SetIsStroke( true );
537  m_gal->SetIsFill( false );
538  m_gal->SetStrokeColor( m_pcbSettings.GetColor( aTrack, aLayer ) );
539  m_gal->SetLineWidth( width / 10.0 );
540  m_gal->SetFontBold( false );
541  m_gal->SetFontItalic( false );
542  m_gal->SetFontUnderlined( false );
543  m_gal->SetTextMirrored( false );
544  m_gal->SetGlyphSize( VECTOR2D( textSize * 0.7, textSize * 0.7 ) );
547  m_gal->BitmapText( netName, textPosition, textOrientation );
548  }
549  }
550  else if( IsCopperLayer( aLayer ) )
551  {
552  // Draw a regular track
553  COLOR4D color = m_pcbSettings.GetColor( aTrack, aLayer );
554  bool outline_mode = m_pcbSettings.m_sketchMode[LAYER_TRACKS];
557  m_gal->SetIsStroke( outline_mode );
558  m_gal->SetIsFill( not outline_mode );
560 
561  m_gal->DrawSegment( start, end, width );
562 
563  // Clearance lines
564  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING | PCB_RENDER_SETTINGS::CL_TRACKS;
565 
566  if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags )
567  {
568  int clearance = aTrack->GetOwnClearance( m_pcbSettings.GetActiveLayer() );
569 
571  m_gal->SetIsFill( false );
572  m_gal->SetIsStroke( true );
574  m_gal->DrawSegment( start, end, width + clearance * 2 );
575  }
576  }
577 }
578 
579 
580 void PCB_PAINTER::draw( const ARC* aArc, int aLayer )
581 {
582  VECTOR2D center( aArc->GetCenter() );
583  int width = aArc->GetWidth();
584 
585  if( IsCopperLayer( aLayer ) )
586  {
587  // Draw a regular track
588  COLOR4D color = m_pcbSettings.GetColor( aArc, aLayer );
589  bool outline_mode = m_pcbSettings.m_sketchMode[LAYER_TRACKS];
592  m_gal->SetIsStroke( outline_mode );
593  m_gal->SetIsFill( not outline_mode );
595 
596  auto radius = aArc->GetRadius();
597  auto start_angle = DECIDEG2RAD( aArc->GetArcAngleStart() );
598  auto angle = DECIDEG2RAD( aArc->GetAngle() );
599 
600  m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width );
601 
602  // Clearance lines
603  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING | PCB_RENDER_SETTINGS::CL_TRACKS;
604 
605  if( ( m_pcbSettings.m_clearance & 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 
621 void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
622 {
623  VECTOR2D center( aVia->GetStart() );
624  double radius = 0.0;
625 
626  // Draw description layer
627  if( IsNetnameLayer( aLayer ) )
628  {
629  VECTOR2D position( center );
630 
631  // Is anything that we can display enabled?
632  if( !m_pcbSettings.m_netNamesOnVias || aVia->GetNetname().empty() )
633  return;
634 
635  // We won't get CLEAR from GetColor below for a non-through via on an inactive layer in
636  // high contrast mode because LAYER_VIAS_NETNAMES will always be part of the high-contrast
637  // set. So we do another check here to prevent drawing netnames for these vias.
639  {
640  bool draw = false;
641 
642  for( unsigned int layer : m_pcbSettings.GetHighContrastLayers() )
643  {
644  if( aVia->IsOnLayer( static_cast<PCB_LAYER_ID>( layer ) ) )
645  {
646  draw = true;
647  break;
648  }
649  }
650 
651  if( !draw )
652  return;
653  }
654 
655  double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
656  double size = aVia->GetWidth();
657 
658  // Font size limits
659  if( size > maxSize )
660  size = maxSize;
661 
662  m_gal->Save();
663  m_gal->Translate( position );
664 
665  // Default font settings
668 
669  // Set the text position to the pad shape position (the pad position is not the best place)
670  VECTOR2D textpos( 0.0, 0.0 );
671 
672  wxString netname = UnescapeString( aVia->GetShortNetname() );
673  // calculate the size of net name text:
674  double tsize = 1.5 * size / netname.Length();
675  tsize = std::min( tsize, size );
676  // Use a smaller text size to handle interline, pen size..
677  tsize *= 0.7;
678  VECTOR2D namesize( tsize, tsize );
679 
680  m_gal->SetGlyphSize( namesize );
681  m_gal->SetLineWidth( namesize.x / 12.0 );
682  m_gal->BitmapText( netname, textpos, 0.0 );
683 
684  m_gal->Restore();
685 
686  return;
687  }
688  else if( aLayer == LAYER_VIAS_HOLES )
689  {
690  radius = getDrillSize( aVia ) / 2.0;
691  }
692  else if( ( aLayer == LAYER_VIA_THROUGH && aVia->GetViaType() == VIATYPE::THROUGH )
693  || ( aLayer == LAYER_VIA_BBLIND && aVia->GetViaType() == VIATYPE::BLIND_BURIED )
694  || ( aLayer == LAYER_VIA_MICROVIA && aVia->GetViaType() == VIATYPE::MICROVIA ) )
695  {
696  radius = aVia->GetWidth() / 2.0;
697  }
698  else
699  {
700  return;
701  }
702 
705  if( IsCopperLayer( aLayer ) && !aVia->FlashLayer( aLayer ) )
706  radius = getDrillSize( aVia ) / 2.0 ;
707 
708  bool sketchMode = false;
709  COLOR4D color = m_pcbSettings.GetColor( aVia, aLayer );
710 
711  if( color == COLOR4D::CLEAR )
712  return;
713 
714  switch( aVia->GetViaType() )
715  {
719  default: wxASSERT( false ); break;
720  }
721 
722  m_gal->SetIsFill( !sketchMode );
723  m_gal->SetIsStroke( sketchMode );
724 
725  if( sketchMode )
726  {
727  // Outline mode
730  }
731  else
732  {
733  // Filled mode
735  }
736 
737  if( ( aVia->GetViaType() == VIATYPE::BLIND_BURIED || aVia->GetViaType() == VIATYPE::MICROVIA )
738  && aLayer != LAYER_VIAS_HOLES
740  {
741  // Outer circles of blind/buried and micro-vias are drawn in a special way to indicate the
742  // top and bottom layers
743  PCB_LAYER_ID layerTop, layerBottom;
744  aVia->LayerPair( &layerTop, &layerBottom );
745 
746  if( !sketchMode )
747  m_gal->SetLineWidth( ( aVia->GetWidth() - aVia->GetDrillValue() ) / 2.0 );
748 
749  m_gal->DrawArc( center, radius, M_PI / 2.0, M_PI );
750  m_gal->DrawArc( center, radius, 3.0 * M_PI / 2.0, 2.0 * M_PI );
751 
752  if( sketchMode )
753  m_gal->SetStrokeColor( m_pcbSettings.GetColor( aVia, layerTop ) );
754  else
755  m_gal->SetFillColor( m_pcbSettings.GetColor( aVia, layerTop ) );
756 
757  m_gal->DrawArc( center, radius, 0.0, M_PI / 2.0 );
758 
759  if( sketchMode )
760  m_gal->SetStrokeColor( m_pcbSettings.GetColor( aVia, layerBottom ) );
761  else
762  m_gal->SetFillColor( m_pcbSettings.GetColor( aVia, layerBottom ) );
763 
764  m_gal->DrawArc( center, radius, M_PI, 3.0 * M_PI / 2.0 );
765  }
766  else
767  {
768  // Draw the outer circles of normal vias and the holes for all vias
769  m_gal->DrawCircle( center, radius );
770  }
771 
772  // Clearance lines
773  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_EXISTING | PCB_RENDER_SETTINGS::CL_VIAS;
774 
775  if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags
776  && aLayer != LAYER_VIAS_HOLES )
777  {
778  PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
779 
780  if( !aVia->FlashLayer( activeLayer ) )
781  {
782  radius = getDrillSize( aVia ) / 2.0 +
784  }
785 
787  m_gal->SetIsFill( false );
788  m_gal->SetIsStroke( true );
790  m_gal->DrawCircle( center, radius + aVia->GetOwnClearance( activeLayer ) );
791  }
792 }
793 
794 
795 void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
796 {
797  // Draw description layer
798  if( IsNetnameLayer( aLayer ) )
799  {
800  // Is anything that we can display enabled?
802  {
803  bool displayNetname = ( m_pcbSettings.m_netNamesOnPads && !aPad->GetNetname().empty() );
804  EDA_RECT padBBox = aPad->GetBoundingBox();
805  VECTOR2D position = padBBox.Centre();
806  VECTOR2D padsize = VECTOR2D( padBBox.GetSize() );
807 
808  if( aPad->GetShape() != PAD_SHAPE_CUSTOM )
809  {
810  // Don't allow a 45ยบ rotation to bloat a pad's bounding box unnecessarily
811  double limit = std::min( aPad->GetSize().x, aPad->GetSize().y ) * 1.1;
812 
813  if( padsize.x > limit && padsize.y > limit )
814  {
815  padsize.x = limit;
816  padsize.y = limit;
817  }
818  }
819 
820  double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
821  double size = padsize.y;
822 
823  m_gal->Save();
824  m_gal->Translate( position );
825 
826  // Keep the size ratio for the font, but make it smaller
827  if( padsize.x < padsize.y )
828  {
829  m_gal->Rotate( DECIDEG2RAD( -900.0 ) );
830  size = padsize.x;
831  std::swap( padsize.x, padsize.y );
832  }
833 
834  // Font size limits
835  if( size > maxSize )
836  size = maxSize;
837 
838  // Default font settings
841  m_gal->SetFontBold( false );
842  m_gal->SetFontItalic( false );
843  m_gal->SetFontUnderlined( false );
844  m_gal->SetTextMirrored( false );
845  m_gal->SetStrokeColor( m_pcbSettings.GetColor( aPad, aLayer ) );
846  m_gal->SetIsStroke( true );
847  m_gal->SetIsFill( false );
848 
849  // We have already translated the GAL to be centered at the center of the pad's
850  // bounding box
851  VECTOR2D textpos( 0.0, 0.0 );
852 
853  // Divide the space, to display both pad numbers and netnames and set the Y text
854  // position to display 2 lines
855  if( displayNetname && m_pcbSettings.m_padNumbers )
856  {
857  size = size / 2.0;
858  textpos.y = size / 2.0;
859  }
860 
861  if( displayNetname )
862  {
863  wxString netname = UnescapeString( aPad->GetShortNetname() );
864 
865  if( netname.StartsWith( "no_connect_" ) )
866  netname = "x";
867 
868  // calculate the size of net name text:
869  double tsize = 1.5 * padsize.x / netname.Length();
870  tsize = std::min( tsize, size );
871  // Use a smaller text size to handle interline, pen size..
872  tsize *= 0.7;
873  VECTOR2D namesize( tsize, tsize );
874 
875  m_gal->SetGlyphSize( namesize );
876  m_gal->SetLineWidth( namesize.x / 12.0 );
877  m_gal->BitmapText( netname, textpos, 0.0 );
878  }
879 
881  {
882  const wxString& padName = aPad->GetName();
883  textpos.y = -textpos.y;
884  double tsize = 1.5 * padsize.x / padName.Length();
885  tsize = std::min( tsize, size );
886  // Use a smaller text size to handle interline, pen size..
887  tsize *= 0.7;
888  tsize = std::min( tsize, size );
889  VECTOR2D numsize( tsize, tsize );
890 
891  m_gal->SetGlyphSize( numsize );
892  m_gal->SetLineWidth( numsize.x / 12.0 );
893  m_gal->BitmapText( padName, textpos, 0.0 );
894  }
895 
896  m_gal->Restore();
897  }
898  return;
899  }
900 
901  // Pad drawing
903  COLOR4D color = m_pcbSettings.GetColor( aPad, aLayer );
904 
906  {
907  // Outline mode
908  m_gal->SetIsFill( false );
909  m_gal->SetIsStroke( true );
912  }
913  else
914  {
915  // Filled mode
916  m_gal->SetIsFill( true );
917  m_gal->SetIsStroke( false );
919  }
920 
921  // Choose drawing settings depending on if we are drawing a pad itself or a hole
922  if( aLayer == LAYER_PADS_PLATEDHOLES || aLayer == LAYER_NON_PLATEDHOLES )
923  {
924  const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
925 
926  if( seg->GetSeg().A == seg->GetSeg().B ) // Circular hole
927  m_gal->DrawCircle( seg->GetSeg().A, getDrillSize( aPad ).x / 2 );
928  else
929  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() );
930  }
931  else if( aLayer == LAYER_PADS_TH
932  && aPad->GetSizeX() <= aPad->GetDrillSizeX()
933  && aPad->GetSizeY() <= aPad->GetDrillSizeY() )
934  {
935  // no annular ring to draw
936  }
937  else
938  {
939  wxSize pad_size = aPad->GetSize();
940  wxSize margin;
941 
942  switch( aLayer )
943  {
944  case F_Mask:
945  case B_Mask:
946  margin.x = margin.y = aPad->GetSolderMaskMargin();
947  break;
948 
949  case F_Paste:
950  case B_Paste:
951  margin = aPad->GetSolderPasteMargin();
952  break;
953 
954  default:
955  margin.x = margin.y = 0;
956  break;
957  }
958 
959  if( margin.x != margin.y )
960  {
961  const_cast<PAD*>( aPad )->SetSize( pad_size + margin + margin );
962  margin.x = margin.y = 0;
963  }
964 
965  // Once we change the size of the pad, check that there is still a pad remaining
966  if( !aPad->GetSize().x || !aPad->GetSize().y )
967  {
968  // Reset the stored pad size
969  if( aPad->GetSize() != pad_size )
970  const_cast<PAD*>( aPad )->SetSize( pad_size );
971 
972  return;
973  }
974 
975  auto shapes = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
976  bool simpleShapes = true;
977 
978  for( SHAPE* shape : shapes->Shapes() )
979  {
980  // Drawing components of compound shapes in outline mode produces a mess.
982  simpleShapes = false;
983 
984  if( !simpleShapes )
985  break;
986 
987  switch( shape->Type() )
988  {
989  case SH_SEGMENT:
990  case SH_CIRCLE:
991  case SH_RECT:
992  case SH_SIMPLE:
993  // OK so far
994  break;
995 
996  default:
997  // Not OK
998  simpleShapes = false;
999  break;
1000  }
1001  }
1002 
1003  if( simpleShapes )
1004  {
1005  for( SHAPE* shape : shapes->Shapes() )
1006  {
1007  switch( shape->Type() )
1008  {
1009  case SH_SEGMENT:
1010  {
1011  const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape;
1012  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
1013  seg->GetWidth() + 2 * margin.x );
1014  }
1015  break;
1016 
1017  case SH_CIRCLE:
1018  {
1019  const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape;
1020  m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + margin.x );
1021  }
1022  break;
1023 
1024  case SH_RECT:
1025  {
1026  const SHAPE_RECT* r = (SHAPE_RECT*) shape;
1027 
1028  m_gal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
1029 
1030  if( margin.x > 0 )
1031  {
1032  m_gal->DrawSegment( r->GetPosition(),
1033  r->GetPosition() + VECTOR2I( r->GetWidth(), 0 ),
1034  margin.x * 2 );
1035  m_gal->DrawSegment( r->GetPosition() + VECTOR2I( r->GetWidth(), 0 ),
1036  r->GetPosition() + r->GetSize(),
1037  margin.x * 2 );
1038  m_gal->DrawSegment( r->GetPosition() + r->GetSize(),
1039  r->GetPosition() + VECTOR2I( 0, r->GetHeight() ),
1040  margin.x * 2 );
1041  m_gal->DrawSegment( r->GetPosition() + VECTOR2I( 0, r->GetHeight() ),
1042  r->GetPosition(),
1043  margin.x * 2 );
1044  }
1045  }
1046  break;
1047 
1048  case SH_SIMPLE:
1049  {
1050  const SHAPE_SIMPLE* poly = static_cast<const SHAPE_SIMPLE*>( shape );
1051  m_gal->DrawPolygon( poly->Vertices() );
1052 
1053  if( margin.x > 0 )
1054  {
1055  for( size_t ii = 0; ii < poly->GetSegmentCount(); ++ii )
1056  {
1057  SEG seg = poly->GetSegment( ii );
1058  m_gal->DrawSegment( seg.A, seg.B, margin.x * 2 );
1059  }
1060  }
1061  }
1062  break;
1063 
1064  default:
1065  // Better not get here; we already pre-flighted the shapes...
1066  break;
1067  }
1068  }
1069  }
1070  else
1071  {
1072  // This is expensive. Avoid if possible.
1073 
1074  SHAPE_POLY_SET polySet;
1075  aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ), margin.x,
1076  bds.m_MaxError, ERROR_INSIDE );
1077  m_gal->DrawPolygon( polySet );
1078  }
1079 
1080  if( aPad->GetSize() != pad_size )
1081  const_cast<PAD*>( aPad )->SetSize( pad_size );
1082  }
1083 
1084  // Clearance outlines
1085  constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_PADS;
1086 
1087  if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags
1088  && ( aLayer == LAYER_PAD_FR || aLayer == LAYER_PAD_BK || aLayer == LAYER_PADS_TH ) )
1089  {
1090  bool flashActiveLayer = aPad->FlashLayer( m_pcbSettings.GetActiveLayer() );
1091 
1092  if( flashActiveLayer || aPad->GetDrillSize().x )
1093  {
1095  m_gal->SetIsStroke( true );
1096  m_gal->SetIsFill( false );
1098 
1099  int clearance = aPad->GetOwnClearance( m_pcbSettings.GetActiveLayer() );
1100 
1101  if( flashActiveLayer && clearance > 0 )
1102  {
1103  auto shape = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
1104 
1105  if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_SEGMENT )
1106  {
1107  const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape->Shapes()[0];
1108  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
1109  seg->GetWidth() + 2 * clearance );
1110  }
1111  else if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_CIRCLE )
1112  {
1113  const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape->Shapes()[0];
1114  m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + clearance );
1115  }
1116  else
1117  {
1118  SHAPE_POLY_SET polySet;
1119  aPad->TransformShapeWithClearanceToPolygon( polySet, ToLAYER_ID( aLayer ),
1120  clearance,
1121  bds.m_MaxError, ERROR_OUTSIDE );
1122  m_gal->DrawPolygon( polySet );
1123  }
1124  }
1125  else if( aPad->GetEffectiveHoleShape() && clearance > 0 )
1126  {
1127  clearance += bds.GetHolePlatingThickness();
1128 
1129  const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
1130  m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
1131  seg->GetWidth() + 2 * clearance );
1132  }
1133  }
1134  }
1135 }
1136 
1137 
1138 void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
1139 {
1140  const COLOR4D& color = m_pcbSettings.GetColor( aShape, aShape->GetLayer() );
1141  bool sketch = m_pcbSettings.m_sketchGraphics;
1142  int thickness = getLineThickness( aShape->GetWidth() );
1143  VECTOR2D start( aShape->GetStart() );
1144  VECTOR2D end( aShape->GetEnd() );
1145 
1146  if( sketch )
1147  {
1148  m_gal->SetIsFill( false );
1149  m_gal->SetIsStroke( true );
1151  }
1152 
1153  m_gal->SetFillColor( color );
1155 
1156  switch( aShape->GetShape() )
1157  {
1158  case S_SEGMENT:
1159  if( sketch )
1160  {
1161  m_gal->DrawSegment( start, end, thickness );
1162  }
1163  else
1164  {
1165  m_gal->SetIsFill( true );
1166  m_gal->SetIsStroke( false );
1167 
1168  m_gal->DrawSegment( start, end, thickness );
1169  }
1170  break;
1171 
1172  case S_RECT:
1173  {
1174  std::vector<wxPoint> pts = aShape->GetRectCorners();
1175 
1176  if( sketch )
1177  {
1178  m_gal->DrawSegment( pts[0], pts[1], thickness );
1179  m_gal->DrawSegment( pts[1], pts[2], thickness );
1180  m_gal->DrawSegment( pts[2], pts[3], thickness );
1181  m_gal->DrawSegment( pts[3], pts[0], thickness );
1182  }
1183  else
1184  {
1185  m_gal->SetIsFill( true );
1186  m_gal->SetIsStroke( false );
1187 
1188  if( thickness > 0 )
1189  {
1190  m_gal->DrawSegment( pts[0], pts[1], thickness );
1191  m_gal->DrawSegment( pts[1], pts[2], thickness );
1192  m_gal->DrawSegment( pts[2], pts[3], thickness );
1193  m_gal->DrawSegment( pts[3], pts[0], thickness );
1194  }
1195 
1196  if( aShape->IsFilled() )
1197  {
1198  SHAPE_POLY_SET poly;
1199  poly.NewOutline();
1200 
1201  for( const wxPoint& pt : pts )
1202  poly.Append( pt );
1203 
1204  m_gal->DrawPolygon( poly );
1205  }
1206  }
1207  }
1208  break;
1209 
1210  case S_ARC:
1211  if( sketch )
1212  {
1213  m_gal->DrawArcSegment( start, aShape->GetRadius(),
1214  DECIDEG2RAD( aShape->GetArcAngleStart() ),
1215  DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this
1216  thickness );
1217  }
1218  else
1219  {
1220  m_gal->SetIsFill( true );
1221  m_gal->SetIsStroke( false );
1222 
1223  m_gal->DrawArcSegment( start, aShape->GetRadius(),
1224  DECIDEG2RAD( aShape->GetArcAngleStart() ),
1225  DECIDEG2RAD( aShape->GetArcAngleStart() + aShape->GetAngle() ), // Change this
1226  thickness );
1227  }
1228  break;
1229 
1230  case S_CIRCLE:
1231  if( sketch )
1232  {
1233  m_gal->DrawCircle( start, aShape->GetRadius() - thickness / 2 );
1234  m_gal->DrawCircle( start, aShape->GetRadius() + thickness / 2 );
1235  }
1236  else
1237  {
1238  m_gal->SetIsFill( aShape->IsFilled() );
1239  m_gal->SetIsStroke( thickness > 0 );
1240  m_gal->SetLineWidth( thickness );
1241 
1242  m_gal->DrawCircle( start, aShape->GetRadius() );
1243  }
1244  break;
1245 
1246  case S_POLYGON:
1247  {
1248  SHAPE_POLY_SET& shape = const_cast<PCB_SHAPE*>( aShape )->GetPolyShape();
1249  FOOTPRINT* parentFootprint = aShape->GetParentFootprint();
1250 
1251  if( shape.OutlineCount() == 0 )
1252  break;
1253 
1254  if( parentFootprint )
1255  {
1256  m_gal->Save();
1257  m_gal->Translate( parentFootprint->GetPosition() );
1258  m_gal->Rotate( -parentFootprint->GetOrientationRadians() );
1259  }
1260 
1261  if( sketch )
1262  {
1263  for( int ii = 0; ii < shape.Outline( 0 ).SegmentCount(); ++ii )
1264  {
1265  SEG seg = shape.Outline( 0 ).Segment( ii );
1266  m_gal->DrawSegment( seg.A, seg.B, thickness );
1267  }
1268  }
1269  else
1270  {
1271  m_gal->SetIsFill( true );
1272  m_gal->SetIsStroke( false );
1273 
1274  if( thickness > 0 )
1275  {
1276  for( int ii = 0; ii < shape.Outline( 0 ).SegmentCount(); ++ii )
1277  {
1278  SEG seg = shape.Outline( 0 ).Segment( ii );
1279  m_gal->DrawSegment( seg.A, seg.B, thickness );
1280  }
1281  }
1282 
1283  if( aShape->IsFilled() )
1284  {
1285  // On Opengl, a not convex filled polygon is usually drawn by using triangles
1286  // as primitives. CacheTriangulation() can create basic triangle primitives to
1287  // draw the polygon solid shape on Opengl. GLU tesselation is much slower, so
1288  // currently we are using our tesselation.
1289  if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() )
1290  shape.CacheTriangulation();
1291 
1292  m_gal->DrawPolygon( shape );
1293  }
1294  }
1295 
1296  if( parentFootprint )
1297  m_gal->Restore();
1298  }
1299  break;
1300 
1301  case S_CURVE:
1302  if( sketch )
1303  {
1304  // Use thickness as filter value to convert the curve to polyline when the curve
1305  // is not supported
1306  m_gal->DrawCurve( VECTOR2D( aShape->GetStart() ),
1307  VECTOR2D( aShape->GetBezControl1() ),
1308  VECTOR2D( aShape->GetBezControl2() ),
1309  VECTOR2D( aShape->GetEnd() ), thickness );
1310  }
1311  else
1312  {
1313  m_gal->SetIsFill( aShape->IsFilled() );
1314  m_gal->SetIsStroke( thickness > 0 );
1315  m_gal->SetLineWidth( thickness );
1316 
1317  // Use thickness as filter value to convert the curve to polyline when the curve
1318  // is not supported
1319  m_gal->DrawCurve( VECTOR2D( aShape->GetStart() ),
1320  VECTOR2D( aShape->GetBezControl1() ),
1321  VECTOR2D( aShape->GetBezControl2() ),
1322  VECTOR2D( aShape->GetEnd() ), thickness );
1323  }
1324  break;
1325 
1326  case S_LAST:
1327  break;
1328  }
1329 }
1330 
1331 
1332 void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer )
1333 {
1334  wxString shownText( aText->GetShownText() );
1335 
1336  if( shownText.Length() == 0 )
1337  return;
1338 
1339  const COLOR4D& color = m_pcbSettings.GetColor( aText, aText->GetLayer() );
1340  VECTOR2D position( aText->GetTextPos().x, aText->GetTextPos().y );
1341 
1343  {
1344  // Outline mode
1346  }
1347  else
1348  {
1349  // Filled mode
1351  }
1352 
1354  m_gal->SetIsFill( false );
1355  m_gal->SetIsStroke( true );
1356  m_gal->SetTextAttributes( aText );
1357  m_gal->StrokeText( shownText, position, aText->GetTextAngleRadians() );
1358 }
1359 
1360 
1361 void PCB_PAINTER::draw( const FP_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, aLayer );
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->GetDrawRotationRadians() );
1387 
1388  // Draw the umbilical line
1389  if( aText->IsSelected() )
1390  {
1392  m_gal->SetStrokeColor( COLOR4D( 0.0, 0.0, 1.0, 1.0 ) );
1393  m_gal->DrawLine( position, aText->GetParent()->GetPosition() );
1394  }
1395 }
1396 
1397 
1398 void PCB_PAINTER::draw( const FOOTPRINT* aFootprint, int aLayer )
1399 {
1400  if( aLayer == LAYER_ANCHOR )
1401  {
1402  const COLOR4D color = m_pcbSettings.GetColor( aFootprint, aLayer );
1403 
1404  // Keep the size and width constant, not related to the scale because the anchor
1405  // is just a marker on screen
1406  double anchorSize = 5.0 / m_gal->GetWorldScale(); // 5 pixels size
1407  double anchorThickness = 1.0 / m_gal->GetWorldScale(); // 1 pixels width
1408 
1409  // Draw anchor
1410  m_gal->SetIsFill( false );
1411  m_gal->SetIsStroke( true );
1413  m_gal->SetLineWidth( anchorThickness );
1414 
1415  VECTOR2D center = aFootprint->GetPosition();
1416  m_gal->DrawLine( center - VECTOR2D( anchorSize, 0 ), center + VECTOR2D( anchorSize, 0 ) );
1417  m_gal->DrawLine( center - VECTOR2D( 0, anchorSize ), center + VECTOR2D( 0, anchorSize ) );
1418 
1419 #if 0 // For debug purpose only: draw the footing bounding box
1420  double bboxThickness = 1.0 / m_gal->GetWorldScale();
1421  m_gal->SetLineWidth( bboxThickness );
1422  EDA_RECT rect = aFootprint->GetBoundingBoxBase();
1423  m_gal->DrawRectangle( VECTOR2D( rect.GetOrigin() ), VECTOR2D( rect.GetEnd() ) );
1424 #endif
1425  }
1426 }
1427 
1428 
1429 void PCB_PAINTER::draw( const PCB_GROUP* aGroup, int aLayer )
1430 {
1431  if( aLayer == LAYER_ANCHOR )
1432  {
1433  const COLOR4D color = m_pcbSettings.GetColor( aGroup, LAYER_ANCHOR );
1434 
1435  EDA_RECT bbox = aGroup->GetBoundingBox();
1438  wxPoint topLeft = bbox.GetPosition();
1439  wxPoint width = wxPoint( bbox.GetWidth(), 0 );
1440  wxPoint height = wxPoint( 0, bbox.GetHeight() );
1441 
1442  m_gal->DrawLine( topLeft, topLeft + width );
1443  m_gal->DrawLine( topLeft + width, topLeft + width + height );
1444  m_gal->DrawLine( topLeft + width + height, topLeft + height );
1445  m_gal->DrawLine( topLeft + height, topLeft );
1446 
1447  wxString name = aGroup->GetName();
1448 
1449  int ptSize = 12;
1450  int scaledSize = abs( KiROUND( m_gal->GetScreenWorldMatrix().GetScale().x * ptSize ) );
1451  int unscaledSize = Mils2iu( ptSize );
1452 
1453  // Scale by zoom a bit, but not too much
1454  int textSize = ( scaledSize + ( unscaledSize * 2 ) ) / 3;
1455  int penWidth = textSize / 10;
1456  wxPoint textOffset = wxPoint( width.x / 2, - KiROUND( textSize * 0.5 ) );
1457  wxPoint titleHeight = wxPoint( 0, KiROUND( textSize * 2.0 ) );
1458 
1459  if( !name.IsEmpty() && (int) aGroup->GetName().Length() * textSize < bbox.GetWidth() )
1460  {
1461  m_gal->DrawLine( topLeft, topLeft - titleHeight );
1462  m_gal->DrawLine( topLeft - titleHeight, topLeft + width - titleHeight );
1463  m_gal->DrawLine( topLeft + width - titleHeight, topLeft + width );
1464 
1465  m_gal->SetFontBold( false );
1466  m_gal->SetFontItalic( true );
1467  m_gal->SetFontUnderlined( false );
1471  m_gal->SetIsFill( false );
1472  m_gal->SetGlyphSize( VECTOR2D( textSize, textSize ) );
1473  m_gal->SetLineWidth( penWidth );
1474  m_gal->StrokeText( aGroup->GetName(), topLeft + textOffset, 0.0 );
1475  }
1476  }
1477 }
1478 
1479 
1480 void PCB_PAINTER::draw( const ZONE* aZone, int aLayer )
1481 {
1488  wxASSERT( IsZoneLayer( aLayer ) );
1489  PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( aLayer - LAYER_ZONE_START );
1490 
1491  if( !aZone->IsOnLayer( layer ) )
1492  return;
1493 
1494  COLOR4D color = m_pcbSettings.GetColor( aZone, layer );
1495  std::deque<VECTOR2D> corners;
1497 
1498  // Draw the outline
1499  const SHAPE_POLY_SET* outline = aZone->Outline();
1500 
1501  if( m_pcbSettings.m_zoneOutlines && outline && outline->OutlineCount() > 0 )
1502  {
1504  m_gal->SetIsFill( false );
1505  m_gal->SetIsStroke( true );
1507 
1508  // Draw each contour (main contour and holes)
1509 
1510  /* This line:
1511  * m_gal->DrawPolygon( *outline );
1512  * should be enough, but currently does not work to draw holes contours in a complex polygon
1513  * so each contour is draw as a simple polygon
1514  */
1515 
1516  // Draw the main contour
1517  m_gal->DrawPolyline( outline->COutline( 0 ) );
1518 
1519  // Draw holes
1520  int holes_count = outline->HoleCount( 0 );
1521 
1522  for( int ii = 0; ii < holes_count; ++ii )
1523  m_gal->DrawPolyline( outline->CHole( 0, ii ) );
1524 
1525  // Draw hatch lines
1526  for( const SEG& hatchLine : aZone->GetHatchLines() )
1527  m_gal->DrawLine( hatchLine.A, hatchLine.B );
1528  }
1529 
1530  // Draw the filling
1531  if( displayMode != ZONE_DISPLAY_MODE::HIDE_FILLED )
1532  {
1533  const SHAPE_POLY_SET& polySet = aZone->GetFilledPolysList( layer );
1534 
1535  if( polySet.OutlineCount() == 0 ) // Nothing to draw
1536  return;
1537 
1538  // Set up drawing options
1539  int outline_thickness = 0;
1540 
1541  if( aZone->GetFilledPolysUseThickness( layer ) )
1542  outline_thickness = aZone->GetMinThickness();
1543 
1545  m_gal->SetFillColor( color );
1546  m_gal->SetLineWidth( outline_thickness );
1547 
1548  if( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED )
1549  {
1550  m_gal->SetIsFill( true );
1551  m_gal->SetIsStroke( outline_thickness > 0 );
1552  }
1553  else if( displayMode == ZONE_DISPLAY_MODE::SHOW_OUTLINED )
1554  {
1555  m_gal->SetIsFill( false );
1556  m_gal->SetIsStroke( true );
1557  }
1558 
1559  m_gal->DrawPolygon( polySet );
1560  }
1561 }
1562 
1563 
1564 void PCB_PAINTER::draw( const DIMENSION_BASE* aDimension, int aLayer )
1565 {
1566  const COLOR4D& strokeColor = m_pcbSettings.GetColor( aDimension, aLayer );
1567 
1568  m_gal->SetStrokeColor( strokeColor );
1569  m_gal->SetIsFill( false );
1570  m_gal->SetIsStroke( true );
1571 
1573  {
1574  // Outline mode
1576  }
1577  else
1578  {
1579  // Filled mode
1580  m_gal->SetLineWidth( getLineThickness( aDimension->GetLineThickness() ) );
1581  }
1582 
1583  // Draw dimension shapes
1584  // TODO(JE) lift this out
1585  for( const std::shared_ptr<SHAPE>& shape : aDimension->GetShapes() )
1586  {
1587  switch( shape->Type() )
1588  {
1589  case SH_SEGMENT:
1590  {
1591  const SEG& seg = static_cast<const SHAPE_SEGMENT*>( shape.get() )->GetSeg();
1592  m_gal->DrawLine( seg.A, seg.B );
1593  break;
1594  }
1595 
1596  case SH_CIRCLE:
1597  {
1598  int radius = static_cast<const SHAPE_CIRCLE*>( shape.get() )->GetRadius();
1599  m_gal->DrawCircle( shape->Centre(), radius );
1600  break;
1601  }
1602 
1603  default:
1604  break;
1605  }
1606  }
1607  // Draw text
1608  PCB_TEXT& text = aDimension->Text();
1609  VECTOR2D position( text.GetTextPos().x, text.GetTextPos().y );
1610 
1612  {
1613  // Outline mode
1615  }
1616  else
1617  {
1618  // Filled mode
1620  }
1621 
1622  m_gal->SetTextAttributes( &text );
1623  m_gal->StrokeText( text.GetShownText(), position, text.GetTextAngleRadians() );
1624 }
1625 
1626 
1627 void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
1628 {
1629  const COLOR4D& strokeColor = m_pcbSettings.GetColor( aTarget, aTarget->GetLayer() );
1630  VECTOR2D position( aTarget->GetPosition() );
1631  double size, radius;
1632 
1633  m_gal->SetLineWidth( getLineThickness( aTarget->GetWidth() ) );
1634  m_gal->SetStrokeColor( strokeColor );
1635  m_gal->SetIsFill( false );
1636  m_gal->SetIsStroke( true );
1637 
1638  m_gal->Save();
1639  m_gal->Translate( position );
1640 
1641  if( aTarget->GetShape() )
1642  {
1643  // shape x
1644  m_gal->Rotate( M_PI / 4.0 );
1645  size = 2.0 * aTarget->GetSize() / 3.0;
1646  radius = aTarget->GetSize() / 2.0;
1647  }
1648  else
1649  {
1650  // shape +
1651  size = aTarget->GetSize() / 2.0;
1652  radius = aTarget->GetSize() / 3.0;
1653  }
1654 
1655  m_gal->DrawLine( VECTOR2D( -size, 0.0 ), VECTOR2D( size, 0.0 ) );
1656  m_gal->DrawLine( VECTOR2D( 0.0, -size ), VECTOR2D( 0.0, size ) );
1657  m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), radius );
1658 
1659  m_gal->Restore();
1660 }
1661 
1662 
1663 void PCB_PAINTER::draw( const PCB_MARKER* aMarker, int aLayer )
1664 {
1665  bool isShadow = aLayer == LAYER_MARKER_SHADOWS;
1666 
1667  // Don't paint shadows for invisible markers.
1668  // It would be nice to do this through layer dependencies but we can't do an "or" there today
1669  if( isShadow && aMarker->GetBoard() &&
1670  !aMarker->GetBoard()->IsElementVisible( aMarker->GetColorLayer() ) )
1671  return;
1672 
1673  SHAPE_LINE_CHAIN polygon;
1674  aMarker->ShapeToPolygon( polygon );
1675 
1676 
1677 
1679  : aMarker->GetColorLayer() );
1680 
1681  m_gal->Save();
1682  m_gal->Translate( aMarker->GetPosition() );
1683 
1684  if( isShadow )
1685  {
1687  m_gal->SetIsStroke( true );
1688  m_gal->SetLineWidth( aMarker->MarkerScale() );
1689  }
1690  else
1691  {
1692  m_gal->SetFillColor( color );
1693  m_gal->SetIsFill( true );
1694  }
1695 
1696  m_gal->DrawPolygon( polygon );
1697  m_gal->Restore();
1698 }
1699 
1700 
1701 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
const std::set< unsigned int > GetHighContrastLayers() const
Function GetHighContrastLayers() Returns the set of currently high-contrast layers.
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:422
Definition: track.h:354
to draw blind/buried vias
virtual void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a rectangle.
const int GetSizeY() const
Definition: pad.h:230
virtual wxPoint GetCenter() const override
Function GetCenter()
Definition: track.h:312
bool IsFilled() const
Definition: pcb_shape.h:96
SHAPE_SIMPLE.
Definition: shape_simple.h:43
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:88
class LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:102
double GetOrientationRadians() const
Definition: footprint.h:206
int OutlineCount() const
Returns the number of outlines in the set
const int GetDrillSizeX() const
Definition: pad.h:238
class FP_TEXT, text in a footprint
Definition: typeinfo.h:93
COLOR4D Inverted() const
Function Inverted Returns an inverted color, alpha remains the same.
Definition: color4d.h:327
int GetRadius() const
Definition: shape_circle.h:99
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:214
bool IsSelected() const
Definition: eda_item.h:191
ZONE_DISPLAY_MODE
Determines how zones should be displayed
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:155
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: track.h:116
double m_TrackOpacity
Opacity override for all tracks.
PCB_GROUP is a set of BOARD_ITEMs (i.e., without duplicates)
Definition: pcb_group.h:50
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:103
virtual void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle)
Draw an arc.
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
SHAPE_POLY_SET * Outline()
Definition: zone.h:318
int GetRadius() const
Function GetRadius returns the radius of this item Has meaning only for arc and circle.
Definition: pcb_shape.h:200
int color
Definition: DXF_plotter.cpp:60
std::vector< wxPoint > GetRectCorners() const
Definition: pcb_shape.cpp:942
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:415
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:56
Net/netclass colors are shown on ratsnest lines only.
int GetWidth() const
Definition: eda_rect.h:119
bool m_padNumbers
Flag determining if pad numbers should be visible
Definition: pcb_painter.h:200
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
to draw via holes (pad holes do not use this layer)
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
COLOR4D WithAlpha(double aAlpha) const
Function WithAlpha Returns a colour with the same colour, but the given alpha.
Definition: color4d.h:315
usual segment : line with rounded ends
Definition: board_item.h:52
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Function GetEffectiveHoleShape Returns a SHAPE object representing the pad's hole.
Definition: pcbnew/pad.cpp:270
wxString GetNetname() const
Function GetNetname.
virtual bool IsOnLayer(PCB_LAYER_ID) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: zone.cpp:313
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:559
bool IsBrightened() const
Definition: eda_item.h:193
Arcs (with rounded ends)
Definition: board_item.h:54
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
class 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_POLY_SET & GetFilledPolysList(PCB_LAYER_ID aLayer) const
Function GetFilledPolysList returns a reference to the list of filled polygons.
Definition: zone.h:647
PAD_SHAPE_T GetShape() const
Definition: pad.h:159
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
const VECTOR2I GetCenter() const
Definition: shape_circle.h:104
PCB_RENDER_SETTINGS m_pcbSettings
Definition: pcb_painter.h:281
const EDA_RECT GetBoundingBox() const override
Definition: pcb_group.cpp:180
virtual wxPoint GetPosition() const
Definition: eda_item.h:325
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
segment with non rounded ends
Definition: board_item.h:53
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
BOARD_CONNECTED_ITEM is a base class derived from BOARD_ITEM for items that can be connected and have...
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
bool IsTriangulationUpToDate() const
virtual 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
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:109
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:380
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.
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 netclass colors
Definition: pcb_painter.h:235
const VECTOR2I GetSize() const
Function GetSize()
Definition: shape_rect.h:123
wxPoint GetPosition() const override
Definition: pcb_target.h:61
NET_COLOR_MODE m_netColorMode
How to display nets and netclasses with color overrides
Definition: pcb_painter.h:232
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:52
const wxPoint GetEnd() const
Definition: eda_rect.h:116
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:236
PCB_DISPLAY_OPTIONS handles display options like enable/disable some optional drawings.
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:57
double a
Alpha component.
Definition: color4d.h:377
bool FlashLayer(int aLayer) const
Definition: pcbnew/pad.cpp:189
int getLineThickness(int aActualThickness) const
Function getLineThickness() 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:171
COLOR4D m_layerColorsDark[LAYER_ID_COUNT]
int GetMinThickness() const
Definition: zone.h:242
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:815
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
last value for this list
Definition: board_item.h:58
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:170
wxString GetName() const
Definition: pcb_group.h:65
bool m_hiContrastEnabled
Parameters for display modes.
virtual void update()
Function update Precalculates extra colors for layers (e.g.
SHAPE_POLY_SET.
bool FlashLayer(int aLayer) const
Checks to see whether the via should have a pad on the specific layer.
Definition: track.cpp:481
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
const wxPoint GetOrigin() const
Definition: eda_rect.h:114
bool IsZoneLayer(LAYER_NUM aLayer)
const VECTOR2I & GetPosition() const
Function GetPosition()
Definition: shape_rect.h:113
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:385
void SetBackgroundColor(const COLOR4D &aColor) override
Sets the background color.
Definition: pcb_painter.h:149
const wxSize & GetSize() const
Definition: pad.h:226
to draw usual through hole vias
PCB_TEXT & Text()
Definition: dimension.h:209
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Definition: pcb_shape.h:144
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
const wxString & GetName() const
Definition: pad.h:127
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox The bounding box is cached, so this will be efficient most of the time.
Definition: pcbnew/pad.cpp:470
RATSNEST_MODE m_ratsnestDisplayMode
Definition: pcb_painter.h:246
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
Function GetEffectiveShape Some pad shapes can be complex (rounded/chamfered rectangle),...
Definition: pcbnew/pad.cpp:261
virtual bool IsOpenGlEngine()
Returns 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:106
SHAPE.
Definition: shape.h:122
void SetTextMirrored(const bool aMirrored)
Set a mirrored property of text.
double GetRadius() const
Definition: track.cpp:883
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.
void SetFontItalic(bool aItalic)
Set italic property of current font.
GAL_LAYER_ID GetColorLayer() const
Definition: pcb_marker.cpp:182
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
int SegmentCount() const
Function SegmentCount()
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
line chain (polyline)
Definition: shape.h:46
double m_ZoneOpacity
Opacity override for filled zone areas.
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
class FOOTPRINT, a footprint
Definition: typeinfo.h:89
bool IsElementVisible(GAL_LAYER_ID aLayer) const
Test whether a given element category is visible.
Definition: board.cpp:497
int GetSolderMaskMargin() const
Function GetSolderMaskMargin.
Definition: pcbnew/pad.cpp:649
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon, int aScale=-1) const
Returns the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to th...
Definition: seg.h:39
virtual size_t GetSegmentCount() const override
Definition: shape_simple.h:187
double GetTextAngleRadians() const
Definition: eda_text.h:183
double GetAngle() const
Definition: track.cpp:889
bool GetHighContrast() const
int MarkerScale() const
The scaling factor to convert polygonal shape coordinates to internal units.
Definition: marker_base.h:81
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
Function TransformShapeWithClearanceToPolygon Convert the pad shape to a closed polygon.
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
SEG Segment(int aIndex)
Function Segment()
bool m_netNamesOnTracks
Flag determining if net names should be visible for tracks
Definition: pcb_painter.h:206
double m_trackOpacity
Opacity override for all tracks.
Definition: pcb_painter.h:249
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:99
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: 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.
void SetFontUnderlined(bool aUnderlined)
const char * name
Definition: DXF_plotter.cpp:59
wxSize GetSolderPasteMargin() const
Function GetSolderPasteMargin.
Definition: pcbnew/pad.cpp:694
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:457
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: pad.h:339
Definition: track.h:272
const int GetDrillSizeY() const
Definition: pad.h:240
SHAPE_LINE_CHAIN.
COLOR4D & Darken(double aFactor)
Function Darken Makes the color darker by a given factor.
Definition: color4d.h:231
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,...
const wxPoint & GetBezControl2() const
Definition: pcb_shape.h:135
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:95
VECTOR2I A
Definition: seg.h:47
double GetAngle() const
Definition: pcb_shape.h:126
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
double DECIDEG2RAD(double deg)
Definition: trigo.h:221
ZONE_DISPLAY_MODE m_ZoneDisplayMode
int GetShape() const
Definition: pcb_target.h:64
HIGH_CONTRAST_MODE m_contrastModeDisplay
How to display inactive layers (HIGH_CONTRAST_MODE:NORMAL, DIMMED or HIDDEN )
Definition: pcb_painter.h:244
const int GetSizeX() const
Definition: pad.h:228
VIATYPE GetViaType() const
Definition: track.h:384
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
EDA_ITEM is a base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:148
PCB_LAYER_ID GetActiveLayer() const
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 GetPosition() const override
Definition: footprint.h:200
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Function GetClearance returns an item's "own" clearance in internal units.
wxPoint Centre() const
Definition: eda_rect.h:62
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:55
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:254
virtual void DrawArcSegment(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle, double aWidth)
Draw an arc segment.
const int GetHeight() const
Function GetHeight()
Definition: shape_rect.h:143
class ORTHOGONAL_DIMENSION, a linear dimension constrained to x/y
Definition: typeinfo.h:104
double GetArcAngleStart() const
Definition: track.cpp:901
void CacheTriangulation(bool aPartition=true)
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:299
bool m_zoneOutlines
Flag determining if zones should have outlines drawn
Definition: pcb_painter.h:212
Definition: shape.h:43
Non-active layers are dimmed (old high-contrast mode)
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Returns the board layer which is in high-contrast.
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:129
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Function IsOnLayer tests to see if this object is on the given layer.
Definition: track.cpp:348
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
Function GetWidth()
Definition: shape_rect.h:133
Definition: pad.h:59
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:179
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:405
Abstract dimension API.
Definition: dimension.h:95
int GetWidth() const
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:91
wxPoint GetPosition() const override
Definition: pcb_marker.h:67
Bezier Curve.
Definition: board_item.h:57
static constexpr int Millimeter2iu(double mm)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Definition: board_item.h:185
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
Definition: netinfo.h:478
std::set< int > m_highlightNetcodes
EDA_RECT GetBoundingBoxBase() const
Returns the last calculated bounding box of the footprint (does not recalculate it).
Definition: footprint.h:161
const wxPoint & GetBezControl1() const
Definition: pcb_shape.h:132
Definition of PCB_DISPLAY_OPTIONS class.
circle
Definition: shape.h:47
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:898
Definition: track.h:83
Additional netnames layers (not associated with a PCB layer)
Outlines of filled polygons are shown.
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: eda_item.h:181
axis-aligned rectangle
Definition: shape.h:44
Class GAL is the abstract interface for drawing on a 2D-surface.
bool GetFilledPolysUseThickness() const
Definition: zone.h:704
bool m_globalRatsnestlines
Flag determining if ratsnest lines are shown by default
Definition: pcb_painter.h:218
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.
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:100
VECTOR2I B
Definition: seg.h:48