refactor: extreure helpers per reduir complexitat cognitiva (tidy net)
This commit is contained in:
+65
-177
@@ -1,5 +1,6 @@
|
||||
#include "core/rendering/text.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
@@ -158,60 +159,57 @@ void Text::loadBitmap(const char* gif_file) {
|
||||
|
||||
// --- Renderitzat ---
|
||||
|
||||
auto Text::resolveGlyph(uint32_t cp) const -> const GlyphInfo* {
|
||||
auto it = glyphs_.find(cp);
|
||||
if (it != glyphs_.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
it = glyphs_.find('?');
|
||||
return (it != glyphs_.end()) ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
void Text::blitGlyph(Uint32* pixel_data, int dst_x, int dst_y, const GlyphInfo& glyph, Uint32 color, int clip_x_min, int clip_x_max, int clip_y_min, int clip_y_max) const {
|
||||
const int GY_START = std::max(0, clip_y_min - dst_y);
|
||||
const int GY_END = std::min(box_height_, clip_y_max - dst_y);
|
||||
const int GX_START = std::max(0, clip_x_min - dst_x);
|
||||
const int GX_END = std::min(glyph.w, clip_x_max - dst_x);
|
||||
for (int gy = GY_START; gy < GY_END; gy++) {
|
||||
const int SRC_Y = glyph.y + gy;
|
||||
if (SRC_Y >= bitmap_height_) {
|
||||
continue;
|
||||
}
|
||||
const int DST_ROW = dst_y + gy;
|
||||
for (int gx = GX_START; gx < GX_END; gx++) {
|
||||
const int SRC_X = glyph.x + gx;
|
||||
if (SRC_X >= bitmap_width_) {
|
||||
continue;
|
||||
}
|
||||
const Uint8 PIXEL = bitmap_[SRC_X + (SRC_Y * bitmap_width_)];
|
||||
if (PIXEL != 0) {
|
||||
pixel_data[(dst_x + gx) + (DST_ROW * SCREEN_WIDTH)] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Text::draw(Uint32* pixel_data, int x, int y, const char* text, Uint32 color) const {
|
||||
if (bitmap_.empty() || (pixel_data == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* ptr = text;
|
||||
int cursor_x = x;
|
||||
|
||||
while (*ptr != 0) {
|
||||
uint32_t cp = nextCodepoint(ptr);
|
||||
if (cp == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto it = glyphs_.find(cp);
|
||||
if (it == glyphs_.end()) {
|
||||
it = glyphs_.find('?');
|
||||
if (it == glyphs_.end()) {
|
||||
cursor_x += box_width_;
|
||||
continue;
|
||||
}
|
||||
const GlyphInfo* glyph = resolveGlyph(cp);
|
||||
if (glyph == nullptr) {
|
||||
cursor_x += box_width_;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& glyph = it->second;
|
||||
|
||||
// Pinta glifo pixel a pixel
|
||||
for (int gy = 0; gy < box_height_; gy++) {
|
||||
int dst_y = y + gy;
|
||||
if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int gx = 0; gx < glyph.w; gx++) {
|
||||
int dst_x = cursor_x + gx;
|
||||
if (dst_x < 0 || dst_x >= SCREEN_WIDTH) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int src_x = glyph.x + gx;
|
||||
int src_y = glyph.y + gy;
|
||||
|
||||
if (src_x >= bitmap_width_ || src_y >= bitmap_height_) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Uint8 pixel = bitmap_[src_x + (src_y * bitmap_width_)];
|
||||
// Píxel no transparent (índex 0 és fons típicament)
|
||||
if (pixel != 0) {
|
||||
pixel_data[dst_x + (dst_y * SCREEN_WIDTH)] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursor_x += glyph.w + 1; // +1 kerning
|
||||
blitGlyph(pixel_data, cursor_x, y, *glyph, color, 0, SCREEN_WIDTH, 0, SCREEN_HEIGHT);
|
||||
cursor_x += glyph->w + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,70 +223,29 @@ void Text::drawClipped(Uint32* pixel_data, int x, int y, const char* text, Uint3
|
||||
if (bitmap_.empty() || (pixel_data == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Descart ràpid si el glifo sencer cau fora verticalment
|
||||
if (y + box_height_ <= clip_y_min || y >= clip_y_max) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int X_MIN = std::max(0, clip_x_min);
|
||||
const int X_MAX = std::min(SCREEN_WIDTH, clip_x_max);
|
||||
const int Y_MIN = std::max(0, clip_y_min);
|
||||
const int Y_MAX = std::min(SCREEN_HEIGHT, clip_y_max);
|
||||
const char* ptr = text;
|
||||
int cursor_x = x;
|
||||
|
||||
while (*ptr != 0) {
|
||||
uint32_t cp = nextCodepoint(ptr);
|
||||
if (cp == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto it = glyphs_.find(cp);
|
||||
if (it == glyphs_.end()) {
|
||||
it = glyphs_.find('?');
|
||||
if (it == glyphs_.end()) {
|
||||
cursor_x += box_width_;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& glyph = it->second;
|
||||
|
||||
// Si el glifo està completament fora del clip horitzontal, salta
|
||||
if (cursor_x + glyph.w <= clip_x_min || cursor_x >= clip_x_max) {
|
||||
cursor_x += glyph.w + 1;
|
||||
const GlyphInfo* glyph = resolveGlyph(cp);
|
||||
if (glyph == nullptr) {
|
||||
cursor_x += box_width_;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int gy = 0; gy < box_height_; gy++) {
|
||||
int dst_y = y + gy;
|
||||
if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) {
|
||||
continue;
|
||||
}
|
||||
if (dst_y < clip_y_min || dst_y >= clip_y_max) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int gx = 0; gx < glyph.w; gx++) {
|
||||
int dst_x = cursor_x + gx;
|
||||
if (dst_x < 0 || dst_x >= SCREEN_WIDTH) {
|
||||
continue;
|
||||
}
|
||||
if (dst_x < clip_x_min || dst_x >= clip_x_max) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int src_x = glyph.x + gx;
|
||||
int src_y = glyph.y + gy;
|
||||
if (src_x >= bitmap_width_ || src_y >= bitmap_height_) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Uint8 pixel = bitmap_[src_x + (src_y * bitmap_width_)];
|
||||
if (pixel != 0) {
|
||||
pixel_data[dst_x + (dst_y * SCREEN_WIDTH)] = color;
|
||||
}
|
||||
}
|
||||
if (cursor_x + glyph->w > X_MIN && cursor_x < X_MAX) {
|
||||
blitGlyph(pixel_data, cursor_x, y, *glyph, color, X_MIN, X_MAX, Y_MIN, Y_MAX);
|
||||
}
|
||||
|
||||
cursor_x += glyph.w + 1;
|
||||
cursor_x += glyph->w + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,54 +253,20 @@ void Text::drawMono(Uint32* pixel_data, int x, int y, const char* text, Uint32 c
|
||||
if (bitmap_.empty() || (pixel_data == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* ptr = text;
|
||||
int cursor_x = x;
|
||||
|
||||
while (*ptr != 0) {
|
||||
uint32_t cp = nextCodepoint(ptr);
|
||||
if (cp == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto it = glyphs_.find(cp);
|
||||
if (it == glyphs_.end()) {
|
||||
it = glyphs_.find('?');
|
||||
if (it == glyphs_.end()) {
|
||||
cursor_x += cell_w;
|
||||
continue;
|
||||
}
|
||||
const GlyphInfo* glyph = resolveGlyph(cp);
|
||||
if (glyph == nullptr) {
|
||||
cursor_x += cell_w;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& glyph = it->second;
|
||||
// Centra el glif dins la cel·la
|
||||
int glyph_x = cursor_x + ((cell_w - glyph.w) / 2);
|
||||
|
||||
for (int gy = 0; gy < box_height_; gy++) {
|
||||
int dst_y = y + gy;
|
||||
if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int gx = 0; gx < glyph.w; gx++) {
|
||||
int dst_x = glyph_x + gx;
|
||||
if (dst_x < 0 || dst_x >= SCREEN_WIDTH) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int src_x = glyph.x + gx;
|
||||
int src_y = glyph.y + gy;
|
||||
if (src_x >= bitmap_width_ || src_y >= bitmap_height_) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Uint8 pixel = bitmap_[src_x + (src_y * bitmap_width_)];
|
||||
if (pixel != 0) {
|
||||
pixel_data[dst_x + (dst_y * SCREEN_WIDTH)] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int GLYPH_X = cursor_x + ((cell_w - glyph->w) / 2);
|
||||
blitGlyph(pixel_data, GLYPH_X, y, *glyph, color, 0, SCREEN_WIDTH, 0, SCREEN_HEIGHT);
|
||||
cursor_x += cell_w;
|
||||
}
|
||||
}
|
||||
@@ -352,62 +275,27 @@ void Text::drawMonoDigits(Uint32* pixel_data, int x, int y, const char* text, Ui
|
||||
if (bitmap_.empty() || (pixel_data == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* ptr = text;
|
||||
int cursor_x = x;
|
||||
bool first = true;
|
||||
|
||||
while (*ptr != 0) {
|
||||
uint32_t cp = nextCodepoint(ptr);
|
||||
if (cp == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto it = glyphs_.find(cp);
|
||||
if (it == glyphs_.end()) {
|
||||
it = glyphs_.find('?');
|
||||
if (it == glyphs_.end()) {
|
||||
if (!first) {
|
||||
cursor_x += 1;
|
||||
}
|
||||
cursor_x += box_width_;
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& glyph = it->second;
|
||||
bool is_digit = (cp >= '0' && cp <= '9');
|
||||
|
||||
if (!first) {
|
||||
cursor_x += 1; // kerning
|
||||
}
|
||||
|
||||
int glyph_x = is_digit ? cursor_x + ((digit_cell_w - glyph.w) / 2) : cursor_x;
|
||||
|
||||
for (int gy = 0; gy < box_height_; gy++) {
|
||||
int dst_y = y + gy;
|
||||
if (dst_y < 0 || dst_y >= SCREEN_HEIGHT) {
|
||||
continue;
|
||||
}
|
||||
for (int gx = 0; gx < glyph.w; gx++) {
|
||||
int dst_x = glyph_x + gx;
|
||||
if (dst_x < 0 || dst_x >= SCREEN_WIDTH) {
|
||||
continue;
|
||||
}
|
||||
int src_x = glyph.x + gx;
|
||||
int src_y = glyph.y + gy;
|
||||
if (src_x >= bitmap_width_ || src_y >= bitmap_height_) {
|
||||
continue;
|
||||
}
|
||||
Uint8 pixel = bitmap_[src_x + (src_y * bitmap_width_)];
|
||||
if (pixel != 0) {
|
||||
pixel_data[dst_x + (dst_y * SCREEN_WIDTH)] = color;
|
||||
}
|
||||
}
|
||||
const GlyphInfo* glyph = resolveGlyph(cp);
|
||||
if (glyph == nullptr) {
|
||||
cursor_x += box_width_;
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
cursor_x += is_digit ? digit_cell_w : glyph.w;
|
||||
const bool IS_DIGIT = (cp >= '0' && cp <= '9');
|
||||
const int GLYPH_X = IS_DIGIT ? cursor_x + ((digit_cell_w - glyph->w) / 2) : cursor_x;
|
||||
blitGlyph(pixel_data, GLYPH_X, y, *glyph, color, 0, SCREEN_WIDTH, 0, SCREEN_HEIGHT);
|
||||
cursor_x += IS_DIGIT ? digit_cell_w : glyph->w;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user