@ -3333,11 +3333,21 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const
return & Glyphs . Data [ i ] ;
}
const char * ImFont : : CalcWordWrapPositionA ( float scale , const char * text , const char * text_end , float wrap_width ) const
// Wrapping skips upcoming blanks
static inline const char * CalcWordWrapNextLineStartA ( const char * text , const char * text_end )
{
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
while ( text < text_end & & ImCharIsBlankA ( * text ) )
text + + ;
if ( * text = = ' \n ' )
text + + ;
return text ;
}
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
const char * ImFont : : CalcWordWrapPositionA ( float scale , const char * text , const char * text_end , float wrap_width ) const
{
// For references, possible wrap point marked with ^
// "aaa bbb, ccc,ddd. eee fff. ggg!"
// ^ ^ ^ ^ ^__ ^ ^
@ -3349,7 +3359,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
// Cut words that cannot possibly fit within one line.
// e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"
float line_width = 0.0f ;
float word_width = 0.0f ;
float blank_width = 0.0f ;
@ -3429,6 +3438,10 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
s = next_s ;
}
// Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
// +1 may not be a character start point in UTF-8 but it's ok because caller loops use (text >= word_wrap_eol).
if ( s = = text & & text < text_end )
return s + 1 ;
return s ;
}
@ -3453,11 +3466,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
{
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
if ( ! word_wrap_eol )
{
word_wrap_eol = CalcWordWrapPositionA ( scale , s , text_end , wrap_width - line_width ) ;
if ( word_wrap_eol = = s ) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
word_wrap_eol + + ; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
}
if ( s > = word_wrap_eol )
{
@ -3466,13 +3475,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
text_size . y + = line_height ;
line_width = 0.0f ;
word_wrap_eol = NULL ;
// Wrapping skips upcoming blanks
while ( s < text_end )
{
const char c = * s ;
if ( ImCharIsBlankA ( c ) ) { s + + ; } else if ( c = = ' \n ' ) { s + + ; break ; } else { break ; }
}
s = CalcWordWrapNextLineStartA ( s , text_end ) ; // Wrapping skips upcoming blanks
continue ;
}
}
@ -3557,7 +3560,6 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
const float scale = size / FontSize ;
const float line_height = FontSize * scale ;
const bool word_wrap_enabled = ( wrap_width > 0.0f ) ;
const char * word_wrap_eol = NULL ;
// Fast-forward to first visible line
const char * s = text_begin ;
@ -3597,6 +3599,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
unsigned int vtx_current_idx = draw_list - > _VtxCurrentIdx ;
const ImU32 col_untinted = col | ~ IM_COL32_A_MASK ;
const char * word_wrap_eol = NULL ;
while ( s < text_end )
{
@ -3604,24 +3607,14 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
{
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
if ( ! word_wrap_eol )
{
word_wrap_eol = CalcWordWrapPositionA ( scale , s , text_end , wrap_width - ( x - start_x ) ) ;
if ( word_wrap_eol = = s ) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
word_wrap_eol + + ; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
}
if ( s > = word_wrap_eol )
{
x = start_x ;
y + = line_height ;
word_wrap_eol = NULL ;
// Wrapping skips upcoming blanks
while ( s < text_end )
{
const char c = * s ;
if ( ImCharIsBlankA ( c ) ) { s + + ; } else if ( c = = ' \n ' ) { s + + ; break ; } else { break ; }
}
s = CalcWordWrapNextLineStartA ( s , text_end ) ; // Wrapping skips upcoming blanks
continue ;
}
}