diff --git a/common/import_gfx/dxf_import_plugin.cpp b/common/import_gfx/dxf_import_plugin.cpp
index 6701d32955..a34817c3d9 100644
--- a/common/import_gfx/dxf_import_plugin.cpp
+++ b/common/import_gfx/dxf_import_plugin.cpp
@@ -178,6 +178,16 @@ double DXF_IMPORT_PLUGIN::GetImageHeight() const
 }
 
 
+BOX2D DXF_IMPORT_PLUGIN::GetImageBBox() const
+{
+    BOX2D bbox;
+    bbox.SetOrigin( m_minX, m_minY );
+    bbox.SetEnd( m_maxX, m_maxY );
+
+    return bbox;
+}
+
+
 void DXF_IMPORT_PLUGIN::SetImporter( GRAPHICS_IMPORTER* aImporter )
 {
     GRAPHICS_IMPORT_PLUGIN::SetImporter( aImporter );
diff --git a/common/import_gfx/dxf_import_plugin.h b/common/import_gfx/dxf_import_plugin.h
index e26ea6830d..9a520d5fda 100644
--- a/common/import_gfx/dxf_import_plugin.h
+++ b/common/import_gfx/dxf_import_plugin.h
@@ -236,6 +236,7 @@ public:
 
     double GetImageWidth() const override;
     double GetImageHeight() const override;
+    BOX2D GetImageBBox() const override;
 
     void updateImageLimits( const VECTOR2D& aPoint );
 
diff --git a/common/import_gfx/graphics_import_plugin.h b/common/import_gfx/graphics_import_plugin.h
index 103c6b7be3..c6189505db 100644
--- a/common/import_gfx/graphics_import_plugin.h
+++ b/common/import_gfx/graphics_import_plugin.h
@@ -27,6 +27,7 @@
 #ifndef GRAPHICS_IMPORT_PLUGIN_H
 #define GRAPHICS_IMPORT_PLUGIN_H
 
+#include <math/box2.h>
 #include <wildcards_and_files_ext.h>
 #include <wx/arrstr.h>
 
@@ -112,6 +113,13 @@ public:
      */
     virtual double GetImageWidth() const = 0;
 
+    /**
+     * Return image bounding box from original imported file.
+     *
+     * @return Image bounding box.
+     */
+    virtual BOX2D GetImageBBox() const = 0;
+
     /**
      * Actually imports the file.
      *
diff --git a/common/import_gfx/graphics_importer.cpp b/common/import_gfx/graphics_importer.cpp
index 6158b1dff8..5b2230796e 100644
--- a/common/import_gfx/graphics_importer.cpp
+++ b/common/import_gfx/graphics_importer.cpp
@@ -2,6 +2,8 @@
  * This program source code file is part of KICAD, a free EDA CAD application.
  *
  * Copyright (C) 2016 CERN
+ * Copyright (C) 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
@@ -30,13 +32,13 @@ GRAPHICS_IMPORTER::GRAPHICS_IMPORTER()
 {
     m_millimeterToIu = 1.0;
     m_lineWidth = DEFAULT_LINE_WIDTH_DFX;
-    m_scale = 1.0;
+    m_scale = VECTOR2D( 1.0, 1.0 );
     m_originalWidth = 0.0;
     m_originalHeight = 0.0;
 }
 
 
-bool GRAPHICS_IMPORTER::Load( const wxString &aFileName )
+bool GRAPHICS_IMPORTER::Load( const wxString& aFileName )
 {
     m_items.clear();
 
@@ -48,10 +50,19 @@ bool GRAPHICS_IMPORTER::Load( const wxString &aFileName )
 
     m_plugin->SetImporter( this );
 
-    return m_plugin->Load( aFileName );
+    bool ret = m_plugin->Load( aFileName );
+
+    if( ret )
+    {
+        m_originalWidth = m_plugin->GetImageWidth();
+        m_originalHeight = m_plugin->GetImageHeight();
+    }
+
+    return ret;
 }
 
-bool GRAPHICS_IMPORTER::Import( double aScale )
+
+bool GRAPHICS_IMPORTER::Import( const VECTOR2D& aScale )
 {
     if( !m_plugin )
     {
diff --git a/common/import_gfx/graphics_importer.h b/common/import_gfx/graphics_importer.h
index 640ae48771..a4236dbbff 100644
--- a/common/import_gfx/graphics_importer.h
+++ b/common/import_gfx/graphics_importer.h
@@ -2,7 +2,7 @@
  * This program source code file is part of KICAD, a free EDA CAD application.
  *
  * Copyright (C) 2016 CERN
- * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * @author Maciej Suminski <maciej.suminski@cern.ch>
  *
@@ -32,6 +32,7 @@
 
 #include <eda_text.h>
 #include <math/vector2d.h>
+#include <gal/color4d.h>
 
 #include <list>
 #include <memory>
@@ -81,9 +82,9 @@ public:
      * It is important to have the file loaded before importing.
      *
      * @param aScale allow import graphic items with a non 1:1 import ratio
-     * aScale = 1.0 to import graphics with their actual size.
+     * VECTOR2D( 1.0, 1.0 ) to import graphics with their actual size.
      */
-    bool Import( double aScale = 1.0 );
+    bool Import( const VECTOR2D& aScale = VECTOR2D( 1.0, 1.0 ) );
 
     /**
      * Collect warning and error messages after loading/importing.
@@ -134,7 +135,7 @@ public:
     /**
      * @return the scale factor affecting the imported shapes.
      */
-    double GetScale() const
+    VECTOR2D GetScale() const
     {
         return m_scale;
     }
@@ -160,7 +161,7 @@ public:
      *
      * This allows conversion between imported shapes units and millimeters.
      */
-    void SetScale( double aScale )
+    void SetScale( const VECTOR2D& aScale )
     {
         m_scale = aScale;
     }
@@ -176,7 +177,7 @@ public:
     /**
      * @return the overall scale factor to convert the imported shapes dimension to mm.
      */
-    double ImportScalingFactor() const
+    VECTOR2D ImportScalingFactor() const
     {
         return m_scale * m_millimeterToIu;
     }
@@ -208,8 +209,10 @@ public:
      * @param aOrigin is the segment origin point expressed in mm.
      * @param aEnd is the segment end point expressed in mm.
      * @param aWidth is the segment thickness in mm. Use -1 for default line thickness
+     * @param aColor is the shape color
      */
-    virtual void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth ) = 0;
+    virtual void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth,
+                          const COLOR4D& aColor ) = 0;
 
     /**
      * Create an object representing a circle.
@@ -217,9 +220,10 @@ public:
      * @param aCenter is the circle center point expressed in mm.
      * @param aRadius is the circle radius expressed in mm.
      * @param aWidth is the segment thickness in mm. Use -1 for default line thickness
+     * @param aColor is the shape color
      */
