#include "Text.h" TTF_Font* Text::vSmallFont = NULL; TTF_Font* Text::smallFont = NULL; TTF_Font* Text::mediumFont = NULL; TTF_Font* Text::largeFont = NULL; TTF_Font* Text::vLargeFont = NULL; const static int lineSpacing = 3; Text::Text(void) { x = 0; y = 0; w = 0; h = 0; lineWidth=50; } Text::~Text(void) { if(!_lines.empty()) { for(std::list::iterator it = _lines.begin(); it != _lines.end(); ++it) { SDL_FreeSurface(*it); } _lines.clear(); } } void Text::LoadFonts(void) { // Load the fonts if they are not already in memory. assert(vSmallFont == NULL); assert(smallFont == NULL); assert(mediumFont == NULL); assert(largeFont == NULL); assert(vLargeFont == NULL); vSmallFont = Font("../Data/Media/Fonts/Enigma_2.ttf", 16); smallFont = Font("../Data/Media/Fonts/Enigma_2.ttf", 23); mediumFont = Font("../Data/Media/Fonts/Enigma_2.ttf", 27); largeFont = Font("../Data/Media/Fonts/Enigma_2.ttf", 32); vLargeFont = Font("../Data/Media/Fonts/Enigma_2.ttf", 48); } void Text::FreeFonts(void) { // If the fonts are loaded, then free them. assert(vSmallFont != NULL); assert(smallFont != NULL); assert(mediumFont != NULL); assert(largeFont != NULL); assert(vLargeFont != NULL); TTF_CloseFont(vSmallFont); TTF_CloseFont(smallFont); TTF_CloseFont(mediumFont); TTF_CloseFont(largeFont); TTF_CloseFont(vLargeFont); } void Text::SetXY(int xArg, int yArg) { x = xArg; y = yArg; } int Text::SetTextBlended(string textArg, textSizes_t size, SDL_Color colour,bool wordWrap) { _textContents = textArg; if(!_lines.empty()) { for(std::list::iterator it = _lines.begin(); it != _lines.end(); ++it) { SDL_FreeSurface(*it); } _lines.clear(); } TTF_Font* font = NULL; if(size == vsmall) { font = vSmallFont; } else if(size == small) { font = smallFont; } else if(size == medium) { font = mediumFont; } else if(size == large) { font = largeFont; } else { font = vLargeFont; } std::string finalTextContents = textArg; if(wordWrap) { finalTextContents = DoWordWrap(font, finalTextContents); } std::list lines; std::string line; for(int i = 0; i < (int)finalTextContents.size(); i++) { char c = finalTextContents.at(i); if(c == '\n') { lines.push_back(line); line.clear(); } else { line += c; } } if (!line.empty()) { lines.push_back(line); } for(std::list::iterator it = lines.begin(); it != lines.end(); ++it) { SDL_Surface* lineSurf = TTF_RenderText_Blended(font, it->c_str(), colour); int linePixelWidth; int linePixelHeight; TTF_SizeText(font, it->c_str(), &linePixelWidth, &linePixelHeight); if(linePixelWidth > w) { w = linePixelWidth; } h += linePixelHeight + lineSpacing; _lines.push_back(lineSurf); } return 1; } int Text::SetTextBlended(string textArg, textSizes_t size, Uint8 r, Uint8 g, Uint8 b, bool wordWrap) { SDL_Color f = { r, g, b }; return SetTextBlended(textArg, size, f, wordWrap); } int Text::SetTextShaded(string textArg, textSizes_t size, SDL_Color colour, SDL_Color bgColour, bool wordWrap) { _textContents = textArg; if(!_lines.empty()) { for(std::list::iterator it = _lines.begin(); it != _lines.end(); ++it) { SDL_FreeSurface(*it); } _lines.clear(); } TTF_Font* font = NULL; if(size == vsmall) { font = vSmallFont; } else if(size == small) { font = smallFont; } else if(size == medium) { font = mediumFont; } else if(size == large) { font = largeFont; } else { font = vLargeFont; } std::string finalTextContents = textArg; if(wordWrap) { finalTextContents = DoWordWrap(font, finalTextContents); } std::list lines; std::string line; for(int i = 0; i < (int)finalTextContents.size(); i++) { char c = finalTextContents.at(i); if(c == '\n') { lines.push_back(line); line.clear(); } else { line += c; } } if (!line.empty()) { lines.push_back(line); } for(std::list::iterator it = lines.begin(); it != lines.end(); ++it) { SDL_Surface* lineSurf = TTF_RenderText_Shaded(font, it->c_str(), colour, bgColour); int linePixelWidth; int linePixelHeight; TTF_SizeText(font, it->c_str(), &linePixelWidth, &linePixelHeight); if(linePixelWidth > w) { w = linePixelWidth; } h += linePixelHeight + lineSpacing; _lines.push_back(lineSurf); } return 1; } int Text::SetTextShaded(string textArg, textSizes_t size, Uint8 rF, Uint8 gF, Uint8 bF, Uint8 rB, Uint8 gB, Uint8 bB, bool wordWrap) { SDL_Color f = { rF, gF, bF }; SDL_Color b = { rB, gB, bB }; return SetTextShaded(textArg, size, f, b, wordWrap); } void Text::Render(void) { int yOffset = 0; for(std::list::iterator it = _lines.begin(); it != _lines.end(); ++it) { SDL_Surface* lineSurf = *it; ApplySurface(x, y + yOffset, lineSurf, screen); yOffset += lineSurf->h + lineSpacing; } } void Text::Render(int xArg, int yArg) { int yOffset = 0; for(std::list::iterator it = _lines.begin(); it != _lines.end(); ++it) { SDL_Surface* lineSurf = *it; ApplySurface(x + xArg, y + yArg + yOffset, lineSurf, screen); yOffset += lineSurf->h + lineSpacing; } } void Text::RenderLiteral(void) { int yOffset = 0; for(std::list::iterator it = _lines.begin(); it != _lines.end(); ++it) { SDL_Surface* lineSurf = *it; ApplySurfaceLiteral(x, y + yOffset, lineSurf, screen); yOffset += lineSurf->h + lineSpacing; } } void Text::RenderLiteral(int xArg, int yArg) { int yOffset = 0; for(std::list::iterator it = _lines.begin(); it != _lines.end(); ++it) { SDL_Surface* lineSurf = *it; ApplySurfaceLiteral(x + xArg, y + yArg + yOffset, lineSurf, screen); yOffset += lineSurf->h + lineSpacing; } } std::string Text::DoWordWrap(TTF_Font* fontArg, const std::string& textArg) { int leftSpace = lineWidth; char* tokenizedText = strdup(textArg.c_str()); char* tokenizedTextOrigin = tokenizedText; std::string wrappedText(textArg); int offsetInWrappedText = 0; int spaceWidth; TTF_SizeText(fontArg, " ", &spaceWidth, NULL); char* word = strtok(tokenizedText, " "); while(word) { int wordWidth; TTF_SizeText(fontArg, word, &wordWidth, NULL); if ((wordWidth + spaceWidth) > leftSpace) { wrappedText.insert((word - tokenizedTextOrigin) + offsetInWrappedText, "\n"); offsetInWrappedText++; leftSpace = lineWidth - wordWidth; } else { leftSpace -= wordWidth + spaceWidth; } word = strtok(NULL, " "); } // delete[] tokenizedText; return wrappedText; }