ref: 0a7518ec993f6d98d10df849cf160434f7a56b8f
dir: /demo/renderer_plan9.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include "common.h"
#include "atlas.inl"
enum
{
Maxcolors = 64,
};
static u32int rgba[Maxcolors];
static u16int lastused[Maxcolors];
static Image *colors[Maxcolors];
static int numcolors = 0;
static u16int frame = 0;
static Image *atlasimage;
static Image *
getcolor(mu_Color color)
{
u32int c;
int i;
u16int diff, leasti;
diff = 0;
leasti = 0;
c = color.r<<24 | color.g<<16 | color.b<<8 | color.a;
if (c == DBlack)
return display->black;
if (c == DWhite)
return display->white;
for (i = 0; i < numcolors; i++) {
if (rgba[i] == c) {
lastused[i] = frame;
return colors[i];
}
if (diff < frame - lastused[i]) {
diff = frame - lastused[i];
leasti = i;
}
}
if (i >= nelem(colors)) {
freeimage(colors[leasti]);
rgba[leasti] = c;
colors[leasti] = allocimage(display, (Rectangle){ZP, (Point){1, 1}}, RGBA32, 1, c);
lastused[leasti] = frame;
return colors[leasti];
}
rgba[numcolors] = c;
colors[numcolors] = allocimage(display, (Rectangle){ZP, (Point){1, 1}}, RGBA32, 1, c);
return colors[numcolors++];
}
static Rectangle
screenrect(mu_Rect rect)
{
Rectangle r;
r.min = screen->r.min;
r.min.x += rect.x;
r.min.y += rect.y;
r.max = r.min;
r.max.x += rect.w;
r.max.y += rect.h;
return r;
}
void
r_init(void)
{
u8int *b;
Rectangle r = {ZP, (Point){ATLAS_WIDTH, ATLAS_HEIGHT}};
int i;
b = malloc(sizeof(atlas_texture)*4);
for (i = 0; i < sizeof(atlas_texture); i++) {
b[i*4+0] = atlas_texture[i];
b[i*4+1] = atlas_texture[i];
b[i*4+2] = atlas_texture[i];
b[i*4+3] = atlas_texture[i];
}
atlasimage = allocimage(display, r, RGBA32, 1, DWhite);
if (loadimage(atlasimage, r, b, sizeof(atlas_texture)*4) < 0)
sysfatal("failed to load atlas");
}
void
r_draw_rect(mu_Rect rect, mu_Color color)
{
draw(screen, screenrect(rect), getcolor(color), nil, ZP);
}
void
r_draw_text(mu_Font font, const char *text, mu_Vec2 pos, mu_Color color) {
Point p;
p = screen->r.min;
p.x += pos.x;
p.y += pos.y;
string(screen, p, getcolor(color), ZP, font, text);
}
void
r_draw_icon(int id, mu_Rect rect, mu_Color color)
{
Rectangle r;
USED(color); /* FIXME no colors */
rect.x += (rect.w - atlas[id].w) / 2;
rect.y += (rect.h - atlas[id].h) / 2;
rect.w = atlas[id].w;
rect.h = atlas[id].h;
r = screenrect(rect);
draw(screen, r, atlasimage, nil, (Point){atlas[id].x, atlas[id].y});
}
int
r_get_text_width(mu_Font font, const char *text, int len)
{
if (len < 0)
len = strlen(text);
return stringnwidth(font, text, len);
}
int
r_get_text_height(mu_Font font)
{
return ((Font*)font)->height;
}
void
r_set_clip_rect(mu_Rect rect)
{
replclipr(screen, 0, screenrect(rect));
}
void
r_clear(mu_Color color)
{
draw(screen, screen->r, getcolor(color), nil, ZP);
}
void
r_present(void)
{
flushimage(display, 1);
frame++;
}