Jump to content
  • Advertisement
Sign in to follow this  
Dandi8

Word Wrap function not working

This topic is 2897 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I've made a text class using one of LazyFoo's tutorials and now I'm trying to make it go to a new line each time it reaches a certain wrapWidth (word wrapping, essentially).

The thing is, it seems to have problems with getting the 'next word' and counting its length. That much I have gathered from testing. But why doesn't the word length counting part work? I'm guessing I must be getting the word in a wrong way but I just can't figure it out. Please help? Code below.


void TextSystem::DrawWrapped(std::string text, int x, int y, int wrapWidth, int charWidth, GLfloat colorR, GLfloat colorG, GLfloat colorB){
int X = x, Y = y;

//If the font has been built
if( FontTex.Texture != NULL ){
//Go through the text
for( int show = 0; text[ show ] != '\0'; show++ )
{
//If the current character is a space
if( text[ show ] == ' ' ){ //Problems start about here
string nextWord = text.substr(show, text.find_first_of(' ', show));
int wordWidth;
wordWidth=0;

for( int showWord = 0; nextWord[ showWord ] != '\0'; showWord++ ){
int ascii = (unsigned char)nextWord[ showWord ];
int charW=32;
wordWidth+=charW;
} //Problems end about here

if(X+wordWidth > wrapWidth){
Y += ( charWidth / ( float(FontTex.Width)/16 ) ) *newLine;
X = x;
}
else
//Move over
X += space;
}
//If the current character is a newline
else if( text[ show ] == '\n' ){
//Move down
Y += ( charWidth / ( float(FontTex.Width)/16 ) ) *newLine;

//Move back
X = x;
}
else
{
//Get the ASCII value of the character
int ascii = (unsigned char)text[ show ];
//Show the character
int charW=( charWidth / ( float(FontTex.Width)/16 ) ) *chars[ascii].w; //chars[ascii].w;
int charH=( charWidth / ( float(FontTex.Width)/16 ) ) *chars[ascii].h;//chars[ascii].h;
int charSpace=( charWidth / ( float(FontTex.Width)/16 ) ) *characterSpace;
Graphics.DrawTexturePart(FontTex, X, Y, charW, charH, chars[ascii].x, chars[ascii].y, chars[ascii].w, chars[ascii].h, colorR, colorG, colorB);

//Move over the width of the character with one pixel of padding
X += charW+charSpace;//+10;//chars[ ascii ].w + 10;
}
}
}
}


[Edited by - Dandi8 on July 11, 2010 2:31:46 PM]

Share this post


Link to post
Share on other sites
Advertisement
First of all (I haven't taken a look at the code yet) you have to calculate the length of the next word in advance.
The code always has to be a word in front of the actual print.

EDIT: the logic I use (pseudo-code):

//input: str
pos = 0;
i = 0;
line_width = 0;

while( str )
{
pos = i;

if( str == '\n' )
{ newline = true;
line_width = 0;
i++;
}

while( 1 )
{
if( str == ' ' || str == '\n' || !str )
{
word_width = measure_width(str+pos,i-pos);
// first param:string, second param: number of chars to measure

line_width += word_width;

if( line_width > MAX_WIDTH ) // a new line has to be started
{
line_width = word_width;
newline = true;
}
if( str == ' ' ) // a new line has to be started
{
line_width += width_of_space;
i++;
}
break;
}
i++;
}
if( newline = true )
{ Position_back_to_new_line();
newline = false;
}

Print_the_portion_of_the_string(str+pos,i-pos);
// first param:start of string, second param: number of chars to print
}



EDITED: don't ask why the code is so strange. It was long ago when I made this. I always reuse it.

EDIT FINISHED.

[Edited by - szecs on July 11, 2010 2:45:39 PM]

Share this post


Link to post
Share on other sites
Edited the post.
I suggest to use a while instead of for, if you ad new features (newline character, coloured string etc) it's better to increase/manipulate the counter explicitly inside the loop.

Share this post


Link to post
Share on other sites
Okay, I actually took a look at the code. Are you sure you have proportional string? I mean so all the characters have the same width?

To be honest, it's pretty hard to read your code.
I'll have to take another look at it...

Share this post


Link to post
Share on other sites
You seem to have a problem with your logic:
you look for a space, and if you find it and the string is wider than it should be, you start a new line.

BUT that's too late! The word already exceeds the allowed width! Otherwise it wouldn't trigger the new line. But the newline will only affect the next word, not the word that triggers it.

That's why I said you have to look one word after the actually printed word.

That's why my logic has an inner loop.
That actually means a word is looped through twice: once when checked, and once when it's printed.

You can't avoid this double check, because you have to know in advance, if a word will exceed the allowed width or not.

I hope that helps.

Share this post


Link to post
Share on other sites
It's kinda hard to read it because LazyFoo's stuff is itself hard to read and I yet have to do some major overhaul to make the code more readable.

@Sicrane:
Wow, how could I have missed that...!?
Updated the code (also in the post). Unfortunately, the problem is still the same :(

EDIT:
I AM checking the word in advance and it's inside a separate loop so then the reading is supposed to go normally (as if there was no check at all) after the line break.


for( int showWord = 0; nextWord[ showWord ] != '\0'; showWord++ ){
int ascii = (unsigned char)nextWord[ showWord ];
int charW=32;//( charWidth / ( float(FontTex.Width)/16 ) ) *chars[ascii].w;
wordWidth+=charW;
}

This is the part of the code where there is a problem. Notice that I'm using a loop that uses showWord. After that the code continues with the normal 'show' loop.

Share this post


Link to post
Share on other sites
Read my above post + some info about my logic.

The checking for '\n' is done in front of the loop, because it affects the characters/word after the '\n'.

The checking for space and word wrap is done this way, because it affects the word before the space.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!