home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xfig / part12 < prev    next >
Encoding:
Text File  |  1993-05-26  |  67.3 KB  |  2,458 lines

  1. Newsgroups: comp.sources.x
  2. From: envbvs@epb9.lbl.gov (Brian V. Smith)
  3. Subject: v19i124:  xfig - Draw amd manipulate objects in an X-Window, Part12/27
  4. Message-ID: <1993May21.021454.6090@sparky.imd.sterling.com>
  5. X-Md4-Signature: d918b7d3d1facbd33d2a9e0cf9e7eeef
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Sterling Software
  8. Date: Fri, 21 May 1993 02:14:54 GMT
  9. Approved: chris@sparky.imd.sterling.com
  10.  
  11. Submitted-by: envbvs@epb9.lbl.gov (Brian V. Smith)
  12. Posting-number: Volume 19, Issue 124
  13. Archive-name: xfig/part12
  14. Environment: X11
  15. Supersedes: xfig: Volume 16, Issue 6-30,39
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 12 (of 27)."
  24. # Contents:  u_bound.c u_redraw.c u_undo.c w_print.c
  25. # Wrapped by envbvs@epb9.lbl.gov.lbl.gov on Mon May  3 12:05:55 1993
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'u_bound.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'u_bound.c'\"
  29. else
  30. echo shar: Extracting \"'u_bound.c'\" \(16661 characters\)
  31. sed "s/^X//" >'u_bound.c' <<'END_OF_FILE'
  32. X/*
  33. X * FIG : Facility for Interactive Generation of figures
  34. X * Copyright (c) 1985 by Supoj Sutanthavibul
  35. X *
  36. X * "Permission to use, copy, modify, distribute, and sell this software and its
  37. X * documentation for any purpose is hereby granted without fee, provided that
  38. X * the above copyright notice appear in all copies and that both the copyright
  39. X * notice and this permission notice appear in supporting documentation. 
  40. X * No representations are made about the suitability of this software for 
  41. X * any purpose.  It is provided "as is" without express or implied warranty."
  42. X */
  43. X
  44. X#include "fig.h"
  45. X#include "resources.h"
  46. X#include "object.h"
  47. X#include "mode.h"
  48. X#include "u_bound.h"
  49. X
  50. X#define        Ninety_deg        M_PI_2
  51. X#define        One_eighty_deg        M_PI
  52. X#define        Two_seventy_deg        (M_PI + M_PI_2)
  53. X#define        Three_sixty_deg        (M_PI + M_PI)
  54. X#define        half(z1 ,z2)        ((z1+z2)/2.0)
  55. X
  56. X/* macro which rounds DOWN the coordinates depending on point positioning mode */
  57. X#define        floor_coords(x) \
  58. X    if (cur_pointposn != P_ANY) { \
  59. X        tmp_t = ((x) + 1) % posn_rnd[cur_pointposn]; \
  60. X        (x) = (x) - tmp_t; \
  61. X    }
  62. X
  63. X/* macro which rounds UP the coordinates depending on point positioning mode */
  64. X#define        ceil_coords(x) \
  65. X    if (cur_pointposn != P_ANY) { \
  66. X        (x) = (x) + posn_rnd[cur_pointposn]; \
  67. X        tmp_t = (x)%posn_rnd[cur_pointposn]; \
  68. X        (x) = (x) - tmp_t - 1; \
  69. X    }
  70. X
  71. Xstatic void    points_bound();
  72. Xstatic void    int_spline_bound();
  73. Xstatic void    normal_spline_bound();
  74. Xstatic int    tmp_t;
  75. X
  76. Xarc_bound(arc, xmin, ymin, xmax, ymax)
  77. X    F_arc       *arc;
  78. X    int           *xmin, *ymin, *xmax, *ymax;
  79. X{
  80. X    float        alpha, beta;
  81. X    double        dx, dy, radius;
  82. X    int            bx, by, sx, sy;
  83. X    int            half_wd;
  84. X
  85. X    dx = arc->point[0].x - arc->center.x;
  86. X    dy = arc->center.y - arc->point[0].y;
  87. X    alpha = atan2(dy, dx);
  88. X    if (alpha < 0.0)
  89. X    alpha += Three_sixty_deg;
  90. X    /* compute_angle returns value between 0 to 2PI */
  91. X
  92. X    radius = sqrt((double) (dx * dx + dy * dy));
  93. X
  94. X    dx = arc->point[2].x - arc->center.x;
  95. X    dy = arc->center.y - arc->point[2].y;
  96. X    beta = atan2(dy, dx);
  97. X    if (beta < 0.0)
  98. X    beta += Three_sixty_deg;
  99. X
  100. X    bx = max2(arc->point[0].x, arc->point[1].x);
  101. X    bx = max2(arc->point[2].x, bx);
  102. X    by = max2(arc->point[0].y, arc->point[1].y);
  103. X    by = max2(arc->point[2].y, by);
  104. X    sx = min2(arc->point[0].x, arc->point[1].x);
  105. X    sx = min2(arc->point[2].x, sx);
  106. X    sy = min2(arc->point[0].y, arc->point[1].y);
  107. X    sy = min2(arc->point[2].y, sy);
  108. X
  109. X    if (arc->direction == 1) {    /* counter clockwise */
  110. X    if (alpha > beta) {
  111. X        if (alpha <= 0 || 0 <= beta)
  112. X        bx = (int) (arc->center.x + radius + 1.0);
  113. X        if (alpha <= Ninety_deg || Ninety_deg <= beta)
  114. X        sy = (int) (arc->center.y - radius - 1.0);
  115. X        if (alpha <= One_eighty_deg || One_eighty_deg <= beta)
  116. X        sx = (int) (arc->center.x - radius - 1.0);
  117. X        if (alpha <= Two_seventy_deg || Two_seventy_deg <= beta)
  118. X        by = (int) (arc->center.y + radius + 1.0);
  119. X    } else {
  120. X        if (0 <= beta && alpha <= 0)
  121. X        bx = (int) (arc->center.x + radius + 1.0);
  122. X        if (Ninety_deg <= beta && alpha <= Ninety_deg)
  123. X        sy = (int) (arc->center.y - radius - 1.0);
  124. X        if (One_eighty_deg <= beta && alpha <= One_eighty_deg)
  125. X        sx = (int) (arc->center.x - radius - 1.0);
  126. X        if (Two_seventy_deg <= beta && alpha <= Two_seventy_deg)
  127. X        by = (int) (arc->center.y + radius + 1.0);
  128. X    }
  129. X    } else {            /* clockwise     */
  130. X    if (alpha > beta) {
  131. X        if (beta <= 0 && 0 <= alpha)
  132. X        bx = (int) (arc->center.x + radius + 1.0);
  133. X        if (beta <= Ninety_deg && Ninety_deg <= alpha)
  134. X        sy = (int) (arc->center.y - radius - 1.0);
  135. X        if (beta <= One_eighty_deg && One_eighty_deg <= alpha)
  136. X        sx = (int) (arc->center.x - radius - 1.0);
  137. X        if (beta <= Two_seventy_deg && Two_seventy_deg <= alpha)
  138. X        by = (int) (arc->center.y + radius + 1.0);
  139. X    } else {
  140. X        if (0 <= alpha || beta <= 0)
  141. X        bx = (int) (arc->center.x + radius + 1.0);
  142. X        if (Ninety_deg <= alpha || beta <= Ninety_deg)
  143. X        sy = (int) (arc->center.y - radius - 1.0);
  144. X        if (One_eighty_deg <= alpha || beta <= One_eighty_deg)
  145. X        sx = (int) (arc->center.x - radius - 1.0);
  146. X        if (Two_seventy_deg <= alpha || beta <= Two_seventy_deg)
  147. X        by = (int) (arc->center.y + radius + 1.0);
  148. X    }
  149. X    }
  150. X    half_wd = arc->thickness / 2;
  151. X    *xmax = bx + half_wd;
  152. X    *ymax = by + half_wd;
  153. X    *xmin = sx - half_wd;
  154. X    *ymin = sy - half_wd;
  155. X}
  156. X
  157. Xcompound_bound(compound, xmin, ymin, xmax, ymax)
  158. X    F_compound       *compound;
  159. X    int           *xmin, *ymin, *xmax, *ymax;
  160. X{
  161. X    F_arc       *a;
  162. X    F_ellipse       *e;
  163. X    F_compound       *c;
  164. X    F_spline       *s;
  165. X    F_line       *l;
  166. X    F_text       *t;
  167. X    int            bx, by, sx, sy, first = 1;
  168. X    int            llx, lly, urx, ury;
  169. X
  170. X    for (a = compound->arcs; a != NULL; a = a->next) {
  171. X    arc_bound(a, &sx, &sy, &bx, &by);
  172. X    if (first) {
  173. X        first = 0;
  174. X        llx = sx;
  175. X        lly = sy;
  176. X        urx = bx;
  177. X        ury = by;
  178. X    } else {
  179. X        llx = min2(llx, sx);
  180. X        lly = min2(lly, sy);
  181. X        urx = max2(urx, bx);
  182. X        ury = max2(ury, by);
  183. X    }
  184. X    }
  185. X
  186. X    for (c = compound->compounds; c != NULL; c = c->next) {
  187. X    sx = c->nwcorner.x;
  188. X    sy = c->nwcorner.y;
  189. X    bx = c->secorner.x;
  190. X    by = c->secorner.y;
  191. X    if (first) {
  192. X        first = 0;
  193. X        llx = sx;
  194. X        lly = sy;
  195. X        urx = bx;
  196. X        ury = by;
  197. X    } else {
  198. X        llx = min2(llx, sx);
  199. X        lly = min2(lly, sy);
  200. X        urx = max2(urx, bx);
  201. X        ury = max2(ury, by);
  202. X    }
  203. X    }
  204. X
  205. X    for (e = compound->ellipses; e != NULL; e = e->next) {
  206. X    ellipse_bound(e, &sx, &sy, &bx, &by);
  207. X    if (first) {
  208. X        first = 0;
  209. X        llx = sx;
  210. X        lly = sy;
  211. X        urx = bx;
  212. X        ury = by;
  213. X    } else {
  214. X        llx = min2(llx, sx);
  215. X        lly = min2(lly, sy);
  216. X        urx = max2(urx, bx);
  217. X        ury = max2(ury, by);
  218. X    }
  219. X    }
  220. X
  221. X    for (l = compound->lines; l != NULL; l = l->next) {
  222. X    line_bound(l, &sx, &sy, &bx, &by);
  223. X    if (first) {
  224. X        first = 0;
  225. X        llx = sx;
  226. X        lly = sy;
  227. X        urx = bx;
  228. X        ury = by;
  229. X    } else {
  230. X        llx = min2(llx, sx);
  231. X        lly = min2(lly, sy);
  232. X        urx = max2(urx, bx);
  233. X        ury = max2(ury, by);
  234. X    }
  235. X    }
  236. X
  237. X    for (s = compound->splines; s != NULL; s = s->next) {
  238. X    spline_bound(s, &sx, &sy, &bx, &by);
  239. X    if (first) {
  240. X        first = 0;
  241. X        llx = sx;
  242. X        lly = sy;
  243. X        urx = bx;
  244. X        ury = by;
  245. X    } else {
  246. X        llx = min2(llx, sx);
  247. X        lly = min2(lly, sy);
  248. X        urx = max2(urx, bx);
  249. X        ury = max2(ury, by);
  250. X    }
  251. X    }
  252. X
  253. X    for (t = compound->texts; t != NULL; t = t->next) {
  254. X    int    dum;
  255. X    text_bound_actual(t, t->angle, &sx, &sy, &bx, &by, 
  256. X              &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  257. X    if (first) {
  258. X        first = 0;
  259. X        llx = sx;
  260. X        lly = sy;
  261. X        urx = bx;
  262. X        ury = by;
  263. X    } else {
  264. X        llx = min2(llx, sx);
  265. X        lly = min2(lly, sy);
  266. X        urx = max2(urx, bx);
  267. X        ury = max2(ury, by);
  268. X    }
  269. X    }
  270. X
  271. X    /* round the corners to the current positioning grid */
  272. X    floor_coords(llx);
  273. X    floor_coords(lly);
  274. X    ceil_coords(urx);
  275. X    ceil_coords(ury);
  276. X    *xmin = llx;
  277. X    *ymin = lly;
  278. X    *xmax = urx;
  279. X    *ymax = ury;
  280. X}
  281. X
  282. X/* basically, use the code for drawing the ellipse to find its bounds */
  283. X/* From James Tough (see u_draw.c: angle_ellipse() */
  284. X/* include the bounds for the markers (even though we don't know if they 
  285. X   are on or off now */
  286. X
  287. Xellipse_bound(e, xmin, ymin, xmax, ymax)
  288. X    F_ellipse       *e;
  289. X    int           *xmin, *ymin, *xmax, *ymax;
  290. X{
  291. X    int        half_wd;
  292. X    double        c1, c2, c3, c4, c5, c6, v1, cphi, sphi, cphisqr, sphisqr;
  293. X    double        xleft, xright, d, asqr, bsqr;
  294. X    int        yymax, yy=0;
  295. X    float        xcen, ycen, a, b; 
  296. X
  297. X    xcen = e->center.x;
  298. X    ycen = e->center.y;
  299. X    a = e->radiuses.x;
  300. X    b = e->radiuses.y;
  301. X    if (a==0 || b==0)
  302. X        {
  303. X        *xmin = *xmax = xcen;
  304. X        *ymin = *ymax = ycen;
  305. X        return;
  306. X        }
  307. X
  308. X    cphi = cos((double)e->angle);
  309. X    sphi = sin((double)e->angle);
  310. X    cphisqr = cphi*cphi;
  311. X    sphisqr = sphi*sphi;
  312. X    asqr = a*a;
  313. X    bsqr = b*b;
  314. X    
  315. X    c1 = (cphisqr/asqr)+(sphisqr/bsqr);
  316. X    c2 = ((cphi*sphi/asqr)-(cphi*sphi/bsqr))/c1;
  317. X    c3 = (bsqr*cphisqr) + (asqr*sphisqr);
  318. X    yymax = sqrt(c3);
  319. X    c4 = a*b/c3;
  320. X    c5 = 0;
  321. X    v1 = c4*c4;
  322. X    c6 = 2*v1;
  323. X    c3 = c3*v1-v1;
  324. X    /* odd first points */
  325. X    *xmin = *ymin =  100000;
  326. X    *xmax = *ymax = -100000;
  327. X    if (yymax % 2) {
  328. X        d = sqrt(c3);
  329. X        *xmin = min2(*xmin,xcen-d);
  330. X        *xmax = max2(*xmax,xcen+d);
  331. X        *ymin = min2(*ymin,ycen);
  332. X        *ymax = max2(*ymax,ycen);
  333. X        c5 = c2;
  334. X        yy=1;
  335. X    }
  336. X    while (c3>=0) {
  337. X        d = sqrt(c3);
  338. X        xleft = c5-d;
  339. X        xright = c5+d;                        
  340. X        *xmin = min2(*xmin,xcen+xleft);
  341. X        *xmax = max2(*xmax,xcen+xleft);
  342. X        *ymax = max2(*ymax,ycen+yy);
  343. X        *xmin = min2(*xmin,xcen+xright);
  344. X        *xmax = max2(*xmax,xcen+xright);
  345. X        *ymax = max2(*ymax,ycen+yy);
  346. X        *xmin = min2(*xmin,xcen-xright);
  347. X        *xmax = max2(*xmax,xcen-xright);
  348. X        *ymin = min2(*ymin,ycen-yy);
  349. X        *xmin = min2(*xmin,xcen-xleft);
  350. X        *xmax = max2(*xmax,xcen-xleft);
  351. X        *ymin = min2(*ymin,ycen-yy);
  352. X        c5+=c2;
  353. X        v1+=c6;
  354. X        c3-=v1;
  355. X        yy=yy+1;
  356. X    }
  357. X    /* for simplicity, just add half the line thickness to xmax and ymax
  358. X       and subtract half from xmin and ymin */
  359. X    half_wd = e->thickness/2;
  360. X    *xmax += half_wd;
  361. X    *ymax += half_wd;
  362. X    *xmin -= half_wd;
  363. X    *ymin -= half_wd;
  364. X    /* now include the markers because they could be outside the bounds of 
  365. X       the ellipse (+/-3 is (roughly) half the size of the markers (5)) */
  366. X    *xmax = max2(*xmax, max2(e->start.x, e->end.x)+3);
  367. X    *ymax = max2(*ymax, max2(e->start.y, e->end.y)+3);
  368. X    *xmin = min2(*xmin, min2(e->start.x, e->end.x)-3);
  369. X    *ymin = min2(*ymin, min2(e->start.y, e->end.y)-3);
  370. X}
  371. X
  372. Xline_bound(l, xmin, ymin, xmax, ymax)
  373. X    F_line       *l;
  374. X    int           *xmin, *ymin, *xmax, *ymax;
  375. X{
  376. X    points_bound(l->points, (l->thickness / 2), xmin, ymin, xmax, ymax);
  377. X}
  378. X
  379. Xspline_bound(s, xmin, ymin, xmax, ymax)
  380. X    F_spline       *s;
  381. X    int           *xmin, *ymin, *xmax, *ymax;
  382. X{
  383. X    if (int_spline(s)) {
  384. X    int_spline_bound(s, xmin, ymin, xmax, ymax);
  385. X    } else {
  386. X    normal_spline_bound(s, xmin, ymin, xmax, ymax);
  387. X    }
  388. X}
  389. X
  390. Xstatic void
  391. Xint_spline_bound(s, xmin, ymin, xmax, ymax)
  392. X    F_spline       *s;
  393. X    int           *xmin, *ymin, *xmax, *ymax;
  394. X{
  395. X    F_point       *p1, *p2;
  396. X    F_control       *cp1, *cp2;
  397. X    float        x0, y0, x1, y1, x2, y2, x3, y3, sx1, sy1, sx2, sy2;
  398. X    float        tx, ty, tx1, ty1, tx2, ty2;
  399. X    float        sx, sy, bx, by;
  400. X    int            half_wd;
  401. X
  402. X    half_wd = s->thickness / 2;
  403. X    p1 = s->points;
  404. X    sx = bx = p1->x;
  405. X    sy = by = p1->y;
  406. X    cp1 = s->controls;
  407. X    for (p2 = p1->next, cp2 = cp1->next; p2 != NULL;
  408. X     p1 = p2, cp1 = cp2, p2 = p2->next, cp2 = cp2->next) {
  409. X    x0 = p1->x;
  410. X    y0 = p1->y;
  411. X    x1 = cp1->rx;
  412. X    y1 = cp1->ry;
  413. X    x2 = cp2->lx;
  414. X    y2 = cp2->ly;
  415. X    x3 = p2->x;
  416. X    y3 = p2->y;
  417. X    tx = half(x1, x2);
  418. X    ty = half(y1, y2);
  419. X    sx1 = half(x0, x1);
  420. X    sy1 = half(y0, y1);
  421. X    sx2 = half(sx1, tx);
  422. X    sy2 = half(sy1, ty);
  423. X    tx2 = half(x2, x3);
  424. X    ty2 = half(y2, y3);
  425. X    tx1 = half(tx2, tx);
  426. X    ty1 = half(ty2, ty);
  427. X
  428. X    sx = min2(x0, sx);
  429. X    sy = min2(y0, sy);
  430. X    sx = min2(sx1, sx);
  431. X    sy = min2(sy1, sy);
  432. X    sx = min2(sx2, sx);
  433. X    sy = min2(sy2, sy);
  434. X    sx = min2(tx1, sx);
  435. X    sy = min2(ty1, sy);
  436. X    sx = min2(tx2, sx);
  437. X    sy = min2(ty2, sy);
  438. X    sx = min2(x3, sx);
  439. X    sy = min2(y3, sy);
  440. X
  441. X    bx = max2(x0, bx);
  442. X    by = max2(y0, by);
  443. X    bx = max2(sx1, bx);
  444. X    by = max2(sy1, by);
  445. X    bx = max2(sx2, bx);
  446. X    by = max2(sy2, by);
  447. X    bx = max2(tx1, bx);
  448. X    by = max2(ty1, by);
  449. X    bx = max2(tx2, bx);
  450. X    by = max2(ty2, by);
  451. X    bx = max2(x3, bx);
  452. X    by = max2(y3, by);
  453. X    }
  454. X    *xmin = round(sx) - half_wd;
  455. X    *ymin = round(sy) - half_wd;
  456. X    *xmax = round(bx) + half_wd;
  457. X    *ymax = round(by) + half_wd;
  458. X}
  459. X
  460. Xstatic void
  461. Xnormal_spline_bound(s, xmin, ymin, xmax, ymax)
  462. X    F_spline       *s;
  463. X    int           *xmin, *ymin, *xmax, *ymax;
  464. X{
  465. X    F_point       *p;
  466. X    float        cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
  467. X    float        x1, y1, x2, y2, sx, sy, bx, by;
  468. X    float        px, py, qx, qy;
  469. X    int            half_wd;
  470. X
  471. X    half_wd = s->thickness / 2;
  472. X    p = s->points;
  473. X    x1 = p->x;
  474. X    y1 = p->y;
  475. X    p = p->next;
  476. X    x2 = p->x;
  477. X    y2 = p->y;
  478. X    cx1 = (x1 + x2) / 2.0;
  479. X    cy1 = (y1 + y2) / 2.0;
  480. X    cx2 = (cx1 + x2) / 2.0;
  481. X    cy2 = (cy1 + y2) / 2.0;
  482. X    if (closed_spline(s)) {
  483. X    x1 = (cx1 + x1) / 2.0;
  484. X    y1 = (cy1 + y1) / 2.0;
  485. X    }
  486. X    sx = min2(x1, cx2);
  487. X    sy = min2(y1, cy2);
  488. X    bx = max2(x1, cx2);
  489. X    by = max2(y1, cy2);
  490. X
  491. X    for (p = p->next; p != NULL; p = p->next) {
  492. X    x1 = x2;
  493. X    y1 = y2;
  494. X    x2 = p->x;
  495. X    y2 = p->y;
  496. X    cx4 = (x1 + x2) / 2.0;
  497. X    cy4 = (y1 + y2) / 2.0;
  498. X    cx3 = (x1 + cx4) / 2.0;
  499. X    cy3 = (y1 + cy4) / 2.0;
  500. X    cx2 = (cx4 + x2) / 2.0;
  501. X    cy2 = (cy4 + y2) / 2.0;
  502. X
  503. X    px = min2(cx2, cx3);
  504. X    py = min2(cy2, cy3);
  505. X    qx = max2(cx2, cx3);
  506. X    qy = max2(cy2, cy3);
  507. X
  508. X    sx = min2(sx, px);
  509. X    sy = min2(sy, py);
  510. X    bx = max2(bx, qx);
  511. X    by = max2(by, qy);
  512. X    }
  513. X    if (closed_spline(s)) {
  514. X    *xmin = round(sx) - half_wd;
  515. X    *ymin = round(sy) - half_wd;
  516. X    *xmax = round(bx) + half_wd;
  517. X    *ymax = round(by) + half_wd;
  518. X    } else {
  519. X    *xmin = round(min2(sx, x2)) - half_wd;
  520. X    *ymin = round(min2(sy, y2)) - half_wd;
  521. X    *xmax = round(max2(bx, x2)) + half_wd;
  522. X    *ymax = round(max2(by, y2)) + half_wd;
  523. X    }
  524. X}
  525. X
  526. X/* This procedure calculates the bounding box for text that is displayed
  527. X   horizontally or vertically (all text on the canvas in otherwords)
  528. X   Use text_bound_actual() to decide whether or not text would be off
  529. X   the PRINTED page (if rotated) */
  530. X
  531. Xtext_bound(t, xmin, ymin, xmax, ymax)
  532. X    F_text       *t;
  533. X    int           *xmin, *ymin, *xmax, *ymax;
  534. X{
  535. X    int            length, dx, dy, mx, my, dum;
  536. X    double        angle;
  537. X
  538. X    angle = t->angle;
  539. X    /* fix the angle to one of four - 0, 90, 180 or 270 */
  540. X    if (angle < M_PI_2 - 0.001)
  541. X    angle = 0.0;
  542. X    else if (angle < M_PI - 0.001)
  543. X    angle = M_PI_2;
  544. X    else if (angle < 3*M_PI_2 - 0.001)
  545. X    angle = M_PI;
  546. X    else
  547. X    angle = 3*M_PI_2;
  548. X    text_bound_actual(t, angle, xmin, ymin, xmax, ymax,
  549. X          &dum, &dum, &dum, &dum, &dum, &dum, &dum, &dum);
  550. X}
  551. X
  552. X/* this procedure calculates the bouding box for text ASSUMING that it 
  553. X   will be DISPLAYED rotated (if it has any rotation angle).
  554. X   The actual corners of the rectangle are returned in (rx1,ry1)...(rx4,ry4)
  555. X   The min and max x and y are returned in (xmin, ymin) (xmax, ymax)
  556. X*/
  557. X
  558. Xtext_bound_actual(t, angle, xmin, ymin, xmax, ymax, 
  559. X          rx1, ry1, rx2, ry2, rx3, ry3, rx4, ry4)
  560. X    F_text       *t;
  561. X    double        angle;
  562. X    int           *xmin, *ymin, *xmax, *ymax;
  563. X    int           *rx1,*ry1, *rx2,*ry2, *rx3,*ry3, *rx4,*ry4;
  564. X{
  565. X    int            h, l;
  566. X    int            x1,y1, x2,y2, x3,y3, x4,y4;
  567. X    double        cost, sint;
  568. X    double        lcost, lsint, hcost, hsint;
  569. X
  570. X    l = text_length(t);
  571. X    h = t->height;
  572. X    cost = cos((double)angle);
  573. X    sint = sin((double)angle);
  574. X    lcost = round(l*cost);
  575. X    lsint = round(l*sint);
  576. X    hcost = round(h*cost);
  577. X    hsint = round(h*sint);
  578. X    x1 = t->base_x;
  579. X    y1 = t->base_y;
  580. X    if (t->type == T_CENTER_JUSTIFIED) {
  581. X    x1 = t->base_x - round((l/2)*cost);
  582. X    y1 = t->base_y + round((l/2)*sint);
  583. X    x2 = x1 + lcost;
  584. X    y2 = y1 - lsint;
  585. X    }
  586. X    else if (t->type == T_RIGHT_JUSTIFIED) {
  587. X    x1 = t->base_x - lcost;
  588. X    y1 = t->base_y + lsint;
  589. X    x2 = t->base_x;
  590. X    y2 = t->base_y;
  591. X    }
  592. X    else {
  593. X    x2 = x1 + lcost;
  594. X    y2 = y1 - lsint;
  595. X    }
  596. X    x4 = x1 - hsint;
  597. X    y4 = y1 - hcost;
  598. X    x3 = x2 - hsint;
  599. X    y3 = y2 - hcost;
  600. X
  601. X    *xmin = min2(x1,min2(x2,min2(x3,x4)));
  602. X    *xmax = max2(x1,max2(x2,max2(x3,x4)));
  603. X    *ymin = min2(y1,min2(y2,min2(y3,y4)));
  604. X    *ymax = max2(y1,max2(y2,max2(y3,y4)));
  605. X    *rx1=x1; *ry1=y1;
  606. X    *rx2=x2; *ry2=y2;
  607. X    *rx3=x3; *ry3=y3;
  608. X    *rx4=x4; *ry4=y4;
  609. X}
  610. X
  611. X/* this procedure calculates the union of the two types of bounding boxes */
  612. X/* this is usually called by the redisplay code which needs the bounding
  613. X   rectangle if the user is displaying the textoutline */
  614. X
  615. Xtext_bound_both(t, xmin, ymin, xmax, ymax,
  616. X          rx1, ry1, rx2, ry2, rx3, ry3, rx4, ry4)
  617. X    F_text      *t;
  618. X    int          *xmin, *ymin, *xmax, *ymax;
  619. X    int           *rx1,*ry1, *rx2,*ry2, *rx3,*ry3, *rx4,*ry4;
  620. X{
  621. X    int           xmin1, ymin1, xmax1, ymax1;
  622. X    int           xmin2, ymin2, xmax2, ymax2;
  623. X    int           dum;
  624. X    text_bound_actual(t, t->angle, &xmin1, &ymin1, &xmax1, &ymax1, 
  625. X          rx1, ry1, rx2, ry2, rx3, ry3, rx4, ry4);
  626. X    text_bound(t, &xmin2, &ymin2, &xmax2, &ymax2);
  627. X    *xmin = min2(xmin1,xmin2);
  628. X    *xmax = max2(xmax1,xmax2);
  629. X    *ymin = min2(ymin1,ymin2);
  630. X    *ymax = max2(ymax1,ymax2);
  631. X}
  632. X
  633. Xstatic void
  634. Xpoints_bound(points, half_wd, xmin, ymin, xmax, ymax)
  635. X    F_point       *points;
  636. X    int            half_wd;
  637. X    int           *xmin, *ymin, *xmax, *ymax;
  638. X{
  639. X    int            bx, by, sx, sy;
  640. X    F_point       *p;
  641. X
  642. X    bx = sx = points->x;
  643. X    by = sy = points->y;
  644. X    for (p = points->next; p != NULL; p = p->next) {
  645. X    sx = min2(sx, p->x);
  646. X    sy = min2(sy, p->y);
  647. X    bx = max2(bx, p->x);
  648. X    by = max2(by, p->y);
  649. X    }
  650. X    *xmin = sx - half_wd;
  651. X    *ymin = sy - half_wd;
  652. X    *xmax = bx + half_wd;
  653. X    *ymax = by + half_wd;
  654. X}
  655. X
  656. Xint
  657. Xoverlapping(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2)
  658. X    int            xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2;
  659. X{
  660. X    if (xmin1 < xmin2)
  661. X    if (ymin1 < ymin2)
  662. X        return (xmax1 >= xmin2 && ymax1 >= ymin2);
  663. X    else
  664. X        return (xmax1 >= xmin2 && ymin1 <= ymax2);
  665. X    else if (ymin1 < ymin2)
  666. X    return (xmin1 <= xmax2 && ymax1 >= ymin2);
  667. X    else
  668. X    return (xmin1 <= xmax2 && ymin1 <= ymax2);
  669. X}
  670. END_OF_FILE
  671. if test 16661 -ne `wc -c <'u_bound.c'`; then
  672.     echo shar: \"'u_bound.c'\" unpacked with wrong size!
  673. fi
  674. # end of 'u_bound.c'
  675. fi
  676. if test -f 'u_redraw.c' -a "${1}" != "-c" ; then 
  677.   echo shar: Will not clobber existing file \"'u_redraw.c'\"
  678. else
  679. echo shar: Extracting \"'u_redraw.c'\" \(14201 characters\)
  680. sed "s/^X//" >'u_redraw.c' <<'END_OF_FILE'
  681. X/*
  682. X * FIG : Facility for Interactive Generation of figures
  683. X * Copyright (c) 1985 by Supoj Sutanthavibul
  684. X *
  685. X * "Permission to use, copy, modify, distribute, and sell this software and its
  686. X * documentation for any purpose is hereby granted without fee, provided that
  687. X * the above copyright notice appear in all copies and that both the copyright
  688. X * notice and this permission notice appear in supporting documentation. 
  689. X * No representations are made about the suitability of this software for 
  690. X * any purpose.  It is provided "as is" without express or implied warranty."
  691. X */
  692. X
  693. X#include "fig.h"
  694. X#include "resources.h"
  695. X#include "object.h"
  696. X#include "paintop.h"
  697. X#include "w_setup.h"
  698. X#include "w_util.h"
  699. X#include "w_zoom.h"
  700. X
  701. X/*
  702. X * Support for rendering based on correct object depth.     A simple depth based
  703. X * caching scheme; anything more will require major surgery on the object
  704. X * data structures that will percolate throughout program.
  705. X *
  706. X * One ``counts'' structure for each object type at each nesting depth from 0
  707. X * to MAXDEPTH - 1.  We track both the number of objects per type per depth,
  708. X * as well as the number of objects drawn so far per type per depth to cut
  709. X * down on search loop overhead.
  710. X */
  711. X
  712. Xstruct counts {
  713. X    unsigned        num_arcs;    /* # arcs at this depth */
  714. X    unsigned        num_lines;    /* # lines at this depth */
  715. X    unsigned        num_ellipses;    /* # ellipses at this depth */
  716. X    unsigned        num_splines;/* # splines at this depth */
  717. X    unsigned        num_texts;    /* # texts at this depth */
  718. X    unsigned        cnt_arcs;    /* count of arcs drawn at this depth */
  719. X    unsigned        cnt_lines;    /* count of lines drawn at this depth */
  720. X    unsigned        cnt_ellipses;    /* count of ellipses drawn at this
  721. X                     * depth */
  722. X    unsigned        cnt_splines;/* count of splines drawn at this depth */
  723. X    unsigned        cnt_texts;    /* count of texts drawn at this depth */
  724. X};
  725. X
  726. X/*
  727. X * The array of ``counts'' structures.    All objects at depth >= MAXDEPTH are
  728. X * accounted for in the counts[MAXDEPTH] entry.
  729. X */
  730. X
  731. Xstruct counts    counts[MAXDEPTH + 1];
  732. X
  733. X/*
  734. X * Function to clear the array of object counts prior to each redraw.
  735. X */
  736. X
  737. Xstatic void
  738. Xclearcounts()
  739. X{
  740. X    register struct counts *cp;
  741. X
  742. X    for (cp = &counts[0]; cp <= &counts[MAXDEPTH]; ++cp) {
  743. X    cp->num_arcs = 0;
  744. X    cp->num_lines = 0;
  745. X    cp->num_ellipses = 0;
  746. X    cp->num_splines = 0;
  747. X    cp->num_texts = 0;
  748. X    cp->cnt_arcs = 0;
  749. X    cp->cnt_lines = 0;
  750. X    cp->cnt_ellipses = 0;
  751. X    cp->cnt_splines = 0;
  752. X    cp->cnt_texts = 0;
  753. X    }
  754. X}
  755. X
  756. Xunsigned int    max_depth;
  757. X
  758. Xredisplay_objects(objects)
  759. X    F_compound       *objects;
  760. X{
  761. X    int            depth;
  762. X
  763. X    if (objects == NULL)
  764. X    return;
  765. X
  766. X    /*
  767. X     * Clear object counts, and then get the max. depth of any object from
  768. X     * the max. depths of each object type in the top level compound.
  769. X     */
  770. X
  771. X    clearcounts();
  772. X    max_depth = max2(compound_depths(objects->compounds),
  773. X          max2(text_depths(objects->texts),
  774. X               spline_depths(objects->splines)));
  775. X    max_depth = max2(arc_depths(objects->arcs),
  776. X             max2(line_depths(objects->lines),
  777. X              max2(ellipse_depths(objects->ellipses),
  778. X                   max_depth)));
  779. X
  780. X    /*
  781. X     * A new outer loop, executing once per depth level from max_depth down
  782. X     * to 0 (negative depths are not supported).  The code inside the loop is
  783. X     * the original code for redisplay_objects.
  784. X     */
  785. X
  786. X    for (depth = max_depth; depth >= 0; --depth) {
  787. X    redisplay_arcobject(objects->arcs, depth);
  788. X    redisplay_compoundobject(objects->compounds, depth);
  789. X    redisplay_ellipseobject(objects->ellipses, depth);
  790. X    redisplay_lineobject(objects->lines, depth);
  791. X    redisplay_splineobject(objects->splines, depth);
  792. X    redisplay_textobject(objects->texts, depth);
  793. X    }
  794. X
  795. X    /*
  796. X     * Point markers and compounds, not being ``real objects'', are handled
  797. X     * outside the depth loop.
  798. X     */
  799. X
  800. X    /* show the markers if they are on */
  801. X    toggle_markers_in_compound(objects);
  802. X}
  803. X
  804. X/*
  805. X * Find the maximum depth of any arc, recording the number of arcs per each
  806. X * level along the way.
  807. X */
  808. X
  809. Xint
  810. Xarc_depths(arcs)
  811. X    F_arc       *arcs;
  812. X{
  813. X    int            maxdepth = 0;
  814. X    F_arc       *fp;
  815. X
  816. X    for (fp = arcs; fp != NULL; fp = fp->next) {
  817. X    if (maxdepth < fp->depth)
  818. X        maxdepth = fp->depth;
  819. X
  820. X    ++counts[min2(fp->depth, MAXDEPTH)].num_arcs;
  821. X    }
  822. X    return maxdepth;
  823. X}
  824. X
  825. X/*
  826. X * Find the maximum depth of any line, recording the number of lines per each
  827. X * level along the way.
  828. X */
  829. X
  830. Xint
  831. Xline_depths(lines)
  832. X    F_line       *lines;
  833. X{
  834. X    int            maxdepth = 0;
  835. X    F_line       *fp;
  836. X
  837. X    for (fp = lines; fp != NULL; fp = fp->next) {
  838. X    if (maxdepth < fp->depth)
  839. X        maxdepth = fp->depth;
  840. X
  841. X    ++counts[min2(fp->depth, MAXDEPTH)].num_lines;
  842. X    }
  843. X    return maxdepth;
  844. X}
  845. X
  846. X/*
  847. X * Find the maximum depth of any ellipse, recording the number of ellipses
  848. X * per each level along the way.
  849. X */
  850. X
  851. Xint
  852. Xellipse_depths(ellipses)
  853. X    F_ellipse       *ellipses;
  854. X{
  855. X    int            maxdepth = 0;
  856. X    F_ellipse       *fp;
  857. X
  858. X    for (fp = ellipses; fp != NULL; fp = fp->next) {
  859. X    if (maxdepth < fp->depth)
  860. X        maxdepth = fp->depth;
  861. X
  862. X    ++counts[min2(fp->depth, MAXDEPTH)].num_ellipses;
  863. X    }
  864. X    return maxdepth;
  865. X}
  866. X
  867. X/*
  868. X * Find the maximum depth of any spline, recording the number of splines per
  869. X * each level along the way.
  870. X */
  871. X
  872. Xint
  873. Xspline_depths(splines)
  874. X    F_spline       *splines;
  875. X{
  876. X    int            maxdepth = 0;
  877. X    F_spline       *fp;
  878. X
  879. X    for (fp = splines; fp != NULL; fp = fp->next) {
  880. X    if (maxdepth < fp->depth)
  881. X        maxdepth = fp->depth;
  882. X
  883. X    ++counts[min2(fp->depth, MAXDEPTH)].num_splines;
  884. X    }
  885. X    return maxdepth;
  886. X}
  887. X
  888. X/*
  889. X * Find the maximum depth of any text, recording the number of texts per each
  890. X * level along the way.
  891. X */
  892. X
  893. Xint
  894. Xtext_depths(texts)
  895. X    F_text       *texts;
  896. X{
  897. X    int            maxdepth = 0;
  898. X    F_text       *fp;
  899. X
  900. X    for (fp = texts; fp != NULL; fp = fp->next) {
  901. X    if (maxdepth < fp->depth)
  902. X        maxdepth = fp->depth;
  903. X
  904. X    ++counts[min2(fp->depth, MAXDEPTH)].num_texts;
  905. X    }
  906. X    return maxdepth;
  907. X}
  908. X
  909. X/*
  910. X * Find the maximum depth of any of the objects contained in the compound.
  911. X */
  912. X
  913. Xint
  914. Xcompound_depths(compounds)
  915. X    F_compound       *compounds;
  916. X{
  917. X    int            maxdepth = 0;
  918. X    F_compound       *fp;
  919. X
  920. X    for (fp = compounds; fp != NULL; fp = fp->next) {
  921. X    maxdepth = max2(compound_depths(fp->compounds),
  922. X              max2(text_depths(fp->texts),
  923. X               max2(spline_depths(fp->splines),
  924. X                maxdepth)));
  925. X    maxdepth = max2(arc_depths(fp->arcs),
  926. X            max2(line_depths(fp->lines),
  927. X                 max2(ellipse_depths(fp->ellipses),
  928. X                  maxdepth)));
  929. X    }
  930. X    return maxdepth;
  931. X}
  932. X
  933. X/*
  934. X * Redisplay a list of arcs.  Only display arcs of the correct depth.
  935. X * For each arc drawn, update the count for the appropriate depth in
  936. X * the counts array.
  937. X */
  938. X
  939. Xredisplay_arcobject(arcs, depth)
  940. X    F_arc       *arcs;
  941. X    int            depth;
  942. X{
  943. X    F_arc       *arc;
  944. X    struct counts  *cp = &counts[min2(depth, MAXDEPTH)];
  945. X
  946. X    arc = arcs;
  947. X    while (arc != NULL && cp->cnt_arcs < cp->num_arcs) {
  948. X    if (depth == arc->depth) {
  949. X        draw_arc(arc, PAINT);
  950. X        ++cp->cnt_arcs;
  951. X        }
  952. X    arc = arc->next;
  953. X    }
  954. X}
  955. X
  956. X/*
  957. X * Redisplay a list of ellipses.  Only display ellipses of the correct depth
  958. X * For each ellipse drawn, update the count for the
  959. X * appropriate depth in the counts array.
  960. X */
  961. X
  962. Xredisplay_ellipseobject(ellipses, depth)
  963. X    F_ellipse       *ellipses;
  964. X    int            depth;
  965. X{
  966. X    F_ellipse       *ep;
  967. X    struct counts  *cp = &counts[min2(depth, MAXDEPTH)];
  968. X
  969. X
  970. X    ep = ellipses;
  971. X    while (ep != NULL && cp->cnt_ellipses < cp->num_ellipses) {
  972. X    if (depth == ep->depth) {
  973. X        draw_ellipse(ep, PAINT);
  974. X        ++cp->cnt_ellipses;
  975. X        }
  976. X    ep = ep->next;
  977. X    }
  978. X}
  979. X
  980. X/*
  981. X * Redisplay a list of lines.  Only display lines of the correct depth.
  982. X * For each line drawn, update the count for the appropriate
  983. X * depth in the counts array.
  984. X */
  985. X
  986. Xredisplay_lineobject(lines, depth)
  987. X    F_line       *lines;
  988. X    int            depth;
  989. X{
  990. X    F_line       *lp;
  991. X    struct counts  *cp = &counts[min2(depth, MAXDEPTH)];
  992. X
  993. X
  994. X    lp = lines;
  995. X    while (lp != NULL && cp->cnt_lines < cp->num_lines) {
  996. X    if (depth == lp->depth) {
  997. X        draw_line(lp, PAINT);
  998. X        ++cp->cnt_lines;
  999. X        }
  1000. X    lp = lp->next;
  1001. X    }
  1002. X}
  1003. X
  1004. X/*
  1005. X * Redisplay a list of splines.     Only display splines of the correct depth
  1006. X * For each spline drawn, update the count for the
  1007. X * appropriate depth in the counts array.
  1008. X */
  1009. X
  1010. Xredisplay_splineobject(splines, depth)
  1011. X    F_spline       *splines;
  1012. X    int            depth;
  1013. X{
  1014. X    F_spline       *spline;
  1015. X    struct counts  *cp = &counts[min2(depth, MAXDEPTH)];
  1016. X
  1017. X    spline = splines;
  1018. X    while (spline != NULL && cp->cnt_splines < cp->num_splines) {
  1019. X    if (depth == spline->depth) {
  1020. X        draw_spline(spline, PAINT);
  1021. X        ++cp->cnt_splines;
  1022. X        }
  1023. X    spline = spline->next;
  1024. X    }
  1025. X}
  1026. X
  1027. X/*
  1028. X * Redisplay a list of texts.  Only display texts of the correct depth.     For
  1029. X * each text drawn, update the count for the appropriate depth in the counts
  1030. X * array.
  1031. X */
  1032. X
  1033. Xredisplay_textobject(texts, depth)
  1034. X    F_text       *texts;
  1035. X    int            depth;
  1036. X{
  1037. X    F_text       *text;
  1038. X    struct counts  *cp = &counts[min2(depth, MAXDEPTH)];
  1039. X
  1040. X    text = texts;
  1041. X    while (text != NULL && cp->cnt_texts < cp->num_texts) {
  1042. X    if (depth == text->depth) {
  1043. X        draw_text(text, PAINT);
  1044. X        ++cp->cnt_texts;
  1045. X    }
  1046. X    text = text->next;
  1047. X    }
  1048. X}
  1049. X
  1050. X/*
  1051. X * Redisplay a list of compounds at a current depth.  Basically just farm the
  1052. X * work out to the objects contained in the compound.
  1053. X */
  1054. X
  1055. Xredisplay_compoundobject(compounds, depth)
  1056. X    F_compound       *compounds;
  1057. X    int            depth;
  1058. X{
  1059. X    F_compound       *c;
  1060. X
  1061. X    for (c = compounds; c != NULL; c = c->next) {
  1062. X    redisplay_arcobject(c->arcs, depth);
  1063. X    redisplay_compoundobject(c->compounds, depth);
  1064. X    redisplay_ellipseobject(c->ellipses, depth);
  1065. X    redisplay_lineobject(c->lines, depth);
  1066. X    redisplay_splineobject(c->splines, depth);
  1067. X    redisplay_textobject(c->texts, depth);
  1068. X    }
  1069. X}
  1070. X
  1071. X/*
  1072. X * Redisplay the entire drawing.
  1073. X */
  1074. Xredisplay_canvas()
  1075. X{
  1076. X    redisplay_region(0, 0, CANVAS_WD, CANVAS_HT);
  1077. X}
  1078. X
  1079. Xredisplay_region(xmin, ymin, xmax, ymax)
  1080. X    int            xmin, ymin, xmax, ymax;
  1081. X{
  1082. X    set_temp_cursor(wait_cursor);
  1083. X    /* kludge so that markers are redrawn */
  1084. X    xmin -= 8;
  1085. X    ymin -= 8;
  1086. X    xmax += 8;
  1087. X    ymax += 8;
  1088. X    set_clip_window(xmin, ymin, xmax, ymax);
  1089. X    clear_canvas();
  1090. X    redisplay_objects(&objects);
  1091. X    reset_clip_window();
  1092. X    reset_cursor();
  1093. X}
  1094. X
  1095. Xredisplay_zoomed_region(xmin, ymin, xmax, ymax)
  1096. X    int            xmin, ymin, xmax, ymax;
  1097. X{
  1098. X    redisplay_region(ZOOMX(xmin), ZOOMY(ymin), ZOOMX(xmax), ZOOMY(ymax));
  1099. X}
  1100. X
  1101. Xredisplay_ellipse(e)
  1102. X    F_ellipse       *e;
  1103. X{
  1104. X    int            xmin, ymin, xmax, ymax;
  1105. X
  1106. X    ellipse_bound(e, &xmin, &ymin, &xmax, &ymax);
  1107. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1108. X}
  1109. X
  1110. Xredisplay_ellipses(e1, e2)
  1111. X    F_ellipse       *e1, *e2;
  1112. X{
  1113. X    int            xmin1, ymin1, xmax1, ymax1;
  1114. X    int            xmin2, ymin2, xmax2, ymax2;
  1115. X
  1116. X    ellipse_bound(e1, &xmin1, &ymin1, &xmax1, &ymax1);
  1117. X    ellipse_bound(e2, &xmin2, &ymin2, &xmax2, &ymax2);
  1118. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2);
  1119. X}
  1120. X
  1121. Xredisplay_arc(a)
  1122. X    F_arc       *a;
  1123. X{
  1124. X    int            xmin, ymin, xmax, ymax;
  1125. X
  1126. X    arc_bound(a, &xmin, &ymin, &xmax, &ymax);
  1127. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1128. X}
  1129. X
  1130. Xredisplay_arcs(a1, a2)
  1131. X    F_arc       *a1, *a2;
  1132. X{
  1133. X    int            xmin1, ymin1, xmax1, ymax1;
  1134. X    int            xmin2, ymin2, xmax2, ymax2;
  1135. X
  1136. X    arc_bound(a1, &xmin1, &ymin1, &xmax1, &ymax1);
  1137. X    arc_bound(a2, &xmin2, &ymin2, &xmax2, &ymax2);
  1138. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2);
  1139. X}
  1140. X
  1141. Xredisplay_spline(s)
  1142. X    F_spline       *s;
  1143. X{
  1144. X    int            xmin, ymin, xmax, ymax;
  1145. X
  1146. X    spline_bound(s, &xmin, &ymin, &xmax, &ymax);
  1147. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1148. X}
  1149. X
  1150. Xredisplay_splines(s1, s2)
  1151. X    F_spline       *s1, *s2;
  1152. X{
  1153. X    int            xmin1, ymin1, xmax1, ymax1;
  1154. X    int            xmin2, ymin2, xmax2, ymax2;
  1155. X
  1156. X    spline_bound(s1, &xmin1, &ymin1, &xmax1, &ymax1);
  1157. X    spline_bound(s2, &xmin2, &ymin2, &xmax2, &ymax2);
  1158. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2);
  1159. X}
  1160. X
  1161. Xredisplay_line(l)
  1162. X    F_line       *l;
  1163. X{
  1164. X    int            xmin, ymin, xmax, ymax;
  1165. X
  1166. X    line_bound(l, &xmin, &ymin, &xmax, &ymax);
  1167. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1168. X}
  1169. X
  1170. Xredisplay_lines(l1, l2)
  1171. X    F_line       *l1, *l2;
  1172. X{
  1173. X    int            xmin1, ymin1, xmax1, ymax1;
  1174. X    int            xmin2, ymin2, xmax2, ymax2;
  1175. X
  1176. X    line_bound(l1, &xmin1, &ymin1, &xmax1, &ymax1);
  1177. X    line_bound(l2, &xmin2, &ymin2, &xmax2, &ymax2);
  1178. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2);
  1179. X}
  1180. X
  1181. Xredisplay_compound(c)
  1182. X    F_compound       *c;
  1183. X{
  1184. X    redisplay_zoomed_region(c->nwcorner.x, c->nwcorner.y,
  1185. X                c->secorner.x, c->secorner.y);
  1186. X}
  1187. X
  1188. Xredisplay_compounds(c1, c2)
  1189. X    F_compound       *c1, *c2;
  1190. X{
  1191. X    redisplay_regions(c1->nwcorner.x, c1->nwcorner.y,
  1192. X              c1->secorner.x, c1->secorner.y,
  1193. X              c2->nwcorner.x, c2->nwcorner.y,
  1194. X              c2->secorner.x, c2->secorner.y);
  1195. X}
  1196. X
  1197. Xredisplay_text(t)
  1198. X    F_text       *t;
  1199. X{
  1200. X    int            xmin, ymin, xmax, ymax;
  1201. X    int            dum;
  1202. X
  1203. X    if (appres.textoutline) {
  1204. X    text_bound_both(t, &xmin, &ymin, &xmax, &ymax,
  1205. X            &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  1206. X    } else {
  1207. X    text_bound(t, &xmin, &ymin, &xmax, &ymax);
  1208. X    }
  1209. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1210. X}
  1211. X
  1212. Xredisplay_texts(t1, t2)
  1213. X    F_text       *t1, *t2;
  1214. X{
  1215. X    int            xmin1, ymin1, xmax1, ymax1;
  1216. X    int            xmin2, ymin2, xmax2, ymax2;
  1217. X    int            dum;
  1218. X
  1219. X    if (appres.textoutline) {
  1220. X    text_bound_both(t1, &xmin1, &ymin1, &xmax1, &ymax1,
  1221. X            &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  1222. X    text_bound_both(t2, &xmin2, &ymin2, &xmax2, &ymax2,
  1223. X            &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  1224. X    } else {
  1225. X    text_bound(t1, &xmin1, &ymin1, &xmax1, &ymax1);
  1226. X    text_bound(t2, &xmin2, &ymin2, &xmax2, &ymax2);
  1227. X    }
  1228. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2);
  1229. X}
  1230. X
  1231. Xredisplay_regions(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2)
  1232. X    int            xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2;
  1233. X{
  1234. X    if (xmin1 == xmin2 && ymin1 == ymin2 && xmax1 == xmax2 && ymax1 == ymax2) {
  1235. X    redisplay_zoomed_region(xmin1, ymin1, xmax1, ymax1);
  1236. X    return;
  1237. X    }
  1238. X    /* below is easier than sending clip rectangle array to X */
  1239. X    if (overlapping(xmin1, ymin1, xmax1, ymax1, xmin2, ymin2, xmax2, ymax2)) {
  1240. X    redisplay_zoomed_region(min2(xmin1, xmin2), min2(ymin1, ymin2),
  1241. X                max2(xmax1, xmax2), max2(ymax1, ymax2));
  1242. X    } else {
  1243. X    redisplay_zoomed_region(xmin1, ymin1, xmax1, ymax1);
  1244. X    redisplay_zoomed_region(xmin2, ymin2, xmax2, ymax2);
  1245. X    }
  1246. X}
  1247. END_OF_FILE
  1248. if test 14201 -ne `wc -c <'u_redraw.c'`; then
  1249.     echo shar: \"'u_redraw.c'\" unpacked with wrong size!
  1250. fi
  1251. # end of 'u_redraw.c'
  1252. fi
  1253. if test -f 'u_undo.c' -a "${1}" != "-c" ; then 
  1254.   echo shar: Will not clobber existing file \"'u_undo.c'\"
  1255. else
  1256. echo shar: Extracting \"'u_undo.c'\" \(17567 characters\)
  1257. sed "s/^X//" >'u_undo.c' <<'END_OF_FILE'
  1258. X/*
  1259. X * FIG : Facility for Interactive Generation of figures
  1260. X * Copyright (c) 1985 by Supoj Sutanthavibul
  1261. X *
  1262. X * "Permission to use, copy, modify, distribute, and sell this software and its
  1263. X * documentation for any purpose is hereby granted without fee, provided that
  1264. X * the above copyright notice appear in all copies and that both the copyright
  1265. X * notice and this permission notice appear in supporting documentation. 
  1266. X * No representations are made about the suitability of this software for 
  1267. X * any purpose.  It is provided "as is" without express or implied warranty."
  1268. X */
  1269. X
  1270. X/**************** IMPORTS ****************/
  1271. X
  1272. X#include "fig.h"
  1273. X#include "resources.h"
  1274. X#include "mode.h"
  1275. X#include "object.h"
  1276. X#include "paintop.h"
  1277. X#include "u_draw.h"
  1278. X#include "u_elastic.h"
  1279. X#include "u_list.h"
  1280. X#include "u_undo.h"
  1281. X#include "w_setup.h"
  1282. X
  1283. X/*************** EXPORTS *****************/
  1284. X
  1285. X/*
  1286. X * Object_tails *usually* points to the last object in each linked list in
  1287. X * objects.  The exceptions occur when multiple objects are added to a figure
  1288. X * (e.g. file read, break compound, undo delete region).  In these cases,
  1289. X * the added objects are appended to the object lists (and saved_objects is
  1290. X * set up to point to the new objects) but object_tails is not changed.
  1291. X * This speeds up a subsequent undo operation which need only set
  1292. X * all the "next" fields of objects pointed to by object_tails to NULL.
  1293. X */
  1294. X
  1295. XF_compound    saved_objects = {0, { 0, 0 }, { 0, 0 }, 
  1296. X                NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  1297. XF_compound    object_tails = {0, { 0, 0 }, { 0, 0 }, 
  1298. X                NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  1299. X
  1300. X/*************** LOCAL *****************/
  1301. X
  1302. Xstatic int    last_object;
  1303. Xstatic int    last_action = F_NULL;
  1304. Xstatic F_pos    last_position, new_position;
  1305. Xstatic int    last_arcpointnum;
  1306. Xstatic F_point *last_prev_point, *last_selected_point, *last_next_point;
  1307. Xstatic F_linkinfo *last_links;
  1308. Xstatic int    last_linkmode;
  1309. X
  1310. Xvoid
  1311. Xundo()
  1312. X{
  1313. X    switch (last_action) {
  1314. X    case F_ADD:
  1315. X    undo_add();
  1316. X    break;
  1317. X    case F_DELETE:
  1318. X    undo_delete();
  1319. X    break;
  1320. X    case F_MOVE:
  1321. X    undo_move();
  1322. X    break;
  1323. X    case F_CHANGE:
  1324. X    undo_change();
  1325. X    break;
  1326. X    case F_GLUE:
  1327. X    undo_glue();
  1328. X    break;
  1329. X    case F_BREAK:
  1330. X    undo_break();
  1331. X    break;
  1332. X    case F_LOAD:
  1333. X    undo_load();
  1334. X    break;
  1335. X    case F_SCALE:
  1336. X    undo_scale();
  1337. X    break;
  1338. X    case F_ADD_POINT:
  1339. X    undo_addpoint();
  1340. X    break;
  1341. X    case F_DELETE_POINT:
  1342. X    undo_deletepoint();
  1343. X    break;
  1344. X    case F_ADD_ARROW_HEAD:
  1345. X    undo_add_arrowhead();
  1346. X    break;
  1347. X    case F_DELETE_ARROW_HEAD:
  1348. X    undo_delete_arrowhead();
  1349. X    break;
  1350. X    case F_CONVERT:
  1351. X    undo_convert();
  1352. X    break;
  1353. X    default:
  1354. X    put_msg("Nothing to UNDO");
  1355. X    return;
  1356. X    }
  1357. X    put_msg("Undo complete");
  1358. X}
  1359. X
  1360. Xundo_addpoint()
  1361. X{
  1362. X    if (last_object == O_POLYLINE)
  1363. X    linepoint_deleting(saved_objects.lines, last_prev_point,
  1364. X               last_selected_point);
  1365. X    else
  1366. X    splinepoint_deleting(saved_objects.splines, last_prev_point,
  1367. X                 last_selected_point);
  1368. X}
  1369. X
  1370. Xundo_deletepoint()
  1371. X{
  1372. X    last_action = F_NULL;    /* to avoid doing a clean-up during adding */
  1373. X
  1374. X    if (last_object == O_POLYLINE)
  1375. X    linepoint_adding(saved_objects.lines, last_prev_point,
  1376. X             last_selected_point, last_next_point);
  1377. X    else
  1378. X    splinepoint_adding(saved_objects.splines, last_prev_point,
  1379. X               last_selected_point, last_next_point);
  1380. X    last_next_point = NULL;
  1381. X}
  1382. X
  1383. Xundo_break()
  1384. X{
  1385. X    cut_objects(&objects, &object_tails);
  1386. X    list_add_compound(&objects.compounds, saved_objects.compounds);
  1387. X    last_action = F_GLUE;
  1388. X    toggle_markers_in_compound(saved_objects.compounds);
  1389. X    mask_toggle_compoundmarker(saved_objects.compounds);
  1390. X}
  1391. X
  1392. Xundo_glue()
  1393. X{
  1394. X    list_delete_compound(&objects.compounds, saved_objects.compounds);
  1395. X    tail(&objects, &object_tails);
  1396. X    append_objects(&objects, saved_objects.compounds, &object_tails);
  1397. X    last_action = F_BREAK;
  1398. X    mask_toggle_compoundmarker(saved_objects.compounds);
  1399. X    toggle_markers_in_compound(saved_objects.compounds);
  1400. X    if (cur_mode != F_GLUE && cur_mode != F_BREAK)
  1401. X    set_tags(saved_objects.compounds, 0);
  1402. X}
  1403. X
  1404. Xundo_convert()
  1405. X{
  1406. X    switch (last_object) {
  1407. X    case O_POLYLINE:
  1408. X    spline_2_line(saved_objects.splines);
  1409. X    break;
  1410. X    case O_SPLINE:
  1411. X    line_2_spline(saved_objects.lines);
  1412. X    break;
  1413. X    }
  1414. X}
  1415. X
  1416. Xundo_add_arrowhead()
  1417. X{
  1418. X    switch (last_object) {
  1419. X    case O_POLYLINE:
  1420. X    delete_linearrow(saved_objects.lines,
  1421. X             last_prev_point, last_selected_point);
  1422. X    break;
  1423. X    case O_SPLINE:
  1424. X    delete_splinearrow(saved_objects.splines,
  1425. X               last_prev_point, last_selected_point);
  1426. X    break;
  1427. X    case O_ARC:
  1428. X    delete_arcarrow(saved_objects.arcs, last_arcpointnum);
  1429. X    break;
  1430. X    default:
  1431. X    return;
  1432. X    }
  1433. X    last_action = F_DELETE_ARROW_HEAD;
  1434. X}
  1435. X
  1436. Xundo_delete_arrowhead()
  1437. X{
  1438. X    switch (last_object) {
  1439. X    case O_POLYLINE:
  1440. X    add_linearrow(saved_objects.lines,
  1441. X              last_prev_point, last_selected_point);
  1442. X    break;
  1443. X    case O_SPLINE:
  1444. X    add_splinearrow(saved_objects.splines,
  1445. X            last_prev_point, last_selected_point);
  1446. X    break;
  1447. X    case O_ARC:
  1448. X    add_arcarrow(saved_objects.arcs, last_arcpointnum);
  1449. X    break;
  1450. X    default:
  1451. X    return;
  1452. X    }
  1453. X    last_action = F_ADD_ARROW_HEAD;
  1454. X}
  1455. X
  1456. X/*
  1457. X * saved_objects.xxxx contains a pointer to the original object,
  1458. X * saved_objects.xxxx->next points to the changed object.
  1459. X */
  1460. X
  1461. Xundo_change()
  1462. X{
  1463. X    int            xmin, ymin, xmax, ymax;
  1464. X    F_compound        swp_comp;
  1465. X
  1466. X    last_action = F_NULL;    /* to avoid a clean-up during "unchange" */
  1467. X    switch (last_object) {
  1468. X    case O_POLYLINE:
  1469. X    new_l = saved_objects.lines;    /* the original */
  1470. X    old_l = saved_objects.lines->next;    /* the changed object */
  1471. X    change_line(old_l, new_l);
  1472. X    redisplay_lines(new_l, old_l);
  1473. X    break;
  1474. X    case O_ELLIPSE:
  1475. X    new_e = saved_objects.ellipses;
  1476. X    old_e = saved_objects.ellipses->next;
  1477. X    change_ellipse(old_e, new_e);
  1478. X    redisplay_ellipses(new_e, old_e);
  1479. X    break;
  1480. X    case O_TEXT:
  1481. X    new_t = saved_objects.texts;
  1482. X    old_t = saved_objects.texts->next;
  1483. X    change_text(old_t, new_t);
  1484. X    redisplay_texts(new_t, old_t);
  1485. X    break;
  1486. X    case O_SPLINE:
  1487. X    new_s = saved_objects.splines;
  1488. X    old_s = saved_objects.splines->next;
  1489. X    change_spline(old_s, new_s);
  1490. X    redisplay_splines(new_s, old_s);
  1491. X    break;
  1492. X    case O_ARC:
  1493. X    new_a = saved_objects.arcs;
  1494. X    old_a = saved_objects.arcs->next;
  1495. X    change_arc(old_a, new_a);
  1496. X    redisplay_arcs(new_a, old_a);
  1497. X    break;
  1498. X    case O_COMPOUND:
  1499. X    new_c = saved_objects.compounds;
  1500. X    old_c = saved_objects.compounds->next;
  1501. X    change_compound(old_c, new_c);
  1502. X    redisplay_compounds(new_c, old_c);
  1503. X    break;
  1504. X    case O_ALL_OBJECT:
  1505. X    swp_comp = objects;
  1506. X    objects = saved_objects;
  1507. X    saved_objects = swp_comp;
  1508. X    new_c = &objects;
  1509. X    old_c = &saved_objects;
  1510. X    set_action_object(F_CHANGE, O_ALL_OBJECT);
  1511. X    set_modifiedflag();
  1512. X    redisplay_zoomed_region(0, 0, CANVAS_WD, CANVAS_HT);
  1513. X    break;
  1514. X    }
  1515. X}
  1516. X
  1517. X/*
  1518. X * When a single object is created, it is appended to the appropriate list
  1519. X * in objects.    It is also placed in the appropriate list in saved_objects.
  1520. X *
  1521. X * When a number of objects are created (usually by reading them in from
  1522. X * a file or undoing a remove-all action), they are appended to the lists in
  1523. X * objects and also saved in saved_objects.  The pointers in object_tails
  1524. X * will be set to point to the last members of the lists in objects prior to
  1525. X * the appending.
  1526. X *
  1527. X * Note: The read operation will set the pointers in object_tails while the
  1528. X * remove-all operation will zero pointers in objects.
  1529. X */
  1530. X
  1531. Xundo_add()
  1532. X{
  1533. X    int            xmin, ymin, xmax, ymax;
  1534. X
  1535. X    switch (last_object) {
  1536. X    case O_POLYLINE:
  1537. X    list_delete_line(&objects.lines, saved_objects.lines);
  1538. X    redisplay_line(saved_objects.lines);
  1539. X    break;
  1540. X    case O_ELLIPSE:
  1541. X    list_delete_ellipse(&objects.ellipses, saved_objects.ellipses);
  1542. X    redisplay_ellipse(saved_objects.ellipses);
  1543. X    break;
  1544. X    case O_TEXT:
  1545. X    list_delete_text(&objects.texts, saved_objects.texts);
  1546. X    redisplay_text(saved_objects.texts);
  1547. X    break;
  1548. X    case O_SPLINE:
  1549. X    list_delete_spline(&objects.splines, saved_objects.splines);
  1550. X    redisplay_spline(saved_objects.splines);
  1551. X    break;
  1552. X    case O_ARC:
  1553. X    list_delete_arc(&objects.arcs, saved_objects.arcs);
  1554. X    redisplay_arc(saved_objects.arcs);
  1555. X    break;
  1556. X    case O_COMPOUND:
  1557. X    list_delete_compound(&objects.compounds, saved_objects.compounds);
  1558. X    redisplay_compound(saved_objects.compounds);
  1559. X    break;
  1560. X    case O_ALL_OBJECT:
  1561. X    cut_objects(&objects, &object_tails);
  1562. X    compound_bound(&saved_objects, &xmin, &ymin, &xmax, &ymax);
  1563. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1564. X    break;
  1565. X    }
  1566. X    last_action = F_DELETE;
  1567. X}
  1568. X
  1569. Xundo_delete()
  1570. X{
  1571. X    int            xmin, ymin, xmax, ymax;
  1572. X
  1573. X    switch (last_object) {
  1574. X    case O_POLYLINE:
  1575. X    list_add_line(&objects.lines, saved_objects.lines);
  1576. X    redisplay_line(saved_objects.lines);
  1577. X    break;
  1578. X    case O_ELLIPSE:
  1579. X    list_add_ellipse(&objects.ellipses, saved_objects.ellipses);
  1580. X    redisplay_ellipse(saved_objects.ellipses);
  1581. X    break;
  1582. X    case O_TEXT:
  1583. X    list_add_text(&objects.texts, saved_objects.texts);
  1584. X    redisplay_text(saved_objects.texts);
  1585. X    break;
  1586. X    case O_SPLINE:
  1587. X    list_add_spline(&objects.splines, saved_objects.splines);
  1588. X    redisplay_spline(saved_objects.splines);
  1589. X    break;
  1590. X    case O_ARC:
  1591. X    list_add_arc(&objects.arcs, saved_objects.arcs);
  1592. X    redisplay_arc(saved_objects.arcs);
  1593. X    break;
  1594. X    case O_COMPOUND:
  1595. X    list_add_compound(&objects.compounds, saved_objects.compounds);
  1596. X    redisplay_compound(saved_objects.compounds);
  1597. X    break;
  1598. X    case O_ALL_OBJECT:
  1599. X    compound_bound(&saved_objects, &xmin, &ymin, &xmax, &ymax);
  1600. X    append_objects(&objects, &saved_objects, &object_tails);
  1601. X    redisplay_zoomed_region(xmin, ymin, xmax, ymax);
  1602. X    }
  1603. X    last_action = F_ADD;
  1604. X}
  1605. X
  1606. Xundo_move()
  1607. X{
  1608. X    int            dx, dy;
  1609. X    int            xmin1, ymin1, xmax1, ymax1;
  1610. X    int            xmin2, ymin2, xmax2, ymax2;
  1611. X    int            dum;
  1612. X
  1613. X    dx = last_position.x - new_position.x;
  1614. X    dy = last_position.y - new_position.y;
  1615. X    switch (last_object) {
  1616. X    case O_POLYLINE:
  1617. X    line_bound(saved_objects.lines, &xmin1, &ymin1, &xmax1, &ymax1);
  1618. X    translate_line(saved_objects.lines, dx, dy);
  1619. X    line_bound(saved_objects.lines, &xmin2, &ymin2, &xmax2, &ymax2);
  1620. X    adjust_links(last_linkmode, last_links, dx, dy, 0, 0, 1.0, 1.0, 0);
  1621. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1622. X              xmin2, ymin2, xmax2, ymax2);
  1623. X    break;
  1624. X    case O_ELLIPSE:
  1625. X    ellipse_bound(saved_objects.ellipses, &xmin1, &ymin1, &xmax1, &ymax1);
  1626. X    translate_ellipse(saved_objects.ellipses, dx, dy);
  1627. X    ellipse_bound(saved_objects.ellipses, &xmin2, &ymin2, &xmax2, &ymax2);
  1628. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1629. X              xmin2, ymin2, xmax2, ymax2);
  1630. X    break;
  1631. X    case O_TEXT:
  1632. X    if (appres.textoutline) {
  1633. X        text_bound_both(saved_objects.texts, &xmin1, &ymin1, &xmax1, &ymax1,
  1634. X            &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  1635. X        translate_text(saved_objects.texts, dx, dy);
  1636. X        text_bound_both(saved_objects.texts, &xmin2, &ymin2, &xmax2, &ymax2,
  1637. X            &dum,&dum,&dum,&dum,&dum,&dum,&dum,&dum);
  1638. X    } else {
  1639. X        text_bound(saved_objects.texts, &xmin1, &ymin1, &xmax1, &ymax1);
  1640. X        translate_text(saved_objects.texts, dx, dy);
  1641. X        text_bound(saved_objects.texts, &xmin2, &ymin2, &xmax2, &ymax2);
  1642. X    }
  1643. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1644. X              xmin2, ymin2, xmax2, ymax2);
  1645. X    break;
  1646. X    case O_SPLINE:
  1647. X    spline_bound(saved_objects.splines, &xmin1, &ymin1, &xmax1, &ymax1);
  1648. X    translate_spline(saved_objects.splines, dx, dy);
  1649. X    spline_bound(saved_objects.splines, &xmin2, &ymin2, &xmax2, &ymax2);
  1650. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1651. X              xmin2, ymin2, xmax2, ymax2);
  1652. X    break;
  1653. X    case O_ARC:
  1654. X    arc_bound(saved_objects.arcs, &xmin1, &ymin1, &xmax1, &ymax1);
  1655. X    translate_arc(saved_objects.arcs, dx, dy);
  1656. X    arc_bound(saved_objects.arcs, &xmin2, &ymin2, &xmax2, &ymax2);
  1657. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1658. X              xmin2, ymin2, xmax2, ymax2);
  1659. X    break;
  1660. X    case O_COMPOUND:
  1661. X    compound_bound(saved_objects.compounds, &xmin1, &ymin1, &xmax1, &ymax1);
  1662. X    translate_compound(saved_objects.compounds, dx, dy);
  1663. X    compound_bound(saved_objects.compounds, &xmin2, &ymin2, &xmax2, &ymax2);
  1664. X    adjust_links(last_linkmode, last_links, dx, dy, 0, 0, 1.0, 1.0, 0);
  1665. X    redisplay_regions(xmin1, ymin1, xmax1, ymax1,
  1666. X              xmin2, ymin2, xmax2, ymax2);
  1667. X    break;
  1668. X    }
  1669. X    swap_newp_lastp();
  1670. X}
  1671. X
  1672. Xundo_load()
  1673. X{
  1674. X    F_compound        temp;
  1675. X    char        ctemp[128];
  1676. X
  1677. X    temp = objects;
  1678. X    objects = saved_objects;
  1679. X    saved_objects = temp;
  1680. X    strcpy(ctemp, cur_filename);
  1681. X    update_cur_filename(save_filename);
  1682. X    strcpy(save_filename, ctemp);
  1683. X    redisplay_canvas();
  1684. X    set_modifiedflag();
  1685. X    last_action = F_LOAD;
  1686. X}
  1687. X
  1688. Xundo_scale()
  1689. X{
  1690. X    float        scalex, scaley;
  1691. X
  1692. X    mask_toggle_compoundmarker(saved_objects.compounds);
  1693. X    draw_compoundelements(saved_objects.compounds, ERASE);
  1694. X    scalex = ((float) (last_position.x - fix_x)) / (new_position.x - fix_x);
  1695. X    scaley = ((float) (last_position.y - fix_y)) / (new_position.y - fix_y);
  1696. X    scale_compound(saved_objects.compounds, scalex, scaley, fix_x, fix_y);
  1697. X    draw_compoundelements(saved_objects.compounds, PAINT);
  1698. X    mask_toggle_compoundmarker(saved_objects.compounds);
  1699. X    swap_newp_lastp();
  1700. X}
  1701. X
  1702. Xswap_newp_lastp()
  1703. X{
  1704. X    int            t;        /* swap new_position and last_position    */
  1705. X
  1706. X    t = new_position.x;
  1707. X    new_position.x = last_position.x;
  1708. X    last_position.x = t;
  1709. X    t = new_position.y;
  1710. X    new_position.y = last_position.y;
  1711. X    last_position.y = t;
  1712. X}
  1713. X
  1714. X/*
  1715. X * Clean_up should be called before committing a user's request. Clean_up
  1716. X * will attempt to free all the allocated memories which resulted from
  1717. X * delete/remove action.  It will set the last_action to F_NULL.  Thus this
  1718. X * routine should be before set_action_object(). if they are to be called in
  1719. X * the same routine.
  1720. X */
  1721. Xclean_up()
  1722. X{
  1723. X    if (last_action == F_CHANGE) {
  1724. X    switch (last_object) {
  1725. X    case O_ARC:
  1726. X        saved_objects.arcs->next = NULL;
  1727. X        free_arc(&saved_objects.arcs);
  1728. X        break;
  1729. X    case O_COMPOUND:
  1730. X        saved_objects.compounds->next = NULL;
  1731. X        free_compound(&saved_objects.compounds);
  1732. X        break;
  1733. X    case O_ELLIPSE:
  1734. X        saved_objects.ellipses->next = NULL;
  1735. X        free_ellipse(&saved_objects.ellipses);
  1736. X        break;
  1737. X    case O_POLYLINE:
  1738. X        saved_objects.lines->next = NULL;
  1739. X        free_line(&saved_objects.lines);
  1740. X        break;
  1741. X    case O_SPLINE:
  1742. X        saved_objects.splines->next = NULL;
  1743. X        free_spline(&saved_objects.splines);
  1744. X        break;
  1745. X    case O_TEXT:
  1746. X        saved_objects.texts->next = NULL;
  1747. X        free_text(&saved_objects.texts);
  1748. X        break;
  1749. X    }
  1750. X    } else if (last_action == F_DELETE) {
  1751. X    switch (last_object) {
  1752. X    case O_ARC:
  1753. X        free_arc(&saved_objects.arcs);
  1754. X        break;
  1755. X    case O_COMPOUND:
  1756. X        free_compound(&saved_objects.compounds);
  1757. X        break;
  1758. X    case O_ELLIPSE:
  1759. X        free_ellipse(&saved_objects.ellipses);
  1760. X        break;
  1761. X    case O_POLYLINE:
  1762. X        free_line(&saved_objects.lines);
  1763. X        break;
  1764. X    case O_SPLINE:
  1765. X        free_spline(&saved_objects.splines);
  1766. X        break;
  1767. X    case O_TEXT:
  1768. X        free_text(&saved_objects.texts);
  1769. X        break;
  1770. X    case O_ALL_OBJECT:
  1771. X        free_arc(&saved_objects.arcs);
  1772. X        free_compound(&saved_objects.compounds);
  1773. X        free_ellipse(&saved_objects.ellipses);
  1774. X        free_line(&saved_objects.lines);
  1775. X        free_spline(&saved_objects.splines);
  1776. X        free_text(&saved_objects.texts);
  1777. X        break;
  1778. X    }
  1779. X    } else if (last_action == F_DELETE_POINT) {
  1780. X    free((char *) last_selected_point);
  1781. X    last_prev_point = NULL;
  1782. X    last_selected_point = NULL;
  1783. X    last_next_point = NULL;
  1784. X    } else if (last_action == F_ADD_POINT) {
  1785. X    last_prev_point = NULL;
  1786. X    last_selected_point = NULL;
  1787. X    } else if (last_action == F_LOAD) {
  1788. X    free_arc(&saved_objects.arcs);
  1789. X    free_compound(&saved_objects.compounds);
  1790. X    free_ellipse(&saved_objects.ellipses);
  1791. X    free_line(&saved_objects.lines);
  1792. X    free_spline(&saved_objects.splines);
  1793. X    free_text(&saved_objects.texts);
  1794. X    } else if (last_action == F_GLUE) {
  1795. X    saved_objects.compounds = NULL;
  1796. X    } else if (last_action == F_BREAK) {
  1797. X    free((char *) saved_objects.compounds);
  1798. X    saved_objects.compounds = NULL;
  1799. X    } else if (last_action == F_ADD || last_action == F_MOVE) {
  1800. X    saved_objects.arcs = NULL;
  1801. X    saved_objects.compounds = NULL;
  1802. X    saved_objects.ellipses = NULL;
  1803. X    saved_objects.lines = NULL;
  1804. X    saved_objects.splines = NULL;
  1805. X    saved_objects.texts = NULL;
  1806. X    free_linkinfo(&last_links);
  1807. X    } else if (last_action == F_CONVERT) {
  1808. X    saved_objects.splines = NULL;
  1809. X    saved_objects.lines = NULL;
  1810. X    } else if (last_action == F_ADD_ARROW_HEAD ||
  1811. X           last_action == F_DELETE_ARROW_HEAD) {
  1812. X    saved_objects.splines = NULL;
  1813. X    saved_objects.lines = NULL;
  1814. X    saved_objects.arcs = NULL;
  1815. X    last_prev_point = NULL;
  1816. X    last_selected_point = NULL;
  1817. X    }
  1818. X    last_action = F_NULL;
  1819. X}
  1820. X
  1821. Xset_latestarc(arc)
  1822. X    F_arc       *arc;
  1823. X{
  1824. X    saved_objects.arcs = arc;
  1825. X}
  1826. X
  1827. Xset_latestobjects(objects)
  1828. X    F_compound       *objects;
  1829. X{
  1830. X    saved_objects = *objects;
  1831. X}
  1832. X
  1833. Xset_latestcompound(compound)
  1834. X    F_compound       *compound;
  1835. X{
  1836. X    saved_objects.compounds = compound;
  1837. X}
  1838. X
  1839. Xset_latestellipse(ellipse)
  1840. X    F_ellipse       *ellipse;
  1841. X{
  1842. X    saved_objects.ellipses = ellipse;
  1843. X}
  1844. X
  1845. Xset_latestline(line)
  1846. X    F_line       *line;
  1847. X{
  1848. X    saved_objects.lines = line;
  1849. X}
  1850. X
  1851. Xset_latestspline(spline)
  1852. X    F_spline       *spline;
  1853. X{
  1854. X    saved_objects.splines = spline;
  1855. X}
  1856. X
  1857. Xset_latesttext(text)
  1858. X    F_text       *text;
  1859. X{
  1860. X    saved_objects.texts = text;
  1861. X}
  1862. X
  1863. Xset_last_prevpoint(prev_point)
  1864. X    F_point       *prev_point;
  1865. X{
  1866. X    last_prev_point = prev_point;
  1867. X}
  1868. X
  1869. Xset_last_selectedpoint(selected_point)
  1870. X    F_point       *selected_point;
  1871. X{
  1872. X    last_selected_point = selected_point;
  1873. X}
  1874. X
  1875. Xset_last_nextpoint(next_point)
  1876. X    F_point       *next_point;
  1877. X{
  1878. X    last_next_point = next_point;
  1879. X}
  1880. X
  1881. Xset_last_arcpointnum(num)
  1882. X    int            num;
  1883. X{
  1884. X    last_arcpointnum = num;
  1885. X}
  1886. X
  1887. Xset_lastposition(x, y)
  1888. X    int            x, y;
  1889. X{
  1890. X    last_position.x = x;
  1891. X    last_position.y = y;
  1892. X}
  1893. X
  1894. Xset_newposition(x, y)
  1895. X    int            x, y;
  1896. X{
  1897. X    new_position.x = x;
  1898. X    new_position.y = y;
  1899. X}
  1900. X
  1901. Xset_action(action)
  1902. X    int            action;
  1903. X{
  1904. X    last_action = action;
  1905. X}
  1906. X
  1907. Xset_action_object(action, object)
  1908. X    int            action, object;
  1909. X{
  1910. X    last_action = action;
  1911. X    last_object = object;
  1912. X}
  1913. X
  1914. Xset_lastlinkinfo(mode, links)
  1915. X    int            mode;
  1916. X    F_linkinfo       *links;
  1917. X{
  1918. X    last_linkmode = mode;
  1919. X    last_links = links;
  1920. X}
  1921. END_OF_FILE
  1922. if test 17567 -ne `wc -c <'u_undo.c'`; then
  1923.     echo shar: \"'u_undo.c'\" unpacked with wrong size!
  1924. fi
  1925. # end of 'u_undo.c'
  1926. fi
  1927. if test -f 'w_print.c' -a "${1}" != "-c" ; then 
  1928.   echo shar: Will not clobber existing file \"'w_print.c'\"
  1929. else
  1930. echo shar: Extracting \"'w_print.c'\" \(14793 characters\)
  1931. sed "s/^X//" >'w_print.c' <<'END_OF_FILE'
  1932. X/*
  1933. X * FIG : Facility for Interactive Generation of figures
  1934. X * Copyright (c) 1991 by Brian V. Smith
  1935. X *
  1936. X * "Permission to use, copy, modify, distribute, and sell this software and its
  1937. X * documentation for any purpose is hereby granted without fee, provided that
  1938. X * the above copyright notice appear in all copies and that both the copyright
  1939. X * notice and this permission notice appear in supporting documentation. 
  1940. X * No representations are made about the suitability of this software for 
  1941. X * any purpose.  It is provided "as is" without express or implied warranty."
  1942. X */
  1943. X
  1944. X#include "fig.h"
  1945. X#include "figx.h"
  1946. X#include "mode.h"
  1947. X#include "resources.h"
  1948. X#include "w_icons.h"
  1949. X#include "w_setup.h"
  1950. X#include "w_util.h"
  1951. X
  1952. Xextern String    text_translations;
  1953. Xextern Widget    make_popup_menu();
  1954. Xextern char    *panel_get_value();
  1955. Xextern char     batch_file[];
  1956. Xextern Boolean  batch_exists;
  1957. Xextern char    *shell_protect_string();
  1958. X
  1959. X/* LOCAL */
  1960. X
  1961. Xstatic char    *orient_items[] = {
  1962. X    "portrait ",
  1963. X    "landscape"};
  1964. X
  1965. Xstatic char    *just_items[] = {
  1966. X    "Centered  ",
  1967. X    "Flush left"};
  1968. X
  1969. Xstatic void    orient_select();
  1970. Xstatic Widget    orient_panel, orient_menu, orient_lab;
  1971. X
  1972. Xstatic void    just_select();
  1973. Xstatic Widget    just_panel, just_menu, just_lab;
  1974. X
  1975. Xstatic Widget    print_panel, print_popup, dismiss, print, 
  1976. X        printer_text, param_text, printer_lab, param_lab, clear_batch, print_batch, 
  1977. X        mag_lab, print_w, mag_text, num_batch_lab, num_batch;
  1978. Xstatic Position xposn, yposn;
  1979. Xstatic String   prin_translations =
  1980. X        "<Message>WM_PROTOCOLS: DismissPrin()\n";
  1981. Xstatic void     print_panel_dismiss(), do_clear_batch();
  1982. Xvoid        do_print(), do_print_batch();
  1983. Xstatic XtActionsRec     prin_actions[] =
  1984. X{
  1985. X    {"DismissPrin", (XtActionProc) print_panel_dismiss},
  1986. X    {"dismiss", (XtActionProc) print_panel_dismiss},
  1987. X    {"print_batch", (XtActionProc) do_print_batch},
  1988. X    {"clear_batch", (XtActionProc) do_clear_batch},
  1989. X    {"print", (XtActionProc) do_print},
  1990. X};
  1991. X
  1992. Xstatic void
  1993. Xprint_panel_dismiss(w, ev)
  1994. X    Widget        w;
  1995. X    XButtonEvent   *ev;
  1996. X{
  1997. X    XtPopdown(print_popup);
  1998. X    XtSetSensitive(print_w, True);
  1999. X}
  2000. X
  2001. Xstatic char    print_msg[] = "PRINT";
  2002. X
  2003. Xvoid
  2004. Xdo_print(w)
  2005. X    Widget        w;
  2006. X{
  2007. X    DeclareArgs(1);
  2008. X    float        mag;
  2009. X    char       *printer_val;
  2010. X    char       *param_val;
  2011. X    char        cmd[100];
  2012. X
  2013. X    if (emptyfigure_msg(print_msg) && !batch_exists)
  2014. X        return;
  2015. X
  2016. X    /* create popup panel if not already there so we have all the
  2017. X       resources necessary (e.g. printer name etc.) */
  2018. X    if (!print_popup) 
  2019. X        create_print_panel(w);
  2020. X    mag = (float) atof(panel_get_value(mag_text)) / 100.0;
  2021. X    if (mag <= 0.0)
  2022. X        mag = 1.0;
  2023. X
  2024. X    FirstArg(XtNstring, &printer_val);
  2025. X    GetValues(printer_text);
  2026. X    /* no printer name specified in resources, get PRINTER environment
  2027. X       var and put it into the widget */
  2028. X    if (emptyname(printer_val)) {
  2029. X        printer_val=getenv("PRINTER");
  2030. X        FirstArg(XtNstring, printer_val);
  2031. X        SetValues(printer_text);
  2032. X    }
  2033. X    FirstArg(XtNstring, ¶m_val);
  2034. X    GetValues(param_text);
  2035. X    if (batch_exists)
  2036. X        {
  2037. X        gen_print_cmd(cmd,batch_file,printer_val,param_val);
  2038. X        if (system(cmd) != 0)
  2039. X        file_msg("Error during PRINT");
  2040. X        /* clear the batch file and the count */
  2041. X        do_clear_batch(w);
  2042. X        }
  2043. X    else
  2044. X        {
  2045. X        print_to_printer(printer_val, mag, print_flushleft, param_val);
  2046. X        }
  2047. X}
  2048. X
  2049. Xgen_print_cmd(cmd,file,printer,pr_params)
  2050. X    char       *cmd;
  2051. X    char       *file;
  2052. X    char       *printer;
  2053. X    char       *pr_params;
  2054. X{
  2055. X    if (emptyname(printer)) {    /* send to default printer */
  2056. X#if defined(SYSV) || defined(SVR4)
  2057. X    sprintf(cmd, "lp %s -oPS %s", 
  2058. X        pr_params,
  2059. X        shell_protect_string(file));
  2060. X#else
  2061. X    sprintf(cmd, "lpr %s -J %s %s",
  2062. X        pr_params,
  2063. X        shell_protect_string(file),
  2064. X        shell_protect_string(file));
  2065. X#endif
  2066. X    put_msg("Printing figure on default printer in %s mode ...     ",
  2067. X        print_landscape ? "LANDSCAPE" : "PORTRAIT");
  2068. X    } else {
  2069. X#if defined(SYSV) || defined(SVR4)
  2070. X    sprintf(cmd, "lp %s, -d%s -oPS %s",
  2071. X        pr_params,
  2072. X        printer, 
  2073. X        shell_protect_string(file));
  2074. X#else
  2075. X    sprintf(cmd, "lpr %s -J %s -P%s %s", 
  2076. X        pr_params,
  2077. X        shell_protect_string(file),
  2078. X        printer,
  2079. X        shell_protect_string(file));
  2080. X#endif
  2081. X    put_msg("Printing figure on printer %s in %s mode ...     ",
  2082. X        printer, print_landscape ? "LANDSCAPE" : "PORTRAIT");
  2083. X    }
  2084. X    app_flush();        /* make sure message gets displayed */
  2085. X}
  2086. X
  2087. Xstatic int num_batch_figures=0;
  2088. Xstatic Boolean writing_batch=False;
  2089. X
  2090. Xvoid
  2091. Xdo_print_batch(w)
  2092. X    Widget        w;
  2093. X{
  2094. X    DeclareArgs(1);
  2095. X    float        mag;
  2096. X    FILE       *infp,*outfp;
  2097. X    char        tmp_exp_file[32];
  2098. X    char        str[255];
  2099. X
  2100. X    if (writing_batch || emptyfigure_msg(print_msg))
  2101. X        return;
  2102. X
  2103. X    /* set lock so we don't come here while still writing a file */
  2104. X    /* this could happen if the user presses the button too fast */
  2105. X    writing_batch = True;
  2106. X
  2107. X    /* make a temporary name to write the batch stuff to */
  2108. X    sprintf(batch_file, "%s/%s%06d", TMPDIR, "xfig-batch", getpid());
  2109. X    /* make a temporary name to write this figure to */
  2110. X    sprintf(tmp_exp_file, "%s/%s%06d", TMPDIR, "xfig-exp", getpid());
  2111. X    batch_exists = True;
  2112. X    if (!print_popup) 
  2113. X        create_print_panel(w);
  2114. X    mag = (float) atof(panel_get_value(mag_text)) / 100.0;
  2115. X    if (mag <= 0.0)
  2116. X        mag = 1.0;
  2117. X
  2118. X    print_to_file(tmp_exp_file, "ps", mag, print_flushleft);
  2119. X    put_msg("Appending to batch file \"%s\" (%s mode) ... done",
  2120. X            batch_file, print_landscape ? "LANDSCAPE" : "PORTRAIT");
  2121. X    app_flush();        /* make sure message gets displayed */
  2122. X
  2123. X    /* now append that to the batch file */
  2124. X    if ((infp = fopen(tmp_exp_file, "r")) == NULL) {
  2125. X        file_msg("Error during PRINT - can't open temporary file to read");
  2126. X        return;
  2127. X        }
  2128. X    if ((outfp = fopen(batch_file, "a")) == NULL) {
  2129. X        file_msg("Error during PRINT - can't open print file to append");
  2130. X        return;
  2131. X        }
  2132. X    while (fgets(str,255,infp) != NULL)
  2133. X        (void) fputs(str,outfp);
  2134. X    fclose(infp);
  2135. X    fclose(outfp);
  2136. X    unlink(tmp_exp_file);
  2137. X    /* count this batch figure */
  2138. X    num_batch_figures++ ;
  2139. X    /* and update the label widget */
  2140. X    update_batch_count();
  2141. X    /* we're done */
  2142. X    writing_batch = False;
  2143. X}
  2144. X
  2145. Xstatic void
  2146. Xdo_clear_batch(w)
  2147. X    Widget        w;
  2148. X{
  2149. X    DeclareArgs(1);
  2150. X  
  2151. X    unlink(batch_file);
  2152. X    batch_exists = False;
  2153. X    num_batch_figures = 0;
  2154. X    /* update the label widget */
  2155. X    update_batch_count();
  2156. X}
  2157. X
  2158. X/* update the label widget with the current number of figures in the batch file */
  2159. X
  2160. Xupdate_batch_count()
  2161. X{
  2162. X    String        num[4];
  2163. X    DeclareArgs(1);
  2164. X
  2165. X    sprintf(num,"%3d",num_batch_figures);
  2166. X    FirstArg(XtNlabel,num);
  2167. X    SetValues(num_batch);
  2168. X    if (num_batch_figures) {
  2169. X        XtSetSensitive(clear_batch, True);
  2170. X        FirstArg(XtNlabel, "Print BATCH \nto Printer");
  2171. X        SetValues(print);
  2172. X    } else {
  2173. X        XtSetSensitive(clear_batch, False);
  2174. X        FirstArg(XtNlabel, "Print FIGURE\nto Printer");
  2175. X        SetValues(print);
  2176. X    }
  2177. X}
  2178. X
  2179. Xstatic void
  2180. Xorient_select(w, new_orient, garbage)
  2181. X    Widget        w;
  2182. X    XtPointer        new_orient, garbage;
  2183. X{
  2184. X    DeclareArgs(1);
  2185. X
  2186. X    FirstArg(XtNlabel, XtName(w));
  2187. X    SetValues(orient_panel);
  2188. X    print_landscape = (int) new_orient;
  2189. X}
  2190. X
  2191. Xstatic void
  2192. Xjust_select(w, new_just, garbage)
  2193. X    Widget        w;
  2194. X    XtPointer        new_just, garbage;
  2195. X{
  2196. X    DeclareArgs(1);
  2197. X
  2198. X    FirstArg(XtNlabel, XtName(w));
  2199. X    SetValues(just_panel);
  2200. X    print_flushleft = (new_just? True: False);
  2201. X}
  2202. X
  2203. Xpopup_print_panel(w)
  2204. X    Widget        w;
  2205. X{
  2206. X    Widget        image;
  2207. X    Pixmap        p;
  2208. X    DeclareArgs(10);
  2209. X    extern        Atom wm_delete_window;
  2210. X
  2211. X    set_temp_cursor(wait_cursor);
  2212. X    XtSetSensitive(w, False);
  2213. X    if (!print_popup)
  2214. X    create_print_panel(w);
  2215. X    XtPopup(print_popup, XtGrabNone);
  2216. X    (void) XSetWMProtocols(XtDisplay(print_popup), XtWindow(print_popup),
  2217. X                           &wm_delete_window, 1);
  2218. X    reset_cursor();
  2219. X
  2220. X}
  2221. X
  2222. Xcreate_print_panel(w)
  2223. X    Widget        w;
  2224. X{
  2225. X    Widget        image;
  2226. X    Pixmap        p;
  2227. X    DeclareArgs(10);
  2228. X
  2229. X    print_w = w;
  2230. X    XtTranslateCoords(w, (Position) 0, (Position) 0, &xposn, &yposn);
  2231. X
  2232. X    FirstArg(XtNx, xposn);
  2233. X    NextArg(XtNy, yposn + 50);
  2234. X    NextArg(XtNtitle, "Xfig: Print menu");
  2235. X    print_popup = XtCreatePopupShell("xfig_print_menu",
  2236. X                     transientShellWidgetClass,
  2237. X                     tool, Args, ArgCount);
  2238. X        XtOverrideTranslations(print_popup,
  2239. X                           XtParseTranslationTable(prin_translations));
  2240. X        XtAppAddActions(tool_app, prin_actions, XtNumber(prin_actions));
  2241. X
  2242. X    print_panel = XtCreateManagedWidget("print_panel", formWidgetClass,
  2243. X                        print_popup, NULL, ZERO);
  2244. X
  2245. X    p = XCreateBitmapFromData(tool_d, XtWindow(canvas_sw),
  2246. X              (char *) printer_ic.data, printer_ic.width, printer_ic.height);
  2247. X
  2248. X    FirstArg(XtNlabel, "   ");
  2249. X    NextArg(XtNwidth, printer_ic.width);
  2250. X    NextArg(XtNheight, printer_ic.height);
  2251. X    NextArg(XtNbitmap, p);
  2252. X    NextArg(XtNborderWidth, 0);
  2253. X    NextArg(XtNinternalWidth, 0);
  2254. X    NextArg(XtNinternalHeight, 0);
  2255. X    NextArg(XtNresize, False);
  2256. X    NextArg(XtNresizable, False);
  2257. X    image = XtCreateManagedWidget("printer_image", labelWidgetClass,
  2258. X                      print_panel, Args, ArgCount);
  2259. X
  2260. X    FirstArg(XtNlabel, "  Magnification%:");
  2261. X    NextArg(XtNfromVert, image);
  2262. X    NextArg(XtNjustify, XtJustifyLeft);
  2263. X    NextArg(XtNborderWidth, 0);
  2264. X    mag_lab = XtCreateManagedWidget("mag_label", labelWidgetClass,
  2265. X                    print_panel, Args, ArgCount);
  2266. X
  2267. X    FirstArg(XtNwidth, 40);
  2268. X    NextArg(XtNfromVert, image);
  2269. X    NextArg(XtNfromHoriz, mag_lab);
  2270. X    NextArg(XtNeditType, "edit");
  2271. X    NextArg(XtNstring, "100");
  2272. X    NextArg(XtNinsertPosition, 3);
  2273. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2274. X    mag_text = XtCreateManagedWidget("magnification", asciiTextWidgetClass,
  2275. X                     print_panel, Args, ArgCount);
  2276. X    XtOverrideTranslations(mag_text,
  2277. X                   XtParseTranslationTable(text_translations));
  2278. X
  2279. X    FirstArg(XtNlabel, "     Orientation:");
  2280. X    NextArg(XtNjustify, XtJustifyLeft);
  2281. X    NextArg(XtNborderWidth, 0);
  2282. X    NextArg(XtNfromVert, mag_text);
  2283. X    orient_lab = XtCreateManagedWidget("orient_label", labelWidgetClass,
  2284. X                       print_panel, Args, ArgCount);
  2285. X
  2286. X    FirstArg(XtNfromHoriz, orient_lab);
  2287. X    NextArg(XtNfromVert, mag_text);
  2288. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2289. X    orient_panel = XtCreateManagedWidget(orient_items[print_landscape],
  2290. X                         menuButtonWidgetClass,
  2291. X                         print_panel, Args, ArgCount);
  2292. X    orient_menu = make_popup_menu(orient_items, XtNumber(orient_items),
  2293. X                      orient_panel, orient_select);
  2294. X
  2295. X    FirstArg(XtNlabel, "   Justification:");
  2296. X    NextArg(XtNjustify, XtJustifyLeft);
  2297. X    NextArg(XtNborderWidth, 0);
  2298. X    NextArg(XtNfromVert, orient_panel);
  2299. X    just_lab = XtCreateManagedWidget("just_label", labelWidgetClass,
  2300. X                     print_panel, Args, ArgCount);
  2301. X
  2302. X    FirstArg(XtNlabel, just_items[print_flushleft? 1 : 0]);
  2303. X    NextArg(XtNfromHoriz, just_lab);
  2304. X    NextArg(XtNfromVert, orient_panel);
  2305. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2306. X    NextArg(XtNresizable, True);
  2307. X    just_panel = XtCreateManagedWidget("justify",
  2308. X                       menuButtonWidgetClass,
  2309. X                       print_panel, Args, ArgCount);
  2310. X    just_menu = make_popup_menu(just_items, XtNumber(just_items),
  2311. X                    just_panel, just_select);
  2312. X
  2313. X
  2314. X    FirstArg(XtNlabel, "         Printer:");
  2315. X    NextArg(XtNfromVert, just_panel);
  2316. X    NextArg(XtNjustify, XtJustifyLeft);
  2317. X    NextArg(XtNborderWidth, 0);
  2318. X    printer_lab = XtCreateManagedWidget("printer_label", labelWidgetClass,
  2319. X                        print_panel, Args, ArgCount);
  2320. X    /*
  2321. X     * don't SetValue the XtNstring so the user may specify the default
  2322. X     * printer in a resource, e.g.:     *printer*string: at6
  2323. X     */
  2324. X
  2325. X    FirstArg(XtNwidth, 100);
  2326. X    NextArg(XtNfromVert, just_panel);
  2327. X    NextArg(XtNfromHoriz, printer_lab);
  2328. X    NextArg(XtNeditType, "edit");
  2329. X    NextArg(XtNinsertPosition, 0);
  2330. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2331. X    printer_text = XtCreateManagedWidget("printer", asciiTextWidgetClass,
  2332. X                         print_panel, Args, ArgCount);
  2333. X
  2334. X    XtOverrideTranslations(printer_text,
  2335. X                   XtParseTranslationTable(text_translations));
  2336. X
  2337. X    FirstArg(XtNlabel, "Print Job Params:");
  2338. X    NextArg(XtNfromVert, printer_text);
  2339. X    NextArg(XtNjustify, XtJustifyLeft);
  2340. X    NextArg(XtNborderWidth, 0);
  2341. X    param_lab = XtCreateManagedWidget("job_params_label", labelWidgetClass,
  2342. X                        print_panel, Args, ArgCount);
  2343. X    /*
  2344. X     * don't SetValue the XtNstring so the user may specify the default
  2345. X     * job parameters in a resource, e.g.:     *param*string: -K2
  2346. X     */
  2347. X
  2348. X    FirstArg(XtNwidth, 100);
  2349. X    NextArg(XtNfromVert, printer_text);
  2350. X    NextArg(XtNfromHoriz, param_lab);
  2351. X    NextArg(XtNeditType, "edit");
  2352. X    NextArg(XtNinsertPosition, 0);
  2353. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2354. X    param_text = XtCreateManagedWidget("job_params", asciiTextWidgetClass,
  2355. X                         print_panel, Args, ArgCount);
  2356. X
  2357. X    XtOverrideTranslations(param_text,
  2358. X                   XtParseTranslationTable(text_translations));
  2359. X
  2360. X    FirstArg(XtNlabel, "Figures in batch:");
  2361. X    NextArg(XtNfromVert, param_text);
  2362. X    NextArg(XtNjustify, XtJustifyLeft);
  2363. X    NextArg(XtNborderWidth, 0);
  2364. X    num_batch_lab = XtCreateManagedWidget("num_batch_label", labelWidgetClass,
  2365. X                        print_panel, Args, ArgCount);
  2366. X    FirstArg(XtNwidth, 30);
  2367. X    NextArg(XtNlabel, "  0");
  2368. X    NextArg(XtNfromVert, param_text);
  2369. X    NextArg(XtNfromHoriz, num_batch_lab);
  2370. X    NextArg(XtNjustify, XtJustifyLeft);
  2371. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2372. X    num_batch = XtCreateManagedWidget("num_batch", labelWidgetClass,
  2373. X                         print_panel, Args, ArgCount);
  2374. X
  2375. X    FirstArg(XtNlabel, "Dismiss");
  2376. X    NextArg(XtNfromVert, num_batch);
  2377. X    NextArg(XtNvertDistance, 10);
  2378. X    NextArg(XtNhorizDistance, 6);
  2379. X    NextArg(XtNheight, 30);
  2380. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2381. X    dismiss = XtCreateManagedWidget("dismiss", commandWidgetClass,
  2382. X                       print_panel, Args, ArgCount);
  2383. X    XtAddEventHandler(dismiss, ButtonReleaseMask, (Boolean) 0,
  2384. X              (XtEventHandler)print_panel_dismiss, (XtPointer) NULL);
  2385. X
  2386. X    FirstArg(XtNlabel, "Print FIGURE\nto Printer");
  2387. X    NextArg(XtNfromVert, num_batch);
  2388. X    NextArg(XtNfromHoriz, dismiss);
  2389. X    NextArg(XtNheight, 30);
  2390. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2391. X    NextArg(XtNvertDistance, 10);
  2392. X    NextArg(XtNhorizDistance, 6);
  2393. X    print = XtCreateManagedWidget("print", commandWidgetClass,
  2394. X                      print_panel, Args, ArgCount);
  2395. X    XtAddEventHandler(print, ButtonReleaseMask, (Boolean) 0,
  2396. X              (XtEventHandler)do_print, (XtPointer) NULL);
  2397. X
  2398. X    FirstArg(XtNlabel, "Print FIGURE\nto Batch");
  2399. X    NextArg(XtNfromVert, num_batch);
  2400. X    NextArg(XtNfromHoriz, print);
  2401. X    NextArg(XtNheight, 30);
  2402. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2403. X    NextArg(XtNvertDistance, 10);
  2404. X    NextArg(XtNhorizDistance, 6);
  2405. X    print_batch = XtCreateManagedWidget("print_batch", commandWidgetClass,
  2406. X                      print_panel, Args, ArgCount);
  2407. X    XtAddEventHandler(print_batch, ButtonReleaseMask, (Boolean) 0,
  2408. X              (XtEventHandler)do_print_batch, (XtPointer) NULL);
  2409. X
  2410. X    FirstArg(XtNlabel, "Clear\nBatch");
  2411. X    NextArg(XtNfromVert, num_batch);
  2412. X    NextArg(XtNfromHoriz, print_batch);
  2413. X    NextArg(XtNheight, 30);
  2414. X    NextArg(XtNborderWidth, INTERNAL_BW);
  2415. X    NextArg(XtNvertDistance, 10);
  2416. X    NextArg(XtNhorizDistance, 6);
  2417. X    clear_batch = XtCreateManagedWidget("clear_batch", commandWidgetClass,
  2418. X                      print_panel, Args, ArgCount);
  2419. X    XtAddEventHandler(clear_batch, ButtonReleaseMask, (Boolean) 0,
  2420. X              (XtEventHandler)do_clear_batch, (XtPointer) NULL);
  2421. X
  2422. X    XtInstallAccelerators(print_panel, dismiss);
  2423. X    XtInstallAccelerators(print_panel, print_batch);
  2424. X    XtInstallAccelerators(print_panel, clear_batch);
  2425. X    XtInstallAccelerators(print_panel, print);
  2426. X    update_batch_count();
  2427. X}
  2428. END_OF_FILE
  2429. if test 14793 -ne `wc -c <'w_print.c'`; then
  2430.     echo shar: \"'w_print.c'\" unpacked with wrong size!
  2431. fi
  2432. # end of 'w_print.c'
  2433. fi
  2434. echo shar: End of archive 12 \(of 27\).
  2435. cp /dev/null ark12isdone
  2436. MISSING=""
  2437. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ; do
  2438.     if test ! -f ark${I}isdone ; then
  2439.     MISSING="${MISSING} ${I}"
  2440.     fi
  2441. done
  2442. if test "${MISSING}" = "" ; then
  2443.     echo You have unpacked all 27 archives.
  2444.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2445. else
  2446.     echo You still need to unpack the following archives:
  2447.     echo "        " ${MISSING}
  2448. fi
  2449. ##  End of shell archive.
  2450. exit 0
  2451.  
  2452. exit 0 # Just in case...
  2453. -- 
  2454.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  2455. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  2456.  "It's intuitively obvious to the |
  2457.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  2458.