VxKernel 0.6.0-2 : Prepare font and text API (WIP)
@add <> include/vhex/display : | add dwidth() primitive | add dheight() primitive <> include/vhex/display/font : | create a font structure that support proportional font | expose font primitives API (WIP) <> vhex/module/display/text/dfont: | support utf8 string format | add geometry font information (WIP) <> vhex/module/display/text/dtext: | write most of the API primitive (WIP) | proper isolation between font <-> text API @update <> include/vhex/display/shader : | add a quit() routine that will be involved at the end of dupdate() | add display_[width/height] in driver interface | add display screen information primitives <> vhex/drivers/screen/r61524/r61524.c | add display driver interface screen information <> vhex/module/display/dclear: | use the 32-bits arguments instead of the broken dshader_call_arg_t | support the new API with quit() routine <> vhex/module/display/dstack: | support the new display screen information | support the quit() routine at the end of the dupdate() @fix <> include/vhex/display/shader : | remove broken transparent-union implicit cast | fix argument transmitted to drawing routine (only 32bit arguments supported)
This commit is contained in:
parent
a916120d66
commit
510c4f1f86
|
@ -5,8 +5,9 @@
|
|||
#include <vhex/display/types.h>
|
||||
#include <vhex/display/draw.h>
|
||||
#include <vhex/display/color.h>
|
||||
#include <vhex/display/text.h>
|
||||
//#include <vhex/display/image.h>
|
||||
//#include <vhex/display/text.h>
|
||||
#include <vhex/display/stack.h>
|
||||
|
||||
//TODO: doc
|
||||
|
||||
|
@ -17,12 +18,16 @@ extern did_t dclear(int color);
|
|||
extern void dupdate(void);
|
||||
|
||||
/* dwidth(): get the screen width */
|
||||
extern size_t dwidth(void);
|
||||
VINLINE size_t dwidth(void)
|
||||
{
|
||||
return dstack_display_width();
|
||||
}
|
||||
|
||||
/* dheight(): get the heigth of the screen */
|
||||
extern size_t dheight(void);
|
||||
|
||||
|
||||
VINLINE size_t dheight(void)
|
||||
{
|
||||
return dstack_display_height();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -33,29 +38,6 @@ extern size_t dheight(void);
|
|||
// Text render API
|
||||
//---
|
||||
#if 0
|
||||
/* Alignment settings for dtext_opt() and dprint_opt(). Combining a vertical
|
||||
and a horizontal alignment option specifies where a given point (x,y) should
|
||||
be relative to the rendered string. */
|
||||
enum {
|
||||
/* Horizontal settings: default in dtext() is DTEXT_LEFT */
|
||||
DTEXT_LEFT = 0,
|
||||
DTEXT_CENTER = 1,
|
||||
DTEXT_RIGHT = 2,
|
||||
/* Vertical settings: default in dtext() is DTEXT_TOP */
|
||||
DTEXT_TOP = 0,
|
||||
DTEXT_MIDDLE = 1,
|
||||
DTEXT_BOTTOM = 2,
|
||||
};
|
||||
|
||||
|
||||
/* dtext_opt(): Display a string of text */
|
||||
extern void dtext_opt(
|
||||
int x, int y,
|
||||
int fg, int bg,
|
||||
int halign, int valign,
|
||||
char const *str, int size
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -70,17 +52,9 @@ extern void dascii(int x, int y, int fg, int bg, int n);
|
|||
/* dline(): Render a straight line */
|
||||
extern void dline(int x1, int y1, int x2, int y2, int color);
|
||||
|
||||
/* dtext() : display raw text */
|
||||
extern void dtext(int x, int y, int fg, char const * restrict const text);
|
||||
|
||||
/* dprint() : display formated text */
|
||||
extern void dprint(int x, int y, int fg, char const * const text, ...);
|
||||
|
||||
/* dsize(): Get the width and height of rendered text */
|
||||
extern void dsize(char const *str, int *w, int *h);
|
||||
|
||||
/* dnsize(): Get the width and height of rendered text for the n first char */
|
||||
extern void dnsize(char const *str, int n, int *w, int *h);
|
||||
|
||||
/* drect(): Fill a rectangle of the screen */
|
||||
extern void drect(int x1, int y1, int x2, int y2, int color);
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef __VHEX_DISPLAY_FONT__
|
||||
# define __VHEX_DISPLAY_FONT__
|
||||
|
||||
#include <vhex/defs/types.h>
|
||||
#include <vhex/defs/attributes.h>
|
||||
#include <vhex/display/shader.h>
|
||||
|
||||
/* font_t: Font data encoded for dfont*() functions */
|
||||
typedef struct font {
|
||||
/* Font name (NUL-terminated), NULL if no title */
|
||||
char const *name;
|
||||
|
||||
/* Font shape flags */
|
||||
byte_union(shape,
|
||||
uint8_t bold :1;
|
||||
uint8_t italic :1;
|
||||
uint8_t serif :1;
|
||||
uint8_t mono :1;
|
||||
uint8_t :3;
|
||||
uint8_t prop :1;
|
||||
);
|
||||
|
||||
/* Line height */
|
||||
uint8_t line_height;
|
||||
/* Storage height */
|
||||
uint8_t data_height;
|
||||
|
||||
/* Number of Unicode blocks */
|
||||
uint8_t block_count;
|
||||
/* Number of total glyphs */
|
||||
uint32_t glyph_count;
|
||||
|
||||
/* Character spacing (usually 1) */
|
||||
uint8_t char_spacing;
|
||||
|
||||
struct {
|
||||
/* Unicode point of first character in block */
|
||||
uint32_t start :20;
|
||||
/* Length of block */
|
||||
uint32_t length :12;
|
||||
} *blocks;
|
||||
|
||||
/* Raw glyph data */
|
||||
uint32_t *data;
|
||||
|
||||
union {
|
||||
/* For monospaced fonts */
|
||||
struct {
|
||||
/* Width of glyphs */
|
||||
uint16_t width;
|
||||
/* Storage size, in longwords, of each glyph */
|
||||
uint16_t storage_size;
|
||||
};
|
||||
/* For proportional fonts */
|
||||
struct {
|
||||
/* Storage index to find glyphs quickly */
|
||||
uint16_t *glyph_index;
|
||||
/* Width of each individual glyph */
|
||||
uint8_t *glyph_width;
|
||||
};
|
||||
};
|
||||
|
||||
} VPACKED(4) font_t;
|
||||
|
||||
/* dfont_get() : get the current font */
|
||||
extern font_t *dfont_get(void);
|
||||
|
||||
/* dfont_text_geometry() : get the char geometry */
|
||||
extern int dfont_text_geometry(
|
||||
font_t *font,
|
||||
char const * const str_char,
|
||||
int *size,
|
||||
size_t *w,
|
||||
size_t *h
|
||||
);
|
||||
|
||||
|
||||
//---
|
||||
// Kernel-level API
|
||||
//---
|
||||
|
||||
/* dfont_render() : draw caracter in surface */
|
||||
extern void dfont_text_render(struct dshader_surface *surface, uint32_t *arg);
|
||||
|
||||
#endif /* __VHEX_DISPLAY_FONT__ */
|
|
@ -4,58 +4,6 @@
|
|||
#include <vhex/defs/attributes.h>
|
||||
#include <vhex/defs/types.h>
|
||||
|
||||
/* dshader_call_arg_t: All types of arguments allowed in an indirect shader call
|
||||
|
||||
Because a function call cannot be easily pieced together, there are
|
||||
restrictions on what arguments can be passed. The following union lists all
|
||||
of the available types. Other types can be used if casted, mainly pointers;
|
||||
see the description of DSHADER*() for details. */
|
||||
typedef union dshader_call_arg {
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
|
||||
int16_t i16;
|
||||
uint16_t u16;
|
||||
|
||||
/* 32-bit integers */
|
||||
int i;
|
||||
unsigned int u;
|
||||
int32_t i32;
|
||||
uint32_t u32;
|
||||
/* 32-bit floating-point */
|
||||
float f;
|
||||
|
||||
/* Pointers to most common types, in all possible const/volatile
|
||||
qualifications */
|
||||
#define POINTER(type, name) \
|
||||
type *name; \
|
||||
type const *name ## _c; \
|
||||
type volatile *name ## _v; \
|
||||
type volatile const *name ## _cv;
|
||||
|
||||
POINTER(void, pv)
|
||||
POINTER(char, pc)
|
||||
POINTER(unsigned char, puc)
|
||||
POINTER(short, ps)
|
||||
POINTER(unsigned short, pus)
|
||||
POINTER(int, pi)
|
||||
POINTER(unsigned int, pui)
|
||||
POINTER(int8_t, pi8)
|
||||
POINTER(uint8_t, pu8)
|
||||
POINTER(int16_t, pi16)
|
||||
POINTER(uint16_t, pu16)
|
||||
POINTER(int32_t, pi32)
|
||||
POINTER(uint32_t, pu32)
|
||||
POINTER(int64_t, pi64)
|
||||
POINTER(uint64_t, pu64)
|
||||
POINTER(long long int, pll)
|
||||
POINTER(unsigned long long int, pull)
|
||||
POINTER(float, pf)
|
||||
POINTER(double, pd)
|
||||
|
||||
#undef POINTER
|
||||
} dshader_call_arg_t;
|
||||
|
||||
/* dshader_surface - Describe the surface */
|
||||
struct dshader_surface {
|
||||
void *draw;
|
||||
|
@ -70,10 +18,10 @@ struct dshader_surface {
|
|||
struct dshader_call {
|
||||
int (*routine)(
|
||||
struct dshader_surface *surface,
|
||||
dshader_call_arg_t *draw_args,
|
||||
dshader_call_arg_t *shader_args
|
||||
uint32_t *draw_args,
|
||||
uint32_t *shader_args
|
||||
);
|
||||
dshader_call_arg_t args[8];
|
||||
uint32_t args[8];
|
||||
};
|
||||
typedef struct dshader_call dshader_call_t;
|
||||
typedef struct dshader_call dshader_t;
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
/* dstack_call - dstack indirect call (same as dshader) */
|
||||
struct dstack_call {
|
||||
int (*routine)(
|
||||
void (*routine)(
|
||||
struct dshader_surface *surface,
|
||||
dshader_call_arg_t *draw_args
|
||||
uint32_t *draw_args
|
||||
);
|
||||
dshader_call_arg_t args[12];
|
||||
uint32_t args[12];
|
||||
};
|
||||
typedef struct dstack_call dstack_call_t;
|
||||
|
||||
|
@ -22,13 +22,12 @@ struct dstack_action {
|
|||
int number;
|
||||
int idx;
|
||||
} shader;
|
||||
void (*quit)(uint32_t *arg);
|
||||
};
|
||||
|
||||
/* DSTACK_CALL - display indirect call */
|
||||
#pragma GCC diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#define DSTACK_CALL(fct, ...) (dstack_call_t){ \
|
||||
.routine = (void*)fct, \
|
||||
.routine = fct, \
|
||||
.args = { __VA_ARGS__ } \
|
||||
}
|
||||
|
||||
|
@ -58,6 +57,8 @@ struct dstack_drv_interface {
|
|||
int (*frame_frag_next)(struct dshader_surface *);
|
||||
int (*frame_frag_send)(struct dshader_surface *);
|
||||
int (*frame_end)(struct dshader_surface *);
|
||||
size_t display_width;
|
||||
size_t display_height;
|
||||
};
|
||||
|
||||
//---
|
||||
|
@ -68,7 +69,11 @@ struct dstack_drv_interface {
|
|||
extern int dstack_init(struct dstack_config *config);
|
||||
|
||||
/* dstack_add_action() : add a new action in the draw stack */
|
||||
extern did_t dstack_add_action(dstack_call_t *call, dshader_call_t *shaders);
|
||||
extern did_t dstack_add_action(
|
||||
dstack_call_t *call,
|
||||
dshader_call_t *shaders,
|
||||
void (*quit)(uint32_t *args)
|
||||
);
|
||||
|
||||
/* dstack_get_action() : get display stack action using its ID */
|
||||
extern struct dstack_action *dstack_get_action(did_t did);
|
||||
|
@ -79,9 +84,14 @@ extern void dstack_render(void);
|
|||
/* dstack_invalidate() : Invalidate the draw stack (reset) */
|
||||
extern int dstack_invalidate(void);
|
||||
|
||||
/* dstack_display_width() : return the display width */
|
||||
extern size_t dstack_display_width(void);
|
||||
|
||||
/* dstack_display_height() : return the display height */
|
||||
extern size_t dstack_display_height(void);
|
||||
|
||||
/* dstack_quit() : Uninit the draw stack */
|
||||
extern int dstack_quit(void);
|
||||
|
||||
|
||||
|
||||
#endif /* __VHEX_DISPLAY_STACK__ */
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef __VHEX_DISPLAY_TEXT__
|
||||
# define __VHEX_DISPLAY_TEXT__
|
||||
|
||||
#include <vhex/defs/types.h>
|
||||
#include <vhex/display/types.h>
|
||||
|
||||
/* Alignment settings for dtext_opt() and dprint_opt(). Combining a vertical
|
||||
and a horizontal alignment option specifies where a given point (x,y) should
|
||||
be relative to the rendered string. */
|
||||
enum {
|
||||
/* Horizontal settings: default in dtext() is DTEXT_LEFT */
|
||||
DTEXT_LEFT = 0,
|
||||
DTEXT_CENTER = 1,
|
||||
DTEXT_RIGHT = 2,
|
||||
/* Vertical settings: default in dtext() is DTEXT_TOP */
|
||||
DTEXT_TOP = 0,
|
||||
DTEXT_MIDDLE = 1,
|
||||
DTEXT_BOTTOM = 2,
|
||||
};
|
||||
|
||||
/* dtext_opt(): Display a string of text */
|
||||
extern did_t dtext_opt(
|
||||
int x, int y,
|
||||
int fg, int bg,
|
||||
int halign, int valign,
|
||||
char const * const str, int size
|
||||
);
|
||||
|
||||
/* dtext() : display raw text */
|
||||
extern did_t dtext(int x, int y, int fg, char const * const text);
|
||||
|
||||
/* dprint_opt(): Display a formated string */
|
||||
extern did_t dprint_opt(
|
||||
int x, int y,
|
||||
int fg, int bg,
|
||||
int halign, int valign,
|
||||
char const * const str, ...
|
||||
);
|
||||
|
||||
/* dprint() : display formated text */
|
||||
extern did_t dprint(int x, int y, int fg, char const * const text, ...);
|
||||
|
||||
/* dnsize(): Get the width and height of rendered text for the n first char */
|
||||
extern int dtext_geometry(char const * const str, int *n, size_t *w, size_t *h);
|
||||
|
||||
#endif /* __VHEX_DISPLAY_TEXT__ */
|
|
@ -148,7 +148,9 @@ static struct dstack_drv_interface drv_r61524_dstack = {
|
|||
.frame_start = &r61524_frame_start,
|
||||
.frame_frag_next = &r61524_frame_frag_next,
|
||||
.frame_frag_send = &r61524_frame_frag_send,
|
||||
.frame_end = &r61524_frame_end
|
||||
.frame_end = &r61524_frame_end,
|
||||
.display_width = 396,
|
||||
.display_height = 224
|
||||
};
|
||||
|
||||
struct vhex_driver drv_r61524 = {
|
||||
|
|
|
@ -3,16 +3,13 @@
|
|||
#include <vhex/display/stack.h>
|
||||
|
||||
/* dclear_draw() : real drawing algorithm */
|
||||
static void dclear_draw(
|
||||
struct dshader_surface *surface,
|
||||
dshader_call_arg_t *arg
|
||||
)
|
||||
static void dclear_draw(struct dshader_surface *surface, uint32_t *arg)
|
||||
{
|
||||
uint32_t * restrict vram;
|
||||
uint32_t color;
|
||||
|
||||
vram = surface->frag;
|
||||
color = arg[0].u16 & 0xffff;
|
||||
color = arg[0] & 0xffff;
|
||||
for (int i = 0; i < 2048; ++i)
|
||||
vram[i] = (color << 16) | (color << 0);
|
||||
}
|
||||
|
@ -20,5 +17,5 @@ static void dclear_draw(
|
|||
/* dclear(): Fill the screen with a single color */
|
||||
did_t dclear(int color)
|
||||
{
|
||||
return dstack_add_action(&DSTACK_CALL(&dclear_draw, color), NULL);
|
||||
return dstack_add_action(&DSTACK_CALL(&dclear_draw, color), NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ static struct {
|
|||
.frame_frag_next = NULL,
|
||||
.frame_frag_send = NULL,
|
||||
.frame_end = NULL,
|
||||
.display_width = 0,
|
||||
.display_height = 0
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -77,8 +79,11 @@ int dstack_quit(void)
|
|||
// Internal API
|
||||
//
|
||||
|
||||
static did_t dstack_action_alloc(dstack_call_t *call, dshader_call_t *shader)
|
||||
{
|
||||
static did_t dstack_action_alloc(
|
||||
dstack_call_t *call,
|
||||
dshader_call_t *shader,
|
||||
void (*quit)(uint32_t *arg)
|
||||
) {
|
||||
struct dstack_action *action;
|
||||
int i;
|
||||
|
||||
|
@ -106,20 +111,24 @@ static did_t dstack_action_alloc(dstack_call_t *call, dshader_call_t *shader)
|
|||
&shader[i],
|
||||
sizeof(dshader_call_t)
|
||||
);
|
||||
action->quit = quit;
|
||||
}
|
||||
}
|
||||
action->shader.idx = i;
|
||||
return dstack_info.pool.idx;
|
||||
}
|
||||
|
||||
//
|
||||
//---
|
||||
// Public API
|
||||
//
|
||||
//---
|
||||
|
||||
/* dstack_add_action() : add a new action in the draw stack */
|
||||
did_t dstack_add_action(dstack_call_t *call, dshader_call_t *shader)
|
||||
{
|
||||
return dstack_action_alloc(call, shader);
|
||||
did_t dstack_add_action(
|
||||
dstack_call_t *call,
|
||||
dshader_call_t *shader,
|
||||
void (*quit)(uint32_t *arg)
|
||||
) {
|
||||
return dstack_action_alloc(call, shader, quit);
|
||||
}
|
||||
|
||||
/* dstack_render(): render a frame */
|
||||
|
@ -129,6 +138,7 @@ void dstack_render(void)
|
|||
struct dstack_action *action;
|
||||
|
||||
action = dstack_info.pool.action;
|
||||
|
||||
dstack_info.driver.frame_start(&surface);
|
||||
do {
|
||||
for (int i = 0; i <= dstack_info.pool.idx; ++i) {
|
||||
|
@ -144,5 +154,23 @@ void dstack_render(void)
|
|||
dstack_info.driver.frame_frag_send(&surface);
|
||||
} while (dstack_info.driver.frame_frag_next(&surface) == 0);
|
||||
dstack_info.driver.frame_end(&surface);
|
||||
|
||||
for (int i = 0; i <= dstack_info.pool.idx; ++i) {
|
||||
if (action[i].quit != NULL)
|
||||
action[i].quit(action[i].call.args);
|
||||
}
|
||||
dstack_info.pool.idx = 0;
|
||||
}
|
||||
|
||||
|
||||
/* dstack_display_width() : return the display width */
|
||||
extern size_t dstack_display_width(void)
|
||||
{
|
||||
return dstack_info.driver.display_width;
|
||||
}
|
||||
|
||||
/* dstack_display_height() : return the display height */
|
||||
extern size_t dstack_display_height(void)
|
||||
{
|
||||
return dstack_info.driver.display_height;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
#include <vhex/display/font.h>
|
||||
|
||||
//---
|
||||
// Internal
|
||||
//---
|
||||
|
||||
/* dfont_utf8_next(): Read the next UTF-8 code point of a string */
|
||||
static uint32_t dfont_utf8_next(uint8_t const **str_pointer)
|
||||
{
|
||||
uint8_t const *str = *str_pointer;
|
||||
uint8_t lead = *str++;
|
||||
|
||||
/* Skip non-leaders which are invalid as starting bytes */
|
||||
while((lead >= 0x80 && lead <= 0xbf) ||
|
||||
lead == 0xc0 || lead == 0xc1 || lead == 0xfe || lead == 0xff) {
|
||||
lead = *str++;
|
||||
}
|
||||
|
||||
/* This base case will handle the NUL terminator */
|
||||
if(lead <= 0x7f) {
|
||||
*str_pointer = str;
|
||||
return lead;
|
||||
}
|
||||
|
||||
uint8_t n2 = (*str++ & 0x3f);
|
||||
if(lead <= 0xdf) {
|
||||
*str_pointer = str;
|
||||
return ((lead & 0x1f) << 6) | n2;
|
||||
}
|
||||
|
||||
uint8_t n3 = (*str++ & 0x3f);
|
||||
if(lead <= 0xef) {
|
||||
*str_pointer = str;
|
||||
return ((lead & 0x0f) << 12) | (n2 << 6) | n3;
|
||||
}
|
||||
|
||||
uint8_t n4 = (*str++ & 0x3f);
|
||||
if(lead <= 0xf7) {
|
||||
*str_pointer = str;
|
||||
return ((lead & 0x07) << 18) | (n2 << 12) | (n3 << 6) | n4;
|
||||
}
|
||||
|
||||
/* It the string is too invalid, force a space and try to continue */
|
||||
*str_pointer = str;
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
/* dfont_glyph_index(): Obtain the glyph index of a Unicode code point */
|
||||
int dfont_glyph_index(font_t const *f, uint32_t code_point)
|
||||
{
|
||||
int glyph_start = 0;
|
||||
|
||||
for(int i = 0; i < f->block_count; i++) {
|
||||
int diff = code_point - f->blocks[i].start;
|
||||
if(diff >= 0 && diff < f->blocks[i].length) {
|
||||
return glyph_start + diff;
|
||||
}
|
||||
|
||||
glyph_start += f->blocks[i].length;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//---
|
||||
// Public API
|
||||
//---
|
||||
|
||||
|
||||
/* dfont_get() : get the current font */
|
||||
font_t *dfont_get(void)
|
||||
{
|
||||
extern font_t font8x9;
|
||||
return &font8x9;
|
||||
}
|
||||
|
||||
/* dfont_geometry() : get the char geometry */
|
||||
int dfont_text_geometry(
|
||||
font_t *font,
|
||||
char const * const str_char,
|
||||
int *size,
|
||||
size_t *w,
|
||||
size_t *h
|
||||
) {
|
||||
uint8_t const *str0 = (void *)str_char;
|
||||
uint8_t const *str1 = (void *)str_char;
|
||||
uint32_t code_point;
|
||||
size_t char_width;
|
||||
size_t length = 0;
|
||||
size_t mx = 0;
|
||||
size_t x = 0;
|
||||
size_t y = 0;
|
||||
int limit;
|
||||
int glyph;
|
||||
|
||||
/* handle special behaviour */
|
||||
if (font == NULL)
|
||||
font = dfont_get();
|
||||
limit = -1;
|
||||
if (size != NULL && *size >= 0)
|
||||
limit = *size;
|
||||
|
||||
/* generate geometry information */
|
||||
while (1) {
|
||||
code_point = dfont_utf8_next(&str0);
|
||||
if (code_point == 0 || (limit > 0 && str0 - str1 >= limit))
|
||||
break;
|
||||
|
||||
char_width = font->width;
|
||||
if (font->shape.prop == 1) {
|
||||
glyph = dfont_glyph_index(font, code_point);
|
||||
if (glyph < 0)
|
||||
return (-1);
|
||||
char_width = font->glyph_width[glyph];
|
||||
}
|
||||
|
||||
/* line discipline */
|
||||
x += char_width;
|
||||
if (code_point == '\n') {
|
||||
y += font->data_height;
|
||||
x = 0;
|
||||
}
|
||||
if (x > mx) mx = x;
|
||||
|
||||
length++;
|
||||
}
|
||||
|
||||
/* set geometry information */
|
||||
if (w != NULL) *w = mx;
|
||||
if (h != NULL) *h = y;
|
||||
if (size != NULL) *size = length;
|
||||
return (0);
|
||||
}
|
|
@ -1,51 +1,147 @@
|
|||
#if 0
|
||||
#include "vhex/display.h"
|
||||
#include "vhex/defs/types.h"
|
||||
#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>
|
||||
|
||||
//TODO: dynamic
|
||||
extern struct {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t pixel[];
|
||||
} font8x9;
|
||||
|
||||
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 */
|
||||
void dtext_opt(
|
||||
did_t dtext_opt(
|
||||
int x, int y,
|
||||
int fg, int bg,
|
||||
int halign, int valign,
|
||||
char const *str, int size
|
||||
char const * const str, int size
|
||||
) {
|
||||
int height;
|
||||
int width;
|
||||
size_t width;
|
||||
size_t height;
|
||||
|
||||
if (size < 0)
|
||||
size = 65535;
|
||||
/* 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);
|
||||
}
|
||||
|
||||
dnsize(str, size, &width, &height);
|
||||
/* 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);
|
||||
|
||||
//TODO: line-discipline
|
||||
for (int i = 0; str[i] != '\0' && i < size; ++i) {
|
||||
dascii(x, y, fg, bg, str[i]);
|
||||
x += font8x9.width + 1;
|
||||
}
|
||||
/* 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 */
|
||||
void dtext(int x, int y, int fg, char const * restrict const text)
|
||||
did_t dtext(int x, int y, int fg, char const * const text)
|
||||
{
|
||||
dtext_opt(x, y, fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, text, -1);
|
||||
return (dtext_opt(x, y, fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, text, -1));
|
||||
}
|
||||
|
||||
void dprint(int x, int y, int fg, char const * const text, ...)
|
||||
/* dprint() : display formated string */
|
||||
did_t dprint(int x, int y, int fg, char const * const text, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buff[1024];
|
||||
|
@ -54,6 +150,22 @@ void dprint(int x, int y, int fg, char const * const text, ...)
|
|||
vsnprintf(buff, 1024, text, ap);
|
||||
va_end(ap);
|
||||
|
||||
dtext_opt(x, y, fg, C_NONE, DTEXT_LEFT, DTEXT_TOP, buff, -1);
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue