From 5875f895319d3b855013c444425339f69a7187c3 Mon Sep 17 00:00:00 2001
From: Jeff Young <jeff@rokeby.ie>
Date: Sat, 3 Jun 2023 16:59:00 +0100
Subject: [PATCH] Centralize text size clamping.

Also introduces alg::clamp to improve readability of
std::max( min, std::max( value, max ) )

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14876
---
 .../3d_canvas/create_3Dgraphic_brd_items.cpp  |  2 +-
 common/eda_draw_frame.cpp                     |  2 +-
 common/eda_text.cpp                           | 26 +++++----
 common/gal/color4d.cpp                        |  9 +--
 common/plotters/HPGL_plotter.cpp              |  4 +-
 common/tool/common_tools.cpp                  |  5 +-
 eeschema/dialogs/dialog_sim_format_value.cpp  |  3 +-
 eeschema/sim/spice_value.cpp                  |  6 +-
 include/eda_text.h                            |  5 ++
 .../preview_items/multistep_geom_manager.h    |  5 +-
 libs/core/include/core/kicad_algo.h           |  9 ++-
 libs/kimath/include/math/box2.h               |  7 ++-
 pcbnew/autorouter/ar_autoplacer.cpp           |  3 +-
 pcbnew/board_design_settings.cpp              | 50 ++++++++--------
 pcbnew/dialogs/dialog_drc.cpp                 |  3 +-
 .../dialogs/dialog_footprint_properties.cpp   | 22 +++----
 .../dialog_footprint_properties_fp_editor.cpp | 18 +++---
 .../dialog_global_edit_text_and_graphics.cpp  | 10 ++--
 pcbnew/dialogs/dialog_text_properties.cpp     |  9 ++-
 pcbnew/dialogs/dialog_textbox_properties.cpp  |  9 ++-
 pcbnew/dialogs/panel_setup_layers.cpp         |  1 -
 pcbnew/exporters/export_d356.cpp              |  3 +-
 pcbnew/exporters/gen_drill_report_files.cpp   |  1 -
 pcbnew/footprint_edit_frame.cpp               |  2 -
 pcbnew/footprint_editor_settings.cpp          | 57 +++++++++----------
 pcbnew/footprint_preview_panel.cpp            |  2 +-
 pcbnew/footprint_wizard_frame_functions.cpp   |  1 -
 pcbnew/initpcb.cpp                            |  3 +-
 pcbnew/microwave/microwave_polygon.cpp        |  1 -
 pcbnew/pad.cpp                                |  4 +-
 pcbnew/pad_custom_shape_functions.cpp         |  4 +-
 pcbnew/pcbnew.h                               | 36 ------------
 pcbnew/plugins/kicad/pcb_parser.cpp           |  6 +-
 pcbnew/zone_settings.cpp                      |  3 +-
 34 files changed, 155 insertions(+), 176 deletions(-)
 delete mode 100644 pcbnew/pcbnew.h

diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
index baa569fed6..9be6d1cfb3 100644
--- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
+++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
@@ -269,7 +269,7 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
         else
         {
             circlesegcount = KiROUND( arcsegcount * 360.0 / std::abs( arc_angle.AsDegrees() ) );
-            circlesegcount = std::max( 1, std::min( circlesegcount, 128 ) );
+            circlesegcount = alg::clamp( 1, circlesegcount, 128 );
         }
 
         transformArcToSegments( VECTOR2I( center.x, center.y ), arc->GetStart(), arc_angle,
diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp
index 4bcbb8e46f..213b1b9bf4 100644
--- a/common/eda_draw_frame.cpp
+++ b/common/eda_draw_frame.cpp
@@ -389,7 +389,7 @@ void EDA_DRAW_FRAME::OnUpdateSelectGrid( wxUpdateUIEvent& aEvent )
     wxCHECK( config(), /* void */ );
 
     int idx = config()->m_Window.grid.last_size_idx;
-    idx = std::max( 0, std::min( idx, (int) m_gridSelectBox->GetCount() - 1 ) );
+    idx = alg::clamp( 0, idx, (int) m_gridSelectBox->GetCount() - 1 );
 
     if( idx != m_gridSelectBox->GetSelection() )
         m_gridSelectBox->SetSelection( idx );
diff --git a/common/eda_text.cpp b/common/eda_text.cpp
index e3fa4a19f7..46174625b1 100644
--- a/common/eda_text.cpp
+++ b/common/eda_text.cpp
@@ -42,6 +42,7 @@
 #include <string_utils.h>     // for UnescapeString
 #include <math/util.h>        // for KiROUND
 #include <math/vector2d.h>
+#include <core/kicad_algo.h>
 #include <richio.h>
 #include <render_settings.h>
 #include <trigo.h>            // for RotatePoint
@@ -52,7 +53,6 @@
 #include <font/outline_font.h>
 #include <geometry/shape_poly_set.h>
 #include <properties/property_validators.h>
-#include <pcbnew.h>          // Text limits are in here for some reason
 
 #include <wx/debug.h>           // for wxASSERT
 #include <wx/string.h>
@@ -358,7 +358,11 @@ void EDA_TEXT::SetLineSpacing( double aLineSpacing )
 
 void EDA_TEXT::SetTextSize( const VECTOR2I& aNewSize )
 {
-    m_attributes.m_Size = aNewSize;
+    int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
+    int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
+
+    m_attributes.m_Size = VECTOR2I( alg::clamp( min, aNewSize.x, max ),
+                                    alg::clamp( min, aNewSize.y, max ) );
     ClearRenderCache();
     m_bounding_box_cache_valid = false;
 }
@@ -366,7 +370,10 @@ void EDA_TEXT::SetTextSize( const VECTOR2I& aNewSize )
 
 void EDA_TEXT::SetTextWidth( int aWidth )
 {
-    m_attributes.m_Size.x = aWidth;
+    int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
+    int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
+
+    m_attributes.m_Size.x = alg::clamp( min, aWidth, max );
     ClearRenderCache();
     m_bounding_box_cache_valid = false;
 }
@@ -374,7 +381,10 @@ void EDA_TEXT::SetTextWidth( int aWidth )
 
 void EDA_TEXT::SetTextHeight( int aHeight )
 {
-    m_attributes.m_Size.y = aHeight;
+    int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
+    int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
+
+    m_attributes.m_Size.y = alg::clamp( min, aHeight, max );
     ClearRenderCache();
     m_bounding_box_cache_valid = false;
 }
@@ -1073,17 +1083,13 @@ static struct EDA_TEXT_DESC
                                                           &EDA_TEXT::SetTextWidth,
                                                           &EDA_TEXT::GetTextWidth,
                                                           PROPERTY_DISPLAY::PT_SIZE ),
