diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index fa800948ca..3016505a44 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -289,6 +289,7 @@ set( COMMON_SRCS selcolor.cpp settings.cpp systemdirsappend.cpp + text_utils.cpp trigo.cpp utf8.cpp validators.cpp diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 29d15096b4..a4eeed546b 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -31,6 +31,7 @@ #include <gal/definitions.h> #include <gl_context_mgr.h> #include <geometry/shape_poly_set.h> +#include <text_utils.h> #include <macros.h> @@ -879,13 +880,16 @@ void OPENGL_GAL::BitmapText( const wxString& aText, const VECTOR2D& aPosition, { wxASSERT_MSG( !IsTextMirrored(), "No support for mirrored text using bitmap fonts." ); + auto processedText = ProcessOverbars( aText ); + const auto& text = processedText.first; + const auto& overbars = processedText.second; + // Compute text size, so it can be properly justified VECTOR2D textSize; float commonOffset; - std::tie( textSize, commonOffset ) = computeBitmapTextSize( aText ); + std::tie( textSize, commonOffset ) = computeBitmapTextSize( text ); const double SCALE = GetGlyphSize().y / textSize.y; - int tildas = 0; bool overbar = false; int overbarLength = 0; @@ -936,46 +940,39 @@ void OPENGL_GAL::BitmapText( const wxString& aText, const VECTOR2D& aPosition, break; } - for( unsigned int ii = 0; ii < aText.length(); ++ii ) + int i = 0; + + for( UTF8::uni_iter chIt = text.ubegin(), end = text.uend(); chIt < end; ++chIt ) { - unsigned int c = aText[ii]; + unsigned int c = *chIt; wxASSERT_MSG( LookupGlyph(c) != nullptr, wxT( "Missing character in bitmap font atlas." ) ); wxASSERT_MSG( c != '\n' && c != '\r', wxT( "No support for multiline bitmap text yet" ) ); // Handle overbar - if( c == '~' ) + if( overbars[i] && !overbar ) { - overbar = !overbar; - ++tildas; - continue; + overbar = true; // beginning of an overbar } - else if( tildas > 0 ) + else if( overbar && !overbars[i] ) { - if( tildas % 2 == 1 ) - { - if( overbar ) // Overbar begins - overbarLength = 0; - else if( overbarLength > 0 ) // Overbar finishes - drawBitmapOverbar( overbarLength, overbarHeight ); - - --tildas; - } - - // Draw tilda characters if there are any remaining - for( int jj = 0; jj < tildas / 2; ++jj ) - overbarLength += drawBitmapChar( '~' ); - - tildas = 0; + overbar = false; // end of an overbar + drawBitmapOverbar( overbarLength, overbarHeight ); + overbarLength = 0; } - overbarLength += drawBitmapChar( c ); + if( overbar ) + overbarLength += drawBitmapChar( c ); + else + drawBitmapChar( c ); + + ++i; } // Handle the case when overbar is active till the end of the drawn text currentManager->Translate( 0, commonOffset, 0 ); - if( overbar ) + if( overbar && overbarLength > 0 ) drawBitmapOverbar( overbarLength, overbarHeight ); Restore(); @@ -1664,32 +1661,15 @@ void OPENGL_GAL::drawBitmapOverbar( double aLength, double aHeight ) Restore(); } -std::pair<VECTOR2D, float> OPENGL_GAL::computeBitmapTextSize( const wxString& aText ) const + +std::pair<VECTOR2D, float> OPENGL_GAL::computeBitmapTextSize( const UTF8& aText ) const { VECTOR2D textSize( 0, 0 ); float commonOffset = std::numeric_limits<float>::max(); - bool wasTilda = false; - for( unsigned int i = 0; i < aText.length(); ++i ) + for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt ) { - // Remove overbar control characters - if( aText[i] == '~' ) - { - if( !wasTilda ) - { - // Only double tildas are counted as characters, so skip it as it might - // be an overbar control character - wasTilda = true; - continue; - } - else - { - // Double tilda detected, reset the state and process as a normal character - wasTilda = false; - } - } - - unsigned int c = aText[i]; + unsigned int c = *chIt; const FONT_GLYPH_TYPE* glyph = LookupGlyph( c ); wxASSERT( glyph ); @@ -1702,7 +1682,6 @@ std::pair<VECTOR2D, float> OPENGL_GAL::computeBitmapTextSize( const wxString& aT glyph = LookupGlyph( c ); } - if( glyph ) { textSize.x += glyph->advance; diff --git a/common/gal/stroke_font.cpp b/common/gal/stroke_font.cpp index ce93291971..ea08fa49ab 100644 --- a/common/gal/stroke_font.cpp +++ b/common/gal/stroke_font.cpp @@ -28,8 +28,10 @@ #include <gal/stroke_font.h> #include <gal/graphics_abstraction_layer.h> +#include <text_utils.h> #include <wx/string.h> + using namespace KIGFX; const double STROKE_FONT::INTERLINE_PITCH_RATIO = 1.5; @@ -241,9 +243,6 @@ void STROKE_FONT::Draw( const UTF8& aText, const VECTOR2D& aPosition, double aRo void STROKE_FONT::drawSingleLineText( const UTF8& aText ) { - // By default the overbar is turned off - bool overbar = false; - double xOffset; VECTOR2D glyphSize( m_gal->GetGlyphSize() ); double overbar_italic_comp = computeOverbarVerticalPosition() * ITALIC_TILT; @@ -303,21 +302,13 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText ) // must not be indented on subsequent letters to ensure that the bar segments // overlap. bool last_had_overbar = false; + auto processedText = ProcessOverbars( aText ); + const auto& text = processedText.first; + const auto& overbars = processedText.second; + int i = 0; - for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt ) + for( UTF8::uni_iter chIt = text.ubegin(), end = text.uend(); chIt < end; ++chIt ) { - // Toggle overbar - if( *chIt == '~' ) - { - if( ++chIt >= end ) - break; - - if( *chIt != '~' ) // It was a single tilda, it toggles overbar - overbar = !overbar; - - // If it is a double tilda, just process the second one - } - int dd = *chIt - ' '; if( dd >= (int) m_glyphBoundingBoxes.size() || dd < 0 ) @@ -326,7 +317,7 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText ) GLYPH& glyph = m_glyphs[dd]; BOX2D& bbox = m_glyphBoundingBoxes[dd]; - if( overbar ) + if( overbars[i] ) { double overbar_start_x = xOffset; double overbar_start_y = - computeOverbarVerticalPosition(); @@ -376,6 +367,7 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText ) } xOffset += glyphSize.x * bbox.GetEnd().x; + ++i; } m_gal->Restore(); diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index 5c8d402fc6..201302eeb6 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -420,7 +420,7 @@ private: * @return Pair containing text bounding box and common Y axis offset. The values are expressed * as a number of pixels on the bitmap font texture and need to be scaled before drawing. */ - std::pair<VECTOR2D, float> computeBitmapTextSize( const wxString& aText ) const; + std::pair<VECTOR2D, float> computeBitmapTextSize( const UTF8& aText ) const; // Event handling /**