DrawGraphicText: remove a static variable, and replace it (when needed) by a new parameter in argument list.

It make this function thread-safe (as far as wxString is thread-safe)
This commit is contained in:
jean-pierre charras 2018-04-06 15:30:52 +02:00
parent baef22df9a
commit 7f6e26e55a
8 changed files with 68 additions and 50 deletions

View File

@ -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 );

View File

@ -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 );
}
}

View File

@ -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 );

View File

@ -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 );
}
}

View File

@ -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

View File

@ -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__ */

View File

@ -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 );
}
}

View File

@ -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;