Cleanup Altium text import

Handle inverted text
Correct location for flags
Add mechanics to detect inverted_rect (like text boxes)
This commit is contained in:
Seth Hillbrand 2024-06-16 13:07:39 -07:00
parent 5c699e3c1e
commit b11e030f8f
3 changed files with 54 additions and 20 deletions

View File

@ -1010,13 +1010,23 @@ ATEXT6::ATEXT6( ALTIUM_BINARY_PARSER& aReader, std::map<uint32_t, wxString>& aSt
aReader.Skip( 4 );
position = aReader.ReadVector2IPos();
height = aReader.ReadKicadUnit();
aReader.Skip( 2 );
strokefonttype = static_cast<STROKE_FONT_TYPE>( aReader.Read<uint16_t>() );
// TODO: The Serif font type doesn't match well with KiCad, we should replace it with a better match
rotation = aReader.Read<double>();
isMirrored = aReader.Read<uint8_t>() != 0;
strokewidth = aReader.ReadKicadUnit();
if( subrecord1 < 123 )
{
aReader.SkipSubrecord();
return;
}
isComment = aReader.Read<uint8_t>() != 0;
isDesignator = aReader.Read<uint8_t>() != 0;
aReader.Skip( 2 );
aReader.Skip( 1 );
fonttype = static_cast<ALTIUM_TEXT_TYPE>( aReader.Read<uint8_t>() );
isBold = aReader.Read<uint8_t>() != 0;
isItalic = aReader.Read<uint8_t>() != 0;
@ -1024,27 +1034,26 @@ ATEXT6::ATEXT6( ALTIUM_BINARY_PARSER& aReader, std::map<uint32_t, wxString>& aSt
aReader.ReadBytes( fontData, sizeof( fontData ) );
fontname = wxString( fontData, wxMBConvUTF16LE(), sizeof( fontData ) ).BeforeFirst( '\0' );
isInverted = aReader.Read<uint8_t>() != 0;
char tmpbyte = aReader.Read<uint8_t>();
isInverted = !!tmpbyte;
inverted_borderwidth = aReader.ReadKicadUnit();
widestring_index = aReader.Read<uint32_t>();
aReader.Skip( 4 );
uint32_t stringIndex = aReader.Read<uint32_t>();
aReader.Skip( 13 );
textposition = static_cast<ALTIUM_TEXT_POSITION>( aReader.Read<uint8_t>() );
/**
* In Altium 14 (subrecord1 == 230) only left bottom is valid? I think there is a bit missing.
* https://gitlab.com/kicad/code/kicad/-/merge_requests/60#note_274913397
*/
if( subrecord1 <= 230 )
textposition = ALTIUM_TEXT_POSITION::LEFT_BOTTOM;
aReader.Skip( 27 );
fonttype = static_cast<ALTIUM_TEXT_TYPE>( aReader.Read<uint8_t>() );
// An inverted rect in Altium is like a text box with the text inverted. The box has a defined
// width and height, justification and offet (indent). This is not currently supported in KiCad.
isInvertedRect = aReader.Read<uint8_t>() != 0;
inverted_rect_width = aReader.ReadKicadUnit();
inverted_rect_height = aReader.ReadKicadUnit();
inverted_rect_justification = static_cast<ALTIUM_TEXT_POSITION>( aReader.Read<uint8_t>() );
inverted_rect_offset = aReader.ReadKicadUnit();
aReader.SkipSubrecord();
// Subrecord 2 - Legacy 8bit string, max 255 chars, unknown codepage
aReader.ReadAndSetSubrecordLength();
auto entry = aStringTable.find( stringIndex );
auto entry = aStringTable.find( widestring_index );
if( entry != aStringTable.end() )
text = entry->second;
@ -1056,6 +1065,13 @@ ATEXT6::ATEXT6( ALTIUM_BINARY_PARSER& aReader, std::map<uint32_t, wxString>& aSt
aReader.SkipSubrecord();
// Altium only supports inverting truetype fonts
if( fonttype != ALTIUM_TEXT_TYPE::TRUETYPE )
{
isInverted = false;
isInvertedRect = false;
}
if( aReader.HasParsingError() )
THROW_IO_ERROR( wxT( "Texts6 stream was not parsed correctly" ) );
}

View File

@ -718,6 +718,14 @@ struct ATRACK6
struct ATEXT6
{
enum class STROKE_FONT_TYPE
{
DEFAULT = 1,
SANSSERIF = 2,
SERIF = 3
};
ALTIUM_LAYER layer;
uint16_t component;
@ -725,12 +733,23 @@ struct ATEXT6
uint32_t height;
double rotation;
uint32_t strokewidth;
ALTIUM_TEXT_POSITION textposition;
STROKE_FONT_TYPE strokefonttype;
bool isBold;
bool isItalic;
bool isMirrored;
bool isInverted;
bool isInvertedRect;
uint32_t inverted_borderwidth;
uint32_t inverted_rect_width;
uint32_t inverted_rect_height;
uint32_t inverted_rect_offset;
// Justification only applies when there is a text box size specified
// Then, the text is justified within the box
ALTIUM_TEXT_POSITION inverted_rect_justification;
uint32_t widestring_index;
bool isComment;
bool isDesignator;

View File

@ -4084,7 +4084,7 @@ void ALTIUM_PCB::ConvertTexts6ToBoardItemOnLayer( const ATEXT6& aElem, PCB_LAYER
pcbText->SetText(kicadText);
pcbText->SetLayer( aLayer );
pcbText->SetPosition( aElem.position );
pcbText->SetTextAngle( EDA_ANGLE( aElem.rotation, DEGREES_T ) );
pcbText->SetIsKnockout( aElem.isInverted );
ConvertTexts6ToEdaTextSettings( aElem, *pcbText );
@ -4125,7 +4125,7 @@ void ALTIUM_PCB::ConvertTexts6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, con
fpText->SetKeepUpright( false );
fpText->SetLayer( aLayer );
fpText->SetPosition( aElem.position );
fpText->SetTextAngle( EDA_ANGLE( aElem.rotation, DEGREES_T ) );
fpText->SetIsKnockout( aElem.isInverted );
ConvertTexts6ToEdaTextSettings( aElem, *fpText );
}
@ -4154,12 +4154,11 @@ void ALTIUM_PCB::ConvertTexts6ToEdaTextSettings( const ATEXT6& aElem, EDA_TEXT&
aEdaText.SetBoldFlag( aElem.isBold );
aEdaText.SetItalic( aElem.isItalic );
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
}