#include "KFont.h" #include #include "KTexture.h" namespace KapitanGame { KFont::KFont() = default; KFont::~KFont() { Free(); } KFont::KFont(KFont&& other) noexcept : Font(other.Font) { other.Font = nullptr; } KFont& KFont::operator=(KFont&& other) noexcept { Font = other.Font; other.Font = nullptr; return *this; } bool KFont::LoadFromFile(const std::string& path, const int ptSize) { bool success = true; Font = TTF_OpenFont(path.c_str(), ptSize); if (Font == nullptr) { printf("Failed to load %s font! SDL_ttf Error: %s\n", path.c_str(), TTF_GetError()); success = false; } return success; } void KFont::Free() { if (Font != nullptr) { TTF_CloseFont(Font); Font = nullptr; } } KTexture KFont::GetTextTexture(const std::string& text, const SDL_Color textColor, SDL_Renderer* renderer) const { KTexture texture; constexpr int spacing = 1; int width, height = width = 0; std::istringstream inputText; inputText.str(text); for(std::string line; std::getline(inputText, line);) { int w, h; TTF_SizeText(Font, line.c_str(), &w, &h); if (w > width) width = w; height += w+spacing; } if (height > 0) height -= spacing; inputText.clear(); inputText.seekg(0); SDL_Surface* textureSurface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 8, SDL_PIXELFORMAT_INDEX8); { const SDL_Palette* palette = textureSurface->format->palette; palette->colors[0].r = 255 - textColor.r; palette->colors[0].g = 255 - textColor.g; palette->colors[0].b = 255 - textColor.b; palette->colors[1].r = textColor.r; palette->colors[1].g = textColor.g; palette->colors[1].b = textColor.b; palette->colors[1].a = textColor.a; } SDL_SetColorKey(textureSurface, SDL_TRUE, 0); int y = 0; for (std::string line; std::getline(inputText, line);) { if (SDL_Surface* textSurface = TTF_RenderText_Solid(Font, line.c_str(), textColor); textSurface == nullptr) { printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError()); } else { SDL_Rect destRect{0, y, textSurface->w, textSurface->h}; SDL_BlitSurface(textSurface, nullptr, textureSurface, &destRect); y += textSurface->h + spacing; SDL_FreeSurface(textSurface); } } texture.LoadFromSurface(textureSurface, renderer); SDL_FreeSurface(textureSurface); return texture; } KTexture KFont::GetTextWithOutlineTexture(const std::string& text, const SDL_Color fgColor, const SDL_Color bgColor, const int outlineSize, SDL_Renderer* renderer) const { KTexture texture; const int originalOutlineSize = TTF_GetFontOutline(Font); if (SDL_Surface* fgSurface = TTF_RenderText_Blended(Font, text.c_str(), fgColor); fgSurface == nullptr) { printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError()); } else { TTF_SetFontOutline(Font, outlineSize); SDL_Surface* bgSurface = TTF_RenderText_Blended(Font, text.c_str(), bgColor); TTF_SetFontOutline(Font, originalOutlineSize); if (bgSurface == nullptr) { printf("Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError()); } else { SDL_Rect rect = { outlineSize, outlineSize, fgSurface->w, fgSurface->h }; /* blit text onto its outline */ SDL_SetSurfaceBlendMode(fgSurface, SDL_BLENDMODE_BLEND); SDL_BlitSurface(fgSurface, nullptr, bgSurface, &rect); texture.LoadFromSurface(bgSurface, renderer); SDL_FreeSurface(bgSurface); } SDL_FreeSurface(fgSurface); } return texture; } }