2dkg/2dkg_zad5/2dgk_zad5/KFont.cpp
2022-01-20 08:52:14 +01:00

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;
}
}