void MADrawTextWrap(gfxScreen_t screen, gfx3dSide_t side, int cursorx, int cursory, char * text, MAFont * font, int red, int green, int blue, int maxWidth, int maxLines) {
//If no maximum width was specified, just draw the text
if (maxWidth < 1) {
MADrawText(screen, side, cursorx, cursory, text, font, red, green, blue);
return;
}
if (maxLines == 1) {
truncateTextToFitMaxWidth(text, maxWidth, font, false);
MADrawText(screen, side, cursorx, cursory, text, font, red, green, blue);
return;
}
//Store initial cursor position in case we need to go down a line
int initialy = cursory;
/*
--------------------------------- To do: get this from the font ---------------------------------
*/
int lineHeight = 20;
//Start from line 1
int currentline = 1;
int maxWords = 128;
int maxWordLen = 64;
char words[maxWords][maxWordLen];
memset(words, 0, maxWords*maxWordLen);
int numWords = 0;
int numChars = strlen(text);
int currentWordStartPosition = 0;
int i=0;
/*
This was originally added for testing the output of the sentence splitting function below.
It is no longer used or even referred to beyond its declaration here and copying one character to it.
I have no idea why, but if this is removed the text wrapping goes all fucked.
I should probably try to figure it out, but I would rather have text wrapping working than
save 1k of memory, and I don't really have the time to figure it out.
*/
char out[1024];
strcpy(out, "|");
while (i < numChars) {
char c[1];
memset(c, 0, 1);
strncpy(c, &text[i], 1);
//We have reached the end of a word
if (charIsWordBreak(c)) {
//Now scan until the beginning of the next word or the end of the string
while (true) {
//Go to the next character
i++;
//If we have reached the end of the string, stop scanning
if (i >= numChars) {
break;
}
//If we have not reached the end of the string, get the next character
char c2[1];
memset(c2, 0, 1);
strncpy(c2, &text[i], 1);
//If we have reached a non word break character, stop scanning
if (!charIsWordBreak(c2)) {
break;
}
}
//Get the index of the character and store it as current word end position
int currentWordEndPosition = i;
//Calculate the length of the current word
int currentWordLength = currentWordEndPosition - currentWordStartPosition;
char currentWord[maxWordLen];
memset(currentWord, 0, maxWordLen);
strncpy(currentWord, &text[currentWordStartPosition], currentWordLength);
//Copy the word to the words array
strncpy(words[numWords], currentWord, maxWordLen);
//Prepare to start scanning the next word
numWords++;
currentWordStartPosition = i;
}
//We have not yet reached the end of a word
else {
//Go to the next character
i++;
//Last word - this is pretty much the same code as above, so needs to be abstracted to a function to save repetition (later!)
if (i >= numChars) {
//Get the index of the character and store it as current word end position
int currentWordEndPosition = i;
//Calculate the length of the current word
int currentWordLength = currentWordEndPosition - currentWordStartPosition;
char currentWord[maxWordLen];
memset(currentWord, 0, maxWordLen);
strncpy(currentWord, &text[currentWordStartPosition], currentWordLength);
strncpy(words[numWords], currentWord, maxWordLen);
numWords++;
}
}
}
for (i=0; i < numWords; i++) {
//Copy the current word from the array
char currentWord[maxWordLen];
memset(currentWord, 0, maxWordLen);
strncpy(currentWord, words[i], maxWordLen);
//Calculate the width of the word about to be drawn
int currentWordWidth = MATextWidthInPixels(currentWord, font);
//Work out how much space is left on the current line
int availableWidthForCurrentWord = maxWidth - (cursory - initialy);
//If there are more words to draw after this one
if (i < numWords-1) {
//Copy the next word from the array
char nextWord[maxWordLen]; // = new char[sNextWord.length() + 1];
memset(nextWord, 0, maxWordLen);
strncpy(nextWord, words[i+1], maxWordLen);
//Calculate the width of the next word
int nextWordWidth = MATextWidthInPixels(nextWord, font);
//Calculate space available for the next word
int availableWidthForNextWord = availableWidthForCurrentWord - currentWordWidth;
//If the next word will fit on this line
if (nextWordWidth <= availableWidthForNextWord) {
//Draw the current word and move the cursor along ready to draw the next word on the next cycle of the loop
MADrawText(screen, side, cursorx, cursory, currentWord, font, red, green, blue);
cursory += currentWordWidth;
}
//If the next word will not fit on this line
else {
//If there is no restriction on the number of lines, or if we have not yet reached the last line
if (maxLines < 1 || currentline < maxLines) {
MADrawText(screen, side, cursorx, cursory, currentWord, font, red, green, blue);
cursory = initialy;
cursorx -= lineHeight;
currentline++;
}
//If there are no more lines left
else {
//Create the minimum truncated version of the next word (its first letter plus ellipses)
char minimumTruncatedNextWord[5];
memset(minimumTruncatedNextWord, 0, 5);
strncpy(minimumTruncatedNextWord, nextWord, 1);
strcat(minimumTruncatedNextWord, "...");
//Get the width of the minimum truncated next word
int minimumTruncatedNextWordWidth = MATextWidthInPixels(minimumTruncatedNextWord, font);
//If the minimum truncated next word will fit
if (minimumTruncatedNextWordWidth <= availableWidthForNextWord) {
//Draw the current word
MADrawText(screen, side, cursorx, cursory, currentWord, font, red, green, blue);
cursory += currentWordWidth;
//Truncate the next word so it will fit on the line with ellipses
truncateTextToFitMaxWidth(nextWord, availableWidthForNextWord, font, false);
//Draw the next word
MADrawText(screen, side, cursorx, cursory, nextWord, font, red, green, blue);
//Break since there's no space for any more words
break;
}
//Even the minimum truncated next word won't fit on this line, and there isn't a line available below for it to go on.
else {
//Truncate the current word and add ellipses
truncateTextToFitMaxWidth(currentWord, availableWidthForCurrentWord, font, true);
//Draw the truncated current word
MADrawText(screen, side, cursorx, cursory, currentWord, font, red, green, blue);
//Break, since there's not space for any more words
break;
}
}
}
}
//This is the last word
else {
//If the last word fits, just draw it and we're done
if (currentWordWidth <= availableWidthForCurrentWord) {
MADrawText(screen, side, cursorx, cursory, currentWord, font, red, green, blue);
/*
DONE
*/
}
//The last word doesn't fit on the current line
else {
//If there is no restriction on the number of lines, or if we still have lines available
if (maxLines < 1 || currentline < maxLines) {
//Move the cursor to the beginning of the next line
cursory = initialy;
cursorx -= lineHeight;
//Truncate the last word if necessary
if (availableWidthForCurrentWord > maxWidth) {
truncateTextToFitMaxWidth(currentWord, availableWidthForCurrentWord, font, false);
}
//Draw the last word
MADrawText(screen, side, cursorx, cursory, currentWord, font, red, green, blue);
/*
DONE
*/
}
//There are no more lines available. Truncate the final word and display it
else {
truncateTextToFitMaxWidth(currentWord, availableWidthForCurrentWord, font, false);
MADrawText(screen, side, cursorx, cursory, currentWord, font, red, green, blue);
/*
DONE
*/
}
}
}
}
}