rsc | b6d9846 | 2006-04-14 00:04:03 +0000 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | #include <math.h> |
| 3 | #include "pic.h" |
| 4 | #include "y.tab.h" |
| 5 | |
| 6 | void |
| 7 | print(void) |
| 8 | { |
| 9 | obj *p; |
| 10 | int i, j, k, m; |
| 11 | double x0, y0, x1, y1, ox, oy, dx, dy, ndx, ndy; |
| 12 | |
| 13 | for (i = 0; i < nobj; i++) { |
| 14 | p = objlist[i]; |
| 15 | ox = p->o_x; |
| 16 | oy = p->o_y; |
| 17 | x1 = 0; |
| 18 | if (p->o_count >= 1) |
| 19 | x1 = p->o_val[0]; |
| 20 | y1 = 0; |
| 21 | if (p->o_count >= 2) |
| 22 | y1 = p->o_val[1]; |
| 23 | m = p->o_mode; |
| 24 | switch (p->o_type) { |
| 25 | case TROFF: |
| 26 | troff(text[p->o_nt1].t_val); |
| 27 | break; |
| 28 | case BOX: |
| 29 | case BLOCK: |
| 30 | x0 = ox - x1 / 2; |
| 31 | y0 = oy - y1 / 2; |
| 32 | x1 = ox + x1 / 2; |
| 33 | y1 = oy + y1 / 2; |
| 34 | if (p->o_attr & FILLBIT) { |
| 35 | move(x0, y0); |
| 36 | fillstart(p->o_fillval); |
| 37 | } |
| 38 | if (p->o_attr & INVIS || p->o_type == BLOCK) |
| 39 | ; /* nothing at all */ |
| 40 | else if (p->o_attr & (DOTBIT|DASHBIT)) |
| 41 | dotbox(x0, y0, x1, y1, p->o_attr, p->o_ddval); |
| 42 | else |
| 43 | box(x0, y0, x1, y1); |
| 44 | if (p->o_attr & FILLBIT) |
| 45 | fillend(); |
| 46 | move(ox, oy); |
| 47 | dotext(p); /* if there are any text strings */ |
| 48 | if (ishor(m)) |
| 49 | move(isright(m) ? x1 : x0, oy); /* right side */ |
| 50 | else |
| 51 | move(ox, isdown(m) ? y0 : y1); /* bottom */ |
| 52 | break; |
| 53 | case BLOCKEND: |
| 54 | break; |
| 55 | case CIRCLE: |
| 56 | if (p->o_attr & FILLBIT) |
| 57 | fillstart(p->o_fillval); |
| 58 | if ((p->o_attr & INVIS) == 0) |
| 59 | circle(ox, oy, x1); |
| 60 | if (p->o_attr & FILLBIT) |
| 61 | fillend(); |
| 62 | move(ox, oy); |
| 63 | dotext(p); |
| 64 | if (ishor(m)) |
| 65 | move(ox + isright(m) ? x1 : -x1, oy); |
| 66 | else |
| 67 | move(ox, oy + isup(m) ? x1 : -x1); |
| 68 | break; |
| 69 | case ELLIPSE: |
| 70 | if (p->o_attr & FILLBIT) |
| 71 | fillstart(p->o_fillval); |
| 72 | if ((p->o_attr & INVIS) == 0) |
| 73 | ellipse(ox, oy, x1, y1); |
| 74 | if (p->o_attr & FILLBIT) |
| 75 | fillend(); |
| 76 | move(ox, oy); |
| 77 | dotext(p); |
| 78 | if (ishor(m)) |
| 79 | move(ox + isright(m) ? x1 : -x1, oy); |
| 80 | else |
| 81 | move(ox, oy - isdown(m) ? y1 : -y1); |
| 82 | break; |
| 83 | case ARC: |
| 84 | move(ox, oy); |
| 85 | dotext(p); |
| 86 | if (p->o_attr & HEAD1) |
| 87 | arrow(x1 - (y1 - oy), y1 + (x1 - ox), |
| 88 | x1, y1, p->o_val[4], p->o_val[5], p->o_val[5]/p->o_val[6]/2, p->o_nhead); |
| 89 | if (p->o_attr & INVIS) |
| 90 | /* probably wrong when it's cw */ |
| 91 | move(x1, y1); |
| 92 | else |
| 93 | arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3]); |
| 94 | if (p->o_attr & HEAD2) |
| 95 | arrow(p->o_val[2] + p->o_val[3] - oy, p->o_val[3] - (p->o_val[2] - ox), |
| 96 | 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); |
| 97 | if (p->o_attr & CW_ARC) |
| 98 | move(x1, y1); /* because drawn backwards */ |
| 99 | break; |
| 100 | case LINE: |
| 101 | case ARROW: |
| 102 | case SPLINE: |
| 103 | move((ox + x1)/2, (oy + y1)/2); /* center */ |
| 104 | dotext(p); |
| 105 | if (p->o_attr & HEAD1) |
| 106 | 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); |
| 107 | if (p->o_attr & INVIS) |
| 108 | move(x1, y1); |
| 109 | else if (p->o_type == SPLINE) |
| 110 | spline(ox, oy, p->o_val[4], &p->o_val[5], p->o_attr & (DOTBIT|DASHBIT), p->o_ddval); |
| 111 | else { |
| 112 | dx = ox; |
| 113 | dy = oy; |
| 114 | for (k=0, j=5; k < p->o_val[4]; k++, j += 2) { |
| 115 | ndx = dx + p->o_val[j]; |
| 116 | ndy = dy + p->o_val[j+1]; |
| 117 | if (p->o_attr & (DOTBIT|DASHBIT)) |
| 118 | dotline(dx, dy, ndx, ndy, p->o_attr, p->o_ddval); |
| 119 | else |
| 120 | line(dx, dy, ndx, ndy); |
| 121 | dx = ndx; |
| 122 | dy = ndy; |
| 123 | } |
| 124 | } |
| 125 | if (p->o_attr & HEAD2) { |
| 126 | dx = ox; |
| 127 | dy = oy; |
| 128 | for (k = 0, j = 5; k < p->o_val[4] - 1; k++, j += 2) { |
| 129 | dx += p->o_val[j]; |
| 130 | dy += p->o_val[j+1]; |
| 131 | } |
| 132 | arrow(dx, dy, x1, y1, p->o_val[2], p->o_val[3], 0.0, p->o_nhead); |
| 133 | } |
| 134 | break; |
| 135 | case MOVE: |
| 136 | case TEXT: |
| 137 | move(ox, oy); |
| 138 | dotext(p); |
| 139 | break; |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | #ifndef NOEXPANDDASH |
| 145 | void |
| 146 | dotline(double x0, double y0, double x1, double y1, int ddtype, double ddval) /* dotted line */ |
| 147 | { |
| 148 | static double prevval = 0.05; /* 20 per inch by default */ |
| 149 | int i, numdots; |
| 150 | double a, b, dx, dy; |
| 151 | |
| 152 | if (ddval == 0) |
| 153 | ddval = prevval; |
| 154 | prevval = ddval; |
| 155 | /* don't save dot/dash value */ |
| 156 | dx = x1 - x0; |
| 157 | dy = y1 - y0; |
| 158 | if (ddtype & DOTBIT) { |
| 159 | numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5; |
| 160 | if (numdots > 0) |
| 161 | for (i = 0; i <= numdots; i++) { |
| 162 | a = (double) i / (double) numdots; |
| 163 | move(x0 + (a * dx), y0 + (a * dy)); |
| 164 | dot(); |
| 165 | } |
| 166 | } else if (ddtype & DASHBIT) { |
| 167 | double d, dashsize, spacesize; |
| 168 | d = sqrt(dx*dx + dy*dy); |
| 169 | if (d <= 2 * prevval) { |
| 170 | line(x0, y0, x1, y1); |
| 171 | return; |
| 172 | } |
| 173 | numdots = d / (2 * prevval) + 1; /* ceiling */ |
| 174 | dashsize = prevval; |
| 175 | spacesize = (d - numdots * dashsize) / (numdots - 1); |
| 176 | b = 0; |
| 177 | for (i = 0; i < numdots-1; i++) { |
| 178 | a = i * (dashsize + spacesize) / d; |
| 179 | b = a + dashsize / d; |
| 180 | line(x0 + (a*dx), y0 + (a*dy), x0 + (b*dx), y0 + (b*dy)); |
| 181 | a = b; |
| 182 | b = a + spacesize / d; |
| 183 | move(x0 + (a*dx), y0 + (a*dy)); |
| 184 | } |
| 185 | line(x0 + (b * dx), y0 + (b * dy), x1, y1); |
| 186 | } |
| 187 | prevval = 0.05; |
| 188 | } |
| 189 | #endif |
| 190 | |
| 191 | void |
| 192 | dotbox(double x0, double y0, double x1, double y1, int ddtype, double ddval) /* dotted or dashed box */ |
| 193 | { |
| 194 | dotline(x0, y0, x1, y0, ddtype, ddval); |
| 195 | dotline(x1, y0, x1, y1, ddtype, ddval); |
| 196 | dotline(x1, y1, x0, y1, ddtype, ddval); |
| 197 | dotline(x0, y1, x0, y0, ddtype, ddval); |
| 198 | } |
| 199 | |
| 200 | void |
| 201 | dotext(obj *p) /* print text strings of p in proper vertical spacing */ |
| 202 | { |
| 203 | int i, nhalf; |
| 204 | |
| 205 | nhalf = p->o_nt2 - p->o_nt1 - 1; |
| 206 | for (i = p->o_nt1; i < p->o_nt2; i++) { |
| 207 | label(text[i].t_val, text[i].t_type, nhalf); |
| 208 | nhalf -= 2; |
| 209 | } |
| 210 | } |