Add a min pin width advanced config for plotting.

Fixes https://gitlab.com/kicad/code/kicad/issues/5546
This commit is contained in:
Jeff Young 2020-09-08 20:18:50 +01:00
parent efb03b7482
commit f347118ce3
19 changed files with 60 additions and 26 deletions

View File

@ -76,8 +76,8 @@ static const wxChar DRCEpsilon[] = wxT( "DRCEpsilon" );
/** /**
* Used to calculate the actual hole size from the finish hole size. * Used to calculate the actual hole size from the finish hole size.
* IPC-6012 says 15-18um; Cadence says at least 0.020 for a Class 2 board and at least 0.025 * IPC-6012 says 0.015-0.018mm; Cadence says at least 0.020mm for a Class 2 board and at least
* for Class 3. * 0.025mm for Class 3.
*/ */
static const wxChar HoleWallThickness[] = wxT( "HoleWallPlatingThickness" ); static const wxChar HoleWallThickness[] = wxT( "HoleWallPlatingThickness" );
@ -132,6 +132,12 @@ static const wxChar StrokeTriangulation[] = wxT( "StrokeTriangulation" );
*/ */
static const wxChar PluginAltiumSch[] = wxT( "PluginAltiumSch" ); static const wxChar PluginAltiumSch[] = wxT( "PluginAltiumSch" );
/**
* Absolute minimum pen width to send to the plotter. PDF seems happy enough with 0.0212mm
* (which equates to 1px @ 1200dpi).
*/
static const wxChar MinPlotPenWidth[] = wxT( "MinPlotPenWidth" );
} // namespace KEYS } // namespace KEYS
@ -217,13 +223,16 @@ ADVANCED_CFG::ADVANCED_CFG()
m_DrawTriangulationOutlines = false; m_DrawTriangulationOutlines = false;
m_PluginAltiumSch = false; m_PluginAltiumSch = false;
m_extraClearance = 0.0005; m_ExtraClearance = 0.0005;
m_DRCEpsilon = 0.0005; // 500nm is small enough not to materially violate m_DRCEpsilon = 0.0005; // 500nm is small enough not to materially violate
// any constraints. // any constraints.
m_holeWallThickness = 0.020; // IPC-6012 says 15-18um; Cadence says at least m_HoleWallThickness = 0.020; // IPC-6012 says 15-18um; Cadence says at least
// 0.020 for a Class 2 board and at least 0.025 // 0.020 for a Class 2 board and at least 0.025
// for Class 3. // for Class 3.
m_MinPlotPenWidth = 0.0212; // 1 pixel at 1200dpi.
loadFromConfigFile(); loadFromConfigFile();
} }
@ -265,13 +274,13 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
&m_realTimeConnectivity, true ) ); &m_realTimeConnectivity, true ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::ExtraFillMargin, configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::ExtraFillMargin,
&m_extraClearance, 0.0005, 0.0, 1.0 ) ); &m_ExtraClearance, 0.0005, 0.0, 1.0 ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::DRCEpsilon, configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::DRCEpsilon,
&m_DRCEpsilon, 0.0005, 0.0, 1.0 ) ); &m_DRCEpsilon, 0.0005, 0.0, 1.0 ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::HoleWallThickness, configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::HoleWallThickness,
&m_holeWallThickness, 0.020, 0.0, 1.0 ) ); &m_HoleWallThickness, 0.020, 0.0, 1.0 ) );
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::CoroutineStackSize, configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::CoroutineStackSize,
&m_coroutineStackSize, AC_STACK::default_stack, &m_coroutineStackSize, AC_STACK::default_stack,
@ -295,6 +304,9 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::PluginAltiumSch, configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::PluginAltiumSch,
&m_PluginAltiumSch, false ) ); &m_PluginAltiumSch, false ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::MinPlotPenWidth,
&m_MinPlotPenWidth, 0.0212, 0.0, 1.0 ) );
wxConfigLoadSetups( &aCfg, configParams ); wxConfigLoadSetups( &aCfg, configParams );
for( PARAM_CFG* param : configParams ) for( PARAM_CFG* param : configParams )

View File

@ -39,6 +39,7 @@ RENDER_SETTINGS::RENDER_SETTINGS() :
m_outlineWidth = 1; m_outlineWidth = 1;
m_worksheetLineWidth = 100000; m_worksheetLineWidth = 100000;
m_defaultPenWidth = 0; m_defaultPenWidth = 0;
m_minPenWidth = 0;
m_showPageLimits = false; m_showPageLimits = false;
} }