-                             textProps )
-                .SetValidator( PROPERTY_VALIDATORS::RangeIntValidator<TEXTS_MIN_SIZE,
-                                                                      TEXTS_MAX_SIZE> );
+                             textProps );
 
         propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _HKI( "Height" ),
                                                           &EDA_TEXT::SetTextHeight,
                                                           &EDA_TEXT::GetTextHeight,
                                                           PROPERTY_DISPLAY::PT_SIZE ),
-                             textProps )
-                .SetValidator( PROPERTY_VALIDATORS::RangeIntValidator<TEXTS_MIN_SIZE,
-                                                                      TEXTS_MAX_SIZE> );
+                             textProps );
 
         propMgr.AddProperty( new PROPERTY_ENUM<EDA_TEXT,
                              GR_TEXT_H_ALIGN_T>( _HKI( "Horizontal Justification" ),
diff --git a/common/gal/color4d.cpp b/common/gal/color4d.cpp
index 56ebb2aa16..186b76f205 100644
--- a/common/gal/color4d.cpp
+++ b/common/gal/color4d.cpp
@@ -29,6 +29,7 @@
 #include <i18n_utility.h>
 #include <wx/crt.h>
 #include <math/util.h>
+#include <core/kicad_algo.h>
 
 using namespace KIGFX;
 
@@ -575,10 +576,10 @@ EDA_COLOR_T COLOR4D::FindNearestLegacyColor( int aR, int aG, int aB )
 
 COLOR4D& COLOR4D::FromCSSRGBA( int aRed, int aGreen, int aBlue, double aAlpha )
 {
-    r = std::max( 0, std::min( 255, aRed ) ) / 255.0;
-    g = std::max( 0, std::min( 255, aGreen ) ) / 255.0;
-    b = std::max( 0, std::min( 255, aBlue ) ) / 255.0;
-    a = std::max( 0.0, std::min( 1.0, aAlpha ) );
+    r = alg::clamp( 0, aRed, 255 ) / 255.0;
+    g = alg::clamp( 0, aGreen, 255 ) / 255.0;
+    b = alg::clamp( 0, aBlue, 255 ) / 255.0;
+    a = alg::clamp( 0.0, aAlpha, 1.0 );
 
     return *this;
 }
diff --git a/common/plotters/HPGL_plotter.cpp b/common/plotters/HPGL_plotter.cpp
index 24e397a4fa..24ce9866a5 100644
--- a/common/plotters/HPGL_plotter.cpp
+++ b/common/plotters/HPGL_plotter.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -424,7 +424,7 @@ void HPGL_PLOTTER::Circle( const VECTOR2I& aCenter, int aDiameter, FILL_T aFill,
     double const target_chord_length = m_arcTargetChordLength;
     EDA_ANGLE    chord_angle         = ANGLE_360 * target_chord_length / circumf;
 
-    chord_angle = std::max( m_arcMinChordDegrees, std::min( chord_angle, ANGLE_45 ) );
+    chord_angle = std::clamp( m_arcMinChordDegrees, chord_angle, ANGLE_45 );
 
     if( aFill == FILL_T::FILLED_SHAPE )
     {
diff --git a/common/tool/common_tools.cpp b/common/tool/common_tools.cpp
index f9976fd87d..1e5781cfba 100644
--- a/common/tool/common_tools.cpp
+++ b/common/tool/common_tools.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2014-2016 CERN
- * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
  * @author Maciej Suminski <maciej.suminski@cern.ch>
  *
  * This program is free software; you can redistribute it and/or
@@ -33,6 +33,7 @@
 #include <gal/graphics_abstraction_layer.h>
 #include <id.h>
 #include <math/vector2wx.h>
+#include <core/kicad_algo.h>
 #include <kiface_base.h>
 #include <settings/app_settings.h>
 #include <tool/actions.h>
@@ -457,7 +458,7 @@ int COMMON_TOOLS::GridPreset( int idx )
 {
     int& currentGrid = m_toolMgr->GetSettings()->m_Window.grid.last_size_idx;
 
-    currentGrid = std::max( 0, std::min( idx, (int) m_grids.size() - 1 ) );
+    currentGrid = alg::clamp( 0, idx, (int) m_grids.size() - 1 );
 
     return OnGridChanged();
 }
diff --git a/eeschema/dialogs/dialog_sim_format_value.cpp b/eeschema/dialogs/dialog_sim_format_value.cpp
index 4f8d46fd9c..cda1d73cc7 100644
--- a/eeschema/dialogs/dialog_sim_format_value.cpp
+++ b/eeschema/dialogs/dialog_sim_format_value.cpp
@@ -23,6 +23,7 @@
 
 #include <dialog_sim_format_value.h>
 #include <sim/spice_value.h>
+#include <core/kicad_algo.h>
 
 
 DIALOG_SIM_FORMAT_VALUE::DIALOG_SIM_FORMAT_VALUE( wxWindow* aParent, SPICE_VALUE_FORMAT* aFormat ) :
@@ -88,7 +89,7 @@ DIALOG_SIM_FORMAT_VALUE::DIALOG_SIM_FORMAT_VALUE( wxWindow* aParent, SPICE_VALUE
 
 bool DIALOG_SIM_FORMAT_VALUE::TransferDataFromWindow()
 {
-    m_format->Precision = std::max( 1, std::min( m_precisionCtrl->GetValue(), 9 ) );
+    m_format->Precision = alg::clamp( 1, m_precisionCtrl->GetValue(), 9 );
 
     if( m_rangeCtrl->GetSelection() == 0 )
         m_format->Range = wxS( "~" ) + m_units;
diff --git a/eeschema/sim/spice_value.cpp b/eeschema/sim/spice_value.cpp
index c31d5fd6b8..7b6e4279a5 100644
--- a/eeschema/sim/spice_value.cpp
+++ b/eeschema/sim/spice_value.cpp
@@ -2,6 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2016 CERN
+ * Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
  * @author Maciej Suminski <maciej.suminski@cern.ch>
  *
  * This program is free software; you can redistribute it and/or
@@ -23,7 +24,8 @@
  */
 
 #include "spice_value.h"
-#include "math/util.h"
+#include <math/util.h>
+#include <core/kicad_algo.h>
 
 #include <stdexcept>
 #include <cmath>
@@ -47,7 +49,7 @@ void SPICE_VALUE_FORMAT::FromString( const wxString& aString )
 
 wxString SPICE_VALUE_FORMAT::ToString() const
 {
-    return wxString::Format( wxS( "%d%s" ), std::max( 0, std::min( Precision, 9 ) ), Range );
+    return wxString::Format( wxS( "%d%s" ), alg::clamp( 0, Precision, 9 ), Range );
 }
 
 
diff --git a/include/eda_text.h b/include/eda_text.h
index 40709084cc..781552a4d3 100644
--- a/include/eda_text.h
+++ b/include/eda_text.h
@@ -38,6 +38,11 @@ class SHAPE_COMPOUND;
 class SHAPE_POLY_SET;
 
 
+// These are only here for algorithmic safety, not to tell the user what to do
+#define TEXT_MIN_SIZE_MILS  1        ///< Minimum text size in mils
+#define TEXT_MAX_SIZE_MILS  10000    ///< Maximum text size in mils (10 inches)
+
+
 namespace KIGFX
 {
     class RENDER_SETTINGS;
diff --git a/include/preview_items/multistep_geom_manager.h b/include/preview_items/multistep_geom_manager.h
index 478de64085..20a648624e 100644
--- a/include/preview_items/multistep_geom_manager.h
+++ b/include/preview_items/multistep_geom_manager.h
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -26,6 +26,7 @@
 
 #include <math/vector2d.h>
 #include <algorithm>
+#include <core/kicad_algo.h>
 
 namespace KIGFX {
 namespace PREVIEW {
@@ -170,7 +171,7 @@ private:
         m_step += aForward ? 1 : -1;
 
         // clamp to allowed values
-        m_step = std::min( std::max( m_step, 0 ), getMaxStep() );
+        m_step = alg::clamp( 0, m_step, getMaxStep() );
     }
 
     ///< Has the geometry changed such that a client should redraw?
diff --git a/libs/core/include/core/kicad_algo.h b/libs/core/include/core/kicad_algo.h
index f99c45563e..428d94e81e 100644
--- a/libs/core/include/core/kicad_algo.h
+++ b/libs/core/include/core/kicad_algo.h
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2019 CERN
- * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.TXT for contributors.
+ * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.TXT for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -200,6 +200,13 @@ bool signbit( T v )
 }
 
 
+template <typename T>
+T clamp( T min, T value, T max )
+{
+    return std::max( min, std::min( value, max ) );
+}
+
+
 } // namespace alg
 
 #endif /* INCLUDE_CORE_KICAD_ALGO_H_ */
diff --git a/libs/kimath/include/math/box2.h b/libs/kimath/include/math/box2.h
index f798513757..5939eab82f 100644
--- a/libs/kimath/include/math/box2.h
+++ b/libs/kimath/include/math/box2.h
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
- * Copyright (C) 2012-2022 Kicad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2012-2023 Kicad Developers, see AUTHORS.txt for contributors.
  * Copyright (C) 2013 CERN
  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  *
@@ -33,6 +33,7 @@
 
 #include <math/vector2d.h>
 #include <geometry/eda_angle.h>
+#include <core/kicad_algo.h>
 #include <trigo.h>
 
 /**
@@ -785,8 +786,8 @@ public:
         me.Normalize(); // ensure size is >= 0
 
         // Determine closest point to the circle centre within this rect
-        coord_type nx = std::max( me.GetLeft(), std::min( aPoint.x, me.GetRight() ) );
-        coord_type ny = std::max( me.GetTop(), std::min( aPoint.y, me.GetBottom() ) );
+        coord_type nx = alg::clamp( me.GetLeft(), aPoint.x, me.GetRight() );
+        coord_type ny = alg::clamp( me.GetTop(), aPoint.y, me.GetBottom() );
 
         return Vec( nx, ny );
     }
diff --git a/pcbnew/autorouter/ar_autoplacer.cpp b/pcbnew/autorouter/ar_autoplacer.cpp
index 3c465eb873..f3dc0ed5ce 100644
--- a/pcbnew/autorouter/ar_autoplacer.cpp
+++ b/pcbnew/autorouter/ar_autoplacer.cpp
@@ -5,7 +5,7 @@
  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
  *
- * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -26,7 +26,6 @@
  */
 
 #include <confirm.h>
-#include <pcbnew.h>
 #include <pcb_edit_frame.h>
 #include <widgets/msgpanel.h>
 #include <board.h>
diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp
index 8afd93d10c..0dabac8dd0 100644
--- a/pcbnew/board_design_settings.cpp
+++ b/pcbnew/board_design_settings.cpp
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -33,7 +33,6 @@
 #include <settings/parameters.h>
 #include <project/project_file.h>
 #include <advanced_config.h>
-#include <pcbnew.h>
 
 const int bdsSchemaVersion = 2;
 
@@ -593,21 +592,26 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
             },
             {} ) );
 
+    int minTextSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
+    int maxTextSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
+    int minStroke = 1;
+    int maxStroke = pcbIUScale.mmToIU( 100 );
+
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_line_width",
             &m_LineThickness[LAYER_CLASS_SILK], pcbIUScale.mmToIU( DEFAULT_SILK_LINE_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_size_v",
             &m_TextSize[LAYER_CLASS_SILK].y, pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE ),
-            TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_size_h",
             &m_TextSize[LAYER_CLASS_SILK].x, pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE ),
-            TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_thickness",
-            &m_TextThickness[LAYER_CLASS_SILK], pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_WIDTH ), 1,
-            TEXTS_MAX_WIDTH, pcbIUScale.MM_PER_IU ) );
+            &m_TextThickness[LAYER_CLASS_SILK], pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_WIDTH ),
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM<bool>( "defaults.silk_text_italic",
             &m_TextItalic[LAYER_CLASS_SILK], false ) );
