VxKernel 0.6.0-3 : Fix dstack crash + pixel API + support assets generation
@add <> include/vhex/display/draw/pixel : | add pixel drawing API <> modules/display/draw/dpixel | add pixel drawing API code @update <> board/fxcg50/board : | remove old DWIDTH/DHEIGHT display API dependencies (use the new driver | interface instead). <> include/vhex/display/font : | update the font structure information <> include/vhex/display/shader : | switch x/y to unsigned int to signed int to avoid many cast in render | primitives <> make/Makefile | support header modification detection (header dependencies) | support assets generation <> modules/display/text/font <> modules/display/text/text | prepare drawing algorithm (WIP) @fix <> kernel/drivers/screen/r61524/r61524 | proper handle geometry of each drawing area | fix clear loop boundary | fix render loop boundary <> modules/display/dstack | fix shader index | remove useless extern keyword
This commit is contained in:
parent
510c4f1f86
commit
eb9b0078c2
|
@ -7,5 +7,5 @@ mpu=sh7305
|
|||
|
||||
[toolchain]
|
||||
prefix=sh-elf-vhex-
|
||||
cflags=-DFXCG50,-m4-nofpu,-mb,-DWIDTH=396,-DHEIGHT=224
|
||||
cflags=-DFXCG50,-m4-nofpu,-mb
|
||||
libs=-lgcc
|
||||
|
|
|
@ -100,17 +100,6 @@ SECTIONS
|
|||
|
||||
/* dynamic BSS information (move me ?) */
|
||||
*(.dynbss)
|
||||
|
||||
/* Video RAM symbols
|
||||
The video RAM contains a full pixel sized frame for the
|
||||
screen. Its size is 396x224 and each pixel depth is 16its,
|
||||
so (3996 * 224) * 2 = 177408
|
||||
*/
|
||||
_vhex_vram = ALIGN(4);
|
||||
|
||||
/* create the VRAM gap */
|
||||
. = _vhex_vram + 177408;
|
||||
|
||||
} > userram
|
||||
|
||||
/* Vhex VBR management geometry
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef __VHEX_DISPLAY_DRAW_PIXEL__
|
||||
# define __VHEX_DISPLAY_DRAW_PIXEL__
|
||||
|
||||
#include <vhex/display/types.h>
|
||||
#include <vhex/display/shader.h>
|
||||
|
||||
//---
|
||||
// User-level API
|
||||
//---
|
||||
|
||||
/* dpixel() : draw a pixel in screen */
|
||||
extern did_t dpixel(int x, int y, int color);
|
||||
|
||||
//---
|
||||
// Kernel-level API
|
||||
//---
|
||||
|
||||
/* dpixel_render_dstack() : dstack-API compatible render */
|
||||
extern void dpixel_render_dstack(struct dshader_surface *surface, uint32_t *arg);
|
||||
|
||||
/* dpixel_render() : drawing algorithm */
|
||||
extern void dpixel_render(struct dshader_surface *surface, int x, int y, int c);
|
||||
|
||||
#endif /* __VHEX_DISPLAY_DRAW_PIXEL__ */
|
|
@ -20,45 +20,41 @@ typedef struct font {
|
|||
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;
|
||||
|
||||
/* glyph information */
|
||||
struct {
|
||||
/* Unicode point of first character in block */
|
||||
uint32_t start :20;
|
||||
/* Length of block */
|
||||
uint32_t length :12;
|
||||
} *blocks;
|
||||
uint8_t height;
|
||||
uint8_t line_height;
|
||||
uint32_t *data;
|
||||
uint32_t count;
|
||||
|
||||
/* Raw glyph data */
|
||||
uint32_t *data;
|
||||
union {
|
||||
/* For monospaced fonts */
|
||||
struct {
|
||||
uint8_t width;
|
||||
uint16_t storage_size;
|
||||
} mono;
|
||||
/* For proportional fonts */
|
||||
struct __workaround {
|
||||
uint8_t width;
|
||||
uint16_t index;
|
||||
uint8_t shift;
|
||||
} *prop;
|
||||
};
|
||||
} glyph;
|
||||
|
||||
union {
|
||||
/* For monospaced fonts */
|
||||
/* unicode blocks */
|
||||
struct {
|
||||
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;
|
||||
};
|
||||
};
|
||||
/* Unicode point of first character in block */
|
||||
uint32_t start :20;
|
||||
/* Length of block */
|
||||
uint32_t length :12;
|
||||
} *blocks;
|
||||
uint8_t block_count;
|
||||
} unicode;
|
||||
|
||||
} VPACKED(4) font_t;
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ struct dshader_surface {
|
|||
void *frag;
|
||||
size_t width;
|
||||
size_t height;
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
/* dshader - display shader definition */
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
#!/usr/bin/make -f
|
||||
# ---
|
||||
# Project: vxKernek - Vhex project kernel
|
||||
# Author: yann.magnin@epitech.eu
|
||||
# Author: yann.magnin@protonmail.com
|
||||
#
|
||||
# TODO:
|
||||
# <> support header modification detection
|
||||
# <> remove "target" folder on any directory
|
||||
# <> installation rule
|
||||
# <> uninstall rule
|
||||
# <> proper clean rule
|
||||
# <> support asset generation
|
||||
# ---
|
||||
|
||||
|
||||
|
@ -100,7 +98,8 @@ nocolor := \033[1;0m
|
|||
# *3 - source file path
|
||||
# *4 - build root directory path
|
||||
# *5 - object file compilation rule list
|
||||
# *6 - unique id (used to generate unique variable name (workaround))
|
||||
# *6 - dependencies file compilation rule list
|
||||
# *7 - unique id (used to generate unique variable name (workaround))
|
||||
define generate-compile-file-rule
|
||||
|
||||
# generate the object file path
|
||||
|
@ -110,7 +109,7 @@ define generate-compile-file-rule
|
|||
# 1) ../board/path/file.c -> ../board/path/file
|
||||
# 2) .._board_path_file -> board_path_file
|
||||
# 3) board_path_file.o -> {build path}/board_path_file.o
|
||||
tname := $(strip $6)
|
||||
tname := $(strip $7)
|
||||
obj-$(tname)-name := $$(basename $3)
|
||||
obj-$(tname)-name := $$(subst /,_,$$(obj-$(tname)-name))
|
||||
obj-$(tname)-name := $$(patsubst .._%,$4/%.o,$$(obj-$(tname)-name))
|
||||
|
@ -121,14 +120,15 @@ $$(obj-$(tname)-name): $3
|
|||
@ mkdir -p $$(dir $$@)
|
||||
ifeq ($(CONFIG.VERBOSE),false)
|
||||
@ printf "$(green)>$(nocolor) $(white)$$@$(nocolor)\n"
|
||||
@ $1 $2 -o $$@ -c $$<
|
||||
@ $1 $2 -o $$@ -c $$< -MMD -MT $$@ -MF $$@.d -MP
|
||||
else
|
||||
$1 $2 -o $$@ -c $$<
|
||||
$1 $2 -o $$@ -c $$< -MMD -MT $$@ -MF $$@.d -MP
|
||||
endif
|
||||
|
||||
# register the buildinf rule
|
||||
# register the build rules and dependencies file name
|
||||
|
||||
$5 += $$(obj-$(tname)-name)
|
||||
$6 += $$(obj-$(tname)-name).d
|
||||
|
||||
endef
|
||||
|
||||
|
@ -190,6 +190,7 @@ endif
|
|||
# list variable, this will be used by the `main` rule
|
||||
|
||||
t-$1-$2-obj :=
|
||||
t-$1-$2-dep :=
|
||||
$$(foreach source,$$(t-$1-$2-src),$$(eval \
|
||||
$$(call generate-compile-file-rule,\
|
||||
$$(t-$1-$2-gcc),\
|
||||
|
@ -197,15 +198,33 @@ $$(foreach source,$$(t-$1-$2-src),$$(eval \
|
|||
$$(source),\
|
||||
$$(t-$1-$2-build),\
|
||||
t-$1-$2-obj,\
|
||||
t-$1-$2-dep,\
|
||||
$1-$2\
|
||||
))\
|
||||
)
|
||||
|
||||
# asset generation
|
||||
t-$1-$2-asset := $(patsubst \
|
||||
$(VXSDK_ASSETS_SRC)/%,\
|
||||
$(VXSDK_ASSETS_BUILD)/$1/$2/%.o,\
|
||||
$(wildcard $(VXSDK_ASSETS_SRC)/*.c) \
|
||||
)
|
||||
|
||||
$(VXSDK_ASSETS_BUILD)/$1/$2/%.o: $(VXSDK_ASSETS_SRC)/%
|
||||
ifeq ($(CONFIG.VERBOSE),true)
|
||||
@ mkdir -p $$(dir $$@)
|
||||
sh-elf-vhex-gcc $$(t-$1-$2-cflags) -o $$@ -c $$<
|
||||
else
|
||||
@ mkdir -p $$(dir $$@)
|
||||
@ printf "$(green)>$(nocolor) $(white)$@$(nocolor)\n"
|
||||
@ sh-elf-vhex-gcc $$(t-$1-$2-cflags) -o $$@ -c $$<
|
||||
endif
|
||||
|
||||
# generate the "main" rule for this lib
|
||||
|
||||
$$(t-$1-$2-exec): $$(t-$1-$2-obj)
|
||||
$$(t-$1-$2-exec): $$(t-$1-$2-obj) $$(t-$1-$2-asset)
|
||||
@ mkdir -p $$(dir $$@)
|
||||
@ echo "dep : $$(t-$1-$2-dep)"
|
||||
@ printf "$(blue)Create the library $(red)$$@$(nocolor)\n"
|
||||
ifeq ($2,dynamic)
|
||||
$$(t-$1-$2-gcc) -shared $$(t-$1-$2-cflags) $$(t-$1-$2-gcc-libs) -o $$@ $$^
|
||||
|
@ -217,6 +236,12 @@ endif
|
|||
|
||||
$3 += $$(t-$1-$2-exec)
|
||||
|
||||
|
||||
# import dependencies rules
|
||||
-include $$(t-$1-$2-dep)
|
||||
$$(t-$1-$2-dep): ;
|
||||
.PRECIOUS: $$(t-$1-$2-dep)
|
||||
|
||||
endef
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ VINLINE void r61524_clear_surface(struct dshader_surface *surface)
|
|||
// > restrict / non-restrict
|
||||
uint32_t * restrict xram = surface->draw;
|
||||
uint32_t * restrict yram = surface->frag;
|
||||
for (int i = 0; i < 2048; ++i) {
|
||||
for (int i = 0; i < 1980; ++i) {
|
||||
xram[i] = 0x00010001;
|
||||
yram[i] = 0x00000000;
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ int r61524_frame_start(struct dshader_surface *surface)
|
|||
|
||||
int r61524_frame_frag_next(struct dshader_surface *surface)
|
||||
{
|
||||
//TODO: perf if culling at the end (220)
|
||||
surface->y += 10;
|
||||
if (surface->y >= 224) {
|
||||
surface->y -= 10;
|
||||
|
@ -71,6 +72,8 @@ int r61524_frame_frag_next(struct dshader_surface *surface)
|
|||
|
||||
int r61524_frame_frag_send(struct dshader_surface *surface)
|
||||
{
|
||||
//static int counter = 0;
|
||||
|
||||
//TODO: assembly
|
||||
//TODO: check cache behaviour:
|
||||
// > full xram then yram
|
||||
|
@ -80,7 +83,7 @@ int r61524_frame_frag_send(struct dshader_surface *surface)
|
|||
uint16_t pixel;
|
||||
uint16_t * restrict xram = surface->draw;
|
||||
uint16_t * restrict yram = surface->frag;
|
||||
for (int i = 0; i < 4096; ++i) {
|
||||
for (int i = 0; i < 3960; ++i) {
|
||||
pixel = xram[i];
|
||||
if (pixel & 0x0001) {
|
||||
r61524_write(yram[i]);
|
||||
|
|
|
@ -52,6 +52,5 @@ void vhex_kernel_exch_panic(void)
|
|||
dtext(6, 121, C_BLACK, "calculator.");
|
||||
dupdate();
|
||||
#endif
|
||||
|
||||
while (1) { __asm__ volatile ("sleep"); }
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#if 0
|
||||
#include <vhex/display.h>
|
||||
#include <vhex/defs/utils.h>
|
||||
#include <vhex/defs/types.h>
|
||||
|
@ -48,4 +49,4 @@ void dvline(int y1, int y2, int x, int color)
|
|||
|
||||
while(height-- > 0) *v = color, v += 396;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#if 0
|
||||
#include <vhex/display.h>
|
||||
#include <vhex/defs/utils.h>
|
||||
|
||||
|
@ -59,3 +60,4 @@ void dline(int x1, int y1, int x2, int y2, int color)
|
|||
|
||||
dpixel(x2, y2, color);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,19 +2,56 @@
|
|||
#include <vhex/defs/attributes.h>
|
||||
#include <vhex/defs/types.h>
|
||||
|
||||
//---
|
||||
// Kernel-level API
|
||||
//---
|
||||
|
||||
VWEAK void dpixel(int x, int y, int color)
|
||||
/* dpixel_render() : drawing algorithm */
|
||||
void dpixel_render(struct dshader_surface *surface, int x, int y, int color)
|
||||
{
|
||||
extern uint16_t vhex_vram[];
|
||||
|
||||
if (color == C_NONE)
|
||||
return;
|
||||
if ((unsigned int)x < 396 && (unsigned int)y < 224) {
|
||||
if (color == C_INVERT) {
|
||||
vhex_vram[(y * 396) + x] ^= 0xffff;
|
||||
return;
|
||||
}
|
||||
vhex_vram[(y * 396) + x] = color;
|
||||
|
||||
/* check point culling */
|
||||
if (y < surface->y
|
||||
|| x < surface->x
|
||||
|| y >= (int)(surface->y + surface->height)
|
||||
|| x >= (int)(surface->x + surface->width)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* calculate the draw index */
|
||||
int real_y = (y - surface->y) * surface->width;
|
||||
int real_x = (x - surface->x);
|
||||
int draw_idx = real_y + real_x;
|
||||
|
||||
/* handle special color */
|
||||
//uint16_t *draw = surface->draw;
|
||||
uint16_t *frag = surface->frag;
|
||||
if (color == C_INVERT)
|
||||
color = frag[draw_idx] ^ 0xffff;
|
||||
|
||||
/* set the pixel */
|
||||
frag[draw_idx] = color;
|
||||
}
|
||||
|
||||
/* dpixel_render_dstack() : dstack-API compatible render */
|
||||
void dpixel_render_dstack(struct dshader_surface *surface, uint32_t *arg)
|
||||
{
|
||||
dpixel_render(surface, arg[0], arg[1], arg[2]);
|
||||
}
|
||||
|
||||
//---
|
||||
// User-level API
|
||||
//---
|
||||
|
||||
/* dpixel() : draw a pixel in screen */
|
||||
did_t dpixel(int x, int y, int color)
|
||||
{
|
||||
return dstack_add_action(
|
||||
&DSTACK_CALL(&dpixel_render_dstack, x, y, color),
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#if 0
|
||||
#include <vhex/display.h>
|
||||
#include <vhex/defs/utils.h>
|
||||
#include <vhex/defs/types.h>
|
||||
|
@ -51,3 +52,4 @@ void drect(int x1, int y1, int x2, int y2, int color)
|
|||
base += 396;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -97,6 +97,7 @@ static did_t dstack_action_alloc(
|
|||
}
|
||||
action = &dstack_info.pool.action[dstack_info.pool.idx];
|
||||
memcpy(&action->call, call, sizeof(dstack_call_t));
|
||||
action->shader.idx = -1;
|
||||
if (shader != NULL) {
|
||||
for (i = 0; shader[i].routine != NULL; ++i) {
|
||||
if (i >= action->shader.number) {
|
||||
|
@ -113,8 +114,8 @@ static did_t dstack_action_alloc(
|
|||
);
|
||||
action->quit = quit;
|
||||
}
|
||||
action->shader.idx = i;
|
||||
}
|
||||
action->shader.idx = i;
|
||||
return dstack_info.pool.idx;
|
||||
}
|
||||
|
||||
|
@ -143,7 +144,7 @@ void dstack_render(void)
|
|||
do {
|
||||
for (int i = 0; i <= dstack_info.pool.idx; ++i) {
|
||||
action[i].call.routine(&surface, action[i].call.args);
|
||||
for (int j = 0; j < action[i].shader.idx; j++) {
|
||||
for (int j = 0; j <= action[i].shader.idx; j++) {
|
||||
action[i].shader.table[j].routine(
|
||||
&surface,
|
||||
action[i].call.args,
|
||||
|
@ -164,13 +165,13 @@ void dstack_render(void)
|
|||
|
||||
|
||||
/* dstack_display_width() : return the display width */
|
||||
extern size_t dstack_display_width(void)
|
||||
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)
|
||||
size_t dstack_display_height(void)
|
||||
{
|
||||
return dstack_info.driver.display_height;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ static uint32_t dfont_utf8_next(uint8_t const **str_pointer)
|
|||
return 0x20;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* dfont_glyph_index(): Obtain the glyph index of a Unicode code point */
|
||||
int dfont_glyph_index(font_t const *f, uint32_t code_point)
|
||||
{
|
||||
|
@ -61,7 +62,152 @@ int dfont_glyph_index(font_t const *f, uint32_t code_point)
|
|||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* dfont_glyph_index(): Obtain the glyph index of a Unicode code point */
|
||||
//TODO: suport unicode block
|
||||
static int dfont_glyph_index(font_t const *f, uint32_t code_point)
|
||||
{
|
||||
code_point -= ' ';
|
||||
if ((int)code_point < 0 || code_point >= f->glyph.count)
|
||||
return (-1);
|
||||
return code_point;
|
||||
}
|
||||
|
||||
/* dfont_char_render() : */
|
||||
static void dfont_char_render(
|
||||
struct dshader_surface *surface,
|
||||
int glyph_idx,
|
||||
int x,
|
||||
int y
|
||||
) {
|
||||
int glyph_shift;
|
||||
int glyph_width;
|
||||
int glyph_size;
|
||||
// int surfa_idx;
|
||||
// int surfa_shift;
|
||||
font_t *font;
|
||||
int counter;
|
||||
int sx;
|
||||
|
||||
(void)surface;
|
||||
|
||||
/* generate font index / shift information */
|
||||
font = dfont_get();
|
||||
if (font->shape.prop == 1) {
|
||||
glyph_width = font->glyph.prop[glyph_idx].width;
|
||||
glyph_shift = font->glyph.prop[glyph_idx].shift;
|
||||
glyph_idx = font->glyph.prop[glyph_idx].index;
|
||||
glyph_size = glyph_width * font->glyph.height;
|
||||
} else {
|
||||
glyph_width = font->glyph.mono.width;
|
||||
glyph_size = font->glyph.mono.storage_size;
|
||||
glyph_shift = glyph_size * glyph_idx;
|
||||
glyph_idx = glyph_shift >> 8;
|
||||
glyph_shift = glyph_shift & 0xff;
|
||||
}
|
||||
|
||||
/* drawing algo */
|
||||
//TODO: cache surface data (limit read/write)
|
||||
sx = x;
|
||||
counter = 0;
|
||||
glyph_shift = 0x80000000 >> glyph_shift;
|
||||
for (int i = 0; i < glyph_size; ++i)
|
||||
{
|
||||
#if 0
|
||||
if (x >= surface->x
|
||||
&& x <= surfa_mx
|
||||
&& y >= surface->y
|
||||
&& y <= surfa_my) {
|
||||
tmp0 = (y - surface->y) * 396;
|
||||
tmp1 = (x - surface->x);
|
||||
surfa_idx = (tmp0 + tmp1) >> 2;
|
||||
surfa_shift = (tmp0 + tmp1) & 0xff;
|
||||
if (font->glyph.data[glyph_idx] & glyph_shift) {
|
||||
surface->frag[surfa_idx] = (uint16_t)arg[4];
|
||||
} else {
|
||||
surface->frag[surfa_idx] = (uint16_t)arg[5];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* update font bitmap index / shift */
|
||||
glyph_shift >>= 1;
|
||||
if (glyph_shift == 0x00000000) {
|
||||
glyph_shift = 0x80000000;
|
||||
glyph_idx += 1;
|
||||
}
|
||||
|
||||
/* update bitmap position */
|
||||
x += 1;
|
||||
counter += 1;
|
||||
if (counter >= glyph_width) {
|
||||
counter = 0;
|
||||
x = sx;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---
|
||||
// Kernel API
|
||||
//---
|
||||
|
||||
|
||||
/* dfont_render() : draw caracter in surface */
|
||||
void dfont_text_render(struct dshader_surface *surface, uint32_t *arg)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int mx;
|
||||
int my;
|
||||
|
||||
/* check culling */
|
||||
x = arg[0];
|
||||
y = arg[1];
|
||||
mx = arg[2];
|
||||
my = arg[3];
|
||||
if (my < surface->y
|
||||
|| mx < surface->x
|
||||
|| y > (int)(surface->y + surface->height)
|
||||
|| x > (int)(surface->x + surface->width)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t const *str = (void*)(uintptr_t)arg[6];
|
||||
int nb_char = arg[7];
|
||||
int counter = -1;
|
||||
uint32_t code_point;
|
||||
font_t *font = dfont_get();
|
||||
int glyph_idx;
|
||||
int glyph_width;
|
||||
|
||||
/* draw algo (update me) */
|
||||
while (++counter < nb_char)
|
||||
{
|
||||
/* get glyph geometry information */
|
||||
code_point = dfont_utf8_next(&str);
|
||||
glyph_idx = dfont_glyph_index(font, code_point);
|
||||
glyph_width = font->glyph.mono.width;
|
||||
if (font->shape.prop == 1)
|
||||
glyph_width = font->glyph.prop[glyph_idx].width;
|
||||
|
||||
/* check char culling */
|
||||
if (x >= surface->x
|
||||
&& y >= surface->y
|
||||
&& y < (int)(surface->y + surface->height)
|
||||
&& x < (int)(surface->x + surface->width)) {
|
||||
dfont_char_render(surface, glyph_idx, x, y);
|
||||
}
|
||||
|
||||
/* line discipline */
|
||||
x += glyph_width + font->char_spacing;
|
||||
if (code_point == '\n') {
|
||||
y += font->glyph.height;
|
||||
x = arg[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---
|
||||
// Public API
|
||||
|
@ -91,8 +237,8 @@ int dfont_text_geometry(
|
|||
size_t mx = 0;
|
||||
size_t x = 0;
|
||||
size_t y = 0;
|
||||
int glyphidx;
|
||||
int limit;
|
||||
int glyph;
|
||||
|
||||
/* handle special behaviour */
|
||||
if (font == NULL)
|
||||
|
@ -107,18 +253,18 @@ int dfont_text_geometry(
|
|||
if (code_point == 0 || (limit > 0 && str0 - str1 >= limit))
|
||||
break;
|
||||
|
||||
char_width = font->width;
|
||||
char_width = font->glyph.mono.width;
|
||||
if (font->shape.prop == 1) {
|
||||
glyph = dfont_glyph_index(font, code_point);
|
||||
if (glyph < 0)
|
||||
glyphidx = dfont_glyph_index(font, code_point);
|
||||
if (glyphidx < 0)
|
||||
return (-1);
|
||||
char_width = font->glyph_width[glyph];
|
||||
char_width = font->glyph.prop[glyphidx].width;
|
||||
}
|
||||
|
||||
/* line discipline */
|
||||
x += char_width;
|
||||
x += char_width + font->char_spacing;
|
||||
if (code_point == '\n') {
|
||||
y += font->data_height;
|
||||
y += font->glyph.height;
|
||||
x = 0;
|
||||
}
|
||||
if (x > mx) mx = x;
|
||||
|
@ -127,7 +273,7 @@ int dfont_text_geometry(
|
|||
}
|
||||
|
||||
/* set geometry information */
|
||||
if (w != NULL) *w = mx;
|
||||
if (w != NULL) *w = mx - font->char_spacing;
|
||||
if (h != NULL) *h = y;
|
||||
if (size != NULL) *size = length;
|
||||
return (0);
|
||||
|
|
|
@ -9,27 +9,21 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.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;
|
||||
struct {
|
||||
char *raw;
|
||||
size_t size;
|
||||
} *text;
|
||||
int number;
|
||||
int idx;
|
||||
} pool;
|
||||
} dtext_info = {
|
||||
.pool = {
|
||||
.geometry = NULL,
|
||||
.text = NULL,
|
||||
.number = 0,
|
||||
.idx = 0
|
||||
}
|
||||
|
@ -43,22 +37,21 @@ VCONSTRUCTOR static void __dtext_constructor(void)
|
|||
{
|
||||
dtext_info.pool.number = 16;
|
||||
dtext_info.pool.idx = -1;
|
||||
dtext_info.pool.geometry = calloc(
|
||||
dtext_info.pool.text = calloc(
|
||||
dtext_info.pool.number,
|
||||
sizeof(struct dtext_geometry)
|
||||
sizeof (*dtext_info.pool.text)
|
||||
);
|
||||
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;
|
||||
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.geometry[i].text.raw);
|
||||
free(dtext_info.pool.geometry);
|
||||
free(dtext_info.pool.text[i].raw);
|
||||
free(dtext_info.pool.text);
|
||||
}
|
||||
|
||||
static void __dtext_quit(void)
|
||||
|
@ -67,29 +60,22 @@ static void __dtext_quit(void)
|
|||
}
|
||||
|
||||
//---
|
||||
// Drawing functions
|
||||
// Private functions
|
||||
//---
|
||||
|
||||
#if 0
|
||||
static void dtext_opt_draw(struct dshader_surface *surface, uint32_t *arg)
|
||||
static char *dtext_info_register(char const * const str)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//---
|
||||
// Public API
|
||||
|
@ -104,6 +90,7 @@ did_t dtext_opt(
|
|||
) {
|
||||
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)
|
||||
|
@ -121,13 +108,16 @@ did_t dtext_opt(
|
|||
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, y, x + width, y + height,
|
||||
fg, bg,
|
||||
(uint32_t)(uintptr_t)str, size
|
||||
(uint32_t)(uintptr_t)real_str, size,
|
||||
),
|
||||
(dtext_info.pool.idx == 0) ? (void*)&__dtext_quit : NULL,
|
||||
NULL
|
||||
|
|
Loading…
Reference in New Issue