1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include "../common/common.h" 5 #include "tr2post.h" 6 7 BOOLEAN drawflag = FALSE; 8 9 void 10 cover(double x, double y) { 11 } 12 13 void 14 drawspline(Biobufhdr *Bp, int flag) { /* flag!=1 connect end points */ 15 int x[100], y[100]; 16 int i, N; 17 /* 18 * 19 * Spline drawing routine for Postscript printers. The complicated stuff is 20 * handled by procedure Ds, which should be defined in the library file. I've 21 * seen wrong implementations of troff's spline drawing, so fo the record I'll 22 * write down the parametric equations and the necessary conversions to Bezier 23 * cubic splines (as used in Postscript). 24 * 25 * 26 * Parametric equation (x coordinate only): 27 * 28 * 29 * (x2 - 2 * x1 + x0) 2 (x0 + x1) 30 * x = ------------------ * t + (x1 - x0) * t + --------- 31 * 2 2 32 * 33 * 34 * The coefficients in the Bezier cubic are, 35 * 36 * 37 * A = 0 38 * B = (x2 - 2 * x1 + x0) / 2 39 * C = x1 - x0 40 * 41 * 42 * while the current point is, 43 * 44 * current-point = (x0 + x1) / 2 45 * 46 * Using the relationships given in the Postscript manual (page 121) it's easy to 47 * see that the control points are given by, 48 * 49 * 50 * x0' = (x0 + 5 * x1) / 6 51 * x1' = (x2 + 5 * x1) / 6 52 * x2' = (x1 + x2) / 2 53 * 54 * 55 * where the primed variables are the ones used by curveto. The calculations 56 * shown above are done in procedure Ds using the coordinates set up in both 57 * the x[] and y[] arrays. 58 * 59 * A simple test of whether your spline drawing is correct would be to use cip 60 * to draw a spline and some tangent lines at appropriate points and then print 61 * the file. 62 * 63 */ 64 65 for (N=2; N<sizeof(x)/sizeof(x[0]); N++) 66 if (Bgetfield(Bp, 'd', &x[N], 0)<=0 || Bgetfield(Bp, 'd', &y[N], 0)<=0) 67 break; 68 69 x[0] = x[1] = hpos; 70 y[0] = y[1] = vpos; 71 72 for (i = 1; i < N; i++) { 73 x[i+1] += x[i]; 74 y[i+1] += y[i]; 75 } 76 77 x[N] = x[N-1]; 78 y[N] = y[N-1]; 79 80 for (i = ((flag!=1)?0:1); i < ((flag!=1)?N-1:N-2); i++) { 81 endstring(); 82 if (pageon()) 83 Bprint(Bstdout, "%d %d %d %d %d %d Ds\n", x[i], y[i], x[i+1], y[i+1], x[i+2], y[i+2]); 84 /* if (dobbox == TRUE) { /* could be better */ 85 /* cover((double)(x[i] + x[i+1])/2,(double)-(y[i] + y[i+1])/2); 86 /* cover((double)x[i+1], (double)-y[i+1]); 87 /* cover((double)(x[i+1] + x[i+2])/2, (double)-(y[i+1] + y[i+2])/2); 88 /* } 89 */ 90 } 91 92 hpos = x[N]; /* where troff expects to be */ 93 vpos = y[N]; 94 } 95 96 void 97 draw(Biobufhdr *Bp) { 98 99 int r, x1, y1, x2, y2, i; 100 int d1, d2; 101 102 drawflag = TRUE; 103 r = Bgetrune(Bp); 104 switch(r) { 105 case 'l': 106 if (Bgetfield(Bp, 'd', &x1, 0)<=0 || Bgetfield(Bp, 'd', &y1, 0)<=0 || Bgetfield(Bp, 'r', &i, 0)<=0) 107 error(FATAL, "draw line function, destination coordinates not found.\n"); 108 109 endstring(); 110 if (pageon()) 111 Bprint(Bstdout, "%d %d %d %d Dl\n", hpos, vpos, hpos+x1, vpos+y1); 112 hpos += x1; 113 vpos += y1; 114 break; 115 case 'c': 116 if (Bgetfield(Bp, 'd', &d1, 0)<=0) 117 error(FATAL, "draw circle function, diameter coordinates not found.\n"); 118 119 endstring(); 120 if (pageon()) 121 Bprint(Bstdout, "%d %d %d %d De\n", hpos, vpos, d1, d1); 122 hpos += d1; 123 break; 124 case 'e': 125 if (Bgetfield(Bp, 'd', &d1, 0)<=0 || Bgetfield(Bp, 'd', &d2, 0)<=0) 126 error(FATAL, "draw ellipse function, diameter coordinates not found.\n"); 127 128 endstring(); 129 if (pageon()) 130 Bprint(Bstdout, "%d %d %d %d De\n", hpos, vpos, d1, d2); 131 hpos += d1; 132 break; 133 case 'a': 134 if (Bgetfield(Bp, 'd', &x1, 0)<=0 || Bgetfield(Bp, 'd', &y1, 0)<=0 || Bgetfield(Bp, 'd', &x2, 0)<=0 || Bgetfield(Bp, 'd', &y2, 0)<=0) 135 error(FATAL, "draw arc function, coordinates not found.\n"); 136 137 endstring(); 138 if (pageon()) 139 Bprint(Bstdout, "%d %d %d %d %d %d Da\n", hpos, vpos, x1, y1, x2, y2); 140 hpos += x1 + x2; 141 vpos += y1 + y2; 142 break; 143 case 'q': 144 drawspline(Bp, 1); 145 break; 146 case '~': 147 drawspline(Bp, 2); 148 break; 149 default: 150 error(FATAL, "unknown draw function <%c>\n", r); 151 break; 152 } 153 } 154