diff --git a/common/eda_text.cpp b/common/eda_text.cpp index d008a8a76d..83b27656cb 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -248,7 +248,7 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const // because only this line can change the bounding box for( unsigned ii = 1; ii < text.size(); ii++ ) { - if( text[ii-1] == '~' && text[ii] != '~' ) + if( text[ii-1] == '~' && text[ii] == '{' ) { hasOverBar = true; break; diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 0fd33a35d5..a0f1b11b72 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -1303,52 +1303,54 @@ void OPENGL_GAL::BitmapText( const wxString& aText, const VECTOR2D& aPosition, break; } - int i = 0; + int overbarDepth = -1; + int braceNesting = 0; for( UTF8::uni_iter chIt = text.ubegin(), end = text.uend(); chIt < end; ++chIt ) { - unsigned int c = *chIt; - wxASSERT_MSG( c != '\n' && c != '\r', wxT( "No support for multiline bitmap text yet" ) ); + wxASSERT_MSG( *chIt != '\n' && *chIt != '\r', + wxT( "No support for multiline bitmap text yet" ) ); - bool wasOverbar = overbar; + bool wasOverbar = overbarDepth == -1; - if( c == '~' ) + if( *chIt == '~' && overbarDepth == -1 ) { - if( ++chIt == end ) - break; + UTF8::uni_iter lookahead = chIt; - c = *chIt; - - if( c == '~' ) + if( ++lookahead != end && *lookahead == '{' ) { - // double ~ is really a ~ so go ahead and process the second one - - // so what's a triple ~? It could be a real ~ followed by an overbar, or - // it could be an overbar followed by a real ~. The old algorithm did the - // former so we will too.... - } - else - { - overbar = !overbar; + chIt = lookahead; + overbarDepth = braceNesting; + braceNesting++; + continue; } } - else if( c == ' ' || c == '}' || c == ')' ) + else if( *chIt == '{' ) { - overbar = false; + braceNesting++; + } + else if( *chIt == '}' ) + { + if( braceNesting > 0 ) + braceNesting--; + + if( braceNesting == overbarDepth ) + { + overbarDepth = -1; + continue; + } } - if( wasOverbar && !overbar ) + if( wasOverbar && overbarDepth == -1 ) { drawBitmapOverbar( overbarLength, overbarHeight ); overbarLength = 0; } if( overbar ) - overbarLength += drawBitmapChar( c ); + overbarLength += drawBitmapChar( *chIt ); else - drawBitmapChar( c ); - - ++i; + drawBitmapChar( *chIt ); } // Handle the case when overbar is active till the end of the drawn text @@ -2064,33 +2066,38 @@ std::pair OPENGL_GAL::computeBitmapTextSize( const UTF8& aText VECTOR2D textSize( 0, 0 ); float commonOffset = std::numeric_limits::max(); - bool in_overbar = false; - float char_height = font_information.max_y - defaultGlyph->miny; + float charHeight = font_information.max_y - defaultGlyph->miny; + int overbarDepth = -1; + int braceNesting = 0; for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt ) { - if( *chIt == '~' ) + if( *chIt == '~' && overbarDepth == -1 ) { - if( ++chIt == end ) - break; + UTF8::uni_iter lookahead = chIt; - if( *chIt == '~' ) + if( ++lookahead != end && *lookahead == '{' ) { - // double ~ is really a ~ so go ahead and process the second one - - // so what's a triple ~? It could be a real ~ followed by an overbar, or - // it could be an overbar followed by a real ~. The old algorithm did the - // former so we will too.... - } - else - { - // single ~ toggles overbar - in_overbar = !in_overbar; + chIt = lookahead; + overbarDepth = braceNesting; + braceNesting++; + continue; } } - else if( in_overbar && ( *chIt == ' ' || *chIt == '}' || *chIt == ')' ) ) + else if( *chIt == '{' ) { - in_overbar = false; + braceNesting++; + } + else if( *chIt == '}' ) + { + if( braceNesting > 0 ) + braceNesting--; + + if( braceNesting == overbarDepth ) + { + overbarDepth = -1; + continue; + } } const FONT_GLYPH_TYPE* glyph = LookupGlyph( *chIt ); @@ -2105,15 +2112,15 @@ std::pair OPENGL_GAL::computeBitmapTextSize( const UTF8& aText { textSize.x += glyph->advance; - if( in_overbar ) + if( overbarDepth != -1 ) { const float H = lineGlyph->maxy - lineGlyph->miny; - textSize.y = std::max( textSize.y, char_height + 1.5 * H ); + textSize.y = std::max( textSize.y, charHeight + 1.5 * H ); } } } - textSize.y = std::max( textSize.y, char_height ); + textSize.y = std::max( textSize.y, charHeight ); commonOffset = std::min( font_information.max_y - defaultGlyph->maxy, commonOffset ); textSize.y -= commonOffset; diff --git a/common/gal/stroke_font.cpp b/common/gal/stroke_font.cpp index a34292df18..b5059de7d0 100644 --- a/common/gal/stroke_font.cpp +++ b/common/gal/stroke_font.cpp @@ -329,9 +329,10 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText ) // The overbar is indented inward at the beginning of an italicized section, but // must not be indented on subsequent letters to ensure that the bar segments // overlap. - bool last_had_overbar = false; - bool in_overbar = false; - bool in_super_or_subscript = false; + bool lastHadOverbar = false; + int overbarDepth = -1; + int superSubDepth = -1; + int braceNesting = 0; VECTOR2D glyphSize = baseGlyphSize; // Allocate only once (for performance) @@ -354,67 +355,72 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText ) glyphSize = baseGlyphSize; yOffset = 0; - - // Tab ends an overbar - in_overbar = false; } - else if( *chIt == '~' ) + else if( *chIt == '^' && superSubDepth == -1 ) { - if( ++chIt == end ) - break; - - if( *chIt == '~' ) - { - // double ~ is really a ~ so go ahead and process the second one - - // so what's a triple ~? It could be a real ~ followed by an overbar, or - // it could be an overbar followed by a real ~. The old algorithm did the - // former so we will too.... - } - else - { - in_overbar = !in_overbar; - } - } - else if( *chIt == '^' ) - { - auto lookahead = chIt; + UTF8::uni_iter lookahead = chIt; if( ++lookahead != end && *lookahead == '{' ) { - // process superscript chIt = lookahead; - in_super_or_subscript = true; + superSubDepth = braceNesting; + braceNesting++; + glyphSize = baseGlyphSize * 0.8; yOffset = -baseGlyphSize.y * 0.3; continue; } } - else if( *chIt == '_' ) + else if( *chIt == '_' && superSubDepth == -1 ) { - auto lookahead = chIt; + UTF8::uni_iter lookahead = chIt; if( ++lookahead != end && *lookahead == '{' ) { - // process subscript chIt = lookahead; - in_super_or_subscript = true; + superSubDepth = braceNesting; + braceNesting++; + glyphSize = baseGlyphSize * 0.8; yOffset = baseGlyphSize.y * 0.1; continue; } } - else if( *chIt == '}' && in_super_or_subscript ) + else if( *chIt == '~' && overbarDepth == -1 ) { - in_super_or_subscript = false; - glyphSize = baseGlyphSize; - yOffset = 0; - continue; + UTF8::uni_iter lookahead = chIt; + + if( ++lookahead != end && *lookahead == '{' ) + { + chIt = lookahead; + overbarDepth = braceNesting; + braceNesting++; + continue; + } } - // Overbar syntax is less precise so we have to have some special cases - else if( in_overbar && ( *chIt == ' ' || *chIt == '}' || *chIt == ')' ) ) + else if( *chIt == '{' ) { - in_overbar = false; + braceNesting++; + } + else if( *chIt == '}' ) + { + if( braceNesting > 0 ) + braceNesting--; + + if( braceNesting == superSubDepth ) + { + superSubDepth = -1; + + glyphSize = baseGlyphSize; + yOffset = 0; + continue; + } + + if( braceNesting == overbarDepth ) + { + overbarDepth = -1; + continue; + } } // Index into bounding boxes table @@ -429,19 +435,19 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText ) const GLYPH* glyph = m_glyphs->at( dd ); const BOX2D& bbox = m_glyphBoundingBoxes->at( dd ); - if( in_overbar ) + if( overbarDepth != -1 ) { double overbar_start_x = xOffset; double overbar_start_y = - computeOverbarVerticalPosition(); double overbar_end_x = xOffset + glyphSize.x * bbox.GetEnd().x; double overbar_end_y = overbar_start_y; - if( !last_had_overbar ) + if( !lastHadOverbar ) { if( m_gal->IsFontItalic() ) overbar_start_x += overbar_italic_comp; - last_had_overbar = true; + lastHadOverbar = true; } VECTOR2D startOverbar( overbar_start_x, overbar_start_y ); @@ -451,7 +457,7 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText ) } else { - last_had_overbar = false; + lastHadOverbar = false; } if( m_gal->IsFontUnderlined() ) @@ -534,12 +540,13 @@ VECTOR2D STROKE_FONT::ComputeStringBoundaryLimits( const UTF8& aText, const VECT double maxX = 0.0, curX = 0.0; double curScale = 1.0; - bool in_overbar = false; - bool in_super_or_subscript = false; + int overbarDepth = -1; + int superSubDepth = -1; + int braceNesting = 0; - for( UTF8::uni_iter it = aText.ubegin(), end = aText.uend(); it < end; ++it ) + for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt ) { - if( *it == '\n' ) + if( *chIt == '\n' ) { curX = 0.0; maxX = std::max( maxX, curX ); @@ -549,67 +556,52 @@ VECTOR2D STROKE_FONT::ComputeStringBoundaryLimits( const UTF8& aText, const VECT // Handle tabs as locked to the nearest 4th column (counting in spaces) // The choice of spaces is somewhat arbitrary but sufficient for aligning text - if( *it == '\t' ) + if( *chIt == '\t' ) { double spaces = m_glyphBoundingBoxes->at( 0 ).GetEnd().x; double addlSpace = 3.0 * spaces - std::fmod( curX, 4.0 * spaces ); // Add the remaining space (between 0 and 3 spaces) curX += addlSpace; - - // Tab ends an overbar - in_overbar = false; } - else if( *it == '~' ) + else if( (*chIt == '^' || *chIt == '_') && superSubDepth == -1 ) { - if( ++it == end ) - break; - - if( *it == '~' ) - { - // double ~ is really a ~ so go ahead and process the second one - - // so what's a triple ~? It could be a real ~ followed by an overbar, or - // it could be an overbar followed by a real ~. The old algorithm did the - // former so we will too.... - } - else - { - // single ~ toggles overbar - in_overbar = !in_overbar; - } - } - else if( *it == '^' || *it == '_' ) - { - auto lookahead = it; + auto lookahead = chIt; if( ++lookahead != end && *lookahead == '{' ) { // process superscript - it = lookahead; - in_super_or_subscript = true; + chIt = lookahead; + superSubDepth = braceNesting; + curScale = 0.8; continue; } } - else if( *it == '}' && in_super_or_subscript ) + else if( *chIt == '{' ) { - in_super_or_subscript = false; - curScale = 1.0; - continue; + braceNesting++; } - // Overbar syntax is less precise so we have to have some special cases - else if( in_overbar && ( *it == ' ' || *it == '}' || *it == ')' ) ) + else if( *chIt == '}' ) { - in_overbar = false; + if( braceNesting > 0 ) + braceNesting--; + + if( braceNesting == superSubDepth ) + { + superSubDepth = -1; + + curScale = 1.0; + continue; + } } // Index in the bounding boxes table - int dd = (signed) *it - ' '; + int dd = (signed) *chIt - ' '; if( dd >= (int) m_glyphBoundingBoxes->size() || dd < 0 ) { - int substitute = *it == '\t' ? ' ' : '?'; + int substitute = *chIt == '\t' ? ' ' : '?'; dd = substitute - ' '; } diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index d918ab988c..da91a5aef1 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -965,11 +965,12 @@ void DXF_PLOTTER::Text( const wxPoint& aPos, in no more details... */ - bool overlining = false; + int braceNesting = 0; + int overbarDepth = -1; fputs( " 1\n", m_outputFile ); - for( unsigned i = 0; i < aText.length(); i++ ) + for( unsigned int i = 0; i < aText.length(); i++ ) { /* Here I do a bad thing: writing the output one byte at a time! but today I'm lazy and I have no idea on how to coerce a Unicode @@ -986,31 +987,30 @@ void DXF_PLOTTER::Text( const wxPoint& aPos, } else { - if( ch == '~' ) + if( aText[i] == '~' && i+1 < aText.length() && aText[i+1] == '{' ) { - if( ++i == aText.length() ) - break; + fputs( "%%o", m_outputFile ); + overbarDepth = braceNesting; - ch = aText[i]; - - if( ch == '~' ) - { - // double ~ is really a ~ so go ahead and process the second one - - // so what's a triple ~? It could be a real ~ followed by an overbar, - // or it could be an overbar followed by a real ~. The old algorithm - // did the former so we will too.... - } - else - { - // Handle the overline toggle - fputs( overlining ? "%%o" : "%%O", m_outputFile ); - overlining = !overlining; - } + // Skip the '{' + i++; + continue; } - else if( ch == ' ' || ch == '}' || ch == ')' ) + else if( aText[i] == '{' ) { - overlining = false; + braceNesting++; + } + else if( aText[i] == '}' ) + { + if( braceNesting > 0 ) + braceNesting--; + + if( braceNesting == overbarDepth ) + { + fputs( "%%O", m_outputFile ); + overbarDepth = -1; + continue; + } } putc( ch, m_outputFile ); diff --git a/common/project/net_settings.cpp b/common/project/net_settings.cpp index 42b6d237c9..110ff2c18d 100644 --- a/common/project/net_settings.cpp +++ b/common/project/net_settings.cpp @@ -272,9 +272,9 @@ const wxString& NET_SETTINGS::GetNetclassName( const wxString& aNetName ) const } -static bool isSuperSub( wxChar c ) +static bool isSuperSubOverbar( wxChar c ) { - return c == '_' || c == '^'; + return c == '_' || c == '^' || c == '~'; } @@ -304,7 +304,7 @@ bool NET_SETTINGS::ParseBusVector( const wxString& aBus, wxString* aName, { if( aBus[i] == '{' ) { - if( i > 0 && isSuperSub( aBus[i-1] ) ) + if( i > 0 && isSuperSubOverbar( aBus[i-1] ) ) braceNesting++; else return false; @@ -376,10 +376,6 @@ bool NET_SETTINGS::ParseBusVector( const wxString& aBus, wxString* aName, braceNesting--; suffix += aBus[i]; } - else if( aBus[i] == '~' ) - { - suffix += aBus[i]; - } else { return false; @@ -431,7 +427,7 @@ bool NET_SETTINGS::ParseBusGroup( const wxString& aGroup, wxString* aName, { if( aGroup[i] == '{' ) { - if( i > 0 && isSuperSub( aGroup[i-1] ) ) + if( i > 0 && isSuperSubOverbar( aGroup[i-1] ) ) braceNesting++; else break; @@ -464,7 +460,7 @@ bool NET_SETTINGS::ParseBusGroup( const wxString& aGroup, wxString* aName, { if( aGroup[i] == '{' ) { - if( i > 0 && isSuperSub( aGroup[i-1] ) ) + if( i > 0 && isSuperSubOverbar( aGroup[i-1] ) ) braceNesting++; else return false; diff --git a/eeschema/sch_connection.cpp b/eeschema/sch_connection.cpp index 773badd6bb..889b3f31f3 100644 --- a/eeschema/sch_connection.cpp +++ b/eeschema/sch_connection.cpp @@ -497,9 +497,9 @@ const std::vector< std::shared_ptr< SCH_CONNECTION > > SCH_CONNECTION::AllMember } -static bool isSuperSub( wxChar c ) +static bool isSuperSubOverbar( wxChar c ) { - return c == '_' || c == '^'; + return c == '_' || c == '^' || c == '~'; }; @@ -509,30 +509,17 @@ wxString SCH_CONNECTION::PrintBusForUI( const wxString& aGroup ) size_t i = 0; wxString ret; int braceNesting = 0; - int tildeNesting = 0; // Parse prefix // for( ; i < groupLen; ++i ) { - if( isSuperSub( aGroup[i] ) && i + 1 < groupLen && aGroup[i+1] == '{' ) + if( isSuperSubOverbar( aGroup[i] ) && i + 1 < groupLen && aGroup[i+1] == '{' ) { braceNesting++; i++; continue; } - else if( aGroup[i] == '~' ) - { - if( tildeNesting ) - { - tildeNesting = 0; - continue; - } - else - { - tildeNesting++; - } - } else if( aGroup[i] == '}' ) { braceNesting--; @@ -551,24 +538,12 @@ wxString SCH_CONNECTION::PrintBusForUI( const wxString& aGroup ) for( ; i < groupLen; ++i ) { - if( isSuperSub( aGroup[i] ) && i + 1 < groupLen && aGroup[i+1] == '{' ) + if( isSuperSubOverbar( aGroup[i] ) && i + 1 < groupLen && aGroup[i+1] == '{' ) { braceNesting++; i++; continue; } - else if( aGroup[i] == '~' ) - { - if( tildeNesting ) - { - tildeNesting = 0; - continue; - } - else - { - tildeNesting++; - } - } else if( aGroup[i] == '}' ) { braceNesting--;