I'm trying to get my FontString class to print word-wrapped text within a certain height, but I'm not sure the best way of going about this. Here's my latest attempt (I have another version that does this character-by-character):
int startIndex = 0;
int startSpriteIndex = 0;
int numWordsOnLine = 0;
Vector2 offset;
Sprite *sprite = NULL;
int specialCharIndex = 0;
int startLineIndex = 0;
float spacing = 0.0f;
float glyphWidth = 0.0f;
bool stopUpdating = false;
// remove sprites
batch->RemoveAllSprites();
sprites.clear();
if(!fontPtr) return;
numLines = 1;
// print the text word-by-word
for(int i=0;i<numWords;i++)
{
int specialCharacter = 0;
int index = startIndex;
float wordWidth = 0.0f;
// stop updating the text if deprecated
if(stopUpdating) break;
// get the number of characters in the word
while(index < (int)text.size())
{
// stop counting if a special character was found
if(text[index] == ' ' || text[index] == '\t' || text[index] == '\n' || text[index] == '\0')
{
specialCharacter = (int)text[index];
break;
}
index++; // increment the index
}
// get the word's length
for(int e=startIndex;e<index;e++)
{
FontGlyph *glyph = fontPtr->GetGlyph(text[e], false);
if(!glyph) continue;
wordWidth += glyph->xAdvance;
}
// wrap the word down to the next line
if(offset.x + wordWidth >= dimensions.x && dimensions.x > 0.0f)
{
// process alignment
if(horizontalAlign != FONT_ALIGN_LEFT)
{
// modify the xExtent based on alignment
float xExtent = dimensions.x - offset.x;
if(horizontalAlign == FONT_ALIGN_CENTER)
xExtent *= 0.5f;
//printf("xExtent: %f - %f = %f\n", dimensions.x, offset.x, xExtent);
// space the sprites accordingly
for(int e=startSpriteIndex;e<(int)sprites.size();e++)
{
sprite = (Sprite*)sprites[e];
sprite->Translate(Vector3(xExtent, 0.0f, 0.0f));
}
startSpriteIndex = (int)sprites.size();
}
// go to the next line
if(deprecated) stopUpdating = true;
offset.x = 0.0f;
offset.y += (float)fontPtr->GetCommonData().lineHeight;
numWordsOnLine = 0;
numLines++;
} else numWordsOnLine++;
// set the sprites
for(int e=startIndex;e<index;e++)
{
FontGlyph *glyph = fontPtr->GetGlyph(text[e], false);
if(!glyph) continue;
// add the sprite to the list and set its parameters
//sprite = batch->AddSprite();
sprite = new Sprite("");
batch->AddSprite(sprite);
TexCoords glyphDims((short)glyph->width, (short)glyph->height);
TexCoords glyphPos((short)glyph->x, (short)glyph->y);
sprite->Blit(glyphDims, glyphPos);
sprite->SetColor(color);
// translate and push the sprite into the batch
Vector3 spritePosition(position.x + (float)glyph->xOffset + ((float)sprite->GetDimensions().x / 2.0f) + offset.x, position.y + (float)glyph->yOffset + ((float)sprite->GetDimensions().y / 2.0f) + offset.y, 0.0f);
sprite->Translate(spritePosition);
sprites.push_back(sprite);
offset.x += (float)glyph->width;
}
// add spacing to the offset based on the special character
switch(specialCharacter)
{
case (int)' ':
offset.x += fontPtr->fixed.x;
break;
case (int)'\t':
offset.x += fontPtr->fixed.x * fontPtr->numTabSpaces;
break;
case (int)'\n':
// process alignment
if(horizontalAlign != FONT_ALIGN_LEFT)
{
// modify the xExtent based on alignment
float xExtent = dimensions.x - offset.x;
if(horizontalAlign == FONT_ALIGN_CENTER)
xExtent *= 0.5f;
//printf("xExtent: %f - %f = %f\n", dimensions.x, offset.x, xExtent);
// space the sprites accordingly
for(int e=startSpriteIndex;e<(int)sprites.size();e++)
{
sprite = (Sprite*)sprites[e];
sprite->Translate(Vector3(xExtent, 0.0f, 0.0f));
}
startSpriteIndex = (int)sprites.size();
}
startSpriteIndex = (int)sprites.size();
if(deprecated) stopUpdating = true;
offset.x = 0.0f;
offset.y += fontPtr->GetCommonData().lineHeight;
numWordsOnLine = 0;
numLines++;
break;
}
startIndex = index+1;
}
I'm pretty lost at this point... This algorithm nearly works, except if there's only 1 word in the line, then that word becomes right-aligned. Same happens when a newline character is found, and there's some issues with tabbing.






