pcbnew and eeschema: Table and textbox rotation / text justification fix

This commit is contained in:
Damjan 2025-04-21 15:32:46 +02:00 committed by Jeff Young
parent 54681278c5
commit af11746cc4
6 changed files with 67 additions and 41 deletions

View File

@ -1597,40 +1597,39 @@ std::vector<VECTOR2I> EDA_SHAPE::GetRectCorners() const
}
std::vector<VECTOR2I> EDA_SHAPE::GetCornersInSequence() const
std::vector<VECTOR2I> EDA_SHAPE::GetCornersInSequence( EDA_ANGLE angle ) const
{
std::vector<VECTOR2I> pts;
EDA_ANGLE textAngle( getDrawRotation() );
textAngle.Normalize();
angle.Normalize();
BOX2I bbox = getBoundingBox();
bbox.Normalize();
if( textAngle.IsCardinal() )
if( angle.IsCardinal() )
{
if( textAngle == ANGLE_0 )
if( angle == ANGLE_0 )
{
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
}
else if( textAngle == ANGLE_90 )
else if( angle == ANGLE_90 )
{
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
}
else if( textAngle == ANGLE_180 )
else if( angle == ANGLE_180 )
{
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
}
else if( textAngle == ANGLE_270 )
else if( angle == ANGLE_270 )
{
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
@ -1640,7 +1639,25 @@ std::vector<VECTOR2I> EDA_SHAPE::GetCornersInSequence() const
}
else
{
std::vector<VECTOR2I> corners = GetRectCorners();
// This function was originally located in pcb_textbox.cpp and was later moved to eda_shape.cpp.
// As a result of this move, access to getCorners was lost, since it is defined in the PCB_SHAPE
// class within pcb_shape.cpp and is not available in the current context.
//
// Additionally, GetRectCorners() cannot be used here, as it assumes the rectangle is rotated by
// a cardinal angle. In non-cardinal cases, it returns incorrect values (e.g., (0, 0)).
//
// To address this, a portion of the getCorners implementation for SHAPE_T::POLY elements
// has been replicated here to restore the correct behavior.
std::vector<VECTOR2I> corners;
for( int ii = 0; ii < GetPolyShape().OutlineCount(); ++ii )
{
for( const VECTOR2I& pt : GetPolyShape().Outline( ii ).CPoints() )
corners.emplace_back( pt );
}
while( corners.size() < 4 )
corners.emplace_back( corners.back() + VECTOR2I( 10, 10 ) );
VECTOR2I minX = corners[0];
VECTOR2I maxX = corners[0];
@ -1662,21 +1679,21 @@ std::vector<VECTOR2I> EDA_SHAPE::GetCornersInSequence() const
maxY = corner;
}
if( textAngle < ANGLE_90 )
if( angle < ANGLE_90 )
{
pts.emplace_back( minX );
pts.emplace_back( minY );
pts.emplace_back( maxX );
pts.emplace_back( maxY );
}
else if( textAngle < ANGLE_180 )
else if( angle < ANGLE_180 )
{
pts.emplace_back( maxY );
pts.emplace_back( minX );
pts.emplace_back( minY );
pts.emplace_back( maxX );
}
else if( textAngle < ANGLE_270 )
else if( angle < ANGLE_270 )
{
pts.emplace_back( maxX );
pts.emplace_back( maxY );

View File

@ -332,10 +332,13 @@ bool SCH_TABLE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
void SCH_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();
EDA_ANGLE drawAngle = GetCell( 0, 0 )->GetTextAngle();
std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> bottomLeft = GetCell( GetRowCount() - 1, 0 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> topRight = GetCell( 0, GetColCount() - 1 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> bottomRight =
GetCell( GetRowCount() - 1, GetColCount() - 1 )->GetCornersInSequence( drawAngle );
STROKE_PARAMS stroke;
for( int col = 0; col < GetColCount() - 1; ++col )
@ -355,7 +358,7 @@ void SCH_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1, con
if( col + cell->GetColSpan() == GetColCount() )
continue;
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
std::vector<VECTOR2I> corners = cell->GetCornersInSequence( drawAngle );
if( corners.size() == 4 )
aCallback( corners[1], corners[2], stroke );
@ -381,7 +384,7 @@ void SCH_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1, con
if( row + cell->GetRowSpan() == GetRowCount() )
continue;
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
std::vector<VECTOR2I> corners = cell->GetCornersInSequence( drawAngle );
if( corners.size() == 4 )
aCallback( corners[2], corners[3], stroke );

View File

@ -285,7 +285,7 @@ public:
VECTOR2I GetArcMid() const;
std::vector<VECTOR2I> GetRectCorners() const;
std::vector<VECTOR2I> GetCornersInSequence() const;
std::vector<VECTOR2I> GetCornersInSequence( EDA_ANGLE angle ) const;
/**
* Calc arc start and end angles such that aStartAngle < aEndAngle. Each may be between

View File

@ -316,10 +316,12 @@ const BOX2I PCB_TABLE::GetBoundingBox() 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();
EDA_ANGLE drawAngle = GetCell( 0, 0 )->GetDrawRotation();
std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> bottomLeft = GetCell( GetRowCount() - 1, 0 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> topRight = GetCell( 0, GetColCount() - 1 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> bottomRight =
GetCell( GetRowCount() - 1, GetColCount() - 1 )->GetCornersInSequence( drawAngle );
STROKE_PARAMS stroke;
for( int col = 0; col < GetColCount() - 1; ++col )
@ -339,7 +341,7 @@ void PCB_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1, con
if( col + cell->GetColSpan() == GetColCount() )
continue;
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
std::vector<VECTOR2I> corners = cell->GetCornersInSequence( drawAngle );
if( corners.size() == 4 )
aCallback( corners[1], corners[2], stroke );
@ -365,7 +367,7 @@ void PCB_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1, con
if( row + cell->GetRowSpan() == GetRowCount() )
continue;
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
std::vector<VECTOR2I> corners = cell->GetCornersInSequence( drawAngle );
if( corners.size() == 4 )
aCallback( corners[2], corners[3], stroke );
@ -384,10 +386,12 @@ void PCB_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1, con
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();
EDA_ANGLE drawAngle = GetCell( 0, 0 )->GetDrawRotation();
std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> bottomLeft = GetCell( GetRowCount() - 1, 0 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> topRight = GetCell( 0, GetColCount() - 1 )->GetCornersInSequence( drawAngle );
std::vector<VECTOR2I> bottomRight =
GetCell( GetRowCount() - 1, GetColCount() - 1 )->GetCornersInSequence( drawAngle );
std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();

View File

@ -273,7 +273,8 @@ VECTOR2I PCB_TEXTBOX::GetDrawPos() const
VECTOR2I PCB_TEXTBOX::GetDrawPos( bool aIsFlipped ) const
{
std::vector<VECTOR2I> corners = GetCornersInSequence();
EDA_ANGLE drawAngle = GetDrawRotation();
std::vector<VECTOR2I> corners = GetCornersInSequence( drawAngle );
GR_TEXT_H_ALIGN_T horizontalAlignment = GetHorizJustify();
GR_TEXT_V_ALIGN_T verticalAlignment = GetVertJustify();
VECTOR2I textAnchor;
@ -439,7 +440,8 @@ wxString PCB_TEXTBOX::GetShownText( bool aAllowExtraText, int aDepth ) const
}
KIFONT::FONT* font = getDrawFont();
std::vector<VECTOR2I> corners = GetCornersInSequence();
EDA_ANGLE drawAngle = GetDrawRotation();
std::vector<VECTOR2I> corners = GetCornersInSequence( drawAngle );
int colWidth = ( corners[1] - corners[0] ).EuclideanNorm();
if( GetTextAngle().IsHorizontal() )
@ -505,12 +507,13 @@ void PCB_TEXTBOX::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
if( GetTextAngle().IsCardinal() && GetShape() != SHAPE_T::RECTANGLE )
{
// To convert the polygon to its equivalent rectangle, we use GetCornersInSequence()
// To convert the polygon to its equivalent rectangle, we use GetCornersInSequence( drawAngle )
// but this method uses the polygon bounding box.
// set the line thickness to 0 to get the actual rectangle corner
int lineWidth = GetWidth();
SetWidth( 0 );
std::vector<VECTOR2I> corners = GetCornersInSequence();
EDA_ANGLE drawAngle = GetDrawRotation();
std::vector<VECTOR2I> corners = GetCornersInSequence( drawAngle );
SetWidth( lineWidth );
VECTOR2I diag = corners[2] - corners[0];
EDA_ANGLE angle = GetTextAngle();

View File

@ -1458,14 +1458,13 @@ void PCB_GRID_HELPER::computeAnchors( BOARD_ITEM* aItem, const VECTOR2I& aRefPos
{
PCB_TABLE* table = static_cast<PCB_TABLE*>( aItem );
VECTOR2I topLeft = table->GetCell( 0, 0 )->GetCornersInSequence()[0];
VECTOR2I bottomLeft =
table->GetCell( table->GetRowCount() - 1, 0 )->GetCornersInSequence()[3];
VECTOR2I topRight =
table->GetCell( 0, table->GetColCount() - 1 )->GetCornersInSequence()[1];
VECTOR2I bottomRight =
table->GetCell( table->GetRowCount() - 1, table->GetColCount() - 1 )
->GetCornersInSequence()[2];
EDA_ANGLE drawAngle = table->GetCell( 0, 0 )->GetDrawRotation();
VECTOR2I topLeft = table->GetCell( 0, 0 )->GetCornersInSequence( drawAngle )[0];
VECTOR2I bottomLeft =
table->GetCell( table->GetRowCount() - 1, 0 )->GetCornersInSequence( drawAngle )[3];
VECTOR2I topRight = table->GetCell( 0, table->GetColCount() - 1 )->GetCornersInSequence( drawAngle )[1];
VECTOR2I bottomRight = table->GetCell( table->GetRowCount() - 1, table->GetColCount() - 1 )
->GetCornersInSequence( drawAngle )[2];
addAnchor( topLeft, CORNER | SNAPPABLE, table, POINT_TYPE::PT_END );
addAnchor( bottomLeft, CORNER | SNAPPABLE, table, POINT_TYPE::PT_END );