@@ -617,19 +621,19 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_line_width",
             &m_LineThickness[LAYER_CLASS_COPPER], pcbIUScale.mmToIU( DEFAULT_COPPER_LINE_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_size_v",
             &m_TextSize[LAYER_CLASS_COPPER].y, pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_SIZE ),
-            TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_size_h",
             &m_TextSize[LAYER_CLASS_COPPER].x, pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_SIZE ),
-            TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_thickness",
             &m_TextThickness[LAYER_CLASS_COPPER], pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM<bool>( "defaults.copper_text_italic",
             &m_TextItalic[LAYER_CLASS_COPPER], false ) );
@@ -639,27 +643,27 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.board_outline_line_width",
             &m_LineThickness[LAYER_CLASS_EDGES], pcbIUScale.mmToIU( DEFAULT_EDGE_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.courtyard_line_width",
             &m_LineThickness[LAYER_CLASS_COURTYARD], pcbIUScale.mmToIU( DEFAULT_COURTYARD_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_line_width",
             &m_LineThickness[LAYER_CLASS_FAB], pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_size_v",
             &m_TextSize[LAYER_CLASS_FAB].y, pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ),
-            TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_size_h",
             &m_TextSize[LAYER_CLASS_FAB].x, pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ),
-            TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_thickness",
             &m_TextThickness[LAYER_CLASS_FAB], pcbIUScale.mmToIU( DEFAULT_TEXT_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM<bool>( "defaults.fab_text_italic",
             &m_TextItalic[LAYER_CLASS_FAB], false ) );
