diff --git a/common/gal/color4d.cpp b/common/gal/color4d.cpp
index d4abcf5c01..823232bd50 100644
--- a/common/gal/color4d.cpp
+++ b/common/gal/color4d.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KICAD, a free EDA CAD application.
  *
  * Copyright 2012 Torsten Hueter, torstenhtr <at> gmx.de
- * Copyright 2017 Kicad Developers, see AUTHORS.txt for contributors.
+ * Copyright 2017-2019 Kicad Developers, see AUTHORS.txt for contributors.
  *
  *
  * This program is free software; you can redistribute it and/or
@@ -283,6 +283,78 @@ std::ostream &operator<<( std::ostream &aStream, COLOR4D const &aColor )
 }
 
 
+void COLOR4D::ToHSL( double& aOutHue, double& aOutSaturation, double& aOutLightness ) const
+{
+    auto min = std::min( r, std::min( g, b ) );
+    auto max = std::max( r, std::max( g, b ) );
+    auto diff = max - min;
+
+    aOutLightness = ( max + min ) / 2.0;
+
+    if( aOutLightness >= 1.0 )
+        aOutSaturation = 0.0;
+    else
+        aOutSaturation = diff / ( 1.0 - std::abs( 2.0 * aOutLightness - 1.0 ) );
+
+    double hue;
+
+    if( diff <= 0.0 )
+        hue = 0.0;
+    else if( max == r )
+        hue = ( g - b ) / diff;
+    else if( max == g )
+        hue = ( b - r ) / diff + 2.0;
+    else
+        hue = ( r - g ) / diff + 4.0;
+
+    aOutHue = hue > 0.0 ? hue * 60.0 : hue * 60.0 + 360.0;
+
+    while( aOutHue < 0.0 )
+        aOutHue += 360.0;
+}
+
+
+void COLOR4D::FromHSL( double aInHue, double aInSaturation, double aInLightness )
+{
+    const auto P = ( 1.0 - std::abs( 2.0 * aInLightness - 1.0 ) ) * aInSaturation;
+    const auto scaled_hue = aInHue / 60.0;
+    const auto Q = P * ( 1.0 - std::abs( std::fmod( scaled_hue, 2.0 ) - 1.0 ) );
+
+    r = g = b = aInLightness - P / 2.0;
+
+    if (scaled_hue < 1.0)
+    {
+        r += P;
+        g += Q;
+    }
+    else if (scaled_hue < 2.0)
+    {
+        r += Q;
+        g += P;
+    }
+    else if (scaled_hue < 3.0)
+    {
+        g += P;
+        b += Q;
+    }
+    else if (scaled_hue < 4.0)
+    {
+        g += Q;
+        b += P;
+    }
+    else if (scaled_hue < 5.0)
+    {
+        r += Q;
+        b += P;
+    }
+    else
+    {
+        r += P;
+        b += Q;
+    }
+}
+
+
 void COLOR4D::ToHSV( double& aOutHue, double& aOutSaturation, double& aOutValue, bool aAlwaysDefineHue ) const
 {
     double min, max, delta;
diff --git a/include/gal/color4d.h b/include/gal/color4d.h
index a5bf00c865..cdbf88d542 100644
--- a/include/gal/color4d.h
+++ b/include/gal/color4d.h
@@ -139,6 +139,28 @@ public:
     static EDA_COLOR_T GetNearestLegacyColor( const COLOR4D &aColor );
 #endif /* WX_COMPATIBLITY */
 
+
+    /**
+     * Function ToHSL()
+     * Converts current color (stored in RGB) to HSL format.
+     *
+     * @param aOutHue is the conversion result for hue component, in degrees 0 ... 360.0
+     * @param aOutSaturation is the conversion result for saturation component (0 ... 1.0).
+     * @param aOutLightness is conversion result for value component (0 ... 1.0).
+     * @note saturation is set to 0.0 for black color if r = g = b,
+     */
+    void ToHSL( double& aOutHue, double& aOutSaturation, double& aOutValue ) const;
+
+    /**
+     * Function FromHSL()
+     * Changes currently used color to the one given by hue, saturation and lightness parameters.
+     *
+     * @param aInHue is hue component, in degrees (0.0 - 360.0)
+     * @param aInSaturation is saturation component (0.0 - 1.0)
+     * @param aInLightness is lightness component (0.0 - 1.0)
+     */
+    void FromHSL( double aInHue, double aInSaturation, double aInLightness );
+
     /**
      * Function Brighten
      * Makes the color brighter by a given factor.
diff --git a/pcbnew/router/pns_tune_status_popup.cpp b/pcbnew/router/pns_tune_status_popup.cpp
index 5c4c283d2c..be519a0c9c 100644
--- a/pcbnew/router/pns_tune_status_popup.cpp
+++ b/pcbnew/router/pns_tune_status_popup.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2014-2015  CERN
- * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2016-2019 KiCad Developers, see AUTHORS.txt for contributors.
  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
  *
  * This program is free software: you can redistribute it and/or modify it
@@ -33,16 +33,33 @@ void PNS_TUNE_STATUS_POPUP::UpdateStatus( PNS::ROUTER* aRouter )
 
     SetText( placer->TuningInfo( m_frame->GetUserUnits() ) );
 
+    // Determine the background color first and choose a contrasting value
+    COLOR4D bg( m_panel->GetBackgroundColour() );
+    double h, s, l;
+    bg.ToHSL( h, s, l );
+
     switch( placer->TuningStatus() )
     {
     case PNS::MEANDER_PLACER::TUNED:
-        SetTextColor( wxColour( 0, 255, 0 ) );
+        if( l < 0.5 )
+            SetTextColor( wxColor( 0, 255, 0 ) );
+        else
+            SetTextColor( wxColor( 0, 128, 0 ) );
+
         break;
     case PNS::MEANDER_PLACER::TOO_SHORT:
-        SetTextColor( wxColour( 255, 128, 128 ) );
+        if( l < 0.5 )
+            SetTextColor( wxColor( 255, 128, 128 ) );
+        else
+            SetTextColor( wxColor( 128, 64, 64 ) );
+
         break;
     case PNS::MEANDER_PLACER::TOO_LONG:
-        SetTextColor( wxColour( 128, 128, 255 ) );
+        if( l < 0.5 )
+            SetTextColor( wxColor( 24, 24, 255 ) );
+        else
+            SetTextColor( wxColor( 19, 19, 195 ) );
+
         break;
     }
 }
diff --git a/qa/common/test_color4d.cpp b/qa/common/test_color4d.cpp
index 9d9354c4a2..0afeb18d76 100644
--- a/qa/common/test_color4d.cpp
+++ b/qa/common/test_color4d.cpp
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
+ * Copyright (C) 2018-2019 KiCad Developers, see CHANGELOG.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
@@ -217,16 +217,70 @@ struct FROM_HSV_TO_HEX_CASE
 BOOST_AUTO_TEST_CASE( FromHsv )
 {
     static const std::vector<FROM_HSV_TO_HEX_CASE> cases = {
-        { 90.0, 0.5, 0.5, 96, 128, 64 },
+        {  10, 0.71, 0.66, 168,  69,  49 },
+        {  15, 0.96, 0.34,  87,  24,   3 },
+        { 120, 0.50, 0.50,  64, 128,  64 },
+        { 190, 0.32, 0.97, 168, 234, 247 },
+        { 240, 0.15, 0.75, 163, 163, 191 },
+        { 240, 0.90, 0.75,  19,  19, 191 },
+        { 310, 0.71, 0.66, 168,  49, 148 },
+        { 331, 0.15, 0.85, 217, 184, 200 },
     };
 
     for( const auto& c : cases )
     {
         auto col = COLOR4D{};
         col.FromHSV( c.h, c.s, c.v );
+        double new_h, new_s, new_v;
+        col.ToHSV( new_h, new_s, new_v );
         const unsigned char alpha = 0xFF;
 
         BOOST_CHECK_PREDICATE( pred_colour_is_near_hex, ( col )( c.r )( c.g )( c.b )( alpha ) );
+        BOOST_CHECK_CLOSE( c.h, new_h, 0.0001 );
+        BOOST_CHECK_CLOSE( c.s, new_s, 0.0001 );
+        BOOST_CHECK_CLOSE( c.v, new_v, 0.0001 );
+    }
+}
+
+struct FROM_HSL_TO_HEX_CASE
+{
+    double        h;
+    double        s;
+    double        l;
+    unsigned char r;
+    unsigned char g;
+    unsigned char b;
+};
+
+
+/**
+ * Check FromHSL
+ */
+BOOST_AUTO_TEST_CASE( FromHsl )
+{
+    static const std::vector<FROM_HSL_TO_HEX_CASE> cases = {
+        {  10, 0.71, 0.66, 230, 127, 107 },
+        {  15, 0.96, 0.34, 170,  45,   3 },
+        { 120, 0.5,  0.5,   64, 191,  64 },
+        { 190, 0.32, 0.97, 245, 249, 250 },
+        { 240, 0.15, 0.75, 182, 182, 201 },
+        { 240, 0.90, 0.75, 134, 134, 249 },
+        { 310, 0.71, 0.66, 230, 107, 209 },
+        { 331, 0.15, 0.85, 222, 211, 217 },
+    };
+
+    for( const auto& c : cases )
+    {
+        auto col = COLOR4D{};
+        col.FromHSL( c.h, c.s, c.l );
+        double new_h, new_s, new_l;
+        col.ToHSL( new_h, new_s, new_l );
+        const unsigned char alpha = 0xFF;
+
+        BOOST_CHECK_PREDICATE( pred_colour_is_near_hex, ( col )( c.r )( c.g )( c.b )( alpha ) );
+        BOOST_CHECK_CLOSE( c.h, new_h, 0.0001 );
+        BOOST_CHECK_CLOSE( c.s, new_s, 0.0001 );
+        BOOST_CHECK_CLOSE( c.l, new_l, 0.0001 );
     }
 }