Fix overbar display in OpenGL canvas

Moved the code handling text overbars to a single function
(ProcessOverbars()) to replace similar pieces of code trying to do the
same thing.

Fixes: lp:1735906
* https://bugs.launchpad.net/kicad/+bug/1735906
This commit is contained in:
Maciej Suminski 2017-12-07 17:20:20 +01:00
parent 86b4a3c3e6
commit 602ecf7502
4 changed files with 38 additions and 66 deletions

View File

@ -289,6 +289,7 @@ set( COMMON_SRCS
selcolor.cpp selcolor.cpp
settings.cpp settings.cpp
systemdirsappend.cpp systemdirsappend.cpp
text_utils.cpp
trigo.cpp trigo.cpp
utf8.cpp utf8.cpp
validators.cpp validators.cpp

View File

@ -31,6 +31,7 @@
#include <gal/definitions.h> #include <gal/definitions.h>
#include <gl_context_mgr.h> #include <gl_context_mgr.h>
#include <geometry/shape_poly_set.h> #include <geometry/shape_poly_set.h>
#include <text_utils.h>
#include <macros.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." ); 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 // Compute text size, so it can be properly justified
VECTOR2D textSize; VECTOR2D textSize;
float commonOffset; float commonOffset;
std::tie( textSize, commonOffset ) = computeBitmapTextSize( aText ); std::tie( textSize, commonOffset ) = computeBitmapTextSize( text );
const double SCALE = GetGlyphSize().y / textSize.y; const double SCALE = GetGlyphSize().y / textSize.y;
int tildas = 0;
bool overbar = false; bool overbar = false;
int overbarLength = 0; int overbarLength = 0;
@ -936,46 +940,39 @@ void OPENGL_GAL::BitmapText( const wxString& aText, const VECTOR2D& aPosition,
break; 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( LookupGlyph(c) != nullptr, wxT( "Missing character in bitmap font atlas." ) );
wxASSERT_MSG( c != '\n' && c != '\r', wxT( "No support for multiline bitmap text yet" ) ); wxASSERT_MSG( c != '\n' && c != '\r', wxT( "No support for multiline bitmap text yet" ) );
// Handle overbar // Handle overbar
if( c == '~' ) if( overbars[i] && !overbar )
{ {
overbar = !overbar; overbar = true; // beginning of an overbar
++tildas;
continue;
} }
else if( tildas > 0 ) else if( overbar && !overbars[i] )
{ {
if( tildas % 2 == 1 ) overbar = false; // end of an overbar
{ drawBitmapOverbar( overbarLength, overbarHeight );
if( overbar ) // Overbar begins overbarLength = 0;
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;
} }
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 // Handle the case when overbar is active till the end of the drawn text
currentManager->Translate( 0, commonOffset, 0 ); currentManager->Translate( 0, commonOffset, 0 );
if( overbar ) if( overbar && overbarLength > 0 )
drawBitmapOverbar( overbarLength, overbarHeight ); drawBitmapOverbar( overbarLength, overbarHeight );
Restore(); Restore();
@ -1664,32 +1661,15 @@ void OPENGL_GAL::drawBitmapOverbar( double aLength, double aHeight )
Restore(); 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 ); VECTOR2D textSize( 0, 0 );
float commonOffset = std::numeric_limits<float>::max(); 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 unsigned int c = *chIt;
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];
const FONT_GLYPH_TYPE* glyph = LookupGlyph( c ); const FONT_GLYPH_TYPE* glyph = LookupGlyph( c );
wxASSERT( glyph ); wxASSERT( glyph );
@ -1702,7 +1682,6 @@ std::pair<VECTOR2D, float> OPENGL_GAL::computeBitmapTextSize( const wxString& aT
glyph = LookupGlyph( c ); glyph = LookupGlyph( c );
} }
if( glyph ) if( glyph )
{ {
textSize.x += glyph->advance; textSize.x += glyph->advance;

View File

@ -28,8 +28,10 @@
#include <gal/stroke_font.h> #include <gal/stroke_font.h>
#include <gal/graphics_abstraction_layer.h> #include <gal/graphics_abstraction_layer.h>
#include <text_utils.h>
#include <wx/string.h> #include <wx/string.h>
using namespace KIGFX; using namespace KIGFX;
const double STROKE_FONT::INTERLINE_PITCH_RATIO = 1.5; 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 ) void STROKE_FONT::drawSingleLineText( const UTF8& aText )
{ {
// By default the overbar is turned off
bool overbar = false;
double xOffset; double xOffset;
VECTOR2D glyphSize( m_gal->GetGlyphSize() ); VECTOR2D glyphSize( m_gal->GetGlyphSize() );
double overbar_italic_comp = computeOverbarVerticalPosition() * ITALIC_TILT; 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 // must not be indented on subsequent letters to ensure that the bar segments
// overlap. // overlap.
bool last_had_overbar = false; 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 - ' '; int dd = *chIt - ' ';
if( dd >= (int) m_glyphBoundingBoxes.size() || dd < 0 ) if( dd >= (int) m_glyphBoundingBoxes.size() || dd < 0 )
@ -326,7 +317,7 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
GLYPH& glyph = m_glyphs[dd]; GLYPH& glyph = m_glyphs[dd];
BOX2D& bbox = m_glyphBoundingBoxes[dd]; BOX2D& bbox = m_glyphBoundingBoxes[dd];
if( overbar ) if( overbars[i] )
{ {
double overbar_start_x = xOffset; double overbar_start_x = xOffset;
double overbar_start_y = - computeOverbarVerticalPosition(); double overbar_start_y = - computeOverbarVerticalPosition();
@ -376,6 +367,7 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
} }
xOffset += glyphSize.x * bbox.GetEnd().x; xOffset += glyphSize.x * bbox.GetEnd().x;
++i;
} }
m_gal->Restore(); m_gal->Restore();

View File

@ -420,7 +420,7 @@ private:
* @return Pair containing text bounding box and common Y axis offset. The values are expressed * @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. * 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 // Event handling
/** /**