Don't depend on wxWidgets dotted and dashed line styles.

Turns out they're buggy on OSX.

Fixes https://gitlab.com/kicad/code/kicad/issues/7144
This commit is contained in:
Jeff Young 2021-02-05 15:46:36 +00:00
parent e8bcdfed29
commit 2ad5108e7d
4 changed files with 100 additions and 39 deletions

View File

@ -609,23 +609,3 @@ void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_TYPE aFill,
PlotPoly( cornerList, aFill, aWidth, aData );
}
wxPenStyle GetwxPenStyle( PLOT_DASH_TYPE aType )
{
switch( aType )
{
case PLOT_DASH_TYPE::DEFAULT:
case PLOT_DASH_TYPE::SOLID:
return wxPENSTYLE_SOLID;
case PLOT_DASH_TYPE::DASH:
return wxPENSTYLE_SHORT_DASH;
case PLOT_DASH_TYPE::DOT:
return wxPENSTYLE_DOT;
case PLOT_DASH_TYPE::DASHDOT:
return wxPENSTYLE_DOT_DASH;
default:
wxFAIL_MSG( "Unhandled PlotDashType" );
return wxPENSTYLE_SOLID;
}
}

View File

@ -34,6 +34,7 @@
#include <settings/color_settings.h>
#include <netclass.h>
#include <trigo.h>
#include <board_item.h>
#include "sch_painter.h"
@ -200,11 +201,56 @@ void SCH_BUS_ENTRY_BASE::Print( const RENDER_SETTINGS* aSettings, const wxPoint&
wxDC* DC = aSettings->GetPrintDC();
COLOR4D color = ( GetStrokeColor() == COLOR4D::UNSPECIFIED ) ?
aSettings->GetLayerColor( m_layer ) : GetStrokeColor();
wxPoint start = m_pos + aOffset;
wxPoint end = GetEnd() + aOffset;
int penWidth = ( GetPenWidth() == 0 ) ? aSettings->GetDefaultPenWidth() : GetPenWidth();
GRLine( nullptr, DC, m_pos.x + aOffset.x, m_pos.y + aOffset.y, GetEnd().x + aOffset.x,
GetEnd().y + aOffset.y, penWidth, color,
GetwxPenStyle( (PLOT_DASH_TYPE) GetStrokeStyle() ) );
if( GetStrokeStyle() <= PLOT_DASH_TYPE::FIRST_TYPE )
{
GRLine( nullptr, DC, start.x, start.y, end.x, end.y, penWidth, color );
}
else
{
EDA_RECT clip( (wxPoint) start, wxSize( end.x - start.x, end.y - start.y ) );
clip.Normalize();
double theta = atan2( end.y - start.y, end.x - start.x );
double strokes[] = { 1.0, DASH_GAP_LEN( penWidth ), 1.0, DASH_GAP_LEN( penWidth ) };
switch( GetStrokeStyle() )
{
default:
case PLOT_DASH_TYPE::DASH:
strokes[0] = strokes[2] = DASH_MARK_LEN( penWidth );
break;
case PLOT_DASH_TYPE::DOT:
strokes[0] = strokes[2] = DOT_MARK_LEN( penWidth );
break;
case PLOT_DASH_TYPE::DASHDOT:
strokes[0] = DASH_MARK_LEN( penWidth );
strokes[2] = DOT_MARK_LEN( penWidth );
break;
}
for( size_t i = 0; i < 10000; ++i )
{
// Calculations MUST be done in doubles to keep from accumulating rounding
// errors as we go.
wxPoint next( start.x + strokes[ i % 4 ] * cos( theta ),
start.y + strokes[ i % 4 ] * sin( theta ) );
// Drawing each segment can be done rounded to ints.
wxPoint segStart( KiROUND( start.x ), KiROUND( start.y ) );
wxPoint segEnd( KiROUND( next.x ), KiROUND( next.y ) );
if( ClipLine( &clip, segStart.x, segStart.y, segEnd.x, segEnd.y ) )
break;
else if( i % 2 == 0 )
GRLine( nullptr, DC, segStart.x, segStart.y, segEnd.x, segEnd.y, penWidth, color );
start = next;
}
}
}

View File

@ -32,7 +32,7 @@
#include <project/project_file.h>
#include <project/net_settings.h>
#include <trigo.h>
#include <board_item.h>
SCH_LINE::SCH_LINE( const wxPoint& pos, int layer ) :
SCH_ITEM( NULL, SCH_LINE_T )
@ -323,12 +323,57 @@ void SCH_LINE::Print( const RENDER_SETTINGS* aSettings, const wxPoint& offset )
if( color == COLOR4D::UNSPECIFIED )
color = aSettings->GetLayerColor( GetLayer() );
wxPoint start = m_start;
wxPoint end = m_end;
int penWidth = std::max( GetPenWidth(), aSettings->GetDefaultPenWidth() );
wxPoint start = m_start;
wxPoint end = m_end;
PLOT_DASH_TYPE lineStyle = GetEffectiveLineStyle();
int penWidth = std::max( GetPenWidth(), aSettings->GetDefaultPenWidth() );
GRLine( nullptr, DC, start.x, start.y, end.x, end.y, penWidth, color,
GetwxPenStyle( GetEffectiveLineStyle() ) );
if( lineStyle <= PLOT_DASH_TYPE::FIRST_TYPE )
{
GRLine( nullptr, DC, start.x, start.y, end.x, end.y, penWidth, color );
}
else
{
EDA_RECT clip( (wxPoint) start, wxSize( end.x - start.x, end.y - start.y ) );
clip.Normalize();
double theta = atan2( end.y - start.y, end.x - start.x );
double strokes[] = { 1.0, DASH_GAP_LEN( penWidth ), 1.0, DASH_GAP_LEN( penWidth ) };
switch( lineStyle )
{
default:
case PLOT_DASH_TYPE::DASH:
strokes[0] = strokes[2] = DASH_MARK_LEN( penWidth );
break;
case PLOT_DASH_TYPE::DOT:
strokes[0] = strokes[2] = DOT_MARK_LEN( penWidth );
break;
case PLOT_DASH_TYPE::DASHDOT:
strokes[0] = DASH_MARK_LEN( penWidth );
strokes[2] = DOT_MARK_LEN( penWidth );
break;
}
for( size_t i = 0; i < 10000; ++i )
{
// Calculations MUST be done in doubles to keep from accumulating rounding
// errors as we go.
wxPoint next( start.x + strokes[ i % 4 ] * cos( theta ),
start.y + strokes[ i % 4 ] * sin( theta ) );
// Drawing each segment can be done rounded to ints.
wxPoint segStart( KiROUND( start.x ), KiROUND( start.y ) );
wxPoint segEnd( KiROUND( next.x ), KiROUND( next.y ) );
if( ClipLine( &clip, segStart.x, segStart.y, segEnd.x, segEnd.y ) )
break;
else if( i % 2 == 0 )
GRLine( nullptr, DC, segStart.x, segStart.y, segEnd.x, segEnd.y, penWidth, color );
start = next;
}
}
}

View File

@ -112,16 +112,6 @@ enum class PLOT_DASH_TYPE
LAST_TYPE = DASHDOT
};
/**
* Convert KiCad line plot styles to wxWidgets device context styles.
*
* @param aType The KiCad line plot style to convert.
*
* @return The equivalent wxPenStyle of \a aType.
*/
wxPenStyle GetwxPenStyle( PLOT_DASH_TYPE aType );
/**
* Base plotter engine class. General rule: all the interface with the caller
* is done in IU, the IU size is specified with SetViewport. Internal and