2025-08-13 15:04:49 -05:00
|
|
|
#include "pxl8_font.h"
|
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
const pxl8_glyph* pxl8_font_find_glyph(const pxl8_font* font, u32 codepoint) {
|
|
|
|
|
if (!font || !font->glyphs) return NULL;
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < font->glyph_count; i++) {
|
|
|
|
|
if (font->glyphs[i].codepoint == codepoint) {
|
|
|
|
|
return &font->glyphs[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pxl8_result pxl8_font_create_atlas(const pxl8_font* font, u8** atlas_data, i32* atlas_width, i32* atlas_height) {
|
|
|
|
|
if (!font || !atlas_data || !atlas_width || !atlas_height) {
|
|
|
|
|
return PXL8_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i32 glyphs_per_row = 16;
|
|
|
|
|
i32 rows_needed = (font->glyph_count + glyphs_per_row - 1) / glyphs_per_row;
|
|
|
|
|
|
|
|
|
|
*atlas_width = glyphs_per_row * font->default_width;
|
|
|
|
|
*atlas_height = rows_needed * font->default_height;
|
|
|
|
|
|
|
|
|
|
i32 atlas_size = (*atlas_width) * (*atlas_height);
|
|
|
|
|
*atlas_data = (u8*)SDL_malloc(atlas_size);
|
|
|
|
|
if (!*atlas_data) {
|
|
|
|
|
return PXL8_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(*atlas_data, 0, atlas_size);
|
|
|
|
|
|
|
|
|
|
for (u32 i = 0; i < font->glyph_count; i++) {
|
|
|
|
|
const pxl8_glyph* glyph = &font->glyphs[i];
|
|
|
|
|
|
|
|
|
|
i32 atlas_x = (i % glyphs_per_row) * font->default_width;
|
|
|
|
|
i32 atlas_y = (i / glyphs_per_row) * font->default_height;
|
|
|
|
|
|
|
|
|
|
for (i32 y = 0; y < glyph->height && y < font->default_height; y++) {
|
|
|
|
|
for (i32 x = 0; x < glyph->width && x < font->default_width; x++) {
|
|
|
|
|
i32 glyph_idx = y * 8 + x;
|
|
|
|
|
i32 atlas_idx = (atlas_y + y) * (*atlas_width) + (atlas_x + x);
|
|
|
|
|
|
|
|
|
|
if (glyph->format == PXL8_FONT_FORMAT_INDEXED) {
|
|
|
|
|
u8 pixel_byte = glyph->data.indexed[glyph_idx / 8];
|
|
|
|
|
u8 pixel_bit = (pixel_byte >> (7 - (glyph_idx % 8))) & 1;
|
|
|
|
|
(*atlas_data)[atlas_idx] = pixel_bit ? 255 : 0;
|
|
|
|
|
} else {
|
|
|
|
|
u32 rgba_pixel = glyph->data.rgba[glyph_idx];
|
|
|
|
|
(*atlas_data)[atlas_idx] = (rgba_pixel >> 24) & 0xFF;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PXL8_OK;
|
2025-09-27 11:03:36 -05:00
|
|
|
}
|