Files
dusk/src/display/ui/rendertext.c
2025-09-02 22:47:07 -05:00

130 lines
2.9 KiB
C

// /**
// * Copyright (c) 2025 Dominic Masters
// *
// * This software is released under the MIT License.
// * https://opensource.org/licenses/MIT
// */
#include "rendertext.h"
#include "asset/assetmanager.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "display/spritebatch/spritebatch.h"
// #include "display/display.h"
// #include "util/math.h"
rendertext_t RENDER_TEXT;
errorret_t renderTextInit(void) {
memoryZero(&RENDER_TEXT, sizeof(rendertext_t));
errorChain(assetManagerLoadAsset(
"font_minogram.dai", &RENDER_TEXT.asset, &RENDER_TEXT.assetRef
));
errorOk();
}
void renderTextDispose(void) {
if(RENDER_TEXT.asset) {
assetUnlock(RENDER_TEXT.asset, RENDER_TEXT.assetRef);
}
}
void renderTextDrawChar(
const float_t x,
const float_t y,
const char_t c,
const uint8_t r,
const uint8_t g,
const uint8_t b
) {
int32_t tileIndex = (int32_t)(c) - RENDER_TEXT_CHAR_START;
assertTrue(
tileIndex >= 0 && tileIndex <= RENDER_TEXT_TILE_COUNT,
"Character is out of bounds for font tiles"
);
const float_t w = (float)RENDER_TEXT.asset->alphaImage.texture.width;
const float_t h = (float)RENDER_TEXT.asset->alphaImage.texture.height;
const int32_t tileX = (tileIndex % RENDER_TEXT_COLUMN_COUNT);
const int32_t tileY = (tileIndex / RENDER_TEXT_COLUMN_COUNT);
spriteBatchPush(
&RENDER_TEXT.asset->alphaImage.texture,
x, y,
x + RENDER_TEXT_TILE_WIDTH, y + RENDER_TEXT_TILE_HEIGHT,
r, g, b, 0xFF,
(tileX * RENDER_TEXT_TILE_WIDTH) / w,
(tileY * RENDER_TEXT_TILE_HEIGHT) / h,
((tileX + 1) * RENDER_TEXT_TILE_WIDTH) / w,
((tileY + 1) * RENDER_TEXT_TILE_HEIGHT) / h
);
}
void renderTextDraw(
const float_t x,
const float_t y,
const char_t *text,
const uint8_t r,
const uint8_t g,
const uint8_t b
) {
assertNotNull(text, "Text cannot be NULL");
float_t posX = x;
float_t posY = y;
char_t c;
int32_t i = 0;
while((c = text[i++]) != '\0') {
if(c == '\n') {
posX = x;
posY += RENDER_TEXT_TILE_HEIGHT;
continue;
}
if(c == ' ') {
posX += RENDER_TEXT_TILE_WIDTH;
continue;
}
renderTextDrawChar(posX, posY, c, r, g, b);
posX += RENDER_TEXT_TILE_WIDTH;
}
}
void renderTextMeasure(
const char_t *text,
int32_t *outWidth,
int32_t *outHeight
) {
assertNotNull(text, "Text cannot be NULL");
assertNotNull(outWidth, "Output width pointer cannot be NULL");
assertNotNull(outHeight, "Output height pointer cannot be NULL");
int32_t width = 0;
int32_t height = RENDER_TEXT_TILE_HEIGHT;
int32_t lineWidth = 0;
char_t c;
int32_t i = 0;
while((c = text[i++]) != '\0') {
if(c == '\n') {
if(lineWidth > width) {
width = lineWidth;
}
lineWidth = 0;
height += RENDER_TEXT_TILE_HEIGHT;
continue;
}
lineWidth += RENDER_TEXT_TILE_WIDTH;
}
if(lineWidth > width) {
width = lineWidth;
}
*outWidth = width;
*outHeight = height;
}