PCB_PAINTER for D_PAD: for round and oval shapes, use native gal draw functions,

instead of convert shapes to polygons.
For small pad sizes (< 0.5mm) the polygonal shape is really ugly.
Moreover, circles and oblong shapes are native in gal and give a much better look.
This commit is contained in:
jean-pierre charras 2020-06-21 19:47:26 +02:00
parent a16c9df79c
commit 7240b3e4d3
1 changed files with 117 additions and 14 deletions

View File

@ -852,7 +852,37 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
case B_Mask: case B_Mask:
{ {
int clearance = aPad->GetSolderMaskMargin(); int clearance = aPad->GetSolderMaskMargin();
if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
{
int radius = (aPad->GetSize().x/2) + clearance;
m_gal->DrawCircle( VECTOR2D( aPad->ShapePos() ), radius );
}
else if( aPad->GetShape() == PAD_SHAPE_OVAL )
{
if( aPad->GetSize().x == aPad->GetSize().y )
{
int radius = (aPad->GetSize().x/2) + clearance;
m_gal->DrawCircle( VECTOR2D( aPad->ShapePos() ), radius );
}
else
{
wxPoint seg_start, seg_end;
aPad->BuildSegmentFromOvalShape( seg_start, seg_end,
aPad->GetOrientation(),
wxSize( 0, 0 ) );
int seg_width = std::min( aPad->GetSize().x, aPad->GetSize().y )
+ 2*clearance;
m_gal->DrawSegment( VECTOR2D( aPad->ShapePos()+seg_start ),
VECTOR2D( aPad->ShapePos()+seg_end ),
seg_width );
}
}
else
{
aPad->TransformShapeWithClearanceToPolygon( polySet, clearance ); aPad->TransformShapeWithClearanceToPolygon( polySet, clearance );
m_gal->DrawPolygon( polySet );
}
} }
break; break;
@ -862,20 +892,62 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
wxSize pad_size = aPad->GetSize(); wxSize pad_size = aPad->GetSize();
wxSize margin = aPad->GetSolderPasteMargin(); wxSize margin = aPad->GetSolderPasteMargin();
const_cast<D_PAD*>(aPad)->SetSize( pad_size + margin + margin ); const_cast<D_PAD*>(aPad)->SetSize( pad_size + margin + margin );
if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
m_gal->DrawCircle( VECTOR2D( aPad->ShapePos() ), aPad->GetSize().x/2 );
else if( aPad->GetShape() == PAD_SHAPE_OVAL )
{
if( aPad->GetSize().x == aPad->GetSize().y )
m_gal->DrawCircle( VECTOR2D( aPad->ShapePos() ), aPad->GetSize().x/2 );
else
{
wxPoint seg_start, seg_end;
aPad->BuildSegmentFromOvalShape( seg_start, seg_end,
aPad->GetOrientation(),
wxSize( 0, 0 ) );
int seg_width = std::min( aPad->GetSize().x, aPad->GetSize().y );
m_gal->DrawSegment( VECTOR2D( aPad->ShapePos()+seg_start ),
VECTOR2D( aPad->ShapePos()+seg_end ),
seg_width );
}
}
else
{
aPad->TransformShapeWithClearanceToPolygon( polySet, 0 ); aPad->TransformShapeWithClearanceToPolygon( polySet, 0 );
m_gal->DrawPolygon( polySet );
}
const_cast<D_PAD*>(aPad)->SetSize( pad_size ); const_cast<D_PAD*>(aPad)->SetSize( pad_size );
} }
break; break;
default: default:
aPad->TransformShapeWithClearanceToPolygon( polySet, 0 ); if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
break; m_gal->DrawCircle( VECTOR2D( aPad->ShapePos() ), aPad->GetSize().x/2 );
else if( aPad->GetShape() == PAD_SHAPE_OVAL )
{
if( aPad->GetSize().x == aPad->GetSize().y )
m_gal->DrawCircle( VECTOR2D( aPad->ShapePos() ), aPad->GetSize().x/2 );
else
{
wxPoint seg_start, seg_end;
aPad->BuildSegmentFromOvalShape( seg_start, seg_end,
aPad->GetOrientation(),
wxSize( 0, 0 ) );
m_gal->DrawSegment( VECTOR2D( aPad->ShapePos()+seg_start ),
VECTOR2D( aPad->ShapePos()+seg_end ),
std::min( aPad->GetSize().x, aPad->GetSize().y ) );
} }
}
else
{
aPad->TransformShapeWithClearanceToPolygon( polySet, 0 );
m_gal->DrawPolygon( polySet ); m_gal->DrawPolygon( polySet );
} }
break;
}
}
// Clearance lines // Clearance outlines
constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_PADS; constexpr int clearanceFlags = PCB_RENDER_SETTINGS::CL_PADS;
if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags if( ( m_pcbSettings.m_clearance & clearanceFlags ) == clearanceFlags
@ -883,14 +955,45 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
|| aLayer == LAYER_PAD_BK || aLayer == LAYER_PAD_BK
|| aLayer == LAYER_PADS_TH ) ) || aLayer == LAYER_PADS_TH ) )
{ {
SHAPE_POLY_SET polySet;
aPad->TransformShapeWithClearanceToPolygon( polySet, aPad->GetClearance() );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetIsFill( false ); m_gal->SetIsFill( false );
m_gal->SetStrokeColor( color ); m_gal->SetStrokeColor( color );
int clearance = aPad->GetClearance();
if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
{
int radius = (aPad->GetSize().x/2) + clearance;
m_gal->DrawCircle( VECTOR2D( aPad->ShapePos() ), radius );
}
else if( aPad->GetShape() == PAD_SHAPE_OVAL )
{
if( aPad->GetSize().x == aPad->GetSize().y )
{
int radius = (aPad->GetSize().x/2) + clearance;
m_gal->DrawCircle( VECTOR2D( aPad->ShapePos() ), radius );
}
else
{
wxPoint seg_start, seg_end;
aPad->BuildSegmentFromOvalShape( seg_start, seg_end,
aPad->GetOrientation(),
wxSize( 0, 0 ) );
int seg_width = std::min( aPad->GetSize().x, aPad->GetSize().y )
+ 2*clearance;
m_gal->DrawSegment( VECTOR2D( aPad->ShapePos()+seg_start ),
VECTOR2D( aPad->ShapePos()+seg_end ),
seg_width );
}
}
else
{
SHAPE_POLY_SET polySet;
aPad->TransformShapeWithClearanceToPolygon( polySet, clearance );
m_gal->DrawPolygon( polySet ); m_gal->DrawPolygon( polySet );
} }
}
} }