// load a texture from given text, font, and color bool Texture::txLoadT(std::string text, TTF_Font* font, SDL_Color color) { txFree(); SDL_Surface* textSurface = TTF_RenderText_Blended_Wrapped(font, text.c_str(), color, 1024); if (textSurface != NULL) { txTexture = SDL_CreateTextureFromSurface(Window::renderer, textSurface); if (txTexture == NULL) { std::cout << "Unable to create texture from rendered text! SDL Error: " << SDL_GetError() << std::endl; } else { if (txRect.w == NULL || txRect.h == NULL) { txRect.w = textSurface->w; txRect.h = textSurface->h; } } SDL_FreeSurface(textSurface); } else { std::cout << "Unable to render text surface! SDL_TTF Error: " << TTF_GetError() << std::endl; } return txTexture != NULL; }
SDL_Texture* NewTextTexture(const std::string &message, TTF_Font *font, SDL_Color color, int fontSize, SDL_Renderer *renderer, int wrapLength) { //We need to first render to a surface as that's what TTF_RenderText //returns, then load that surface into a texture SDL_Surface *surf = (wrapLength == 0)? TTF_RenderText_Blended(font, message.c_str(), color): TTF_RenderText_Blended_Wrapped(font, message.c_str(), color, wrapLength); if (surf == nullptr) { TTF_CloseFont(font); //logSDLError(std::cout, "TTF_RenderText"); return nullptr; } SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf); if (texture == nullptr) { //logSDLError(std::cout, "CreateTexture"); } //Clean up the surface and font SDL_FreeSurface(surf); //TTF_CloseFont(font); return texture; }
Text::Text(int x, int y, std::string fontName, std::string text, int taille) : text(text), taille(taille), fontName(fontName), surfaceText(nullptr), textTexture(nullptr) { fgColor = { 0xFF, 0xFF, 0xFF }; surfaceText = new SDL_Surface(); font = TTF_OpenFont(fontName.c_str(), taille); surfaceText = TTF_RenderText_Blended_Wrapped(font, text.c_str(), fgColor, 950); textTexture = SDL_CreateTextureFromSurface(gEngine->GetRenderer(), surfaceText); std::stringstream ss; ss << fontName << "_" << taille; this->fontName = ss.str(); SetTexture(this->fontName.c_str(), textTexture); SetPosition(x, y); SetSrcRect(0, 0, surfaceText->h, surfaceText->w); SetSize(surfaceText->w, surfaceText->h); SDL_FreeSurface(surfaceText); }
std::shared_ptr<Textfield> Textfield::SetText(std::string text, std::string font_path, Uint32 size, SDL_Color color, unsigned width) { if (texture) { texture->Destroy(); //Output_Handler::Output << "MSG Textfield::Change : Textfield already set\n"; //return this; } auto font = TTF_OpenFont(font_path.c_str(), size); if (!font) { Output_Handler::Error << "ERR Textfield::Change : Cannot open " << font_path << " font\n"; return nullptr; } SDL_Surface* srf = width > 0 ? TTF_RenderText_Blended_Wrapped(font, text.c_str(), color, width) : TTF_RenderText_Blended(font, text.c_str(), color); if (!srf) { Output_Handler::Error << "ERR Textfield::Change : Cannot render text\n"; return nullptr; } double x_off = texture ? texture->Get_Starting_Pos().first : 0; double y_off = texture ? texture->Get_Starting_Pos().second : 0; SDL_Texture* ttr = SDL_CreateTextureFromSurface(Screen::Renderer, srf); std::shared_ptr<Textfield> tf = std::dynamic_pointer_cast<Textfield>(this->shared_from_this()); Texture::Load(tf, ttr, srf->w, srf->h, x_off, y_off); SDL_FreeSurface(srf); TTF_CloseFont(font); //if(texture) texture->Scale = 1 / Screen::Get_Scale(); _Text = text; return tf; }
/** * @brief Loads a text surface in font. * @param aFont Font to use. * @param aText Text to render. * @param aForegroundColor Color of the text. * @param aBackgroundColor Color of the background. * @param aSize Size of font. * @param aMaxWidth Max width of a single line (in pixels). * @return */ Vector3 PCShaderSurface::LoadText(HashString const &aFont, HashString const &aText, Vector4 const &aForegroundColor, Vector4 const &aBackgroundColor, int aSize, int aMaxWidth) { // Endianness is important here Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif HashString const textureDataHash = aFont + aText + Common::IntToString(aSize); TextureData const& data = GetManager()->GetTextureData(textureDataHash); if(data.mTextureID != (unsigned)-1) { Vector3 size = Vector3(data.mWidth, data.mHeight, 0); mTextureID = data.mTextureID; SetTextureSize(size); return size; } else { if(!TTF_WasInit()) TTF_Init(); mFont = TTF_OpenFont(Common::RelativePath("Fonts", aFont).c_str(), aSize); if(!mFont) { mFont = NULL; DebugLogPrint("warning: file not found or incompatible format, check this out\n"); DebugLogPrint("%s", TTF_GetError()); return Vector3(0, 0, 0); } // Create text texture SDL_Color fgColor = {(Uint8)aForegroundColor.x, (Uint8)aForegroundColor.y, (Uint8)aForegroundColor.z, (Uint8)aForegroundColor.w}; //SDL_Color bgColor = {(Uint8)aBackgroundColor.x, (Uint8)aBackgroundColor.y, (Uint8)aBackgroundColor.z, (Uint8)aBackgroundColor.w}; SDL_Surface *msg = TTF_RenderText_Blended_Wrapped(mFont, aText.ToCharArray(), fgColor, aMaxWidth); if(!msg) { DebugLogPrint("TTF_RenderText failed: %s", TTF_GetError()); assert(msg); } mTextureFormat = GL_RGBA; mSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, msg->w, msg->h, 32, rmask, gmask, bmask, amask); SetTextureSize(Vector3(mSurface->w, mSurface->h, 0)); SDL_BlitSurface(msg, NULL, mSurface, NULL); AddTexturePairing(textureDataHash); return Vector3(mSurface->w, mSurface->h, 0); } }
extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Blended_Wrapped_p( TTF_Font *font, const char *text, SDL_Color *fg, uint32_t wrapLength) { return TTF_RenderText_Blended_Wrapped(font, text, *fg, wrapLength); }
void Text::UpdateText() { SDL_DestroyTexture(texture); surface = TTF_RenderText_Blended_Wrapped(font, text.c_str(), color, wrapping); SDL_SetSurfaceAlphaMod(surface, alpha); texture = SDL_CreateTextureFromSurface(Engine::GetInstance()->GetRenderer(), surface); SDL_FreeSurface(surface); SDL_QueryTexture(texture, NULL, NULL, &srcRect->w, &srcRect->h); SDL_QueryTexture(texture, NULL, NULL, &dstRect->w, &dstRect->h); Scale(scaling); }
void Text::SetFgColor(SDL_Color newColor) { fgColor = newColor; surfaceText = TTF_RenderText_Blended_Wrapped(font, text.c_str(), fgColor, 950); textTexture = SDL_CreateTextureFromSurface(gEngine->GetRenderer(), surfaceText); std::stringstream ss; ss << fontName << "_" << taille; fontName = ss.str(); SetTexture(fontName.c_str(), textTexture); SDL_FreeSurface(surfaceText); }
/** c-tor used for creation wrapped text using TTF text -- text, used for texture cration font -- contains font and size of text color -- color of text x, y, w, h -- position and size of texture w, h defaulted to 0 (means they'll use texture w and h)*/ Texture::Texture(std::string text, uint16_t wrap_width, TTF_Font* font, SDL_Color text_color, uint16_t x, uint16_t y ) : form({x, y, 0, 0}) { obj_counter++; path = "text"; //making surface with text make_texture(TTF_RenderText_Blended_Wrapped(font, text.c_str(), text_color, wrap_width)); }
void textClass::setMessage(std::stringstream &message, bool appendText) { // If were not appending text, set the message to empty if (!appendText) { textMessage = ""; } // Set the message from parameter textMessage = message.str(); //Render the message to an SDL_Surface, as that's what TTF_RenderText_X returns textSurface = TTF_RenderText_Blended_Wrapped(font, textMessage.c_str(), textColor,400); objectTexture = surfaceIntoTexture(textSurface); }
void Menu::Draw(SDL_Renderer *renderer) { if(_font == nullptr) throw Exception("No menu font"); vector<SDL_Surface*> surfaces; Uint32 maxLenIndex = 0; for(Uint32 i = 0; i < _menuItems.size(); ++i) { string str = _menuItems[i]->GetFocusedString(); SDL_Surface *surf = TTF_RenderText_Blended_Wrapped(_font, str.data(), _textColor, -1); surfaces.push_back(surf); if(surf->w > surfaces[maxLenIndex]->w) maxLenIndex = i; } Uint32 x, y, dx, dy, step_y; Converter::ScreenPercentToPixel(_pos.x, _pos.y, &x, &y); Converter::ScreenPercentToPixel(0.05f, 0.02f, &dx, &dy); Converter::ScreenPercentToPixel(0, 0.01f, nullptr, &step_y); SDL_Rect rectScreen = {x, y, surfaces[maxLenIndex]->w + 2*dx}; for(Uint32 i = 0; i < surfaces.size(); ++i) { SDL_Surface *surf = SDL_CreateRGBSurface(0, surfaces[maxLenIndex]->w + 2*dx, surfaces[i]->h + 2*dy, 32, 0, 0, 0, 0); if(i == _inFocus) SDL_FillRect(surf, nullptr, (~_bgColor) | 0xFF); else SDL_FillRect(surf, nullptr, _bgColor); SDL_Rect rect = {(surf->w - surfaces[i]->w)/2, dy}; SDL_BlitSurface(surfaces[i], nullptr, surf, &rect); SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf); rectScreen.h = surfaces[i]->h + 2*dy; SDL_RenderCopy(renderer, texture, nullptr, &rectScreen); rectScreen.y += surf->h + step_y; // cannot free "surfaces" here: we will free MaxLenSurface SDL_FreeSurface(surf); SDL_DestroyTexture(texture); } for(Uint32 i = 0; i < surfaces.size(); ++i) SDL_FreeSurface(surfaces[i]); }
void CText::write(std::string Font, int size, std::string Text, int x, int y, int w, int h, int imageY) { TTF_Init(); rect.x = x; rect.y = y; crop.x = 0; crop.y = imageY; if (fontFile != Font | fontSize != size) { fontFile = Font; fontSize = size; font = TTF_OpenFont(fontFile.c_str(), fontSize); } //render the message to an SDL_Surface, as that's what ttf_renderText_x returns if (text != Text) { if (surf) { SDL_FreeSurface(surf); } if (texture) { SDL_DestroyTexture(texture); } text = Text; surf = TTF_RenderText_Blended_Wrapped(font, text.c_str(), Color3, w); texture = SDL_CreateTextureFromSurface(sdl_Setup->GetRenderer(), surf); } if (h != NULL) { crop.w = w; rect.w = w; if (crop.h + crop.y < surf->h && crop.y >= 0) { rect.h = h; crop.h = h; } else if (crop.h + crop.y > surf->h) { rect.h = h - (crop.h + crop.y - surf->h); } if (crop.y < 0) { rect.h = h + crop.y; rect.y = y - crop.y; } } else { crop.w = surf->w; crop.h = surf->h; rect.w = surf->w; rect.h = surf->h; } SDL_SetTextureAlphaMod(texture, alpha); SDL_RenderCopy(sdl_Setup->GetRenderer(), texture, &crop, &rect); }
void Set(cstring new_text) { if(text == new_text) return; text = new_text; if(tex) SDL_DestroyTexture(tex); SDL_Color color = {0,0,0}; SDL_Surface* s = TTF_RenderText_Blended_Wrapped(font, text.c_str(), color, w); if(!s) throw Format("ERROR: Failed to render TTF text (%d).", TTF_GetError()); tex = SDL_CreateTextureFromSurface(renderer, s); SDL_FreeSurface(s); if(!tex) throw Format("ERROR: Failed to convert text surface to texture (%d).", SDL_GetError()); }
void Text::SetText(std::string newText) { text = newText; surfaceText = TTF_RenderText_Blended_Wrapped(font, text.c_str(), fgColor, 950); textTexture = SDL_CreateTextureFromSurface(gEngine->GetRenderer(), surfaceText); //SetSurfaceAlpha(textTexture, 128); std::stringstream ss; ss << fontName << "_" << taille; fontName = ss.str(); SetTexture(fontName.c_str(), textTexture); SetSrcRect(0, 0, surfaceText->h, surfaceText->w); SetSize(surfaceText->w, surfaceText->h); SDL_FreeSurface(surfaceText); }
Texture Texture_createText(const char* s, int p, SDL_Color c, int wl) { SDL_Surface* swap = NULL; Texture texture; texture.raw = NULL; texture.type = TEXTURE_UNFINISHED; if(wl <= 0) swap = TTF_RenderText_Blended(GAME_FONT, s, c); if(wl > 0) swap = TTF_RenderText_Blended_Wrapped(GAME_FONT, s, c, wl); if(swap == NULL) { throw_warning("Failed to render text! Returning empty texture."); return texture; } texture.raw = SDL_CreateTextureFromSurface(RENDERER, swap); if(texture.raw == NULL) { throw_warning("Failed to create texture! Returning empty texture."); SDL_FreeSurface(swap); return texture; } texture.cropX = 0; texture.cropY = 0; texture.cropW = 0; texture.cropH = 0; texture.positionX = 0; texture.positionY = 0; texture.sizeX = (float)strlen(s) * p; texture.sizeY = (float)p; SDL_FreeSurface(swap); texture.type = TEXTURE_TEXT; return texture; }
static mrb_value mrb_sdl2_ttf_font_render_text_blended_wrapped(mrb_state *mrb, mrb_value self) { mrb_value text; mrb_int r, g, b, a, wrapLength; SDL_Surface * c; SDL_Color color; mrb_get_args(mrb, "Siiiii", &text, &r, &g, &b, &a, &wrapLength); color.r = r; color.g = g; color.b = b; color.a = a; c = TTF_RenderText_Blended_Wrapped(mrb_sdl2_font_get_ptr(mrb, self), RSTRING_PTR(text), color, wrapLength); if (c == NULL) { mruby_sdl2_raise_error(mrb); return mrb_false_value(); } return mrb_sdl2_video_surface(mrb, c, 0); }
SDL_Texture* render_text(SDL_Renderer *renderer, const char *message, const char *font_file, SDL_Color font_color, int font_size) { TTF_Font *font = TTF_OpenFont(font_file, font_size); if (!font) { printf("Can't load font: %s\n", TTF_GetError()); return NULL; } SDL_Color back_color = {255, 255, 255, 255}; // SDL_Surface *surf = TTF_RenderText_Shaded(font, message, font_color, back_color); SDL_Surface *surf = TTF_RenderText_Blended_Wrapped(font, message, font_color, 1200); SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf); SDL_FreeSurface(surf); TTF_CloseFont(font); return texture; }
SDL_Texture* TextElement::renderText(std::string& message, int size, int font_type, int wrapped_width) { std::string key = message + std::to_string(size); // try to find it in the cache first if (ImageCache::cache.count(key)) return ImageCache::cache[key]; // not found, make/render it TTF_Font* font; if (font_type == MONOSPACED) font = TTF_OpenFont(ROMFS "./res/mono.ttf", size); else if (font_type == ICON) font = TTF_OpenFont(ROMFS "./res/nxicons.ttf", size); else font = TTF_OpenFont(ROMFS "./res/opensans.ttf", size); // font couldn't load, don't render anything if (!font) return NULL; SDL_Surface* surf; if (font_type == ICON) surf = TTF_RenderUTF8_Blended(font, message.c_str(), this->color); else if (wrapped_width == 0) surf = TTF_RenderText_Blended(font, message.c_str(), this->color); else surf = TTF_RenderText_Blended_Wrapped(font, message.c_str(), this->color, wrapped_width); SDL_Texture* texture = SDL_CreateTextureFromSurface(MainDisplay::mainRenderer, surf); SDL_FreeSurface(surf); // SDL_FreeSurface(surf); TTF_CloseFont(font); // save it to the cache for later ImageCache::cache[key] = texture; return texture; }
SDL_Rect Renderer::draw_text(const char * text, int x, int y, int font_size, SDL_Color c) { static TTF_Font *fonts[50]; if (fonts[font_size] == nullptr) { fonts[font_size] = TTF_OpenFont("arial.ttf", font_size); } SDL_Surface *text_surface; text_surface = TTF_RenderText_Blended_Wrapped(fonts[font_size], text, c, 500); SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, text_surface); int iW, iH; SDL_QueryTexture(texture, NULL, NULL, &iW, &iH); SDL_Rect rect{ x, y, iW, iH }; SDL_RenderCopy(renderer, texture, 0, &rect); SDL_FreeSurface(text_surface); SDL_DestroyTexture(texture); return rect; }
void AscentApp::InventoryRender() { std::stringstream invstream; const Inventory& inventory = engine->getPlayerInventory(); if (inventory.total() > 0) { invstream << "Inventory:\n"; for (int i = 0; i < 26 * 2; i++) { char c = INV_indextochar(i); inventory_entry_t ientry = inventory[c]; if (ientry.second > 0) { invstream << c << " - " << itemProperties.at(ientry.first).name << " (" << ientry.second << ")\n"; } } } else { invstream << "Inventory Empty\nPress Esc"; } std::string invstring = invstream.str(); SDL_Surface* textSurface = TTF_RenderText_Blended_Wrapped(font, invstring.c_str(), {0xFF, 0xFF, 0xFF, 0xFF}, windowWidth - MESSAGE_BORDER * 4); if (textSurface == NULL) { fprintf(stderr, "Couldn\'t make the text surface. %s\n", TTF_GetError()); return; } int message_w = textSurface->w; int message_h = textSurface->h; if (statusMessage != NULL) SDL_DestroyTexture(statusMessage); statusMessage = SDL_CreateTextureFromSurface(renderer, textSurface); SDL_FreeSurface(textSurface); if (statusMessage == NULL) { fprintf(stderr, "Couldn\'t create the text texture. %s\n", SDL_GetError()); return; } SDL_Rect messageRect = { MESSAGE_BORDER, MESSAGE_BORDER, message_w, message_h }; SDL_RenderCopy(renderer, statusMessage, NULL, &messageRect); }
bool Image::renderText(const std::string& text, SDL_Color color, int width) { if (this->texture) { SDL_DestroyTexture(this->texture); this->texture = nullptr; } SDL_Surface* surface = nullptr; if (width) { surface = TTF_RenderText_Blended_Wrapped(App::db.font, text.c_str(), color, width); } else { surface = TTF_RenderText_Blended(App::db.font, text.c_str(), color); } if (!surface) { std::cerr << "Error rendering text: " << TTF_GetError() << std::endl; } else { this->w = surface->w; this->h = surface->h; this->texture = SDL_CreateTextureFromSurface(App::renderer, surface); if (!this->texture) { std::cerr << "Error converting surface: " << SDL_GetError() << std::endl; } SDL_FreeSurface(surface); } return (this->texture != nullptr); }
void render_text(SDL_Renderer *renderer, std::string const & font, int fontSize, std::string const & text, TEXT_ANCHOR_X anchX, TEXT_ANCHOR_Y anchY, int x, int y, Uint8 colorR, Uint8 colorG, Uint8 colorB, Uint8 colorA, bool wrap, Uint32 wrapLength) { SDL_Surface *textSurface; SDL_Texture *textTexture; SDL_Color textColor = { colorR, colorG, colorB, colorA }; if (wrap) { textSurface = TTF_RenderText_Blended_Wrapped(get_font(font, fontSize), text.c_str(), textColor, wrapLength); } else { textSurface = TTF_RenderText_Blended(get_font(font, fontSize), text.c_str(), textColor); } textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); SDL_SetTextureAlphaMod(textTexture, colorA); int rendererWidth, rendererHeight; SDL_GetRendererOutputSize(renderer, &rendererWidth, &rendererHeight); SDL_Rect dstRect = {x, y, textSurface->w, textSurface->h}; if (anchX == TEXT_ANCHOR_X::RIGHT) { dstRect.x = rendererWidth - dstRect.x - textSurface->w; } else if (anchX == TEXT_ANCHOR_X::CENTER) { dstRect.x = (rendererWidth - textSurface->w)/2 + x; } if (anchY == TEXT_ANCHOR_Y::BOTTOM) { dstRect.y = rendererHeight - dstRect.y -textSurface->h; } else if (anchY == TEXT_ANCHOR_Y::MIDDLE) { dstRect.y = (rendererHeight - textSurface->h)/2 + y; } SDL_RenderCopy(renderer, textTexture, NULL, &dstRect); SDL_DestroyTexture(textTexture); SDL_FreeSurface(textSurface); }
/** * Prints the provided string after formatting it to increase readability. */ void print_long_text(char *string, Renderer *renderer) { char log_buffer[MAXIMUM_STRING_SIZE]; const int font_width = get_font_width(); const int width = get_window_width() - 2 * get_padding() * font_width; TTF_Font *font = get_font(); SDL_Surface *surface; SDL_Texture *texture; SDL_Color color = to_sdl_color(COLOR_DEFAULT_FOREGROUND); SDL_Rect position; position.x = get_padding() * font_width; position.y = get_padding() * font_width; clear(renderer); /* Validate that the string is not empty and that x and y are nonnegative. */ if (string == NULL || string[0] == '\0') { return; } remove_first_breaks(string); surface = TTF_RenderText_Blended_Wrapped(font, string, color, width); if (surface == NULL) { sprintf(log_buffer, CREATE_SURFACE_FAIL, "print_long_text()"); log_message(log_buffer); return; } texture = SDL_CreateTextureFromSurface(renderer, surface); if (texture == NULL) { sprintf(log_buffer, CREATE_TEXTURE_FAIL, "print_long_text()"); log_message(log_buffer); return; } /* Copy destination width and height from the texture. */ SDL_QueryTexture(texture, NULL, NULL, &position.w, &position.h); SDL_RenderCopy(renderer, texture, NULL, &position); SDL_DestroyTexture(texture); SDL_FreeSurface(surface); present(renderer); }
bool Card::loadingText(SDL_Renderer* r, std::string svHeader, std::string svText, std::string enHeader, std::string enText, std::vector<std::string> svCat, std::vector<std::string> enCat){ // /Library/Fonts Arial.ttf bool success = true; // Loading font if( TTF_Init() == -1 ) { printf( "SDL_ttf could not initialize! SDL_ttf Error: %s\n", TTF_GetError() ); success = false; } TTF_Font *gFont = NULL; gFont = TTF_OpenFont( "/Library/Fonts/Arial.ttf", 100 ); // Apple: "/Library/Fonts/Arial.ttf" if( gFont == NULL ) { printf( "Failed to load lazy font! SDL_ttf Error: %s\n", TTF_GetError() ); success = false; } SDL_Color textColor = { 0, 0, 0}; // Loading text SDL_Surface* textSurface = NULL; // Svenska header textSurface = TTF_RenderText_Blended( gFont, svHeader.c_str(), textColor); if( textSurface == NULL ) { printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() ); success = false; } else { //Create texture from surface pixels headersSv.push_back( SDL_CreateTextureFromSurface( r, textSurface )); if( headersSv[infoIndex] == NULL ) { printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() ); success = false; } //Get rid of old surface SDL_FreeSurface( textSurface ); } // Svenska text textSurface = NULL; textSurface = TTF_RenderText_Blended_Wrapped( gFont, svText.c_str(), textColor, 3000); if( textSurface == NULL ) { printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() ); success = false; } else { //Create texture from surface pixels infoTextSv.push_back( SDL_CreateTextureFromSurface( r, textSurface )); if( infoTextSv[infoIndex] == NULL ) { printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() ); success = false; } //Get rid of old surface SDL_FreeSurface( textSurface ); } // Svenska kategorier textSurface = NULL; std::string catString = "Kategorier som kortet tillhˆr kommer synas h‰r"; for (int i = 0; i < svCat.size(); i++) { if (i > 0) { catString += " - "; catString += svCat[i].c_str() ; } else { catString = svCat[i].c_str() ; } } textSurface = TTF_RenderText_Blended( gFont, catString.c_str(), textColor); if( textSurface == NULL ) { printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() ); success = false; } else { //Create texture from surface pixels catTextSv.push_back( SDL_CreateTextureFromSurface( r, textSurface )); if( catTextSv[infoIndex] == NULL ) { printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() ); success = false; } //Get rid of old surface SDL_FreeSurface( textSurface ); } // English header textSurface = NULL; textSurface = TTF_RenderText_Blended( gFont, enHeader.c_str(), textColor); if( textSurface == NULL ) { printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() ); success = false; } else { //Create texture from surface pixels headersEn.push_back( SDL_CreateTextureFromSurface( r, textSurface )); if( headersEn[infoIndex] == NULL ) { printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() ); success = false; } //Get rid of old surface SDL_FreeSurface( textSurface ); } // English text textSurface = NULL; textSurface = TTF_RenderText_Blended_Wrapped( gFont, enText.c_str(), textColor, 3000); if( textSurface == NULL ) { printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() ); success = false; } else { //Create texture from surface pixels infoTextEn.push_back( SDL_CreateTextureFromSurface( r, textSurface )); if( infoTextEn[infoIndex] == NULL ) { printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() ); success = false; } //Get rid of old surface SDL_FreeSurface( textSurface ); } // Engelska kategorier textSurface = NULL; catString = "Categories for the cards will be here"; for (int i = 0; i < enCat.size(); i++) { if (i > 0) { catString += " - "; catString += enCat[i].c_str() ; } else { catString = enCat[i].c_str() ; } } textSurface = TTF_RenderText_Blended( gFont, catString.c_str(), textColor); if( textSurface == NULL ) { printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() ); success = false; } else { //Create texture from surface pixels catTextEn.push_back( SDL_CreateTextureFromSurface( r, textSurface )); if( catTextEn[infoIndex] == NULL ) { printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() ); success = false; } //Get rid of old surface SDL_FreeSurface( textSurface ); } TTF_CloseFont( gFont ); gFont = NULL; return success; }
void AscentApp::drawStatusBox() { std::stringstream msgstringstream; switch (userInputRequested) { case InputType::Standard: { Foreground tb = engine->underWitch(); if (tb != Foreground::NONE) { msgstringstream << engine->underItemString() << "\n"; } msgstringstream << "HP: " << engine->playerHP(); if (engine->playerMaxHP()) msgstringstream << " (MAX)"; if (!engine->playerAlive()) msgstringstream << " (Dead)"; } break; case InputType::InventoryItemToDrop: msgstringstream << "Select an item to drop (a-zA-Z); Esc to cancel\n"; break; case InputType::InventoryItemToView: msgstringstream << "Select an item to view (Not implemented); Esc to cancel\n"; break; case InputType::EndGame: msgstringstream << "Esc to quit"; break; default: return; } std::string msgstring = msgstringstream.str(); if (msgstring.length() == 0) return; SDL_Surface* textSurface = TTF_RenderText_Blended_Wrapped(font, msgstring.c_str(), {0xFF, 0xFF, 0xFF, 0xFF}, windowWidth - MESSAGE_BORDER * 4); if (textSurface == NULL) { fprintf(stderr, "Couldn\'t make the text surface. %s\n", TTF_GetError()); return; } int message_w = textSurface->w; int message_h = textSurface->h; if (statusMessage != NULL) SDL_DestroyTexture(statusMessage); statusMessage = SDL_CreateTextureFromSurface(renderer, textSurface); SDL_FreeSurface(textSurface); if (statusMessage == NULL) { fprintf(stderr, "Couldn\'t create the text texture. %s\n", SDL_GetError()); return; } SDL_Rect messageRect = { MESSAGE_BORDER, windowHeight - message_h - MESSAGE_BORDER, message_w, message_h }; SDL_Rect messageBackgroundRect = { 0, windowHeight - message_h - MESSAGE_BORDER * 2, // message_w + MESSAGE_BORDER * 2, windowWidth, message_h + MESSAGE_BORDER * 2 }; SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xC0); SDL_RenderFillRect(renderer, &messageBackgroundRect); SDL_RenderCopy(renderer, statusMessage, NULL, &messageRect); }
texture2D * TTF_system::render_text_to_texture(std::string const& text, unsigned size) { static std::string const font_file_path = resource_manager::get_resource_dir() + "fonts/rambla/Rambla-Regular.ttf"; // TODO: Store font instead of creating each time true_type_font rambla_ttf(font_file_path, size); // Quick hack to allow rendering of multiple lines using newlines. Uint32 wrap_length = 0; if(text.empty() == false) { // Finds what the rendered text width will be, since the only way to get SDL_ttf to handle // newlines is by using TTF_RenderText_Blended_Wrapped, which requires a wrap_length. // STL_ttf will pad the texture to this size, so I need to find the actual size (vs // using very large value). // Slow and dirty, just needs to get job done for now. std::vector<std::string> lines; size_t line_start = 0; size_t newline_pos = text.find('\n'); while(newline_pos != std::string::npos) { lines.push_back(text.substr(line_start, newline_pos - line_start)); line_start = newline_pos + 1; newline_pos = text.find('\n', line_start); } // Get last line if it did not end with a newline if(text.back() != '\n') { lines.push_back(text.substr(line_start, text.length() - line_start)); } auto longest_line_it = std::max_element(lines.begin(), lines.end(), [](std::string const& lhs, std::string const& rhs)->bool { return lhs.length() < rhs.length(); }); int w, h; TTF_SizeText(rambla_ttf.get_raw(), longest_line_it->c_str(), &w, &h); wrap_length = w; } SDL_Surface * text_surface = TTF_RenderText_Blended_Wrapped( rambla_ttf.get_raw(), text.c_str(), SDL_Color{255, 255, 255, 255}, wrap_length); if(text_surface == nullptr) { log_error(log_scope::ENGINE, "Error rendering text using TTF: {}", TTF_GetError()); SDL_ClearError(); throw resource_exception {}; } texture2D * text_texture = new texture2D; text_texture->set_data( GL_RGBA8, text_surface->w, text_surface->h, GL_RGBA, GL_UNSIGNED_BYTE, text_surface->pixels); SDL_FreeSurface(text_surface); return text_texture; }
void flashback(char* path) { //////////////////////////////////////initialize music, video and text///////////////////////////////////// SDL_Surface *screen; SDL_Window *window; SDL_Surface *text; SDL_Rect paper = { 560, 140, 800, 800 }; char *fullString = ReadFile(path); char *string; int cnt = 0; int quit = 1; Mix_Music *typing = NULL; //init sdl mixer if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); } //load music typing = Mix_LoadMUS("sounds/typing.mp3"); if (NULL == typing) { printf("Failed to load low sound effect! SDL_mixer Error: %s\n", Mix_GetError()); } Mix_PlayMusic(typing, -1); // init video SDL_Init(SDL_INIT_VIDEO); // create the window window = SDL_CreateWindow("popup", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_BORDERLESS); // Initialize SDL_ttf library if (TTF_Init() != 0) { fprintf(stderr, "Init TTF failed! SDL_Error: %s", SDL_GetError()); } // Load a font TTF_Font *font; font = TTF_OpenFont("FreeMonoBold.ttf", 24); if (font == NULL) { fprintf(stderr, "loading font failed! SDL_Error: %s", SDL_GetError()); } // draw directly to the screen screen = SDL_GetWindowSurface(window); SDL_Event end; //////////////////////////////////////render Text on Screen///////////////////////////////////// while (1) { while(SDL_PollEvent(&end)); string = addToString(cnt, fullString); cnt++; //write text to surface SDL_Color text_color = { 255, 255, 255 }; text = TTF_RenderText_Blended_Wrapped(font, string, text_color, 1000); SDL_FillRect(screen, NULL, 0x000000); //overwrite screen in black SDL_BlitSurface(text, NULL, screen, &paper); // blit it to the screen SDL_UpdateWindowSurface(window); // show image for 60 ms SDL_Delay(60); //////////////////////////////////////Skip text on tap any key////////////////////////////////// if (SDL_KEYDOWN == end.type || '\0' == fullString[cnt]) { Mix_HaltMusic(); end.type = 0; SDL_FillRect(screen, NULL, 0x000000); text = TTF_RenderText_Blended_Wrapped(font, fullString, text_color, 1000); SDL_BlitSurface(text, NULL, screen, &paper); SDL_UpdateWindowSurface(window); Mix_HaltMusic(); while (1) { while(SDL_PollEvent(&end)); if (SDL_KEYDOWN == end.type) { quit = 0; break; } } break; } } Mix_HaltMusic(); Mix_FreeMusic(typing); typing = NULL; SDL_FreeSurface(text); SDL_FreeSurface(screen); SDL_DestroyWindow(window); }
//Draws a string to the screen //param:font->The index of the font //param:message->The message to display //param:drawMode->The draw mode to apply to the string: //Blended: Blends the text with whatever is behind it using transparency. This mode is required for wrapping. Slowest mode //Shaded: Gives the text a background that utilizes background color //Solid: Fastest rendering speed. No box around, just quick straight text //param:foregroundColor->The color of the text //param:backgroundColor->The color of the background box. Used with Shaded drawmode //param:wrapLength->Wraps the text past this width (in pixels). Requires empty space, will not separate words. Only //works in Blended mode //param:position->Point to draw the text at //param:angle->Angle to rotate the text //param:origin->The origin point to rotate about //param:scale->Amount to size the text. Will distort quickly //param:flip-> Flip texture horizontally, vertically, both or none //param:layerDepth->The depth to draw on //Returns 0 for success, -1 for errors int SpriteBatch::DrawString(Uint32 font, std::string message, StringDrawMode drawMode, SDL_Color foregroundColor, SDL_Color backgroundColor, int wrapLength, const SDL_Point* position, float angle, const SDL_Point* origin, float scale, SDL_RendererFlip flip, float layerDepth) { //Check if spritebatch.begin has been called if(!begun) { std::cout<<"Begin must be called before attempting to draw"<<std::endl; return -1; } //make sure we have a valid layer depth if(layerDepth < 0 || layerDepth > 1) { std::cout <<"Layer Depth must be between 0 and 1"<<std::endl; return -1; } //Make sure we have a valid renderer if(!renderer) { std::cout<<"Renderer is null. Did you Initialize Spritebatch?"<<std::endl; return -1; } try{ TTF_Font* fontToDraw; //Get the texture (at performs bounds checking, which will validate the index for us, regardless of sort mode) fontToDraw = fontManager->GetFont(font); //If sort mode is immediate, draw right away if(sortMode == SpriteBatchSortMode::Immediate) { SDL_Surface* textSurface = nullptr; //Create surface based on draw mode if(drawMode == StringDrawMode::Blended) { if(wrapLength <= 0) textSurface = TTF_RenderText_Blended(fontToDraw, message.c_str(), foregroundColor); else textSurface = TTF_RenderText_Blended_Wrapped(fontToDraw, message.c_str(), foregroundColor, wrapLength); } else if(drawMode == StringDrawMode::Shaded) { textSurface = TTF_RenderText_Shaded(fontToDraw, message.c_str(), foregroundColor, backgroundColor); } else if(drawMode == StringDrawMode::Solid) { textSurface = TTF_RenderText_Solid(fontToDraw, message.c_str(), foregroundColor); } //Generate the texture from the surface SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer, textSurface); //Free the surface and get rid of the pointer to it SDL_FreeSurface(textSurface); textSurface = nullptr; int w = 0; int h = 0; SDL_QueryTexture(tex, NULL, NULL, &w, &h); //Check for null position SDL_Point point; if(position == nullptr) point = CreatePoint(0, 0); else point = CreatePoint(position->x, position->y); //Create a rectangle that is the size of the string SDL_Rect sourceRect = CreateRect(0, 0, w, h); SDL_Rect destRect = CreateRect(point.x, point.y, (int)(w * scale), (int)(h * scale)); //if no flip or angle, draw with Render Copy if(angle == 0 && flip == 0) SDL_RenderCopy(renderer, tex, &sourceRect, &destRect); else ///Draw the image with any flip/angle SDL_RenderCopyEx(renderer, tex, &sourceRect, &destRect, angle, origin, flip); } else { //Take the layer depth, multiply by 10 and floor it. A layer depth of 0.09 would then go into //index 0 map, while a 0.99 will go into index 9 int sortIndex = (int)std::floor(layerDepth * 10); SDL_Rect* destRect = &CreateRect(position->x, position->y, 0, 0); SDL_Rect sourceRect = CreateRect(0, 0, 0, 0); //Package the information PackedSprite package = PackedSprite(PackedSprite::PackType::String, font, message, drawMode, destRect, origin, backgroundColor, foregroundColor, flip, angle, scale, wrapLength); //if sort index is greater than 9, put it in array slot 9. We do this because //1.0 * 10 = floor(10) = 10. Our array only goes to the 9th index if(sortIndex >= 9) { sortedImages[9].insert(std::pair<float, PackedSprite>(layerDepth, package)); } else { //otherwise, just put it in the appropriate slot sortedImages[sortIndex].insert(std::pair<float, PackedSprite>(layerDepth, package)); } } } //If invalid index, we throw the error catch (std::out_of_range problem) { std::cout<<"SPRITEBATCH_DRAWSTRING ERROR: Font not a valid index"<<std::endl; return -1; } return 0; }
//Draw the texture from the PackedSprite structure //param:packedSprite->The packed sprite to draw from void SpriteBatch::DrawTexture(PackedSprite packedSprite) { if(packedSprite.Type == PackedSprite::PackType::Sprite) { //Get the texture (we dont do bounds checking because when we added the texture to the list //we checked the bounds) We also don't check for begin, because that would've been checked in the //users call to DrawTexture. This is a private function. Only spritebatch calls this one. SDL_Texture* tex = textureList[packedSprite.Texture]; //Apply any blends ApplyBlendToTexture(tex, packedSprite.Tint); //if no flip or angle, draw with Render Copy if(packedSprite.Rotation == 0 && packedSprite.FlipEffects == 0) SDL_RenderCopy(renderer, tex, packedSprite.SourceRect, packedSprite.DestRect); else ///Draw the image with any flip/angle SDL_RenderCopyEx(renderer, tex, packedSprite.SourceRect, packedSprite.DestRect, packedSprite.Rotation, packedSprite.Origin, packedSprite.FlipEffects); } else { SDL_Surface* textSurface; //Generate surface based on draw mode if(packedSprite.DrawMode == StringDrawMode::Blended) { if(packedSprite.WrapLength <= 0) textSurface = TTF_RenderText_Blended(fontManager->GetFont(packedSprite.Texture), packedSprite.Message.c_str(), packedSprite.Tint); else textSurface = TTF_RenderText_Blended_Wrapped(fontManager->GetFont(packedSprite.Texture), packedSprite.Message.c_str(), packedSprite.Tint, packedSprite.WrapLength); } else if(packedSprite.DrawMode == StringDrawMode::Shaded) { textSurface = TTF_RenderText_Shaded(fontManager->GetFont(packedSprite.Texture), packedSprite.Message.c_str(), packedSprite.Tint, packedSprite.BackgroundColor); } else if(packedSprite.DrawMode == StringDrawMode::Solid) { textSurface = TTF_RenderText_Solid(fontManager->GetFont(packedSprite.Texture), packedSprite.Message.c_str(), packedSprite.Tint); } //Generate the texture from the surface SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer, textSurface); //Free the surface and get rid of the pointer to it SDL_FreeSurface(textSurface); textSurface = nullptr; int w = 0; int h = 0; SDL_QueryTexture(tex, NULL, NULL, &w, &h); //Create a rectangle that is the size of the string SDL_Rect sourceRect = CreateRect(0, 0, w, h); SDL_Rect destRect = CreateRect(packedSprite.DestRect->x, packedSprite.DestRect->y, (Uint32)(w * packedSprite.StringScale), (Uint32)(h * packedSprite.StringScale)); //if no flip or angle, draw with Render Copy if(packedSprite.Rotation == 0 && packedSprite.FlipEffects == SDL_RendererFlip::SDL_FLIP_NONE) SDL_RenderCopy(renderer, tex, &sourceRect, &destRect); else ///Draw the image with any flip/angle SDL_RenderCopyEx(renderer, tex, &sourceRect, &destRect, packedSprite.Rotation, packedSprite.Origin, packedSprite.FlipEffects); } }
void UiLabel::labelPreRender() { if(needUpdate) { if(labelText.empty()) { setUiObjectTexture(NULL); setUiObjectSize(0, 0); } else { if(parentUiManager == NULL) { std::cout << "UiLabel (\"" << labelText << "\") without parentUiManager (is NULL)." << std::endl; return; } if(labelFont == NULL) { std::cout << "Failed to load labelFont in UiLabel! SDL_ttf Error: " << TTF_GetError() << std::endl; return; } SDL_Surface* tempSurface = TTF_RenderText_Blended_Wrapped(labelFont, labelText.c_str(), {(Uint8) colorR, (Uint8) colorG, (Uint8) colorB}, 1920); //TTF_RenderText_Blended(labelFont, labelText.c_str(), {(Uint8) colorR, (Uint8) colorG, (Uint8) colorB}); if(tempSurface == NULL) { std::cout << "Unable to render text surface in UiLabel! SDL_ttf Error: " << TTF_GetError() << std::endl; return; } //Create texture from surface pixels SDL_Texture *tempTex = SDL_CreateTextureFromSurface(parentUiManager->getRenderer(), tempSurface); // SDL_TEXTUREACCESS_STATIC if(tempTex == NULL) { std::cout << "Unable to create texture from rendered text in UiLabel! SDL Error: " << SDL_GetError() << std::endl; SDL_FreeSurface(tempSurface); return; } setUiObjectTexture(std::make_shared<SdlTexture>(tempTex)); setUiObjectSize(tempSurface->w, tempSurface->h); setUiObjectLogicalSize(0, 0); SDL_FreeSurface(tempSurface); } getUiObjectOffset(originalX, originalY); if(align == ALIGN_TOP_LEFT || align == ALIGN_CENTER_LEFT || align == ALIGN_BOTTOM_LEFT) alignedX = originalX; else if(align == ALIGN_TOP_CENTER || align == ALIGN_CENTER_CENTER || align == ALIGN_BOTTOM_CENTER) alignedX = originalX - getWidth() / 2.f; else if(align == ALIGN_TOP_RIGHT || align == ALIGN_CENTER_RIGHT || align == ALIGN_BOTTOM_RIGHT) alignedX = originalX - getWidth(); if(align == ALIGN_TOP_LEFT || align == ALIGN_TOP_CENTER || align == ALIGN_TOP_RIGHT) alignedY = originalY; else if(align == ALIGN_CENTER_LEFT || align == ALIGN_CENTER_CENTER || align == ALIGN_CENTER_RIGHT) alignedY = originalY - getHeight() / 2.f; else if(align == ALIGN_BOTTOM_LEFT || align == ALIGN_BOTTOM_CENTER || align == ALIGN_BOTTOM_RIGHT) alignedY = originalY - getHeight(); needUpdate = false; } setUiObjectOffset(alignedX, alignedY); }