Browse Source

De-duplicate table border drawing code.

Also cleans up a misconception about table header borders,
and renames the getter/setter to be clearer.

Also makes sure that table cells are updated when the table
layer changes.

And another bug where we were writing the grey color value
back to the cell for hidden cells.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20319
revert-0c36e162
Jeff Young 9 months ago
parent
commit
93ea523eec
  1. 2
      common/hash_eda.cpp
  2. 14
      eeschema/dialogs/dialog_table_properties.cpp
  3. 4
      eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp
  4. 2
      eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_parser.cpp
  5. 2
      eeschema/sch_painter.cpp
  6. 10
      eeschema/sch_table.cpp
  7. 6
      eeschema/sch_table.h
  8. 15
      pcbnew/dialogs/dialog_table_properties.cpp
  9. 4
      pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp
  10. 2
      pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp
  11. 117
      pcbnew/pcb_painter.cpp
  12. 128
      pcbnew/pcb_table.cpp
  13. 10
      pcbnew/pcb_table.h
  14. 110
      pcbnew/plot_brditems_plotter.cpp

2
common/hash_eda.cpp

@ -323,7 +323,7 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags )
ret = hash_board_item( table, aFlags );
hash_combine( ret, table->StrokeExternal() );
hash_combine( ret, table->StrokeHeader() );
hash_combine( ret, table->StrokeHeaderSeparator() );
hash_combine( ret, table->StrokeColumns() );
hash_combine( ret, table->StrokeRows() );

14
eeschema/dialogs/dialog_table_properties.cpp

@ -188,7 +188,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
//
m_borderCheckbox->SetValue( m_table->StrokeExternal() );
m_headerBorder->SetValue( m_table->StrokeHeader() );
m_headerBorder->SetValue( m_table->StrokeHeaderSeparator() );
if( m_table->GetBorderStroke().GetWidth() >= 0 )
m_borderWidth.SetValue( m_table->GetBorderStroke().GetWidth() );
@ -202,11 +202,11 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
else
m_borderStyleCombo->SetSelection( 0 );
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderColorLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderColorSwatch->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderColorLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderColorSwatch->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
@ -344,7 +344,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
}
m_table->SetStrokeExternal( m_borderCheckbox->GetValue() );
m_table->SetStrokeHeader( m_headerBorder->GetValue() );
m_table->SetStrokeHeaderSeparator( m_headerBorder->GetValue() );
{
STROKE_PARAMS stroke = m_table->GetBorderStroke();

4
eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr.cpp

@ -1392,9 +1392,9 @@ void SCH_IO_KICAD_SEXPR::saveTable( SCH_TABLE* aTable )
m_out->Print( "(border" );
KICAD_FORMAT::FormatBool( m_out, "external", aTable->StrokeExternal() );
KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeader() );
KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeaderSeparator() );
if( aTable->StrokeExternal() || aTable->StrokeHeader() )
if( aTable->StrokeExternal() || aTable->StrokeHeaderSeparator() )
aTable->GetBorderStroke().Format( m_out, schIUScale );
m_out->Print( ")" ); // Close `border` token.

2
eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_parser.cpp

@ -4607,7 +4607,7 @@ SCH_TABLE* SCH_IO_KICAD_SEXPR_PARSER::parseSchTable()
break;
case T_header:
table->SetStrokeHeader( parseBool() );
table->SetStrokeHeaderSeparator( parseBool() );
NeedRIGHT();
break;

2
eeschema/sch_painter.cpp

