ref: b53399a1815178d6a221f580be4e5bce9614474d
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++; }