From 495c23a3d25d2f0aef9978c0a51d25dccd0de5a4 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 22 Mar 2026 19:43:35 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20en=20la=20migracio=20de=20la=20marquesin?= =?UTF-8?q?a=20a=20la=20nova=20versio=20de=20Text=20s'havia=20posat=20per?= =?UTF-8?q?=20error=20un=20kerning=20superior=20al=20que=20havia=20opt:=20?= =?UTF-8?q?millores=20en=20la=20geti=C3=B3=20de=20la=20marquesina=20per=20?= =?UTF-8?q?optimitzar=20rendiment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/core/rendering/text.cpp | 11 +++++++++++ source/core/rendering/text.hpp | 8 +++++--- source/game/scenes/title.cpp | 15 ++++++++------- source/game/scenes/title.hpp | 1 + 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/source/core/rendering/text.cpp b/source/core/rendering/text.cpp index 402336b..ed52509 100644 --- a/source/core/rendering/text.cpp +++ b/source/core/rendering/text.cpp @@ -274,6 +274,17 @@ auto Text::glyphWidth(uint32_t codepoint, int kerning) const -> int { return 0; } +// Devuelve el clip rect (región en el bitmap) de un glifo dado su codepoint +auto Text::getGlyphClip(uint32_t codepoint) const -> SDL_FRect { + auto it = offset_.find(codepoint); + if (it == offset_.end()) { it = offset_.find('?'); } + if (it == offset_.end()) { return {.x = 0.0F, .y = 0.0F, .w = 0.0F, .h = 0.0F}; } + return {.x = static_cast(it->second.x), + .y = static_cast(it->second.y), + .w = static_cast(box_width_), + .h = static_cast(box_height_)}; +} + // Devuelve el tamaño de la caja de cada caracter auto Text::getCharacterSize() const -> int { return box_width_; diff --git a/source/core/rendering/text.hpp b/source/core/rendering/text.hpp index 2211f06..b0900a4 100644 --- a/source/core/rendering/text.hpp +++ b/source/core/rendering/text.hpp @@ -48,9 +48,11 @@ class Text { auto writeToSurface(const std::string& text, int zoom = 1, int kerning = 1) -> std::shared_ptr; // Escribe el texto en una textura auto writeDXToSurface(Uint8 flags, const std::string& text, int kerning = 1, Uint8 text_color = Uint8(), Uint8 shadow_distance = 1, Uint8 shadow_color = Uint8(), int lenght = -1) -> std::shared_ptr; // Escribe el texto con extras en una textura - [[nodiscard]] auto length(const std::string& text, int kerning = 1) const -> int; // Obtiene la longitud en pixels de una cadena - [[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el tamaño del caracter - [[nodiscard]] auto glyphWidth(uint32_t codepoint, int kerning = 0) const -> int; // Devuelve el ancho en pixels de un glifo + [[nodiscard]] auto length(const std::string& text, int kerning = 1) const -> int; // Obtiene la longitud en pixels de una cadena + [[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el tamaño del caracter + [[nodiscard]] auto glyphWidth(uint32_t codepoint, int kerning = 0) const -> int; // Devuelve el ancho en pixels de un glifo + [[nodiscard]] auto getGlyphClip(uint32_t codepoint) const -> SDL_FRect; // Devuelve el clip rect del glifo + [[nodiscard]] auto getSprite() const -> SurfaceSprite* { return sprite_.get(); } // Acceso al sprite interno void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra diff --git a/source/game/scenes/title.cpp b/source/game/scenes/title.cpp index 0f8272a..68a33f0 100644 --- a/source/game/scenes/title.cpp +++ b/source/game/scenes/title.cpp @@ -66,8 +66,9 @@ void Title::initMarquee() { uint32_t cp = Text::nextCodepoint(long_text_, pos); Glyph l; l.codepoint = cp; + l.clip = marquee_text_->getGlyphClip(cp); // Pre-calcular clip rect (evita búsqueda por frame) l.x = MARQUEE_START_X; - l.width = static_cast(marquee_text_->glyphWidth(cp, 1)); // Pre-calcular ancho con kerning + l.width = static_cast(marquee_text_->glyphWidth(cp, 0)); // Pre-calcular ancho visual del glifo l.enabled = false; letters_.push_back(l); } @@ -223,15 +224,15 @@ void Title::updateMarquee(float delta_time) { // Dibuja la marquesina void Title::renderMarquee() { + auto* sprite = marquee_text_->getSprite(); + sprite->setY(MARQUEE_Y); // Solo renderizar letras activas (optimización: usa cache y rangos) for (int i = first_active_letter_; i <= last_active_letter_ + 1 && i < (int)letters_.size(); ++i) { const auto& letter = letters_[i]; - if (letter.enabled) { - marquee_text_->writeColored( - static_cast(letter.x), // Conversión explícita float→int - static_cast(MARQUEE_Y), // Usar constante - Text::codepointToUtf8(letter.codepoint), // Convertir codepoint a string UTF-8 - static_cast(PaletteColor::MAGENTA)); + if (letter.enabled && letter.clip.w > 0.0F) { + sprite->setClip(letter.clip); + sprite->setX(letter.x); + sprite->render(1, static_cast(PaletteColor::MAGENTA)); } } } diff --git a/source/game/scenes/title.hpp b/source/game/scenes/title.hpp index ea04450..64a799c 100644 --- a/source/game/scenes/title.hpp +++ b/source/game/scenes/title.hpp @@ -26,6 +26,7 @@ class Title { // --- Estructuras y enumeraciones --- struct Glyph { uint32_t codepoint{0}; // Codepoint Unicode del carácter + SDL_FRect clip{}; // Clip rect pre-calculado en el bitmap de fuente float x{0.0F}; // Posición en el eje x (float para precisión con delta time) float width{0.0F}; // Ancho pre-calculado del carácter bool enabled{false}; // Solo se escriben y mueven si estan habilitadas