Files
vibe3_physics/source/text/textrenderer.cpp

175 lines
5.5 KiB
C++

#include "textrenderer.h"
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
TextRenderer::TextRenderer() : renderer_(nullptr), font_(nullptr), font_size_(0), use_antialiasing_(true) {
}
TextRenderer::~TextRenderer() {
cleanup();
}
bool TextRenderer::init(SDL_Renderer* renderer, const char* font_path, int font_size, bool use_antialiasing) {
renderer_ = renderer;
font_size_ = font_size;
use_antialiasing_ = use_antialiasing;
// Inicializar SDL_ttf si no está inicializado
if (!TTF_WasInit()) {
if (!TTF_Init()) {
SDL_Log("Error al inicializar SDL_ttf: %s", SDL_GetError());
return false;
}
}
// Cargar la fuente
font_ = TTF_OpenFont(font_path, font_size);
if (font_ == nullptr) {
SDL_Log("Error al cargar fuente '%s': %s", font_path, SDL_GetError());
return false;
}
return true;
}
void TextRenderer::cleanup() {
if (font_ != nullptr) {
TTF_CloseFont(font_);
font_ = nullptr;
}
renderer_ = nullptr;
}
void TextRenderer::print(int x, int y, const char* text, uint8_t r, uint8_t g, uint8_t b) {
if (!isInitialized() || text == nullptr || text[0] == '\0') {
return;
}
// Crear superficie con el texto renderizado
SDL_Color color = {r, g, b, 255};
SDL_Surface* text_surface = nullptr;
if (use_antialiasing_) {
// Con antialiasing (suave, mejor calidad)
text_surface = TTF_RenderText_Blended(font_, text, strlen(text), color);
} else {
// Sin antialiasing (píxeles nítidos, estilo retro)
text_surface = TTF_RenderText_Solid(font_, text, strlen(text), color);
}
if (text_surface == nullptr) {
SDL_Log("Error al renderizar texto: %s", SDL_GetError());
return;
}
// Crear textura desde la superficie
SDL_Texture* text_texture = SDL_CreateTextureFromSurface(renderer_, text_surface);
if (text_texture == nullptr) {
SDL_Log("Error al crear textura: %s", SDL_GetError());
SDL_DestroySurface(text_surface);
return;
}
// Preparar rectángulo de destino
SDL_FRect dest_rect;
dest_rect.x = static_cast<float>(x);
dest_rect.y = static_cast<float>(y);
dest_rect.w = static_cast<float>(text_surface->w);
dest_rect.h = static_cast<float>(text_surface->h);
// Renderizar la textura
SDL_RenderTexture(renderer_, text_texture, nullptr, &dest_rect);
// Limpiar recursos
SDL_DestroyTexture(text_texture);
SDL_DestroySurface(text_surface);
}
void TextRenderer::print(int x, int y, const std::string& text, uint8_t r, uint8_t g, uint8_t b) {
print(x, y, text.c_str(), r, g, b);
}
void TextRenderer::printPhysical(int logical_x, int logical_y, const char* text, uint8_t r, uint8_t g, uint8_t b, float scale_x, float scale_y) {
if (!isInitialized() || text == nullptr || text[0] == '\0') {
return;
}
// Convertir coordenadas lógicas a físicas
int physical_x = static_cast<int>(logical_x * scale_x);
int physical_y = static_cast<int>(logical_y * scale_y);
// Crear superficie con el texto renderizado
SDL_Color color = {r, g, b, 255};
SDL_Surface* text_surface = nullptr;
if (use_antialiasing_) {
text_surface = TTF_RenderText_Blended(font_, text, strlen(text), color);
} else {
text_surface = TTF_RenderText_Solid(font_, text, strlen(text), color);
}
if (text_surface == nullptr) {
SDL_Log("Error al renderizar texto: %s", SDL_GetError());
return;
}
// Crear textura desde la superficie
SDL_Texture* text_texture = SDL_CreateTextureFromSurface(renderer_, text_surface);
if (text_texture == nullptr) {
SDL_Log("Error al crear textura: %s", SDL_GetError());
SDL_DestroySurface(text_surface);
return;
}
// Renderizar en coordenadas físicas (bypass presentación lógica)
// Usar SDL_RenderTexture con coordenadas absolutas de ventana
SDL_FRect dest_rect;
dest_rect.x = static_cast<float>(physical_x);
dest_rect.y = static_cast<float>(physical_y);
dest_rect.w = static_cast<float>(text_surface->w);
dest_rect.h = static_cast<float>(text_surface->h);
// Deshabilitar temporalmente presentación lógica para renderizar en píxeles físicos
int logical_w = 0, logical_h = 0;
SDL_RendererLogicalPresentation presentation_mode;
SDL_GetRenderLogicalPresentation(renderer_, &logical_w, &logical_h, &presentation_mode);
// Renderizar sin presentación lógica (coordenadas absolutas)
SDL_SetRenderLogicalPresentation(renderer_, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED);
SDL_RenderTexture(renderer_, text_texture, nullptr, &dest_rect);
// Restaurar presentación lógica
SDL_SetRenderLogicalPresentation(renderer_, logical_w, logical_h, presentation_mode);
// Limpiar recursos
SDL_DestroyTexture(text_texture);
SDL_DestroySurface(text_surface);
}
void TextRenderer::printPhysical(int logical_x, int logical_y, const std::string& text, uint8_t r, uint8_t g, uint8_t b, float scale_x, float scale_y) {
printPhysical(logical_x, logical_y, text.c_str(), r, g, b, scale_x, scale_y);
}
int TextRenderer::getTextWidth(const char* text) {
if (!isInitialized() || text == nullptr) {
return 0;
}
int width = 0;
int height = 0;
if (!TTF_GetStringSize(font_, text, strlen(text), &width, &height)) {
return 0;
}
return width;
}
int TextRenderer::getTextHeight() {
if (!isInitialized()) {
return 0;
}
return TTF_GetFontHeight(font_);
}