@ -2199,7 +2199,7 @@ void SCH_PAINTER::draw( const SCH_TABLE* aTable, int aLayer, bool aDimmed )
setupStroke( aTable->GetBorderStroke() );
if( aTable->StrokeHeader() )
if( aTable->StrokeHeaderSeparator() )
{
if( !first->GetTextAngle().IsHorizontal() )
strokeLine( VECTOR2I( first->GetEndX(), pos.y ),

10
eeschema/sch_table.cpp

@ -38,7 +38,7 @@
SCH_TABLE::SCH_TABLE( int aLineWidth ) :
SCH_ITEM( nullptr, SCH_TABLE_T ),
m_strokeExternal( true ),
m_strokeHeader( true ),
m_StrokeHeaderSeparator( true ),
m_borderStroke( aLineWidth, LINE_STYLE::DEFAULT, COLOR4D::UNSPECIFIED ),
m_strokeRows( true ),
m_strokeColumns( true ),
@ -53,7 +53,7 @@ SCH_TABLE::SCH_TABLE( const SCH_TABLE& aTable ) :
SCH_ITEM( aTable )
{
m_strokeExternal = aTable.m_strokeExternal;
m_strokeHeader = aTable.m_strokeHeader;
m_StrokeHeaderSeparator = aTable.m_StrokeHeaderSeparator;
m_borderStroke = aTable.m_borderStroke;
m_strokeRows = aTable.m_strokeRows;
m_strokeColumns = aTable.m_strokeColumns;
@ -86,7 +86,7 @@ void SCH_TABLE::SwapData( SCH_ITEM* aItem )
SCH_TABLE* table = static_cast<SCH_TABLE*>( aItem );
std::swap( m_strokeExternal, table->m_strokeExternal );
std::swap( m_strokeHeader, table->m_strokeHeader );
std::swap( m_StrokeHeaderSeparator, table->m_StrokeHeaderSeparator );
std::swap( m_borderStroke, table->m_borderStroke );
std::swap( m_strokeRows, table->m_strokeRows );
std::swap( m_strokeColumns, table->m_strokeColumns );
@ -425,7 +425,7 @@ void SCH_TABLE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS&
setupStroke( GetBorderStroke() );
SCH_TABLECELL* cell = GetCell( 0, 0 );
if( StrokeHeader() )
if( StrokeHeaderSeparator() )
{
if( !cell->GetTextAngle().IsHorizontal() )
{
@ -526,7 +526,7 @@ static struct SCH_TABLE_DESC
tableProps );
propMgr.AddProperty( new PROPERTY<SCH_TABLE, bool>( _HKI( "Header Border" ),
&SCH_TABLE::SetStrokeHeader, &SCH_TABLE::StrokeHeader ),
&SCH_TABLE::SetStrokeHeaderSeparator, &SCH_TABLE::StrokeHeaderSeparator ),
tableProps );
propMgr.AddProperty( new PROPERTY<SCH_TABLE, int>( _HKI( "Border Width" ),

6
eeschema/sch_table.h

@ -53,8 +53,8 @@ public:
void SetStrokeExternal( bool aDoStroke ) { m_strokeExternal = aDoStroke; }
bool StrokeExternal() const { return m_strokeExternal; }
void SetStrokeHeader( bool aDoStroke ) { m_strokeHeader = aDoStroke; }
bool StrokeHeader() const { return m_strokeHeader; }
void SetStrokeHeaderSeparator( bool aDoStroke ) { m_StrokeHeaderSeparator = aDoStroke; }
bool StrokeHeaderSeparator() const { return m_StrokeHeaderSeparator; }
void SetBorderStroke( const STROKE_PARAMS& aParams ) { m_borderStroke = aParams; }
const STROKE_PARAMS& GetBorderStroke() const { return m_borderStroke; }
@ -238,7 +238,7 @@ public:
protected:
bool m_strokeExternal;
bool m_strokeHeader;
bool m_StrokeHeaderSeparator;
STROKE_PARAMS m_borderStroke;
bool m_strokeRows;
bool m_strokeColumns;

15
pcbnew/dialogs/dialog_table_properties.cpp

@ -211,7 +211,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
m_cbLocked->SetValue( m_table->IsLocked() );
m_borderCheckbox->SetValue( m_table->StrokeExternal() );
m_headerBorder->SetValue( m_table->StrokeHeader() );
m_headerBorder->SetValue( m_table->StrokeHeaderSeparator() );
if( m_table->GetBorderStroke().GetWidth() >= 0 )
m_borderWidth.SetValue( m_table->GetBorderStroke().GetWidth() );
@ -223,9 +223,9 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
else
m_borderStyleCombo->SetSelection( 0 );
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
@ -339,6 +339,10 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
wxString txt = m_grid->GetCellValue( row, col );
// Don't insert grey colour value back in to table cell
if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
txt = wxEmptyString;
// convert any text variable cross-references to their UUIDs
txt = board->ConvertCrossReferencesToKIIDs( txt );
@ -353,6 +357,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
#endif
tableCell->SetText( txt );
tableCell->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );
}
}
@ -360,7 +365,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
m_table->SetLocked( m_cbLocked->GetValue() );
m_table->SetStrokeExternal( m_borderCheckbox->GetValue() );
m_table->SetStrokeHeader( m_headerBorder->GetValue() );
m_table->SetStrokeHeaderSeparator( m_headerBorder->GetValue() );
{
STROKE_PARAMS stroke = m_table->GetBorderStroke();

4
pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp

@ -2129,9 +2129,9 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TABLE* aTable ) const
m_out->Print( "(border" );
KICAD_FORMAT::FormatBool( m_out, "external", aTable->StrokeExternal() );
KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeader() );
KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeaderSeparator() );
if( aTable->StrokeExternal() || aTable->StrokeHeader() )
if( aTable->StrokeExternal() || aTable->StrokeHeaderSeparator() )
aTable->GetBorderStroke().Format( m_out, pcbIUScale );
m_out->Print( ")" ); // Close `border` token.