@@ -669,19 +673,19 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_line_width",
             &m_LineThickness[LAYER_CLASS_OTHERS], pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_size_v",
-            &m_TextSize[LAYER_CLASS_OTHERS].y, pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), TEXTS_MIN_SIZE,
-            TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            &m_TextSize[LAYER_CLASS_OTHERS].y, pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ),
+            minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_size_h",
-            &m_TextSize[LAYER_CLASS_OTHERS].x, pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), TEXTS_MIN_SIZE,
-            TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            &m_TextSize[LAYER_CLASS_OTHERS].x, pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ),
+            minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_thickness",
             &m_TextThickness[LAYER_CLASS_OTHERS], pcbIUScale.mmToIU( DEFAULT_TEXT_WIDTH ),
-            pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ), pcbIUScale.MM_PER_IU ) );
+            minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM<bool>( "defaults.other_text_italic",
             &m_TextItalic[LAYER_CLASS_OTHERS], false ) );
diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp
index bf75e6bbc6..32f87e262d 100644
--- a/pcbnew/dialogs/dialog_drc.cpp
+++ b/pcbnew/dialogs/dialog_drc.cpp
@@ -193,8 +193,7 @@ void DIALOG_DRC::OnActivateDlg( wxActivateEvent& aEvent )
 
 bool DIALOG_DRC::updateUI()
 {
-    double cur = (double) m_progress.load() / m_maxProgress;
-    cur = std::max( 0.0, std::min( cur, 1.0 ) );
+    double cur = alg::clamp( 0.0, (double) m_progress.load() / m_maxProgress, 1.0 );
 
     m_gauge->SetValue( KiROUND( cur * 1000.0 ) );
     wxSafeYield( this );
diff --git a/pcbnew/dialogs/dialog_footprint_properties.cpp b/pcbnew/dialogs/dialog_footprint_properties.cpp
index 5c4d25029d..5cf9746e4f 100644
--- a/pcbnew/dialogs/dialog_footprint_properties.cpp
+++ b/pcbnew/dialogs/dialog_footprint_properties.cpp
@@ -35,7 +35,6 @@
 #include <pcb_edit_frame.h>
 #include <pcbnew_settings.h>
 #include <pgm_base.h>
-#include <pcbnew.h>
 #include <kiplatform/ui.h>
 #include <widgets/grid_text_button_helpers.h>
 #include <widgets/text_ctrl_eval.h>
@@ -367,11 +366,14 @@ bool DIALOG_FOOTPRINT_PROPERTIES::Validate()
             }
         }
 
+        int minSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
+        int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
         int width = m_frame->ValueFromString( m_itemsGrid->GetCellValue( i, FPT_WIDTH ) );
+        int height = m_frame->ValueFromString( m_itemsGrid->GetCellValue( i, FPT_HEIGHT ) );
 
-        if( width < TEXTS_MIN_SIZE )
+        if( width < minSize )
         {
-            wxString min = m_frame->StringFromValue( TEXTS_MIN_SIZE, true );
+            wxString min = m_frame->StringFromValue( minSize, true );
 
             m_itemsGrid->SetCellValue( i, FPT_WIDTH, min );
 
@@ -382,9 +384,9 @@ bool DIALOG_FOOTPRINT_PROPERTIES::Validate()
 
             return false;
         }
-        else if( width > TEXTS_MAX_SIZE )
+        else if( width > maxSize )
         {
-            wxString max = m_frame->StringFromValue( TEXTS_MAX_SIZE, true );
+            wxString max = m_frame->StringFromValue( maxSize, true );
 
             m_itemsGrid->SetCellValue( i, FPT_WIDTH, max );
 
@@ -396,11 +398,9 @@ bool DIALOG_FOOTPRINT_PROPERTIES::Validate()
             return false;
         }
 
-        int height = m_frame->ValueFromString( m_itemsGrid->GetCellValue( i, FPT_HEIGHT ) );
-
-        if( height < TEXTS_MIN_SIZE )
+        if( height < minSize )
         {
-            wxString min = m_frame->StringFromValue( TEXTS_MIN_SIZE, true );
+            wxString min = m_frame->StringFromValue( minSize, true );
 
             m_itemsGrid->SetCellValue( i, FPT_HEIGHT, min );
 
@@ -411,9 +411,9 @@ bool DIALOG_FOOTPRINT_PROPERTIES::Validate()
 
             return false;
         }
-        else if( height > TEXTS_MAX_SIZE )
+        else if( height > maxSize )
         {
-            wxString max = m_frame->StringFromValue( TEXTS_MAX_SIZE, true );
+            wxString max = m_frame->StringFromValue( maxSize, true );
 
             m_itemsGrid->SetCellValue( i, FPT_HEIGHT, max );
 
diff --git a/pcbnew/dialogs/dialog_footprint_properties_fp_editor.cpp b/pcbnew/dialogs/dialog_footprint_properties_fp_editor.cpp
index bb6cfb9d87..c748389a04 100644
--- a/pcbnew/dialogs/dialog_footprint_properties_fp_editor.cpp
+++ b/pcbnew/dialogs/dialog_footprint_properties_fp_editor.cpp
@@ -4,7 +4,7 @@
  * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
  * Copyright (C) 2015 Dick Hollenbeck, dick@softplc.com
  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
- * Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2004-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -44,7 +44,6 @@
 #include "3d_rendering/opengl/3d_model.h"
 #include "filename_resolver.h"
 #include <pgm_base.h>
-#include <pcbnew.h>
 #include "dialogs/panel_preview_3d_model.h"
 #include "dialogs/3d_cache_dialogs.h"
 #include <settings/settings_manager.h>
@@ -420,24 +419,27 @@ bool DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::Validate()
             return false;
         }
 
-        if( text.GetTextWidth() < TEXTS_MIN_SIZE || text.GetTextWidth() > TEXTS_MAX_SIZE )
+        int minSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
+        int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
+
+        if( text.GetTextWidth() < minSize || text.GetTextWidth() > maxSize )
         {
             m_delayedFocusGrid = m_itemsGrid;
             m_delayedErrorMessage = wxString::Format( _( "The text width must be between %s and %s." ),
-                                                      m_frame->StringFromValue( TEXTS_MIN_SIZE, true ),
-                                                      m_frame->StringFromValue( TEXTS_MAX_SIZE, true ) );
+                                                      m_frame->StringFromValue( minSize, true ),
+                                                      m_frame->StringFromValue( maxSize, true ) );
             m_delayedFocusColumn = FPT_WIDTH;
             m_delayedFocusRow = i;
 
             return false;
         }
 
-        if( text.GetTextHeight() < TEXTS_MIN_SIZE || text.GetTextHeight() > TEXTS_MAX_SIZE )
+        if( text.GetTextHeight() < minSize || text.GetTextHeight() > maxSize )
         {
             m_delayedFocusGrid = m_itemsGrid;
             m_delayedErrorMessage = wxString::Format( _( "The text height must be between %s and %s." ),
-                                                      m_frame->StringFromValue( TEXTS_MIN_SIZE, true ),
-                                                      m_frame->StringFromValue( TEXTS_MAX_SIZE, true ) );
+                                                      m_frame->StringFromValue( minSize, true ),
+                                                      m_frame->StringFromValue( maxSize, true ) );
             m_delayedFocusColumn = FPT_HEIGHT;
             m_delayedFocusRow = i;
 
diff --git a/pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp b/pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp
index 9dba3e0149..32df5611bf 100644
--- a/pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp
+++ b/pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -27,7 +27,6 @@
 #include <pcb_edit_frame.h>
 #include <footprint_edit_frame.h>
 #include <pcb_layer_box_selector.h>
-#include <pcbnew.h>
 #include <board.h>
 #include <board_design_settings.h>
 #include <footprint.h>
@@ -497,8 +496,11 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( BOARD_COMMIT& aCommit, BOA
 
 bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataFromWindow()
 {
-    if( !m_textWidth.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE )
-        || !m_textHeight.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE ) )
+    int minTextSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
+    int maxTextSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
+
+    if( !m_textWidth.Validate( minTextSize, maxTextSize )
+        || !m_textHeight.Validate( minTextSize, maxTextSize ) )
     {
         return false;
     }
diff --git a/pcbnew/dialogs/dialog_text_properties.cpp b/pcbnew/dialogs/dialog_text_properties.cpp
index 1ae0a231d5..32050265d4 100644
--- a/pcbnew/dialogs/dialog_text_properties.cpp
+++ b/pcbnew/dialogs/dialog_text_properties.cpp
@@ -30,7 +30,6 @@
 #include <board.h>
 #include <footprint.h>
 #include <pcb_text.h>
-#include <pcbnew.h>
 #include <project.h>
 #include <pcb_edit_frame.h>
 #include <pcb_layer_box_selector.h>
@@ -365,11 +364,11 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataFromWindow()
     if( !DIALOG_TEXT_PROPERTIES_BASE::TransferDataFromWindow() )
         return false;
 
-    if( !m_textWidth.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE )
-        || !m_textHeight.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE ) )
-    {
+    int minSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
+    int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
+
+    if( !m_textWidth.Validate( minSize, maxSize ) || !m_textHeight.Validate( minSize, maxSize ) )
         return false;
-    }
 
     BOARD_COMMIT commit( m_frame );
     commit.Modify( m_item );
diff --git a/pcbnew/dialogs/dialog_textbox_properties.cpp b/pcbnew/dialogs/dialog_textbox_properties.cpp
index 6f04e0e52c..8473f4a1cf 100644
--- a/pcbnew/dialogs/dialog_textbox_properties.cpp
+++ b/pcbnew/dialogs/dialog_textbox_properties.cpp
@@ -30,7 +30,6 @@
 #include <board.h>
 #include <footprint.h>
 #include <pcb_textbox.h>
