diff --git a/common/string_utils.cpp b/common/string_utils.cpp index 646f9b4734..3fb336530e 100644 --- a/common/string_utils.cpp +++ b/common/string_utils.cpp @@ -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"; diff --git a/include/string_utils.h b/include/string_utils.h index dfdc20c831..3e9e574541 100644 --- a/include/string_utils.h +++ b/include/string_utils.h @@ -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 * diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 5b0faa1055..3dc19faa71 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -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 );