diff --git a/common/drc_rules.keywords b/common/drc_rules.keywords index a10cdc2702..564ecba7bd 100644 --- a/common/drc_rules.keywords +++ b/common/drc_rules.keywords @@ -4,10 +4,15 @@ buried_via clearance condition constraint +courtyard_clearance +diff_pair_gap +diff_pair_uncoupled disallow +edge_clearance footprint graphic hole +hole_clearance hole_size hole_to_hole inner @@ -22,18 +27,15 @@ outer pad pth rule +silk_clearance +skew text +text_height +text_thickness track track_width version via -zone -edge_clearance -hole_clearance -courtyard_clearance -silk_clearance -skew -diff_pair_gap -diff_pair_uncoupled via_count -via_diameter \ No newline at end of file +via_diameter +zone diff --git a/include/board_design_settings.h b/include/board_design_settings.h index 30f0227ffe..4fb408d207 100644 --- a/include/board_design_settings.h +++ b/include/board_design_settings.h @@ -559,27 +559,6 @@ public: */ int GetCurrentDiffPairViaGap() const; - /** - * @param aValue The minimum distance between the edges of two holes or 0 to disable - * hole-to-hole separation checking. - */ - void SetMinHoleSeparation( int aDistance ); - - /** - * @param aValue The minimum distance between copper items and board edges. - */ - void SetCopperEdgeClearance( int aDistance ); - - /** - * Set the minimum distance between silk items to \a aValue. - * - * @note Compound graphics within a single footprint or on the board are not checked, - * but distances between text and between graphics from different footprints are. - * - * @param aValue The minimum distance between silk items. - */ - void SetSilkClearance( int aDistance ); - /** * Return a bit-mask of all the layers that are enabled. * @@ -700,6 +679,8 @@ public: int m_HoleClearance; // Hole to copper clearance int m_HoleToHoleMin; // Min width of web between two drilled holes int m_SilkClearance; + int m_MinSilkTextHeight; // Min text height for silkscreen layers + int m_MinSilkTextThickness; // Min text thickness for silkscreen layers std::shared_ptr m_DRCEngine; std::map m_DRCSeverities; // Map from DRCErrorCode to SEVERITY diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index b551222a45..8795e2ac3b 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -241,6 +241,7 @@ set( PCBNEW_DRC_SRCS drc/drc_test_provider_library_parity.cpp drc/drc_test_provider_schematic_parity.cpp drc/drc_test_provider_misc.cpp + drc/drc_test_provider_text_dims.cpp drc/drc_test_provider_track_width.cpp drc/drc_test_provider_via_diameter.cpp drc/drc_test_provider_silk_to_mask.cpp diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp index 82ee5462ed..a6d5bbdd4c 100644 --- a/pcbnew/board_design_settings.cpp +++ b/pcbnew/board_design_settings.cpp @@ -151,6 +151,8 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: m_HoleClearance = Millimeter2iu( DEFAULT_HOLECLEARANCE ); m_HoleToHoleMin = Millimeter2iu( DEFAULT_HOLETOHOLEMIN ); m_SilkClearance = Millimeter2iu( DEFAULT_SILKCLEARANCE ); + m_MinSilkTextHeight = Millimeter2iu( DEFAULT_SILK_TEXT_SIZE * 0.8 ); + m_MinSilkTextThickness= Millimeter2iu( DEFAULT_SILK_TEXT_WIDTH * 0.8 ); for( int errorCode = DRCE_FIRST; errorCode <= DRCE_LAST; ++errorCode ) m_DRCSeverities[ errorCode ] = RPT_SEVERITY_ERROR; @@ -171,6 +173,8 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: m_DRCSeverities[ DRCE_OVERLAPPING_SILK ] = RPT_SEVERITY_WARNING; m_DRCSeverities[ DRCE_SILK_MASK_CLEARANCE ] = RPT_SEVERITY_WARNING; + m_DRCSeverities[ DRCE_TEXT_HEIGHT ] = RPT_SEVERITY_WARNING; + m_DRCSeverities[ DRCE_TEXT_THICKNESS ] = RPT_SEVERITY_WARNING; m_MaxError = ARC_HIGH_DEF; m_ZoneFillVersion = 6; // Use new algo by default to fill zones @@ -252,6 +256,14 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: Millimeter2iu( DEFAULT_SILKCLEARANCE ), Millimeter2iu( 0.00 ), Millimeter2iu( 100.0 ), MM_PER_IU ) ); + m_params.emplace_back( new PARAM_SCALED( "rules.min_text_height", &m_MinSilkTextHeight, + Millimeter2iu( DEFAULT_SILK_TEXT_SIZE * 0.8 ), Millimeter2iu( 0.00 ), + Millimeter2iu( 100.0 ), MM_PER_IU ) ); + + m_params.emplace_back( new PARAM_SCALED( "rules.min_text_thickness", &m_MinSilkTextThickness, + Millimeter2iu( DEFAULT_SILK_TEXT_WIDTH * 0.8 ), Millimeter2iu( 0.00 ), + Millimeter2iu( 25.0 ), MM_PER_IU ) ); + // Note: a clearance of -0.01 is a flag indicating we should use the legacy (pre-6.0) method // based on the edge cut thicknesses. m_params.emplace_back( new PARAM_SCALED( "rules.min_copper_edge_clearance", @@ -691,6 +703,8 @@ void BOARD_DESIGN_SETTINGS::initFromOther( const BOARD_DESIGN_SETTINGS& aOther ) m_HoleClearance = aOther.m_HoleClearance; m_HoleToHoleMin = aOther.m_HoleToHoleMin; m_SilkClearance = aOther.m_SilkClearance; + m_MinSilkTextHeight = aOther.m_MinSilkTextHeight; + m_MinSilkTextThickness = aOther.m_MinSilkTextThickness; m_DRCSeverities = aOther.m_DRCSeverities; m_DrcExclusions = aOther.m_DrcExclusions; m_ZoneFillVersion = aOther.m_ZoneFillVersion; @@ -1054,24 +1068,6 @@ int BOARD_DESIGN_SETTINGS::GetCurrentDiffPairViaGap() const } -void BOARD_DESIGN_SETTINGS::SetMinHoleSeparation( int aDistance ) -{ - m_HoleToHoleMin = aDistance; -} - - -void BOARD_DESIGN_SETTINGS::SetCopperEdgeClearance( int aDistance ) -{ - m_CopperEdgeClearance = aDistance; -} - - -void BOARD_DESIGN_SETTINGS::SetSilkClearance( int aDistance ) -{ - m_SilkClearance = aDistance; -} - - void BOARD_DESIGN_SETTINGS::SetCopperLayerCount( int aNewLayerCount ) { m_copperLayerCount = aNewLayerCount; diff --git a/pcbnew/dialogs/panel_setup_constraints.cpp b/pcbnew/dialogs/panel_setup_constraints.cpp index 4a12988ffb..88146f590b 100644 --- a/pcbnew/dialogs/panel_setup_constraints.cpp +++ b/pcbnew/dialogs/panel_setup_constraints.cpp @@ -46,6 +46,8 @@ PANEL_SETUP_CONSTRAINTS::PANEL_SETUP_CONSTRAINTS( PAGED_DIALOG* aParent, PCB_EDI m_holeClearance( aFrame, m_HoleClearanceLabel, m_HoleClearanceCtrl, m_HoleClearanceUnits ), m_edgeClearance( aFrame, m_EdgeClearanceLabel, m_EdgeClearanceCtrl, m_EdgeClearanceUnits ), m_silkClearance( aFrame, m_silkClearanceLabel, m_silkClearanceCtrl, m_silkClearanceUnits ), + m_minTextHeight( aFrame, m_textHeightLabel, m_textHeightCtrl, m_textHeightUnits ), + m_minTextThickness( aFrame, m_textThicknessLabel, m_textThicknessCtrl, m_textThicknessUnits ), m_maxError( aFrame, m_maxErrorTitle, m_maxErrorCtrl, m_maxErrorUnits ) { m_Frame = aFrame; @@ -86,6 +88,8 @@ bool PANEL_SETUP_CONSTRAINTS::TransferDataToWindow() m_uviaMinDrill.SetValue( m_BrdSettings->m_MicroViasMinDrill ); m_silkClearance.SetValue( m_BrdSettings->m_SilkClearance ); + m_minTextHeight.SetValue( m_BrdSettings->m_MinSilkTextHeight ); + m_minTextThickness.SetValue( m_BrdSettings->m_MinSilkTextThickness ); return true; } @@ -135,15 +139,17 @@ bool PANEL_SETUP_CONSTRAINTS::TransferDataFromWindow() m_BrdSettings->m_ViasMinAnnularWidth = m_viaMinAnnulus.GetValue(); m_BrdSettings->m_ViasMinSize = m_viaMinSize.GetValue(); m_BrdSettings->m_HoleClearance = m_holeClearance.GetValue(); - m_BrdSettings->SetCopperEdgeClearance( m_edgeClearance.GetValue() ); + m_BrdSettings->m_CopperEdgeClearance = m_edgeClearance.GetValue(); m_BrdSettings->m_MinThroughDrill = m_throughHoleMin.GetValue(); - m_BrdSettings->SetMinHoleSeparation( m_holeToHoleMin.GetValue() ); + m_BrdSettings->m_HoleToHoleMin = m_holeToHoleMin.GetValue(); m_BrdSettings->m_MicroViasMinSize = m_uviaMinSize.GetValue(); m_BrdSettings->m_MicroViasMinDrill = m_uviaMinDrill.GetValue(); m_BrdSettings->m_SilkClearance = m_silkClearance.GetValue(); + m_BrdSettings->m_MinSilkTextHeight = m_minTextHeight.GetValue(); + m_BrdSettings->m_MinSilkTextThickness = m_minTextThickness.GetValue(); return true; } diff --git a/pcbnew/dialogs/panel_setup_constraints.h b/pcbnew/dialogs/panel_setup_constraints.h index 2a21f977ce..8c07666539 100644 --- a/pcbnew/dialogs/panel_setup_constraints.h +++ b/pcbnew/dialogs/panel_setup_constraints.h @@ -62,6 +62,8 @@ public: UNIT_BINDER m_holeClearance; UNIT_BINDER m_edgeClearance; UNIT_BINDER m_silkClearance; + UNIT_BINDER m_minTextHeight; + UNIT_BINDER m_minTextThickness; UNIT_BINDER m_maxError; private: diff --git a/pcbnew/dialogs/panel_setup_constraints_base.cpp b/pcbnew/dialogs/panel_setup_constraints_base.cpp index 4b08cb33dd..3bd950cfde 100644 --- a/pcbnew/dialogs/panel_setup_constraints_base.cpp +++ b/pcbnew/dialogs/panel_setup_constraints_base.cpp @@ -438,6 +438,34 @@ PANEL_SETUP_CONSTRAINTS_BASE::PANEL_SETUP_CONSTRAINTS_BASE( wxWindow* parent, wx fgFeatureConstraints->Add( m_silkClearanceUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + fgFeatureConstraints->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_textHeightLabel = new wxStaticText( m_scrolledWindow, wxID_ANY, _("Minimum text height:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textHeightLabel->Wrap( -1 ); + fgFeatureConstraints->Add( m_textHeightLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_textHeightCtrl = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgFeatureConstraints->Add( m_textHeightCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textHeightUnits = new wxStaticText( m_scrolledWindow, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textHeightUnits->Wrap( -1 ); + fgFeatureConstraints->Add( m_textHeightUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + + fgFeatureConstraints->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_textThicknessLabel = new wxStaticText( m_scrolledWindow, wxID_ANY, _("Minimum text thickness:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textThicknessLabel->Wrap( -1 ); + fgFeatureConstraints->Add( m_textThicknessLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_textThicknessCtrl = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgFeatureConstraints->Add( m_textThicknessCtrl, 0, wxTOP|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textThicknessUnits = new wxStaticText( m_scrolledWindow, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textThicknessUnits->Wrap( -1 ); + fgFeatureConstraints->Add( m_textThicknessUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + sbFeatureConstraints->Add( fgFeatureConstraints, 1, wxEXPAND|wxLEFT, 5 ); diff --git a/pcbnew/dialogs/panel_setup_constraints_base.fbp b/pcbnew/dialogs/panel_setup_constraints_base.fbp index 13d22665c1..1531865670 100644 --- a/pcbnew/dialogs/panel_setup_constraints_base.fbp +++ b/pcbnew/dialogs/panel_setup_constraints_base.fbp @@ -1541,11 +1541,11 @@ sbFeatureConstraints wxVERTICAL none - + 5 wxEXPAND|wxLEFT 1 - + 4 wxBOTH @@ -5253,6 +5253,398 @@ -1 + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Minimum text height: + 0 + + 0 + + + 0 + + 1 + m_textHeightLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textHeightCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_textHeightUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Minimum text thickness: + 0 + + 0 + + + 0 + + 1 + m_textThicknessLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxTOP|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textThicknessCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_textThicknessUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + diff --git a/pcbnew/dialogs/panel_setup_constraints_base.h b/pcbnew/dialogs/panel_setup_constraints_base.h index 7e1c2fdf08..7507e4dae1 100644 --- a/pcbnew/dialogs/panel_setup_constraints_base.h +++ b/pcbnew/dialogs/panel_setup_constraints_base.h @@ -120,6 +120,12 @@ class PANEL_SETUP_CONSTRAINTS_BASE : public wxPanel wxStaticText* m_silkClearanceLabel; wxTextCtrl* m_silkClearanceCtrl; wxStaticText* m_silkClearanceUnits; + wxStaticText* m_textHeightLabel; + wxTextCtrl* m_textHeightCtrl; + wxStaticText* m_textHeightUnits; + wxStaticText* m_textThicknessLabel; + wxTextCtrl* m_textThicknessCtrl; + wxStaticText* m_textThicknessUnits; // Virtual event handlers, overide them in your derived class virtual void onChangeOutlineOpt( wxCommandEvent& event ) { event.Skip(); } diff --git a/pcbnew/dialogs/panel_setup_rules.cpp b/pcbnew/dialogs/panel_setup_rules.cpp index 3b8567b2d5..1775eb3d68 100644 --- a/pcbnew/dialogs/panel_setup_rules.cpp +++ b/pcbnew/dialogs/panel_setup_rules.cpp @@ -303,6 +303,8 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent ) "hole_to_hole|" "silk_clearance|" "skew|" + "text_height|" + "text_thickness|" "track_width|" "via_count|" "via_diameter"; diff --git a/pcbnew/dialogs/panel_setup_rules_help.md b/pcbnew/dialogs/panel_setup_rules_help.md index e1e2dcb62e..904ae70b5c 100644 --- a/pcbnew/dialogs/panel_setup_rules_help.md +++ b/pcbnew/dialogs/panel_setup_rules_help.md @@ -32,6 +32,8 @@ * hole\_size * silk\_clearance * skew + * text\_height + * text\_thickness * track\_width * via\_count * via\_diameter diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index 7e6b5df3d6..2f2e2247b3 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -174,10 +174,19 @@ void DRC_ENGINE::loadImplicitRules() rule = createImplicitRule( _( "board setup constraints silk" ) ); rule->m_LayerCondition = LSET( 2, F_SilkS, B_SilkS ); + DRC_CONSTRAINT silkClearanceConstraint( SILK_CLEARANCE_CONSTRAINT ); silkClearanceConstraint.Value().SetMin( bds.m_SilkClearance ); rule->AddConstraint( silkClearanceConstraint ); + DRC_CONSTRAINT silkTextHeightConstraint( TEXT_HEIGHT_CONSTRAINT ); + silkTextHeightConstraint.Value().SetMin( bds.m_MinSilkTextHeight ); + rule->AddConstraint( silkTextHeightConstraint ); + + DRC_CONSTRAINT silkTextThicknessConstraint( TEXT_THICKNESS_CONSTRAINT ); + silkTextThicknessConstraint.Value().SetMin( bds.m_MinSilkTextThickness ); + rule->AddConstraint( silkTextThicknessConstraint ); + rule = createImplicitRule( _( "board setup constraints hole" ) ); DRC_CONSTRAINT holeClearanceConstraint( HOLE_CLEARANCE_CONSTRAINT ); holeClearanceConstraint.Value().SetMin( bds.m_HoleClearance ); @@ -496,6 +505,8 @@ static wxString formatConstraint( const DRC_CONSTRAINT& constraint ) { HOLE_SIZE_CONSTRAINT, "hole_size", formatMinMax }, { COURTYARD_CLEARANCE_CONSTRAINT, "courtyard_clearance", formatMinMax }, { SILK_CLEARANCE_CONSTRAINT, "silk_clearance", formatMinMax }, + { TEXT_HEIGHT_CONSTRAINT, "text_height", formatMinMax }, + { TEXT_THICKNESS_CONSTRAINT, "text_thickness", formatMinMax }, { TRACK_WIDTH_CONSTRAINT, "track_width", formatMinMax }, { ANNULAR_WIDTH_CONSTRAINT, "annular_width", formatMinMax }, { DISALLOW_CONSTRAINT, "disallow", nullptr }, diff --git a/pcbnew/drc/drc_item.cpp b/pcbnew/drc/drc_item.cpp index 27d9649815..3772ee68ee 100644 --- a/pcbnew/drc/drc_item.cpp +++ b/pcbnew/drc/drc_item.cpp @@ -186,6 +186,14 @@ DRC_ITEM DRC_ITEM::silkOverlaps( DRCE_OVERLAPPING_SILK, _( "Silkscreen overlap" ), wxT( "silk_overlap" ) ); +DRC_ITEM DRC_ITEM::textHeightOutOfRange( DRCE_TEXT_HEIGHT, + _( "Text height out of range" ), + wxT( "text_height" ) ); + +DRC_ITEM DRC_ITEM::textThicknessOutOfRange( DRCE_TEXT_THICKNESS, + _( "Text thickness out of range" ), + wxT( "text_thickness" ) ); + DRC_ITEM DRC_ITEM::lengthOutOfRange( DRCE_LENGTH_OUT_OF_RANGE, _( "Trace length out of range" ), wxT( "length_out_of_range" ) ); @@ -306,6 +314,8 @@ std::shared_ptr DRC_ITEM::Create( int aErrorCode ) case DRCE_UNRESOLVED_VARIABLE: return std::make_shared( unresolvedVariable ); case DRCE_OVERLAPPING_SILK: return std::make_shared( silkOverlaps ); case DRCE_SILK_MASK_CLEARANCE: return std::make_shared( silkMaskClearance ); + case DRCE_TEXT_HEIGHT: return std::make_shared( textHeightOutOfRange ); + case DRCE_TEXT_THICKNESS: return std::make_shared( textThicknessOutOfRange ); case DRCE_LENGTH_OUT_OF_RANGE: return std::make_shared( lengthOutOfRange ); case DRCE_SKEW_OUT_OF_RANGE: return std::make_shared( skewOutOfRange ); case DRCE_TOO_MANY_VIAS: return std::make_shared( tooManyVias ); diff --git a/pcbnew/drc/drc_item.h b/pcbnew/drc/drc_item.h index b5c29b7fd7..213a64c580 100644 --- a/pcbnew/drc/drc_item.h +++ b/pcbnew/drc/drc_item.h @@ -74,6 +74,8 @@ enum PCB_DRC_CODE { DRCE_UNRESOLVED_VARIABLE, DRCE_SILK_MASK_CLEARANCE, // silkscreen clipped by mask (potentially leaving it // over pads, exposed copper, etc.) + DRCE_TEXT_HEIGHT, + DRCE_TEXT_THICKNESS, DRCE_OVERLAPPING_SILK, // silk to silk clearance error DRCE_LENGTH_OUT_OF_RANGE, DRCE_SKEW_OUT_OF_RANGE, @@ -169,6 +171,8 @@ private: static DRC_ITEM unresolvedVariable; static DRC_ITEM silkMaskClearance; static DRC_ITEM silkOverlaps; + static DRC_ITEM textHeightOutOfRange; + static DRC_ITEM textThicknessOutOfRange; static DRC_ITEM lengthOutOfRange; static DRC_ITEM skewOutOfRange; static DRC_ITEM tooManyVias; diff --git a/pcbnew/drc/drc_rule.h b/pcbnew/drc/drc_rule.h index e3f7512219..1ac6bb4e80 100644 --- a/pcbnew/drc/drc_rule.h +++ b/pcbnew/drc/drc_rule.h @@ -48,6 +48,8 @@ enum DRC_CONSTRAINT_T HOLE_SIZE_CONSTRAINT, COURTYARD_CLEARANCE_CONSTRAINT, SILK_CLEARANCE_CONSTRAINT, + TEXT_HEIGHT_CONSTRAINT, + TEXT_THICKNESS_CONSTRAINT, TRACK_WIDTH_CONSTRAINT, ANNULAR_WIDTH_CONSTRAINT, DISALLOW_CONSTRAINT, diff --git a/pcbnew/drc/drc_rule_parser.cpp b/pcbnew/drc/drc_rule_parser.cpp index 2dd4b07017..2b2f8f2151 100644 --- a/pcbnew/drc/drc_rule_parser.cpp +++ b/pcbnew/drc/drc_rule_parser.cpp @@ -272,6 +272,8 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule ) case T_hole_to_hole: c.m_Type = HOLE_TO_HOLE_CONSTRAINT; break; case T_courtyard_clearance: c.m_Type = COURTYARD_CLEARANCE_CONSTRAINT; break; case T_silk_clearance: c.m_Type = SILK_CLEARANCE_CONSTRAINT; break; + case T_text_height: c.m_Type = TEXT_HEIGHT_CONSTRAINT; break; + case T_text_thickness: c.m_Type = TEXT_THICKNESS_CONSTRAINT; break; case T_track_width: c.m_Type = TRACK_WIDTH_CONSTRAINT; break; case T_annular_width: c.m_Type = ANNULAR_WIDTH_CONSTRAINT; break; case T_via_diameter: c.m_Type = VIA_DIAMETER_CONSTRAINT; break; diff --git a/pcbnew/drc/drc_test_provider_text_dims.cpp b/pcbnew/drc/drc_test_provider_text_dims.cpp new file mode 100644 index 0000000000..d8236ba7f9 --- /dev/null +++ b/pcbnew/drc/drc_test_provider_text_dims.cpp @@ -0,0 +1,233 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2021 KiCad Developers. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include + + +/* + Text dimensions tests. + Errors generated: + - DRCE_TEXT_HEIGHT + - DRCE_TEXT_THICKNESS +*/ + +class DRC_TEST_PROVIDER_TEXT_DIMS : public DRC_TEST_PROVIDER +{ +public: + DRC_TEST_PROVIDER_TEXT_DIMS() + { + } + + virtual ~DRC_TEST_PROVIDER_TEXT_DIMS() + { + } + + virtual bool Run() override; + + virtual const wxString GetName() const override + { + return "text_dimensions"; + }; + + virtual const wxString GetDescription() const override + { + return "Tests text height and thickness"; + } + + virtual std::set GetConstraintTypes() const override; +}; + + +bool DRC_TEST_PROVIDER_TEXT_DIMS::Run() +{ + const int delta = 100; // This is the number of tests between 2 calls to the progress bar + int count = 0; + int ii = 0; + + if( m_drcEngine->IsErrorLimitExceeded( DRCE_TEXT_HEIGHT ) + && m_drcEngine->IsErrorLimitExceeded( DRCE_TEXT_THICKNESS ) ) + { + reportAux( "Text dimension violations ignored. Tests not run." ); + return true; // continue with other tests + } + + if( !m_drcEngine->HasRulesForConstraintType( TEXT_HEIGHT_CONSTRAINT ) + && !m_drcEngine->HasRulesForConstraintType( TEXT_THICKNESS_CONSTRAINT ) ) + { + reportAux( "No text height or text thickness constraints found. Tests not run." ); + return true; // continue with other tests + } + + if( !reportPhase( _( "Checking text dimensions..." ) ) ) + return false; // DRC cancelled + + auto countItems = + [&]( BOARD_ITEM* item ) -> bool + { + ++count; + return true; + }; + + auto checkTextDims = + [&]( BOARD_ITEM* item ) -> bool + { + if( m_drcEngine->IsErrorLimitExceeded( DRCE_TEXT_HEIGHT ) + && m_drcEngine->IsErrorLimitExceeded( DRCE_TEXT_THICKNESS ) ) + { + return false; + } + + if( !reportProgress( ii++, count, delta ) ) + return false; + + PCB_TEXT* textItem = static_cast( item ); + DRC_CONSTRAINT constraint; + + if( !textItem->IsVisible() ) + return true; + + if( !m_drcEngine->IsErrorLimitExceeded( DRCE_TEXT_HEIGHT ) ) + { + constraint = m_drcEngine->EvalRules( TEXT_HEIGHT_CONSTRAINT, item, nullptr, + item->GetLayer() ); + bool fail_min = false; + bool fail_max = false; + int constraintHeight; + int actual = textItem->GetTextHeight(); + + if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + { + fail_min = true; + constraintHeight = constraint.Value().Min(); + } + + if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) + { + fail_max = true; + constraintHeight = constraint.Value().Max(); + } + + if( fail_min || fail_max ) + { + std::shared_ptr drcItem = DRC_ITEM::Create( DRCE_TEXT_HEIGHT ); + + if( fail_min ) + { + m_msg.Printf( _( "(%s min height %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), constraintHeight ), + MessageTextFromValue( userUnits(), actual ) ); + } + else + { + m_msg.Printf( _( "(%s max height %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), constraintHeight ), + MessageTextFromValue( userUnits(), actual ) ); + } + + drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg ); + drcItem->SetItems( item ); + drcItem->SetViolatingRule( constraint.GetParentRule() ); + + reportViolation( drcItem, item->GetPosition() ); + } + } + + if( !m_drcEngine->IsErrorLimitExceeded( DRCE_TEXT_THICKNESS ) ) + { + constraint = m_drcEngine->EvalRules( TEXT_THICKNESS_CONSTRAINT, item, nullptr, + item->GetLayer() ); + bool fail_min = false; + bool fail_max = false; + int constraintThickness; + int actual = textItem->GetTextThickness(); + + if( constraint.Value().HasMin() && actual < constraint.Value().Min() ) + { + fail_min = true; + constraintThickness = constraint.Value().Min(); + } + + if( constraint.Value().HasMax() && actual > constraint.Value().Max() ) + { + fail_max = true; + constraintThickness = constraint.Value().Max(); + } + + if( fail_min || fail_max ) + { + std::shared_ptr drcItem = DRC_ITEM::Create( DRCE_TEXT_THICKNESS ); + + if( fail_min ) + { + m_msg.Printf( _( "(%s min thickness %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), constraintThickness ), + MessageTextFromValue( userUnits(), actual ) ); + } + else + { + m_msg.Printf( _( "(%s max thickness %s; actual %s)" ), + constraint.GetName(), + MessageTextFromValue( userUnits(), constraintThickness ), + MessageTextFromValue( userUnits(), actual ) ); + } + + drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg ); + drcItem->SetItems( item ); + drcItem->SetViolatingRule( constraint.GetParentRule() ); + + reportViolation( drcItem, item->GetPosition() ); + } + } + + return true; + }; + + static const std::vector itemTypes = { PCB_TEXT_T, PCB_FP_TEXT_T }; + + forEachGeometryItem( itemTypes, LSET::AllLayersMask(), countItems ); + forEachGeometryItem( itemTypes, LSET::AllLayersMask(), checkTextDims ); + + reportRuleStatistics(); + + return true; +} + + +std::set DRC_TEST_PROVIDER_TEXT_DIMS::GetConstraintTypes() const +{ + return { TEXT_HEIGHT_CONSTRAINT, TEXT_THICKNESS_CONSTRAINT }; +} + + +namespace detail +{ +static DRC_REGISTER_TEST_PROVIDER dummy; +} diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 2383e9d480..6048b8815d 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -765,7 +765,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in if( !loadedBoard->m_LegacyCopperEdgeClearanceLoaded ) { int edgeClearance = inferLegacyEdgeClearance( loadedBoard ); - loadedBoard->GetDesignSettings().SetCopperEdgeClearance( edgeClearance ); + loadedBoard->GetDesignSettings().m_CopperEdgeClearance = edgeClearance; } // On save; design settings will be removed from the board