View File

@ -275,7 +275,7 @@ void LIB_ARC::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
if( !already_filled || pen_size > 0 ) if( !already_filled || pen_size > 0 )
{ {
pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetDefaultPenWidth() ); pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetMinPenWidth() );
aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
aPlotter->Arc( pos, -t2, -t1, m_Radius, already_filled ? NO_FILL : m_Fill, pen_size ); aPlotter->Arc( pos, -t2, -t1, m_Radius, already_filled ? NO_FILL : m_Fill, pen_size );

View File

@ -187,7 +187,7 @@ void LIB_BEZIER::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
if( !already_filled || pen_size > 0 ) if( !already_filled || pen_size > 0 )
{ {
pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetDefaultPenWidth() ); pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetMinPenWidth() );
aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
aPlotter->PlotPoly( cornerList, already_filled ? NO_FILL : m_Fill, pen_size ); aPlotter->PlotPoly( cornerList, already_filled ? NO_FILL : m_Fill, pen_size );

View File

@ -178,7 +178,7 @@ void LIB_CIRCLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
if( !already_filled || pen_size > 0 ) if( !already_filled || pen_size > 0 )
{ {
pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetDefaultPenWidth() ); pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetMinPenWidth() );
aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
aPlotter->Circle( pos, GetRadius() * 2, already_filled ? NO_FILL : m_Fill, pen_size ); aPlotter->Circle( pos, GetRadius() * 2, already_filled ? NO_FILL : m_Fill, pen_size );

View File

@ -288,7 +288,7 @@ void LIB_FIELD::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
else else
color = COLOR4D::BLACK; color = COLOR4D::BLACK;
int penWidth = std::max( GetPenWidth(),aPlotter->RenderSettings()->GetDefaultPenWidth() ); int penWidth = std::max( GetPenWidth(),aPlotter->RenderSettings()->GetMinPenWidth() );
aPlotter->Text( textpos, color, GetShownText(), orient, GetTextSize(), hjustify, vjustify, aPlotter->Text( textpos, color, GetShownText(), orient, GetTextSize(), hjustify, vjustify,
penWidth, IsItalic(), IsBold() ); penWidth, IsItalic(), IsBold() );

View File

@ -144,7 +144,7 @@ void LIB_RECTANGLE::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
if( !already_filled || pen_size > 0 ) if( !already_filled || pen_size > 0 )
{ {
pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetDefaultPenWidth() ); pen_size = std::max( pen_size, aPlotter->RenderSettings()->GetMinPenWidth() );
aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) ); aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_DEVICE ) );
aPlotter->Rect( pos, end, already_filled ? NO_FILL : m_Fill, pen_size ); aPlotter->Rect( pos, end, already_filled ? NO_FILL : m_Fill, pen_size );

View File

