From 91485422195841c428d18880f2056103f294bc70 Mon Sep 17 00:00:00 2001
From: Roberto Fernandez Bautista <roberto.fer.bau@gmail.com>
Date: Fri, 9 Apr 2021 20:11:12 +0100
Subject: [PATCH] CADSTAR Schematic: Fix Text Positioning within Symbols

---
 common/eda_text.cpp                           |  7 +++-
 .../cadstar/cadstar_archive_parser.cpp        |  9 +++++
 .../cadstar/cadstar_sch_archive_loader.cpp    | 40 ++++++++++++++++++-
 3 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/common/eda_text.cpp b/common/eda_text.cpp
index 0fa5dd8f66..34fc886d95 100644
--- a/common/eda_text.cpp
+++ b/common/eda_text.cpp
@@ -235,7 +235,7 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
 
         if( strings.GetCount() )     // GetCount() == 0 for void strings
         {
-            if( aLine >= 0 && ( aLine < (int)strings.GetCount() ) )
+            if( aLine >= 0 && ( aLine < static_cast<int>( strings.GetCount() ) ) )
                 text = strings.Item( aLine );
             else
                 text = strings.Item( 0 );
@@ -267,6 +267,11 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
     wxSize textsize = wxSize( dx, dy );
     wxPoint pos = GetTextPos();
 
+    if( IsMultilineAllowed() && aLine > 0 && ( aLine < static_cast<int>( strings.GetCount() ) ) )
+    {
+        pos.y -= aLine * GetInterline();
+    }
+
     if( aInvertY )
         pos.y = -pos.y;
 
diff --git a/common/plugins/cadstar/cadstar_archive_parser.cpp b/common/plugins/cadstar/cadstar_archive_parser.cpp
index 281f63e4be..1e167490cd 100644
--- a/common/plugins/cadstar/cadstar_archive_parser.cpp
+++ b/common/plugins/cadstar/cadstar_archive_parser.cpp
@@ -2541,6 +2541,15 @@ void CADSTAR_ARCHIVE_PARSER::FixTextPositionNoAlignment( EDA_TEXT* aKiCadTextIte
         wxPoint positionOffset( 0, aKiCadTextItem->GetInterline() );
         RotatePoint( &positionOffset, txtAngleDecideg );
 
+        EDA_ITEM* textEdaItem = dynamic_cast<EDA_ITEM*>( aKiCadTextItem );
+
+        if( textEdaItem && ( textEdaItem->Type() == LIB_TEXT_T )
+            || ( textEdaItem->Type() == LIB_FIELD_T ) )
+        {
+            // Y coordinate increases upwards in the symbol editor
+            positionOffset.y = -positionOffset.y;
+        }
+
         //Count num of additional lines
         wxString text = aKiCadTextItem->GetText();
         int      numExtraLines = text.Replace( "\n", "\n" );
diff --git a/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp b/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp
index dfb352412d..22010bab89 100644
--- a/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp
+++ b/eeschema/sch_plugins/cadstar/cadstar_sch_archive_loader.cpp
@@ -1280,11 +1280,13 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary( const SYMDEF_ID& aSymdef
 
     for( std::pair<TEXT_ID, TEXT> textPair : symbol.Texts )
     {
-        TEXT      csText  = textPair.second;
+        TEXT csText = textPair.second;
+
         LIB_TEXT* libtext = new LIB_TEXT( aPart );
         libtext->SetText( csText.Text );
         libtext->SetUnit( gateNumber );
         libtext->SetPosition( getKiCadLibraryPoint( csText.Position, symbol.Origin ) );
+        libtext->SetMultilineAllowed( true ); // temporarily so that we calculate bbox correctly
 
         applyTextSettings( libtext,
                            csText.TextCodeID,
@@ -1293,7 +1295,39 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary( const SYMDEF_ID& aSymdef
                            csText.OrientAngle,
                            csText.Mirror );
 
-        aPart->AddDrawItem( libtext );
+        // Split out multi line text items into individual text elements
+        if( csText.Text.Contains( "\n" ) )
+        {
+            wxArrayString strings;
+            wxStringSplit( csText.Text, strings, '\n' );
+            wxPoint firstLinePos;
+
+            for( int ii = 0; ii < strings.size(); ++ii )
+            {
+                EDA_RECT bbox = libtext->GetTextBox( ii, true );
+                wxPoint  linePos = { bbox.GetLeft(), -bbox.GetBottom() };
+
+                RotatePoint( &linePos, libtext->GetTextPos(), -libtext->GetTextAngle() );
+
+                LIB_TEXT* line = static_cast<LIB_TEXT*>( libtext->Clone() );
+                line->SetText( strings[ii] );
+                line->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+                line->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM );
+                line->SetTextPos( linePos );
+
+                // Multiline text not allowed in LIB_TEXT
+                line->SetMultilineAllowed( false );
+                aPart->AddDrawItem( line );
+            }
+
+            delete libtext;
+        }
+        else
+        {
+            // Multiline text not allowed in LIB_TEXT
+            libtext->SetMultilineAllowed( false );
+            aPart->AddDrawItem( libtext );
+        }
     }
 
     if( symbol.TextLocations.find( SYMBOL_NAME_ATTRID ) != symbol.TextLocations.end() )
@@ -2494,6 +2528,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::applyTextSettings( EDA_TEXT*            aKiCadT
     {
     // Some KiCad schematic text items only permit a limited amount of angles
     // and text justifications
+    case LIB_TEXT_T:
     case SCH_FIELD_T:
     case LIB_FIELD_T:
     {
@@ -2560,6 +2595,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::applyTextSettings( EDA_TEXT*            aKiCadT
         return;
 
     default:
+        wxFAIL_MSG( "Unexpected item type" );
         return;
     }
 }