-#include <pcbnew.h>
 #include <project.h>
 #include <pcb_edit_frame.h>
 #include <pcb_layer_box_selector.h>
@@ -284,11 +283,11 @@ bool DIALOG_TEXTBOX_PROPERTIES::TransferDataFromWindow()
     if( !DIALOG_TEXTBOX_PROPERTIES_BASE::TransferDataFromWindow() )
         return false;
 
-    if( !m_textWidth.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE )
-        || !m_textHeight.Validate( TEXTS_MIN_SIZE, TEXTS_MAX_SIZE ) )
-    {
+    int minSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
+    int maxSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
+
+    if( !m_textWidth.Validate( minSize, maxSize ) || !m_textHeight.Validate( minSize, maxSize ) )
         return false;
-    }
 
     BOARD_COMMIT commit( m_frame );
     commit.Modify( m_textBox );
diff --git a/pcbnew/dialogs/panel_setup_layers.cpp b/pcbnew/dialogs/panel_setup_layers.cpp
index ceb49bd691..58fa7f5166 100644
--- a/pcbnew/dialogs/panel_setup_layers.cpp
+++ b/pcbnew/dialogs/panel_setup_layers.cpp
@@ -27,7 +27,6 @@
 #include <confirm.h>
 #include <core/arraydim.h>
 #include <core/kicad_algo.h>
-#include <pcbnew.h>
 #include <pcb_edit_frame.h>
 #include <board.h>
 #include <collectors.h>
diff --git a/pcbnew/exporters/export_d356.cpp b/pcbnew/exporters/export_d356.cpp
index 225b8645d7..c8e50fc775 100644
--- a/pcbnew/exporters/export_d356.cpp
+++ b/pcbnew/exporters/export_d356.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2011-2013 Lorenzo Marcantonio <l.marcantonio@logossrl.com>
- * Copyright (C) 2004-2022 KiCad Developers, see change_log.txt for contributors.
+ * Copyright (C) 2004-2023 KiCad Developers, see change_log.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -36,7 +36,6 @@
 #include <macros.h>
 #include <wildcards_and_files_ext.h>
 #include <locale_io.h>
-#include <pcbnew.h>
 #include <board.h>
 #include <board_design_settings.h>
 #include <footprint.h>
diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp
index 2bb2fedfa5..a9516685f8 100644
--- a/pcbnew/exporters/gen_drill_report_files.cpp
+++ b/pcbnew/exporters/gen_drill_report_files.cpp
@@ -34,7 +34,6 @@
 
 #include <board.h>
 
-#include <pcbnew.h>
 #include <pcbplot.h>
 #include <gendrill_file_writer_base.h>
 #include <pcb_painter.h>
diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp
index 97b7054e7d..118336af3f 100644
--- a/pcbnew/footprint_edit_frame.cpp
+++ b/pcbnew/footprint_edit_frame.cpp
@@ -43,14 +43,12 @@
 #include <footprint_info_impl.h>
 #include <footprint_tree_pane.h>
 #include <fp_lib_table.h>
-#include <plugins/kicad/pcb_plugin.h>
 #include <kiface_base.h>
 #include <kiplatform/app.h>
 #include <kiway.h>
 #include <macros.h>
 #include <pcb_draw_panel_gal.h>
 #include <pcb_edit_frame.h>
-#include <pcbnew.h>
 #include <pcbnew_id.h>
 #include <pgm_base.h>
 #include <project.h>
diff --git a/pcbnew/footprint_editor_settings.cpp b/pcbnew/footprint_editor_settings.cpp
index 7953ddc0a5..f8afcb5675 100644
--- a/pcbnew/footprint_editor_settings.cpp
+++ b/pcbnew/footprint_editor_settings.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
- * Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * 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
@@ -22,15 +22,14 @@
 #include <footprint_editor_settings.h>
 #include <layer_ids.h>
 #include <pgm_base.h>
+#include <eda_text.h>
 #include <settings/common_settings.h>
 #include <settings/json_settings_internals.h>
 #include <settings/parameters.h>
 #include <settings/settings_manager.h>
 #include <wx/config.h>
 #include <base_units.h>
-#include <widgets/ui_common.h>
 #include <wx/log.h>
-#include <pcbnew.h>
 
 
 ///! Update the schema version whenever a migration is required
@@ -161,95 +160,91 @@ FOOTPRINT_EDITOR_SETTINGS::FOOTPRINT_EDITOR_SETTINGS() :
                                        { "${REFERENCE}", true, F_Fab }
                                    } ) ) );
 
+    int minTextSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
+    int maxTextSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
+    int minStroke = 1;
+    int maxStroke = pcbIUScale.mmToIU( 100 );
+
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.silk_line_width",
             &m_DesignSettings.m_LineThickness[ LAYER_CLASS_SILK ],
-            pcbIUScale.mmToIU( DEFAULT_SILK_LINE_WIDTH ), pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 100.0 ),
-            pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_SILK_LINE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.silk_text_size_h",
             &m_DesignSettings.m_TextSize[ LAYER_CLASS_SILK ].x,
-            pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.silk_text_size_v",
             &m_DesignSettings.m_TextSize[ LAYER_CLASS_SILK ].y,
-            pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.silk_text_thickness",
             &m_DesignSettings.m_TextThickness[ LAYER_CLASS_SILK ],
-            pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_WIDTH ), 1, TEXTS_MAX_WIDTH, pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_SILK_TEXT_WIDTH ), 1, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM<bool>( "design_settings.silk_text_italic",
             &m_DesignSettings.m_TextItalic[ LAYER_CLASS_SILK ], false ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.copper_line_width",
             &m_DesignSettings.m_LineThickness[ LAYER_CLASS_COPPER ],
-            pcbIUScale.mmToIU( DEFAULT_COPPER_LINE_WIDTH ), pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ),
-            pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_COPPER_LINE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.copper_text_size_h",
             &m_DesignSettings.m_TextSize[ LAYER_CLASS_COPPER ].x,
