shithub: microui

ref: 05178ae202fb620c3397fe8db5578186edec1d59
dir: /demo/renderer_plan9.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include "common.h"
#include "atlas_p9.h"

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 = setalpha(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, Rect(0, 0, 1, 1), RGBA32, 1, c);
		lastused[leasti] = frame;
		return colors[leasti];
	}

	rgba[numcolors] = c;
	colors[numcolors] = allocimage(display, Rect(0, 0, 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)
{
	Rectangle r = Rect(0, 0, atlas[ATLAS_DIMENSIONS].w, atlas[ATLAS_DIMENSIONS].h);
	int res;

	atlasimage = allocimage(display, r, RGBA32, 1, DTransparent);
	if (memcmp(atlas_texture, "compressed\n", 11) == 0)
		res = cloadimage(atlasimage, r, atlas_texture+11+5*12, sizeof(atlas_texture)-11-5*12);
	else
		res = loadimage(atlasimage, r, atlas_texture, sizeof(atlas_texture));
	if (res < 0)
		sysfatal("failed to load atlas: %r");
}

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) {
	string(screen, addpt(screen->r.min, Pt(pos.x, pos.y)), 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, Pt(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++;
}