From a297e8f202050dc81d60ca0aa32487f5b78cc246 Mon Sep 17 00:00:00 2001
From: jean-pierre charras <jp.charras@wanadoo.fr>
Date: Sat, 12 Jun 2021 09:18:48 +0200
Subject: [PATCH] Gerbview, export to pcbnew: use gr_circle instead of polygon
 for flashed round shapes

---
 .../bom_csv_grouped_by_value.py               |  7 ++--
 gerbview/export_to_pcbnew.cpp                 | 35 +++++++++++++++++--
 gerbview/export_to_pcbnew.h                   | 11 ++++++
 3 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/eeschema/plugins/python_scripts/bom_csv_grouped_by_value.py b/eeschema/plugins/python_scripts/bom_csv_grouped_by_value.py
index 8a3729ada2..6722da7423 100644
--- a/eeschema/plugins/python_scripts/bom_csv_grouped_by_value.py
+++ b/eeschema/plugins/python_scripts/bom_csv_grouped_by_value.py
@@ -27,9 +27,12 @@ import sys
 # A helper function to convert a UTF8/Unicode/locale string read in netlist
 # for python2 or python3 (Windows/unix)
 def fromNetlistText( aText ):
-    if sys.platform.startswith('win32'):
+    currpage = sys.stdout.encoding      #the current code page. can be none
+    if currpage is None:
+        return aText
+    if currpage != 'utf-8':
         try:
-            return aText.encode('utf-8').decode('cp1252')
+            return aText.encode('utf-8').decode(currpage)
         except UnicodeDecodeError:
             return aText
     else:
diff --git a/gerbview/export_to_pcbnew.cpp b/gerbview/export_to_pcbnew.cpp
index a8da99fddb..06c3f1aab6 100644
--- a/gerbview/export_to_pcbnew.cpp
+++ b/gerbview/export_to_pcbnew.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-2020 KiCad Developers, see change_log.txt for contributors.
+ * Copyright (C) 1992-2021 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
@@ -159,6 +159,13 @@ void GBR_TO_PCB_EXPORTER::export_non_copper_item( const GERBER_DRAW_ITEM* aGbrIt
         break;
 
     case GBR_SPOT_CIRCLE:
+        {
+        VECTOR2I center = aGbrItem->GetABPosition( seg_start );
+        int radius = d_codeDescr->m_Size.x / 2;
+        writePcbFilledCircle( center, radius, aLayer );
+        }
+        break;
+
     case GBR_SPOT_RECT:
     case GBR_SPOT_OVAL:
     case GBR_SPOT_POLY:
@@ -428,13 +435,37 @@ void GBR_TO_PCB_EXPORTER::export_flashed_copper_item( const GERBER_DRAW_ITEM* aG
         }
     }
 
-    d_codeDescr->ConvertShapeToPolygon();
     wxPoint offset = aGbrItem->GetABPosition( aGbrItem->m_Start );
 
+    if( aGbrItem->m_Shape == GBR_SPOT_CIRCLE ) // export it as filled circle
+    {
+        VECTOR2I center = offset;
+        int radius = d_codeDescr->m_Size.x / 2;
+        writePcbFilledCircle( center, radius, aLayer );
+        return;
+    }
+
+    d_codeDescr->ConvertShapeToPolygon();
     writePcbPolygon( d_codeDescr->m_Polygon, aLayer, offset );
 }
 
 
+void GBR_TO_PCB_EXPORTER::writePcbFilledCircle( const VECTOR2I& aCenterPosition, int aRadius,
+                                                LAYER_NUM aLayer )
+{
+
+    fprintf( m_fp, "(gr_circle (center %s %s) (end %s %s)",
+             Double2Str( MapToPcbUnits( aCenterPosition.x ) ).c_str(),
+             Double2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str(),
+             Double2Str( MapToPcbUnits( aCenterPosition.x + aRadius ) ).c_str(),
+             Double2Str( MapToPcbUnits( aCenterPosition.y ) ).c_str() );
+
+
+    fprintf( m_fp, "(layer %s) (width 0) (fill solid) )\n",
+             TO_UTF8( GetPCBDefaultLayerName( aLayer ) ) );
+}
+
+
 void GBR_TO_PCB_EXPORTER::writePcbHeader( const LAYER_NUM* aLayerLookUpTable )
 {
     fprintf( m_fp, "(kicad_pcb (version 4) (generator gerbview)\n\n" );
diff --git a/gerbview/export_to_pcbnew.h b/gerbview/export_to_pcbnew.h
index 6008cdf450..5c6d4e3e53 100644
--- a/gerbview/export_to_pcbnew.h
+++ b/gerbview/export_to_pcbnew.h
@@ -92,6 +92,17 @@ private:
     void    writePcbPolygon( const SHAPE_POLY_SET& aPolys, LAYER_NUM aLayer,
                              const wxPoint& aOffset = { 0, 0 } );
 
+    /**
+     * Write a filled circle to the board file (with line thickness = 0).
+     *
+     * @param aCenterPosition is the actual position of the filled circle,
+     *  given by <round_flashed_shape>->GetABPosition()
+     * @param aRadius is the circle radius.
+     * @param aLayer is the layer to use.
+     */
+    void    writePcbFilledCircle( const VECTOR2I& aCenterPosition, int aRadius,
+                                  LAYER_NUM aLayer );
+
     /**
      * Write a zone item to the board file.
      *