@ -287,8 +287,9 @@ void LIB_TEXT::Plot( PLOTTER* plotter, const wxPoint& offset, bool fill,
else else
color = COLOR4D::BLACK; color = COLOR4D::BLACK;
int penWidth = std::max( GetEffectiveTextPenWidth(), RENDER_SETTINGS* settings = plotter->RenderSettings();
plotter->RenderSettings()->GetDefaultPenWidth() );
int penWidth = std::max( GetEffectiveTextPenWidth(), settings->GetMinPenWidth() );
plotter->Text( pos, color, GetText(), t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT, GetTextSize(), plotter->Text( pos, color, GetText(), t1 ? TEXT_ANGLE_HORIZ : TEXT_ANGLE_VERT, GetTextSize(),
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, penWidth, IsItalic(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, penWidth, IsItalic(),

View File

@ -395,6 +395,8 @@ void SCH_BUS_ENTRY_BASE::Plot( PLOTTER* aPlotter )
settings->GetLayerColor( m_Layer ) : GetStrokeColor(); settings->GetLayerColor( m_Layer ) : GetStrokeColor();
int penWidth = ( GetPenWidth() == 0 ) ? settings->GetDefaultPenWidth() : GetPenWidth(); int penWidth = ( GetPenWidth() == 0 ) ? settings->GetDefaultPenWidth() : GetPenWidth();
penWidth = std::max( penWidth, settings->GetMinPenWidth() );
aPlotter->SetCurrentLineWidth( penWidth ); aPlotter->SetCurrentLineWidth( penWidth );
aPlotter->SetColor( color ); aPlotter->SetColor( color );
aPlotter->SetDash( GetStrokeStyle() ); aPlotter->SetDash( GetStrokeStyle() );

View File

@ -526,9 +526,11 @@ bool SCH_FIELD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy )
void SCH_FIELD::Plot( PLOTTER* aPlotter ) void SCH_FIELD::Plot( PLOTTER* aPlotter )
{ {
COLOR4D color = aPlotter->RenderSettings()->GetLayerColor( GetLayer() ); RENDER_SETTINGS* settings = aPlotter->RenderSettings();
int penWidth = GetEffectiveTextPenWidth( COLOR4D color = settings->GetLayerColor( GetLayer() );
aPlotter->RenderSettings()->GetDefaultPenWidth() ); int penWidth = GetEffectiveTextPenWidth( settings->GetDefaultPenWidth() );
penWidth = std::max( penWidth, settings->GetMinPenWidth() );
if( !IsVisible() ) if( !IsVisible() )
return; return;

View File

@ -749,11 +749,11 @@ void SCH_LINE::Plot( PLOTTER* aPlotter )
default: penWidth = GetPenWidth(); break; default: penWidth = GetPenWidth(); break;
} }
penWidth = std::max( penWidth, aPlotter->RenderSettings()->GetDefaultPenWidth() );
if( m_stroke.GetWidth() != 0 ) if( m_stroke.GetWidth() != 0 )
penWidth = m_stroke.GetWidth(); penWidth = m_stroke.GetWidth();
penWidth = std::max( penWidth, settings->GetMinPenWidth() );
aPlotter->SetCurrentLineWidth( penWidth ); aPlotter->SetCurrentLineWidth( penWidth );
aPlotter->SetDash( GetEffectiveLineStyle() ); aPlotter->SetDash( GetEffectiveLineStyle() );

View File

@ -177,7 +177,7 @@ void SCH_NO_CONNECT::Plot( PLOTTER* aPlotter )
int delta = GetSize() / 2; int delta = GetSize() / 2;
int pX = m_pos.x; int pX = m_pos.x;
int pY = m_pos.y; int pY = m_pos.y;
int penWidth = std::max( GetPenWidth(), aPlotter->RenderSettings()->GetDefaultPenWidth() ); int penWidth = std::max( GetPenWidth(), aPlotter->RenderSettings()->GetMinPenWidth() );
aPlotter->SetCurrentLineWidth( penWidth ); aPlotter->SetCurrentLineWidth( penWidth );
aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_NOCONNECT ) ); aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_NOCONNECT ) );

View File

@ -62,6 +62,7 @@
#include <view/view.h> #include <view/view.h>
#include <kiface_i.h> #include <kiface_i.h>
#include <default_values.h> #include <default_values.h>
#include <advanced_config.h>
#include "sch_painter.h" #include "sch_painter.h"
namespace KIGFX namespace KIGFX
@ -83,6 +84,8 @@ SCH_RENDER_SETTINGS::SCH_RENDER_SETTINGS() :
m_JunctionSize( DEFAULT_JUNCTION_DIAM * IU_PER_MILS ) m_JunctionSize( DEFAULT_JUNCTION_DIAM * IU_PER_MILS )
{ {
SetDefaultPenWidth( DEFAULT_LINE_THICKNESS * IU_PER_MILS ); SetDefaultPenWidth( DEFAULT_LINE_THICKNESS * IU_PER_MILS );
m_minPenWidth = ADVANCED_CFG::GetCfg().m_MinPlotPenWidth * IU_PER_MM;
} }

View File

@ -966,7 +966,7 @@ void SCH_SHEET::Plot( PLOTTER* aPlotter )
aPlotter->SetColor( borderColor ); aPlotter->SetColor( borderColor );
int penWidth = std::max( GetPenWidth(), aPlotter->RenderSettings()->GetDefaultPenWidth() ); int penWidth = std::max( GetPenWidth(), aPlotter->RenderSettings()->GetMinPenWidth() );
aPlotter->SetCurrentLineWidth( penWidth ); aPlotter->SetCurrentLineWidth( penWidth );
aPlotter->MoveTo( m_pos ); aPlotter->MoveTo( m_pos );

View File

