From 7a1ab44207c2cd7a24c2213ea4f5e90129fe4d7c Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 22 May 2024 18:18:14 +0100 Subject: [PATCH] Rewrite Eagle rotated text algorithm. Fixes https://gitlab.com/kicad/code/kicad/-/issues/18019 (cherry picked from commit debc94ff49f18b9d61d40f4bb6cea37523e917e5) --- pcbnew/pcb_io/eagle/pcb_io_eagle.cpp | 138 ++++++++++++--------------- 1 file changed, 59 insertions(+), 79 deletions(-) diff --git a/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp b/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp index 945615e940..f12d59c0f8 100644 --- a/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp +++ b/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp @@ -723,102 +723,82 @@ void PCB_IO_EAGLE::loadPlain( wxXmlNode* aGraphics ) pcbtxt->SetLayer( layer ); wxString kicadText = interpretText( t.text ); pcbtxt->SetText( kicadText ); - pcbtxt->SetTextPos( VECTOR2I( kicad_x( t.x ), kicad_y( t.y ) ) ); double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default int textThickness = KiROUND( t.size.ToPcbUnits() * ratio / 100 ); pcbtxt->SetTextThickness( textThickness ); pcbtxt->SetTextSize( kicad_fontsize( t.size, textThickness ) ); - int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; + // Eagle's anchor is independent of text justification; KiCad's is not. + VECTOR2I eagleAnchor( kicad_x( t.x ), kicad_y( t.y ) ); + int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; + BOX2I textbox = pcbtxt->GetBoundingBox(); + VECTOR2I offset( 0, 0 ); + double degrees = 0; + int signX = 0; + int signY = 0; if( t.rot ) { - int sign = t.rot->mirror ? -1 : 1; - pcbtxt->SetMirrored( t.rot->mirror ); + if( !t.rot->spin ) + degrees = t.rot->degrees; - double degrees = t.rot->degrees; + if( t.rot->mirror ) + pcbtxt->SetMirrored( t.rot->mirror ); - if( degrees == 90 || t.rot->spin ) + if( degrees > 90 && degrees <= 270 ) { - pcbtxt->SetTextAngle( EDA_ANGLE( sign * degrees, DEGREES_T ) ); + if( degrees == 270 && t.rot->mirror ) + degrees = 270; // an odd special-case + else + degrees -= 180; - if( sign < 0 ) - { - BOX2I bbox = pcbtxt->GetBoundingBox(); - VECTOR2I pos = pcbtxt->GetTextPos(); - pos.y -= sign * bbox.GetWidth(); // yes, width: bbox is unrotated - pcbtxt->SetTextPos( pos ); - } + signX = t.rot->mirror ? 1 : -1; + signY = 1; } - else if( degrees == 180 ) - { - if( sign < 0 ) - { - BOX2I bbox = pcbtxt->GetBoundingBox(); - VECTOR2I pos = pcbtxt->GetTextPos(); - pos.x -= sign * bbox.GetWidth(); - pcbtxt->SetTextPos( pos ); - } - switch( align ) - { - case ETEXT::TOP_CENTER: align = ETEXT::BOTTOM_CENTER; break; - case ETEXT::TOP_LEFT: align = ETEXT::BOTTOM_RIGHT; break; - case ETEXT::TOP_RIGHT: align = ETEXT::BOTTOM_LEFT; break; - case ETEXT::BOTTOM_CENTER: align = ETEXT::TOP_CENTER; break; - case ETEXT::BOTTOM_LEFT: align = ETEXT::TOP_RIGHT; break; - case ETEXT::BOTTOM_RIGHT: align = ETEXT::TOP_LEFT; break; - case ETEXT::CENTER_LEFT: align = ETEXT::CENTER_RIGHT; break; - case ETEXT::CENTER_RIGHT: align = ETEXT::CENTER_LEFT; break; - } - } - else if( degrees == 270 ) - { - if( sign < 0 ) - { - BOX2I bbox = pcbtxt->GetBoundingBox(); - VECTOR2I pos = pcbtxt->GetTextPos(); - pos.y -= sign * bbox.GetWidth(); // yes, width; bbox is unrotated - pcbtxt->SetTextPos( pos ); - } - - pcbtxt->SetTextAngle( EDA_ANGLE( sign * 90, DEGREES_T ) ); - - switch( align ) - { - case ETEXT::TOP_CENTER: align = ETEXT::BOTTOM_CENTER; break; - case ETEXT::TOP_LEFT: align = ETEXT::BOTTOM_RIGHT; break; - case ETEXT::TOP_RIGHT: align = ETEXT::BOTTOM_LEFT; break; - case ETEXT::BOTTOM_CENTER: align = ETEXT::TOP_CENTER; break; - case ETEXT::BOTTOM_LEFT: align = ETEXT::TOP_RIGHT; break; - case ETEXT::BOTTOM_RIGHT: align = ETEXT::TOP_LEFT; break; - case ETEXT::CENTER_LEFT: align = ETEXT::CENTER_RIGHT; break; - case ETEXT::CENTER_RIGHT: align = ETEXT::CENTER_LEFT; break; - } - } - else if( degrees > 90 && degrees < 270 ) - { - pcbtxt->SetTextAngle( EDA_ANGLE( sign * ( degrees + 180 ), DEGREES_T ) ); - - switch( align ) - { - case ETEXT::TOP_CENTER: align = ETEXT::BOTTOM_CENTER; break; - case ETEXT::TOP_LEFT: align = ETEXT::BOTTOM_RIGHT; break; - case ETEXT::TOP_RIGHT: align = ETEXT::BOTTOM_LEFT; break; - case ETEXT::BOTTOM_CENTER: align = ETEXT::TOP_CENTER; break; - case ETEXT::BOTTOM_LEFT: align = ETEXT::TOP_RIGHT; break; - case ETEXT::BOTTOM_RIGHT: align = ETEXT::TOP_LEFT; break; - case ETEXT::CENTER_LEFT: align = ETEXT::CENTER_RIGHT; break; - case ETEXT::CENTER_RIGHT: align = ETEXT::CENTER_LEFT; break; - } - } - else - { - pcbtxt->SetTextAngle( EDA_ANGLE( sign * degrees, DEGREES_T ) ); - } + pcbtxt->SetTextAngle( EDA_ANGLE( degrees, DEGREES_T ) ); } + switch( align ) + { + case ETEXT::BOTTOM_CENTER: + case ETEXT::BOTTOM_LEFT: + case ETEXT::BOTTOM_RIGHT: + offset.y = signY * (int) textbox.GetHeight(); + break; + + case ETEXT::TOP_CENTER: + case ETEXT::TOP_LEFT: + case ETEXT::TOP_RIGHT: + offset.y = -signY * (int) textbox.GetHeight(); + break; + + default: + break; + } + + switch( align ) + { + case ETEXT::TOP_LEFT: + case ETEXT::CENTER_LEFT: + case ETEXT::BOTTOM_LEFT: + offset.x = signX * (int) textbox.GetWidth(); + break; + + case ETEXT::TOP_RIGHT: + case ETEXT::CENTER_RIGHT: + case ETEXT::BOTTOM_RIGHT: + offset.x = -signX * (int) textbox.GetWidth(); + break; + + default: + break; + } + + RotatePoint( offset, EDA_ANGLE( degrees, DEGREES_T ) ); + pcbtxt->SetTextPos( eagleAnchor + offset ); + switch( align ) { case ETEXT::CENTER: