diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
index c6bb1a7e77..7da42233b5 100644
--- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
+++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
@@ -66,7 +66,7 @@ static const CBBOX2D *s_boardBBox3DU = NULL;
 static const BOARD_ITEM *s_boardItem = NULL;
 
 // This is a call back function, used by DrawGraphicText to draw the 3D text shape:
-void addTextSegmToContainer( int x0, int y0, int xf, int yf )
+void addTextSegmToContainer( int x0, int y0, int xf, int yf, void* aData )
 {
     wxASSERT( s_boardBBox3DU != NULL );
     wxASSERT( s_dstcontainer != NULL );
diff --git a/common/basic_gal.cpp b/common/basic_gal.cpp
index 91fb95c0c2..02ddc7deb6 100644
--- a/common/basic_gal.cpp
+++ b/common/basic_gal.cpp
@@ -97,7 +97,7 @@ void BASIC_GAL::DrawPolyline( const std::deque<VECTOR2D>& aPointList )
         for( unsigned ii = 1; ii < polyline_corners.size(); ii++ )
         {
             m_callback( polyline_corners[ii-1].x, polyline_corners[ii-1].y,
-                        polyline_corners[ii].x, polyline_corners[ii].y );
+                        polyline_corners[ii].x, polyline_corners[ii].y, m_callbackData );
         }
     }
 }
@@ -129,6 +129,6 @@ void BASIC_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint
     else if( m_callback )
     {
             m_callback( startVector.x, startVector.y,
-                        endVector.x, endVector.y );
+                        endVector.x, endVector.y, m_callbackData );
     }
 }
diff --git a/common/draw_graphic_text.cpp b/common/draw_graphic_text.cpp
index f941fb3a14..aa8136e009 100644
--- a/common/draw_graphic_text.cpp
+++ b/common/draw_graphic_text.cpp
@@ -1,15 +1,15 @@
 /**
  * Functions to draw and plot text on screen
- * @file drawtxt.cpp
+ * @file draw_graphic_text.cpp
  */
 
 /*
  * 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) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
- * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2018 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
@@ -38,6 +38,7 @@
 #include <macros.h>
 #include <class_drawpanel.h>
 #include <base_screen.h>
+#include <draw_graphic_text.h>
 
 #include <basic_gal.h>
 
@@ -114,8 +115,11 @@ int GraphicTextWidth( const wxString& aText, const wxSize& aSize, bool aItalic,
  *      Use a value min(aSize.x, aSize.y) / 5 for a bold text
  *  @param aItalic = true to simulate an italic font
  *  @param aBold = true to use a bold font. Useful only with default width value (aWidth = 0)
- *  @param aCallback() = function called (if non null) to draw each segment.
- *                  used to draw 3D texts or for plotting, NULL for normal drawings
+ *  @param aCallback( int x0, int y0, int xf, int yf, void* aData ) is a function called
+ *                  (if non null) to draw each segment. used to draw 3D texts or for plotting.
+ *                  NULL for normal drawings
+ *  @param aCallbackData = is the auxiliary parameter aData for the callback function.
+ *                         can be nullptr if no auxiliary parameter is needed
  *  @param aPlotter = a pointer to a PLOTTER instance, when this function is used to plot
  *                  the text. NULL to draw this text.
  */
