mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
203 lines
4.2 KiB
C
203 lines
4.2 KiB
C
|
#include "stdinc.h"
|
||
|
#include "dat.h"
|
||
|
#include "fns.h"
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
Top = 1,
|
||
|
Bottom = 1,
|
||
|
Left = 40,
|
||
|
Right = 0,
|
||
|
MinWidth = Left+Right+2,
|
||
|
MinHeight = Top+Bottom+2,
|
||
|
DefaultWidth = Left+Right+500,
|
||
|
DefaultHeight = Top+Bottom+40
|
||
|
};
|
||
|
|
||
|
QLock memdrawlock;
|
||
|
static Memsubfont *smallfont;
|
||
|
static Memimage *black;
|
||
|
static Memimage *blue;
|
||
|
static Memimage *red;
|
||
|
static Memimage *lofill[6];
|
||
|
static Memimage *hifill[6];
|
||
|
static Memimage *grid;
|
||
|
|
||
|
static ulong fill[] = {
|
||
|
0xFFAAAAFF, 0xBB5D5DFF, /* peach */
|
||
|
DPalegreygreen, DPurpleblue, /* aqua */
|
||
|
DDarkyellow, DYellowgreen, /* yellow */
|
||
|
DMedgreen, DDarkgreen, /* green */
|
||
|
0x00AAFFFF, 0x0088CCFF, /* blue */
|
||
|
0xCCCCCCFF, 0x888888FF, /* grey */
|
||
|
};
|
||
|
|
||
|
Memimage*
|
||
|
allocrepl(ulong color)
|
||
|
{
|
||
|
Memimage *m;
|
||
|
|
||
|
m = allocmemimage(Rect(0,0,1,1), RGB24);
|
||
|
memfillcolor(m, color);
|
||
|
m->flags |= Frepl;
|
||
|
m->clipr = Rect(-1000000, -1000000, 1000000, 1000000);
|
||
|
return m;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
ginit(void)
|
||
|
{
|
||
|
static int first = 1;
|
||
|
int i;
|
||
|
|
||
|
if(!first)
|
||
|
return;
|
||
|
|
||
|
first = 0;
|
||
|
memimageinit();
|
||
|
smallfont = openmemsubfont(unsharp("#9/font/lucidasans/lstr.10"));
|
||
|
black = memblack;
|
||
|
blue = allocrepl(DBlue);
|
||
|
red = allocrepl(DRed);
|
||
|
grid = allocrepl(0x77777777);
|
||
|
for(i=0; i<nelem(fill)/2 && i<nelem(lofill) && i<nelem(hifill); i++){
|
||
|
lofill[i] = allocrepl(fill[2*i]);
|
||
|
hifill[i] = allocrepl(fill[2*i+1]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
mklabel(char *str, int v)
|
||
|
{
|
||
|
if(v < 0){
|
||
|
v = -v;
|
||
|
*str++ = '-';
|
||
|
}
|
||
|
if(v < 10000)
|
||
|
sprint(str, "%d", v);
|
||
|
else if(v < 10000000)
|
||
|
sprint(str, "%dk", v/1000);
|
||
|
else
|
||
|
sprint(str, "%dM", v/1000000);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
drawlabel(Memimage *m, Point p, int n)
|
||
|
{
|
||
|
char buf[30];
|
||
|
Point w;
|
||
|
|
||
|
mklabel(buf, n);
|
||
|
w = memsubfontwidth(smallfont, buf);
|
||
|
memimagestring(m, Pt(p.x-5-w.x, p.y), memblack, ZP, smallfont, buf);
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
scalept(int val, int valmin, int valmax, int ptmin, int ptmax)
|
||
|
{
|
||
|
if(val <= valmin)
|
||
|
val = valmin;
|
||
|
if(val >= valmax)
|
||
|
val = valmax;
|
||
|
if(valmax == valmin)
|
||
|
valmax++;
|
||
|
return ptmin + (vlong)(val-valmin)*(ptmax-ptmin)/(valmax-valmin);
|
||
|
}
|
||
|
|
||
|
Memimage*
|
||
|
statgraph(Graph *g)
|
||
|
{
|
||
|
int i, lastlo, nbin, x, lo, hi, min, max, first;
|
||
|
Memimage *m;
|
||
|
Rectangle r;
|
||
|
Statbin *b, bin[2000]; /* 32 kB, but whack is worse */
|
||
|
|
||
|
needstack(8192); /* double check that bin didn't kill us */
|
||
|
|
||
|
if(g->wid <= MinWidth)
|
||
|
g->wid = DefaultWidth;
|
||
|
if(g->ht <= MinHeight)
|
||
|
g->ht = DefaultHeight;
|
||
|
if(g->wid > nelem(bin))
|
||
|
g->wid = nelem(bin);
|
||
|
if(g->fill < 0)
|
||
|
g->fill = ((uint)g->arg>>8)%nelem(lofill);
|
||
|
if(g->fill > nelem(lofill))
|
||
|
g->fill %= nelem(lofill);
|
||
|
|
||
|
nbin = g->wid - (Left+Right);
|
||
|
binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin);
|
||
|
|
||
|
/*
|
||
|
* compute bounds
|
||
|
*/
|
||
|
min = g->min;
|
||
|
max = g->max;
|
||
|
if(min < 0 || max <= min){
|
||
|
min = max = 0;
|
||
|
first = 1;
|
||
|
for(i=0; i<nbin; i++){
|
||
|
b = &bin[i];
|
||
|
if(b->nsamp == 0)
|
||
|
continue;
|
||
|
if(first || b->min < min)
|
||
|
min = b->min;
|
||
|
if(first || b->max > max)
|
||
|
max = b->max;
|
||
|
first = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
qlock(&memdrawlock);
|
||
|
ginit();
|
||
|
if(smallfont==nil || black==nil || blue==nil || red==nil || hifill==nil || lofill==nil){
|
||
|
werrstr("graphics initialization failed");
|
||
|
qunlock(&memdrawlock);
|
||
|
return nil;
|
||
|
}
|
||
|
|
||
|
/* fresh image */
|
||
|
m = allocmemimage(Rect(0,0,g->wid,g->ht), ABGR32);
|
||
|
if(m == nil){
|
||
|
qunlock(&memdrawlock);
|
||
|
return nil;
|
||
|
}
|
||
|
r = Rect(Left, Top, g->wid-Right, g->ht-Bottom);
|
||
|
memfillcolor(m, DTransparent);
|
||
|
|
||
|
/* x axis */
|
||
|
memimagedraw(m, Rect(r.min.x, r.max.y, r.max.x, r.max.y+1), black, ZP, memopaque, ZP, S);
|
||
|
|
||
|
/* y labels */
|
||
|
drawlabel(m, r.min, max);
|
||
|
if(min != 0)
|
||
|
drawlabel(m, Pt(r.min.x, r.max.y-smallfont->height), min);
|
||
|
|
||
|
/* actual data */
|
||
|
lastlo = -1;
|
||
|
for(i=0; i<nbin; i++){
|
||
|
b = &bin[i];
|
||
|
if(b->nsamp == 0)
|
||
|
continue;
|
||
|
lo = scalept(b->min, min, max, r.max.y, r.min.y);
|
||
|
hi = scalept(b->max, min, max, r.max.y, r.min.y);
|
||
|
x = r.min.x+i;
|
||
|
hi-=2;
|
||
|
if(0)
|
||
|
if(lastlo != -1){
|
||
|
if(lastlo < lo)
|
||
|
memimagedraw(m, Rect(x-1, lastlo, x, lo), hifill[g->fill], ZP, memopaque, ZP, S);
|
||
|
else if(lastlo > lo)
|
||
|
memimagedraw(m, Rect(x-1, lo, x, lastlo), hifill[g->fill], ZP, memopaque, ZP, S);
|
||
|
}
|
||
|
memimagedraw(m, Rect(x, hi, x+1,lo), hifill[g->fill], ZP, memopaque, ZP, S);
|
||
|
memimagedraw(m, Rect(x, lo, x+1, r.max.y), lofill[g->fill], ZP, memopaque, ZP, S);
|
||
|
lastlo = lo;
|
||
|
}
|
||
|
|
||
|
if(bin[nbin-1].nsamp)
|
||
|
drawlabel(m, Pt(r.max.x, r.min.y+(Dy(r)-smallfont->height)/2), bin[nbin-1].avg);
|
||
|
qunlock(&memdrawlock);
|
||
|
return m;
|
||
|
}
|