2
pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp

@ -3932,7 +3932,7 @@ PCB_TABLE* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TABLE( BOARD_ITEM* aParent )
break;
case T_header:
table->SetStrokeHeader( parseBool() );
table->SetStrokeHeaderSeparator( parseBool() );
NeedRIGHT();
break;

117
pcbnew/pcb_painter.cpp

@ -2481,43 +2481,26 @@ void PCB_PAINTER::draw( const PCB_TABLE* aTable, int aLayer )
return;
for( PCB_TABLECELL* cell : aTable->GetCells() )
draw( static_cast<PCB_TEXTBOX*>( cell ), aLayer );
{
if( cell->GetColSpan() > 0 || cell->GetRowSpan() > 0 )
draw( static_cast<PCB_TEXTBOX*>( cell ), aLayer );
}
// Selection for tables is done with a background wash, so pass in nullptr to GetColor()
// so we just get the "normal" (un-selected/un-brightened) color for the borders.
COLOR4D color = m_pcbSettings.GetColor( nullptr, aLayer );
int lineWidth;
LINE_STYLE lineStyle;
COLOR4D color = m_pcbSettings.GetColor( nullptr, aLayer );
auto setupStroke =
[&]( const STROKE_PARAMS& stroke )
aTable->DrawBorders(
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
{
lineWidth = getLineThickness( stroke.GetWidth() );
lineStyle = stroke.GetLineStyle();
int lineWidth = getLineThickness( stroke.GetWidth() );
LINE_STYLE lineStyle = stroke.GetLineStyle();
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->SetLineWidth( lineWidth );
};
auto strokeShape =
[&]( const SHAPE& shape )
{
STROKE_PARAMS::Stroke( &shape, lineStyle, lineWidth, &m_pcbSettings,
[&]( VECTOR2I a, VECTOR2I b )
{
// DrawLine has problem with 0 length lines so enforce minimum
if( a == b )
m_gal->DrawLine( a+1, b );
else
m_gal->DrawLine( a, b );
} );
};
auto strokeLine =
[&]( VECTOR2I ptA, VECTOR2I ptB )
{
if( lineStyle <= LINE_STYLE::FIRST_TYPE )
{
m_gal->DrawLine( ptA, ptB );
@ -2525,80 +2508,18 @@ void PCB_PAINTER::draw( const PCB_TABLE* aTable, int aLayer )
else
{
SHAPE_SEGMENT seg( ptA, ptB );
strokeShape( seg );
}
};
if( aTable->GetSeparatorsStroke().GetWidth() >= 0 )
{
setupStroke( aTable->GetSeparatorsStroke() );
// Stroke column edges
if( aTable->StrokeColumns() )
{
for( int col = 0; col < aTable->GetColCount() - 1; ++col )
{
int row = aTable->StrokeHeader() ? 0 : 1;
for( ; row < aTable->GetRowCount(); ++row )
{
PCB_TABLECELL* cell = aTable->GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
{
// Draw right edge (between adjacent cells)
strokeLine( corners[1], corners[2] );
}
STROKE_PARAMS::Stroke( &seg, lineStyle, lineWidth, &m_pcbSettings,
[&]( VECTOR2I a, VECTOR2I b )
{
// DrawLine has problem with 0 length lines so enforce minimum
if( a == b )
m_gal->DrawLine( a+1, b );
else
m_gal->DrawLine( a, b );
} );
}
}
}
// Stroke row edges
if( aTable->StrokeRows() )
{
for( int row = 0; row < aTable->GetRowCount() - 1; ++row )
{
for( int col = 0; col < aTable->GetColCount(); ++col )
{
PCB_TABLECELL* cell = aTable->GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
{
// Draw bottom edge (between adjacent cells)
strokeLine( corners[2], corners[3] );
}
}
}
}
}
if( aTable->GetBorderStroke().GetWidth() >= 0 )
{
setupStroke( aTable->GetBorderStroke() );
std::vector<VECTOR2I> topLeft = aTable->GetCell( 0, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomLeft = aTable->GetCell( aTable->GetRowCount() - 1, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> topRight = aTable->GetCell( 0, aTable->GetColCount() - 1 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomRight = aTable->GetCell( aTable->GetRowCount() - 1, aTable->GetColCount() - 1 )->GetCornersInSequence();
if( aTable->StrokeHeader() )
{
strokeLine( topLeft[0], topRight[1] );
strokeLine( topLeft[0], topLeft[3] );
strokeLine( topLeft[3], topRight[2] );
strokeLine( topRight[1], topRight[2] );
}
if( aTable->StrokeExternal() )
{
strokeLine( topLeft[3], topRight[2] );
strokeLine( topRight[2], bottomRight[2] );
strokeLine( bottomRight[2], bottomLeft[3] );
strokeLine( bottomLeft[3], topLeft[3] );
}
}
} );
// Highlight selected tablecells with a background wash.
for( PCB_TABLECELL* cell : aTable->GetCells() )

128
pcbnew/pcb_table.cpp

@ -33,7 +33,7 @@
PCB_TABLE::PCB_TABLE( BOARD_ITEM* aParent, int aLineWidth ) :
BOARD_ITEM_CONTAINER( aParent, PCB_TABLE_T ),
m_strokeExternal( true ),
m_strokeHeader( true ),
m_StrokeHeaderSeparator( true ),
m_borderStroke( aLineWidth, LINE_STYLE::DEFAULT, COLOR4D::UNSPECIFIED ),
m_strokeRows( true ),
m_strokeColumns( true ),
@ -47,7 +47,7 @@ PCB_TABLE::PCB_TABLE( const PCB_TABLE& aTable ) :
BOARD_ITEM_CONTAINER( aTable )
{
m_strokeExternal = aTable.m_strokeExternal;
m_strokeHeader = aTable.m_strokeHeader;
m_StrokeHeaderSeparator = aTable.m_StrokeHeaderSeparator;
m_borderStroke = aTable.m_borderStroke;
m_strokeRows = aTable.m_strokeRows;
m_strokeColumns = aTable.m_strokeColumns;
@ -81,7 +81,7 @@ void PCB_TABLE::swapData( BOARD_ITEM* aImage )
std::swap( m_isLocked, table->m_isLocked );
std::swap( m_strokeExternal, table->m_strokeExternal );
std::swap( m_strokeHeader, table->m_strokeHeader );
std::swap( m_StrokeHeaderSeparator, table->m_StrokeHeaderSeparator );
std::swap( m_borderStroke, table->m_borderStroke );
std::swap( m_strokeRows, table->m_strokeRows );
std::swap( m_strokeColumns, table->m_strokeColumns );
@ -236,77 +236,93 @@ const BOX2I PCB_TABLE::GetBoundingBox() const
}
std::shared_ptr<SHAPE> PCB_TABLE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
void PCB_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1,
const VECTOR2I& aPt2,
const STROKE_PARAMS& aStroke )>& aCallback ) const
{
std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomLeft = GetCell( GetRowCount() - 1, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> topRight = GetCell( 0, GetColCount() - 1 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomRight = GetCell( GetRowCount() - 1, GetColCount() - 1 )->GetCornersInSequence();
STROKE_PARAMS stroke;
std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
std::vector<VECTOR2I> pts;
pts.emplace_back( topLeft[3] );
pts.emplace_back( topRight[2] );
pts.emplace_back( bottomRight[2] );
pts.emplace_back( bottomLeft[3] );
shape->AddShape( new SHAPE_SIMPLE( pts ) );
auto addSeg =
[&shape]( const VECTOR2I& ptA, const VECTOR2I& ptB, int width )
{
shape->AddShape( new SHAPE_SEGMENT( ptA, ptB, width ) );
};
if( StrokeColumns() && GetSeparatorsStroke().GetWidth() >= 0)
for( int col = 0; col < GetColCount() - 1; ++col )
{
for( int col = 0; col < GetColCount() - 1; ++col )
if( StrokeColumns() )
stroke = GetSeparatorsStroke();
else
continue;
for( int row = 0; row < GetRowCount(); ++row )
{
int row = StrokeHeader() ? 0 : 1;
PCB_TABLECELL* cell = GetCell( row, col );
for( ; row < GetRowCount(); ++row )
{
PCB_TABLECELL* cell = GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( cell->GetColSpan() == 0 )
continue;
if( corners.size() == 4 )
addSeg( corners[1], corners[2], GetSeparatorsStroke().GetWidth() );
}
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
aCallback( corners[1], corners[2], stroke );
}
}
if( StrokeRows() && GetSeparatorsStroke().GetWidth() >= 0 )
for( int row = 0; row < GetRowCount() - 1; ++row )
{
for( int row = 0; row < GetRowCount() - 1; ++row )
if( row == 0 && StrokeHeaderSeparator() )
stroke = GetBorderStroke();
else if( StrokeRows() )
stroke = GetSeparatorsStroke();
else
continue;
for( int col = 0; col < GetColCount(); ++col )
{
for( int col = 0; col < GetColCount(); ++col )
{
PCB_TABLECELL* cell = GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
PCB_TABLECELL* cell = GetCell( row, col );
if( corners.size() == 4 )
addSeg( corners[2], corners[3], GetSeparatorsStroke().GetWidth() );
}
}
}
if( cell->GetRowSpan() == 0 )
continue;
if( StrokeHeader() && GetBorderStroke().GetWidth() >= 0 )
{
addSeg( topLeft[0], topRight[1], GetBorderStroke().GetWidth() );
addSeg( topLeft[0], topLeft[3], GetBorderStroke().GetWidth() );
addSeg( topLeft[3], topRight[2], GetBorderStroke().GetWidth() );
addSeg( topRight[1], topRight[2], GetBorderStroke().GetWidth() );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
aCallback( corners[2], corners[3], stroke );
}
}
if( StrokeExternal() && GetBorderStroke().GetWidth() >= 0 )
{
addSeg( topLeft[3], topRight[2], GetBorderStroke().GetWidth() );
addSeg( topRight[2], bottomRight[2], GetBorderStroke().GetWidth() );
addSeg( bottomRight[2], bottomLeft[3], GetBorderStroke().GetWidth() );
addSeg( bottomLeft[3], topLeft[3], GetBorderStroke().GetWidth() );
aCallback( topLeft[0], topRight[1], GetBorderStroke() );
aCallback( topRight[1], bottomRight[2], GetBorderStroke() );
aCallback( bottomRight[2], bottomLeft[3], GetBorderStroke() );
aCallback( bottomLeft[3], topLeft[0], GetBorderStroke() );
}
}
std::shared_ptr<SHAPE> PCB_TABLE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomLeft = GetCell( GetRowCount() - 1, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> topRight = GetCell( 0, GetColCount() - 1 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomRight = GetCell( GetRowCount() - 1, GetColCount() - 1 )->GetCornersInSequence();
std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
std::vector<VECTOR2I> pts;
pts.emplace_back( topLeft[3] );
pts.emplace_back( topRight[2] );
pts.emplace_back( bottomRight[2] );
pts.emplace_back( bottomLeft[3] );
shape->AddShape( new SHAPE_SIMPLE( pts ) );
DrawBorders(
[&shape]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
{
shape->AddShape( new SHAPE_SEGMENT( ptA, ptB, stroke.GetWidth() ) );
} );
return shape;
}
@ -321,7 +337,7 @@ void PCB_TABLE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID a
if( StrokeColumns() || StrokeRows() )
gap = std::max( gap, aClearance + GetSeparatorsStroke().GetWidth() / 2 );
if( StrokeExternal() || StrokeHeader() )
if( StrokeExternal() || StrokeHeaderSeparator() )
gap = std::max( gap, aClearance + GetBorderStroke().GetWidth() / 2 );
for( PCB_TABLECELL* cell : m_cells )
@ -456,7 +472,7 @@ bool PCB_TABLE::operator==( const PCB_TABLE& aOther ) const
if( m_strokeExternal != aOther.m_strokeExternal )
return false;
if( m_strokeHeader != aOther.m_strokeHeader )
if( m_StrokeHeaderSeparator != aOther.m_StrokeHeaderSeparator )
return false;
if( m_borderStroke != aOther.m_borderStroke )
@ -502,7 +518,7 @@ double PCB_TABLE::Similarity( const BOARD_ITEM& aOther ) const
if( m_strokeExternal != other.m_strokeExternal )
similarity *= 0.9;
if( m_strokeHeader != other.m_strokeHeader )
if( m_StrokeHeaderSeparator != other.m_StrokeHeaderSeparator )
similarity *= 0.9;
if( m_borderStroke != other.m_borderStroke )
@ -567,7 +583,7 @@ static struct PCB_TABLE_DESC
tableProps );
propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "Header Border" ),
&PCB_TABLE::SetStrokeHeader, &PCB_TABLE::StrokeHeader ),
&PCB_TABLE::SetStrokeHeaderSeparator, &PCB_TABLE::StrokeHeaderSeparator ),
tableProps );
propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Border Width" ),

10
pcbnew/pcb_table.h

@ -52,8 +52,8 @@ public:
void SetStrokeExternal( bool aDoStroke ) { m_strokeExternal = aDoStroke; }
bool StrokeExternal() const { return m_strokeExternal; }
void SetStrokeHeader( bool aDoStroke ) { m_strokeHeader = aDoStroke; }
bool StrokeHeader() const { return m_strokeHeader; }
void SetStrokeHeaderSeparator( bool aDoStroke ) { m_StrokeHeaderSeparator = aDoStroke; }
bool StrokeHeaderSeparator() const { return m_StrokeHeaderSeparator; }
void SetBorderStroke( const STROKE_PARAMS& aParams ) { m_borderStroke = aParams; }
const STROKE_PARAMS& GetBorderStroke() const { return m_borderStroke; }
@ -204,6 +204,10 @@ public:
const BOX2I GetBoundingBox() const override;
void DrawBorders( const std::function<void( const VECTOR2I& aPt1,
const VECTOR2I& aPt2,
const STROKE_PARAMS& aStroke )>& aCallback ) const;
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
@ -252,7 +256,7 @@ protected:
protected:
bool m_strokeExternal;
bool m_strokeHeader;
bool m_StrokeHeaderSeparator;
STROKE_PARAMS m_borderStroke;
bool m_strokeRows;
bool m_strokeColumns;

