ref: abebab3746b86e330baed2e96b62f018da3a680c
dir: /cfg/nk.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
static char *
dtoa(char *s, double n)
{
sprint(s, "%g", n);
return s;
}
#define NK_IMPLEMENTATION
#include "nk.h"
static ulong rgba[32];
static Image *colors[32];
static int numcolors = 0;
static void *oldcmds = nil;
static int oldcmdslen = 0, oldcmdsmax = 0;
static void*
nk_alloc_p9(nk_handle handle, void *old, nk_size size)
{
USED(handle);
return realloc(old, size);
}
static void
nk_free_p9(nk_handle handle, void *old)
{
USED(handle);
free(old);
}
static float
nk_text_width_p9(nk_handle handle, float height, const char *text, int len)
{
USED(height);
return stringnwidth(handle.ptr, text, len);
}
static struct nk_allocator nkallocp9 = {
.alloc = nk_alloc_p9,
.free = nk_free_p9,
};
static struct nk_user_font nkfontp9 = {
.width = nk_text_width_p9,
};
int
nk_init_p9(struct nk_context *ctx)
{
nkfontp9.userdata.ptr = display->defaultfont;
nkfontp9.height = display->defaultfont->height;
return nk_init(ctx, &nkallocp9, &nkfontp9);
}
static Image *
nk_color_p9(struct nk_color c)
{
ulong x;
int i;
x = c.r<<24 | c.g<<16 | c.b<<8 | c.a;
for (i = 0; i < numcolors; i++) {
if (rgba[i] == x)
return colors[i];
}
if (i >= nelem(colors))
return display->black;
rgba[numcolors] = x;
colors[numcolors] = allocimagemix(display, x, x);
return colors[numcolors++];
}
#define THICK(x) ((x)/2-1)
void
nk_redraw_p9(struct nk_context *ctx, Image *screen)
{
Point p, sp;
Rectangle rect;
const struct nk_command *cmd;
void *cmds;
/* check if there is anything changed, return if nothing */
cmds = nk_buffer_memory(&ctx->memory);
if (ctx->memory.allocated == oldcmdslen && memcmp(oldcmds, cmds, oldcmdslen) == 0)
return;
if (ctx->memory.allocated > oldcmdsmax) {
oldcmdsmax = ctx->memory.allocated;
oldcmds = realloc(oldcmds, oldcmdsmax);
}
oldcmdslen = ctx->memory.allocated;
memmove(oldcmds, cmds, oldcmdslen);
rect.min = screen->r.min;
p = rect.min;
sp = p;
nk_foreach(cmd, ctx) {
switch (cmd->type) {
case NK_COMMAND_NOP:
break;
case NK_COMMAND_SCISSOR:
{
const struct nk_command_scissor *s = (void*)cmd;
rect.min.x += s->x;
rect.min.y += s->y;
rect.max = rect.min;
rect.max.x += s->w;
rect.max.y += s->h;
replclipr(screen, 0, rect);
}
break;
case NK_COMMAND_LINE:
{
const struct nk_command_line *l = (void*)cmd;
p.x += l->begin.x;
p.y += l->begin.y;
sp.x += l->end.x;
sp.y += l->end.y;
line(screen, p, sp, Endsquare, Endsquare, THICK(l->line_thickness), nk_color_p9(l->color), ZP);
}
break;
case NK_COMMAND_CURVE:
fprint(2, "NK_COMMAND_CURVE\n");
break;
case NK_COMMAND_RECT:
{
const struct nk_command_rect *r = (void*)cmd;
rect.min.x += r->x;
rect.min.y += r->y;
rect.max = rect.min;
rect.max.x += r->w;
rect.max.y += r->h;
border(screen, rect, THICK(r->line_thickness), nk_color_p9(r->color), ZP);
}
break;
case NK_COMMAND_RECT_FILLED:
{
const struct nk_command_rect_filled *r = (void*)cmd;
rect.min.x += r->x;
rect.min.y += r->y;
rect.max = rect.min;
rect.max.x += r->w;
rect.max.y += r->h;
draw(screen, rect, nk_color_p9(r->color), nil, ZP);
}
break;
case NK_COMMAND_RECT_MULTI_COLOR:
fprint(2, "NK_COMMAND_RECT_MULTI_COLOR\n");
break;
case NK_COMMAND_CIRCLE:
{
const struct nk_command_circle *c = (void*)cmd;
p.x += c->x + c->w/4;
p.y += c->y - c->h/4;
ellipse(screen, p, c->w/2, c->h/2, THICK(c->line_thickness), nk_color_p9(c->color), ZP);
}
break;
case NK_COMMAND_CIRCLE_FILLED:
{
const struct nk_command_circle_filled *c = (void*)cmd;
p.x += c->x + c->w/4;
p.y += c->y - c->h/4;
fillellipse(screen, p, c->w/2, c->h/2, nk_color_p9(c->color), ZP);
}
break;
case NK_COMMAND_ARC:
fprint(2, "NK_COMMAND_ARC\n");
break;
case NK_COMMAND_ARC_FILLED:
fprint(2, "NK_COMMAND_ARC_FILLED\n");
break;
case NK_COMMAND_TRIANGLE:
fprint(2, "NK_COMMAND_TRIANGLE\n");
break;
case NK_COMMAND_TRIANGLE_FILLED:
fprint(2, "NK_COMMAND_TRIANGLE_FILLED\n");
break;
case NK_COMMAND_POLYGON:
fprint(2, "NK_COMMAND_POLYGON\n");
break;
case NK_COMMAND_POLYGON_FILLED:
fprint(2, "NK_COMMAND_POLYGON_FILLED\n");
break;
case NK_COMMAND_POLYLINE:
fprint(2, "NK_COMMAND_POLYLINE\n");
break;
case NK_COMMAND_TEXT:
{
const struct nk_command_text *t = (void*)cmd;
p.x += t->x;
p.y += t->y;
sp = p;
sp.x += t->w;
sp.y += t->h;
stringn(screen, p, nk_color_p9(t->foreground), sp, nkfontp9.userdata.ptr, t->string, t->length);
}
break;
case NK_COMMAND_IMAGE:
fprint(2, "NK_COMMAND_IMAGE\n");
break;
case NK_COMMAND_CUSTOM:
fprint(2, "NK_COMMAND_CUSTOM\n");
break;
}
}
flushimage(display, 1);
}