mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-27 11:52:03 +00:00
132 lines
2.7 KiB
C
132 lines
2.7 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include "grap.h"
|
|
#include "y.tab.h"
|
|
|
|
void line(int type, Point p1, Point p2, Attr *desc) /* draw a line segment */
|
|
{
|
|
fprintf(tfd, "%s %s from %s",
|
|
type==LINE ? "line" : "arrow", desc_str(desc), xyname(p1));
|
|
fprintf(tfd, " to %s", xyname(p2)); /* 'cause xyname is botched */
|
|
fprintf(tfd, "\n");
|
|
range(p1);
|
|
range(p2);
|
|
}
|
|
|
|
void circle(double r, Point pt) /* draw a circle */
|
|
{
|
|
if (r > 0.0)
|
|
fprintf(tfd, "circle rad %g at %s\n", r, xyname(pt));
|
|
else
|
|
fprintf(tfd, "\"\\s-3\\(ob\\s0\" at %s\n", xyname(pt));
|
|
range(pt);
|
|
}
|
|
|
|
char *xyname(Point pt) /* generate xy name macro for point p */
|
|
{
|
|
static char buf[200];
|
|
Obj *p;
|
|
|
|
p = pt.obj;
|
|
if (p->log & XFLAG) {
|
|
if (pt.x <= 0.0)
|
|
ERROR "can't take log of x coord %g", pt.x FATAL;
|
|
logit(pt.x);
|
|
}
|
|
if (p->log & YFLAG) {
|
|
if (pt.y <= 0.0)
|
|
ERROR "can't take log of y coord %g", pt.y FATAL;
|
|
logit(pt.y);
|
|
}
|
|
sprintf(buf, "xy_%s(%g,%g)", p->name, pt.x, pt.y);
|
|
return buf; /* WATCH IT: static */
|
|
}
|
|
|
|
void pic(char *s) /* fire out pic stuff directly */
|
|
{
|
|
while (*s == ' ')
|
|
s++;
|
|
fprintf(tfd, "%s\n", s);
|
|
}
|
|
|
|
int auto_x = 0; /* counts abscissa if none provided */
|
|
|
|
void numlist(void) /* print numbers in default way */
|
|
{
|
|
Obj *p;
|
|
Point pt;
|
|
int i;
|
|
static char *spot = "\\(bu";
|
|
Attr *ap;
|
|
|
|
p = pt.obj = lookup(curr_coord, 1);
|
|
if (nnum == 1) {
|
|
nnum = 2;
|
|
num[1] = num[0];
|
|
num[0] = ++auto_x;
|
|
}
|
|
pt.x = num[0];
|
|
if (p->attr && p->attr->sval)
|
|
spot = p->attr->sval;
|
|
for (i = 1; i < nnum; i++) {
|
|
pt.y = num[i];
|
|
if (p->attr == 0 || p->attr->type == 0) {
|
|
ap = makesattr(tostring(spot));
|
|
plot(ap, pt);
|
|
} else
|
|
next(p, pt, p->attr);
|
|
}
|
|
nnum = 0;
|
|
}
|
|
|
|
void plot(Attr *sl, Point pt) /* put stringlist sl at point pt */
|
|
{
|
|
fprintf(tfd, "%s at %s\n", slprint(sl), xyname(pt));
|
|
range(pt);
|
|
freeattr(sl);
|
|
}
|
|
|
|
void plotnum(double f, char *fmt, Point pt) /* plot value f at point */
|
|
{
|
|
char buf[100];
|
|
|
|
if (fmt) {
|
|
sprintf(buf, fmt, f);
|
|
free(fmt);
|
|
} else if (f >= 0.0)
|
|
sprintf(buf, "%g", f);
|
|
else
|
|
sprintf(buf, "\\-%g", -f);
|
|
fprintf(tfd, "\"%s\" at %s\n", buf, xyname(pt));
|
|
range(pt);
|
|
}
|
|
|
|
void drawdesc(int type, Obj *p, Attr *desc, char *s) /* set line description for p */
|
|
{
|
|
p->attr = desc;
|
|
p->attr->sval = s;
|
|
if (type == NEW) {
|
|
p->first = 0; /* so it really looks new */
|
|
auto_x = 0;
|
|
}
|
|
}
|
|
|
|
void next(Obj *p, Point pt, Attr *desc) /* add component to a path */
|
|
{
|
|
char *s;
|
|
|
|
if (p->first == 0) {
|
|
p->first++;
|
|
fprintf(tfd, "L%s: %s\n", p->name, xyname(pt));
|
|
} else {
|
|
fprintf(tfd, "line %s from L%s to %s; L%s: Here\n",
|
|
desc_str(desc->type ? desc : p->attr),
|
|
p->name, xyname(pt), p->name);
|
|
}
|
|
if (p->attr && (s=p->attr->sval)) {
|
|
/* BUG: should fix size here */
|
|
fprintf(tfd, "\"%s\" at %s\n", s, xyname(pt));
|
|
}
|
|
range(pt);
|
|
}
|