From 7d0299f15303fd4ea1c398606c1e644c063fd90d Mon Sep 17 00:00:00 2001 From: Eldar Khayrullin Date: Wed, 24 Feb 2016 13:03:56 -0500 Subject: [PATCH] Pcbnew: fix issues in PCAD import of P-CAD ASCII files. (fixes lp:1547822) --- .../pcad2kicad_common.cpp | 165 ++++++++++++++---- .../pcad2kicadpcb_plugin/pcad2kicad_common.h | 18 +- pcbnew/pcad2kicadpcb_plugin/pcb.cpp | 7 +- pcbnew/pcad2kicadpcb_plugin/pcb_component.h | 6 +- pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp | 26 ++- pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp | 15 +- 6 files changed, 179 insertions(+), 58 deletions(-) diff --git a/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.cpp b/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.cpp index f588bbce1b..7ff4a60ed3 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.cpp @@ -37,6 +37,9 @@ namespace PCAD2KICAD { +// PCAD stroke font average ratio of width to height +const double TEXT_WIDTH_TO_HEIGHT = 0.79; + wxString GetWord( wxString* aStr ) { wxString result = wxEmptyString; @@ -270,6 +273,31 @@ void SetDoublePrecisionPosition( wxString aStr, aActualConversion ); } +TTEXT_JUSTIFY GetJustifyIdentificator( wxString aJustify ) +{ + TTEXT_JUSTIFY id; + + if( aJustify == wxT( "LowerCenter" ) ) + id = LowerCenter; + else if( aJustify == wxT( "LowerRight" ) ) + id = LowerRight; + else if( aJustify == wxT( "UpperLeft" ) ) + id = UpperLeft; + else if( aJustify == wxT( "UpperCenter" ) ) + id = UpperCenter; + else if( aJustify == wxT( "UpperRight" ) ) + id = UpperRight; + else if( aJustify == wxT( "Left" ) ) + id = Left; + else if( aJustify == wxT( "Center" ) ) + id = Center; + else if( aJustify == wxT( "Right" ) ) + id = Right; + else + id = LowerLeft; + + return id; +} void SetTextParameters( XNODE* aNode, TTEXTVALUE* aTextValue, @@ -304,6 +332,14 @@ void SetTextParameters( XNODE* aNode, else if( str == wxT( "False" ) ) aTextValue->textIsVisible = 0; + str = FindNodeGetContent( aNode, wxT( "justify" ) ); + aTextValue->justify = GetJustifyIdentificator( str ); + + str = FindNodeGetContent( aNode, wxT( "isFlipped" ) ); + + if( str == wxT( "True" ) ) + aTextValue->mirror = 1; + tNode = FindNode( aNode, wxT( "textStyleRef" ) ); if( tNode ) @@ -367,48 +403,102 @@ void SetFontProperty( XNODE* aNode, } } - -void CorrectTextPosition( TTEXTVALUE* aValue, int aRotation ) +int CalculateTextLengthSize( TTEXTVALUE* aText ) { - aValue->correctedPositionX = aValue->textPositionX; - aValue->correctedPositionY = aValue->textPositionY; - aValue->correctedPositionY = aValue->correctedPositionY - KiROUND( - (double) aValue->textHeight / 3.0 ); - aValue->correctedPositionX = aValue->correctedPositionX + - KiROUND( ( (double) aValue->text.Len() / - 1.4 ) * ( (double) aValue->textHeight / 1.8 ) ); + return KiROUND( (double) aText->text.Len() * + (double) aText->textHeight * TEXT_WIDTH_TO_HEIGHT ); +} - if( aRotation == 900 ) - { - aValue->correctedPositionX = -aValue->textPositionY; - aValue->correctedPositionY = aValue->textPositionX; - aValue->correctedPositionX = aValue->correctedPositionX + KiROUND( - (double) aValue->textHeight / 3.0 ); - aValue->correctedPositionY = aValue->correctedPositionY + - KiROUND( ( (double) aValue->text.Len() / - 1.4 ) * ( (double) aValue->textHeight / 1.8 ) ); - } +void CorrectTextPosition( TTEXTVALUE* aValue ) +{ + int cm = aValue->mirror ? -1 : 1; + // sizes of justify correction + int cl = KiROUND( (double) CalculateTextLengthSize( aValue ) / 2.0 ); + int ch = KiROUND( (double) aValue->textHeight / 2.0 ); - if( aRotation == 1800 ) - { - aValue->correctedPositionX = -aValue->textPositionX; - aValue->correctedPositionY = -aValue->textPositionY; - aValue->correctedPositionY = aValue->correctedPositionY + - KiROUND( (double) aValue->textHeight / 3.0 ); - aValue->correctedPositionX = aValue->correctedPositionX - - KiROUND( ( (double) aValue->text.Len() / - 1.4 ) * ( (double) aValue->textHeight / 1.8 ) ); - } + aValue->correctedPositionX = aValue->textPositionX; + aValue->correctedPositionY = aValue->textPositionY; - if( aRotation == 2700 ) + switch( aValue->textRotation ) { - aValue->correctedPositionX = aValue->textPositionY; - aValue->correctedPositionY = -aValue->textPositionX; - aValue->correctedPositionX = aValue->correctedPositionX + - KiROUND( (double) aValue->textHeight / 1.0 ); - aValue->correctedPositionY = aValue->correctedPositionY - - KiROUND( ( (double) aValue->text.Len() / - 3.4 ) * ( (double) aValue->textHeight / 1.8 ) ); + case 0: + if( aValue->justify == LowerLeft || + aValue->justify == Left || + aValue->justify == UpperLeft ) + aValue->correctedPositionX += cl * cm; + else if( aValue->justify == LowerRight || + aValue->justify == Right || + aValue->justify == UpperRight ) + aValue->correctedPositionX -= cl * cm; + + if( aValue->justify == LowerLeft || + aValue->justify == LowerCenter || + aValue->justify == LowerRight ) + aValue->correctedPositionY -= ch; + else if( aValue->justify == UpperLeft || + aValue->justify == UpperCenter || + aValue->justify == UpperRight ) + aValue->correctedPositionY += ch; + break; + case 900: + if( aValue->justify == LowerLeft || + aValue->justify == LowerCenter || + aValue->justify == LowerRight ) + aValue->correctedPositionX -= ch * cm; + else if( aValue->justify == UpperLeft || + aValue->justify == UpperCenter || + aValue->justify == UpperRight ) + aValue->correctedPositionX += ch * cm; + + if( aValue->justify == LowerLeft || + aValue->justify == Left || + aValue->justify == UpperLeft ) + aValue->correctedPositionY -= cl; + else if( aValue->justify == LowerRight || + aValue->justify == Right || + aValue->justify == UpperRight ) + aValue->correctedPositionY += cl; + break; + case 1800: + if( aValue->justify == LowerLeft || + aValue->justify == Left || + aValue->justify == UpperLeft ) + aValue->correctedPositionX -= cl * cm; + else if( aValue->justify == LowerRight || + aValue->justify == Right || + aValue->justify == UpperRight ) + aValue->correctedPositionX += cl * cm; + + if( aValue->justify == LowerLeft || + aValue->justify == LowerCenter || + aValue->justify == LowerRight ) + aValue->correctedPositionY += ch; + else if( aValue->justify == UpperLeft || + aValue->justify == UpperCenter || + aValue->justify == UpperRight ) + aValue->correctedPositionY -= ch; + break; + case 2700: + if( aValue->justify == LowerLeft || + aValue->justify == LowerCenter || + aValue->justify == LowerRight ) + aValue->correctedPositionX += ch * cm; + else if( aValue->justify == UpperLeft || + aValue->justify == UpperCenter || + aValue->justify == UpperRight ) + aValue->correctedPositionX -= ch * cm; + + if( aValue->justify == LowerLeft || + aValue->justify == Left || + aValue->justify == UpperLeft ) + aValue->correctedPositionY += cl; + else if( aValue->justify == LowerRight || + aValue->justify == Right || + aValue->justify == UpperRight ) + aValue->correctedPositionY -= cl; + break; + default: + break; } } @@ -457,6 +547,7 @@ void InitTTextValue( TTEXTVALUE* aTextValue ) aTextValue->textUnit = 0; aTextValue->correctedPositionX = 0; aTextValue->correctedPositionY = 0; + aTextValue->justify = LowerLeft; } } // namespace PCAD2KICAD diff --git a/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.h b/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.h index 30ce190536..ce61cc2446 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.h +++ b/pcbnew/pcad2kicadpcb_plugin/pcad2kicad_common.h @@ -39,6 +39,19 @@ namespace PCAD2KICAD #define PCAD2KICAD_SCALE_SCH_TO_INCH_GRID +enum TTEXT_JUSTIFY +{ + LowerLeft, + LowerCenter, + LowerRight, + UpperLeft, + UpperCenter, + UpperRight, + Left, + Center, + Right +}; + typedef struct _TTEXTVALUE { wxString text; @@ -46,6 +59,7 @@ typedef struct _TTEXTVALUE textRotation, textHeight, textstrokeWidth; int textIsVisible, mirror, textUnit; int correctedPositionX, correctedPositionY; + TTEXT_JUSTIFY justify; } TTEXTVALUE; extern wxString GetWord( wxString* aStr ); @@ -69,6 +83,7 @@ extern void SetDoublePrecisionPosition( wxString aStr, double* aX, double* aY, wxString aActualConversion ); +extern TTEXT_JUSTIFY GetJustifyIdentificator( wxString aJustify ); extern void SetTextParameters( XNODE* aNode, TTEXTVALUE* aTextValue, wxString aDefaultMeasurementUnit, @@ -77,7 +92,8 @@ extern void SetFontProperty( XNODE* aNode, TTEXTVALUE* aTextValue, wxString aDefaultMeasurementUnit, wxString aActualConversion ); -extern void CorrectTextPosition( TTEXTVALUE* aValue, int aRotation ); +extern int CalculateTextLengthSize( TTEXTVALUE* aText ); +extern void CorrectTextPosition( TTEXTVALUE* aValue ); extern XNODE* FindNode( XNODE* aChild, wxString aTag ); extern wxString FindNodeGetContent( XNODE* aChild, wxString aTag ); diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp index 41f79d2b85..8f5316b47c 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb.cpp @@ -166,7 +166,7 @@ void PCB::SetTextProperty( XNODE* aNode, TTEXTVALUE* aTextValue, wxString aActualConversion ) { XNODE* tNode, * t1Node; - wxString n, pn, propValue, str; + wxString n, nnew, pn, propValue, str; // aNode is pattern now tNode = aNode; @@ -199,7 +199,8 @@ void PCB::SetTextProperty( XNODE* aNode, TTEXTVALUE* aTextValue, str = aTextValue->text; str.Trim( false ); str.Trim( true ); - n = n + wxT( ' ' ) + str; // changed in new file version..... + nnew = n; // new file version + n = n + wxT( ' ' ) + str; // old file version tNode = NULL; } } @@ -219,7 +220,7 @@ void PCB::SetTextProperty( XNODE* aNode, TTEXTVALUE* aTextValue, propValue.Trim( false ); propValue.Trim( true ); - if( propValue == n ) + if( propValue == n || propValue == nnew ) break; tNode = tNode->GetNext(); diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_component.h b/pcbnew/pcad2kicadpcb_plugin/pcb_component.h index 41c55abf09..6088fad74e 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_component.h +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_component.h @@ -56,11 +56,11 @@ public: int m_positionX; int m_positionY; int m_rotation; - TTEXTVALUE m_name; // name has also privete positions, rotations nand so on.... + TTEXTVALUE m_name; // name has also private positions, rotations and so on.... wxString m_net; int m_netCode; - wxString m_compRef; // internal ussage for XL parsing - wxString m_patGraphRefName; // internal ussage for XL parsing + wxString m_compRef; // internal usage for XL parsing + wxString m_patGraphRefName; // internal usage for XL parsing PCB_COMPONENT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ); ~PCB_COMPONENT(); diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp index cd4ba511a3..5bcf7d9aa4 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_module.cpp @@ -43,6 +43,8 @@ #include #include +#include + namespace PCAD2KICAD { PCB_MODULE::PCB_MODULE( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ) : PCB_COMPONENT( aCallbacks, @@ -282,7 +284,7 @@ void PCB_MODULE::DoLayerContentsObjects( XNODE* aNode, propValue.Trim( false ); propValue.Trim( true ); - if( propValue == wxT( "Type" ) ) + if( propValue == wxT( "RefDes" ) ) { tNode = FindNode( lNode, wxT( "textStyleRef" ) ); @@ -500,10 +502,16 @@ wxString PCB_MODULE::ModuleLayer( int aMirror ) void PCB_MODULE::AddToBoard() { int i; + int r; // transform text positions - CorrectTextPosition( &m_name, m_rotation ); - CorrectTextPosition( &m_value, m_rotation ); + CorrectTextPosition( &m_name ); + RotatePoint( &m_name.correctedPositionX, &m_name.correctedPositionY, + (double) -m_rotation ); + + CorrectTextPosition( &m_value ); + RotatePoint( &m_value.correctedPositionX, &m_value.correctedPositionY, + (double) -m_rotation ); MODULE* module = new MODULE( m_board ); m_board->Add( module, ADD_APPEND ); @@ -528,7 +536,9 @@ void PCB_MODULE::AddToBoard() ref_text->SetSize( wxSize( KiROUND( m_name.textHeight / 2 ), KiROUND( m_name.textHeight / 1.5 ) ) ); - ref_text->SetOrientation( m_name.textRotation ); + r = m_name.textRotation - m_rotation; + ref_text->SetOrientation( r ); + ref_text->SetThickness( m_name.textstrokeWidth ); ref_text->SetMirrored( m_name.mirror ); @@ -549,7 +559,9 @@ void PCB_MODULE::AddToBoard() val_text->SetSize( wxSize( KiROUND( m_value.textHeight / 2 ), KiROUND( m_value.textHeight / 1.5 ) ) ); - val_text->SetOrientation( m_value.textRotation ); + r = m_value.textRotation - m_rotation; + val_text->SetOrientation( r ); + val_text->SetThickness( m_value.textstrokeWidth ); val_text->SetMirrored( m_value.mirror ); @@ -611,10 +623,6 @@ void PCB_MODULE::Flip() // Flipped m_KiCadLayer = FlipLayer( m_KiCadLayer ); m_rotation = -m_rotation; - m_name.textPositionX = -m_name.textPositionX; - m_name.mirror = m_mirror; - m_value.textPositionX = -m_value.textPositionX; - m_value.mirror = m_mirror; for( i = 0; i < (int) m_moduleObjects.GetCount(); i++ ) { diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp index a760d0b01d..db8b57f219 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_text.cpp @@ -78,6 +78,9 @@ void PCB_TEXT::Parse( XNODE* aNode, aNode->GetAttribute( wxT( "Name" ), &m_name.text ); + str = FindNodeGetContent( aNode, wxT( "justify" ) ); + m_name.justify = GetJustifyIdentificator( str ); + str = FindNodeGetContent( aNode, wxT( "isFlipped" ) ); if( str == wxT( "True" ) ) @@ -98,9 +101,10 @@ void PCB_TEXT::AddToModule( MODULE* aModule ) void PCB_TEXT::AddToBoard() { // Simple, not the best, but acceptable text positioning. - m_name.textPositionX = m_positionX; - m_name.textPositionY = m_positionY; - CorrectTextPosition( &m_name, m_rotation ); + m_name.textPositionX = m_positionX; + m_name.textPositionY = m_positionY; + m_name.textRotation = m_rotation; + CorrectTextPosition( &m_name ); TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board ); m_board->Add( pcbtxt, ADD_APPEND ); @@ -111,9 +115,10 @@ void PCB_TEXT::AddToBoard() KiROUND( m_name.textHeight / 1.1 ) ) ); pcbtxt->SetThickness( m_name.textstrokeWidth ); - pcbtxt->SetOrientation( m_rotation ); + pcbtxt->SetOrientation( m_name.textRotation ); - pcbtxt->SetTextPosition( wxPoint( m_name.correctedPositionX, m_name.correctedPositionY ) ); + pcbtxt->SetTextPosition( wxPoint( m_name.correctedPositionX, + m_name.correctedPositionY ) ); pcbtxt->SetMirrored( m_name.mirror ); pcbtxt->SetTimeStamp( 0 );