-    virtual void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth,
-                            bool aFilled ) = 0;
+    virtual void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled,
+                            const COLOR4D& aColor ) = 0;
 
     /**
      * Create an object representing an arc.
@@ -229,11 +233,13 @@ public:
      * Its length is the arc radius.
      * @param aAngle is the arc angle.
      * @param aWidth is the segment thickness in mm. Use -1 for default line thickness
+     * @param aColor is the shape color
      */
     virtual void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle,
-                         double aWidth ) = 0;
+                         double aWidth, const COLOR4D& aColor ) = 0;
 
-    virtual void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) = 0;
+    virtual void AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth,
+                             const COLOR4D& aColor ) = 0;
 
     /**
      * Create an object representing a text.
@@ -246,10 +252,12 @@ public:
      * @param aHJustify is the text horizontal justification.
      * @param aVJustify is the text vertical justification.
      * @param aWidth is the segment thickness in mm. Use -1 for default line thickness
+     * @param aColor is the shape color
      */
     virtual void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight,
                           double aWidth, double aThickness, double aOrientation,
-                          GR_TEXT_H_ALIGN_T aHJustify, GR_TEXT_V_ALIGN_T aVJustify ) = 0;
+                          GR_TEXT_H_ALIGN_T aHJustify, GR_TEXT_V_ALIGN_T aVJustify,
+                          const COLOR4D& aColor ) = 0;
 
     /**
      * Create an object representing an arc.
@@ -259,10 +267,11 @@ public:
      * @param aBezierControl2 is the second Bezier control point expressed in mm.
      * @param aEnd is the curve end point expressed in mm.
      * @param aWidth is the segment thickness in mm. Use -1 for default line thickness
+     * @param aColor is the shape color
      */
     virtual void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1,
-                            const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd,
-                            double aWidth ) = 0;
+                            const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth,
+                            const COLOR4D& aColor ) = 0;
 
 protected:
     ///< Add an item to the imported shapes list.
@@ -297,7 +306,7 @@ private:
      * 1.0 does not change the size of imported items
      * scale < 1.0 reduce the size of imported items
      */
-    double m_scale;
+    VECTOR2D m_scale;
 
     ///< Default line thickness for the imported graphics
     double m_lineWidth;
diff --git a/common/import_gfx/graphics_importer_buffer.cpp b/common/import_gfx/graphics_importer_buffer.cpp
index 3084436ecb..36d9ab47d6 100644
--- a/common/import_gfx/graphics_importer_buffer.cpp
+++ b/common/import_gfx/graphics_importer_buffer.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KICAD, a free EDA CAD application.
  *
  * Copyright (C) 2017 CERN
- * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
  * @author Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
@@ -38,28 +38,32 @@ static std::unique_ptr<T> make_shape( const Args&... aArguments )
     return std::make_unique<T>( aArguments... );
 }
 
-void GRAPHICS_IMPORTER_BUFFER::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth )
+void GRAPHICS_IMPORTER_BUFFER::AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth,
+                                        const COLOR4D& aColor )
 {
-    m_shapes.push_back( make_shape< IMPORTED_LINE >( aStart, aEnd, aWidth ) );
+    m_shapes.push_back( make_shape< IMPORTED_LINE >( aStart, aEnd, aWidth, aColor ) );
 }
 
 
-void GRAPHICS_IMPORTER_BUFFER::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled )
+void GRAPHICS_IMPORTER_BUFFER::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth,
+                                          bool aFilled, const COLOR4D& aColor )
 {
-    m_shapes.push_back( make_shape<IMPORTED_CIRCLE>( aCenter, aRadius, aWidth, aFilled ) );
+    m_shapes.push_back( make_shape<IMPORTED_CIRCLE>( aCenter, aRadius, aWidth, aFilled, aColor ) );
 }
 
 
 void GRAPHICS_IMPORTER_BUFFER::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart,
-                                       const EDA_ANGLE& aAngle, double aWidth )
+                                       const EDA_ANGLE& aAngle, double aWidth,
+                                       const COLOR4D& aColor )
 {
-    m_shapes.push_back( make_shape<IMPORTED_ARC>( aCenter, aStart, aAngle, aWidth ) );
+    m_shapes.push_back( make_shape<IMPORTED_ARC>( aCenter, aStart, aAngle, aWidth, aColor ) );
 }
 
 
-void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth )
+void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth,
+                                           const COLOR4D& aColor )
 {
-    m_shapes.push_back( make_shape<IMPORTED_POLYGON>( aVertices, aWidth ) );
+    m_shapes.push_back( make_shape<IMPORTED_POLYGON>( aVertices, aWidth, aColor ) );
     m_shapes.back()->SetParentShapeIndex( m_shapeFillRules.size() - 1 );
 }
 
@@ -67,17 +71,18 @@ void GRAPHICS_IMPORTER_BUFFER::AddPolygon( const std::vector< VECTOR2D >& aVerti
 void GRAPHICS_IMPORTER_BUFFER::AddText( const VECTOR2D& aOrigin, const wxString& aText,
                                         double aHeight, double aWidth, double aThickness,
                                         double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
-                                        GR_TEXT_V_ALIGN_T aVJustify )
+                                        GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor )
 {
     m_shapes.push_back( make_shape< IMPORTED_TEXT >( aOrigin, aText, aHeight, aWidth,
-                        aThickness, aOrientation, aHJustify, aVJustify ) );
+                        aThickness, aOrientation, aHJustify, aVJustify, aColor ) );
 }
 
 
 void GRAPHICS_IMPORTER_BUFFER::AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1,
-                const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd , double aWidth )
+                                          const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd,
+                                          double aWidth, const COLOR4D& aColor )
 {
-    m_shapes.push_back( make_shape<IMPORTED_SPLINE>( aStart, aBezierControl1, aBezierControl2, aEnd, aWidth ) );
+    m_shapes.push_back( make_shape<IMPORTED_SPLINE>( aStart, aBezierControl1, aBezierControl2, aEnd, aWidth, aColor ) );
 }
 
 
@@ -96,8 +101,8 @@ void GRAPHICS_IMPORTER_BUFFER::ImportTo( GRAPHICS_IMPORTER& aImporter )
 // converts a single SVG-style polygon (multiple outlines, hole detection based on orientation, custom fill rule) to a format that can be digested by KiCad (single outline, fractured)
 static void convertPolygon( std::list<std::unique_ptr<IMPORTED_SHAPE>>& aShapes,
                             std::vector<IMPORTED_POLYGON*>&             aPaths,
-                            GRAPHICS_IMPORTER::POLY_FILL_RULE           aFillRule,
-                            double aWidth )
+                            GRAPHICS_IMPORTER::POLY_FILL_RULE aFillRule, double aWidth,
+                            const COLOR4D& aColor )
 {
     double minX = std::numeric_limits<double>::max();
     double minY = minX;
@@ -165,15 +170,16 @@ static void convertPolygon( std::list<std::unique_ptr<IMPORTED_SHAPE>>& aShapes,
             pts.emplace_back( VECTOR2D( xp, yp ) );
         }
 
-        aShapes.push_back( std::make_unique<IMPORTED_POLYGON>( pts, aWidth ) );
+        aShapes.push_back( std::make_unique<IMPORTED_POLYGON>( pts, aWidth, aColor ) );
     }
 }
 
 
 void GRAPHICS_IMPORTER_BUFFER::PostprocessNestedPolygons()
 {
-    int curShapeIdx = -1;
-    double lastWidth = 0;
+    int     curShapeIdx = -1;
+    double  lastWidth = 0;
+    COLOR4D lastColor = COLOR4D::UNSPECIFIED;
 
     std::list<std::unique_ptr<IMPORTED_SHAPE>> newShapes;
     std::vector<IMPORTED_POLYGON*>             polypaths;
@@ -192,17 +198,19 @@ void GRAPHICS_IMPORTER_BUFFER::PostprocessNestedPolygons()
 
         if( index != curShapeIdx && curShapeIdx >= 0 )
         {
-            convertPolygon( newShapes, polypaths, m_shapeFillRules[curShapeIdx], lastWidth );
+            convertPolygon( newShapes, polypaths, m_shapeFillRules[curShapeIdx], lastWidth,
+                            lastColor );
             polypaths.clear();
         }
 
         curShapeIdx = index;
         lastWidth = poly->GetWidth();
+        lastColor = poly->GetColor();
         polypaths.push_back( poly );
     }
 
     if( curShapeIdx >= 0 )
-        convertPolygon( newShapes, polypaths, m_shapeFillRules[curShapeIdx], lastWidth );
+        convertPolygon( newShapes, polypaths, m_shapeFillRules[curShapeIdx], lastWidth, lastColor );
 
     m_shapes.swap( newShapes );
 }
diff --git a/common/import_gfx/graphics_importer_buffer.h b/common/import_gfx/graphics_importer_buffer.h
index 52c2cb372d..26889e7acf 100644
--- a/common/import_gfx/graphics_importer_buffer.h
+++ b/common/import_gfx/graphics_importer_buffer.h
@@ -2,7 +2,7 @@
  * This program source code file is part of KICAD, a free EDA CAD application.
  *
  * Copyright (C) 2017 CERN
- * Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * @author Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
  *
@@ -53,16 +53,16 @@ protected:
 class IMPORTED_LINE : public IMPORTED_SHAPE
 {
 public:
-    IMPORTED_LINE( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth ) :
+    IMPORTED_LINE( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth,
+                   const COLOR4D& aColor ) :
             m_start( aStart ),
-            m_end( aEnd ),
-            m_width( aWidth )
+            m_end( aEnd ), m_width( aWidth ), m_color( aColor )
     {
     }
 
     void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override
     {
-        aImporter.AddLine( m_start, m_end, m_width );
+        aImporter.AddLine( m_start, m_end, m_width, m_color );
     }
 
     virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override
@@ -80,23 +80,23 @@ private:
     VECTOR2D m_start;
     VECTOR2D m_end;
     double   m_width;
+    COLOR4D  m_color;
 };
 
 
 class IMPORTED_CIRCLE : public IMPORTED_SHAPE
 {
 public:
-    IMPORTED_CIRCLE( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled ) :
+    IMPORTED_CIRCLE( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled,
+                     const COLOR4D& aColor ) :
             m_center( aCenter ),
-            m_radius( aRadius ),
-            m_width( aWidth ),
-            m_filled( aFilled )
+            m_radius( aRadius ), m_width( aWidth ), m_filled( aFilled ), m_color( aColor )
     {
     }
 
     void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override
     {
-        aImporter.AddCircle( m_center, m_radius, m_width, m_filled );
+        aImporter.AddCircle( m_center, m_radius, m_width, m_filled, m_color );
     }
 
     virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override
@@ -120,6 +120,7 @@ private:
     double   m_radius;
     double   m_width;
     bool     m_filled;
+    COLOR4D  m_color;
 };
 
 
@@ -127,17 +128,15 @@ class IMPORTED_ARC : public IMPORTED_SHAPE
 {
 public:
     IMPORTED_ARC( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle,
-                  double aWidth )  :
+                  double aWidth, const COLOR4D& aColor ) :
             m_center( aCenter ),
-            m_start( aStart ),
-            m_angle( aAngle ),
-            m_width( aWidth )
+            m_start( aStart ), m_angle( aAngle ), m_width( aWidth ), m_color( aColor )
     {
     }
 
     void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override
     {
-        aImporter.AddArc( m_center, m_start, m_angle, m_width );
+        aImporter.AddArc( m_center, m_start, m_angle, m_width, m_color );
     }
 
     virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override
@@ -156,21 +155,23 @@ private:
     VECTOR2D  m_start;
     EDA_ANGLE m_angle;
     double    m_width;
