From e91fb98d322f7d6cb2e66bef5cdeca9f15f095e6 Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Sun, 4 Oct 2020 00:49:23 +0330 Subject: [PATCH] pic: use troff drawing commands for filling objects --- pic/pltroff.c | 136 +++++++++++++++++++++++++++++++++++++++------------------- pic/print.c | 69 +++++++++++++---------------- 2 files changed, 120 insertions(+), 85 deletions(-) diff --git a/pic/pltroff.c b/pic/pltroff.c index dbe92f8..49b5dee 100644 --- a/pic/pltroff.c +++ b/pic/pltroff.c @@ -39,6 +39,12 @@ void hgoto(double), vgoto(double), hmot(double), vmot(double); void move(double, double), movehv(double, double); void cont(double, double); +void line(double x0, double y0, double x1, double y1) /* draw line from x0,y0 to x1,y1 */ +{ + move(x0, y0); + cont(x1, y1); +} + void openpl(char *s) /* initialize device; s is residue of .PS invocation line */ { double maxw, maxh, ratio = 1; @@ -216,10 +222,49 @@ void label(char *s, int t, int nh) /* text s of type t nh half-lines up */ flyback(); } -void line(double x0, double y0, double x1, double y1) /* draw line from x0,y0 to x1,y1 */ +static char *fillbeg(double fillval) { - move(x0, y0); - cont(x1, y1); + static char buf[32]; + buf[0] = '\0'; + if (fillval >= 0 && fillval <= 1) + sprintf(buf, "\\m[#%02x]", (int) (fillval * 255)); + return buf; +} + +static char *fillend(double fillval) +{ + static char buf[32]; + buf[0] = '\0'; + if (fillval >= 0 && fillval <= 1) + sprintf(buf, "\\m[]"); + return buf; +} + +void muline(double x, double y, double n, ofloat *p, int fill, double fillval) +{ + int i; + double dx, dy; + double xerr, yerr; + + move(x, y); + hvflush(); + xerr = yerr = 0.0; + if (fill) + printf("%s\\D'P ", fillbeg(fillval)); + for (i = 0; i < 2 * n; i += 2) { + dx = xsc(xerr += p[i]); + xerr -= dx/xscale; + dy = ysc(yerr += p[i+1]); + yerr -= dy/yscale; + if (!fill) + printf("\\D'l "); + printf(" %.3fi %.3fi", dx, -dy); /* WATCH SIGN */ + if (!fill) + printf("'"); + } + if (fill) + printf("'%s\n", fillend(fillval)); + flyback(); } void arrow(double x0, double y0, double x1, double y1, double w, double h, @@ -244,41 +289,23 @@ void arrow(double x0, double y0, double x1, double y1, double w, double h, } } -double lastgray = 0; - -void fillstart(double v) /* this works only for postscript, obviously. */ -{ /* uses drechsler's dpost conventions... */ - hvflush(); - if (v >= 0 && v <= 1) - printf("\\X'BeginObject %g setgray'\n", v); - else - printf("\\X'BeginObject'\n"); - lastgray = v; - flyback(); -} - -void fillend(int vis, int fill) +void box(double x0, double y0, double x1, double y1, int fill, double fillval) { + double h1, v1; + double dh, dv; + move(x0, y0); + h1 = xconv(x1); + v1 = yconv(y1); + dh = h1 - hpos; + dv = v1 - vpos; hvflush(); - if (lastgray >= 0 && lastgray <= 1) { - printf("\\X'EndObject gsave eofill grestore %g setgray %s'\n", - !vis ? lastgray : 0.0, - vis ? "stroke" : ""); + if (fill) { + printf("%s\\D'P 0 %.3fi %.3fi 0 0 %.3fi %.3fi 0'%s\n", + fillbeg(fillval), dv, dh, -dv, -dh, fillend(fillval)); } else { - printf("\\X'EndObject gsave eofill grestore %s'\n", vis ? "stroke" : ""); + printf("\\D'p 0 %.3fi %.3fi 0 0 %.3fi %.3fi 0'\n", dv, dh, -dv, -dh); } - /* for dashed: [50] 0 setdash just before stroke. */ - lastgray = 0; - flyback(); -} - -void box(double x0, double y0, double x1, double y1) -{ - move(x0, y0); - cont(x0, y1); - cont(x1, y1); - cont(x1, y0); - cont(x0, y0); + flyback(); /* expensive */ } void cont(double x, double y) /* continue line from here to x,y */ @@ -297,15 +324,18 @@ void cont(double x, double y) /* continue line from here to x,y */ vpos = v1; } -void circle(double x, double y, double r) +void circle(double x, double y, double r, int fill, double fillval) { move(x-r, y); hvflush(); - printf("\\D'c%.3fi'\n", xsc(2 * r)); + if (fill) + printf("%s\\D'C%.3fi'%s\n", fillbeg(fillval), xsc(2 * r), fillend(fillval)); + else + printf("\\D'c%.3fi'\n", xsc(2 * r)); flyback(); } -void spline(double x, double y, double n, ofloat *p, int dashed, double ddval) +void spline(double x, double y, double n, ofloat *p, int dashed, double ddval, int fill, double fillval) { int i; double dx, dy; @@ -314,7 +344,10 @@ void spline(double x, double y, double n, ofloat *p, int dashed, double ddval) move(x, y); hvflush(); xerr = yerr = 0.0; - printf("\\D'~"); + if (fill) + printf("%s\\D'P ~", fillbeg(fillval)); + else + printf("\\D'~"); for (i = 0; i < 2 * n; i += 2) { dx = xsc(xerr += p[i]); xerr -= dx/xscale; @@ -322,29 +355,42 @@ void spline(double x, double y, double n, ofloat *p, int dashed, double ddval) yerr -= dy/yscale; printf(" %.3fi %.3fi", dx, -dy); /* WATCH SIGN */ } - printf("'\n"); + if (fill) + printf("'%s\n", fillend(fillval)); + else + printf("'\n"); flyback(); } -void ellipse(double x, double y, double r1, double r2) +void ellipse(double x, double y, double r1, double r2, int fill, double fillval) { double ir1, ir2; - move(x-r1, y); hvflush(); ir1 = xsc(r1); ir2 = ysc(r2); - printf("\\D'e%.3fi %.3fi'\n", 2 * ir1, 2 * abs(ir2)); + if (fill) { + printf("%s\\D'E%.3fi %.3fi'%s\n", + fillbeg(fillval), 2 * ir1, 2 * abs(ir2), fillend(fillval)); + } else { + printf("\\D'e%.3fi %.3fi'\n", 2 * ir1, 2 * abs(ir2)); + } flyback(); } -void arc(double x, double y, double x0, double y0, double x1, double y1) /* draw arc with center x,y */ +void arc(double x, double y, double x0, double y0, double x1, double y1, int fill, double fillval) /* draw arc with center x,y */ { move(x0, y0); hvflush(); - printf("\\D'a%.3fi %.3fi %.3fi %.3fi'\n", - xsc(x-x0), -ysc(y-y0), xsc(x1-x), -ysc(y1-y)); /* WATCH SIGNS */ + if (fill) { + printf("%s\\D'P a %.3fi %.3fi %.3fi %.3fi'%s\n", + fillbeg(fillval), xsc(x-x0), -ysc(y-y0), + xsc(x1-x), -ysc(y1-y), fillend(fillval)); /* WATCH SIGNS */ + } else { + printf("\\D'a%.3fi %.3fi %.3fi %.3fi'\n", + xsc(x-x0), -ysc(y-y0), xsc(x1-x), -ysc(y1-y)); /* WATCH SIGNS */ + } flyback(); } diff --git a/pic/print.c b/pic/print.c index ad21e0d..d03ef7e 100644 --- a/pic/print.c +++ b/pic/print.c @@ -6,17 +6,17 @@ void dotext(obj *); void dotline(double, double, double, double, int, double); void dotbox(double, double, double, double, int, double); -void ellipse(double, double, double, double); -void circle(double, double, double); -void arc(double, double, double, double, double, double); +void ellipse(double, double, double, double, int, double); +void circle(double, double, double, int, double); +void arc(double, double, double, double, double, double, int, double); void arrow(double, double, double, double, double, double, double, int); void line(double, double, double, double); -void box(double, double, double, double); -void spline(double x, double y, double n, ofloat *p, int dashed, double ddval); +void box(double, double, double, double, int, double); +void spline(double x, double y, double n, ofloat *p, int dashed, double ddval, int fill, double fillval); +void muline(double x, double y, double n, ofloat *p, int fill, double fillval); void move(double, double); void troff(char *); void dot(void); -void fillstart(double), fillend(int vis, int noedge); void print(void) { @@ -47,10 +47,8 @@ void print(void) y0 = oy - y1 / 2; x1 = ox + x1 / 2; y1 = oy + y1 / 2; - if (fill) { - move(x0, y0); - fillstart(p->o_fillval); - } + if (fill) + box(x0, y0, x1, y1, 1, p->o_fillval); if (p->o_type == BLOCK) ; /* nothing at all */ else if (invis && !fill) @@ -58,9 +56,7 @@ void print(void) else if (p->o_attr & (DOTBIT|DASHBIT)) dotbox(x0, y0, x1, y1, p->o_attr, p->o_ddval); else - box(x0, y0, x1, y1); - if (fill) - fillend(vis, fill); + box(x0, y0, x1, y1, 0, 0); move(ox, oy); dotext(p); /* if there are any text strings */ if (ishor(m)) @@ -72,11 +68,9 @@ void print(void) break; case CIRCLE: if (fill) - fillstart(p->o_fillval); - if (vis || fill) - circle(ox, oy, x1); - if (fill) - fillend(vis, fill); + circle(ox, oy, x1, 1, p->o_fillval); + if (vis) + circle(ox, oy, x1, 0, 0); move(ox, oy); dotext(p); if (ishor(m)) @@ -86,11 +80,9 @@ void print(void) break; case ELLIPSE: if (fill) - fillstart(p->o_fillval); - if (vis || fill) - ellipse(ox, oy, x1, y1); - if (fill) - fillend(vis, fill); + ellipse(ox, oy, x1, y1, 1, p->o_fillval); + if (vis) + ellipse(ox, oy, x1, y1, 0, 0); move(ox, oy); dotext(p); if (ishor(m)) @@ -99,23 +91,19 @@ void print(void) move(ox, oy - isdown(m) ? y1 : -y1); break; case ARC: - if (fill) { - move(ox, oy); - fillstart(p->o_fillval); - } if (p->o_attr & HEAD1) arrow(x1 - (y1 - oy), y1 + (x1 - ox), x1, y1, p->o_val[4], p->o_val[5], p->o_val[5]/p->o_val[6]/2, p->o_nhead); + if (fill) + arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3], 1, p->o_fillval); if (invis && !fill) /* probably wrong when it's cw */ move(x1, y1); - else - arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3]); + else if (vis) + arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3], 0, 0); if (p->o_attr & HEAD2) arrow(p->o_val[2] + p->o_val[3] - oy, p->o_val[3] - (p->o_val[2] - ox), p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5], -p->o_val[5]/p->o_val[6]/2, p->o_nhead); - if (fill) - fillend(vis, fill); if (p->o_attr & CW_ARC) move(x1, y1); /* because drawn backwards */ move(ox, oy); @@ -124,17 +112,20 @@ void print(void) case LINE: case ARROW: case SPLINE: - if (fill) { - move(ox, oy); - fillstart(p->o_fillval); - } if (vis && p->o_attr & HEAD1) arrow(ox + p->o_val[5], oy + p->o_val[6], ox, oy, p->o_val[2], p->o_val[3], 0.0, p->o_nhead); if (invis && !fill) move(x1, y1); - else if (p->o_type == SPLINE) - spline(ox, oy, p->o_val[4], &p->o_val[5], p->o_attr & (DOTBIT|DASHBIT), p->o_ddval); - else { + else if (p->o_type == SPLINE) { + if (fill) + spline(ox, oy, p->o_val[4], &p->o_val[5], + p->o_attr & (DOTBIT|DASHBIT), p->o_ddval, 1, p->o_fillval); + if (vis) + spline(ox, oy, p->o_val[4], &p->o_val[5], + p->o_attr & (DOTBIT|DASHBIT), p->o_ddval, 0, 0); + } else { + if (fill) + muline(ox, oy, p->o_val[4], &p->o_val[5], 1, p->o_fillval); dx = ox; dy = oy; for (k=0, j=5; k < p->o_val[4]; k++, j += 2) { @@ -157,8 +148,6 @@ void print(void) } arrow(dx, dy, x1, y1, p->o_val[2], p->o_val[3], 0.0, p->o_nhead); } - if (fill) - fillend(vis, fill); move((ox + x1)/2, (oy + y1)/2); /* center */ dotext(p); break; -- 2.11.4.GIT