vxKernel/src/modules/display/text/dtext.c

162 lines
3.3 KiB
C

#include <vhex/defs/types.h>
#include <vhex/display/text.h>
#include <vhex/display/shader.h>
#include <vhex/display/stack.h>
#include <vhex/display/color.h>
#include <vhex/display/font.h>
#include <vhex/display.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static struct {
struct {
struct {
char *raw;
size_t size;
} *text;
int number;
int idx;
} pool;
} dtext_info = {
.pool = {
.text = NULL,
.number = 0,
.idx = 0
}
};
//---
// Internal module functions
//---
VCONSTRUCTOR static void __dtext_constructor(void)
{
dtext_info.pool.number = 16;
dtext_info.pool.idx = -1;
dtext_info.pool.text = calloc(
dtext_info.pool.number,
sizeof (*dtext_info.pool.text)
);
for (int i = 0; i < dtext_info.pool.number; ++i) {
dtext_info.pool.text[i].raw = malloc(32);
dtext_info.pool.text[i].size = 32;
}
}
VDESTRUCTOR void __dtext_destructor(void)
{
for (int i = 0; i < dtext_info.pool.number; ++i)
free(dtext_info.pool.text[i].raw);
free(dtext_info.pool.text);
}
static void __dtext_quit(void)
{
dtext_info.pool.idx = 0;
}
//---
// Private functions
//---
static char *dtext_info_register(char const * const str)
{
dtext_info.pool.idx += 1;
if (dtext_info.pool.idx >= dtext_info.pool.number) {
dtext_info.pool.number += dtext_info.pool.number;
dtext_info.pool.text = realloc(
dtext_info.pool.text,
dtext_info.pool.number
);
}
strcpy(dtext_info.pool.text[dtext_info.pool.idx].raw, str);
return dtext_info.pool.text[dtext_info.pool.idx].raw;
}
//---
// Public API
//---
/* dtext_opt(): Display a string of text */
did_t dtext_opt(
int x, int y,
int fg, int bg,
int halign, int valign,
char const * const str, int size
) {
size_t width;
size_t height;
void *real_str;
/* get text geometry and handle obvious culling */
if (dfont_text_geometry(NULL, str, &size, &width, &height) != 0)
return (-1);
if (x >= (int)dwidth()
|| y >= (int)dheight()
|| x + (int)width < 0
|| y + (int)height < 0) {
return (-1);
}
/* handle position */
if (halign == DTEXT_CENTER) x = x - (width / 2);
if (halign == DTEXT_RIGHT) x = x - (width);
if (valign == DTEXT_CENTER) y = y - (height / 2);
if (valign == DTEXT_BOTTOM) y = y - (height);
/* register the string */
real_str = dtext_info_register(str);
/* request draw call */
return dstack_add_action(
&DSTACK_CALL(
&dfont_text_render,
x, y, x + width, y + height,
fg, bg,
(uint32_t)(uintptr_t)real_str, size,
),
(dtext_info.pool.idx == 0) ? (void*)&__dtext_quit : NULL,
NULL
);
}
/* dtext() : display text information */
did_t dtext(int x, int y, int fg, char const * const text)
{
return (dtext_opt(x, y, fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, text, -1));
}
/* dprint() : display formated string */
did_t dprint(int x, int y, int fg, char const * const text, ...)
{
va_list ap;
char buff[1024];
va_start(ap, text);
vsnprintf(buff, 1024, text, ap);
va_end(ap);
return (dtext_opt(x, y, fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, buff, -1));
}
/* dprint_opt(): Display a string of text */
did_t dprint_opt(
int x, int y,
int fg, int bg,
int halign, int valign,
char const *text, ...
) {
va_list ap;
char buff[1024];
va_start(ap, text);
vsnprintf(buff, 1024, text, ap);
va_end(ap);
return (dtext_opt(x, y, fg, bg, halign, valign, buff, -1));
}