+    COLOR4D   m_color;
 };
 
 
 class IMPORTED_POLYGON : public IMPORTED_SHAPE
 {
 public:
-    IMPORTED_POLYGON( const std::vector< VECTOR2D >& aVertices, double aWidth ) :
+    IMPORTED_POLYGON( const std::vector<VECTOR2D>& aVertices, double aWidth,
+                      const COLOR4D& aColor ) :
             m_vertices( aVertices ),
-            m_width( aWidth )
+            m_width( aWidth ), m_color( aColor )
     {
     }
 
     void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override
     {
-        aImporter.AddPolygon( m_vertices, m_width );
+        aImporter.AddPolygon( m_vertices, m_width, m_color );
     }
 
     virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override
@@ -190,9 +191,12 @@ public:
 
     double GetWidth() const { return m_width; }
 
+    const COLOR4D& GetColor() const { return m_color; }
+
 private:
     std::vector<VECTOR2D> m_vertices;
     double                m_width;
+    COLOR4D               m_color;
 };
 
 
@@ -201,22 +205,18 @@ class IMPORTED_TEXT : public IMPORTED_SHAPE
 public:
     IMPORTED_TEXT( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth,
                    double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
-                   GR_TEXT_V_ALIGN_T aVJustify ) :
-        m_origin( aOrigin ),
-        m_text( aText ),
-        m_height( aHeight ),
-        m_width( aWidth ),
-        m_thickness( aThickness ),
-        m_orientation( aOrientation ),
-        m_hJustify( aHJustify ),
-        m_vJustify( aVJustify )
+                   GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) :
+            m_origin( aOrigin ),
+            m_text( aText ), m_height( aHeight ), m_width( aWidth ), m_thickness( aThickness ),
+            m_orientation( aOrientation ), m_hJustify( aHJustify ), m_vJustify( aVJustify ),
+            m_color( aColor )
     {
     }
 
     void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override
     {
-        aImporter.AddText( m_origin, m_text, m_height, m_width,
-                    m_thickness, m_orientation, m_hJustify, m_vJustify );
+        aImporter.AddText( m_origin, m_text, m_height, m_width, m_thickness, m_orientation,
+                           m_hJustify, m_vJustify, m_color );
     }
 
     virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override
@@ -238,6 +238,7 @@ private:
     double              m_orientation;
     GR_TEXT_H_ALIGN_T   m_hJustify;
     GR_TEXT_V_ALIGN_T   m_vJustify;
+    COLOR4D             m_color;
 };
 
 
@@ -245,18 +246,17 @@ class IMPORTED_SPLINE : public IMPORTED_SHAPE
 {
 public:
     IMPORTED_SPLINE( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1,
-                     const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth ) :
-        m_start( aStart ),
-        m_bezierControl1( aBezierControl1 ),
-        m_bezierControl2( aBezierControl2 ),
-        m_end( aEnd ),
-        m_width( aWidth )
+                     const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth,
+                     const COLOR4D& aColor ) :
+            m_start( aStart ),
+            m_bezierControl1( aBezierControl1 ), m_bezierControl2( aBezierControl2 ), m_end( aEnd ),
+            m_width( aWidth ), m_color( aColor )
     {
     }
 
     void ImportTo( GRAPHICS_IMPORTER& aImporter ) const override
     {
-        aImporter.AddSpline( m_start, m_bezierControl1, m_bezierControl2, m_end, m_width );
+        aImporter.AddSpline( m_start, m_bezierControl1, m_bezierControl2, m_end, m_width, m_color );
     }
 
     virtual std::unique_ptr<IMPORTED_SHAPE> clone() const override
@@ -278,27 +278,33 @@ private:
     VECTOR2D m_bezierControl2;
     VECTOR2D m_end;
     double   m_width;
+    COLOR4D  m_color;
 };
 
 
 class GRAPHICS_IMPORTER_BUFFER : public GRAPHICS_IMPORTER
 {
 public:
-    void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth ) override;
+    void AddLine( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aWidth,
+                  const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override;
 
-    void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled ) override;
+    void AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled,
+                    const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override;
 
     void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle,
-                 double aWidth ) override;
+                 double aWidth, const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override;
 
-    void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) override;
+    void AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth,
+                     const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override;
 
     void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth,
                   double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
-                  GR_TEXT_V_ALIGN_T aVJustify ) override;
+                  GR_TEXT_V_ALIGN_T aVJustify,
+                  const COLOR4D&    aColor = COLOR4D::UNSPECIFIED ) override;
 
     void AddSpline( const VECTOR2D& aStart, const VECTOR2D& BezierControl1,
-                    const VECTOR2D& BezierControl2, const VECTOR2D& aEnd , double aWidth ) override;
+                    const VECTOR2D& BezierControl2, const VECTOR2D& aEnd, double aWidth,
+                    const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) override;
 
     void ImportTo( GRAPHICS_IMPORTER& aImporter );
     void AddShape( std::unique_ptr<IMPORTED_SHAPE>& aShape );
diff --git a/common/import_gfx/svg_import_plugin.cpp b/common/import_gfx/svg_import_plugin.cpp
index 2540d4dca1..0a71b9deca 100644
--- a/common/import_gfx/svg_import_plugin.cpp
+++ b/common/import_gfx/svg_import_plugin.cpp
@@ -29,8 +29,6 @@
 #include <algorithm>
 #include <cmath>
 
-#include <math/vector2d.h>
-
 #include <eda_item.h>
 #include "graphics_importer.h"
 
@@ -101,9 +99,24 @@ bool SVG_IMPORT_PLUGIN::Import()
 
     for( NSVGshape* shape = m_parsedImage->shapes; shape != nullptr; shape = shape->next )
     {
-        double lineWidth = shape->strokeWidth;
+        double lineWidth = shape->stroke.type != NSVG_PAINT_NONE ? shape->strokeWidth : -1;
         bool   filled = shape->fill.type != NSVG_PAINT_NONE && alpha( shape->fill.color ) > 0;
 
+        COLOR4D color = COLOR4D::UNSPECIFIED;
+
+        if( shape->fill.type == NSVG_PAINT_COLOR )
+        {
+            unsigned int icolor = shape->fill.color;
+
+            color.r = std::clamp( ( icolor >> 0 ) & 0xFF, 0u, 255u ) / 255.0;
+            color.g = std::clamp( ( icolor >> 8 ) & 0xFF, 0u, 255u ) / 255.0;
+            color.b = std::clamp( ( icolor >> 16 ) & 0xFF, 0u, 255u ) / 255.0;
+            color.a = std::clamp( ( icolor >> 24 ) & 0xFF, 0u, 255u ) / 255.0;
+
+            if( color == COLOR4D::BLACK ) // nanosvg probably didn't read it properly, use default
+                color = COLOR4D::UNSPECIFIED;
+        }
+
         GRAPHICS_IMPORTER::POLY_FILL_RULE rule = GRAPHICS_IMPORTER::PF_NONZERO;
 
         switch( shape->fillRule )
@@ -119,7 +132,7 @@ bool SVG_IMPORT_PLUGIN::Import()
         {
             bool closed = path->closed || filled || rule == GRAPHICS_IMPORTER::PF_EVEN_ODD;
 
-            DrawPath( path->pts, path->npts, closed, filled, lineWidth );
+            DrawPath( path->pts, path->npts, closed, filled, lineWidth, color );
         }
     }
 
