print.c 6.1 KB

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