circgen.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <stdio.h>
  2. #include "pic.h"
  3. #include "y.tab.h"
  4. obj *circgen(int type)
  5. {
  6. static double rad[2] = { HT2, WID2 };
  7. static double rad2[2] = { HT2, HT2 };
  8. int i, at, t, with, battr;
  9. double xwith, ywith;
  10. double r, r2, ddval, fillval;
  11. obj *p, *ppos;
  12. Attr *ap;
  13. battr = at = 0;
  14. with = xwith = ywith = fillval = ddval = 0;
  15. t = (type == CIRCLE) ? 0 : 1;
  16. if (type == CIRCLE)
  17. r = r2 = getfval("circlerad");
  18. else if (type == ELLIPSE) {
  19. r = getfval("ellipsewid") / 2;
  20. r2 = getfval("ellipseht") / 2;
  21. }
  22. for (i = 0; i < nattr; i++) {
  23. ap = &attr[i];
  24. switch (ap->a_type) {
  25. case TEXTATTR:
  26. savetext(ap->a_sub, ap->a_val.p);
  27. break;
  28. case RADIUS:
  29. r = ap->a_val.f;
  30. break;
  31. case DIAMETER:
  32. case WIDTH:
  33. r = ap->a_val.f / 2;
  34. break;
  35. case HEIGHT:
  36. r2 = ap->a_val.f / 2;
  37. break;
  38. case SAME:
  39. r = rad[t];
  40. r2 = rad2[t];
  41. break;
  42. case WITH:
  43. with = ap->a_val.i;
  44. break;
  45. case AT:
  46. ppos = ap->a_val.o;
  47. curx = ppos->o_x;
  48. cury = ppos->o_y;
  49. at++;
  50. break;
  51. case INVIS:
  52. battr |= INVIS;
  53. break;
  54. case NOEDGE:
  55. battr |= NOEDGEBIT;
  56. break;
  57. case DOT:
  58. case DASH:
  59. battr |= ap->a_type==DOT ? DOTBIT : DASHBIT;
  60. if (ap->a_sub == DEFAULT)
  61. ddval = getfval("dashwid");
  62. else
  63. ddval = ap->a_val.f;
  64. break;
  65. case FILL:
  66. battr |= FILLBIT;
  67. if (ap->a_sub == DEFAULT)
  68. fillval = getfval("fillval");
  69. else
  70. fillval = ap->a_val.f;
  71. break;
  72. }
  73. }
  74. if (type == CIRCLE)
  75. r2 = r; /* probably superfluous */
  76. if (with) {
  77. switch (with) {
  78. case NORTH: ywith = -r2; break;
  79. case SOUTH: ywith = r2; break;
  80. case EAST: xwith = -r; break;
  81. case WEST: xwith = r; break;
  82. case NE: xwith = -r * 0.707; ywith = -r2 * 0.707; break;
  83. case SE: xwith = -r * 0.707; ywith = r2 * 0.707; break;
  84. case NW: xwith = r * 0.707; ywith = -r2 * 0.707; break;
  85. case SW: xwith = r * 0.707; ywith = r2 * 0.707; break;
  86. }
  87. curx += xwith;
  88. cury += ywith;
  89. }
  90. if (!at) {
  91. if (isright(hvmode))
  92. curx += r;
  93. else if (isleft(hvmode))
  94. curx -= r;
  95. else if (isup(hvmode))
  96. cury += r2;
  97. else
  98. cury -= r2;
  99. }
  100. p = makenode(type, 2);
  101. p->o_val[0] = rad[t] = r;
  102. p->o_val[1] = rad2[t] = r2;
  103. if (r <= 0 || r2 <= 0) {
  104. ERROR "%s has invalid radius %g\n", (type==CIRCLE) ? "circle" : "ellipse", r<r2 ? r : r2 WARNING;
  105. }
  106. p->o_attr = battr;
  107. p->o_ddval = ddval;
  108. p->o_fillval = fillval;
  109. extreme(curx+r, cury+r2);
  110. extreme(curx-r, cury-r2);
  111. if (type == CIRCLE)
  112. dprintf("C %g %g %g\n", curx, cury, r);
  113. if (type == ELLIPSE)
  114. dprintf("E %g %g %g %g\n", curx, cury, r, r2);
  115. if (isright(hvmode))
  116. curx += r;
  117. else if (isleft(hvmode))
  118. curx -= r;
  119. else if (isup(hvmode))
  120. cury += r2;
  121. else
  122. cury -= r2;
  123. return(p);
  124. }