@@ -139,7 +152,7 @@ double SVG_IMPORT_PLUGIN::GetImageHeight() const
         return 0.0;
     }
 
-    return m_parsedImage->height;
+    return m_parsedImage->height / SVG_DPI * inches2mm;
 }
 
 
@@ -151,12 +164,37 @@ double SVG_IMPORT_PLUGIN::GetImageWidth() const
         return 0.0;
     }
 
-    return m_parsedImage->width;
+    return m_parsedImage->width / SVG_DPI * inches2mm;
+}
+
+
+BOX2D SVG_IMPORT_PLUGIN::GetImageBBox() const
+{
+    BOX2D bbox;
+
+    if( !m_parsedImage || !m_parsedImage->shapes )
+    {
+        wxASSERT_MSG( false, wxT( "Image must have been loaded before getting bbox" ) );
+        return bbox;
+    }
+
+    for( NSVGshape* shape = m_parsedImage->shapes; shape != nullptr; shape = shape->next )
+    {
+        BOX2D shapeBbox;
+        float( &bounds )[4] = shape->bounds;
+
+        shapeBbox.SetOrigin( bounds[0], bounds[1] );
+        shapeBbox.SetEnd( bounds[2], bounds[3] );
+
+        bbox.Merge( shapeBbox );
+    }
+
+    return bbox;
 }
 
 
 void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aPoly, bool aFilled,
-                                  double aLineWidth )
+                                  double aLineWidth, const COLOR4D& aColor )
 {
     std::vector< VECTOR2D > collectedPathPoints;
 
@@ -164,9 +202,9 @@ void SVG_IMPORT_PLUGIN::DrawPath( const float* aPoints, int aNumPoints, bool aPo
         DrawCubicBezierPath( aPoints, aNumPoints, collectedPathPoints );
 
     if( aPoly && aFilled )
-        DrawPolygon( collectedPathPoints, aLineWidth );
+        DrawPolygon( collectedPathPoints, aLineWidth, aColor );
     else
-        DrawLineSegments( collectedPathPoints, aLineWidth );
+        DrawLineSegments( collectedPathPoints, aLineWidth, aColor );
 }
 
 
@@ -201,18 +239,20 @@ void SVG_IMPORT_PLUGIN::DrawCubicBezierCurve( const float* aPoints,
 }
 
 
-void SVG_IMPORT_PLUGIN::DrawPolygon( const std::vector< VECTOR2D >& aPoints, double aWidth )
+void SVG_IMPORT_PLUGIN::DrawPolygon( const std::vector<VECTOR2D>& aPoints, double aWidth,
+                                     const COLOR4D& aColor )
 {
-    m_internalImporter.AddPolygon( aPoints, aWidth );
+    m_internalImporter.AddPolygon( aPoints, aWidth, aColor );
 }
 
 
-void SVG_IMPORT_PLUGIN::DrawLineSegments( const std::vector< VECTOR2D >& aPoints, double aWidth )
+void SVG_IMPORT_PLUGIN::DrawLineSegments( const std::vector<VECTOR2D>& aPoints, double aWidth,
+                                          const COLOR4D& aColor )
 {
     unsigned int numLineStartPoints = aPoints.size() - 1;
 
     for( unsigned int pointIndex = 0; pointIndex < numLineStartPoints; ++pointIndex )
-        m_internalImporter.AddLine( aPoints[ pointIndex ], aPoints[ pointIndex + 1 ], aWidth );
+        m_internalImporter.AddLine( aPoints[ pointIndex ], aPoints[ pointIndex + 1 ], aWidth, aColor );
 }
 
 
diff --git a/common/import_gfx/svg_import_plugin.h b/common/import_gfx/svg_import_plugin.h
index 06d9ddbc90..698e5d18f5 100644
--- a/common/import_gfx/svg_import_plugin.h
+++ b/common/import_gfx/svg_import_plugin.h
@@ -28,7 +28,6 @@
 
 #include "graphics_import_plugin.h"
 #include "graphics_importer_buffer.h"
-#include <math/vector2d.h>
 #include <wildcards_and_files_ext.h>
 
 #include <vector>
@@ -68,18 +67,21 @@ public:
 
     virtual double GetImageHeight() const override;
     virtual double GetImageWidth() const override;
+    virtual BOX2D GetImageBBox() const override;
 
 private:
-    void DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath, bool aFilled, double aLineWidth );
+    void DrawPath( const float* aPoints, int aNumPoints, bool aClosedPath, bool aFilled,
+                   double aLineWidth, const COLOR4D& aColor );
 
     void DrawCubicBezierPath( const float* aPoints, int aNumPoints,
-            std::vector< VECTOR2D >& aGeneratedPoints );
+                              std::vector<VECTOR2D>& aGeneratedPoints );
 
-    void DrawCubicBezierCurve( const float* aPoints,
-            std::vector< VECTOR2D >& aGeneratedPoints );
+    void DrawCubicBezierCurve( const float* aPoints, std::vector<VECTOR2D>& aGeneratedPoints );
 
-    void DrawPolygon( const std::vector< VECTOR2D >& aPoints, double aWidth );
-    void DrawLineSegments( const std::vector< VECTOR2D >& aPoints, double aWidth );
+    void DrawPolygon( const std::vector<VECTOR2D>& aPoints, double aWidth, const COLOR4D& aColor );
+
+    void DrawLineSegments( const std::vector<VECTOR2D>& aPoints, double aWidth,
+                           const COLOR4D& aColor );
 
     struct NSVGimage* m_parsedImage;
 
diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt
index 187e7c089f..2151da0a10 100644
--- a/eeschema/CMakeLists.txt
+++ b/eeschema/CMakeLists.txt
@@ -268,6 +268,10 @@ set ( EESCHEMA_LIBEDIT_SRCS
     symbol_editor/toolbars_symbol_editor.cpp
     )
 
+set( EESCHEMA_IMPORT_GFX
+    import_gfx/graphics_importer_lib_symbol.cpp
+    )
+
 set( EESCHEMA_SRCS
     ${EESCHEMA_DLGS}
     ${EESCHEMA_LIBEDIT_SRCS}
@@ -276,6 +280,7 @@ set( EESCHEMA_SRCS
     ${EESCHEMA_SCH_PLUGINS_LTSPICE}
     ${EESCHEMA_SIM_SRCS}
     ${EESCHEMA_WIDGETS}
+    ${EESCHEMA_IMPORT_GFX}
     annotate.cpp
     autoplace_fields.cpp
     bom_plugins.cpp
diff --git a/eeschema/import_gfx/graphics_importer_lib_symbol.cpp b/eeschema/import_gfx/graphics_importer_lib_symbol.cpp
new file mode 100644
index 0000000000..d3a6f399ce
--- /dev/null
+++ b/eeschema/import_gfx/graphics_importer_lib_symbol.cpp
@@ -0,0 +1,217 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2016 CERN
+ * @author Maciej Suminski <maciej.suminski@cern.ch>
+ * Copyright (C) 2018-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 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 "graphics_importer_lib_symbol.h"
+
+#include <lib_symbol.h>
+#include <lib_shape.h>
+#include <lib_text.h>
+#include <memory>
+#include <tuple>
+
+
+GRAPHICS_IMPORTER_LIB_SYMBOL::GRAPHICS_IMPORTER_LIB_SYMBOL( LIB_SYMBOL* aSymbol, int aUnit ) :
+        m_symbol( aSymbol ), m_unit( aUnit )
+{
+    m_millimeterToIu = schIUScale.mmToIU( 1.0 );
+}
+
+
+VECTOR2I GRAPHICS_IMPORTER_LIB_SYMBOL::MapCoordinate( const VECTOR2D& aCoordinate )
+{
+    VECTOR2D coord = aCoordinate;
+    coord *= GetScale();
+    coord += GetImportOffsetMM();
+    coord *= GetMillimeterToIuFactor();
+
+    return VECTOR2I( KiROUND( coord.x ), KiROUND( coord.y ) );
+}
+
+
+int GRAPHICS_IMPORTER_LIB_SYMBOL::MapLineWidth( double aLineWidth )
+{
+    VECTOR2D factor = ImportScalingFactor();
+    double   scale = ( factor.x + factor.y ) * 0.5;
+
+    if( aLineWidth <= 0.0 )
+        return int( GetLineWidthMM() * scale );
+
+    // aLineWidth is in mm:
+    return int( aLineWidth * scale );
+}
+
+
+void GRAPHICS_IMPORTER_LIB_SYMBOL::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd,
+                                         double aWidth, const COLOR4D& aColor )
+{
+    std::unique_ptr<LIB_SHAPE> line = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::SEGMENT );
+    line->SetUnit( m_unit );
+    line->SetFillColor( aColor );
+    line->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
+    line->SetStart( MapCoordinate( aOrigin ) );
+    line->SetEnd( MapCoordinate( aEnd ) );
+
+    // Skip 0 len lines:
+    if( line->GetStart() == line->GetEnd() )
+        return;
+
+    addItem( std::move( line ) );
+}
+
+
+void GRAPHICS_IMPORTER_LIB_SYMBOL::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth,
+                                           bool aFilled, const COLOR4D& aColor )
+{
+    std::unique_ptr<LIB_SHAPE> circle = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::CIRCLE );
+    circle->SetUnit( m_unit );
+    circle->SetFillColor( aColor );
+    circle->SetFilled( aFilled );
+    circle->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
+    circle->SetStart( MapCoordinate( aCenter ));
+    circle->SetEnd( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) );
+
+    addItem( std::move( circle ) );
+}
+
+
+void GRAPHICS_IMPORTER_LIB_SYMBOL::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart,
+                                        const EDA_ANGLE& aAngle, double aWidth,
+                                        const COLOR4D& aColor )
+{
+    std::unique_ptr<LIB_SHAPE> arc = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::ARC );
+    arc->SetUnit( m_unit );
+    arc->SetFillColor( aColor );
+
+    /**
+     * We need to perform the rotation/conversion here while still using floating point values
+     * to avoid rounding errors when operating in integer space in KiCad
+     */
+    VECTOR2D end = aStart;
+    VECTOR2D mid = aStart;
+
+    RotatePoint( end, aCenter, -aAngle );
+    RotatePoint( mid, aCenter, -aAngle / 2.0 );
+
+    arc->SetArcGeometry( MapCoordinate( aStart ), MapCoordinate( mid ), MapCoordinate( end ) );
+
+    // Ensure the arc can be handled by KiCad. Arcs with a too big radius cannot.
+    // The criteria used here is radius < MAX_INT / 2.
+    // this is not perfect, but we do not know the exact final position of the arc, so
+    // we cannot test the coordinate values, because the arc can be moved before being placed.
+    VECTOR2D center = CalcArcCenter( arc->GetStart(), arc->GetEnd(), aAngle );
+    double radius = ( center - arc->GetStart() ).EuclideanNorm();
+    constexpr double rd_max_value = std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0;
+
+    if( radius >= rd_max_value )
+    {
+        // Arc cannot be handled: convert it to a segment
+        AddLine( aStart, end, aWidth, aColor );
+        return;
+    }
+
+    arc->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
+
+    addItem( std::move( arc ) );
+}
+
+
+void GRAPHICS_IMPORTER_LIB_SYMBOL::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth,
+                                            const COLOR4D& aColor )
+{
+    std::vector<VECTOR2I> convertedPoints;
+    convertedPoints.reserve( aVertices.size() );
+
+    for( const VECTOR2D& precisePoint : aVertices )
+        convertedPoints.emplace_back( MapCoordinate( precisePoint ) );
+
+    if( convertedPoints.empty() )
+        return;
+
+    std::unique_ptr<LIB_SHAPE> polygon = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::POLY );
+    polygon->SetUnit( m_unit );
+    polygon->SetFilled( true );
+    polygon->SetFillMode( aColor != COLOR4D::UNSPECIFIED ? FILL_T::FILLED_WITH_COLOR
+                                                         : FILL_T::FILLED_SHAPE );
+    polygon->SetFillColor( aColor );
+    polygon->SetPolyPoints( convertedPoints );
+    polygon->AddPoint( convertedPoints[0] ); // Need to close last point for libedit
+
+    polygon->SetStroke(
+            STROKE_PARAMS( aWidth != -1 ? MapLineWidth( aWidth ) : -1, PLOT_DASH_TYPE::SOLID ) );
+
+    addItem( std::move( polygon ) );
+}
+
+
+void GRAPHICS_IMPORTER_LIB_SYMBOL::AddText( const VECTOR2D& aOrigin, const wxString& aText,
+                                        double aHeight, double aWidth, double aThickness,
+                                        double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
+                                         GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor )
+{
+    std::unique_ptr<LIB_TEXT> textItem = std::make_unique<LIB_TEXT>( m_symbol );
+    textItem->SetUnit( m_unit );
+    textItem->SetTextColor( aColor );
+    textItem->SetTextThickness( MapLineWidth( aThickness ) );
+    textItem->SetTextPos( MapCoordinate( aOrigin ) );
+    textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) );
+    textItem->SetTextWidth( aWidth * ImportScalingFactor().x );
+    textItem->SetTextHeight( aHeight * ImportScalingFactor().y );
+    textItem->SetVertJustify( aVJustify );
+    textItem->SetHorizJustify( aHJustify );
+    textItem->SetText( aText );
+
+    addItem( std::move( textItem ) );
+}
+
+
+void GRAPHICS_IMPORTER_LIB_SYMBOL::AddSpline( const VECTOR2D& aStart, const VECTOR2D& BezierControl1,
+                                          const VECTOR2D& BezierControl2, const VECTOR2D& aEnd,
+                                           double aWidth, const COLOR4D& aColor )
+{
+    std::unique_ptr<LIB_SHAPE> spline = std::make_unique<LIB_SHAPE>( m_symbol, SHAPE_T::BEZIER );
+    spline->SetUnit( m_unit );
+    spline->SetFillColor( aColor );
+    spline->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
+    spline->SetStart( MapCoordinate( aStart ) );
+    spline->SetBezierC1( MapCoordinate( BezierControl1 ));
+    spline->SetBezierC2( MapCoordinate( BezierControl2 ));
+    spline->SetEnd( MapCoordinate( aEnd ) );
+    spline->RebuildBezierToSegmentsPointsList( aWidth );
+
+    // If the spline is degenerated (i.e. a segment) add it as segment or discard it if
+    // null (i.e. very small) length
+    if( spline->GetBezierPoints().size() <= 2 )
+    {
+        spline->SetShape( SHAPE_T::SEGMENT );
+        int dist = VECTOR2I(spline->GetStart()- spline->GetEnd()).EuclideanNorm();
+
+        // segment smaller than MIN_SEG_LEN_ACCEPTABLE_NM nanometers are skipped.
+        #define MIN_SEG_LEN_ACCEPTABLE_NM 20
+        if( dist < MIN_SEG_LEN_ACCEPTABLE_NM )
+            return;
+    }
+
+    addItem( std::move( spline ) );
+}
diff --git a/eeschema/import_gfx/graphics_importer_lib_symbol.h b/eeschema/import_gfx/graphics_importer_lib_symbol.h
new file mode 100644
index 0000000000..fa24f830a5
--- /dev/null
+++ b/eeschema/import_gfx/graphics_importer_lib_symbol.h
@@ -0,0 +1,83 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 2016 CERN
+ * Copyright (C) 2018-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
+ * 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 GRAPHICS_IMPORTER_EESCHEMA_H
+#define GRAPHICS_IMPORTER_EESCHEMA_H
+
+#include <import_gfx/graphics_importer.h>
+
+#include <layer_ids.h>
+
+class LIB_SYMBOL;
+class LIB_SHAPE;
+class LIB_TEXT;
+
+class GRAPHICS_IMPORTER_LIB_SYMBOL : public GRAPHICS_IMPORTER
+{
+public:
+    GRAPHICS_IMPORTER_LIB_SYMBOL( LIB_SYMBOL* aSymbol, int aUnit );
+
+    void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth,
+                  const COLOR4D& aColor ) override;
+
+    void AddCircle( const VECTOR2D& aOrigin, double aRadius, double aWidth, bool aFilled,
+                    const COLOR4D& aColor ) override;
+
+    void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle,
+                 double aWidth, const COLOR4D& aColor ) override;
+
+    void AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth,
+                     const COLOR4D& aColor ) override;
+
+    void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth,
+                  double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
+                  GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) override;
+
+    void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1,
+                    const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth,
+                    const COLOR4D& aColor ) override;
+
+    /**
+     * Convert an imported coordinate to a board coordinate, according to the internal units,
+     * user scale and offset
+     *
+     * @param aCoordinate is the imported coordinate in mm.
+     */
+    VECTOR2I MapCoordinate( const VECTOR2D& aCoordinate );
+
+    /**
+     * If aLineWidth < 0, the default line thickness value is returned.
+     *
+     * @param aLineWidth is the line thickness in mm to convert.
+     * @return a line thickness in a board Iu value, according to the internal units.
+     */
+    int MapLineWidth( double aLineWidth );
+
+    LIB_SYMBOL* m_symbol;
+    int         m_unit;
+};
+
+#endif /* GRAPHICS_IMPORTER_EESCHEMA */
diff --git a/pcbnew/import_gfx/dialog_import_gfx.cpp b/pcbnew/import_gfx/dialog_import_gfx.cpp
index 85f588fedf..ff77ef2b56 100644
--- a/pcbnew/import_gfx/dialog_import_gfx.cpp
+++ b/pcbnew/import_gfx/dialog_import_gfx.cpp
@@ -259,7 +259,7 @@ bool DIALOG_IMPORT_GFX::TransferDataFromWindow()
         LOCALE_IO dummy;    // Ensure floats can be read.
 
         if( m_importer->Load( m_textCtrlFileName->GetValue() ) )
