From 7108a25278e8d116a490c07dca135491e4882712 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 2 Aug 2020 16:12:33 +0100 Subject: [PATCH] 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 --- pcbnew/class_pcb_text.cpp | 72 ++++++++++++++++++++++++----------- pcbnew/tools/drawing_tool.cpp | 6 +-- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/pcbnew/class_pcb_text.cpp b/pcbnew/class_pcb_text.cpp index 72dd275901..644a4193a2 100644 --- a/pcbnew/class_pcb_text.cpp +++ b/pcbnew/class_pcb_text.cpp @@ -163,31 +163,59 @@ void TEXTE_PCB::Rotate( const wxPoint& aRotCentre, double aAngle ) void TEXTE_PCB::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) { - if( aFlipLeftRight ) - SetTextX( aCentre.x - ( GetTextPos().x - aCentre.x ) ); - else - SetTextY( aCentre.y - ( GetTextPos().y - aCentre.y ) ); + double angle = GetTextAngle(); + bool vertical = KiROUND( angle ) % 1800 == 900; - int copperLayerCount = GetBoard()->GetCopperLayerCount(); - - 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( KiROUND( angle ) != 0 ) { - if( ( GetHorizJustify() == GR_TEXT_HJUSTIFY_RIGHT ) == IsMirrored() ) - SetTextX( GetTextPos().x - GetTextBox().GetWidth() ); - else - SetTextX( GetTextPos().x + GetTextBox().GetWidth() ); + Rotate( aCentre, -angle ); + + if( vertical ) + 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() ); } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index aafd8afc6c..cdf9099f71 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -859,8 +859,8 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) { bool leftRight = m_frame->Settings().m_FlipLeftRight; - for( auto item : preview ) - static_cast( item )->Flip( (wxPoint) cursorPos, leftRight); + for( EDA_ITEM* item : preview ) + static_cast( item )->Flip( (wxPoint) cursorPos, leftRight ); m_view->Update( &preview ); } @@ -872,7 +872,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { // Place the imported drawings - for( auto item : preview ) + for( EDA_ITEM* item : preview ) commit.Add( item ); commit.Push( _( "Place a DXF_SVG drawing" ) );