Exclude formatting chars from text width approximation.

Fixes https://gitlab.com/kicad/code/kicad/issues/9080
This commit is contained in:
Jeff Young 2021-09-04 22:08:52 +01:00
parent 6818539f6d
commit 59c15842f8
3 changed files with 103 additions and 11 deletions

View File

@ -452,7 +452,7 @@ wxString EscapeHTML( const wxString& aString )
{
wxString converted;
for( wxUniChar c: aString )
for( wxUniChar c : aString )
{
if( c == '\"' )
converted += """;
@ -480,6 +480,90 @@ bool NoPrintableChars( const wxString& aString )
}
/**
* Return the number of printable (ie: non-formatting) chars. Used to approximate rendered
* text size when speed is more important than accuracy.
*/
int PrintableCharCount( const wxString& aString )
{
int char_count = 0;
int overbarDepth = -1;
int superSubDepth = -1;
int braceNesting = 0;
for( auto chIt = aString.begin(), end = aString.end(); chIt < end; ++chIt )
{
if( *chIt == '\t' )
{
// We don't format tabs in bitmap text (where this is currently used), so just
// drop them from the count.
continue;
}
else if( *chIt == '^' && superSubDepth == -1 )
{
auto lookahead = chIt;
if( ++lookahead != end && *lookahead == '{' )
{
chIt = lookahead;
superSubDepth = braceNesting;
braceNesting++;
continue;
}
}
else if( *chIt == '_' && superSubDepth == -1 )
{
auto lookahead = chIt;
if( ++lookahead != end && *lookahead == '{' )
{
chIt = lookahead;
superSubDepth = braceNesting;
braceNesting++;
continue;
}
}
else if( *chIt == '~' && overbarDepth == -1 )
{
auto lookahead = chIt;
if( ++lookahead != end && *lookahead == '{' )
{
chIt = lookahead;
overbarDepth = braceNesting;
braceNesting++;
continue;
}
}
else if( *chIt == '{' )
{
braceNesting++;
}
else if( *chIt == '}' )
{
if( braceNesting > 0 )
braceNesting--;
if( braceNesting == superSubDepth )
{
superSubDepth = -1;
continue;
}
if( braceNesting == overbarDepth )
{
overbarDepth = -1;
continue;
}
}
char_count++;
}
return char_count;
}
char* StrPurge( char* text )
{
static const char whitespace[] = " \t\n\r\f\v";

View File

@ -133,6 +133,12 @@ char* GetLine( FILE* aFile, char* Line, int* LineNum = nullptr, int SizeLine = 2
*/
bool NoPrintableChars( const wxString& aString );
/**
* Return the number of printable (ie: non-formatting) chars. Used to approximate rendered
* text size when speed is more important than accuracy.
*/
int PrintableCharCount( const wxString& aString );
/**
* Remove leading and training spaces, tabs and end of line chars in \a text
*

View File

@ -778,8 +778,8 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer )
wxString netname = UnescapeString( aVia->GetShortNetname() );
// calculate the size of net name text:
double tsize = 1.5 * size / netname.Length();
// approximate the size of net name text:
double tsize = 1.5 * size / PrintableCharCount( netname );
tsize = std::min( tsize, size );
// Use a smaller text size to handle interline, pen size..
@ -960,8 +960,8 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
// position to display 2 lines
if( displayNetname && m_pcbSettings.m_padNumbers )
{
size = size / 2.0;
textpos.y = size / 2.0;
size = size / 2.5;
textpos.y = size / 1.7;
}
if( displayNetname )
@ -974,11 +974,11 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
else if( pinType == wxT( "free" ) && netname.StartsWith( wxT( "unconnected-(" ) ) )
netname = "*";
// calculate the size of net name text:
double tsize = 1.5 * padsize.x / netname.Length();
// approximate the size of net name text:
double tsize = 1.5 * padsize.x / PrintableCharCount( netname );
tsize = std::min( tsize, size );
// Use a smaller text size to handle interline, pen size..
// Use a smaller text size to handle interline, pen size...
tsize *= 0.7;
VECTOR2D namesize( tsize, tsize );
@ -991,10 +991,12 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
{
const wxString& padNumber = aPad->GetNumber();
textpos.y = -textpos.y;
double tsize = 1.5 * padsize.x / padNumber.Length();
// approximate the size of the pad number text:
double tsize = 1.5 * padsize.x / PrintableCharCount( padNumber );
tsize = std::min( tsize, size );
// Use a smaller text size to handle interline, pen size..
// Use a smaller text size to handle interline, pen size...
tsize *= 0.7;
tsize = std::min( tsize, size );
VECTOR2D numsize( tsize, tsize );
@ -1665,7 +1667,7 @@ void PCB_PAINTER::draw( const PCB_GROUP* aGroup, int aLayer )
wxPoint textOffset = wxPoint( width.x / 2, - KiROUND( textSize * 0.5 ) );
wxPoint titleHeight = wxPoint( 0, KiROUND( textSize * 2.0 ) );
if( !name.IsEmpty() && (int) aGroup->GetName().Length() * textSize < bbox.GetWidth() )
if( PrintableCharCount( name ) * textSize < bbox.GetWidth() )
{
m_gal->DrawLine( topLeft, topLeft - titleHeight );
m_gal->DrawLine( topLeft - titleHeight, topLeft + width - titleHeight );