-            pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
-            pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.copper_text_size_v",
             &m_DesignSettings.m_TextSize[ LAYER_CLASS_COPPER ].y,
-            pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE,
-            pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.copper_text_thickness",
             &m_DesignSettings.m_TextThickness[ LAYER_CLASS_COPPER ],
-            pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_WIDTH ), pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ),
-            pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_COPPER_TEXT_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM<bool>( "design_settings.copper_text_italic",
             &m_DesignSettings.m_TextItalic[ LAYER_CLASS_COPPER ], false ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.edge_line_width",
             &m_DesignSettings.m_LineThickness[ LAYER_CLASS_EDGES ],
-            pcbIUScale.mmToIU( DEFAULT_EDGE_WIDTH ), pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ),
-            pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_EDGE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.courtyard_line_width",
             &m_DesignSettings.m_LineThickness[ LAYER_CLASS_COURTYARD ],
-            pcbIUScale.mmToIU( DEFAULT_COURTYARD_WIDTH ), pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ),
-            pcbIUScale.MM_PER_IU ) );
+            pcbIUScale.mmToIU( DEFAULT_COURTYARD_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.fab_line_width",
            &m_DesignSettings.m_LineThickness[ LAYER_CLASS_FAB ],
-           pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ),
-           pcbIUScale.MM_PER_IU ) );
+           pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.fab_text_size_h",
            &m_DesignSettings.m_TextSize[ LAYER_CLASS_FAB ].x,
-           pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+           pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.fab_text_size_v",
            &m_DesignSettings.m_TextSize[ LAYER_CLASS_FAB ].y,
-           pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+           pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.fab_text_thickness",
            &m_DesignSettings.m_TextThickness[ LAYER_CLASS_FAB ],
-           pcbIUScale.mmToIU( DEFAULT_TEXT_WIDTH ), 1, TEXTS_MAX_WIDTH, pcbIUScale.MM_PER_IU ) );
+           pcbIUScale.mmToIU( DEFAULT_TEXT_WIDTH ), 1, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM<bool>( "design_settings.fab_text_italic",
-            &m_DesignSettings.m_TextItalic[ LAYER_CLASS_FAB ], false ) );
+           &m_DesignSettings.m_TextItalic[ LAYER_CLASS_FAB ], false ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.others_line_width",
            &m_DesignSettings.m_LineThickness[ LAYER_CLASS_OTHERS ],
-           pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), pcbIUScale.mmToIU( 0.01 ), pcbIUScale.mmToIU( 5.0 ),
-           pcbIUScale.MM_PER_IU ) );
+           pcbIUScale.mmToIU( DEFAULT_LINE_WIDTH ), minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.others_text_size_h",
            &m_DesignSettings.m_TextSize[ LAYER_CLASS_OTHERS ].x,
-           pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+           pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.others_text_size_v",
            &m_DesignSettings.m_TextSize[ LAYER_CLASS_OTHERS ].y,
-           pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, pcbIUScale.MM_PER_IU ) );
+           pcbIUScale.mmToIU( DEFAULT_TEXT_SIZE ), minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM_SCALED<int>( "design_settings.others_text_thickness",
            &m_DesignSettings.m_TextThickness[ LAYER_CLASS_OTHERS ],
-           pcbIUScale.mmToIU( DEFAULT_TEXT_WIDTH ), 1, TEXTS_MAX_WIDTH, pcbIUScale.MM_PER_IU ) );
+           pcbIUScale.mmToIU( DEFAULT_TEXT_WIDTH ), 1, maxTextSize, pcbIUScale.MM_PER_IU ) );
 
     m_params.emplace_back( new PARAM<bool>( "design_settings.others_text_italic",
             &m_DesignSettings.m_TextItalic[ LAYER_CLASS_OTHERS ], false ) );
diff --git a/pcbnew/footprint_preview_panel.cpp b/pcbnew/footprint_preview_panel.cpp
index 53b16d16e3..edca7ddc15 100644
--- a/pcbnew/footprint_preview_panel.cpp
+++ b/pcbnew/footprint_preview_panel.cpp
@@ -258,7 +258,7 @@ FOOTPRINT_PREVIEW_PANEL* FOOTPRINT_PREVIEW_PANEL::New( KIWAY* aKiway, wxWindow*
     panel->GetGAL()->SetGridVisibility( gridCfg.show );
 
     //Bounds checking cannot include number of elements as an index!
-    int    gridIdx = std::max( 0, std::min( gridCfg.last_size_idx, (int) gridCfg.sizes.size() - 1 ) );
+    int    gridIdx = alg::clamp( 0, gridCfg.last_size_idx, (int) gridCfg.sizes.size() - 1 );
     double gridSize = EDA_UNIT_UTILS::UI::DoubleValueFromString( pcbIUScale, EDA_UNITS::MILS,
                                                                  gridCfg.sizes[ gridIdx ] );
     panel->GetGAL()->SetGridSize( VECTOR2D( gridSize, gridSize ) );
diff --git a/pcbnew/footprint_wizard_frame_functions.cpp b/pcbnew/footprint_wizard_frame_functions.cpp
index e57497eaee..4dc604c773 100644
--- a/pcbnew/footprint_wizard_frame_functions.cpp
+++ b/pcbnew/footprint_wizard_frame_functions.cpp
@@ -26,7 +26,6 @@
 #include <pcb_edit_frame.h>
 #include <board.h>
 #include <footprint.h>
-#include <pcbnew.h>
 #include <pcbnew_id.h>
 #include <wildcards_and_files_ext.h>
 #include <dialogs/dialog_footprint_wizard_list.h>
diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp
index 08d95f3612..ad49a6dccd 100644
--- a/pcbnew/initpcb.cpp
+++ b/pcbnew/initpcb.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -35,7 +35,6 @@
 #include <board.h>
 #include <board_design_settings.h>
 
-#include <pcbnew.h>
 #include <footprint_edit_frame.h>
 #include <widgets/appearance_controls.h>
 
diff --git a/pcbnew/microwave/microwave_polygon.cpp b/pcbnew/microwave/microwave_polygon.cpp
index d2682252ad..6314944fd8 100644
--- a/pcbnew/microwave/microwave_polygon.cpp
+++ b/pcbnew/microwave/microwave_polygon.cpp
@@ -36,7 +36,6 @@
 #include <pcb_shape.h>
 #include <microwave/microwave_tool.h>
 #include <pad.h>
-#include <pcbnew.h>
 #include <math/util.h>      // for KiROUND
 
 #include <wx/button.h>
diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp
index 82678e3304..2200af9604 100644
--- a/pcbnew/pad.cpp
+++ b/pcbnew/pad.cpp
@@ -343,7 +343,7 @@ void PAD::SetRoundRectCornerRadius( double aRadius )
 
 void PAD::SetRoundRectRadiusRatio( double aRadiusScale )
 {
-    m_roundedCornerScale = std::max( 0.0, std::min( aRadiusScale, 0.5 ) );
+    m_roundedCornerScale = alg::clamp( 0.0, aRadiusScale, 0.5 );
 
     SetDirty();
 }
@@ -351,7 +351,7 @@ void PAD::SetRoundRectRadiusRatio( double aRadiusScale )
 
 void PAD::SetChamferRectRatio( double aChamferScale )
 {
-    m_chamferScale = std::max( 0.0, std::min( aChamferScale, 0.5 ) );
+    m_chamferScale = alg::clamp( 0.0, aChamferScale, 0.5 );
 
     SetDirty();
 }
diff --git a/pcbnew/pad_custom_shape_functions.cpp b/pcbnew/pad_custom_shape_functions.cpp
index b7ea9414cc..9a8083ce42 100644
--- a/pcbnew/pad_custom_shape_functions.cpp
+++ b/pcbnew/pad_custom_shape_functions.cpp
@@ -278,8 +278,8 @@ bool PAD::GetBestAnchorPosition( VECTOR2I& aPos )
         stepsX = minSteps * (double) bbox.GetWidth() / (double )(bbox.GetHeight() + 1);
     }
 
