Altium: Handle textboxes
Also, corrects a minor issue with the text width calculation where
Altium calculates centerline to centerline but KiCad text heights are to
the edge of the stroke font. Need to still do better adjustments for
the various altium stroke fonts
Fixes https://gitlab.com/kicad/code/kicad/-/issues/9468
(cherry picked from commit 7e561acf53
)
This commit is contained in:
parent
a605c4b6ff
commit
48077d77c4
|
@ -1035,9 +1035,13 @@ ATEXT6::ATEXT6( ALTIUM_BINARY_PARSER& aReader, std::map<uint32_t, wxString>& aSt
|
||||||
if( subrecord1 <= 230 )
|
if( subrecord1 <= 230 )
|
||||||
textposition = ALTIUM_TEXT_POSITION::LEFT_BOTTOM;
|
textposition = ALTIUM_TEXT_POSITION::LEFT_BOTTOM;
|
||||||
|
|
||||||
aReader.Skip( 27 );
|
// An inverted rect in Altium is like a text box with the text inverted.
|
||||||
fonttype = static_cast<ALTIUM_TEXT_TYPE>( aReader.Read<uint8_t>() );
|
isInvertedRect = aReader.Read<uint8_t>() != 0;
|
||||||
|
|
||||||
|
textbox_rect_width = aReader.ReadKicadUnit();
|
||||||
|
textbox_rect_height = aReader.ReadKicadUnit();
|
||||||
|
textbox_rect_justification = static_cast<ALTIUM_TEXT_POSITION>( aReader.Read<uint8_t>() );
|
||||||
|
textbox_rect_offset = aReader.ReadKicadUnit();
|
||||||
aReader.SkipSubrecord();
|
aReader.SkipSubrecord();
|
||||||
|
|
||||||
// Subrecord 2 - Legacy 8bit string, max 255 chars, unknown codepage
|
// Subrecord 2 - Legacy 8bit string, max 255 chars, unknown codepage
|
||||||
|
|
|
@ -731,6 +731,17 @@ struct ATEXT6
|
||||||
bool isItalic;
|
bool isItalic;
|
||||||
bool isMirrored;
|
bool isMirrored;
|
||||||
bool isInverted;
|
bool isInverted;
|
||||||
|
bool isInvertedRect;
|
||||||
|
uint32_t inverted_borderwidth;
|
||||||
|
uint32_t textbox_rect_width;
|
||||||
|
uint32_t textbox_rect_height;
|
||||||
|
uint32_t textbox_rect_offset;
|
||||||
|
|
||||||
|
// Justification only applies when there is a text box size specified
|
||||||
|
// Then, the text is justified within the box
|
||||||
|
ALTIUM_TEXT_POSITION textbox_rect_justification;
|
||||||
|
|
||||||
|
uint32_t widestring_index;
|
||||||
|
|
||||||
bool isComment;
|
bool isComment;
|
||||||
bool isDesignator;
|
bool isDesignator;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <pad.h>
|
#include <pad.h>
|
||||||
#include <pcb_shape.h>
|
#include <pcb_shape.h>
|
||||||
#include <pcb_text.h>
|
#include <pcb_text.h>
|
||||||
|
#include <pcb_textbox.h>
|
||||||
#include <pcb_track.h>
|
#include <pcb_track.h>
|
||||||
#include <core/profile.h>
|
#include <core/profile.h>
|
||||||
#include <pad_shapes.h>
|
#include <pad_shapes.h>
|
||||||
|
@ -3925,7 +3926,9 @@ void ALTIUM_PCB::ConvertTexts6ToFootprintItem( FOOTPRINT* aFootprint, const ATEX
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertTexts6ToBoardItemOnLayer( const ATEXT6& aElem, PCB_LAYER_ID aLayer )
|
void ALTIUM_PCB::ConvertTexts6ToBoardItemOnLayer( const ATEXT6& aElem, PCB_LAYER_ID aLayer )
|
||||||
{
|
{
|
||||||
PCB_TEXT* pcbText = new PCB_TEXT( m_board );
|
std::unique_ptr<PCB_TEXTBOX> pcbTextbox = std::make_unique<PCB_TEXTBOX>( m_board );
|
||||||
|
std::unique_ptr<PCB_TEXT> pcbText = std::make_unique<PCB_TEXT>( m_board );
|
||||||
|
bool isTextbox = ( aElem.textbox_rect_height != 0 );
|
||||||
|
|
||||||
static const std::map<wxString, wxString> variableMap = {
|
static const std::map<wxString, wxString> variableMap = {
|
||||||
{ "LAYER_NAME", "LAYER" },
|
{ "LAYER_NAME", "LAYER" },
|
||||||
|
@ -3933,35 +3936,104 @@ void ALTIUM_PCB::ConvertTexts6ToBoardItemOnLayer( const ATEXT6& aElem, PCB_LAYER
|
||||||
};
|
};
|
||||||
|
|
||||||
wxString kicadText = AltiumPcbSpecialStringsToKiCadStrings( aElem.text, variableMap );
|
wxString kicadText = AltiumPcbSpecialStringsToKiCadStrings( aElem.text, variableMap );
|
||||||
|
BOARD_ITEM* item = pcbText.get();
|
||||||
|
EDA_TEXT* text = pcbText.get();
|
||||||
|
|
||||||
pcbText->SetText(kicadText);
|
if( isTextbox )
|
||||||
pcbText->SetLayer( aLayer );
|
{
|
||||||
|
// Altium textboxes do not have borders
|
||||||
|
pcbTextbox->SetBorderEnabled( false );
|
||||||
|
|
||||||
|
item = pcbTextbox.get();
|
||||||
|
text = pcbTextbox.get();
|
||||||
|
pcbTextbox->SetPosition( aElem.position );
|
||||||
|
pcbTextbox->SetRectangle( -aElem.textbox_rect_height, aElem.textbox_rect_width );
|
||||||
|
|
||||||
|
switch( aElem.textbox_rect_justification )
|
||||||
|
{
|
||||||
|
case ALTIUM_TEXT_POSITION::LEFT_TOP:
|
||||||
|
case ALTIUM_TEXT_POSITION::LEFT_CENTER:
|
||||||
|
case ALTIUM_TEXT_POSITION::LEFT_BOTTOM:
|
||||||
|
pcbTextbox->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
|
||||||
|
pcbTextbox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||||
|
break;
|
||||||
|
case ALTIUM_TEXT_POSITION::CENTER_TOP:
|
||||||
|
case ALTIUM_TEXT_POSITION::CENTER_CENTER:
|
||||||
|
case ALTIUM_TEXT_POSITION::CENTER_BOTTOM:
|
||||||
|
pcbTextbox->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
|
||||||
|
pcbTextbox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||||
|
break;
|
||||||
|
case ALTIUM_TEXT_POSITION::RIGHT_TOP:
|
||||||
|
case ALTIUM_TEXT_POSITION::RIGHT_CENTER:
|
||||||
|
case ALTIUM_TEXT_POSITION::RIGHT_BOTTOM:
|
||||||
|
pcbTextbox->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
|
||||||
|
pcbTextbox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if( m_reporter )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
msg.Printf( _( "Unknown textbox justification %d, text %s" ),
|
||||||
|
aElem.textbox_rect_justification, aElem.text );
|
||||||
|
m_reporter->Report( msg, RPT_SEVERITY_DEBUG );
|
||||||
|
}
|
||||||
|
|
||||||
|
pcbTextbox->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
|
||||||
|
pcbTextbox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pcbText->SetPosition( aElem.position );
|
pcbText->SetPosition( aElem.position );
|
||||||
pcbText->SetTextAngle( EDA_ANGLE( aElem.rotation, DEGREES_T ) );
|
pcbText->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
|
||||||
|
pcbText->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
|
||||||
|
}
|
||||||
|
|
||||||
ConvertTexts6ToEdaTextSettings( aElem, pcbText );
|
text->SetText(kicadText);
|
||||||
|
item->SetLayer( aLayer );
|
||||||
|
item->SetIsKnockout( aElem.isInverted );
|
||||||
|
|
||||||
m_board->Add( pcbText, ADD_MODE::APPEND );
|
ConvertTexts6ToEdaTextSettings( aElem, text );
|
||||||
|
|
||||||
|
if( isTextbox )
|
||||||
|
m_board->Add( pcbTextbox.release(), ADD_MODE::APPEND );
|
||||||
|
else
|
||||||
|
m_board->Add( pcbText.release(), ADD_MODE::APPEND );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertTexts6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, const ATEXT6& aElem,
|
void ALTIUM_PCB::ConvertTexts6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, const ATEXT6& aElem,
|
||||||
PCB_LAYER_ID aLayer )
|
PCB_LAYER_ID aLayer )
|
||||||
{
|
{
|
||||||
PCB_TEXT* fpText;
|
std::unique_ptr<PCB_TEXTBOX> fpTextbox = std::make_unique<PCB_TEXTBOX>( aFootprint );
|
||||||
|
std::unique_ptr<PCB_TEXT> fpText = std::make_unique<PCB_TEXT>( aFootprint );
|
||||||
|
|
||||||
|
BOARD_ITEM* item = fpText.get();
|
||||||
|
EDA_TEXT* text = fpText.get();
|
||||||
|
PCB_FIELD* field = nullptr;
|
||||||
|
|
||||||
|
bool isTextbox = ( aElem.textbox_rect_height != 0 );
|
||||||
|
bool toAdd = false;
|
||||||
|
|
||||||
if( aElem.isDesignator )
|
if( aElem.isDesignator )
|
||||||
{
|
{
|
||||||
fpText = &aFootprint->Reference(); // TODO: handle multiple layers
|
item = &aFootprint->Reference(); // TODO: handle multiple layers
|
||||||
|
text = &aFootprint->Reference();
|
||||||
|
field = &aFootprint->Reference();
|
||||||
}
|
}
|
||||||
else if( aElem.isComment )
|
else if( aElem.isComment )
|
||||||
{
|
{
|
||||||
fpText = &aFootprint->Value(); // TODO: handle multiple layers
|
item = &aFootprint->Value(); // TODO: handle multiple layers
|
||||||
|
text = &aFootprint->Value();
|
||||||
|
field = &aFootprint->Value();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fpText = new PCB_TEXT( aFootprint );
|
item = fpText.get();
|
||||||
aFootprint->Add( fpText, ADD_MODE::APPEND );
|
text = fpText.get();
|
||||||
|
toAdd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::map<wxString, wxString> variableMap = {
|
static const std::map<wxString, wxString> variableMap = {
|
||||||
|
@ -3974,19 +4046,77 @@ void ALTIUM_PCB::ConvertTexts6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, con
|
||||||
|
|
||||||
wxString kicadText = AltiumPcbSpecialStringsToKiCadStrings( aElem.text, variableMap );
|
wxString kicadText = AltiumPcbSpecialStringsToKiCadStrings( aElem.text, variableMap );
|
||||||
|
|
||||||
fpText->SetText(kicadText);
|
text->SetText(kicadText);
|
||||||
fpText->SetKeepUpright( false );
|
text->SetKeepUpright( false );
|
||||||
fpText->SetLayer( aLayer );
|
item->SetLayer( aLayer );
|
||||||
fpText->SetPosition( aElem.position );
|
item->SetIsKnockout( aElem.isInverted );
|
||||||
fpText->SetTextAngle( EDA_ANGLE( aElem.rotation, DEGREES_T ) );
|
|
||||||
|
|
||||||
ConvertTexts6ToEdaTextSettings( aElem, fpText );
|
if( isTextbox )
|
||||||
|
{
|
||||||
|
item = fpTextbox.get();
|
||||||
|
text = fpTextbox.get();
|
||||||
|
fpTextbox->SetPosition( aElem.position );
|
||||||
|
fpTextbox->SetRectangle( aElem.textbox_rect_height, aElem.textbox_rect_width );
|
||||||
|
|
||||||
|
// KiCad only does top alignment for textboxes atm
|
||||||
|
switch( aElem.textbox_rect_justification )
|
||||||
|
{
|
||||||
|
case ALTIUM_TEXT_POSITION::LEFT_TOP:
|
||||||
|
case ALTIUM_TEXT_POSITION::LEFT_CENTER:
|
||||||
|
case ALTIUM_TEXT_POSITION::LEFT_BOTTOM:
|
||||||
|
fpTextbox->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
|
||||||
|
fpTextbox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||||
|
break;
|
||||||
|
case ALTIUM_TEXT_POSITION::CENTER_TOP:
|
||||||
|
case ALTIUM_TEXT_POSITION::CENTER_CENTER:
|
||||||
|
case ALTIUM_TEXT_POSITION::CENTER_BOTTOM:
|
||||||
|
fpTextbox->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
|
||||||
|
fpTextbox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||||
|
break;
|
||||||
|
case ALTIUM_TEXT_POSITION::RIGHT_TOP:
|
||||||
|
case ALTIUM_TEXT_POSITION::RIGHT_CENTER:
|
||||||
|
case ALTIUM_TEXT_POSITION::RIGHT_BOTTOM:
|
||||||
|
fpTextbox->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
|
||||||
|
fpTextbox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if( m_reporter )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
msg.Printf( _( "Unknown textbox justification %d, text %s" ),
|
||||||
|
aElem.textbox_rect_justification, aElem.text );
|
||||||
|
m_reporter->Report( msg, RPT_SEVERITY_DEBUG );
|
||||||
|
}
|
||||||
|
|
||||||
|
fpTextbox->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
|
||||||
|
fpTextbox->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field->SetPosition( aElem.position );
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertTexts6ToEdaTextSettings( aElem, *text );
|
||||||
|
|
||||||
|
if( toAdd )
|
||||||
|
{
|
||||||
|
if( isTextbox )
|
||||||
|
aFootprint->Add( fpTextbox.release(), ADD_MODE::APPEND );
|
||||||
|
else
|
||||||
|
aFootprint->Add( fpText.release(), ADD_MODE::APPEND );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ALTIUM_PCB::ConvertTexts6ToEdaTextSettings( const ATEXT6& aElem, EDA_TEXT* aEdaText )
|
void ALTIUM_PCB::ConvertTexts6ToEdaTextSettings( const ATEXT6& aElem, EDA_TEXT* aEdaText )
|
||||||
{
|
{
|
||||||
aEdaText->SetTextSize( VECTOR2I( aElem.height, aElem.height ) ); // TODO: parse text width
|
// Altium counts the width of the text from the centerline of each stroke while KiCad measures
|
||||||
|
// it to the outside of the stroke. TODO: need to adjust this based on the stroke font. Altium Default is
|
||||||
|
// definitely wider than the sans serif font.
|
||||||
|
aEdaText->SetTextSize( VECTOR2I( aElem.height, aElem.height + aElem.strokewidth ) );
|
||||||
|
|
||||||
if( aElem.fonttype == ALTIUM_TEXT_TYPE::TRUETYPE )
|
if( aElem.fonttype == ALTIUM_TEXT_TYPE::TRUETYPE )
|
||||||
{
|
{
|
||||||
|
@ -4007,12 +4137,7 @@ void ALTIUM_PCB::ConvertTexts6ToEdaTextSettings( const ATEXT6& aElem, EDA_TEXT*
|
||||||
aEdaText->SetBold( aElem.isBold );
|
aEdaText->SetBold( aElem.isBold );
|
||||||
aEdaText->SetItalic( aElem.isItalic );
|
aEdaText->SetItalic( aElem.isItalic );
|
||||||
aEdaText->SetMirrored( aElem.isMirrored );
|
aEdaText->SetMirrored( aElem.isMirrored );
|
||||||
|
aEdaText->SetTextAngle( EDA_ANGLE( aElem.rotation, DEGREES_T ) );
|
||||||
// Altium position always specifies the bottom left corner
|
|
||||||
aEdaText->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
|
|
||||||
aEdaText->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
|
|
||||||
|
|
||||||
// TODO: correct the position and set proper justification
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue