Fix issues flipping text.

This is a really hard problem to get right.  This algorithm won't
look quite right if you assemble a paragraph from disjoint text
objects and flip them all top-to-bottom (as it will re-order the
text).  But this is really the nature of the problem (and has to
stay that way to correctly flip disjoint graphic items or mixed
text and graphic items).  The real fix here is to support text
wrapped in a single text box.

Fixes https://gitlab.com/kicad/code/kicad/issues/4480
This commit is contained in:
Jeff Young 2020-08-02 16:12:33 +01:00
parent 6d319e5bf7
commit 7108a25278
2 changed files with 53 additions and 25 deletions

View File

@ -163,31 +163,59 @@ void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle )
void TEXTE_PCB::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) void TEXTE_PCB::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
{ {
if( aFlipLeftRight ) double angle = GetTextAngle();
SetTextX( aCentre.x - ( GetTextPos().x - aCentre.x ) ); bool vertical = KiROUND( angle ) % 1800 == 900;
else
SetTextY( aCentre.y - ( GetTextPos().y - aCentre.y ) );
int copperLayerCount = GetBoard()->GetCopperLayerCount(); if( KiROUND( angle ) != 0 )
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
SetMirrored( !IsMirrored() );
double text_angle = GetTextAngle();
if( text_angle < 1800 )
text_angle = 1800 - text_angle;
else
text_angle = 3600 - text_angle + 1800;
SetTextAngle( text_angle );
// adjust justified text for mirroring
if( GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT || GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT )
{ {
if( ( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT ) == IsMirrored() ) Rotate( aCentre, -angle );
SetTextX( GetTextPos().x - GetTextBox().GetWidth() );
else if( vertical )
SetTextX( GetTextPos().x + GetTextBox().GetWidth() ); aFlipLeftRight = !aFlipLeftRight;
} }
// Flip the bounding box
EDA_RECT box = GetTextBox();
int left = box.GetLeft();
int right = box.GetRight();
int top = box.GetTop();
int bottom = box.GetBottom();
if( aFlipLeftRight )
{
MIRROR( left, aCentre.x );
MIRROR( right, aCentre.x );
std::swap( left, right );
}
else
{
MIRROR( top, aCentre.y );
MIRROR( bottom, aCentre.y );
std::swap( top, bottom );
}
// Now put the text back in it (these look backwards but remember that out text will
// be mirrored when all is said and done)
switch( GetHorizJustify() )
{
case GR_TEXT_HJUSTIFY_LEFT: SetTextX( right ); break;
case GR_TEXT_HJUSTIFY_CENTER: SetTextX( ( left + right ) / 2 ); break;
case GR_TEXT_HJUSTIFY_RIGHT: SetTextX( left ); break;
}
switch( GetVertJustify() )
{
case GR_TEXT_VJUSTIFY_TOP: SetTextY( bottom ); break;
case GR_TEXT_VJUSTIFY_CENTER: SetTextY( ( top + bottom ) / 2 ); break;
case GR_TEXT_VJUSTIFY_BOTTOM: SetTextY( top ); break;
}
// And restore orientation
if( KiROUND( angle ) != 0 )
Rotate( aCentre, angle );
SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
SetMirrored( !IsMirrored() );
} }

View File

@ -859,7 +859,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
{ {
bool leftRight = m_frame->Settings().m_FlipLeftRight; bool leftRight = m_frame->Settings().m_FlipLeftRight;
for( auto item : preview ) for( EDA_ITEM* item : preview )
static_cast<BOARD_ITEM*>( item )->Flip( (wxPoint) cursorPos, leftRight ); static_cast<BOARD_ITEM*>( item )->Flip( (wxPoint) cursorPos, leftRight );
m_view->Update( &preview ); m_view->Update( &preview );
@ -872,7 +872,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
// Place the imported drawings // Place the imported drawings
for( auto item : preview ) for( EDA_ITEM* item : preview )
commit.Add( item ); commit.Add( item );
commit.Push( _( "Place a DXF_SVG drawing" ) ); commit.Push( _( "Place a DXF_SVG drawing" ) );