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

172 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>
struct dtext_geometry {
struct {
char *raw;
size_t raw_size;
int size;
} text;
int x;
int y;
};
static struct {
struct {
struct dtext_geometry *geometry;
int number;
int idx;
} pool;
} dtext_info = {
.pool = {
.geometry = 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.geometry = calloc(
dtext_info.pool.number,
sizeof(struct dtext_geometry)
);
for (int i = 0; i < dtext_info.pool.number; ++i) {
dtext_info.pool.geometry[i].text.raw = malloc(32);
dtext_info.pool.geometry[i].text.raw_size = 32;
dtext_info.pool.geometry[i].text.size = 0;
}
}
VDESTRUCTOR void __dtext_destructor(void)
{
for (int i = 0; i < dtext_info.pool.number; ++i)
free(dtext_info.pool.geometry[i].text.raw);
free(dtext_info.pool.geometry);
}
static void __dtext_quit(void)
{
dtext_info.pool.idx = 0;
}
//---
// Drawing functions
//---
#if 0
static void dtext_opt_draw(struct dshader_surface *surface, uint32_t *arg)
{
uint32_t buff[5];
char *str;
buff[0] = (uintptr_t)dfont_get();
buff[1] = arg[0]; // x
buff[2] = arg[1]; // y
buff[3] = arg[2]; // fg
buff[4] = arg[3]; // bg
str = (void*)(uintptr_t)arg[4];
for (int i = 0; i < (int)arg[5]; ++i) {
buff[5] = str[i];
dfont_render(surface, buff);
}
}
#endif
//---
// 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;
/* 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);
/* request draw call */
return dstack_add_action(
&DSTACK_CALL(
&dfont_text_render,
x, y,
fg, bg,
(uint32_t)(uintptr_t)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));
}