@ -581,6 +581,7 @@ void SCH_TEXT::Plot( PLOTTER* aPlotter )
COLOR4D color = aPlotter->RenderSettings()->GetLayerColor( GetLayer() ); COLOR4D color = aPlotter->RenderSettings()->GetLayerColor( GetLayer() );
int penWidth = GetEffectiveTextPenWidth( aPlotter->RenderSettings()->GetDefaultPenWidth() ); int penWidth = GetEffectiveTextPenWidth( aPlotter->RenderSettings()->GetDefaultPenWidth() );
penWidth = std::max( penWidth, aPlotter->RenderSettings()->GetMinPenWidth() );
aPlotter->SetCurrentLineWidth( penWidth ); aPlotter->SetCurrentLineWidth( penWidth );
if( IsMultilineAllowed() ) if( IsMultilineAllowed() )

View File

@ -84,20 +84,21 @@ public:
/** /**
* Extra fill clearance for zone fills. Note that for zone tests this is essentially * Extra fill clearance for zone fills. Note that for zone tests this is essentially
* additive with m_DRCEpsilon. * additive with m_DRCEpsilon. Units are mm.
*/ */
double m_extraClearance; double m_ExtraClearance;
/** /**
* Epsilon for DRC tests. Note that for zone tests this is essentially additive with * Epsilon for DRC tests. Note that for zone tests this is essentially additive with
* m_extraClearance. * m_extraClearance. Units are mm.
*/ */
double m_DRCEpsilon; double m_DRCEpsilon;
/** /**
* Hole wall plating thickness. Used to determine actual hole size from finish hole size. * Hole wall plating thickness. Used to determine actual hole size from finish hole size.
* Units are mm.
*/ */
double m_holeWallThickness; double m_HoleWallThickness;
/** /**
* Do real-time connectivity * Do real-time connectivity
@ -131,6 +132,12 @@ public:
*/ */
bool m_PluginAltiumSch; bool m_PluginAltiumSch;
/**
* Sets an absolute minimum pen width for plotting. Some formats (PDF, for example) don't
* like ultra-thin lines. Units are mm.
*/
double m_MinPlotPenWidth;
private: private:
ADVANCED_CFG(); ADVANCED_CFG();

View File

@ -164,6 +164,9 @@ public:
int GetDefaultPenWidth() const { return m_defaultPenWidth; } int GetDefaultPenWidth() const { return m_defaultPenWidth; }
void SetDefaultPenWidth( int aWidth ) { m_defaultPenWidth = aWidth; } void SetDefaultPenWidth( int aWidth ) { m_defaultPenWidth = aWidth; }
int GetMinPenWidth() const { return m_minPenWidth; }
void SetMinPenWidth( int aWidth ) { m_minPenWidth = aWidth; }
bool GetShowPageLimits() const { return m_showPageLimits; } bool GetShowPageLimits() const { return m_showPageLimits; }
void SetShowPageLimits( bool aDraw ) { m_showPageLimits = aDraw; } void SetShowPageLimits( bool aDraw ) { m_showPageLimits = aDraw; }
@ -268,6 +271,8 @@ protected:
float m_worksheetLineWidth; // Line width used when drawing worksheet float m_worksheetLineWidth; // Line width used when drawing worksheet
int m_defaultPenWidth; int m_defaultPenWidth;
int m_minPenWidth; // Some clients (such as PDF) don't like ultra-thin
// lines. This sets an absolute minimum.
bool m_showPageLimits; bool m_showPageLimits;
wxDC* m_printDC; // This can go away once we have Cairo-based printing. wxDC* m_printDC; // This can go away once we have Cairo-based printing.

View File

@ -969,7 +969,7 @@ int BOARD_DESIGN_SETTINGS::GetDRCEpsilon() const
int BOARD_DESIGN_SETTINGS::GetHolePlatingThickness() const int BOARD_DESIGN_SETTINGS::GetHolePlatingThickness() const
{ {
return Millimeter2iu( ADVANCED_CFG::GetCfg().m_holeWallThickness ); return Millimeter2iu( ADVANCED_CFG::GetCfg().m_HoleWallThickness );
} }

View File

@ -601,7 +601,7 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE_CONTAINER* aZone, PCB_LA
// requested clearance due to many approximations in calculations, like arc to segment // requested clearance due to many approximations in calculations, like arc to segment
// approx, rounding issues, etc. // approx, rounding issues, etc.
// 1 micron is a good value // 1 micron is a good value
int extra_margin = Millimeter2iu( ADVANCED_CFG::GetCfg().m_extraClearance ); int extra_margin = Millimeter2iu( ADVANCED_CFG::GetCfg().m_ExtraClearance );
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
int zone_clearance = aZone->GetLocalClearance(); int zone_clearance = aZone->GetLocalClearance();