-            m_importer->Import( scale );
+            m_importer->Import( VECTOR2D( scale, scale ) );
 
         // Get warning messages:
         wxString warnings = m_importer->GetMessages();
diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp
index 319f823cfb..6862219839 100644
--- a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp
+++ b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp
@@ -42,23 +42,30 @@ GRAPHICS_IMPORTER_PCBNEW::GRAPHICS_IMPORTER_PCBNEW()
 
 VECTOR2I GRAPHICS_IMPORTER_PCBNEW::MapCoordinate( const VECTOR2D& aCoordinate )
 {
-    VECTOR2D coord = ( aCoordinate + GetImportOffsetMM() ) * ImportScalingFactor();
+    VECTOR2D coord = aCoordinate;
+    coord *= GetScale();
+    coord += GetImportOffsetMM();
+    coord *= GetMillimeterToIuFactor();
+
     return VECTOR2I( KiROUND( coord.x ), KiROUND( coord.y ) );
 }
 
 
 int GRAPHICS_IMPORTER_PCBNEW::MapLineWidth( double aLineWidth )
 {
+    VECTOR2D factor = ImportScalingFactor();
+    double   scale = ( factor.x + factor.y ) * 0.5;
+
     if( aLineWidth <= 0.0 )
-        return int( GetLineWidthMM() * ImportScalingFactor() );
+        return int( GetLineWidthMM() * scale );
 
     // aLineWidth is in mm:
-    return int( aLineWidth * ImportScalingFactor() );
+    return int( aLineWidth * scale );
 }
 
 
 void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd,