-    stepsX = std::max(minSteps, std::min( maxSteps, stepsX ) );
-    stepsY = std::max(minSteps, std::min( maxSteps, stepsY ) );
+    stepsX = alg::clamp( minSteps, maxSteps, stepsX );
+    stepsY = alg::clamp( minSteps, maxSteps, stepsY );
 
     VECTOR2I center = bbox.Centre();
 
diff --git a/pcbnew/pcbnew.h b/pcbnew/pcbnew.h
deleted file mode 100644
index c2049c1c7b..0000000000
--- a/pcbnew/pcbnew.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This program source code file is part of KiCad, a free EDA CAD application.
- *
- * Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
- *
- * 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
- */
-
-#ifndef PCBNEW_H
-#define PCBNEW_H
-
-#include <eda_units.h> // to define pcbIUScale.MilsToIU() conversion function
-
-// These are only here for algorithmic safety, not to tell the user what to do
-#define TEXTS_MIN_SIZE  pcbIUScale.MilsToIU( 1 )        ///< Minimum text size in internal units (1 mil)
-#define TEXTS_MAX_SIZE  pcbIUScale.MilsToIU( 10000 )    ///< Maximum text size in internal units (10 inches)
-#define TEXTS_MAX_WIDTH pcbIUScale.MilsToIU( 10000 )    ///< Maximum text width in internal units (10 inches)
-
-
-#endif // PCBNEW_H
diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp
index 8445bb0ad3..79b6e0f6dc 100644
--- a/pcbnew/plugins/kicad/pcb_parser.cpp
+++ b/pcbnew/plugins/kicad/pcb_parser.cpp
@@ -3402,7 +3402,7 @@ PCB_DIMENSION_BASE* PCB_PARSER::parseDIMENSION( BOARD_ITEM* aParent )
             if( dim->Type() == PCB_DIM_ORTHOGONAL_T )
             {
                 PCB_DIM_ORTHOGONAL* ortho = static_cast<PCB_DIM_ORTHOGONAL*>( dim.get() );
-                orientation = std::max( 0, std::min( 1, orientation ) );
+                orientation = alg::clamp( 0, orientation, 1 );
                 ortho->SetOrientation( static_cast<PCB_DIM_ORTHOGONAL::DIR>( orientation ) );
             }
 
@@ -3442,7 +3442,7 @@ PCB_DIMENSION_BASE* PCB_PARSER::parseDIMENSION( BOARD_ITEM* aParent )
                 case T_units_format:
                 {
                     int format = parseInt( "dimension units format" );
-                    format = std::max( 0, std::min( 3, format ) );
+                    format = alg::clamp( 0, format, 3 );
                     dim->SetUnitsFormat( static_cast<DIM_UNITS_FORMAT>( format ) );
                     NeedRIGHT();
                     break;
@@ -3529,7 +3529,7 @@ PCB_DIMENSION_BASE* PCB_PARSER::parseDIMENSION( BOARD_ITEM* aParent )
                     PCB_DIM_LEADER* leader = static_cast<PCB_DIM_LEADER*>( dim.get() );
 
                     int textFrame = parseInt( "text frame mode" );
-                    textFrame = std::max( 0, std::min( 3, textFrame ) );
+                    textFrame = alg::clamp( 0, textFrame, 3 );
                     leader->SetTextBorder( static_cast<DIM_TEXT_BORDER>( textFrame ));
                     NeedRIGHT();
                     break;
diff --git a/pcbnew/zone_settings.cpp b/pcbnew/zone_settings.cpp
index c15b71e5df..4e436e5965 100644
--- a/pcbnew/zone_settings.cpp
+++ b/pcbnew/zone_settings.cpp
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
- * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -25,7 +25,6 @@
 
 #include <zone_settings.h>
 
-#include <pcbnew.h>
 #include <pcb_base_frame.h>
 #include <board.h>
 #include <settings/color_settings.h>