110
pcbnew/plot_brditems_plotter.cpp

@ -1122,8 +1122,6 @@ void BRDITEMS_PLOTTER::PlotTableBorders( const PCB_TABLE* aTable )
if( !m_layerMask[aTable->GetLayer()] )
return;
int lineWidth;
LINE_STYLE lineStyle;
GBR_METADATA gbr_metadata;
if( const FOOTPRINT* parentFP = aTable->GetParentFootprint() )
@ -1132,27 +1130,12 @@ void BRDITEMS_PLOTTER::PlotTableBorders( const PCB_TABLE* aTable )
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP );
}
auto setupStroke =
[&]( const STROKE_PARAMS& stroke )
aTable->DrawBorders(
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
{
lineWidth = stroke.GetWidth();
lineStyle = stroke.GetLineStyle();
};
auto strokeShape =
[&]( const SHAPE& shape )
{
STROKE_PARAMS::Stroke( &shape, lineStyle, lineWidth, m_plotter->RenderSettings(),
[&]( const VECTOR2I& a, const VECTOR2I& b )
{
m_plotter->ThickSegment( a, b, lineWidth, GetPlotMode(),
&gbr_metadata );
} );
};
int lineWidth = stroke.GetWidth();
LINE_STYLE lineStyle = stroke.GetLineStyle();
auto strokeLine =
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB )
{
if( lineStyle <= LINE_STYLE::FIRST_TYPE )
{
m_plotter->ThickSegment( ptA, ptB, lineWidth, GetPlotMode(), &gbr_metadata );
@ -1160,86 +1143,15 @@ void BRDITEMS_PLOTTER::PlotTableBorders( const PCB_TABLE* aTable )
else
{
SHAPE_SEGMENT seg( ptA, ptB );
strokeShape( seg );
}
};
if( aTable->GetSeparatorsStroke().GetWidth() >= 0 )
{
setupStroke( aTable->GetSeparatorsStroke() );
if( aTable->StrokeColumns() )
{
for( int col = 0; col < aTable->GetColCount() - 1; ++col )
{
int row = 1;
if( aTable->StrokeHeader() )
{
row = 0;
}
for( ; row < aTable->GetRowCount(); ++row )
{
PCB_TABLECELL* cell = aTable->GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
{
// Draw right edge (between adjacent cells)
strokeLine( corners[1], corners[2] );
}
}
}
}
if( aTable->StrokeRows() )
{
for( int row = 0; row < aTable->GetRowCount() - 1; ++row )
{
for( int col = 0; col < aTable->GetColCount(); ++col )
{
PCB_TABLECELL* cell = aTable->GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
{
// Draw bottom edge (between adjacent cells)
strokeLine( corners[2], corners[3] );
}
STROKE_PARAMS::Stroke( &seg, lineStyle, lineWidth, m_plotter->RenderSettings(),
[&]( const VECTOR2I& a, const VECTOR2I& b )
{
m_plotter->ThickSegment( a, b, lineWidth, GetPlotMode(),
&gbr_metadata );
} );
}
}
}
}
if( aTable->GetBorderStroke().GetWidth() >= 0 )
{
setupStroke( aTable->GetBorderStroke() );
std::vector<VECTOR2I> topLeft = aTable->GetCell( 0, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomLeft =
aTable->GetCell( aTable->GetRowCount() - 1, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> topRight =
aTable->GetCell( 0, aTable->GetColCount() - 1 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomRight =
aTable->GetCell( aTable->GetRowCount() - 1, aTable->GetColCount() - 1 )
->GetCornersInSequence();
if( aTable->StrokeHeader() )
{
strokeLine( topLeft[0], topRight[1] );
strokeLine( topLeft[0], topLeft[3] );
strokeLine( topLeft[3], topRight[2] );
strokeLine( topRight[1], topRight[2] );
}
if( aTable->StrokeExternal() )
{
strokeLine( topLeft[3], topRight[2] );
strokeLine( topRight[2], bottomRight[2] );
strokeLine( bottomRight[2], bottomLeft[3] );
strokeLine( bottomLeft[3], topLeft[3] );
}
}
} );
}

Loading…
Cancel
Save