ref: 59402bf42b8b199218f1f0d111aaf273a3c1806a
dir: /draw.c/
#include <u.h>
#include <libc.h>
#include <String.h>
#include "dat.h"
#include "fns.h"
static int lineheight = 10;
static int charwidth = 6;
static int foldline = 32;
static int boxoffsetx = 2;
static int boxoffsety = 2;
static int borderoffset = 2;
static int labeloffset = 20;
void
dheader()
{
print(
"%%!PS\n"
"%%%%Creator: netgraph\n"
"%%%%Origin: 0 0\n"
"%%%%BoundingBox: 0 0 %d %d\n"
"%%%%Pages: 1\n"
"/Courier 10 selectfont\n",
pagewidth, pageheight
);
}
void
dfooter()
{
print("showpage\n%%%%EOF\n");
}
static void
drawtext(Pos p, int off, char *fmt, ...)
{
va_list arg;
print("%d %d moveto\n(", p.x, p.y - (off * lineheight));
va_start(arg, fmt);
vfprint(1, fmt, arg);
va_end(arg);
print(") show\n");
}
static void
drawbox(Block *b)
{
Pos p1, p2;
p1 = b->p;
p1.y = pageheight - p1.y;
p2 = p1;
p1.x -= boxoffsetx;
p1.y += boxoffsety - borderoffset;
p2.x += boxoffsetx + b->width;
p2.y -= boxoffsety + b->height + borderoffset;
print("newpath\n"
"%d %d moveto\n"
"%d %d lineto\n"
"%d %d lineto\n"
"%d %d lineto\n"
"closepath\n"
"gsave\n"
"1 setgray\n"
"fill\n"
"grestore\n"
"1 setlinewidth\n"
"0 setgray\n"
"stroke\n",
p1.x, p1.y,
p2.x, p1.y,
p2.x, p2.y,
p1.x, p2.y);
}
static char*
strrnchr(char *str, int n, int c)
{
char *s;
s = &str[n];
while (s > str) {
if (*s == c)
return s;
s--;
}
return nil;
}
static int
isipnet(Tuple *t)
{
return strcmp(t->key, Sipnet) == 0;
}
static void
drawtuple(Tuple *t, void *aux)
{
Color c;
Pos *p = aux;
char *s, *s2;
int n, fl;
int ipnet = isipnet(t);
if (!showipnet && t->ipnet && !ipnet)
return;
if (ipnet) {
print("gsave\n");
c = getipnetcolor(Sipnet, t->value);
print("%f %f %f setrgbcolor\n", c.r, c.g, c.b);
}
fl = foldline - strlen(t->key) - 3;
s = t->value;
while (strlen(s) > fl) {
s2 = strrnchr(s, fl, ',');
if (!s2)
s2 = &s[fl];
n = s2 - s + 1;
drawtext(*p, 1, "%s%s: %.*s", t->ipnet ? "*" : "", t->key, n, s);
p->y -= lineheight;
s = s2;
if (*s == ',')
s++;
while (*s == ' ')
s++;
}
if (strlen(s)) {
drawtext(*p, 1, "%s%s: %s", t->ipnet ? "*" : "", t->key, s);
p->y -= lineheight;
}
if (ipnet) {
print("grestore\n");
}
}
void
dblock(Block *b)
{
Pos np;
Pos p = b->p;
p.y = pageheight - p.y;
drawbox(b);
np = p;
fortuple(b, drawtuple, &np);
}
static void
tuplesize(Tuple *t, void *aux)
{
Block *b = aux;
char *s, *s2;
int w, nw;
int fl;
if (!showipnet && t->ipnet && !isipnet(t))
return;
fl = foldline - strlen(t->key) - 3;
w = 0;
s = t->value;
while (strlen(s) > fl) {
s2 = strrnchr(s, fl, ',');
if (!s2)
s2 = &s[fl];
nw = s2 - s + 1;
if (nw > w) w = nw;
b->height += lineheight;
s = s2;
if (*s == ',')
s++;
while (*s == ' ')
s++;
}
if (strlen(s)) {
nw = strlen(s);
if (nw > w) w = nw;
b->height += lineheight;
}
w = strlen(t->key) + w + 3;
if (w > b->width)
b->width = w;
}
void
setblocksize(Block *b)
{
b->width = 0;
fortuple(b, tuplesize, b);
b->width *= charwidth;
}
static void
dlabel(Pos p, float angle, char *label)
{
int n = charwidth * strlen(label) + 4;
print("gsave\n");
print(
"%d %d translate\n"
"%f rotate\n"
"newpath\n"
"-2 -5 moveto\n"
"%d %d rlineto\n"
"%d %d rlineto\n"
"%d %d rlineto\n"
"closepath\n"
"gsave\n"
"1 setgray\n"
"fill\n"
"grestore\n"
"0 setgray\n"
"0.5 setlinewidth\n"
"stroke\n",
p.x, p.y,
angle,
n, 0,
0, lineheight+2,
-n, 0
);
print(
"newpath\n"
"0 -2 moveto\n"
"(%s) show\n",
label);
print("grestore\n");
}
void
dconn(Block *from, Block *to, char *label)
{
Pos p1, p2, c, c2;
float fx, fy, d;
int m;
p1 = from->p;
p2 = to->p;
p1.y = pageheight - p1.y;
p2.y = pageheight - p2.y;
p1.x += from->width/2;
p1.y -= from->height/2;
p2.x += from->width/2;
p2.y -= from->height/2;
c.x = pagewidth/2;
c.y = pageheight/2;
c2.x = p1.x + (p2.x - p1.x) / 2;
c2.y = p1.y + (p2.y - p1.y) / 2;
c.x = c2.x + (c.x - c2.x) / 2;
c.y = c2.y + (c.y - c2.y) / 2;
print("newpath\n"
"%d %d moveto\n"
"%d %d %d %d %d %d curveto\n"
"1 setlinewidth\n"
"stroke\n",
p1.x, p1.y,
c.x, c.y, c.x, c.y,
p2.x, p2.y);
m = from->width > from->height ? from->width : from->height;
m /= 2;
m += labeloffset;
fx = c.x - p1.x;
fy = c.y - p1.y;
d = sqrt(fx*fx + fy*fy);
fx /= d;
fy /= d;
p1.x += fx * m;
p1.y += fy * m;
fx = atan2(fy, fx) * 180./PI;
dlabel(p1, fx, label);
}