Overhaul the pad drawing special cases yet again.
New strategy is to draw the hole wall cylinder if the pad (or via) isn't flashed on a particular layer. This is (1) more correct, (2) keeps pads which aren't flashed on any layer from disappearing, and (3) allows us to remove a bunch of the other special cases. Or at least I think it does. The proof will be in the (lack of) follow-on bug reports.... Also fixes a bug where via annular rings weren't highlighted in high contrast mode. Fixes https://gitlab.com/kicad/code/kicad/issues/7279
This commit is contained in:
parent
78dbcdcdb7
commit
636ae012ed
|
@ -1252,10 +1252,6 @@ double PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
|
||||||
{
|
{
|
||||||
LSET visible = board->GetVisibleLayers() & board->GetEnabledLayers();
|
LSET visible = board->GetVisibleLayers() & board->GetEnabledLayers();
|
||||||
|
|
||||||
// Only draw the pad if at least one of the layers it crosses is being displayed
|
|
||||||
if( !FlashLayer( visible ) )
|
|
||||||
return HIDE;
|
|
||||||
|
|
||||||
// Don't draw the copper ring of a PTH if none of the copper layers are visible
|
// Don't draw the copper ring of a PTH if none of the copper layers are visible
|
||||||
if( aLayer == LAYER_PADS_TH && ( LSET::AllCuMask() & GetLayerSet() & visible ).none() )
|
if( aLayer == LAYER_PADS_TH && ( LSET::AllCuMask() & GetLayerSet() & visible ).none() )
|
||||||
return HIDE;
|
return HIDE;
|
||||||
|
|
|
@ -280,6 +280,7 @@ void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( PCB_LAYER_ID aLayer )
|
||||||
GetNetnameLayer( aLayer ),
|
GetNetnameLayer( aLayer ),
|
||||||
ZONE_LAYER_FOR( aLayer ),
|
ZONE_LAYER_FOR( aLayer ),
|
||||||
LAYER_PADS_TH, LAYER_PADS_PLATEDHOLES, LAYER_NON_PLATEDHOLES,
|
LAYER_PADS_TH, LAYER_PADS_PLATEDHOLES, LAYER_NON_PLATEDHOLES,
|
||||||
|
LAYER_VIA_THROUGH, LAYER_VIA_BBLIND, LAYER_VIA_MICROVIA,
|
||||||
LAYER_DRC_ERROR, LAYER_DRC_WARNING, LAYER_DRC_EXCLUSION, LAYER_MARKER_SHADOWS,
|
LAYER_DRC_ERROR, LAYER_DRC_WARNING, LAYER_DRC_EXCLUSION, LAYER_MARKER_SHADOWS,
|
||||||
LAYER_SELECT_OVERLAY, LAYER_GP_OVERLAY,
|
LAYER_SELECT_OVERLAY, LAYER_GP_OVERLAY,
|
||||||
LAYER_RATSNEST, LAYER_CURSOR, LAYER_ANCHOR
|
LAYER_RATSNEST, LAYER_CURSOR, LAYER_ANCHOR
|
||||||
|
|
|
@ -235,38 +235,27 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons
|
||||||
if( !item )
|
if( !item )
|
||||||
return m_layerColors[aLayer];
|
return m_layerColors[aLayer];
|
||||||
|
|
||||||
// Pad hole color is pad-type-specific: the background color for PTHs (which are assumed
|
if( aLayer == LAYER_PADS_PLATEDHOLES
|
||||||
// to have an annular ring) and the pad color for NPTHs (which are assumed *not* to have
|
|| aLayer == LAYER_NON_PLATEDHOLES
|
||||||
// an annular ring).
|
|| aLayer == LAYER_VIAS_HOLES )
|
||||||
// However, this means a PTH pad with *no* annular ring won't get drawn, so we need to
|
|
||||||
// special-case that.
|
|
||||||
// We have the opposite issue when printing in B&W: both a PTH hole and its annular ring
|
|
||||||
// will normally get assigned black, so we need to special-case that too.
|
|
||||||
if( aLayer == LAYER_PADS_PLATEDHOLES || aLayer == LAYER_NON_PLATEDHOLES )
|
|
||||||
{
|
{
|
||||||
const PAD* pad = static_cast<const PAD*>( item );
|
// Careful that we don't end up with the same colour for the annular ring and the hole
|
||||||
bool hasAnnularRing = pad->GetSizeX() > pad->GetDrillSizeX()
|
// when printing in B&W.
|
||||||
&& pad->GetSizeY() > pad->GetDrillSizeY();
|
const PAD* pad = dynamic_cast<const PAD*>( item );
|
||||||
|
const VIA* via = dynamic_cast<const VIA*>( item );
|
||||||
if( !hasAnnularRing && m_layerColors[ aLayer ] == m_layerColors[ LAYER_PCB_BACKGROUND ] )
|
int holeLayer = aLayer;
|
||||||
aLayer = LAYER_MOD_TEXT_INVISIBLE;
|
|
||||||
|
|
||||||
if( hasAnnularRing && m_layerColors[ aLayer ] == m_layerColors[ LAYER_PADS_TH ] )
|
|
||||||
aLayer = LAYER_PCB_BACKGROUND;
|
|
||||||
}
|
|
||||||
else if( aLayer == LAYER_VIAS_HOLES )
|
|
||||||
{
|
|
||||||
const VIA* via = static_cast<const VIA*>( item );
|
|
||||||
int annularRingLayer;
|
int annularRingLayer;
|
||||||
|
|
||||||
if( via->GetViaType() == VIATYPE::MICROVIA )
|
if( pad )
|
||||||
|
annularRingLayer = LAYER_PADS_TH;
|
||||||
|
else if( via->GetViaType() == VIATYPE::MICROVIA )
|
||||||
annularRingLayer = LAYER_VIA_MICROVIA;
|
annularRingLayer = LAYER_VIA_MICROVIA;
|
||||||
else if( via->GetViaType() == VIATYPE::BLIND_BURIED )
|
else if( via->GetViaType() == VIATYPE::BLIND_BURIED )
|
||||||
annularRingLayer = LAYER_VIA_BBLIND;
|
annularRingLayer = LAYER_VIA_BBLIND;
|
||||||
else
|
else
|
||||||
annularRingLayer = LAYER_VIA_THROUGH;
|
annularRingLayer = LAYER_VIA_THROUGH;
|
||||||
|
|
||||||
if( m_layerColors[ aLayer ] == m_layerColors[ annularRingLayer ] )
|
if( m_layerColors[ holeLayer ] == m_layerColors[ annularRingLayer ] )
|
||||||
aLayer = LAYER_PCB_BACKGROUND;
|
aLayer = LAYER_PCB_BACKGROUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,33 +331,12 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons
|
||||||
PCB_LAYER_ID primary = GetPrimaryHighContrastLayer();
|
PCB_LAYER_ID primary = GetPrimaryHighContrastLayer();
|
||||||
bool isActive = m_highContrastLayers.count( aLayer );
|
bool isActive = m_highContrastLayers.count( aLayer );
|
||||||
|
|
||||||
// We currently add synthetic drawing layers (LAYER_VIA_THROUGH, LAYER_PAD_FR, etc.) to
|
// Track annotations are drawn on synthetic layers, but we only want them drawn if the
|
||||||
// m_highContrastLayers, but it's not sufficiently fine-grained as it can't differentiate
|
// track itself is on the primary layer.
|
||||||
// between (for instance) a via which is flashed on the primary layer and one that is not.
|
|
||||||
// So we need to refine isActive to be more discriminating for some items.
|
|
||||||
if( IsCopperLayer( primary ) )
|
|
||||||
{
|
|
||||||
if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
|
if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
|
||||||
{
|
{
|
||||||
// Track itself isn't on a synthetic layer, but its netname annotations are, and
|
if( !static_cast<const TRACK*>( item )->IsOnLayer( primary ) )
|
||||||
// we want to dim them based on whether or not the track is on the primary layer.
|
isActive = false;
|
||||||
isActive = static_cast<const TRACK*>( item )->IsOnLayer( primary );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool flashed = true;
|
|
||||||
|
|
||||||
if( item->Type() == PCB_VIA_T )
|
|
||||||
flashed = static_cast<const VIA*>( item )->FlashLayer( primary, true );
|
|
||||||
else if( item->Type() == PCB_PAD_T )
|
|
||||||
flashed = static_cast<const PAD*>( item )->FlashLayer( primary, true );
|
|
||||||
|
|
||||||
// For pads and vias, we only want to override the active state for copper layers
|
|
||||||
// (both board copper layers such as F_Cu *and* synthetic copper layers such as
|
|
||||||
// LAYER_VIA_THROUGH).
|
|
||||||
if( IsCopperLayer( aLayer, true ) )
|
|
||||||
isActive = flashed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !isActive )
|
if( !isActive )
|
||||||
|
@ -709,12 +677,9 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Vias not connected to copper are optionally not drawn
|
|
||||||
/// We draw instead the hole size to ensure we show the proper clearance
|
|
||||||
if( IsCopperLayer( aLayer ) && !aVia->FlashLayer( aLayer, true ) )
|
|
||||||
radius = getDrillSize( aVia ) / 2.0 ;
|
|
||||||
|
|
||||||
bool sketchMode = false;
|
bool sketchMode = false;
|
||||||
|
BOARD* board = aVia->GetBoard();
|
||||||
|
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||||
COLOR4D color = m_pcbSettings.GetColor( aVia, aLayer );
|
COLOR4D color = m_pcbSettings.GetColor( aVia, aLayer );
|
||||||
|
|
||||||
if( color == COLOR4D::CLEAR )
|
if( color == COLOR4D::CLEAR )
|
||||||
|
@ -743,8 +708,11 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
|
||||||
m_gal->SetFillColor( color );
|
m_gal->SetFillColor( color );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( aVia->GetViaType() == VIATYPE::BLIND_BURIED || aVia->GetViaType() == VIATYPE::MICROVIA )
|
if( aLayer == LAYER_VIAS_HOLES )
|
||||||
&& aLayer != LAYER_VIAS_HOLES
|
{
|
||||||
|
m_gal->DrawCircle( center, radius );
|
||||||
|
}
|
||||||
|
else if( ( aVia->GetViaType() == VIATYPE::BLIND_BURIED || aVia->GetViaType() == VIATYPE::MICROVIA )
|
||||||
&& !m_pcbSettings.GetDrawIndividualViaLayers() )
|
&& !m_pcbSettings.GetDrawIndividualViaLayers() )
|
||||||
{
|
{
|
||||||
// Outer circles of blind/buried and micro-vias are drawn in a special way to indicate the
|
// Outer circles of blind/buried and micro-vias are drawn in a special way to indicate the
|
||||||
|
@ -774,7 +742,30 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Draw the outer circles of normal vias and the holes for all vias
|
bool drawHoleWallOnly = false;
|
||||||
|
|
||||||
|
if( m_pcbSettings.m_hiContrastEnabled && !aVia->IsSelected() )
|
||||||
|
{
|
||||||
|
if( !aVia->FlashLayer( m_pcbSettings.GetPrimaryHighContrastLayer() ) )
|
||||||
|
drawHoleWallOnly = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LSET visible = board->GetVisibleLayers() & board->GetEnabledLayers();
|
||||||
|
|
||||||
|
if( !aVia->FlashLayer( visible ) )
|
||||||
|
drawHoleWallOnly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( drawHoleWallOnly )
|
||||||
|
{
|
||||||
|
m_gal->SetIsFill( false );
|
||||||
|
m_gal->SetIsStroke( true );
|
||||||
|
m_gal->SetStrokeColor( color );
|
||||||
|
m_gal->SetLineWidth( bds.GetHolePlatingThickness() * 2 );
|
||||||
|
radius = getDrillSize( aVia ) / 2.0 ;
|
||||||
|
}
|
||||||
|
|
||||||
m_gal->DrawCircle( center, radius );
|
m_gal->DrawCircle( center, radius );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,7 +908,8 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pad drawing
|
// Pad drawing
|
||||||
BOARD_DESIGN_SETTINGS& bds = aPad->GetBoard()->GetDesignSettings();
|
BOARD* board = aPad->GetBoard();
|
||||||
|
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||||
COLOR4D color = m_pcbSettings.GetColor( aPad, aLayer );
|
COLOR4D color = m_pcbSettings.GetColor( aPad, aLayer );
|
||||||
|
|
||||||
if( m_pcbSettings.m_sketchMode[LAYER_PADS_TH] )
|
if( m_pcbSettings.m_sketchMode[LAYER_PADS_TH] )
|
||||||
|
@ -936,8 +928,58 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
||||||
m_gal->SetFillColor( color );
|
m_gal->SetFillColor( color );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose drawing settings depending on if we are drawing a pad itself or a hole
|
auto drawHoleWallCylinder =
|
||||||
|
[&]( const PAD* aPad )
|
||||||
|
{
|
||||||
|
if( aPad->GetAttribute() != PAD_ATTRIB_PTH )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( m_pcbSettings.m_hiContrastEnabled && !aPad->IsSelected() )
|
||||||
|
{
|
||||||
|
if( !aPad->FlashLayer( m_pcbSettings.GetPrimaryHighContrastLayer() ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LSET visible = board->GetVisibleLayers() & board->GetEnabledLayers();
|
||||||
|
|
||||||
|
if( !aPad->FlashLayer( visible ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aPad->GetShape() != PAD_SHAPE_CUSTOM
|
||||||
|
&& aPad->GetSizeX() <= aPad->GetDrillSizeX()
|
||||||
|
&& aPad->GetSizeY() <= aPad->GetDrillSizeY();
|
||||||
|
};
|
||||||
|
|
||||||
if( aLayer == LAYER_PADS_PLATEDHOLES || aLayer == LAYER_NON_PLATEDHOLES )
|
if( aLayer == LAYER_PADS_PLATEDHOLES || aLayer == LAYER_NON_PLATEDHOLES )
|
||||||
|
{
|
||||||
|
// Drawing the hole ------------------------------------------------------
|
||||||
|
|
||||||
|
const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
|
||||||
|
|
||||||
|
if( seg->GetSeg().A == seg->GetSeg().B ) // Circular hole
|
||||||
|
m_gal->DrawCircle( seg->GetSeg().A, getDrillSize( aPad ).x / 2 );
|
||||||
|
else
|
||||||
|
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() );
|
||||||
|
}
|
||||||
|
else if( drawHoleWallCylinder( aPad ) )
|
||||||
|
{
|
||||||
|
// Drawing only the hole wall --------------------------------------------
|
||||||
|
|
||||||
|
bool draw = true;
|
||||||
|
m_gal->SetIsFill( false );
|
||||||
|
m_gal->SetIsStroke( true );
|
||||||
|
m_gal->SetStrokeColor( color );
|
||||||
|
|
||||||
|
if( aLayer == LAYER_PADS_TH )
|
||||||
|
m_gal->SetLineWidth( bds.GetHolePlatingThickness() * 2 );
|
||||||
|
else if( aLayer == F_Mask || aLayer == B_Mask )
|
||||||
|
m_gal->SetLineWidth( ( bds.GetHolePlatingThickness() + aPad->GetSolderMaskMargin() ) * 2 );
|
||||||
|
else
|
||||||
|
draw = false;
|
||||||
|
|
||||||
|
if( draw )
|
||||||
{
|
{
|
||||||
const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
|
const SHAPE_SEGMENT* seg = aPad->GetEffectiveHoleShape();
|
||||||
|
|
||||||
|
@ -946,15 +988,11 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
|
||||||
else
|
else
|
||||||
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() );
|
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() );
|
||||||
}
|
}
|
||||||
else if( aLayer == LAYER_PADS_TH
|
|
||||||
&& aPad->GetShape() != PAD_SHAPE_CUSTOM
|
|
||||||
&& aPad->GetSizeX() <= aPad->GetDrillSizeX()
|
|
||||||
&& aPad->GetSizeY() <= aPad->GetDrillSizeY() )
|
|
||||||
{
|
|
||||||
// no annular ring to draw
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Drawing the pad -------------------------------------------------------
|
||||||
|
|
||||||
wxSize pad_size = aPad->GetSize();
|
wxSize pad_size = aPad->GetSize();
|
||||||
wxSize margin;
|
wxSize margin;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue