162 lines
3.3 KiB
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));
|
|
}
|