133 lines
3.5 KiB
C++
133 lines
3.5 KiB
C++
#include "KFont.h"
|
|
|
|
#include <sstream>
|
|
|
|
#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;
|
|
}
|
|
}
|