Shapes for schematic.

ADDED arc, circle and rectangle shapes for schematic.  Shapes support
line styles and fill colors.

CHANGED sheet background color in Edit Text & Graphics Properties to
fill color (and it now affects shapes).

Pushed STROKE_PARAMS down into common and moved all shapes to using it
for stroke descriptions.
This commit is contained in:
Jeff Young 2021-07-17 20:56:18 +01:00
parent 4b6bf3095a
commit 2bc86fa0a8
110 changed files with 4100 additions and 909 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 666 B

View File

@ -385,6 +385,7 @@ set( COMMON_SRCS
search_stack.cpp
searchhelpfilefullpath.cpp
status_popup.cpp
stroke_params.cpp
systemdirsappend.cpp
template_fieldnames.cpp
textentry_tricks.cpp
@ -613,6 +614,14 @@ generate_lemon_grammar(
libeval_compiler/grammar.lemon
)
# auto-generate stroke_params_lexer.h and stroke_params_keywords.cpp
make_lexer(
common
stroke_params.keywords
stroke_params_lexer.h
stroke_params_keywords.cpp
STROKEPARAMS_T
)
# auto-generate netlist_lexer.h and netlist_keywords.cpp
make_lexer(

View File

@ -35,11 +35,10 @@
*/
#include <base_units.h>
#include <common.h>
#include <string_utils.h>
#include <math/util.h> // for KiROUND
#include <macros.h>
#include <title_block.h>
#if defined( PCBNEW ) || defined( CVPCB ) || defined( EESCHEMA ) || defined( GERBVIEW ) || defined( PL_EDITOR )
#define IU_TO_MM( x ) ( x / IU_PER_MM )

View File

@ -40,8 +40,9 @@
EDA_SHAPE::EDA_SHAPE( SHAPE_T aType, int aLineWidth, FILL_T aFill, bool eeWinding ) :
m_endsSwapped( false ),
m_shape( aType ),
m_width( aLineWidth ),
m_stroke( aLineWidth, PLOT_DASH_TYPE::DEFAULT, COLOR4D::UNSPECIFIED ),
m_fill( aFill ),
m_fillColor( COLOR4D::UNSPECIFIED ),
m_editState( 0 ),
m_eeWinding( eeWinding )
{
@ -352,7 +353,7 @@ void EDA_SHAPE::flip( const wxPoint& aCentre, bool aFlipLeftRight )
{
std::vector<wxPoint> ctrlPoints = { m_start, m_bezierC1, m_bezierC2, m_end };
BEZIER_POLY converter( ctrlPoints );
converter.GetPoly( m_bezierPoints, m_width );
converter.GetPoly( m_bezierPoints, m_stroke.GetWidth() );
}
break;
@ -605,7 +606,7 @@ void EDA_SHAPE::ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PA
break;
}
aList.emplace_back( _( "Line width" ), MessageTextFromValue( units, m_width ) );
aList.emplace_back( _( "Line width" ), MessageTextFromValue( units, GetWidth() ) );
}
@ -663,7 +664,7 @@ const EDA_RECT EDA_SHAPE::getBoundingBox() const
break;
}
bbox.Inflate( std::max( 0, m_width / 2 ) );
bbox.Inflate( std::max( 0, GetWidth() ) / 2 );
bbox.Normalize();
return bbox;
@ -674,8 +675,8 @@ bool EDA_SHAPE::hitTest( const wxPoint& aPosition, int aAccuracy ) const
{
int maxdist = aAccuracy;
if( m_width > 0 )
maxdist += m_width / 2;
if( GetWidth() > 0 )
maxdist += GetWidth() / 2;
switch( m_shape )
{
@ -727,7 +728,7 @@ bool EDA_SHAPE::hitTest( const wxPoint& aPosition, int aAccuracy ) const
}
case SHAPE_T::BEZIER:
const_cast<EDA_SHAPE*>( this )->RebuildBezierToSegmentsPointsList( m_width );
const_cast<EDA_SHAPE*>( this )->RebuildBezierToSegmentsPointsList( GetWidth() );
for( unsigned int i= 1; i < m_bezierPoints.size(); i++)
{
@ -1070,7 +1071,7 @@ void EDA_SHAPE::SetPolyPoints( const std::vector<wxPoint>& aPoints )
}
std::vector<SHAPE*> EDA_SHAPE::MakeEffectiveShapes() const
std::vector<SHAPE*> EDA_SHAPE::MakeEffectiveShapes( bool aEdgeOnly ) const
{
std::vector<SHAPE*> effectiveShapes;
@ -1078,60 +1079,50 @@ std::vector<SHAPE*> EDA_SHAPE::MakeEffectiveShapes() const
{
case SHAPE_T::ARC:
effectiveShapes.emplace_back( new SHAPE_ARC( m_arcCenter, m_start, GetArcAngle() / 10.0,
m_width ) );
GetWidth() ) );
break;
case SHAPE_T::SEGMENT:
effectiveShapes.emplace_back( new SHAPE_SEGMENT( m_start, m_end, m_width ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( m_start, m_end, GetWidth() ) );
break;
case SHAPE_T::RECT:
{
std::vector<wxPoint> pts = GetRectCorners();
if( IsFilled() )
if( IsFilled() && !aEdgeOnly )
effectiveShapes.emplace_back( new SHAPE_SIMPLE( pts ) );
if( m_width > 0 || !IsFilled() )
if( GetWidth() > 0 || !IsFilled() || aEdgeOnly )
{
effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[0], pts[1], m_width ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[1], pts[2], m_width ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[2], pts[3], m_width ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[3], pts[0], m_width ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[0], pts[1], GetWidth() ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[1], pts[2], GetWidth() ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[2], pts[3], GetWidth() ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( pts[3], pts[0], GetWidth() ) );
}
}
break;
case SHAPE_T::CIRCLE:
{
if( IsFilled() )
if( IsFilled() && !aEdgeOnly )
effectiveShapes.emplace_back( new SHAPE_CIRCLE( getCenter(), GetRadius() ) );
if( m_width > 0 || !IsFilled() )
{
// SHAPE_CIRCLE has no ConvertToPolyline() method, so use a 360.0 SHAPE_ARC
SHAPE_ARC circle( getCenter(), GetEnd(), 360.0 );
SHAPE_LINE_CHAIN l = circle.ConvertToPolyline();
for( int i = 0; i < l.SegmentCount(); i++ )
{
effectiveShapes.emplace_back( new SHAPE_SEGMENT( l.Segment( i ).A, l.Segment( i ).B,
m_width ) );
}
}
if( GetWidth() > 0 || !IsFilled() || aEdgeOnly )
effectiveShapes.emplace_back( new SHAPE_ARC( getCenter(), GetEnd(), 360.0 ) );
break;
}
case SHAPE_T::BEZIER:
{
auto bezierPoints = buildBezierToSegmentsPointsList( GetWidth() );
std::vector<wxPoint> bezierPoints = buildBezierToSegmentsPointsList( GetWidth() );
wxPoint start_pt = bezierPoints[0];
for( unsigned int jj = 1; jj < bezierPoints.size(); jj++ )
{
wxPoint end_pt = bezierPoints[jj];
effectiveShapes.emplace_back( new SHAPE_SEGMENT( start_pt, end_pt, m_width ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( start_pt, end_pt, GetWidth() ) );
start_pt = end_pt;
}
@ -1145,13 +1136,13 @@ std::vector<SHAPE*> EDA_SHAPE::MakeEffectiveShapes() const
l.Rotate( -DECIDEG2RAD( getParentOrientation() ) );
l.Move( getParentPosition() );
if( IsFilled() )
if( IsFilled() && !aEdgeOnly )
effectiveShapes.emplace_back( new SHAPE_SIMPLE( l ) );
if( m_width > 0 || !IsFilled() )
if( GetWidth() > 0 || !IsFilled() || aEdgeOnly )
{
for( int i = 0; i < l.SegmentCount(); i++ )
effectiveShapes.emplace_back( new SHAPE_SEGMENT( l.Segment( i ), m_width ) );
effectiveShapes.emplace_back( new SHAPE_SEGMENT( l.Segment( i ), GetWidth() ) );
}
}
break;
@ -1322,9 +1313,9 @@ void EDA_SHAPE::calcEdit( const wxPoint& aPosition )
case 4:
{
double chordA = GetLineLength( m_start, aPosition );
double chordB = GetLineLength( m_end, aPosition );
radius = int( ( chordA + chordB ) / 2.0 ) + 1;
double radialA = GetLineLength( m_start, aPosition );
double radialB = GetLineLength( m_end, aPosition );
radius = int( ( radialA + radialB ) / 2.0 ) + 1;
}
break;
@ -1373,6 +1364,10 @@ void EDA_SHAPE::calcEdit( const wxPoint& aPosition )
case 4:
// Pick the one closer to the mouse position
m_arcCenter = GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ? c1 : c2;
if( GetArcAngle() > 1800 )
std::swap( m_start, m_end );
break;
}
}
@ -1425,7 +1420,7 @@ void EDA_SHAPE::SwapShape( EDA_SHAPE* aImage )
EDA_SHAPE* image = dynamic_cast<EDA_SHAPE*>( aImage );
assert( image );
std::swap( m_width, image->m_width );
std::swap( m_stroke, image->m_stroke );
std::swap( m_start, image->m_start );
std::swap( m_end, image->m_end );
std::swap( m_arcCenter, image->m_arcCenter );
@ -1462,12 +1457,16 @@ int EDA_SHAPE::Compare( const EDA_SHAPE* aOther ) const
else if( m_shape == SHAPE_T::POLY )
{
TEST( m_poly.TotalVertices(), aOther->m_poly.TotalVertices() );
for( int ii = 0; ii < m_poly.TotalVertices(); ++ii )
TEST_PT( m_poly.CVertex( ii ), aOther->m_poly.CVertex( ii ) );
}
TEST_E( m_width, aOther->m_width );
for( size_t ii = 0; ii < m_bezierPoints.size(); ++ii )
TEST_PT( m_bezierPoints[ii], aOther->m_bezierPoints[ii] );
for( int ii = 0; ii < m_poly.TotalVertices(); ++ii )
TEST_PT( m_poly.CVertex( ii ), aOther->m_poly.CVertex( ii ) );
TEST_E( m_stroke.GetWidth(), aOther->m_stroke.GetWidth() );
TEST( (int) m_stroke.GetPlotStyle(), (int) aOther->m_stroke.GetPlotStyle() );
TEST( (int) m_fill, (int) aOther->m_fill );
return 0;
@ -1479,7 +1478,7 @@ void EDA_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth ) const
{
int width = ignoreLineWidth ? 0 : m_width;
int width = ignoreLineWidth ? 0 : GetWidth();
width += 2 * aClearanceValue;
@ -1580,7 +1579,7 @@ void EDA_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuf
std::vector<wxPoint> ctrlPts = { GetStart(), GetBezierC1(), GetBezierC2(), GetEnd() };
BEZIER_POLY converter( ctrlPts );
std::vector< wxPoint> poly;
converter.GetPoly( poly, m_width );
converter.GetPoly( poly, GetWidth() );
for( unsigned ii = 1; ii < poly.size(); ii++ )
{

View File

@ -117,6 +117,7 @@ wxString LayerName( int aLayer )
case LAYER_DEVICE: return _( "Symbol body outlines" );
case LAYER_DEVICE_BACKGROUND: return _( "Symbol body fills" );
case LAYER_NOTES: return _( "Schematic text && graphics" );
case LAYER_NOTES_BACKGROUND: return _( "Schematic text && graphics backgrounds" );
case LAYER_PIN: return _( "Pins" );
case LAYER_SHEET: return _( "Sheet borders" );
case LAYER_SHEET_BACKGROUND: return _( "Sheet backgrounds" );

View File

@ -41,7 +41,6 @@
#include <eda_item.h>
#include <plotters/plotter.h>
#include <geometry/shape_line_chain.h>
#include <geometry/geometry_utils.h>
#include <bezier_curves.h>
#include <math/util.h> // for KiROUND
@ -138,19 +137,19 @@ double PLOTTER::userToDeviceSize( double size ) const
double PLOTTER::GetDotMarkLenIU() const
{
return userToDeviceSize( dot_mark_len( GetCurrentLineWidth() ) );
return userToDeviceSize( m_renderSettings->GetDotLength( GetCurrentLineWidth() ) );
}
double PLOTTER::GetDashMarkLenIU() const
{
return userToDeviceSize( dash_mark_len( GetCurrentLineWidth() ) );
return userToDeviceSize( m_renderSettings->GetDashLength( GetCurrentLineWidth() ) );
}
double PLOTTER::GetDashGapLenIU() const
{
return userToDeviceSize( dash_gap_len( GetCurrentLineWidth() ) );
return userToDeviceSize( m_renderSettings->GetGapLength( GetCurrentLineWidth() ) );
}

View File

@ -51,6 +51,27 @@ RENDER_SETTINGS::~RENDER_SETTINGS()
}
constexpr double visualCorrection = 0.8;
double RENDER_SETTINGS::GetDashLength( int aLineWidth ) const
{
return std::max( m_dashLengthRatio - visualCorrection, 1.0 ) * aLineWidth;
}
double RENDER_SETTINGS::GetDotLength( int aLineWidth ) const
{
return ( 1.0 - visualCorrection ) * aLineWidth;
}
double RENDER_SETTINGS::GetGapLength( int aLineWidth ) const
{
return std::max( m_gapLengthRatio + visualCorrection, 1.0 ) * aLineWidth;
}
void RENDER_SETTINGS::update()
{
// Calculate darkened/highlighted variants of layer colors

View File

@ -48,6 +48,7 @@ static const std::map<int, COLOR4D> s_defaultTheme =
{ LAYER_LOCLABEL, CSS_COLOR( 15, 15, 15, 1 ) },
{ LAYER_NOCONNECT, CSS_COLOR( 0, 0, 132, 1 ) },
{ LAYER_NOTES, CSS_COLOR( 0, 0, 194, 1 ) },
{ LAYER_NOTES_BACKGROUND, CSS_COLOR( 0, 0, 0, 0 ) },
{ LAYER_PIN, CSS_COLOR( 132, 0, 0, 1 ) },
{ LAYER_PINNAM, CSS_COLOR( 0, 100, 100, 1 ) },
{ LAYER_PINNUM, CSS_COLOR( 169, 0, 0, 1 ) },
@ -193,6 +194,7 @@ static const std::map<int, COLOR4D> s_classicTheme =
{ LAYER_LOCLABEL, COLOR4D( BLACK ) },
{ LAYER_NOCONNECT, COLOR4D( BLUE ) },
{ LAYER_NOTES, COLOR4D( LIGHTBLUE ) },
{ LAYER_NOTES_BACKGROUND, COLOR4D( UNSPECIFIED_COLOR ) },
{ LAYER_PIN, COLOR4D( RED ) },
{ LAYER_PINNAM, COLOR4D( CYAN ) },
{ LAYER_PINNUM, COLOR4D( RED ) },

View File

@ -94,6 +94,7 @@ COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath )
CLR( "schematic.label_local", LAYER_LOCLABEL );
CLR( "schematic.no_connect", LAYER_NOCONNECT );
CLR( "schematic.note", LAYER_NOTES );
CLR( "schematic.note_background", LAYER_NOTES_BACKGROUND );
CLR( "schematic.pin", LAYER_PIN );
CLR( "schematic.pin_name", LAYER_PINNAM );
CLR( "schematic.pin_number", LAYER_PINNUM );

276
common/stroke_params.cpp Normal file
View File

@ -0,0 +1,276 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include <macros.h>
#include <base_units.h>
#include <string_utils.h>
#include <eda_rect.h>
#include <render_settings.h>
#include <geometry/shape.h>
#include <geometry/shape_segment.h>
#include <geometry/shape_simple.h>
#include <geometry/geometry_utils.h>
#include <stroke_params.h>
#include <trigo.h>
using namespace STROKEPARAMS_T;
void STROKE_PARAMS::Stroke( const SHAPE* aShape, PLOT_DASH_TYPE aLineStyle, int aWidth,
const KIGFX::RENDER_SETTINGS* aRenderSettings,
std::function<void( const wxPoint& a, const wxPoint& b )> aStroker )
{
double strokes[6];
int wrapAround;
switch( aLineStyle )
{
case PLOT_DASH_TYPE::DASH:
strokes[0] = aRenderSettings->GetDashLength( aWidth );
strokes[1] = aRenderSettings->GetGapLength( aWidth );
wrapAround = 2;
break;
case PLOT_DASH_TYPE::DOT:
strokes[0] = aRenderSettings->GetDotLength( aWidth );
strokes[1] = aRenderSettings->GetGapLength( aWidth );
wrapAround = 2;
break;
case PLOT_DASH_TYPE::DASHDOT:
strokes[0] = aRenderSettings->GetDashLength( aWidth );
strokes[1] = aRenderSettings->GetGapLength( aWidth );
strokes[2] = aRenderSettings->GetDotLength( aWidth );
strokes[3] = aRenderSettings->GetGapLength( aWidth );
wrapAround = 4;
break;
default:
UNIMPLEMENTED_FOR( lineTypeNames.at( aLineStyle ).name );
}
switch( aShape->Type() )
{
case SH_SIMPLE:
{
const SHAPE_SIMPLE* poly = static_cast<const SHAPE_SIMPLE*>( aShape );
for( size_t ii = 0; ii < poly->GetSegmentCount(); ++ii )
{
SEG seg = poly->GetSegment( ii );
SHAPE_SEGMENT line( seg.A, seg.B );
STROKE_PARAMS::Stroke( &line, aLineStyle, aWidth, aRenderSettings, aStroker );
}
}
break;
case SH_SEGMENT:
{
const SHAPE_SEGMENT* line = static_cast<const SHAPE_SEGMENT*>( aShape );
VECTOR2D start = line->GetSeg().A;
VECTOR2D end = line->GetSeg().B;
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 );
for( size_t i = 0; i < 10000; ++i )
{
// Calculations MUST be done in doubles to keep from accumulating rounding
// errors as we go.
VECTOR2D next( start.x + strokes[ i % wrapAround ] * cos( theta ),
start.y + strokes[ i % wrapAround ] * sin( theta ) );
// Drawing each segment can be done rounded to ints.
wxPoint a( KiROUND( start.x ), KiROUND( start.y ) );
wxPoint b( KiROUND( next.x ), KiROUND( next.y ) );
if( ClipLine( &clip, a.x, a.y, b.x, b.y ) )
break;
else if( i % 2 == 0 )
aStroker( a, b );
start = next;
}
}
break;
case SH_ARC:
{
const SHAPE_ARC* arc = static_cast<const SHAPE_ARC*>( aShape );
double r = arc->GetRadius();
double C = 2.0 * M_PI * r;
VECTOR2I center = arc->GetCenter();
VECTOR2D startRadial( arc->GetP0() - center );
double startAngle = 180.0 / M_PI * atan2( startRadial.y, startRadial.x );
VECTOR2D endRadial( arc->GetP1() - center );
double arcEndAngle = 180.0 / M_PI * atan2( endRadial.y, endRadial.x );
if( arcEndAngle == startAngle )
arcEndAngle = startAngle + 360.0; // ring, not null
if( startAngle > arcEndAngle )
{
if( arcEndAngle < 0 )
arcEndAngle = NormalizeAngleDegrees( arcEndAngle, 0.0, 360.0 );
else
startAngle = NormalizeAngleDegrees( startAngle, -360.0, 0.0 );
}
wxASSERT( startAngle < arcEndAngle );
for( size_t i = 0; i < 10000 && startAngle < arcEndAngle; ++i )
{
double theta = 360.0 * strokes[ i % wrapAround ] / C;
double endAngle = std::min( startAngle + theta, arcEndAngle );
if( i % 2 == 0 )
{
wxPoint a( center.x + r * cos( startAngle * M_PI / 180.0 ),
center.y + r * sin( startAngle * M_PI / 180.0 ) );
wxPoint b( center.x + r * cos( endAngle * M_PI / 180.0 ),
center.y + r * sin( endAngle * M_PI / 180.0 ) );
aStroker( a, b );
}
startAngle = endAngle;
}
}
break;
case SH_CIRCLE:
// A circle is always filled; a ring is represented by a 360° arc.
KI_FALLTHROUGH;
default:
UNIMPLEMENTED_FOR( SHAPE_TYPE_asString( aShape->Type() ) );
}
}
static wxString getLineStyleToken( PLOT_DASH_TYPE aStyle )
{
wxString token;
switch( aStyle )
{
case PLOT_DASH_TYPE::DASH: token = "dash"; break;
case PLOT_DASH_TYPE::DOT: token = "dot"; break;
case PLOT_DASH_TYPE::DASHDOT: token = "dash_dot"; break;
case PLOT_DASH_TYPE::SOLID: token = "solid"; break;
case PLOT_DASH_TYPE::DEFAULT: token = "default"; break;
}
return token;
}
void STROKE_PARAMS::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel ) const
{
wxASSERT( aFormatter != nullptr );
aFormatter->Print( aNestLevel, "(stroke (width %s) (type %s) (color %d %d %d %s))",
FormatInternalUnits(GetWidth() ).c_str(),
TO_UTF8( getLineStyleToken( GetPlotStyle() ) ),
KiROUND( GetColor().r * 255.0 ),
KiROUND( GetColor().g * 255.0 ),
KiROUND( GetColor().b * 255.0 ),
Double2Str( GetColor().a ).c_str() );
}
void STROKE_PARAMS_PARSER::ParseStroke( STROKE_PARAMS& aStroke )
{
for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_width:
aStroke.SetWidth( parseDouble( "stroke width" ) * m_iuPerMM );
NeedRIGHT();
break;
case T_type:
{
token = NextTok();
switch( token )
{
case T_dash: aStroke.SetPlotStyle( PLOT_DASH_TYPE::DASH ); break;
case T_dot: aStroke.SetPlotStyle( PLOT_DASH_TYPE::DOT ); break;
case T_dash_dot: aStroke.SetPlotStyle( PLOT_DASH_TYPE::DASHDOT ); break;
case T_solid: aStroke.SetPlotStyle( PLOT_DASH_TYPE::SOLID ); break;
case T_default: aStroke.SetPlotStyle( PLOT_DASH_TYPE::DEFAULT ); break;
default:
Expecting( "solid, dash, dash_dot, dot or default" );
}
NeedRIGHT();
break;
}
case T_color:
{
KIGFX::COLOR4D color;
color.r = parseInt( "red" ) / 255.0;
color.g = parseInt( "green" ) / 255.0;
color.b = parseInt( "blue" ) / 255.0;
color.a = Clamp( parseDouble( "alpha" ), 0.0, 1.0 );
aStroke.SetColor( color );
NeedRIGHT();
break;
}
default:
Expecting( "width, type, or color" );
}
}
}
int STROKE_PARAMS_PARSER::parseInt( const char* aText )
{
T token = NextTok();
if( token != T_NUMBER )
Expecting( aText );
return atoi( CurText() );
}
double STROKE_PARAMS_PARSER::parseDouble( const char* aText )
{
T token = NextTok();
if( token != T_NUMBER )
Expecting( aText );
double val = strtod( CurText(), NULL );
return val;
}

View File

@ -0,0 +1,10 @@
color
dash
dash_dot
dash_dot_dot
default
dot
solid
stroke
type
width

View File

@ -91,6 +91,8 @@ set( EESCHEMA_DLGS
dialogs/dialog_rescue_each_base.cpp
dialogs/dialog_sch_import_settings.cpp
dialogs/dialog_sch_import_settings_base.cpp
dialogs/dialog_shape_properties.cpp
dialogs/dialog_shape_properties_base.cpp
dialogs/dialog_sheet_pin_properties.cpp
dialogs/dialog_sheet_pin_properties_base.cpp
dialogs/dialog_sheet_properties.cpp
@ -183,7 +185,6 @@ set( EESCHEMA_SRCS
lib_pin.cpp
lib_symbol.cpp
lib_text.cpp
symbol_viewer_frame.cpp
libarch.cpp
menubar.cpp
pin_numbers.cpp
@ -210,6 +211,7 @@ set( EESCHEMA_SRCS
sch_screen.cpp
sch_plugins/kicad/sch_sexpr_parser.cpp
sch_plugins/kicad/sch_sexpr_plugin.cpp
sch_shape.cpp
sch_sheet.cpp
sch_sheet_path.cpp
sch_sheet_pin.cpp
@ -226,6 +228,7 @@ set( EESCHEMA_SRCS
symbol_library.cpp
symbol_tree_model_adapter.cpp
symbol_tree_synchronizing_adapter.cpp
symbol_viewer_frame.cpp
toolbars_symbol_viewer.cpp
toolbars_sch_editor.cpp
transform.cpp

View File

@ -319,7 +319,7 @@ bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, SCH_SCREEN* aScreen )
{
static const KICAD_T wiresAndBuses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
static const KICAD_T wiresAndBuses[] = { SCH_ITEM_LOCATE_WIRE_T, SCH_ITEM_LOCATE_BUS_T, EOT };
if( aScreen == nullptr )
aScreen = GetScreen();
@ -380,7 +380,7 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
SCH_SCREEN* screen = GetScreen();
PICKED_ITEMS_LIST undoList;
EE_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
KICAD_T wiresAndBuses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
KICAD_T wiresAndBuses[] = { SCH_ITEM_LOCATE_WIRE_T, SCH_ITEM_LOCATE_BUS_T, EOT };
auto remove_item = [ & ]( SCH_ITEM* aItem ) -> void
{

View File

@ -27,6 +27,7 @@
#include <sch_symbol.h>
#include <sch_connection.h>
#include <sch_edit_frame.h>
#include <sch_shape.h>
#include <sch_line.h>
#include <sch_junction.h>
#include <sch_sheet.h>
@ -117,8 +118,8 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS( SCH_
m_colorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
m_colorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
m_bgColorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
m_bgColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
m_fillColorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
m_fillColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
m_dotColorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
m_dotColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
@ -217,7 +218,7 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataToWindow()
m_lineStyle->SetStringSelection( INDETERMINATE_ACTION );
m_junctionSize.SetValue( INDETERMINATE_ACTION );
m_setColor->SetValue( false );
m_setBgColor->SetValue( false );
m_setFillColor->SetValue( false );
m_setDotColor->SetValue( false );
return true;
@ -240,7 +241,6 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::processItem( const SCH_SHEET_PATH& aS
EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( aItem );
SCH_TEXT* sch_text = dynamic_cast<SCH_TEXT*>( aItem );
SCH_LINE* lineItem = dynamic_cast<SCH_LINE*>( aItem );
SCH_JUNCTION* junction = dynamic_cast<SCH_JUNCTION*>( aItem );
m_parent->SaveCopyInUndoList( aSheetPath.LastScreen(), aItem, UNDO_REDO::CHANGED, m_appendUndo );
@ -274,21 +274,40 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::processItem( const SCH_SHEET_PATH& aS
sch_text->SetLabelSpinStyle( (LABEL_SPIN_STYLE::SPIN) m_orientation->GetSelection() );
}
if( lineItem )
if( aItem->HasLineStroke() )
{
STROKE_PARAMS stroke = aItem->GetStroke();
if( !m_lineWidth.IsIndeterminate() )
lineItem->SetLineWidth( m_lineWidth.GetValue() );
stroke.SetWidth( m_lineWidth.GetValue() );
if( m_lineStyle->GetStringSelection() != INDETERMINATE_ACTION )
{
if( m_lineStyle->GetStringSelection() == DEFAULT_STYLE )
lineItem->SetLineStyle( PLOT_DASH_TYPE::DEFAULT );
stroke.SetPlotStyle( PLOT_DASH_TYPE::DEFAULT );
else
lineItem->SetLineStyle( m_lineStyle->GetSelection() );
stroke.SetPlotStyle( (PLOT_DASH_TYPE) m_lineStyle->GetSelection() );
}
if( m_setColor->GetValue() )
lineItem->SetLineColor( m_colorSwatch->GetSwatchColor() );
stroke.SetColor( m_colorSwatch->GetSwatchColor() );
aItem->SetStroke( stroke );
}
if( aItem->Type() == SCH_SHAPE_T )
{
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
if( m_setFillColor->GetValue() )
{
shape->SetFillColor( m_fillColorSwatch->GetSwatchColor() );
if( m_fillColorSwatch->GetSwatchColor() == COLOR4D::UNSPECIFIED )
shape->SetFillMode( FILL_T::NO_FILL );
else
shape->SetFillMode( FILL_T::FILLED_WITH_COLOR );
}
}
if( junction )
@ -348,9 +367,9 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
}
}
static KICAD_T wireTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LABEL_LOCATE_WIRE_T, EOT };
static KICAD_T busTypes[] = { SCH_LINE_LOCATE_BUS_T, SCH_LABEL_LOCATE_BUS_T, EOT };
static KICAD_T schTextAndGraphics[] = { SCH_TEXT_T, SCH_LINE_LOCATE_GRAPHIC_LINE_T, EOT };
static KICAD_T wireTypes[] = { SCH_ITEM_LOCATE_WIRE_T, SCH_LABEL_LOCATE_WIRE_T, EOT };
static KICAD_T busTypes[] = { SCH_ITEM_LOCATE_BUS_T, SCH_LABEL_LOCATE_BUS_T, EOT };
static KICAD_T schTextAndGraphics[] = { SCH_TEXT_T, SCH_ITEM_LOCATE_GRAPHIC_LINE_T, EOT };
if( aItem->Type() == SCH_SYMBOL_T )
{
@ -409,8 +428,8 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( const SCH_SHEET_PATH& aShe
if( m_setColor->GetValue() )
sheet->SetBorderColor( m_colorSwatch->GetSwatchColor() );
if( m_setBgColor->GetValue() )
sheet->SetBackgroundColor( m_bgColorSwatch->GetSwatchColor() );
if( m_setFillColor->GetValue() )
sheet->SetBackgroundColor( m_fillColorSwatch->GetSwatchColor() );
}
}
else if( aItem->Type() == SCH_JUNCTION_T )

View File

@ -327,14 +327,14 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_BASE::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_
fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
m_setBgColor = new wxCheckBox( m_specifiedValues, wxID_ANY, _("Sheet background color:"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_setBgColor, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_setFillColor = new wxCheckBox( m_specifiedValues, wxID_ANY, _("Fill color:"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_setFillColor, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_bgColorSwatch = new COLOR_SWATCH( m_specifiedValues, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_bgColorSwatch->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
m_bgColorSwatch->SetMinSize( wxSize( 48,24 ) );
m_fillColorSwatch = new COLOR_SWATCH( m_specifiedValues, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_fillColorSwatch->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
m_fillColorSwatch->SetMinSize( wxSize( 48,24 ) );
fgSizer1->Add( m_bgColorSwatch, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgSizer1->Add( m_fillColorSwatch, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_dotSizeLabel = new wxStaticText( m_specifiedValues, wxID_ANY, _("Junction size:"), wxDefaultPosition, wxDefaultSize, 0 );
m_dotSizeLabel->Wrap( -1 );

View File

@ -3570,7 +3570,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Sheet background color:</property>
<property name="label">Fill color:</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -3578,7 +3578,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_setBgColor</property>
<property name="name">m_setFillColor</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -3644,7 +3644,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size">48,24</property>
<property name="moveable">1</property>
<property name="name">m_bgColorSwatch</property>
<property name="name">m_fillColorSwatch</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>

View File

@ -88,8 +88,8 @@ class DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_BASE : public DIALOG_SHIM
COLOR_SWATCH* m_colorSwatch;
wxStaticText* lineStyleLabel;
wxChoice* m_lineStyle;
wxCheckBox* m_setBgColor;
COLOR_SWATCH* m_bgColorSwatch;
wxCheckBox* m_setFillColor;
COLOR_SWATCH* m_fillColorSwatch;
wxStaticText* m_dotSizeLabel;
wxTextCtrl* m_dotSizeCtrl;
wxStaticText* m_dotSizeUnits;

View File

@ -25,7 +25,7 @@
#include <dialog_lib_shape_properties.h>
#include <symbol_edit_frame.h>
#include <confirm.h>
#include <lib_shape.h>
DIALOG_LIB_SHAPE_PROPERTIES::DIALOG_LIB_SHAPE_PROPERTIES( SYMBOL_EDIT_FRAME* aParent,
LIB_ITEM* aItem ) :
@ -85,7 +85,7 @@ bool DIALOG_LIB_SHAPE_PROPERTIES::TransferDataToWindow()
m_checkApplyToAllConversions->Enable( enblConvOptStyle );
if( shape )
m_fillCtrl->SetSelection( static_cast<int>( shape->GetFillType() ) - 1 );
m_fillCtrl->SetSelection( static_cast<int>( shape->GetFillMode() ) - 1 );
m_fillCtrl->Enable( shape != nullptr );
@ -98,13 +98,16 @@ bool DIALOG_LIB_SHAPE_PROPERTIES::TransferDataFromWindow()
if( !wxDialog::TransferDataFromWindow() )
return false;
EDA_SHAPE* shape = dynamic_cast<EDA_SHAPE*>( m_item );
LIB_SHAPE* shape = dynamic_cast<LIB_SHAPE*>( m_item );
if( shape )
{
shape->SetFillMode( static_cast<FILL_T>( std::max( m_fillCtrl->GetSelection() + 1, 1 ) ) );
if( shape )
shape->SetWidth( m_lineWidth.GetValue() );
STROKE_PARAMS stroke = shape->GetStroke();
stroke.SetWidth( m_lineWidth.GetValue() );
shape->SetStroke( stroke );
}
if( GetApplyToAllConversions() )
m_item->SetConvert( 0 );

View File

@ -22,37 +22,15 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <bitmaps.h>
#include <sch_line.h>
#include <dialog_line_wire_bus_properties.h>
#include <dialogs/dialog_color_picker.h>
#include <settings/settings_manager.h>
#include <sch_edit_frame.h>
#include <stroke_params.h>
#include <widgets/color_swatch.h>
struct lineTypeStruct
{
wxString name;
const BITMAPS bitmap;
};
/*
* Conversion map between PLOT_DASH_TYPE values and style names displayed
*/
const std::map<PLOT_DASH_TYPE, struct lineTypeStruct> lineTypeNames = {
{ PLOT_DASH_TYPE::SOLID, { _( "Solid" ), BITMAPS::stroke_solid } },
{ PLOT_DASH_TYPE::DASH, { _( "Dashed" ), BITMAPS::stroke_dash } },
{ PLOT_DASH_TYPE::DOT, { _( "Dotted" ), BITMAPS::stroke_dot } },
{ PLOT_DASH_TYPE::DASHDOT, { _( "Dash-Dot" ), BITMAPS::stroke_dashdot } },
};
#define DEFAULT_STYLE _( "Default" )
#define INDETERMINATE_STYLE _( "Leave unchanged" )
DIALOG_LINE_WIRE_BUS_PROPERTIES::DIALOG_LINE_WIRE_BUS_PROPERTIES( SCH_EDIT_FRAME* aParent,
std::deque<SCH_ITEM*>& aItems ) :
DIALOG_LINE_WIRE_BUS_PROPERTIES_BASE( aParent ),

View File

@ -0,0 +1,113 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 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 <widgets/color_swatch.h>
#include <stroke_params.h>
#include <sch_edit_frame.h>
#include <sch_shape.h>
#include <dialog_shape_properties.h>
DIALOG_SHAPE_PROPERTIES::DIALOG_SHAPE_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_SHAPE* aShape ) :
DIALOG_SHAPE_PROPERTIES_BASE( aParent ),
m_shape( aShape ),
m_lineWidth( aParent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits, true )
{
SetTitle( wxString::Format( GetTitle(), aShape->ShowShape() ) );
m_helpLabel1->SetFont( KIUI::GetInfoFont( this ) );
m_helpLabel2->SetFont( KIUI::GetInfoFont( this ) );
SetInitialFocus( m_lineWidthCtrl );
m_lineColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
for( const std::pair<const PLOT_DASH_TYPE, lineTypeStruct>& typeEntry : lineTypeNames )
m_lineStyleCombo->Append( typeEntry.second.name, KiBitmap( typeEntry.second.bitmap ) );
m_lineStyleCombo->Append( DEFAULT_STYLE );
m_fillColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
// Required under wxGTK if we want to dismiss the dialog with the ESC key
SetFocus();
m_sdbSizerOK->SetDefault();
// Now all widgets have the size fixed, call FinishDialogSettings
finishDialogSettings();
}
bool DIALOG_SHAPE_PROPERTIES::TransferDataToWindow()
{
if( !wxDialog::TransferDataToWindow() )
return false;
m_lineWidth.SetValue( m_shape->GetWidth() );
m_lineColorSwatch->SetSwatchColor( m_shape->GetStroke().GetColor(), false );
int style = static_cast<int>( m_shape->GetStroke().GetPlotStyle() );
if( style == -1 )
m_lineStyleCombo->SetStringSelection( DEFAULT_STYLE );
else if( style < (int) lineTypeNames.size() )
m_lineStyleCombo->SetSelection( style );
else
wxFAIL_MSG( "Line type not found in the type lookup map" );
m_filledCtrl->SetValue( m_shape->IsFilled() );
m_fillColorSwatch->SetSwatchColor( m_shape->GetFillColor(), false );
return true;
}
bool DIALOG_SHAPE_PROPERTIES::TransferDataFromWindow()
{
if( !wxDialog::TransferDataFromWindow() )
return false;
STROKE_PARAMS stroke = m_shape->GetStroke();
if( !m_lineWidth.IsIndeterminate() )
stroke.SetWidth( m_lineWidth.GetValue() );
auto it = lineTypeNames.begin();
std::advance( it, m_lineStyleCombo->GetSelection() );
if( it == lineTypeNames.end() )
stroke.SetPlotStyle( PLOT_DASH_TYPE::DEFAULT );
else
stroke.SetPlotStyle( it->first );
stroke.SetColor( m_lineColorSwatch->GetSwatchColor() );
m_shape->SetStroke( stroke );
m_shape->SetFillMode( m_filledCtrl->GetValue() ? FILL_T::FILLED_WITH_COLOR : FILL_T::NO_FILL );
m_shape->SetFillColor( m_fillColorSwatch->GetSwatchColor() );
return true;
}

View File

@ -0,0 +1,49 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 KiCad Developers, see CHANGELOG.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
*/
#ifndef DIALOG_SHAPE_PROPERTIES_H
#define DIALOG_SHAPE_PROPERTIES_H
class SCH_SHAPE;
class SCH_EDIT_FRAME;
#include <dialog_shape_properties_base.h>
#include <widgets/unit_binder.h>
class DIALOG_SHAPE_PROPERTIES : public DIALOG_SHAPE_PROPERTIES_BASE
{
public:
DIALOG_SHAPE_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_SHAPE* aShape );
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
private:
SCH_SHAPE* m_shape;
UNIT_BINDER m_lineWidth;
};
#endif // DIALOG_SHAPE_PROPERTIES_H

View File

@ -0,0 +1,146 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/color_swatch.h"
#include "dialog_shape_properties_base.h"
///////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE( DIALOG_SHAPE_PROPERTIES_BASE, DIALOG_SHIM )
EVT_BUTTON( wxID_APPLY, DIALOG_SHAPE_PROPERTIES_BASE::_wxFB_resetDefaults )
END_EVENT_TABLE()
DIALOG_SHAPE_PROPERTIES_BASE::DIALOG_SHAPE_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* mainSizer;
mainSizer = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer* fgSizerGeneral;
fgSizerGeneral = new wxFlexGridSizer( 0, 3, 7, 0 );
fgSizerGeneral->AddGrowableCol( 1 );
fgSizerGeneral->SetFlexibleDirection( wxBOTH );
fgSizerGeneral->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_lineWidthLabel = new wxStaticText( this, wxID_ANY, _("Line width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lineWidthLabel->Wrap( -1 );
fgSizerGeneral->Add( m_lineWidthLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
m_lineWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
fgSizerGeneral->Add( m_lineWidthCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT, 3 );
m_lineWidthUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_lineWidthUnits->Wrap( -1 );
m_lineWidthUnits->SetMinSize( wxSize( 40,-1 ) );
fgSizerGeneral->Add( m_lineWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
m_lineColorLabel = new wxStaticText( this, wxID_ANY, _("Line color:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lineColorLabel->Wrap( -1 );
fgSizerGeneral->Add( m_lineColorLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_panel1 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE|wxTAB_TRAVERSAL );
wxBoxSizer* bSizer2;
bSizer2 = new wxBoxSizer( wxVERTICAL );
m_lineColorSwatch = new COLOR_SWATCH( m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_lineColorSwatch, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_panel1->SetSizer( bSizer2 );
m_panel1->Layout();
bSizer2->Fit( m_panel1 );
fgSizerGeneral->Add( m_panel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 2 );
fgSizerGeneral->Add( 0, 0, 1, wxEXPAND, 5 );
m_lineStyleLabel = new wxStaticText( this, wxID_ANY, _("Line style:"), wxDefaultPosition, wxDefaultSize, 0 );
m_lineStyleLabel->Wrap( -1 );
fgSizerGeneral->Add( m_lineStyleLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_lineStyleCombo = new wxBitmapComboBox( this, wxID_ANY, _("Combo!"), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
m_lineStyleCombo->SetMinSize( wxSize( 240,-1 ) );
fgSizerGeneral->Add( m_lineStyleCombo, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT, 3 );
fgSizerGeneral->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerGeneral->Add( 0, 0, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
fgSizerGeneral->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerGeneral->Add( 0, 0, 1, wxEXPAND, 5 );
m_filledCtrl = new wxCheckBox( this, wxID_ANY, _("Filled shape"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizerGeneral->Add( m_filledCtrl, 0, wxALIGN_CENTER_VERTICAL, 5 );
fgSizerGeneral->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerGeneral->Add( 0, 0, 1, wxEXPAND, 5 );
m_fillColorLabel = new wxStaticText( this, wxID_ANY, _("Fill color:"), wxDefaultPosition, wxDefaultSize, 0 );
m_fillColorLabel->Wrap( -1 );
fgSizerGeneral->Add( m_fillColorLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_panel11 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE|wxTAB_TRAVERSAL );
wxBoxSizer* bSizer21;
bSizer21 = new wxBoxSizer( wxVERTICAL );
m_fillColorSwatch = new COLOR_SWATCH( m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
bSizer21->Add( m_fillColorSwatch, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_panel11->SetSizer( bSizer21 );
m_panel11->Layout();
bSizer21->Fit( m_panel11 );
fgSizerGeneral->Add( m_panel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
mainSizer->Add( fgSizerGeneral, 1, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 10 );
m_helpLabel1 = new wxStaticText( this, wxID_ANY, _("Set line width to 0 to use Schematic Editor line widths."), wxDefaultPosition, wxDefaultSize, 0 );
m_helpLabel1->Wrap( 333 );
mainSizer->Add( m_helpLabel1, 0, wxTOP|wxRIGHT|wxLEFT, 10 );
m_helpLabel2 = new wxStaticText( this, wxID_ANY, _("Set line color to transparent to use Schematic Editor colors."), wxDefaultPosition, wxDefaultSize, 0 );
m_helpLabel2->Wrap( -1 );
mainSizer->Add( m_helpLabel2, 0, wxBOTTOM|wxRIGHT|wxLEFT, 10 );
m_staticline = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
mainSizer->Add( m_staticline, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerApply = new wxButton( this, wxID_APPLY );
m_sdbSizer->AddButton( m_sdbSizerApply );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
mainSizer->Add( m_sdbSizer, 0, wxALL|wxALIGN_RIGHT, 5 );
this->SetSizer( mainSizer );
this->Layout();
mainSizer->Fit( this );
this->Centre( wxBOTH );
}
DIALOG_SHAPE_PROPERTIES_BASE::~DIALOG_SHAPE_PROPERTIES_BASE()
{
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class COLOR_SWATCH;
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/bmpcbox.h>
#include <wx/checkbox.h>
#include <wx/statline.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_SHAPE_PROPERTIES_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_SHAPE_PROPERTIES_BASE : public DIALOG_SHIM
{
DECLARE_EVENT_TABLE()
private:
// Private event handlers
void _wxFB_resetDefaults( wxCommandEvent& event ){ resetDefaults( event ); }
protected:
wxStaticText* m_lineWidthLabel;
wxTextCtrl* m_lineWidthCtrl;
wxStaticText* m_lineWidthUnits;
wxStaticText* m_lineColorLabel;
wxPanel* m_panel1;
COLOR_SWATCH* m_lineColorSwatch;
wxStaticText* m_lineStyleLabel;
wxBitmapComboBox* m_lineStyleCombo;
wxCheckBox* m_filledCtrl;
wxStaticText* m_fillColorLabel;
wxPanel* m_panel11;
COLOR_SWATCH* m_fillColorSwatch;
wxStaticText* m_helpLabel1;
wxStaticText* m_helpLabel2;
wxStaticLine* m_staticline;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerApply;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, overide them in your derived class
virtual void resetDefaults( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_SHAPE_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("%s Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_SHAPE_PROPERTIES_BASE();
};

View File

@ -49,6 +49,7 @@
std::set<int> g_excludedLayers =
{
LAYER_NOTES_BACKGROUND,
LAYER_DANGLING
};
@ -209,7 +210,6 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createSwatches()
layers.push_back( i );
}
std::sort( layers.begin(), layers.end(),
[]( SCH_LAYER_ID a, SCH_LAYER_ID b )
{
@ -382,7 +382,7 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems()
comp_body->SetUnit( 0 );
comp_body->SetConvert( 0 );
comp_body->SetWidth( Mils2iu( 10 ) );
comp_body->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
comp_body->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
comp_body->AddPoint( MILS_POINT( p.x - 200, p.y + 200 ) );
comp_body->AddPoint( MILS_POINT( p.x + 200, p.y ) );

View File

@ -43,6 +43,7 @@ const KICAD_T EE_COLLECTOR::AllItems[] = {
const KICAD_T EE_COLLECTOR::EditableItems[] = {
SCH_SHAPE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
@ -80,6 +81,7 @@ const KICAD_T EE_COLLECTOR::MovableItems[] =
SCH_BUS_WIRE_ENTRY_T,
SCH_LINE_T,
SCH_BITMAP_T,
SCH_SHAPE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,

View File

@ -33,10 +33,9 @@
#include <lib_shape.h>
LIB_SHAPE::LIB_SHAPE( LIB_SYMBOL* aParent, SHAPE_T aShape, int aDefaultLineWidth,
FILL_T aFillType ) :
LIB_SHAPE::LIB_SHAPE( LIB_SYMBOL* aParent, SHAPE_T aShape, int aLineWidth, FILL_T aFillType ) :
LIB_ITEM( LIB_SHAPE_T, aParent ),
EDA_SHAPE( aShape, aDefaultLineWidth, aFillType, true )
EDA_SHAPE( aShape, aLineWidth, aFillType, true )
{
m_editState = 0;
}
@ -260,7 +259,7 @@ void LIB_SHAPE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset,
std::swap( pt1, pt2 );
}
if( forceNoFill || GetFillType() == FILL_T::NO_FILL )
if( forceNoFill || GetFillMode() == FILL_T::NO_FILL )
{
penWidth = std::max( penWidth, aSettings->GetDefaultPenWidth() );
@ -292,7 +291,7 @@ void LIB_SHAPE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset,
}
else
{
if( GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR )
if( GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR )
fillColor = aSettings->GetLayerColor( LAYER_DEVICE_BACKGROUND );
switch( GetShape() )
@ -415,46 +414,20 @@ void LIB_SHAPE::AddPoint( const wxPoint& aPosition )
}
else
{
wxFAIL_MSG( "LIB_SHAPE::AddPoint not implemented for " + SHAPE_T_asString() );
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
}
}
void LIB_SHAPE::CalcArcAngles( int& aStartAngle, int& aEndAngle ) const
{
wxPoint centerStartVector = GetStart() - GetCenter();
wxPoint centerEndVector = GetEnd() - GetCenter();
double start;
double end;
// Angles in Eeschema are still integers
aStartAngle = KiROUND( ArcTangente( centerStartVector.y, centerStartVector.x ) );
aEndAngle = KiROUND( ArcTangente( centerEndVector.y, centerEndVector.x ) );
EDA_SHAPE::CalcArcAngles( start, end );
NORMALIZE_ANGLE_POS( aStartAngle );
NORMALIZE_ANGLE_POS( aEndAngle ); // angles = 0 .. 3600
// Restrict angle to less than 180 to avoid PBS display mirror Trace because it is
// assumed that the arc is less than 180 deg to find orientation after rotate or mirror.
if( ( aEndAngle - aStartAngle ) > 1800 )
aEndAngle -= 3600;
else if( ( aEndAngle - aStartAngle ) <= -1800 )
aEndAngle += 3600;
while( ( aEndAngle - aStartAngle ) >= 1800 )
{
aEndAngle--;
aStartAngle++;
}
while( ( aStartAngle - aEndAngle ) >= 1800 )
{
aEndAngle++;
aStartAngle--;
}
NORMALIZE_ANGLE_POS( aStartAngle );
if( !IsMoving() )
NORMALIZE_ANGLE_POS( aEndAngle );
aStartAngle = KiROUND( start * 10.0 );
aEndAngle = KiROUND( end * 10.0 );
}

View File

@ -49,6 +49,9 @@ public:
return ShowShape();
}
STROKE_PARAMS GetStroke() const { return m_stroke; }
void SetStroke( const STROKE_PARAMS& aStroke ) { m_stroke = aStroke; }
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
@ -59,7 +62,7 @@ public:
// For historical reasons, a stored value of 0 means "default width" and negative
// numbers meant "don't stroke".
if( GetPenWidth() < 0 && GetFillType() != FILL_T::NO_FILL )
if( GetPenWidth() < 0 && GetFillMode() != FILL_T::NO_FILL )
return 0;
else if( GetPenWidth() == 0 )
return aSettings->GetDefaultPenWidth();

View File

@ -531,7 +531,7 @@ void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset
if( aConvert && shape.m_convert && ( shape.m_convert != aConvert ) )
continue;
if( shape.GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR )
if( shape.GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR )
shape.Print( aSettings, aOffset, (void*) false, aOpts.transform );
}
}
@ -568,7 +568,7 @@ void LIB_SYMBOL::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset
else if( item.Type() == LIB_SHAPE_T )
{
LIB_SHAPE& shape = static_cast<LIB_SHAPE&>( item );
bool forceNoFill = shape.GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR;
bool forceNoFill = shape.GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR;
shape.Print( aSettings, aOffset, (void*) forceNoFill, aOpts.transform );
}
@ -603,7 +603,7 @@ void LIB_SYMBOL::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint
if( aConvert && shape.m_convert && ( shape.m_convert != aConvert ) )
continue;
if( shape.GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR && aPlotter->GetColorMode() )
if( shape.GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR && aPlotter->GetColorMode() )
shape.Plot( aPlotter, aOffset, true, aTransform );
}
@ -627,7 +627,7 @@ void LIB_SYMBOL::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint
if( item.Type() == LIB_SHAPE_T )
{
const LIB_SHAPE& shape = static_cast<const LIB_SHAPE&>( item );
forceNoFill = shape.GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR;
forceNoFill = shape.GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR;
}
item.Plot( aPlotter, aOffset, !forceNoFill, aTransform );

View File

@ -215,6 +215,9 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
placeMenu->Add( EE_ACTIONS::importSheetPin );
placeMenu->AppendSeparator();
placeMenu->Add( EE_ACTIONS::drawRectangle );
placeMenu->Add( EE_ACTIONS::drawCircle );
placeMenu->Add( EE_ACTIONS::drawArc );
placeMenu->Add( EE_ACTIONS::drawLines );
placeMenu->Add( EE_ACTIONS::placeSchematicText );
placeMenu->Add( EE_ACTIONS::placeImage );

View File

@ -26,6 +26,7 @@
#include <bitmaps.h>
#include <core/mirror.h>
#include <schematic.h>
#include <geometry/shape_segment.h>
#include <sch_bus_entry.h>
#include <sch_edit_frame.h>
#include <sch_junction.h>
@ -172,7 +173,7 @@ const EDA_RECT SCH_BUS_ENTRY_BASE::GetBoundingBox() const
}
COLOR4D SCH_BUS_ENTRY_BASE::GetStrokeColor() const
COLOR4D SCH_BUS_ENTRY_BASE::GetBusEntryColor() const
{
if( m_stroke.GetColor() != COLOR4D::UNSPECIFIED )
{
@ -190,7 +191,7 @@ COLOR4D SCH_BUS_ENTRY_BASE::GetStrokeColor() const
}
PLOT_DASH_TYPE SCH_BUS_ENTRY_BASE::GetStrokeStyle() const
PLOT_DASH_TYPE SCH_BUS_ENTRY_BASE::GetLineStyle() const
{
if( m_stroke.GetPlotStyle() != PLOT_DASH_TYPE::DEFAULT )
{
@ -267,57 +268,25 @@ void SCH_BUS_BUS_ENTRY::GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemLis
void SCH_BUS_ENTRY_BASE::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
{
wxDC* DC = aSettings->GetPrintDC();
COLOR4D color = ( GetStrokeColor() == COLOR4D::UNSPECIFIED ) ?
aSettings->GetLayerColor( m_layer ) : GetStrokeColor();
COLOR4D color = ( GetBusEntryColor() == COLOR4D::UNSPECIFIED ) ?
aSettings->GetLayerColor( m_layer ) : GetBusEntryColor();
wxPoint start = m_pos + aOffset;
wxPoint end = GetEnd() + aOffset;
int penWidth = ( GetPenWidth() == 0 ) ? aSettings->GetDefaultPenWidth() : GetPenWidth();
if( GetStrokeStyle() <= PLOT_DASH_TYPE::FIRST_TYPE )
if( GetLineStyle() <= 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();
SHAPE_SEGMENT segment( start, end );
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;
}
STROKE_PARAMS::Stroke( &segment, GetLineStyle(), penWidth, aSettings,
[&]( const wxPoint& a, const wxPoint& b )
{
GRLine( nullptr, DC, a.x, a.y, b.x, b.y, penWidth, color );
} );
}
}
@ -503,15 +472,15 @@ void SCH_BUS_ENTRY_BASE::Plot( PLOTTER* aPlotter ) const
{
auto* settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( aPlotter->RenderSettings() );
COLOR4D color = ( GetStrokeColor() == COLOR4D::UNSPECIFIED ) ?
settings->GetLayerColor( m_layer ) : GetStrokeColor();
COLOR4D color = ( GetBusEntryColor() == COLOR4D::UNSPECIFIED ) ?
settings->GetLayerColor( m_layer ) : GetBusEntryColor();
int penWidth = ( GetPenWidth() == 0 ) ? settings->GetDefaultPenWidth() : GetPenWidth();
penWidth = std::max( penWidth, settings->GetMinPenWidth() );
aPlotter->SetCurrentLineWidth( penWidth );
aPlotter->SetColor( color );
aPlotter->SetDash( GetStrokeStyle() );
aPlotter->SetDash( GetLineStyle() );
aPlotter->MoveTo( m_pos );
aPlotter->FinishTo( GetEnd() );
}

View File

@ -22,11 +22,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file sch_bus_entry.h
*
*/
#ifndef _SCH_BUS_ENTRY_H_
#define _SCH_BUS_ENTRY_H_
@ -81,11 +76,9 @@ public:
virtual STROKE_PARAMS GetStroke() const override { return m_stroke; }
virtual void SetStroke( const STROKE_PARAMS& aStroke ) override { m_stroke = aStroke; }
PLOT_DASH_TYPE GetStrokeStyle() const;
void SetStrokeStyle( PLOT_DASH_TYPE aStyle ) { m_stroke.SetPlotStyle( aStyle ); }
PLOT_DASH_TYPE GetLineStyle() const;
COLOR4D GetStrokeColor() const;
void SetStrokeColor( const COLOR4D& aColor ) { m_stroke.SetColor( aColor ); }
COLOR4D GetBusEntryColor() const;
void SwapData( SCH_ITEM* aItem ) override;

View File

@ -66,4 +66,5 @@
//#define SEXPR_SCHEMATIC_FILE_VERSION 20210606 // Change overbar syntax from `~...~` to `~{...}`.
//#define SEXPR_SCHEMATIC_FILE_VERSION 20210615 // Update overbar syntax in net names.
//#define SEXPR_SCHEMATIC_FILE_VERSION 20210621 // Update overbar syntax in bus aliases.
#define SEXPR_SCHEMATIC_FILE_VERSION 20211123 // R/W uuids for junctions.
//#define SEXPR_SCHEMATIC_FILE_VERSION 20211123 // R/W uuids for junctions.
#define SEXPR_SCHEMATIC_FILE_VERSION 20220101 // Circles, arcs, rects, polys & beziers

View File

@ -29,8 +29,7 @@
#include <unordered_set>
#include <eda_item.h>
#include <plotters/plotter.h> // for PLOT_DASH_TYPE definition
#include <plotters/plotter.h>
#include <default_values.h>
#include <sch_sheet_path.h>
#include <netclass.h>
@ -134,44 +133,6 @@ private:
typedef std::unordered_set<SCH_ITEM*> SCH_ITEM_SET;
/**
* Simple container to manage line stroke parameters.
*/
class STROKE_PARAMS
{
public:
STROKE_PARAMS( int aWidth = Mils2iu( DEFAULT_LINE_WIDTH_MILS ),
PLOT_DASH_TYPE aPlotStyle = PLOT_DASH_TYPE::DEFAULT,
const COLOR4D& aColor = COLOR4D::UNSPECIFIED ) :
m_width( aWidth ),
m_plotstyle( aPlotStyle ),
m_color( aColor )
{
}
int GetWidth() const { return m_width; }
void SetWidth( int aWidth ) { m_width = aWidth; }
PLOT_DASH_TYPE GetPlotStyle() const { return m_plotstyle; }
void SetPlotStyle( PLOT_DASH_TYPE aPlotStyle ) { m_plotstyle = aPlotStyle; }
COLOR4D GetColor() const { return m_color; }
void SetColor( const COLOR4D& aColor ) { m_color = aColor; }
bool operator!=( const STROKE_PARAMS& aOther )
{
return m_width != aOther.m_width
|| m_plotstyle != aOther.m_plotstyle
|| m_color != aOther.m_color;
}
private:
int m_width;
PLOT_DASH_TYPE m_plotstyle;
COLOR4D m_color;
};
/**
* Base class for any item which can be embedded within the #SCHEMATIC container class,
* and therefore instances of derived classes should only be found in EESCHEMA or other
@ -195,6 +156,24 @@ public:
return wxT( "SCH_ITEM" );
}
bool IsType( const KICAD_T aScanTypes[] ) const override
{
if( EDA_ITEM::IsType( aScanTypes ) )
return true;
for( const KICAD_T* p = aScanTypes; *p != EOT; ++p )
{
if( *p == SCH_ITEM_LOCATE_WIRE_T && m_layer == LAYER_WIRE )
return true;
else if ( *p == SCH_ITEM_LOCATE_BUS_T && m_layer == LAYER_BUS )
return true;
else if ( *p == SCH_ITEM_LOCATE_GRAPHIC_LINE_T && m_layer == LAYER_NOTES )
return true;
}
return false;
}
/**
* Swap the internal data structures \a aItem with the schematic item.
* Obviously, aItem must have the same type than me.

View File

@ -26,6 +26,7 @@
#include <core/mirror.h>
#include <sch_painter.h>
#include <plotters/plotter.h>
#include <geometry/shape_segment.h>
#include <sch_line.h>
#include <sch_edit_frame.h>
#include <settings/color_settings.h>
@ -37,6 +38,7 @@
#include <board_item.h>
#include <advanced_config.h>
SCH_LINE::SCH_LINE( const wxPoint& pos, int layer ) :
SCH_ITEM( nullptr, SCH_LINE_T )
{
@ -382,45 +384,13 @@ void SCH_LINE::Print( const RENDER_SETTINGS* aSettings, const wxPoint& offset )
}
else
{
EDA_RECT clip( (wxPoint) start, wxSize( end.x - start.x, end.y - start.y ) );
clip.Normalize();
SHAPE_SEGMENT segment( start, end );
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;
}
STROKE_PARAMS::Stroke( &segment, lineStyle, penWidth, aSettings,
[&]( const wxPoint& a, const wxPoint& b )
{
GRLine( nullptr, DC, a.x, a.y, b.x, b.y, penWidth, color );
} );
}
}

View File

@ -59,24 +59,6 @@ public:
return wxT( "SCH_LINE" );
}
bool IsType( const KICAD_T aScanTypes[] ) const override
{
if( SCH_ITEM::IsType( aScanTypes ) )
return true;
for( const KICAD_T* p = aScanTypes; *p != EOT; ++p )
{
if( *p == SCH_LINE_LOCATE_WIRE_T && m_layer == LAYER_WIRE )
return true;
else if ( *p == SCH_LINE_LOCATE_BUS_T && m_layer == LAYER_BUS )
return true;
else if ( *p == SCH_LINE_LOCATE_GRAPHIC_LINE_T && m_layer == LAYER_NOTES )
return true;
}
return false;
}
bool IsEndPoint( const wxPoint& aPoint ) const
{
return aPoint == m_start || aPoint == m_end;
@ -276,11 +258,11 @@ public:
private:
bool doIsConnected( const wxPoint& aPosition ) const override;
bool m_startIsDangling; ///< True if start point is not connected.
bool m_endIsDangling; ///< True if end point is not connected.
wxPoint m_start; ///< Line start point
wxPoint m_end; ///< Line end point
STROKE_PARAMS m_stroke; ///< Line stroke properties.
bool m_startIsDangling; ///< True if start point is not connected.
bool m_endIsDangling; ///< True if end point is not connected.
wxPoint m_start; ///< Line start point
wxPoint m_end; ///< Line end point
STROKE_PARAMS m_stroke; ///< Line stroke properties.
// If real-time connectivity gets disabled (due to being too slow on a particular
// design), we can no longer rely on getting the NetClass to find netclass-specific

View File

@ -27,12 +27,12 @@
#include <sch_item.h>
#include <trigo.h>
#include <bezier_curves.h>
#include <symbol_library.h>
#include <connection_graph.h>
#include <gal/graphics_abstraction_layer.h>
#include <geometry/geometry_utils.h>
#include <geometry/shape_line_chain.h>
#include <geometry/shape_segment.h>
#include <geometry/shape_simple.h>
#include <gr_text.h>
#include <lib_shape.h>
#include <lib_field.h>
@ -60,7 +60,10 @@
#include <default_values.h>
#include <advanced_config.h>
#include <string_utils.h>
#include <stroke_params.h>
#include "sch_painter.h"
#include "sch_shape.h"
namespace KIGFX
{
@ -82,6 +85,8 @@ SCH_RENDER_SETTINGS::SCH_RENDER_SETTINGS() :
m_JunctionSize( DEFAULT_JUNCTION_DIAM * IU_PER_MILS )
{
SetDefaultPenWidth( DEFAULT_LINE_WIDTH_MILS * IU_PER_MILS );
SetDashLengthRatio( 5 );
SetGapLengthRatio( 3 );
m_minPenWidth = ADVANCED_CFG::GetCfg().m_MinPlotPenWidth * IU_PER_MM;
}
@ -216,6 +221,7 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
HANDLE_ITEM( SCH_SYMBOL_T, SCH_SYMBOL );
HANDLE_ITEM( SCH_JUNCTION_T, SCH_JUNCTION );
HANDLE_ITEM( SCH_LINE_T, SCH_LINE );
HANDLE_ITEM( SCH_SHAPE_T, SCH_SHAPE );
HANDLE_ITEM( SCH_TEXT_T, SCH_TEXT );
HANDLE_ITEM( SCH_LABEL_T, SCH_TEXT );
HANDLE_ITEM( SCH_FIELD_T, SCH_FIELD );
@ -280,7 +286,7 @@ COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM* aItem, int aLayer, bool aDr
}
else if( aItem->Type() == SCH_BUS_WIRE_ENTRY_T )
{
COLOR4D busEntryColor = static_cast<const SCH_BUS_WIRE_ENTRY*>( aItem )->GetStrokeColor();
COLOR4D busEntryColor = static_cast<const SCH_BUS_WIRE_ENTRY*>( aItem )->GetBusEntryColor();
if( busEntryColor != COLOR4D::UNSPECIFIED )
color = busEntryColor;
@ -496,11 +502,11 @@ bool SCH_PAINTER::setDeviceColors( const LIB_ITEM* aItem, int aLayer )
return false;
case LAYER_DEVICE_BACKGROUND:
if( shape && shape->GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR )
if( shape && shape->GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR )
{
COLOR4D fillColor = getRenderColor( aItem, LAYER_DEVICE_BACKGROUND, false );
m_gal->SetIsFill( shape->GetFillType() == FILL_T::FILLED_WITH_BG_BODYCOLOR );
m_gal->SetIsFill( shape->GetFillMode() == FILL_T::FILLED_WITH_BG_BODYCOLOR );
m_gal->SetFillColor( fillColor );
m_gal->SetIsStroke( false );
return true;
@ -509,7 +515,7 @@ bool SCH_PAINTER::setDeviceColors( const LIB_ITEM* aItem, int aLayer )
return false;
case LAYER_DEVICE:
m_gal->SetIsFill( shape && shape->GetFillType() == FILL_T::FILLED_SHAPE );
m_gal->SetIsFill( shape && shape->GetFillMode() == FILL_T::FILLED_SHAPE );
m_gal->SetFillColor( getRenderColor( aItem, LAYER_DEVICE, false ) );
if( aItem->GetPenWidth() >= 0 || !shape || !shape->IsFilled() )
@ -597,7 +603,7 @@ void SCH_PAINTER::draw( const LIB_SHAPE *aShape, int aLayer )
break;
default:
wxFAIL_MSG( "SCH_PAINTER::draw not implemented for " + aShape->SHAPE_T_asString() );
UNIMPLEMENTED_FOR( aShape->SHAPE_T_asString() );
}
}
}
@ -640,21 +646,19 @@ void SCH_PAINTER::draw( const LIB_FIELD *aField, int aLayer )
return;
}
m_gal->SetLineWidth( getTextThickness( aField, drawingShadows ) );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getTextThickness( aField, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->SetIsFill( drawingShadows && eeconfig()->m_Selection.text_as_box );
m_gal->SetFillColor( color );
EDA_RECT bbox = aField->GetBoundingBox();
wxPoint textpos = bbox.Centre();
if( drawingShadows && eeconfig()->m_Selection.text_as_box )
{
m_gal->SetIsFill( true );
m_gal->SetFillColor( color );
m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 );
bbox.RevertYAxis();
m_gal->SetLineWidth( m_gal->GetLineWidth() / 2 );
m_gal->DrawRectangle( mapCoords( bbox.GetPosition() ), mapCoords( bbox.GetEnd() ) );
}
else
@ -948,11 +952,11 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
LIB_SYMBOL* libEntry = aPin->GetParent();
// Draw the labels
if( drawingShadows
&& ( libEntry->Type() == LIB_SYMBOL_T || libEntry->IsSelected() )
&& !eeconfig()->m_Selection.draw_selected_children )
if( libEntry->Type() == LIB_SYMBOL_T )
{
return;
if( drawingShadows && !eeconfig()->m_Selection.draw_selected_children )
return;
}
float penWidth = (float) m_schSettings.GetDefaultPenWidth();
@ -1278,47 +1282,120 @@ void SCH_PAINTER::draw( const SCH_LINE *aLine, int aLayer )
}
else
{
VECTOR2D start = aLine->GetStartPoint();
VECTOR2D end = aLine->GetEndPoint();
SHAPE_SEGMENT line( aLine->GetStartPoint(), aLine->GetEndPoint() );
EDA_RECT clip( (wxPoint)start, wxSize( end.x - start.x, end.y - start.y ) );
clip.Normalize();
STROKE_PARAMS::Stroke( &line, lineStyle, width, &m_schSettings,
[&]( const wxPoint& a, const wxPoint& b )
{
m_gal->DrawLine( a, b );
} );
}
}
double theta = atan2( end.y - start.y, end.x - start.x );
double strokes[] = { 1.0, dash_gap_len( width ), 1.0, dash_gap_len( width ) };
switch( lineStyle )
void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
PLOT_DASH_TYPE lineStyle = aShape->GetEffectiveLineStyle();
if( drawingShadows && !aShape->IsSelected() )
return;
auto drawShape =
[&]( const SCH_SHAPE* shape )
{
switch( shape->GetShape() )
{
case SHAPE_T::ARC:
{
int startAngle;
int endAngle;
aShape->CalcArcAngles( startAngle, endAngle );
m_gal->DrawArc( aShape->GetCenter(), aShape->GetRadius(),
DECIDEG2RAD( startAngle ), DECIDEG2RAD( endAngle ) );
}
break;
case SHAPE_T::CIRCLE:
m_gal->DrawCircle( shape->GetPosition(), shape->GetRadius() );
break;
case SHAPE_T::RECT:
m_gal->DrawRectangle( shape->GetPosition(), shape->GetEnd() );
break;
case SHAPE_T::POLY:
{
std::deque<VECTOR2D> pts;
for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
pts.push_back( pt );
m_gal->DrawPolygon( pts );
}
break;
case SHAPE_T::BEZIER:
{
std::deque<VECTOR2D> pts;
for( const VECTOR2I &p : shape->GetPolyShape().Outline( 0 ).CPoints() )
pts.push_back( p );
m_gal->DrawPolygon( pts );
}
break;
default:
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}
};
if( aLayer == LAYER_SELECTION_SHADOWS && eeconfig()->m_Selection.fill_shapes )
{
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
m_gal->SetFillColor( getRenderColor( aShape, aLayer, drawingShadows ) );
drawShape( aShape );
}
else if( aLayer == LAYER_NOTES_BACKGROUND && aShape->IsFilled() )
{
m_gal->SetIsFill( true );
m_gal->SetIsStroke( false );
m_gal->SetFillColor( aShape->GetFillColor() );
drawShape( aShape );
}
else if( aLayer == LAYER_NOTES )
{
int lineWidth = getLineWidth( aShape, drawingShadows );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( lineWidth );
m_gal->SetStrokeColor( getRenderColor( aShape, aLayer, drawingShadows ) );
if( lineStyle <= PLOT_DASH_TYPE::FIRST_TYPE || drawingShadows )
{
default:
case PLOT_DASH_TYPE::DASH:
strokes[0] = strokes[2] = dash_mark_len( width );
break;
case PLOT_DASH_TYPE::DOT:
strokes[0] = strokes[2] = dot_mark_len( width );
break;
case PLOT_DASH_TYPE::DASHDOT:
strokes[0] = dash_mark_len( width );
strokes[2] = dot_mark_len( width );
break;
drawShape( aShape );
}
for( size_t i = 0; i < 10000; ++i )
else
{
// Calculations MUST be done in doubles to keep from accumulating rounding
// errors as we go.
VECTOR2D next( start.x + strokes[ i % 4 ] * cos( theta ),
start.y + strokes[ i % 4 ] * sin( theta ) );
std::vector<SHAPE*> shapes = aShape->MakeEffectiveShapes( true );
// 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 ) );
for( SHAPE* shape : shapes )
{
STROKE_PARAMS::Stroke( shape, lineStyle, lineWidth, &m_schSettings,
[&]( const wxPoint& a, const wxPoint& b )
{
m_gal->DrawLine( a, b );
} );
}
if( ClipLine( &clip, segStart.x, segStart.y, segEnd.x, segEnd.y ) )
break;
else if( i % 2 == 0 )
m_gal->DrawLine( segStart, segEnd );
start = next;
for( SHAPE* shape : shapes )
delete shape;
}
}
}
@ -1373,10 +1450,11 @@ void SCH_PAINTER::draw( const SCH_TEXT *aText, int aLayer )
return;
}
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getTextThickness( aText, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->SetIsFill( drawingShadows && eeconfig()->m_Selection.text_as_box );
m_gal->SetFillColor( color );
VECTOR2D text_offset = aText->GetTextPos() + aText->GetSchematicTextOffset( &m_schSettings );
wxString shownText( aText->GetShownText() );
@ -1386,22 +1464,19 @@ void SCH_PAINTER::draw( const SCH_TEXT *aText, int aLayer )
if( eeconfig()->m_Selection.text_as_box )
{
EDA_RECT bBox = aText->GetBoundingBox();
m_gal->SetIsFill( true );
m_gal->SetFillColor( color );
m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 );
bBox.RevertYAxis();
m_gal->DrawRectangle( mapCoords( bBox.GetPosition() ), mapCoords( bBox.GetEnd() ) );
return;
}
float shadowWidth = getShadowWidth();
switch( aText->GetLabelSpinStyle() )
{
case LABEL_SPIN_STYLE::LEFT: text_offset.x += getShadowWidth() / 2; break;
case LABEL_SPIN_STYLE::UP: text_offset.y += getShadowWidth() / 2; break;
case LABEL_SPIN_STYLE::RIGHT: text_offset.x -= getShadowWidth() / 2; break;
case LABEL_SPIN_STYLE::BOTTOM: text_offset.y -= getShadowWidth() / 2; break;
case LABEL_SPIN_STYLE::LEFT: text_offset.x += shadowWidth / 2.0; break;
case LABEL_SPIN_STYLE::UP: text_offset.y += shadowWidth / 2.0; break;
case LABEL_SPIN_STYLE::RIGHT: text_offset.x -= shadowWidth / 2.0; break;
case LABEL_SPIN_STYLE::BOTTOM: text_offset.y -= shadowWidth / 2.0; break;
}
}
@ -1538,11 +1613,8 @@ void SCH_PAINTER::draw( const SCH_FIELD *aField, int aLayer )
if( aField->IsVoid() )
return;
if( drawingShadows && aField->GetParent()->IsSelected()
&& !eeconfig()->m_Selection.draw_selected_children )
{
if( drawingShadows && !eeconfig()->m_Selection.draw_selected_children )
return;
}
bool underline = false;
@ -1581,16 +1653,16 @@ void SCH_PAINTER::draw( const SCH_FIELD *aField, int aLayer )
EDA_RECT bbox = aField->GetBoundingBox();
wxPoint textpos = bbox.Centre();
m_gal->SetStrokeColor( color );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getTextThickness( aField, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->SetIsFill( drawingShadows && eeconfig()->m_Selection.text_as_box );
m_gal->SetFillColor( color );
if( drawingShadows && eeconfig()->m_Selection.text_as_box )
{
m_gal->SetIsFill( true );
m_gal->SetFillColor( color );
m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 );
bbox.RevertYAxis();
m_gal->SetLineWidth( m_gal->GetLineWidth() / 2 );
m_gal->DrawRectangle( mapCoords( bbox.GetPosition() ), mapCoords( bbox.GetEnd() ) );
}
else
@ -1603,7 +1675,6 @@ void SCH_PAINTER::draw( const SCH_FIELD *aField, int aLayer )
m_gal->SetFontItalic( aField->IsItalic() );
m_gal->SetFontUnderlined( underline );
m_gal->SetTextMirrored( aField->IsMirrored() );
m_gal->SetLineWidth( getTextThickness( aField, drawingShadows ) );
strokeText( aField->GetShownText(), textpos, orient == TEXT_ANGLE_VERT ? M_PI / 2 : 0 );
}
@ -1624,38 +1695,36 @@ void SCH_PAINTER::draw( SCH_GLOBALLABEL *aLabel, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
if( !drawingShadows || aLabel->IsSelected() )
{
COLOR4D color = getRenderColor( aLabel, LAYER_GLOBLABEL, drawingShadows );
std::vector<wxPoint> pts;
std::deque<VECTOR2D> pts2;
aLabel->CreateGraphicShape( &m_schSettings, pts, aLabel->GetTextPos() );
for( const wxPoint& p : pts )
pts2.emplace_back( VECTOR2D( p.x, p.y ) );
// The text is drawn inside the graphic shape.
// On Cairo the graphic shape is filled by the background before drawing the text.
// However if the text is selected, it is draw twice: first on LAYER_SELECTION_SHADOWS
// and second on the text layer. The second must not erase the first drawing.
bool fillBg = ( ( aLayer == LAYER_SELECTION_SHADOWS ) || !aLabel->IsSelected() )
&& aLayer != LAYER_DANGLING;
m_gal->SetIsFill( fillBg );
m_gal->SetFillColor( m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ) );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getTextThickness( aLabel, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->DrawPolyline( pts2 );
draw( static_cast<SCH_TEXT*>( aLabel ), aLayer );
}
if( !drawingShadows || eeconfig()->m_Selection.draw_selected_children || !aLabel->IsSelected() )
{
if( !drawingShadows || eeconfig()->m_Selection.draw_selected_children )
draw( aLabel->GetIntersheetRefs(), aLayer );
}
if( drawingShadows && !( aLabel->IsBrightened() || aLabel->IsSelected() ) )
return;
COLOR4D color = getRenderColor( aLabel, LAYER_GLOBLABEL, drawingShadows );
std::vector<wxPoint> pts;
std::deque<VECTOR2D> pts2;
aLabel->CreateGraphicShape( &m_schSettings, pts, aLabel->GetTextPos() );
for( const wxPoint& p : pts )
pts2.emplace_back( VECTOR2D( p.x, p.y ) );
// The text is drawn inside the graphic shape.
// On Cairo the graphic shape is filled by the background before drawing the text.
// However if the text is selected, it is draw twice: first on LAYER_SELECTION_SHADOWS
// and second on the text layer. The second must not erase the first drawing.
bool fillBg = ( ( aLayer == LAYER_SELECTION_SHADOWS ) || !aLabel->IsSelected() )
&& aLayer != LAYER_DANGLING;
m_gal->SetIsFill( fillBg );
m_gal->SetFillColor( m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ) );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getTextThickness( aLabel, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->DrawPolyline( pts2 );
draw( static_cast<SCH_TEXT*>( aLabel ), aLayer );
}
@ -1833,7 +1902,7 @@ void SCH_PAINTER::draw( const SCH_BUS_ENTRY_BASE *aEntry, int aLayer )
else
{
line.SetLineColor( color );
line.SetLineStyle( aEntry->GetStrokeStyle() );
line.SetLineStyle( aEntry->GetLineStyle() );
draw( &line, aLayer );
}

View File

@ -47,6 +47,7 @@ class SCH_HIERLABEL;
class SCH_GLOBALLABEL;
class SCH_SHEET;
class SCH_SHEET_PIN;
class SCH_SHAPE;
class SCH_MARKER;
class SCH_NO_CONNECT;
class SCH_LINE;
@ -156,6 +157,7 @@ private:
void draw( SCH_SYMBOL* aSymbol, int aLayer );
void draw( const SCH_JUNCTION* aJct, int aLayer );
void draw( const SCH_FIELD* aField, int aLayer );
void draw( const SCH_SHAPE* shape, int aLayer );
void draw( const SCH_TEXT* aText, int aLayer );
void draw( SCH_HIERLABEL* aLabel, int aLayer );
void draw( SCH_GLOBALLABEL* aLabel, int aLayer );

View File

@ -1059,7 +1059,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map<wxString, wxString>& aProper
symbol ) );
}
line->SetWidth( elem.lineWidth );
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
}
else if( i + 3 == elem.points.size() )
{
@ -1078,7 +1078,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map<wxString, wxString>& aProper
symbol ) );
}
line->SetWidth( elem.lineWidth );
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
}
else
{
@ -1102,7 +1102,7 @@ void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map<wxString, wxString>& aProper
}
}
bezier->SetWidth( elem.lineWidth );
bezier->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
}
}
}
@ -1163,7 +1163,7 @@ void SCH_ALTIUM_PLUGIN::ParsePolyline( const std::map<wxString, wxString>& aProp
for( wxPoint& point : elem.points )
line->AddPoint( GetRelativePosition( point + m_sheetOffset, symbol ) );
line->SetWidth( elem.lineWidth );
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
}
}
@ -1224,7 +1224,7 @@ void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map<wxString, wxString>& aPrope
line->AddPoint( GetRelativePosition( elem.points.front() + m_sheetOffset, symbol ) );
line->SetWidth( elem.lineWidth );
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
if( !elem.isSolid )
line->SetFillMode( FILL_T::NO_FILL );
@ -1303,7 +1303,7 @@ void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map<wxString, wxString>&
rect->SetPosition( GetRelativePosition( elem.topRight + m_sheetOffset, symbol ) );
rect->SetEnd( GetRelativePosition( elem.bottomLeft + m_sheetOffset, symbol ) );
rect->SetWidth( elem.lineWidth );
rect->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
if( !elem.isSolid )
rect->SetFillMode( FILL_T::NO_FILL );
@ -1351,7 +1351,7 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map<wxString, wxString>& aPropertie
circle->SetPosition( GetRelativePosition( elem.center + m_sheetOffset, symbol ) );
circle->SetEnd( circle->GetPosition() + wxPoint( elem.radius, 0 ) );
circle->SetWidth( elem.lineWidth );
circle->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
}
else
{
@ -1371,7 +1371,7 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map<wxString, wxString>& aPropertie
arcEnd += arc->GetCenter();
arc->SetEnd( arcEnd );
arc->SetWidth( elem.lineWidth );
arc->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
}
}
}
@ -1417,7 +1417,7 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map<wxString, wxString>& aProperti
line->AddPoint( GetRelativePosition( elem.point1 + m_sheetOffset, symbol ) );
line->AddPoint( GetRelativePosition( elem.point2 + m_sheetOffset, symbol ) );
line->SetWidth( elem.lineWidth );
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
}
}
@ -1487,7 +1487,7 @@ void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map<wxString, wxString>& aPro
rect->SetPosition( GetRelativePosition( sheetTopRight, symbol ) );
rect->SetEnd( GetRelativePosition( sheetBottomLeft, symbol ) );
rect->SetWidth( elem.lineWidth );
rect->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
if( !elem.isSolid )
rect->SetFillMode( FILL_T::NO_FILL );
@ -1606,7 +1606,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line1 );
line1->SetWidth( Mils2iu( 10 ) );
line1->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line1->AddPoint( { 0, 0 } );
line1->AddPoint( { 0, Mils2iu( -50 ) } );
@ -1614,7 +1614,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* circle = new LIB_SHAPE( aKsymbol, SHAPE_T::CIRCLE );
aKsymbol->AddDrawItem( circle );
circle->SetWidth( Mils2iu( 5 ) );
circle->SetStroke( STROKE_PARAMS( Mils2iu( 5 ), PLOT_DASH_TYPE::SOLID ) );
circle->SetPosition( { Mils2iu( 0 ), Mils2iu( -75 ) } );
circle->SetEnd( circle->GetPosition() + wxPoint( Mils2iu( 25 ), 0 ) );
}
@ -1622,7 +1622,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line2 );
line2->SetWidth( Mils2iu( 10 ) );
line2->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line2->AddPoint( { Mils2iu( -25 ), Mils2iu( -50 ) } );
line2->AddPoint( { Mils2iu( 25 ), Mils2iu( -50 ) } );
line2->AddPoint( { Mils2iu( 0 ), Mils2iu( -100 ) } );
@ -1635,13 +1635,13 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line );
line->SetWidth( Mils2iu( 10 ) );
line->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line->AddPoint( { 0, 0 } );
line->AddPoint( { 0, Mils2iu( -72 ) } );
LIB_SHAPE* bezier = new LIB_SHAPE( aKsymbol, SHAPE_T::BEZIER );
aKsymbol->AddDrawItem( bezier );
bezier->SetWidth( Mils2iu( 5 ) );
bezier->SetStroke( STROKE_PARAMS( Mils2iu( 5 ), PLOT_DASH_TYPE::SOLID ) );
bezier->AddPoint( { Mils2iu( 30 ), Mils2iu( -50 ) } );
bezier->AddPoint( { Mils2iu( 30 ), Mils2iu( -87 ) } );
bezier->AddPoint( { Mils2iu( -30 ), Mils2iu( -63 ) } );
@ -1656,7 +1656,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line1 );
line1->SetWidth( Mils2iu( 10 ) );
line1->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line1->AddPoint( { 0, 0 } );
line1->AddPoint( { 0, Mils2iu( -100 ) } );
@ -1664,25 +1664,25 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line2 );
line2->SetWidth( Mils2iu( 10 ) );
line2->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -100 ) } );
line2->AddPoint( { Mils2iu( 100 ), Mils2iu( -100 ) } );
LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line3 );
line3->SetWidth( Mils2iu( 10 ) );
line3->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line3->AddPoint( { Mils2iu( -70 ), Mils2iu( -130 ) } );
line3->AddPoint( { Mils2iu( 70 ), Mils2iu( -130 ) } );
LIB_SHAPE* line4 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line4 );
line4->SetWidth( Mils2iu( 10 ) );
line4->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line4->AddPoint( { Mils2iu( -40 ), Mils2iu( -160 ) } );
line4->AddPoint( { Mils2iu( 40 ), Mils2iu( -160 ) } );
LIB_SHAPE* line5 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line5 );
line5->SetWidth( Mils2iu( 10 ) );
line5->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line5->AddPoint( { Mils2iu( -10 ), Mils2iu( -190 ) } );
line5->AddPoint( { Mils2iu( 10 ), Mils2iu( -190 ) } );
}
@ -1690,7 +1690,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line2 );
line2->SetWidth( Mils2iu( 10 ) );
line2->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -100 ) } );
line2->AddPoint( { Mils2iu( 100 ), Mils2iu( -100 ) } );
line2->AddPoint( { Mils2iu( 0 ), Mils2iu( -200 ) } );
@ -1700,7 +1700,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line2 );
line2->SetWidth( Mils2iu( 10 ) );
line2->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line2->AddPoint( { Mils2iu( -150 ), Mils2iu( -200 ) } );
line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -100 ) } );
line2->AddPoint( { Mils2iu( 100 ), Mils2iu( -100 ) } );
@ -1708,7 +1708,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line3 );
line3->SetWidth( Mils2iu( 10 ) );
line3->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line3->AddPoint( { Mils2iu( 0 ), Mils2iu( -100 ) } );
line3->AddPoint( { Mils2iu( -50 ), Mils2iu( -200 ) } );
}
@ -1716,7 +1716,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line2 );
line2->SetWidth( Mils2iu( 10 ) );
line2->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line2->AddPoint( { Mils2iu( -25 ), Mils2iu( -50 ) } );
line2->AddPoint( { Mils2iu( 0 ), Mils2iu( -100 ) } );
line2->AddPoint( { Mils2iu( 25 ), Mils2iu( -50 ) } );
@ -1731,25 +1731,25 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line1 );
line1->SetWidth( Mils2iu( 10 ) );
line1->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line1->AddPoint( { 0, 0 } );
line1->AddPoint( { 0, Mils2iu( -160 ) } );
LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line2 );
line2->SetWidth( Mils2iu( 10 ) );
line2->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -160 ) } );
line2->AddPoint( { Mils2iu( 100 ), Mils2iu( -160 ) } );
LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line3 );
line3->SetWidth( Mils2iu( 10 ) );
line3->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line3->AddPoint( { Mils2iu( -60 ), Mils2iu( -200 ) } );
line3->AddPoint( { Mils2iu( 60 ), Mils2iu( -200 ) } );
LIB_SHAPE* line4 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line4 );
line4->SetWidth( Mils2iu( 10 ) );
line4->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line4->AddPoint( { Mils2iu( -20 ), Mils2iu( -240 ) } );
line4->AddPoint( { Mils2iu( 20 ), Mils2iu( -240 ) } );
@ -1758,7 +1758,7 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
LIB_SHAPE* circle = new LIB_SHAPE( aKsymbol, SHAPE_T::CIRCLE );
aKsymbol->AddDrawItem( circle );
circle->SetWidth( Mils2iu( 10 ) );
circle->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
circle->SetPosition( { Mils2iu( 0 ), Mils2iu( -160 ) } );
circle->SetEnd( circle->GetPosition() + wxPoint( Mils2iu( 120 ), 0 ) );
@ -1768,13 +1768,13 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
{
LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line1 );
line1->SetWidth( Mils2iu( 10 ) );
line1->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line1->AddPoint( { 0, 0 } );
line1->AddPoint( { 0, Mils2iu( -200 ) } );
LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line2 );
line2->SetWidth( Mils2iu( 10 ) );
line2->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line2->AddPoint( { Mils2iu( -100 ), Mils2iu( -200 ) } );
line2->AddPoint( { Mils2iu( 100 ), Mils2iu( -200 ) } );
@ -1790,13 +1790,13 @@ wxPoint HelperGeneratePowerPortGraphics( LIB_SYMBOL* aKsymbol, ASCH_POWER_PORT_S
LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line1 );
line1->SetWidth( Mils2iu( 10 ) );
line1->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line1->AddPoint( { 0, 0 } );
line1->AddPoint( { 0, Mils2iu( -100 ) } );
LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
aKsymbol->AddDrawItem( line2 );
line2->SetWidth( Mils2iu( 10 ) );
line2->SetStroke( STROKE_PARAMS( Mils2iu( 10 ), PLOT_DASH_TYPE::SOLID ) );
line2->AddPoint( { Mils2iu( -50 ), Mils2iu( -100 ) } );
line2->AddPoint( { Mils2iu( 50 ), Mils2iu( -100 ) } );

View File

@ -1682,7 +1682,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadLibrarySymbolShapeVertices( const std::vect
}
shape->SetUnit( aGateNumber );
shape->SetWidth( aLineThickness );
shape->SetStroke( STROKE_PARAMS( aLineThickness, PLOT_DASH_TYPE::SOLID ) );
aSymbol->AddDrawItem( shape );
prev = cur;

View File

@ -33,11 +33,11 @@
#include <wx/tokenzr.h>
#include <wx/wfstream.h>
#include <wx/xml/xml.h>
#include <wx/msgdlg.h>
#include <symbol_library.h>
#include <plugins/eagle/eagle_parser.h>
#include <string_utils.h>
#include <gr_text.h>
#include <lib_shape.h>
#include <lib_id.h>
#include <lib_item.h>
@ -1755,7 +1755,7 @@ LIB_SHAPE* SCH_EAGLE_PLUGIN::loadSymbolCircle( std::unique_ptr<LIB_SYMBOL>& aSym
circle->SetPosition( center );
circle->SetEnd( wxPoint( center.x + c.radius.ToSchUnits(), center.y ) );
circle->SetWidth( c.width.ToSchUnits() );
circle->SetStroke( STROKE_PARAMS( c.width.ToSchUnits(), PLOT_DASH_TYPE::SOLID ) );
circle->SetUnit( aGateNumber );
return circle;
@ -1823,12 +1823,12 @@ LIB_ITEM* SCH_EAGLE_PLUGIN::loadSymbolWire( std::unique_ptr<LIB_SYMBOL>& aSymbol
+ ( ( center.y - begin.y ) * ( center.y - begin.y ) ) ) )
* 2;
arc->SetWidth( 1 );
arc->SetStroke( STROKE_PARAMS( 1, PLOT_DASH_TYPE::SOLID ) );
arc->SetFillMode( FILL_T::FILLED_SHAPE );
}
else
{
arc->SetWidth( ewire.width.ToSchUnits() );
arc->SetStroke( STROKE_PARAMS( ewire.width.ToSchUnits(), PLOT_DASH_TYPE::SOLID ) );
}
arc->SetArcGeometry( begin, (wxPoint) CalcArcMid( begin, end, center ), end );
@ -1843,7 +1843,7 @@ LIB_ITEM* SCH_EAGLE_PLUGIN::loadSymbolWire( std::unique_ptr<LIB_SYMBOL>& aSymbol
poly->AddPoint( begin );
poly->AddPoint( end );
poly->SetUnit( aGateNumber );
poly->SetWidth( ewire.width.ToSchUnits() );
poly->SetStroke( STROKE_PARAMS( ewire.width.ToSchUnits(), PLOT_DASH_TYPE::SOLID ) );
return poly;
}

View File

@ -52,7 +52,7 @@
#include <template_fieldnames.h>
#include <trigo.h>
#include <progress_reporter.h>
#include <sch_shape.h>
using namespace TSCHEMATIC_T;
@ -489,67 +489,11 @@ int SCH_SEXPR_PARSER::parseInternalUnits( const char* aExpected )
void SCH_SEXPR_PARSER::parseStroke( STROKE_PARAMS& aStroke )
{
wxCHECK_RET( CurTok() == T_stroke,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a stroke." ) );
STROKE_PARAMS_PARSER strokeParser( reader, IU_PER_MM );
strokeParser.SyncLineReaderWith( *this );
aStroke.SetWidth( Mils2iu( DEFAULT_LINE_WIDTH_MILS ) );
aStroke.SetPlotStyle( PLOT_DASH_TYPE::DEFAULT );
aStroke.SetColor( COLOR4D::UNSPECIFIED );
T token;
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_width:
aStroke.SetWidth( parseInternalUnits( "stroke width" ) );
NeedRIGHT();
break;
case T_type:
{
token = NextTok();
switch( token )
{
case T_dash: aStroke.SetPlotStyle( PLOT_DASH_TYPE::DASH ); break;
case T_dot: aStroke.SetPlotStyle( PLOT_DASH_TYPE::DOT ); break;
case T_dash_dot: aStroke.SetPlotStyle( PLOT_DASH_TYPE::DASHDOT ); break;
case T_solid: aStroke.SetPlotStyle( PLOT_DASH_TYPE::SOLID ); break;
case T_default: aStroke.SetPlotStyle( PLOT_DASH_TYPE::DEFAULT ); break;
default:
Expecting( "solid, dash, dash_dot, dot or default" );
}
NeedRIGHT();
break;
}
case T_color:
{
COLOR4D color;
color.r = parseInt( "red" ) / 255.0;
color.g = parseInt( "green" ) / 255.0;
color.b = parseInt( "blue" ) / 255.0;
color.a = Clamp( parseDouble( "alpha" ), 0.0, 1.0 );
aStroke.SetColor( color );
NeedRIGHT();
break;
}
default:
Expecting( "width, type, or color" );
}
}
strokeParser.ParseStroke( aStroke );
SyncLineReaderWith( strokeParser );
}
@ -580,7 +524,8 @@ void SCH_SEXPR_PARSER::parseFill( FILL_PARAMS& aFill )
case T_none: aFill.m_FillType = FILL_T::NO_FILL; break;
case T_outline: aFill.m_FillType = FILL_T::FILLED_SHAPE; break;
case T_background: aFill.m_FillType = FILL_T::FILLED_WITH_BG_BODYCOLOR; break;
default: Expecting( "none, outline, or background" );
case T_color: aFill.m_FillType = FILL_T::FILLED_WITH_COLOR; break;
default: Expecting( "none, outline, color or background" );
}
NeedRIGHT();
@ -1008,7 +953,7 @@ LIB_SHAPE* SCH_SEXPR_PARSER::parseArc()
case T_stroke:
parseStroke( stroke );
arc->SetWidth( stroke.GetWidth() );
arc->SetStroke( stroke );
break;
case T_fill:
@ -1107,7 +1052,7 @@ LIB_SHAPE* SCH_SEXPR_PARSER::parseBezier()
case T_stroke:
parseStroke( stroke );
bezier->SetWidth( stroke.GetWidth() );
bezier->SetStroke( stroke );
break;
case T_fill:
@ -1163,7 +1108,7 @@ LIB_SHAPE* SCH_SEXPR_PARSER::parseCircle()
case T_stroke:
parseStroke( stroke );
circle->SetWidth( stroke.GetWidth() );
circle->SetStroke( stroke );
break;
case T_fill:
@ -1435,7 +1380,7 @@ LIB_SHAPE* SCH_SEXPR_PARSER::parsePolyLine()
case T_stroke:
parseStroke( stroke );
poly->SetWidth( stroke.GetWidth() );
poly->SetStroke( stroke );
break;
case T_fill:
@ -1486,7 +1431,7 @@ LIB_SHAPE* SCH_SEXPR_PARSER::parseRectangle()
case T_stroke:
parseStroke( stroke );
rectangle->SetWidth( stroke.GetWidth() );
rectangle->SetStroke( stroke );
break;
case T_fill:
@ -2170,6 +2115,22 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyableOnly,
screen->Append( static_cast<SCH_ITEM*>( parseLine() ) );
break;
case T_arc:
screen->Append( static_cast<SCH_ITEM*>( parseSchArc() ) );
break;
case T_circle:
screen->Append( static_cast<SCH_ITEM*>( parseSchCircle() ) );
break;
case T_rectangle:
screen->Append( static_cast<SCH_ITEM*>( parseSchRectangle() ) );
break;
case T_bezier:
screen->Append( static_cast<SCH_ITEM*>( parseSchBezier() ) );
break;
case T_text:
case T_label:
case T_global_label:
@ -2837,6 +2798,320 @@ SCH_LINE* SCH_SEXPR_PARSER::parseLine()
}
SCH_SHAPE* SCH_SEXPR_PARSER::parseSchArc()
{
wxCHECK_MSG( CurTok() == T_arc, nullptr,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as an arc." ) );
T token;
wxPoint startPoint;
wxPoint midPoint;
wxPoint endPoint;
wxPoint pos;
int startAngle;
int endAngle;
STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT );
FILL_PARAMS fill;
bool hasMidPoint = false;
bool hasAngles = false;
std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_start:
startPoint = parseXY();
NeedRIGHT();
break;
case T_mid:
midPoint = parseXY();
NeedRIGHT();
hasMidPoint = true;
break;
case T_end:
endPoint = parseXY();
NeedRIGHT();
break;
case T_radius:
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_at:
pos = parseXY();
NeedRIGHT();
break;
case T_length:
parseInternalUnits( "radius length" );
NeedRIGHT();
break;
case T_angles:
{
startAngle = KiROUND( parseDouble( "start radius angle" ) * 10.0 );
endAngle = KiROUND( parseDouble( "end radius angle" ) * 10.0 );
NORMALIZE_ANGLE_POS( startAngle );
NORMALIZE_ANGLE_POS( endAngle );
NeedRIGHT();
hasAngles = true;
break;
}
default:
Expecting( "at, length, or angle" );
}
}
break;
case T_stroke:
parseStroke( stroke );
arc->SetStroke( stroke );
break;
case T_fill:
parseFill( fill );
arc->SetFillMode( fill.m_FillType );
arc->SetFillColor( fill.m_Color );
break;
case T_uuid:
NeedSYMBOL();
const_cast<KIID&>( arc->m_Uuid ) = KIID( FromUTF8() );
NeedRIGHT();
break;
default:
Expecting( "start, mid, end, radius, stroke, fill or uuid" );
}
}
arc->SetStart( startPoint );
arc->SetEnd( endPoint );
if( hasMidPoint )
{
VECTOR2I center = CalcArcCenter( arc->GetStart(), midPoint, arc->GetEnd() );
arc->SetCenter( (wxPoint) center );
}
else if( hasAngles )
{
arc->SetCenter( pos );
/**
* This accounts for an oddity in the old library format, where the symbol is overdefined.
* The previous draw (based on wxwidgets) used start point and end point and always drew
* counter-clockwise. The new GAL draw takes center, radius and start/end angles. All of
* these points were stored in the file, so we need to mimic the swapping of start/end
* points rather than using the stored angles in order to properly map edge cases.
*/
if( !TRANSFORM().MapAngles( &startAngle, &endAngle ) )
{
wxPoint temp = arc->GetStart();
arc->SetStart( arc->GetEnd() );
arc->SetEnd( temp );
}
}
else
wxFAIL_MSG( "Setting arc without either midpoint or angles not implemented." );
return arc.release();
}
SCH_SHAPE* SCH_SEXPR_PARSER::parseSchCircle()
{
wxCHECK_MSG( CurTok() == T_circle, nullptr,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a circle." ) );
T token;
wxPoint center;
int radius;
STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT );
FILL_PARAMS fill;
std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_center:
center = parseXY();
NeedRIGHT();
break;
case T_radius:
radius = parseInternalUnits( "radius length" );
NeedRIGHT();
break;
case T_stroke:
parseStroke( stroke );
circle->SetStroke( stroke );
break;
case T_fill:
parseFill( fill );
circle->SetFillMode( fill.m_FillType );
circle->SetFillColor( fill.m_Color );
break;
case T_uuid:
NeedSYMBOL();
const_cast<KIID&>( circle->m_Uuid ) = KIID( FromUTF8() );
NeedRIGHT();
break;
default:
Expecting( "center, radius, stroke, fill or uuid" );
}
}
circle->SetCenter( center );
circle->SetEnd( wxPoint( center.x + radius, center.y ) );
return circle.release();
}
SCH_SHAPE* SCH_SEXPR_PARSER::parseSchRectangle()
{
wxCHECK_MSG( CurTok() == T_rectangle, nullptr,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a rectangle." ) );
T token;
STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT );
FILL_PARAMS fill;
std::unique_ptr<SCH_SHAPE> rectangle = std::make_unique<SCH_SHAPE>( SHAPE_T::RECT );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_start:
rectangle->SetPosition( parseXY() );
NeedRIGHT();
break;
case T_end:
rectangle->SetEnd( parseXY() );
NeedRIGHT();
break;
case T_stroke:
parseStroke( stroke );
rectangle->SetStroke( stroke );
break;
case T_fill:
parseFill( fill );
rectangle->SetFillMode( fill.m_FillType );
rectangle->SetFillColor( fill.m_Color );
break;
case T_uuid:
NeedSYMBOL();
const_cast<KIID&>( rectangle->m_Uuid ) = KIID( FromUTF8() );
NeedRIGHT();
break;
default:
Expecting( "start, end, stroke, fill or uuid" );
}
}
return rectangle.release();
}
SCH_SHAPE* SCH_SEXPR_PARSER::parseSchBezier()
{
wxCHECK_MSG( CurTok() == T_bezier, nullptr,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a bezier." ) );
T token;
STROKE_PARAMS stroke( Mils2iu( DEFAULT_LINE_WIDTH_MILS ), PLOT_DASH_TYPE::DEFAULT );
FILL_PARAMS fill;
std::unique_ptr<SCH_SHAPE> bezier = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER );
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
switch( token )
{
case T_pts:
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token != T_LEFT )
Expecting( T_LEFT );
token = NextTok();
if( token != T_xy )
Expecting( "xy" );
bezier->AddPoint( parseXY() );
NeedRIGHT();
}
break;
case T_stroke:
parseStroke( stroke );
bezier->SetStroke( stroke );
break;
case T_fill:
parseFill( fill );
bezier->SetFillMode( fill.m_FillType );
bezier->SetFillColor( fill.m_Color );
break;
case T_uuid:
NeedSYMBOL();
const_cast<KIID&>( bezier->m_Uuid ) = KIID( FromUTF8() );
NeedRIGHT();
break;
default:
Expecting( "pts, stroke, fill or uuid" );
}
}
return bezier.release();
}
SCH_TEXT* SCH_SEXPR_PARSER::parseSchText()
{
T token;

View File

@ -49,6 +49,7 @@ class SCH_BITMAP;
class SCH_BUS_WIRE_ENTRY;
class SCH_SYMBOL;
class SCH_FIELD;
class SCH_SHAPE;
class SCH_JUNCTION;
class SCH_LINE;
class SCH_NO_CONNECT;
@ -188,6 +189,10 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER
SCH_NO_CONNECT* parseNoConnect();
SCH_BUS_WIRE_ENTRY* parseBusEntry();
SCH_LINE* parseLine();
SCH_SHAPE* parseSchArc();
SCH_SHAPE* parseSchCircle();
SCH_SHAPE* parseSchRectangle();
SCH_SHAPE* parseSchBezier();
SCH_TEXT* parseSchText();
void parseBusAlias( SCH_SCREEN* aScreen );

View File

@ -37,6 +37,7 @@
#include <sch_edit_frame.h> // SYMBOL_ORIENTATION_T
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_shape.h>
#include <sch_no_connect.h>
#include <sch_text.h>
#include <sch_sheet.h>
@ -59,7 +60,6 @@
#include <wx_filename.h> // for ::ResolvePossibleSymlinks()
#include <progress_reporter.h>
using namespace TSCHEMATIC_T;
@ -80,13 +80,26 @@ static void formatFill( OUTPUTFORMATTER* aFormatter, int aNestLevel, FILL_T aFil
switch( aFillMode )
{
default:
case FILL_T::NO_FILL: fillType = "none"; break;
case FILL_T::FILLED_SHAPE: fillType = "outline"; break;
case FILL_T::FILLED_WITH_BG_BODYCOLOR: fillType = "background"; break;
case FILL_T::FILLED_WITH_COLOR: fillType = "color"; break;
}
aFormatter->Print( aNestLevel, "(fill (type %s))", fillType );
if( aFillMode == FILL_T::FILLED_WITH_COLOR )
{
aFormatter->Print( aNestLevel, "(fill (type %s) (color %d %d %d %s))",
fillType,
KiROUND( aFillColor.r * 255.0 ),
KiROUND( aFillColor.g * 255.0 ),
KiROUND( aFillColor.b * 255.0 ),
Double2Str( aFillColor.a ).c_str() );
}
else
{
aFormatter->Print( aNestLevel, "(fill (type %s))",
fillType );
}
}
@ -222,23 +235,6 @@ static double getSheetPinAngle( SHEET_SIDE aSide )
}
static wxString getLineStyleToken( PLOT_DASH_TYPE aStyle )
{
wxString token;
switch( aStyle )
{
case PLOT_DASH_TYPE::DASH: token = "dash"; break;
case PLOT_DASH_TYPE::DOT: token = "dot"; break;
case PLOT_DASH_TYPE::DASHDOT: token = "dash_dot"; break;
case PLOT_DASH_TYPE::SOLID: token = "solid"; break;
case PLOT_DASH_TYPE::DEFAULT: token = "default"; break;
}
return token;
}
static const char* getTextTypeToken( KICAD_T aType )
{
switch( aType )
@ -252,28 +248,6 @@ static const char* getTextTypeToken( KICAD_T aType )
}
/**
* Write stroke definition to \a aFormatter.
*
* @param aFormatter A pointer to the #OUTPUTFORMATTER object to write to.
* @param aNestLevel The nest level to indent the stroke definition.
* @param aStroke The stroke width, line-style and color.
*/
static void formatStroke( OUTPUTFORMATTER* aFormatter, int aNestLevel,
const STROKE_PARAMS& aStroke )
{
wxASSERT( aFormatter != nullptr );
aFormatter->Print( aNestLevel, "(stroke (width %s) (type %s) (color %d %d %d %s))",
FormatInternalUnits( aStroke.GetWidth() ).c_str(),
TO_UTF8( getLineStyleToken( aStroke.GetPlotStyle() ) ),
KiROUND( aStroke.GetColor().r * 255.0 ),
KiROUND( aStroke.GetColor().g * 255.0 ),
KiROUND( aStroke.GetColor().b * 255.0 ),
Double2Str( aStroke.GetColor().a ).c_str() );
}
static void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc, int x1, int x2,
const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor,
KIID aUuid = niluuid )
@ -289,7 +263,7 @@ static void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* a
FormatInternalUnits( aArc->GetArcMid() ).c_str(),
FormatInternalUnits( aArc->GetEnd() ).c_str() );
formatStroke( aFormatter, aNestLevel + 1, aStroke );
aStroke.Format( aFormatter, aNestLevel + 1 );
aFormatter->Print( 0, "\n" );
formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
aFormatter->Print( 0, "\n" );
@ -310,7 +284,7 @@ static void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE
FormatInternalUnits( aCircle->GetStart().y ).c_str(),
FormatInternalUnits( aCircle->GetRadius() ).c_str() );
formatStroke( aFormatter, aNestLevel + 1, aStroke );
aStroke.Format( aFormatter, aNestLevel + 1 );
aFormatter->Print( 0, "\n" );
formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
aFormatter->Print( 0, "\n" );
@ -331,7 +305,7 @@ static void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE*
FormatInternalUnits( aRect->GetStart().y ).c_str(),
FormatInternalUnits( aRect->GetEnd().x ).c_str(),
FormatInternalUnits( aRect->GetEnd().y ).c_str() );
formatStroke( aFormatter, aNestLevel + 1, aStroke );
aStroke.Format( aFormatter, aNestLevel + 1 );
aFormatter->Print( 0, "\n" );
formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
aFormatter->Print( 0, "\n" );
@ -359,7 +333,7 @@ static void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE
aFormatter->Print( 0, ")\n" ); // Closes pts token on same line.
formatStroke( aFormatter, aNestLevel + 1, aStroke );
aStroke.Format( aFormatter, aNestLevel + 1 );
aFormatter->Print( 0, "\n" );
formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
aFormatter->Print( 0, "\n" );
@ -411,7 +385,7 @@ static void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE*
aFormatter->Print( aNestLevel + 1, ")\n" ); // Closes pts token with multiple lines.
}
formatStroke( aFormatter, aNestLevel + 1, aStroke );
aStroke.Format( aFormatter, aNestLevel + 1 );
aFormatter->Print( 0, "\n" );
formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
aFormatter->Print( 0, "\n" );
@ -840,6 +814,10 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet )
saveLine( static_cast<SCH_LINE*>( item ), 1 );
break;
case SCH_SHAPE_T:
saveShape( static_cast<SCH_SHAPE*>( item ), 1 );
break;
case SCH_TEXT_T:
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
@ -981,6 +959,10 @@ void SCH_SEXPR_PLUGIN::Format( EE_SELECTION* aSelection, SCH_SHEET_PATH* aSelect
saveLine( static_cast< SCH_LINE* >( item ), 0 );
break;
case SCH_SHAPE_T:
saveShape( static_cast<SCH_SHAPE*>( item ), 0 );
break;
case SCH_TEXT_T:
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
@ -1252,7 +1234,7 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel )
aSheet->GetBorderColor() );
stroke.SetWidth( aSheet->GetBorderWidth() );
formatStroke( m_out, aNestLevel + 1, stroke );
stroke.Format( m_out, aNestLevel + 1 );
m_out->Print( 0, "\n" );
@ -1341,7 +1323,7 @@ void SCH_SEXPR_PLUGIN::saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry, int aNestLev
FormatInternalUnits( aBusEntry->GetSize().GetWidth() ).c_str(),
FormatInternalUnits( aBusEntry->GetSize().GetHeight() ).c_str() );
formatStroke( m_out, aNestLevel + 1, aBusEntry->GetStroke() );
aBusEntry->GetStroke().Format( m_out, aNestLevel + 1 );
m_out->Print( 0, "\n" );
@ -1352,6 +1334,50 @@ void SCH_SEXPR_PLUGIN::saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry, int aNestLev
}
void SCH_SEXPR_PLUGIN::saveShape( SCH_SHAPE* aShape, int aNestLevel )
{
wxCHECK_RET( aShape != nullptr && m_out != nullptr, "" );
wxString lineType;
switch( aShape->GetShape() )
{
case SHAPE_T::ARC:
int x1;
int x2;
aShape->CalcArcAngles( x1, x2 );
formatArc( m_out, aNestLevel, aShape, x1, x2, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid );
break;
case SHAPE_T::CIRCLE:
formatCircle( m_out, aNestLevel, aShape, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid );
break;
case SHAPE_T::RECT:
formatRect( m_out, aNestLevel, aShape, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid );
break;
case SHAPE_T::BEZIER:
formatBezier( m_out, aNestLevel, aShape, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid );
break;
case SHAPE_T::POLY:
formatPoly( m_out, aNestLevel, aShape, aShape->GetStroke(), aShape->GetFillMode(),
aShape->GetFillColor(), aShape->m_Uuid );
break;
default:
UNIMPLEMENTED_FOR( aShape->SHAPE_T_asString() );
}
}
void SCH_SEXPR_PLUGIN::saveLine( SCH_LINE* aLine, int aNestLevel )
{
wxCHECK_RET( aLine != nullptr && m_out != nullptr, "" );
@ -1364,8 +1390,9 @@ void SCH_SEXPR_PLUGIN::saveLine( SCH_LINE* aLine, int aNestLevel )
{
case LAYER_BUS: lineType = "bus"; break;
case LAYER_WIRE: lineType = "wire"; break;
case LAYER_NOTES:
default: lineType = "polyline"; break;
case LAYER_NOTES: lineType = "polyline"; break;
default:
UNIMPLEMENTED_FOR( LayerName( aLine->GetLayer() ) );
}
m_out->Print( aNestLevel, "(%s (pts (xy %s %s) (xy %s %s))\n",
@ -1375,7 +1402,7 @@ void SCH_SEXPR_PLUGIN::saveLine( SCH_LINE* aLine, int aNestLevel )
FormatInternalUnits( aLine->GetEndPoint().x ).c_str(),
FormatInternalUnits( aLine->GetEndPoint().y ).c_str() );
formatStroke( m_out, aNestLevel + 1, line_stroke );
line_stroke.Format( m_out, aNestLevel + 1 );
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aLine->m_Uuid.AsString() ) );
@ -1934,7 +1961,7 @@ void SCH_SEXPR_PLUGIN_CACHE::saveSymbolDrawItem( LIB_ITEM* aItem, OUTPUTFORMATTE
{
LIB_SHAPE* shape = static_cast<LIB_SHAPE*>( aItem );
STROKE_PARAMS stroke;
FILL_T fillMode = shape->GetFillType();
FILL_T fillMode = shape->GetFillMode();
stroke.SetWidth( shape->GetWidth() );

View File

@ -39,6 +39,7 @@ class SCH_BITMAP;
class SCH_JUNCTION;
class SCH_NO_CONNECT;
class SCH_LINE;
class SCH_SHAPE;
class SCH_BUS_ENTRY_BASE;
class SCH_TEXT;
class SCH_SYMBOL;
@ -148,6 +149,7 @@ private:
void saveNoConnect( SCH_NO_CONNECT* aNoConnect, int aNestLevel );
void saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry, int aNestLevel );
void saveLine( SCH_LINE* aLine, int aNestLevel );
void saveShape( SCH_SHAPE* aShape, int aNestLevel );
void saveText( SCH_TEXT* aText, int aNestLevel );
void saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias, int aNestLevel );
void saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheets,

View File

@ -41,6 +41,7 @@
#include <trigo.h>
#include <progress_reporter.h>
#include <general.h>
#include <gr_text.h>
#include <sch_bitmap.h>
#include <sch_bus_entry.h>
#include <sch_symbol.h>
@ -3286,7 +3287,8 @@ LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr<LIB_SYMBOL>& aSymbo
arc->SetUnit( parseInt( aReader, line, &line ) );
arc->SetConvert( parseInt( aReader, line, &line ) );
arc->SetWidth( Mils2Iu( parseInt( aReader, line, &line ) ) );
arc->SetStroke( STROKE_PARAMS( Mils2Iu( parseInt( aReader, line, &line ) ),
PLOT_DASH_TYPE::SOLID ) );
// Old libraries (version <= 2.2) do not have always this FILL MODE param
// when fill mode is no fill (default mode).
@ -3359,7 +3361,8 @@ LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadCircle( std::unique_ptr<LIB_SYMBOL>& aSy
circle->SetEnd( wxPoint( center.x + radius, center.y ) );
circle->SetUnit( parseInt( aReader, line, &line ) );
circle->SetConvert( parseInt( aReader, line, &line ) );
circle->SetWidth( Mils2Iu( parseInt( aReader, line, &line ) ) );
circle->SetStroke( STROKE_PARAMS( Mils2Iu( parseInt( aReader, line, &line ) ),
PLOT_DASH_TYPE::SOLID ) );
if( *line != 0 )
circle->SetFillMode( parseFillMode( aReader, line, &line ) );
@ -3488,7 +3491,8 @@ LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadRect( std::unique_ptr<LIB_SYMBOL>& aSymb
rectangle->SetUnit( parseInt( aReader, line, &line ) );
rectangle->SetConvert( parseInt( aReader, line, &line ) );
rectangle->SetWidth( Mils2Iu( parseInt( aReader, line, &line ) ) );
rectangle->SetStroke( STROKE_PARAMS( Mils2Iu( parseInt( aReader, line, &line ) ),
PLOT_DASH_TYPE::SOLID ) );
if( *line != 0 )
rectangle->SetFillMode( parseFillMode( aReader, line, &line ) );
@ -3708,7 +3712,8 @@ LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr<LIB_SYMBOL>& a
int points = parseInt( aReader, line, &line );
polyLine->SetUnit( parseInt( aReader, line, &line ) );
polyLine->SetConvert( parseInt( aReader, line, &line ) );
polyLine->SetWidth( Mils2Iu( parseInt( aReader, line, &line ) ) );
polyLine->SetStroke( STROKE_PARAMS( Mils2Iu( parseInt( aReader, line, &line ) ),
PLOT_DASH_TYPE::SOLID ) );
wxPoint pt;
@ -3741,7 +3746,8 @@ LIB_SHAPE* SCH_LEGACY_PLUGIN_CACHE::loadBezier( std::unique_ptr<LIB_SYMBOL>& aSy
bezier->SetUnit( parseInt( aReader, line, &line ) );
bezier->SetConvert( parseInt( aReader, line, &line ) );
bezier->SetWidth( Mils2Iu( parseInt( aReader, line, &line ) ) );
bezier->SetStroke( STROKE_PARAMS( Mils2Iu( parseInt( aReader, line, &line ) ),
PLOT_DASH_TYPE::SOLID ) );
bezier->SetStart( wxPoint( Mils2Iu( parseInt( aReader, line, &line ) ),
Mils2Iu( parseInt( aReader, line, &line ) ) ) );
@ -4002,7 +4008,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveArc( LIB_SHAPE* aArc, OUTPUTFORMATTER& aFormat
aArc->GetUnit(),
aArc->GetConvert(),
Iu2Mils( aArc->GetWidth() ),
fill_tab[ static_cast<int>( aArc->GetFillType() ) - 1 ],
fill_tab[ static_cast<int>( aArc->GetFillMode() ) - 1 ],
Iu2Mils( aArc->GetStart().x ),
Iu2Mils( aArc->GetStart().y ),
Iu2Mils( aArc->GetEnd().x ),
@ -4023,7 +4029,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveBezier( LIB_SHAPE* aBezier, OUTPUTFORMATTER& a
for( const wxPoint& pt : aBezier->GetBezierPoints() )
aFormatter.Print( 0, " %d %d", Iu2Mils( pt.x ), Iu2Mils( pt.y ) );
aFormatter.Print( 0, " %c\n", fill_tab[ static_cast<int>( aBezier->GetFillType() ) - 1 ] );
aFormatter.Print( 0, " %c\n", fill_tab[ static_cast<int>( aBezier->GetFillMode() ) - 1 ] );
}
@ -4038,7 +4044,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveCircle( LIB_SHAPE* aCircle, OUTPUTFORMATTER& a
aCircle->GetUnit(),
aCircle->GetConvert(),
Iu2Mils( aCircle->GetWidth() ),
fill_tab[ static_cast<int>( aCircle->GetFillType() ) - 1 ] );
fill_tab[ static_cast<int>( aCircle->GetFillMode() ) - 1 ] );
}
@ -4168,7 +4174,7 @@ void SCH_LEGACY_PLUGIN_CACHE::savePolyLine( LIB_SHAPE* aPolyLine, OUTPUTFORMATTE
for( const VECTOR2I& pt : aPolyLine->GetPolyShape().Outline( 0 ).CPoints() )
aFormatter.Print( 0, " %d %d", Iu2Mils( pt.x ), Iu2Mils( pt.y ) );
aFormatter.Print( 0, " %c\n", fill_tab[ static_cast<int>( aPolyLine->GetFillType() ) - 1 ] );
aFormatter.Print( 0, " %c\n", fill_tab[ static_cast<int>( aPolyLine->GetFillMode() ) - 1 ] );
}
@ -4184,7 +4190,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveRectangle( LIB_SHAPE* aRectangle, OUTPUTFORMAT
aRectangle->GetUnit(),
aRectangle->GetConvert(),
Iu2Mils( aRectangle->GetWidth() ),
fill_tab[ static_cast<int>( aRectangle->GetFillType() ) - 1 ] );
fill_tab[ static_cast<int>( aRectangle->GetFillMode() ) - 1 ] );
}

422
eeschema/sch_shape.cpp Normal file
View File

@ -0,0 +1,422 @@
/*
* 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) 2004-2021 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 <sch_draw_panel.h>
#include <macros.h>
#include <plotters/plotter.h>
#include <base_units.h>
#include <widgets/msgpanel.h>
#include <bitmaps.h>
#include <eda_draw_frame.h>
#include <general.h>
#include <sch_shape.h>
SCH_SHAPE::SCH_SHAPE( SHAPE_T aShape, int aLineWidth, FILL_T aFillType ) :
SCH_ITEM( nullptr, SCH_SHAPE_T ),
EDA_SHAPE( aShape, aLineWidth, aFillType, true )
{
SetLayer( LAYER_NOTES );
}
EDA_ITEM* SCH_SHAPE::Clone() const
{
return new SCH_SHAPE( *this );
}
void SCH_SHAPE::SetStroke( const STROKE_PARAMS& aStroke )
{
m_stroke = aStroke;
}
void SCH_SHAPE::Move( const wxPoint& aOffset )
{
move( aOffset );
}
void SCH_SHAPE::MirrorHorizontally( int aCenter )
{
flip( wxPoint( aCenter, 0 ), true );
}
void SCH_SHAPE::MirrorVertically( int aCenter )
{
flip( wxPoint( 0, aCenter ), false );
}
void SCH_SHAPE::Rotate( const wxPoint& aCenter )
{
rotate( aCenter, 900 );
}
void SCH_SHAPE::Plot( PLOTTER* aPlotter ) const
{
int pen_size = std::max( GetPenWidth(), aPlotter->RenderSettings()->GetMinPenWidth() );
wxPoint center;
int radius;
int startAngle;
int endAngle;
static std::vector<wxPoint> cornerList;
if( GetShape() == SHAPE_T::POLY )
{
cornerList.clear();
for( const VECTOR2I& pt : m_poly.Outline( 0 ).CPoints() )
cornerList.push_back( (wxPoint) pt );
}
else if( GetShape() == SHAPE_T::ARC )
{
center = getCenter();
radius = GetRadius();
CalcArcAngles( startAngle, endAngle );
}
if( GetStroke().GetColor() == COLOR4D::UNSPECIFIED )
aPlotter->SetColor( aPlotter->RenderSettings()->GetLayerColor( LAYER_NOTES ) );
else
aPlotter->SetColor( GetStroke().GetColor() );
aPlotter->SetCurrentLineWidth( pen_size );
aPlotter->SetDash( GetStroke().GetPlotStyle() );
switch( GetShape() )
{
case SHAPE_T::ARC:
// TODO: doesn't work for dash styles
aPlotter->Arc( center, -endAngle, -startAngle, radius, FILL_T::NO_FILL, pen_size );
break;
case SHAPE_T::CIRCLE:
// TODO: doesn't work for dash styles
aPlotter->Circle( GetStart(), GetRadius() * 2, FILL_T::NO_FILL, pen_size );
break;
case SHAPE_T::RECT:
{
std::vector<wxPoint> pts = GetRectCorners();
aPlotter->MoveTo( pts[0] );
aPlotter->LineTo( pts[1] );
aPlotter->LineTo( pts[2] );
aPlotter->LineTo( pts[3] );
aPlotter->FinishTo( pts[0] );
}
break;
case SHAPE_T::POLY:
{
aPlotter->MoveTo( cornerList[0] );
for( size_t ii = 1; ii < cornerList.size(); ++ii )
aPlotter->LineTo( cornerList[ii] );
aPlotter->FinishTo( cornerList[0] );
}
break;
case SHAPE_T::BEZIER:
// TODO: doesn't work for dash styles
aPlotter->PlotPoly( m_bezierPoints, FILL_T::NO_FILL, pen_size );
break;
default:
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
}
aPlotter->SetDash( PLOT_DASH_TYPE::SOLID );
if( m_fill == FILL_T::FILLED_WITH_COLOR && GetFillColor() != COLOR4D::UNSPECIFIED )
{
aPlotter->SetColor( GetFillColor() );
switch( GetShape() )
{
case SHAPE_T::ARC:
aPlotter->Arc( center, -endAngle, -startAngle, radius, m_fill, 0 );
break;
case SHAPE_T::CIRCLE:
aPlotter->Circle( GetStart(), GetRadius() * 2, m_fill, 0 );
break;
case SHAPE_T::RECT:
aPlotter->Rect( GetStart(), GetEnd(), m_fill, 0 );
break;
case SHAPE_T::POLY:
aPlotter->PlotPoly( cornerList, m_fill, 0 );
break;
case SHAPE_T::BEZIER:
aPlotter->PlotPoly( m_bezierPoints, m_fill, 0 );
break;
default:
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
}
}
}
int SCH_SHAPE::GetPenWidth() const
{
// Historically 0 meant "default width" and negative numbers meant "don't stroke".
if( GetWidth() < 0 && GetFillMode() != FILL_T::NO_FILL )
return 0;
else
return std::max( GetWidth(), 1 );
}
void SCH_SHAPE::Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
{
int penWidth = GetPenWidth();
wxDC* DC = aSettings->GetPrintDC();
wxPoint pt1 = GetStart();
wxPoint pt2 = GetEnd();
wxPoint c;
COLOR4D color;
penWidth = std::max( penWidth, aSettings->GetDefaultPenWidth() );
unsigned ptCount = 0;
wxPoint* buffer = nullptr;
if( GetShape() == SHAPE_T::POLY )
{
SHAPE_LINE_CHAIN poly = m_poly.Outline( 0 );
ptCount = poly.GetPointCount();
buffer = new wxPoint[ ptCount ];
for( unsigned ii = 0; ii < ptCount; ++ii )
buffer[ii] = (wxPoint) poly.CPoint( ii );
}
else if( GetShape() == SHAPE_T::BEZIER )
{
ptCount = m_bezierPoints.size();
buffer = new wxPoint[ ptCount ];
for( size_t ii = 0; ii < ptCount; ++ii )
buffer[ii] = m_bezierPoints[ii];
}
else if( GetShape() == SHAPE_T::ARC )
{
c = getCenter();
int t1, t2;
CalcArcAngles( t1, t2 );
if( NormalizeAngle180( t1 - t2 ) > 0 )
std::swap( pt1, pt2 );
}
if( GetFillMode() == FILL_T::FILLED_WITH_COLOR )
{
color = GetFillColor();
switch( GetShape() )
{
case SHAPE_T::ARC:
GRFilledArc1( nullptr, DC, pt1, pt2, c, 0, color, color );
break;
case SHAPE_T::CIRCLE:
GRFilledCircle( nullptr, DC, pt1.x, pt1.y, GetRadius(), 0, color, color );
break;
case SHAPE_T::RECT:
GRFilledRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, 0, color, color );
break;
case SHAPE_T::POLY:
GRPoly( nullptr, DC, ptCount, buffer, true, 0, color, color );
break;
case SHAPE_T::BEZIER:
GRPoly( nullptr, DC, ptCount, buffer, true, 0, color, color );
break;
default:
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
}
}
if( GetStroke().GetColor() == COLOR4D::UNSPECIFIED )
color = aSettings->GetLayerColor( LAYER_NOTES );
else
color = GetStroke().GetColor();
if( GetStroke().GetPlotStyle() <= PLOT_DASH_TYPE::FIRST_TYPE )
{
switch( GetShape() )
{
case SHAPE_T::ARC:
GRArc1( nullptr, DC, pt1, pt2, c, penWidth, color );
break;
case SHAPE_T::CIRCLE:
GRCircle( nullptr, DC, pt1.x, pt1.y, GetRadius(), penWidth, color );
break;
case SHAPE_T::RECT:
GRRect( nullptr, DC, pt1.x, pt1.y, pt2.x, pt2.y, penWidth, color );
break;
case SHAPE_T::POLY:
GRPoly( nullptr, DC, ptCount, buffer, false, penWidth, color, color );
break;
case SHAPE_T::BEZIER:
GRPoly( nullptr, DC, ptCount, buffer, false, penWidth, color, color );
break;
default:
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
}
}
else
{
std::vector<SHAPE*> shapes = MakeEffectiveShapes( true );
for( SHAPE* shape : shapes )
{
STROKE_PARAMS::Stroke( shape, GetStroke().GetPlotStyle(), penWidth, aSettings,
[&]( const wxPoint& a, const wxPoint& b )
{
GRLine( nullptr, DC, a.x, a.y, b.x, b.y, penWidth, color );
} );
}
for( SHAPE* shape : shapes )
delete shape;
}
delete[] buffer;
}
void SCH_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
{
SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
ShapeGetMsgPanelInfo( aFrame, aList );
}
wxString SCH_SHAPE::GetSelectMenuText( EDA_UNITS aUnits ) const
{
switch( GetShape() )
{
case SHAPE_T::ARC:
return wxString::Format( _( "Arc, radius %s" ),
MessageTextFromValue( aUnits, GetRadius() ) );
case SHAPE_T::CIRCLE:
return wxString::Format( _( "Circle, radius %s" ),
MessageTextFromValue( aUnits, GetRadius() ) );
case SHAPE_T::RECT:
return wxString::Format( _( "Rectangle, width %s height %s" ),
MessageTextFromValue( aUnits, std::abs( m_start.x - m_end.x ) ),
MessageTextFromValue( aUnits, std::abs( m_start.y - m_end.y ) ) );
case SHAPE_T::POLY:
return wxString::Format( _( "Polyline, %d points" ),
int( m_poly.Outline( 0 ).GetPointCount() ) );
case SHAPE_T::BEZIER:
return wxString::Format( _( "Bezier Curve, %d points" ),
int( m_bezierPoints.size() ) );
default:
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
return wxEmptyString;
}
}
BITMAPS SCH_SHAPE::GetMenuImage() const
{
switch( GetShape() )
{
case SHAPE_T::SEGMENT: return BITMAPS::add_line;
case SHAPE_T::ARC: return BITMAPS::add_arc;
case SHAPE_T::CIRCLE: return BITMAPS::add_circle;
case SHAPE_T::RECT: return BITMAPS::add_rectangle;
case SHAPE_T::POLY: return BITMAPS::add_graphical_segments;
default:
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
return BITMAPS::question_mark;
}
}
void SCH_SHAPE::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 3;
aLayers[0] = LAYER_NOTES;
aLayers[1] = LAYER_NOTES_BACKGROUND;
aLayers[2] = LAYER_SELECTION_SHADOWS;
}
void SCH_SHAPE::AddPoint( const wxPoint& aPosition )
{
if( GetShape() == SHAPE_T::POLY )
{
if( m_poly.IsEmpty() )
m_poly.NewOutline();
m_poly.Outline( 0 ).Append( aPosition, true );
}
else
{
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
}
}
void SCH_SHAPE::CalcArcAngles( int& aStartAngle, int& aEndAngle ) const
{
double start;
double end;
EDA_SHAPE::CalcArcAngles( start, end );
aStartAngle = KiROUND( start * 10.0 );
aEndAngle = KiROUND( end * 10.0 );
}

119
eeschema/sch_shape.h Normal file
View File

@ -0,0 +1,119 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2004-2021 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
*/
#ifndef SCH_SHAPE_H
#define SCH_SHAPE_H
#include <sch_item.h>
#include <eda_shape.h>
class SCH_SHAPE : public SCH_ITEM, public EDA_SHAPE
{
public:
SCH_SHAPE( SHAPE_T aShape, int aLineWidth = 0, FILL_T aFillType = FILL_T::NO_FILL );
// Do not create a copy constructor. The one generated by the compiler is adequate.
~SCH_SHAPE() { }
wxString GetClass() const override
{
return wxT( "SCH_SHAPE" );
}
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override
{
return hitTest( aPosition, aAccuracy );
}
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override
{
return hitTest( aRect, aContained, aAccuracy );
}
int GetPenWidth() const override;
bool HasLineStroke() const override { return true; }
STROKE_PARAMS GetStroke() const override { return m_stroke; }
void SetStroke( const STROKE_PARAMS& aStroke ) override;
PLOT_DASH_TYPE GetEffectiveLineStyle() const
{
if( IsFilled() )
return PLOT_DASH_TYPE::SOLID;
else if( m_stroke.GetPlotStyle() == PLOT_DASH_TYPE::DEFAULT )
return PLOT_DASH_TYPE::DASH;
else
return m_stroke.GetPlotStyle();
}
const EDA_RECT GetBoundingBox() const override { return getBoundingBox(); }
wxPoint GetPosition() const override { return getPosition(); }
void SetPosition( const wxPoint& aPos ) override { setPosition( aPos ); }
wxPoint GetCenter() const { return getCenter(); }
void CalcArcAngles( int& aStartAngle, int& aEndAngle ) const;
void BeginEdit( const wxPoint& aStartPoint ) { beginEdit( aStartPoint ); }
bool ContinueEdit( const wxPoint& aPosition ) { return continueEdit( aPosition ); }
void CalcEdit( const wxPoint& aPosition ) { calcEdit( aPosition ); }
void EndEdit() { endEdit(); }
void SetEditState( int aState ) { setEditState( aState ); }
void Move( const wxPoint& aOffset ) override;
void MirrorHorizontally( int aCenter ) override;
void MirrorVertically( int aCenter ) override;
void Rotate( const wxPoint& aCenter ) override;
void AddPoint( const wxPoint& aPosition );
void Plot( PLOTTER* aPlotter ) const override;
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
BITMAPS GetMenuImage() const override;
EDA_ITEM* Clone() const override;
void ViewGetLayers( int aLayers[], int& aCount ) const override;
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
private:
void Print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset ) override;
double getParentOrientation() const override { return 0.0; }
wxPoint getParentPosition() const override { return wxPoint(); }
};
#endif // SCH_SHAPE_H

View File

@ -95,10 +95,10 @@ static LIB_SYMBOL* dummy()
}
SCH_SYMBOL::SCH_SYMBOL( const wxPoint& aPos, SCH_ITEM* aParent ) :
SCH_ITEM( aParent, SCH_SYMBOL_T )
SCH_SYMBOL::SCH_SYMBOL() :
SCH_ITEM( nullptr, SCH_SYMBOL_T )
{
Init( aPos );
Init( wxPoint( 0, 0 ) );
}

View File

@ -78,7 +78,7 @@ extern std::string toUTFTildaText( const wxString& txt );
class SCH_SYMBOL : public SCH_ITEM
{
public:
SCH_SYMBOL( const wxPoint& pos = wxPoint( 0, 0 ), SCH_ITEM* aParent = nullptr );
SCH_SYMBOL();
/**
* Create schematic symbol from library symbol object.

View File

@ -853,8 +853,8 @@ EDA_ITEM* SCH_LABEL::Clone() const
bool SCH_LABEL::IsType( const KICAD_T aScanTypes[] ) const
{
static KICAD_T wireTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_PIN_T, EOT };
static KICAD_T busTypes[] = { SCH_LINE_LOCATE_BUS_T, EOT };
static KICAD_T wireTypes[] = { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T, EOT };
static KICAD_T busTypes[] = { SCH_ITEM_LOCATE_BUS_T, EOT };
if( SCH_ITEM::IsType( aScanTypes ) )
return true;

View File

@ -56,6 +56,7 @@ static const LAYER_NUM SCH_LAYER_ORDER[] =
LAYER_SELECTION_SHADOWS,
LAYER_DEVICE_BACKGROUND,
LAYER_SHEET_BACKGROUND,
LAYER_NOTES_BACKGROUND,
LAYER_DRAWINGSHEET
};

View File

@ -21,13 +21,10 @@ color
comment
company
convert
dash
dash_dot
data
date
default
diameter
dot
edge_clock_high
effects
end
@ -108,7 +105,6 @@ shape
sheet
sheet_instances
size
solid
start
stroke
symbol

View File

@ -139,9 +139,9 @@ void SYMBOL_EDIT_FRAME::ReCreateMenuBar()
placeMenu->Add( EE_ACTIONS::placeSymbolPin );
placeMenu->Add( EE_ACTIONS::placeSymbolText );
placeMenu->Add( EE_ACTIONS::drawSymbolRectangle );
placeMenu->Add( EE_ACTIONS::drawSymbolCircle );
placeMenu->Add( EE_ACTIONS::drawSymbolArc );
placeMenu->Add( EE_ACTIONS::drawRectangle );
placeMenu->Add( EE_ACTIONS::drawCircle );
placeMenu->Add( EE_ACTIONS::drawArc );
placeMenu->Add( EE_ACTIONS::drawSymbolLines );

View File

@ -490,9 +490,9 @@ void SYMBOL_EDIT_FRAME::setupUIConditions()
mgr->SetConditions( ACTIONS::deleteTool, EDIT_TOOL( ACTIONS::deleteTool ) );
mgr->SetConditions( EE_ACTIONS::placeSymbolPin, EDIT_TOOL( EE_ACTIONS::placeSymbolPin ) );
mgr->SetConditions( EE_ACTIONS::placeSymbolText, EDIT_TOOL( EE_ACTIONS::placeSymbolText ) );
mgr->SetConditions( EE_ACTIONS::drawSymbolRectangle, EDIT_TOOL( EE_ACTIONS::drawSymbolRectangle ) );
mgr->SetConditions( EE_ACTIONS::drawSymbolCircle, EDIT_TOOL( EE_ACTIONS::drawSymbolCircle ) );
mgr->SetConditions( EE_ACTIONS::drawSymbolArc, EDIT_TOOL( EE_ACTIONS::drawSymbolArc ) );
mgr->SetConditions( EE_ACTIONS::drawRectangle, EDIT_TOOL( EE_ACTIONS::drawRectangle ) );
mgr->SetConditions( EE_ACTIONS::drawCircle, EDIT_TOOL( EE_ACTIONS::drawCircle ) );
mgr->SetConditions( EE_ACTIONS::drawArc, EDIT_TOOL( EE_ACTIONS::drawArc ) );
mgr->SetConditions( EE_ACTIONS::drawSymbolLines, EDIT_TOOL( EE_ACTIONS::drawSymbolLines ) );
mgr->SetConditions( EE_ACTIONS::placeSymbolAnchor, EDIT_TOOL( EE_ACTIONS::placeSymbolAnchor ) );

View File

@ -59,9 +59,9 @@ void SYMBOL_EDIT_FRAME::ReCreateVToolbar()
m_drawToolBar->AddScaledSeparator( this );
m_drawToolBar->Add( EE_ACTIONS::placeSymbolPin, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::placeSymbolText, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::drawSymbolRectangle, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::drawSymbolCircle, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::drawSymbolArc, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::drawRectangle, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::drawArc, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::drawSymbolLines, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( EE_ACTIONS::placeSymbolAnchor, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( ACTIONS::deleteTool, ACTION_TOOLBAR::TOGGLE );

View File

@ -225,21 +225,6 @@ TOOL_ACTION EE_ACTIONS::placeSymbolText( "eeschema.SymbolDrawing.placeSymbolText
_( "Add Text" ), _( "Add a text item" ),
BITMAPS::text, AF_ACTIVATE, (void*) LIB_TEXT_T );
TOOL_ACTION EE_ACTIONS::drawSymbolRectangle( "eeschema.SymbolDrawing.drawSymbolRectangle",
AS_GLOBAL, 0, "",
_( "Add Rectangle" ), _( "Add a rectangle" ),
BITMAPS::add_rectangle, AF_ACTIVATE, (void*) SHAPE_T::RECT );
TOOL_ACTION EE_ACTIONS::drawSymbolCircle( "eeschema.SymbolDrawing.drawSymbolCircle",
AS_GLOBAL, 0, "",
_( "Add Circle" ), _( "Add a circle" ),
BITMAPS::add_circle, AF_ACTIVATE, (void*) SHAPE_T::CIRCLE );
TOOL_ACTION EE_ACTIONS::drawSymbolArc( "eeschema.SymbolDrawing.drawSymbolArc",
AS_GLOBAL, 0, "",
_( "Add Arc" ), _( "Add an arc" ),
BITMAPS::add_arc, AF_ACTIVATE, (void*) SHAPE_T::ARC );
TOOL_ACTION EE_ACTIONS::drawSymbolLines( "eeschema.SymbolDrawing.drawSymbolLines",
AS_GLOBAL, 0, "",
_( "Add Lines" ), _( "Add connected graphic lines" ),
@ -345,6 +330,21 @@ TOOL_ACTION EE_ACTIONS::placeSchematicText( "eeschema.InteractiveDrawing.placeSc
_( "Add Text" ), _( "Add text" ),
BITMAPS::text, AF_ACTIVATE );
TOOL_ACTION EE_ACTIONS::drawRectangle( "eeschema.InteractiveDrawing.drawRectangle",
AS_GLOBAL, 0, "",
_( "Add Rectangle" ), _( "Add a rectangle" ),
BITMAPS::add_rectangle, AF_ACTIVATE, (void*) SHAPE_T::RECT );
TOOL_ACTION EE_ACTIONS::drawCircle( "eeschema.InteractiveDrawing.drawCircle",
AS_GLOBAL, 0, "",
_( "Add Circle" ), _( "Add a circle" ),
BITMAPS::add_circle, AF_ACTIVATE, (void*) SHAPE_T::CIRCLE );
TOOL_ACTION EE_ACTIONS::drawArc( "eeschema.InteractiveDrawing.drawArc",
AS_GLOBAL, 0, "",
_( "Add Arc" ), _( "Add an arc" ),
BITMAPS::add_arc, AF_ACTIVATE, (void*) SHAPE_T::ARC );
TOOL_ACTION EE_ACTIONS::placeImage( "eeschema.InteractiveDrawing.placeImage",
AS_GLOBAL, 0, "",
_( "Add Image" ), _( "Add bitmap image" ),

View File

@ -88,6 +88,9 @@ public:
static TOOL_ACTION drawSheet;
static TOOL_ACTION importSheetPin;
static TOOL_ACTION placeSchematicText;
static TOOL_ACTION drawRectangle;
static TOOL_ACTION drawCircle;
static TOOL_ACTION drawArc;
static TOOL_ACTION drawLines;
static TOOL_ACTION placeImage;
static TOOL_ACTION finishLineWireOrBus;
@ -99,9 +102,6 @@ public:
// Symbol Tools
static TOOL_ACTION placeSymbolPin;
static TOOL_ACTION placeSymbolText;
static TOOL_ACTION drawSymbolRectangle;
static TOOL_ACTION drawSymbolCircle;
static TOOL_ACTION drawSymbolArc;
static TOOL_ACTION drawSymbolLines;
static TOOL_ACTION placeSymbolAnchor;
static TOOL_ACTION finishDrawing;

View File

@ -37,6 +37,7 @@ using namespace std::placeholders;
#include <sch_line.h>
#include <sch_bitmap.h>
#include <sch_sheet.h>
#include <sch_shape.h>
#include <sch_sheet_pin.h>
#include <symbol_edit_frame.h>
#include <lib_shape.h>
@ -123,8 +124,59 @@ public:
break;
default:
wxFAIL_MSG( "EDIT_POINTS_FACTORY::Make not implemented for "
+ shape->SHAPE_T_asString() );
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}
}
break;
case SCH_SHAPE_T:
{
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
switch( shape->GetShape() )
{
case SHAPE_T::ARC:
points->AddPoint( shape->GetPosition() );
points->AddPoint( shape->GetStart() );
points->AddPoint( shape->GetEnd() );
break;
case SHAPE_T::CIRCLE:
points->AddPoint( shape->GetPosition() );
points->AddPoint( shape->GetEnd() );
break;
case SHAPE_T::RECT:
{
// point editor works only with rectangles having width and height > 0
// Some symbols can have rectangles with width or height < 0
// So normalize the size:
BOX2I dummy;
dummy.SetOrigin( shape->GetPosition() );
dummy.SetEnd( shape->GetEnd() );
dummy.Normalize();
VECTOR2I topLeft = dummy.GetPosition();
VECTOR2I botRight = dummy.GetEnd();
points->AddPoint( topLeft );
points->AddPoint( VECTOR2I( botRight.x, topLeft.y ) );
points->AddPoint( VECTOR2I( topLeft.x, botRight.y ) );
points->AddPoint( botRight );
}
break;
case SHAPE_T::POLY:
for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
points->AddPoint( pt );
break;
case SHAPE_T::BEZIER:
// TODO
break;
default:
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}
}
break;
@ -275,8 +327,9 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
{
static KICAD_T supportedTypes[] = {
LIB_SHAPE_T,
SCH_SHAPE_T,
SCH_SHEET_T,
SCH_LINE_LOCATE_GRAPHIC_LINE_T,
SCH_ITEM_LOCATE_GRAPHIC_LINE_T,
SCH_BITMAP_T,
EOT
};
@ -540,8 +593,71 @@ void EE_POINT_EDITOR::updateParentItem() const
break;
default:
wxFAIL_MSG( "EE_POINT_EDITOR::updateParentItem not implemented for "
+ shape->SHAPE_T_asString() );
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}
}
break;
case SCH_SHAPE_T:
{
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
switch( shape->GetShape() )
{
case SHAPE_T::ARC:
if( getEditedPointIndex() == ARC_CENTER )
{
shape->SetEditState( 4 );
shape->CalcEdit( (wxPoint) m_editPoints->Point( ARC_CENTER ).GetPosition() );
}
else if( getEditedPointIndex() == ARC_START )
{
shape->SetEditState( 2 );
shape->CalcEdit( (wxPoint) m_editPoints->Point( ARC_START ).GetPosition() );
}
else if( getEditedPointIndex() == ARC_END )
{
shape->SetEditState( 3 );
shape->CalcEdit( (wxPoint) m_editPoints->Point( ARC_END ).GetPosition() );
}
break;
case SHAPE_T::CIRCLE:
shape->SetPosition( (wxPoint) m_editPoints->Point( CIRC_CENTER ).GetPosition() );
shape->SetEnd( (wxPoint) m_editPoints->Point( CIRC_END ).GetPosition() );
break;
case SHAPE_T::POLY:
shape->GetPolyShape().RemoveAllContours();
shape->GetPolyShape().NewOutline();
for( unsigned i = 0; i < m_editPoints->PointsSize(); ++i )
shape->GetPolyShape().Append( m_editPoints->Point( i ).GetPosition() );
break;
case SHAPE_T::RECT:
{
EE_GRID_HELPER gridHelper( m_toolMgr );
VECTOR2I topLeft = m_editPoints->Point( RECT_TOPLEFT ).GetPosition();
VECTOR2I topRight = m_editPoints->Point( RECT_TOPRIGHT ).GetPosition();
VECTOR2I botLeft = m_editPoints->Point( RECT_BOTLEFT ).GetPosition();
VECTOR2I botRight = m_editPoints->Point( RECT_BOTRIGHT ).GetPosition();
pinEditedCorner( getEditedPointIndex(), Mils2iu( 1 ), Mils2iu( 1 ),
topLeft, topRight, botLeft, botRight, &gridHelper );
shape->SetPosition( (wxPoint) topLeft );
shape->SetEnd( (wxPoint) botRight );
}
break;
case SHAPE_T::BEZIER:
// TODO
break;
default:
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}
}
break;
@ -732,8 +848,73 @@ void EE_POINT_EDITOR::updatePoints()
break;
default:
wxFAIL_MSG( "EE_POINT_EDITOR::updatePoints not implemented for "
+ shape->SHAPE_T_asString() );
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}
}
break;
case SCH_SHAPE_T:
{
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( item );
switch( shape->GetShape() )
{
case SHAPE_T::ARC:
m_editPoints->Point( ARC_CENTER ).SetPosition( shape->GetPosition() );
m_editPoints->Point( ARC_START ).SetPosition( shape->GetStart() );
m_editPoints->Point( ARC_END ).SetPosition( shape->GetEnd() );
break;
case SHAPE_T::CIRCLE:
m_editPoints->Point( CIRC_CENTER ).SetPosition( shape->GetPosition() );
m_editPoints->Point( CIRC_END ).SetPosition( shape->GetEnd() );
break;
case SHAPE_T::POLY:
{
if( (int) m_editPoints->PointsSize() != shape->GetPointCount() )
{
getView()->Remove( m_editPoints.get() );
m_editedPoint = nullptr;
m_editPoints = EDIT_POINTS_FACTORY::Make( item, m_frame );
getView()->Add( m_editPoints.get() );
}
else
{
int ii = 0;
for( const VECTOR2I& pt : shape->GetPolyShape().Outline( 0 ).CPoints() )
m_editPoints->Point( ii++ ).SetPosition( pt );
}
break;
}
case SHAPE_T::RECT:
{
// point editor works only with rectangles having width and height > 0
// Some symbols can have rectangles with width or height < 0
// So normalize the size:
BOX2I dummy;
dummy.SetOrigin( shape->GetPosition() );
dummy.SetEnd( shape->GetEnd() );
dummy.Normalize();
VECTOR2I topLeft = dummy.GetPosition();
VECTOR2I botRight = dummy.GetEnd();
m_editPoints->Point( RECT_TOPLEFT ).SetPosition( topLeft );
m_editPoints->Point( RECT_TOPRIGHT ).SetPosition( VECTOR2I( botRight.x, topLeft.y ) );
m_editPoints->Point( RECT_BOTLEFT ).SetPosition( VECTOR2I( topLeft.x, botRight.y ) );
m_editPoints->Point( RECT_BOTRIGHT ).SetPosition( botRight );
}
break;
case SHAPE_T::BEZIER:
// TODO
break;
default:
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}
}
break;

View File

@ -150,13 +150,13 @@ bool EE_SELECTION_TOOL::Init()
m_isSymbolViewer = symbolViewerFrame != nullptr;
}
static KICAD_T wireOrBusTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
static KICAD_T connectedTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T,
static KICAD_T wireOrBusTypes[] = { SCH_ITEM_LOCATE_WIRE_T, SCH_ITEM_LOCATE_BUS_T, EOT };
static KICAD_T connectedTypes[] = { SCH_ITEM_LOCATE_WIRE_T, SCH_ITEM_LOCATE_BUS_T,
SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T, SCH_LABEL_T,
SCH_SHEET_PIN_T, SCH_PIN_T, EOT };
auto wireSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_LINE_LOCATE_WIRE_T );
auto busSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_LINE_LOCATE_BUS_T );
auto wireSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_ITEM_LOCATE_WIRE_T );
auto busSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_ITEM_LOCATE_BUS_T );
auto wireOrBusSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( wireOrBusTypes );
auto connectedSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( connectedTypes );
auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
@ -293,6 +293,7 @@ const KICAD_T movableSchematicItems[] =
SCH_BUS_WIRE_ENTRY_T,
SCH_LINE_T,
SCH_BITMAP_T,
SCH_SHAPE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
@ -307,7 +308,7 @@ const KICAD_T movableSchematicItems[] =
const KICAD_T movableSymbolItems[] =
{
LIB_SHAPE_T,
LIB_SHAPE_T,
LIB_TEXT_T,
LIB_PIN_T,
LIB_FIELD_T,
@ -1334,18 +1335,18 @@ bool EE_SELECTION_TOOL::selectMultiple()
static KICAD_T nodeTypes[] =
{
SCH_SYMBOL_LOCATE_POWER_T,
SCH_PIN_T,
SCH_LINE_LOCATE_WIRE_T,
SCH_LINE_LOCATE_BUS_T,
SCH_BUS_WIRE_ENTRY_T,
SCH_BUS_BUS_ENTRY_T,
SCH_LABEL_T,
SCH_HIER_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_SHEET_PIN_T,
SCH_JUNCTION_T,
EOT
SCH_SYMBOL_LOCATE_POWER_T,
SCH_PIN_T,
SCH_ITEM_LOCATE_WIRE_T,
SCH_ITEM_LOCATE_BUS_T,
SCH_BUS_WIRE_ENTRY_T,
SCH_BUS_BUS_ENTRY_T,
SCH_LABEL_T,
SCH_HIER_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_SHEET_PIN_T,
SCH_JUNCTION_T,
EOT
};
@ -1383,7 +1384,7 @@ int EE_SELECTION_TOOL::SelectNode( const TOOL_EVENT& aEvent )
int EE_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent )
{
static KICAD_T wiresAndBuses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
static KICAD_T wiresAndBuses[] = { SCH_ITEM_LOCATE_WIRE_T, SCH_ITEM_LOCATE_BUS_T, EOT };
RequestSelection( wiresAndBuses );

View File

@ -53,7 +53,7 @@
#include <string_utils.h>
#include <wildcards_and_files_ext.h>
#include <wx/filedlg.h>
#include <sch_shape.h>
SCH_DRAWING_TOOLS::SCH_DRAWING_TOOLS() :
EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveDrawing" ),
@ -62,7 +62,9 @@ SCH_DRAWING_TOOLS::SCH_DRAWING_TOOLS() :
m_lastTextOrientation( LABEL_SPIN_STYLE::RIGHT ),
m_lastTextBold( false ),
m_lastTextItalic( false ),
m_lastFillStyle( FILL_T::NO_FILL ),
m_inPlaceSymbol( false ),
m_inDrawShape( false ),
m_inPlaceImage( false ),
m_inSingleClickPlace( false ),
m_inTwoClickPlace( false ),
@ -1180,8 +1182,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
else // ... and second click places:
{
item->ClearFlags( IS_MOVING );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item,
false );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), item, false );
item = nullptr;
m_view->ClearPreview();
@ -1238,6 +1239,165 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
}
int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
{
if( m_inDrawShape )
return 0;
else
m_inDrawShape = true;
SHAPE_T type = aEvent.Parameter<SHAPE_T>();
// We might be running as the same shape in another co-routine. Make sure that one
// gets whacked.
m_toolMgr->DeactivateTool();
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
getViewControls()->ShowCursor( true );
std::string tool = aEvent.GetCommandStr().get();
m_frame->PushTool( tool );
Activate();
SCH_SHAPE* item = nullptr;
auto setCursor =
[&]()
{
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
};
auto cleanup =
[&] ()
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview();
delete item;
item = nullptr;
};
// Prime the pump
if( aEvent.HasPosition() )
m_toolMgr->RunAction( ACTIONS::cursorClick );
// Set initial cursor
setCursor();
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
setCursor();
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
if( evt->IsCancelInteractive() )
{
if( item )
{
cleanup();
}
else
{
m_frame->PopTool( tool );
break;
}
}
else if( evt->IsActivate() )
{
if( item && evt->IsMoveTool() )
{
// we're already drawing our own item; ignore the move tool
evt->SetPassEvent( false );
continue;
}
if( item )
cleanup();
if( evt->IsPointEditor() )
{
// don't exit (the point editor runs in the background)
}
else if( evt->IsMoveTool() )
{
// leave ourselves on the stack so we come back after the move
break;
}
else
{
m_frame->PopTool( tool );
break;
}
}
else if( evt->IsClick( BUT_LEFT ) && !item )
{
EESCHEMA_SETTINGS* cfg = m_frame->eeconfig();
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
int lineWidth = Mils2iu( cfg->m_Drawing.default_line_thickness );
item = new SCH_SHAPE( type, lineWidth, m_lastFillStyle );
item->SetFlags( IS_NEW );
item->BeginEdit( (wxPoint) cursorPos );
m_view->ClearPreview();
m_view->AddToPreview( item->Clone() );
}
else if( item && ( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT )
|| evt->IsAction( &EE_ACTIONS::finishDrawing ) ) )
{
if( evt->IsDblClick( BUT_LEFT ) || evt->IsAction( &EE_ACTIONS::finishDrawing )
|| !item->ContinueEdit( (wxPoint) cursorPos ) )
{
item->EndEdit();
item->ClearEditFlags();
item->SetFlags( IS_NEW );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), item, false );
m_selectionTool->AddItemToSel( item );
item = nullptr;
m_view->ClearPreview();
m_toolMgr->RunAction( ACTIONS::activatePointEditor );
}
}
else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
{
item->CalcEdit( (wxPoint) cursorPos );
m_view->ClearPreview();
m_view->AddToPreview( item->Clone() );
}
else if( evt->IsDblClick( BUT_LEFT ) && !item )
{
m_toolMgr->RunAction( EE_ACTIONS::properties, true );
}
else if( evt->IsClick( BUT_RIGHT ) )
{
// Warp after context menu only if dragging...
if( !item )
m_toolMgr->VetoContextMenuMouseWarp();
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
}
else
{
evt->SetPassEvent();
}
// Enable autopanning and cursor capture only when there is a shape being drawn
getViewControls()->SetAutoPan( item != nullptr );
getViewControls()->CaptureCursor( item != nullptr );
}
getViewControls()->SetAutoPan( false );
getViewControls()->CaptureCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_inDrawShape = false;
return 0;
}
int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
{
SCH_SHEET* sheet = nullptr;
@ -1333,8 +1493,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
sheet = new SCH_SHEET( m_frame->GetCurrentSheet().Last(),
static_cast<wxPoint>( cursorPos ) );
sheet = new SCH_SHEET( m_frame->GetCurrentSheet().Last(), (wxPoint) cursorPos );
sheet->SetFlags( IS_NEW | IS_RESIZING );
sheet->SetScreen( nullptr );
sheet->SetBorderWidth( Mils2iu( cfg->m_Drawing.default_line_thickness ) );
@ -1448,5 +1607,8 @@ void SCH_DRAWING_TOOLS::setTransitions()
Go( &SCH_DRAWING_TOOLS::TwoClickPlace, EE_ACTIONS::importSheetPin.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::SingleClickPlace, EE_ACTIONS::importSingleSheetPin.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::TwoClickPlace, EE_ACTIONS::placeSchematicText.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawRectangle.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawCircle.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawArc.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::PlaceImage, EE_ACTIONS::placeImage.MakeEvent() );
}

View File

@ -53,6 +53,7 @@ public:
int PlaceSymbol( const TOOL_EVENT& aEvent );
int SingleClickPlace( const TOOL_EVENT& aEvent );
int TwoClickPlace( const TOOL_EVENT& aEvent );
int DrawShape( const TOOL_EVENT& aEvent );
int DrawSheet( const TOOL_EVENT& aEvent );
int PlaceImage( const TOOL_EVENT& aEvent );
@ -88,9 +89,11 @@ private:
LABEL_SPIN_STYLE m_lastTextOrientation;
bool m_lastTextBold;
bool m_lastTextItalic;
FILL_T m_lastFillStyle;
///< Re-entrancy guards
bool m_inPlaceSymbol;
bool m_inDrawShape;
bool m_inPlaceImage;
bool m_inSingleClickPlace;
bool m_inTwoClickPlace;

View File

@ -28,15 +28,16 @@
#include <tools/ee_selection_tool.h>
#include <tools/sch_line_wire_bus_tool.h>
#include <tools/sch_move_tool.h>
#include <tools/sch_drawing_tools.h>
#include <widgets/infobar.h>
#include <ee_actions.h>
#include <bitmaps.h>
#include <confirm.h>
#include <eda_item.h>
#include <reporter.h>
#include <string_utils.h>
#include <sch_item.h>
#include <sch_symbol.h>
#include <sch_shape.h>
#include <sch_sheet.h>
#include <sch_sheet_pin.h>
#include <sch_text.h>
@ -59,17 +60,15 @@
#include <dialogs/dialog_sheet_pin_properties.h>
#include <dialogs/dialog_field_properties.h>
#include <dialogs/dialog_junction_props.h>
#include "sch_drawing_tools.h"
#include <dialogs/dialog_shape_properties.h>
#include <dialogs/dialog_text_and_label_properties.h>
#include <math/util.h> // for KiROUND
#include <pgm_base.h>
#include <settings/settings_manager.h>
#include <symbol_editor_settings.h>
#include <dialogs/dialog_text_and_label_properties.h>
#include <core/kicad_algo.h>
#include <wx/textdlg.h>
class SYMBOL_UNIT_MENU : public ACTION_MENU
{
public:
@ -415,6 +414,7 @@ bool SCH_EDIT_TOOL::Init()
const KICAD_T rotatableItems[] = {
SCH_SHAPE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
@ -533,6 +533,13 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
break;
}
case SCH_SHAPE_T:
for( int i = 0; clockwise ? i < 1 : i < 3; ++i )
head->Rotate( rotPoint );
break;
case SCH_BITMAP_T:
for( int i = 0; clockwise ? i < 3 : i < 1; ++i )
head->Rotate( rotPoint );
@ -554,7 +561,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
}
default:
break;
UNIMPLEMENTED_FOR( head->GetClass() );
}
connections = head->IsConnectable();
@ -744,6 +751,14 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
break;
}
case SCH_SHAPE_T:
if( vertical )
item->MirrorVertically( item->GetPosition().y );
else
item->MirrorHorizontally( item->GetPosition().x );
break;
case SCH_BITMAP_T:
if( vertical )
item->MirrorVertically( item->GetPosition().y );
@ -766,7 +781,7 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
break;
default:
break;
UNIMPLEMENTED_FOR( item->GetClass() );
}
connections = item->IsConnectable();
@ -915,6 +930,7 @@ static KICAD_T deletableItems[] =
SCH_LINE_T,
SCH_BUS_BUS_ENTRY_T,
SCH_BUS_WIRE_ENTRY_T,
SCH_SHAPE_T,
SCH_TEXT_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
@ -1458,6 +1474,18 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
}
break;
case SCH_SHAPE_T:
{
DIALOG_SHAPE_PROPERTIES dlg( m_frame, static_cast<SCH_SHAPE*>( item ) );
if( dlg.ShowModal() == wxID_OK )
{
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
m_frame->OnModify();
}
}
break;
case SCH_BITMAP_T:
{
SCH_BITMAP* bitmap = static_cast<SCH_BITMAP*>( item );

View File

@ -734,8 +734,8 @@ void SCH_EDITOR_CONTROL::doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aF
#ifdef KICAD_SPICE
static KICAD_T wires[] = { SCH_LINE_LOCATE_WIRE_T, EOT };
static KICAD_T wiresAndPins[] = { SCH_LINE_LOCATE_WIRE_T, SCH_PIN_T, SCH_SHEET_PIN_T, EOT };
static KICAD_T wires[] = { SCH_ITEM_LOCATE_WIRE_T, EOT };
static KICAD_T wiresAndPins[] = { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T, SCH_SHEET_PIN_T, EOT };
static KICAD_T fieldsAndSymbols[] = { SCH_SYMBOL_T, SCH_FIELD_T, EOT };
#define HITTEST_THRESHOLD_PIXELS 5

View File

@ -95,7 +95,7 @@ private:
{
SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) getToolManager()->GetToolHolder();
EE_SELECTION_TOOL* selTool = getToolManager()->GetTool<EE_SELECTION_TOOL>();
KICAD_T busType[] = { SCH_LINE_LOCATE_BUS_T, EOT };
KICAD_T busType[] = { SCH_ITEM_LOCATE_BUS_T, EOT };
EE_SELECTION& selection = selTool->RequestSelection( busType );
SCH_LINE* bus = (SCH_LINE*) selection.Front();
@ -200,7 +200,7 @@ bool SCH_LINE_WIRE_BUS_TOOL::Init()
};
auto busSelection = EE_CONDITIONS::MoreThan( 0 )
&& EE_CONDITIONS::OnlyType( SCH_LINE_LOCATE_BUS_T );
&& EE_CONDITIONS::OnlyType( SCH_ITEM_LOCATE_BUS_T );
auto& ctxMenu = m_menu.GetMenu();
@ -248,21 +248,21 @@ bool SCH_LINE_WIRE_BUS_TOOL::Init()
bool SCH_LINE_WIRE_BUS_TOOL::IsDrawingLine( const SELECTION& aSelection )
{
static KICAD_T graphicLineType[] = { SCH_LINE_LOCATE_GRAPHIC_LINE_T, EOT };
static KICAD_T graphicLineType[] = { SCH_ITEM_LOCATE_GRAPHIC_LINE_T, EOT };
return IsDrawingLineWireOrBus( aSelection ) && aSelection.Front()->IsType( graphicLineType );
}
bool SCH_LINE_WIRE_BUS_TOOL::IsDrawingWire( const SELECTION& aSelection )
{
static KICAD_T wireType[] = { SCH_LINE_LOCATE_WIRE_T, EOT };
static KICAD_T wireType[] = { SCH_ITEM_LOCATE_WIRE_T, EOT };
return IsDrawingLineWireOrBus( aSelection ) && aSelection.Front()->IsType( wireType );
}
bool SCH_LINE_WIRE_BUS_TOOL::IsDrawingBus( const SELECTION& aSelection )
{
static KICAD_T busType[] = { SCH_LINE_LOCATE_BUS_T, EOT };
static KICAD_T busType[] = { SCH_ITEM_LOCATE_BUS_T, EOT };
return IsDrawingLineWireOrBus( aSelection ) && aSelection.Front()->IsType( busType );
}

View File

@ -90,6 +90,15 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
};
auto cleanup =
[&] ()
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview();
delete item;
item = nullptr;
};
Activate();
// Must be done after Activate() so that it gets set into the correct context
getViewControls()->ShowCursor( true );
@ -100,6 +109,9 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
if( aEvent.HasPosition() || ( isText && !aEvent.IsReactivate() ) )
m_toolMgr->RunAction( ACTIONS::cursorClick );
// Set initial cursor
setCursor();
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
@ -107,15 +119,6 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
cursorPos = getViewControls()->GetCursorPosition( !evt->DisableGridSnapping() );
auto cleanup =
[&] ()
{
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_view->ClearPreview();
delete item;
item = nullptr;
};
if( evt->IsCancelInteractive() )
{
if( item )
@ -310,7 +313,9 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
if( evt->IsCancelInteractive() )
{
if( item )
{
cleanup();
}
else
{
m_frame->PopTool( tool );
@ -379,7 +384,7 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
}
else if( item && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
{
item->CalcEdit( wxPoint( cursorPos.x, -cursorPos.y) );
item->CalcEdit( wxPoint( cursorPos.x, -cursorPos.y ) );
m_view->ClearPreview();
m_view->AddToPreview( item->Clone() );
}
@ -514,9 +519,9 @@ void SYMBOL_EDITOR_DRAWING_TOOLS::setTransitions()
{
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace, EE_ACTIONS::placeSymbolPin.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace, EE_ACTIONS::placeSymbolText.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawSymbolRectangle.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawSymbolCircle.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawSymbolArc.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawRectangle.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawCircle.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawArc.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape, EE_ACTIONS::drawSymbolLines.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::PlaceAnchor, EE_ACTIONS::placeSymbolAnchor.MakeEvent() );
Go( &SYMBOL_EDITOR_DRAWING_TOOLS::RepeatDrawItem, EE_ACTIONS::repeatDrawItem.MakeEvent() );

View File

@ -32,6 +32,7 @@
#include <gr_basic.h>
#include <layer_ids.h>
#include <geometry/geometry_utils.h>
#include <stroke_params.h>
class BOARD;
class BOARD_ITEM_CONTAINER;
@ -136,6 +137,16 @@ public:
BOARD_ITEM_CONTAINER* GetParentFootprint() const;
/**
* Check if this item has line stoke properties.
*
* @see #STROKE_PARAMS
*/
virtual bool HasLineStroke() const { return false; }
virtual STROKE_PARAMS GetStroke() const;
virtual void SetStroke( const STROKE_PARAMS& aStroke );
/**
* Return the primary layer this item is on.
*/

View File

@ -127,6 +127,7 @@ enum KICAD_T
SCH_BUS_WIRE_ENTRY_T,
SCH_BUS_BUS_ENTRY_T,
SCH_LINE_T,
SCH_SHAPE_T,
SCH_BITMAP_T,
SCH_TEXT_T,
SCH_LABEL_T,
@ -146,10 +147,10 @@ enum KICAD_T
SCH_FIELD_LOCATE_FOOTPRINT_T,
SCH_FIELD_LOCATE_DATASHEET_T,
// Same for picking wires and buses from SCH_LINE_T items
SCH_LINE_LOCATE_WIRE_T,
SCH_LINE_LOCATE_BUS_T,
SCH_LINE_LOCATE_GRAPHIC_LINE_T,
// Same for picking wires, buses and graphics from SCH_ITEM_T items
SCH_ITEM_LOCATE_WIRE_T,
SCH_ITEM_LOCATE_BUS_T,
SCH_ITEM_LOCATE_GRAPHIC_LINE_T,
// Same for picking labels attached to wires and/or buses
SCH_LABEL_LOCATE_WIRE_T,
@ -224,7 +225,7 @@ enum KICAD_T
* Return the underlying type of the given type.
*
* This is useful for finding the element type given one of the "non-type" types such as
* SCH_LINE_LOCATE_WIRE_T.
* SCH_ITEM_LOCATE_WIRE_T.
*
* @param aType Given type to resolve.
* @return Base type.
@ -239,9 +240,9 @@ constexpr KICAD_T BaseType( const KICAD_T aType )
case SCH_FIELD_LOCATE_DATASHEET_T:
return SCH_FIELD_T;
case SCH_LINE_LOCATE_WIRE_T:
case SCH_LINE_LOCATE_BUS_T:
case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
case SCH_ITEM_LOCATE_WIRE_T:
case SCH_ITEM_LOCATE_BUS_T:
case SCH_ITEM_LOCATE_GRAPHIC_LINE_T:
return SCH_LINE_T;
case SCH_LABEL_LOCATE_WIRE_T:
@ -287,9 +288,9 @@ constexpr bool IsInstantiableType( const KICAD_T aType )
case SCH_FIELD_LOCATE_FOOTPRINT_T:
case SCH_FIELD_LOCATE_DATASHEET_T:
case SCH_LINE_LOCATE_WIRE_T:
case SCH_LINE_LOCATE_BUS_T:
case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
case SCH_ITEM_LOCATE_WIRE_T:
case SCH_ITEM_LOCATE_BUS_T:
case SCH_ITEM_LOCATE_GRAPHIC_LINE_T:
case SCH_LABEL_LOCATE_WIRE_T:
case SCH_LABEL_LOCATE_BUS_T:
@ -346,9 +347,9 @@ constexpr bool IsEeschemaType( const KICAD_T aType )
case SCH_FIELD_LOCATE_FOOTPRINT_T:
case SCH_FIELD_LOCATE_DATASHEET_T:
case SCH_LINE_LOCATE_WIRE_T:
case SCH_LINE_LOCATE_BUS_T:
case SCH_LINE_LOCATE_GRAPHIC_LINE_T:
case SCH_ITEM_LOCATE_WIRE_T:
case SCH_ITEM_LOCATE_BUS_T:
case SCH_ITEM_LOCATE_GRAPHIC_LINE_T:
case SCH_LABEL_LOCATE_WIRE_T:
case SCH_LABEL_LOCATE_BUS_T:

View File

@ -30,12 +30,14 @@
#include <trigo.h>
#include <geometry/shape_poly_set.h>
#include <geometry/geometry_utils.h>
#include <stroke_params.h>
class LINE_READER;
class EDA_DRAW_FRAME;
class FOOTPRINT;
class MSG_PANEL_ITEM;
using KIGFX::COLOR4D;
enum class SHAPE_T : int
{
@ -75,18 +77,24 @@ public:
wxString SHAPE_T_asString() const;
void SetFillMode( FILL_T aFill ) { m_fill = aFill; }
FILL_T GetFillType() const { return m_fill; }
bool IsFilled() const { return GetFillType() != FILL_T::NO_FILL; }
bool IsFilled() const
{
return GetFillMode() != FILL_T::NO_FILL;
}
void SetFilled( bool aFlag )
{
m_fill = aFlag ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL;
}
void SetWidth( int aWidth ) { m_width = aWidth; }
int GetWidth() const { return m_width; }
void SetFillMode( FILL_T aFill ) { m_fill = aFill; }
FILL_T GetFillMode() const { return m_fill; }
COLOR4D GetFillColor() const { return m_fillColor; }
void SetFillColor( const COLOR4D& aColor ) { m_fillColor = aColor; }
void SetWidth( int aWidth ) { m_stroke.SetWidth( aWidth ); }
int GetWidth() const { return m_stroke.GetWidth(); }
void SetShape( SHAPE_T aShape ) { m_shape = aShape; }
SHAPE_T GetShape() const { return m_shape; }
@ -232,9 +240,12 @@ public:
/**
* Make a set of SHAPE objects representing the EDA_SHAPE. Caller owns the objects.
*
* @param aEdgeOnly indicates only edges should be generated (even if 0 width), and no fill
* shapes.
*/
// fixme: move to shape_compound
std::vector<SHAPE*> MakeEffectiveShapes() const;
std::vector<SHAPE*> MakeEffectiveShapes( bool aEdgeOnly = false ) const;
void ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList );
@ -294,8 +305,10 @@ protected:
protected:
bool m_endsSwapped; // true if start/end were swapped e.g. SetArcAngleAndEnd
SHAPE_T m_shape; // Shape: line, Circle, Arc
int m_width; // thickness of lines ...
STROKE_PARAMS m_stroke; // Line style, width, etc.
FILL_T m_fill;
COLOR4D m_fillColor;
wxPoint m_start; // Line start point or Circle center
wxPoint m_end; // Line end point or Circle 3 o'clock point

View File

@ -338,6 +338,7 @@ enum SCH_LAYER_ID: int
LAYER_FIELDS,
LAYER_DEVICE,
LAYER_NOTES,
LAYER_NOTES_BACKGROUND,
LAYER_PIN,
LAYER_SHEET,
LAYER_SHEETNAME,

View File

@ -38,6 +38,7 @@
#include <page_info.h>
#include <outline_mode.h>
#include <gal/color4d.h>
#include <stroke_params.h>
#include <render_settings.h>
class COLOR_SETTINGS;
@ -98,20 +99,6 @@ enum class PLOT_TEXT_MODE
DEFAULT
};
/**
* Dashed line types.
*/
enum class PLOT_DASH_TYPE
{
DEFAULT = -1,
SOLID = 0,
FIRST_TYPE = SOLID,
DASH,
DOT,
DASHDOT,
LAST_TYPE = DASHDOT
};
/**
* 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

View File

@ -203,6 +203,15 @@ public:
int GetMinPenWidth() const { return m_minPenWidth; }
void SetMinPenWidth( int aWidth ) { m_minPenWidth = aWidth; }
double GetDashLengthRatio() const { return m_dashLengthRatio; }
void SetDashLengthRatio( double aRatio ) { m_dashLengthRatio = aRatio; }
double GetDashLength( int aLineWidth ) const;
double GetDotLength( int aLineWidth ) const;
double GetGapLengthRatio() const { return m_gapLengthRatio; }
void SetGapLengthRatio( double aRatio ) { m_gapLengthRatio = aRatio; }
double GetGapLength( int aLineWidth ) const;
bool GetShowPageLimits() const { return m_showPageLimits; }
void SetShowPageLimits( bool aDraw ) { m_showPageLimits = aDraw; }
@ -309,6 +318,9 @@ protected:
int m_defaultPenWidth;
int m_minPenWidth; // Some clients (such as PDF) don't like ultra-thin
// lines. This sets an absolute minimum.
double m_dashLengthRatio;
double m_gapLengthRatio;
bool m_showPageLimits;
bool m_isPrinting;

145
include/stroke_params.h Normal file
View File

@ -0,0 +1,145 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 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
*/
#ifndef STROKE_PARAMS_H
#define STROKE_PARAMS_H
#include <map>
#include <bitmaps.h>
#include <gal/color4d.h>
#include <wx/translation.h>
#include <geometry/shape.h>
#include <stroke_params_lexer.h>
class STROKE_PARAMS_LEXER;
namespace KIGFX
{
class RENDER_SETTINGS;
}
/**
* Dashed line types.
*/
enum class PLOT_DASH_TYPE
{
DEFAULT = -1,
SOLID = 0,
FIRST_TYPE = SOLID,
DASH,
DOT,
DASHDOT,
LAST_TYPE = DASHDOT
};
struct lineTypeStruct
{
wxString name;
const BITMAPS bitmap;
};
/*
* Conversion map between PLOT_DASH_TYPE values and style names displayed
*/
const std::map<PLOT_DASH_TYPE, struct lineTypeStruct> lineTypeNames =
{
{ PLOT_DASH_TYPE::SOLID, { _( "Solid" ), BITMAPS::stroke_solid } },
{ PLOT_DASH_TYPE::DASH, { _( "Dashed" ), BITMAPS::stroke_dash } },
{ PLOT_DASH_TYPE::DOT, { _( "Dotted" ), BITMAPS::stroke_dot } },
{ PLOT_DASH_TYPE::DASHDOT, { _( "Dash-Dot" ), BITMAPS::stroke_dashdot } }
};
#define DEFAULT_STYLE _( "Default" )
#define INDETERMINATE_STYLE _( "Leave unchanged" )
/**
* Simple container to manage line stroke parameters.
*/
class STROKE_PARAMS
{
public:
STROKE_PARAMS( int aWidth = 0, PLOT_DASH_TYPE aPlotStyle = PLOT_DASH_TYPE::DEFAULT,
const KIGFX::COLOR4D& aColor = KIGFX::COLOR4D::UNSPECIFIED ) :
m_width( aWidth ),
m_plotstyle( aPlotStyle ),
m_color( aColor )
{
}
int GetWidth() const { return m_width; }
void SetWidth( int aWidth ) { m_width = aWidth; }
PLOT_DASH_TYPE GetPlotStyle() const { return m_plotstyle; }
void SetPlotStyle( PLOT_DASH_TYPE aPlotStyle ) { m_plotstyle = aPlotStyle; }
KIGFX::COLOR4D GetColor() const { return m_color; }
void SetColor( const KIGFX::COLOR4D& aColor ) { m_color = aColor; }
bool operator!=( const STROKE_PARAMS& aOther )
{
return m_width != aOther.m_width
|| m_plotstyle != aOther.m_plotstyle
|| m_color != aOther.m_color;
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) const;
// Helper functions
static void Stroke( const SHAPE* aShape, PLOT_DASH_TYPE aLineStyle, int aWidth,
const KIGFX::RENDER_SETTINGS* aRenderSettings,
std::function<void( const wxPoint& a, const wxPoint& b )> aStroker );
private:
int m_width;
PLOT_DASH_TYPE m_plotstyle;
KIGFX::COLOR4D m_color;
};
class STROKE_PARAMS_PARSER : public STROKE_PARAMS_LEXER
{
public:
STROKE_PARAMS_PARSER( LINE_READER* aReader, int iuPerMM ) :
STROKE_PARAMS_LEXER( aReader ),
m_iuPerMM( iuPerMM )
{
}
void ParseStroke( STROKE_PARAMS& aStroke );
private:
int parseInt( const char* aText );
double parseDouble( const char* aText );
private:
int m_iuPerMM;
};
#endif // STROKE_PARAMS_H

View File

@ -149,24 +149,5 @@ VECTOR2<T> GetVectorSnapped45( const VECTOR2<T>& aVec, bool only45 = false )
bool ClipLine( const EDA_RECT *aClipBox, int &x1, int &y1, int &x2, int &y2 );
/**
* Dashed and dotted line patterns.
*/
constexpr double dot_mark_len( double aLineWidth )
{
return std::max( 1.0, aLineWidth );
}
constexpr double dash_gap_len( double aLineWidth )
{
return 3.0 * dot_mark_len( aLineWidth ) + ( 2.0 * aLineWidth );
}
constexpr double dash_mark_len( double aLineWidth )
{
return std::max( dash_gap_len( aLineWidth ), 5.0 * dot_mark_len( aLineWidth ) );
}
#endif // #ifndef GEOMETRY_UTILS_H

View File

@ -30,6 +30,7 @@
#include <i18n_utility.h>
#include <macros.h>
#include <board.h>
#include <board_design_settings.h>
#include <pcb_group.h>
@ -72,6 +73,18 @@ bool BOARD_ITEM::IsLocked() const
}
STROKE_PARAMS BOARD_ITEM::GetStroke() const
{
wxCHECK( false, STROKE_PARAMS( Millimeter2iu( DEFAULT_LINE_WIDTH ) ) );
}
void BOARD_ITEM::SetStroke( const STROKE_PARAMS& aStroke )
{
wxCHECK( false, /* void */ );
}
wxString BOARD_ITEM::GetLayerName() const
{
const BOARD* board = GetBoard();

View File

@ -745,8 +745,7 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
break;
default:
wxFAIL_MSG( "ConvertOutlineToPolygon not implemented for "
+ graphic->SHAPE_T_asString() );
UNIMPLEMENTED_FOR( graphic->SHAPE_T_asString() );
return false;
}

View File

@ -320,7 +320,11 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::processItem( BOARD_COMMIT& aCommit, B
if( !m_lineWidth.IsIndeterminate() )
{
if( drawItem )
drawItem->SetWidth( m_lineWidth.GetValue() );
{
STROKE_PARAMS stroke = drawItem->GetStroke();
stroke.SetWidth( m_lineWidth.GetValue() );
drawItem->SetStroke( stroke );
}
if( dimension )
dimension->SetLineThickness( m_lineWidth.GetValue() );
@ -341,7 +345,11 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::processItem( BOARD_COMMIT& aCommit, B
fpTextItem->SetKeepUpright( m_brdSettings->GetTextUpright( layer ) );
if( drawItem )
drawItem->SetWidth( m_brdSettings->GetLineThickness( layer ) );
{
STROKE_PARAMS stroke = drawItem->GetStroke();
stroke.SetWidth( m_brdSettings->GetLineThickness( layer ) );
drawItem->SetStroke( stroke );
}
if( dimension )
dimension->SetLineThickness( m_brdSettings->GetLineThickness( layer ) );

View File

@ -338,7 +338,11 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow()
m_item->SetFilled( m_filledCtrl->GetValue() );
m_item->SetLocked( m_locked->GetValue() );
m_item->SetWidth( m_thickness.GetValue() );
STROKE_PARAMS stroke = m_item->GetStroke();
stroke.SetWidth( m_thickness.GetValue() );
m_item->SetStroke( stroke );
m_item->SetLayer( ToLAYER_ID( layer ) );
m_item->RebuildBezierToSegmentsPointsList( m_item->GetWidth() );

View File

@ -181,7 +181,10 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow()
}
// Transfer data out of the GUI.
m_shape->SetWidth( m_thickness.GetValue() );
STROKE_PARAMS stroke = m_shape->GetStroke();
stroke.SetWidth( m_thickness.GetValue() );
m_shape->SetStroke( stroke );
m_shape->SetFilled( m_filledCtrl->GetValue() );
switch( m_shape->GetShape() )
@ -311,7 +314,11 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::TransferDataFromWindow()
return false;
m_shape->SetPolyPoints( m_currPoints );
m_shape->SetWidth( m_thickness.GetValue() );
STROKE_PARAMS stroke = m_shape->GetStroke();
stroke.SetWidth( m_thickness.GetValue() );
m_shape->SetStroke( stroke );
m_shape->SetFilled( m_filledCtrl->GetValue() );
return true;
@ -616,7 +623,10 @@ void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<std::shared_ptr<PCB
}
// Transform parameters common to all shape types (some can be unused)
shape->SetWidth( KiROUND( shape->GetWidth() * scale ) );
STROKE_PARAMS stroke = shape->GetStroke();
stroke.SetWidth( KiROUND( shape->GetWidth() * scale ) );
shape->SetStroke( stroke );
shape->Move( currMoveVect );
shape->Scale( scale );
shape->Rotate( wxPoint( 0, 0 ), curr_rotation );

View File

@ -2142,7 +2142,8 @@ void DIALOG_PAD_PROPERTIES::onAddPrimitive( wxCommandEvent& event )
PCB_SHAPE* primitive = new PCB_SHAPE();
primitive->SetShape( listtype[type] );
primitive->SetWidth( m_board->GetDesignSettings().GetLineThickness( F_Cu ) );
primitive->SetStroke( STROKE_PARAMS( m_board->GetDesignSettings().GetLineThickness( F_Cu ),
PLOT_DASH_TYPE::SOLID ) );
primitive->SetFilled( true );
if( listtype[type] == SHAPE_T::POLY )

View File

@ -148,7 +148,8 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
auto queryBoardOutlineItems =
[&]( BOARD_ITEM *item ) -> bool
{
PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
STROKE_PARAMS stroke( 0 );
if( shape->GetShape() == SHAPE_T::RECT )
{
@ -157,19 +158,19 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetEndX( shape->GetStartX() );
edges.back()->SetWidth( 0 );
edges.back()->SetStroke( stroke );
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetEndY( shape->GetStartY() );
edges.back()->SetWidth( 0 );
edges.back()->SetStroke( stroke );
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetStartX( shape->GetEndX() );
edges.back()->SetWidth( 0 );
edges.back()->SetStroke( stroke );
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetStartY( shape->GetEndY() );
edges.back()->SetWidth( 0 );
edges.back()->SetStroke( stroke );
return true;
}
else if( shape->GetShape() == SHAPE_T::POLY )
@ -185,12 +186,12 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetStart((wxPoint) seg.A );
edges.back()->SetEnd((wxPoint) seg.B );
edges.back()->SetWidth( 0 );
edges.back()->SetStroke( stroke );
}
}
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetWidth( 0 );
edges.back()->SetStroke( stroke );
return true;
};

View File

@ -22,6 +22,7 @@
*/
#include <kiway.h>
#include <macros.h>
#include <netlist_reader/pcb_netlist.h>
#include <fp_lib_table.h>
#include <board.h>

View File

@ -442,7 +442,7 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
switch( pad->GetShape() )
{
default:
wxASSERT_MSG( false, "Pad type not implemented" );
UNIMPLEMENTED_FOR( pad->ShowPadShape() );
KI_FALLTHROUGH;
case PAD_SHAPE::CIRCLE:

View File

@ -103,7 +103,7 @@ void FP_SHAPE::SetDrawCoord()
m_bezierC2 += fp->GetPosition();
}
RebuildBezierToSegmentsPointsList( m_width );
RebuildBezierToSegmentsPointsList( GetWidth() );
}
@ -247,7 +247,7 @@ void FP_SHAPE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
}
if( GetShape() == SHAPE_T::BEZIER )
RebuildBezierToSegmentsPointsList( m_width );
RebuildBezierToSegmentsPointsList( GetWidth() );
if( GetShape() == SHAPE_T::ARC )
{
@ -306,7 +306,7 @@ void FP_SHAPE::Mirror( const wxPoint& aCentre, bool aMirrorAroundXAxis )
}
if( GetShape() == SHAPE_T::BEZIER )
RebuildBezierToSegmentsPointsList( m_width );
RebuildBezierToSegmentsPointsList( GetWidth() );
break;

View File

@ -308,7 +308,7 @@ void GRAPHICS_CLEANER::mergeRects()
rect->SetStart( top->start );
rect->SetEnd( bottom->end );
rect->SetLayer( top->shape->GetLayer() );
rect->SetWidth( top->shape->GetWidth() );
rect->SetStroke( top->shape->GetStroke() );
m_commit.Add( rect );
m_commit.Remove( left->shape );

View File

@ -59,12 +59,13 @@ int GRAPHICS_IMPORTER_PCBNEW::MapLineWidth( double aLineWidth )
}
void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd, double aWidth )
void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D& aEnd,
double aWidth )
{
std::unique_ptr<PCB_SHAPE> line( createDrawing() );
line->SetShape( SHAPE_T::SEGMENT );
line->SetLayer( GetLayer() );
line->SetWidth( MapLineWidth( aWidth ) );
line->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
line->SetStart( MapCoordinate( aOrigin ) );
line->SetEnd( MapCoordinate( aEnd ) );
@ -75,13 +76,14 @@ void GRAPHICS_IMPORTER_PCBNEW::AddLine( const VECTOR2D& aOrigin, const VECTOR2D&
}
void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth, bool aFilled )
void GRAPHICS_IMPORTER_PCBNEW::AddCircle( const VECTOR2D& aCenter, double aRadius, double aWidth,
bool aFilled )
{
std::unique_ptr<PCB_SHAPE> circle( createDrawing() );
circle->SetShape( SHAPE_T::CIRCLE );
circle->SetFilled( aFilled );
circle->SetLayer( GetLayer() );
circle->SetWidth( MapLineWidth( aWidth ) );
circle->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
circle->SetStart( MapCoordinate( aCenter ));
circle->SetEnd( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) );
@ -111,7 +113,7 @@ void GRAPHICS_IMPORTER_PCBNEW::AddArc( const VECTOR2D& aCenter, const VECTOR2D&
arc->SetArcGeometry( MapCoordinate( aStart ), MapCoordinate( mid ), MapCoordinate( end ) );
arc->SetWidth( MapLineWidth( aWidth ) );
arc->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
if( arc->Type() == PCB_FP_SHAPE_T )
static_cast<FP_SHAPE*>( arc.get() )->SetLocalCoord();
@ -137,14 +139,15 @@ void GRAPHICS_IMPORTER_PCBNEW::AddPolygon( const std::vector< VECTOR2D >& aVerti
if( polygon->Type() == PCB_FP_SHAPE_T )
static_cast<FP_SHAPE*>( polygon.get() )->SetLocalCoord();
polygon->SetWidth( MapLineWidth( aWidth ) );
polygon->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
addItem( std::move( polygon ) );
}
void GRAPHICS_IMPORTER_PCBNEW::AddText( const VECTOR2D& aOrigin, const wxString& aText,
double aHeight, double aWidth, double aThickness, double aOrientation,
EDA_TEXT_HJUSTIFY_T aHJustify, EDA_TEXT_VJUSTIFY_T aVJustify )
double aHeight, double aWidth, double aThickness,
double aOrientation, EDA_TEXT_HJUSTIFY_T aHJustify,
EDA_TEXT_VJUSTIFY_T aVJustify )
{
std::unique_ptr<BOARD_ITEM> boardItem;
EDA_TEXT* textItem;
@ -167,12 +170,13 @@ 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 )
const VECTOR2D& BezierControl2, const VECTOR2D& aEnd,
double aWidth )
{
std::unique_ptr<PCB_SHAPE> spline( createDrawing() );
spline->SetShape( SHAPE_T::BEZIER );
spline->SetLayer( GetLayer() );
spline->SetWidth( MapLineWidth( aWidth ) );
spline->SetStroke( STROKE_PARAMS( MapLineWidth( aWidth ), PLOT_DASH_TYPE::SOLID ) );
spline->SetStart( MapCoordinate( aStart ) );
spline->SetBezierC1( MapCoordinate( BezierControl1 ));
spline->SetBezierC2( MapCoordinate( BezierControl2 ));

View File

@ -427,7 +427,7 @@ FOOTPRINT* MICROWAVE_TOOL::createMicrowaveInductor( MICROWAVE_INDUCTOR_PATTERN&
FP_SHAPE* seg = new FP_SHAPE( footprint, SHAPE_T::SEGMENT );
seg->SetStart( buffer[jj - 1] );
seg->SetEnd( buffer[jj] );
seg->SetWidth( aInductorPattern.m_Width );
seg->SetStroke( STROKE_PARAMS( aInductorPattern.m_Width, PLOT_DASH_TYPE::SOLID ) );
seg->SetLayer( footprint->GetLayer() );
seg->SetStart0( seg->GetStart() - footprint->GetPosition() );
seg->SetEnd0( seg->GetEnd() - footprint->GetPosition() );

View File

@ -389,7 +389,7 @@ FOOTPRINT* MICROWAVE_TOOL::createPolygonShape()
// Set the polygon outline thickness to 0, only the polygonal shape is filled
// without extra thickness.
shape->SetWidth( 0 );
shape->SetStroke( STROKE_PARAMS( 0, PLOT_DASH_TYPE::SOLID ) );
g_PolyEdges.clear();
editFrame.OnModify();

View File

@ -48,7 +48,7 @@ void PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aF
item->SetShape( SHAPE_T::POLY );
item->SetFilled( aFilled );
item->SetPolyShape( poly_no_hole );
item->SetWidth( aThickness );
item->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
SetDirty();
@ -60,7 +60,7 @@ void PAD::AddPrimitivePoly( const std::vector<wxPoint>& aPoly, int aThickness, b
PCB_SHAPE* item = new PCB_SHAPE( nullptr, SHAPE_T::POLY );
item->SetFilled( aFilled );
item->SetPolyPoints( aPoly );
item->SetWidth( aThickness );
item->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
SetDirty();
@ -73,7 +73,7 @@ void PAD::AddPrimitiveSegment( const wxPoint& aStart, const wxPoint& aEnd, int a
item->SetFilled( false );
item->SetStart( aStart );
item->SetEnd( aEnd );
item->SetWidth( aThickness );
item->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
SetDirty();
@ -88,7 +88,7 @@ void PAD::AddPrimitiveArc( const wxPoint& aCenter, const wxPoint& aStart, int aA
item->SetCenter( aCenter );
item->SetStart( aStart );
item->SetArcAngleAndEnd( aArcAngle );
item->SetWidth( aThickness );
item->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
SetDirty();
@ -104,7 +104,7 @@ void PAD::AddPrimitiveCurve( const wxPoint& aStart, const wxPoint& aEnd, const w
item->SetEnd( aEnd );
item->SetBezierC1( aCtrl1 );
item->SetBezierC2( aCtrl2 );
item->SetWidth( aThickness );
item->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
SetDirty();
@ -117,7 +117,7 @@ void PAD::AddPrimitiveCircle( const wxPoint& aCenter, int aRadius, int aThicknes
item->SetFilled( aFilled );
item->SetStart( aCenter );
item->SetEnd( wxPoint( aCenter.x + aRadius, aCenter.y ) );
item->SetWidth( aThickness );
item->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
SetDirty();
@ -131,7 +131,7 @@ void PAD::AddPrimitiveRect( const wxPoint& aStart, const wxPoint& aEnd, int aThi
item->SetFilled( aFilled );
item->SetStart( aStart );
item->SetEnd( aEnd );
item->SetWidth( aThickness );
item->SetStroke( STROKE_PARAMS( aThickness, PLOT_DASH_TYPE::SOLID ) );
item->SetParent( this );
m_editPrimitives.emplace_back( item );
SetDirty();

View File

@ -254,8 +254,9 @@ static struct PCB_SHAPE_DESC
propMgr.InheritsAfter( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( BOARD_ITEM ) );
propMgr.InheritsAfter( TYPE_HASH( PCB_SHAPE ), TYPE_HASH( EDA_SHAPE ) );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Thickness" ),
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::DISTANCE ) );
// JEY TODO:
//propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Thickness" ),
// &EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::DISTANCE ) );
// TODO show certain properties depending on the shape
//propMgr.AddProperty( new PROPERTY<PCB_SHAPE, double>( _HKI( "Angle" ),
// &PCB_SHAPE::SetArcAngle, &PCB_SHAPE::GetAngle, PROPERTY_DISPLAY::DECIDEGREE ) );

View File

@ -78,6 +78,11 @@ public:
wxPoint GetCenter() const override { return getCenter(); }
bool HasLineStroke() const override { return true; }
STROKE_PARAMS GetStroke() const override { return m_stroke; }
void SetStroke( const STROKE_PARAMS& aStroke ) override { m_stroke = aStroke; }
/**
* Allows items to return their visual center rather than their anchor. For some shapes this
* is similar to GetCenter(), but for unfilled shapes a point on the outline is better.

View File

@ -319,7 +319,7 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aSrcPr
}
else if( ext == FootprintAssignmentFileExtension )
{
// JEY TODO
// TODO
}
else if( ext == "rpt" )
{

View File

@ -421,7 +421,7 @@ void BRDITEMS_PLOTTER::PlotDimension( const PCB_DIMENSION_BASE* aDim )
PCB_SHAPE draw;
draw.SetWidth( aDim->GetLineThickness() );
draw.SetStroke( STROKE_PARAMS( aDim->GetLineThickness(), PLOT_DASH_TYPE::SOLID ) );
draw.SetLayer( aDim->GetLayer() );
COLOR4D color = ColorSettings()->GetColor( aDim->GetLayer() );
@ -482,7 +482,7 @@ void BRDITEMS_PLOTTER::PlotPcbTarget( const PCB_TARGET* aMire )
draw.SetShape( SHAPE_T::CIRCLE );
draw.SetFilled( false );
draw.SetWidth( aMire->GetWidth() );
draw.SetStroke( STROKE_PARAMS( aMire->GetWidth(), PLOT_DASH_TYPE::SOLID ) );
draw.SetLayer( aMire->GetLayer() );
draw.SetStart( aMire->GetPosition() );
radius = aMire->GetSize() / 3;

View File

@ -848,6 +848,9 @@ void ALTIUM_PCB::HelperCreateBoardOutline( const std::vector<ALTIUM_VERTICE>& aV
if( !aVertices.empty() )
{
const ALTIUM_VERTICE* last = &aVertices.at( 0 );
STROKE_PARAMS stroke( m_board->GetDesignSettings().GetLineThickness( Edge_Cuts ),
PLOT_DASH_TYPE::SOLID );
for( size_t i = 0; i < aVertices.size(); i++ )
{
const ALTIUM_VERTICE* cur = &aVertices.at( ( i + 1 ) % aVertices.size() );
@ -855,7 +858,7 @@ void ALTIUM_PCB::HelperCreateBoardOutline( const std::vector<ALTIUM_VERTICE>& aV
PCB_SHAPE* shape = new PCB_SHAPE( m_board );
m_board->Add( shape, ADD_MODE::APPEND );
shape->SetWidth( m_board->GetDesignSettings().GetLineThickness( Edge_Cuts ) );
shape->SetStroke( stroke );
shape->SetLayer( Edge_Cuts );
if( !last->isRound && !cur->isRound )
@ -887,7 +890,7 @@ void ALTIUM_PCB::HelperCreateBoardOutline( const std::vector<ALTIUM_VERTICE>& aV
PCB_SHAPE* shape2 = new PCB_SHAPE( m_board, SHAPE_T::SEGMENT );
m_board->Add( shape2, ADD_MODE::APPEND );
shape2->SetWidth( m_board->GetDesignSettings().GetLineThickness( Edge_Cuts ) );
shape2->SetStroke( stroke );
shape2->SetLayer( Edge_Cuts );
shape2->SetStart( last->position );
@ -1245,7 +1248,7 @@ void ALTIUM_PCB::HelperParseDimensions6Leader( const ADIMENSION6& aElem )
PCB_SHAPE* shape = new PCB_SHAPE( m_board, SHAPE_T::SEGMENT );
m_board->Add( shape, ADD_MODE::APPEND );
shape->SetLayer( klayer );
shape->SetWidth( aElem.linewidth );
shape->SetStroke( STROKE_PARAMS( aElem.linewidth, PLOT_DASH_TYPE::SOLID ) );
shape->SetStart( last );
shape->SetEnd( aElem.referencePoint.at( i ) );
last = aElem.referencePoint.at( i );
@ -1265,7 +1268,7 @@ void ALTIUM_PCB::HelperParseDimensions6Leader( const ADIMENSION6& aElem )
PCB_SHAPE* shape1 = new PCB_SHAPE( m_board, SHAPE_T::SEGMENT );
m_board->Add( shape1, ADD_MODE::APPEND );
shape1->SetLayer( klayer );
shape1->SetWidth( aElem.linewidth );
shape1->SetStroke( STROKE_PARAMS( aElem.linewidth, PLOT_DASH_TYPE::SOLID ) );
shape1->SetStart( referencePoint0 );
shape1->SetEnd( referencePoint0 + arrVec );
@ -1274,7 +1277,7 @@ void ALTIUM_PCB::HelperParseDimensions6Leader( const ADIMENSION6& aElem )
PCB_SHAPE* shape2 = new PCB_SHAPE( m_board, SHAPE_T::SEGMENT );
m_board->Add( shape2, ADD_MODE::APPEND );
shape2->SetLayer( klayer );
shape2->SetWidth( aElem.linewidth );
shape2->SetStroke( STROKE_PARAMS( aElem.linewidth, PLOT_DASH_TYPE::SOLID ) );
shape2->SetStart( referencePoint0 );
shape2->SetEnd( referencePoint0 + arrVec );
}
@ -1316,7 +1319,7 @@ void ALTIUM_PCB::HelperParseDimensions6Datum( const ADIMENSION6& aElem )
PCB_SHAPE* shape = new PCB_SHAPE( m_board, SHAPE_T::SEGMENT );
m_board->Add( shape, ADD_MODE::APPEND );
shape->SetLayer( klayer );
shape->SetWidth( aElem.linewidth );
shape->SetStroke( STROKE_PARAMS( aElem.linewidth, PLOT_DASH_TYPE::SOLID ) );
shape->SetStart( aElem.referencePoint.at( i ) );
// shape->SetEnd( /* TODO: seems to be based on TEXTY */ );
}
@ -1795,7 +1798,7 @@ void ALTIUM_PCB::ParseShapeBasedRegions6Data( const CFB::CompoundFileReader& aRe
m_board->Add( shape, ADD_MODE::APPEND );
shape->SetFilled( true );
shape->SetLayer( klayer );
shape->SetWidth( 0 );
shape->SetStroke( STROKE_PARAMS( 0 ) );
shape->SetPolyShape( linechain );
}
@ -1926,7 +1929,7 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
if( elem.is_keepout || IsAltiumLayerAPlane( elem.layer ) )
{
PCB_SHAPE shape( nullptr ); // just a helper to get the graphic
shape.SetWidth( elem.width );
shape.SetStroke( STROKE_PARAMS( elem.width, PLOT_DASH_TYPE::SOLID ) );
if( elem.startangle == 0. && elem.endangle == 360. )
{ // TODO: other variants to define circle?
@ -2031,7 +2034,7 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
else
{
PCB_SHAPE* shape = HelperCreateAndAddShape( elem.component );
shape->SetWidth( elem.width );
shape->SetStroke( STROKE_PARAMS( elem.width, PLOT_DASH_TYPE::SOLID ) );
shape->SetLayer( klayer );
if( elem.startangle == 0. && elem.endangle == 360. )
@ -2329,7 +2332,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem )
shape->SetShape( SHAPE_T::POLY );
shape->SetFilled( true );
shape->SetLayer( klayer );
shape->SetWidth( 0 );
shape->SetStroke( STROKE_PARAMS( 0 ) );
shape->SetPolyPoints( { aElem.position + wxPoint( aElem.topsize.x / 2, aElem.topsize.y / 2 ),
aElem.position + wxPoint( aElem.topsize.x / 2, -aElem.topsize.y / 2 ),
@ -2353,7 +2356,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem )
PCB_SHAPE* shape = HelperCreateAndAddShape( aElem.component );
shape->SetLayer( klayer );
shape->SetWidth( offset * 2 );
shape->SetStroke( STROKE_PARAMS( offset * 2, PLOT_DASH_TYPE::SOLID ) );
if( cornerradius < 100 )
{
@ -2376,7 +2379,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem )
shape->SetFilled( true );
shape->SetStart( aElem.position );
shape->SetEnd( aElem.position - wxPoint( 0, aElem.topsize.x / 4 ) );
shape->SetWidth( aElem.topsize.x / 2 );
shape->SetStroke( STROKE_PARAMS( aElem.topsize.x / 2, PLOT_DASH_TYPE::SOLID ) );
}
else if( aElem.topsize.x < aElem.topsize.y )
{
@ -2409,7 +2412,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem )
shape->SetLayer( klayer );
shape->SetStart( aElem.position );
shape->SetEnd( aElem.position - wxPoint( 0, aElem.topsize.x / 4 ) );
shape->SetWidth( aElem.topsize.x / 2 );
shape->SetStroke( STROKE_PARAMS( aElem.topsize.x / 2, PLOT_DASH_TYPE::SOLID ) );
HelperShapeSetLocalCoord( shape, aElem.component );
}
else
@ -2418,7 +2421,8 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem )
PCB_SHAPE* shape = HelperCreateAndAddShape( aElem.component );
shape->SetShape( SHAPE_T::SEGMENT );
shape->SetLayer( klayer );
shape->SetWidth( std::min( aElem.topsize.x, aElem.topsize.y ) );
shape->SetStroke( STROKE_PARAMS( std::min( aElem.topsize.x, aElem.topsize.y ),
PLOT_DASH_TYPE::SOLID ) );
if( aElem.topsize.x < aElem.topsize.y )
{
@ -2447,7 +2451,7 @@ void ALTIUM_PCB::HelperParsePad6NonCopper( const APAD6& aElem )
shape->SetShape( SHAPE_T::POLY );
shape->SetFilled( true );
shape->SetLayer( klayer );
shape->SetWidth( 0 );
shape->SetStroke( STROKE_PARAMS( 0 ) );
wxPoint p11 = aElem.position + wxPoint( aElem.topsize.x / 2, aElem.topsize.y / 2 );
wxPoint p12 = aElem.position + wxPoint( aElem.topsize.x / 2, -aElem.topsize.y / 2 );
@ -2564,7 +2568,7 @@ void ALTIUM_PCB::ParseTracks6Data( const CFB::CompoundFileReader& aReader,
PCB_SHAPE shape( nullptr, SHAPE_T::SEGMENT );
shape.SetStart( elem.start );
shape.SetEnd( elem.end );
shape.SetWidth( elem.width );
shape.SetStroke( STROKE_PARAMS( elem.width, PLOT_DASH_TYPE::SOLID ) );
ZONE* zone = new ZONE( m_board );
m_board->Add( zone, ADD_MODE::APPEND );
@ -2612,7 +2616,7 @@ void ALTIUM_PCB::ParseTracks6Data( const CFB::CompoundFileReader& aReader,
klayer = Eco1_User;
}
if( klayer >= F_Cu && klayer <= B_Cu )
if( IsCopperLayer( klayer ) )
{
PCB_TRACK* track = new PCB_TRACK( m_board );
m_board->Add( track, ADD_MODE::APPEND );
@ -2629,7 +2633,7 @@ void ALTIUM_PCB::ParseTracks6Data( const CFB::CompoundFileReader& aReader,
shape->SetShape( SHAPE_T::SEGMENT );
shape->SetStart( elem.start );
shape->SetEnd( elem.end );
shape->SetWidth( elem.width );
shape->SetStroke( STROKE_PARAMS( elem.width, PLOT_DASH_TYPE::SOLID ) );
shape->SetLayer( klayer );
HelperShapeSetLocalCoord( shape, elem.component );
}
@ -2915,7 +2919,7 @@ void ALTIUM_PCB::ParseFills6Data( const CFB::CompoundFileReader& aReader,
m_board->Add( shape, ADD_MODE::APPEND );
shape->SetFilled( true );
shape->SetLayer( klayer );
shape->SetWidth( 0 );
shape->SetStroke( STROKE_PARAMS( 0 ) );
shape->SetPolyPoints( { p11, p12, p22, p21 } );

View File

@ -1179,7 +1179,7 @@ PAD* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad( const COMPONENT_PAD& aCadstarPad,
padShape->SetShape( SHAPE_T::POLY );
padShape->SetFilled( true );
padShape->SetPolyShape( padOutline );
padShape->SetWidth( 0 );
padShape->SetStroke( STROKE_PARAMS( 0 ) );
padShape->Move( padOffset - drillOffset );
padShape->Rotate( wxPoint( 0, 0 ),
1800.0 - getAngleTenthDegree( csPadcode.SlotOrientation ) );
@ -2436,7 +2436,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadNetTracks( const NET_ID& aCadstarNe
{
PCB_SHAPE* shape = getShapeFromVertex( prevEnd, v.Vertex );
shape->SetLayer( getKiCadLayer( aCadstarRoute.LayerID ) );
shape->SetWidth( getKiCadLength( v.RouteWidth ) );
shape->SetStroke( STROKE_PARAMS( getKiCadLength( v.RouteWidth ), PLOT_DASH_TYPE::SOLID ) );
shape->SetLocked( v.Fixed );
shapes.push_back( shape );
prevEnd = v.Vertex.End;
@ -2695,14 +2695,15 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape( const SHAPE& aCadstarShape,
shape->SetFilled( true );
SHAPE_POLY_SET shapePolys = getPolySetFromCadstarShape(
aCadstarShape, -1, aContainer, aMoveVector, aRotationAngle, aScalingFactor,
aTransformCentre, aMirrorInvert );
SHAPE_POLY_SET shapePolys = getPolySetFromCadstarShape( aCadstarShape, -1, aContainer,
aMoveVector, aRotationAngle,
aScalingFactor, aTransformCentre,
aMirrorInvert );
shapePolys.Fracture( SHAPE_POLY_SET::POLYGON_MODE::PM_STRICTLY_SIMPLE );
shape->SetPolyShape( shapePolys );
shape->SetWidth( aLineThickness );
shape->SetStroke( STROKE_PARAMS( aLineThickness, PLOT_DASH_TYPE::SOLID ) );
shape->SetLayer( aKiCadLayer );
aContainer->Add( shape, ADD_MODE::APPEND );
@ -2752,7 +2753,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarVerticesAsShapes( const std::vector<
for( PCB_SHAPE* shape : shapes )
{
shape->SetWidth( aLineThickness );
shape->SetStroke( STROKE_PARAMS( aLineThickness, PLOT_DASH_TYPE::SOLID ) );
shape->SetLayer( aKiCadLayer );
shape->SetParent( aContainer );
aContainer->Add( shape, ADD_MODE::APPEND );

View File

@ -730,7 +730,7 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
}
shape->SetLayer( layer );
shape->SetWidth( width );
shape->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
}
m_xpath->pop();
@ -912,7 +912,7 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
shape->SetLayer( layer );
shape->SetStart( wxPoint( kicad_x( c.x ), kicad_y( c.y ) ) );
shape->SetEnd( wxPoint( kicad_x( c.x ) + radius, kicad_y( c.y ) ) );
shape->SetWidth( width );
shape->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
}
}
@ -1804,7 +1804,7 @@ void EAGLE_PLUGIN::packageWire( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const
}
dwg->SetLayer( layer );
dwg->SetWidth( width );
dwg->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
dwg->SetDrawCoord();
aFootprint->Add( dwg );
@ -2076,7 +2076,7 @@ void EAGLE_PLUGIN::packageRectangle( FOOTPRINT* aFootprint, wxXmlNode* aTree ) c
aFootprint->Add( dwg );
dwg->SetLayer( layer );
dwg->SetWidth( 0 );
dwg->SetStroke( STROKE_PARAMS( 0 ) );
dwg->SetFilled( true );
std::vector<wxPoint> pts;
@ -2189,7 +2189,7 @@ void EAGLE_PLUGIN::packagePolygon( FOOTPRINT* aFootprint, wxXmlNode* aTree ) con
aFootprint->Add( dwg );
dwg->SetWidth( 0 ); // it's filled, no need for boundary width
dwg->SetStroke( STROKE_PARAMS( 0 ) );
dwg->SetFilled( true );
dwg->SetLayer( layer );
@ -2269,7 +2269,7 @@ void EAGLE_PLUGIN::packageCircle( FOOTPRINT* aFootprint, wxXmlNode* aTree ) cons
}
aFootprint->Add( gr );
gr->SetWidth( width );
gr->SetStroke( STROKE_PARAMS( width, PLOT_DASH_TYPE::SOLID ) );
switch( (int) layer )
{

View File

@ -2083,6 +2083,8 @@ bool FABMASTER::loadFootprints( BOARD* aBoard )
if( IsPcbLayer( getLayer( seg->layer ) ) )
layer = getLayer( seg->layer );
STROKE_PARAMS defaultStroke( ds.GetLineThickness( layer ) );
switch( seg->shape )
{
@ -2105,11 +2107,11 @@ bool FABMASTER::loadFootprints( BOARD* aBoard )
line->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
}
line->SetWidth( lsrc->width );
line->SetStroke( STROKE_PARAMS( lsrc->width, PLOT_DASH_TYPE::SOLID ) );
line->SetLocalCoord();
if( lsrc->width == 0 )
line->SetWidth( ds.GetLineThickness( line->GetLayer() ) );
line->SetStroke( defaultStroke );
fp->Add( line, ADD_MODE::APPEND );
break;
@ -2145,11 +2147,11 @@ bool FABMASTER::loadFootprints( BOARD* aBoard )
arc->SetArcGeometry( (wxPoint) lsrc->result.GetP0(),
(wxPoint) lsrc->result.GetArcMid(),
(wxPoint) lsrc->result.GetP1() );
arc->SetWidth( lsrc->width );
arc->SetStroke( STROKE_PARAMS( lsrc->width, PLOT_DASH_TYPE::SOLID ) );
arc->SetLocalCoord();
if( lsrc->width == 0 )
arc->SetWidth( ds.GetLineThickness( arc->GetLayer() ) );
arc->SetStroke( defaultStroke );
if( src->mirror )
arc->Flip( arc->GetCenter(), false );
@ -2177,7 +2179,7 @@ bool FABMASTER::loadFootprints( BOARD* aBoard )
rect->SetEnd( wxPoint( lsrc->end_x, lsrc->end_y ) );
}
rect->SetWidth( ds.GetLineThickness( rect->GetLayer() ) );
rect->SetStroke( defaultStroke );
rect->SetLocalCoord();
fp->Add( rect, ADD_MODE::APPEND );
@ -2626,7 +2628,8 @@ bool FABMASTER::loadPolygon( BOARD* aBoard, const std::unique_ptr<FABMASTER::TRA
if( poly_outline.OutlineCount() < 1 || poly_outline.COutline( 0 ).PointCount() < 3 )
return false;
PCB_SHAPE* new_poly = new PCB_SHAPE( aBoard );
STROKE_PARAMS defaultStroke( aBoard->GetDesignSettings().GetLineThickness( layer ) );
PCB_SHAPE* new_poly = new PCB_SHAPE( aBoard );
new_poly->SetShape( SHAPE_T::POLY );
new_poly->SetLayer( layer );
@ -2635,14 +2638,15 @@ bool FABMASTER::loadPolygon( BOARD* aBoard, const std::unique_ptr<FABMASTER::TRA
if( layer == F_SilkS || layer == B_SilkS )
{
new_poly->SetFilled( true );
new_poly->SetWidth( 0 );
new_poly->SetStroke( STROKE_PARAMS( 0 ) );
}
else
{
new_poly->SetWidth( ( *( aLine->segment.begin() ) )->width );
new_poly->SetStroke( STROKE_PARAMS( ( *( aLine->segment.begin() ) )->width,
PLOT_DASH_TYPE::SOLID ) );
if( new_poly->GetWidth() == 0 )
new_poly->SetWidth( aBoard->GetDesignSettings().GetLineThickness( layer ) );
new_poly->SetStroke( defaultStroke );
}
new_poly->SetPolyShape( poly_outline );
@ -2765,6 +2769,8 @@ bool FABMASTER::loadOutline( BOARD* aBoard, const std::unique_ptr<FABMASTER::TRA
else
layer = Cmts_User;
STROKE_PARAMS defaultStroke( aBoard->GetDesignSettings().GetLineThickness( layer ) );
for( auto& seg : aLine->segment )
{
switch( seg->shape )
@ -2778,10 +2784,10 @@ bool FABMASTER::loadOutline( BOARD* aBoard, const std::unique_ptr<FABMASTER::TRA
line->SetLayer( layer );
line->SetStart( wxPoint( src->start_x, src->start_y ) );
line->SetEnd( wxPoint( src->end_x, src->end_y ) );
line->SetWidth( src->width );
line->SetStroke( STROKE_PARAMS( src->width, PLOT_DASH_TYPE::SOLID ) );
if( line->GetWidth() == 0 )
line->SetWidth( aBoard->GetDesignSettings().GetLineThickness( layer ) );
line->SetStroke( defaultStroke );
aBoard->Add( line, ADD_MODE::APPEND );
break;
@ -2812,10 +2818,10 @@ bool FABMASTER::loadOutline( BOARD* aBoard, const std::unique_ptr<FABMASTER::TRA
arc->SetArcGeometry( (wxPoint) src->result.GetP0(),
(wxPoint) src->result.GetArcMid(),
(wxPoint) src->result.GetP1() );
arc->SetWidth( src->width );
arc->SetStroke( STROKE_PARAMS( src->width, PLOT_DASH_TYPE::SOLID ) );
if( arc->GetWidth() == 0 )
arc->SetWidth( aBoard->GetDesignSettings().GetLineThickness( layer ) );
arc->SetStroke( defaultStroke );
aBoard->Add( arc, ADD_MODE::APPEND );
break;
@ -2829,7 +2835,7 @@ bool FABMASTER::loadOutline( BOARD* aBoard, const std::unique_ptr<FABMASTER::TRA
rect->SetLayer( layer );
rect->SetStart( wxPoint( src->start_x, src->start_y ) );
rect->SetEnd( wxPoint( src->end_x, src->end_y ) );
rect->SetWidth( aBoard->GetDesignSettings().GetLineThickness( layer ) );
rect->SetStroke( defaultStroke );
aBoard->Add( rect, ADD_MODE::APPEND );
break;
@ -2891,7 +2897,7 @@ bool FABMASTER::loadGraphics( BOARD* aBoard )
PCB_SHAPE* new_poly = new PCB_SHAPE( aBoard, SHAPE_T::POLY );
new_poly->SetLayer( layer );
new_poly->SetPolyShape( poly_outline );
new_poly->SetWidth( 0 );
new_poly->SetStroke( STROKE_PARAMS( 0 ) );
if( layer == F_SilkS || layer == B_SilkS )
new_poly->SetFilled( true );
@ -2913,7 +2919,7 @@ bool FABMASTER::loadGraphics( BOARD* aBoard )
line->SetLayer( layer );
line->SetStart( wxPoint( src->start_x, src->start_y ) );
line->SetEnd( wxPoint( src->end_x, src->end_y ) );
line->SetWidth( src->width );
line->SetStroke( STROKE_PARAMS( src->width, PLOT_DASH_TYPE::SOLID ) );
aBoard->Add( line, ADD_MODE::APPEND );
break;
@ -2941,7 +2947,7 @@ bool FABMASTER::loadGraphics( BOARD* aBoard )
arc->SetArcGeometry( (wxPoint) src->result.GetP0(),
(wxPoint) src->result.GetArcMid(),
(wxPoint) src->result.GetP1() );
arc->SetWidth( src->width );
arc->SetStroke( STROKE_PARAMS( src->width, PLOT_DASH_TYPE::SOLID ) );
aBoard->Add( arc, ADD_MODE::APPEND );
break;
@ -2955,7 +2961,7 @@ bool FABMASTER::loadGraphics( BOARD* aBoard )
rect->SetLayer( layer );
rect->SetStart( wxPoint( src->start_x, src->start_y ) );
rect->SetEnd( wxPoint( src->end_x, src->end_y ) );
rect->SetWidth( 0 );
rect->SetStroke( STROKE_PARAMS( 0 ) );
rect->SetFilled( true );
aBoard->Add( rect, ADD_MODE::APPEND );
break;
@ -2990,9 +2996,7 @@ bool FABMASTER::loadGraphics( BOARD* aBoard )
bool FABMASTER::orderZones( BOARD* aBoard )
{
std::vector<ZONE*> zones = aBoard->Zones();
std::sort( zones.begin(), zones.end(),
std::sort( aBoard->Zones().begin(), aBoard->Zones().end(),
[&]( const ZONE* a, const ZONE* b )
{
if( a->GetLayer() == b->GetLayer() )
@ -3004,7 +3008,7 @@ bool FABMASTER::orderZones( BOARD* aBoard )
PCB_LAYER_ID layer = UNDEFINED_LAYER;
unsigned int priority = 0;
for( ZONE* zone : zones )
for( ZONE* zone : aBoard->Zones() )
{
/// Rule areas do not have priorities
if( zone->GetIsRuleArea() )

View File

@ -469,7 +469,8 @@ FOOTPRINT* GPCB_FPL_CACHE::parseFOOTPRINT( LINE_READER* aLineReader )
parseInt( parameters[3], conv_unit ) ) );
shape->SetEnd0( wxPoint( parseInt( parameters[4], conv_unit ),
parseInt( parameters[5], conv_unit ) ) );
shape->SetWidth( parseInt( parameters[6], conv_unit ) );
shape->SetStroke( STROKE_PARAMS( parseInt( parameters[6], conv_unit ),
PLOT_DASH_TYPE::SOLID ) );
shape->SetDrawCoord();
footprint->Add( shape );
continue;
@ -517,7 +518,8 @@ FOOTPRINT* GPCB_FPL_CACHE::parseFOOTPRINT( LINE_READER* aLineReader )
// Angle value is clockwise in gpcb and Pcbnew.
shape->SetArcAngleAndEnd0( sweep_angle );
shape->SetWidth( parseInt( parameters[8], conv_unit ) );
shape->SetStroke( STROKE_PARAMS( parseInt( parameters[8], conv_unit ),
PLOT_DASH_TYPE::SOLID ) );
shape->SetDrawCoord();
continue;
}

View File

@ -2366,6 +2366,7 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
T token;
wxPoint pt;
STROKE_PARAMS stroke( 0, PLOT_DASH_TYPE::SOLID );
std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( nullptr );
switch( CurTok() )
@ -2572,7 +2573,6 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
case T_gr_poly:
{
shape->SetShape( SHAPE_T::POLY );
shape->SetWidth( 0 ); // this is the default value. will be (perhaps) modified later
shape->SetPolyPoints( {} );
SHAPE_LINE_CHAIN& outline = shape->GetPolyShape().Outline( 0 );
@ -2640,7 +2640,7 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
break;
case T_width:
shape->SetWidth( parseBoardUnits( T_width ) );
stroke.SetWidth( parseBoardUnits( T_width ) );
NeedRIGHT();
break;
@ -2699,7 +2699,7 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
{
// Legacy versions didn't have a filled flag but allowed some shapes to indicate they
// should be filled by specifying a 0 stroke-width.
if( shape->GetWidth() == 0
if( stroke.GetWidth() == 0
&& ( shape->GetShape() == SHAPE_T::RECT || shape->GetShape() == SHAPE_T::CIRCLE ) )
{
shape->SetFilled( true );
@ -2713,11 +2713,13 @@ PCB_SHAPE* PCB_PARSER::parsePCB_SHAPE()
// Only filled shapes may have a zero line-width. This is not permitted in KiCad but some
// external tools can generate invalid files.
if( shape->GetWidth() <= 0 && !shape->IsFilled() )
if( stroke.GetWidth() <= 0 && !shape->IsFilled() )
{
shape->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
stroke.SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
}
shape->SetStroke( stroke );
return shape.release();
}
@ -3670,6 +3672,7 @@ FP_SHAPE* PCB_PARSER::parseFP_SHAPE()
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as FP_SHAPE." ) );
wxPoint pt;
STROKE_PARAMS stroke( 0, PLOT_DASH_TYPE::SOLID );
T token;
std::unique_ptr<FP_SHAPE> shape = std::make_unique<FP_SHAPE>( nullptr );
@ -3933,7 +3936,7 @@ FP_SHAPE* PCB_PARSER::parseFP_SHAPE()
break;
case T_width:
shape->SetWidth( parseBoardUnits( T_width ) );
stroke.SetWidth( parseBoardUnits( T_width ) );
NeedRIGHT();
break;
@ -3992,7 +3995,7 @@ FP_SHAPE* PCB_PARSER::parseFP_SHAPE()
{
// Legacy versions didn't have a filled flag but allowed some shapes to indicate they
// should be filled by specifying a 0 stroke-width.
if( shape->GetWidth() == 0
if( stroke.GetWidth() == 0
&& ( shape->GetShape() == SHAPE_T::RECT || shape->GetShape() == SHAPE_T::CIRCLE ) )
{
shape->SetFilled( true );
@ -4006,11 +4009,13 @@ FP_SHAPE* PCB_PARSER::parseFP_SHAPE()
// Only filled shapes may have a zero line-width. This is not permitted in KiCad but some
// external tools can generate invalid files.
if( shape->GetWidth() <= 0 && !shape->IsFilled() )
if( stroke.GetWidth() <= 0 && !shape->IsFilled() )
{
shape->SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
stroke.SetWidth( Millimeter2iu( DEFAULT_LINE_WIDTH ) );
}
shape->SetStroke( stroke );
return shape.release();
}

Some files were not shown because too many files have changed in this diff Show More