@@ -131,7 +135,8 @@ void DrawGraphicText( EDA_RECT* aClipBox,
                       int aWidth,
                       bool aItalic,
                       bool aBold,
-                      void (* aCallback)( int x0, int y0, int xf, int yf ),
+                      void (* aCallback)( int x0, int y0, int xf, int yf, void* aData ),
+                      void* aCallbackData,
                       PLOTTER* aPlotter )
 {
     bool    fill_mode = true;
@@ -164,7 +169,7 @@ void DrawGraphicText( EDA_RECT* aClipBox,
 
     basic_gal.SetTextAttributes( &dummy );
     basic_gal.SetPlotter( aPlotter );
-    basic_gal.SetCallback( aCallback );
+    basic_gal.SetCallback( aCallback, aCallbackData );
     basic_gal.m_DC = aDC;
     basic_gal.m_Color = aColor;
     basic_gal.SetClipBox( aClipBox );
@@ -184,7 +189,8 @@ void DrawGraphicHaloText( EDA_RECT* aClipBox, wxDC * aDC,
                           enum EDA_TEXT_HJUSTIFY_T aH_justify,
                           enum EDA_TEXT_VJUSTIFY_T aV_justify,
                           int aWidth, bool aItalic, bool aBold,
-                          void (*aCallback)( int x0, int y0, int xf, int yf ),
+                          void (*aCallback)( int x0, int y0, int xf, int yf, void* aData ),
+                          void* aCallbackData,
                           PLOTTER * aPlotter )
 {
     // Swap color if contrast would be better
@@ -199,12 +205,12 @@ void DrawGraphicHaloText( EDA_RECT* aClipBox, wxDC * aDC,
     // Draw the background
     DrawGraphicText( aClipBox, aDC, aPos, aColor1, aText, aOrient, aSize,
                      aH_justify, aV_justify, aWidth, aItalic, aBold,
-                     aCallback, aPlotter );
+                     aCallback, aCallbackData, aPlotter );
 
     // Draw the text
     DrawGraphicText( aClipBox, aDC, aPos, aColor2, aText, aOrient, aSize,
                      aH_justify, aV_justify, aWidth/4, aItalic, aBold,
-                     aCallback, aPlotter );
+                     aCallback, aCallbackData, aPlotter );
 }
 
 /**
@@ -256,7 +262,7 @@ void PLOTTER::Text( const wxPoint&              aPos,
     DrawGraphicText( NULL, NULL, aPos, aColor, aText,
                      aOrient, aSize,
                      aH_justify, aV_justify,
-                     textPensize, aItalic, aBold, NULL, this );
+                     textPensize, aItalic, aBold, nullptr, nullptr, this );
 
     if( aWidth != textPensize )
         SetCurrentLineWidth( aWidth, aData );
diff --git a/common/eda_text.cpp b/common/eda_text.cpp
index 3351bf74d7..c11c9c1fc3 100644
--- a/common/eda_text.cpp
+++ b/common/eda_text.cpp
@@ -467,13 +467,13 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
 // each segment is stored as 2 wxPoints: its starting point and its ending point
 // we are using DrawGraphicText to create the segments.
 // and therefore a call-back function is needed
-static std::vector<wxPoint>* s_cornerBuffer;
 
 // This is a call back function, used by DrawGraphicText to put each segment in buffer
-static void addTextSegmToBuffer( int x0, int y0, int xf, int yf )
+static void addTextSegmToBuffer( int x0, int y0, int xf, int yf, void* aData )
 {
-    s_cornerBuffer->push_back( wxPoint( x0, y0 ) );
-    s_cornerBuffer->push_back( wxPoint( xf, yf ) );
+    std::vector<wxPoint>* cornerBuffer = static_cast<std::vector<wxPoint>*>( aData );
+    cornerBuffer->push_back( wxPoint( x0, y0 ) );
+    cornerBuffer->push_back( wxPoint( xf, yf ) );
 }
 
 void EDA_TEXT::TransformTextShapeToSegmentList( std::vector<wxPoint>& aCornerBuffer ) const
@@ -483,7 +483,6 @@ void EDA_TEXT::TransformTextShapeToSegmentList( std::vector<wxPoint>& aCornerBuf
     if( IsMirrored() )
         size.x = -size.x;
 
-    s_cornerBuffer = &aCornerBuffer;
     COLOR4D color = COLOR4D::BLACK;  // not actually used, but needed by DrawGraphicText
 
     if( IsMultilineAllowed() )
@@ -501,7 +500,7 @@ void EDA_TEXT::TransformTextShapeToSegmentList( std::vector<wxPoint>& aCornerBuf
                              txt, GetTextAngle(), size,
                              GetHorizJustify(), GetVertJustify(),
                              GetThickness(), IsItalic(),
-                             true, addTextSegmToBuffer );
+                             true, addTextSegmToBuffer, &aCornerBuffer );
         }
     }
     else
@@ -510,6 +509,6 @@ void EDA_TEXT::TransformTextShapeToSegmentList( std::vector<wxPoint>& aCornerBuf
                          GetText(), GetTextAngle(), size,
                          GetHorizJustify(), GetVertJustify(),
                          GetThickness(), IsItalic(),
-                         true, addTextSegmToBuffer );
+                         true, addTextSegmToBuffer, &aCornerBuffer );
     }
 }
diff --git a/include/basic_gal.h b/include/basic_gal.h
index 446ef7f582..bbada69d30 100644
--- a/include/basic_gal.h
+++ b/include/basic_gal.h
@@ -74,6 +74,7 @@ public:
         m_Color = RED;
         m_plotter = NULL;
         m_callback = NULL;
+        m_callbackData = nullptr;
         m_isClipped = false;
     }
 
@@ -82,9 +83,10 @@ public:
         m_plotter = aPlotter;
     }
 
-    void SetCallback( void (* aCallback)( int x0, int y0, int xf, int yf ) )
+    void SetCallback( void (* aCallback)( int x0, int y0, int xf, int yf, void* aData ), void* aData  )
     {
         m_callback = aCallback;
+        m_callbackData = aData;
     }
 
     /// Set a clip box for drawings
@@ -154,7 +156,8 @@ private:
     // When calling the draw functions outside a wxDC, to get the basic drawings
     // lines / polylines ..., a callback function (used in DRC) to store
     // coordinates of each segment:
-    void (* m_callback)( int x0, int y0, int xf, int yf );
+    void (* m_callback)( int x0, int y0, int xf, int yf, void* aData );
+    void* m_callbackData;       // a optional parameter for m_callback
 
     // When calling the draw functions for plot, the plotter acts as a wxDC
     // to plot basic items
diff --git a/include/draw_graphic_text.h b/include/draw_graphic_text.h
index c87873cfd5..f1b7d65918 100644
--- a/include/draw_graphic_text.h
+++ b/include/draw_graphic_text.h
@@ -97,8 +97,11 @@ int GraphicTextWidth( const wxString& aText, const wxSize& aSize, bool italic, b
  *      Use a value min(aSize.x, aSize.y) / 5 for a bold text
  *  @param aItalic = true to simulate an italic font
  *  @param aBold = true to use a bold font
- *  @param aCallback() = function called (if non null) to draw each segment.
- *                  used to draw 3D texts or for plotting, NULL for normal drawings
+ *  @param aCallback( int x0, int y0, int xf, int yf, void* aData ) is a function called
+ *                  (if non null) to draw each segment. used to draw 3D texts or for plotting.
+ *                  NULL for normal drawings
+ *  @param aCallbackData = is the auxiliary parameter aData for the callback function.
+ *                         can be nullptr if no auxiliary parameter is needed
  *  @param aPlotter = a pointer to a PLOTTER instance, when this function is used to plot
  *                  the text. NULL to draw this text.
  */
@@ -114,8 +117,9 @@ void DrawGraphicText( EDA_RECT* aClipBox,
                       int aWidth,
                       bool aItalic,
                       bool aBold,
-                      void (*aCallback)( int x0, int y0, int xf, int yf ) = NULL,
-                      PLOTTER * aPlotter = NULL );
+                      void (*aCallback)( int x0, int y0, int xf, int yf, void* aData ) = nullptr,
+                      void* aCallbackData = nullptr,
+                      PLOTTER * aPlotter = nullptr );
 
 
 /**
@@ -138,7 +142,8 @@ void DrawGraphicHaloText( EDA_RECT* aClipBox,
                           int aWidth,
                           bool aItalic,
                           bool aBold,
-                          void (*aCallback)( int x0, int y0, int xf, int yf ) = NULL,
-                          PLOTTER * aPlotter = NULL );
+                          void (*aCallback)( int x0, int y0, int xf, int yf, void* aData ) = nullptr,
+                          void* aCallbackData = nullptr,
+                          PLOTTER * aPlotter = nullptr );
 
 #endif /* __INCLUDE__DRAWTXT_H__ */
diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp
index a1a31d81f8..175953bdee 100644
--- a/pcbnew/board_items_to_polygon_shape_transform.cpp
+++ b/pcbnew/board_items_to_polygon_shape_transform.cpp
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2009-2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
+ * Copyright (C) 2009-2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
  * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
@@ -49,12 +49,16 @@
 #include <convert_basic_shapes_to_polygon.h>
 #include <geometry/geometry_utils.h>
 
+// A helper struct for the callback function
 // These variables are parameters used in addTextSegmToPoly.
 // But addTextSegmToPoly is a call-back function,
 // so we cannot send them as arguments.
-static int s_textWidth;
-static int s_textCircle2SegmentCount;
-static SHAPE_POLY_SET* s_cornerBuffer;
+struct TSEGM_2_POLY_PRMS {
+    int m_textWidth;
+    int m_textCircle2SegmentCount;
+    SHAPE_POLY_SET* m_cornerBuffer;
+};
+TSEGM_2_POLY_PRMS prms;
 
 // The max error is the distance between the middle of a segment, and the circle
 // for circle/arc to segment approximation.
@@ -63,11 +67,12 @@ static SHAPE_POLY_SET* s_cornerBuffer;
 double s_error_max = Millimeter2iu( 0.02 );
 
 // This is a call back function, used by DrawGraphicText to draw the 3D text shape:
-static void addTextSegmToPoly( int x0, int y0, int xf, int yf )
+static void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData )
 {
-    TransformRoundedEndsSegmentToPolygon( *s_cornerBuffer,
+    TSEGM_2_POLY_PRMS* prm = static_cast<TSEGM_2_POLY_PRMS*>( aData );
+    TransformRoundedEndsSegmentToPolygon( *prm->m_cornerBuffer,
                                            wxPoint( x0, y0), wxPoint( xf, yf ),
-                                           s_textCircle2SegmentCount, s_textWidth );
+                                           prm->m_textCircle2SegmentCount, prm->m_textWidth );
 }
 
 