-                                        double aWidth )
+                                        double aWidth, const COLOR4D& aColor )
 {
     std::unique_ptr<PCB_SHAPE> line( createDrawing() );
     line->SetShape( SHAPE_T::SEGMENT );
@@ -76,7 +83,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D&
 
 
 void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth,
-                                          bool aFilled )
+                                          bool aFilled, const COLOR4D& aColor )
 {
     std::unique_ptr<PCB_SHAPE> circle( createDrawing() );
     circle->SetShape( SHAPE_T::CIRCLE );
@@ -91,7 +98,8 @@ void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadiu
 
 
 void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart,
-                                       const EDA_ANGLE& aAngle, double aWidth )
+                                       const EDA_ANGLE& aAngle, double aWidth,
+                                       const COLOR4D& aColor )
 {
     std::unique_ptr<PCB_SHAPE> arc( createDrawing() );
     arc->SetShape( SHAPE_T::ARC );
@@ -120,7 +128,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D&
     if( radius >= rd_max_value )
     {
         // Arc cannot be handled: convert it to a segment
-        AddLine( aStart, end, aWidth );
+        AddLine( aStart, end, aWidth, aColor );
         return;
     }
 
@@ -130,7 +138,8 @@ void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D&
 }
 
 
-void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth )
+void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth,
+                                           const COLOR4D& aColor )
 {
     std::vector<VECTOR2I> convertedPoints;
     convertedPoints.reserve( aVertices.size() );
@@ -158,15 +167,15 @@ void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector<VECTOR2D>& aVertice
 void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& aText,
                                         double aHeight, double aWidth, double aThickness,
                                         double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
-                                        GR_TEXT_V_ALIGN_T aVJustify )
+                                        GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor )
 {
     std::unique_ptr<PCB_TEXT> textItem = createText();
     textItem->SetLayer( GetLayer() );
     textItem->SetTextThickness( MapLineWidth( aThickness ) );
     textItem->SetTextPos( MapCoordinate( aOrigin ) );
     textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) );
-    textItem->SetTextWidth( aWidth * ImportScalingFactor() );
-    textItem->SetTextHeight( aHeight * ImportScalingFactor() );
+    textItem->SetTextWidth( aWidth * ImportScalingFactor().x );
+    textItem->SetTextHeight( aHeight * ImportScalingFactor().y );
     textItem->SetVertJustify( aVJustify );
     textItem->SetHorizJustify( aHJustify );
     textItem->SetText( aText );
@@ -177,7 +186,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString&
 
 void GRAPHICS_IMPORTER_PCBNEW::AddSpline( const VECTOR2D& aStart, const VECTOR2D& BezierControl1,
                                           const VECTOR2D& BezierControl2, const VECTOR2D& aEnd,
-                                          double aWidth )
+                                          double aWidth, const COLOR4D& aColor )
 {
     std::unique_ptr<PCB_SHAPE> spline( createDrawing() );
     spline->SetShape( SHAPE_T::BEZIER );
diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.h b/pcbnew/import_gfx/graphics_importer_pcbnew.h
index d66042be57..258b7f4dd3 100644
--- a/pcbnew/import_gfx/graphics_importer_pcbnew.h
+++ b/pcbnew/import_gfx/graphics_importer_pcbnew.h
@@ -59,22 +59,25 @@ public:
         return m_layer;
     }
 
-    void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth ) override;
+    void AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth,
+                  const COLOR4D& aColor ) override;
 
-    void AddCircle( const VECTOR2D& aOrigin, double aRadius, double aWidth, bool aFilled ) override;
+    void AddCircle( const VECTOR2D& aOrigin, double aRadius, double aWidth, bool aFilled,
+                    const COLOR4D& aColor ) override;
 
     void AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart, const EDA_ANGLE& aAngle,
-                 double aWidth ) override;
+                 double aWidth, const COLOR4D& aColor ) override;
 
-    void AddPolygon( const std::vector< VECTOR2D >& aVertices, double aWidth ) override;
+    void AddPolygon( const std::vector<VECTOR2D>& aVertices, double aWidth,
+                     const COLOR4D& aColor ) override;
 
     void AddText( const VECTOR2D& aOrigin, const wxString& aText, double aHeight, double aWidth,
                   double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
-                  GR_TEXT_V_ALIGN_T aVJustify ) override;
+                  GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor ) override;
 
     void AddSpline( const VECTOR2D& aStart, const VECTOR2D& aBezierControl1,
-                    const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd,
-                    double aWidth ) override;
+                    const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd, double aWidth,
+                    const COLOR4D& aColor ) override;
 
     /**
      * Convert an imported coordinate to a board coordinate, according to the internal units,