@@ -260,18 +265,18 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
     if( Value().GetLayer() == aLayer && Value().IsVisible() )
         texts.push_back( &Value() );
 
-    s_cornerBuffer = &aCornerBuffer;
+    prms.m_cornerBuffer = &aCornerBuffer;
 
     // To allow optimization of circles approximated by segments,
     // aCircleToSegmentsCountForTexts, when not 0, is used.
     // if 0 (default value) the aCircleToSegmentsCount is used
-    s_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
+    prms.m_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
                                 aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
 
     for( unsigned ii = 0; ii < texts.size(); ii++ )
     {
         TEXTE_MODULE *textmod = texts[ii];
-        s_textWidth  = textmod->GetThickness() + ( 2 * aInflateValue );
+        prms.m_textWidth  = textmod->GetThickness() + ( 2 * aInflateValue );
         wxSize size = textmod->GetTextSize();
 
         if( textmod->IsMirrored() )
@@ -281,7 +286,7 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
                          textmod->GetShownText(), textmod->GetDrawRotation(), size,
                          textmod->GetHorizJustify(), textmod->GetVertJustify(),
                          textmod->GetThickness(), textmod->IsItalic(),
-                         true, addTextSegmToPoly );
+                         true, addTextSegmToPoly, &prms );
     }
 
 }
@@ -329,18 +334,18 @@ void MODULE::TransformGraphicTextWithClearanceToPolygonSet(
     if( Value().GetLayer() == aLayer && Value().IsVisible() )
         texts.push_back( &Value() );
 
-    s_cornerBuffer = &aCornerBuffer;
+    prms.m_cornerBuffer = &aCornerBuffer;
 
     // To allow optimization of circles approximated by segments,
     // aCircleToSegmentsCountForTexts, when not 0, is used.
     // if 0 (default value) the aCircleToSegmentsCount is used
-    s_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
+    prms.m_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
                                 aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
 
     for( unsigned ii = 0; ii < texts.size(); ii++ )
     {
         TEXTE_MODULE *textmod = texts[ii];
-        s_textWidth  = textmod->GetThickness() + ( 2 * aInflateValue );
+        prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
         wxSize size = textmod->GetTextSize();
 
         if( textmod->IsMirrored() )
@@ -350,7 +355,7 @@ void MODULE::TransformGraphicTextWithClearanceToPolygonSet(
                          textmod->GetShownText(), textmod->GetDrawRotation(), size,
                          textmod->GetHorizJustify(), textmod->GetVertJustify(),
                          textmod->GetThickness(), textmod->IsItalic(),
-                         true, addTextSegmToPoly );
+                         true, addTextSegmToPoly, &prms );
     }
 
 }
@@ -459,9 +464,9 @@ void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
     if( IsMirrored() )
         size.x = -size.x;
 
-    s_cornerBuffer = &aCornerBuffer;
-    s_textWidth  = GetThickness() + ( 2 * aClearanceValue );
-    s_textCircle2SegmentCount = aCircleToSegmentsCount;
+    prms.m_cornerBuffer = &aCornerBuffer;
+    prms.m_textWidth  = GetThickness() + ( 2 * aClearanceValue );
+    prms.m_textCircle2SegmentCount = aCircleToSegmentsCount;
     COLOR4D color = COLOR4D::BLACK;  // not actually used, but needed by DrawGraphicText
 
     if( IsMultilineAllowed() )
@@ -479,7 +484,7 @@ void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
                              txt, GetTextAngle(), size,
                              GetHorizJustify(), GetVertJustify(),
                              GetThickness(), IsItalic(),
-                             true, addTextSegmToPoly );
+                             true, addTextSegmToPoly, &prms );
         }
     }
     else
@@ -488,7 +493,7 @@ void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
                          GetShownText(), GetTextAngle(), size,
                          GetHorizJustify(), GetVertJustify(),
                          GetThickness(), IsItalic(),
-                         true, addTextSegmToPoly );
+                         true, addTextSegmToPoly, &prms );
     }
 }
 
diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp
index 566818bdee..d8457d2b50 100644
--- a/pcbnew/exporters/export_vrml.cpp
+++ b/pcbnew/exporters/export_vrml.cpp
@@ -751,7 +751,7 @@ static void export_vrml_drawsegment( MODEL_VRML& aModel, DRAWSEGMENT* drawseg )
 
 /* C++ doesn't have closures and neither continuation forms... this is
  * for coupling the vrml_text_callback with the common parameters */
-static void vrml_text_callback( int x0, int y0, int xf, int yf )
+static void vrml_text_callback( int x0, int y0, int xf, int yf, void* aData )
 {
     LAYER_NUM m_text_layer = model_vrml->m_text_layer;
     int m_text_width = model_vrml->m_text_width;